summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBenoit Giannangeli <giann008@gmail.com>2017-05-28 15:19:41 +0200
committerBenoit Giannangeli <giann008@gmail.com>2017-05-28 15:39:20 +0200
commit63be1b456e4ac32d5f4d32f3aad486e8b4007279 (patch)
treef225c8819f3deb1b3d3123ea26187a182c4425ac
parent42404e2251ce2390b08ef920018a0029e914c69d (diff)
downloadfengari-63be1b456e4ac32d5f4d32f3aad486e8b4007279.tar.gz
fengari-63be1b456e4ac32d5f4d32f3aad486e8b4007279.tar.bz2
fengari-63be1b456e4ac32d5f4d32f3aad486e8b4007279.zip
ltests.js: listcode
-rw-r--r--tests/test-suite/inprogress/code.js52
-rw-r--r--tests/test-suite/ltests.js89
2 files changed, 120 insertions, 21 deletions
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) {