diff options
author | daurnimator <quae@daurnimator.com> | 2017-04-19 18:12:07 +1000 |
---|---|---|
committer | daurnimator <quae@daurnimator.com> | 2017-04-19 18:12:07 +1000 |
commit | 662381f6669f28f90a1d50c89647d265ca3804a4 (patch) | |
tree | 5ae3bce5dcf2a83302618280163d3088e5d090f8 /src/ldebug.js | |
parent | 4d596650dff0417660874727964a32dae23dc9ea (diff) | |
parent | 6be8db07196c407cd321a7b04f5022939c4ffce3 (diff) | |
download | fengari-662381f6669f28f90a1d50c89647d265ca3804a4.tar.gz fengari-662381f6669f28f90a1d50c89647d265ca3804a4.tar.bz2 fengari-662381f6669f28f90a1d50c89647d265ca3804a4.zip |
Merge branch 'master' into cli
Diffstat (limited to 'src/ldebug.js')
-rw-r--r-- | src/ldebug.js | 129 |
1 files changed, 106 insertions, 23 deletions
diff --git a/src/ldebug.js b/src/ldebug.js index 713a0fb..16449e2 100644 --- a/src/ldebug.js +++ b/src/ldebug.js @@ -38,6 +38,33 @@ const swapextra = function(L) { } }; +const lua_sethook = function(L, func, mask, count) { + if (func === null || mask === 0) { /* turn off hooks? */ + mask = 0; + func = null; + } + if (L.ci.callstatus & lstate.CIST_LUA) + L.oldpc = L.ci.pcOff; + L.hook = func; + L.basehookcount = count; + L.hookcount = L.basehookcount; + L.hookmask = mask; +}; + +const lua_gethook = function(L) { + return L.hook; +}; + + +const lua_gethookmask = function(L) { + return L.hookmask; +}; + + +const lua_gethookcount = function(L) { + return L.basehookcount; +}; + const lua_getstack = function(L, level, ar) { let ci; let status; @@ -52,10 +79,11 @@ const lua_getstack = function(L, level, ar) { return status; }; +// TODO: returns TValue or String array ? const upvalname = function(p, uv) { assert(uv < p.upvalues.length); let s = p.upvalues[uv].name; - if (s === null) return "?".charCodeAt(0); + if (s === null) return ["?".charCodeAt(0)]; return s; }; @@ -66,7 +94,7 @@ const findvararg = function(ci, n, pos) { else { return { pos: ci.funcOff + nparams + n, - name: lua.to_luastring("(*vararg)") /* generic name for any vararg */ + name: lua.to_luastring("(*vararg)", true) /* generic name for any vararg */ }; } }; @@ -87,7 +115,7 @@ const findlocal = function(L, ci, n) { if (name === null) { /* no 'standard' name? */ let limit = ci === L.ci ? L.top : ci.next.func; if (limit - base >= n && n > 0) /* is 'n' inside 'ci' stack? */ - name = lua.to_luastring("(*temporary)"); /* generic name for any valid slot */ + name = lua.to_luastring("(*temporary)", true); /* generic name for any valid slot */ else return null; /* no name */ } @@ -116,18 +144,32 @@ const lua_getlocal = function(L, ar, n) { return name; }; +const lua_setlocal = function(L, ar, n) { + swapextra(L); + let local = findlocal(L, ar.i_ci, n); + let name = local.name; + let pos = local.pos; + if (name) { + L.stack[pos].type = L.stack[L.top - 1].type; + L.stack[pos].value = L.stack[L.top - 1].value; + L.top--; /* pop value */ + } + swapextra(L); + return name; +}; + const funcinfo = function(ar, cl) { if (cl === null || cl.type === CT.LUA_TCCL) { - ar.source = lua.to_luastring("=[JS]"); + ar.source = lua.to_luastring("=[JS]", true); ar.linedefined = -1; ar.lastlinedefined = -1; ar.what = "J"; } else { let p = cl.p; - ar.source = p.source ? p.source : lua.to_luastring("=?"); + ar.source = p.source ? p.source : lua.to_luastring("=?", true); ar.linedefined = p.linedefined; ar.lastlinedefined = p.lastlinedefined; - ar.what = ar.linedefined === 0 ? lua.to_luastring("main") : lua.to_luastring("Lua"); + ar.what = ar.linedefined === 0 ? lua.to_luastring("main", true) : lua.to_luastring("Lua", true); } ar.short_src = lobject.luaO_chunkid(ar.source, luaconf.LUA_IDSIZE); @@ -156,8 +198,8 @@ const getfuncname = function(L, ci) { if (ci === null) return null; else if (ci.callstatus & lstate.CIST_FIN) { /* is this a finalizer? */ - r.name = lua.to_luastring("__gc"); - r.funcname = lua.to_luastring("metamethod"); /* report it as such */ + r.name = lua.to_luastring("__gc", true); + r.funcname = lua.to_luastring("metamethod", true); /* report it as such */ return r; } /* calling function is a known Lua function? */ @@ -260,8 +302,8 @@ const kname = function(p, pc, c) { /* else no reasonable name found */ } else { /* 'c' is a register */ let what = getobjname(p, pc, c); /* search for 'c' */ - if (what && what.name[0] === 'c'.charCodeAt(0)) { - return what; + if (what && what.funcname[0] === 'c'.charCodeAt(0)) { /* found a constant name? */ + return what; /* 'name' already filled */ } /* else no reasonable name found */ } @@ -331,7 +373,7 @@ const getobjname = function(p, lastpc, reg) { }; if (r.name) { /* is a local? */ - r.funcname = lua.to_luastring("local"); + r.funcname = lua.to_luastring("local", true); return r; } @@ -352,13 +394,14 @@ const getobjname = function(p, lastpc, reg) { let k = i.C; /* key index */ let t = i.B; /* table index */ let vn = op === 'OP_GETTABLE' ? lfunc.luaF_getlocalname(p, t + 1, pc) : upvalname(p, t); - r.name = kname(p, pc, k); - r.funcname = vn && vn === lua.to_luastring("_ENV") ? lua.to_luastring("global") : lua.to_luastring("field"); + vn = vn ? vn.jsstring() : null; + r.name = kname(p, pc, k).name; + r.funcname = vn && vn === "_ENV" ? lua.to_luastring("global", true) : lua.to_luastring("field", true); return r; } case 'OP_GETUPVAL': { r.name = upvalname(p, i.B); - r.funcname = lua.to_luastring("upvalue"); + r.funcname = lua.to_luastring("upvalue", true); return r; } case 'OP_LOADK': @@ -366,15 +409,15 @@ const getobjname = function(p, lastpc, reg) { let b = op === 'OP_LOADK' ? i.Bx : p.code[pc + 1].Ax; if (p.k[b].ttisstring()) { r.name = p.k[b].value; - r.funcname = lua.to_luastring("constant"); + r.funcname = lua.to_luastring("constant", true); return r; } break; } case 'OP_SELF': { let k = i.C; - r.name = kname(p, pc, k); - r.funcname = lua.to_luastring("method"); + r.name = kname(p, pc, k).name; + r.funcname = lua.to_luastring("method", true); return r; } default: break; @@ -403,7 +446,7 @@ const funcnamefromcode = function(L, ci) { if (ci.callstatus & lstate.CIST_HOOKED) { r.name = [lua.char["?"]]; - r.funcname = lua.to_luastring("hook"); + r.funcname = lua.to_luastring("hook", true); return r; } @@ -412,8 +455,8 @@ const funcnamefromcode = function(L, ci) { case 'OP_TAILCALL': return getobjname(p, pc, i.A); /* get function name */ case 'OP_TFORCALL': - r.name = lua.to_luastring("for iterator"); - r.funcname = lua.to_luastring("for iterator"); + r.name = lua.to_luastring("for iterator", true); + r.funcname = lua.to_luastring("for iterator", true); return r; /* other instructions can do calls through metamethods */ case 'OP_SELF': @@ -449,7 +492,7 @@ const funcnamefromcode = function(L, ci) { } r.name = L.l_G.tmname[tm]; - r.funcname = lua.to_luastring("metamethod"); + r.funcname = lua.to_luastring("metamethod", true); return r; }; @@ -473,7 +516,7 @@ const getupvalname = function(L, ci, o, name) { if (c.upvals[i].val(L) === o) { return { name: upvalname(c.p, i), - funcname: lua.to_luastring('upvalue') + funcname: lua.to_luastring('upvalue', true) }; } } @@ -501,7 +544,7 @@ const luaG_typeerror = function(L, o, op) { const luaG_concaterror = function(L, p1, p2) { if (p1.ttisstring() || p1.ttisnumber()) p1 = p2; - luaG_typeerror(L, p1, lua.to_luastring('concatenate')); + luaG_typeerror(L, p1, lua.to_luastring('concatenate', true)); }; /* @@ -563,6 +606,40 @@ const luaG_tointerror = function(L, p1, p2) { luaG_runerror(L, lua.to_luastring(`number${lobject.jsstring(varinfo(L, p2))} has no integer representation`)); }; +const luaG_traceexec = function(L) { + let ci = L.ci; + let mask = L.hookmask; + let counthook = (--L.hookcount === 0 && (mask & lua.LUA_MASKCOUNT)); + if (counthook) + L.hookcount = L.basehookcount; /* reset count */ + else if (!(mask & lua.LUA_MASKLINE)) + return; /* no line hook and count != 0; nothing to be done */ + if (ci.callstatus & lstate.CIST_HOOKYIELD) { /* called hook last time? */ + ci.callstatus &= ~lstate.CIST_HOOKYIELD; /* erase mark */ + return; /* do not call hook again (VM yielded, so it did not move) */ + } + if (counthook) + ldo.luaD_hook(L, lua.LUA_HOOKCOUNT, -1); /* call count hook */ + if (mask & lua.LUA_MASKLINE) { + let p = ci.func.p; + let npc = ci.pcOff; // pcRel(ci.u.l.savedpc, p); + let newline = p.lineinfo ? p.lineinfo[npc] : -1; + if (npc === 0 || /* call linehook when enter a new function, */ + ci.pcOff <= L.oldpc || /* when jump back (loop), or when */ + newline !== p.lineinfo ? p.lineinfo[L.oldpc] : -1) /* enter a new line */ + ldo.luaD_hook(L, lua.LUA_HOOKLINE, newline); /* call line hook */ + } + L.oldpc = ci.pcOff; + if (L.status === TS.LUA_YIELD) { /* did hook yield? */ + if (counthook) + L.hookcount = 1; /* undo decrement to zero */ + ci.u.l.savedpc--; /* undo increment (resume will increment it again) */ + ci.callstatus |= lstate.CIST_HOOKYIELD; /* mark that it yielded */ + ci.func = L.top - 1; /* protect stack below results */ + ldo.luaD_throw(L, TS.LUA_YIELD); + } +}; + module.exports.luaG_addinfo = luaG_addinfo; module.exports.luaG_concaterror = luaG_concaterror; module.exports.luaG_errormsg = luaG_errormsg; @@ -570,7 +647,13 @@ module.exports.luaG_opinterror = luaG_opinterror; module.exports.luaG_ordererror = luaG_ordererror; module.exports.luaG_runerror = luaG_runerror; module.exports.luaG_tointerror = luaG_tointerror; +module.exports.luaG_traceexec = luaG_traceexec; module.exports.luaG_typeerror = luaG_typeerror; +module.exports.lua_gethook = lua_gethook; +module.exports.lua_gethookcount = lua_gethookcount; +module.exports.lua_gethookmask = lua_gethookmask; module.exports.lua_getinfo = lua_getinfo; module.exports.lua_getlocal = lua_getlocal; module.exports.lua_getstack = lua_getstack; +module.exports.lua_sethook = lua_sethook; +module.exports.lua_setlocal = lua_setlocal; |