From cdf8cf1806ca793c47095b69382b2dd733899af7 Mon Sep 17 00:00:00 2001 From: Benoit Giannangeli Date: Fri, 17 Feb 2017 12:25:28 +0100 Subject: lua can read globals set by js --- README.md | 8 ++++---- src/lapi.js | 33 ++++++++++++++++++++++++++++++--- src/lvm.js | 3 ++- tests/lapi.js | 30 ++++++++++++++++++++++++++++++ 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 -- cgit v1.2.3-70-g09d2