summaryrefslogtreecommitdiff
path: root/tests/test-suite/inprogress/code.js
diff options
context:
space:
mode:
Diffstat (limited to 'tests/test-suite/inprogress/code.js')
-rw-r--r--tests/test-suite/inprogress/code.js450
1 files changed, 448 insertions, 2 deletions
diff --git a/tests/test-suite/inprogress/code.js b/tests/test-suite/inprogress/code.js
index 00ca53b..e7ff501 100644
--- a/tests/test-suite/inprogress/code.js
+++ b/tests/test-suite/inprogress/code.js
@@ -11,7 +11,7 @@ const lualib = require('../../../src/lualib.js');
const ltests = require('../ltests.js');
-test("[test-suite] api: testing reuse in constant table", function (t) {
+test("[test-suite] code: testing reuse in constant table", function (t) {
let luaCode = `
local function checkKlist (func, list)
local k = T.listk(func)
@@ -79,7 +79,7 @@ const prefix = `
end
`;
-test("[test-suite] api: some basic instructions", function (t) {
+test("[test-suite] code: some basic instructions", function (t) {
let luaCode = `
check(function ()
(function () end){f()}
@@ -106,3 +106,449 @@ test("[test-suite] api: some basic instructions", function (t) {
}, "Lua program ran without error");
});
+
+
+test("[test-suite] code: sequence of LOADNILs", function (t) {
+ let luaCode = `
+ check(function ()
+ local a,b,c
+ local d; local e;
+ local f,g,h;
+ d = nil; d=nil; b=nil; a=nil; c=nil;
+ end, 'LOADNIL', 'RETURN')
+
+ check(function ()
+ local a,b,c,d = 1,1,1,1
+ d=nil;c=nil;b=nil;a=nil
+ end, 'LOADK', 'LOADK', 'LOADK', 'LOADK', 'LOADNIL', 'RETURN')
+
+ do
+ local a,b,c,d = 1,1,1,1
+ d=nil;c=nil;b=nil;a=nil
+ assert(a == nil and b == nil and c == nil and d == nil)
+ end
+ `, 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");
+});
+
+
+test("[test-suite] code: single return", function (t) {
+ let luaCode = `
+ check (function (a,b,c) return a end, '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");
+});
+
+
+test("[test-suite] code: infinite loops", function (t) {
+ let luaCode = `
+ check(function () while true do local a = -1 end end,
+ 'LOADK', 'JMP', 'RETURN')
+
+ check(function () while 1 do local a = -1 end end,
+ 'LOADK', 'JMP', 'RETURN')
+
+ check(function () repeat local x = 1 until true end,
+ 'LOADK', '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");
+});
+
+
+test("[test-suite] code: concat optimization", function (t) {
+ let luaCode = `
+ check(function (a,b,c,d) return a..b..c..d end,
+ 'MOVE', 'MOVE', 'MOVE', 'MOVE', 'CONCAT', '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");
+});
+
+
+test("[test-suite] code: not", function (t) {
+ let luaCode = `
+ check(function () return not not nil end, 'LOADBOOL', 'RETURN')
+ check(function () return not not false end, 'LOADBOOL', 'RETURN')
+ check(function () return not not true end, 'LOADBOOL', 'RETURN')
+ check(function () return not not 1 end, 'LOADBOOL', '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");
+});
+
+
+test("[test-suite] code: direct access to locals", function (t) {
+ let luaCode = `
+ check(function ()
+ local a,b,c,d
+ a = b*2
+ c[2], a[b] = -((a + d/2 - a[b]) ^ a.x), b
+ end,
+ 'LOADNIL',
+ 'MUL',
+ 'DIV', 'ADD', 'GETTABLE', 'SUB', 'GETTABLE', 'POW',
+ 'UNM', 'SETTABLE', 'SETTABLE', '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");
+});
+
+
+test("[test-suite] code: direct access to constants", function (t) {
+ let luaCode = `
+ check(function ()
+ local a,b
+ a.x = 3.2
+ a.x = b
+ a[b] = 'x'
+ end,
+ 'LOADNIL', 'SETTABLE', 'SETTABLE', 'SETTABLE', 'RETURN')
+
+ check(function ()
+ local a,b
+ a = 1 - a
+ b = 1/a
+ b = 5-4
+ end,
+ 'LOADNIL', 'SUB', 'DIV', 'LOADK', 'RETURN')
+
+ check(function ()
+ local a,b
+ a[true] = false
+ end,
+ 'LOADNIL', 'SETTABLE', '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");
+});
+
+
+test("[test-suite] code: constant folding", function (t) {
+ let luaCode = `
+ local function checkK (func, val)
+ check(func, 'LOADK', 'RETURN')
+ local k = T.listk(func)
+ assert(#k == 1 and k[1] == val and math.type(k[1]) == math.type(val))
+ assert(func() == val)
+ end
+ checkK(function () return 0.0 end, 0.0)
+ checkK(function () return 0 end, 0)
+ checkK(function () return -0//1 end, 0)
+ checkK(function () return 3^-1 end, 1/3)
+ checkK(function () return (1 + 1)^(50 + 50) end, 2^100)
+ checkK(function () return (-2)^(31 - 2) end, -0x20000000 + 0.0)
+ checkK(function () return (-3^0 + 5) // 3.0 end, 1.0)
+ checkK(function () return -3 % 5 end, 2)
+ checkK(function () return -((2.0^8 + -(-1)) % 8)/2 * 4 - 3 end, -5.0)
+ checkK(function () return -((2^8 + -(-1)) % 8)//2 * 4 - 3 end, -7.0)
+ checkK(function () return 0xF0.0 | 0xCC.0 ~ 0xAA & 0xFD end, 0xF4)
+ checkK(function () return ~(~0xFF0 | 0xFF0) end, 0)
+ checkK(function () return ~~-100024.0 end, -100024)
+ checkK(function () return ((100 << 6) << -4) >> 2 end, 100)
+ `, 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");
+});
+
+
+test("[test-suite] code: no folding", function (t) {
+ let luaCode = `
+ check(function () return -0.0 end, 'LOADK', 'UNM', 'RETURN')
+ check(function () return 3/0 end, 'DIV', 'RETURN')
+ check(function () return 0%0 end, 'MOD', 'RETURN')
+ check(function () return -4//0 end, 'IDIV', '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");
+});
+
+
+test("[test-suite] code: bug in constant folding for 5.1", function (t) {
+ let luaCode = `
+ check(function () return -nil end, 'LOADNIL', 'UNM', 'RETURN')
+
+
+ check(function ()
+ local a,b,c
+ b[c], a = c, b
+ b[a], a = c, b
+ a, b = c, a
+ a = a
+ end,
+ 'LOADNIL',
+ 'MOVE', 'MOVE', 'SETTABLE',
+ 'MOVE', 'MOVE', 'MOVE', 'SETTABLE',
+ 'MOVE', 'MOVE', 'MOVE',
+ -- no code for a = a
+ '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");
+});
+
+
+test("[test-suite] code: x == nil , x ~= nil", function (t) {
+ let luaCode = `
+ checkequal(function () if (a==nil) then a=1 end; if a~=nil then a=1 end end,
+ function () if (a==9) then a=1 end; if a~=9 then a=1 end end)
+
+ check(function () if a==nil then a='a' end end,
+ 'GETTABUP', 'EQ', 'JMP', 'SETTABUP', 'RETURN')
+
+ checkequal(function () local a; if not (a or b) then b=a end end,
+ function () local a; if (not a and not b) then b=a end end)
+
+ checkequal(function (l) local a; return 0 <= a and a <= l end,
+ function (l) local a; return not (not(a >= 0) or not(a <= l)) end)
+ `, 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");
+});
+
+
+test("[test-suite] code: if-goto optimizations", function (t) {
+ let luaCode = `
+ check(function (a, b, c, d, e)
+ if a == b then goto l1
+ elseif a == c then goto l2
+ elseif a == d then goto l2
+ else if a == e then goto l3
+ else goto l3
+ end
+ end
+ ::l1:: ::l2:: ::l3:: ::l4::
+ end, 'EQ', 'JMP', 'EQ', 'JMP', 'EQ', 'JMP', 'EQ', 'JMP', 'JMP', 'RETURN')
+
+ checkequal(
+ function (a) while a < 10 do a = a + 1 end end,
+ function (a) ::L2:: if not(a < 10) then goto L1 end; a = a + 1;
+ goto L2; ::L1:: end
+ )
+
+ checkequal(
+ function (a) while a < 10 do a = a + 1 end end,
+ function (a) while true do if not(a < 10) then break end; a = a + 1; end end
+ )
+ `, 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");
+});