Pull request: Reduce allocations per LuaClosure call #76
This commit is contained in:
@@ -1,28 +1,31 @@
|
|||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
* Copyright (c) 2009 Luaj.org. All rights reserved.
|
* Copyright (c) 2009 Luaj.org. All rights reserved.
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
* in the Software without restriction, including without limitation the rights
|
* in the Software without restriction, including without limitation the rights
|
||||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
* copies of the Software, and to permit persons to whom the Software is
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
* furnished to do so, subject to the following conditions:
|
* furnished to do so, subject to the following conditions:
|
||||||
*
|
*
|
||||||
* The above copyright notice and this permission notice shall be included in
|
* The above copyright notice and this permission notice shall be included in
|
||||||
* all copies or substantial portions of the Software.
|
* all copies or substantial portions of the Software.
|
||||||
*
|
*
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
* THE SOFTWARE.
|
* THE SOFTWARE.
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
package org.luaj.vm2;
|
package org.luaj.vm2;
|
||||||
|
|
||||||
import org.luaj.vm2.libs.DebugLib.CallFrame;
|
import org.luaj.vm2.libs.DebugLib.CallFrame;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Extension of {@link LuaFunction} which executes lua bytecode.
|
* Extension of {@link LuaFunction} which executes lua bytecode.
|
||||||
* <p>
|
* <p>
|
||||||
@@ -30,7 +33,7 @@ import org.luaj.vm2.libs.DebugLib.CallFrame;
|
|||||||
* 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>
|
||||||
@@ -85,13 +88,13 @@ import org.luaj.vm2.libs.DebugLib.CallFrame;
|
|||||||
*/
|
*/
|
||||||
public class LuaClosure extends LuaFunction {
|
public class LuaClosure extends LuaFunction {
|
||||||
private static final UpValue[] NOUPVALUES = new UpValue[0];
|
private static final UpValue[] NOUPVALUES = new UpValue[0];
|
||||||
|
|
||||||
public final Prototype p;
|
public final Prototype p;
|
||||||
|
|
||||||
public UpValue[] upValues;
|
public UpValue[] upValues;
|
||||||
|
|
||||||
final Globals globals;
|
final Globals globals;
|
||||||
|
|
||||||
/** 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.
|
||||||
@@ -102,7 +105,7 @@ public class LuaClosure extends LuaFunction {
|
|||||||
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) {
|
||||||
if (p.upvalues == null || p.upvalues.length == 0)
|
if (p.upvalues == null || p.upvalues.length == 0)
|
||||||
this.upValues = NOUPVALUES;
|
this.upValues = NOUPVALUES;
|
||||||
@@ -112,11 +115,11 @@ public class LuaClosure extends LuaFunction {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public boolean isclosure() {
|
public boolean isclosure() {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public LuaClosure optclosure(LuaClosure defval) {
|
public LuaClosure optclosure(LuaClosure defval) {
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
@@ -124,61 +127,119 @@ public class LuaClosure extends LuaFunction {
|
|||||||
public LuaClosure checkclosure() {
|
public LuaClosure checkclosure() {
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String tojstring() {
|
public String tojstring() {
|
||||||
return "function: " + p.toString();
|
return "function: " + p.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private List<LuaValue[]> stackPool = new ArrayList<>();
|
||||||
private LuaValue[] getNewStack() {
|
private LuaValue[] getNewStack() {
|
||||||
|
if (stackPool.isEmpty()) {
|
||||||
|
return getNewStackRaw();
|
||||||
|
} else {
|
||||||
|
return stackPool.remove(stackPool.size() - 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private LuaValue[] getNewStackRaw() {
|
||||||
int max = p.maxstacksize;
|
int max = p.maxstacksize;
|
||||||
LuaValue[] stack = new LuaValue[max];
|
LuaValue[] stack = new LuaValue[max];
|
||||||
System.arraycopy(NILS, 0, stack, 0, max);
|
System.arraycopy(NILS, 0, stack, 0, max);
|
||||||
return stack;
|
return stack;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void releaseStack(LuaValue[] stack) {
|
||||||
|
System.arraycopy(NILS, 0, stack, 0, stack.length);
|
||||||
|
stackPool.add(stack);
|
||||||
|
}
|
||||||
|
|
||||||
public final LuaValue call() {
|
public final LuaValue call() {
|
||||||
LuaValue[] stack = getNewStack();
|
LuaValue[] stack = getNewStack();
|
||||||
return execute(stack,NONE).arg1();
|
LuaValue result = execute(stack,NONE).arg1();
|
||||||
|
releaseStack(stack);
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
public final LuaValue call(LuaValue arg) {
|
public final LuaValue call(LuaValue arg) {
|
||||||
LuaValue[] stack = getNewStack();
|
LuaValue[] stack = getNewStack();
|
||||||
|
LuaValue result;
|
||||||
switch ( p.numparams ) {
|
switch ( p.numparams ) {
|
||||||
default: stack[0]=arg; return execute(stack,NONE).arg1();
|
default:
|
||||||
case 0: return execute(stack,arg).arg1();
|
stack[0]=arg;
|
||||||
|
result = execute(stack,NONE).arg1();
|
||||||
|
break;
|
||||||
|
case 0:
|
||||||
|
result = execute(stack,arg).arg1();
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
releaseStack(stack);
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
public final LuaValue call(LuaValue arg1, LuaValue arg2) {
|
public final LuaValue call(LuaValue arg1, LuaValue arg2) {
|
||||||
LuaValue[] stack = getNewStack();
|
LuaValue[] stack = getNewStack();
|
||||||
|
LuaValue result;
|
||||||
switch ( p.numparams ) {
|
switch ( p.numparams ) {
|
||||||
default: stack[0]=arg1; stack[1]=arg2; return execute(stack,NONE).arg1();
|
default:
|
||||||
case 1: stack[0]=arg1; return execute(stack,arg2).arg1();
|
stack[0]=arg1;
|
||||||
case 0: return execute(stack,p.is_vararg!=0? varargsOf(arg1,arg2): NONE).arg1();
|
stack[1]=arg2;
|
||||||
|
result = execute(stack,NONE).arg1();
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
stack[0]=arg1;
|
||||||
|
result = execute(stack,arg2).arg1();
|
||||||
|
break;
|
||||||
|
case 0:
|
||||||
|
result = execute(stack,p.is_vararg!=0 ? varargsOf(arg1,arg2) : NONE).arg1();
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
releaseStack(stack);
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
public final LuaValue call(LuaValue arg1, LuaValue arg2, LuaValue arg3) {
|
public final LuaValue call(LuaValue arg1, LuaValue arg2, LuaValue arg3) {
|
||||||
LuaValue[] stack = getNewStack();
|
LuaValue[] stack = getNewStack();
|
||||||
|
LuaValue result;
|
||||||
switch ( p.numparams ) {
|
switch ( p.numparams ) {
|
||||||
default: stack[0]=arg1; stack[1]=arg2; stack[2]=arg3; return execute(stack,NONE).arg1();
|
default:
|
||||||
case 2: stack[0]=arg1; stack[1]=arg2; return execute(stack,arg3).arg1();
|
stack[0]=arg1;
|
||||||
case 1: stack[0]=arg1; return execute(stack,p.is_vararg!=0? varargsOf(arg2,arg3): NONE).arg1();
|
stack[1]=arg2;
|
||||||
case 0: return execute(stack,p.is_vararg!=0? varargsOf(arg1,arg2,arg3): NONE).arg1();
|
stack[2]=arg3;
|
||||||
|
result = execute(stack,NONE).arg1();
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
stack[0]=arg1;
|
||||||
|
stack[1]=arg2;
|
||||||
|
result = execute(stack,arg3).arg1();
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
stack[0]=arg1;
|
||||||
|
result = execute(stack,p.is_vararg!=0 ? varargsOf(arg2,arg3) : NONE).arg1();
|
||||||
|
break;
|
||||||
|
case 0:
|
||||||
|
result = execute(stack,p.is_vararg!=0 ? varargsOf(arg1,arg2,arg3) : NONE).arg1();
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
releaseStack(stack);
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
public final Varargs invoke(Varargs varargs) {
|
public final Varargs invoke(Varargs varargs) {
|
||||||
return onInvoke(varargs).eval();
|
return onInvoke(varargs).eval();
|
||||||
}
|
}
|
||||||
|
|
||||||
public final Varargs onInvoke(Varargs varargs) {
|
public final Varargs onInvoke(Varargs varargs) {
|
||||||
LuaValue[] stack = getNewStack();
|
LuaValue[] stack = getNewStack();
|
||||||
for ( int i=0; i<p.numparams; i++ )
|
for ( int i=0; i<p.numparams; i++ )
|
||||||
stack[i] = varargs.arg(i+1);
|
stack[i] = varargs.arg(i+1);
|
||||||
return execute(stack,p.is_vararg!=0? varargs.subargs(p.numparams+1): NONE);
|
Varargs result = execute(stack,p.is_vararg!=0 ? varargs.subargs(p.numparams+1) : NONE);
|
||||||
|
if (result instanceof LuaValue) {
|
||||||
|
releaseStack(stack);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected Varargs execute( LuaValue[] stack, Varargs varargs ) {
|
protected Varargs execute( LuaValue[] stack, Varargs varargs ) {
|
||||||
// loop through instructions
|
// loop through instructions
|
||||||
int i,a,b,c,pc=0,top=0;
|
int i,a,b,c,pc=0,top=0;
|
||||||
@@ -186,11 +247,11 @@ public class LuaClosure extends LuaFunction {
|
|||||||
Varargs v = NONE;
|
Varargs v = NONE;
|
||||||
int[] code = p.code;
|
int[] code = p.code;
|
||||||
LuaValue[] k = p.k;
|
LuaValue[] k = p.k;
|
||||||
|
|
||||||
// upvalues are only possible when closures create closures
|
// upvalues are only possible when closures create closures
|
||||||
// TODO: use linked list.
|
// TODO: use linked list.
|
||||||
UpValue[] openups = p.p.length>0? new UpValue[stack.length]: null;
|
UpValue[] openups = p.p.length>0? new UpValue[stack.length]: null;
|
||||||
|
|
||||||
// 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 );
|
||||||
@@ -200,116 +261,116 @@ public class LuaClosure extends LuaFunction {
|
|||||||
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];
|
||||||
a = ((i>>6) & 0xff);
|
a = ((i>>6) & 0xff);
|
||||||
|
|
||||||
// process the op code
|
// process the op code
|
||||||
switch ( i & 0x3f ) {
|
switch ( i & 0x3f ) {
|
||||||
|
|
||||||
case Lua.OP_MOVE:/* A B R(A):= R(B) */
|
case Lua.OP_MOVE:/* A B R(A):= R(B) */
|
||||||
stack[a] = stack[i>>>23];
|
stack[a] = stack[i>>>23];
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
case Lua.OP_LOADK:/* A Bx R(A):= Kst(Bx) */
|
case Lua.OP_LOADK:/* A Bx R(A):= Kst(Bx) */
|
||||||
stack[a] = k[i>>>14];
|
stack[a] = k[i>>>14];
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
case Lua.OP_LOADKX:/* A R(A) := Kst(extra arg) */
|
case Lua.OP_LOADKX:/* A R(A) := Kst(extra arg) */
|
||||||
++pc;
|
++pc;
|
||||||
i = code[pc];
|
i = code[pc];
|
||||||
if ((i & 0x3f) != Lua.OP_EXTRAARG) {
|
if ((i & 0x3f) != Lua.OP_EXTRAARG) {
|
||||||
int op = i & 0x3f;
|
int op = i & 0x3f;
|
||||||
throw new LuaError("OP_EXTRAARG expected after OP_LOADKX, got " +
|
throw new LuaError("OP_EXTRAARG expected after OP_LOADKX, got " +
|
||||||
(op < Print.OPNAMES.length - 1 ? Print.OPNAMES[op] : "UNKNOWN_OP_" + op));
|
(op < Print.OPNAMES.length - 1 ? Print.OPNAMES[op] : "UNKNOWN_OP_" + op));
|
||||||
}
|
}
|
||||||
stack[a] = k[i>>>6];
|
stack[a] = k[i>>>6];
|
||||||
continue;
|
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)
|
||||||
++pc; /* skip next instruction (if C) */
|
++pc; /* skip next instruction (if C) */
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
case Lua.OP_LOADNIL: /* A B R(A):= ...:= R(A+B):= nil */
|
case Lua.OP_LOADNIL: /* A B R(A):= ...:= R(A+B):= nil */
|
||||||
for ( b=i>>>23; b-->=0; )
|
for ( b=i>>>23; b-->=0; )
|
||||||
stack[a++] = LuaValue.NIL;
|
stack[a++] = LuaValue.NIL;
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
case Lua.OP_GETUPVAL: /* A B R(A):= UpValue[B] */
|
case Lua.OP_GETUPVAL: /* A B R(A):= UpValue[B] */
|
||||||
stack[a] = upValues[i>>>23].getValue();
|
stack[a] = upValues[i>>>23].getValue();
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
case Lua.OP_GETTABUP: /* A B C R(A) := UpValue[B][RK(C)] */
|
case Lua.OP_GETTABUP: /* A B C R(A) := UpValue[B][RK(C)] */
|
||||||
stack[a] = upValues[i>>>23].getValue().get((c=(i>>14)&0x1ff)>0xff? k[c&0x0ff]: stack[c]);
|
stack[a] = upValues[i>>>23].getValue().get((c=(i>>14)&0x1ff)>0xff? k[c&0x0ff]: stack[c]);
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
case Lua.OP_GETTABLE: /* A B C R(A):= R(B)[RK(C)] */
|
case Lua.OP_GETTABLE: /* A B C R(A):= R(B)[RK(C)] */
|
||||||
stack[a] = stack[i>>>23].get((c=(i>>14)&0x1ff)>0xff? k[c&0x0ff]: stack[c]);
|
stack[a] = stack[i>>>23].get((c=(i>>14)&0x1ff)>0xff? k[c&0x0ff]: stack[c]);
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
case Lua.OP_SETTABUP: /* A B C UpValue[A][RK(B)] := RK(C) */
|
case Lua.OP_SETTABUP: /* A B C UpValue[A][RK(B)] := RK(C) */
|
||||||
upValues[a].getValue().set(((b=i>>>23)>0xff? k[b&0x0ff]: stack[b]), (c=(i>>14)&0x1ff)>0xff? k[c&0x0ff]: stack[c]);
|
upValues[a].getValue().set(((b=i>>>23)>0xff? k[b&0x0ff]: stack[b]), (c=(i>>14)&0x1ff)>0xff? k[c&0x0ff]: stack[c]);
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
case Lua.OP_SETUPVAL: /* A B UpValue[B]:= R(A) */
|
case Lua.OP_SETUPVAL: /* A B UpValue[B]:= R(A) */
|
||||||
upValues[i>>>23].setValue(stack[a]);
|
upValues[i>>>23].setValue(stack[a]);
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
case Lua.OP_SETTABLE: /* A B C R(A)[RK(B)]:= RK(C) */
|
case Lua.OP_SETTABLE: /* A B C R(A)[RK(B)]:= RK(C) */
|
||||||
stack[a].set(((b=i>>>23)>0xff? k[b&0x0ff]: stack[b]), (c=(i>>14)&0x1ff)>0xff? k[c&0x0ff]: stack[c]);
|
stack[a].set(((b=i>>>23)>0xff? k[b&0x0ff]: stack[b]), (c=(i>>14)&0x1ff)>0xff? k[c&0x0ff]: stack[c]);
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
case Lua.OP_NEWTABLE: /* A B C R(A):= {} (size = B,C) */
|
case Lua.OP_NEWTABLE: /* A B C R(A):= {} (size = B,C) */
|
||||||
stack[a] = new LuaTable(i>>>23,(i>>14)&0x1ff);
|
stack[a] = new LuaTable(i>>>23,(i>>14)&0x1ff);
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
case Lua.OP_SELF: /* A B C R(A+1):= R(B): R(A):= R(B)[RK(C)] */
|
case Lua.OP_SELF: /* A B C R(A+1):= R(B): R(A):= R(B)[RK(C)] */
|
||||||
stack[a+1] = (o = stack[i>>>23]);
|
stack[a+1] = (o = stack[i>>>23]);
|
||||||
stack[a] = o.get((c=(i>>14)&0x1ff)>0xff? k[c&0x0ff]: stack[c]);
|
stack[a] = o.get((c=(i>>14)&0x1ff)>0xff? k[c&0x0ff]: stack[c]);
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
case Lua.OP_ADD: /* A B C R(A):= RK(B) + RK(C) */
|
case Lua.OP_ADD: /* A B C R(A):= RK(B) + RK(C) */
|
||||||
stack[a] = ((b=i>>>23)>0xff? k[b&0x0ff]: stack[b]).add((c=(i>>14)&0x1ff)>0xff? k[c&0x0ff]: stack[c]);
|
stack[a] = ((b=i>>>23)>0xff? k[b&0x0ff]: stack[b]).add((c=(i>>14)&0x1ff)>0xff? k[c&0x0ff]: stack[c]);
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
case Lua.OP_SUB: /* A B C R(A):= RK(B) - RK(C) */
|
case Lua.OP_SUB: /* A B C R(A):= RK(B) - RK(C) */
|
||||||
stack[a] = ((b=i>>>23)>0xff? k[b&0x0ff]: stack[b]).sub((c=(i>>14)&0x1ff)>0xff? k[c&0x0ff]: stack[c]);
|
stack[a] = ((b=i>>>23)>0xff? k[b&0x0ff]: stack[b]).sub((c=(i>>14)&0x1ff)>0xff? k[c&0x0ff]: stack[c]);
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
case Lua.OP_MUL: /* A B C R(A):= RK(B) * RK(C) */
|
case Lua.OP_MUL: /* A B C R(A):= RK(B) * RK(C) */
|
||||||
stack[a] = ((b=i>>>23)>0xff? k[b&0x0ff]: stack[b]).mul((c=(i>>14)&0x1ff)>0xff? k[c&0x0ff]: stack[c]);
|
stack[a] = ((b=i>>>23)>0xff? k[b&0x0ff]: stack[b]).mul((c=(i>>14)&0x1ff)>0xff? k[c&0x0ff]: stack[c]);
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
case Lua.OP_DIV: /* A B C R(A):= RK(B) / RK(C) */
|
case Lua.OP_DIV: /* A B C R(A):= RK(B) / RK(C) */
|
||||||
stack[a] = ((b=i>>>23)>0xff? k[b&0x0ff]: stack[b]).div((c=(i>>14)&0x1ff)>0xff? k[c&0x0ff]: stack[c]);
|
stack[a] = ((b=i>>>23)>0xff? k[b&0x0ff]: stack[b]).div((c=(i>>14)&0x1ff)>0xff? k[c&0x0ff]: stack[c]);
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
case Lua.OP_MOD: /* A B C R(A):= RK(B) % RK(C) */
|
case Lua.OP_MOD: /* A B C R(A):= RK(B) % RK(C) */
|
||||||
stack[a] = ((b=i>>>23)>0xff? k[b&0x0ff]: stack[b]).mod((c=(i>>14)&0x1ff)>0xff? k[c&0x0ff]: stack[c]);
|
stack[a] = ((b=i>>>23)>0xff? k[b&0x0ff]: stack[b]).mod((c=(i>>14)&0x1ff)>0xff? k[c&0x0ff]: stack[c]);
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
case Lua.OP_POW: /* A B C R(A):= RK(B) ^ RK(C) */
|
case Lua.OP_POW: /* A B C R(A):= RK(B) ^ RK(C) */
|
||||||
stack[a] = ((b=i>>>23)>0xff? k[b&0x0ff]: stack[b]).pow((c=(i>>14)&0x1ff)>0xff? k[c&0x0ff]: stack[c]);
|
stack[a] = ((b=i>>>23)>0xff? k[b&0x0ff]: stack[b]).pow((c=(i>>14)&0x1ff)>0xff? k[c&0x0ff]: stack[c]);
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
case Lua.OP_UNM: /* A B R(A):= -R(B) */
|
case Lua.OP_UNM: /* A B R(A):= -R(B) */
|
||||||
stack[a] = stack[i>>>23].neg();
|
stack[a] = stack[i>>>23].neg();
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
case Lua.OP_NOT: /* A B R(A):= not R(B) */
|
case Lua.OP_NOT: /* A B R(A):= not R(B) */
|
||||||
stack[a] = stack[i>>>23].not();
|
stack[a] = stack[i>>>23].not();
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
case Lua.OP_LEN: /* A B R(A):= length of R(B) */
|
case Lua.OP_LEN: /* A B R(A):= length of R(B) */
|
||||||
stack[a] = stack[i>>>23].len();
|
stack[a] = stack[i>>>23].len();
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
case Lua.OP_CONCAT: /* A B C R(A):= R(B).. ... ..R(C) */
|
case Lua.OP_CONCAT: /* A B C R(A):= R(B).. ... ..R(C) */
|
||||||
b = i>>>23;
|
b = i>>>23;
|
||||||
c = (i>>14)&0x1ff;
|
c = (i>>14)&0x1ff;
|
||||||
{
|
{
|
||||||
if ( c > b+1 ) {
|
if ( c > b+1 ) {
|
||||||
Buffer sb = stack[c].buffer();
|
Buffer sb = stack[c].buffer();
|
||||||
@@ -321,112 +382,112 @@ public class LuaClosure extends LuaFunction {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
case Lua.OP_JMP: /* A sBx pc+=sBx; if (A) close all upvalues >= R(A - 1) */
|
case Lua.OP_JMP: /* A sBx pc+=sBx; if (A) close all upvalues >= R(A - 1) */
|
||||||
pc += (i>>>14)-0x1ffff;
|
pc += (i>>>14)-0x1ffff;
|
||||||
if (a > 0) {
|
if (a > 0) {
|
||||||
for (--a, b = openups.length; --b>=0; )
|
for (--a, b = openups.length; --b>=0; )
|
||||||
if (openups[b] != null && openups[b].index >= a) {
|
if (openups[b] != null && openups[b].index >= a) {
|
||||||
openups[b].close();
|
openups[b].close();
|
||||||
openups[b] = null;
|
openups[b] = null;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
continue;
|
|
||||||
|
|
||||||
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) )
|
|
||||||
++pc;
|
|
||||||
continue;
|
|
||||||
|
|
||||||
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) )
|
|
||||||
++pc;
|
|
||||||
continue;
|
|
||||||
|
|
||||||
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) )
|
|
||||||
++pc;
|
|
||||||
continue;
|
|
||||||
|
|
||||||
case Lua.OP_TEST: /* A C if not (R(A) <=> C) then pc++ */
|
|
||||||
if ( stack[a].toboolean() != ((i&(0x1ff<<14))!=0) )
|
|
||||||
++pc;
|
|
||||||
continue;
|
|
||||||
|
|
||||||
case Lua.OP_TESTSET: /* A B C if (R(B) <=> C) then R(A):= R(B) else pc++ */
|
|
||||||
/* note: doc appears to be reversed */
|
|
||||||
if ( (o=stack[i>>>23]).toboolean() != ((i&(0x1ff<<14))!=0) )
|
|
||||||
++pc;
|
|
||||||
else
|
|
||||||
stack[a] = o; // TODO: should be sBx?
|
|
||||||
continue;
|
|
||||||
|
|
||||||
case Lua.OP_CALL: /* A B C R(A), ... ,R(A+C-2):= R(A)(R(A+1), ... ,R(A+B-1)) */
|
|
||||||
switch ( i & (Lua.MASK_B | Lua.MASK_C) ) {
|
|
||||||
case (1<<Lua.POS_B) | (0<<Lua.POS_C): v=stack[a].invoke(NONE); top=a+v.narg(); continue;
|
|
||||||
case (2<<Lua.POS_B) | (0<<Lua.POS_C): v=stack[a].invoke(stack[a+1]); top=a+v.narg(); continue;
|
|
||||||
case (1<<Lua.POS_B) | (1<<Lua.POS_C): stack[a].call(); continue;
|
|
||||||
case (2<<Lua.POS_B) | (1<<Lua.POS_C): stack[a].call(stack[a+1]); continue;
|
|
||||||
case (3<<Lua.POS_B) | (1<<Lua.POS_C): stack[a].call(stack[a+1],stack[a+2]); continue;
|
|
||||||
case (4<<Lua.POS_B) | (1<<Lua.POS_C): stack[a].call(stack[a+1],stack[a+2],stack[a+3]); continue;
|
|
||||||
case (1<<Lua.POS_B) | (2<<Lua.POS_C): stack[a] = stack[a].call(); continue;
|
|
||||||
case (2<<Lua.POS_B) | (2<<Lua.POS_C): stack[a] = stack[a].call(stack[a+1]); continue;
|
|
||||||
case (3<<Lua.POS_B) | (2<<Lua.POS_C): stack[a] = stack[a].call(stack[a+1],stack[a+2]); continue;
|
|
||||||
case (4<<Lua.POS_B) | (2<<Lua.POS_C): stack[a] = stack[a].call(stack[a+1],stack[a+2],stack[a+3]); continue;
|
|
||||||
default:
|
|
||||||
b = i>>>23;
|
|
||||||
c = (i>>14)&0x1ff;
|
|
||||||
v = stack[a].invoke(b>0?
|
|
||||||
varargsOf(stack, a+1, b-1): // exact arg count
|
|
||||||
varargsOf(stack, a+1, top-v.narg()-(a+1), v)); // from prev top
|
|
||||||
if ( c > 0 ) {
|
|
||||||
v.copyto(stack, a, c-1);
|
|
||||||
v = NONE;
|
|
||||||
} else {
|
|
||||||
top = a + v.narg();
|
|
||||||
v = v.dealias();
|
|
||||||
}
|
}
|
||||||
continue;
|
continue;
|
||||||
}
|
|
||||||
|
case Lua.OP_EQ: /* A B C if ((RK(B) == RK(C)) ~= A) then pc++ */
|
||||||
case Lua.OP_TAILCALL: /* A B C return R(A)(R(A+1), ... ,R(A+B-1)) */
|
if ( ((b=i>>>23)>0xff? k[b&0x0ff]: stack[b]).eq_b((c=(i>>14)&0x1ff)>0xff? k[c&0x0ff]: stack[c]) != (a!=0) )
|
||||||
switch ( i & Lua.MASK_B ) {
|
++pc;
|
||||||
case (1<<Lua.POS_B): return new TailcallVarargs(stack[a], NONE);
|
continue;
|
||||||
case (2<<Lua.POS_B): return new TailcallVarargs(stack[a], stack[a+1]);
|
|
||||||
case (3<<Lua.POS_B): return new TailcallVarargs(stack[a], varargsOf(stack[a+1],stack[a+2]));
|
case Lua.OP_LT: /* A B C if ((RK(B) < RK(C)) ~= A) then pc++ */
|
||||||
case (4<<Lua.POS_B): return new TailcallVarargs(stack[a], varargsOf(stack[a+1],stack[a+2],stack[a+3]));
|
if ( ((b=i>>>23)>0xff? k[b&0x0ff]: stack[b]).lt_b((c=(i>>14)&0x1ff)>0xff? k[c&0x0ff]: stack[c]) != (a!=0) )
|
||||||
default:
|
++pc;
|
||||||
|
continue;
|
||||||
|
|
||||||
|
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) )
|
||||||
|
++pc;
|
||||||
|
continue;
|
||||||
|
|
||||||
|
case Lua.OP_TEST: /* A C if not (R(A) <=> C) then pc++ */
|
||||||
|
if ( stack[a].toboolean() != ((i&(0x1ff<<14))!=0) )
|
||||||
|
++pc;
|
||||||
|
continue;
|
||||||
|
|
||||||
|
case Lua.OP_TESTSET: /* A B C if (R(B) <=> C) then R(A):= R(B) else pc++ */
|
||||||
|
/* note: doc appears to be reversed */
|
||||||
|
if ( (o=stack[i>>>23]).toboolean() != ((i&(0x1ff<<14))!=0) )
|
||||||
|
++pc;
|
||||||
|
else
|
||||||
|
stack[a] = o; // TODO: should be sBx?
|
||||||
|
continue;
|
||||||
|
|
||||||
|
case Lua.OP_CALL: /* A B C R(A), ... ,R(A+C-2):= R(A)(R(A+1), ... ,R(A+B-1)) */
|
||||||
|
switch ( i & (Lua.MASK_B | Lua.MASK_C) ) {
|
||||||
|
case (1<<Lua.POS_B) | (0<<Lua.POS_C): v=stack[a].invoke(NONE); top=a+v.narg(); continue;
|
||||||
|
case (2<<Lua.POS_B) | (0<<Lua.POS_C): v=stack[a].invoke(stack[a+1]); top=a+v.narg(); continue;
|
||||||
|
case (1<<Lua.POS_B) | (1<<Lua.POS_C): stack[a].call(); continue;
|
||||||
|
case (2<<Lua.POS_B) | (1<<Lua.POS_C): stack[a].call(stack[a+1]); continue;
|
||||||
|
case (3<<Lua.POS_B) | (1<<Lua.POS_C): stack[a].call(stack[a+1],stack[a+2]); continue;
|
||||||
|
case (4<<Lua.POS_B) | (1<<Lua.POS_C): stack[a].call(stack[a+1],stack[a+2],stack[a+3]); continue;
|
||||||
|
case (1<<Lua.POS_B) | (2<<Lua.POS_C): stack[a] = stack[a].call(); continue;
|
||||||
|
case (2<<Lua.POS_B) | (2<<Lua.POS_C): stack[a] = stack[a].call(stack[a+1]); continue;
|
||||||
|
case (3<<Lua.POS_B) | (2<<Lua.POS_C): stack[a] = stack[a].call(stack[a+1],stack[a+2]); continue;
|
||||||
|
case (4<<Lua.POS_B) | (2<<Lua.POS_C): stack[a] = stack[a].call(stack[a+1],stack[a+2],stack[a+3]); continue;
|
||||||
|
default:
|
||||||
|
b = i>>>23;
|
||||||
|
c = (i>>14)&0x1ff;
|
||||||
|
v = stack[a].invoke(b>0?
|
||||||
|
varargsOf(stack, a+1, b-1): // exact arg count
|
||||||
|
varargsOf(stack, a+1, top-v.narg()-(a+1), v)); // from prev top
|
||||||
|
if ( c > 0 ) {
|
||||||
|
v.copyto(stack, a, c-1);
|
||||||
|
v = NONE;
|
||||||
|
} else {
|
||||||
|
top = a + v.narg();
|
||||||
|
v = v.dealias();
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
case Lua.OP_TAILCALL: /* A B C return R(A)(R(A+1), ... ,R(A+B-1)) */
|
||||||
|
switch ( i & Lua.MASK_B ) {
|
||||||
|
case (1<<Lua.POS_B): return new TailcallVarargs(stack[a], NONE);
|
||||||
|
case (2<<Lua.POS_B): return new TailcallVarargs(stack[a], stack[a+1]);
|
||||||
|
case (3<<Lua.POS_B): return new TailcallVarargs(stack[a], varargsOf(stack[a+1],stack[a+2]));
|
||||||
|
case (4<<Lua.POS_B): return new TailcallVarargs(stack[a], varargsOf(stack[a+1],stack[a+2],stack[a+3]));
|
||||||
|
default:
|
||||||
|
b = i>>>23;
|
||||||
|
v = b>0?
|
||||||
|
varargsOf(stack,a+1,b-1): // exact arg count
|
||||||
|
varargsOf(stack, a+1, top-v.narg()-(a+1), v); // from prev top
|
||||||
|
return new TailcallVarargs( stack[a], v );
|
||||||
|
}
|
||||||
|
|
||||||
|
case Lua.OP_RETURN: /* A B return R(A), ... ,R(A+B-2) (see note) */
|
||||||
b = i>>>23;
|
b = i>>>23;
|
||||||
v = b>0?
|
switch ( b ) {
|
||||||
varargsOf(stack,a+1,b-1): // exact arg count
|
case 0: return varargsOf(stack, a, top-v.narg()-a, v);
|
||||||
varargsOf(stack, a+1, top-v.narg()-(a+1), v); // from prev top
|
case 1: return NONE;
|
||||||
return new TailcallVarargs( stack[a], v );
|
case 2: return stack[a];
|
||||||
}
|
default:
|
||||||
|
return varargsOf(stack, a, b-1);
|
||||||
case Lua.OP_RETURN: /* A B return R(A), ... ,R(A+B-2) (see note) */
|
}
|
||||||
b = i>>>23;
|
|
||||||
switch ( b ) {
|
case Lua.OP_FORLOOP: /* A sBx R(A)+=R(A+2): if R(A) <?= R(A+1) then { pc+=sBx: R(A+3)=R(A) }*/
|
||||||
case 0: return varargsOf(stack, a, top-v.narg()-a, v);
|
|
||||||
case 1: return NONE;
|
|
||||||
case 2: return stack[a];
|
|
||||||
default:
|
|
||||||
return varargsOf(stack, a, b-1);
|
|
||||||
}
|
|
||||||
|
|
||||||
case Lua.OP_FORLOOP: /* A sBx R(A)+=R(A+2): if R(A) <?= R(A+1) then { pc+=sBx: R(A+3)=R(A) }*/
|
|
||||||
{
|
{
|
||||||
LuaValue limit = stack[a + 1];
|
LuaValue limit = stack[a + 1];
|
||||||
LuaValue step = stack[a + 2];
|
LuaValue step = stack[a + 2];
|
||||||
LuaValue idx = stack[a].add(step);
|
LuaValue idx = stack[a].add(step);
|
||||||
if (step.gt_b(0)? idx.lteq_b(limit): idx.gteq_b(limit)) {
|
if (step.gt_b(0)? idx.lteq_b(limit): idx.gteq_b(limit)) {
|
||||||
stack[a] = idx;
|
stack[a] = idx;
|
||||||
stack[a + 3] = idx;
|
stack[a + 3] = idx;
|
||||||
pc += (i>>>14)-0x1ffff;
|
pc += (i>>>14)-0x1ffff;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
case Lua.OP_FORPREP: /* A sBx R(A)-=R(A+2): pc+=sBx */
|
case Lua.OP_FORPREP: /* A sBx R(A)-=R(A+2): pc+=sBx */
|
||||||
{
|
{
|
||||||
LuaValue init = stack[a].checknumber("'for' initial value must be a number");
|
LuaValue init = stack[a].checknumber("'for' initial value must be a number");
|
||||||
LuaValue limit = stack[a + 1].checknumber("'for' limit must be a number");
|
LuaValue limit = stack[a + 1].checknumber("'for' limit must be a number");
|
||||||
@@ -438,44 +499,44 @@ public class LuaClosure extends LuaFunction {
|
|||||||
}
|
}
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
case Lua.OP_TFORCALL: /* A C R(A+3), ... ,R(A+2+C) := R(A)(R(A+1), R(A+2)); */
|
case Lua.OP_TFORCALL: /* A C R(A+3), ... ,R(A+2+C) := R(A)(R(A+1), R(A+2)); */
|
||||||
v = stack[a].invoke(varargsOf(stack[a+1],stack[a+2]));
|
v = stack[a].invoke(varargsOf(stack[a+1],stack[a+2]));
|
||||||
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;
|
v = NONE;
|
||||||
|
continue;
|
||||||
|
|
||||||
|
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? */
|
||||||
|
stack[a] = stack[a+1]; /* save control varible. */
|
||||||
|
pc += (i>>>14)-0x1ffff;
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
|
||||||
|
case Lua.OP_SETLIST: /* A B C R(A)[(C-1)*FPF+i]:= R(A+i), 1 <= i <= B */
|
||||||
|
{
|
||||||
|
if ( (c=(i>>14)&0x1ff) == 0 )
|
||||||
|
c = code[++pc];
|
||||||
|
int offset = (c-1) * Lua.LFIELDS_PER_FLUSH;
|
||||||
|
o = stack[a];
|
||||||
|
if ( (b=i>>>23) == 0 ) {
|
||||||
|
b = top - a - 1;
|
||||||
|
int m = b - v.narg();
|
||||||
|
int j=1;
|
||||||
|
for ( ;j<=m; j++ )
|
||||||
|
o.set(offset+j, stack[a + j]);
|
||||||
|
for ( ;j<=b; j++ )
|
||||||
|
o.set(offset+j, v.arg(j-m));
|
||||||
|
} else {
|
||||||
|
o.presize( offset + b );
|
||||||
|
for (int j=1; j<=b; j++)
|
||||||
|
o.set(offset+j, stack[a + j]);
|
||||||
|
}
|
||||||
|
}
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
case Lua.OP_TFORLOOP: /* A sBx if R(A+1) ~= nil then { R(A)=R(A+1); pc += sBx */
|
case Lua.OP_CLOSURE: /* A Bx R(A):= closure(KPROTO[Bx]) */
|
||||||
if (!stack[a+1].isnil()) { /* continue loop? */
|
|
||||||
stack[a] = stack[a+1]; /* save control varible. */
|
|
||||||
pc += (i>>>14)-0x1ffff;
|
|
||||||
}
|
|
||||||
continue;
|
|
||||||
|
|
||||||
case Lua.OP_SETLIST: /* A B C R(A)[(C-1)*FPF+i]:= R(A+i), 1 <= i <= B */
|
|
||||||
{
|
|
||||||
if ( (c=(i>>14)&0x1ff) == 0 )
|
|
||||||
c = code[++pc];
|
|
||||||
int offset = (c-1) * Lua.LFIELDS_PER_FLUSH;
|
|
||||||
o = stack[a];
|
|
||||||
if ( (b=i>>>23) == 0 ) {
|
|
||||||
b = top - a - 1;
|
|
||||||
int m = b - v.narg();
|
|
||||||
int j=1;
|
|
||||||
for ( ;j<=m; j++ )
|
|
||||||
o.set(offset+j, stack[a + j]);
|
|
||||||
for ( ;j<=b; j++ )
|
|
||||||
o.set(offset+j, v.arg(j-m));
|
|
||||||
} else {
|
|
||||||
o.presize( offset + b );
|
|
||||||
for (int j=1; j<=b; j++)
|
|
||||||
o.set(offset+j, stack[a + j]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
continue;
|
|
||||||
|
|
||||||
case Lua.OP_CLOSURE: /* A Bx R(A):= closure(KPROTO[Bx]) */
|
|
||||||
{
|
{
|
||||||
Prototype newp = p.p[i>>>14];
|
Prototype newp = p.p[i>>>14];
|
||||||
LuaClosure ncl = new LuaClosure(newp, globals);
|
LuaClosure ncl = new LuaClosure(newp, globals);
|
||||||
@@ -489,23 +550,23 @@ public class LuaClosure extends LuaFunction {
|
|||||||
stack[a] = ncl;
|
stack[a] = ncl;
|
||||||
}
|
}
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
case Lua.OP_VARARG: /* A B R(A), R(A+1), ..., R(A+B-1) = vararg */
|
|
||||||
b = i>>>23;
|
|
||||||
if ( b == 0 ) {
|
|
||||||
top = a + (b = varargs.narg());
|
|
||||||
v = varargs;
|
|
||||||
} else {
|
|
||||||
for ( int j=1; j<b; ++j )
|
|
||||||
stack[a+j-1] = varargs.arg(j);
|
|
||||||
}
|
|
||||||
continue;
|
|
||||||
|
|
||||||
case Lua.OP_EXTRAARG:
|
case Lua.OP_VARARG: /* A B R(A), R(A+1), ..., R(A+B-1) = vararg */
|
||||||
throw new IllegalArgumentException("Uexecutable opcode: OP_EXTRAARG");
|
b = i>>>23;
|
||||||
|
if ( b == 0 ) {
|
||||||
|
top = a + (b = varargs.narg());
|
||||||
|
v = varargs;
|
||||||
|
} else {
|
||||||
|
for ( int j=1; j<b; ++j )
|
||||||
|
stack[a+j-1] = varargs.arg(j);
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
|
||||||
default:
|
case Lua.OP_EXTRAARG:
|
||||||
throw new IllegalArgumentException("Illegal opcode: " + (i & 0x3f));
|
throw new java.lang.IllegalArgumentException("Uexecutable opcode: OP_EXTRAARG");
|
||||||
|
|
||||||
|
default:
|
||||||
|
throw new java.lang.IllegalArgumentException("Illegal opcode: " + (i & 0x3f));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch ( LuaError le ) {
|
} catch ( LuaError le ) {
|
||||||
@@ -569,7 +630,7 @@ public class LuaClosure extends LuaFunction {
|
|||||||
le.fileline = file + ":" + line;
|
le.fileline = file + ":" + line;
|
||||||
le.traceback = errorHook(le.getMessage(), le.level);
|
le.traceback = errorHook(le.getMessage(), le.level);
|
||||||
}
|
}
|
||||||
|
|
||||||
private UpValue findupval(LuaValue[] stack, short idx, UpValue[] openups) {
|
private UpValue findupval(LuaValue[] stack, short idx, UpValue[] openups) {
|
||||||
final int n = openups.length;
|
final int n = openups.length;
|
||||||
for (int i = 0; i < n; ++i)
|
for (int i = 0; i < n; ++i)
|
||||||
@@ -585,7 +646,7 @@ public class LuaClosure extends LuaFunction {
|
|||||||
protected LuaValue getUpvalue(int i) {
|
protected LuaValue getUpvalue(int i) {
|
||||||
return upValues[i].getValue();
|
return upValues[i].getValue();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void setUpvalue(int i, LuaValue v) {
|
protected void setUpvalue(int i, LuaValue v) {
|
||||||
upValues[i].setValue(v);
|
upValues[i].setValue(v);
|
||||||
}
|
}
|
||||||
@@ -593,6 +654,6 @@ public class LuaClosure extends LuaFunction {
|
|||||||
public String name() {
|
public String name() {
|
||||||
return "<"+p.shortsource()+":"+p.linedefined+">";
|
return "<"+p.shortsource()+":"+p.linedefined+">";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user