Fix weak tables, improve unit test

This commit is contained in:
James Roseborough
2008-04-11 13:44:39 +00:00
parent 89dd1594b4
commit 79734ab679
5 changed files with 85 additions and 53 deletions

View File

@@ -28,7 +28,6 @@ import org.luaj.vm.LFunction;
import org.luaj.vm.LString;
import org.luaj.vm.LTable;
import org.luaj.vm.LValue;
import org.luaj.vm.LWeakTable;
import org.luaj.vm.LuaState;
@@ -186,7 +185,9 @@ public class TableLib extends LFunction {
LTable table = vm.totable(2);
int pos = (n>=3? vm.tointeger(3): 0);
vm.resettop();
vm.pushlvalue( table.luaRemovePos( pos ) );
LValue v = table.luaRemovePos(pos);
if ( ! v.isNil() )
vm.pushlvalue( v );
break;
}

View File

@@ -49,8 +49,8 @@ import org.luaj.vm.LuaState;
*/
public class LTable extends LValue {
private Object[] array;
private LValue[] hashKeys;
protected Object[] array;
protected LValue[] hashKeys;
private Object[] hashValues;
private int hashEntries;
private LTable m_metatable;
@@ -70,7 +70,8 @@ public class LTable extends LValue {
* in the range 1 .. narray and nhash non-integer keys.
*/
public LTable( int narray, int nhash ) {
nhash = Math.max(nhash,MIN_HASH_CAPACITY);
if ( nhash > 0 && nhash < MIN_HASH_CAPACITY )
nhash = MIN_HASH_CAPACITY;
array = new Object[narray];
hashKeys = new LValue[nhash];
hashValues = new Object[nhash];
@@ -205,9 +206,8 @@ public class LTable extends LValue {
}
/**
* Return true if the table contains an entry with the given key, false if
* not. Ignores the metatable.
*
* Return true if the table contains an entry with the given key,
* false if not. Ignores the metatable.
*/
public boolean containsKey( LValue key ) {
if ( key.isInteger() ) {
@@ -218,11 +218,14 @@ public class LTable extends LValue {
return null != hashGet(key);
}
/** Check if a integer-valued key exists */
/**
* Return true if the table contains an entry with the given integer-valued key,
* false if not. Ignores the metatable.
*/
public boolean containsKey( int key ) {
return null != (key>0 && key<=array.length?
array[key-1]:
hashGet(LInteger.valueOf(key)) );
return (key>0 && key<=array.length?
array[key-1] != null:
(hashKeys.length>0 && hashKeys[hashFindSlot(LInteger.valueOf(key))]!=null));
}
@@ -244,9 +247,9 @@ public class LTable extends LValue {
private static final int MAX_KEY = 0x3fffffff;
/*
** Try to find a boundary in table `t'. A `boundary' is an integer index
** such that t[i] is non-nil and t[i+1] is nil (and 0 if t[1] is nil).
/**
* Try to find a boundary in table `t'. A `boundary' is an integer index
* such that t[i] is non-nil and t[i+1] is nil (and 0 if t[1] is nil).
*/
public int luaLength() {
int j = array.length;
@@ -258,10 +261,8 @@ public class LTable extends LValue {
// find `i' and `j' such that i is present and j is not
int i = 0;
while ( containsKey(j) && j < MAX_KEY ) {
for ( ++j; containsKey(j) && j < MAX_KEY; j*=2 )
i = j;
j *= 2;
}
// binary search
while ( j - i > 1) {
@@ -289,7 +290,7 @@ public class LTable extends LValue {
org.luaj.vm.LTable t = (org.luaj.vm.LTable) metatable;
LValue m = t.get(TM_MODE);
if ( "v".equals(m.toJavaString()) ) {
// m_backing = new WeakBacking(m_backing);
return new LWeakTable(this);
}
this.m_metatable = t;
}
@@ -435,8 +436,8 @@ public class LTable extends LValue {
}
private boolean compare(int i, int j, LuaState vm, LValue cmpfunc) {
LValue a = get(i);
LValue b = get(j);
LValue a = get(i+1);
LValue b = get(j+1);
if ( a.isNil() || b.isNil() )
return false;
if ( ! cmpfunc.isNil() ) {
@@ -453,9 +454,9 @@ public class LTable extends LValue {
}
private void swap(int i, int j) {
LValue a = get(i);
put(i, get(j));
put(j, a);
LValue a = get(i+1);
put(i+1, get(j+1));
put(j+1, a);
}
/**
@@ -478,7 +479,7 @@ public class LTable extends LValue {
Object a = array[i];
if ( a != null ) {
vm.pushinteger(i+1);
vm.pushlvalue((LValue)a);
vm.pushlvalue(normalizeGet(a));
return true;
} else if ( indexedonly ) {
vm.pushnil();
@@ -493,7 +494,7 @@ public class LTable extends LValue {
if ( v != null ) {
LValue k = hashKeys[i];
vm.pushlvalue(k);
vm.pushlvalue((LValue)v);
vm.pushlvalue(normalizeGet(v));
return true;
}
}
@@ -508,7 +509,7 @@ public class LTable extends LValue {
// first iteration
if ( key.isNil() )
return -1;
return 0;
// is `key' inside array part?
if ( key.isInteger() ) {

View File

@@ -36,6 +36,17 @@ public class LWeakTable extends LTable {
super(narray, nhash);
}
public LWeakTable(LTable copy) {
super( copy.array.length, copy.hashKeys.length );
for ( int i=0, k=1, n=copy.array.length; i<n; i++, k++ )
this.put( k, copy.get(k) );
for ( int i=0, n=copy.hashKeys.length; i<n; i++ ) {
LValue k = copy.hashKeys[i];
if ( k != null )
this.put( k, copy.get(k) );
}
}
protected LValue normalizeGet(Object val) {
if ( val != null )
val = ((WeakReference)val).get();
@@ -46,4 +57,14 @@ public class LWeakTable extends LTable {
return val==LNil.NIL? null: new WeakReference(val);
}
public boolean next(LuaState vm, LValue key, boolean indexedonly) {
while ( super.next(vm, key, indexedonly) ) {
if ( ! vm.isnil(-1) )
return true;
vm.pop(1);
key = vm.poplvalue();
}
return false;
}
}

View File

@@ -1,3 +1,11 @@
local t = { "one", "two", "three", a='aaa', b='bbb', c='ccc' }
table.insert(t,'six');
table.insert(t,1,'seven');
table.insert(t,4,'eight');
table.insert(t,7,'nine');
table.insert(t,10,'ten'); print( #t )
-- concat
print( '-- concat tests' )
function tryconcat(t)
@@ -30,26 +38,26 @@ function eles(t,f)
end
-- insert, maxn
print( '-- insert, maxn tests' )
print( '-- insert, len tests' )
local t = { "one", "two", "three", a='aaa', b='bbb', c='ccc' }
print( eles(t) )
table.insert(t,'six'); print( eles(t) )
table.insert(t,1,'seven'); print( eles(t) )
table.insert(t,4,'eight'); print( eles(t) )
table.insert(t,7,'nine'); print( eles(t) )
table.insert(t,10,'ten'); print( eles(t) )
print( eles(t), #t )
table.insert(t,'six'); print( eles(t), #t )
table.insert(t,1,'seven'); print( eles(t), #t )
table.insert(t,4,'eight'); print( eles(t), #t )
table.insert(t,7,'nine'); print( eles(t), #t )
table.insert(t,10,'ten'); print( eles(t), #t )
-- remove
print( '-- remove tests' )
t = { "one", "two", "three", "four", "five", "six", "seven", [10]="ten", a='aaa', b='bbb', c='ccc' }
print( eles(t) )
print( 'table.remove(t)', table.remove(t) ); print( eles(t) )
print( 'table.remove(t,1)', table.remove(t,1) ); print( eles(t) )
print( 'table.remove(t,3)', table.remove(t,3) ); print( eles(t) )
print( 'table.remove(t,5)', table.remove(t,5) ); print( eles(t) )
print( 'table.remove(t,10)', table.remove(t,10) ); print( eles(t) )
print( 'table.remove(t,-1)', table.remove(t,-1) ); print( eles(t) )
print( 'table.remove(t,-1)', table.remove(t,-1) ) ; print( eles(t) )
print( eles(t), #t )
print( 'table.remove(t)', table.remove(t) ); print( eles(t), #t )
print( 'table.remove(t,1)', table.remove(t,1) ); print( eles(t), #t )
print( 'table.remove(t,3)', table.remove(t,3) ); print( eles(t), #t )
print( 'table.remove(t,5)', table.remove(t,5) ); print( eles(t), #t )
print( 'table.remove(t,10)', table.remove(t,10) ); print( eles(t), #t )
print( 'table.remove(t,-1)', table.remove(t,-1) ); print( eles(t), #t )
print( 'table.remove(t,-1)', table.remove(t,-1) ) ; print( eles(t), #t )
-- sort
print( '-- sort tests' )

View File

@@ -1,28 +1,29 @@
function newtable(t)
n = setmetatable(t,{__mode="v"})
for k,v in pairs(t) do
n[k] = v
end
return n;
end
-- normalized printing
function eles(t,f)
f = f or pairs
all = {}
for k,v in f(t) do
if type(v) == 'table' then
v = '{'..tostring(v.v)..'}'
end
table.insert( all, "["..tostring(k).."]="..tostring(v) )
end
table.sort( all )
return tostring(t).."{"..table.concat(all,',').."}"
return "{"..table.concat(all,',').."}"
end
function newtable(t)
return setmetatable(t,{__mode="v"})
end
function new(a)
return {v='_'..tostring(a).."_"}
end
-- basic weak-reference table test
local src = "return { 'one', 'two', 'three', 'four', a='aaa', b='bbb', c='ccc', d='ddd'}"
local weak = newtable( loadstring(src)() )
local weak = newtable{ new('one'), new('two'), new('three'), new('four'), a=new('aaa'), b=new('bbb'), c=new('ccc'), d=new('ddd') }
local strong = { weak[1], weak[3], a=weak.a, c=weak.c }
print( 'before, weak:', eles(weak) )
print( 'before, strong:', eles(strong) )