From 612b75d201066da249dae68c742b8bd21596cd86 Mon Sep 17 00:00:00 2001 From: James Roseborough Date: Fri, 23 Apr 2010 14:33:58 +0000 Subject: [PATCH] Code generator improvements. --- src/jse/org/luaj/vm2/luajc/Slots.java | 74 ++++++++++++---------- test/junit/org/luaj/vm2/FragmentsTest.java | 43 +++++++++++++ 2 files changed, 85 insertions(+), 32 deletions(-) diff --git a/src/jse/org/luaj/vm2/luajc/Slots.java b/src/jse/org/luaj/vm2/luajc/Slots.java index 49ec903e..d0411696 100644 --- a/src/jse/org/luaj/vm2/luajc/Slots.java +++ b/src/jse/org/luaj/vm2/luajc/Slots.java @@ -104,11 +104,17 @@ public class Slots { switch ( Lua.GET_OPCODE(ins) ) { case Lua.OP_GETUPVAL: /* A B R(A):= UpValue[B] */ - case Lua.OP_SETUPVAL: /* A B UpValue[B]:= R(A) */ case Lua.OP_NEWTABLE: /* A B C R(A):= {} (size = B,C) */ + case Lua.OP_LOADK:/* A Bx R(A):= Kst(Bx) */ + case Lua.OP_GETGLOBAL: /* A Bx R(A):= Gbl[Kst(Bx)] */ s[a] |= BIT_ASSIGN; break; + case Lua.OP_SETUPVAL: /* A B UpValue[B]:= R(A) */ + case Lua.OP_SETGLOBAL: /* A Bx Gbl[Kst(Bx)]:= R(A) */ + s[a] |= BIT_REFER; + break; + case Lua.OP_MOVE:/* A B R(A):= R(B) */ case Lua.OP_UNM: /* A B R(A):= -R(B) */ case Lua.OP_NOT: /* A B R(A):= not R(B) */ @@ -117,14 +123,8 @@ public class Slots { s[b] |= BIT_REFER; break; - case Lua.OP_LOADK:/* A Bx R(A):= Kst(Bx) */ - case Lua.OP_GETGLOBAL: /* A Bx R(A):= Gbl[Kst(Bx)] */ - case Lua.OP_SETGLOBAL: /* A Bx Gbl[Kst(Bx)]:= R(A) */ - s[a] |= BIT_ASSIGN; - break; - case Lua.OP_LOADNIL: /* A B R(A):= ...:= R(B):= nil */ - while ( a C) then pc++ */ s[a] |= BIT_REFER; - branchdest[index+2] = true; + //branchdest[index+2] = true; break; case Lua.OP_TESTSET: /* A B C if (R(B) <=> C) then R(A):= R(B) else pc++ */ s[a] |= BIT_REFER; s[b] |= BIT_REFER; - branchdest[index+2] = true; + //branchdest[index+2] = true; break; case Lua.OP_CALL: /* A B C R(A), ... ,R(A+C-2):= R(A)(R(A+1), ... ,R(A+B-1)) */ - for ( int i=0; iassign) promoteUpvalue( slots[index--], j ); @@ -377,16 +381,23 @@ public class Slots { } private int prevUndefined(int index, int j) { - while ( index>0 && ((slots[index][j] & BIT_INVALID) == 0) ) - --index; + for ( ; index>=0; --index ) + if ( ((slots[index][j] & BIT_INVALID) != 0) ) + return 0; return index; } - private int firstAssignAfter(int index, int limit, int j) { - for ( ; index0 && this.branchdest[index-1] ) return index; - } + return index; + } + + private int lastAssignBefore(int index, int limit, int j) { + for ( int i=index-1; i>limit; --i ) + if ( (slots[i][j] & (BIT_ASSIGN | BIT_NIL)) != 0 ) + return i; return index; } @@ -397,10 +408,9 @@ public class Slots { } private int lastAccessBefore(int index, int limit, int j) { - for ( --index; index>limit; --index ) { + for ( --index; index>limit; --index ) if ( (slots[index][j] & (BIT_ASSIGN|BIT_REFER)) != 0 ) return index; - } return index; } diff --git a/test/junit/org/luaj/vm2/FragmentsTest.java b/test/junit/org/luaj/vm2/FragmentsTest.java index 80ff3705..d6c6885f 100644 --- a/test/junit/org/luaj/vm2/FragmentsTest.java +++ b/test/junit/org/luaj/vm2/FragmentsTest.java @@ -291,4 +291,47 @@ public class FragmentsTest extends TestCase { "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" ); + } + }