diff options
-rw-r--r-- | src/ldebug.js | 26 | ||||
-rw-r--r-- | src/ldo.js | 16 | ||||
-rw-r--r-- | tests/ldblib.js | 2 | ||||
-rw-r--r-- | tests/test-suite/inprogress/db.js | 178 |
4 files changed, 100 insertions, 122 deletions
diff --git a/src/ldebug.js b/src/ldebug.js index 532fd9c..1c55264 100644 --- a/src/ldebug.js +++ b/src/ldebug.js @@ -116,7 +116,7 @@ const findlocal = function(L, ci, n) { base = ci.funcOff + 1; if (name === null) { /* no 'standard' name? */ - let limit = ci === L.ci ? L.top : ci.next.func; + let limit = ci === L.ci ? L.top : ci.next.funcOff; if (limit - base >= n && n > 0) /* is 'n' inside 'ci' stack? */ name = defs.to_luastring("(*temporary)", true); /* generic name for any valid slot */ else @@ -475,18 +475,18 @@ const funcnamefromcode = function(L, ci) { case OCi.OP_SETTABLE: tm = ltm.TMS.TM_NEWINDEX; break; - case OCi.OP_ADD: tm = ltm.TMS.OP_ADD; break; - case OCi.OP_SUB: tm = ltm.TMS.OP_SUB; break; - case OCi.OP_MUL: tm = ltm.TMS.OP_MUL; break; - case OCi.OP_MOD: tm = ltm.TMS.OP_MOD; break; - case OCi.OP_POW: tm = ltm.TMS.OP_POW; break; - case OCi.OP_DIV: tm = ltm.TMS.OP_DIV; break; - case OCi.OP_IDIV: tm = ltm.TMS.OP_IDI; break; - case OCi.OP_BAND: tm = ltm.TMS.OP_BAN; break; - case OCi.OP_BOR: tm = ltm.TMS.OP_BOR; break; - case OCi.OP_BXOR: tm = ltm.TMS.OP_BXO; break; - case OCi.OP_SHL: tm = ltm.TMS.OP_SHL; break; - case OCi.OP_SHR: tm = ltm.TMS.OP_SHR; break; + case OCi.OP_ADD: tm = ltm.TMS.TM_ADD; break; + case OCi.OP_SUB: tm = ltm.TMS.TM_SUB; break; + case OCi.OP_MUL: tm = ltm.TMS.TM_MUL; break; + case OCi.OP_MOD: tm = ltm.TMS.TM_MOD; break; + case OCi.OP_POW: tm = ltm.TMS.TM_POW; break; + case OCi.OP_DIV: tm = ltm.TMS.TM_DIV; break; + case OCi.OP_IDIV: tm = ltm.TMS.TM_IDIV; break; + case OCi.OP_BAND: tm = ltm.TMS.TM_BAND; break; + case OCi.OP_BOR: tm = ltm.TMS.TM_BOR; break; + case OCi.OP_BXOR: tm = ltm.TMS.TM_BXOR; break; + case OCi.OP_SHL: tm = ltm.TMS.TM_SHL; break; + case OCi.OP_SHR: tm = ltm.TMS.TM_SHR; break; case OCi.OP_UNM: tm = ltm.TMS.TM_UNM; break; case OCi.OP_BNOT: tm = ltm.TMS.TM_BNOT; break; case OCi.OP_LEN: tm = ltm.TMS.TM_LEN; break; @@ -9,6 +9,7 @@ const ldebug = require('./ldebug.js'); const lfunc = require('./lfunc.js'); const llimit = require('./llimit.js'); const lobject = require('./lobject.js'); +const lopcodes= require('./lopcodes.js'); const lparser = require('./lparser.js'); const lstate = require('./lstate.js'); const lstring = require('./lstring.js'); @@ -173,7 +174,8 @@ const luaD_precall = function(L, off, nresults) { ci.l_code = p.code; ci.l_savedpc = 0; ci.callstatus = lstate.CIST_LUA; - + if (L.hookmask & defs.LUA_MASKCALL) + callhook(L, ci); return false; } default: @@ -272,6 +274,18 @@ const luaD_hook = function(L, event, line) { } }; +const callhook = function(L, ci) { + let hook = defs.LUA_HOOKCALL; + ci.l_savedpc++; /* hooks assume 'pc' is already incremented */ + if ((ci.previous.callstatus & lstate.CIST_LUA) && + ci.previous.l_code[ci.previous.l_savedpc - 1].opcode == lopcodes.OpCodesI.OP_TAILCALL) { + ci.callstatus |= lstate.CIST_TAIL; + hook = defs.LUA_HOOKTAILCALL; + } + luaD_hook(L, hook, -1); + ci.l_savedpc--; /* correct 'pc' */ +}; + const adjust_varargs = function(L, p, actual) { let nfixargs = p.numparams; /* move fixed parameters to final position */ diff --git a/tests/ldblib.js b/tests/ldblib.js index 82d40c2..7f39c09 100644 --- a/tests/ldblib.js +++ b/tests/ldblib.js @@ -44,7 +44,7 @@ test('debug.sethook', function (t) { t.strictEqual( lua.lua_tojsstring(L, -1), - "return count line count line count line count line return count line count line count line return count line count line count line return count line ", + "return count line count line count line call count line return count line count line call count line return count line count line call count line return count line ", "Correct element(s) on the stack" ); diff --git a/tests/test-suite/inprogress/db.js b/tests/test-suite/inprogress/db.js index 2481096..b6ac68b 100644 --- a/tests/test-suite/inprogress/db.js +++ b/tests/test-suite/inprogress/db.js @@ -12,9 +12,9 @@ const lualib = require('../../../src/lualib.js'); const prefix = ` local function dostring(s) return assert(load(s))() end - local testline = 4 -- line where 'test' is defined - function test (s, l, p) -- this must be line 4 - -- collectgarbage() -- avoid gc during trace + local testline = 5 -- line where 'test' is defined + function test (s, l, p) -- this must be line 5 + local a = 1 -- do something that's active instead of collectgarbage() local function f (event, line) assert(event == 'line') local l = table.remove(l, 1) @@ -27,54 +27,22 @@ const prefix = ` `; test("[test-suite] db: getinfo, ...line...", function (t) { - let luaCode = `-- $Id: db.lua,v 1.79 2016/11/07 13:02:34 roberto Exp $ - -- See Copyright Notice in file all.lua - - -- testing debug library - - local debug = require "debug" - - local function dostring(s) return assert(load(s))() end - - print"testing debug library and debug information" - - do - local a=1 - end - - assert(not debug.gethook()) - - local testline = 19 -- line where 'test' is defined - function test (s, l, p) -- this must be line 19 - collectgarbage() -- avoid gc during trace - local function f (event, line) - assert(event == 'line') - local l = table.remove(l, 1) - if p then print(l, line) end - assert(l == line, "wrong trace!!") - end - debug.sethook(f,"l"); load(s)(); debug.sethook() - assert(#l == 0) - end - - - do - assert(not pcall(debug.getinfo, print, "X")) -- invalid option - assert(not debug.getinfo(1000)) -- out of range level - assert(not debug.getinfo(-1)) -- out of range level - local a = debug.getinfo(print) - assert(a.what == "J" and a.short_src == "[JS]") - a = debug.getinfo(print, "L") - assert(a.activelines == nil) - local b = debug.getinfo(test, "SfL") - assert(b.name == nil and b.what == "Lua" and b.linedefined == testline and - b.lastlinedefined == b.linedefined + 10 and - b.func == test and string.find(b.short_src, "%[")) - assert(b.activelines[b.linedefined + 1] and - b.activelines[b.lastlinedefined]) - assert(not b.activelines[b.linedefined] and - not b.activelines[b.lastlinedefined + 1]) - end + let luaCode = ` + assert(not pcall(debug.getinfo, print, "X")) -- invalid option + assert(not debug.getinfo(1000)) -- out of range level + assert(not debug.getinfo(-1)) -- out of range level + local a = debug.getinfo(print) + assert(a.what == "J" and a.short_src == "[JS]") + a = debug.getinfo(print, "L") + assert(a.activelines == nil) + local b = debug.getinfo(test, "SfL") + assert(b.name == nil and b.what == "Lua" and b.linedefined == testline and + b.lastlinedefined == b.linedefined + 10 and + b.func == test and string.find(b.short_src, "%[")) + assert(b.activelines[b.linedefined + 1] and + b.activelines[b.lastlinedefined]) + assert(not b.activelines[b.linedefined] and + not b.activelines[b.lastlinedefined + 1]) `, L; t.plan(2); @@ -85,7 +53,7 @@ test("[test-suite] db: getinfo, ...line...", function (t) { lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(luaCode)); + lauxlib.luaL_loadstring(L, lua.to_luastring(prefix + luaCode)); }, "Lua program loaded without error"); @@ -133,7 +101,7 @@ test("[test-suite] db: test file ad string names truncation", function (t) { lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(prefix + luaCode)); + lauxlib.luaL_loadstring(L, lua.to_luastring(luaCode)); }, "Lua program loaded without error"); @@ -192,7 +160,7 @@ test("[test-suite] db: local", function (t) { lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(prefix + luaCode)); + lauxlib.luaL_loadstring(L, lua.to_luastring(luaCode)); }, "Lua program loaded without error"); @@ -297,7 +265,7 @@ test("[test-suite] db: invalid levels in [gs]etlocal", function (t) { lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(prefix + luaCode)); + lauxlib.luaL_loadstring(L, lua.to_luastring(luaCode)); }, "Lua program loaded without error"); @@ -333,7 +301,7 @@ test("[test-suite] db: parameter names", function (t) { lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(prefix + luaCode)); + lauxlib.luaL_loadstring(L, lua.to_luastring(luaCode)); }, "Lua program loaded without error"); @@ -382,7 +350,7 @@ test("[test-suite] db: vararg", function (t) { lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(prefix + luaCode)); + lauxlib.luaL_loadstring(L, lua.to_luastring(luaCode)); }, "Lua program loaded without error"); @@ -409,7 +377,7 @@ test("[test-suite] db: access to vararg in non-vararg function", function (t) { lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(prefix + luaCode)); + lauxlib.luaL_loadstring(L, lua.to_luastring(luaCode)); }, "Lua program loaded without error"); @@ -506,7 +474,6 @@ test("[test-suite] db: test hook presence in debug info", function (t) { g() - print(a[f], a[g], a[assert], a[debug.getlocal], a[print]) assert(a[f] and a[g] and a[assert] and a[debug.getlocal] and not a[print]) `, L; @@ -518,7 +485,7 @@ test("[test-suite] db: test hook presence in debug info", function (t) { lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(prefix + luaCode)); + lauxlib.luaL_loadstring(L, lua.to_luastring(luaCode)); }, "Lua program loaded without error"); @@ -564,7 +531,7 @@ test("[test-suite] db: tests for manipulating non-registered locals (C and Lua t lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(prefix + luaCode)); + lauxlib.luaL_loadstring(L, lua.to_luastring(luaCode)); }, "Lua program loaded without error"); @@ -684,7 +651,7 @@ test("[test-suite] db: testing access to local variables in return hook (bug in lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(prefix + luaCode)); + lauxlib.luaL_loadstring(L, lua.to_luastring(luaCode)); }, "Lua program loaded without error"); @@ -736,7 +703,7 @@ test("[test-suite] db: testing upvalue access", function (t) { lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(prefix + luaCode)); + lauxlib.luaL_loadstring(L, lua.to_luastring(luaCode)); }, "Lua program loaded without error"); @@ -778,7 +745,7 @@ test("[test-suite] db: testing count hooks", function (t) { lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(prefix + luaCode)); + lauxlib.luaL_loadstring(L, lua.to_luastring(luaCode)); }, "Lua program loaded without error"); @@ -857,7 +824,7 @@ test("[test-suite] db: tests for tail calls", function (t) { lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(prefix + luaCode)); + lauxlib.luaL_loadstring(L, lua.to_luastring(luaCode)); }, "Lua program loaded without error"); @@ -899,7 +866,7 @@ test("[test-suite] db: testing local function information", function (t) { lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(prefix + luaCode)); + lauxlib.luaL_loadstring(L, lua.to_luastring(luaCode)); }, "Lua program loaded without error"); @@ -936,7 +903,7 @@ test("[test-suite] db: testing traceback", function (t) { lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(prefix + luaCode)); + lauxlib.luaL_loadstring(L, lua.to_luastring(luaCode)); }, "Lua program loaded without error"); @@ -973,7 +940,7 @@ test("[test-suite] db: testing nparams, nups e isvararg", function (t) { lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(prefix + luaCode)); + lauxlib.luaL_loadstring(L, lua.to_luastring(luaCode)); }, "Lua program loaded without error"); @@ -1064,7 +1031,7 @@ test("[test-suite] db: testing debugging of coroutines", function (t) { lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(prefix + luaCode)); + lauxlib.luaL_loadstring(L, lua.to_luastring(luaCode)); }, "Lua program loaded without error"); @@ -1103,7 +1070,7 @@ test("[test-suite] db: check get/setlocal in coroutines", function (t) { lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(prefix + luaCode)); + lauxlib.luaL_loadstring(L, lua.to_luastring(luaCode)); }, "Lua program loaded without error"); @@ -1150,7 +1117,7 @@ test("[test-suite] db: check traceback of suspended (or dead with error) corouti lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(prefix + luaCode)); + lauxlib.luaL_loadstring(L, lua.to_luastring(luaCode)); }, "Lua program loaded without error"); @@ -1193,7 +1160,7 @@ test("[test-suite] db: check test acessing line numbers of a coroutine from a re lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(prefix + luaCode)); + lauxlib.luaL_loadstring(L, lua.to_luastring(luaCode)); }, "Lua program loaded without error"); @@ -1245,7 +1212,7 @@ test("[test-suite] db: test tagmethod information", function (t) { lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(prefix + luaCode)); + lauxlib.luaL_loadstring(L, lua.to_luastring(luaCode)); }, "Lua program loaded without error"); @@ -1277,7 +1244,7 @@ test("[test-suite] db: testing for-iterator name", function (t) { lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(prefix + luaCode)); + lauxlib.luaL_loadstring(L, lua.to_luastring(luaCode)); }, "Lua program loaded without error"); @@ -1292,42 +1259,39 @@ test("[test-suite] db: testing for-iterator name", function (t) { test("[test-suite] db: testing traceback sizes", function (t) { let luaCode = ` - do - local function countlines (s) - return select(2, string.gsub(s, "\n", "")) - end + local function countlines (s) + return select(2, string.gsub(s, "\\n", "")) + end - local function deep (lvl, n) - if lvl == 0 then - return (debug.traceback("message", n)) - else - return (deep(lvl-1, n)) - end + local function deep (lvl, n) + if lvl == 0 then + return (debug.traceback("message", n)) + else + return (deep(lvl-1, n)) end + end - local function checkdeep (total, start) - local s = deep(total, start) - local rest = string.match(s, "^message\nstack traceback:\n(.*)$") - local cl = countlines(rest) - -- at most 10 lines in first part, 11 in second, plus '...' - assert(cl <= 10 + 11 + 1) - local brk = string.find(rest, "%.%.%.") - if brk then -- does message have '...'? - local rest1 = string.sub(rest, 1, brk) - local rest2 = string.sub(rest, brk, #rest) - assert(countlines(rest1) == 10 and countlines(rest2) == 11) - else - assert(cl == total - start + 2) - end + local function checkdeep (total, start) + local s = deep(total, start) + local rest = string.match(s, "^message\\nstack traceback:\\n(.*)$") + local cl = countlines(rest) + -- at most 10 lines in first part, 11 in second, plus '...' + assert(cl <= 10 + 11 + 1) + local brk = string.find(rest, "%.%.%.") + if brk then -- does message have '...'? + local rest1 = string.sub(rest, 1, brk) + local rest2 = string.sub(rest, brk, #rest) + assert(countlines(rest1) == 10 and countlines(rest2) == 11) + else + assert(cl == total - start + 2) end + end - for d = 1, 51, 10 do - for l = 1, d do - -- use coroutines to ensure complete control of the stack - coroutine.wrap(checkdeep)(d, l) - end + for d = 1, 51, 10 do + for l = 1, d do + -- use coroutines to ensure complete control of the stack + coroutine.wrap(checkdeep)(d, l) end - end `, L; @@ -1339,7 +1303,7 @@ test("[test-suite] db: testing traceback sizes", function (t) { lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(prefix + luaCode)); + lauxlib.luaL_loadstring(L, lua.to_luastring(luaCode)); }, "Lua program loaded without error"); @@ -1406,7 +1370,7 @@ test("[test-suite] db: testing debug functions on chunk without debug info", fun lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(prefix + luaCode)); + lauxlib.luaL_loadstring(L, lua.to_luastring(luaCode)); }, "Lua program loaded without error"); @@ -1462,7 +1426,7 @@ test("[test-suite] db: tests for 'source' in binary dumps", function (t) { lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(prefix + luaCode)); + lauxlib.luaL_loadstring(L, lua.to_luastring(luaCode)); }, "Lua program loaded without error"); |