diff options
Diffstat (limited to 'src/ldblib.js')
-rw-r--r-- | src/ldblib.js | 60 |
1 files changed, 60 insertions, 0 deletions
diff --git a/src/ldblib.js b/src/ldblib.js index 39b9574..efab872 100644 --- a/src/ldblib.js +++ b/src/ldblib.js @@ -5,9 +5,69 @@ const assert = require('assert'); const lua = require('./lua.js'); const lapi = require('./lapi.js'); const lauxlib = require('./lauxlib.js'); +const ldebug = require('./ldebug.js'); +/* +** If L1 != L, L1 can be in any state, and therefore there are no +** guarantees about its stack space; any push in L1 must be +** checked. +*/ +const checkstack = function(L, L1, n) { + if (L !== L1 && !lapi.lua_checkstack(L1, n)) + lauxlib.luaL_error(L, "stack overflow"); +}; + +/* +** Auxiliary function used by several library functions: check for +** an optional thread as function's first argument and set 'arg' with +** 1 if this argument is present (so that functions can skip it to +** access their other arguments) +*/ +const getthread = function(L) { + if (lapi.lua_isthread(L, 1)) { + return { + arg: 1, + thread: lapi.lua_tothread(L, 1) + }; + } else { + return { + arg: 0, + thread: L + }; /* function will operate over current thread */ + } +}; + +const db_getlocal = function(L) { + let thread = getthread(L); + let L1 = thread.thread; + let arg = thread.arg; + let ar = new lua.lua_Debug(); + let nvar = lauxlib.luaL_checkinteger(L, arg + 2); /* local-variable index */ + if (lapi.lua_isfunction(L, arg + 1)) { + lapi.lua_pushvalue(L, arg + 1); /* push function */ + lapi.lua_pushstring(L, ldebug.lua_getlocal(L, null, nvar)); /* push local name */ + return 1; /* return only name (there is no value) */ + } else { /* stack-level argument */ + let level = lauxlib.luaL_checkinteger(L, arg + 1); + if (!ldebug.lua_getstack(L1, level, ar)) /* out of range? */ + return lauxlib.luaL_argerror(L, arg+1, lapi.to_luastring("level out of range")); + checkstack(L, L1, 1); + let name = ldebug.lua_getlocal(L1, ar, nvar); + if (name) { + lapi.lua_xmove(L1, L, 1); /* move local value */ + lapi.lua_pushstring(L, name.value); /* push name */ + lapi.lua_rotate(L, -2, 1); /* re-order */ + return 2; + } + else { + lapi.lua_pushnil(L); /* no name (nor value) */ + return 1; + } + } +}; const dblib = { + "getlocal": db_getlocal }; // Only with Node |