From 6d3d22b3938a811bdde9a311753837003df42d08 Mon Sep 17 00:00:00 2001 From: Benoit Giannangeli Date: Mon, 20 Feb 2017 11:58:46 +0100 Subject: rawset, rawget --- README.md | 31 ++++++++++++++++++++++------ src/lapi.js | 9 +++++++++ src/lbaselib.js | 19 ++++++++++++++++++ tests/lbaselib.js | 60 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 113 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 1a4a4e3..43bc000 100644 --- a/README.md +++ b/README.md @@ -63,6 +63,7 @@ - [x] lua_pushliteral - [x] lua_rawget - [x] lua_rawgeti + - [x] lua_rawset - [x] lua_setfield - [x] lua_settop - [x] lua_tostring @@ -113,7 +114,6 @@ - [ ] lua_pushvfstring - [ ] lua_rawgetp - [ ] lua_rawlen - - [ ] lua_rawset - [ ] lua_rawseti - [ ] lua_rawsetp - [ ] lua_register @@ -202,11 +202,30 @@ - [ ] luaL_unref - [ ] luaL_where - [ ] Standard library - - [x] tostring - - [x] print - - [x] getmetatable - - [x] setmetatable - - [x] rawequal + - [ ] Base lib + - [x] tostring + - [x] print + - [x] getmetatable + - [x] setmetatable + - [x] rawequal + - [x] rawset + - [x] rawget + - [ ] assert + - [ ] collectgarbage + - [ ] dofile + - [ ] error + - [ ] ipairs + - [ ] loadfile + - [ ] load + - [ ] loadstring + - [ ] next + - [ ] pairs + - [ ] pcall + - [ ] rawlen + - [ ] select + - [ ] tonumber + - [ ] type + - [ ] xpcall - [ ] ... - [ ] Debug (errors) - [ ] DOM API binding diff --git a/src/lapi.js b/src/lapi.js index 95eb6f7..bb6c224 100644 --- a/src/lapi.js +++ b/src/lapi.js @@ -299,6 +299,14 @@ const lua_setfield = function(L, idx, k) { auxsetstr(L, index2addr(L, idx), k) }; +const lua_rawset = function(L, idx) { + assert(2 < L.top - L.ci.funcOff, "not enough elements in the stack"); + let o = index2addr(L, idx); + assert(o.ttistable(), "table expected"); + o.__newindex(o, L.stack[L.top - 2], L.stack[L.top - 1]); + L.top -= 2; +}; + /* ** get functions (Lua -> stack) */ @@ -586,6 +594,7 @@ module.exports.lua_gettable = lua_gettable; module.exports.lua_absindex = lua_absindex; module.exports.index2addr = index2addr; module.exports.lua_rawget = lua_rawget; +module.exports.lua_rawset = lua_rawset; module.exports.lua_isstring = lua_isstring; module.exports.lua_rotate = lua_rotate; module.exports.lua_remove = lua_remove; diff --git a/src/lbaselib.js b/src/lbaselib.js index 62d25df..a89cf9d 100644 --- a/src/lbaselib.js +++ b/src/lbaselib.js @@ -64,12 +64,31 @@ const luaB_rawequal = function(L) { return 1; }; +const luaB_rawget = function(L) { + lauxlib.luaL_checktype(L, 1, CT.LUA_TTABLE); + lauxlib.luaL_checkany(L, 2); + lapi.lua_settop(L, 2); + lapi.lua_rawget(L, 1); + return 1; +}; + +const luaB_rawset = function(L) { + lauxlib.luaL_checktype(L, 1, CT.LUA_TTABLE); + lauxlib.luaL_checkany(L, 2); + lauxlib.luaL_checkany(L, 3); + lapi.lua_settop(L, 3); + lapi.lua_rawset(L, 1); + return 1; +}; + const base_funcs = { "print": luaB_print, "tostring": luaB_tostring, "getmetatable": luaB_getmetatable, "setmetatable": luaB_setmetatable, "rawequal": luaB_rawequal, + "rawset": luaB_rawset, + "rawget": luaB_rawget, }; const luaopen_base = function(L) { diff --git a/tests/lbaselib.js b/tests/lbaselib.js index ab68a5f..b3af927 100644 --- a/tests/lbaselib.js +++ b/tests/lbaselib.js @@ -126,4 +126,64 @@ test('rawequal', function (t) { lapi.lua_toboolean(L, -1), "Correct element(s) on the stack" ); +}); + + +test('rawset, rawget', function (t) { + let luaCode = ` + local mt = { + __newindex = function (table, key, value) + rawset(table, key, "hello") + end + } + + local t = {} + + setmetatable(t, mt); + + t["yo"] = "bye" + rawset(t, "yoyo", "bye") + + return rawget(t, "yo"), t["yo"], rawget(t, "yoyo"), t["yoyo"] + `, L; + + t.plan(5); + + t.doesNotThrow(function () { + + let bc = toByteCode(luaCode).dataView; + + L = lauxlib.luaL_newstate(); + + linit.luaL_openlibs(L); + + lapi.lua_load(L, bc, "test-rawequal"); + + lapi.lua_call(L, 0, -1); + + }, "JS Lua program ran without error"); + + t.strictEqual( + lapi.lua_tostring(L, -4), + "hello", + "Correct element(s) on the stack" + ); + + t.strictEqual( + lapi.lua_tostring(L, -3), + "hello", + "Correct element(s) on the stack" + ); + + t.strictEqual( + lapi.lua_tostring(L, -2), + "bye", + "Correct element(s) on the stack" + ); + + t.strictEqual( + lapi.lua_tostring(L, -1), + "bye", + "Correct element(s) on the stack" + ); }); \ No newline at end of file -- cgit v1.2.3-70-g09d2