diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/lapi.js | 72 | ||||
| -rw-r--r-- | src/lauxlib.js | 18 | ||||
| -rw-r--r-- | src/lbaselib.js | 6 | ||||
| -rw-r--r-- | src/linit.js | 6 | ||||
| -rw-r--r-- | src/lstate.js | 4 | 
5 files changed, 80 insertions, 26 deletions
diff --git a/src/lapi.js b/src/lapi.js index b5a8fab..dc8ca68 100644 --- a/src/lapi.js +++ b/src/lapi.js @@ -65,9 +65,9 @@ const lua_checkstack = function(L, n) {  ** convert an acceptable stack index into an absolute index  */  const lua_absindex = function(L, idx) { -    return (idx > 0 || idx > lua.LUA_REGISTRYINDEX) +    return (idx > 0 || idx <= lua.LUA_REGISTRYINDEX)           ? idx -         : L.top - L.ci.funcOff + idx; +         : (L.top - L.ci.funcOff) + idx;  };  const lua_gettop = function(L) { @@ -113,14 +113,14 @@ const lua_rotate = function(L, idx, n) {      let t = L.stack[L.top - 1];      let p = index2addr(L, idx); -    assert(!p.ttisnil() && idx > LUA_REGISTRYINDEX, "index not in the stack"); +    assert(!p.ttisnil() && idx > lua.LUA_REGISTRYINDEX, "index not in the stack");      assert((n >= 0 ? n : -n) <= (L.top - idx), "invalid 'n'"); -    let m = n >= 0 ? L.top - 1 - n : idx - n - 1;  /* end of prefix */ +    let m = n >= 0 ? L.top - 1 - n : L.top + idx - n - 1;  /* end of prefix */ -    reverse(L, idx, m); +    reverse(L, L.top + idx, m);      reverse(L, m + 1, L.top - 1); -    reverse(L, idx, L.top - 1); +    reverse(L, L.top + idx, L.top - 1);  };  const lua_remove = function(L, idx) { @@ -250,15 +250,14 @@ const auxsetstr = function(L, t, k) {          t.__newindex(t, k, L.stack[L.top - 1]);          L.top--; /* pop value */      } else { -        L.stack[L.top] = str; -        L.top++; -        lvm.luaV_finishset(L, t, L.stack[L.top - 1], L.stack[L.top - 2], t.__index(t, k), 0); +        L.stack[L.top++] = str; +        lvm.settable(L, t, L.stack[L.top - 1], L.stack[L.top - 2]);          L.top -= 2; /* pop value and key */      }  };  const lua_setglobal = function(L, name) { -    auxsetstr(L, L.l_G.l_registry.value.array[lua.LUA_RIDX_GLOBALS], name); +    auxsetstr(L, L.l_G.l_registry.value.array[lua.LUA_RIDX_GLOBALS - 1], name);  };  const lua_settable = function(L, idx) { @@ -277,6 +276,21 @@ const lua_setfield = function(L, idx, k) {  ** get functions (Lua -> stack)  */ +const auxgetstr = function(L, t, k) { +    let str = new TValue(CT.LUA_TLNGSTR, k); +    let slot = t.__index(t, k); +    if (t.ttistable() && !slot.ttisnil()) { +        L.stack[L.top++] = slot; +        assert(L.top <= L.ci.top, "stack overflow"); +    } else { +        L.stack[L.top++] = str; +        assert(L.top <= L.ci.top, "stack overflow"); +        lvm.gettable(L, t, L.stack[L.top - 1], L.top - 1); +    } + +    return L.stack[L.top - 1].ttnov(); +}; +  const lua_rawgeti = function(L, idx, n) {      let t = index2addr(L, idx); @@ -314,12 +328,43 @@ const lua_newtable = function(L) {      lua_createtable(L, 0, 0);  }; +const lua_getmetatable = function(L, objindex) { +    let obj = index2addr(L, objindex); +    let mt; +    let res = false; +    switch (obj.ttnov()) { +        case CT.LUA_TTABLE: +        case CT.LUA_TUSERDATA: +            mt = obj.metatable; +            break; +        default: +            mt = L.l_G.mt[obj.ttnov]; +            break; +    } + +    if (mt !== null && mt !== undefined) { +        L.stack[L.top++] = mt; +        assert(L.top <= L.ci.top, "stack overflow"); +        res = true; +    } + +    return res; +}; +  const lua_gettable = function(L, idx) {      let t = index2addr(L, idx);      lvm.gettable(L, t, L.stack[L.top - 1], L.top - 1);      return L.stack[L.top - 1].ttnov();  }; +const lua_getfield = function(L, idx, k) { +    return auxgetstr(L, index2addr(L, idx), k); +}; + +const lua_getglobal = function(L, name) { +    return auxgetstr(L, L.l_G.l_registry.value.array[lua.LUA_RIDX_GLOBALS - 1], name); +}; +  /*  ** access functions (stack -> JS)  */ @@ -386,7 +431,7 @@ const lua_load = function(L, data, chunckname) {          if (f.nupvalues >= 1) { /* does it have an upvalue? */              /* get global table from registry */              let reg = L.l_G.l_registry; -            let gt = reg.value.array[lua.LUA_RIDX_GLOBALS]; +            let gt = reg.value.array[lua.LUA_RIDX_GLOBALS - 1];              /* set global table as 1st upvalue of 'f' (may be LUA_ENV) */              f.upvals[0].u.value = gt;          } @@ -514,4 +559,7 @@ module.exports.lua_remove          = lua_remove;  module.exports.lua_checkstack      = lua_checkstack;  module.exports.lua_rawgeti         = lua_rawgeti;  module.exports.lua_pushglobaltable = lua_pushglobaltable; -module.exports.lua_setfield        = lua_setfield;
\ No newline at end of file +module.exports.lua_setfield        = lua_setfield; +module.exports.lua_getfield        = lua_getfield; +module.exports.lua_getglobal       = lua_getglobal; +module.exports.lua_getmetatable    = lua_getmetatable;
\ No newline at end of file diff --git a/src/lauxlib.js b/src/lauxlib.js index af09df7..6db0aae 100644 --- a/src/lauxlib.js +++ b/src/lauxlib.js @@ -8,6 +8,8 @@ const lapi   = require('./lapi.js');  const lua    = require('./lua.js');  const CT     = lua.constant_types; +const LUA_LOADED_TABLE = "_LOADED" +  const panic = function(L) {      console.log(`PANIC: unprotected error in call to Lua API (...)`);      return 0; @@ -86,7 +88,7 @@ const luaL_tolstring = function(L, idx, len) {  ** Leaves resulting module on the top.  */  const luaL_requiref = function(L, modname, openf, glb) { -    luaL_getsubtable(L, lua.LUA_REGISTRYINDEX, lua.LUA_LOADED_TABLE); +    luaL_getsubtable(L, lua.LUA_REGISTRYINDEX, LUA_LOADED_TABLE);      lapi.lua_getfield(L, -1, modname); /* LOADED[modname] */      if (!lapi.lua_toboolean(L, -1)) {  /* package not already loaded? */          lapi.lua_pop(L, 1);  /* remove field */ @@ -98,8 +100,8 @@ const luaL_requiref = function(L, modname, openf, glb) {      }      lapi.lua_remove(L, -2);  /* remove LOADED table */      if (glb) { -        lua_pushvalue(L, -1);  /* copy of module */ -        lua_setglobal(L, modname);  /* _G[modname] = module */ +        lapi.lua_pushvalue(L, -1);  /* copy of module */ +        lapi.lua_setglobal(L, modname);  /* _G[modname] = module */      }  }; @@ -127,13 +129,13 @@ const luaL_getsubtable = function(L, idx, fname) {  */  const luaL_setfuncs = function(L, l, nup) {      luaL_checkstack(L, nup, "too many upvalues"); -    for (lib in l) {  /* fill the table with given functions */ +    for (let lib in l) {  /* fill the table with given functions */          for (let i = 0; i < nup; i++)  /* copy upvalues to the top */              lapi.lua_pushvalue(L, -nup);          lapi.lua_pushcclosure(L, l[lib], nup);  /* closure with those upvalues */          lapi.lua_setfield(L, -(nup + 2), lib);      } -    lapi.lua_pop(l, nup);  /* remove upvalues */ +    lapi.lua_pop(L, nup);  /* remove upvalues */  };  /* @@ -144,7 +146,7 @@ const luaL_setfuncs = function(L, l, nup) {  ** but without 'msg'.)  */  const luaL_checkstack = function(L, space, msg) { -    if (!lapi.luaL_checkstack(L, space)) { +    if (!lapi.lua_checkstack(L, space)) {          if (msg)              throw new Error(L, `stack overflow (${msg})`);          else @@ -160,4 +162,6 @@ module.exports.luaL_getmetafield = luaL_getmetafield;  module.exports.luaL_requiref     = luaL_requiref;  module.exports.luaL_getsubtable  = luaL_getsubtable;  module.exports.luaL_setfuncs     = luaL_setfuncs; -module.exports.luaL_checkstack   = luaL_checkstack;
\ No newline at end of file +module.exports.luaL_checkstack   = luaL_checkstack; +module.exports.LUA_LOADED_TABLE  = LUA_LOADED_TABLE; +module.exports.luaL_tolstring    = luaL_tolstring;
\ No newline at end of file diff --git a/src/lbaselib.js b/src/lbaselib.js index d28a3d5..b046f67 100644 --- a/src/lbaselib.js +++ b/src/lbaselib.js @@ -3,6 +3,7 @@  const assert  = require('assert'); +const lua     = require('./lua.js');  const lapi    = require('./lapi.js');  const lauxlib = require('./lauxlib.js'); @@ -15,7 +16,7 @@ const luaB_print = function(L) {          lapi.lua_pushvalue(L, -1);  /* function to be called */          lapi.lua_pushvalue(L, i);  /* value to print */          lapi.lua_call(L, 1, 1); -        s = lapi.lua_tolstring(L, -1, null); +        let s = lapi.lua_tolstring(L, -1, null);          if (s === null)              throw new Error("'tostring' must return a string to 'print");          if (i > 1) s = `\t${s}`; @@ -53,4 +54,5 @@ const luaopen_base = function(L) {  };  module.exports.luaB_tostring = luaB_tostring; -module.exports.luaB_print = luaB_print; +module.exports.luaB_print    = luaB_print; +module.exports.luaopen_base  = luaopen_base; diff --git a/src/linit.js b/src/linit.js index 2747fc2..fc2a54d 100644 --- a/src/linit.js +++ b/src/linit.js @@ -8,15 +8,15 @@ const lauxlib  = require('./lauxlib.js');  const lbaselib = require('./lbaselib.js');  const loadedlibs = { -    "_G" = luaopen_base +    "_G": lbaselib.luaopen_base  };  const luaL_openlibs = function(L) {      /* "require" functions from 'loadedlibs' and set results to global table */ -    for (lib in loadedlibs) { +    for (let lib in loadedlibs) {          lauxlib.luaL_requiref(L, lib, loadedlibs[lib], 1);          lapi.lua_pop(L, 1); /* remove lib */      } -} +};  module.exports.luaL_openlibs = luaL_openlibs;
\ No newline at end of file diff --git a/src/lstate.js b/src/lstate.js index 54e7ac7..30e4b15 100644 --- a/src/lstate.js +++ b/src/lstate.js @@ -96,8 +96,8 @@ const stack_init = function(L1, L) {  const init_registry = function(L, g) {      let registry = new Table();      g.l_registry = registry; -    registry.value.array[lua.LUA_RIDX_MAINTHREAD] = L; -    registry.value.array[lua.LUA_RIDX_GLOBALS] = new Table(); +    registry.value.array[lua.LUA_RIDX_MAINTHREAD - 1] = L; +    registry.value.array[lua.LUA_RIDX_GLOBALS - 1] = new Table();  };  /*  | 
