Add "Java API" like "C API" for use with JavaFunctions.
This commit is contained in:
@@ -219,7 +219,7 @@ public class LuaCompat extends LFunction {
|
||||
if ( t instanceof LTable ) {
|
||||
( (LTable) t ).put( k, v );
|
||||
} else {
|
||||
vm.lua_error( "expected table" );
|
||||
vm.error( "expected table" );
|
||||
}
|
||||
} break;
|
||||
case SETFENV:
|
||||
@@ -478,8 +478,8 @@ public class LuaCompat extends LFunction {
|
||||
private static boolean loadis(VM vm, InputStream is, String chunkname ) {
|
||||
try {
|
||||
vm.setResult();
|
||||
if ( 0 != vm.lua_load(is, chunkname) ) {
|
||||
vm.setErrorResult( LNil.NIL, "cannot load "+chunkname+": "+vm.lua_tolvalue(-1) );
|
||||
if ( 0 != vm.load(is, chunkname) ) {
|
||||
vm.setErrorResult( LNil.NIL, "cannot load "+chunkname+": "+vm.topointer(-1) );
|
||||
return false;
|
||||
} else {
|
||||
return true;
|
||||
@@ -515,10 +515,10 @@ public class LuaCompat extends LFunction {
|
||||
private void dofile( VM vm ) {
|
||||
String filename = vm.getArgAsString(0);
|
||||
if ( loadfile( vm, filename ) ) {
|
||||
int s = vm.lua_pcall(1, 0);
|
||||
int s = vm.pcall(1, 0, 0);
|
||||
vm.setResult( LInteger.valueOf( s!=0? 1: 0 ) );
|
||||
} else {
|
||||
vm.lua_error("cannot open "+filename);
|
||||
vm.error("cannot open "+filename);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -532,7 +532,7 @@ public class LuaCompat extends LFunction {
|
||||
// return true if loaded, false if error put onto stack
|
||||
private boolean load(VM vm, LValue chunkPartLoader, String chunkname) {
|
||||
if ( ! (chunkPartLoader instanceof Closure) ) {
|
||||
vm.lua_error("not a closure: "+chunkPartLoader);
|
||||
vm.error("not a closure: "+chunkPartLoader);
|
||||
}
|
||||
|
||||
// load all the parts
|
||||
@@ -541,7 +541,7 @@ public class LuaCompat extends LFunction {
|
||||
try {
|
||||
while ( true ) {
|
||||
vm.setResult(c);
|
||||
if ( 0 != vm.lua_pcall(0, 1) ) {
|
||||
if ( 0 != vm.pcall(0, 1, 0) ) {
|
||||
vm.setErrorResult(LNil.NIL, vm.getArgAsString(0));
|
||||
return false;
|
||||
}
|
||||
@@ -599,7 +599,7 @@ public class LuaCompat extends LFunction {
|
||||
// ======================== Module, Package loading =============================
|
||||
|
||||
public static void module( VM vm ) {
|
||||
vm.lua_error( "module not implemented" );
|
||||
vm.error( "module not implemented" );
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -635,9 +635,9 @@ public class LuaCompat extends LFunction {
|
||||
else {
|
||||
String s = modname.toJavaString();
|
||||
if ( ! loadfile(vm, s+".luac") && ! loadfile(vm, s+".lua") )
|
||||
vm.lua_error( "not found: "+s );
|
||||
else if ( 0 == vm.lua_pcall(0, 1) ) {
|
||||
LValue result = vm.lua_tolvalue( -1 );
|
||||
vm.error( "not found: "+s );
|
||||
else if ( 0 == vm.pcall(0, 1, 0) ) {
|
||||
LValue result = vm.topointer( -1 );
|
||||
if ( result != LNil.NIL )
|
||||
LOADED.put(modname, result);
|
||||
else if ( ! LOADED.containsKey(modname) )
|
||||
@@ -648,11 +648,11 @@ public class LuaCompat extends LFunction {
|
||||
}
|
||||
|
||||
public static void loadlib( VM vm ) {
|
||||
vm.lua_error( "loadlib not implemented" );
|
||||
vm.error( "loadlib not implemented" );
|
||||
}
|
||||
|
||||
public static void seeall( VM vm ) {
|
||||
vm.lua_error( "seeall not implemented" );
|
||||
vm.error( "seeall not implemented" );
|
||||
}
|
||||
|
||||
|
||||
@@ -683,7 +683,7 @@ public class LuaCompat extends LFunction {
|
||||
}
|
||||
vm.setResult( new LString( baos.toByteArray() ) );
|
||||
} catch (IOException e) {
|
||||
vm.lua_error(e.getMessage());
|
||||
vm.error(e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -68,7 +68,7 @@ public class StrLib {
|
||||
* TODO: port dumping code as optional add-on
|
||||
*/
|
||||
static void dump( VM vm ) {
|
||||
vm.lua_error("dump() not supported");
|
||||
vm.error("dump() not supported");
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -509,8 +509,8 @@ public class StrLib {
|
||||
lbuf.append( s.substring( soff, e ) );
|
||||
} else {
|
||||
push_onecapture( b - '1', soff, e );
|
||||
lbuf.append( vm.lua_tolvalue( -1 ).luaAsString() );
|
||||
vm.lua_pop( 1 );
|
||||
lbuf.append( vm.topointer( -1 ).luaAsString() );
|
||||
vm.pop( 1 );
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -523,25 +523,25 @@ public class StrLib {
|
||||
} else if ( repl instanceof LFunction ) {
|
||||
vm.push( repl );
|
||||
int n = push_captures( true, soffset, end );
|
||||
vm.lua_call( n, 1 );
|
||||
vm.call( n, 1 );
|
||||
} else if ( repl instanceof LTable ) {
|
||||
// Need to call push_onecapture here for the error checking
|
||||
push_onecapture( 0, soffset, end );
|
||||
LValue k = vm.lua_tolvalue( -1 );
|
||||
vm.lua_pop( 1 );
|
||||
LValue k = vm.topointer( -1 );
|
||||
vm.pop( 1 );
|
||||
((LTable) repl).luaGetTable( vm, repl, k );
|
||||
} else {
|
||||
vm.lua_error( "string/function/table expected" );
|
||||
vm.error( "string/function/table expected" );
|
||||
return;
|
||||
}
|
||||
|
||||
repl = vm.lua_tolvalue( -1 );
|
||||
repl = vm.topointer( -1 );
|
||||
if ( !repl.luaAsBoolean() ) {
|
||||
repl = s.substring( soffset, end );
|
||||
} else if ( ! ( repl instanceof LString || repl instanceof LNumber ) ) {
|
||||
vm.lua_error( "invalid replacement value (a "+repl.luaGetTypeName()+")" );
|
||||
vm.error( "invalid replacement value (a "+repl.luaGetTypeName()+")" );
|
||||
}
|
||||
vm.lua_pop( 1 );
|
||||
vm.pop( 1 );
|
||||
lbuf.append( repl.luaAsString() );
|
||||
}
|
||||
|
||||
@@ -558,12 +558,12 @@ public class StrLib {
|
||||
if ( i == 0 ) {
|
||||
vm.push( s.substring( soff, end ) );
|
||||
} else {
|
||||
vm.lua_error( "invalid capture index" );
|
||||
vm.error( "invalid capture index" );
|
||||
}
|
||||
} else {
|
||||
int l = clen[i];
|
||||
if ( l == CAP_UNFINISHED ) {
|
||||
vm.lua_error( "unfinished capture" );
|
||||
vm.error( "unfinished capture" );
|
||||
}
|
||||
if ( l == CAP_POSITION ) {
|
||||
vm.push( LInteger.valueOf( cinit[i] + 1 ) );
|
||||
@@ -577,7 +577,7 @@ public class StrLib {
|
||||
private int check_capture( int l ) {
|
||||
l -= '1';
|
||||
if ( l < 0 || l >= level || this.clen[l] == CAP_UNFINISHED ) {
|
||||
vm.lua_error("invalid capture index");
|
||||
vm.error("invalid capture index");
|
||||
}
|
||||
return l;
|
||||
}
|
||||
@@ -587,7 +587,7 @@ public class StrLib {
|
||||
for ( level--; level >= 0; level-- )
|
||||
if ( clen[level] == CAP_UNFINISHED )
|
||||
return level;
|
||||
vm.lua_error("invalid pattern capture");
|
||||
vm.error("invalid pattern capture");
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -595,7 +595,7 @@ public class StrLib {
|
||||
switch ( p.luaByte( poffset++ ) ) {
|
||||
case L_ESC:
|
||||
if ( poffset == p.length() ) {
|
||||
vm.lua_error( "malformed pattern (ends with %)" );
|
||||
vm.error( "malformed pattern (ends with %)" );
|
||||
}
|
||||
return poffset + 1;
|
||||
|
||||
@@ -603,7 +603,7 @@ public class StrLib {
|
||||
if ( p.luaByte( poffset ) == '^' ) poffset++;
|
||||
do {
|
||||
if ( poffset == p.length() ) {
|
||||
vm.lua_error( "malformed pattern (missing ])" );
|
||||
vm.error( "malformed pattern (missing ])" );
|
||||
}
|
||||
if ( p.luaByte( poffset++ ) == L_ESC && poffset != p.length() )
|
||||
poffset++;
|
||||
@@ -695,7 +695,7 @@ public class StrLib {
|
||||
case 'f': {
|
||||
poffset += 2;
|
||||
if ( p.luaByte( poffset ) != '[' ) {
|
||||
vm.lua_error("Missing [ after %f in pattern");
|
||||
vm.error("Missing [ after %f in pattern");
|
||||
}
|
||||
int ep = classend( poffset );
|
||||
int previous = ( soffset == 0 ) ? -1 : s.luaByte( soffset - 1 );
|
||||
@@ -775,7 +775,7 @@ public class StrLib {
|
||||
int res;
|
||||
int level = this.level;
|
||||
if ( level >= MAX_CAPTURES ) {
|
||||
vm.lua_error( "too many captures" );
|
||||
vm.error( "too many captures" );
|
||||
}
|
||||
cinit[ level ] = soff;
|
||||
clen[ level ] = what;
|
||||
@@ -807,7 +807,7 @@ public class StrLib {
|
||||
int matchbalance( int soff, int poff ) {
|
||||
final int plen = p.length();
|
||||
if ( poff == plen || poff + 1 == plen ) {
|
||||
vm.lua_error( "unbalanced pattern" );
|
||||
vm.error( "unbalanced pattern" );
|
||||
}
|
||||
if ( s.luaByte( soff ) != p.luaByte( poff ) )
|
||||
return -1;
|
||||
|
||||
@@ -78,9 +78,9 @@ final class Builtin extends LFunction {
|
||||
break;
|
||||
case PCALL: {
|
||||
int n = vm.getArgCount();
|
||||
int s = vm.lua_pcall( n-1, Lua.LUA_MULTRET );
|
||||
int s = vm.pcall( n-1, Lua.LUA_MULTRET, 0 );
|
||||
if ( s != 0 ) {
|
||||
LValue v = vm.lua_tolvalue(-1);
|
||||
LValue v = vm.topointer(-1);
|
||||
vm.setResult( LBoolean.FALSE );
|
||||
vm.push( v );
|
||||
} else {
|
||||
|
||||
74
src/main/java/lua/JavaFunction.java
Normal file
74
src/main/java/lua/JavaFunction.java
Normal file
@@ -0,0 +1,74 @@
|
||||
package lua;
|
||||
|
||||
import lua.value.LFunction;
|
||||
|
||||
|
||||
/**
|
||||
Type for Java functions.
|
||||
|
||||
|
||||
<p>
|
||||
In order to communicate properly with Lua,
|
||||
a Java function must use the following protocol,
|
||||
which defines the way parameters and results are passed:
|
||||
a Java function receives its arguments from Lua in its stack
|
||||
in direct order (the first argument is pushed first).
|
||||
So, when the function starts,
|
||||
<code>lua_gettop(L)</code> returns the number of arguments received by the function.
|
||||
The first argument (if any) is at index 1
|
||||
and its last argument is at index <code>lua_gettop(L)</code>.
|
||||
To return values to Lua, a Java function just pushes them onto the stack,
|
||||
in direct order (the first result is pushed first),
|
||||
and returns the number of results.
|
||||
Any other value in the stack below the results will be properly
|
||||
discarded by Lua.
|
||||
Like a Lua function, a Java function called by Lua can also return
|
||||
many results.
|
||||
|
||||
|
||||
<p>
|
||||
As an example, the following function receives a variable number
|
||||
of numerical arguments and returns their average and sum:
|
||||
|
||||
<pre><code>
|
||||
int foo (VM lua) {
|
||||
int n = lua.gettop(); // number of arguments
|
||||
double sum = 0;
|
||||
int i;
|
||||
for (i = 1; i <= n; i++) {
|
||||
if (!lua.isnumber(L, i)) {
|
||||
lua.pushstring(L, "incorrect argument");
|
||||
lua.error(L);
|
||||
}
|
||||
sum += lua.tonumber(L, i);
|
||||
}
|
||||
lua.pushnumber(L, sum/n); // first result
|
||||
lua.pushnumber(L, sum); // second result
|
||||
return 2; // number of results
|
||||
}
|
||||
</code></pre>
|
||||
*/
|
||||
|
||||
abstract public class JavaFunction extends LFunction {
|
||||
|
||||
/**
|
||||
* Called to invoke a JavaFunction.
|
||||
*
|
||||
* The implementation should manipulate the stack
|
||||
* via the VM Java API in the same way that lua_CFunctions
|
||||
* do so in standard lua.
|
||||
*
|
||||
* @param lua the LuaState calling this function.
|
||||
* @return number of results pushed onto the stack.
|
||||
*/
|
||||
abstract public int invoke( VM lua );
|
||||
|
||||
/**
|
||||
* Set up a Java invocation, and fix up the results
|
||||
* when it returns.
|
||||
*/
|
||||
public boolean luaStackCall(VM vm) {
|
||||
vm.invokeJavaFunction( this );
|
||||
return true;
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -89,8 +89,8 @@ public class DebugStackState extends StackState implements DebugRequestListener
|
||||
|
||||
|
||||
// override and fill in line number info
|
||||
public void lua_error(String message) {
|
||||
super.lua_error( getFileLine(cc)+": "+message );
|
||||
public void error(String message) {
|
||||
super.error( getFileLine(cc)+": "+message );
|
||||
}
|
||||
|
||||
private void printLuaTrace() {
|
||||
|
||||
@@ -15,14 +15,14 @@ public class LFunction extends LValue {
|
||||
vm.push( table );
|
||||
vm.push( key );
|
||||
vm.push( val );
|
||||
vm.lua_call( 3, 0 );
|
||||
vm.call( 3, 0 );
|
||||
}
|
||||
|
||||
public void luaGetTable(VM vm, LValue table, LValue key) {
|
||||
vm.push( this );
|
||||
vm.push( table );
|
||||
vm.push( key );
|
||||
vm.lua_call( 2, 1 );
|
||||
vm.call( 2, 1 );
|
||||
}
|
||||
|
||||
public int luaGetType() {
|
||||
|
||||
@@ -33,7 +33,7 @@ public class LValue {
|
||||
// perform a lua call, return true if the call is to a lua function, false
|
||||
// if it ran to completion.
|
||||
public boolean luaStackCall(VM vm) {
|
||||
vm.lua_error("attempt to call "+this);
|
||||
vm.error("attempt to call "+this);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user