Fix for loop processing in luajc compiler code generator for lua 5.3 bytecodes
This commit is contained in:
@@ -225,8 +225,7 @@ public class Lua {
|
|||||||
public static final int OP_FORPREP = 33; /* A sBx R(A)-=R(A+2); pc+=sBx */
|
public static final int OP_FORPREP = 33; /* A sBx R(A)-=R(A+2); pc+=sBx */
|
||||||
|
|
||||||
public static final int OP_TFORCALL = 34; /* A C R(A+3), ... ,R(A+2+C) := R(A)(R(A+1), R(A+2)); */
|
public static final int OP_TFORCALL = 34; /* A C R(A+3), ... ,R(A+2+C) := R(A)(R(A+1), R(A+2)); */
|
||||||
public static final int OP_TFORLOOP = 35; /* A C R(A+3), ... ,R(A+2+C) := R(A)(R(A+1), R(A+2));
|
public static final int OP_TFORLOOP = 35; /* A sBx if R(A+1) ~= nil then { R(A)=R(A+1); pc += sBx } */
|
||||||
if R(A+3) ~= nil then R(A+2)=R(A+3) else pc++ */
|
|
||||||
public static final int OP_SETLIST = 36; /* A B C R(A)[(C-1)*FPF+i] := R(A+i), 1 <= i <= B */
|
public static final int OP_SETLIST = 36; /* A B C R(A)[(C-1)*FPF+i] := R(A+i), 1 <= i <= B */
|
||||||
|
|
||||||
public static final int OP_CLOSURE = 37; /* A Bx R(A) := closure(KPROTO[Bx], R(A), ... ,R(A+n)) */
|
public static final int OP_CLOSURE = 37; /* A Bx R(A) := closure(KPROTO[Bx], R(A), ... ,R(A+n)) */
|
||||||
|
|||||||
@@ -434,9 +434,10 @@ public class LuaClosure extends LuaFunction {
|
|||||||
c = (i>>14) & 0x1ff;
|
c = (i>>14) & 0x1ff;
|
||||||
while (--c >= 0)
|
while (--c >= 0)
|
||||||
stack[a+3+c] = v.arg(c+1);
|
stack[a+3+c] = v.arg(c+1);
|
||||||
|
v = NONE;
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
case Lua.OP_TFORLOOP: /* A sBx if R(A) != nil then ps+= sBx */
|
case Lua.OP_TFORLOOP: /* A sBx if R(A+1) ~= nil then { R(A)=R(A+1); pc += sBx */
|
||||||
if (!stack[a+1].isnil()) { /* continue loop? */
|
if (!stack[a+1].isnil()) { /* continue loop? */
|
||||||
stack[a] = stack[a+1]; /* save control varible. */
|
stack[a] = stack[a+1]; /* save control varible. */
|
||||||
pc += (i>>>14)-0x1ffff;
|
pc += (i>>>14)-0x1ffff;
|
||||||
|
|||||||
@@ -395,11 +395,15 @@ public class DebugLib extends OneArgFunction {
|
|||||||
// debug.upvaluejoin (f1, n1, f2, n2)
|
// debug.upvaluejoin (f1, n1, f2, n2)
|
||||||
final class upvaluejoin extends VarArgFunction {
|
final class upvaluejoin extends VarArgFunction {
|
||||||
public Varargs invoke(Varargs args) {
|
public Varargs invoke(Varargs args) {
|
||||||
LuaValue f1 = args.checkfunction(1);
|
LuaClosure f1 = args.checkclosure(1);
|
||||||
int n1 = args.checkint(2);
|
int n1 = args.checkint(2);
|
||||||
LuaValue f2 = args.checkfunction(3);
|
LuaClosure f2 = args.checkclosure(3);
|
||||||
int n2 = args.checkint(4);
|
int n2 = args.checkint(4);
|
||||||
f1.checkclosure().upValues[n1] = f2.checkclosure().upValues[n2];
|
if (n1 < 1 || n1 > f1.upValues.length)
|
||||||
|
argerror("index out of range");
|
||||||
|
if (n2 < 1 || n2 > f2.upValues.length)
|
||||||
|
argerror("index out of range");
|
||||||
|
f1.upValues[n1-1] = f2.upValues[n2-1];
|
||||||
return NONE;
|
return NONE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -120,7 +120,6 @@ public class BasicBlock {
|
|||||||
case Lua.OP_LE:
|
case Lua.OP_LE:
|
||||||
case Lua.OP_TEST:
|
case Lua.OP_TEST:
|
||||||
case Lua.OP_TESTSET:
|
case Lua.OP_TESTSET:
|
||||||
case Lua.OP_TFORLOOP:
|
|
||||||
if ( Lua.GET_OPCODE(code[i+1]) != Lua.OP_JMP )
|
if ( Lua.GET_OPCODE(code[i+1]) != Lua.OP_JMP )
|
||||||
throw new IllegalArgumentException("test not followed by jump at "+i);
|
throw new IllegalArgumentException("test not followed by jump at "+i);
|
||||||
sbx = Lua.GETARG_sBx(code[i+1]);
|
sbx = Lua.GETARG_sBx(code[i+1]);
|
||||||
@@ -129,6 +128,7 @@ public class BasicBlock {
|
|||||||
visitor.visitBranch( i, j );
|
visitor.visitBranch( i, j );
|
||||||
visitor.visitBranch( i, i+1 );
|
visitor.visitBranch( i, i+1 );
|
||||||
continue;
|
continue;
|
||||||
|
case Lua.OP_TFORLOOP:
|
||||||
case Lua.OP_FORLOOP:
|
case Lua.OP_FORLOOP:
|
||||||
sbx = Lua.GETARG_sBx(ins);
|
sbx = Lua.GETARG_sBx(ins);
|
||||||
j = i + sbx + 1;
|
j = i + sbx + 1;
|
||||||
|
|||||||
@@ -361,10 +361,12 @@ public class JavaGen {
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Lua.OP_TFORLOOP:/* A sBx if R(A) != nil then ps+= sBx */
|
case Lua.OP_TFORLOOP:/* A sBx if R(A+1) ~= nil then { R(A)=R(A+1); pc += sBx } */
|
||||||
builder.loadLocal(pc, a);
|
builder.loadLocal(pc, a+1);
|
||||||
|
builder.dup();
|
||||||
|
builder.storeLocal(pc, a);
|
||||||
builder.isNil();
|
builder.isNil();
|
||||||
builder.addBranch(pc, JavaBuilder.BRANCH_IFNE, pc+1+sbx);
|
builder.addBranch(pc, JavaBuilder.BRANCH_IFEQ, pc+1+sbx);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Lua.OP_SETLIST: /* A B C R(A)[(C-1)*FPF+i]:= R(A+i), 1 <= i <= B */
|
case Lua.OP_SETLIST: /* A B C R(A)[(C-1)*FPF+i]:= R(A+i), 1 <= i <= B */
|
||||||
|
|||||||
@@ -264,7 +264,7 @@ public class ProtoInfo {
|
|||||||
v[a+1][pc].isreferenced = true;
|
v[a+1][pc].isreferenced = true;
|
||||||
v[a+3][pc] = new VarInfo(a+3,pc);
|
v[a+3][pc] = new VarInfo(a+3,pc);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Lua.OP_LOADNIL: /* A B R(A) := ... := R(A+B) := nil */
|
case Lua.OP_LOADNIL: /* A B R(A) := ... := R(A+B) := nil */
|
||||||
a = Lua.GETARG_A( ins );
|
a = Lua.GETARG_A( ins );
|
||||||
b = Lua.GETARG_B( ins );
|
b = Lua.GETARG_B( ins );
|
||||||
@@ -296,6 +296,24 @@ public class ProtoInfo {
|
|||||||
v[a][pc] = VarInfo.INVALID;
|
v[a][pc] = VarInfo.INVALID;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case Lua.OP_TFORCALL: /* A C R(A+3), ... ,R(A+2+C) := R(A)(R(A+1), R(A+2)); */
|
||||||
|
a = Lua.GETARG_A( ins );
|
||||||
|
c = Lua.GETARG_C( ins );
|
||||||
|
v[a++][pc].isreferenced = true;
|
||||||
|
v[a++][pc].isreferenced = true;
|
||||||
|
v[a++][pc].isreferenced = true;
|
||||||
|
for ( int j=0; j<c; j++, a++ )
|
||||||
|
v[a][pc] = new VarInfo(a,pc);
|
||||||
|
for ( ; a<m; a++ )
|
||||||
|
v[a][pc] = VarInfo.INVALID;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Lua.OP_TFORLOOP: /* A sBx if R(A+1) ~= nil then { R(A)=R(A+1); pc += sBx */
|
||||||
|
a = Lua.GETARG_A( ins );
|
||||||
|
v[a+1][pc].isreferenced = true;
|
||||||
|
v[a][pc] = new VarInfo(a,pc);
|
||||||
|
break;
|
||||||
|
|
||||||
case Lua.OP_TAILCALL: /* A B C return R(A)(R(A+1), ... ,R(A+B-1)) */
|
case Lua.OP_TAILCALL: /* A B C return R(A)(R(A+1), ... ,R(A+B-1)) */
|
||||||
a = Lua.GETARG_A( ins );
|
a = Lua.GETARG_A( ins );
|
||||||
b = Lua.GETARG_B( ins );
|
b = Lua.GETARG_B( ins );
|
||||||
@@ -311,20 +329,6 @@ public class ProtoInfo {
|
|||||||
v[a+i][pc].isreferenced = true;
|
v[a+i][pc].isreferenced = true;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Lua.OP_TFORCALL: /* A C R(A+3), ... ,R(A+2+C) := R(A)(R(A+1), R(A+2)); */
|
|
||||||
case Lua.OP_TFORLOOP: /* A C R(A+3), ... ,R(A+2+C) := R(A)(R(A+1), R(A+2));
|
|
||||||
if R(A+3) ~= nil then R(A+2)=R(A+3) else pc++ */
|
|
||||||
a = Lua.GETARG_A( ins );
|
|
||||||
c = Lua.GETARG_C( ins );
|
|
||||||
v[a++][pc].isreferenced = true;
|
|
||||||
v[a++][pc].isreferenced = true;
|
|
||||||
v[a++][pc].isreferenced = true;
|
|
||||||
for ( int j=0; j<c; j++, a++ )
|
|
||||||
v[a][pc] = new VarInfo(a,pc);
|
|
||||||
for ( ; a<m; a++ )
|
|
||||||
v[a][pc] = VarInfo.INVALID;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case Lua.OP_CLOSURE: { /* A Bx R(A) := closure(KPROTO[Bx], R(A), ... ,R(A+n)) */
|
case Lua.OP_CLOSURE: { /* A Bx R(A) := closure(KPROTO[Bx], R(A), ... ,R(A+n)) */
|
||||||
a = Lua.GETARG_A( ins );
|
a = Lua.GETARG_A( ins );
|
||||||
b = Lua.GETARG_Bx( ins );
|
b = Lua.GETARG_Bx( ins );
|
||||||
|
|||||||
@@ -29,7 +29,10 @@ import java.util.Hashtable;
|
|||||||
|
|
||||||
import org.luaj.vm2.LuaTable;
|
import org.luaj.vm2.LuaTable;
|
||||||
import org.luaj.vm2.LuaValue;
|
import org.luaj.vm2.LuaValue;
|
||||||
|
import org.luaj.vm2.Print;
|
||||||
|
import org.luaj.vm2.Prototype;
|
||||||
import org.luaj.vm2.Varargs;
|
import org.luaj.vm2.Varargs;
|
||||||
|
import org.luaj.vm2.compiler.LuaC;
|
||||||
import org.luaj.vm2.lib.jse.JsePlatform;
|
import org.luaj.vm2.lib.jse.JsePlatform;
|
||||||
import org.luaj.vm2.luajc.LuaJC;
|
import org.luaj.vm2.luajc.LuaJC;
|
||||||
|
|
||||||
@@ -37,8 +40,9 @@ public class TestLuaJC {
|
|||||||
// create the script
|
// create the script
|
||||||
public static String name = "script";
|
public static String name = "script";
|
||||||
public static String script =
|
public static String script =
|
||||||
"_ENV={}; return _ENV\n"+
|
"for n,p in ipairs({77}) do\n"+
|
||||||
"";
|
" print('n,p',n,p)\n"+
|
||||||
|
"end\n";
|
||||||
|
|
||||||
public static void main(String[] args) throws Exception {
|
public static void main(String[] args) throws Exception {
|
||||||
System.out.println(script);
|
System.out.println(script);
|
||||||
@@ -48,12 +52,16 @@ public class TestLuaJC {
|
|||||||
LuaTable _G = JsePlatform.standardGlobals();
|
LuaTable _G = JsePlatform.standardGlobals();
|
||||||
System.out.println("_G: "+_G);
|
System.out.println("_G: "+_G);
|
||||||
System.out.println("_G.print: "+_G.get("print"));
|
System.out.println("_G.print: "+_G.get("print"));
|
||||||
|
|
||||||
// compile into a chunk, or load as a class
|
// print the chunk as a closure
|
||||||
LuaValue chunk;
|
byte[] bytes = script.getBytes();
|
||||||
|
LuaValue chunk = LuaC.instance.load(new ByteArrayInputStream(bytes), "script", _G);
|
||||||
|
Prototype p = chunk.checkclosure().p;
|
||||||
|
Print.print(p);
|
||||||
|
|
||||||
|
// compile into a luajc chunk, or load as a class
|
||||||
if ( ! (args.length>0 && args[0].equals("nocompile")) ) {
|
if ( ! (args.length>0 && args[0].equals("nocompile")) ) {
|
||||||
InputStream is = new ByteArrayInputStream( script.getBytes() );
|
chunk = LuaJC.getInstance().load(new ByteArrayInputStream(bytes), "script", _G);
|
||||||
chunk = LuaJC.getInstance().load(is, "script", _G);
|
|
||||||
} else {
|
} else {
|
||||||
chunk = (LuaValue) Class.forName("script").newInstance();
|
chunk = (LuaValue) Class.forName("script").newInstance();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -94,6 +94,15 @@ public class FragmentsTest extends TestSuite {
|
|||||||
"return b" );
|
"return b" );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void testSimpleForloop() {
|
||||||
|
runFragment( LuaValue.valueOf(77),
|
||||||
|
"for n,p in ipairs({77}) do\n"+
|
||||||
|
" print('n,p',n,p)\n"+
|
||||||
|
" return p\n"+
|
||||||
|
"end\n");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
public void testForloopParamUpvalues() {
|
public void testForloopParamUpvalues() {
|
||||||
runFragment( LuaValue.varargsOf(new LuaValue[] {
|
runFragment( LuaValue.varargsOf(new LuaValue[] {
|
||||||
LuaValue.valueOf(77),
|
LuaValue.valueOf(77),
|
||||||
|
|||||||
@@ -216,22 +216,41 @@ tryhooks("r")
|
|||||||
tryhooks("l")
|
tryhooks("l")
|
||||||
tryhooks("crl")
|
tryhooks("crl")
|
||||||
|
|
||||||
print( '----- debug.getupvalueid' )
|
print( '----- debug.upvalueid' )
|
||||||
local x=1, y=2
|
local x,y = 100,200
|
||||||
function a()
|
function a(b,c)
|
||||||
|
local z,w = b,c
|
||||||
return function()
|
return function()
|
||||||
return x,y
|
x,y,z,w = x+1,y+1,z+1,w+1
|
||||||
|
return x,y,z,w
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
a1 = a()
|
a1 = a(300,400)
|
||||||
a2 = a()
|
a2 = a(500,600)
|
||||||
print('debug.getupvalue(a1,1)', debug.getupvalue(a1,1))
|
print('debug.getupvalue(a1,1)', debug.getupvalue(a1,1))
|
||||||
print('debug.getupvalue(a1,2)', debug.getupvalue(a1,2))
|
print('debug.getupvalue(a1,2)', debug.getupvalue(a1,2))
|
||||||
print('debug.getupvalue(a2,1)', debug.getupvalue(a2,1))
|
print('debug.getupvalue(a2,1)', debug.getupvalue(a2,1))
|
||||||
print('debug.getupvalue(a2,2)', debug.getupvalue(a2,2))
|
print('debug.getupvalue(a2,2)', debug.getupvalue(a2,2))
|
||||||
print('debug.getupvalueid(a1,1) == debug.getupvalueid(a1,1)', debug.getupvalueid(a1,1) == debug.getupvalueid(a1,1))
|
print('debug.upvalueid(a1,1) == debug.upvalueid(a1,1)', debug.upvalueid(a1,1) == debug.upvalueid(a1,1))
|
||||||
print('debug.getupvalueid(a1,1) == debug.getupvalueid(a2,1)', debug.getupvalueid(a1,1) == debug.getupvalueid(a2,1))
|
print('debug.upvalueid(a1,1) == debug.upvalueid(a2,1)', debug.upvalueid(a1,1) == debug.upvalueid(a2,1))
|
||||||
print('debug.getupvalueid(a1,2) == debug.getupvalueid(a1,2)', debug.getupvalueid(a1,2) == debug.getupvalueid(a1,2))
|
print('debug.upvalueid(a1,1) == debug.upvalueid(a1,2)', debug.upvalueid(a1,1) == debug.upvalueid(a1,2))
|
||||||
print('debug.getupvalueid(a1,2) == debug.getupvalueid(a2,2)', debug.getupvalueid(a1,2) == debug.getupvalueid(a2,2))
|
|
||||||
|
|
||||||
v
|
print( '----- debug.upvaluejoin' )
|
||||||
|
print('a1',a1())
|
||||||
|
print('a2',a2())
|
||||||
|
print('debug.upvaluejoin(a1,1,a2,2)', debug.upvaluejoin(a1,1,a2,2))
|
||||||
|
print('debug.upvaluejoin(a1,3,a2,4)', debug.upvaluejoin(a1,3,a2,4))
|
||||||
|
print('a1',a1())
|
||||||
|
print('a2',a2())
|
||||||
|
print('a1',a1())
|
||||||
|
print('a2',a2())
|
||||||
|
for i = 1,4 do
|
||||||
|
print('debug.getupvalue(a1,'..i..')', debug.getupvalue(a1,i))
|
||||||
|
print('debug.getupvalue(a2,'..i..')', debug.getupvalue(a2,i))
|
||||||
|
for j = 1,4 do
|
||||||
|
print('debug.upvalueid(a1,'..i..') == debug.upvalueid(a1,'..j..')', debug.upvalueid(a1,i) == debug.upvalueid(a1,j))
|
||||||
|
print('debug.upvalueid(a1,'..i..') == debug.upvalueid(a2,'..j..')', debug.upvalueid(a1,i) == debug.upvalueid(a2,j))
|
||||||
|
print('debug.upvalueid(a2,'..i..') == debug.upvalueid(a1,'..j..')', debug.upvalueid(a2,i) == debug.upvalueid(a1,j))
|
||||||
|
print('debug.upvalueid(a2,'..i..') == debug.upvalueid(a2,'..j..')', debug.upvalueid(a2,i) == debug.upvalueid(a2,j))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|||||||
Reference in New Issue
Block a user