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 UpValue[] upValues;
|
||||
private UpValue openUpValues = null;
|
||||
|
||||
LuaClosure() {
|
||||
p = null;
|
||||
@@ -43,6 +42,12 @@ public class LuaClosure extends LuaFunction {
|
||||
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() {
|
||||
return true;
|
||||
}
|
||||
@@ -103,7 +108,7 @@ public class LuaClosure extends LuaFunction {
|
||||
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
|
||||
int i,a,b,c,pc=0,top=0;
|
||||
LuaValue o;
|
||||
@@ -111,6 +116,9 @@ public class LuaClosure extends LuaFunction {
|
||||
int[] code = p.code;
|
||||
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
|
||||
if ( p.is_vararg >= Lua.VARARG_NEEDSARG )
|
||||
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) */
|
||||
closeUpValues();
|
||||
b = i>>>23;
|
||||
switch ( b ) {
|
||||
case 0: return varargsOf(stack, a, top-v.narg()-a, v);
|
||||
@@ -394,7 +401,11 @@ public class LuaClosure extends LuaFunction {
|
||||
continue;
|
||||
|
||||
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;
|
||||
|
||||
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;
|
||||
newcl.upValues[j] = (i&4) != 0?
|
||||
upValues[b]:
|
||||
findUpValue(stack,b);
|
||||
openups[b]!=null? openups[b]: (openups[b]=new UpValue(stack,b));
|
||||
}
|
||||
stack[a] = newcl;
|
||||
}
|
||||
@@ -436,56 +447,20 @@ public class LuaClosure extends LuaFunction {
|
||||
throw le;
|
||||
} finally {
|
||||
LuaThread.onReturn();
|
||||
if ( openups != null )
|
||||
for ( int u=openups.length; --u>=0; )
|
||||
if ( openups[u] != null )
|
||||
openups[u].close();
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: inline, optimize when targs come in ascending order?
|
||||
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;
|
||||
protected LuaValue getUpvalue(int i) {
|
||||
return upValues[i].getValue();
|
||||
}
|
||||
|
||||
// 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;
|
||||
}
|
||||
protected void setUpvalue(int i, LuaValue v) {
|
||||
upValues[i].setValue(v);
|
||||
}
|
||||
|
||||
// TODO: inline?
|
||||
void closeUpValues() {
|
||||
UpValue up=openUpValues;
|
||||
while ( up != null ) {
|
||||
UpValue next = up.next;
|
||||
up.close(-1);
|
||||
up.next = null;
|
||||
up = next;
|
||||
}
|
||||
openUpValues = null;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -27,17 +27,14 @@ public final class UpValue {
|
||||
|
||||
LuaValue[] array; // initially the stack, becomes a holder
|
||||
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.index = index;
|
||||
this.next = next;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return (closed? "-": "+") + array[index];
|
||||
return array[index].toString();
|
||||
}
|
||||
|
||||
public final LuaValue getValue() {
|
||||
@@ -48,17 +45,8 @@ public final class UpValue {
|
||||
array[index] = value;
|
||||
}
|
||||
|
||||
public final boolean close( int limit ) {
|
||||
if ( (!closed) && (index>=limit) ) {
|
||||
array = new LuaValue[] { array[index] };
|
||||
index = 0;
|
||||
return (closed = true);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public final boolean isClosed() {
|
||||
return closed;
|
||||
public final void close() {
|
||||
array = new LuaValue[] { array[index] };
|
||||
index = 0;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,2 +1,2 @@
|
||||
# on the way to version 2.0
|
||||
version: 1.9.52
|
||||
version: 1.9.53
|
||||
|
||||
Reference in New Issue
Block a user