From 74dda64eab7951da520dc451a1f3bbb8c7d62706 Mon Sep 17 00:00:00 2001 From: Benoit Giannangeli Date: Tue, 28 Feb 2017 21:15:16 +0100 Subject: Bytecode generation --- src/lua.js | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) (limited to 'src/lua.js') diff --git a/src/lua.js b/src/lua.js index c7d1fd7..60cc78e 100644 --- a/src/lua.js +++ b/src/lua.js @@ -62,6 +62,25 @@ constant_types.LUA_TLCL = constant_types.LUA_TFUNCTION | (0 << 4); /* Lua closu constant_types.LUA_TLCF = constant_types.LUA_TFUNCTION | (1 << 4); /* light C function */ constant_types.LUA_TCCL = constant_types.LUA_TFUNCTION | (2 << 4); /* C closure */ +/* +** Comparison and arithmetic functions +*/ + +const LUA_OPADD = 0; /* ORDER TM, ORDER OP */ +const LUA_OPSUB = 1; +const LUA_OPMUL = 2; +const LUA_OPMOD = 3; +const LUA_OPPOW = 4; +const LUA_OPDIV = 5; +const LUA_OPIDIV = 6; +const LUA_OPBAND = 7; +const LUA_OPBOR = 8; +const LUA_OPBXOR = 9; +const LUA_OPSHL = 10; +const LUA_OPSHR = 11; +const LUA_OPUNM = 12; +const LUA_OPBNOT = 13; + const LUA_OPEQ = 0; const LUA_OPLT = 1; const LUA_OPLE = 2; @@ -121,9 +140,23 @@ module.exports.LUA_INIT_VAR = LUA_INIT_VAR; module.exports.LUA_MINSTACK = LUA_MINSTACK; module.exports.LUA_MULTRET = -1; module.exports.LUA_NUMTAGS = LUA_NUMTAGS; +module.exports.LUA_OPADD = LUA_OPADD; +module.exports.LUA_OPBAND = LUA_OPBAND; +module.exports.LUA_OPBNOT = LUA_OPBNOT; +module.exports.LUA_OPBOR = LUA_OPBOR; +module.exports.LUA_OPBXOR = LUA_OPBXOR; +module.exports.LUA_OPDIV = LUA_OPDIV; module.exports.LUA_OPEQ = LUA_OPEQ; +module.exports.LUA_OPIDIV = LUA_OPIDIV; module.exports.LUA_OPLE = LUA_OPLE; module.exports.LUA_OPLT = LUA_OPLT; +module.exports.LUA_OPMOD = LUA_OPMOD; +module.exports.LUA_OPMUL = LUA_OPMUL; +module.exports.LUA_OPPOW = LUA_OPPOW; +module.exports.LUA_OPSHL = LUA_OPSHL; +module.exports.LUA_OPSHR = LUA_OPSHR; +module.exports.LUA_OPSUB = LUA_OPSUB; +module.exports.LUA_OPUNM = LUA_OPUNM; module.exports.LUA_REGISTRYINDEX = LUA_REGISTRYINDEX; module.exports.LUA_RELEASE = LUA_RELEASE; module.exports.LUA_RIDX_GLOBALS = LUA_RIDX_GLOBALS; -- cgit v1.2.3-54-g00ecf From ae8b95ee9c3871f506b20c74367fdc9e8cb098e2 Mon Sep 17 00:00:00 2001 From: Benoit Giannangeli Date: Wed, 1 Mar 2017 10:23:32 +0100 Subject: lua_load will load both binary and text --- src/lapi.js | 31 +++++++++++----------- src/lcode.js | 50 +++++++++++++++++++++++++++++++++-- src/ldo.js | 78 +++++++++++++++++++++++++++++++++++++++++-------------- src/llex.js | 46 ++++++++++++++++++-------------- src/lobject.js | 50 +---------------------------------- src/lparser.js | 44 ++++++++++++++++++++++++++++++- src/lua.js | 32 +++++++++++++---------- src/lundump.js | 3 ++- tests/lapi.js | 1 - tests/lbaselib.js | 1 - tests/lcorolib.js | 1 - tests/ldebug.js | 1 - tests/llex.js | 1 - tests/lmathlib.js | 1 - tests/load.js | 68 ++++++++++++++++++++++++++++++++++++++++++++++++ tests/ltablib.js | 1 - tests/ltm.js | 1 - tests/lvm.js | 1 - tests/tests.js | 1 - 19 files changed, 282 insertions(+), 130 deletions(-) create mode 100644 tests/load.js (limited to 'src/lua.js') diff --git a/src/lapi.js b/src/lapi.js index 9a05638..36da7c6 100644 --- a/src/lapi.js +++ b/src/lapi.js @@ -2,16 +2,17 @@ const assert = require('assert'); +const ldebug = require('./ldebug.js'); const ldo = require('./ldo.js'); +const lfunc = require('./lfunc.js'); +const llex = require('./llex.js'); const lobject = require('./lobject.js'); +const lstate = require('./lstate.js'); const ltm = require('./ltm.js'); -const lfunc = require('./lfunc.js'); const lua = require('./lua.js'); const luaconf = require('./luaconf.js'); -const lstate = require('./lstate.js'); -const lvm = require('./lvm.js'); const lundump = require('./lundump.js'); -const ldebug = require('./ldebug.js'); +const lvm = require('./lvm.js'); const MAXUPVAL = lfunc.MAXUPVAL; const CT = lua.constant_types; const TS = lua.thread_status; @@ -137,7 +138,7 @@ const lua_settop = function(L, idx) { const lua_pop = function(L, n) { lua_settop(L, -n - 1); -} +}; const reverse = function(L, from, to) { for (; from < to; from++, to--) { @@ -356,7 +357,7 @@ const lua_settable = function(L, idx) { }; const lua_setfield = function(L, idx, k) { - auxsetstr(L, index2addr(L, idx), k) + auxsetstr(L, index2addr(L, idx), k); }; const lua_seti = function(L, idx, n) { @@ -514,11 +515,11 @@ const lua_rawlen = function(L, idx) { }; const lua_tointeger = function(L, idx) { - return lvm.tointeger(index2addr(L, idx)) + return lvm.tointeger(index2addr(L, idx)); }; const lua_tonumber = function(L, idx) { - return lvm.tonumber(index2addr(L, idx)) + return lvm.tonumber(index2addr(L, idx)); }; const lua_tothread = function(L, idx) { @@ -596,7 +597,7 @@ const lua_typename = function(L, t) { const lua_isnoneornil = function(L, n) { return lua_type(L, n) <= 0; -} +}; const lua_istable = function(L, idx) { return index2addr(L, idx).ttistable(); @@ -625,13 +626,14 @@ const lua_rawequal = function(L, index1, index2) { ** 'load' and 'call' functions (run Lua code) */ -const lua_load = function(L, data, chunckname) { +// TODO: reader is ignored because we don't implement ZIO +const lua_load = function(L, reader, data, chunckname, mode) { + let z = new llex.MBuffer(data); if (!chunckname) chunckname = "?"; - - let status = ldo.luaD_protectedparser(L, data, chunckname); - if (status === TS.LUA_OK) { + let status = ldo.luaD_protectedparser(L, z, chunckname, mode); + if (status === TS.LUA_OK) { /* no errors? */ let f = L.stack[L.top - 1]; /* get newly created function */ - if (f.nupvalues >= 1) { /* does it have an upvalue? */ + if (f.nupvalues >= 1) { /* does it have an upvalue? */ /* get global table from registry */ let reg = L.l_G.l_registry; let gt = reg.value.get(lua.LUA_RIDX_GLOBALS - 1); @@ -639,7 +641,6 @@ const lua_load = function(L, data, chunckname) { f.upvals[0].u.value = gt; } } - return status; }; diff --git a/src/lcode.js b/src/lcode.js index c2134ff..9b48d4d 100644 --- a/src/lcode.js +++ b/src/lcode.js @@ -5,14 +5,60 @@ const assert = require('assert'); const llex = require('./llex.js'); const llimit = require('./llimit.js'); const lobject = require('./lobject.js'); -const lopcode = require('./lopcode.js'); +const lopcode = require('./lopcodes.js'); const lparser = require('./lparser.js'); +const ltm = require('./ltm.js'); const lua = require('./lua.js'); const lvm = require('./lvm.js'); const CT = lua.constants_type; const OpCodesI = lopcode.OpCodesI; const TValue = lobject.TValue; +const luaO_arith = function(L, op, p1, p2, res) { + switch (op) { + case lvm.LUA_OPBAND: case lvm.LUA_OPBOR: case lvm.LUA_OPBXOR: + case lvm.LUA_OPSHL: case lvm.LUA_OPSHR: + case lvm.LUA_OPBNOT: { /* operate only on integers */ + let i1 = lvm.tointeger(p1); + let i2 = lvm.tointeger(p2); + if (i1 !== false && i2 !== false) { + res.type = CT.LUA_TNUMINT; + res.value = lobject.intarith(L, op, i1, i2); + return; + } + else break; /* go to the end */ + } + case lvm.LUA_OPDIV: case lvm.LUA_OPPOW: { /* operate only on floats */ + let n1 = lvm.tonumber(p1); + let n2 = lvm.tonumber(p2); + if (n1 !== false && n2 !== false) { + res.type = CT.LUA_TNUMFLT; + res.value = lobject.numarith(L, op, n1, n2); + return; + } + else break; /* go to the end */ + } + default: { /* other operations */ + let n1 = lvm.tonumber(p1); + let n2 = lvm.tonumber(p2); + if (p1.ttisinteger() && p2.ttisinteger()) { + res.type = CT.LUA_TNUMINT; + res.value = lobject.intarith(L, op, p1.value, p2.value); + return; + } + else if (n1 !== false && n2 !== false) { + res.type = CT.LUA_TNUMFLT; + res.value = lobject.numarith(L, op, n1, n2); + return; + } + else break; /* go to the end */ + } + } + /* could not perform raw operation; try metamethod */ + assert(L !== null); /* should not fail when folding (compile time) */ + ltm.luaT_trybinTM(L, p1, p2, res, (op - lua.LUA_OPADD) + ltm.TMS.TM_ADD); +}; + /* Maximum number of registers in a Lua function (must fit in 8 bits) */ const MAXREGS = 255; @@ -964,7 +1010,7 @@ const constfolding = function(fs, op, e1, e2) { let res = new TValue(); if (!tonumeral(e1, v1) || !tonumeral(e2, v2) || !validop(op, v1, v2)) return 0; /* non-numeric operands or not safe to fold */ - lobject.luaO_arith(fs.ls.L, op, v1, v2, res); /* does operation */ + luaO_arith(fs.ls.L, op, v1, v2, res); /* does operation */ if (res.ttisinteger()) { e1.k = ek.VKINT; e1.u.ival = res.value; diff --git a/src/ldo.js b/src/ldo.js index 4345b15..f78cc9c 100644 --- a/src/ldo.js +++ b/src/ldo.js @@ -3,15 +3,18 @@ const assert = require('assert'); -const lua = require('./lua.js'); +const BytecodeParser = require('./lundump.js'); +const lapi = require('./lapi.js'); +const ldebug = require('./ldebug.js'); +const lfunc = require('./lfunc.js'); +const llex = require('./llex.js'); +const llimit = require('./llimit.js'); const lobject = require('./lobject.js'); +const lparser = require('./lparser.js'); const lstate = require('./lstate.js'); -const llimit = require('./llimit.js'); const ltm = require('./ltm.js'); +const lua = require('./lua.js'); const lvm = require('./lvm.js'); -const lfunc = require('./lfunc.js'); -const BytecodeParser = require('./lundump.js'); -const ldebug = require('./ldebug.js'); const CT = lua.constant_types; const TS = lua.thread_status; const LUA_MULTRET = lua.LUA_MULTRET; @@ -475,7 +478,7 @@ const lua_yield = function(L, n) { const luaD_pcall = function(L, func, u, old_top, ef) { let old_ci = L.ci; - // TODO: lu_byte old_allowhooks = L->allowhook; + let old_allowhooks = L.allowhook; let old_nny = L.nny; let old_errfunc = L.errfunc; L.errfunc = ef; @@ -486,7 +489,7 @@ const luaD_pcall = function(L, func, u, old_top, ef) { lfunc.luaF_close(L, old_top); seterrorobj(L, status, old_top); L.ci = old_ci; - // TODO: L->allowhook = old_allowhooks; + L.allowhook = old_allowhooks; L.nny = old_nny; } @@ -504,31 +507,64 @@ const luaD_callnoyield = function(L, off, nResults) { L.nny--; }; -// TODO: since we only handle binary, no need for a reader or mode -const f_parser = function(L, data) { - let p = new BytecodeParser(data); - let cl = p.luaU_undump(L); +/* +** Execute a protected parser. +*/ +class SParser { + constructor() { /* data to 'f_parser' */ + this.z = new llex.MBuffer(); + this.buff = new llex.MBuffer(); /* dynamic structure used by the scanner */ + this.dyd = new lparser.Dyndata(); /* dynamic structures used by the parser */ + this.mode = null; + this.name = null; + } +} - assert(cl.nupvalues === cl.p.upvalues.length); +const checkmode = function(L, mode, x) { + if (mode && mode !== x) { + lapi.lua_pushstring(L, `attempt to load a ${x} chunk (mode is '${mode}')`); + luaD_throw(L, TS.LUA_ERRSYNTAX); + } +}; + +const f_parser = function(L, p) { + let cl; + 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(p.z.buffer).luaU_undump(L); + } else { + checkmode(L, p.mode, "text"); + cl = lparser.luaY_parser(L, p.z, p.buff, p.dyd, p.name, c); + } + assert(cl.nupvalues === cl.p.upvalues.length); lfunc.luaF_initupvals(L, cl); }; -const luaD_protectedparser = function(L, data, name) { - L.nny++; +const luaD_protectedparser = function(L, z, name, mode) { + let p = new SParser(); + L.nny++; /* cannot yield during parsing */ + + p.z = z; + p.name = name; + p.mode = mode; + p.dyd.actvar.arr = null; + p.dyd.actvar.size = 0; + p.dyd.gt.arr = null; + p.dyd.gt.size = 0; + p.dyd.label.arr = null; + p.dyd.label.size = 0; - let status = luaD_pcall(L, f_parser, data, L.top, L.errfunc); + let status = luaD_pcall(L, f_parser, p, L.top, L.errfunc); L.nny--; return status; }; +module.exports.SParser = SParser; module.exports.adjust_varargs = adjust_varargs; -module.exports.lua_isyieldable = lua_isyieldable; -module.exports.lua_resume = lua_resume; -module.exports.lua_yield = lua_yield; -module.exports.lua_yieldk = lua_yieldk; module.exports.luaD_call = luaD_call; module.exports.luaD_callnoyield = luaD_callnoyield; module.exports.luaD_pcall = luaD_pcall; @@ -537,6 +573,10 @@ module.exports.luaD_precall = luaD_precall; module.exports.luaD_protectedparser = luaD_protectedparser; module.exports.luaD_rawrunprotected = luaD_rawrunprotected; module.exports.luaD_throw = luaD_throw; +module.exports.lua_isyieldable = lua_isyieldable; +module.exports.lua_resume = lua_resume; +module.exports.lua_yield = lua_yield; +module.exports.lua_yieldk = lua_yieldk; module.exports.moveresults = moveresults; module.exports.nil = nil; module.exports.stackerror = stackerror; diff --git a/src/llex.js b/src/llex.js index 59bc4a4..73cda58 100644 --- a/src/llex.js +++ b/src/llex.js @@ -1,17 +1,18 @@ "use strict"; -const assert = require('assert'); - -const lapi = require('./lapi.js'); -const lauxlib = require('./lauxlib.js'); -const ldebug = require('./ldebug.js'); -const ldo = require('./ldo.js'); -const ljstype = require('./ljstype'); -const lobject = require('./lobject'); -const lua = require('./lua.js'); -const TValue = lobject.TValue; -const CT = lua.constant_types; -const TS = lua.thread_status; +const DataView = require('buffer-dataview'); +const assert = require('assert'); + +const lapi = require('./lapi.js'); +const lauxlib = require('./lauxlib.js'); +const ldebug = require('./ldebug.js'); +const ldo = require('./ldo.js'); +const ljstype = require('./ljstype'); +const lobject = require('./lobject'); +const lua = require('./lua.js'); +const TValue = lobject.TValue; +const CT = lua.constant_types; +const TS = lua.thread_status; const FIRST_RESERVED = 257; @@ -72,11 +73,18 @@ const luaX_tokens = [ const NUM_RESERVED = Object.keys(RESERVED).length; class MBuffer { - constructor(string) { - this.buffer = string ? string.split('') : []; - this.n = this.buffer.length; + constructor(data) { + this.buffer = typeof data === "string" ? data.split('') : (data ? data : []); + this.n = this.buffer instanceof DataView ? this.buffer.byteLength : this.buffer.length; this.off = 0; } + + getc() { + if (this.buffer instanceof DataView) + return this.n-- > 0 ? this.buffer.getUint8(this.off++, true) : -1; + + return this.n-- > 0 ? this.buffer[this.off++] : -1; + } } class SemInfo { @@ -90,7 +98,7 @@ class SemInfo { class Token { constructor() { this.token = NaN; - this.seminfo = null; + this.seminfo = new SemInfo(); } } @@ -101,8 +109,8 @@ class LexState { this.current = NaN; /* current character (charint) */ this.linenumber = NaN; /* input line counter */ this.lastline = NaN; /* line of last token 'consumed' */ - this.t = null; /* current token */ - this.lookahead = null; /* look ahead token */ + this.t = new Token(); /* current token */ + this.lookahead = new Token(); /* look ahead token */ this.fs = null; /* current function (parser) */ this.L = null; this.z = new MBuffer(); @@ -140,7 +148,7 @@ const currIsNewline = function(ls) { }; const next = function(ls) { - ls.current = ls.z.n-- > 0 ? ls.z.buffer[ls.z.off++] : -1; + ls.current = ls.z.getc(); }; const save_and_next = function(ls) { diff --git a/src/lobject.js b/src/lobject.js index f3078d1..f748416 100644 --- a/src/lobject.js +++ b/src/lobject.js @@ -4,10 +4,8 @@ const assert = require('assert'); const ljstype = require('./ljstype.js'); -const ltm = require('./ltm.js'); const lua = require('./lua.js'); -const lvm = require('./lvm.js'); -const CT = require('./lua.js').constant_types; +const CT = lua.constant_types; const UpVal = require('./lfunc.js').UpVal; class TValue { @@ -400,57 +398,11 @@ const numarith = function(L, op, v1, v2) { } }; -const luaO_arith = function(L, op, p1, p2, res) { - switch (op) { - case lvm.LUA_OPBAND: case lvm.LUA_OPBOR: case lvm.LUA_OPBXOR: - case lvm.LUA_OPSHL: case lvm.LUA_OPSHR: - case lvm.LUA_OPBNOT: { /* operate only on integers */ - let i1 = lvm.tointeger(p1); - let i2 = lvm.tointeger(p2); - if (i1 !== false && i2 !== false) { - res.type = CT.LUA_TNUMINT; - res.value = intarith(L, op, i1, i2); - return; - } - else break; /* go to the end */ - } - case lvm.LUA_OPDIV: case lvm.LUA_OPPOW: { /* operate only on floats */ - let n1 = lvm.tonumber(p1); - let n2 = lvm.tonumber(p2); - if (n1 !== false && n2 !== false) { - res.type = CT.LUA_TNUMFLT; - res.value = numarith(L, op, n1, n2); - return; - } - else break; /* go to the end */ - } - default: { /* other operations */ - let n1 = lvm.tonumber(p1); - let n2 = lvm.tonumber(p2); - if (p1.ttisinteger() && p2.ttisinteger()) { - res.type = CT.LUA_TNUMINT; - res.value = intarith(L, op, p1.value, p2.value); - return; - } - else if (n1 !== false && n2 !== false) { - res.type = CT.LUA_TNUMFLT; - res.value = numarith(L, op, n1, n2); - return; - } - else break; /* go to the end */ - } - } - /* could not perform raw operation; try metamethod */ - assert(L !== null); /* should not fail when folding (compile time) */ - ltm.luaT_trybinTM(L, p1, p2, res, (op - lua.LUA_OPADD) + ltm.TMS.TM_ADD); -}; - module.exports.CClosure = CClosure; module.exports.LClosure = LClosure; module.exports.TValue = TValue; module.exports.Table = Table; module.exports.UTF8BUFFSZ = UTF8BUFFSZ; -module.exports.luaO_arith = luaO_arith; module.exports.luaO_chunkid = luaO_chunkid; module.exports.luaO_hexavalue = luaO_hexavalue; module.exports.luaO_int2fb = luaO_int2fb; diff --git a/src/lparser.js b/src/lparser.js index 074542a..40d6c88 100644 --- a/src/lparser.js +++ b/src/lparser.js @@ -7,7 +7,7 @@ const lfunc = require('./lfunc.js'); const llex = require('./llex.js'); const llimit = require('./llimit.js'); const lobject = require('./lobject.js'); -const lopcode = require('./lopcode.js'); +const lopcode = require('./lopcodes.js'); const lua = require('./lua.js'); const BinOpr = lcode.BinOpr; const CT = lua.constants_type; @@ -106,6 +106,47 @@ class FuncState { } } + /* description of active local variable */ +class Vardesc { + constructor() { + this.idx = NaN; /* variable index in stack */ + } +} + + +/* description of pending goto statements and label statements */ +class Labeldesc { + constructor() { + this.name = null; /* label identifier */ + this.pc = NaN; /* position in code */ + this.line = NaN; /* line where it appeared */ + this.nactvar = NaN; /* local level where it appears in current block */ + } +} + + +/* list of labels or gotos */ +class Labellist { + constructor() { + this.arr = []; /* array */ + this.n = NaN; /* number of entries in use */ + this.size = NaN; /* array size */ + } +} + +/* dynamic structures used by the parser */ +class Dyndata { + constructor() { + this.actvar = { /* list of active local variables */ + arr: [], + n: NaN, + size: NaN + }; + this.gt = new Labellist(); + this.label = new Labellist(); + } +} + const semerror = function(ls, msg) { ls.t.token = 0; /* remove "near " from final message */ llex.luaX_syntaxerror(ls, msg); @@ -1511,6 +1552,7 @@ const luaY_parser = function(L, z, buff, dyd, name, firstchar) { }; +module.exports.Dyndata = Dyndata; module.exports.expkind = expkind; module.exports.luaY_parser = luaY_parser; module.exports.vkisinreg = vkisinreg; \ No newline at end of file diff --git a/src/lua.js b/src/lua.js index 60cc78e..9367746 100644 --- a/src/lua.js +++ b/src/lua.js @@ -5,6 +5,9 @@ const assert = require('assert'); const lualib = require('./lualib.js'); const luaconf = require('./luaconf.js'); +/* mark for precompiled code ('Lua') */ +const LUA_SIGNATURE = "\x1bLua"; + const LUA_VERSION_MAJOR = "5"; const LUA_VERSION_MINOR = "3"; const LUA_VERSION_NUM = 503; @@ -106,21 +109,21 @@ const print_version = function() { class lua_Debug { constructor() { - // int event; - // const char *name; /* (n) */ - // const char *namewhat; /* (n) 'global', 'local', 'field', 'method' */ - // const char *what; /* (S) 'Lua', 'C', 'main', 'tail' */ - // const char *source; /* (S) */ - // int currentline; /* (l) */ - // int linedefined; /* (S) */ - // int lastlinedefined; /* (S) */ - // unsigned char nups; /* (u) number of upvalues */ - // unsigned char nparams;/* (u) number of parameters */ - // char isvararg; /* (u) */ - // char istailcall; /* (t) */ - // char short_src[LUA_IDSIZE]; /* (S) */ + this.event = NaN; + this.name = null; /* (n) */ + this.namewhat = null; /* (n) 'global', 'local', 'field', 'method' */ + this.what = null; /* (S) 'Lua', 'C', 'main', 'tail' */ + this.source = null; /* (S) */ + this.currentline = NaN; /* (l) */ + this.linedefined = NaN; /* (S) */ + this.lastlinedefined = NaN; /* (S) */ + this.nups = NaN; /* (u) number of upvalues */ + this.nparams = NaN; /* (u) number of parameters */ + this.isvararg = NaN; /* (u) */ + this.istailcall = NaN; /* (t) */ + this.short_src = null; /* (S) */ /* private part */ - // struct CallInfo *i_ci; /* active function */ + this.i_ci = null; /* active function */ } } @@ -162,6 +165,7 @@ module.exports.LUA_RELEASE = LUA_RELEASE; module.exports.LUA_RIDX_GLOBALS = LUA_RIDX_GLOBALS; module.exports.LUA_RIDX_LAST = LUA_RIDX_LAST; module.exports.LUA_RIDX_MAINTHREAD = LUA_RIDX_MAINTHREAD; +module.exports.LUA_SIGNATURE = LUA_SIGNATURE; module.exports.LUA_VERSION = LUA_VERSION; module.exports.LUA_VERSION_MAJOR = LUA_VERSION_MAJOR; module.exports.LUA_VERSION_MINOR = LUA_VERSION_MINOR; diff --git a/src/lundump.js b/src/lundump.js index b79e6ea..5a6d8c4 100644 --- a/src/lundump.js +++ b/src/lundump.js @@ -5,6 +5,7 @@ const DataView = require('buffer-dataview'); const fs = require('fs'); const assert = require('assert'); +const lua = require('./lua.js'); const LClosure = require('./lobject.js').LClosure; const TValue = require('./lobject.js').TValue; const Proto = require('./lfunc.js').Proto; @@ -256,7 +257,7 @@ class BytecodeParser { } checkHeader() { - if (this.readString(4) !== "\x1bLua") + if (this.readString(4) !== lua.LUA_SIGNATURE) throw new Error("bad LUA_SIGNATURE, expected 'Lua'"); if (this.readByte() !== 0x53) diff --git a/tests/lapi.js b/tests/lapi.js index 30366d5..6761425 100644 --- a/tests/lapi.js +++ b/tests/lapi.js @@ -1,4 +1,3 @@ -/*jshint esversion: 6 */ "use strict"; const test = require('tape'); diff --git a/tests/lbaselib.js b/tests/lbaselib.js index be5cdad..72a2f15 100644 --- a/tests/lbaselib.js +++ b/tests/lbaselib.js @@ -1,4 +1,3 @@ -/*jshint esversion: 6 */ "use strict"; const test = require('tape'); diff --git a/tests/lcorolib.js b/tests/lcorolib.js index 78024dd..022cda6 100644 --- a/tests/lcorolib.js +++ b/tests/lcorolib.js @@ -1,4 +1,3 @@ -/*jshint esversion: 6 */ "use strict"; const test = require('tape'); diff --git a/tests/ldebug.js b/tests/ldebug.js index 491b8ba..45194e9 100644 --- a/tests/ldebug.js +++ b/tests/ldebug.js @@ -1,4 +1,3 @@ -/*jshint esversion: 6 */ "use strict"; const test = require('tape'); diff --git a/tests/llex.js b/tests/llex.js index 1457af3..8b69acc 100644 --- a/tests/llex.js +++ b/tests/llex.js @@ -1,4 +1,3 @@ -/*jshint esversion: 6 */ "use strict"; const test = require('tape'); diff --git a/tests/lmathlib.js b/tests/lmathlib.js index ba6853c..48ae1a2 100644 --- a/tests/lmathlib.js +++ b/tests/lmathlib.js @@ -1,4 +1,3 @@ -/*jshint esversion: 6 */ "use strict"; const test = require('tape'); diff --git a/tests/load.js b/tests/load.js new file mode 100644 index 0000000..4df3f6a --- /dev/null +++ b/tests/load.js @@ -0,0 +1,68 @@ +"use strict"; + +const test = require('tape'); +const beautify = require('js-beautify').js_beautify; + +const tests = require("./tests.js"); +const toByteCode = tests.toByteCode; + +const lapi = require("../src/lapi.js"); +const lauxlib = require("../src/lauxlib.js"); +const linit = require('../src/linit.js'); + +test('lua_load, binary mode', function (t) { + let luaCode = ` + return "hello world" + `, L; + + t.plan(2); + + t.doesNotThrow(function () { + + let bc = toByteCode(luaCode).dataView; + + L = lauxlib.luaL_newstate(); + + linit.luaL_openlibs(L); + + lapi.lua_load(L, null, bc, "test-math", "binary"); + + lapi.lua_call(L, 0, -1); + + }, "JS Lua program ran without error"); + + t.strictEqual( + lapi.lua_tostring(L, -1), + "hello world", + "Correct element(s) on the stack" + ); + +}); + + +test('lua_load, text mode', function (t) { + let luaCode = ` + return "hello world" + `, L; + + t.plan(2); + + // t.doesNotThrow(function () { + + L = lauxlib.luaL_newstate(); + + linit.luaL_openlibs(L); + + lapi.lua_load(L, null, luaCode, "test-math", "text"); + + lapi.lua_call(L, 0, -1); + + // }, "JS Lua program ran without error"); + + t.strictEqual( + lapi.lua_tostring(L, -1), + "hello world", + "Correct element(s) on the stack" + ); + +}); \ No newline at end of file diff --git a/tests/ltablib.js b/tests/ltablib.js index fa15d6a..2ebf98c 100644 --- a/tests/ltablib.js +++ b/tests/ltablib.js @@ -1,4 +1,3 @@ -/*jshint esversion: 6 */ "use strict"; const test = require('tape'); diff --git a/tests/ltm.js b/tests/ltm.js index a05d2b5..d749d7b 100644 --- a/tests/ltm.js +++ b/tests/ltm.js @@ -1,4 +1,3 @@ -/*jshint esversion: 6 */ "use strict"; const test = require('tape'); diff --git a/tests/lvm.js b/tests/lvm.js index 4f02ed5..5d4eae1 100644 --- a/tests/lvm.js +++ b/tests/lvm.js @@ -1,4 +1,3 @@ -/*jshint esversion: 6 */ "use strict"; const test = require('tape'); diff --git a/tests/tests.js b/tests/tests.js index 0963159..a47aee5 100644 --- a/tests/tests.js +++ b/tests/tests.js @@ -1,4 +1,3 @@ -/*jshint esversion: 6 */ "use strict"; const fs = require('fs'); -- cgit v1.2.3-54-g00ecf From 444182dbbb18f44cf7cafc378f092c28006be365 Mon Sep 17 00:00:00 2001 From: Benoit Giannangeli Date: Wed, 1 Mar 2017 11:51:00 +0100 Subject: Loading tests (binary/text) --- src/lcode.js | 20 ++++++++------------ src/lfunc.js | 4 ++++ src/llex.js | 4 ++-- src/lopcodes.js | 34 ++++++++++++++++++++++++++-------- src/lparser.js | 10 ++++------ src/lua.js | 8 +++++++- src/lualib.js | 25 ++++++++++--------------- tests/lapi.js | 6 +++--- tests/lbaselib.js | 34 +++++++++++++++++----------------- tests/lcorolib.js | 10 +++++----- tests/ldebug.js | 14 +++++++------- tests/lexparse.js | 39 +++++++++++++++++++++++++++++++++++++++ tests/lmathlib.js | 26 +++++++++++++------------- tests/load.js | 8 ++++---- tests/ltablib.js | 16 ++++++++-------- 15 files changed, 157 insertions(+), 101 deletions(-) create mode 100644 tests/lexparse.js (limited to 'src/lua.js') diff --git a/src/lcode.js b/src/lcode.js index 9b48d4d..d8b0252 100644 --- a/src/lcode.js +++ b/src/lcode.js @@ -10,7 +10,7 @@ const lparser = require('./lparser.js'); const ltm = require('./ltm.js'); const lua = require('./lua.js'); const lvm = require('./lvm.js'); -const CT = lua.constants_type; +const CT = lua.CT; const OpCodesI = lopcode.OpCodesI; const TValue = lobject.TValue; @@ -483,7 +483,7 @@ const freeexps = function(fs, e1, e2) { const addk = function(fs, key, v) { let f = fs.f; let idx = fs.ls.h.__index(fs.ls.h, key); /* index scanner table */ - if (idx) { /* is there an index there? */ + if (idx && !idx.ttisnil()) { /* is there an index there? */ /* correct value? (warning: must distinguish floats from integers!) */ if (f.k[idx].ttype() === v.ttype() && f.k[idx].value === v.value) return idx; /* reuse index */ @@ -500,8 +500,7 @@ const addk = function(fs, key, v) { ** Add a string to list of constants and return its index. */ const luaK_stringK = function(fs, s) { - let o = new TValue(CT.LUA_TLNGSTR, s); - return addk(fs, o, o); /* use string itself as key */ + return addk(fs, s, s); /* use string itself as key */ }; @@ -512,8 +511,8 @@ const luaK_stringK = function(fs, s) { ** are no "precision" problems. */ const luaK_intK = function(fs, n) { - let k = new TValue(CT.LUA_TLNGSTR, `n`); - let o = new TValue(CT.LUA_TNUMINT, n); + let k = new TValue(CT.LUA_TLNGSTR, `${n.value}`); + let o = new TValue(CT.LUA_TNUMINT, n.value); return addk(fs, k, o); }; @@ -521,8 +520,7 @@ const luaK_intK = function(fs, n) { ** Add a float to list of constants and return its index. */ const luaK_numberK = function(fs, r) { - let o = new TValue(CT.LUA_TNUMFLT, r); - return addk(fs, o, o); /* use number itself as key */ + return addk(fs, r, r); /* use number itself as key */ }; @@ -530,8 +528,7 @@ const luaK_numberK = function(fs, r) { ** Add a boolean to list of constants and return its index. */ const boolK = function(fs, b) { - let o = new TValue(CT.LUA_TBOOLEAN, b); - return addk(fs, o, o); /* use boolean itself as key */ + return addk(fs, b, b); /* use boolean itself as key */ }; @@ -539,8 +536,7 @@ const boolK = function(fs, b) { ** Add nil to list of constants and return its index. */ const nilK = function(fs) { - let o = new TValue(CT.LUA_TNIL, null); - return addk(fs, o, o); + return addk(fs, new TValue(CT.LUA_TLNGSTR, `null`), new TValue(CT.LUA_TNIL, null)); }; /* diff --git a/src/lfunc.js b/src/lfunc.js index 37239b2..227606d 100644 --- a/src/lfunc.js +++ b/src/lfunc.js @@ -102,12 +102,16 @@ const luaF_close = function(L, level) { } }; +/* +** fill a closure with new closed upvalues +*/ const luaF_initupvals = function(L, cl) { for (let i = 0; i < cl.nupvalues; i++) { let uv = new UpVal(L); uv.refcount = 1; uv.u.value = null; uv.v = uv.u.value; + cl.upvals[i] = uv; } }; diff --git a/src/llex.js b/src/llex.js index 73cda58..63a1fbb 100644 --- a/src/llex.js +++ b/src/llex.js @@ -453,7 +453,7 @@ const read_string = function(ls, del, seminfo) { } } save_and_next(ls); /* skip delimiter */ - seminfo.ts = new TValue(CT.LUA_TLNGSTR, ls.buff.buffer.slice(1).join('')); + seminfo.ts = new TValue(CT.LUA_TLNGSTR, ls.buff.buffer.slice(1, ls.buff.buffer.length-1).join('')); }; const isreserved = function(w) { @@ -566,7 +566,7 @@ const llex = function(ls, seminfo) { let ts = new TValue(CT.LUA_TLNGSTR, 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.value); if (kidx >= 0) /* reserved word? */ return kidx + FIRST_RESERVED; else diff --git a/src/lopcodes.js b/src/lopcodes.js index 3f7f63b..bfcd993 100644 --- a/src/lopcodes.js +++ b/src/lopcodes.js @@ -209,6 +209,7 @@ const MAXARG_A = ((1 << SIZE_A) - 1); const MAXARG_B = ((1 << SIZE_B) - 1); const MAXARG_C = ((1 << SIZE_C) - 1); +/* this bit 1 means constant (0 means register) */ const BITRK = (1 << (SIZE_B - 1)); /* @@ -216,14 +217,22 @@ const BITRK = (1 << (SIZE_B - 1)); */ const NO_REG = MAXARG_A; +/* test whether value is a constant */ const ISK = function (x) { return x & BITRK; }; +/* gets the index of the constant */ const INDEXK = function (r) { return r & ~BITRK; }; +/* code a constant index as a RK value */ +const RKASK = function(x) { + return x | BITRK; +}; + + /* creates a mask with 'n' 1 bits at position 'p' */ const MASK1 = function(n, p) { return ((~((~0)<<(n)))<<(p)); @@ -267,7 +276,7 @@ const SETARG_sBx = function(i, b) { ** Pre-calculate all possible part of the instruction */ const fullins = function(ins) { - if (typeof ins === "integer") { + if (typeof ins === "number") { return { code: ins, opcode: (ins >> POS_OP) & MASK1(SIZE_OP, 0), @@ -280,13 +289,13 @@ const fullins = function(ins) { }; } else { let i = ins.code; - ins.opcode = (i >> POS_OP) & MASK1(SIZE_OP, 0), - ins.A = (i >> POS_A) & MASK1(SIZE_A, 0), - ins.B = (i >> POS_B) & MASK1(SIZE_B, 0), - ins.C = (i >> POS_C) & MASK1(SIZE_C, 0), - ins.Bx = (i >> POS_Bx) & MASK1(SIZE_Bx, 0), - ins.Ax = (i >> POS_Ax) & MASK1(SIZE_Ax, 0), - ins.sBx = ((i >> POS_Bx) & MASK1(SIZE_Bx, 0)) - MAXARG_sBx + ins.opcode = (i >> POS_OP) & MASK1(SIZE_OP, 0); + ins.A = (i >> POS_A) & MASK1(SIZE_A, 0); + ins.B = (i >> POS_B) & MASK1(SIZE_B, 0); + ins.C = (i >> POS_C) & MASK1(SIZE_C, 0); + ins.Bx = (i >> POS_Bx) & MASK1(SIZE_Bx, 0); + ins.Ax = (i >> POS_Ax) & MASK1(SIZE_Ax, 0); + ins.sBx = ((i >> POS_Bx) & MASK1(SIZE_Bx, 0)) - MAXARG_sBx; return ins; } }; @@ -320,6 +329,10 @@ module.exports.MAXARG_Bx = MAXARG_Bx; module.exports.MAXARG_C = MAXARG_C; module.exports.MAXARG_sBx = MAXARG_sBx; module.exports.NO_REG = NO_REG; +module.exports.OpArgK = OpArgK; +module.exports.OpArgN = OpArgN; +module.exports.OpArgR = OpArgR; +module.exports.OpArgU = OpArgU; module.exports.OpCodes = OpCodes; module.exports.OpCodesI = OpCodesI; module.exports.POS_A = POS_A; @@ -328,6 +341,7 @@ module.exports.POS_B = POS_B; module.exports.POS_Bx = POS_Bx; module.exports.POS_C = POS_C; module.exports.POS_OP = POS_OP; +module.exports.RKASK = RKASK; module.exports.SETARG_A = SETARG_A; module.exports.SETARG_Ax = SETARG_Ax; module.exports.SETARG_B = SETARG_B; @@ -344,5 +358,9 @@ module.exports.fullins = fullins; module.exports.getBMode = getBMode; module.exports.getCMode = getCMode; module.exports.getOpMode = getOpMode; +module.exports.iABC = iABC; +module.exports.iABx = iABx; +module.exports.iAsBx = iAsBx; +module.exports.iAx = iAx; module.exports.testAMode = testAMode; module.exports.testTMode = testTMode; \ No newline at end of file diff --git a/src/lparser.js b/src/lparser.js index 40d6c88..aa48f10 100644 --- a/src/lparser.js +++ b/src/lparser.js @@ -10,7 +10,6 @@ const lobject = require('./lobject.js'); const lopcode = require('./lopcodes.js'); const lua = require('./lua.js'); const BinOpr = lcode.BinOpr; -const CT = lua.constants_type; const OpCodesI = lopcode.OpCodesI; const Proto = lfunc.Proto; const R = llex.RESERVED; @@ -239,7 +238,7 @@ const new_localvar = function(ls, name) { }; const new_localvarliteral = function(ls, name) { - new_localvar(ls, new TValue(CT.LUA_TLNGSTR, name)); + new_localvar(ls, new TValue(lua.CT.LUA_TLNGSTR, name)); }; const getlocvar = function(fs, i) { @@ -469,7 +468,7 @@ const enterblock = function(fs, bl, isloop) { ** create a label named 'break' to resolve break statements */ const breaklabel = function(ls) { - let n = new TValue(CT.LUA_TLNGSTR, "break"); + let n = new TValue(lua.CT.LUA_TLNGSTR, "break"); let l = newlabelentry(ls, ls.dyd.label, n, 0, ls.fs.pc); findgotos(ls, ls.dyd.label.arr[l]); }; @@ -507,7 +506,6 @@ const codeclosure = function(ls, v) { }; const open_func = function(ls, fs, bl) { - this.f = new Proto(); fs.prev = ls.fs; /* linked list of funcstates */ fs.ls = ls; ls.fs = fs; @@ -1132,7 +1130,7 @@ const gotostat = function(ls, pc) { label = str_checkname(ls); else { llex.luaX_next(ls); /* skip break */ - label = new TValue(CT.LUA_TLNGSTR, "break"); + label = new TValue(lua.CT.LUA_TLNGSTR, "break"); } let g = newlabelentry(ls, ls.dyd.gt, label, line, pc); findlabel(ls, g); /* close it if label already defined */ @@ -1538,7 +1536,7 @@ const luaY_parser = function(L, z, buff, dyd, name, firstchar) { lexstate.h = new Table(); /* create table for scanner */ L.stack[L.top++] = lexstate.h; funcstate.f = cl.p = new Proto(L); - funcstate.f.source = new TValue(CT.LUA_TLNGSTR, name); + funcstate.f.source = new TValue(lua.CT.LUA_TLNGSTR, name); lexstate.buff = buff; lexstate.dyd = dyd; dyd.actvar.n = dyd.gt.n = dyd.label.n = 0; diff --git a/src/lua.js b/src/lua.js index 9367746..ef5385c 100644 --- a/src/lua.js +++ b/src/lua.js @@ -28,8 +28,10 @@ const FENGARI_RELEASE = FENGARI_VERSION + "." + FENGARI_VERSION_RELEASE; const FENGARI_COPYRIGHT = FENGARI_RELEASE + " Copyright (C) 2017 BenoƮt Giannangeli\nBased on: " + LUA_COPYRIGHT; const FENGARI_AUTHORS = "B. Giannangeli"; +const LUA_VERSUFFIX = "_" + LUA_VERSION_MAJOR + "_" + LUA_VERSION_MINOR; + const LUA_INIT_VAR = "LUA_INIT"; -const LUA_INITVARVERSION = LUA_INIT_VAR + lualib.LUA_VERSUFFIX; +const LUA_INITVARVERSION = LUA_INIT_VAR + LUA_VERSUFFIX; const thread_status = { LUA_OK: 0, @@ -55,6 +57,8 @@ const constant_types = { LUA_NUMTAGS: 9 }; +const CT = constant_types; + constant_types.LUA_TSHRSTR = constant_types.LUA_TSTRING | (0 << 4); /* short strings */ constant_types.LUA_TLNGSTR = constant_types.LUA_TSTRING | (1 << 4); /* long strings */ @@ -128,6 +132,7 @@ class lua_Debug { } +module.exports.CT = CT; module.exports.FENGARI_AUTHORS = FENGARI_AUTHORS; module.exports.FENGARI_COPYRIGHT = FENGARI_COPYRIGHT; module.exports.FENGARI_RELEASE = FENGARI_RELEASE; @@ -171,6 +176,7 @@ module.exports.LUA_VERSION_MAJOR = LUA_VERSION_MAJOR; module.exports.LUA_VERSION_MINOR = LUA_VERSION_MINOR; module.exports.LUA_VERSION_NUM = LUA_VERSION_NUM; module.exports.LUA_VERSION_RELEASE = LUA_VERSION_RELEASE; +module.exports.LUA_VERSUFFIX = LUA_VERSUFFIX; module.exports.constant_types = constant_types; module.exports.lua_Debug = lua_Debug; module.exports.lua_upvalueindex = lua_upvalueindex; diff --git a/src/lualib.js b/src/lualib.js index d87cfbc..da9b290 100644 --- a/src/lualib.js +++ b/src/lualib.js @@ -2,21 +2,17 @@ "use strict"; const assert = require('assert'); -const lua = require('./lua.js'); - - -const LUA_VERSUFFIX = "_" + lua.LUA_VERSION_MAJOR + "_" + lua.LUA_VERSION_MINOR; const LUA_COLIBNAME = "coroutine"; -const LUA_TABLIBNAME = "table" -const LUA_IOLIBNAME = "io" -const LUA_OSLIBNAME = "os" -const LUA_STRLIBNAME = "string" -const LUA_UTF8LIBNAME = "utf8" -const LUA_BITLIBNAME = "bit32" -const LUA_MATHLIBNAME = "math" -const LUA_DBLIBNAME = "debug" -const LUA_LOADLIBNAME = "package" +const LUA_TABLIBNAME = "table"; +const LUA_IOLIBNAME = "io"; +const LUA_OSLIBNAME = "os"; +const LUA_STRLIBNAME = "string"; +const LUA_UTF8LIBNAME = "utf8"; +const LUA_BITLIBNAME = "bit32"; +const LUA_MATHLIBNAME = "math"; +const LUA_DBLIBNAME = "debug"; +const LUA_LOADLIBNAME = "package"; module.exports.LUA_BITLIBNAME = LUA_BITLIBNAME; @@ -28,5 +24,4 @@ module.exports.LUA_MATHLIBNAME = LUA_MATHLIBNAME; module.exports.LUA_OSLIBNAME = LUA_OSLIBNAME; module.exports.LUA_STRLIBNAME = LUA_STRLIBNAME; module.exports.LUA_TABLIBNAME = LUA_TABLIBNAME; -module.exports.LUA_UTF8LIBNAME = LUA_UTF8LIBNAME; -module.exports.LUA_VERSUFFIX = LUA_VERSUFFIX; \ No newline at end of file +module.exports.LUA_UTF8LIBNAME = LUA_UTF8LIBNAME; \ No newline at end of file diff --git a/tests/lapi.js b/tests/lapi.js index 6761425..c422ada 100644 --- a/tests/lapi.js +++ b/tests/lapi.js @@ -329,7 +329,7 @@ test('lua_pcall that breaks', function (t) { t.doesNotThrow(function () { let fn = function(L) { - return undefined_value; + return "undefined_value"; }; L = lauxlib.luaL_newstate(); @@ -382,7 +382,7 @@ test('lua_load and lua_call it', function (t) { L = lauxlib.luaL_newstate(); - lapi.lua_load(L, bc, "test-lua_load") + lapi.lua_load(L, null, bc, "test-lua_load", "binary"); lapi.lua_call(L, 0, 1); @@ -409,7 +409,7 @@ test('lua script reads js upvalues', function (t) { L = lauxlib.luaL_newstate(); - lapi.lua_load(L, bc, "test-lua_load") + lapi.lua_load(L, null, bc, "test-lua_load", "binary"); lapi.lua_pushstring(L, "hello"); lapi.lua_setglobal(L, "js"); diff --git a/tests/lbaselib.js b/tests/lbaselib.js index 72a2f15..be741dc 100644 --- a/tests/lbaselib.js +++ b/tests/lbaselib.js @@ -31,7 +31,7 @@ test('print', function (t) { linit.luaL_openlibs(L); - lapi.lua_load(L, bc, "test-print"); + lapi.lua_load(L, null, bc, "test-print", "binary"); lapi.lua_call(L, 0, -1); @@ -65,7 +65,7 @@ test('setmetatable, getmetatable', function (t) { linit.luaL_openlibs(L); - lapi.lua_load(L, bc, "test-setmetatable-getmetatable"); + lapi.lua_load(L, null, bc, "test-setmetatable-getmetatable", "binary"); lapi.lua_call(L, 0, -1); @@ -110,7 +110,7 @@ test('rawequal', function (t) { linit.luaL_openlibs(L); - lapi.lua_load(L, bc, "test-rawequal"); + lapi.lua_load(L, null, bc, "test-rawequal", "binary"); lapi.lua_call(L, 0, -1); @@ -156,7 +156,7 @@ test('rawset, rawget', function (t) { linit.luaL_openlibs(L); - lapi.lua_load(L, bc, "test-rawequal"); + lapi.lua_load(L, null, bc, "test-rawequal", "binary"); lapi.lua_call(L, 0, -1); @@ -203,7 +203,7 @@ test('type', function (t) { linit.luaL_openlibs(L); - lapi.lua_load(L, bc, "test-type"); + lapi.lua_load(L, null, bc, "test-type", "binary"); lapi.lua_call(L, 0, -1); @@ -256,7 +256,7 @@ test('error', function (t) { linit.luaL_openlibs(L); - lapi.lua_load(L, bc, "test-error"); + lapi.lua_load(L, null, bc, "test-error", "binary"); lapi.lua_call(L, 0, -1); @@ -279,7 +279,7 @@ test('error, protected', function (t) { linit.luaL_openlibs(L); - lapi.lua_load(L, bc, "test-error"); + lapi.lua_load(L, null, bc, "test-error", "binary"); lapi.lua_pcall(L, 0, -1, 0); @@ -311,7 +311,7 @@ test('pcall', function (t) { linit.luaL_openlibs(L); - lapi.lua_load(L, bc, "test-pcall"); + lapi.lua_load(L, null, bc, "test-pcall", "binary"); lapi.lua_call(L, 0, -1); @@ -347,7 +347,7 @@ test('xpcall', function (t) { linit.luaL_openlibs(L); - lapi.lua_load(L, bc, "test-pcall"); + lapi.lua_load(L, null, bc, "test-pcall", "binary"); lapi.lua_call(L, 0, -1); @@ -389,7 +389,7 @@ test('ipairs', function (t) { linit.luaL_openlibs(L); - lapi.lua_load(L, bc, "test-ipairs"); + lapi.lua_load(L, null, bc, "test-ipairs", "binary"); lapi.lua_call(L, 0, -1); @@ -418,7 +418,7 @@ test('select', function (t) { linit.luaL_openlibs(L); - lapi.lua_load(L, bc, "test-select"); + lapi.lua_load(L, null, bc, "test-select", "binary"); lapi.lua_call(L, 0, -1); @@ -459,7 +459,7 @@ test('tonumber', function (t) { linit.luaL_openlibs(L); - lapi.lua_load(L, bc, "test-tonumber"); + lapi.lua_load(L, null, bc, "test-tonumber", "binary"); lapi.lua_call(L, 0, -1); @@ -506,7 +506,7 @@ test('assert', function (t) { linit.luaL_openlibs(L); - lapi.lua_load(L, bc, "test-assert"); + lapi.lua_load(L, null, bc, "test-assert", "binary"); lapi.lua_pcall(L, 0, -1, 0); @@ -534,7 +534,7 @@ test('rawlen', function (t) { linit.luaL_openlibs(L); - lapi.lua_load(L, bc, "test-rawlen"); + lapi.lua_load(L, null, bc, "test-rawlen", "binary"); lapi.lua_call(L, 0, -1); @@ -581,7 +581,7 @@ test('next', function (t) { linit.luaL_openlibs(L); - lapi.lua_load(L, bc, "test-next"); + lapi.lua_load(L, null, bc, "test-next", "binary"); lapi.lua_call(L, 0, -1); @@ -622,7 +622,7 @@ test('pairs', function (t) { linit.luaL_openlibs(L); - lapi.lua_load(L, bc, "test-pairs"); + lapi.lua_load(L, null, bc, "test-pairs", "binary"); lapi.lua_call(L, 0, -1); @@ -672,7 +672,7 @@ test('pairs with __pairs', function (t) { linit.luaL_openlibs(L); - lapi.lua_load(L, bc, "test-pairs"); + lapi.lua_load(L, null, bc, "test-pairs", "binary"); lapi.lua_call(L, 0, -1); diff --git a/tests/lcorolib.js b/tests/lcorolib.js index 022cda6..9c1d9b1 100644 --- a/tests/lcorolib.js +++ b/tests/lcorolib.js @@ -40,7 +40,7 @@ test('coroutine.create, coroutine.yield, coroutine.resume', function (t) { linit.luaL_openlibs(L); - lapi.lua_load(L, bc, "test-coroutine"); + lapi.lua_load(L, null, bc, "test-coroutine", "binary"); lapi.lua_call(L, 0, -1); @@ -83,7 +83,7 @@ test('coroutine.status', function (t) { linit.luaL_openlibs(L); - lapi.lua_load(L, bc, "test-coroutine.status"); + lapi.lua_load(L, null, bc, "test-coroutine.status", "binary"); lapi.lua_call(L, 0, -1); @@ -124,7 +124,7 @@ test('coroutine.isyieldable', function (t) { linit.luaL_openlibs(L); - lapi.lua_load(L, bc, "test-coroutine.isyieldable"); + lapi.lua_load(L, null, bc, "test-coroutine.isyieldable", "binary"); lapi.lua_call(L, 0, -1); @@ -165,7 +165,7 @@ test('coroutine.running', function (t) { linit.luaL_openlibs(L); - lapi.lua_load(L, bc, "test-coroutine.running"); + lapi.lua_load(L, null, bc, "test-coroutine.running", "binary"); lapi.lua_call(L, 0, -1); @@ -206,7 +206,7 @@ test('coroutine.wrap', function (t) { linit.luaL_openlibs(L); - lapi.lua_load(L, bc, "test-coroutine.wrap"); + lapi.lua_load(L, null, bc, "test-coroutine.wrap", "binary"); lapi.lua_call(L, 0, -1); diff --git a/tests/ldebug.js b/tests/ldebug.js index 45194e9..472c66b 100644 --- a/tests/ldebug.js +++ b/tests/ldebug.js @@ -30,7 +30,7 @@ test('luaG_typeerror', function (t) { linit.luaL_openlibs(L); - lapi.lua_load(L, bc, "test-typeerror"); + lapi.lua_load(L, null, bc, "test-typeerror", "binary"); lapi.lua_pcall(L, 0, -1, 0); @@ -60,7 +60,7 @@ test('luaG_typeerror', function (t) { linit.luaL_openlibs(L); - lapi.lua_load(L, bc, "test-typeerror"); + lapi.lua_load(L, null, bc, "test-typeerror", "binary"); lapi.lua_pcall(L, 0, -1, 0); @@ -89,7 +89,7 @@ test('luaG_typeerror', function (t) { linit.luaL_openlibs(L); - lapi.lua_load(L, bc, "test-typeerror"); + lapi.lua_load(L, null, bc, "test-typeerror", "binary"); lapi.lua_pcall(L, 0, -1, 0); @@ -118,7 +118,7 @@ test('luaG_typeerror', function (t) { linit.luaL_openlibs(L); - lapi.lua_load(L, bc, "test-typeerror"); + lapi.lua_load(L, null, bc, "test-typeerror", "binary"); lapi.lua_pcall(L, 0, -1, 0); @@ -146,7 +146,7 @@ test('luaG_concaterror', function (t) { linit.luaL_openlibs(L); - lapi.lua_load(L, bc, "test-typeerror"); + lapi.lua_load(L, null, bc, "test-typeerror", "binary"); lapi.lua_pcall(L, 0, -1, 0); @@ -174,7 +174,7 @@ test('luaG_opinterror', function (t) { linit.luaL_openlibs(L); - lapi.lua_load(L, bc, "test-typeerror"); + lapi.lua_load(L, null, bc, "test-typeerror", "binary"); lapi.lua_pcall(L, 0, -1, 0); @@ -202,7 +202,7 @@ test('luaG_tointerror', function (t) { linit.luaL_openlibs(L); - lapi.lua_load(L, bc, "test-typeerror"); + lapi.lua_load(L, null, bc, "test-typeerror", "binary"); lapi.lua_pcall(L, 0, -1, 0); diff --git a/tests/lexparse.js b/tests/lexparse.js new file mode 100644 index 0000000..8320588 --- /dev/null +++ b/tests/lexparse.js @@ -0,0 +1,39 @@ +"use strict"; + +const test = require('tape'); +const beautify = require('js-beautify').js_beautify; + +const tests = require("./tests.js"); +const toByteCode = tests.toByteCode; + +const lapi = require("../src/lapi.js"); +const lauxlib = require("../src/lauxlib.js"); +const linit = require('../src/linit.js'); + + +test('Hello World', function (t) { + let luaCode = ` + return "hello world" + `, L; + + t.plan(2); + + t.doesNotThrow(function () { + + L = lauxlib.luaL_newstate(); + + linit.luaL_openlibs(L); + + lapi.lua_load(L, null, luaCode, "test-load", "text"); + + lapi.lua_call(L, 0, -1); + + }, "JS Lua program ran without error"); + + t.strictEqual( + lapi.lua_tostring(L, -1), + "hello world", + "Correct element(s) on the stack" + ); + +}); \ No newline at end of file diff --git a/tests/lmathlib.js b/tests/lmathlib.js index 48ae1a2..ae0c40b 100644 --- a/tests/lmathlib.js +++ b/tests/lmathlib.js @@ -33,7 +33,7 @@ test('math.abs, math.sin, math.cos, math.tan, math.asin, math.acos, math.atan', linit.luaL_openlibs(L); - lapi.lua_load(L, bc, "test-math"); + lapi.lua_load(L, null, bc, "test-math", "binary"); lapi.lua_call(L, 0, -1); @@ -98,7 +98,7 @@ test('math.ceil, math.floor', function (t) { linit.luaL_openlibs(L); - lapi.lua_load(L, bc, "test-math"); + lapi.lua_load(L, null, bc, "test-math", "binary"); lapi.lua_call(L, 0, -1); @@ -134,7 +134,7 @@ test('math.deg, math.rad', function (t) { linit.luaL_openlibs(L); - lapi.lua_load(L, bc, "test-math"); + lapi.lua_load(L, null, bc, "test-math", "binary"); lapi.lua_call(L, 0, -1); @@ -170,7 +170,7 @@ test('math.log', function (t) { linit.luaL_openlibs(L); - lapi.lua_load(L, bc, "test-math"); + lapi.lua_load(L, null, bc, "test-math", "binary"); lapi.lua_call(L, 0, -1); @@ -212,7 +212,7 @@ test('math.exp', function (t) { linit.luaL_openlibs(L); - lapi.lua_load(L, bc, "test-math"); + lapi.lua_load(L, null, bc, "test-math", "binary"); lapi.lua_call(L, 0, -1); @@ -242,7 +242,7 @@ test('math.min, math.max', function (t) { linit.luaL_openlibs(L); - lapi.lua_load(L, bc, "test-math"); + lapi.lua_load(L, null, bc, "test-math", "binary"); lapi.lua_call(L, 0, -1); @@ -278,7 +278,7 @@ test('math.random', function (t) { linit.luaL_openlibs(L); - lapi.lua_load(L, bc, "test-math"); + lapi.lua_load(L, null, bc, "test-math", "binary"); lapi.lua_call(L, 0, -1); @@ -312,7 +312,7 @@ test('math.sqrt', function (t) { linit.luaL_openlibs(L); - lapi.lua_load(L, bc, "test-math"); + lapi.lua_load(L, null, bc, "test-math", "binary"); lapi.lua_call(L, 0, -1); @@ -342,7 +342,7 @@ test('math.tointeger', function (t) { linit.luaL_openlibs(L); - lapi.lua_load(L, bc, "test-math"); + lapi.lua_load(L, null, bc, "test-math", "binary"); lapi.lua_call(L, 0, -1); @@ -372,7 +372,7 @@ test('math.type', function (t) { linit.luaL_openlibs(L); - lapi.lua_load(L, bc, "test-math"); + lapi.lua_load(L, null, bc, "test-math", "binary"); lapi.lua_call(L, 0, -1); @@ -414,7 +414,7 @@ test('math.ult', function (t) { linit.luaL_openlibs(L); - lapi.lua_load(L, bc, "test-math"); + lapi.lua_load(L, null, bc, "test-math", "binary"); lapi.lua_call(L, 0, -1); @@ -444,7 +444,7 @@ test('math.fmod', function (t) { linit.luaL_openlibs(L); - lapi.lua_load(L, bc, "test-math"); + lapi.lua_load(L, null, bc, "test-math", "binary"); lapi.lua_call(L, 0, -1); @@ -474,7 +474,7 @@ test('math.modf', function (t) { linit.luaL_openlibs(L); - lapi.lua_load(L, bc, "test-math"); + lapi.lua_load(L, null, bc, "test-math", "binary"); lapi.lua_call(L, 0, -1); diff --git a/tests/load.js b/tests/load.js index 4df3f6a..a71de6b 100644 --- a/tests/load.js +++ b/tests/load.js @@ -25,7 +25,7 @@ test('lua_load, binary mode', function (t) { linit.luaL_openlibs(L); - lapi.lua_load(L, null, bc, "test-math", "binary"); + lapi.lua_load(L, null, bc, "test-load", "binary"); lapi.lua_call(L, 0, -1); @@ -47,17 +47,17 @@ test('lua_load, text mode', function (t) { t.plan(2); - // t.doesNotThrow(function () { + t.doesNotThrow(function () { L = lauxlib.luaL_newstate(); linit.luaL_openlibs(L); - lapi.lua_load(L, null, luaCode, "test-math", "text"); + lapi.lua_load(L, null, luaCode, "test-load", "text"); lapi.lua_call(L, 0, -1); - // }, "JS Lua program ran without error"); + }, "JS Lua program ran without error"); t.strictEqual( lapi.lua_tostring(L, -1), diff --git a/tests/ltablib.js b/tests/ltablib.js index 2ebf98c..c8a1e73 100644 --- a/tests/ltablib.js +++ b/tests/ltablib.js @@ -42,7 +42,7 @@ test('table.concat', function (t) { linit.luaL_openlibs(L); - lapi.lua_load(L, bc, "test-table.concat"); + lapi.lua_load(L, null, bc, "test-table.concat", "binary"); lapi.lua_call(L, 0, -1); @@ -71,7 +71,7 @@ test('table.pack', function (t) { linit.luaL_openlibs(L); - lapi.lua_load(L, bc, "test-table.pack"); + lapi.lua_load(L, null, bc, "test-table.pack", "binary"); lapi.lua_call(L, 0, -1); @@ -102,7 +102,7 @@ test('table.unpack', function (t) { linit.luaL_openlibs(L); - lapi.lua_load(L, bc, "test-table.unpack"); + lapi.lua_load(L, null, bc, "test-table.unpack", "binary"); lapi.lua_call(L, 0, -1); @@ -146,7 +146,7 @@ test('table.insert', function (t) { linit.luaL_openlibs(L); - lapi.lua_load(L, bc, "test-table.insert"); + lapi.lua_load(L, null, bc, "test-table.insert", "binary"); lapi.lua_call(L, 0, -1); @@ -180,7 +180,7 @@ test('table.remove', function (t) { linit.luaL_openlibs(L); - lapi.lua_load(L, bc, "test-table.remove"); + lapi.lua_load(L, null, bc, "test-table.remove", "binary"); lapi.lua_call(L, 0, -1); @@ -213,7 +213,7 @@ test('table.move', function (t) { linit.luaL_openlibs(L); - lapi.lua_load(L, bc, "test-table.move"); + lapi.lua_load(L, null, bc, "test-table.move", "binary"); lapi.lua_call(L, 0, -1); @@ -246,7 +246,7 @@ test('table.sort (<)', function (t) { linit.luaL_openlibs(L); - lapi.lua_load(L, bc, "test-table.sort"); + lapi.lua_load(L, null, bc, "test-table.sort", "binary"); lapi.lua_call(L, 0, -1); @@ -279,7 +279,7 @@ test('table.sort with cmp function', function (t) { linit.luaL_openlibs(L); - lapi.lua_load(L, bc, "test-table.sort"); + lapi.lua_load(L, null, bc, "test-table.sort", "binary"); lapi.lua_call(L, 0, -1); -- cgit v1.2.3-54-g00ecf