From be0757bcfc96dc6146d72e9536fa8e32d9a3dec7 Mon Sep 17 00:00:00 2001 From: Benoit Giannangeli Date: Thu, 16 Feb 2017 21:29:06 +0100 Subject: lua_pop, lua_settop, js closure --- src/lapi.js | 27 +++++++++++++++++++++------ src/lua.js | 36 ------------------------------------ tests/C/Makefile | 3 ++- tests/C/lua_call-jsclosure.c | 30 ++++++++++++++++++++++++++++++ 4 files changed, 53 insertions(+), 43 deletions(-) create mode 100644 tests/C/lua_call-jsclosure.c diff --git a/src/lapi.js b/src/lapi.js index 99955a3..41c0fbb 100644 --- a/src/lapi.js +++ b/src/lapi.js @@ -10,7 +10,6 @@ const lfunc = require('./lfunc.js'); const lua = require('./lua.js'); const lstate = require('./lstate.js'); const lvm = require('./lvm.js'); -const nil = ldo.nil; const MAXUPVAL = lfunc.MAXUPVAL; const CT = lua.constant_types; const TS = lua.thread_status; @@ -34,7 +33,7 @@ const index2addr = function(L, idx) { if (idx > 0) { let o = ci.funcOff + idx; assert(idx <= ci.top - (ci.funcOff + 1), "unacceptable index"); - if (o >= L.top) return nil; + if (o >= L.top) return ldo.nil; else return L.stack[o]; } else if (idx < 0) { // TODO: pseudo-indices relative to LUA_REGISTRYINDEX assert(idx !== 0 && -idx <= L.top, "invalid index"); @@ -44,9 +43,9 @@ const index2addr = function(L, idx) { idx = -idx; assert(idx <= MAXUPVAL + 1, "upvalue index too large"); if (ci.func.ttislcf()) /* light C function? */ - return nil; /* it has no upvalues */ + return ldo.nil; /* it has no upvalues */ else { - return idx <= ci.func.nupvalues ? ci.func.upvalue[idx - 1] : nil; + return idx <= ci.func.nupvalues ? ci.func.upvalue[idx - 1] : ldo.nil; } } @@ -67,12 +66,28 @@ const lua_pushvalue = function(L, idx) { assert(L.top <= L.ci.top, "stack overflow"); }; +const lua_settop = function(L, idx) { + let func = L.ci.funcOff; + if (idx >= 0) { + while (L.top < func + 1 + idx) + L.stack[L.top++] = ldo.nil; + L.top = func + 1 + idx; + } else { + assert(-(idx + 1) <= L.top - (func + 1), "invalid new top"); + L.top += idx + 1; /* 'subtract' index (index is negative) */ + } +}; + +const lua_pop = function(L, n) { + lua_settop(L, -n - 1); +} + /* ** push functions (JS -> stack) */ const lua_pushnil = function(L) { - L.stack[L.top] = nil; + L.stack[L.top] = ldo.nil; L.top++; assert(L.top <= L.ci.top, "stack overflow"); @@ -112,7 +127,7 @@ const lua_pushlstring = function(L, s, len) { // TODO: embedded \0 const lua_pushstring = function (L, s) { assert(typeof s === "string"); if (!s) - L.stack[L.top] = nil; + L.stack[L.top] = ldo.nil; else { let ts = new TValue(CT.LUA_TLNGSTR, s); L.stack[L.top] = ts; diff --git a/src/lua.js b/src/lua.js index 4534f78..245c826 100644 --- a/src/lua.js +++ b/src/lua.js @@ -73,42 +73,6 @@ const print_version = function() { console.log(FENGARI_COPYRIGHT); }; - -const handle_script = function(L, args) { - // TODO: stdin - -}; - -const handle_luainit = function(L) { - // TODO: Should execute script in LUA_INIT_5_3 - return thread_status.LUA_OK; -}; - -/* -** Main body of stand-alone interpreter (to be called in protected mode). -** Reads the options and handles them all. -*/ -const pmain = function(L) { - // arguments are a userdata wrapping a plain JS object - let args = L.stack[1].value; // For now it should only hold a DataView containing bytecode - - // TODO: luaL_checkversion(L); - // TODO: LUA_NOENV - // TODO: luaL_openlibs(L); - // TODO: createargtable(L, argv, argc, script); - - if (!args.E) { - if (handle_luainit(L) != thread_status.LUA_OK) - return 0; /* error running LUA_INIT */ - } - - // TODO: runargs(L, argv, script) - if (args.script && handle_script(L, args) != thread_status.LUA_OK) - return 0; - - // TODO: doREPL(L); -}; - module.exports.constant_types = constant_types; module.exports.thread_status = thread_status; module.exports.LUA_MULTRET = -1; diff --git a/tests/C/Makefile b/tests/C/Makefile index 816be44..6d21b19 100644 --- a/tests/C/Makefile +++ b/tests/C/Makefile @@ -11,4 +11,5 @@ all: $(CC) $(CFLAGS) $(LIBS) lua_pushboolean.c -o lua_pushboolean.out $(CC) $(CFLAGS) $(LIBS) lua_pushvalue.c -o lua_pushvalue.out $(CC) $(CFLAGS) $(LIBS) lua_pushcclosure-light.c -o lua_pushcclosure-light.out - $(CC) $(CFLAGS) $(LIBS) lua_call.c -o lua_call.out \ No newline at end of file + $(CC) $(CFLAGS) $(LIBS) lua_call.c -o lua_call.out + $(CC) $(CFLAGS) $(LIBS) lua_call-jsclosure.c -o lua_call-jsclosure.out \ No newline at end of file diff --git a/tests/C/lua_call-jsclosure.c b/tests/C/lua_call-jsclosure.c new file mode 100644 index 0000000..98fa739 --- /dev/null +++ b/tests/C/lua_call-jsclosure.c @@ -0,0 +1,30 @@ +#include +#include +#include +#include +#include + +int func(lua_State *L) { + const char *s = lua_tostring(L, lua_upvalueindex(1)); + lua_pushstring(L, s); + return 1; +} + +int main(void) { + + lua_State *L = luaL_newstate(); + + luaL_openlibs(L); + + lua_pushstring(L, "upvalue hello !"); + lua_pushcclosure(L, func, 1); + + lua_call(L, 0, 1); + + printf("Lua returned: %s\n", lua_tostring(L, -1)); + + lua_close(L); + + return 0; + +} \ No newline at end of file -- cgit v1.2.3-54-g00ecf