summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--README.md6
-rw-r--r--src/lapi.js21
-rw-r--r--src/ldblib.js13
-rw-r--r--tests/ldblib.js45
4 files changed, 78 insertions, 7 deletions
diff --git a/README.md b/README.md
index 47c80bf..e32f8f5 100644
--- a/README.md
+++ b/README.md
@@ -34,7 +34,6 @@
- [ ] lua_getstack
- [ ] lua_getupvalue
- [ ] lua_isboolean
- - [ ] lua_iscfunction
- [ ] lua_islightuserdata
- [ ] lua_isuserdata
- [ ] lua_pcallk
@@ -48,7 +47,6 @@
- [ ] lua_setallocf
- [ ] lua_sethook
- [ ] lua_tocfunction
- - [ ] lua_upvaluejoin
- [ ] Auxiliary library
- [x] ...
- [ ] luaL_addsize
@@ -94,10 +92,10 @@
- [x] debug.setupvalue
- [x] debug.setuservalue
- [x] debug.traceback
+ - [x] debug.upvalueid
+ - [x] debug.upvaluejoin
- [ ] debug.gethook
- [ ] debug.sethook
- - [ ] debug.upvalueid
- - [ ] debug.upvaluejoin
- [ ] Run [Lua test suite](https://github.com/lua/tests)
- [ ] DOM API binding
diff --git a/src/lapi.js b/src/lapi.js
index b41cfbe..caafc0a 100644
--- a/src/lapi.js
+++ b/src/lapi.js
@@ -719,6 +719,11 @@ const lua_typename = function(L, t) {
return ltm.ttypename(t);
};
+const lua_iscfunction = function(L, idx) {
+ let o = index2addr(L, idx);
+ return o.ttislcf(o) || o.ttisCclosure();
+};
+
const lua_isnil = function(L, n) {
return lua_type(L, n) === CT.LUA_TNIL;
};
@@ -933,7 +938,8 @@ const getupvalref = function(L, fidx, n, pf) {
assert(1 <= n && n <= f.p.upvalues.length, "invalid upvalue index");
return {
closure: f,
- upval: f.upvals[n - 1]
+ upval: f.upvals[n - 1],
+ upvalOff: n - 1
};
};
@@ -955,6 +961,17 @@ const lua_upvalueid = function(L, fidx, n) {
}
};
+const lua_upvaluejoin = function(L, fidx1, n1, fidx2, n2) {
+ let ref1 = getupvalref(L, fidx1, n1);
+ let ref2 = getupvalref(L, fidx2, n2);
+ let up1 = ref1.upvalOff;
+ let up2 = ref2.upval;
+ let f1 = ref1.closure;
+
+ f1.upvals[up1] = up2;
+ up2.u.open.touched = true; // TODO: useful
+};
+
// This functions are only there for compatibility purposes
const lua_gc = function () {};
@@ -993,6 +1010,7 @@ module.exports.lua_gettop = lua_gettop;
module.exports.lua_getupvalue = lua_getupvalue;
module.exports.lua_getuservalue = lua_getuservalue;
module.exports.lua_insert = lua_insert;
+module.exports.lua_iscfunction = lua_iscfunction;
module.exports.lua_isfunction = lua_isfunction;
module.exports.lua_isinteger = lua_isinteger;
module.exports.lua_isnil = lua_isnil;
@@ -1061,5 +1079,6 @@ module.exports.lua_touserdata = lua_touserdata;
module.exports.lua_type = lua_type;
module.exports.lua_typename = lua_typename;
module.exports.lua_upvalueid = lua_upvalueid;
+module.exports.lua_upvaluejoin = lua_upvaluejoin;
module.exports.lua_version = lua_version;
module.exports.lua_xmove = lua_xmove;
diff --git a/src/ldblib.js b/src/ldblib.js
index 9fc6ce6..27aca96 100644
--- a/src/ldblib.js
+++ b/src/ldblib.js
@@ -248,13 +248,21 @@ const checkupval = function(L, argf, argnup) {
return nup;
};
-
const db_upvalueid = function(L) {
let n = checkupval(L, 1, 2);
lapi.lua_pushlightuserdata(L, lapi.lua_upvalueid(L, 1, n));
return 1;
};
+const db_upvaluejoin = function(L) {
+ let n1 = checkupval(L, 1, 2);
+ let n2 = checkupval(L, 3, 4);
+ lauxlib.luaL_argcheck(L, !lapi.lua_iscfunction(L, 1), 1, lua.to_luastring("Lua function expected"));
+ lauxlib.luaL_argcheck(L, !lapi.lua_iscfunction(L, 3), 3, lua.to_luastring("Lua function expected"));
+ lapi.lua_upvaluejoin(L, 1, n1, 3, n2);
+ return 0;
+};
+
const db_traceback = function(L) {
let thread = getthread(L);
let L1 = thread.thread;
@@ -281,7 +289,8 @@ const dblib = {
"setupvalue": db_setupvalue,
"setuservalue": db_setuservalue,
"traceback": db_traceback,
- "upvalueid": db_upvalueid
+ "upvalueid": db_upvalueid,
+ "upvaluejoin": db_upvaluejoin
};
// Only with Node
diff --git a/tests/ldblib.js b/tests/ldblib.js
index 30a3eb6..7dd35c3 100644
--- a/tests/ldblib.js
+++ b/tests/ldblib.js
@@ -157,6 +157,51 @@ test('debug.upvalueid', function (t) {
});
+test('debug.upvaluejoin', function (t) {
+ let luaCode = `
+ local upvalue1 = "upvalue1"
+ local upvalue2 = "upvalue2"
+
+ local l1 = function()
+ return upvalue1
+ end
+
+ local l2 = function()
+ return upvalue2
+ end
+
+ debug.upvaluejoin(l1, 1, l2, 1)
+
+ return l1()
+ `, L;
+
+ t.plan(3);
+
+ t.doesNotThrow(function () {
+
+ L = lauxlib.luaL_newstate();
+
+ linit.luaL_openlibs(L);
+
+ lauxlib.luaL_loadstring(L, lua.to_luastring(luaCode));
+
+ }, "Lua program loaded without error");
+
+ t.doesNotThrow(function () {
+
+ lapi.lua_call(L, 0, -1);
+
+ }, "Lua program ran without error");
+
+ t.strictEqual(
+ lapi.lua_tojsstring(L, -1),
+ "upvalue2",
+ "Correct element(s) on the stack"
+ );
+
+});
+
+
test('debug.traceback (with a global)', function (t) {
let luaCode = `
local trace