aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBenoit Giannangeli <giann008@gmail.com>2017-03-12 16:48:53 +0100
committerBenoit Giannangeli <giann@users.noreply.github.com>2017-03-13 11:03:24 +0100
commit2a6993bf0e23e2a3759abb9d7127525577dc346c (patch)
tree2b605f78ee91ca242770c1573d1c2138677fd66b
parent4c404c404c281f1872f0283acbaee97657f3e08b (diff)
downloadfengari-2a6993bf0e23e2a3759abb9d7127525577dc346c.tar.gz
fengari-2a6993bf0e23e2a3759abb9d7127525577dc346c.tar.bz2
fengari-2a6993bf0e23e2a3759abb9d7127525577dc346c.zip
Testing 8-bit strings
-rw-r--r--src/lapi.js3
-rw-r--r--src/ldo.js2
-rw-r--r--src/llex.js2
-rw-r--r--src/lobject.js6
-rw-r--r--src/lparser.js12
-rw-r--r--src/ltm.js32
-rw-r--r--src/lua.js6
-rw-r--r--src/lvm.js29
-rw-r--r--tests/lexparse.js10
-rw-r--r--tests/ltm.js867
-rw-r--r--tests/lvm.js62
-rw-r--r--tests/tests.js1
12 files changed, 281 insertions, 751 deletions
diff --git a/src/lapi.js b/src/lapi.js
index 79cd6fb..96fe207 100644
--- a/src/lapi.js
+++ b/src/lapi.js
@@ -231,7 +231,6 @@ const lua_pushstring = function (L, s) {
else {
let ts = L.l_G.intern(lua.to_luastring(s));
L.stack[L.top] = ts;
- s = ts.value;
}
L.top++;
@@ -537,7 +536,7 @@ const lua_tolstring = function(L, idx) {
if (!o.ttisstring() && !o.ttisnumber())
return null;
- return o.ttisstring() ? String.fromCharCode(...o.value) : `${o.value}`;
+ return o.ttisstring() ? o.jsstring() : `${o.value}`;
};
const lua_tostring = lua_tolstring;
diff --git a/src/ldo.js b/src/ldo.js
index e088d8d..7df4c62 100644
--- a/src/ldo.js
+++ b/src/ldo.js
@@ -532,7 +532,7 @@ const f_parser = function(L, p) {
let c = p.z.getc(); /* read first character */
if (String.fromCharCode(c) === lua.LUA_SIGNATURE.charAt(0)) {
checkmode(L, p.mode, "binary");
- cl = new BytecodeParser(L, p.z.buffer);
+ cl = new BytecodeParser(L, p.z.buffer).luaU_undump();
} else {
checkmode(L, p.mode, "text");
cl = lparser.luaY_parser(L, p.z, p.buff, p.dyd, p.name, c);
diff --git a/src/llex.js b/src/llex.js
index fc3603f..e747fdd 100644
--- a/src/llex.js
+++ b/src/llex.js
@@ -596,7 +596,7 @@ const llex = function(ls, seminfo) {
let ts = new TValue(CT.LUA_TLNGSTR, lua.to_luastring(ls.buff.buffer.join('')));
seminfo.ts = ts;
- let kidx = luaX_tokens.slice(0, 22).indexOf(ts.value);
+ let kidx = luaX_tokens.slice(0, 22).indexOf(ts.jsstring());
if (kidx >= 0) /* reserved word? */
return kidx + FIRST_RESERVED;
else
diff --git a/src/lobject.js b/src/lobject.js
index 92dd560..739db50 100644
--- a/src/lobject.js
+++ b/src/lobject.js
@@ -110,6 +110,10 @@ class TValue {
return this.ttisnil() || (this.ttisboolean() && this.value === false);
}
+ jsstring() {
+ return this.ttisstring() ? String.fromCharCode(...this.value) : null;
+ }
+
}
const nil = new TValue(CT.LUA_TNIL, null);
@@ -133,6 +137,8 @@ class Table extends TValue {
} else if ([CT.LUA_TSHRSTR, CT.LUA_TLNGSTR].indexOf(key.type) > -1) {
key = key.value.map(e => `${e}|`).join('');
}
+ } else if (typeof key === "string") { // To avoid
+ key = lua.to_luastring(key).map(e => `${e}|`).join('');
}
return key;
diff --git a/src/lparser.js b/src/lparser.js
index 42337cc..1806bbe 100644
--- a/src/lparser.js
+++ b/src/lparser.js
@@ -273,7 +273,7 @@ const removevars = function(fs, tolevel) {
const searchupvalue = function(fs, name) {
let up = fs.f.upvalues;
for (let i = 0; i < fs.nups; i++) {
- if (up[i].name.value === name.value)
+ if (up[i].name.jsstring() === name.jsstring())
return i;
}
return -1; /* not found */
@@ -291,7 +291,7 @@ const newupvalue = function(fs, name, v) {
const searchvar = function(fs, n) {
for (let i = fs.nactvar - 1; i >= 0; i--) {
- if (n.value === getlocvar(fs, i).varname.value)
+ if (n.jsstring() === getlocvar(fs, i).varname.jsstring())
return i;
}
@@ -383,7 +383,7 @@ const closegoto = function(ls, g, label) {
let fs = ls.fs;
let gl = ls.dyd.gt;
let gt = gl.arr[g];
- assert(gt.name.value === label.name.value);
+ assert(gt.name.jsstring() === label.name.jsstring());
if (gt.nactvar < label.nactvar) {
let vname = getlocvar(fs, gt.nactvar).varname;
semerror(ls, `<goto ${gt.name.value}> at line ${gt.line} jumps into the scope of local '${vname.value}'`);
@@ -405,7 +405,7 @@ const findlabel = function(ls, g) {
/* check labels in current block for a match */
for (let i = bl.firstlabel; i < dyd.label.n; i++) {
let lb = dyd.label.arr[i];
- if (lb.name.value === gt.name.value) { /* correct label? */
+ if (lb.name.jsstring() === gt.name.jsstring()) { /* correct label? */
if (gt.nactvar > lb.nactvar && (bl.upval || dyd.label.n > bl.firstlabel))
lcode.luaK_patchclose(ls.fs, gt.pc, lb.nactvar);
closegoto(ls, g, lb); /* close it */
@@ -434,7 +434,7 @@ const findgotos = function(ls, lb) {
let gl = ls.dyd.gt;
let i = ls.fs.bl.firstgoto;
while (i < gl.n) {
- if (gl.arr[i].name.value === lb.name.value)
+ if (gl.arr[i].name.jsstring() === lb.name.jsstring())
closegoto(ls, i, lb);
else
i++;
@@ -1150,7 +1150,7 @@ const gotostat = function(ls, pc) {
/* check for repeated labels on the same block */
const checkrepeated = function(fs, ll, label) {
for (let i = fs.bl.firstlabel; i < ll.n; i++) {
- if (label.value === ll.arr[i].name.value) {
+ if (label.jsstring() === ll.arr[i].name.jsstring()) {
semerror(fs.ls, `label '${label}' already defined on line ${ll.arr[i].line}`);
}
}
diff --git a/src/ltm.js b/src/ltm.js
index 51ab8ec..6377c93 100644
--- a/src/ltm.js
+++ b/src/ltm.js
@@ -38,8 +38,34 @@ const TMS = {
TM_LT: "__lt",
TM_LE: "__le",
TM_CONCAT: "__concat",
- TM_CALL: "__call",
- TM_N: 26
+ TM_CALL: "__call"
+};
+
+const TMS8 = {
+ TM_INDEX: lua.to_luastring(TMS.TM_INDEX),
+ TM_NEWINDEX: lua.to_luastring(TMS.TM_NEWINDEX),
+ TM_GC: lua.to_luastring(TMS.TM_GC),
+ TM_MODE: lua.to_luastring(TMS.TM_MODE),
+ TM_LEN: lua.to_luastring(TMS.TM_LEN),
+ TM_EQ: lua.to_luastring(TMS.TM_EQ), /* last tag method with fast access */
+ TM_ADD: lua.to_luastring(TMS.TM_ADD),
+ TM_SUB: lua.to_luastring(TMS.TM_SUB),
+ TM_MUL: lua.to_luastring(TMS.TM_MUL),
+ TM_MOD: lua.to_luastring(TMS.TM_MOD),
+ TM_POW: lua.to_luastring(TMS.TM_POW),
+ TM_DIV: lua.to_luastring(TMS.TM_DIV),
+ TM_IDIV: lua.to_luastring(TMS.TM_IDIV),
+ TM_BAND: lua.to_luastring(TMS.TM_BAND),
+ TM_BOR: lua.to_luastring(TMS.TM_BOR),
+ TM_BXOR: lua.to_luastring(TMS.TM_BXOR),
+ TM_SHL: lua.to_luastring(TMS.TM_SHL),
+ TM_SHR: lua.to_luastring(TMS.TM_SHR),
+ TM_UNM: lua.to_luastring(TMS.TM_UNM),
+ TM_BNOT: lua.to_luastring(TMS.TM_BNOT),
+ TM_LT: lua.to_luastring(TMS.TM_LT),
+ TM_LE: lua.to_luastring(TMS.TM_LE),
+ TM_CONCAT: lua.to_luastring(TMS.TM_CONCAT),
+ TM_CALL: lua.to_luastring(TMS.TM_CALL)
};
const luaT_typenames_ = [
@@ -77,7 +103,7 @@ const luaT_objtypename = function(L, o) {
|| (o.ttisfulluserdata() && o.metatable !== null)) {
let name = o.__index(o, '__name');
if (name.ttisstring())
- return String.fromCharCode(...name.value);
+ return name.jsstring();
}
return ttypename(o.ttnov());
diff --git a/src/lua.js b/src/lua.js
index 12d4e65..08bad58 100644
--- a/src/lua.js
+++ b/src/lua.js
@@ -133,8 +133,8 @@ class lua_Debug {
}
const to_luastring = function(str, maxBytesToWrite) {
- maxBytesToWrite = maxBytesToWrite !== undefined ? maxBytesToWrite : str.length;
- let outU8Array = new Array(maxBytesToWrite);
+ maxBytesToWrite = maxBytesToWrite !== undefined ? maxBytesToWrite : str.length + 1;
+ let outU8Array = [];
if (!(maxBytesToWrite > 0)) // Parameter maxBytesToWrite is not optional. Negative values, 0, null, undefined and false each don't write out any bytes.
return 0;
@@ -184,7 +184,7 @@ const to_luastring = function(str, maxBytesToWrite) {
}
}
// Null-terminate the pointer to the buffer.
- outU8Array[outIdx] = 0;
+ // outU8Array[outIdx] = 0;
return outU8Array;
};
diff --git a/src/lvm.js b/src/lvm.js
index 3cf3fb6..873cd20 100644
--- a/src/lvm.js
+++ b/src/lvm.js
@@ -856,8 +856,7 @@ const luaV_tointeger = function(obj, mode) {
} else if (obj.ttisinteger()) {
return obj.value|0;
} else if (obj.ttisstring()) {
- let str = String.fromCharCode(...obj.value);
- return luaV_tointeger(new TValue(CT.LUA_TNUMFLT, parseFloat(str)), mode); // TODO: luaO_str2num
+ return luaV_tointeger(new TValue(CT.LUA_TNUMFLT, parseFloat(obj.jsstring())), mode); // TODO: luaO_str2num
}
return false;
@@ -921,8 +920,8 @@ const LTintfloat = function(l, r) {
const l_strcmp = function(ls, rs) {
// TODO: lvm.c:248 static int l_strcmp (const TString *ls, const TString *rs)
- ls = String.fromCharCode(...ls.value);
- rs = String.fromCharCode(...rs.value);
+ ls = ls.jsstring();
+ rs = rs.jsstring();
return ls === rs ? 0 : (ls < rs ? -1 : 1);
};
@@ -955,11 +954,11 @@ const luaV_objlen = function(L, ra, rb) {
const tostring = function(L, i) {
let o = L.stack[i];
- let str = `${o.value}`;
- str = lua.to_luastring(str, str.length);
- if (o.ttisstring() || (o.ttisnumber() && !isNaN(str))) {
- L.stack[i] = L.l_G.intern(str);
+ if (o.ttisstring()) return true;
+
+ if (o.ttisnumber() && !isNaN(o.value)) {
+ L.stack[i] = L.l_G.intern(lua.to_luastring(`${o.value}`));
return true;
}
@@ -975,18 +974,16 @@ const luaV_concat = function(L, total) {
do {
let top = L.top;
let n = 2; /* number of elements handled in this pass (at least 2) */
- let v = L.stack[top-2];
- let v2 = L.stack[top-1];
- if (!(v.ttisstring() || v.ttisnumber()) || !tostring(L, top - 2)) // TODO: tostring
- ltm.luaT_trybinTM(L, v, v2, top-2, ltm.TMS.TM_CONCAT);
- else if (v2.ttisstring() && v2.value.length === 0)
+ if (!(L.stack[top-2].ttisstring() || L.stack[top-2].ttisnumber()) || !tostring(L, top - 1))
+ ltm.luaT_trybinTM(L, L.stack[top-2], L.stack[top-1], top-2, ltm.TMS.TM_CONCAT);
+ else if (L.stack[top-1].ttisstring() && L.stack[top-1].value.length === 0)
tostring(L, top - 2);
- else if (v.ttisstring() && v.value.length === 0)
+ else if (L.stack[top-2].ttisstring() && L.stack[top-2].value.length === 0)
L.stack[top - 2] = L.stack[top - 1];
else {
/* at least two non-empty string values; get as many as possible */
- let tl = v.value.length;
+ let tl = L.stack[top-2].value.length;
/* collect total length and number of strings */
for (n = 1; n < total && tostring(L, top - n - 1); n++) {
let l = L.stack[top - n - 1].value.length;
@@ -1018,7 +1015,7 @@ const gettable = function(L, table, key, ra, recur) {
let element = table.__index(table, key);
if (!element.ttisnil()) {
- L.stack[ra] = table.__index(table, key);
+ L.stack[ra] = element;
} else {
luaV_finishget(L, table, key, ra, element, recur);
}
diff --git a/tests/lexparse.js b/tests/lexparse.js
index cd80e43..704f875 100644
--- a/tests/lexparse.js
+++ b/tests/lexparse.js
@@ -741,13 +741,13 @@ test('SETTABLE, GETTABLE', function (t) {
}, "Lua program ran without error");
t.strictEqual(
- lapi.lua_topointer(L, -1).get(0).value,
+ lapi.lua_topointer(L, -1).get(0).jsstring(),
"hello",
"Program output is correct"
);
t.strictEqual(
- lapi.lua_topointer(L, -1).get("two").value,
+ lapi.lua_topointer(L, -1).get('116|119|111|').jsstring(),
"world",
"Program output is correct"
);
@@ -834,13 +834,13 @@ test('SETTABUP, GETTABUP', function (t) {
}, "Lua program ran without error");
t.strictEqual(
- lapi.lua_topointer(L, -1).get(0).value,
+ lapi.lua_topointer(L, -1).get(0).jsstring(),
"hello",
"Program output is correct"
);
t.strictEqual(
- lapi.lua_topointer(L, -1).get("two").value,
+ lapi.lua_topointer(L, -1).get('116|119|111|').jsstring(),
"world",
"Program output is correct"
);
@@ -1149,7 +1149,7 @@ test('CONCAT', function (t) {
}, "Lua program ran without error");
t.strictEqual(
- L.stack[L.top - 1].value,
+ lapi.lua_tostring(L, -1),
"hello 2 you",
"Program output is correct"
);
diff --git a/tests/ltm.js b/tests/ltm.js
index d749d7b..9eedc4c 100644
--- a/tests/ltm.js
+++ b/tests/ltm.js
@@ -1,13 +1,17 @@
"use strict";
-const test = require('tape');
-const beautify = require('js-beautify').js_beautify;
+const test = require('tape');
+const beautify = require('js-beautify').js_beautify;
-const VM = require("../src/lvm.js");
-const lapi = require("../src/lapi.js");
-const OC = require('../src/lopcodes.js');
+const VM = require("../src/lvm.js");
+const lapi = require("../src/lapi.js");
+const linit = require("../src/linit.js");
+const lauxlib = require("../src/lauxlib.js");
+const OC = require('../src/lopcodes.js');
-const getState = require("./tests.js").getState;
+const tests = require("./tests.js");
+const getState = tests.getState;
+const toByteCode = tests.toByteCode;
test('__index, __newindex: with actual table', function (t) {
@@ -21,28 +25,33 @@ test('__index, __newindex: with actual table', function (t) {
t.comment("Running following code: \n" + luaCode);
t.doesNotThrow(function () {
- L = getState(luaCode);
+ let bc = toByteCode(luaCode).dataView;
+
+ L = lauxlib.luaL_newstate();
+
+ linit.luaL_openlibs(L);
+
+ lapi.lua_load(L, null, bc, "test", "binary");
lapi.lua_call(L, 0, -1);
}, "Program executed without errors");
- t.strictEqual(
- L.stack[L.top - 1].value,
- null,
+ t.ok(
+ lapi.lua_isnil(L, -1),
"Program output is correct"
);
t.strictEqual(
- L.stack[L.top - 2].value,
+ lapi.lua_tointeger(L, -2),
1,
"Program output is correct"
);
});
-test('__index: with non table', function (t) {
+test('__newindex: with non table', function (t) {
let luaCode = `
local t = "a string"
- return t.yo
+ t.yo = "hello"
`, L;
t.plan(2);
@@ -50,27 +59,13 @@ test('__index: with non table', function (t) {
t.comment("Running following code: \n" + luaCode);
t.doesNotThrow(function () {
- L = getState(luaCode);
- }, "Bytecode parsed without errors");
-
- t.throws(function () {
- lapi.lua_call(L, 0, -1);
- }, "Program executed with expected error");
-});
-
+ let bc = toByteCode(luaCode).dataView;
-test('__newindex: with non table', function (t) {
- let luaCode = `
- local t = "a string"
- t.yo = "hello"
- `, L;
-
- t.plan(2);
+ L = lauxlib.luaL_newstate();
- t.comment("Running following code: \n" + luaCode);
+ linit.luaL_openlibs(L);
- t.doesNotThrow(function () {
- L = getState(luaCode);
+ lapi.lua_load(L, null, bc, "test", "binary");
}, "Bytecode parsed without errors");
t.throws(function () {
@@ -89,78 +84,32 @@ test('__index function in metatable', function (t) {
local t = {}
- -- setmetatable(t, mt)
+ setmetatable(t, mt)
return t.yo
`, L;
- t.plan(8);
+ t.plan(3);
t.comment("Running following code: \n" + luaCode);
t.doesNotThrow(function () {
- L = getState(luaCode);
- }, "Bytecode parsed without errors");
+ let bc = toByteCode(luaCode).dataView;
+ L = lauxlib.luaL_newstate();
- // main <hello.lua:0,0> (7 instructions at 0x7fe6b4403050)
- // 0+ params, 3 slots, 1 upvalue, 2 locals, 2 constants, 1 function
- // 1 [1] NEWTABLE 0 0 1
- // 2 [4] CLOSURE 1 0 ; 0x7fe6b4403290
- // 3 [4] SETTABLE 0 -1 1 ; "__index" -
- // 4 [7] NEWTABLE 1 0 0
- // 5 [9] GETTABLE 2 1 -2 ; "yo" <=== We stop here
- // 6 [9] RETURN 2 2
- // 7 [9] RETURN 0 1
- //
- // function <hello.lua:2,4> (3 instructions at 0x7fe6b4403290)
- // 2 params, 3 slots, 0 upvalues, 2 locals, 1 constant, 0 functions
- // 1 [3] LOADK 2 -1 ; "__index"
- // 2 [3] RETURN 2 2
- // 3 [4] RETURN 0 1
+ linit.luaL_openlibs(L);
- t.strictEqual(
- OC.OpCodes[L.stack[1].p.code[4].opcode],
- "OP_GETTABLE",
- "Correct opcode marked as breakpoint"
- );
+ lapi.lua_load(L, null, bc, "test", "binary");
+ }, "Bytecode parsed without errors");
- t.comment("We set a breakpoint")
- L.stack[1].p.code[4].breakpoint = true;
t.doesNotThrow(function () {
lapi.lua_call(L, 0, -1);
- }, "First part of the program executed without errors");
-
- t.strictEqual(
- OC.OpCodes[L.ci.u.l.savedpc[L.ci.pcOff - 1].opcode],
- "OP_GETTABLE",
- "Stopped at correct opcode"
- );
-
- t.comment("We unset the breakpoint and correct pcOff");
- L.ci.pcOff--;
- L.stack[1].p.code[4].breakpoint = false;
-
- t.ok(
- L.stack[3].ttistable() && !L.stack[3].value.get("__index"),
- "t is on stack at 3"
- );
-
- t.ok(
- L.stack[2].ttistable() && L.stack[2].value.get("__index"),
- "mt is on stack at 2"
- );
-
- t.comment("We manually set t's metatable to mt");
- L.stack[3].metatable = L.stack[2];
-
- t.doesNotThrow(function () {
- VM.luaV_execute(L);
- }, "Second part of the program executed without errors");
+ }, "Program executed without errors");
t.strictEqual(
- L.stack[L.top - 1].value,
+ lapi.lua_tostring(L, -1),
"__index",
"Program output is correct"
);
@@ -177,82 +126,33 @@ test('__newindex function in metatable', function (t) {
local t = {}
- -- setmetatable(t, mt)
+ setmetatable(t, mt)
t.yo = "hello"
return t.yo
`, L;
- t.plan(8);
+ t.plan(3);
t.comment("Running following code: \n" + luaCode);
t.doesNotThrow(function () {
- L = getState(luaCode);
- }, "Bytecode parsed without errors");
+ let bc = toByteCode(luaCode).dataView;
+ L = lauxlib.luaL_newstate();
- // main <hello.lua:0,0> (8 instructions at 0x7faadcf00ac0)
- // 0+ params, 3 slots, 1 upvalue, 2 locals, 3 constants, 1 function
- // 1 [1] NEWTABLE 0 0 1
- // 2 [4] CLOSURE 1 0 ; 0x7faadcf00d10
- // 3 [4] SETTABLE 0 -1 1 ; "__newindex" -
- // 4 [7] NEWTABLE 1 0 0
- // 5 [11] SETTABLE 1 -2 -3 ; "yo" "hello" <=== We stop here
- // 6 [13] GETTABLE 2 1 -2 ; "yo"
- // 7 [13] RETURN 2 2
- // 8 [13] RETURN 0 1
- //
- // function <hello.lua:2,4> (3 instructions at 0x7faadcf00d10)
- // 3 params, 4 slots, 0 upvalues, 3 locals, 1 constant, 0 functions
- // 1 [3] LOADK 3 -1 ; "__newindex"
- // 2 [3] RETURN 3 2
- // 3 [4] RETURN 0 1
+ linit.luaL_openlibs(L);
- t.strictEqual(
- OC.OpCodes[L.stack[1].p.code[4].opcode],
- "OP_SETTABLE",
- "Correct opcode marked as breakpoint"
- );
-
- t.comment("We set a breakpoint")
- L.stack[1].p.code[4].breakpoint = true;
+ lapi.lua_load(L, null, bc, "test", "binary");
+ }, "Bytecode parsed without errors");
t.doesNotThrow(function () {
lapi.lua_call(L, 0, -1);
- }, "First part of the program executed without errors");
-
- t.strictEqual(
- OC.OpCodes[L.ci.u.l.savedpc[L.ci.pcOff - 1].opcode],
- "OP_SETTABLE",
- "Stopped at correct opcode"
- );
-
- t.comment("We unset the breakpoint and correct pcOff");
- L.ci.pcOff--;
- L.stack[1].p.code[4].breakpoint = false;
-
- t.ok(
- L.stack[3].ttistable() && !L.stack[3].value.get("__newindex"),
- "t is on stack at 3"
- );
+ }, "Program executed without errors");
t.ok(
- L.stack[2].ttistable() && L.stack[2].value.get("__newindex"),
- "mt is on stack at 2"
- );
-
- t.comment("We manually set t's metatable to mt");
- L.stack[3].metatable = L.stack[2];
-
- t.doesNotThrow(function () {
- VM.luaV_execute(L);
- }, "Second part of the program executed without errors");
-
- t.strictEqual(
- L.stack[L.top - 1].value,
- null,
+ lapi.lua_isnil(L, -1),
"Program output is correct"
);
});
@@ -270,73 +170,31 @@ test('__index table in metatable', function (t) {
local t = {}
- -- setmetatable(t, mt)
+ setmetatable(t, mt)
return t.yo
`, L;
- t.plan(8);
+ t.plan(3);
t.comment("Running following code: \n" + luaCode);
t.doesNotThrow(function () {
- L = getState(luaCode);
- }, "Bytecode parsed without errors");
+ let bc = toByteCode(luaCode).dataView;
+ L = lauxlib.luaL_newstate();
- // main <hello.lua:0,0> (8 instructions at 0x7fb57cc03210)
- // 0+ params, 4 slots, 1 upvalue, 3 locals, 3 constants, 0 functions
- // 1 [1] NEWTABLE 0 0 1
- // 2 [2] SETTABLE 0 -1 -2 ; "yo" "hello"
- // 3 [4] NEWTABLE 1 0 1
- // 4 [5] SETTABLE 1 -3 0 ; "__index" -
- // 5 [7] NEWTABLE 2 0 0
- // 6 [9] GETTABLE 3 2 -1 ; "yo" <=== We stop here
- // 7 [9] RETURN 3 2
- // 8 [9] RETURN 0 1
+ linit.luaL_openlibs(L);
- t.strictEqual(
- OC.OpCodes[L.stack[1].p.code[5].opcode],
- "OP_GETTABLE",
- "Correct opcode marked as breakpoint"
- );
-
- t.comment("We set a breakpoint")
- L.stack[1].p.code[5].breakpoint = true;
+ lapi.lua_load(L, null, bc, "test", "binary");
+ }, "Bytecode parsed without errors");
t.doesNotThrow(function () {
lapi.lua_call(L, 0, -1);
- }, "First part of the program executed without errors");
-
- t.strictEqual(
- OC.OpCodes[L.ci.u.l.savedpc[L.ci.pcOff - 1].opcode],
- "OP_GETTABLE",
- "Stopped at correct opcode"
- );
-
- t.comment("We unset the breakpoint and correct pcOff");
- L.ci.pcOff--;
- L.stack[1].p.code[5].breakpoint = false;
-
- t.ok(
- L.stack[4].ttistable() && !L.stack[4].value.get("__index"),
- "t is on stack at 4"
- );
-
- t.ok(
- L.stack[3].ttistable() && L.stack[3].value.get("__index"),
- "mt is on stack at 3"
- );
-
- t.comment("We manually set t's metatable to mt");
- L.stack[4].metatable = L.stack[3];
-
- t.doesNotThrow(function () {
- VM.luaV_execute(L);
- }, "Second part of the program executed without errors");
+ }, "Program executed without errors");
t.strictEqual(
- L.stack[L.top - 1].value,
+ lapi.lua_tostring(L, -1),
"hello",
"Program output is correct"
);
@@ -355,84 +213,39 @@ test('__newindex table in metatable', function (t) {
local t = {}
- -- setmetatable(t, mt)
+ setmetatable(t, mt)
t.yo = "world"
return t.yo, mmt.yo
`, L;
- t.plan(9);
+ t.plan(4);
t.comment("Running following code: \n" + luaCode);
t.doesNotThrow(function () {
- L = getState(luaCode);
- }, "Bytecode parsed without errors");
+ let bc = toByteCode(luaCode).dataView;
+ L = lauxlib.luaL_newstate();
- // main <hello.lua:0,0> (10 instructions at 0x7fba6a403210)
- // 0+ params, 5 slots, 1 upvalue, 3 locals, 4 constants, 0 functions
- // 1 [1] NEWTABLE 0 0 1
- // 2 [2] SETTABLE 0 -1 -2 ; "yo" "hello"
- // 3 [5] NEWTABLE 1 0 1
- // 4 [6] SETTABLE 1 -3 0 ; "__newindex" -
- // 5 [9] NEWTABLE 2 0 0
- // 6 [13] SETTABLE 2 -1 -4 ; "yo" "world" <=== We stop here
- // 7 [15] GETTABLE 3 2 -1 ; "yo"
- // 8 [15] GETTABLE 4 0 -1 ; "yo"
- // 9 [15] RETURN 3 3
- // 10 [15] RETURN 0 1
+ linit.luaL_openlibs(L);
- t.strictEqual(
- OC.OpCodes[L.stack[1].p.code[5].opcode],
- "OP_SETTABLE",
- "Correct opcode marked as breakpoint"
- );
-
- t.comment("We set a breakpoint")
- L.stack[1].p.code[5].breakpoint = true;
+ lapi.lua_load(L, null, bc, "test", "binary");
+ }, "Bytecode parsed without errors");
t.doesNotThrow(function () {
lapi.lua_call(L, 0, -1);
- }, "First part of the program executed without errors");
-
- t.strictEqual(
- OC.OpCodes[L.ci.u.l.savedpc[L.ci.pcOff - 1].opcode],
- "OP_SETTABLE",
- "Stopped at correct opcode"
- );
-
- t.comment("We unset the breakpoint and correct pcOff");
- L.ci.pcOff--;
- L.stack[1].p.code[5].breakpoint = false;
-
- t.ok(
- L.stack[4].ttistable() && !L.stack[4].value.get("__newindex"),
- "t is on stack at 4"
- );
-
- t.ok(
- L.stack[3].ttistable() && L.stack[3].value.get("__newindex"),
- "mt is on stack at 3"
- );
-
- t.comment("We manually set t's metatable to mt");
- L.stack[4].metatable = L.stack[3];
-
- t.doesNotThrow(function () {
- VM.luaV_execute(L);
- }, "Second part of the program executed without errors");
+ }, "Program executed without errors");
t.strictEqual(
- L.stack[L.top - 1].value,
+ lapi.lua_tostring(L, -1),
"world",
"Program output is correct"
);
- t.strictEqual(
- L.stack[L.top - 2].value,
- null,
+ t.ok(
+ lapi.lua_isnil(L, -2),
"Program output is correct"
);
});
@@ -450,7 +263,7 @@ test('__index table with own metatable', function (t) {
yoo = "bye"
}
- -- setmetatable(mmt, mmmt)
+ setmetatable(mmt, mmmt)
local mt = {
__index = mmt
@@ -458,69 +271,31 @@ test('__index table with own metatable', function (t) {
local t = {}
- -- setmetatable(t, mt)
+ setmetatable(t, mt)
return t.yo
`, L;
- t.plan(5);
+ t.plan(3);
t.comment("Running following code: \n" + luaCode);
t.doesNotThrow(function () {
- L = getState(luaCode);
- }, "Bytecode parsed without errors");
-
-
- // main <hello.lua:0,0> (11 instructions at 0x7f96e3403210)
- // 0+ params, 5 slots, 1 upvalue, 4 locals, 3 constants, 1 function
- // 1 [1] NEWTABLE 0 0 1
- // 2 [4] CLOSURE 1 0 ; 0x7f96e3403440
- // 3 [4] SETTABLE 0 -1 1 ; "__index" -
- // 4 [7] NEWTABLE 1 0 1
- // 5 [8] SETTABLE 1 -2 -3 ; "yo" "bye"
- // 6 [13] NEWTABLE 2 0 1 <=== We stop here
- // 7 [14] SETTABLE 2 -1 1 ; "__index" -
- // 8 [17] NEWTABLE 3 0 0
- // 9 [21] GETTABLE 4 3 -2 ; "yo" <=== We stop here
- // 10 [21] RETURN 4 2
- // 11 [21] RETURN 0 1
- //
- // function <hello.lua:2,4> (3 instructions at 0x7f96e3403440)
- // 2 params, 3 slots, 0 upvalues, 2 locals, 1 constant, 0 functions
- // 1 [3] LOADK 2 -1 ; "hello"
- // 2 [3] RETURN 2 2
- // 3 [4] RETURN 0 1
-
- L.stack[1].p.code[5].breakpoint = true;
- L.stack[1].p.code[8].breakpoint = true;
-
- t.doesNotThrow(function () {
- lapi.lua_call(L, 0, -1);
- }, "First part of the program executed without errors");
-
- L.ci.pcOff--;
- L.stack[1].p.code[5].breakpoint = false;
+ let bc = toByteCode(luaCode).dataView;
- t.comment("We manually set mmt's metatable to mmmt");
- L.stack[3].metatable = L.stack[2];
-
- t.doesNotThrow(function () {
- VM.luaV_execute(L);
- }, "Second part of the program executed without errors");
+ L = lauxlib.luaL_newstate();
- L.ci.pcOff--;
- L.stack[1].p.code[8].breakpoint = false;
+ linit.luaL_openlibs(L);
- t.comment("We manually set t's metatable to mt");
- L.stack[5].metatable = L.stack[4];
+ lapi.lua_load(L, null, bc, "test", "binary");
+ }, "Bytecode parsed without errors");
t.doesNotThrow(function () {
- VM.luaV_execute(L);
- }, "Third part of the program executed without errors");
+ lapi.lua_call(L, 0, -1);
+ }, "Program executed without errors");
t.strictEqual(
- L.stack[L.top - 1].value,
+ lapi.lua_tostring(L, -1),
"hello",
"Program output is correct"
);
@@ -539,100 +314,49 @@ test('__newindex table with own metatable', function (t) {
local mmt = {}
- -- setmetatable(mmt, mmmt)
+ setmetatable(mmt, mmmt)
local mt = {
__newindex = mmt
}
- -- setmetatable(mt, mmt)
+ setmetatable(mt, mmt)
local t = {}
- -- setmetatable(t, mt)
+ setmetatable(t, mt)
t.yo = "hello"
return t.yo, up
`, L;
- t.plan(7);
+ t.plan(4);
t.comment("Running following code: \n" + luaCode);
t.doesNotThrow(function () {
- L = getState(luaCode);
- }, "Bytecode parsed without errors");
-
-
- // main <hello.lua:0,0> (13 instructions at 0x7ff6ed500640)
- // 0+ params, 7 slots, 1 upvalue, 5 locals, 3 constants, 1 function
- // 1 [1] LOADNIL 0 0
- // 2 [3] NEWTABLE 1 0 1
- // 3 [6] CLOSURE 2 0 ; 0x7ff6ed5007f0
- // 4 [6] SETTABLE 1 -1 2 ; "__newindex" -
- // 5 [9] NEWTABLE 2 0 0
- // 6 [13] NEWTABLE 3 0 1 <=== We stop here
- // 7 [14] SETTABLE 3 -1 2 ; "__newindex" -
- // 8 [19] NEWTABLE 4 0 0 <=== We stop here
- // 9 [23] SETTABLE 4 -2 -3 ; "yo" "hello" <=== We stop here
- // 10 [25] GETTABLE 5 4 -2 ; "yo"
- // 11 [25] MOVE 6 0
- // 12 [25] RETURN 5 3
- // 13 [25] RETURN 0 1
- //
- // function <hello.lua:4,6> (2 instructions at 0x7ff6ed5007f0)
- // 3 params, 3 slots, 1 upvalue, 3 locals, 0 constants, 0 functions
- // 1 [5] SETUPVAL 2 0 ; up
- // 2 [6] RETURN 0 1
-
- L.stack[1].p.code[5].breakpoint = true;
- L.stack[1].p.code[7].breakpoint = true;
- L.stack[1].p.code[8].breakpoint = true;
-
- t.doesNotThrow(function () {
- lapi.lua_call(L, 0, -1);
- }, "First part of the program executed without errors");
+ let bc = toByteCode(luaCode).dataView;
- L.ci.pcOff--;
- L.stack[1].p.code[5].breakpoint = false;
+ L = lauxlib.luaL_newstate();
- t.comment("We manually set mmt's metatable to mmmt");
- L.stack[4].metatable = L.stack[3];
+ linit.luaL_openlibs(L);
- t.doesNotThrow(function () {
- VM.luaV_execute(L);
- }, "Second part of the program executed without errors");
-
- L.ci.pcOff--;
- L.stack[1].p.code[7].breakpoint = false;
-
- t.comment("We manually set mt's metatable to mmt");
- L.stack[5].metatable = L.stack[4];
-
- t.doesNotThrow(function () {
- VM.luaV_execute(L);
- }, "Third part of the program executed without errors");
-
- L.ci.pcOff--;
- L.stack[1].p.code[8].breakpoint = false;
-
- t.comment("We manually set t's metatable to mt");
- L.stack[6].metatable = L.stack[5];
+ lapi.lua_load(L, null, bc, "test", "binary");
+ }, "Bytecode parsed without errors");
t.doesNotThrow(function () {
- VM.luaV_execute(L);
- }, "Fourth part of the program executed without errors");
+ lapi.lua_call(L, 0, -1);
+ }, "Program executed without errors");
t.strictEqual(
- L.stack[L.top - 1].value,
+ lapi.lua_tostring(L, -1),
"hello",
"Program output is correct"
);
- t.strictEqual(
- L.stack[L.top - 2].value,
- null,
+ t.ok(
+ lapi.lua_isnil(L, -2),
"Program output is correct"
);
});
@@ -693,7 +417,7 @@ test('binary __xxx functions in metatable', function (t) {
local t = {}
- -- setmetatable(t, mt)
+ setmetatable(t, mt)
return
t + 1,
@@ -710,79 +434,26 @@ test('binary __xxx functions in metatable', function (t) {
t >> 1
`, L;
- t.plan(4);
+ t.plan(3);
t.comment("Running following code: \n" + luaCode);
t.doesNotThrow(function () {
- L = getState(luaCode);
- }, "Bytecode parsed without errors");
+ let bc = toByteCode(luaCode).dataView;
+ L = lauxlib.luaL_newstate();
-
- //main <hello.lua:0,0> (40 instructions at 0x7fd29ac03210)
- //0+ params, 14 slots, 1 upvalue, 2 locals, 13 constants, 12 functions
- // 1 [1] NEWTABLE 0 0 12
- // 2 [4] CLOSURE 1 0 ; 0x7fd29ac03440
- // 3 [4] SETTABLE 0 -1 1 ; "__add" -
- // 4 [8] CLOSURE 1 1 ; 0x7fd29ac03500
- // 5 [8] SETTABLE 0 -2 1 ; "__sub" -
- // 6 [12] CLOSURE 1 2 ; 0x7fd29ac038c0
- // 7 [12] SETTABLE 0 -3 1 ; "__mul" -
- // 8 [16] CLOSURE 1 3 ; 0x7fd29ac039e0
- // 9 [16] SETTABLE 0 -4 1 ; "__mod" -
- // 10 [20] CLOSURE 1 4 ; 0x7fd29ac03c00
- // 11 [20] SETTABLE 0 -5 1 ; "__pow" -
- // 12 [24] CLOSURE 1 5 ; 0x7fd29ac036a0
- // 13 [24] SETTABLE 0 -6 1 ; "__div" -
- // 14 [28] CLOSURE 1 6 ; 0x7fd29ac037c0
- // 15 [28] SETTABLE 0 -7 1 ; "__idiv" -
- // 16 [32] CLOSURE 1 7 ; 0x7fd29ac03ce0
- // 17 [32] SETTABLE 0 -8 1 ; "__band" -
- // 18 [36] CLOSURE 1 8 ; 0x7fd29ac03b00
- // 19 [36] SETTABLE 0 -9 1 ; "__bor" -
- // 20 [40] CLOSURE 1 9 ; 0x7fd29ac04060
- // 21 [40] SETTABLE 0 -10 1 ; "__bxor" -
- // 22 [44] CLOSURE 1 10 ; 0x7fd29ac04180
- // 23 [44] SETTABLE 0 -11 1 ; "__shl" -
- // 24 [48] CLOSURE 1 11 ; 0x7fd29ac042a0
- // 25 [48] SETTABLE 0 -12 1 ; "__shr" -
- // 26 [52] NEWTABLE 1 0 0
- // 27 [57] ADD 2 1 -13 ; - 1 <=== We stop here
- // 28 [58] SUB 3 1 -13 ; - 1
- // 29 [59] MUL 4 1 -13 ; - 1
- // 30 [60] MOD 5 1 -13
- // 31 [61] POW 6 1 -13 ; - 1
- // 32 [62] DIV 7 1 -13 ; - 1
- // 33 [63] IDIV 8 1 -13 ; - 1
- // 34 [64] BAND 9 1 -13 ; - 1
- // 35 [65] BOR 10 1 -13 ; - 1
- // 36 [66] BXOR 11 1 -13 ; - 1
- // 37 [67] SHL 12 1 -13 ; - 1
- // 38 [68] SHR 13 1 -13 ; - 1
- // 39 [68] RETURN 2 13
- // 40 [68] RETURN 0 1
- //
- // ...
-
- L.stack[1].p.code[26].breakpoint = true;
+ linit.luaL_openlibs(L);
- t.doesNotThrow(function () {
- lapi.lua_call(L, 0, -1);
- }, "First part of the program executed without errors");
-
- L.ci.pcOff--;
- L.stack[1].p.code[26].breakpoint = false;
-
- t.comment("We manually set t's metatable to mt");
- L.stack[3].metatable = L.stack[2];
+ lapi.lua_load(L, null, bc, "test", "binary");
+ }, "Bytecode parsed without errors");
t.doesNotThrow(function () {
- VM.luaV_execute(L);
- }, "Second part of the program executed without errors");
+ lapi.lua_call(L, 0, -1);
+ }, "Program executed without errors");
t.deepEqual(
- L.stack.slice(L.top - 12, L.top).map(e => e.value),
+ L.stack.slice(L.top - 12, L.top).map(e => e.jsstring()),
[
"{} + 1",
"{} - 1",
@@ -812,54 +483,31 @@ test('__eq', function (t) {
local t = {}
- -- setmetatable(t, mt)
+ setmetatable(t, mt)
return t == {}
`, L;
- t.plan(4);
+ t.plan(3);
t.comment("Running following code: \n" + luaCode);
- // main <hello.lua:0,0> (11 instructions at 0x7fce9fc03210)
- // 0+ params, 3 slots, 1 upvalue, 2 locals, 1 constant, 1 function
- // 1 [1] NEWTABLE 0 0 1
- // 2 [4] CLOSURE 1 0 ; 0x7fce9fc03440
- // 3 [4] SETTABLE 0 -1 1 ; "__eq" -
- // 4 [7] NEWTABLE 1 0 0
- // 5 [11] NEWTABLE 2 0 0
- // 6 [11] EQ 1 1 2 <=== We stop here
- // 7 [11] JMP 0 1 ; to 9
- // 8 [11] LOADBOOL 2 0 1
- // 9 [11] LOADBOOL 2 1 0
- // 10 [11] RETURN 2 2
- // 11 [11] RETURN 0 1
- //
- // ...
-
t.doesNotThrow(function () {
- L = getState(luaCode);
- }, "Bytecode parsed without errors");
+ let bc = toByteCode(luaCode).dataView;
- L.stack[1].p.code[5].breakpoint = true;
+ L = lauxlib.luaL_newstate();
- t.doesNotThrow(function () {
- lapi.lua_call(L, 0, -1);
- }, "First part of the program executed without errors");
+ linit.luaL_openlibs(L);
- L.ci.pcOff--;
- L.stack[1].p.code[5].breakpoint = false;
-
- t.comment("We manually set t's metatable to mt");
- L.stack[3].metatable = L.stack[2];
+ lapi.lua_load(L, null, bc, "test", "binary");
+ }, "Bytecode parsed without errors");
t.doesNotThrow(function () {
- VM.luaV_execute(L);
- }, "Second part of the program executed without errors");
+ lapi.lua_call(L, 0, -1);
+ }, "Program executed without errors");
- t.strictEqual(
- L.stack[L.top - 1].value,
- true,
+ t.ok(
+ lapi.lua_toboolean(L, -1),
"Program output is correct"
);
});
@@ -875,54 +523,31 @@ test('__lt', function (t) {
local t = {}
- -- setmetatable(t, mt)
+ setmetatable(t, mt)
return t < {}
`, L;
- t.plan(4);
+ t.plan(3);
t.comment("Running following code: \n" + luaCode);
- // main <hello.lua:0,0> (11 instructions at 0x7fc879d00ac0)
- // 0+ params, 3 slots, 1 upvalue, 2 locals, 1 constant, 1 function
- // 1 [1] NEWTABLE 0 0 1
- // 2 [4] CLOSURE 1 0 ; 0x7fc879d00d10
- // 3 [4] SETTABLE 0 -1 1 ; "__lt" -
- // 4 [7] NEWTABLE 1 0 0
- // 5 [11] NEWTABLE 2 0 0
- // 6 [11] LT 1 1 2 <=== We stop here
- // 7 [11] JMP 0 1 ; to 9
- // 8 [11] LOADBOOL 2 0 1
- // 9 [11] LOADBOOL 2 1 0
- // 10 [11] RETURN 2 2
- // 11 [11] RETURN 0 1
- //
- // ...
-
t.doesNotThrow(function () {
- L = getState(luaCode);
- }, "Bytecode parsed without errors");
-
- L.stack[1].p.code[5].breakpoint = true;
+ let bc = toByteCode(luaCode).dataView;
- t.doesNotThrow(function () {
- lapi.lua_call(L, 0, -1);
- }, "First part of the program executed without errors");
+ L = lauxlib.luaL_newstate();
- L.ci.pcOff--;
- L.stack[1].p.code[5].breakpoint = false;
+ linit.luaL_openlibs(L);
- t.comment("We manually set t's metatable to mt");
- L.stack[3].metatable = L.stack[2];
+ lapi.lua_load(L, null, bc, "test", "binary");
+ }, "Bytecode parsed without errors");
t.doesNotThrow(function () {
- VM.luaV_execute(L);
- }, "Second part of the program executed without errors");
+ lapi.lua_call(L, 0, -1);
+ }, "Program executed without errors");
- t.strictEqual(
- L.stack[L.top - 1].value,
- true,
+ t.ok(
+ lapi.lua_toboolean(L, -1),
"Program output is correct"
);
});
@@ -938,54 +563,31 @@ test('__le', function (t) {
local t = {}
- -- setmetatable(t, mt)
+ setmetatable(t, mt)
return t <= {}
`, L;
- t.plan(4);
+ t.plan(3);
t.comment("Running following code: \n" + luaCode);
- // main <hello.lua:0,0> (11 instructions at 0x7fc879d00ac0)
- // 0+ params, 3 slots, 1 upvalue, 2 locals, 1 constant, 1 function
- // 1 [1] NEWTABLE 0 0 1
- // 2 [4] CLOSURE 1 0 ; 0x7fc879d00d10
- // 3 [4] SETTABLE 0 -1 1 ; "__lt" -
- // 4 [7] NEWTABLE 1 0 0
- // 5 [11] NEWTABLE 2 0 0
- // 6 [11] LE 1 1 2 <=== We stop here
- // 7 [11] JMP 0 1 ; to 9
- // 8 [11] LOADBOOL 2 0 1
- // 9 [11] LOADBOOL 2 1 0
- // 10 [11] RETURN 2 2
- // 11 [11] RETURN 0 1
- //
- // ...
-
t.doesNotThrow(function () {
- L = getState(luaCode);
- }, "Bytecode parsed without errors");
+ let bc = toByteCode(luaCode).dataView;
- L.stack[1].p.code[5].breakpoint = true;
+ L = lauxlib.luaL_newstate();
- t.doesNotThrow(function () {
- lapi.lua_call(L, 0, -1);
- }, "First part of the program executed without errors");
-
- L.ci.pcOff--;
- L.stack[1].p.code[5].breakpoint = false;
+ linit.luaL_openlibs(L);
- t.comment("We manually set t's metatable to mt");
- L.stack[3].metatable = L.stack[2];
+ lapi.lua_load(L, null, bc, "test", "binary");
+ }, "Bytecode parsed without errors");
t.doesNotThrow(function () {
- VM.luaV_execute(L);
- }, "Second part of the program executed without errors");
+ lapi.lua_call(L, 0, -1);
+ }, "Program executed without errors");
- t.strictEqual(
- L.stack[L.top - 1].value,
- true,
+ t.ok(
+ lapi.lua_toboolean(L, -1),
"Program output is correct"
);
});
@@ -1001,54 +603,31 @@ test('__le that uses __lt', function (t) {
local t = {}
- -- setmetatable(t, mt)
+ setmetatable(t, mt)
return {} <= t
`, L;
- t.plan(4);
+ t.plan(3);
t.comment("Running following code: \n" + luaCode);
- // main <hello.lua:0,0> (11 instructions at 0x7fc879d00ac0)
- // 0+ params, 3 slots, 1 upvalue, 2 locals, 1 constant, 1 function
- // 1 [1] NEWTABLE 0 0 1
- // 2 [4] CLOSURE 1 0 ; 0x7fc879d00d10
- // 3 [4] SETTABLE 0 -1 1 ; "__lt" -
- // 4 [7] NEWTABLE 1 0 0
- // 5 [11] NEWTABLE 2 0 0
- // 6 [11] LE 1 1 2 <=== We stop here
- // 7 [11] JMP 0 1 ; to 9
- // 8 [11] LOADBOOL 2 0 1
- // 9 [11] LOADBOOL 2 1 0
- // 10 [11] RETURN 2 2
- // 11 [11] RETURN 0 1
- //
- // ...
-
t.doesNotThrow(function () {
- L = getState(luaCode);
- }, "Bytecode parsed without errors");
+ let bc = toByteCode(luaCode).dataView;
- L.stack[1].p.code[5].breakpoint = true;
+ L = lauxlib.luaL_newstate();
- t.doesNotThrow(function () {
- lapi.lua_call(L, 0, -1);
- }, "First part of the program executed without errors");
-
- L.ci.pcOff--;
- L.stack[1].p.code[5].breakpoint = false;
+ linit.luaL_openlibs(L);
- t.comment("We manually set t's metatable to mt");
- L.stack[3].metatable = L.stack[2];
+ lapi.lua_load(L, null, bc, "test", "binary");
+ }, "Bytecode parsed without errors");
t.doesNotThrow(function () {
- VM.luaV_execute(L);
- }, "Second part of the program executed without errors");
+ lapi.lua_call(L, 0, -1);
+ }, "Program executed without errors");
- t.strictEqual(
- L.stack[L.top - 1].value,
- true,
+ t.ok(
+ lapi.lua_toboolean(L, -1),
"Program output is correct"
);
});
@@ -1068,58 +647,37 @@ test('__unm, __bnot', function (t) {
local t = {}
- -- setmetatable(t, mt)
+ setmetatable(t, mt)
return -t, ~t
`, L;
- t.plan(5);
+ t.plan(4);
t.comment("Running following code: \n" + luaCode);
- // main <hello.lua:0,0> (10 instructions at 0x7ff10e403210)
- // 0+ params, 4 slots, 1 upvalue, 2 locals, 2 constants, 2 functions
- // 1 [1] NEWTABLE 0 0 2
- // 2 [4] CLOSURE 1 0 ; 0x7ff10e403440
- // 3 [4] SETTABLE 0 -1 1 ; "__unm" -
- // 4 [8] CLOSURE 1 1 ; 0x7ff10e4033c0
- // 5 [8] SETTABLE 0 -2 1 ; "__bnot" -
- // 6 [11] NEWTABLE 1 0 0
- // 7 [15] UNM 2 1 <=== We stop here
- // 8 [15] BNOT 3 1
- // 9 [15] RETURN 2 3
- // 10 [15] RETURN 0 1
- //
- // ...
-
t.doesNotThrow(function () {
- L = getState(luaCode);
- }, "Bytecode parsed without errors");
+ let bc = toByteCode(luaCode).dataView;
- L.stack[1].p.code[6].breakpoint = true;
+ L = lauxlib.luaL_newstate();
- t.doesNotThrow(function () {
- lapi.lua_call(L, 0, -1);
- }, "First part of the program executed without errors");
+ linit.luaL_openlibs(L);
- L.ci.pcOff--;
- L.stack[1].p.code[6].breakpoint = false;
-
- t.comment("We manually set t's metatable to mt");
- L.stack[3].metatable = L.stack[2];
+ lapi.lua_load(L, null, bc, "test", "binary");
+ }, "Bytecode parsed without errors");
t.doesNotThrow(function () {
- VM.luaV_execute(L);
- }, "Second part of the program executed without errors");
+ lapi.lua_call(L, 0, -1);
+ }, "Program executed without errors");
t.strictEqual(
- L.stack[L.top - 1].value,
+ lapi.lua_tostring(L, -1),
"world",
"Program output is correct"
);
t.strictEqual(
- L.stack[L.top - 2].value,
+ lapi.lua_tostring(L, -2),
"hello",
"Program output is correct"
);
@@ -1136,49 +694,31 @@ test('__len', function (t) {
local t = {}
- -- setmetatable(t, mt)
+ setmetatable(t, mt)
return #t
`, L;
- t.plan(4);
+ t.plan(3);
t.comment("Running following code: \n" + luaCode);
- // main <hello.lua:0,0> (7 instructions at 0x7f91f0600ac0)
- // 0+ params, 3 slots, 1 upvalue, 2 locals, 1 constant, 1 function
- // 1 [1] NEWTABLE 0 0 1
- // 2 [4] CLOSURE 1 0 ; 0x7f91f0600d10
- // 3 [4] SETTABLE 0 -1 1 ; "__len" -
- // 4 [7] NEWTABLE 1 0 0
- // 5 [11] LEN 2 1 <=== We stop here
- // 6 [11] RETURN 2 2
- // 7 [11] RETURN 0 1
- //
- // ...
-
t.doesNotThrow(function () {
- L = getState(luaCode);
- }, "Bytecode parsed without errors");
-
- L.stack[1].p.code[4].breakpoint = true;
+ let bc = toByteCode(luaCode).dataView;
- t.doesNotThrow(function () {
- lapi.lua_call(L, 0, -1);
- }, "First part of the program executed without errors");
+ L = lauxlib.luaL_newstate();
- L.ci.pcOff--;
- L.stack[1].p.code[4].breakpoint = false;
+ linit.luaL_openlibs(L);
- t.comment("We manually set t's metatable to mt");
- L.stack[3].metatable = L.stack[2];
+ lapi.lua_load(L, null, bc, "test", "binary");
+ }, "Bytecode parsed without errors");
t.doesNotThrow(function () {
- VM.luaV_execute(L);
- }, "Second part of the program executed without errors");
+ lapi.lua_call(L, 0, -1);
+ }, "Program executed without errors");
t.strictEqual(
- L.stack[L.top - 1].value,
+ lapi.lua_tostring(L, -1),
"hello",
"Program output is correct"
);
@@ -1195,51 +735,31 @@ test('__concat', function (t) {
local t = {}
- -- setmetatable(t, mt)
+ setmetatable(t, mt)
return t .. " world"
`, L;
- t.plan(4);
+ t.plan(3);
t.comment("Running following code: \n" + luaCode);
- // main <hello.lua:0,0> (9 instructions at 0x7ffacdc03210)
- // 0+ params, 4 slots, 1 upvalue, 2 locals, 2 constants, 1 function
- // 1 [1] NEWTABLE 0 0 1
- // 2 [4] CLOSURE 1 0 ; 0x7ffacdc03440
- // 3 [4] SETTABLE 0 -1 1 ; "__concat" -
- // 4 [7] NEWTABLE 1 0 0
- // 5 [11] MOVE 2 1
- // 6 [11] LOADK 3 -2 ; " world"
- // 7 [11] CONCAT 2 2 3 <=== We stop here
- // 8 [11] RETURN 2 2
- // 9 [11] RETURN 0 1
- //
- // ...
-
t.doesNotThrow(function () {
- L = getState(luaCode);
- }, "Bytecode parsed without errors");
+ let bc = toByteCode(luaCode).dataView;
- L.stack[1].p.code[6].breakpoint = true;
+ L = lauxlib.luaL_newstate();
- t.doesNotThrow(function () {
- lapi.lua_call(L, 0, -1);
- }, "First part of the program executed without errors");
+ linit.luaL_openlibs(L);
- L.ci.pcOff--;
- L.stack[1].p.code[6].breakpoint = false;
-
- t.comment("We manually set t's metatable to mt");
- L.stack[3].metatable = L.stack[2];
+ lapi.lua_load(L, null, bc, "test", "binary");
+ }, "Bytecode parsed without errors");
t.doesNotThrow(function () {
- VM.luaV_execute(L);
- }, "Second part of the program executed without errors");
+ lapi.lua_call(L, 0, -1);
+ }, "Program executed without errors");
t.strictEqual(
- L.stack[L.top - 1].value,
+ lapi.lua_tostring(L, -1),
"hello",
"Program output is correct"
);
@@ -1256,50 +776,31 @@ test('__call', function (t) {
local t = {}
- -- setmetatable(t, mt)
+ setmetatable(t, mt)
return t("world","wow")
`, L;
- t.plan(4);
+ t.plan(3);
t.comment("Running following code: \n" + luaCode);
- // main <hello.lua:0,0> (10 instructions at 0x7fc4c9403210)
- // 0+ params, 5 slots, 1 upvalue, 2 locals, 3 constants, 1 function
- // 1 [1] NEWTABLE 0 0 1
- // 2 [4] CLOSURE 1 0 ; 0x7fc4c9403440
- // 3 [4] SETTABLE 0 -1 1 ; "__call" -
- // 4 [7] NEWTABLE 1 0 0
- // 5 [11] MOVE 2 1
- // 6 [11] LOADK 3 -2 ; "world"
- // 7 [11] LOADK 4 -3 ; "wow"
- // 8 [11] TAILCALL 2 3 0 <=== We stop here
- // 9 [11] RETURN 2 0
- // 10 [11] RETURN 0 1
-
t.doesNotThrow(function () {
- L = getState(luaCode);
- }, "Bytecode parsed without errors");
-
- L.stack[1].p.code[7].breakpoint = true;
+ let bc = toByteCode(luaCode).dataView;
- t.doesNotThrow(function () {
- lapi.lua_call(L, 0, -1);
- }, "First part of the program executed without errors");
+ L = lauxlib.luaL_newstate();
- L.ci.pcOff--;
- L.stack[1].p.code[7].breakpoint = false;
+ linit.luaL_openlibs(L);
- t.comment("We manually set t's metatable to mt");
- L.stack[3].metatable = L.stack[2];
+ lapi.lua_load(L, null, bc, "test", "binary");
+ }, "Bytecode parsed without errors");
t.doesNotThrow(function () {
- VM.luaV_execute(L);
- }, "Second part of the program executed without errors");
+ lapi.lua_call(L, 0, -1);
+ }, "Program executed without errors");
t.deepEqual(
- L.stack.slice(L.top - 3, L.top).map(e => e.value),
+ L.stack.slice(L.top - 3, L.top).map(e => e.jsstring()),
["hello", "world", "wow"],
"Program output is correct"
);
diff --git a/tests/lvm.js b/tests/lvm.js
index f5948eb..69195d1 100644
--- a/tests/lvm.js
+++ b/tests/lvm.js
@@ -26,7 +26,7 @@ test('LOADK, RETURN', function (t) {
}, "Program executed without errors");
t.strictEqual(
- L.stack[L.top - 1].value,
+ lapi.lua_tostring(L, -1),
"hello world",
"Program output is correct"
);
@@ -50,7 +50,7 @@ test('MOVE', function (t) {
}, "Program executed without errors");
t.strictEqual(
- L.stack[L.top - 1].value,
+ lapi.lua_tostring(L, -1),
"hello world",
"Program output is correct"
);
@@ -147,7 +147,7 @@ test('CALL', function (t) {
}, "Program executed without errors");
t.strictEqual(
- L.stack[L.top - 1].value,
+ lapi.lua_tointeger(L, -1),
3,
"Program output is correct"
);
@@ -205,7 +205,7 @@ test('TAILCALL', function (t) {
}, "Program executed without errors");
t.strictEqual(
- L.stack[L.top - 1].value,
+ lapi.lua_tointeger(L, -1),
3,
"Program output is correct"
);
@@ -255,7 +255,7 @@ test('LE, JMP', function (t) {
}, "Program executed without errors");
t.strictEqual(
- L.stack[L.top - 1].value,
+ lapi.lua_toboolean(L, -1),
true,
"Program output is correct"
);
@@ -279,7 +279,7 @@ test('LT', function (t) {
}, "Program executed without errors");
t.strictEqual(
- L.stack[L.top - 1].value,
+ lapi.lua_toboolean(L, -1),
false,
"Program output is correct"
);
@@ -303,7 +303,7 @@ test('EQ', function (t) {
}, "Program executed without errors");
t.strictEqual(
- L.stack[L.top - 1].value,
+ lapi.lua_toboolean(L, -1),
true,
"Program output is correct"
);
@@ -328,7 +328,7 @@ test('TESTSET (and)', function (t) {
}, "Program executed without errors");
t.strictEqual(
- L.stack[L.top - 1].value,
+ lapi.lua_tostring(L, -1),
"hello",
"Program output is correct"
);
@@ -353,7 +353,7 @@ test('TESTSET (or)', function (t) {
}, "Program executed without errors");
t.strictEqual(
- L.stack[L.top - 1].value,
+ lapi.lua_tostring(L, -1),
"hello",
"Program output is correct"
);
@@ -382,7 +382,7 @@ test('TEST (true)', function (t) {
}, "Program executed without errors");
t.strictEqual(
- L.stack[L.top - 1].value,
+ lapi.lua_tostring(L, -1),
"hello",
"Program output is correct"
);
@@ -411,7 +411,7 @@ test('TEST (false)', function (t) {
}, "Program executed without errors");
t.strictEqual(
- L.stack[L.top - 1].value,
+ lapi.lua_tostring(L, -1),
"goodbye",
"Program output is correct"
);
@@ -439,7 +439,7 @@ test('FORPREP, FORLOOP (int)', function (t) {
}, "Program executed without errors");
t.strictEqual(
- L.stack[L.top - 1].value,
+ lapi.lua_tointeger(L, -1),
55,
"Program output is correct"
);
@@ -467,7 +467,7 @@ test('FORPREP, FORLOOP (float)', function (t) {
}, "Program executed without errors");
t.strictEqual(
- L.stack[L.top - 1].value,
+ lapi.lua_tonumber(L, -1),
60.5,
"Program output is correct"
);
@@ -493,14 +493,16 @@ test('SETTABLE, GETTABLE', function (t) {
lapi.lua_call(L, 0, -1);
}, "Program executed without errors");
- t.strictEqual(
- L.stack[L.top - 1].value.get(0).value,
+ console.log(L.stack[L.top - 1]);
+
+ t.deepEqual(
+ L.stack[L.top - 1].value.get(0).jsstring(),
"hello",
"Program output is correct"
);
- t.strictEqual(
- L.stack[L.top - 1].value.get("two").value,
+ t.deepEqual(
+ L.stack[L.top - 1].value.get('116|119|111|').jsstring(), // "two"
"world",
"Program output is correct"
);
@@ -530,7 +532,7 @@ test('SETUPVAL, GETUPVAL', function (t) {
}, "Program executed without errors");
t.strictEqual(
- L.stack[L.top - 1].value,
+ lapi.lua_tostring(L, -1),
"world",
"Program output is correct"
);
@@ -556,15 +558,15 @@ test('SETTABUP, GETTABUP', function (t) {
lapi.lua_call(L, 0, -1);
}, "Program executed without errors");
- t.strictEqual(
- L.stack[L.top - 1].value.get(0).value,
- "hello",
+ t.deepEqual(
+ L.stack[L.top - 1].value.get(0).jsstring(),
+ "hello", // "hello"
"Program output is correct"
);
- t.strictEqual(
- L.stack[L.top - 1].value.get("two").value,
- "world",
+ t.deepEqual(
+ L.stack[L.top - 1].value.get('116|119|111|').jsstring(), // "two"
+ "world", // "world"
"Program output is correct"
);
});
@@ -592,7 +594,7 @@ test('SELF', function (t) {
}, "Program executed without errors");
t.strictEqual(
- L.stack[L.top - 1].value,
+ lapi.lua_tostring(L, -1),
"hello",
"Program output is correct"
);
@@ -732,7 +734,7 @@ test('TFORCALL, TFORLOOP', function (t) {
}, "Program executed without errors");
t.strictEqual(
- L.stack[L.top - 1].value,
+ lapi.lua_tointeger(L, -1),
6,
"Program output is correct"
);
@@ -758,19 +760,19 @@ test('LEN', function (t) {
}, "Program executed without errors");
t.strictEqual(
- L.stack[L.top - 1].value,
+ lapi.lua_tointeger(L, -1),
5,
"Program output is correct"
);
t.strictEqual(
- L.stack[L.top - 2].value,
+ lapi.lua_tointeger(L, -2),
3,
"Program output is correct"
);
t.strictEqual(
- L.stack[L.top - 3].value,
+ lapi.lua_tointeger(L, -3),
0,
"Program output is correct"
);
@@ -792,7 +794,7 @@ test('CONCAT', function (t) {
}, "Program executed without errors");
t.strictEqual(
- L.stack[L.top - 1].value,
+ lapi.lua_tostring(L, -1),
"hello 2 you",
"Program output is correct"
);
diff --git a/tests/tests.js b/tests/tests.js
index 32f6563..40bebd8 100644
--- a/tests/tests.js
+++ b/tests/tests.js
@@ -40,6 +40,5 @@ const getState = function(luaCode) {
return L;
};
-
module.exports.getState = getState;
module.exports.toByteCode = toByteCode; \ No newline at end of file