/*jshint esversion: 6 */ "use strict"; const assert = require('assert'); const defs = require('./defs.js'); const ldebug = require('./ldebug.js'); const lobject = require('./lobject.js'); const lstring = require('./lstring.js'); const CT = defs.constant_types; const table_hash = function(key) { switch(key.type) { case CT.LUA_TBOOLEAN: case CT.LUA_TLIGHTUSERDATA: /* XXX: if user pushes conflicting lightuserdata then the table will do odd things */ case CT.LUA_TNUMFLT: case CT.LUA_TNUMINT: case CT.LUA_TTABLE: case CT.LUA_TLCL: case CT.LUA_TLCF: case CT.LUA_TCCL: case CT.LUA_TUSERDATA: case CT.LUA_TTHREAD: return key.value; case CT.LUA_TSHRSTR: case CT.LUA_TLNGSTR: return lstring.luaS_hashlongstr(key.tsvalue()); default: throw new Error("unknown key type: " + key.type); } }; class Table { constructor(L) { this.id = L.l_G.id_counter++; this.strong = new Map(); this.dead_hashes = []; this.metatable = null; } } const clean_dead_keys = function(t) { for (let i=0; i 1) { let m = Math.floor((i+j)/2); if (luaH_getint(t, m).ttisnil()) j = m; else i = m; } return i; }; /* ** Javascript tables don't have any next-like primitive. ** For each call of `next` this does a full iteration up to the item */ const luaH_next = function(L, table, keyI) { let keyO = L.stack[keyI]; let iterresult; if (keyO.type === CT.LUA_TNIL) { iterresult = table.strong.keys().next(); } else { let hash = table_hash(keyO); if (!table.strong.has(hash)) /* item not in table */ return ldebug.luaG_runerror(L, "invalid key to 'next'"); let indexes = table.strong.keys(); while (1) { let e = indexes.next(); if (e.done) throw "unreachable"; else if (e.value == hash) break; } iterresult = indexes.next(); } if (iterresult.done) return false; let entry = table.strong.get(iterresult.value); L.stack[keyI] = new lobject.TValue(entry.key.type, entry.key.value); L.stack[keyI+1] = new lobject.TValue(entry.value.type, entry.value.value); return true; }; module.exports.luaH_delete = luaH_delete; module.exports.luaH_get = luaH_get; module.exports.luaH_getint = luaH_getint; module.exports.luaH_getn = luaH_getn; module.exports.luaH_getstr = luaH_getstr; module.exports.luaH_set = luaH_set; module.exports.luaH_setint = luaH_setint; module.exports.luaH_new = luaH_new; module.exports.luaH_next = luaH_next;