From 9ff3e69b37f7b7603056b684a19b1dd8c641c8d5 Mon Sep 17 00:00:00 2001 From: Benoit Giannangeli Date: Wed, 22 Feb 2017 15:38:45 +0100 Subject: lua_copy, lua_next, luaL_argerror --- src/lapi.js | 13 ++++++++- src/lauxlib.js | 92 +++++++++++++++++++++++++++++++++++++++++++++------------- src/ltable.js | 4 +++ 3 files changed, 88 insertions(+), 21 deletions(-) (limited to 'src') diff --git a/src/lapi.js b/src/lapi.js index 76dee1b..625608b 100644 --- a/src/lapi.js +++ b/src/lapi.js @@ -149,6 +149,12 @@ const lua_rotate = function(L, idx, n) { reverse(L, pIdx, L.top - 1); }; +const lua_copy = function(L, fromidx, toidx) { + let fr = index2addr_(L, fromidx); + let to = index2addr_(L, toidx); + L.stack[to] = fr; +}; + const lua_remove = function(L, idx) { lua_rotate(L, idx, -1); lua_pop(L, 1); @@ -647,6 +653,10 @@ const lua_error = function(L) { ldebug.luaG_errormsg(L); }; +const lua_next = function(L, idx) { + +}; + const lua_concat = function(L, n) { assert(n < L.top - L.ci.funcOff, "not enough elements in the stack"); if (n >= 2) @@ -729,4 +739,5 @@ module.exports.lua_insert = lua_insert; module.exports.lua_gc = lua_gc; module.exports.lua_getallocf = lua_getallocf; module.exports.lua_getextraspace = lua_getextraspace; -module.exports.lua_stringtonumber = lua_stringtonumber; \ No newline at end of file +module.exports.lua_stringtonumber = lua_stringtonumber; +module.exports.lua_copy = lua_copy; \ No newline at end of file diff --git a/src/lauxlib.js b/src/lauxlib.js index e295fe6..4e32437 100644 --- a/src/lauxlib.js +++ b/src/lauxlib.js @@ -11,29 +11,80 @@ const CT = lua.constant_types; const LUA_LOADED_TABLE = "_LOADED" + +/* +** search for 'objidx' in table at index -1. +** return 1 + string at top if find a good name. +*/ +const findfield = function(L, objidx, level) { + if (level === 0 || !lapi.lua_istable(L, -1)) + return 0; /* not found */ + + lapi.lua_pushnil(L); /* start 'next' loop */ + + while (lapi.lua_next(L, -2)) { /* for each pair in table */ + if (lapi.lua_type(L, -2) === CT.LUA_TSTRING) { /* ignore non-string keys */ + if (lapi.lua_rawequal(L, objidx, -1)) { /* found object? */ + lapi.lua_pop(L, 1); /* remove value (but keep name) */ + return 1; + } else if (findfield(L, objidx, level - 1)) { /* try recursively */ + lapi.lua_remove(L, -2); /* remove table (but keep name) */ + lapi.lua_pushliteral(L, "."); + lapi.lua_insert(L, -2); /* place '.' between the two names */ + lapi.lua_concat(L, 3); + return 1; + } + } + lapi.lua_pop(L, 1); /* remove value */ + } + + return 0; /* not found */ +}; + +/* +** Search for a name for a function in all loaded modules +*/ +const pushglobalfuncname = function(L, ar) { + let top = lapi.lua_gettop(L); + lapi.lua_getinfo(L, 'f', ar); /* push function */ + lapi.lua_getfield(L, lua.LUA_REGISTRYINDEX, lua.LUA_LOADED_TABLE); + if (findfield(L, top + 1, 2)) { + let name = lapi.lua_tostring(L, -1); + if (name.startsWith("_G.")) { + lapi.lua_pushstring(L, name.slice(3)); /* name start with '_G.'? */ + lapi.lua_remove(L, -2); /* name start with '_G.'? */ + } + lapi.lua_copy(L, -1, top + 1); /* name start with '_G.'? */ + lapi.lua_pop(L, 2); /* name start with '_G.'? */ + } else { + lapi.lua_settop(L, top); /* remove function and global table */ + return 0; + } +}; + const panic = function(L) { throw new Error(`PANIC: unprotected error in call to Lua API (${lapi.lua_tostring(L, -1)})`); }; -// const luaL_argerror = function(L, arg, extramsg) { -// let ar = new lua.lua_Debug(); -// -// if (!lapi.lua_getstack(L, 0, ar)) /* no stack frame? */ -// return luaL_error(L, 'bad argument #%d (%s)', arg, extramsg); -// -// ldebug.lua_getinfo(L, 'n', ar); -// -// if (ar.namewhat === 'method') { -// arg--; /* do not count 'self' */ -// if (arg === 0) /* error is in the self argument itself? */ -// return luaL_error(L, "calling '%s' on bad self (%s)", ar.name, extramsg); -// } -// -// if (ar.name === null) -// ar.name = pushglobalfuncname(L, ar) ? lapi.lua_tostring(L, -1) : "?"; -// -// return luaL_error(L, "bad argument #%d to '%s' (%s)", arg, ar.name, extramsg); -// }; +const luaL_argerror = function(L, arg, extramsg) { + let ar = new lua.lua_Debug(); + + if (!lapi.lua_getstack(L, 0, ar)) /* no stack frame? */ + return luaL_error(L, 'bad argument #%d (%s)', arg, extramsg); + + ldebug.lua_getinfo(L, 'n', ar); + + if (ar.namewhat === 'method') { + arg--; /* do not count 'self' */ + if (arg === 0) /* error is in the self argument itself? */ + return luaL_error(L, "calling '%s' on bad self (%s)", ar.name, extramsg); + } + + if (ar.name === null) + ar.name = pushglobalfuncname(L, ar) ? lapi.lua_tostring(L, -1) : "?"; + + return luaL_error(L, `bad argument #${arg} to '${ar.name}' (${extramsg})`); +}; const typeerror = function(L, arg, tname) { let typearg; @@ -282,4 +333,5 @@ module.exports.luaL_checkinteger = luaL_checkinteger; module.exports.luaL_optinteger = luaL_optinteger; module.exports.luaL_opt = luaL_opt; module.exports.luaL_where = luaL_where; -module.exports.luaL_error = luaL_error; \ No newline at end of file +module.exports.luaL_error = luaL_error; +module.exports.luaL_argerror = luaL_argerror; \ No newline at end of file diff --git a/src/ltable.js b/src/ltable.js index 95ca5a5..c1d5430 100644 --- a/src/ltable.js +++ b/src/ltable.js @@ -31,4 +31,8 @@ Table.prototype.luaH_getn = function() { else if (hash.size === 0) return j; else return hash.get(j); +}; + +Table.prototype.luaH_next = function(key) { + }; \ No newline at end of file -- cgit v1.2.3-54-g00ecf