From bf663878cb19c37186789fcd4ff3105d15e9e8e8 Mon Sep 17 00:00:00 2001 From: Enyby Date: Mon, 4 Nov 2019 07:57:49 +0200 Subject: [PATCH] Add support for metatags to table lib methods: sort, insert, remove, unpack. ``` do -- testing table library with metamethods local function test (proxy, t) for i = 1, 10 do table.insert(proxy, 1, i) end assert(#proxy == 10 and #t == 10, tostring(#proxy)..'; '..tostring(#t)) for i = 1, 10 do assert(t[i] == 11 - i) end table.sort(proxy) for i = 1, 10 do assert(t[i] == i and proxy[i] == i, i..': '..tostring(proxy[i])..'; '..tostring(t[i])) end assert(table.concat(proxy, ",") == "1,2,3,4,5,6,7,8,9,10") for i = 1, 8 do assert(table.remove(proxy, 1) == i) end assert(#proxy == 2 and #t == 2) local a, b, c = table.unpack(proxy) assert(a == 9 and b == 10 and c == nil) end -- all virtual local t = {} local proxy = setmetatable({}, { __len = function () return #t end, __index = t, __newindex = t, }) test(proxy, t) -- only __newindex local count = 0 t = setmetatable({}, { __newindex = function (t,k,v) count = count + 1; rawset(t,k,v) end}) test(t, t) assert(count == 10) -- after first 10, all other sets are not new -- no __newindex t = setmetatable({}, { __index = function (_,k) return k + 1 end, __len = function (_) return 5 end}) assert(table.concat(t, ";") == "2;3;4;5;6") end function check (a, f) f = f or function (x,y) return x n) return NONE; - LuaValue v = rawget(pos); + LuaValue v = get(pos); for ( LuaValue r=v; !r.isnil(); ) { - r = rawget(pos+1); - rawset(pos++, r); + r = get(pos+1); + set(pos++, r); } return v.isnil()? NONE: v; } @@ -319,10 +319,10 @@ public class LuaTable extends LuaValue implements Metatable { */ public void insert(int pos, LuaValue value) { if ( pos == 0 ) - pos = rawlen()+1; + pos = length()+1; while ( ! value.isnil() ) { - LuaValue v = rawget( pos ); - rawset(pos++, value); + LuaValue v = get( pos ); + set(pos++, value); value = v; } } @@ -789,40 +789,35 @@ public class LuaTable extends LuaValue implements Metatable { if (m_metatable != null && m_metatable.useWeakValues()) { dropWeakArrayValues(); } - LuaValue[] array = this.array; - int n = array.length; - while ( n > 0 && array[n-1] == null ) - --n; + int n = length(); if ( n > 1 ) heapSort(n, comparator.isnil() ? null : comparator); } private void heapSort(int count, LuaValue cmpfunc) { heapify(count, cmpfunc); - LuaValue[] array = this.array; - for ( int end=count-1; end>0; ) { - LuaValue a = array[end]; // swap(end, 0) - array[end] = array[0]; - array[0] = a; - siftDown(0, --end, cmpfunc); + for ( int end=count; end>1; ) { + LuaValue a = get(end); // swap(end, 1) + set(end, get(1)); + set(1, a); + siftDown(1, --end, cmpfunc); } } private void heapify(int count, LuaValue cmpfunc) { - for ( int start=count/2-1; start>=0; --start ) - siftDown(start, count - 1, cmpfunc); + for ( int start=count/2; start>0; --start ) + siftDown(start, count, cmpfunc); } private void siftDown(int start, int end, LuaValue cmpfunc) { - LuaValue[] array = this.array; - for ( int root=start; root*2+1 <= end; ) { - int child = root*2+1; + for ( int root=start; root*2 <= end; ) { + int child = root*2; if (child < end && compare(child, child + 1, cmpfunc)) ++child; if (compare(root, child, cmpfunc)) { - LuaValue a = array[root]; // swap(root, child) - array[root] = array[child]; - array[child] = a; + LuaValue a = get(root); // swap(root, child) + set(root, get(child)); + set(child, a); root = child; } else return; @@ -830,16 +825,7 @@ public class LuaTable extends LuaValue implements Metatable { } private boolean compare(int i, int j, LuaValue cmpfunc) { - LuaValue a, b; - LuaValue[] array = this.array; - Metatable m_metatable = this.m_metatable; - if (m_metatable == null) { - a = array[i]; - b = array[j]; - } else { - a = m_metatable.arrayget(array, i); - b = m_metatable.arrayget(array, j); - } + LuaValue a = get(i), b = get(j); if ( a == null || b == null ) return false; if ( cmpfunc != null ) { diff --git a/src/core/org/luaj/vm2/lib/TableLib.java b/src/core/org/luaj/vm2/lib/TableLib.java index 086ac8ef..64959277 100644 --- a/src/core/org/luaj/vm2/lib/TableLib.java +++ b/src/core/org/luaj/vm2/lib/TableLib.java @@ -151,7 +151,7 @@ public class TableLib extends TwoArgFunction { public Varargs invoke(Varargs args) { LuaTable t = args.checktable(1); // do not waste resource for calc rawlen if arg3 is not nil - int len = args.arg(3).isnil() ? t.rawlen() : 0; + int len = args.arg(3).isnil() ? t.length() : 0; return t.unpack(args.optint(2, 1), args.optint(3, len)); } }