diff options
| author | Benoit Giannangeli <giann008@gmail.com> | 2017-04-12 10:06:25 +0200 | 
|---|---|---|
| committer | Benoit Giannangeli <giann008@gmail.com> | 2017-04-12 10:54:41 +0200 | 
| commit | eeb3d8ac1de70703ce7db4788b7fb43fcda80aa8 (patch) | |
| tree | a3d8b2dffceeb2cd7b0bc0dc95feaaa2386939c4 /src | |
| parent | fc08312ebf8cf01a53b4826acce0f1c3aedcdc53 (diff) | |
| download | fengari-eeb3d8ac1de70703ce7db4788b7fb43fcda80aa8.tar.gz fengari-eeb3d8ac1de70703ce7db4788b7fb43fcda80aa8.tar.bz2 fengari-eeb3d8ac1de70703ce7db4788b7fb43fcda80aa8.zip | |
debug.getinfo
Diffstat (limited to 'src')
| -rw-r--r-- | src/lapi.js | 4 | ||||
| -rw-r--r-- | src/ldblib.js | 91 | ||||
| -rw-r--r-- | src/ldebug.js | 8 | 
3 files changed, 97 insertions, 6 deletions
| diff --git a/src/lapi.js b/src/lapi.js index fcb07d6..894b5bb 100644 --- a/src/lapi.js +++ b/src/lapi.js @@ -230,7 +230,7 @@ const lua_pushlstring = function(L, s, len) {  };  const lua_pushstring = function (L, s) { -    assert(Array.isArray(s), "lua_pushstring expects array of byte"); +    assert(Array.isArray(s) || s === undefined || s === null, "lua_pushstring expects array of byte");      if (s === undefined || s === null)          L.stack[L.top] = new TValue(CT.LUA_TNIL, null); @@ -245,7 +245,7 @@ const lua_pushstring = function (L, s) {  };  const lua_pushliteral = function (L, s) { -    assert(typeof s === "string", "lua_pushliteral expects a JS string"); +    assert(typeof s === "string" || s === undefined || s === null, "lua_pushliteral expects a JS string");      if (s === undefined || s === null)          L.stack[L.top] = new TValue(CT.LUA_TNIL, null); diff --git a/src/ldblib.js b/src/ldblib.js index 318e616..ea080c0 100644 --- a/src/ldblib.js +++ b/src/ldblib.js @@ -3,6 +3,7 @@  const assert  = require('assert');  const lua     = require('./lua.js'); +const char    = lua.char;  const lapi    = require('./lapi.js');  const lauxlib = require('./lauxlib.js');  const ldebug  = require('./ldebug.js'); @@ -37,6 +38,95 @@ const getthread = function(L) {      }  }; +/* +** Variations of 'lua_settable', used by 'db_getinfo' to put results +** from 'lua_getinfo' into result table. Key is always a string; +** value can be a string, an int, or a boolean. +*/ +const settabss = function(L, k, v) { +    lapi.lua_pushstring(L, v); +    lapi.lua_setfield(L, -2, k); +}; + +const settabsi = function(L, k, v) { +    lapi.lua_pushinteger(L, v); +    lapi.lua_setfield(L, -2, k); +}; + +const settabsb = function(L, k, v) { +    lapi.lua_pushboolean(L, v); +    lapi.lua_setfield(L, -2, k); +}; + + +/* +** In function 'db_getinfo', the call to 'lua_getinfo' may push +** results on the stack; later it creates the result table to put +** these objects. Function 'treatstackoption' puts the result from +** 'lua_getinfo' on top of the result table so that it can call +** 'lua_setfield'. +*/ +const treatstackoption = function(L, L1, fname) { +    if (L == L1) +        lapi.lua_rotate(L, -2, 1);  /* exchange object and table */ +    else +        lapi.lua_xmove(L1, L, 1);  /* move object to the "main" stack */ +    lapi.lua_setfield(L, -2, fname);  /* put object into table */ +}; + +/* +** Calls 'lua_getinfo' and collects all results in a new table. +** L1 needs stack space for an optional input (function) plus +** two optional outputs (function and line table) from function +** 'lua_getinfo'. +*/ +const db_getinfo = function(L) { +    let ar = new lua.lua_Debug(); +    let thread = getthread(L); +    let arg = thread.arg; +    let L1 = thread.thread; +    let options = lauxlib.luaL_optstring(L, arg + 2, lua.to_luastring("flnStu")); +    checkstack(L, L1, 3); +    if (lapi.lua_isfunction(L, arg + 1)) {  /* info about a function? */ +        options = [char['>']].concat(options);  /* add '>' to 'options' */ +        lapi.lua_pushvalue(L, arg + 1);  /* move function to 'L1' stack */ +        lapi.lua_xmove(L, L1, 1); +    } else {  /* stack level */ +        if (!ldebug.lua_getstack(L1, lauxlib.luaL_checkinteger(L, arg + 1), ar)) { +            lapi.lua_pushnil(L);  /* level out of range */ +            return 1; +        } +    } + +    if (!ldebug.lua_getinfo(L1, options, ar)) +        lauxlib.luaL_argerror(L, arg + 2, lua.to_luastring("invalid option")); +    lapi.lua_newtable(L);  /* table to collect results */ +    if (options.indexOf(char['S']) > -1) { +        settabss(L, lua.to_luastring("source"), ar.source.value); +        settabss(L, lua.to_luastring("short_src"), ar.short_src); +        settabss(L, lua.to_luastring("linedefined"), lua.to_luastring(`${ar.linedefined}`)); +        settabss(L, lua.to_luastring("lastlinedefined"), lua.to_luastring(`${ar.lastlinedefined}`)); +        settabss(L, lua.to_luastring("what"), ar.what); +    } +    if (options.indexOf(char['l']) > -1) +        settabsi(L, lua.to_luastring("currentline"), ar.currentline); +    if (options.indexOf(char['u']) > -1) +        settabsi(L, lua.to_luastring("nups"), ar.nups); +        settabsi(L, lua.to_luastring("nparams"), ar.nparams); +        settabsb(L, lua.to_luastring("isvararg"), ar.isvararg); +    if (options.indexOf(char['n']) > - 1) { +        settabss(L, lua.to_luastring("name"), ar.name ? ar.name.value : null); +        settabss(L, lua.to_luastring("namewhat"), ar.namewhat ? ar.namewhat : null); +    } +    if (options.indexOf(char['t']) > - 1) +        settabsb(L, lua.to_luastring("istailcall"), ar.istailcall); +    if (options.indexOf(char['L']) > - 1) +        treatstackoption(L, L1, lua.to_luastring("activelines")); +    if (options.indexOf(char['f']) > - 1) +        treatstackoption(L, L1, lua.to_luastring("func")); +    return 1;  /* return table */ +}; +  const db_getlocal = function(L) {      let thread = getthread(L);      let L1 = thread.thread; @@ -99,6 +189,7 @@ const db_traceback = function(L) {  };  const dblib = { +    "getinfo":   db_getinfo,      "getlocal":  db_getlocal,      "traceback": db_traceback,      "upvalueid": db_upvalueid diff --git a/src/ldebug.js b/src/ldebug.js index ce62abc..713a0fb 100644 --- a/src/ldebug.js +++ b/src/ldebug.js @@ -179,13 +179,13 @@ const auxgetinfo = function(L, what, ar, f, ci) {                  break;              }              case 'u': { -                ar.nups = f === null ? 0 : f.c.nupvalues; -                if (f === null || f.c.type === CT.LUA_TCCL) { +                ar.nups = f === null ? 0 : f.nupvalues; +                if (f === null || f.type === CT.LUA_TCCL) {                      ar.isvararg = true;                      ar.nparams = 0;                  } else { -                    ar.isvararg = f.l.p.is_vararg; -                    ar.nparams = f.l.p.numparams; +                    ar.isvararg = f.p.is_vararg; +                    ar.nparams = f.p.numparams;                  }                  break;              } | 
