aboutsummaryrefslogtreecommitdiff
path: root/src/lauxlib.js
diff options
context:
space:
mode:
authorBenoit Giannangeli <benoit.giannangeli@boursorama.fr>2017-02-22 15:38:45 +0100
committerBenoit Giannangeli <benoit.giannangeli@boursorama.fr>2017-02-22 15:38:45 +0100
commit9ff3e69b37f7b7603056b684a19b1dd8c641c8d5 (patch)
tree1a7436a107753891efe5d2f7d42314ab7c7d1736 /src/lauxlib.js
parenteb9ad22e7538a25ef565e93c842eef48dba2469e (diff)
downloadfengari-9ff3e69b37f7b7603056b684a19b1dd8c641c8d5.tar.gz
fengari-9ff3e69b37f7b7603056b684a19b1dd8c641c8d5.tar.bz2
fengari-9ff3e69b37f7b7603056b684a19b1dd8c641c8d5.zip
lua_copy, lua_next, luaL_argerror
Diffstat (limited to 'src/lauxlib.js')
-rw-r--r--src/lauxlib.js92
1 files changed, 72 insertions, 20 deletions
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