diff --git a/README.html b/README.html index 07c31f85..567b328c 100644 --- a/README.html +++ b/README.html @@ -731,6 +731,7 @@ and LuaForge:
  • Allow access to public members of private inner classes where possible
  • Add line and column info to org.luaj.vm2.ast parse tree elements generated using LuaParser
  • Drop support for lua source to java surce (lua2java) in favor of direct java bytecode output (luajc)
  • +
  • Remove compatibility functions like table.getn(), table.maxn(), table.foreach(), and math.log10()
  • diff --git a/src/core/org/luaj/vm2/Lua.java b/src/core/org/luaj/vm2/Lua.java index fb34f027..57f3b40c 100644 --- a/src/core/org/luaj/vm2/Lua.java +++ b/src/core/org/luaj/vm2/Lua.java @@ -182,7 +182,7 @@ public class Lua { public static final int OP_LOADK = 1;/* A Bx R(A) := Kst(Bx) */ public static final int OP_LOADKX = 2;/* A R(A) := Kst(extra arg) */ public static final int OP_LOADBOOL = 3;/* A B C R(A) := (Bool)B; if (C) pc++ */ - public static final int OP_LOADNIL = 4; /* A B R(A) := ... := R(B) := nil */ + public static final int OP_LOADNIL = 4; /* A B R(A) := ... := R(A+B) := nil */ public static final int OP_GETUPVAL = 5; /* A B R(A) := UpValue[B] */ public static final int OP_GETTABUP = 6; /* A B C R(A) := UpValue[B][RK(C)] */ diff --git a/src/core/org/luaj/vm2/LuaClosure.java b/src/core/org/luaj/vm2/LuaClosure.java index d11a0556..6ee03729 100644 --- a/src/core/org/luaj/vm2/LuaClosure.java +++ b/src/core/org/luaj/vm2/LuaClosure.java @@ -134,12 +134,16 @@ public class LuaClosure extends LuaFunction { public final LuaValue call() { LuaValue[] stack = new LuaValue[p.maxstacksize]; + for (int i = 0; i < p.numparams; ++i ) + stack[i] = NIL; return execute(stack,NONE).arg1(); } public final LuaValue call(LuaValue arg) { LuaValue[] stack = new LuaValue[p.maxstacksize]; System.arraycopy(NILS, 0, stack, 0, p.maxstacksize); + for (int i = 1; i < p.numparams; ++i ) + stack[i] = NIL; switch ( p.numparams ) { default: stack[0]=arg; return execute(stack,NONE).arg1(); case 0: return execute(stack,arg).arg1(); @@ -148,7 +152,8 @@ public class LuaClosure extends LuaFunction { public final LuaValue call(LuaValue arg1, LuaValue arg2) { LuaValue[] stack = new LuaValue[p.maxstacksize]; - System.arraycopy(NILS, 0, stack, 0, p.maxstacksize); + for (int i = 2; i < p.numparams; ++i ) + stack[i] = NIL; switch ( p.numparams ) { default: stack[0]=arg1; stack[1]=arg2; return execute(stack,NONE).arg1(); case 1: stack[0]=arg1; return execute(stack,arg2).arg1(); @@ -158,7 +163,8 @@ public class LuaClosure extends LuaFunction { public final LuaValue call(LuaValue arg1, LuaValue arg2, LuaValue arg3) { LuaValue[] stack = new LuaValue[p.maxstacksize]; - System.arraycopy(NILS, 0, stack, 0, p.maxstacksize); + for (int i = 3; i < p.numparams; ++i ) + stack[i] = NIL; switch ( p.numparams ) { default: stack[0]=arg1; stack[1]=arg2; stack[2]=arg3; return execute(stack,NONE).arg1(); case 2: stack[0]=arg1; stack[1]=arg2; return execute(stack,arg3).arg1(); @@ -173,7 +179,6 @@ public class LuaClosure extends LuaFunction { public Varargs onInvoke(Varargs varargs) { LuaValue[] stack = new LuaValue[p.maxstacksize]; - System.arraycopy(NILS, 0, stack, 0, p.maxstacksize); for ( int i=0; i>>23; a<=b; ) + case Lua.OP_LOADNIL: /* A B R(A):= ...:= R(A+B):= nil */ + for ( b=i>>>23; b-->=0; ) stack[a++] = LuaValue.NIL; continue; diff --git a/src/core/org/luaj/vm2/LuaTable.java b/src/core/org/luaj/vm2/LuaTable.java index 80a9c545..53f79cab 100644 --- a/src/core/org/luaj/vm2/LuaTable.java +++ b/src/core/org/luaj/vm2/LuaTable.java @@ -322,8 +322,11 @@ public class LuaTable extends LuaValue { * @return The removed item, or {@link #NONE} if not removed */ public LuaValue remove(int pos) { + int n = length(); if ( pos == 0 ) - pos = length(); + pos = n; + else if (pos > n) + return NONE; LuaValue v = rawget(pos); for ( LuaValue r=v; !r.isnil(); ) { r = rawget(pos+1); @@ -366,13 +369,6 @@ public class LuaTable extends LuaValue { return sb.tostring(); } - public LuaValue getn() { - for ( int n=getArrayLength(); n>0; --n ) - if ( !rawget(n).isnil() ) - return LuaInteger.valueOf(n); - return ZERO; - } - public int length() { int a = getArrayLength(); int n = a+1,m=0; @@ -398,27 +394,6 @@ public class LuaTable extends LuaValue { return length(); } - /** Return table.maxn() as defined by lua 5.0. - *

    - * Provided for compatibility, not a scalable operation. - * @return value for maxn - */ - public int maxn() { - int n = 0; - for ( int i=0; i n ) - n = key; - } - } - return n; - } - /** * Get the next element after a particular key in the table * @return key,value or nil @@ -469,36 +444,6 @@ public class LuaTable extends LuaValue { LuaValue v = rawget(k); return v.isnil()? NONE: varargsOf(LuaInteger.valueOf(k),v); } - - /** - * Call the supplied function once for each key-value pair - * - * @param func function to call - */ - public LuaValue foreach(LuaValue func) { - Varargs n; - LuaValue k = NIL; - LuaValue v; - while ( !(k = ((n = next(k)).arg1())).isnil() ) - if ( ! (v = func.call(k, n.arg(2))).isnil() ) - return v; - return NIL; - } - - /** - * Call the supplied function once for each key-value pair - * in the contiguous array part - * - * @param func - */ - public LuaValue foreachi(LuaValue func) { - LuaValue v,r; - for ( int k=0; !(v = rawget(++k)).isnil(); ) - if ( ! (r = func.call(valueOf(k), v)).isnil() ) - return r; - return NIL; - } - /** * Set a hashtable value diff --git a/src/core/org/luaj/vm2/LuaValue.java b/src/core/org/luaj/vm2/LuaValue.java index 960e711b..4e628f5e 100644 --- a/src/core/org/luaj/vm2/LuaValue.java +++ b/src/core/org/luaj/vm2/LuaValue.java @@ -2014,12 +2014,6 @@ public class LuaValue extends Varargs { * @throws LuaError if {@code this} is not a table or string. */ public int rawlen() { typerror("table or string"); return 0; } - - /** Implementation of lua 5.0 getn() function. - * @return value of getn() as defined in lua 5.0 spec if {@code this} is a {@link LuaTable} - * @throws LuaError if {@code this} is not a {@link LuaTable} - */ - public LuaValue getn() { return typerror("getn"); } // object equality, used for key comparison public boolean equals(Object obj) { return this == obj; } diff --git a/src/core/org/luaj/vm2/WeakTable.java b/src/core/org/luaj/vm2/WeakTable.java index 32a6334f..73cb5b64 100644 --- a/src/core/org/luaj/vm2/WeakTable.java +++ b/src/core/org/luaj/vm2/WeakTable.java @@ -185,11 +185,6 @@ public class WeakTable extends LuaTable { } return i; } - - public int maxn() { - return super.maxn(); - } - /** * Get the next element after a particular key in the table diff --git a/src/core/org/luaj/vm2/lib/TableLib.java b/src/core/org/luaj/vm2/lib/TableLib.java index 7c7327d7..4fd5f518 100644 --- a/src/core/org/luaj/vm2/lib/TableLib.java +++ b/src/core/org/luaj/vm2/lib/TableLib.java @@ -63,9 +63,9 @@ public class TableLib extends OneArgFunction { private LuaTable init(LuaValue env) { LuaTable t = new LuaTable(); - bind(t, TableLib.class, new String[] { "getn", "maxn", }, 1 ); + bind(t, TableLib.class, new String[] {}, 1 ); bind(t, TableLibV.class, new String[] { - "remove", "concat", "insert", "sort", "foreach", "foreachi", "unpack", } ); + "remove", "concat", "insert", "sort", "unpack", } ); env.set("table", t); PackageLib.instance.LOADED.set("table", t); return t; @@ -75,10 +75,6 @@ public class TableLib extends OneArgFunction { switch ( opcode ) { case 0: // init library return init(arg); - case 1: // "getn" (table) -> number - return arg.checktable().getn(); - case 2: // "maxn" (table) -> number - return valueOf( arg.checktable().maxn()); } return NIL; } @@ -111,13 +107,7 @@ public class TableLib extends OneArgFunction { table.sort( compare ); return NONE; } - case 4: { // (table, func) -> void - return args.checktable(1).foreach( args.checkfunction(2) ); - } - case 5: { // "foreachi" (table, func) -> void - return args.checktable(1).foreachi( args.checkfunction(2) ); - } - case 6: // "unpack", // (list [,i [,j]]) -> result1, ... + case 4: // "unpack", // (list [,i [,j]]) -> result1, ... { LuaTable t = args.checktable(1); switch (args.narg()) { diff --git a/src/jse/org/luaj/vm2/luajc/JavaGen.java b/src/jse/org/luaj/vm2/luajc/JavaGen.java index f9c6ff8e..b9c757a9 100644 --- a/src/jse/org/luaj/vm2/luajc/JavaGen.java +++ b/src/jse/org/luaj/vm2/luajc/JavaGen.java @@ -122,10 +122,10 @@ public class JavaGen { builder.storeLocal( pc, a ); break; - case Lua.OP_LOADNIL: /* A B R(A):= ...:= R(B):= nil */ + case Lua.OP_LOADNIL: /* A B R(A):= ...:= R(A+B):= nil */ builder.loadNil(); - for ( ; a<=b; a++ ) { - if ( a < b ) + for ( ; b>=0; a++, b-- ) { + if ( b > 0 ) builder.dup(); builder.storeLocal( pc, a ); } diff --git a/src/jse/org/luaj/vm2/luajc/ProtoInfo.java b/src/jse/org/luaj/vm2/luajc/ProtoInfo.java index 3b003b50..b09fb281 100644 --- a/src/jse/org/luaj/vm2/luajc/ProtoInfo.java +++ b/src/jse/org/luaj/vm2/luajc/ProtoInfo.java @@ -265,10 +265,10 @@ public class ProtoInfo { v[a+3][pc] = new VarInfo(a+3,pc); break; - case Lua.OP_LOADNIL: /* A B R(A) := ... := R(B) := nil */ + case Lua.OP_LOADNIL: /* A B R(A) := ... := R(A+B) := nil */ a = Lua.GETARG_A( ins ); b = Lua.GETARG_B( ins ); - for ( ; a<=b; a++ ) + for ( ; b-->=0; a++ ) v[a][pc] = new VarInfo(a,pc); break; diff --git a/test/java/Model.java b/test/java/Model.java new file mode 100644 index 00000000..7d86cfd1 --- /dev/null +++ b/test/java/Model.java @@ -0,0 +1,12 @@ + + +import org.luaj.vm2.LuaValue; +import org.luaj.vm2.lib.VarArgFunction; + +public class Model extends VarArgFunction { + LuaValue[] u0; + + public void initupvalue1(LuaValue env) { + u0 = this.newupl(env); + } +} diff --git a/test/java/org/luaj/luajc/SampleMainChunk.java b/test/java/org/luaj/luajc/SampleMainChunk.java new file mode 100644 index 00000000..87168ada --- /dev/null +++ b/test/java/org/luaj/luajc/SampleMainChunk.java @@ -0,0 +1,61 @@ +package org.luaj.luajc; + +import org.luaj.vm2.LuaValue; +import org.luaj.vm2.Varargs; +import org.luaj.vm2.lib.TwoArgFunction; +import org.luaj.vm2.lib.VarArgFunction; + +public class SampleMainChunk extends VarArgFunction { + + static final LuaValue $print = valueOf("print"); + static final LuaValue $foo = valueOf("foo"); + + LuaValue[] rw_ENV; // The environment when it is read-write +// LuaValue ro_ENV; // The environment when it is read-only in all sub-functions + + LuaValue[] rw_openup1; // upvalue that we create and modify in "slot" 1, passed to sub-function in initer. + LuaValue[] rw_openup2; // array is instantiated on first set or before supply to closure, after that value is get, set. + LuaValue[] rw_openup3; // closing these nulls them out, sub-functions still retain references to array & can use + LuaValue ro_openup4; // open upvalue that is read-only once it is supplied to an inner function. + LuaValue ro_openup5; // closing this also nulls it out. + + // Must have this in the main chunk so it can be loaded and instantiated on all platforms. + public SampleMainChunk() { + } + + public void initupvalue1(LuaValue[] v) { + this.rw_ENV = v; + } + + public Varargs invoke(Varargs args) { + rw_ENV[0].get($print).call($foo); + + rw_ENV[0].set($print, new InnerFunction(rw_openup3, rw_openup1, ro_openup5)); + + return null; + } + + static class InnerFunction extends TwoArgFunction { + static final LuaValue $print = valueOf("print"); // A constant, named for what it is. + static final LuaValue $foo = valueOf("foo"); + + final LuaValue[] rw_upvalue1; // from enclosing function, corresponds to upvaldesc not instack. + final LuaValue[] rw_upvalue2; // from enclosing function, corresponds to upvaldesc not instack. + final LuaValue ro_upvalue3; // from enclosing function, but read-only everywhere. + + LuaValue[] rw_openup1; // closing these nulls them out, sub-functions still retain references to array & can use + LuaValue ro_openup2; // open upvalue that is read-only once it is supplied to an inner function. + + InnerFunction(LuaValue[] rw_upvalue1, LuaValue[] rw_upvalue2, LuaValue ro_upvalue3) { + this.rw_upvalue1 = rw_upvalue1; + this.rw_upvalue2 = rw_upvalue2; + this.ro_upvalue3 = ro_upvalue3; + } + + public LuaValue call(LuaValue arg1, LuaValue arg2) { + return NIL; + } + + } + +} diff --git a/test/java/org/luaj/luajc/TestLuaJC.java b/test/java/org/luaj/luajc/TestLuaJC.java index e6790e39..6f985683 100644 --- a/test/java/org/luaj/luajc/TestLuaJC.java +++ b/test/java/org/luaj/luajc/TestLuaJC.java @@ -37,12 +37,7 @@ public class TestLuaJC { // create the script public static String name = "script"; public static String script = - "local t = a or nil\n"+ - "local t\n" + - "b = function()\n"+ - " return t\n"+ - "end\n"+ - "return t\n"+ + "_ENV={}; return _ENV\n"+ ""; public static void main(String[] args) throws Exception { @@ -51,6 +46,8 @@ public class TestLuaJC { // create an environment to run in LuaTable _G = JsePlatform.standardGlobals(); + System.out.println("_G: "+_G); + System.out.println("_G.print: "+_G.get("print")); // compile into a chunk, or load as a class LuaValue chunk; @@ -60,7 +57,6 @@ public class TestLuaJC { } else { chunk = (LuaValue) Class.forName("script").newInstance(); } - //chunk.setfenv(_G); // TODO: convert to setupvalue()? // call with arguments LuaValue[] vargs = new LuaValue[args.length]; diff --git a/test/junit/org/luaj/vm2/FragmentsTest.java b/test/junit/org/luaj/vm2/FragmentsTest.java index 42029d04..5ef30ea7 100644 --- a/test/junit/org/luaj/vm2/FragmentsTest.java +++ b/test/junit/org/luaj/vm2/FragmentsTest.java @@ -87,6 +87,13 @@ public class FragmentsTest extends TestSuite { } } + public void testFirstArgNilExtended() { + runFragment( LuaValue.NIL, + "function f1(a) print( 'f1:', a ) return a end\n" + + "b = f1()\n" + + "return b" ); + } + public void testForloopParamUpvalues() { runFragment( LuaValue.varargsOf(new LuaValue[] { LuaValue.valueOf(77), @@ -119,7 +126,7 @@ public class FragmentsTest extends TestSuite { "end\n" + "return v('abc')\n" ); } - + public void testSetlistVarargs() { runFragment( LuaValue.valueOf("abc"), "local f = function() return 'abc' end\n" + diff --git a/test/junit/org/luaj/vm2/TableArrayTest.java b/test/junit/org/luaj/vm2/TableArrayTest.java index 3ce96ea4..ac084e92 100644 --- a/test/junit/org/luaj/vm2/TableArrayTest.java +++ b/test/junit/org/luaj/vm2/TableArrayTest.java @@ -225,7 +225,6 @@ public class TableArrayTest extends TestCase { LuaValue v = LuaString.valueOf( "Test Value! "+i ); t.set( i, v ); assertEquals( i, t.length() ); - assertEquals( i, t.maxn() ); } } @@ -237,7 +236,6 @@ public class TableArrayTest extends TestCase { t.set( i, LuaString.valueOf( "Test Value! "+i ) ); } assertEquals( j, t.length() ); - assertEquals( j, t.maxn() ); } } @@ -247,7 +245,6 @@ public class TableArrayTest extends TestCase { for ( int i = 1; i <= 32; ++i ) { t.set( "str-"+i, LuaString.valueOf( "String Key Test Value! "+i ) ); assertEquals( 0, t.length() ); - assertEquals( 0, t.maxn() ); } } @@ -258,7 +255,6 @@ public class TableArrayTest extends TestCase { t.set( "str-"+i, LuaString.valueOf( "String Key Test Value! "+i ) ); t.set( i, LuaString.valueOf( "Int Key Test Value! "+i ) ); assertEquals( i, t.length() ); - assertEquals( i, t.maxn() ); } } diff --git a/test/junit/org/luaj/vm2/TableTest.java b/test/junit/org/luaj/vm2/TableTest.java index 8c9c1953..785981fa 100644 --- a/test/junit/org/luaj/vm2/TableTest.java +++ b/test/junit/org/luaj/vm2/TableTest.java @@ -228,7 +228,6 @@ public class TableTest extends TestCase { for ( int i = 1; i <= 32; ++i ) { t.set( i, LuaValue.valueOf( "Test Value! "+i ) ); assertEquals( i, t.length() ); - assertEquals( i, t.maxn() ); } } @@ -240,7 +239,6 @@ public class TableTest extends TestCase { t.set( i, LuaValue.valueOf( "Test Value! "+i ) ); } assertEquals( j, t.length() ); - assertEquals( j, t.maxn() ); } } @@ -250,7 +248,6 @@ public class TableTest extends TestCase { for ( int i = 1; i <= 32; ++i ) { t.set( "str-"+i, LuaValue.valueOf( "String Key Test Value! "+i ) ); assertEquals( 0, t.length() ); - assertEquals( 0, t.maxn() ); } } @@ -261,7 +258,6 @@ public class TableTest extends TestCase { t.set( "str-"+i, LuaValue.valueOf( "String Key Test Value! "+i ) ); t.set( i, LuaValue.valueOf( "Int Key Test Value! "+i ) ); assertEquals( i, t.length() ); - assertEquals( i, t.maxn() ); } } diff --git a/test/lua/debuglib.lua b/test/lua/debuglib.lua index 10125669..2af54ae9 100644 --- a/test/lua/debuglib.lua +++ b/test/lua/debuglib.lua @@ -122,7 +122,7 @@ local fields = { 'source', 'short_src', 'what', 'currentline', 'linedefined', 'lastlinedefined', 'nups', 'func', 'activelines' } local printinfo = function(...) - for i,a in ipairs(arg) do + for i,a in ipairs({...}) do if type(a) == 'table' then for j,field in ipairs(fields) do printfield( a, field) diff --git a/test/lua/errors/tablelibargs.lua b/test/lua/errors/tablelibargs.lua index ab91c10b..895b79a6 100644 --- a/test/lua/errors/tablelibargs.lua +++ b/test/lua/errors/tablelibargs.lua @@ -29,11 +29,6 @@ checkallpass('table.insert',{sometable,somei,notanil}) checkallerrors('table.insert',{notatable,somestring},'bad argument') checkallerrors('table.insert',{sometable,notij,notanil},'bad argument') --- table.maxn -banner('table.maxn') -checkallpass('table.maxn',{sometable}) -checkallerrors('table.maxn',{notatable},'bad argument') - -- table.remove banner('table.remove') checkallpass('table.remove',{sometable}) diff --git a/test/lua/tablelib.lua b/test/lua/tablelib.lua index f7139430..7c33c253 100644 --- a/test/lua/tablelib.lua +++ b/test/lua/tablelib.lua @@ -52,7 +52,7 @@ function eles(t,f) return "{"..table.concat(all,',').."}" end --- insert, maxn +-- insert, len print( '-- insert, len tests' ) local t = { "one", "two", "three", a='aaa', b='bbb', c='ccc' } @@ -105,40 +105,6 @@ sorttest{ "one", "two", "three" } sorttest{ "www", "vvv", "uuu", "ttt", "sss", "zzz", "yyy", "xxx" } sorttest( { "www", "vvv", "uuu", "ttt", "sss", "zzz", "yyy", "xxx" }, function(a,b) return b