aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authordaurnimator <quae@daurnimator.com>2017-04-27 15:41:16 +1000
committerBenoit Giannangeli <giann008@gmail.com>2017-04-28 14:15:58 +0200
commit4cd7e4062219ccffbbc9e397e1ab599c26a3ae76 (patch)
tree9902acf8475e45cf7313bccbdf35eb54a4c51a93
parent6527126b549870eb1767dfc74e41d8e8eb7b62b5 (diff)
downloadfengari-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.js28
-rw-r--r--src/ltm.js2
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");
diff --git a/src/ltm.js b/src/ltm.js
index 8687eb0..c94d8f1 100644
--- a/src/ltm.js
+++ b/src/ltm.js
@@ -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;