Simplify and fix upvalue implementation.
This commit is contained in:
@@ -30,7 +30,6 @@ public class LuaClosure extends LuaFunction {
|
|||||||
|
|
||||||
public final Prototype p;
|
public final Prototype p;
|
||||||
public final UpValue[] upValues;
|
public final UpValue[] upValues;
|
||||||
private UpValue openUpValues = null;
|
|
||||||
|
|
||||||
LuaClosure() {
|
LuaClosure() {
|
||||||
p = null;
|
p = null;
|
||||||
@@ -43,6 +42,12 @@ public class LuaClosure extends LuaFunction {
|
|||||||
this.upValues = p.nups>0? new UpValue[p.nups]: NOUPVALUES;
|
this.upValues = p.nups>0? new UpValue[p.nups]: NOUPVALUES;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected LuaClosure(int nupvalues, LuaValue env) {
|
||||||
|
super( env );
|
||||||
|
this.p = null;
|
||||||
|
this.upValues = nupvalues>0? new UpValue[nupvalues]: NOUPVALUES;
|
||||||
|
}
|
||||||
|
|
||||||
public boolean isclosure() {
|
public boolean isclosure() {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -103,7 +108,7 @@ public class LuaClosure extends LuaFunction {
|
|||||||
return execute(stack,p.is_vararg!=0? varargs.subargs(p.numparams+1): NONE);
|
return execute(stack,p.is_vararg!=0? varargs.subargs(p.numparams+1): NONE);
|
||||||
}
|
}
|
||||||
|
|
||||||
private final 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;
|
||||||
LuaValue o;
|
LuaValue o;
|
||||||
@@ -111,6 +116,9 @@ public class LuaClosure extends LuaFunction {
|
|||||||
int[] code = p.code;
|
int[] code = p.code;
|
||||||
LuaValue[] k = p.k;
|
LuaValue[] k = p.k;
|
||||||
|
|
||||||
|
// upvalues are only possible when closures create closures
|
||||||
|
UpValue[] openups = p.p.length>0? new UpValue[stack.length]: null;
|
||||||
|
|
||||||
// create varargs "arg" table
|
// create varargs "arg" table
|
||||||
if ( p.is_vararg >= Lua.VARARG_NEEDSARG )
|
if ( p.is_vararg >= Lua.VARARG_NEEDSARG )
|
||||||
stack[p.numparams] = new LuaTable(varargs);
|
stack[p.numparams] = new LuaTable(varargs);
|
||||||
@@ -319,7 +327,6 @@ public class LuaClosure extends LuaFunction {
|
|||||||
}
|
}
|
||||||
|
|
||||||
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) */
|
||||||
closeUpValues();
|
|
||||||
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);
|
||||||
@@ -394,7 +401,11 @@ public class LuaClosure extends LuaFunction {
|
|||||||
continue;
|
continue;
|
||||||
|
|
||||||
case Lua.OP_CLOSE: /* A close all variables in the stack up to (>=) R(A)*/
|
case Lua.OP_CLOSE: /* A close all variables in the stack up to (>=) R(A)*/
|
||||||
closeUpValues( a );
|
for ( b=openups.length; --b>=a; )
|
||||||
|
if ( openups[b]!=null ) {
|
||||||
|
openups[b].close();
|
||||||
|
openups[b] = null;
|
||||||
|
}
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
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)) */
|
||||||
@@ -407,7 +418,7 @@ public class LuaClosure extends LuaFunction {
|
|||||||
b = i>>>23;
|
b = i>>>23;
|
||||||
newcl.upValues[j] = (i&4) != 0?
|
newcl.upValues[j] = (i&4) != 0?
|
||||||
upValues[b]:
|
upValues[b]:
|
||||||
findUpValue(stack,b);
|
openups[b]!=null? openups[b]: (openups[b]=new UpValue(stack,b));
|
||||||
}
|
}
|
||||||
stack[a] = newcl;
|
stack[a] = newcl;
|
||||||
}
|
}
|
||||||
@@ -436,56 +447,20 @@ public class LuaClosure extends LuaFunction {
|
|||||||
throw le;
|
throw le;
|
||||||
} finally {
|
} finally {
|
||||||
LuaThread.onReturn();
|
LuaThread.onReturn();
|
||||||
}
|
if ( openups != null )
|
||||||
}
|
for ( int u=openups.length; --u>=0; )
|
||||||
|
if ( openups[u] != null )
|
||||||
// TODO: inline, optimize when targs come in ascending order?
|
openups[u].close();
|
||||||
UpValue findUpValue(LuaValue[] stack, int target) {
|
|
||||||
UpValue prev=null,up=openUpValues;
|
|
||||||
while ( up != null ) {
|
|
||||||
if (up.index == target) {
|
|
||||||
return up;
|
|
||||||
} else if (up.index < target) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
up = (prev=up).next;
|
|
||||||
}
|
|
||||||
up = new UpValue(stack, target, up);
|
|
||||||
if ( prev!=null )
|
|
||||||
prev.next = up;
|
|
||||||
else
|
|
||||||
this.openUpValues = up;
|
|
||||||
return up;
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: inline?
|
|
||||||
void closeUpValues(int limit) {
|
|
||||||
UpValue prev=null,up=openUpValues;
|
|
||||||
while ( up != null ) {
|
|
||||||
UpValue next = up.next;
|
|
||||||
if ( up.close(limit) ) {
|
|
||||||
if ( prev==null )
|
|
||||||
this.openUpValues = up.next;
|
|
||||||
else
|
|
||||||
prev.next = up.next;
|
|
||||||
up.next = null;
|
|
||||||
} else {
|
|
||||||
prev = up;
|
|
||||||
}
|
|
||||||
up = next;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: inline?
|
protected LuaValue getUpvalue(int i) {
|
||||||
void closeUpValues() {
|
return upValues[i].getValue();
|
||||||
UpValue up=openUpValues;
|
|
||||||
while ( up != null ) {
|
|
||||||
UpValue next = up.next;
|
|
||||||
up.close(-1);
|
|
||||||
up.next = null;
|
|
||||||
up = next;
|
|
||||||
}
|
|
||||||
openUpValues = null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected void setUpvalue(int i, LuaValue v) {
|
||||||
|
upValues[i].setValue(v);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -27,17 +27,14 @@ public final class UpValue {
|
|||||||
|
|
||||||
LuaValue[] array; // initially the stack, becomes a holder
|
LuaValue[] array; // initially the stack, becomes a holder
|
||||||
int index;
|
int index;
|
||||||
boolean closed;
|
|
||||||
UpValue next = null;
|
|
||||||
|
|
||||||
public UpValue( LuaValue[] stack, int index, UpValue next ) {
|
public UpValue( LuaValue[] stack, int index) {
|
||||||
this.array = stack;
|
this.array = stack;
|
||||||
this.index = index;
|
this.index = index;
|
||||||
this.next = next;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return (closed? "-": "+") + array[index];
|
return array[index].toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
public final LuaValue getValue() {
|
public final LuaValue getValue() {
|
||||||
@@ -48,17 +45,8 @@ public final class UpValue {
|
|||||||
array[index] = value;
|
array[index] = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
public final boolean close( int limit ) {
|
public final void close() {
|
||||||
if ( (!closed) && (index>=limit) ) {
|
array = new LuaValue[] { array[index] };
|
||||||
array = new LuaValue[] { array[index] };
|
index = 0;
|
||||||
index = 0;
|
|
||||||
return (closed = true);
|
|
||||||
} else {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public final boolean isClosed() {
|
|
||||||
return closed;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,2 +1,2 @@
|
|||||||
# on the way to version 2.0
|
# on the way to version 2.0
|
||||||
version: 1.9.52
|
version: 1.9.53
|
||||||
|
|||||||
Reference in New Issue
Block a user