diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/lapi.js | 33 | ||||
-rw-r--r-- | src/lbaselib.js | 2 | ||||
-rw-r--r-- | src/lcode.js | 4 | ||||
-rw-r--r-- | src/ldblib.js | 2 | ||||
-rw-r--r-- | src/ldebug.js | 5 | ||||
-rw-r--r-- | src/ldo.js | 2 | ||||
-rw-r--r-- | src/lobject.js | 70 | ||||
-rw-r--r-- | src/loslib.js | 6 | ||||
-rw-r--r-- | src/lparser.js | 5 | ||||
-rw-r--r-- | src/lstate.js | 4 | ||||
-rw-r--r-- | src/lstrlib.js | 4 | ||||
-rw-r--r-- | src/ltable.js | 28 | ||||
-rw-r--r-- | src/ltm.js | 5 | ||||
-rw-r--r-- | src/lvm.js | 17 |
14 files changed, 87 insertions, 100 deletions
diff --git a/src/lapi.js b/src/lapi.js index 72c35f0..99b0859 100644 --- a/src/lapi.js +++ b/src/lapi.js @@ -14,6 +14,7 @@ const lua = require('./lua.js'); const luaconf = require('./luaconf.js'); const lundump = require('./lundump.js'); const lvm = require('./lvm.js'); +const ltable = require('./ltable.js'); const MAXUPVAL = lfunc.MAXUPVAL; const CT = lua.constant_types; const TS = lua.thread_status; @@ -335,8 +336,8 @@ const auxsetstr = function(L, t, k) { assert(1 < L.top - L.ci.funcOff, "not enough elements in the stack"); - if (t.ttistable() && !t.__index(t, k).ttisnil()) { - t.__newindex(t, k, L.stack[L.top - 1]); + if (t.ttistable() && !lobject.table_index(t, k).ttisnil()) { + lobject.table_newindex(t, k, L.stack[L.top - 1]); L.top--; /* pop value */ } else { L.stack[L.top++] = str; @@ -399,7 +400,7 @@ const lua_rawset = function(L, idx) { assert(2 < L.top - L.ci.funcOff, "not enough elements in the stack"); let o = index2addr(L, idx); assert(o.ttistable(), "table expected"); - o.__newindex(o, L.stack[L.top - 2], L.stack[L.top - 1]); + lobject.table_newindex(o, L.stack[L.top - 2], L.stack[L.top - 1]); L.top -= 2; }; @@ -408,7 +409,7 @@ const lua_rawsetp = function(L, idx, p) { let o = index2addr(L, idx); assert(L, o.ttistable(), "table expected"); let k = p; - o.__newindex(o, k, L.stack[L.top - 1]); + lobject.table_newindex(o, k, L.stack[L.top - 1]); L.top--; }; @@ -420,7 +421,7 @@ const auxgetstr = function(L, t, k) { assert(Array.isArray(k), "key must be an array of bytes"); let str = L.l_G.intern(k); - let slot = t.__index(t, k); + let slot = lobject.table_index(t, k); if (t.ttistable() && !slot.ttisnil()) { L.stack[L.top++] = slot; assert(L.top <= L.ci.top, "stack overflow"); @@ -438,7 +439,7 @@ const lua_rawgeti = function(L, idx, n) { assert(t.ttistable(), "table expected"); - L.stack[L.top++] = t.__index(t, n); + L.stack[L.top++] = lobject.table_index(t, n); assert(L.top <= L.ci.top, "stack overflow"); @@ -449,7 +450,7 @@ const lua_rawgetp = function(L, idx, p) { let t = index2addr(L, idx); assert(t.ttistable(), "table expected"); let k = p; - L.stack[L.top++] = t.__index(t, k); + L.stack[L.top++] = lobject.table_index(t, k); assert(L.top <= L.ci.top, "stack overflow"); return L.stack[L.top - 1].ttnov(); }; @@ -459,14 +460,14 @@ const lua_rawget = function(L, idx) { assert(t.ttistable(t), "table expected"); - L.stack[L.top - 1] = t.__index(t, L.stack[L.top - 1]); + L.stack[L.top - 1] = lobject.table_index(t, L.stack[L.top - 1]); return L.stack[L.top - 1].ttnov(); }; // narray and nrec are mostly useless for this implementation const lua_createtable = function(L, narray, nrec) { - let t = new lobject.Table(); + let t = new lobject.TValue(CT.LUA_TTABLE, new Map()); L.stack[L.top++] = t; assert(L.top <= L.ci.top, "stack overflow"); @@ -509,8 +510,8 @@ const lua_getupvalue = function(L, funcindex, n) { let name = up.name; let val = up.val; if (name) - L.stack[L.top++] = new TValue(name.type, name.value); - return name; + L.stack[L.top++] = new TValue(val.type, val.value); + return name.value; }; const lua_setupvalue = function(L, funcindex, n) { @@ -525,7 +526,7 @@ const lua_setupvalue = function(L, funcindex, n) { val.type = L.stack[L.top].type; val.value = L.stack[L.top].value; } - return name; + return name.value; }; const lua_newtable = function(L) { @@ -576,7 +577,7 @@ const lua_getfield = function(L, idx, k) { const lua_geti = function(L, idx, n) { let t = index2addr(L, idx); - let slot = t.__index(t, n); + let slot = lobject.table_index(t, n); if (!slot.ttisnil()) { L.stack[L.top++] = slot; assert(L.top <= L.ci.top, "stack overflow"); @@ -645,7 +646,7 @@ const lua_rawlen = function(L, idx) { case CT.LUA_TUSERDATA: return o.len; case CT.LUA_TTABLE: - return o.luaH_getn(); + return ltable.luaH_getn(o); default: return 0; } @@ -807,7 +808,7 @@ const lua_load = function(L, reader, data, chunckname, mode) { let reg = L.l_G.l_registry; let gt = reg.value.get(lua.LUA_RIDX_GLOBALS); /* set global table as 1st upvalue of 'f' (may be LUA_ENV) */ - f.upvals[0].u.value = gt; + f.upvals[0].u.value = new TValue(gt.type, gt.value); } } return status; @@ -923,7 +924,7 @@ const lua_error = function(L) { const lua_next = function(L, idx) { let t = index2addr(L, idx); assert(t.ttistable(), "table expected"); - let more = t.luaH_next(L, L.top - 1); + let more = ltable.luaH_next(L, t, L.top - 1); if (more) { L.top++; assert(L.top <= L.ci.top, "stack overflow"); diff --git a/src/lbaselib.js b/src/lbaselib.js index af7c3cc..57173b6 100644 --- a/src/lbaselib.js +++ b/src/lbaselib.js @@ -314,7 +314,7 @@ const luaB_load = function(L) { }; const base_funcs = { - "collectgarbage": function () {}, + "collectgarbage": function () { return 0; }, "assert": luaB_assert, "error": luaB_error, "getmetatable": luaB_getmetatable, diff --git a/src/lcode.js b/src/lcode.js index ec233c6..2f95baa 100644 --- a/src/lcode.js +++ b/src/lcode.js @@ -483,7 +483,7 @@ const freeexps = function(fs, e1, e2) { */ const addk = function(fs, key, v) { let f = fs.f; - let idx = fs.ls.h.__index(fs.ls.h, key); /* index scanner table */ + let idx = lobject.table_index(fs.ls.h, key); /* index scanner table */ if (idx && !idx.ttisnil()) { /* is there an index there? */ /* correct value? (warning: must distinguish floats from integers!) */ if (idx.value < fs.nk && f.k[idx.value].ttype() === v.ttype() && f.k[idx.value].value === v.value) @@ -491,7 +491,7 @@ const addk = function(fs, key, v) { } /* constant not found; create a new entry */ let k = fs.nk; - fs.ls.h.__newindex(fs.ls.h, key, new TValue(CT.LUA_TNUMINT, k)); + lobject.table_newindex(fs.ls.h, key, new TValue(CT.LUA_TNUMINT, k)); f.k[k] = v; fs.nk++; return k; diff --git a/src/ldblib.js b/src/ldblib.js index c637af2..a4de832 100644 --- a/src/ldblib.js +++ b/src/ldblib.js @@ -15,7 +15,7 @@ const ldebug = require('./ldebug.js'); */ const checkstack = function(L, L1, n) { if (L !== L1 && !lapi.lua_checkstack(L1, n)) - lauxlib.luaL_error(L, "stack overflow"); + lauxlib.luaL_error(L, lua.to_luastring("stack overflow", true)); }; const db_getregistry = function(L) { diff --git a/src/ldebug.js b/src/ldebug.js index 16449e2..4090011 100644 --- a/src/ldebug.js +++ b/src/ldebug.js @@ -14,7 +14,6 @@ const ltm = require('./ltm.js'); const lfunc = require('./lfunc.js'); const lapi = require('./lapi.js'); const TValue = lobject.TValue; -const Table = lobject.Table; const CT = lua.constant_types; const TS = lua.thread_status; @@ -181,12 +180,12 @@ const collectvalidlines = function(L, f) { assert(L.top <= L.ci.top, "stack overflow"); } else { let lineinfo = f.l.p.lineinfo; - let t = new Table(); + let t = new TValue(CT.LUA_TTABLE, new Map()); L.stack[L.top++] = t; assert(L.top <= L.ci.top, "stack overflow"); let v = new TValue(true, CT.LUA_TBOOLEAN); for (let i = 0; i < f.l.p.length; i++) - t.__newindex(t, lineinfo[i], v); + lobject.table_newindex(t, lineinfo[i], v); } }; @@ -227,7 +227,7 @@ const adjust_varargs = function(L, p, actual) { const tryfuncTM = function(L, off, func) { let tm = ltm.luaT_gettmbyobj(L, func, ltm.TMS.TM_CALL); if (!tm.ttisfunction(tm)) - ldebug.luaG_typeerror(L, func, "call"); + ldebug.luaG_typeerror(L, func, lua.to_luastring("call", true)); /* Open a hole inside the stack at 'func' */ for (let p = L.top; p > off; p--) L.stack[p] = L.stack[p-1]; diff --git a/src/lobject.js b/src/lobject.js index 52ca385..9a79c95 100644 --- a/src/lobject.js +++ b/src/lobject.js @@ -176,53 +176,39 @@ const jsstring = function(value, from, to) { return str; }; -class Table extends TValue { - - constructor(array, hash) { - super(CT.LUA_TTABLE, new Map(hash)); - - this.metatable = null; - } - - static keyValue(key) { - // Those lua values are used by value, others by reference - if (key instanceof TValue) { - if ([CT.LUA_TNIL, - CT.LUA_TBOOLEAN, - CT.LUA_TSTRING, - CT.LUA_TNUMINT].indexOf(key.type) > -1) { - key = key.value; - } else if ([CT.LUA_TSHRSTR, CT.LUA_TLNGSTR].indexOf(key.type) > -1) { - key = key.value.map(e => `${e}|`).join(''); - } - } else if (typeof key === "string") { // To avoid - key = lua.to_luastring(key).map(e => `${e}|`).join(''); - } else if (Array.isArray(key)) { - key = key.map(e => `${e}|`).join(''); +const table_keyValue = function(key) { + // Those lua values are used by value, others by reference + if (key instanceof TValue) { + if ([CT.LUA_TNIL, + CT.LUA_TBOOLEAN, + CT.LUA_TSTRING, + CT.LUA_TNUMINT].indexOf(key.type) > -1) { + key = key.value; + } else if ([CT.LUA_TSHRSTR, CT.LUA_TLNGSTR].indexOf(key.type) > -1) { + key = key.value.map(e => `${e}|`).join(''); } - - return key; + } else if (typeof key === "string") { // To avoid + key = lua.to_luastring(key).map(e => `${e}|`).join(''); + } else if (Array.isArray(key)) { + key = key.map(e => `${e}|`).join(''); } - __newindex(table, key, value) { - key = Table.keyValue(key); - - table.value.set(key, value); - } + return key; +}; - __index(table, key) { - key = Table.keyValue(key); +const table_newindex = function(table, key, value) { + key = table_keyValue(key); - let v = table.value.get(key); + table.value.set(key, value); +}; - return v ? v : luaO_nilobject; - } +const table_index = function(table, key) { + key = table_keyValue(key); - __len(table) { - return this.luaH_getn(); - } + let v = table.value.get(key); -} + return v ? v : luaO_nilobject; +}; class LClosure extends TValue { @@ -237,7 +223,7 @@ class LClosure extends TValue { _ENV.v = null; _ENV.u.open.next = null; _ENV.u.open.touched = true; - _ENV.u.value = new Table(); + _ENV.u.value = new TValue(CT.LUA_TTABLE, new Map()); this.upvals = [ _ENV @@ -570,7 +556,6 @@ module.exports.CClosure = CClosure; module.exports.LClosure = LClosure; module.exports.LocVar = LocVar; module.exports.TValue = TValue; -module.exports.Table = Table; module.exports.UTF8BUFFSZ = UTF8BUFFSZ; module.exports.frexp = frexp; module.exports.intarith = intarith; @@ -583,3 +568,6 @@ module.exports.luaO_str2num = luaO_str2num; module.exports.luaO_utf8desc = luaO_utf8desc; module.exports.luaO_utf8esc = luaO_utf8esc; module.exports.numarith = numarith; +module.exports.table_index = table_index; +module.exports.table_keyValue = table_keyValue; +module.exports.table_newindex = table_newindex; diff --git a/src/loslib.js b/src/loslib.js index 20675a1..a319b3b 100644 --- a/src/loslib.js +++ b/src/loslib.js @@ -33,14 +33,14 @@ const getfield = function(L, key, d, delta) { let res = lapi.lua_tointegerx(L, -1); if (res !== false) { /* field is not an integer? */ if (t != lua.CT.LUA_TNIL) /* some other value? */ - return lauxlib.luaL_error(L, `field '${key}' is not an integer`); + return lauxlib.luaL_error(L, lua.to_luastring(`field '${key}' is not an integer`), true); else if (d < 0) /* absent field; no default? */ - return lauxlib.luaL_error(L, `field '${key}' missing in date table`); + return lauxlib.luaL_error(L, lua.to_luastring(`field '${key}' missing in date table`), true); res = d; } else { if (!(-L_MAXDATEFIELD <= res && res <= L_MAXDATEFIELD)) - return lauxlib.luaL_error(L, `field '${key}' is out-of-bound`); + return lauxlib.luaL_error(L, lua.to_luastring(`field '${key}' is out-of-bound`), true); res -= delta; } lapi.lua_pop(L, 1); diff --git a/src/lparser.js b/src/lparser.js index cf5f55b..a0d671b 100644 --- a/src/lparser.js +++ b/src/lparser.js @@ -14,7 +14,6 @@ const OpCodesI = lopcode.OpCodesI; const Proto = lfunc.Proto; const R = llex.RESERVED; const TValue = lobject.TValue; -const Table = lobject.Table; const UnOpr = lcode.UnOpr; const UpVal = lfunc.UpVal; const char = lua.char; @@ -1342,7 +1341,7 @@ const test_then_block = function(ls, escapelist) { escapelist = lcode.luaK_concat(fs, escapelist, lcode.luaK_jump(fs)); /* must jump over it */ lcode.luaK_patchtohere(fs, jf); - return escapelist + return escapelist; }; const ifstat = function(ls, line) { @@ -1547,7 +1546,7 @@ const luaY_parser = function(L, z, buff, dyd, name, firstchar) { let funcstate = new FuncState(); let cl = lfunc.luaF_newLclosure(L, 1); /* create main closure */ L.stack[L.top++] = cl; - lexstate.h = new Table(); /* create table for scanner */ + lexstate.h = new TValue(lua.CT.LUA_TTABLE, new Map()); /* create table for scanner */ L.stack[L.top++] = lexstate.h; funcstate.f = cl.p = new Proto(L); funcstate.f.source = new TValue(lua.CT.LUA_TLNGSTR, name); diff --git a/src/lstate.js b/src/lstate.js index e18e7aa..d95889b 100644 --- a/src/lstate.js +++ b/src/lstate.js @@ -107,10 +107,10 @@ const stack_init = function(L1, L) { ** Create registry table and its predefined values */ const init_registry = function(L, g) { - let registry = new lobject.Table(); + let registry = new lobject.TValue(CT.LUA_TTABLE, new Map()); g.l_registry = registry; registry.value.set(lua.LUA_RIDX_MAINTHREAD, L); - registry.value.set(lua.LUA_RIDX_GLOBALS, new lobject.Table()); + registry.value.set(lua.LUA_RIDX_GLOBALS, new lobject.TValue(CT.LUA_TTABLE, new Map())); }; /* diff --git a/src/lstrlib.js b/src/lstrlib.js index c2ee817..f8158a8 100644 --- a/src/lstrlib.js +++ b/src/lstrlib.js @@ -81,7 +81,7 @@ const str_dump = function(L) { lauxlib.luaL_checktype(L, 1, CT.LUA_TFUNCTION); lapi.lua_settop(L, 1); if (lapi.lua_dump(L, writer, b, strip) !== 0) - return lauxlib.luaL_error(L, "unable to dump given function"); + return lauxlib.luaL_error(L, lua.to_luastring("unable to dump given function")); lapi.lua_pushstring(L, b); return 1; }; @@ -1392,7 +1392,7 @@ const createmetatable = function(L) { lapi.lua_setmetatable(L, -2); /* set table as metatable for strings */ lapi.lua_pop(L, 1); /* pop dummy string */ lapi.lua_pushvalue(L, -2); /* get string library */ - lapi.lua_setfield(L, -2, lua.to_luastring("__index", true)); /* metatable.__index = string */ + lapi.lua_setfield(L, -2, lua.to_luastring("__index", true)); /* lobject.table_index = string */ lapi.lua_pop(L, 1); /* pop metatable */ }; diff --git a/src/ltable.js b/src/ltable.js index 6ba8236..23ecc11 100644 --- a/src/ltable.js +++ b/src/ltable.js @@ -7,20 +7,19 @@ const lobject = require('./lobject.js'); const lua = require('./lua.js'); const CT = lua.constant_types; const nil = require('./ldo.js').nil; -const Table = lobject.Table; const TValue = lobject.TValue; -Table.prototype.ordered_intindexes = function() { - return [...this.value.keys()] +const ordered_intindexes = function(table) { + return [...table.value.keys()] .filter(e => typeof e === 'number' && e % 1 === 0 && e > 0) // Only integer indexes .sort(function (a, b) { return a > b ? 1 : -1; }); }; -Table.prototype.ordered_indexes = function() { - return [...this.value.keys()] +const ordered_indexes = function(table) { + return [...table.value.keys()] .sort(function(a, b) { if (typeof a !== "number" || a <= 0) return 1; if (typeof b !== "number" || b <= 0) return -1; @@ -32,8 +31,8 @@ Table.prototype.ordered_indexes = function() { ** 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). */ -Table.prototype.luaH_getn = function() { - let indexes = this.ordered_intindexes(); +const luaH_getn = function(table) { + let indexes = ordered_intindexes(table); let len = indexes.length; // If first index != 1, length is 0 @@ -42,8 +41,8 @@ Table.prototype.luaH_getn = function() { for (let i = 0; i < len; i++) { let key = indexes[i]; - if (!this.__index(this, key).ttisnil() // t[key] is non-nil - && (indexes[i + 1] - key > 1 || this.__index(this, indexes[i + 1]).ttisnil())) { // gap with next key or next value is nil + if (!lobject.table_index(table, key).ttisnil() // t[key] is non-nil + && (indexes[i + 1] - key > 1 || lobject.table_index(table, indexes[i + 1]).ttisnil())) { // gap with next key or next value is nil return indexes[i]; } } @@ -51,10 +50,10 @@ Table.prototype.luaH_getn = function() { return 0; }; -Table.prototype.luaH_next = function(L, keyI) { +const luaH_next = function(L, table, keyI) { let keyO = L.stack[keyI]; - let key = Table.keyValue(keyO); - let indexes = this.ordered_indexes(); + let key = lobject.table_keyValue(keyO); + let indexes = ordered_indexes(table); if (indexes.length === 0) return 0; @@ -72,9 +71,12 @@ Table.prototype.luaH_next = function(L, keyI) { else L.stack[keyI] = indexes[i + 1]; - L.stack[keyI + 1] = this.value.get(indexes[i + 1]); + L.stack[keyI + 1] = table.value.get(indexes[i + 1]); return 1; } return 0; }; + +module.exports.luaH_next = luaH_next; +module.exports.luaH_getn = luaH_getn; @@ -5,7 +5,6 @@ const assert = require('assert'); const lobject = require('./lobject.js'); const TValue = lobject.TValue; -const Table = lobject.Table; const ldo = require('./ldo.js'); const lstate = require('./lstate.js'); const lua = require('./lua.js'); @@ -71,7 +70,7 @@ const luaT_init = function(L) { */ const luaT_objtypename = function(L, o) { if ((o.ttistable() && o.metatable !== null) || (o.ttisfulluserdata() && o.metatable !== null)) { - let name = o.__index(o, lua.to_luastring('__name', true)); + let name = lobject.table_index(o, lua.to_luastring('__name', true)); if (name.ttisstring()) return name.jsstring(); } @@ -149,7 +148,7 @@ const luaT_gettmbyobj = function(L, o, event) { mt = L.l_G.mt[o.ttnov()]; } - return mt ? mt.__index(mt, event) : lobject.luaO_nilobject; + return mt ? lobject.table_index(mt, event) : lobject.luaO_nilobject; }; module.exports.TMS = TMS; @@ -11,7 +11,6 @@ const CT = lua.constant_types; const LUA_MULTRET = lua.LUA_MULTRET; const lobject = require('./lobject.js'); const TValue = lobject.TValue; -const Table = lobject.Table; const LClosure = lobject.LClosure; const lfunc = require('./lfunc.js'); const UpVal = lfunc.UpVal; @@ -212,7 +211,7 @@ const luaV_execute = function(L) { break; } case OCi.OP_NEWTABLE: { - L.stack[ra] = new Table(); + L.stack[ra] = new TValue(CT.LUA_TTABLE, new Map()); break; } case OCi.OP_SELF: { @@ -660,7 +659,7 @@ const luaV_execute = function(L) { let last = ((c - 1) * OC.LFIELDS_PER_FLUSH) + n; for (; n > 0; n--) { - table.__newindex(table, last--, L.stack[ra + n]); + lobject.table_newindex(table, last--, L.stack[ra + n]); } L.top = ci.top; /* correct top (in case of previous open call) */ @@ -799,7 +798,7 @@ const luaV_equalobj = function(L, t1, t2) { case CT.LUA_TLIGHTUSERDATA: case CT.LUA_TUSERDATA: case CT.LUA_TTABLE: - if (t1 === t2) return 1; + if (t1.value === t2.value) return 1; else if (L === null) return 0; // TODO: fasttm ? @@ -978,7 +977,7 @@ const luaV_objlen = function(L, ra, rb) { case CT.LUA_TTABLE: { tm = ltm.luaT_gettmbyobj(L, rb, ltm.TMS.TM_LEN); if (!tm.ttisnil()) break; - L.stack[ra] = new TValue(CT.LUA_TNUMINT, rb.luaH_getn()); + L.stack[ra] = new TValue(CT.LUA_TNUMINT, ltable.luaH_getn(rb)); return; } case CT.LUA_TSHRSTR: @@ -1056,7 +1055,7 @@ const gettable = function(L, table, key, ra, recur) { ldebug.luaG_runerror(L, lua.to_luastring("'__index' chain too long; possible loop", true)); if (table.ttistable()) { - let element = table.__index(table, key); + let element = lobject.table_index(table, key); if (!element.ttisnil()) { L.stack[ra] = element; @@ -1099,10 +1098,10 @@ const settable = function(L, table, key, v, recur) { ldebug.luaG_runerror(L, lua.to_luastring("'__newindex' chain too long; possible loop", true)); if (table.ttistable()) { - let element = table.__index(table, key); + let element = lobject.table_index(table, key); if (!element.ttisnil()) { - table.__newindex(table, key, v); + lobject.table_newindex(table, key, v); } else { luaV_finishset(L, table, key, v, element, recur); } @@ -1117,7 +1116,7 @@ const luaV_finishset = function(L, t, key, val, slot, recur) { assert(slot.ttisnil()); tm = ltm.luaT_gettmbyobj(L, t, ltm.TMS.TM_NEWINDEX); // TODO: fasttm if (tm.ttisnil()) { - t.__newindex(t, key, val); + lobject.table_newindex(t, key, val); return; } } else { /* not a table; check metamethod */ |