aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBenoit Giannangeli <benoit.giannangeli@boursorama.fr>2017-02-17 11:33:23 +0100
committerBenoit Giannangeli <benoit.giannangeli@boursorama.fr>2017-02-17 11:34:49 +0100
commita8e82fc01f2558550289f76f55c917039296ec11 (patch)
treeb226aeca2d8445ee8bcfd644477992a0635e46e0
parent4a03542f6ebc8c6d4ed624bc0d30f5a7148a279b (diff)
downloadfengari-a8e82fc01f2558550289f76f55c917039296ec11.tar.gz
fengari-a8e82fc01f2558550289f76f55c917039296ec11.tar.bz2
fengari-a8e82fc01f2558550289f76f55c917039296ec11.zip
lua_load (bytecode only), lua_call(k)
-rw-r--r--README.md6
-rw-r--r--src/lapi.js19
-rw-r--r--src/ldo.js35
-rw-r--r--tests/lapi.js48
-rw-r--r--tests/tests.js6
5 files changed, 82 insertions, 32 deletions
diff --git a/README.md b/README.md
index fb727b4..e79a6a8 100644
--- a/README.md
+++ b/README.md
@@ -41,10 +41,11 @@
- [x] lua_pushjsclosure (lua_pushcclosure)
- [x] lua_pushjsfunction (lua_pushcfunction)
- [x] lua_pop
+ - [x] lua_load
+ - [x] lua_call
+ - [x] lua_callk
- [ ] lua_absindex
- [ ] lua_arith
- - [ ] lua_call
- - [ ] lua_callk
- [ ] lua_checkstack
- [ ] lua_close
- [ ] lua_compare
@@ -85,7 +86,6 @@
- [ ] lua_isuserdata
- [ ] lua_isyieldable
- [ ] lua_len
- - [ ] lua_load
- [ ] lua_newtable
- [ ] lua_newthread
- [ ] lua_newuserdata
diff --git a/src/lapi.js b/src/lapi.js
index 976841d..6cc95b2 100644
--- a/src/lapi.js
+++ b/src/lapi.js
@@ -240,6 +240,24 @@ const lua_typename = function(L, t) {
** 'load' and 'call' functions (run Lua code)
*/
+const lua_load = function(L, data, chunckname) {
+ if (!chunckname) chunckname = "?";
+
+ let status = ldo.luaD_protectedparser(L, data, chunckname);
+ if (status === TS.LUA_OK) {
+ let f = L.stack[L.top - 1]; /* get newly created function */
+ if (f.nupvalues >= 1) { /* does it have an upvalue? */
+ /* get global table from registry */
+ 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 ?
+ }
+ }
+
+ return status;
+};
+
const lua_callk = function(L, nargs, nresults, ctx, k) {
assert(k === null || !(L.ci.callstatus & CIST_LUA), "cannot use continuations inside hooks");
assert(nargs + 1 < L.top - L.ci.funcOff, "not enough elements in the stack");
@@ -333,6 +351,7 @@ module.exports.lua_tointeger = lua_tointeger;
module.exports.lua_toboolean = lua_toboolean;
module.exports.lua_tolstring = lua_tolstring;
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
diff --git a/src/ldo.js b/src/ldo.js
index 3686f7d..632bc22 100644
--- a/src/ldo.js
+++ b/src/ldo.js
@@ -9,6 +9,8 @@ const lstate = require('./lstate.js');
const llimit = require('./llimit.js');
const ltm = require('./ltm.js');
const lvm = require('./lvm.js');
+const lfunc = require('./lfunc.js');
+const BytecodeParser = require('./lundump.js');
const CT = lua.constant_types;
const TS = lua.thread_status;
const LUA_MULTRET = lua.LUA_MULTRET;
@@ -237,7 +239,7 @@ const luaD_pcall = function(L, func, u, old_top, ef) {
let old_errfunc = L.errfunc;
L.errfunc = ef;
- status = luaD_rawrunprotected(L, func, u);
+ let status = luaD_rawrunprotected(L, func, u);
if (status !== TS.LUA_OK) {
lfunc.luaF_close(L, old_top);
@@ -263,12 +265,10 @@ const luaD_callnoyield = function(L, off, nResults) {
// TODO: since we only handle binary, no need for a reader or mode
const f_parser = function(L, data) {
- assert(data instanceof DataView, "data must be a DataView");
+ let p = new BytecodeParser(data);
+ let cl = p.luaU_undump(L);
- let p = new lundump.BytecodeParser(data);
- let cl = p.luaU_undump();
-
- assert(cl.nupvalues == cl.p.sizeupvalues);
+ assert(cl.nupvalues == cl.p.upvalues.length);
lfunc.luaF_initupvals(L, cl);
};
@@ -283,14 +283,15 @@ const luaD_protectedparser = function(L, data, name) {
return status;
};
-module.exports.nil = nil;
-module.exports.luaD_precall = luaD_precall;
-module.exports.luaD_poscall = luaD_poscall;
-module.exports.moveresults = moveresults;
-module.exports.adjust_varargs = adjust_varargs;
-module.exports.tryfuncTM = tryfuncTM;
-module.exports.stackerror = stackerror;
-module.exports.luaD_call = luaD_call;
-module.exports.luaD_callnoyield = luaD_callnoyield;
-module.exports.luaD_pcall = luaD_pcall;
-module.exports.luaD_rawrunprotected = luaD_rawrunprotected; \ No newline at end of file
+module.exports.nil = nil;
+module.exports.luaD_precall = luaD_precall;
+module.exports.luaD_poscall = luaD_poscall;
+module.exports.moveresults = moveresults;
+module.exports.adjust_varargs = adjust_varargs;
+module.exports.tryfuncTM = tryfuncTM;
+module.exports.stackerror = stackerror;
+module.exports.luaD_call = luaD_call;
+module.exports.luaD_callnoyield = luaD_callnoyield;
+module.exports.luaD_pcall = luaD_pcall;
+module.exports.luaD_rawrunprotected = luaD_rawrunprotected;
+module.exports.luaD_protectedparser = luaD_protectedparser; \ No newline at end of file
diff --git a/tests/lapi.js b/tests/lapi.js
index fa1fb59..ff76920 100644
--- a/tests/lapi.js
+++ b/tests/lapi.js
@@ -1,17 +1,19 @@
/*jshint esversion: 6 */
"use strict";
-const test = require('tape');
-const beautify = require('js-beautify').js_beautify;
+const test = require('tape');
+const beautify = require('js-beautify').js_beautify;
-const getState = require("./tests.js").getState;
+const tests = require("./tests.js");
+const getState = tests.getState;
+const toByteCode = tests.toByteCode;
-const VM = require("../src/lvm.js");
-const ldo = require("../src/ldo.js");
-const lapi = require("../src/lapi.js");
-const lauxlib = require("../src/lauxlib.js");
-const lua = require('../src/lua.js');
-const CT = lua.constant_types;
+const VM = require("../src/lvm.js");
+const ldo = require("../src/ldo.js");
+const lapi = require("../src/lapi.js");
+const lauxlib = require("../src/lauxlib.js");
+const lua = require('../src/lua.js');
+const CT = lua.constant_types;
test('luaL_newstate, lua_pushnil, lua_gettop, luaL_typename', function (t) {
let L;
@@ -378,4 +380,32 @@ test('lua_pop', function (t) {
"hello",
"Correct element(s) on the stack"
);
+});
+
+
+test('lua_load and lua_call it', function (t) {
+ let luaCode = `
+ local a = "JS > Lua > JS \o/"
+ return a
+ `, 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_call(L, 0, 1);
+
+ }, "JS Lua program ran without error");
+
+ t.strictEqual(
+ lapi.lua_tostring(L, -1),
+ "JS > Lua > JS \o/",
+ "Correct element(s) on the stack"
+ );
}); \ No newline at end of file
diff --git a/tests/tests.js b/tests/tests.js
index 5a1b023..a9f8730 100644
--- a/tests/tests.js
+++ b/tests/tests.js
@@ -42,6 +42,6 @@ const getState = function(luaCode) {
return L;
};
-module.exports = {
- getState: getState
-} \ No newline at end of file
+
+module.exports.getState = getState;
+module.exports.toByteCode = toByteCode; \ No newline at end of file