Add support for OP_LOADKX. #43
This commit is contained in:
@@ -23,10 +23,10 @@ package org.luaj.vm2;
|
|||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constants for lua limits and opcodes.
|
* Constants for lua limits and opcodes.
|
||||||
* <p>
|
* <p>
|
||||||
* This is a direct translation of C lua distribution header file constants
|
* This is a direct translation of C lua distribution header file constants
|
||||||
* for bytecode creation and processing.
|
* for bytecode creation and processing.
|
||||||
*/
|
*/
|
||||||
public class Lua {
|
public class Lua {
|
||||||
/** version is supplied by ant build task */
|
/** version is supplied by ant build task */
|
||||||
@@ -80,7 +80,6 @@ public class Lua {
|
|||||||
public static final int POS_Bx = POS_C;
|
public static final int POS_Bx = POS_C;
|
||||||
public static final int POS_Ax = POS_A;
|
public static final int POS_Ax = POS_A;
|
||||||
|
|
||||||
|
|
||||||
public static final int MAX_OP = ((1<<SIZE_OP)-1);
|
public static final int MAX_OP = ((1<<SIZE_OP)-1);
|
||||||
public static final int MAXARG_A = ((1<<SIZE_A)-1);
|
public static final int MAXARG_A = ((1<<SIZE_A)-1);
|
||||||
public static final int MAXARG_B = ((1<<SIZE_B)-1);
|
public static final int MAXARG_B = ((1<<SIZE_B)-1);
|
||||||
@@ -89,17 +88,18 @@ public class Lua {
|
|||||||
public static final int MAXARG_sBx = (MAXARG_Bx>>1); /* `sBx' is signed */
|
public static final int MAXARG_sBx = (MAXARG_Bx>>1); /* `sBx' is signed */
|
||||||
public static final int MAXARG_Ax = ((1<<SIZE_Ax)-1);
|
public static final int MAXARG_Ax = ((1<<SIZE_Ax)-1);
|
||||||
|
|
||||||
public static final int MASK_OP = ((1<<SIZE_OP)-1)<<POS_OP;
|
public static final int MASK_OP = ((1<<SIZE_OP)-1)<<POS_OP;
|
||||||
public static final int MASK_A = ((1<<SIZE_A)-1)<<POS_A;
|
public static final int MASK_A = ((1<<SIZE_A)-1)<<POS_A;
|
||||||
public static final int MASK_B = ((1<<SIZE_B)-1)<<POS_B;
|
public static final int MASK_B = ((1<<SIZE_B)-1)<<POS_B;
|
||||||
public static final int MASK_C = ((1<<SIZE_C)-1)<<POS_C;
|
public static final int MASK_C = ((1<<SIZE_C)-1)<<POS_C;
|
||||||
public static final int MASK_Bx = ((1<<SIZE_Bx)-1)<<POS_Bx;
|
public static final int MASK_Bx = ((1<<SIZE_Bx)-1)<<POS_Bx;
|
||||||
|
public static final int MASK_Ax = ((1<<SIZE_Ax)-1)<<POS_Ax;
|
||||||
|
|
||||||
public static final int MASK_NOT_OP = ~MASK_OP;
|
public static final int MASK_NOT_OP = ~MASK_OP;
|
||||||
public static final int MASK_NOT_A = ~MASK_A;
|
public static final int MASK_NOT_A = ~MASK_A;
|
||||||
public static final int MASK_NOT_B = ~MASK_B;
|
public static final int MASK_NOT_B = ~MASK_B;
|
||||||
public static final int MASK_NOT_C = ~MASK_C;
|
public static final int MASK_NOT_C = ~MASK_C;
|
||||||
public static final int MASK_NOT_Bx = ~MASK_Bx;
|
public static final int MASK_NOT_Bx = ~MASK_Bx;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** the following macros help to manipulate instructions
|
** the following macros help to manipulate instructions
|
||||||
@@ -213,8 +213,8 @@ public class Lua {
|
|||||||
public static final int OP_LT = 25; /* A B C if ((RK(B) < RK(C)) ~= A) then pc++ */
|
public static final int OP_LT = 25; /* A B C if ((RK(B) < RK(C)) ~= A) then pc++ */
|
||||||
public static final int OP_LE = 26; /* A B C if ((RK(B) <= RK(C)) ~= A) then pc++ */
|
public static final int OP_LE = 26; /* A B C if ((RK(B) <= RK(C)) ~= A) then pc++ */
|
||||||
|
|
||||||
public static final int OP_TEST = 27; /* A C if not (R(A) <=> C) then pc++ */
|
public static final int OP_TEST = 27; /* A C if not (R(A) <=> C) then pc++ */
|
||||||
public static final int OP_TESTSET = 28; /* A B C if (R(B) <=> C) then R(A) := R(B) else pc++ */
|
public static final int OP_TESTSET = 28; /* A B C if (R(B) <=> C) then R(A) := R(B) else pc++ */
|
||||||
|
|
||||||
public static final int OP_CALL = 29; /* A B C R(A), ... ,R(A+C-2) := R(A)(R(A+1), ... ,R(A+B-1)) */
|
public static final int OP_CALL = 29; /* A B C R(A), ... ,R(A+C-2) := R(A)(R(A+1), ... ,R(A+B-1)) */
|
||||||
public static final int OP_TAILCALL = 30; /* A B C return R(A)(R(A+1), ... ,R(A+B-1)) */
|
public static final int OP_TAILCALL = 30; /* A B C return R(A)(R(A+1), ... ,R(A+B-1)) */
|
||||||
@@ -225,7 +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 sBx if R(A+1) ~= nil then { R(A)=R(A+1); pc += sBx } */
|
public static final int OP_TFORLOOP = 35; /* A sBx if R(A+1) ~= nil then { R(A)=R(A+1); pc += sBx } */
|
||||||
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)) */
|
||||||
@@ -237,11 +237,11 @@ public class Lua {
|
|||||||
public static final int NUM_OPCODES = OP_EXTRAARG + 1;
|
public static final int NUM_OPCODES = OP_EXTRAARG + 1;
|
||||||
|
|
||||||
/* pseudo-opcodes used in parsing only. */
|
/* pseudo-opcodes used in parsing only. */
|
||||||
public static final int OP_GT = 63; // >
|
public static final int OP_GT = 63; // >
|
||||||
public static final int OP_GE = 62; // >=
|
public static final int OP_GE = 62; // >=
|
||||||
public static final int OP_NEQ = 61; // ~=
|
public static final int OP_NEQ = 61; // ~=
|
||||||
public static final int OP_AND = 60; // and
|
public static final int OP_AND = 60; // and
|
||||||
public static final int OP_OR = 59; // or
|
public static final int OP_OR = 59; // or
|
||||||
|
|
||||||
/*===========================================================================
|
/*===========================================================================
|
||||||
Notes:
|
Notes:
|
||||||
@@ -271,7 +271,7 @@ public class Lua {
|
|||||||
** bits 4-5: B arg mode
|
** bits 4-5: B arg mode
|
||||||
** bit 6: instruction set register A
|
** bit 6: instruction set register A
|
||||||
** bit 7: operator is a test
|
** bit 7: operator is a test
|
||||||
*/
|
*/
|
||||||
|
|
||||||
public static final int OpArgN = 0; /* argument is not used */
|
public static final int OpArgN = 0; /* argument is not used */
|
||||||
public static final int OpArgU = 1; /* argument is used */
|
public static final int OpArgU = 1; /* argument is used */
|
||||||
@@ -353,7 +353,7 @@ public class Lua {
|
|||||||
source = "[string \""+source;
|
source = "[string \""+source;
|
||||||
end = "\"]";
|
end = "\"]";
|
||||||
}
|
}
|
||||||
int n = source.length() + end.length();
|
int n = source.length() + end.length();
|
||||||
if ( n > MAXSRC )
|
if ( n > MAXSRC )
|
||||||
source = source.substring(0,MAXSRC-end.length()-3) + "...";
|
source = source.substring(0,MAXSRC-end.length()-3) + "...";
|
||||||
return source + end;
|
return source + end;
|
||||||
|
|||||||
@@ -22,22 +22,22 @@
|
|||||||
package org.luaj.vm2;
|
package org.luaj.vm2;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Extension of {@link LuaFunction} which executes lua bytecode.
|
* Extension of {@link LuaFunction} which executes lua bytecode.
|
||||||
* <p>
|
* <p>
|
||||||
* A {@link LuaClosure} is a combination of a {@link Prototype}
|
* A {@link LuaClosure} is a combination of a {@link Prototype}
|
||||||
* and a {@link LuaValue} to use as an environment for execution.
|
* and a {@link LuaValue} to use as an environment for execution.
|
||||||
* Normally the {@link LuaValue} is a {@link Globals} in which case the environment
|
* Normally the {@link LuaValue} is a {@link Globals} in which case the environment
|
||||||
* will contain standard lua libraries.
|
* will contain standard lua libraries.
|
||||||
*
|
*
|
||||||
* <p>
|
* <p>
|
||||||
* There are three main ways {@link LuaClosure} instances are created:
|
* There are three main ways {@link LuaClosure} instances are created:
|
||||||
* <ul>
|
* <ul>
|
||||||
* <li>Construct an instance using {@link #LuaClosure(Prototype, LuaValue)}</li>
|
* <li>Construct an instance using {@link #LuaClosure(Prototype, LuaValue)}</li>
|
||||||
* <li>Construct it indirectly by loading a chunk via {@link Globals#load(java.io.Reader, String)}
|
* <li>Construct it indirectly by loading a chunk via {@link Globals#load(java.io.Reader, String)}
|
||||||
* <li>Execute the lua bytecode {@link Lua#OP_CLOSURE} as part of bytecode processing
|
* <li>Execute the lua bytecode {@link Lua#OP_CLOSURE} as part of bytecode processing
|
||||||
* </ul>
|
* </ul>
|
||||||
* <p>
|
* <p>
|
||||||
* To construct it directly, the {@link Prototype} is typically created via a compiler such as
|
* To construct it directly, the {@link Prototype} is typically created via a compiler such as
|
||||||
* {@link org.luaj.vm2.compiler.LuaC}:
|
* {@link org.luaj.vm2.compiler.LuaC}:
|
||||||
* <pre> {@code
|
* <pre> {@code
|
||||||
* String script = "print( 'hello, world' )";
|
* String script = "print( 'hello, world' )";
|
||||||
@@ -46,9 +46,9 @@ package org.luaj.vm2;
|
|||||||
* LuaValue globals = JsePlatform.standardGlobals();
|
* LuaValue globals = JsePlatform.standardGlobals();
|
||||||
* LuaClosure f = new LuaClosure(p, globals);
|
* LuaClosure f = new LuaClosure(p, globals);
|
||||||
* f.call();
|
* f.call();
|
||||||
* }</pre>
|
* }</pre>
|
||||||
* <p>
|
* <p>
|
||||||
* To construct it indirectly, the {@link Globals#load(java.io.Reader, String)} method may be used:
|
* To construct it indirectly, the {@link Globals#load(java.io.Reader, String)} method may be used:
|
||||||
* <pre> {@code
|
* <pre> {@code
|
||||||
* Globals globals = JsePlatform.standardGlobals();
|
* Globals globals = JsePlatform.standardGlobals();
|
||||||
* LuaFunction f = globals.load(new StringReader(script), "script");
|
* LuaFunction f = globals.load(new StringReader(script), "script");
|
||||||
@@ -56,11 +56,11 @@ package org.luaj.vm2;
|
|||||||
* c.call();
|
* c.call();
|
||||||
* }</pre>
|
* }</pre>
|
||||||
* <p>
|
* <p>
|
||||||
* In this example, the "checkclosure()" may fail if direct lua-to-java-bytecode
|
* In this example, the "checkclosure()" may fail if direct lua-to-java-bytecode
|
||||||
* compiling using LuaJC is installed, because no LuaClosure is created in that case
|
* compiling using LuaJC is installed, because no LuaClosure is created in that case
|
||||||
* and the value returned is a {@link LuaFunction} but not a {@link LuaClosure}.
|
* and the value returned is a {@link LuaFunction} but not a {@link LuaClosure}.
|
||||||
* <p>
|
* <p>
|
||||||
* Since a {@link LuaClosure} is a {@link LuaFunction} which is a {@link LuaValue},
|
* Since a {@link LuaClosure} is a {@link LuaFunction} which is a {@link LuaValue},
|
||||||
* all the value operations can be used directly such as:
|
* all the value operations can be used directly such as:
|
||||||
* <ul>
|
* <ul>
|
||||||
* <li>{@link LuaValue#call()}</li>
|
* <li>{@link LuaValue#call()}</li>
|
||||||
@@ -71,7 +71,7 @@ package org.luaj.vm2;
|
|||||||
* <li>{@link LuaValue#method(String,LuaValue)}</li>
|
* <li>{@link LuaValue#method(String,LuaValue)}</li>
|
||||||
* <li>{@link LuaValue#invokemethod(String)}</li>
|
* <li>{@link LuaValue#invokemethod(String)}</li>
|
||||||
* <li>{@link LuaValue#invokemethod(String,Varargs)}</li>
|
* <li>{@link LuaValue#invokemethod(String,Varargs)}</li>
|
||||||
* <li> ...</li>
|
* <li> ...</li>
|
||||||
* </ul>
|
* </ul>
|
||||||
* @see LuaValue
|
* @see LuaValue
|
||||||
* @see LuaFunction
|
* @see LuaFunction
|
||||||
@@ -92,13 +92,13 @@ public class LuaClosure extends LuaFunction {
|
|||||||
|
|
||||||
/** Create a closure around a Prototype with a specific environment.
|
/** Create a closure around a Prototype with a specific environment.
|
||||||
* If the prototype has upvalues, the environment will be written into the first upvalue.
|
* If the prototype has upvalues, the environment will be written into the first upvalue.
|
||||||
* @param p the Prototype to construct this Closure for.
|
* @param p the Prototype to construct this Closure for.
|
||||||
* @param env the environment to associate with the closure.
|
* @param env the environment to associate with the closure.
|
||||||
*/
|
*/
|
||||||
public LuaClosure(Prototype p, LuaValue env) {
|
public LuaClosure(Prototype p, LuaValue env) {
|
||||||
this.p = p;
|
this.p = p;
|
||||||
this.initupvalue1(env);
|
this.initupvalue1(env);
|
||||||
globals = env instanceof Globals? (Globals) env: null;
|
globals = env instanceof Globals? (Globals) env: null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void initupvalue1(LuaValue env) {
|
public void initupvalue1(LuaValue env) {
|
||||||
@@ -191,13 +191,13 @@ public class LuaClosure extends LuaFunction {
|
|||||||
|
|
||||||
// allow for debug hooks
|
// allow for debug hooks
|
||||||
if (globals != null && globals.debuglib != null)
|
if (globals != null && globals.debuglib != null)
|
||||||
globals.debuglib.onCall( this, varargs, stack );
|
globals.debuglib.onCall( this, varargs, stack );
|
||||||
|
|
||||||
// process instructions
|
// process instructions
|
||||||
try {
|
try {
|
||||||
for (; true; ++pc) {
|
for (; true; ++pc) {
|
||||||
if (globals != null && globals.debuglib != null)
|
if (globals != null && globals.debuglib != null)
|
||||||
globals.debuglib.onInstruction( pc, v, top );
|
globals.debuglib.onInstruction( pc, v, top );
|
||||||
|
|
||||||
// pull out instruction
|
// pull out instruction
|
||||||
i = code[pc];
|
i = code[pc];
|
||||||
@@ -214,6 +214,17 @@ public class LuaClosure extends LuaFunction {
|
|||||||
stack[a] = k[i>>>14];
|
stack[a] = k[i>>>14];
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
case Lua.OP_LOADKX:/* A R(A) := Kst(extra arg) */
|
||||||
|
++pc;
|
||||||
|
i = code[pc];
|
||||||
|
if ((i & 0x3f) != Lua.OP_EXTRAARG) {
|
||||||
|
int op = i & 0x3f;
|
||||||
|
throw new LuaError("OP_EXTRAARG expected after OP_LOADKX, got " +
|
||||||
|
(op < Print.OPNAMES.length - 1 ? Print.OPNAMES[op] : "UNKNOWN_OP_" + op));
|
||||||
|
}
|
||||||
|
stack[a] = k[i>>>6];
|
||||||
|
continue;
|
||||||
|
|
||||||
case Lua.OP_LOADBOOL:/* A B C R(A):= (Bool)B: if (C) pc++ */
|
case Lua.OP_LOADBOOL:/* A B C R(A):= (Bool)B: if (C) pc++ */
|
||||||
stack[a] = (i>>>23!=0)? LuaValue.TRUE: LuaValue.FALSE;
|
stack[a] = (i>>>23!=0)? LuaValue.TRUE: LuaValue.FALSE;
|
||||||
if ((i&(0x1ff<<14)) != 0)
|
if ((i&(0x1ff<<14)) != 0)
|
||||||
@@ -300,7 +311,7 @@ public class LuaClosure extends LuaFunction {
|
|||||||
{
|
{
|
||||||
if ( c > b+1 ) {
|
if ( c > b+1 ) {
|
||||||
Buffer sb = stack[c].buffer();
|
Buffer sb = stack[c].buffer();
|
||||||
while ( --c>=b )
|
while ( --c>=b )
|
||||||
sb.concatTo(stack[c]);
|
sb.concatTo(stack[c]);
|
||||||
stack[a] = sb.value();
|
stack[a] = sb.value();
|
||||||
} else {
|
} else {
|
||||||
@@ -321,31 +332,31 @@ public class LuaClosure extends LuaFunction {
|
|||||||
continue;
|
continue;
|
||||||
|
|
||||||
case Lua.OP_EQ: /* A B C if ((RK(B) == RK(C)) ~= A) then pc++ */
|
case Lua.OP_EQ: /* A B C if ((RK(B) == RK(C)) ~= A) then pc++ */
|
||||||
if ( ((b=i>>>23)>0xff? k[b&0x0ff]: stack[b]).eq_b((c=(i>>14)&0x1ff)>0xff? k[c&0x0ff]: stack[c]) != (a!=0) )
|
if ( ((b=i>>>23)>0xff? k[b&0x0ff]: stack[b]).eq_b((c=(i>>14)&0x1ff)>0xff? k[c&0x0ff]: stack[c]) != (a!=0) )
|
||||||
++pc;
|
++pc;
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
case Lua.OP_LT: /* A B C if ((RK(B) < RK(C)) ~= A) then pc++ */
|
case Lua.OP_LT: /* A B C if ((RK(B) < RK(C)) ~= A) then pc++ */
|
||||||
if ( ((b=i>>>23)>0xff? k[b&0x0ff]: stack[b]).lt_b((c=(i>>14)&0x1ff)>0xff? k[c&0x0ff]: stack[c]) != (a!=0) )
|
if ( ((b=i>>>23)>0xff? k[b&0x0ff]: stack[b]).lt_b((c=(i>>14)&0x1ff)>0xff? k[c&0x0ff]: stack[c]) != (a!=0) )
|
||||||
++pc;
|
++pc;
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
case Lua.OP_LE: /* A B C if ((RK(B) <= RK(C)) ~= A) then pc++ */
|
case Lua.OP_LE: /* A B C if ((RK(B) <= RK(C)) ~= A) then pc++ */
|
||||||
if ( ((b=i>>>23)>0xff? k[b&0x0ff]: stack[b]).lteq_b((c=(i>>14)&0x1ff)>0xff? k[c&0x0ff]: stack[c]) != (a!=0) )
|
if ( ((b=i>>>23)>0xff? k[b&0x0ff]: stack[b]).lteq_b((c=(i>>14)&0x1ff)>0xff? k[c&0x0ff]: stack[c]) != (a!=0) )
|
||||||
++pc;
|
++pc;
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
case Lua.OP_TEST: /* A C if not (R(A) <=> C) then pc++ */
|
case Lua.OP_TEST: /* A C if not (R(A) <=> C) then pc++ */
|
||||||
if ( stack[a].toboolean() != ((i&(0x1ff<<14))!=0) )
|
if ( stack[a].toboolean() != ((i&(0x1ff<<14))!=0) )
|
||||||
++pc;
|
++pc;
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
case Lua.OP_TESTSET: /* A B C if (R(B) <=> C) then R(A):= R(B) else pc++ */
|
case Lua.OP_TESTSET: /* A B C if (R(B) <=> C) then R(A):= R(B) else pc++ */
|
||||||
/* note: doc appears to be reversed */
|
/* note: doc appears to be reversed */
|
||||||
if ( (o=stack[i>>>23]).toboolean() != ((i&(0x1ff<<14))!=0) )
|
if ( (o=stack[i>>>23]).toboolean() != ((i&(0x1ff<<14))!=0) )
|
||||||
++pc;
|
++pc;
|
||||||
else
|
else
|
||||||
stack[a] = o; // TODO: should be sBx?
|
stack[a] = o; // TODO: should be sBx?
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
case Lua.OP_CALL: /* A B C R(A), ... ,R(A+C-2):= R(A)(R(A+1), ... ,R(A+B-1)) */
|
case Lua.OP_CALL: /* A B C R(A), ... ,R(A+C-2):= R(A)(R(A+1), ... ,R(A+B-1)) */
|
||||||
@@ -363,9 +374,9 @@ public class LuaClosure extends LuaFunction {
|
|||||||
default:
|
default:
|
||||||
b = i>>>23;
|
b = i>>>23;
|
||||||
c = (i>>14)&0x1ff;
|
c = (i>>14)&0x1ff;
|
||||||
v = stack[a].invoke(b>0?
|
v = stack[a].invoke(b>0?
|
||||||
varargsOf(stack, a+1, b-1): // exact arg count
|
varargsOf(stack, a+1, b-1): // exact arg count
|
||||||
varargsOf(stack, a+1, top-v.narg()-(a+1), v)); // from prev top
|
varargsOf(stack, a+1, top-v.narg()-(a+1), v)); // from prev top
|
||||||
if ( c > 0 ) {
|
if ( c > 0 ) {
|
||||||
v.copyto(stack, a, c-1);
|
v.copyto(stack, a, c-1);
|
||||||
v = NONE;
|
v = NONE;
|
||||||
@@ -384,18 +395,18 @@ public class LuaClosure extends LuaFunction {
|
|||||||
case (4<<Lua.POS_B): return new TailcallVarargs(stack[a], varargsOf(stack[a+1],stack[a+2],stack[a+3]));
|
case (4<<Lua.POS_B): return new TailcallVarargs(stack[a], varargsOf(stack[a+1],stack[a+2],stack[a+3]));
|
||||||
default:
|
default:
|
||||||
b = i>>>23;
|
b = i>>>23;
|
||||||
v = b>0?
|
v = b>0?
|
||||||
varargsOf(stack,a+1,b-1): // exact arg count
|
varargsOf(stack,a+1,b-1): // exact arg count
|
||||||
varargsOf(stack, a+1, top-v.narg()-(a+1), v); // from prev top
|
varargsOf(stack, a+1, top-v.narg()-(a+1), v); // from prev top
|
||||||
return new TailcallVarargs( stack[a], v );
|
return new TailcallVarargs( stack[a], v );
|
||||||
}
|
}
|
||||||
|
|
||||||
case Lua.OP_RETURN: /* A B return R(A), ... ,R(A+B-2) (see note) */
|
case Lua.OP_RETURN: /* A B return R(A), ... ,R(A+B-2) (see note) */
|
||||||
b = i>>>23;
|
b = i>>>23;
|
||||||
switch ( b ) {
|
switch ( b ) {
|
||||||
case 0: return varargsOf(stack, a, top-v.narg()-a, v);
|
case 0: return varargsOf(stack, a, top-v.narg()-a, v);
|
||||||
case 1: return NONE;
|
case 1: return NONE;
|
||||||
case 2: return stack[a];
|
case 2: return stack[a];
|
||||||
default:
|
default:
|
||||||
return varargsOf(stack, a, b-1);
|
return varargsOf(stack, a, b-1);
|
||||||
}
|
}
|
||||||
@@ -448,7 +459,7 @@ public class LuaClosure extends LuaFunction {
|
|||||||
o = stack[a];
|
o = stack[a];
|
||||||
if ( (b=i>>>23) == 0 ) {
|
if ( (b=i>>>23) == 0 ) {
|
||||||
b = top - a - 1;
|
b = top - a - 1;
|
||||||
int m = b - v.narg();
|
int m = b - v.narg();
|
||||||
int j=1;
|
int j=1;
|
||||||
for ( ;j<=m; j++ )
|
for ( ;j<=m; j++ )
|
||||||
o.set(offset+j, stack[a + j]);
|
o.set(offset+j, stack[a + j]);
|
||||||
@@ -482,11 +493,11 @@ public class LuaClosure extends LuaFunction {
|
|||||||
if ( b == 0 ) {
|
if ( b == 0 ) {
|
||||||
top = a + (b = varargs.narg());
|
top = a + (b = varargs.narg());
|
||||||
v = varargs;
|
v = varargs;
|
||||||
} else {
|
} else {
|
||||||
for ( int j=1; j<b; ++j )
|
for ( int j=1; j<b; ++j )
|
||||||
stack[a+j-1] = varargs.arg(j);
|
stack[a+j-1] = varargs.arg(j);
|
||||||
}
|
}
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
case Lua.OP_EXTRAARG:
|
case Lua.OP_EXTRAARG:
|
||||||
throw new java.lang.IllegalArgumentException("Uexecutable opcode: OP_EXTRAARG");
|
throw new java.lang.IllegalArgumentException("Uexecutable opcode: OP_EXTRAARG");
|
||||||
@@ -515,7 +526,7 @@ public class LuaClosure extends LuaFunction {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Run the error hook if there is one
|
* Run the error hook if there is one
|
||||||
* @param msg the message to use in error hook processing.
|
* @param msg the message to use in error hook processing.
|
||||||
* */
|
* */
|
||||||
String errorHook(String msg, int level) {
|
String errorHook(String msg, int level) {
|
||||||
if (globals == null ) return msg;
|
if (globals == null ) return msg;
|
||||||
@@ -536,7 +547,7 @@ public class LuaClosure extends LuaFunction {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void processErrorHooks(LuaError le, Prototype p, int pc) {
|
private void processErrorHooks(LuaError le, Prototype p, int pc) {
|
||||||
le.fileline = (p.source != null? p.source.tojstring(): "?") + ":"
|
le.fileline = (p.source != null? p.source.tojstring(): "?") + ":"
|
||||||
+ (p.lineinfo != null && pc >= 0 && pc < p.lineinfo.length? String.valueOf(p.lineinfo[pc]): "?");
|
+ (p.lineinfo != null && pc >= 0 && pc < p.lineinfo.length? String.valueOf(p.lineinfo[pc]): "?");
|
||||||
le.traceback = errorHook(le.getMessage(), le.level);
|
le.traceback = errorHook(le.getMessage(), le.level);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -46,20 +46,20 @@ public class Constants extends Lua {
|
|||||||
|
|
||||||
|
|
||||||
/* OpMode - basic instruction format */
|
/* OpMode - basic instruction format */
|
||||||
static final int
|
static final int
|
||||||
iABC = 0,
|
iABC = 0,
|
||||||
iABx = 1,
|
iABx = 1,
|
||||||
iAsBx = 2;
|
iAsBx = 2;
|
||||||
|
|
||||||
/* OpArgMask */
|
/* OpArgMask */
|
||||||
static final int
|
static final int
|
||||||
OpArgN = 0, /* argument is not used */
|
OpArgN = 0, /* argument is not used */
|
||||||
OpArgU = 1, /* argument is used */
|
OpArgU = 1, /* argument is used */
|
||||||
OpArgR = 2, /* argument is a register or a jump offset */
|
OpArgR = 2, /* argument is a register or a jump offset */
|
||||||
OpArgK = 3; /* argument is a constant or register/constant */
|
OpArgK = 3; /* argument is a constant or register/constant */
|
||||||
|
|
||||||
|
|
||||||
protected static void _assert(boolean b) {
|
protected static void _assert(boolean b) {
|
||||||
if (!b)
|
if (!b)
|
||||||
throw new LuaError("compiler assert failed");
|
throw new LuaError("compiler assert failed");
|
||||||
}
|
}
|
||||||
@@ -104,6 +104,11 @@ public class Constants extends Lua {
|
|||||||
((a << POS_A) & MASK_A) |
|
((a << POS_A) & MASK_A) |
|
||||||
((bc << POS_Bx) & MASK_Bx) ;
|
((bc << POS_Bx) & MASK_Bx) ;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int CREATE_Ax(int o, int a) {
|
||||||
|
return ((o << POS_OP) & MASK_OP) |
|
||||||
|
((a << POS_Ax) & MASK_Ax) ;
|
||||||
|
}
|
||||||
|
|
||||||
// vector reallocation
|
// vector reallocation
|
||||||
|
|
||||||
@@ -150,7 +155,7 @@ public class Constants extends Lua {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static LexState.Labeldesc[] grow(LexState.Labeldesc[] v, int min_n) {
|
static LexState.Labeldesc[] grow(LexState.Labeldesc[] v, int min_n) {
|
||||||
return v == null ? new LexState.Labeldesc[2] : v.length < min_n ? realloc(v, v.length*2) : v;
|
return v == null ? new LexState.Labeldesc[2] : v.length < min_n ? realloc(v, v.length*2) : v;
|
||||||
}
|
}
|
||||||
|
|
||||||
static LexState.Labeldesc[] realloc(LexState.Labeldesc[] v, int n) {
|
static LexState.Labeldesc[] realloc(LexState.Labeldesc[] v, int n) {
|
||||||
|
|||||||
@@ -580,11 +580,11 @@ public class FuncState extends Constants {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case LexState.VK: {
|
case LexState.VK: {
|
||||||
this.codeABx(OP_LOADK, reg, e.u.info);
|
this.codeK(reg, e.u.info);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case LexState.VKNUM: {
|
case LexState.VKNUM: {
|
||||||
this.codeABx(OP_LOADK, reg, this.numberK(e.u.nval()));
|
this.codeK(reg, this.numberK(e.u.nval()));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case LexState.VRELOCABLE: {
|
case LexState.VRELOCABLE: {
|
||||||
@@ -1116,6 +1116,20 @@ public class FuncState extends Constants {
|
|||||||
return this.code(CREATE_ABx(o, a, bc), this.ls.lastline);
|
return this.code(CREATE_ABx(o, a, bc), this.ls.lastline);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int codeextraarg(int a) {
|
||||||
|
_assert(a <= MAXARG_Ax);
|
||||||
|
return this.code(CREATE_Ax(OP_EXTRAARG, a), this.ls.lastline);
|
||||||
|
}
|
||||||
|
|
||||||
|
int codeK(int reg, int k) {
|
||||||
|
if (k <= MAXARG_Bx)
|
||||||
|
return codeABx(OP_LOADK, reg, k);
|
||||||
|
else {
|
||||||
|
int p = codeABx(OP_LOADKX, reg, 0);
|
||||||
|
codeextraarg(k);
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void setlist(int base, int nelems, int tostore) {
|
void setlist(int base, int nelems, int tostore) {
|
||||||
int c = (nelems - 1) / LFIELDS_PER_FLUSH + 1;
|
int c = (nelems - 1) / LFIELDS_PER_FLUSH + 1;
|
||||||
|
|||||||
@@ -62,14 +62,14 @@ public class LexState extends Constants {
|
|||||||
|
|
||||||
private static final int EOZ = (-1);
|
private static final int EOZ = (-1);
|
||||||
private static final int MAX_INT = Integer.MAX_VALUE-2;
|
private static final int MAX_INT = Integer.MAX_VALUE-2;
|
||||||
private static final int UCHAR_MAX = 255; // TODO, convert to unicode CHAR_MAX?
|
private static final int UCHAR_MAX = 255; // TODO, convert to unicode CHAR_MAX?
|
||||||
private static final int LUAI_MAXCCALLS = 200;
|
private static final int LUAI_MAXCCALLS = 200;
|
||||||
|
|
||||||
private static final String LUA_QS(String s) { return "'"+s+"'"; }
|
private static final String LUA_QS(String s) { return "'"+s+"'"; }
|
||||||
private static final String LUA_QL(Object o) { return LUA_QS(String.valueOf(o)); }
|
private static final String LUA_QL(Object o) { return LUA_QS(String.valueOf(o)); }
|
||||||
|
|
||||||
private static final int LUA_COMPAT_LSTR = 1; // 1 for compatibility, 2 for old behavior
|
private static final int LUA_COMPAT_LSTR = 1; // 1 for compatibility, 2 for old behavior
|
||||||
private static final boolean LUA_COMPAT_VARARG = true;
|
private static final boolean LUA_COMPAT_VARARG = true;
|
||||||
|
|
||||||
public static boolean isReservedKeyword(String varName) {
|
public static boolean isReservedKeyword(String varName) {
|
||||||
return RESERVED_LOCAL_VAR_KEYWORDS_TABLE.containsKey(varName);
|
return RESERVED_LOCAL_VAR_KEYWORDS_TABLE.containsKey(varName);
|
||||||
@@ -84,7 +84,7 @@ public class LexState extends Constants {
|
|||||||
/*
|
/*
|
||||||
** grep "ORDER OPR" if you change these enums
|
** grep "ORDER OPR" if you change these enums
|
||||||
*/
|
*/
|
||||||
static final int
|
static final int
|
||||||
OPR_ADD=0, OPR_SUB=1, OPR_MUL=2, OPR_DIV=3, OPR_MOD=4, OPR_POW=5,
|
OPR_ADD=0, OPR_SUB=1, OPR_MUL=2, OPR_DIV=3, OPR_MOD=4, OPR_POW=5,
|
||||||
OPR_CONCAT=6,
|
OPR_CONCAT=6,
|
||||||
OPR_NE=7, OPR_EQ=8,
|
OPR_NE=7, OPR_EQ=8,
|
||||||
@@ -92,11 +92,11 @@ public class LexState extends Constants {
|
|||||||
OPR_AND=13, OPR_OR=14,
|
OPR_AND=13, OPR_OR=14,
|
||||||
OPR_NOBINOPR=15;
|
OPR_NOBINOPR=15;
|
||||||
|
|
||||||
static final int
|
static final int
|
||||||
OPR_MINUS=0, OPR_NOT=1, OPR_LEN=2, OPR_NOUNOPR=3;
|
OPR_MINUS=0, OPR_NOT=1, OPR_LEN=2, OPR_NOUNOPR=3;
|
||||||
|
|
||||||
/* exp kind */
|
/* exp kind */
|
||||||
static final int
|
static final int
|
||||||
VVOID = 0, /* no value */
|
VVOID = 0, /* no value */
|
||||||
VNIL = 1,
|
VNIL = 1,
|
||||||
VTRUE = 2,
|
VTRUE = 2,
|
||||||
@@ -153,14 +153,14 @@ public class LexState extends Constants {
|
|||||||
"::", "<eos>", "<number>", "<name>", "<string>", "<eof>",
|
"::", "<eos>", "<number>", "<name>", "<string>", "<eof>",
|
||||||
};
|
};
|
||||||
|
|
||||||
final static int
|
final static int
|
||||||
/* terminal symbols denoted by reserved words */
|
/* terminal symbols denoted by reserved words */
|
||||||
TK_AND=257, TK_BREAK=258, TK_DO=259, TK_ELSE=260, TK_ELSEIF=261,
|
TK_AND=257, TK_BREAK=258, TK_DO=259, TK_ELSE=260, TK_ELSEIF=261,
|
||||||
TK_END=262, TK_FALSE=263, TK_FOR=264, TK_FUNCTION=265, TK_GOTO=266, TK_IF=267,
|
TK_END=262, TK_FALSE=263, TK_FOR=264, TK_FUNCTION=265, TK_GOTO=266, TK_IF=267,
|
||||||
TK_IN=268, TK_LOCAL=269, TK_NIL=270, TK_NOT=271, TK_OR=272, TK_REPEAT=273,
|
TK_IN=268, TK_LOCAL=269, TK_NIL=270, TK_NOT=271, TK_OR=272, TK_REPEAT=273,
|
||||||
TK_RETURN=274, TK_THEN=275, TK_TRUE=276, TK_UNTIL=277, TK_WHILE=278,
|
TK_RETURN=274, TK_THEN=275, TK_TRUE=276, TK_UNTIL=277, TK_WHILE=278,
|
||||||
/* other terminal symbols */
|
/* other terminal symbols */
|
||||||
TK_CONCAT=279, TK_DOTS=280, TK_EQ=281, TK_GE=282, TK_LE=283, TK_NE=284,
|
TK_CONCAT=279, TK_DOTS=280, TK_EQ=281, TK_GE=282, TK_LE=283, TK_NE=284,
|
||||||
TK_DBCOLON=285, TK_EOS=286, TK_NUMBER=287, TK_NAME=288, TK_STRING=289;
|
TK_DBCOLON=285, TK_EOS=286, TK_NUMBER=287, TK_NAME=288, TK_STRING=289;
|
||||||
|
|
||||||
final static int FIRST_RESERVED = TK_AND;
|
final static int FIRST_RESERVED = TK_AND;
|
||||||
@@ -175,7 +175,7 @@ public class LexState extends Constants {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private boolean isalnum(int c) {
|
private boolean isalnum(int c) {
|
||||||
return (c >= '0' && c <= '9')
|
return (c >= '0' && c <= '9')
|
||||||
|| (c >= 'a' && c <= 'z')
|
|| (c >= 'a' && c <= 'z')
|
||||||
|| (c >= 'A' && c <= 'Z')
|
|| (c >= 'A' && c <= 'Z')
|
||||||
|| (c == '_');
|
|| (c == '_');
|
||||||
@@ -188,13 +188,13 @@ public class LexState extends Constants {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private boolean isdigit(int c) {
|
private boolean isdigit(int c) {
|
||||||
return (c >= '0' && c <= '9');
|
return (c >= '0' && c <= '9');
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean isxdigit(int c) {
|
private boolean isxdigit(int c) {
|
||||||
return (c >= '0' && c <= '9')
|
return (c >= '0' && c <= '9')
|
||||||
|| (c >= 'a' && c <= 'f')
|
|| (c >= 'a' && c <= 'f')
|
||||||
|| (c >= 'A' && c <= 'F');
|
|| (c >= 'A' && c <= 'F');
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean isspace(int c) {
|
private boolean isspace(int c) {
|
||||||
@@ -235,7 +235,7 @@ public class LexState extends Constants {
|
|||||||
|
|
||||||
String token2str( int token ) {
|
String token2str( int token ) {
|
||||||
if ( token < FIRST_RESERVED ) {
|
if ( token < FIRST_RESERVED ) {
|
||||||
return iscntrl(token)?
|
return iscntrl(token)?
|
||||||
L.pushfstring( "char("+((int)token)+")" ):
|
L.pushfstring( "char("+((int)token)+")" ):
|
||||||
L.pushfstring( String.valueOf( (char) token ) );
|
L.pushfstring( String.valueOf( (char) token ) );
|
||||||
} else {
|
} else {
|
||||||
@@ -821,7 +821,7 @@ public class LexState extends Constants {
|
|||||||
|
|
||||||
/* dynamic structures used by the parser */
|
/* dynamic structures used by the parser */
|
||||||
static class Dyndata {
|
static class Dyndata {
|
||||||
Vardesc[] actvar; /* list of active local variables */
|
Vardesc[] actvar; /* list of active local variables */
|
||||||
int n_actvar = 0;
|
int n_actvar = 0;
|
||||||
Labeldesc[] gt; /* list of pending gotos */
|
Labeldesc[] gt; /* list of pending gotos */
|
||||||
int n_gt = 0;
|
int n_gt = 0;
|
||||||
@@ -1610,7 +1610,7 @@ public class LexState extends Constants {
|
|||||||
switch (t.token) {
|
switch (t.token) {
|
||||||
case TK_ELSE: case TK_ELSEIF: case TK_END: case TK_EOS:
|
case TK_ELSE: case TK_ELSEIF: case TK_END: case TK_EOS:
|
||||||
return true;
|
return true;
|
||||||
case TK_UNTIL:
|
case TK_UNTIL:
|
||||||
return withuntil;
|
return withuntil;
|
||||||
default: return false;
|
default: return false;
|
||||||
}
|
}
|
||||||
@@ -1634,7 +1634,7 @@ public class LexState extends Constants {
|
|||||||
static class LHS_assign {
|
static class LHS_assign {
|
||||||
LHS_assign prev;
|
LHS_assign prev;
|
||||||
/* variable (global, local, upvalue, or indexed) */
|
/* variable (global, local, upvalue, or indexed) */
|
||||||
expdesc v = new expdesc();
|
expdesc v = new expdesc();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@@ -1845,7 +1845,7 @@ public class LexState extends Constants {
|
|||||||
if (this.testnext(','))
|
if (this.testnext(','))
|
||||||
this.exp1(); /* optional step */
|
this.exp1(); /* optional step */
|
||||||
else { /* default step = 1 */
|
else { /* default step = 1 */
|
||||||
fs.codeABx(Lua.OP_LOADK, fs.freereg, fs.numberK(LuaInteger.valueOf(1)));
|
fs.codeK(fs.freereg, fs.numberK(LuaInteger.valueOf(1)));
|
||||||
fs.reserveregs(1);
|
fs.reserveregs(1);
|
||||||
}
|
}
|
||||||
this.forbody(base, line, 1, true);
|
this.forbody(base, line, 1, true);
|
||||||
|
|||||||
Reference in New Issue
Block a user