From e02fa80026ed5789e04ab865f238c8d184487dd2 Mon Sep 17 00:00:00 2001 From: Benoit Giannangeli Date: Fri, 17 Feb 2017 07:39:04 +0100 Subject: JS closure --- README.md | 4 ++-- src/lapi.js | 50 ++++++++++++++++++++++++++++---------------------- src/lua.js | 2 +- tests/lapi.js | 48 ++++++++++++++++++++++++++++++++++++++++++------ 4 files changed, 73 insertions(+), 31 deletions(-) diff --git a/README.md b/README.md index 9d95a2b..5d52e2e 100644 --- a/README.md +++ b/README.md @@ -38,8 +38,8 @@ - [x] lua_tonumber - [x] lua_tonumberx - [x] lua_toboolean - - [x] lua_pushcclosure - - [x] lua_pushcfunction + - [x] lua_pushjsclosure (lua_pushcclosure) + - [x] lua_pushjsfunction (lua_pushcfunction) - [ ] lua_absindex - [ ] lua_arith - [ ] lua_call diff --git a/src/lapi.js b/src/lapi.js index dd74552..2bef5a5 100644 --- a/src/lapi.js +++ b/src/lapi.js @@ -151,7 +151,7 @@ const lua_pushcclosure = function(L, fn, n) { assert(n < L.top - L.ci.funcOff, "not enough elements in the stack"); assert(n <= MAXUPVAL, "upvalue index too large"); - let cl = new CClosure(L, fn, n); + let cl = new CClosure(fn, n); L.top -= n; while (n--) { @@ -165,10 +165,14 @@ const lua_pushcclosure = function(L, fn, n) { assert(L.top <= L.ci.top, "stack overflow"); }; +const lua_pushjsclosure = lua_pushcclosure; + const lua_pushcfunction = function(L, fn) { lua_pushcclosure(L, fn, 0); }; +const lua_pushjsfunction = lua_pushcfunction; + const lua_pushboolean = function(L, b) { L.stack[L.top] = new TValue(CT.LUA_TBOOLEAN, b ? true : false); @@ -307,24 +311,26 @@ const lua_pcallk = function(L, nargs, nresults, errfunc, ctx, k) { return status; }; -module.exports.lua_pushvalue = lua_pushvalue; -module.exports.lua_pushnil = lua_pushnil; -module.exports.lua_pushnumber = lua_pushnumber; -module.exports.lua_pushinteger = lua_pushinteger; -module.exports.lua_pushlstring = lua_pushlstring; -module.exports.lua_pushstring = lua_pushstring; -module.exports.lua_pushboolean = lua_pushboolean; -module.exports.lua_pushcclosure = lua_pushcclosure; -module.exports.lua_pushcfunction = lua_pushcfunction; -module.exports.lua_version = lua_version; -module.exports.lua_atpanic = lua_atpanic; -module.exports.lua_gettop = lua_gettop; -module.exports.lua_typename = lua_typename; -module.exports.lua_type = lua_type; -module.exports.lua_tonumber = lua_tonumber; -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_callk = lua_callk; -module.exports.lua_call = lua_call; \ No newline at end of file +module.exports.lua_pushvalue = lua_pushvalue; +module.exports.lua_pushnil = lua_pushnil; +module.exports.lua_pushnumber = lua_pushnumber; +module.exports.lua_pushinteger = lua_pushinteger; +module.exports.lua_pushlstring = lua_pushlstring; +module.exports.lua_pushstring = lua_pushstring; +module.exports.lua_pushboolean = lua_pushboolean; +module.exports.lua_pushcclosure = lua_pushcclosure; +module.exports.lua_pushcfunction = lua_pushcfunction; +module.exports.lua_pushjsclosure = lua_pushjsclosure; +module.exports.lua_pushjsfunction = lua_pushjsfunction; +module.exports.lua_version = lua_version; +module.exports.lua_atpanic = lua_atpanic; +module.exports.lua_gettop = lua_gettop; +module.exports.lua_typename = lua_typename; +module.exports.lua_type = lua_type; +module.exports.lua_tonumber = lua_tonumber; +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_callk = lua_callk; +module.exports.lua_call = lua_call; \ No newline at end of file diff --git a/src/lua.js b/src/lua.js index 58cc0cd..6ebf250 100644 --- a/src/lua.js +++ b/src/lua.js @@ -68,7 +68,7 @@ const LUA_MINSTACK = 20; const LUA_REGISTRYINDEX = -luaconf.LUAI_MAXSTACK - 1000; const lua_upvalueindex = function(i) { - LUA_REGISTRYINDEX - i; + return LUA_REGISTRYINDEX - i; }; /* predefined values in the registry */ diff --git a/tests/lapi.js b/tests/lapi.js index c0f1cdc..de7a401 100644 --- a/tests/lapi.js +++ b/tests/lapi.js @@ -10,7 +10,8 @@ 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 CT = require('../src/lua.js').constant_types; +const lua = require('../src/lua.js'); +const CT = lua.constant_types; test('luaL_newstate, lua_pushnil, lua_gettop, luaL_typename', function (t) { let L; @@ -218,7 +219,7 @@ test('lua_pushvalue', function (t) { }); -test('lua_pushcclosure', function (t) { +test('lua_pushjsclosure', function (t) { let L; t.plan(3); @@ -232,7 +233,7 @@ test('lua_pushcclosure', function (t) { L = lauxlib.luaL_newstate(); lapi.lua_pushstring(L, "a value associated to the C closure"); - lapi.lua_pushcclosure(L, fn, 1); + lapi.lua_pushjsclosure(L, fn, 1); }, "JS Lua program ran without error"); @@ -250,7 +251,7 @@ test('lua_pushcclosure', function (t) { }); -test('lua_pushcfunction', function (t) { +test('lua_pushjsfunction', function (t) { let L; t.plan(3); @@ -263,7 +264,7 @@ test('lua_pushcfunction', function (t) { L = lauxlib.luaL_newstate(); - lapi.lua_pushcfunction(L, fn); + lapi.lua_pushjsfunction(L, fn); }, "JS Lua program ran without error"); @@ -295,7 +296,7 @@ test('lua_call (calling a light JS function)', function (t) { L = lauxlib.luaL_newstate(); - lapi.lua_pushcfunction(L, fn); + lapi.lua_pushjsfunction(L, fn); lapi.lua_call(L, 0, 1); @@ -312,4 +313,39 @@ test('lua_call (calling a light JS function)', function (t) { "hello", "top is correct" ); +}); + + +test('lua_call (calling a JS closure)', function (t) { + let L; + + t.plan(3); + + t.doesNotThrow(function () { + + let fn = function(L) { + lapi.lua_pushstring(L, lapi.lua_tostring(L, lua.lua_upvalueindex(1))); + return 1; + }; + + L = lauxlib.luaL_newstate(); + + lapi.lua_pushstring(L, "upvalue hello !"); + lapi.lua_pushjsclosure(L, fn, 1); + + lapi.lua_call(L, 0, 1); + + }, "JS Lua program ran without error"); + + t.strictEqual( + lapi.lua_gettop(L), + 1, + "top is correct" + ); + + t.strictEqual( + lapi.lua_tostring(L, -1), + "upvalue hello !", + "top is correct" + ); }); \ No newline at end of file -- cgit v1.2.3-70-g09d2