aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--README.md8
-rw-r--r--src/lapi.js33
-rw-r--r--src/lvm.js3
-rw-r--r--tests/lapi.js30
4 files changed, 66 insertions, 8 deletions
diff --git a/README.md b/README.md
index e79a6a8..6bade18 100644
--- a/README.md
+++ b/README.md
@@ -21,6 +21,7 @@
- [ ] `__tostring`
- [ ] `__pairs`
- [ ] C API
+ - [x] lua_version
- [x] lua_atpanic
- [x] lua_newstate
- [x] lua_pushnil
@@ -30,6 +31,7 @@
- [x] lua_pushboolean
- [x] lua_pushinteger
- [x] lua_pushnumber
+ - [x] lua_pushlstring
- [x] lua_pushstring
- [x] lua_pushvalue
- [x] lua_tointeger
@@ -44,6 +46,8 @@
- [x] lua_load
- [x] lua_call
- [x] lua_callk
+ - [x] lua_setglobal
+ - [x] lua_upvalueindex
- [ ] lua_absindex
- [ ] lua_arith
- [ ] lua_checkstack
@@ -97,7 +101,6 @@
- [ ] lua_pushglobaltable
- [ ] lua_pushlightuserdata
- [ ] lua_pushliteral
- - [ ] lua_pushlstring
- [ ] lua_pushthread
- [ ] lua_pushvfstring
- [ ] lua_rawequal
@@ -115,7 +118,6 @@
- [ ] lua_rotate
- [ ] lua_setallocf
- [ ] lua_setfield
- - [ ] lua_setglobal
- [ ] lua_sethook
- [ ] lua_seti
- [ ] lua_setlocal
@@ -132,9 +134,7 @@
- [ ] lua_tothread
- [ ] lua_touserdata
- [ ] lua_upvalueid
- - [ ] lua_upvalueindex
- [ ] lua_upvaluejoin
- - [ ] lua_version
- [ ] lua_xmove
- [ ] lua_yield
- [ ] lua_yieldk
diff --git a/src/lapi.js b/src/lapi.js
index 6cc95b2..6a88f6f 100644
--- a/src/lapi.js
+++ b/src/lapi.js
@@ -50,7 +50,6 @@ const index2addr = function(L, idx) {
return idx <= ci.func.nupvalues ? ci.func.upvalue[idx - 1] : ldo.nil;
}
}
-
};
/*
@@ -190,6 +189,33 @@ const lua_pushlightuserdata = function(L, p) {
assert(L.top <= L.ci.top, "stack overflow");
};
+/*
+** set functions (stack -> Lua)
+*/
+
+/*
+** t[k] = value at the top of the stack (where 'k' is a string)
+*/
+const auxsetstr = function(L, t, k) {
+ let str = new TValue(CT.LUA_TLNGSTR, k);
+
+ assert(1 < L.top - L.ci.funcOff, "not enough elements in the stack");
+
+ if (t.ttistable() && !t.__index(t, k).ttisnil()) {
+ 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.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);
+};
+
/*
** access functions (stack -> JS)
@@ -251,7 +277,7 @@ const lua_load = function(L, data, chunckname) {
let reg = L.l_G.l_registry;
let gt = reg.value.array[lua.LUA_RIDX_GLOBALS];
/* set global table as 1st upvalue of 'f' (may be LUA_ENV) */
- f.upvals[0].v = gt; // TODO: is gt on the stack ? is that upvalue opened or closed ?
+ f.upvals[0].u.value = gt;
}
}
@@ -354,4 +380,5 @@ module.exports.lua_tostring = lua_tostring;
module.exports.lua_load = lua_load;
module.exports.lua_callk = lua_callk;
module.exports.lua_call = lua_call;
-module.exports.lua_pop = lua_pop; \ No newline at end of file
+module.exports.lua_pop = lua_pop;
+module.exports.lua_setglobal = lua_setglobal; \ No newline at end of file
diff --git a/src/lvm.js b/src/lvm.js
index 931b7a5..4f52678 100644
--- a/src/lvm.js
+++ b/src/lvm.js
@@ -1033,4 +1033,5 @@ module.exports.LEnum = LEnum;
module.exports.LEintfloat = LEintfloat;
module.exports.LTintfloat = LTintfloat;
module.exports.l_strcmp = l_strcmp;
-module.exports.luaV_objlen = luaV_objlen; \ No newline at end of file
+module.exports.luaV_objlen = luaV_objlen;
+module.exports.luaV_finishset = luaV_finishset; \ No newline at end of file
diff --git a/tests/lapi.js b/tests/lapi.js
index ff76920..419e5c4 100644
--- a/tests/lapi.js
+++ b/tests/lapi.js
@@ -408,4 +408,34 @@ test('lua_load and lua_call it', function (t) {
"JS > Lua > JS \o/",
"Correct element(s) on the stack"
);
+});
+
+
+test('lua script reads js upvalues', function (t) {
+ let luaCode = `
+ return js .. " world"
+ `, L;
+
+ t.plan(2);
+
+ t.doesNotThrow(function () {
+
+ let bc = toByteCode(luaCode).dataView;
+
+ L = lauxlib.luaL_newstate();
+
+ lapi.lua_load(L, bc, "test-lua_load")
+
+ lapi.lua_pushstring(L, "hello");
+ lapi.lua_setglobal(L, "js");
+
+ lapi.lua_call(L, 0, 1);
+
+ }, "JS Lua program ran without error");
+
+ t.strictEqual(
+ lapi.lua_tostring(L, -1),
+ "hello world",
+ "Correct element(s) on the stack"
+ );
}); \ No newline at end of file