diff --git a/README.html b/README.html index 344a6ab2..25f6a7fa 100644 --- a/README.html +++ b/README.html @@ -457,7 +457,6 @@ and LuaForge:
  • tail calls are not tracked in debug information
  • using both version 1 and 2 libraries together in the same java vm has not been tested
  • module() and setfenv() only partially supported for lau2java or luajc compiled lua -
  • luajc can produce invalid class files in some cases
  • values associated with weak keys may linger longer than expected diff --git a/src/jse/org/luaj/vm2/luajc/JavaBuilder.java b/src/jse/org/luaj/vm2/luajc/JavaBuilder.java index 01afa650..61d9a9bd 100644 --- a/src/jse/org/luaj/vm2/luajc/JavaBuilder.java +++ b/src/jse/org/luaj/vm2/luajc/JavaBuilder.java @@ -355,6 +355,17 @@ public class JavaBuilder { } } } + + public void convertToUpvalue(int pc, int slot) { + boolean isupassign = slots.isUpvalueAssign(pc, slot); + if ( isupassign ) { + int index = findSlotIndex( slot, false ); + append(new ALOAD(index)); + append(factory.createInvoke(classname, "newupl", TYPE_LOCALUPVALUE, new Type[] { TYPE_LUAVALUE }, Constants.INVOKESTATIC)); + int upindex = findSlotIndex( slot, true ); + append(new ASTORE(upindex)); + } + } private static String upvalueName(int upindex) { return PREFIX_UPVALUE+upindex; diff --git a/src/jse/org/luaj/vm2/luajc/JavaGen.java b/src/jse/org/luaj/vm2/luajc/JavaGen.java index 93f7d5dc..4026d38a 100644 --- a/src/jse/org/luaj/vm2/luajc/JavaGen.java +++ b/src/jse/org/luaj/vm2/luajc/JavaGen.java @@ -60,7 +60,7 @@ public class JavaGen { for ( int pc=0, n=p.code.length; pcc), (b>0)\n" ); - } + "t()\n" + + "return w\n" ); + + } + + public void testForLoops() { + runFragment( LuaValue.valueOf("12345 357 963"), + "local s,t,u = '','',''\n"+ + "for m=1,5 do\n"+ + " s = s..m\n"+ + "end\n"+ + "for m=3,7,2 do\n"+ + " t = t..m\n"+ + "end\n"+ + "for m=9,3,-3 do\n"+ + " u = u..m\n"+ + "end\n"+ + "return s..' '..t..' '..u\n" ); + } + + public void testLocalFunctionDeclarations() { + runFragment( LuaValue.varargsOf(LuaValue.valueOf("function"),LuaValue.valueOf("nil")), + "local function aaa()\n"+ + " return type(aaa)\n"+ + "end\n"+ + "local bbb = function()\n"+ + " return type(bbb)\n"+ + "end\n"+ + "return aaa(),bbb()\n" ); + } + + public void testNilsInTableConstructor() { + runFragment( LuaValue.valueOf("1=111 2=222 3=333 "), + "local t = { 111, 222, 333, nil, nil }\n"+ + "local s = ''\n"+ + "for i,v in ipairs(t) do \n" + + " s=s..tostring(i)..'='..tostring(v)..' '\n" + + "end\n"+ + "return s\n" ); + + } + + public void testUnreachableCode() { + runFragment( LuaValue.valueOf(66), + "local function foo(x) return x * 2 end\n" + + "local function bar(x, y)\n" + + " if x==y then\n" + + " return y\n" + + " else\n" + + " return foo(x)\n" + + " end\n" + + "end\n" + + "return bar(33,44)\n" ); + + } + public void testVarargsWithParameters() { + runFragment( LuaValue.valueOf(222), + "local func = function(t,...)\n"+ + " return (...)\n"+ + "end\n"+ + "return func(111,222,333)\n" ); + } + + public void testNoReturnValuesPlainCall() { + runFragment( LuaValue.TRUE, + "local testtable = {}\n"+ + "return pcall( function() testtable[1]=2 end )\n" ); + } + + public void testVarargsInTableConstructor() { + runFragment( LuaValue.valueOf(222), + "local function foo() return 111,222,333 end\n"+ + "local t = {'a','b',c='c',foo()}\n"+ + "return t[4]\n" ); + } - public void testNumericForUpvalues() { - runFragment( LuaValue.valueOf(8), - "for i = 3,4 do\n"+ - " i = i + 5\n"+ - " local a = function()\n"+ - " return i\n"+ - " end\n" + - " return a()\n"+ - "end\n"); + public void testVarargsInFirstArg() { + runFragment( LuaValue.valueOf(123), + "function aaa(x) return x end\n" + + "function bbb(y) return y end\n" + + "function ccc(z) return z end\n" + + "return ccc( aaa(bbb(123)), aaa(456) )\n" ); + } + + public void testSetUpvalueTableInitializer() { + runFragment( LuaValue.valueOf("b"), + "local aliases = {a='b'}\n" + + "local foo = function()\n" + + " return aliases\n" + + "end\n" + + "return foo().a\n" ); + } + + + public void testLoadNilUpvalue() { + runFragment( LuaValue.NIL, + "tostring = function() end\n" + + "local pc \n" + + "local pcall = function(...)\n" + + " pc(...)\n" + + "end\n" + + "return NIL\n" ); + } + + public void testUpvalueClosure() { + runFragment( LuaValue.NIL, + "print()\n"+ + "local function f2() end\n"+ + "local function f3()\n"+ + " return f3\n"+ + "end\n" + + "return NIL\n" ); + } + + public void testUninitializedUpvalue() { + runFragment( LuaValue.NIL, + "local f\n"+ + "do\n"+ + " function g()\n"+ + " print(f())\n"+ + " end\n"+ + "end\n" + + "return NIL\n" ); + } + + public void testTestOpUpvalues() { + runFragment( LuaValue.varargsOf(LuaValue.valueOf(1),LuaValue.valueOf(2),LuaValue.valueOf(3)), + "print( nil and 'T' or 'F' )\n"+ + "local a,b,c = 1,2,3\n"+ + "function foo()\n"+ + " return a,b,c\n"+ + "end\n" + + "return foo()\n" ); + } + public void testTestSimpleBinops() { + runFragment( LuaValue.varargsOf(new LuaValue[] { + LuaValue.FALSE, LuaValue.FALSE, LuaValue.TRUE, LuaValue.TRUE, LuaValue.FALSE }), + "local a,b,c = 2,-2.5,0\n" + + "return (a==c), (b==c), (a==a), (a>c), (b>0)\n" ); + } + + public void testNumericForUpvalues() { + runFragment( LuaValue.valueOf(8), + "for i = 3,4 do\n"+ + " i = i + 5\n"+ + " local a = function()\n"+ + " return i\n"+ + " end\n" + + " return a()\n"+ + "end\n"); + } } }