diff options
author | daurnimator <quae@daurnimator.com> | 2017-04-27 15:41:16 +1000 |
---|---|---|
committer | Benoit Giannangeli <giann008@gmail.com> | 2017-04-28 14:15:58 +0200 |
commit | 4cd7e4062219ccffbbc9e397e1ab599c26a3ae76 (patch) | |
tree | 9902acf8475e45cf7313bccbdf35eb54a4c51a93 | |
parent | 6527126b549870eb1767dfc74e41d8e8eb7b62b5 (diff) | |
download | fengari-4cd7e4062219ccffbbc9e397e1ab599c26a3ae76.tar.gz fengari-4cd7e4062219ccffbbc9e397e1ab599c26a3ae76.tar.bz2 fengari-4cd7e4062219ccffbbc9e397e1ab599c26a3ae76.zip |
Userdata needs to be boxed so it can have uservalue+metatable
metatable should not be on the TValue
-rw-r--r-- | src/lapi.js | 28 | ||||
-rw-r--r-- | src/ltm.js | 2 |
2 files changed, 18 insertions, 12 deletions
diff --git a/src/lapi.js b/src/lapi.js index 4b5223a..9c01e95 100644 --- a/src/lapi.js +++ b/src/lapi.js @@ -466,15 +466,22 @@ const lua_createtable = function(L, narray, nrec) { assert(L.top <= L.ci.top, "stack overflow"); }; -// ignore size argument -const lua_newuserdata = function(L, size) { - let box = Object.create(null); +const luaS_newudata = function(L, size) { + return { + metatable: null, + uservalue: null, + len: size, + data: Object.create(null) // ignores size argument + }; +}; - L.stack[L.top++] = new lobject.TValue(CT.LUA_TUSERDATA, box); +const lua_newuserdata = function(L, size) { + let u = luaS_newudata(L, size); + L.stack[L.top++] = new lobject.TValue(CT.LUA_TUSERDATA, u); assert(L.top <= L.ci.top, "stack overflow"); - return box; + return u.data; }; const aux_upvalue = function(L, fi, n) { @@ -562,8 +569,8 @@ const lua_getmetatable = function(L, objindex) { const lua_getuservalue = function(L, idx) { let o = index2addr(L, idx); assert(L, o.ttisfulluserdata(), "full userdata expected"); - L.stack[L.top].type = o.type; - L.stack[L.top++].value = o.value; + let uv = o.uservalue; + L.stack[L.top++] = new TValue(uv.type, uv.value); assert(L.top <= L.ci.top, "stack overflow"); return L.stack[L.top - 1].ttnov(); }; @@ -667,6 +674,7 @@ const lua_touserdata = function(L, idx) { let o = index2addr(L, idx); switch (o.ttnov()) { case CT.LUA_TUSERDATA: + return o.value.data; case CT.LUA_TLIGHTUSERDATA: return o.value; default: return null; @@ -832,12 +840,10 @@ const lua_setuservalue = function(L, idx) { assert(1 < L.top - L.ci.funcOff, "not enough elements in the stack"); let o = index2addr(L, idx); assert(L, o.ttisfulluserdata(), "full userdata expected"); - L.stack[L.top - 1].type = o.type; - L.stack[L.top - 1].value = o.value; - L.top--; + o.uservalue.setfrom(L.stack[L.top - 1]); + L.stack[--L.top] = void 0; }; - const lua_callk = function(L, nargs, nresults, ctx, k) { assert(k === null || !(L.ci.callstatus & lstate.CIST_LUA), "cannot use continuations inside hooks"); assert(nargs + 1 < L.top - L.ci.funcOff, "not enough elements in the stack"); @@ -70,7 +70,7 @@ const luaT_init = function(L) { const luaT_objtypename = function(L, o) { let mt; if ((o.ttistable() && (mt = o.metatable) !== null) || - (o.ttisfulluserdata() && (mt = o.metatable) !== null)) { + (o.ttisfulluserdata() && (mt = o.value.metatable) !== null)) { let name = lobject.table_index(mt, defs.to_luastring('__name', true)); if (name.ttisstring()) return name.value; |