diff --git a/src/addon/java/lua/addon/luacompat/LuaCompat.java b/src/addon/java/lua/addon/luacompat/LuaCompat.java index 9195ad62..5eaf2b26 100644 --- a/src/addon/java/lua/addon/luacompat/LuaCompat.java +++ b/src/addon/java/lua/addon/luacompat/LuaCompat.java @@ -66,7 +66,6 @@ public class LuaCompat extends LFunction { } public static final String[] GLOBAL_NAMES = { - "assert", "loadfile", "tonumber", "rawget", @@ -127,22 +126,21 @@ public class LuaCompat extends LFunction { }; private static final int GLOBALS_BASE = 0; - private static final int ASSERT = GLOBALS_BASE + 0; - private static final int LOADFILE = GLOBALS_BASE + 1; - private static final int TONUMBER = GLOBALS_BASE + 2; - private static final int RAWGET = GLOBALS_BASE + 3; - private static final int RAWSET = GLOBALS_BASE + 4; - private static final int SETFENV = GLOBALS_BASE + 5; - private static final int SELECT = GLOBALS_BASE + 6; - private static final int COLLECTGARBAGE = GLOBALS_BASE + 7; - private static final int DOFILE = GLOBALS_BASE + 8; - private static final int LOADSTRING = GLOBALS_BASE + 9; - private static final int LOAD = GLOBALS_BASE + 10; - private static final int TOSTRING = GLOBALS_BASE + 11; - private static final int UNPACK = GLOBALS_BASE + 12; - private static final int NEXT = GLOBALS_BASE + 13; - private static final int MODULE = GLOBALS_BASE + 14; - private static final int REQUIRE = GLOBALS_BASE + 15; + private static final int LOADFILE = GLOBALS_BASE + 0; + private static final int TONUMBER = GLOBALS_BASE + 1; + private static final int RAWGET = GLOBALS_BASE + 2; + private static final int RAWSET = GLOBALS_BASE + 3; + private static final int SETFENV = GLOBALS_BASE + 4; + private static final int SELECT = GLOBALS_BASE + 5; + private static final int COLLECTGARBAGE = GLOBALS_BASE + 6; + private static final int DOFILE = GLOBALS_BASE + 7; + private static final int LOADSTRING = GLOBALS_BASE + 8; + private static final int LOAD = GLOBALS_BASE + 9; + private static final int TOSTRING = GLOBALS_BASE + 10; + private static final int UNPACK = GLOBALS_BASE + 11; + private static final int NEXT = GLOBALS_BASE + 12; + private static final int MODULE = GLOBALS_BASE + 13; + private static final int REQUIRE = GLOBALS_BASE + 14; private static final int MATH_BASE = 20; @@ -191,18 +189,6 @@ public class LuaCompat extends LFunction { public boolean luaStackCall( VM vm ) { switch ( id ) { - case ASSERT: { - if ( !vm.getArgAsBoolean(0) ) { - String message; - if ( vm.getArgCount() > 1 ) { - message = vm.getArgAsString(1); - } else { - message = "assertion failed!"; - } - throw new RuntimeException(message); - } - vm.setResult(); - } break; case LOADFILE: loadfile(vm, vm.getArgAsString(0)); break; diff --git a/src/main/java/lua/Builtin.java b/src/main/java/lua/Builtin.java index 84ed1335..17c15d7a 100644 --- a/src/main/java/lua/Builtin.java +++ b/src/main/java/lua/Builtin.java @@ -24,6 +24,8 @@ final class Builtin extends JavaFunction { "type", "pcall", "ipairs", + "error", + "assert", }; private static final int PRINT = 0; private static final int PAIRS = 1; @@ -32,6 +34,8 @@ final class Builtin extends JavaFunction { private static final int TYPE = 4; private static final int PCALL = 5; private static final int IPAIRS = 6; + private static final int ERROR = 7; + private static final int ASSERT = 8; private static PrintStream stdout = System.out; @@ -90,6 +94,16 @@ final class Builtin extends JavaFunction { return 2; } } + case ERROR: { + vm.error(vm.tostring(1), vm.gettop()>1? vm.tointeger(2): 1); + } + case ASSERT: { + if ( ! vm.toboolean(1) ) { + vm.error( vm.gettop()>1? vm.tostring(2): "assertion failed!", 0 ); + } else { + return vm.gettop(); + } + } default: luaUnsupportedOperation(); return 0; diff --git a/src/main/java/lua/VM.java b/src/main/java/lua/VM.java index d3675080..8e8bee52 100644 --- a/src/main/java/lua/VM.java +++ b/src/main/java/lua/VM.java @@ -357,6 +357,14 @@ public interface VM { */ public void error(); + /** + * Raises an error with the default level. + * + * In the java implementation this throws a RuntimeException, possibly filling + * line number information first. + */ + public void error(String message); + /** * Raises an error. The message is pushed onto the stack and used as the error message. * It also adds at the beginning of the message the file name and the line number where @@ -365,7 +373,7 @@ public interface VM { * In the java implementation this throws a RuntimeException, possibly filling * line number information first. */ - public void error(String message); + public void error(String message, int level); /** * Controls the garbage collector. [-0, +0, e] diff --git a/src/main/java/lua/debug/DebugStackState.java b/src/main/java/lua/debug/DebugStackState.java index 11830710..5e3d665a 100644 --- a/src/main/java/lua/debug/DebugStackState.java +++ b/src/main/java/lua/debug/DebugStackState.java @@ -94,11 +94,16 @@ public class DebugStackState extends StackState implements DebugRequestListener return source+":"+line+"("+func+")"; } - // override and fill in line number info - public void error(String message) { - super.error( getFileLine(cc)+": "+message ); + public void error(String message, int level) { + super.error( level<=0? message: getFileLine(cc+1-level)+": "+message ); } + + // use line numbers by default + public void error(String message) { + error(message, 1); + } + private void printLuaTrace() { System.out.println( "Lua location: "+getFileLine(cc) ); @@ -112,11 +117,10 @@ public class DebugStackState extends StackState implements DebugRequestListener super.exec(); } catch (AbortException e) { // ignored. Client aborts the debugging session. - } catch ( Exception t ) { - t.printStackTrace(); - printLuaTrace(); - System.out.flush(); } + // let other exceptions be processed + // the same as the base class to minimize differences + // between the debug and non-debug behavior } diff --git a/src/main/java/lua/value/LThread.java b/src/main/java/lua/value/LThread.java index f7b0bfa4..781754dd 100644 --- a/src/main/java/lua/value/LThread.java +++ b/src/main/java/lua/value/LThread.java @@ -54,10 +54,9 @@ public class LThread extends LValue { public void resumeFrom(VM vm, int nargs) { if ( status == STATUS_DEAD ) { - vm.error("cannot resume dead coroutine"); -// vm.settop(0); -// vm.pushboolean(false); -// vm.pushstring("cannot resume dead coroutine"); + vm.settop(0); + vm.pushboolean(false); + vm.pushstring("cannot resume dead coroutine"); return; } diff --git a/src/test/java/lua/LuaJTest.java b/src/test/java/lua/LuaJTest.java index e2a6d570..2b7edbd2 100644 --- a/src/test/java/lua/LuaJTest.java +++ b/src/test/java/lua/LuaJTest.java @@ -16,12 +16,6 @@ import lua.value.LValue; public class LuaJTest extends TestCase { - /* - public void testCoroutines() throws IOException, InterruptedException { - runTest( "coroutines" ); - } - - /*/ public void testTest1() throws IOException, InterruptedException { runTest( "test1" ); } @@ -82,6 +76,10 @@ public class LuaJTest extends TestCase { runTest( "metatables" ); } + public void testPcalls() throws IOException, InterruptedException { + runTest( "pcalls" ); + } + public void testSelect() throws IOException, InterruptedException { runTest( "select" ); } @@ -109,7 +107,6 @@ public class LuaJTest extends TestCase { public void testUpvalues2() throws IOException, InterruptedException { runTest( "upvalues2" ); } - //*/ private void runTest( String testName ) throws IOException, InterruptedException { diff --git a/src/test/res/compile.sh b/src/test/res/compile.sh index 436f0cf8..eb930f15 100644 --- a/src/test/res/compile.sh +++ b/src/test/res/compile.sh @@ -1,6 +1,5 @@ #!/bin/bash TESTS=`echo *.lua` -TESTS="test3.lua" for x in $TESTS do echo compiling $x diff --git a/src/test/res/coroutines.luac b/src/test/res/coroutines.luac new file mode 100644 index 00000000..7f11dd30 Binary files /dev/null and b/src/test/res/coroutines.luac differ diff --git a/src/test/res/mathlib.luac b/src/test/res/mathlib.luac new file mode 100644 index 00000000..43d7c928 Binary files /dev/null and b/src/test/res/mathlib.luac differ diff --git a/src/test/res/pcalls.lua b/src/test/res/pcalls.lua new file mode 100644 index 00000000..12aa0385 --- /dev/null +++ b/src/test/res/pcalls.lua @@ -0,0 +1,36 @@ + +-- sample lua function that returns values in reverse order +local function lc(a,b,c) + return c,b,a +end + +-- sample lua function that throws a lua error +local function le(a,b,c) + error( 'sample error', 0 ) +end + +-- function that does a plain call to the underlying function +local function cp(f,a,b,c) + global = f(a,b,c) + return global +end + +-- function that does a tail call to the underlying function +local function ct(f,a,b,c) + return f(a,b,c) +end + +-- lua calls +print( 'lc(22,33,44)', lc(22,33,44) ) +print( 'pcall(lc,22,33,44)', pcall(lc,22,33,44) ) +print( 'pcall(le,22,33,44)', pcall(le,22,33,44) ) +print( 'cp(lc,22,33,44)', cp(lc,22,33,44) ) +print( 'pcall(cp,lc,22,33,44)', pcall(cp,lc,22,33,44) ) +print( 'pcall(cp,le,22,33,44)', pcall(cp,le,22,33,44) ) +print( 'ct(lc,22,33,44)', ct(lc,22,33,44) ) +print( 'pcall(ct,lc,22,33,44)', pcall(ct,lc,22,33,44) ) +print( 'pcall(ct,le,22,33,44)', pcall(ct,le,22,33,44) ) + +print( "assert(true,'a','b','c')", assert( true, 'a', 'b', 'c' ) ) +print( "pcall(assert,true,'a','b','c')", pcall(assert, true, 'a', 'b', 'c' ) ) +print( "pcall(assert,false,'a','b','c')", pcall(assert, false, 'a', 'b', 'c' ) ) diff --git a/src/test/res/pcalls.luac b/src/test/res/pcalls.luac new file mode 100644 index 00000000..4063726f Binary files /dev/null and b/src/test/res/pcalls.luac differ diff --git a/src/test/res/strlib.luac b/src/test/res/strlib.luac new file mode 100644 index 00000000..bb8dd750 Binary files /dev/null and b/src/test/res/strlib.luac differ