From 63be1b456e4ac32d5f4d32f3aad486e8b4007279 Mon Sep 17 00:00:00 2001 From: Benoit Giannangeli Date: Sun, 28 May 2017 15:19:41 +0200 Subject: ltests.js: listcode --- tests/test-suite/inprogress/code.js | 52 ++++++++++++++++++++++ tests/test-suite/ltests.js | 89 ++++++++++++++++++++++++++++--------- 2 files changed, 120 insertions(+), 21 deletions(-) (limited to 'tests/test-suite') diff --git a/tests/test-suite/inprogress/code.js b/tests/test-suite/inprogress/code.js index cc4b131..00ca53b 100644 --- a/tests/test-suite/inprogress/code.js +++ b/tests/test-suite/inprogress/code.js @@ -54,3 +54,55 @@ test("[test-suite] api: testing reuse in constant table", function (t) { }, "Lua program ran without error"); }); + + +const prefix = ` + function check (f, ...) + local arg = {...} + local c = T.listcode(f) + for i=1, #arg do + print(arg[i], c[i]) + assert(string.find(c[i], '- '..arg[i]..' *%d')) + end + assert(c[#arg+2] == nil) + end + + + function checkequal (a, b) + a = T.listcode(a) + b = T.listcode(b) + for i = 1, #a do + a[i] = string.gsub(a[i], '%b()', '') -- remove line number + b[i] = string.gsub(b[i], '%b()', '') -- remove line number + assert(a[i] == b[i]) + end + end +`; + +test("[test-suite] api: some basic instructions", function (t) { + let luaCode = ` + check(function () + (function () end){f()} + end, 'CLOSURE', 'NEWTABLE', 'GETTABUP', 'CALL', 'SETLIST', 'CALL', 'RETURN') + `, L; + + t.plan(2); + + t.doesNotThrow(function () { + + L = lauxlib.luaL_newstate(); + + lualib.luaL_openlibs(L); + + ltests.luaopen_tests(L); + + lauxlib.luaL_loadstring(L, lua.to_luastring(prefix + luaCode)); + + }, "Lua program loaded without error"); + + t.doesNotThrow(function () { + + lua.lua_call(L, 0, -1); + + }, "Lua program ran without error"); +}); diff --git a/tests/test-suite/ltests.js b/tests/test-suite/ltests.js index 1fe114c..9f10369 100644 --- a/tests/test-suite/ltests.js +++ b/tests/test-suite/ltests.js @@ -2,12 +2,13 @@ global.WEB = false; -const assert = require("assert"); +const assert = require("assert"); -const lua = require('../../src/lua.js'); -const lauxlib = require('../../src/lauxlib.js'); -const ljstype = require('../../src/ljstype.js'); -const lobject = require('../../src/lobject.js'); +const lua = require('../../src/lua.js'); +const lauxlib = require('../../src/lauxlib.js'); +const ljstype = require('../../src/ljstype.js'); +const lopcodes = require('../../src/lopcodes.js'); +const sprintf = require('sprintf-js').sprintf; const delimits = [" ", "\t", "\n", ",", ";"].map(e => e.charCodeAt(0)); @@ -784,11 +785,56 @@ const obj_at = function(L, k) { return L.stack[L.ci.funcOff + k].value.p; }; +const setnameval = function(L, name, val) { + lua.lua_pushstring(L, name); + lua.lua_pushinteger(L, val); + lua.lua_settable(L, -3); +}; + const pushobject = function(L, o){ L.stack[L.top++] = o; assert(L.top <= L.ci.top, "stack overflow"); }; +const buildop = function(p, pc) { + let i = p.code[pc]; + let o = lopcodes.GET_OPCODE(i); + let name = lopcodes.OpCodes[o]; + let line = p.lineinfo.length !== 0 ? p.lineinfo[pc] : -1; + let result = sprintf("(%4d) %4d - ", line, pc); //`(${line}) ${pc} - `; + switch (lopcodes.getOpMode(o)) { + case lopcodes.iABC: + result += sprintf("%-12s%4d %4d %4d", name, lopcodes.GETARG_A(i), lopcodes.GETARG_B(i), lopcodes.GETARG_C(i)); // `${name} ${lopcodes.GETARG_A(i)} ${lopcodes.GETARG_B(i)} ${lopcodes.GETARG_C(i)}`; + break; + case lopcodes.iABx: + result += sprintf("%-12s%4d %4d", name, lopcodes.GETARG_A(i), lopcodes.GETARG_Bx(i)); // `${name} ${lopcodes.GETARG_A(i)} ${lopcodes.GETARG_Bx(i)}`; + break; + case lopcodes.iAsBx: + result += sprintf("%-12s%4d %4d", name, lopcodes.GETARG_A(i), lopcodes.GETARG_sBx(i)); // `${name} ${lopcodes.GETARG_A(i)} ${lopcodes.GETARG_sBx(i)}`; + break; + case lopcodes.iAx: + result += sprintf("%-12s%4d", name, lopcodes.GETARG_Ax(i)); // `${name} ${lopcodes.GETARG_Ax(i)}`; + break; + } + + return lua.to_luastring(result); +}; + +const listcode = function(L) { + lauxlib.luaL_argcheck(L, lua.lua_isfunction(L, 1) && !lua.lua_iscfunction(L, 1), + 1, lua.to_luastring("Lua function expected", true)); + let p = obj_at(L, 1); + lua.lua_newtable(L); + setnameval(L, lua.to_luastring("maxstack", true), p.maxstacksize); + setnameval(L, lua.to_luastring("numparams", true), p.numparams); + for (let pc = 0; pc < p.code.length; pc++) { + lua.lua_pushinteger(L, pc+1); + lua.lua_pushstring(L, buildop(p, pc)); + lua.lua_settable(L, -3); + } + return 1; +}; + const listk = function(L) { lauxlib.luaL_argcheck(L, lua.lua_isfunction(L, 1) && !lua.lua_iscfunction(L, 1), @@ -803,23 +849,24 @@ const listk = function(L) { }; const tests_funcs = { - "checkpanic": checkpanic, - "closestate": closestate, - "d2s": d2s, - "doremote": doremote, - "listk": listk, - "loadlib": loadlib, - "makeCfunc": makeCfunc, - "newstate": newstate, - "newuserdata": newuserdata, + "checkpanic": checkpanic, + "closestate": closestate, + "d2s": d2s, + "doremote": doremote, + "listcode": listcode, + "listk": listk, + "loadlib": loadlib, + "makeCfunc": makeCfunc, + "newstate": newstate, + "newuserdata": newuserdata, "pushuserdata": pushuserdata, - "resume": coresume, - "s2d": s2d, - "sethook": sethook, - "testC": testJS, - "testJS": testJS, - "udataval": udataval, - "upvalue": upvalue + "resume": coresume, + "s2d": s2d, + "sethook": sethook, + "testC": testJS, + "testJS": testJS, + "udataval": udataval, + "upvalue": upvalue }; const luaB_opentests = function(L) { -- cgit v1.2.3-70-g09d2