diff options
81 files changed, 5358 insertions, 4181 deletions
@@ -1,7 +1,7 @@ MIT License -Copyright © 2017 Benoit Giannangeli -Copyright © 2017 Daurnimator +Copyright © 2017-2018 Benoit Giannangeli +Copyright © 2017-2018 Daurnimator Copyright © 1994–2017 Lua.org, PUC-Rio. Permission is hereby granted, free of charge, to any person obtaining a copy @@ -45,7 +45,7 @@ Fengari implements Lua 5.3 semantics and will hopefully follow future Lua releas Lua strings are 8-bits clean and can embed `\0`. Which means that invalid UTF-8/16 strings are valid Lua strings. Lua functions like `string.dump` even use strings as a way of storing binary data. -To address that issue, Fengari uses [`Uint8Array`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Uint8Array) objects containing the raw bytes to implement lua strings. To push a JS string on the stack you can use `lua_pushliteral` which will convert it to an array of bytes before pushing it. To get a Lua string on the stack as a JS string you can use `lua_tojsstring` which will attempt to convert it to a UTF-16 JS string. The latter won't give you what you expect if the Lua string is not a valid UTF-16 sequence. You can also convert strings with `lua.to_luastring`, `lua.to_jsstring` and `lua.to_uristring`. +To address that issue, Fengari uses [`Uint8Array`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Uint8Array) objects containing the raw bytes to implement lua strings. To push a JS string on the stack you can use `lua_pushliteral` which will convert it to an array of bytes before pushing it. To get a Lua string on the stack as a JS string you can use `lua_tojsstring` which will attempt to convert it to a UTF-16 JS string. The latter won't give you what you expect if the Lua string is not a valid UTF-16 sequence. You can also convert strings with `luastring_of`, `to_luastring`, `to_jsstring` and `to_uristring`. ### Integers diff --git a/package.json b/package.json index 631b2e9..81accf4 100644 --- a/package.json +++ b/package.json @@ -43,6 +43,7 @@ "strftime": "^0.10.0", "tmp": "^0.0.33" }, + "sideEffects": false, "eslintConfig": { "env": { "browser": true, @@ -55,7 +56,9 @@ "indent": [ "error", 4, - {"SwitchCase": 1} + { + "SwitchCase": 1 + } ], "linebreak-style": [ "error", @@ -64,11 +67,15 @@ "no-console": 0, "no-empty": [ 2, - { "allowEmptyCatch": true } + { + "allowEmptyCatch": true + } ], "no-unused-vars": [ 2, - { "args": "none" } + { + "args": "none" + } ], "semi": [ "error", diff --git a/src/defs.js b/src/defs.js index a2c5c75..70d0c73 100644 --- a/src/defs.js +++ b/src/defs.js @@ -1,16 +1,200 @@ "use strict"; -const assert = require('assert'); -const luaconf = require('./luaconf.js'); +const { LUAI_MAXSTACK } = require('./luaconf.js'); -// To avoid charCodeAt everywhere -const char = []; -for (let i = 0; i < 127; i++) - char[String.fromCharCode(i)] = i; -module.exports.char = char; +/* + * Fengari specific string conversion functions + */ + +let luastring_from; +if (typeof Uint8Array.from === "function") { + luastring_from = Uint8Array.from.bind(Uint8Array); +} else { + luastring_from = function(a) { + let i = 0; + let len = a.length; + let r = new Uint8Array(len); + while (len > i) r[i] = a[i++]; + return r; + }; +} + +let luastring_indexOf; +if (typeof (new Uint8Array().indexOf) === "function") { + luastring_indexOf = function(s, v, i) { + return s.indexOf(v, i); + }; +} else { + /* Browsers that don't support Uint8Array.indexOf seem to allow using Array.indexOf on Uint8Array objects e.g. IE11 */ + let array_indexOf = [].indexOf; + if (array_indexOf.call(new Uint8Array(1), 0) !== 0) throw Error("missing .indexOf"); + luastring_indexOf = function(s, v, i) { + return array_indexOf.call(s, v, i); + }; +} + +let luastring_of; +if (typeof Uint8Array.of === "function") { + luastring_of = Uint8Array.of.bind(Uint8Array); +} else { + luastring_of = function() { + return luastring_from(arguments); + }; +} + +const is_luastring = function(s) { + return s instanceof Uint8Array; +}; + +/* test two lua strings for equality */ +const luastring_eq = function(a, b) { + if (a !== b) { + let len = a.length; + if (len !== b.length) return false; + /* XXX: Should this be a constant time algorithm? */ + for (let i=0; i<len; i++) + if (a[i] !== b[i]) return false; + } + return true; +}; + +const to_jsstring = function(value, from, to) { + if (!is_luastring(value)) throw new TypeError("to_jsstring expects a Uint8Array"); + + if (to === void 0) { + to = value.length; + } else { + to = Math.min(value.length, to); + } + + let str = ""; + for (let i = (from!==void 0?from:0); i < to;) { + let u0 = value[i++]; + if (u0 < 0x80) { + /* single byte sequence */ + str += String.fromCharCode(u0); + } else if (u0 < 0xC2 || u0 > 0xF4) { + throw RangeError("cannot convert invalid utf8 to javascript string"); + } else if (u0 <= 0xDF) { + /* two byte sequence */ + if (i >= to) throw RangeError("cannot convert invalid utf8 to javascript string"); + let u1 = value[i++]; + if ((u1&0xC0) !== 0x80) throw RangeError("cannot convert invalid utf8 to javascript string"); + str += String.fromCharCode(((u0 & 0x1F) << 6) + (u1 & 0x3F)); + } else if (u0 <= 0xEF) { + /* three byte sequence */ + if (i+1 >= to) throw RangeError("cannot convert invalid utf8 to javascript string"); + let u1 = value[i++]; + if ((u1&0xC0) !== 0x80) throw RangeError("cannot convert invalid utf8 to javascript string"); + let u2 = value[i++]; + if ((u2&0xC0) !== 0x80) throw RangeError("cannot convert invalid utf8 to javascript string"); + let u = ((u0 & 0x0F) << 12) + ((u1 & 0x3F) << 6) + (u2 & 0x3F); + if (u <= 0xFFFF) { /* BMP codepoint */ + str += String.fromCharCode(u); + } else { /* Astral codepoint */ + u -= 0x10000; + let s1 = (u >> 10) + 0xD800; + let s2 = (u % 0x400) + 0xDC00; + str += String.fromCharCode(s1, s2); + } + } else { + /* four byte sequence */ + if (i+2 >= to) throw RangeError("cannot convert invalid utf8 to javascript string"); + let u1 = value[i++]; + if ((u1&0xC0) !== 0x80) throw RangeError("cannot convert invalid utf8 to javascript string"); + let u2 = value[i++]; + if ((u2&0xC0) !== 0x80) throw RangeError("cannot convert invalid utf8 to javascript string"); + let u3 = value[i++]; + if ((u3&0xC0) !== 0x80) throw RangeError("cannot convert invalid utf8 to javascript string"); + /* Has to be astral codepoint */ + let u = ((u0 & 0x07) << 18) + ((u1 & 0x3F) << 12) + ((u2 & 0x3F) << 6) + (u3 & 0x3F); + u -= 0x10000; + let s1 = (u >> 10) + 0xD800; + let s2 = (u % 0x400) + 0xDC00; + str += String.fromCharCode(s1, s2); + } + } + return str; +}; + +/* bytes allowed unescaped in a uri */ +const uri_allowed = (";,/?:@&=+$abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789,-_.!~*'()#").split('').reduce(function(uri_allowed, c) { + uri_allowed[c.charCodeAt(0)] = true; + return uri_allowed; +}, {}); + +/* utility function to convert a lua string to a js string with uri escaping */ +const to_uristring = function(a) { + if (!is_luastring(a)) throw new TypeError("to_uristring expects a Uint8Array"); + let s = ""; + for (let i=0; i<a.length; i++) { + let v = a[i]; + if (uri_allowed[v]) { + s += String.fromCharCode(v); + } else { + s += "%" + (v<0x10?"0":"") + v.toString(16); + } + } + return s; +}; + +const to_luastring_cache = {}; + +const to_luastring = function(str, cache) { + if (typeof str !== "string") throw new TypeError("to_luastring expects a javascript string"); + + if (cache) { + let cached = to_luastring_cache[str]; + if (is_luastring(cached)) return cached; + } + + let len = str.length; + let outU8Array = Array(len); /* array is at *least* going to be length of string */ + let outIdx = 0; + for (let i = 0; i < len; ++i) { + let u = str.charCodeAt(i); + if (u <= 0x7F) { + outU8Array[outIdx++] = u; + } else if (u <= 0x7FF) { + outU8Array[outIdx++] = 0xC0 | (u >> 6); + outU8Array[outIdx++] = 0x80 | (u & 63); + } else { + /* This part is to work around possible lack of String.codePointAt */ + if (u >= 0xD800 && u <= 0xDBFF && (i+1) < len) { + /* is first half of surrogate pair */ + let v = str.charCodeAt(i+1); + if (v >= 0xDC00 && v <= 0xDFFF) { + /* is valid low surrogate */ + i++; + u = (u - 0xD800) * 0x400 + v + 0x2400; + } + } + if (u <= 0xFFFF) { + outU8Array[outIdx++] = 0xE0 | (u >> 12); + outU8Array[outIdx++] = 0x80 | ((u >> 6) & 63); + outU8Array[outIdx++] = 0x80 | (u & 63); + } else { + outU8Array[outIdx++] = 0xF0 | (u >> 18); + outU8Array[outIdx++] = 0x80 | ((u >> 12) & 63); + outU8Array[outIdx++] = 0x80 | ((u >> 6) & 63); + outU8Array[outIdx++] = 0x80 | (u & 63); + } + } + } + outU8Array = luastring_from(outU8Array); + + if (cache) to_luastring_cache[str] = outU8Array; + + return outU8Array; +}; + +const from_userstring = function(str) { + if (!is_luastring(str)) throw new TypeError("expects an array of bytes"); + return str; +}; /* mark for precompiled code ('<esc>Lua') */ -const LUA_SIGNATURE = "\x1bLua"; +const LUA_SIGNATURE = to_luastring("\x1bLua"); const LUA_VERSION_MAJOR = "5"; const LUA_VERSION_MINOR = "3"; @@ -22,16 +206,6 @@ const LUA_RELEASE = LUA_VERSION + "." + LUA_VERSION_RELEASE; const LUA_COPYRIGHT = LUA_RELEASE + " Copyright (C) 1994-2017 Lua.org, PUC-Rio"; const LUA_AUTHORS = "R. Ierusalimschy, L. H. de Figueiredo, W. Celes"; -const FENGARI_VERSION_MAJOR = "0"; -const FENGARI_VERSION_MINOR = "0"; -const FENGARI_VERSION_NUM = 1; -const FENGARI_VERSION_RELEASE = "1"; - -const FENGARI_VERSION = "Fengari " + FENGARI_VERSION_MAJOR + "." + FENGARI_VERSION_MINOR; -const FENGARI_RELEASE = FENGARI_VERSION + "." + FENGARI_VERSION_RELEASE; -const FENGARI_AUTHORS = "B. Giannangeli, Daurnimator"; -const FENGARI_COPYRIGHT = FENGARI_RELEASE + " Copyright (C) 2017 " + FENGARI_AUTHORS + "\nBased on: " + LUA_COPYRIGHT; - const LUA_VERSUFFIX = "_" + LUA_VERSION_MAJOR + "_" + LUA_VERSION_MINOR; const LUA_INIT_VAR = "LUA_INIT"; @@ -71,8 +245,6 @@ 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 */ -const CT = constant_types; - /* ** Comparison and arithmetic functions */ @@ -98,7 +270,7 @@ const LUA_OPLE = 2; const LUA_MINSTACK = 20; -const LUA_REGISTRYINDEX = -luaconf.LUAI_MAXSTACK - 1000; +const LUA_REGISTRYINDEX = -LUAI_MAXSTACK - 1000; const lua_upvalueindex = function(i) { return LUA_REGISTRYINDEX - i; @@ -110,7 +282,6 @@ const LUA_RIDX_GLOBALS = 2; const LUA_RIDX_LAST = LUA_RIDX_GLOBALS; class lua_Debug { - constructor() { this.event = NaN; this.name = null; /* (n) */ @@ -128,130 +299,8 @@ class lua_Debug { /* private part */ this.i_ci = null; /* active function */ } - -} - -const string_of = Uint8Array.of.bind(Uint8Array); - -const is_luastring = function(s) { - return s instanceof Uint8Array; -}; - -/* test two lua strings for equality */ -const luastring_cmp = function(a, b) { - return a === b || (a.length === b.length && a.join() === b.join()); -}; - -const to_jsstring = function(value, from, to) { - assert(is_luastring(value), "jsstring expects a Uint8Array"); - - if (to === void 0) { - to = value.length; - } else { - to = Math.min(value.length, to); - } - - let str = ""; - for (let i = (from!==void 0?from:0); i < to;) { - let u; - let u0 = value[i++]; - if (u0 < 0x80) { - /* single byte sequence */ - u = u0; - } else if (u0 < 0xC2 || u0 > 0xF4) { - throw RangeError("cannot convert invalid utf8 to javascript string"); - } else if (u0 <= 0xDF) { - /* two byte sequence */ - if (i >= to) throw RangeError("cannot convert invalid utf8 to javascript string"); - let u1 = value[i++]; - if ((u1&0xC0) !== 0x80) throw RangeError("cannot convert invalid utf8 to javascript string"); - u = ((u0 & 0x1F) << 6) + (u1 & 0x3F); - } else if (u0 <= 0xEF) { - /* three byte sequence */ - if (i+1 >= to) throw RangeError("cannot convert invalid utf8 to javascript string"); - let u1 = value[i++]; - if ((u1&0xC0) !== 0x80) throw RangeError("cannot convert invalid utf8 to javascript string"); - let u2 = value[i++]; - if ((u2&0xC0) !== 0x80) throw RangeError("cannot convert invalid utf8 to javascript string"); - u = ((u0 & 0x0F) << 12) + ((u1 & 0x3F) << 6) + (u2 & 0x3F); - } else { - /* four byte sequence */ - if (i+2 >= to) throw RangeError("cannot convert invalid utf8 to javascript string"); - let u1 = value[i++]; - if ((u1&0xC0) !== 0x80) throw RangeError("cannot convert invalid utf8 to javascript string"); - let u2 = value[i++]; - if ((u2&0xC0) !== 0x80) throw RangeError("cannot convert invalid utf8 to javascript string"); - let u3 = value[i++]; - if ((u3&0xC0) !== 0x80) throw RangeError("cannot convert invalid utf8 to javascript string"); - u = ((u0 & 0x07) << 18) + ((u1 & 0x3F) << 12) + ((u2 & 0x3F) << 6) + (u3 & 0x3F); - } - str += String.fromCodePoint(u); - } - return str; -}; - -const uri_allowed = {}; /* bytes allowed unescaped in a uri */ -for (let c of ";,/?:@&=+$abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789,-_.!~*'()#") { - uri_allowed[c.charCodeAt(0)] = true; } -/* utility function to convert a lua string to a js string with uri escaping */ -const to_uristring = function(a) { - let s = ""; - for (let i=0; i<a.length; i++) { - let v = a[i]; - if (uri_allowed[v]) { - s += String.fromCharCode(v); - } else { - s += "%" + (v<0x10?"0":"") + v.toString(16); - } - } - return s; -}; - -const to_luastring_cache = {}; - -const to_luastring = function(str, cache) { - assert(typeof str === "string", "to_luastring expects a javascript string"); - - if (cache) { - let cached = to_luastring_cache[str]; - if (is_luastring(cached)) return cached; - } - - let outU8Array = Array(str.length); /* array is at *least* going to be length of string */ - let outIdx = 0; - for (let i = 0; i < str.length; ++i) { - let u = str.codePointAt(i); - if (u <= 0x7F) { - outU8Array[outIdx++] = u; - } else if (u <= 0x7FF) { - outU8Array[outIdx++] = 0xC0 | (u >> 6); - outU8Array[outIdx++] = 0x80 | (u & 63); - } else if (u <= 0xFFFF) { - outU8Array[outIdx++] = 0xE0 | (u >> 12); - outU8Array[outIdx++] = 0x80 | ((u >> 6) & 63); - outU8Array[outIdx++] = 0x80 | (u & 63); - } else { - i++; /* It was a surrogate pair and hence used up two javascript chars */ - outU8Array[outIdx++] = 0xF0 | (u >> 18); - outU8Array[outIdx++] = 0x80 | ((u >> 12) & 63); - outU8Array[outIdx++] = 0x80 | ((u >> 6) & 63); - outU8Array[outIdx++] = 0x80 | (u & 63); - } - } - outU8Array = Uint8Array.from(outU8Array); - - if (cache) to_luastring_cache[str] = outU8Array; - - return outU8Array; -}; - -const from_userstring = function(str) { - assert(is_luastring(str), "expects an array of bytes"); - return str; -}; - /* ** Event codes */ @@ -309,14 +358,16 @@ if (typeof process === "undefined") { const LUA_CDIR = "./lua/" + LUA_VDIR + "/"; module.exports.LUA_CDIR = LUA_CDIR; - const LUA_PATH_DEFAULT = + const LUA_PATH_DEFAULT = to_luastring( LUA_LDIR + "?.lua;" + LUA_LDIR + "?/init.lua;" + LUA_CDIR + "?.lua;" + LUA_CDIR + "?/init.lua;" + - "./?.lua;./?/init.lua"; + "./?.lua;./?/init.lua" + ); module.exports.LUA_PATH_DEFAULT = LUA_PATH_DEFAULT; - const LUA_CPATH_DEFAULT = - LUA_CDIR + "?.js;" + LUA_CDIR + "loadall.js;./?.js"; + const LUA_CPATH_DEFAULT = to_luastring( + LUA_CDIR + "?.js;" + LUA_CDIR + "loadall.js;./?.js" + ); module.exports.LUA_CPATH_DEFAULT = LUA_CPATH_DEFAULT; } else if (require('os').platform() === 'win32') { const LUA_DIRSEP = "\\"; @@ -335,17 +386,19 @@ if (typeof process === "undefined") { const LUA_SHRDIR = "!\\..\\share\\lua\\" + LUA_VDIR + "\\"; module.exports.LUA_SHRDIR = LUA_SHRDIR; - const LUA_PATH_DEFAULT = + const LUA_PATH_DEFAULT = to_luastring( LUA_LDIR + "?.lua;" + LUA_LDIR + "?\\init.lua;" + LUA_CDIR + "?.lua;" + LUA_CDIR + "?\\init.lua;" + LUA_SHRDIR + "?.lua;" + LUA_SHRDIR + "?\\init.lua;" + - ".\\?.lua;.\\?\\init.lua"; + ".\\?.lua;.\\?\\init.lua" + ); module.exports.LUA_PATH_DEFAULT = LUA_PATH_DEFAULT; - const LUA_CPATH_DEFAULT = + const LUA_CPATH_DEFAULT = to_luastring( LUA_CDIR + "?.dll;" + LUA_CDIR + "..\\lib\\lua\\" + LUA_VDIR + "\\?.dll;" + - LUA_CDIR + "loadall.dll;.\\?.dll"; + LUA_CDIR + "loadall.dll;.\\?.dll" + ); module.exports.LUA_CPATH_DEFAULT = LUA_CPATH_DEFAULT; } else { const LUA_DIRSEP = "/"; @@ -360,26 +413,19 @@ if (typeof process === "undefined") { const LUA_CDIR = LUA_ROOT + "lib/lua/" + LUA_VDIR + "/"; module.exports.LUA_CDIR = LUA_CDIR; - const LUA_PATH_DEFAULT = + const LUA_PATH_DEFAULT = to_luastring( LUA_LDIR + "?.lua;" + LUA_LDIR + "?/init.lua;" + LUA_CDIR + "?.lua;" + LUA_CDIR + "?/init.lua;" + - "./?.lua;./?/init.lua"; + "./?.lua;./?/init.lua" + ); module.exports.LUA_PATH_DEFAULT = LUA_PATH_DEFAULT; - const LUA_CPATH_DEFAULT = - LUA_CDIR + "?.so;" + LUA_CDIR + "loadall.so;./?.so"; + const LUA_CPATH_DEFAULT = to_luastring( + LUA_CDIR + "?.so;" + LUA_CDIR + "loadall.so;./?.so" + ); module.exports.LUA_CPATH_DEFAULT = LUA_CPATH_DEFAULT; } -module.exports.CT = CT; -module.exports.FENGARI_AUTHORS = FENGARI_AUTHORS; -module.exports.FENGARI_COPYRIGHT = FENGARI_COPYRIGHT; -module.exports.FENGARI_RELEASE = FENGARI_RELEASE; -module.exports.FENGARI_VERSION = FENGARI_VERSION; -module.exports.FENGARI_VERSION_MAJOR = FENGARI_VERSION_MAJOR; -module.exports.FENGARI_VERSION_MINOR = FENGARI_VERSION_MINOR; -module.exports.FENGARI_VERSION_NUM = FENGARI_VERSION_NUM; -module.exports.FENGARI_VERSION_RELEASE = FENGARI_VERSION_RELEASE; module.exports.LUA_AUTHORS = LUA_AUTHORS; module.exports.LUA_COPYRIGHT = LUA_COPYRIGHT; module.exports.LUA_HOOKCALL = LUA_HOOKCALL; @@ -429,8 +475,10 @@ module.exports.lua_Debug = lua_Debug; module.exports.lua_upvalueindex = lua_upvalueindex; module.exports.thread_status = thread_status; module.exports.is_luastring = is_luastring; -module.exports.luastring_cmp = luastring_cmp; -module.exports.string_of = string_of; +module.exports.luastring_eq = luastring_eq; +module.exports.luastring_from = luastring_from; +module.exports.luastring_indexOf = luastring_indexOf; +module.exports.luastring_of = luastring_of; module.exports.to_jsstring = to_jsstring; module.exports.to_luastring = to_luastring; module.exports.to_uristring = to_uristring; diff --git a/src/fengari.js b/src/fengari.js index 3d35334..b37f7d6 100644 --- a/src/fengari.js +++ b/src/fengari.js @@ -1,5 +1,23 @@ "use strict"; +const core = require("./fengaricore.js"); + +module.exports.FENGARI_AUTHORS = core.FENGARI_AUTHORS; +module.exports.FENGARI_COPYRIGHT = core.FENGARI_COPYRIGHT; +module.exports.FENGARI_RELEASE = core.FENGARI_RELEASE; +module.exports.FENGARI_VERSION = core.FENGARI_VERSION; +module.exports.FENGARI_VERSION_MAJOR = core.FENGARI_VERSION_MAJOR; +module.exports.FENGARI_VERSION_MINOR = core.FENGARI_VERSION_MINOR; +module.exports.FENGARI_VERSION_NUM = core.FENGARI_VERSION_NUM; +module.exports.FENGARI_VERSION_RELEASE = core.FENGARI_VERSION_RELEASE; + +module.exports.luastring_eq = core.luastring_eq; +module.exports.luastring_indexOf = core.luastring_indexOf; +module.exports.luastring_of = core.luastring_of; +module.exports.to_jsstring = core.to_jsstring; +module.exports.to_luastring = core.to_luastring; +module.exports.to_uristring = core.to_uristring; + const lua = require('./lua.js'); const lauxlib = require('./lauxlib.js'); const lualib = require('./lualib.js'); diff --git a/src/fengaricore.js b/src/fengaricore.js new file mode 100644 index 0000000..1fd0354 --- /dev/null +++ b/src/fengaricore.js @@ -0,0 +1,36 @@ +/* Fengari specific functions + * + * This file includes fengari-specific data or and functionality for users to + * manipulate fengari's string type. + * The fields are exposed to the user on the 'fengari' entry point; however to + * avoid a dependency on defs.js from lauxlib.js they are defined in this file. + */ + +const defs = require("./defs.js"); + +const FENGARI_VERSION_MAJOR = "0"; +const FENGARI_VERSION_MINOR = "0"; +const FENGARI_VERSION_NUM = 1; +const FENGARI_VERSION_RELEASE = "1"; +const FENGARI_VERSION = "Fengari " + FENGARI_VERSION_MAJOR + "." + FENGARI_VERSION_MINOR; +const FENGARI_RELEASE = FENGARI_VERSION + "." + FENGARI_VERSION_RELEASE; +const FENGARI_AUTHORS = "B. Giannangeli, Daurnimator"; +const FENGARI_COPYRIGHT = FENGARI_RELEASE + " Copyright (C) 2017-2018 " + FENGARI_AUTHORS + "\nBased on: " + defs.LUA_COPYRIGHT; + +module.exports.FENGARI_AUTHORS = FENGARI_AUTHORS; +module.exports.FENGARI_COPYRIGHT = FENGARI_COPYRIGHT; +module.exports.FENGARI_RELEASE = FENGARI_RELEASE; +module.exports.FENGARI_VERSION = FENGARI_VERSION; +module.exports.FENGARI_VERSION_MAJOR = FENGARI_VERSION_MAJOR; +module.exports.FENGARI_VERSION_MINOR = FENGARI_VERSION_MINOR; +module.exports.FENGARI_VERSION_NUM = FENGARI_VERSION_NUM; +module.exports.FENGARI_VERSION_RELEASE = FENGARI_VERSION_RELEASE; +module.exports.is_luastring = defs.is_luastring; +module.exports.luastring_eq = defs.luastring_eq; +module.exports.luastring_from = defs.luastring_from; +module.exports.luastring_indexOf = defs.luastring_indexOf; +module.exports.luastring_of = defs.luastring_of; +module.exports.to_jsstring = defs.to_jsstring; +module.exports.to_luastring = defs.to_luastring; +module.exports.to_uristring = defs.to_uristring; +module.exports.from_userstring = defs.from_userstring; diff --git a/src/lapi.js b/src/lapi.js index b42ad92..6196812 100644 --- a/src/lapi.js +++ b/src/lapi.js @@ -1,32 +1,76 @@ "use strict"; -const assert = require('assert'); - -const defs = require('./defs.js'); +const { + LUA_MULTRET, + LUA_OPBNOT, + LUA_OPEQ, + LUA_OPLE, + LUA_OPLT, + LUA_OPUNM, + LUA_REGISTRYINDEX, + LUA_RIDX_GLOBALS, + LUA_VERSION_NUM, + constant_types: { + LUA_NUMTAGS, + LUA_TBOOLEAN, + LUA_TCCL, + LUA_TFUNCTION, + LUA_TLCF, + LUA_TLCL, + LUA_TLIGHTUSERDATA, + LUA_TLNGSTR, + LUA_TNIL, + LUA_TNONE, + LUA_TNUMFLT, + LUA_TNUMINT, + LUA_TSHRSTR, + LUA_TTABLE, + LUA_TTHREAD, + LUA_TUSERDATA + }, + thread_status: { LUA_OK }, + from_userstring, + to_luastring, +} = require('./defs.js'); +const { api_check } = require('./llimits.js'); const ldebug = require('./ldebug.js'); const ldo = require('./ldo.js'); -const ldump = require('./ldump.js'); +const { luaU_dump } = require('./ldump.js'); const lfunc = require('./lfunc.js'); const lobject = require('./lobject.js'); const lstate = require('./lstate.js'); -const lstring = require('./lstring.js'); +const { + luaS_bless, + luaS_new, + luaS_newliteral +} = require('./lstring.js'); const ltm = require('./ltm.js'); -const luaconf = require('./luaconf.js'); +const { LUAI_MAXSTACK } = require('./luaconf.js'); const lvm = require('./lvm.js'); const ltable = require('./ltable.js'); -const lzio = require('./lzio.js'); -const MAXUPVAL = lfunc.MAXUPVAL; -const CT = defs.constant_types; -const TS = defs.thread_status; +const { ZIO } = require('./lzio.js'); const TValue = lobject.TValue; const CClosure = lobject.CClosure; +const api_incr_top = function(L) { + L.top++; + api_check(L, L.top <= L.ci.top, "stack overflow"); +}; + +const api_checknelems = function(L, n) { + api_check(L, n < (L.top - L.ci.funcOff), "not enough elements in the stack"); +}; + +const fengari_argcheck = function(c) { + if (!c) throw TypeError("invalid argument"); +}; + const isvalid = function(o) { return o !== lobject.luaO_nilobject; }; const lua_version = function(L) { - if (L === null) return defs.LUA_VERSION_NUM; + if (L === null) return LUA_VERSION_NUM; else return L.l_G.version; }; @@ -47,17 +91,17 @@ const index2addr = function(L, idx) { let ci = L.ci; if (idx > 0) { let o = ci.funcOff + idx; - assert(idx <= ci.top - (ci.funcOff + 1), "unacceptable index"); + api_check(L, idx <= ci.top - (ci.funcOff + 1), "unacceptable index"); if (o >= L.top) return lobject.luaO_nilobject; else return L.stack[o]; - } else if (idx > defs.LUA_REGISTRYINDEX) { - assert(idx !== 0 && -idx <= L.top, "invalid index"); + } else if (idx > LUA_REGISTRYINDEX) { + api_check(L, idx !== 0 && -idx <= L.top, "invalid index"); return L.stack[L.top + idx]; - } else if (idx === defs.LUA_REGISTRYINDEX) { + } else if (idx === LUA_REGISTRYINDEX) { return L.l_G.l_registry; } else { /* upvalues */ - idx = defs.LUA_REGISTRYINDEX - idx; - assert(idx <= MAXUPVAL + 1, "upvalue index too large"); + idx = LUA_REGISTRYINDEX - idx; + api_check(L, idx <= lfunc.MAXUPVAL + 1, "upvalue index too large"); if (ci.func.ttislcf()) /* light C function? */ return lobject.luaO_nilobject; /* it has no upvalues */ else { @@ -71,11 +115,11 @@ const index2addr_ = function(L, idx) { let ci = L.ci; if (idx > 0) { let o = ci.funcOff + idx; - assert(idx <= ci.top - (ci.funcOff + 1), "unacceptable index"); + api_check(L, idx <= ci.top - (ci.funcOff + 1), "unacceptable index"); if (o >= L.top) return null; else return o; - } else if (idx > defs.LUA_REGISTRYINDEX) { - assert(idx !== 0 && -idx <= L.top, "invalid index"); + } else if (idx > LUA_REGISTRYINDEX) { + api_check(L, idx !== 0 && -idx <= L.top, "invalid index"); return L.top + idx; } else { /* registry or upvalue */ throw Error("attempt to use pseudo-index"); @@ -85,12 +129,12 @@ const index2addr_ = function(L, idx) { const lua_checkstack = function(L, n) { let res; let ci = L.ci; - assert(n >= 0, "negative 'n'"); + api_check(L, n >= 0, "negative 'n'"); if (L.stack_last - L.top > n) /* stack large enough? */ res = true; else { /* no; need to grow stack */ let inuse = L.top + lstate.EXTRA_STACK; - if (inuse > luaconf.LUAI_MAXSTACK - n) /* can grow without overflow? */ + if (inuse > LUAI_MAXSTACK - n) /* can grow without overflow? */ res = false; /* no */ else { /* try to grow stack */ ldo.luaD_growstack(L, n); @@ -106,10 +150,9 @@ const lua_checkstack = function(L, n) { const lua_xmove = function(from, to, n) { if (from === to) return; - assert(n < (from.top - from.ci.funcOff), "not enough elements in the stack"); - assert(from.l_G === to.l_G, "moving among independent states"); - assert(to.ci.top - to.top >= n, "stack overflow"); - + api_checknelems(from, n); + api_check(from, from.l_G === to.l_G, "moving among independent states"); + api_check(from, to.ci.top - to.top >= n, "stack overflow"); from.top -= n; for (let i = 0; i < n; i++) { to.stack[to.top] = new lobject.TValue(); @@ -127,7 +170,7 @@ const lua_xmove = function(from, to, n) { ** convert an acceptable stack index into an absolute index */ const lua_absindex = function(L, idx) { - return (idx > 0 || idx <= defs.LUA_REGISTRYINDEX) + return (idx > 0 || idx <= LUA_REGISTRYINDEX) ? idx : (L.top - L.ci.funcOff) + idx; }; @@ -138,17 +181,17 @@ const lua_gettop = function(L) { const lua_pushvalue = function(L, idx) { lobject.pushobj2s(L, index2addr(L, idx)); - assert(L.top <= L.ci.top, "stack overflow"); + api_check(L, L.top <= L.ci.top, "stack overflow"); }; const lua_settop = function(L, idx) { let func = L.ci.funcOff; let newtop; if (idx >= 0) { - assert(idx <= L.stack_last - (func + 1), "new top too large"); + api_check(L, idx <= L.stack_last - (func + 1), "new top too large"); newtop = func + 1 + idx; } else { - assert(-(idx + 1) <= L.top - (func + 1), "invalid new top"); + api_check(L, -(idx + 1) <= L.top - (func + 1), "invalid new top"); newtop = L.top + idx + 1; /* 'subtract' index (index is negative) */ } ldo.adjust_top(L, newtop); @@ -175,12 +218,9 @@ const lua_rotate = function(L, idx, n) { let t = L.top - 1; let pIdx = index2addr_(L, idx); let p = L.stack[pIdx]; - - assert(isvalid(p) && idx > defs.LUA_REGISTRYINDEX, "index not in the stack"); - assert((n >= 0 ? n : -n) <= (t - pIdx + 1), "invalid 'n'"); - + api_check(L, isvalid(p) && idx > LUA_REGISTRYINDEX, "index not in the stack"); + api_check(L, (n >= 0 ? n : -n) <= (t - pIdx + 1), "invalid 'n'"); let m = n >= 0 ? t - n : pIdx - n - 1; /* end of prefix */ - reverse(L, pIdx, m); reverse(L, m + 1, L.top - 1); reverse(L, pIdx, L.top - 1); @@ -210,93 +250,84 @@ const lua_replace = function(L, idx) { */ const lua_pushnil = function(L) { - L.stack[L.top] = new TValue(CT.LUA_TNIL, null); - L.top++; - assert(L.top <= L.ci.top, "stack overflow"); + L.stack[L.top] = new TValue(LUA_TNIL, null); + api_incr_top(L); }; const lua_pushnumber = function(L, n) { - assert(typeof n === "number"); - - L.stack[L.top] = new TValue(CT.LUA_TNUMFLT, n); - L.top++; - assert(L.top <= L.ci.top, "stack overflow"); + fengari_argcheck(typeof n === "number"); + L.stack[L.top] = new TValue(LUA_TNUMFLT, n); + api_incr_top(L); }; const lua_pushinteger = function(L, n) { - assert(typeof n === "number" && (n|0) === n); - L.stack[L.top] = new TValue(CT.LUA_TNUMINT, n); - L.top++; - assert(L.top <= L.ci.top, "stack overflow"); + fengari_argcheck(typeof n === "number" && (n|0) === n); + L.stack[L.top] = new TValue(LUA_TNUMINT, n); + api_incr_top(L); }; const lua_pushlstring = function(L, s, len) { - assert(typeof len === "number"); + fengari_argcheck(typeof len === "number"); let ts; if (len === 0) { - s = defs.to_luastring("", true); + s = to_luastring("", true); + ts = luaS_bless(L, s); } else { - s = defs.from_userstring(s); - assert(s.length >= len, "invalid length to lua_pushlstring"); - s = s.slice(0, len); + s = from_userstring(s); + api_check(L, s.length >= len, "invalid length to lua_pushlstring"); + ts = luaS_new(L, s.subarray(0, len)); } - ts = lstring.luaS_bless(L, s); lobject.pushsvalue2s(L, ts); - assert(L.top <= L.ci.top, "stack overflow"); - + api_check(L, L.top <= L.ci.top, "stack overflow"); return ts.value; }; const lua_pushstring = function (L, s) { if (s === undefined || s === null) { - L.stack[L.top] = new TValue(CT.LUA_TNIL, null); + L.stack[L.top] = new TValue(LUA_TNIL, null); L.top++; } else { - let ts = lstring.luaS_new(L, defs.from_userstring(s)); + let ts = luaS_new(L, from_userstring(s)); lobject.pushsvalue2s(L, ts); s = ts.getstr(); /* internal copy */ } - assert(L.top <= L.ci.top, "stack overflow"); - + api_check(L, L.top <= L.ci.top, "stack overflow"); return s; }; const lua_pushvfstring = function (L, fmt, argp) { - fmt = defs.from_userstring(fmt); + fmt = from_userstring(fmt); return lobject.luaO_pushvfstring(L, fmt, argp); }; const lua_pushfstring = function (L, fmt, ...argp) { - fmt = defs.from_userstring(fmt); + fmt = from_userstring(fmt); return lobject.luaO_pushvfstring(L, fmt, argp); }; /* Similar to lua_pushstring, but takes a JS string */ const lua_pushliteral = function (L, s) { if (s === undefined || s === null) { - L.stack[L.top] = new TValue(CT.LUA_TNIL, null); + L.stack[L.top] = new TValue(LUA_TNIL, null); L.top++; } else { - assert(typeof s === "string", "lua_pushliteral expects a JS string"); - let ts = lstring.luaS_newliteral(L, s); + fengari_argcheck(typeof s === "string", "lua_pushliteral expects a JS string"); + let ts = luaS_newliteral(L, s); lobject.pushsvalue2s(L, ts); s = ts.getstr(); /* internal copy */ } - assert(L.top <= L.ci.top, "stack overflow"); + api_check(L, L.top <= L.ci.top, "stack overflow"); return s; }; const lua_pushcclosure = function(L, fn, n) { - assert(typeof fn === "function"); - assert(typeof n === "number"); - + fengari_argcheck(typeof fn === "function" || typeof n === "number"); if (n === 0) - L.stack[L.top] = new TValue(CT.LUA_TLCF, fn); + L.stack[L.top] = new TValue(LUA_TLCF, fn); else { - assert(n < L.top - L.ci.funcOff, "not enough elements in the stack"); - assert(n <= MAXUPVAL, "upvalue index too large"); - + api_checknelems(L, n); + api_check(L, n <= lfunc.MAXUPVAL, "upvalue index too large"); let cl = new CClosure(L, fn, n); for (let i=0; i<n; i++) cl.upvalue[i].setfrom(L.stack[L.top - n + i]); @@ -306,8 +337,7 @@ const lua_pushcclosure = function(L, fn, n) { --L.top; L.stack[L.top].setclCvalue(cl); } - L.top++; - assert(L.top <= L.ci.top, "stack overflow"); + api_incr_top(L); }; const lua_pushjsclosure = lua_pushcclosure; @@ -319,26 +349,23 @@ const lua_pushcfunction = function(L, fn) { const lua_pushjsfunction = lua_pushcfunction; const lua_pushboolean = function(L, b) { - L.stack[L.top] = new TValue(CT.LUA_TBOOLEAN, b ? true : false); - L.top++; - assert(L.top <= L.ci.top, "stack overflow"); + L.stack[L.top] = new TValue(LUA_TBOOLEAN, b ? true : false); + api_incr_top(L); }; const lua_pushlightuserdata = function(L, p) { - L.stack[L.top] = new TValue(CT.LUA_TLIGHTUSERDATA, p); - L.top++; - assert(L.top <= L.ci.top, "stack overflow"); + L.stack[L.top] = new TValue(LUA_TLIGHTUSERDATA, p); + api_incr_top(L); }; const lua_pushthread = function(L) { - L.stack[L.top] = new TValue(CT.LUA_TTHREAD, L); - L.top++; - assert(L.top <= L.ci.top, "stack overflow"); + L.stack[L.top] = new TValue(LUA_TTHREAD, L); + api_incr_top(L); return L.l_G.mainthread === L; }; const lua_pushglobaltable = function(L) { - lua_rawgeti(L, defs.LUA_REGISTRYINDEX, defs.LUA_RIDX_GLOBALS); + lua_rawgeti(L, LUA_REGISTRYINDEX, LUA_RIDX_GLOBALS); }; /* @@ -349,10 +376,10 @@ const lua_pushglobaltable = function(L) { ** t[k] = value at the top of the stack (where 'k' is a string) */ const auxsetstr = function(L, t, k) { - let str = lstring.luaS_new(L, defs.from_userstring(k)); - assert(1 < L.top - L.ci.funcOff, "not enough elements in the stack"); + let str = luaS_new(L, from_userstring(k)); + api_checknelems(L, 1); lobject.pushsvalue2s(L, str); /* push 'str' (to make it a TValue) */ - assert(L.top <= L.ci.top, "stack overflow"); + api_check(L, L.top <= L.ci.top, "stack overflow"); lvm.settable(L, t, L.stack[L.top - 1], L.stack[L.top - 2]); /* pop value and key */ delete L.stack[--L.top]; @@ -360,23 +387,23 @@ const auxsetstr = function(L, t, k) { }; const lua_setglobal = function(L, name) { - auxsetstr(L, ltable.luaH_getint(L.l_G.l_registry.value, defs.LUA_RIDX_GLOBALS), name); + auxsetstr(L, ltable.luaH_getint(L.l_G.l_registry.value, LUA_RIDX_GLOBALS), name); }; const lua_setmetatable = function(L, objindex) { - assert(1 < L.top - L.ci.funcOff, "not enough elements in the stack"); + api_checknelems(L, 1); let mt; let obj = index2addr(L, objindex); if (L.stack[L.top - 1].ttisnil()) mt = null; else { - assert(L.stack[L.top - 1].ttistable(), "table expected"); + api_check(L, L.stack[L.top - 1].ttistable(), "table expected"); mt = L.stack[L.top - 1].value; } switch (obj.ttnov()) { - case CT.LUA_TUSERDATA: - case CT.LUA_TTABLE: { + case LUA_TUSERDATA: + case LUA_TTABLE: { obj.value.metatable = mt; break; } @@ -391,8 +418,7 @@ const lua_setmetatable = function(L, objindex) { }; const lua_settable = function(L, idx) { - assert(2 < L.top - L.ci.funcOff, "not enough elements in the stack"); - + api_checknelems(L, 2); let t = index2addr(L, idx); lvm.settable(L, t, L.stack[L.top - 2], L.stack[L.top - 1]); delete L.stack[--L.top]; @@ -404,12 +430,11 @@ const lua_setfield = function(L, idx, k) { }; const lua_seti = function(L, idx, n) { - assert(typeof n === "number" && (n|0) === n); - assert(1 < L.top - L.ci.funcOff, "not enough elements in the stack"); + fengari_argcheck(typeof n === "number" && (n|0) === n); + api_checknelems(L, 1); let t = index2addr(L, idx); - L.stack[L.top] = new TValue(CT.LUA_TNUMINT, n); - L.top++; - assert(L.top <= L.ci.top, "stack overflow"); + L.stack[L.top] = new TValue(LUA_TNUMINT, n); + api_incr_top(L); lvm.settable(L, t, L.stack[L.top - 1], L.stack[L.top - 2]); /* pop value and key */ delete L.stack[--L.top]; @@ -417,9 +442,9 @@ const lua_seti = function(L, idx, n) { }; const lua_rawset = function(L, idx) { - assert(2 < L.top - L.ci.funcOff, "not enough elements in the stack"); + api_checknelems(L, 2); let o = index2addr(L, idx); - assert(o.ttistable(), "table expected"); + api_check(L, o.ttistable(), "table expected"); let k = L.stack[L.top - 2]; let v = L.stack[L.top - 1]; if (v.ttisnil()) { @@ -434,18 +459,18 @@ const lua_rawset = function(L, idx) { }; const lua_rawseti = function(L, idx, n) { - assert(1 < L.top - L.ci.funcOff, "not enough elements in the stack"); + api_checknelems(L, 1); let o = index2addr(L, idx); - assert(o.ttistable(), "table expected"); + api_check(L, o.ttistable(), "table expected"); ltable.luaH_setint(o.value, n, L.stack[L.top - 1]); delete L.stack[--L.top]; }; const lua_rawsetp = function(L, idx, p) { - assert(1 < L.top - L.ci.funcOff, "not enough elements in the stack"); + api_checknelems(L, 1); let o = index2addr(L, idx); - assert(L, o.ttistable(), "table expected"); - let k = new TValue(CT.LUA_TLIGHTUSERDATA, p); + api_check(L, o.ttistable(), "table expected"); + let k = new TValue(LUA_TLIGHTUSERDATA, p); let v = L.stack[L.top - 1]; if (v.ttisnil()) { ltable.luaH_delete(L, o.value, k); @@ -461,43 +486,42 @@ const lua_rawsetp = function(L, idx, p) { */ const auxgetstr = function(L, t, k) { - let str = lstring.luaS_new(L, defs.from_userstring(k)); + let str = luaS_new(L, from_userstring(k)); lobject.pushsvalue2s(L, str); - assert(L.top <= L.ci.top, "stack overflow"); + api_check(L, L.top <= L.ci.top, "stack overflow"); lvm.luaV_gettable(L, t, L.stack[L.top - 1], L.top - 1); return L.stack[L.top - 1].ttnov(); }; const lua_rawgeti = function(L, idx, n) { let t = index2addr(L, idx); - assert(t.ttistable(), "table expected"); + api_check(L, t.ttistable(), "table expected"); lobject.pushobj2s(L, ltable.luaH_getint(t.value, n)); - assert(L.top <= L.ci.top, "stack overflow"); + api_check(L, L.top <= L.ci.top, "stack overflow"); return L.stack[L.top - 1].ttnov(); }; const lua_rawgetp = function(L, idx, p) { let t = index2addr(L, idx); - assert(t.ttistable(), "table expected"); - let k = new TValue(CT.LUA_TLIGHTUSERDATA, p); + api_check(L, t.ttistable(), "table expected"); + let k = new TValue(LUA_TLIGHTUSERDATA, p); lobject.pushobj2s(L, ltable.luaH_get(L, t.value, k)); - assert(L.top <= L.ci.top, "stack overflow"); + api_check(L, L.top <= L.ci.top, "stack overflow"); return L.stack[L.top - 1].ttnov(); }; const lua_rawget = function(L, idx) { let t = index2addr(L, idx); - assert(t.ttistable(t), "table expected"); + api_check(L, t.ttistable(t), "table expected"); lobject.setobj2s(L, L.top - 1, ltable.luaH_get(L, t.value, L.stack[L.top - 1])); return L.stack[L.top - 1].ttnov(); }; // narray and nrec are mostly useless for this implementation const lua_createtable = function(L, narray, nrec) { - let t = new lobject.TValue(CT.LUA_TTABLE, ltable.luaH_new(L)); + let t = new lobject.TValue(LUA_TTABLE, ltable.luaH_new(L)); L.stack[L.top] = t; - L.top++; - assert(L.top <= L.ci.top, "stack overflow"); + api_incr_top(L); }; const luaS_newudata = function(L, size) { @@ -506,30 +530,29 @@ const luaS_newudata = function(L, size) { const lua_newuserdata = function(L, size) { let u = luaS_newudata(L, size); - L.stack[L.top] = new lobject.TValue(CT.LUA_TUSERDATA, u); - L.top++; - assert(L.top <= L.ci.top, "stack overflow"); + L.stack[L.top] = new lobject.TValue(LUA_TUSERDATA, u); + api_incr_top(L); return u.data; }; const aux_upvalue = function(L, fi, n) { switch(fi.ttype()) { - case CT.LUA_TCCL: { /* C closure */ + case LUA_TCCL: { /* C closure */ let f = fi.value; if (!(1 <= n && n <= f.nupvalues)) return null; return { - name: defs.to_luastring("", true), + name: to_luastring("", true), val: f.upvalue[n-1] }; } - case CT.LUA_TLCL: { /* Lua closure */ + case LUA_TLCL: { /* Lua closure */ let f = fi.value; let p = f.p; if (!(1 <= n && n <= p.upvalues.length)) return null; let name = p.upvalues[n-1].name; return { - name: name ? name.getstr() : defs.to_luastring("(*no name)", true), - val: f.upvals[n-1].v + name: name ? name.getstr() : to_luastring("(*no name)", true), + val: f.upvals[n-1] }; } default: return null; /* not a closure */ @@ -542,7 +565,7 @@ const lua_getupvalue = function(L, funcindex, n) { let name = up.name; let val = up.val; lobject.pushobj2s(L, val); - assert(L.top <= L.ci.top, "stack overflow"); + api_check(L, L.top <= L.ci.top, "stack overflow"); return name; } return null; @@ -550,7 +573,7 @@ const lua_getupvalue = function(L, funcindex, n) { const lua_setupvalue = function(L, funcindex, n) { let fi = index2addr(L, funcindex); - assert(1 < L.top - L.ci.funcOff, "not enough elements in the stack"); + api_checknelems(L, 1); let aux = aux_upvalue(L, fi, n); if (aux) { let name = aux.name; @@ -576,8 +599,8 @@ const lua_getmetatable = function(L, objindex) { let mt; let res = false; switch (obj.ttnov()) { - case CT.LUA_TTABLE: - case CT.LUA_TUSERDATA: + case LUA_TTABLE: + case LUA_TUSERDATA: mt = obj.value.metatable; break; default: @@ -586,9 +609,8 @@ const lua_getmetatable = function(L, objindex) { } if (mt !== null && mt !== undefined) { - L.stack[L.top] = new TValue(CT.LUA_TTABLE, mt); - L.top++; - assert(L.top <= L.ci.top, "stack overflow"); + L.stack[L.top] = new TValue(LUA_TTABLE, mt); + api_incr_top(L); res = true; } @@ -597,11 +619,10 @@ const lua_getmetatable = function(L, objindex) { const lua_getuservalue = function(L, idx) { let o = index2addr(L, idx); - assert(L, o.ttisfulluserdata(), "full userdata expected"); + api_check(L, o.ttisfulluserdata(), "full userdata expected"); let uv = o.value.uservalue; L.stack[L.top] = new TValue(uv.type, uv.value); - L.top++; - assert(L.top <= L.ci.top, "stack overflow"); + api_incr_top(L); return L.stack[L.top - 1].ttnov(); }; @@ -616,17 +637,16 @@ const lua_getfield = function(L, idx, k) { }; const lua_geti = function(L, idx, n) { - assert(typeof n === "number" && (n|0) === n); + fengari_argcheck(typeof n === "number" && (n|0) === n); let t = index2addr(L, idx); - L.stack[L.top] = new TValue(CT.LUA_TNUMINT, n); - L.top++; - assert(L.top <= L.ci.top, "stack overflow"); + L.stack[L.top] = new TValue(LUA_TNUMINT, n); + api_incr_top(L); lvm.luaV_gettable(L, t, L.stack[L.top - 1], L.top - 1); return L.stack[L.top - 1].ttnov(); }; const lua_getglobal = function(L, name) { - return auxgetstr(L, ltable.luaH_getint(L.l_G.l_registry.value, defs.LUA_RIDX_GLOBALS), name); + return auxgetstr(L, ltable.luaH_getint(L.l_G.l_registry.value, LUA_RIDX_GLOBALS), name); }; /* @@ -674,12 +694,12 @@ const lua_todataview = function(L, idx) { const lua_rawlen = function(L, idx) { let o = index2addr(L, idx); switch (o.ttype()) { - case CT.LUA_TSHRSTR: - case CT.LUA_TLNGSTR: + case LUA_TSHRSTR: + case LUA_TLNGSTR: return o.vslen(); - case CT.LUA_TUSERDATA: + case LUA_TUSERDATA: return o.value.len; - case CT.LUA_TTABLE: + case LUA_TTABLE: return ltable.luaH_getn(o.value); default: return 0; @@ -713,9 +733,9 @@ const lua_tonumberx = function(L, idx) { const lua_touserdata = function(L, idx) { let o = index2addr(L, idx); switch (o.ttnov()) { - case CT.LUA_TUSERDATA: + case LUA_TUSERDATA: return o.value.data; - case CT.LUA_TLIGHTUSERDATA: + case LUA_TLIGHTUSERDATA: return o.value; default: return null; } @@ -729,13 +749,13 @@ const lua_tothread = function(L, idx) { const lua_topointer = function(L, idx) { let o = index2addr(L, idx); switch (o.ttype()) { - case CT.LUA_TTABLE: - case CT.LUA_TLCL: - case CT.LUA_TCCL: - case CT.LUA_TLCF: - case CT.LUA_TTHREAD: - case CT.LUA_TUSERDATA: /* note: this differs in behaviour to reference lua implementation */ - case CT.LUA_TLIGHTUSERDATA: + case LUA_TTABLE: + case LUA_TLCL: + case LUA_TCCL: + case LUA_TLCF: + case LUA_TTHREAD: + case LUA_TUSERDATA: /* note: this differs in behaviour to reference lua implementation */ + case LUA_TLIGHTUSERDATA: return o.value; default: return null; @@ -759,10 +779,9 @@ const lua_isproxy = function(p, L) { /* Use 'create_proxy' helper function so that 'L' is not in scope */ const create_proxy = function(G, type, value) { let proxy = function(L) { - assert(L instanceof lstate.lua_State && G === L.l_G, "must be from same global state"); + api_check(L, L instanceof lstate.lua_State && G === L.l_G, "must be from same global state"); L.stack[L.top] = new TValue(type, value); - L.top++; - assert(L.top <= L.ci.top, "stack overflow"); + api_incr_top(L); }; seen.set(proxy, G); return proxy; @@ -783,10 +802,10 @@ const lua_compare = function(L, index1, index2, op) { if (isvalid(o1) && isvalid(o2)) { switch (op) { - case defs.LUA_OPEQ: i = lvm.luaV_equalobj(L, o1, o2); break; - case defs.LUA_OPLT: i = lvm.luaV_lessthan(L, o1, o2); break; - case defs.LUA_OPLE: i = lvm.luaV_lessequal(L, o1, o2); break; - default: assert(false, "invalid option"); + case LUA_OPEQ: i = lvm.luaV_equalobj(L, o1, o2); break; + case LUA_OPLT: i = lvm.luaV_lessthan(L, o1, o2); break; + case LUA_OPLE: i = lvm.luaV_lessequal(L, o1, o2); break; + default: api_check(L, false, "invalid option"); } } @@ -798,8 +817,7 @@ const lua_stringtonumber = function(L, s) { let sz = lobject.luaO_str2num(s, tv); if (sz !== 0) { L.stack[L.top] = tv; - L.top++; - assert(L.top <= L.ci.top, "stack overflow"); + api_incr_top(L); } return sz; }; @@ -810,11 +828,11 @@ const f_call = function(L, ud) { const lua_type = function(L, idx) { let o = index2addr(L, idx); - return isvalid(o) ? o.ttnov() : CT.LUA_TNONE; + return isvalid(o) ? o.ttnov() : LUA_TNONE; }; const lua_typename = function(L, t) { - assert(CT.LUA_TNONE <= t && t < CT.LUA_NUMTAGS, "invalid tag"); + api_check(L, LUA_TNONE <= t && t < LUA_NUMTAGS, "invalid tag"); return ltm.ttypename(t); }; @@ -824,15 +842,15 @@ const lua_iscfunction = function(L, idx) { }; const lua_isnil = function(L, n) { - return lua_type(L, n) === CT.LUA_TNIL; + return lua_type(L, n) === LUA_TNIL; }; const lua_isboolean = function(L, n) { - return lua_type(L, n) === CT.LUA_TBOOLEAN; + return lua_type(L, n) === LUA_TBOOLEAN; }; const lua_isnone = function(L, n) { - return lua_type(L, n) === CT.LUA_TNONE; + return lua_type(L, n) === LUA_TNONE; }; const lua_isnoneornil = function(L, n) { @@ -862,15 +880,15 @@ const lua_isuserdata = function(L, idx) { }; const lua_isthread = function(L, idx) { - return lua_type(L, idx) === CT.LUA_TTHREAD; + return lua_type(L, idx) === LUA_TTHREAD; }; const lua_isfunction = function(L, idx) { - return lua_type(L, idx) === CT.LUA_TFUNCTION; + return lua_type(L, idx) === LUA_TFUNCTION; }; const lua_islightuserdata = function(L, idx) { - return lua_type(L, idx) === CT.LUA_TLIGHTUSERDATA; + return lua_type(L, idx) === LUA_TLIGHTUSERDATA; }; const lua_rawequal = function(L, index1, index2) { @@ -880,12 +898,12 @@ const lua_rawequal = function(L, index1, index2) { }; const lua_arith = function(L, op) { - if (op !== defs.LUA_OPUNM && op !== defs.LUA_OPBNOT) - assert(2 < L.top - L.ci.funcOff, "not enough elements in the stack"); /* all other operations expect two operands */ + if (op !== LUA_OPUNM && op !== LUA_OPBNOT) + api_checknelems(L, 2); /* all other operations expect two operands */ else { /* for unary operations, add fake 2nd operand */ - assert(1 < L.top - L.ci.funcOff, "not enough elements in the stack"); + api_checknelems(L, 1); lobject.pushobj2s(L, L.stack[L.top-1]); - assert(L.top <= L.ci.top, "stack overflow"); + api_check(L, L.top <= L.ci.top, "stack overflow"); } /* first operand at top - 2, second at top - 1; result go to top - 2 */ lobject.luaO_arith(L, op, L.stack[L.top - 2], L.stack[L.top - 1], L.stack[L.top - 2]); @@ -896,30 +914,30 @@ const lua_arith = function(L, op) { ** 'load' and 'call' functions (run Lua code) */ -const default_chunkname = defs.to_luastring("?"); +const default_chunkname = to_luastring("?"); const lua_load = function(L, reader, data, chunkname, mode) { if (!chunkname) chunkname = default_chunkname; - else chunkname = defs.from_userstring(chunkname); - if (mode !== null) mode = defs.from_userstring(mode); - let z = new lzio.ZIO(L, reader, data); + else chunkname = from_userstring(chunkname); + if (mode !== null) mode = from_userstring(mode); + let z = new ZIO(L, reader, data); let status = ldo.luaD_protectedparser(L, z, chunkname, mode); - if (status === TS.LUA_OK) { /* no errors? */ + if (status === LUA_OK) { /* no errors? */ let f = L.stack[L.top - 1].value; /* get newly created function */ if (f.nupvalues >= 1) { /* does it have an upvalue? */ /* get global table from registry */ - let gt = ltable.luaH_getint(L.l_G.l_registry.value, defs.LUA_RIDX_GLOBALS); + let gt = ltable.luaH_getint(L.l_G.l_registry.value, LUA_RIDX_GLOBALS); /* set global table as 1st upvalue of 'f' (may be LUA_ENV) */ - f.upvals[0].v.setfrom(gt); + f.upvals[0].setfrom(gt); } } return status; }; const lua_dump = function(L, writer, data, strip) { - assert(1 < L.top - L.ci.funcOff, "not enough elements in the stack"); + api_checknelems(L, 1); let o = L.stack[L.top -1]; if (o.ttisLclosure()) - return ldump.luaU_dump(L, o.value.p, writer, data, strip); + return luaU_dump(L, o.value.p, writer, data, strip); return 1; }; @@ -928,19 +946,23 @@ const lua_status = function(L) { }; const lua_setuservalue = function(L, idx) { - assert(1 < L.top - L.ci.funcOff, "not enough elements in the stack"); + api_checknelems(L, 1); let o = index2addr(L, idx); - assert(L, o.ttisfulluserdata(), "full userdata expected"); + api_check(L, o.ttisfulluserdata(), "full userdata expected"); o.value.uservalue.setfrom(L.stack[L.top - 1]); delete L.stack[--L.top]; }; -const lua_callk = function(L, nargs, nresults, ctx, k) { - assert(k === null || !(L.ci.callstatus & lstate.CIST_LUA), "cannot use continuations inside hooks"); - assert(nargs + 1 < L.top - L.ci.funcOff, "not enough elements in the stack"); - assert(L.status === TS.LUA_OK, "cannot do calls on non-normal thread"); - assert(nargs === defs.LUA_MULTRET || (L.ci.top - L.top >= nargs - nresults), "results from function overflow current stack size"); +const checkresults = function(L,na,nr) { + api_check(L, (nr) == LUA_MULTRET || (L.ci.top - L.top >= (nr) - (na)), + "results from function overflow current stack size"); +}; +const lua_callk = function(L, nargs, nresults, ctx, k) { + api_check(L, k === null || !(L.ci.callstatus & lstate.CIST_LUA), "cannot use continuations inside hooks"); + api_checknelems(L, nargs + 1); + api_check(L, L.status === LUA_OK, "cannot do calls on non-normal thread"); + checkresults(L, nargs, nresults); let func = L.top - (nargs + 1); if (k !== null && L.nny === 0) { /* need to prepare continuation? */ L.ci.c_k = k; @@ -950,7 +972,7 @@ const lua_callk = function(L, nargs, nresults, ctx, k) { ldo.luaD_callnoyield(L, func, nresults); } - if (nresults === defs.LUA_MULTRET && L.ci.top < L.top) + if (nresults === LUA_MULTRET && L.ci.top < L.top) L.ci.top = L.top; }; @@ -959,10 +981,10 @@ const lua_call = function(L, n, r) { }; const lua_pcallk = function(L, nargs, nresults, errfunc, ctx, k) { - assert(nargs + 1 < L.top - L.ci.funcOff, "not enough elements in the stack"); - assert(L.status === TS.LUA_OK, "cannot do calls on non-normal thread"); - assert(nargs === defs.LUA_MULTRET || (L.ci.top - L.top >= nargs - nresults), "results from function overflow current stack size"); - + api_check(L, k === null || !(L.ci.callstatus & lstate.CIST_LUA), "cannot use continuations inside hooks"); + api_checknelems(L, nargs + 1); + api_check(L, L.status === LUA_OK, "cannot do calls on non-normal thread"); + checkresults(L, nargs, nresults); let c = { func: null, funcOff: NaN, @@ -998,10 +1020,10 @@ const lua_pcallk = function(L, nargs, nresults, errfunc, ctx, k) { ldo.luaD_call(L, c.funcOff, nresults); /* do the call */ ci.callstatus &= ~lstate.CIST_YPCALL; L.errfunc = ci.c_old_errfunc; - status = TS.LUA_OK; + status = LUA_OK; } - if (nresults === defs.LUA_MULTRET && L.ci.top < L.top) + if (nresults === LUA_MULTRET && L.ci.top < L.top) L.ci.top = L.top; return status; @@ -1016,18 +1038,17 @@ const lua_pcall = function(L, n, r, f) { */ const lua_error = function(L) { - assert(1 < L.top - L.ci.funcOff, "not enough elements in the stack"); + api_checknelems(L, 1); ldebug.luaG_errormsg(L); }; const lua_next = function(L, idx) { let t = index2addr(L, idx); - assert(t.ttistable(), "table expected"); + api_check(L, t.ttistable(), "table expected"); L.stack[L.top] = new TValue(); let more = ltable.luaH_next(L, t.value, L.top - 1); if (more) { - L.top++; - assert(L.top <= L.ci.top, "stack overflow"); + api_incr_top(L); return 1; } else { delete L.stack[L.top]; @@ -1037,12 +1058,12 @@ const lua_next = function(L, idx) { }; const lua_concat = function(L, n) { - assert(n < L.top - L.ci.funcOff, "not enough elements in the stack"); + api_checknelems(L, n); if (n >= 2) lvm.luaV_concat(L, n); else if (n === 0) { - lobject.pushsvalue2s(L, lstring.luaS_bless(L, defs.to_luastring("", true))); - assert(L.top <= L.ci.top, "stack overflow"); + lobject.pushsvalue2s(L, luaS_bless(L, to_luastring("", true))); + api_check(L, L.top <= L.ci.top, "stack overflow"); } }; @@ -1051,35 +1072,34 @@ const lua_len = function(L, idx) { let tv = new TValue(); lvm.luaV_objlen(L, tv, t); L.stack[L.top] = tv; - L.top++; - assert(L.top <= L.ci.top, "stack overflow"); + api_incr_top(L); }; const getupvalref = function(L, fidx, n) { let fi = index2addr(L, fidx); - assert(fi.ttisLclosure(), "Lua function expected"); + api_check(L, fi.ttisLclosure(), "Lua function expected"); let f = fi.value; - assert(1 <= n && n <= f.p.upvalues.length, "invalid upvalue index"); + api_check(L, n|0 === n && 1 <= n && n <= f.p.upvalues.length, "invalid upvalue index"); return { - closure: f, - upval: f.upvals[n - 1], - upvalOff: n - 1 + f: f, + i: n - 1 }; }; const lua_upvalueid = function(L, fidx, n) { let fi = index2addr(L, fidx); switch (fi.ttype()) { - case CT.LUA_TLCL: { /* lua closure */ - return getupvalref(L, fidx, n).upval; + case LUA_TLCL: { /* lua closure */ + let ref = getupvalref(L, fidx, n); + return ref.f.upvals[ref.i]; } - case CT.LUA_TCCL: { /* C closure */ + case LUA_TCCL: { /* C closure */ let f = fi.value; - assert(1 <= n && n <= f.nupvalues, "invalid upvalue index"); + api_check(L, n|0 === n && 1 <= n && n <= f.nupvalues, "invalid upvalue index"); return f.upvalue[n - 1]; } default: { - assert(false, "closure expected"); + api_check(L, false, "closure expected"); return null; } } @@ -1088,13 +1108,8 @@ const lua_upvalueid = function(L, fidx, n) { const lua_upvaluejoin = function(L, fidx1, n1, fidx2, n2) { let ref1 = getupvalref(L, fidx1, n1); let ref2 = getupvalref(L, fidx2, n2); - let up1 = ref1.upval; - let up2 = ref2.upval; - let f1 = ref1.closure; - assert(up1.refcount > 0); - up1.refcount--; - f1.upvals[ref1.upvalOff] = up2; - up2.refcount++; + let up2 = ref2.f.upvals[ref2.i]; + ref1.f.upvals[ref1.i] = up2; }; // This functions are only there for compatibility purposes @@ -1115,8 +1130,8 @@ const lua_getextraspace = function () { return 0; }; -module.exports.index2addr = index2addr; -module.exports.index2addr_ = index2addr_; +module.exports.api_incr_top = api_incr_top; +module.exports.api_checknelems = api_checknelems; module.exports.lua_absindex = lua_absindex; module.exports.lua_arith = lua_arith; module.exports.lua_atpanic = lua_atpanic; diff --git a/src/lauxlib.js b/src/lauxlib.js index e6d407f..437b6cf 100644 --- a/src/lauxlib.js +++ b/src/lauxlib.js @@ -1,25 +1,109 @@ "use strict"; -const lua = require('./lua.js'); +const { + LUA_ERRERR, + LUA_MULTRET, + LUA_REGISTRYINDEX, + LUA_SIGNATURE, + LUA_TBOOLEAN, + LUA_TLIGHTUSERDATA, + LUA_TNIL, + LUA_TNONE, + LUA_TNUMBER, + LUA_TSTRING, + LUA_TTABLE, + LUA_VERSION_NUM, + lua_Debug, + lua_absindex, + lua_atpanic, + lua_call, + lua_checkstack, + lua_concat, + lua_copy, + lua_createtable, + lua_error, + lua_getfield, + lua_getinfo, + lua_getmetatable, + lua_getstack, + lua_gettop, + lua_insert, + lua_isinteger, + lua_isnil, + lua_isnumber, + lua_isstring, + lua_istable, + lua_len, + lua_load, + lua_newstate, + lua_newtable, + lua_next, + lua_pcall, + lua_pop, + lua_pushboolean, + lua_pushcclosure, + lua_pushcfunction, + lua_pushfstring, + lua_pushinteger, + lua_pushliteral, + lua_pushlstring, + lua_pushnil, + lua_pushstring, + lua_pushvalue, + lua_pushvfstring, + lua_rawequal, + lua_rawget, + lua_rawgeti, + lua_rawlen, + lua_rawseti, + lua_remove, + lua_setfield, + lua_setglobal, + lua_setmetatable, + lua_settop, + lua_toboolean, + lua_tointeger, + lua_tointegerx, + lua_tojsstring, + lua_tolstring, + lua_tonumber, + lua_tonumberx, + lua_topointer, + lua_tostring, + lua_touserdata, + lua_type, + lua_typename, + lua_version +} = require('./lua.js'); +const { + luastring_eq, + to_luastring, + to_uristring +} = require("./fengaricore.js"); + +/* extra error code for 'luaL_loadfilex' */ +const LUA_ERRFILE = LUA_ERRERR+1; /* key, in the registry, for table of loaded modules */ -const LUA_LOADED_TABLE = lua.to_luastring("_LOADED"); +const LUA_LOADED_TABLE = to_luastring("_LOADED"); /* key, in the registry, for table of preloaded loaders */ -const LUA_PRELOAD_TABLE = lua.to_luastring("_PRELOAD"); +const LUA_PRELOAD_TABLE = to_luastring("_PRELOAD"); -const LUA_FILEHANDLE = lua.to_luastring("FILE*"); +const LUA_FILEHANDLE = to_luastring("FILE*"); const LUAL_NUMSIZES = 4*16 + 8; -const __name = lua.to_luastring("__name"); -const __tostring = lua.to_luastring("__tostring"); +const __name = to_luastring("__name"); +const __tostring = to_luastring("__tostring"); + +const empty = new Uint8Array(0); class luaL_Buffer { constructor() { - this.b = null; this.L = null; - this.initb = null; + this.b = empty; + this.n = 0; } } @@ -31,25 +115,25 @@ const LEVELS2 = 11; /* size of the second part of the stack */ ** return 1 + string at top if find a good name. */ const findfield = function(L, objidx, level) { - if (level === 0 || !lua.lua_istable(L, -1)) + if (level === 0 || !lua_istable(L, -1)) return 0; /* not found */ - lua.lua_pushnil(L); /* start 'next' loop */ + lua_pushnil(L); /* start 'next' loop */ - while (lua.lua_next(L, -2)) { /* for each pair in table */ - if (lua.lua_type(L, -2) === lua.LUA_TSTRING) { /* ignore non-string keys */ - if (lua.lua_rawequal(L, objidx, -1)) { /* found object? */ - lua.lua_pop(L, 1); /* remove value (but keep name) */ + while (lua_next(L, -2)) { /* for each pair in table */ + if (lua_type(L, -2) === LUA_TSTRING) { /* ignore non-string keys */ + if (lua_rawequal(L, objidx, -1)) { /* found object? */ + lua_pop(L, 1); /* remove value (but keep name) */ return 1; } else if (findfield(L, objidx, level - 1)) { /* try recursively */ - lua.lua_remove(L, -2); /* remove table (but keep name) */ - lua.lua_pushliteral(L, "."); - lua.lua_insert(L, -2); /* place '.' between the two names */ - lua.lua_concat(L, 3); + lua_remove(L, -2); /* remove table (but keep name) */ + lua_pushliteral(L, "."); + lua_insert(L, -2); /* place '.' between the two names */ + lua_concat(L, 3); return 1; } } - lua.lua_pop(L, 1); /* remove value */ + lua_pop(L, 1); /* remove value */ } return 0; /* not found */ @@ -59,155 +143,158 @@ const findfield = function(L, objidx, level) { ** Search for a name for a function in all loaded modules */ const pushglobalfuncname = function(L, ar) { - let top = lua.lua_gettop(L); - lua.lua_getinfo(L, lua.to_luastring("f"), ar); /* push function */ - lua.lua_getfield(L, lua.LUA_REGISTRYINDEX, LUA_LOADED_TABLE); + let top = lua_gettop(L); + lua_getinfo(L, to_luastring("f"), ar); /* push function */ + lua_getfield(L, LUA_REGISTRYINDEX, LUA_LOADED_TABLE); if (findfield(L, top + 1, 2)) { - let name = lua.lua_tostring(L, -1); - if (name[0] === "_".charCodeAt(0) && name[1] === "G".charCodeAt(0) && name[2] === ".".charCodeAt(0)) { /* name start with '_G.'? */ - lua.lua_pushstring(L, name.subarray(3)); /* push name without prefix */ - lua.lua_remove(L, -2); /* remove original name */ + let name = lua_tostring(L, -1); + if (name[0] === 95 /* '_'.charCodeAt(0) */ && + name[1] === 71 /* 'G'.charCodeAt(0) */ && + name[2] === 46 /* '.'.charCodeAt(0) */ + ) { /* name start with '_G.'? */ + lua_pushstring(L, name.subarray(3)); /* push name without prefix */ + lua_remove(L, -2); /* remove original name */ } - lua.lua_copy(L, -1, top + 1); /* move name to proper place */ - lua.lua_pop(L, 2); /* remove pushed values */ + lua_copy(L, -1, top + 1); /* move name to proper place */ + lua_pop(L, 2); /* remove pushed values */ return 1; } else { - lua.lua_settop(L, top); /* remove function and global table */ + lua_settop(L, top); /* remove function and global table */ return 0; } }; const pushfuncname = function(L, ar) { if (pushglobalfuncname(L, ar)) { /* try first a global name */ - lua.lua_pushfstring(L, lua.to_luastring("function '%s'"), lua.lua_tostring(L, -1)); - lua.lua_remove(L, -2); /* remove name */ + lua_pushfstring(L, to_luastring("function '%s'"), lua_tostring(L, -1)); + lua_remove(L, -2); /* remove name */ } else if (ar.namewhat.length !== 0) /* is there a name from code? */ - lua.lua_pushfstring(L, lua.to_luastring("%s '%s'"), ar.namewhat, ar.name); /* use it */ - else if (ar.what && ar.what[0] === 'm'.charCodeAt(0)) /* main? */ - lua.lua_pushliteral(L, "main chunk"); - else if (ar.what && ar.what[0] === 'L'.charCodeAt(0)) /* for Lua functions, use <file:line> */ - lua.lua_pushfstring(L, lua.to_luastring("function <%s:%d>"), ar.short_src, ar.linedefined); + lua_pushfstring(L, to_luastring("%s '%s'"), ar.namewhat, ar.name); /* use it */ + else if (ar.what && ar.what[0] === 109 /* 'm'.charCodeAt(0) */) /* main? */ + lua_pushliteral(L, "main chunk"); + else if (ar.what && ar.what[0] === 76 /* 'L'.charCodeAt(0) */) /* for Lua functions, use <file:line> */ + lua_pushfstring(L, to_luastring("function <%s:%d>"), ar.short_src, ar.linedefined); else /* nothing left... */ - lua.lua_pushliteral(L, "?"); + lua_pushliteral(L, "?"); }; const lastlevel = function(L) { - let ar = new lua.lua_Debug(); + let ar = new lua_Debug(); let li = 1; let le = 1; /* find an upper bound */ - while (lua.lua_getstack(L, le, ar)) { li = le; le *= 2; } + while (lua_getstack(L, le, ar)) { li = le; le *= 2; } /* do a binary search */ while (li < le) { let m = Math.floor((li + le)/2); - if (lua.lua_getstack(L, m, ar)) li = m + 1; + if (lua_getstack(L, m, ar)) li = m + 1; else le = m; } return le - 1; }; const luaL_traceback = function(L, L1, msg, level) { - let ar = new lua.lua_Debug(); - let top = lua.lua_gettop(L); + let ar = new lua_Debug(); + let top = lua_gettop(L); let last = lastlevel(L1); let n1 = last - level > LEVELS1 + LEVELS2 ? LEVELS1 : -1; if (msg) - lua.lua_pushfstring(L, lua.to_luastring("%s\n"), msg); + lua_pushfstring(L, to_luastring("%s\n"), msg); luaL_checkstack(L, 10, null); - lua.lua_pushliteral(L, "stack traceback:"); - while (lua.lua_getstack(L1, level++, ar)) { + lua_pushliteral(L, "stack traceback:"); + while (lua_getstack(L1, level++, ar)) { if (n1-- === 0) { /* too many levels? */ - lua.lua_pushliteral(L, "\n\t..."); /* add a '...' */ + lua_pushliteral(L, "\n\t..."); /* add a '...' */ level = last - LEVELS2 + 1; /* and skip to last ones */ } else { - lua.lua_getinfo(L1, lua.to_luastring("Slnt", true), ar); - lua.lua_pushfstring(L, lua.to_luastring("\n\t%s:"), ar.short_src); + lua_getinfo(L1, to_luastring("Slnt", true), ar); + lua_pushfstring(L, to_luastring("\n\t%s:"), ar.short_src); if (ar.currentline > 0) - lua.lua_pushliteral(L, `${ar.currentline}:`); - lua.lua_pushliteral(L, " in "); + lua_pushliteral(L, `${ar.currentline}:`); + lua_pushliteral(L, " in "); pushfuncname(L, ar); if (ar.istailcall) - lua.lua_pushliteral(L, "\n\t(...tail calls..)"); - lua.lua_concat(L, lua.lua_gettop(L) - top); + lua_pushliteral(L, "\n\t(...tail calls..)"); + lua_concat(L, lua_gettop(L) - top); } } - lua.lua_concat(L, lua.lua_gettop(L) - top); + lua_concat(L, lua_gettop(L) - top); }; const panic = function(L) { let msg = "PANIC: unprotected error in call to Lua API"; try { - msg += " (" + lua.lua_tojsstring(L, -1) + ")"; + msg += " (" + lua_tojsstring(L, -1) + ")"; } catch (e) { } throw new Error(msg); }; const luaL_argerror = function(L, arg, extramsg) { - let ar = new lua.lua_Debug(); + let ar = new lua_Debug(); - if (!lua.lua_getstack(L, 0, ar)) /* no stack frame? */ - return luaL_error(L, lua.to_luastring("bad argument #%d (%s)"), arg, extramsg); + if (!lua_getstack(L, 0, ar)) /* no stack frame? */ + return luaL_error(L, to_luastring("bad argument #%d (%s)"), arg, extramsg); - lua.lua_getinfo(L, lua.to_luastring("n"), ar); + lua_getinfo(L, to_luastring("n"), ar); - if (ar.namewhat.join() === lua.to_luastring("method").join()) { + if (luastring_eq(ar.namewhat, to_luastring("method"))) { arg--; /* do not count 'self' */ if (arg === 0) /* error is in the self argument itself? */ - return luaL_error(L, lua.to_luastring("calling '%s' on bad self (%s)"), ar.name, extramsg); + return luaL_error(L, to_luastring("calling '%s' on bad self (%s)"), ar.name, extramsg); } if (ar.name === null) - ar.name = pushglobalfuncname(L, ar) ? lua.lua_tostring(L, -1) : lua.to_luastring("?"); + ar.name = pushglobalfuncname(L, ar) ? lua_tostring(L, -1) : to_luastring("?"); - return luaL_error(L, lua.to_luastring("bad argument #%d to '%s' (%s)"), arg, ar.name, extramsg); + return luaL_error(L, to_luastring("bad argument #%d to '%s' (%s)"), arg, ar.name, extramsg); }; const typeerror = function(L, arg, tname) { let typearg; - if (luaL_getmetafield(L, arg, __name) === lua.LUA_TSTRING) - typearg = lua.lua_tostring(L, -1); - else if (lua.lua_type(L, arg) === lua.LUA_TLIGHTUSERDATA) - typearg = lua.to_luastring("light userdata", true); + if (luaL_getmetafield(L, arg, __name) === LUA_TSTRING) + typearg = lua_tostring(L, -1); + else if (lua_type(L, arg) === LUA_TLIGHTUSERDATA) + typearg = to_luastring("light userdata", true); else typearg = luaL_typename(L, arg); - let msg = lua.lua_pushfstring(L, lua.to_luastring("%s expected, got %s"), tname, typearg); + let msg = lua_pushfstring(L, to_luastring("%s expected, got %s"), tname, typearg); return luaL_argerror(L, arg, msg); }; const luaL_where = function(L, level) { - let ar = new lua.lua_Debug(); - if (lua.lua_getstack(L, level, ar)) { - lua.lua_getinfo(L, lua.to_luastring("Sl", true), ar); + let ar = new lua_Debug(); + if (lua_getstack(L, level, ar)) { + lua_getinfo(L, to_luastring("Sl", true), ar); if (ar.currentline > 0) { - lua.lua_pushfstring(L, lua.to_luastring("%s:%d: "), ar.short_src, ar.currentline); + lua_pushfstring(L, to_luastring("%s:%d: "), ar.short_src, ar.currentline); return; } } - lua.lua_pushstring(L, lua.to_luastring("")); + lua_pushstring(L, to_luastring("")); }; const luaL_error = function(L, fmt, ...argp) { luaL_where(L, 1); - lua.lua_pushvfstring(L, fmt, argp); - lua.lua_concat(L, 2); - return lua.lua_error(L); + lua_pushvfstring(L, fmt, argp); + lua_concat(L, 2); + return lua_error(L); }; /* Unlike normal lua, we pass in an error object */ const luaL_fileresult = function(L, stat, fname, e) { if (stat) { - lua.lua_pushboolean(L, 1); + lua_pushboolean(L, 1); return 1; } else { - lua.lua_pushnil(L); + lua_pushnil(L); if (fname) - lua.lua_pushfstring(L, lua.to_luastring("%s: %s"), fname, lua.to_luastring(e.message)); + lua_pushfstring(L, to_luastring("%s: %s"), fname, to_luastring(e.message)); else - lua.lua_pushstring(L, lua.to_luastring(e.message)); - lua.lua_pushinteger(L, -e.errno); + lua_pushstring(L, to_luastring(e.message)); + lua_pushinteger(L, -e.errno); return 3; } }; @@ -216,9 +303,9 @@ const luaL_fileresult = function(L, stat, fname, e) { const luaL_execresult = function(L, e) { let what, stat; if (e === null) { - lua.lua_pushboolean(L, 1); - lua.lua_pushliteral(L, "exit"); - lua.lua_pushinteger(L, 0); + lua_pushboolean(L, 1); + lua_pushliteral(L, "exit"); + lua_pushinteger(L, 0); return 3; } else if (e.status) { what = "exit"; @@ -230,42 +317,42 @@ const luaL_execresult = function(L, e) { /* XXX: node seems to have e.errno as a string instead of a number */ return luaL_fileresult(L, 0, null, e); } - lua.lua_pushnil(L); - lua.lua_pushliteral(L, what); - lua.lua_pushinteger(L, stat); + lua_pushnil(L); + lua_pushliteral(L, what); + lua_pushinteger(L, stat); return 3; }; const luaL_getmetatable = function(L, n) { - return lua.lua_getfield(L, lua.LUA_REGISTRYINDEX, n); + return lua_getfield(L, LUA_REGISTRYINDEX, n); }; const luaL_newmetatable = function(L, tname) { - if (luaL_getmetatable(L, tname) !== lua.LUA_TNIL) /* name already in use? */ + if (luaL_getmetatable(L, tname) !== LUA_TNIL) /* name already in use? */ return 0; /* leave previous value on top, but return 0 */ - lua.lua_pop(L, 1); - lua.lua_createtable(L, 0, 2); /* create metatable */ - lua.lua_pushstring(L, tname); - lua.lua_setfield(L, -2, __name); /* metatable.__name = tname */ - lua.lua_pushvalue(L, -1); - lua.lua_setfield(L, lua.LUA_REGISTRYINDEX, tname); /* registry.name = metatable */ + lua_pop(L, 1); + lua_createtable(L, 0, 2); /* create metatable */ + lua_pushstring(L, tname); + lua_setfield(L, -2, __name); /* metatable.__name = tname */ + lua_pushvalue(L, -1); + lua_setfield(L, LUA_REGISTRYINDEX, tname); /* registry.name = metatable */ return 1; }; const luaL_setmetatable = function(L, tname) { luaL_getmetatable(L, tname); - lua.lua_setmetatable(L, -2); + lua_setmetatable(L, -2); }; const luaL_testudata = function(L, ud, tname) { - let p = lua.lua_touserdata(L, ud); + let p = lua_touserdata(L, ud); if (p !== null) { /* value is a userdata? */ - if (lua.lua_getmetatable(L, ud)) { /* does it have a metatable? */ + if (lua_getmetatable(L, ud)) { /* does it have a metatable? */ luaL_getmetatable(L, tname); /* get correct metatable */ - if (!lua.lua_rawequal(L, -1, -2)) /* not the same? */ + if (!lua_rawequal(L, -1, -2)) /* not the same? */ p = null; /* value is a userdata with wrong metatable */ - lua.lua_pop(L, 2); /* remove both metatables */ + lua_pop(L, 2); /* remove both metatables */ return p; } } @@ -283,22 +370,22 @@ const luaL_checkoption = function(L, arg, def, lst) { for (let i = 0; lst[i]; i++) if (lst[i].join('|') === name.join('|')) return i; - return luaL_argerror(L, arg, lua.lua_pushfstring(L, lua.to_luastring("invalid option '%s'"), name)); + return luaL_argerror(L, arg, lua_pushfstring(L, to_luastring("invalid option '%s'"), name)); }; const tag_error = function(L, arg, tag) { - typeerror(L, arg, lua.lua_typename(L, tag)); + typeerror(L, arg, lua_typename(L, tag)); }; const luaL_newstate = function() { - let L = lua.lua_newstate(); - if (L) lua.lua_atpanic(L, panic); + let L = lua_newstate(); + if (L) lua_atpanic(L, panic); return L; }; const luaL_typename = function(L, i) { - return lua.lua_typename(L, lua.lua_type(L, i)); + return lua_typename(L, lua_type(L, i)); }; const luaL_argcheck = function(L, cond, arg, extramsg) { @@ -306,12 +393,12 @@ const luaL_argcheck = function(L, cond, arg, extramsg) { }; const luaL_checkany = function(L, arg) { - if (lua.lua_type(L, arg) === lua.LUA_TNONE) - luaL_argerror(L, arg, lua.to_luastring("value expected", true)); + if (lua_type(L, arg) === LUA_TNONE) + luaL_argerror(L, arg, to_luastring("value expected", true)); }; const luaL_checktype = function(L, arg, t) { - if (lua.lua_type(L, arg) !== t) + if (lua_type(L, arg) !== t) tag_error(L, arg, t); }; @@ -320,13 +407,13 @@ const luaL_checkstring = function(L, n) { }; const luaL_checklstring = function(L, arg) { - let s = lua.lua_tolstring(L, arg); - if (s === null || s === undefined) tag_error(L, arg, lua.LUA_TSTRING); + let s = lua_tolstring(L, arg); + if (s === null || s === undefined) tag_error(L, arg, LUA_TSTRING); return s; }; const luaL_optlstring = function(L, arg, def) { - if (lua.lua_type(L, arg) <= 0) { + if (lua_type(L, arg) <= 0) { return def; } else return luaL_checklstring(L, arg); }; @@ -334,16 +421,16 @@ const luaL_optlstring = function(L, arg, def) { const luaL_optstring = luaL_optlstring; const interror = function(L, arg) { - if (lua.lua_isnumber(L, arg)) - luaL_argerror(L, arg, lua.to_luastring("number has no integer representation", true)); + if (lua_isnumber(L, arg)) + luaL_argerror(L, arg, to_luastring("number has no integer representation", true)); else - tag_error(L, arg, lua.LUA_TNUMBER); + tag_error(L, arg, LUA_TNUMBER); }; const luaL_checknumber = function(L, arg) { - let d = lua.lua_tonumberx(L, arg); + let d = lua_tonumberx(L, arg); if (d === false) - tag_error(L, arg, lua.LUA_TNUMBER); + tag_error(L, arg, LUA_TNUMBER); return d; }; @@ -352,7 +439,7 @@ const luaL_optnumber = function(L, arg, def) { }; const luaL_checkinteger = function(L, arg) { - let d = lua.lua_tointegerx(L, arg); + let d = lua_tointegerx(L, arg); if (d === false) interror(L, arg); return d; @@ -363,13 +450,19 @@ const luaL_optinteger = function(L, arg, def) { }; const luaL_prepbuffsize = function(B, sz) { - B.initb = new Uint8Array(sz); - return B.initb; + let newend = B.n + sz; + if (B.b.length < newend) { + let newsize = Math.max(B.b.length * 2, newend); /* double buffer size */ + let newbuff = new Uint8Array(newsize); /* create larger buffer */ + newbuff.set(B.b); /* copy original content */ + B.b = newbuff; + } + return B.b.subarray(B.n, newend); }; const luaL_buffinit = function(L, B) { B.L = L; - B.b = []; + B.b = empty; }; const luaL_buffinitsize = function(L, B, sz) { @@ -384,24 +477,31 @@ const luaL_prepbuffer = function(B) { }; const luaL_addlstring = function(B, s, l) { - B.b = B.b.concat(Array.from(s.subarray(0, l))); + if (l > 0) { + let b = luaL_prepbuffsize(B, l); + b.set(s.subarray(0, l)); + luaL_addsize(B, l); + } }; -const luaL_addstring = luaL_addlstring; +const luaL_addstring = function(B, s) { + luaL_addlstring(B, s, s.length); +}; const luaL_pushresult = function(B) { - let L = B.L; - lua.lua_pushstring(L, Uint8Array.from(B.b)); + lua_pushlstring(B.L, B.b, B.n); + /* delete old buffer */ + B.n = 0; + B.b = empty; }; const luaL_addchar = function(B, c) { - B.b.push(c); + luaL_prepbuffsize(B, 1); + B.b[B.n++] = c; }; const luaL_addsize = function(B, s) { - B.b = B.b.concat(Array.from(B.initb.subarray(0, s))); B.n += s; - B.initb = null; }; const luaL_pushresultsize = function(B, sz) { @@ -411,14 +511,13 @@ const luaL_pushresultsize = function(B, sz) { const luaL_addvalue = function(B) { let L = B.L; - let s = lua.lua_tostring(L, -1); - // TODO: buffonstack ? necessary ? - luaL_addstring(B, s); - lua.lua_remove(L, -1); + let s = lua_tostring(L, -1); + luaL_addlstring(B, s, s.length); + lua_pop(L, 1); /* remove value */ }; const luaL_opt = function(L, f, n, d) { - return lua.lua_type(L, n) <= 0 ? d : f(L, n); + return lua_type(L, n) <= 0 ? d : f(L, n); }; const getS = function(L, ud) { @@ -428,7 +527,7 @@ const getS = function(L, ud) { }; const luaL_loadbufferx = function(L, buff, size, name, mode) { - return lua.lua_load(L, getS, {string: buff}, name, mode); + return lua_load(L, getS, {string: buff}, name, mode); }; const luaL_loadbuffer = function(L, s, sz, n) { @@ -440,80 +539,80 @@ const luaL_loadstring = function(L, s) { }; const luaL_dostring = function(L, s) { - return (luaL_loadstring(L, s) || lua.lua_pcall(L, 0, lua.LUA_MULTRET, 0)); + return (luaL_loadstring(L, s) || lua_pcall(L, 0, LUA_MULTRET, 0)); }; const luaL_getmetafield = function(L, obj, event) { - if (!lua.lua_getmetatable(L, obj)) /* no metatable? */ - return lua.LUA_TNIL; + if (!lua_getmetatable(L, obj)) /* no metatable? */ + return LUA_TNIL; else { - lua.lua_pushstring(L, event); - let tt = lua.lua_rawget(L, -2); - if (tt === lua.LUA_TNIL) /* is metafield nil? */ - lua.lua_pop(L, 2); /* remove metatable and metafield */ + lua_pushstring(L, event); + let tt = lua_rawget(L, -2); + if (tt === LUA_TNIL) /* is metafield nil? */ + lua_pop(L, 2); /* remove metatable and metafield */ else - lua.lua_remove(L, -2); /* remove only metatable */ + lua_remove(L, -2); /* remove only metatable */ return tt; /* return metafield type */ } }; const luaL_callmeta = function(L, obj, event) { - obj = lua.lua_absindex(L, obj); - if (luaL_getmetafield(L, obj, event) === lua.LUA_TNIL) + obj = lua_absindex(L, obj); + if (luaL_getmetafield(L, obj, event) === LUA_TNIL) return false; - lua.lua_pushvalue(L, obj); - lua.lua_call(L, 1, 1); + lua_pushvalue(L, obj); + lua_call(L, 1, 1); return true; }; const luaL_len = function(L, idx) { - lua.lua_len(L, idx); - let l = lua.lua_tointegerx(L, -1); + lua_len(L, idx); + let l = lua_tointegerx(L, -1); if (l === false) - luaL_error(L, lua.to_luastring("object length is not an integer", true)); - lua.lua_pop(L, 1); /* remove object */ + luaL_error(L, to_luastring("object length is not an integer", true)); + lua_pop(L, 1); /* remove object */ return l; }; -const p_I = lua.to_luastring("%I"); -const p_f = lua.to_luastring("%f"); +const p_I = to_luastring("%I"); +const p_f = to_luastring("%f"); const luaL_tolstring = function(L, idx) { if (luaL_callmeta(L, idx, __tostring)) { - if (!lua.lua_isstring(L, -1)) - luaL_error(L, lua.to_luastring("'__tostring' must return a string")); + if (!lua_isstring(L, -1)) + luaL_error(L, to_luastring("'__tostring' must return a string")); } else { - let t = lua.lua_type(L, idx); + let t = lua_type(L, idx); switch(t) { - case lua.LUA_TNUMBER: { - if (lua.lua_isinteger(L, idx)) - lua.lua_pushfstring(L, p_I, lua.lua_tointeger(L, idx)); + case LUA_TNUMBER: { + if (lua_isinteger(L, idx)) + lua_pushfstring(L, p_I, lua_tointeger(L, idx)); else - lua.lua_pushfstring(L, p_f, lua.lua_tonumber(L, idx)); + lua_pushfstring(L, p_f, lua_tonumber(L, idx)); break; } - case lua.LUA_TSTRING: - lua.lua_pushvalue(L, idx); + case LUA_TSTRING: + lua_pushvalue(L, idx); break; - case lua.LUA_TBOOLEAN: - lua.lua_pushliteral(L, (lua.lua_toboolean(L, idx) ? "true" : "false")); + case LUA_TBOOLEAN: + lua_pushliteral(L, (lua_toboolean(L, idx) ? "true" : "false")); break; - case lua.LUA_TNIL: - lua.lua_pushliteral(L, "nil"); + case LUA_TNIL: + lua_pushliteral(L, "nil"); break; default: { let tt = luaL_getmetafield(L, idx, __name); - let kind = tt === lua.LUA_TSTRING ? lua.lua_tostring(L, -1) : luaL_typename(L, idx); - lua.lua_pushfstring(L, lua.to_luastring("%s: %p"), kind, lua.lua_topointer(L, idx)); - if (tt !== lua.LUA_TNIL) - lua.lua_remove(L, -2); + let kind = tt === LUA_TSTRING ? lua_tostring(L, -1) : luaL_typename(L, idx); + lua_pushfstring(L, to_luastring("%s: %p"), kind, lua_topointer(L, idx)); + if (tt !== LUA_TNIL) + lua_remove(L, -2); break; } } } - return lua.lua_tolstring(L, -1); + return lua_tolstring(L, -1); }; /* @@ -523,20 +622,20 @@ const luaL_tolstring = function(L, idx) { ** Leaves resulting module on the top. */ const luaL_requiref = function(L, modname, openf, glb) { - luaL_getsubtable(L, lua.LUA_REGISTRYINDEX, LUA_LOADED_TABLE); - lua.lua_getfield(L, -1, modname); /* LOADED[modname] */ - if (!lua.lua_toboolean(L, -1)) { /* package not already loaded? */ - lua.lua_pop(L, 1); /* remove field */ - lua.lua_pushcfunction(L, openf); - lua.lua_pushstring(L, modname); /* argument to open function */ - lua.lua_call(L, 1, 1); /* call 'openf' to open module */ - lua.lua_pushvalue(L, -1); /* make copy of module (call result) */ - lua.lua_setfield(L, -3, modname); /* LOADED[modname] = module */ + luaL_getsubtable(L, LUA_REGISTRYINDEX, LUA_LOADED_TABLE); + lua_getfield(L, -1, modname); /* LOADED[modname] */ + if (!lua_toboolean(L, -1)) { /* package not already loaded? */ + lua_pop(L, 1); /* remove field */ + lua_pushcfunction(L, openf); + lua_pushstring(L, modname); /* argument to open function */ + lua_call(L, 1, 1); /* call 'openf' to open module */ + lua_pushvalue(L, -1); /* make copy of module (call result) */ + lua_setfield(L, -3, modname); /* LOADED[modname] = module */ } - lua.lua_remove(L, -2); /* remove LOADED table */ + lua_remove(L, -2); /* remove LOADED table */ if (glb) { - lua.lua_pushvalue(L, -1); /* copy of module */ - lua.lua_setglobal(L, modname); /* _G[modname] = module */ + lua_pushvalue(L, -1); /* copy of module */ + lua_setglobal(L, modname); /* _G[modname] = module */ } }; @@ -556,15 +655,16 @@ const find_subarray = function(arr, subarr, from_index) { const luaL_gsub = function(L, s, p, r) { let wild; - let b = []; + let b = new luaL_Buffer(); + luaL_buffinit(L, b); while ((wild = find_subarray(s, p)) >= 0) { - b.push(...s.slice(0, wild)); /* push prefix */ - b.push(...r); /* push replacement in place of pattern */ - s = s.slice(wild + p.length); /* continue after 'p' */ + luaL_addlstring(b, s, wild); /* push prefix */ + luaL_addstring(b, r); /* push replacement in place of pattern */ + s = s.subarray(wild + p.length); /* continue after 'p' */ } - b.push(...s); /* push last suffix */ - lua.lua_pushstring(L, Uint8Array.from(b)); - return lua.lua_tostring(L, -1); + luaL_addstring(b, s); /* push last suffix */ + luaL_pushresult(b); + return lua_tostring(L, -1); }; /* @@ -572,14 +672,14 @@ const luaL_gsub = function(L, s, p, r) { ** into the stack */ const luaL_getsubtable = function(L, idx, fname) { - if (lua.lua_getfield(L, idx, fname) === lua.LUA_TTABLE) + if (lua_getfield(L, idx, fname) === LUA_TTABLE) return true; /* table already there */ else { - lua.lua_pop(L, 1); /* remove previous result */ - idx = lua.lua_absindex(L, idx); - lua.lua_newtable(L); - lua.lua_pushvalue(L, -1); /* copy to be left at top */ - lua.lua_setfield(L, idx, fname); /* assign new table to field */ + lua_pop(L, 1); /* remove previous result */ + idx = lua_absindex(L, idx); + lua_newtable(L); + lua_pushvalue(L, -1); /* copy to be left at top */ + lua_setfield(L, idx, fname); /* assign new table to field */ return false; /* false, because did not find table there */ } }; @@ -590,14 +690,14 @@ const luaL_getsubtable = function(L, idx, fname) { ** Returns with only the table at the stack. */ const luaL_setfuncs = function(L, l, nup) { - luaL_checkstack(L, nup, lua.to_luastring("too many upvalues", true)); + luaL_checkstack(L, nup, to_luastring("too many upvalues", true)); for (let lib in l) { /* fill the table with given functions */ for (let i = 0; i < nup; i++) /* copy upvalues to the top */ - lua.lua_pushvalue(L, -nup); - lua.lua_pushcclosure(L, l[lib], nup); /* closure with those upvalues */ - lua.lua_setfield(L, -(nup + 2), lua.to_luastring(lib)); + lua_pushvalue(L, -nup); + lua_pushcclosure(L, l[lib], nup); /* closure with those upvalues */ + lua_setfield(L, -(nup + 2), to_luastring(lib)); } - lua.lua_pop(L, nup); /* remove upvalues */ + lua_pop(L, nup); /* remove upvalues */ }; /* @@ -608,20 +708,20 @@ const luaL_setfuncs = function(L, l, nup) { ** but without 'msg'.) */ const luaL_checkstack = function(L, space, msg) { - if (!lua.lua_checkstack(L, space)) { + if (!lua_checkstack(L, space)) { if (msg) - luaL_error(L, lua.to_luastring("stack overflow (%s)"), msg); + luaL_error(L, to_luastring("stack overflow (%s)"), msg); else - luaL_error(L, lua.to_luastring('stack overflow', true)); + luaL_error(L, to_luastring('stack overflow', true)); } }; const luaL_newlibtable = function(L) { - lua.lua_createtable(L); + lua_createtable(L); }; const luaL_newlib = function(L, l) { - lua.lua_createtable(L); + lua_createtable(L); luaL_setfuncs(L, l, 0); }; @@ -631,42 +731,42 @@ const LUA_REFNIL = -1; const luaL_ref = function(L, t) { let ref; - if (lua.lua_isnil(L, -1)) { - lua.lua_pop(L, 1); /* remove from stack */ + if (lua_isnil(L, -1)) { + lua_pop(L, 1); /* remove from stack */ return LUA_REFNIL; /* 'nil' has a unique fixed reference */ } - t = lua.lua_absindex(L, t); - lua.lua_rawgeti(L, t, 0); /* get first free element */ - ref = lua.lua_tointeger(L, -1); /* ref = t[freelist] */ - lua.lua_pop(L, 1); /* remove it from stack */ + t = lua_absindex(L, t); + lua_rawgeti(L, t, 0); /* get first free element */ + ref = lua_tointeger(L, -1); /* ref = t[freelist] */ + lua_pop(L, 1); /* remove it from stack */ if (ref !== 0) { /* any free element? */ - lua.lua_rawgeti(L, t, ref); /* remove it from list */ - lua.lua_rawseti(L, t, 0); /* (t[freelist] = t[ref]) */ + lua_rawgeti(L, t, ref); /* remove it from list */ + lua_rawseti(L, t, 0); /* (t[freelist] = t[ref]) */ } else /* no free elements */ - ref = lua.lua_rawlen(L, t) + 1; /* get a new reference */ - lua.lua_rawseti(L, t, ref); + ref = lua_rawlen(L, t) + 1; /* get a new reference */ + lua_rawseti(L, t, ref); return ref; }; const luaL_unref = function(L, t, ref) { if (ref >= 0) { - t = lua.lua_absindex(L, t); - lua.lua_rawgeti(L, t, 0); - lua.lua_rawseti(L, t, ref); /* t[ref] = t[freelist] */ - lua.lua_pushinteger(L, ref); - lua.lua_rawseti(L, t, 0); /* t[freelist] = ref */ + t = lua_absindex(L, t); + lua_rawgeti(L, t, 0); + lua_rawseti(L, t, ref); /* t[ref] = t[freelist] */ + lua_pushinteger(L, ref); + lua_rawseti(L, t, 0); /* t[freelist] = ref */ } }; const errfile = function(L, what, fnameindex, error) { let serr = error.message; - let filename = lua.lua_tostring(L, fnameindex).slice(1); - lua.lua_pushfstring(L, lua.to_luastring("cannot %s %s: %s"), lua.to_luastring(what), filename, lua.to_luastring(serr)); - lua.lua_remove(L, fnameindex); - return lua.LUA_ERRFILE; + let filename = lua_tostring(L, fnameindex).subarray(1); + lua_pushfstring(L, to_luastring("cannot %s %s: %s"), to_luastring(what), filename, to_luastring(serr)); + lua_remove(L, fnameindex); + return LUA_ERRFILE; }; let getc; @@ -695,10 +795,10 @@ const skipBOM = function(lf) { */ const skipcomment = function(lf) { let c = skipBOM(lf); - if (c === '#'.charCodeAt(0)) { /* first line is a comment (Unix exec. file)? */ + if (c === 35 /* '#'.charCodeAt(0) */) { /* first line is a comment (Unix exec. file)? */ do { /* skip first line */ c = getc(lf); - } while (c && c !== '\n'.charCodeAt(0)); + } while (c && c !== 10 /* '\n'.charCodeAt(0) */); return { skipped: true, @@ -746,12 +846,12 @@ if (typeof process === "undefined") { luaL_loadfilex = function(L, filename, mode) { let lf = new LoadF(); - let fnameindex = lua.lua_gettop(L) + 1; /* index of filename on the stack */ + let fnameindex = lua_gettop(L) + 1; /* index of filename on the stack */ if (filename === null) { throw new Error("Can't read stdin in the browser"); } else { - lua.lua_pushfstring(L, lua.to_luastring("@%s"), filename); - let path = lua.to_uristring(filename); + lua_pushfstring(L, to_luastring("@%s"), filename); + let path = to_uristring(filename); let xhr = new XMLHttpRequest(); xhr.open("GET", path, false); /* XXX: Synchronous xhr in main thread always returns a js string @@ -763,7 +863,7 @@ if (typeof process === "undefined") { xhr.send(); if (xhr.status >= 200 && xhr.status <= 299) { if (typeof xhr.response === "string") { - lf.f = lua.to_luastring(xhr.response); + lf.f = to_luastring(xhr.response); } else { lf.f = new Uint8Array(xhr.response); } @@ -774,20 +874,20 @@ if (typeof process === "undefined") { } let com = skipcomment(lf); /* check for signature first, as we don't want to add line number corrections in binary case */ - if (com.c === lua.LUA_SIGNATURE.charCodeAt(0) && filename) { /* binary file? */ + if (com.c === LUA_SIGNATURE[0] && filename) { /* binary file? */ /* no need to re-open in node.js */ } else if (com.skipped) { /* read initial portion */ - lf.buff[lf.n++] = '\n'.charCodeAt(0); /* add line to correct line numbers */ + lf.buff[lf.n++] = 10 /* '\n'.charCodeAt(0) */; /* add line to correct line numbers */ } if (com.c !== null) lf.buff[lf.n++] = com.c; /* 'c' is the first character of the stream */ - let status = lua.lua_load(L, getF, lf, lua.lua_tostring(L, -1), mode); + let status = lua_load(L, getF, lf, lua_tostring(L, -1), mode); let readstatus = lf.err; if (readstatus) { - lua.lua_settop(L, fnameindex); /* ignore results from 'lua_load' */ + lua_settop(L, fnameindex); /* ignore results from 'lua_load' */ return errfile(L, "read", fnameindex, readstatus); } - lua.lua_remove(L, fnameindex); + lua_remove(L, fnameindex); return status; }; } else { @@ -809,7 +909,7 @@ if (typeof process === "undefined") { lf.pos += bytes; } if (bytes > 0) - return lf.buff.subarray(0, bytes); /* slice on a node.js Buffer is 'free' */ + return lf.buff.subarray(0, bytes); else return null; }; @@ -828,36 +928,35 @@ if (typeof process === "undefined") { luaL_loadfilex = function(L, filename, mode) { let lf = new LoadF(); - let fnameindex = lua.lua_gettop(L) + 1; /* index of filename on the stack */ + let fnameindex = lua_gettop(L) + 1; /* index of filename on the stack */ if (filename === null) { - lua.lua_pushliteral(L, "=stdin"); + lua_pushliteral(L, "=stdin"); lf.f = process.stdin.fd; } else { - lua.lua_pushfstring(L, lua.to_luastring("@%s"), filename); + lua_pushfstring(L, to_luastring("@%s"), filename); try { - let jsfilename = Uint8Array.from(filename); - lf.f = fs.openSync(jsfilename, "r"); + lf.f = fs.openSync(filename, "r"); } catch (e) { return errfile(L, "open", fnameindex, e); } } let com = skipcomment(lf); /* check for signature first, as we don't want to add line number corrections in binary case */ - if (com.c === lua.LUA_SIGNATURE.charCodeAt(0) && filename) { /* binary file? */ + if (com.c === LUA_SIGNATURE[0] && filename) { /* binary file? */ /* no need to re-open in node.js */ } else if (com.skipped) { /* read initial portion */ - lf.buff[lf.n++] = '\n'.charCodeAt(0); /* add line to correct line numbers */ + lf.buff[lf.n++] = 10 /* '\n'.charCodeAt(0) */; /* add line to correct line numbers */ } if (com.c !== null) lf.buff[lf.n++] = com.c; /* 'c' is the first character of the stream */ - let status = lua.lua_load(L, getF, lf, lua.lua_tostring(L, -1), mode); + let status = lua_load(L, getF, lf, lua_tostring(L, -1), mode); let readstatus = lf.err; if (filename) try { fs.closeSync(lf.f); } catch(e) {} /* close file (even in case of errors) */ if (readstatus) { - lua.lua_settop(L, fnameindex); /* ignore results from 'lua_load' */ + lua_settop(L, fnameindex); /* ignore results from 'lua_load' */ return errfile(L, "read", fnameindex, readstatus); } - lua.lua_remove(L, fnameindex); + lua_remove(L, fnameindex); return status; }; } @@ -867,7 +966,7 @@ const luaL_loadfile = function(L, filename) { }; const luaL_dofile = function(L, filename) { - return (luaL_loadfile(L, filename) || lua.lua_pcall(L, 0, lua.LUA_MULTRET, 0)); + return (luaL_loadfile(L, filename) || lua_pcall(L, 0, LUA_MULTRET, 0)); }; const lua_writestringerror = function() { @@ -888,18 +987,22 @@ const lua_writestringerror = function() { } }; -const luaL_checkversion = function(L) { - let ver = lua.LUA_VERSION_NUM; - let sz = LUAL_NUMSIZES; - let v = lua.lua_version(L); +const luaL_checkversion_ = function(L, ver, sz) { + let v = lua_version(L); if (sz != LUAL_NUMSIZES) /* check numeric types */ - luaL_error(L, lua.to_luastring("core and library have incompatible numeric types")); - if (v != lua.lua_version(null)) - luaL_error(L, lua.to_luastring("multiple Lua VMs detected")); + luaL_error(L, to_luastring("core and library have incompatible numeric types")); + if (v != lua_version(null)) + luaL_error(L, to_luastring("multiple Lua VMs detected")); else if (v !== ver) - luaL_error(L, lua.to_luastring("version mismatch: app. needs %f, Lua core provides %f"), ver, v); + luaL_error(L, to_luastring("version mismatch: app. needs %f, Lua core provides %f"), ver, v); +}; + +/* There is no point in providing this function... */ +const luaL_checkversion = function(L) { + luaL_checkversion_(L, LUA_VERSION_NUM, LUAL_NUMSIZES); }; +module.exports.LUA_ERRFILE = LUA_ERRFILE; module.exports.LUA_FILEHANDLE = LUA_FILEHANDLE; module.exports.LUA_LOADED_TABLE = LUA_LOADED_TABLE; module.exports.LUA_NOREF = LUA_NOREF; @@ -926,6 +1029,7 @@ module.exports.luaL_checkstring = luaL_checkstring; module.exports.luaL_checktype = luaL_checktype; module.exports.luaL_checkudata = luaL_checkudata; module.exports.luaL_checkversion = luaL_checkversion; +module.exports.luaL_checkversion_ = luaL_checkversion_; module.exports.luaL_dofile = luaL_dofile; module.exports.luaL_dostring = luaL_dostring; module.exports.luaL_error = luaL_error; diff --git a/src/lbaselib.js b/src/lbaselib.js index 86ba6cc..4212525 100644 --- a/src/lbaselib.js +++ b/src/lbaselib.js @@ -1,22 +1,115 @@ "use strict"; -const lua = require('./lua.js'); -const lauxlib = require('./lauxlib.js'); +const { + LUA_MULTRET, + LUA_OK, + LUA_TFUNCTION, + LUA_TNIL, + LUA_TNONE, + LUA_TNUMBER, + LUA_TSTRING, + LUA_TTABLE, + LUA_VERSION, + LUA_YIELD, + lua_call, + lua_callk, + lua_concat, + lua_error, + lua_getglobal, + lua_geti, + lua_getmetatable, + lua_gettop, + lua_insert, + lua_isnil, + lua_isnone, + lua_isstring, + lua_load, + lua_next, + lua_pcallk, + lua_pop, + lua_pushboolean, + lua_pushcfunction, + lua_pushglobaltable, + lua_pushinteger, + lua_pushliteral, + lua_pushnil, + lua_pushstring, + lua_pushvalue, + lua_rawequal, + lua_rawget, + lua_rawlen, + lua_rawset, + lua_remove, + lua_replace, + lua_rotate, + lua_setfield, + lua_setmetatable, + lua_settop, + lua_setupvalue, + lua_stringtonumber, + lua_toboolean, + lua_tolstring, + lua_tostring, + lua_type, + lua_typename +} = require('./lua.js'); +const { + luaL_argcheck, + luaL_checkany, + luaL_checkinteger, + luaL_checkoption, + luaL_checkstack, + luaL_checktype, + luaL_error, + luaL_getmetafield, + luaL_loadbufferx, + luaL_loadfile, + luaL_loadfilex, + luaL_optinteger, + luaL_optstring, + luaL_setfuncs, + luaL_tolstring, + luaL_where +} = require('./lauxlib.js'); +const { + to_jsstring, + to_luastring +} = require("./fengaricore.js"); let lua_writestring; let lua_writeline; if (typeof process === "undefined") { - let buff = ""; - let decoder = new TextDecoder("utf-8"); - lua_writestring = function(s) { - buff += decoder.decode(s, {stream: true}); - }; - let empty = new Uint8Array(0); - lua_writeline = function() { - buff += decoder.decode(empty); - console.log(buff); - buff = ""; - }; + if (typeof TextDecoder === "function") { /* Older browsers don't have TextDecoder */ + let buff = ""; + let decoder = new TextDecoder("utf-8"); + lua_writestring = function(s) { + buff += decoder.decode(s, {stream: true}); + }; + let empty = new Uint8Array(0); + lua_writeline = function() { + buff += decoder.decode(empty); + console.log(buff); + buff = ""; + }; + } else { + let buff = []; + lua_writestring = function(s) { + try { + /* If the string is valid utf8, then we can use to_jsstring */ + s = to_jsstring(s); + } catch(e) { + /* otherwise push copy of raw array */ + let copy = new Uint8Array(s.length); + copy.set(s); + s = copy; + } + buff.push(s); + }; + lua_writeline = function() { + console.log.apply(console.log, buff); + buff = []; + }; + } } else { lua_writestring = function(s) { process.stdout.write(Buffer.from(s)); @@ -26,79 +119,79 @@ if (typeof process === "undefined") { }; } const luaB_print = function(L) { - let n = lua.lua_gettop(L); /* number of arguments */ - lua.lua_getglobal(L, lua.to_luastring("tostring", true)); + let n = lua_gettop(L); /* number of arguments */ + lua_getglobal(L, to_luastring("tostring", true)); for (let i = 1; i <= n; i++) { - lua.lua_pushvalue(L, -1); /* function to be called */ - lua.lua_pushvalue(L, i); /* value to print */ - lua.lua_call(L, 1, 1); - let s = lua.lua_tolstring(L, -1); + lua_pushvalue(L, -1); /* function to be called */ + lua_pushvalue(L, i); /* value to print */ + lua_call(L, 1, 1); + let s = lua_tolstring(L, -1); if (s === null) - return lauxlib.luaL_error(L, lua.to_luastring("'tostring' must return a string to 'print'", true)); - if (i > 1) lua_writestring(lua.to_luastring("\t")); + return luaL_error(L, to_luastring("'tostring' must return a string to 'print'", true)); + if (i > 1) lua_writestring(to_luastring("\t")); lua_writestring(s); - lua.lua_pop(L, 1); + lua_pop(L, 1); } lua_writeline(); return 0; }; const luaB_tostring = function(L) { - lauxlib.luaL_checkany(L, 1); - lauxlib.luaL_tolstring(L, 1); + luaL_checkany(L, 1); + luaL_tolstring(L, 1); return 1; }; const luaB_getmetatable = function(L) { - lauxlib.luaL_checkany(L, 1); - if (!lua.lua_getmetatable(L, 1)) { - lua.lua_pushnil(L); + luaL_checkany(L, 1); + if (!lua_getmetatable(L, 1)) { + lua_pushnil(L); return 1; /* no metatable */ } - lauxlib.luaL_getmetafield(L, 1, lua.to_luastring("__metatable", true)); + luaL_getmetafield(L, 1, to_luastring("__metatable", true)); return 1; /* returns either __metatable field (if present) or metatable */ }; const luaB_setmetatable = function(L) { - let t = lua.lua_type(L, 2); - lauxlib.luaL_checktype(L, 1, lua.LUA_TTABLE); - lauxlib.luaL_argcheck(L, t === lua.LUA_TNIL || t === lua.LUA_TTABLE, 2, lua.to_luastring("nil or table expected", true)); - if (lauxlib.luaL_getmetafield(L, 1, lua.to_luastring("__metatable", true)) !== lua.LUA_TNIL) - return lauxlib.luaL_error(L, lua.to_luastring("cannot change a protected metatable", true)); - lua.lua_settop(L, 2); - lua.lua_setmetatable(L, 1); + let t = lua_type(L, 2); + luaL_checktype(L, 1, LUA_TTABLE); + luaL_argcheck(L, t === LUA_TNIL || t === LUA_TTABLE, 2, to_luastring("nil or table expected", true)); + if (luaL_getmetafield(L, 1, to_luastring("__metatable", true)) !== LUA_TNIL) + return luaL_error(L, to_luastring("cannot change a protected metatable", true)); + lua_settop(L, 2); + lua_setmetatable(L, 1); return 1; }; const luaB_rawequal = function(L) { - lauxlib.luaL_checkany(L, 1); - lauxlib.luaL_checkany(L, 2); - lua.lua_pushboolean(L, lua.lua_rawequal(L, 1, 2)); + luaL_checkany(L, 1); + luaL_checkany(L, 2); + lua_pushboolean(L, lua_rawequal(L, 1, 2)); return 1; }; const luaB_rawlen = function(L) { - let t = lua.lua_type(L, 1); - lauxlib.luaL_argcheck(L, t === lua.LUA_TTABLE || t === lua.LUA_TSTRING, 1, lua.to_luastring("table or string expected", true)); - lua.lua_pushinteger(L, lua.lua_rawlen(L, 1)); + let t = lua_type(L, 1); + luaL_argcheck(L, t === LUA_TTABLE || t === LUA_TSTRING, 1, to_luastring("table or string expected", true)); + lua_pushinteger(L, lua_rawlen(L, 1)); return 1; }; const luaB_rawget = function(L) { - lauxlib.luaL_checktype(L, 1, lua.LUA_TTABLE); - lauxlib.luaL_checkany(L, 2); - lua.lua_settop(L, 2); - lua.lua_rawget(L, 1); + luaL_checktype(L, 1, LUA_TTABLE); + luaL_checkany(L, 2); + lua_settop(L, 2); + lua_rawget(L, 1); return 1; }; const luaB_rawset = function(L) { - lauxlib.luaL_checktype(L, 1, lua.LUA_TTABLE); - lauxlib.luaL_checkany(L, 2); - lauxlib.luaL_checkany(L, 3); - lua.lua_settop(L, 3); - lua.lua_rawset(L, 1); + luaL_checktype(L, 1, LUA_TTABLE); + luaL_checkany(L, 2); + luaL_checkany(L, 3); + lua_settop(L, 3); + lua_rawset(L, 1); return 1; }; @@ -106,56 +199,56 @@ const opts = [ "stop", "restart", "collect", "count", "step", "setpause", "setstepmul", "isrunning" -].map((e) => lua.to_luastring(e)); +].map((e) => to_luastring(e)); const luaB_collectgarbage = function(L) { - lauxlib.luaL_checkoption(L, 1, lua.to_luastring("collect"), opts); - lauxlib.luaL_optinteger(L, 2, 0); - lauxlib.luaL_error(L, lua.to_luastring("lua_gc not implemented")); + luaL_checkoption(L, 1, to_luastring("collect"), opts); + luaL_optinteger(L, 2, 0); + luaL_error(L, to_luastring("lua_gc not implemented")); }; const luaB_type = function(L) { - let t = lua.lua_type(L, 1); - lauxlib.luaL_argcheck(L, t !== lua.LUA_TNONE, 1, lua.to_luastring("value expected", true)); - lua.lua_pushstring(L, lua.lua_typename(L, t)); + let t = lua_type(L, 1); + luaL_argcheck(L, t !== LUA_TNONE, 1, to_luastring("value expected", true)); + lua_pushstring(L, lua_typename(L, t)); return 1; }; const pairsmeta = function(L, method, iszero, iter) { - lauxlib.luaL_checkany(L, 1); - if (lauxlib.luaL_getmetafield(L, 1, method) === lua.LUA_TNIL) { /* no metamethod? */ - lua.lua_pushcfunction(L, iter); /* will return generator, */ - lua.lua_pushvalue(L, 1); /* state, */ - if (iszero) lua.lua_pushinteger(L, 0); /* and initial value */ - else lua.lua_pushnil(L); + luaL_checkany(L, 1); + if (luaL_getmetafield(L, 1, method) === LUA_TNIL) { /* no metamethod? */ + lua_pushcfunction(L, iter); /* will return generator, */ + lua_pushvalue(L, 1); /* state, */ + if (iszero) lua_pushinteger(L, 0); /* and initial value */ + else lua_pushnil(L); } else { - lua.lua_pushvalue(L, 1); /* argument 'self' to metamethod */ - lua.lua_call(L, 1, 3); /* get 3 values from metamethod */ + lua_pushvalue(L, 1); /* argument 'self' to metamethod */ + lua_call(L, 1, 3); /* get 3 values from metamethod */ } return 3; }; const luaB_next = function(L) { - lauxlib.luaL_checktype(L, 1, lua.LUA_TTABLE); - lua.lua_settop(L, 2); /* create a 2nd argument if there isn't one */ - if (lua.lua_next(L, 1)) + luaL_checktype(L, 1, LUA_TTABLE); + lua_settop(L, 2); /* create a 2nd argument if there isn't one */ + if (lua_next(L, 1)) return 2; else { - lua.lua_pushnil(L); + lua_pushnil(L); return 1; } }; const luaB_pairs = function(L) { - return pairsmeta(L, lua.to_luastring("__pairs", true), 0, luaB_next); + return pairsmeta(L, to_luastring("__pairs", true), 0, luaB_next); }; /* ** Traversal function for 'ipairs' */ const ipairsaux = function(L) { - let i = lauxlib.luaL_checkinteger(L, 2) + 1; - lua.lua_pushinteger(L, i); - return lua.lua_geti(L, 1, i) === lua.LUA_TNIL ? 1 : 2; + let i = luaL_checkinteger(L, 2) + 1; + lua_pushinteger(L, i); + return lua_geti(L, 1, i) === LUA_TNIL ? 1 : 2; }; /* @@ -166,94 +259,86 @@ const luaB_ipairs = function(L) { // Lua 5.2 // return pairsmeta(L, "__ipairs", 1, ipairsaux); - lauxlib.luaL_checkany(L, 1); - lua.lua_pushcfunction(L, ipairsaux); /* iteration function */ - lua.lua_pushvalue(L, 1); /* state */ - lua.lua_pushinteger(L, 0); /* initial value */ + luaL_checkany(L, 1); + lua_pushcfunction(L, ipairsaux); /* iteration function */ + lua_pushvalue(L, 1); /* state */ + lua_pushinteger(L, 0); /* initial value */ return 3; }; const b_str2int = function(s, base) { try { - s = lua.to_jsstring(s); + s = to_jsstring(s); } catch (e) { return null; } let r = /^[\t\v\f \n\r]*([+-]?)0*([0-9A-Za-z]+)[\t\v\f \n\r]*$/.exec(s); if (!r) return null; - let neg = r[1] === "-"; - let digits = r[2]; - let n = 0; - for (let si=0; si<digits.length; si++) { - let digit = /\d/.test(digits[si]) - ? (digits.charCodeAt(si) - '0'.charCodeAt(0)) - : (digits[si].toUpperCase().charCodeAt(0) - 'A'.charCodeAt(0) + 10); - if (digit >= base) return null; /* invalid numeral */ - n = ((n * base)|0) + digit; - } - return (neg ? -n : n)|0; + let v = parseInt(r[1]+r[2], base); + if (isNaN(v)) return null; + return v|0; }; const luaB_tonumber = function(L) { - if (lua.lua_type(L, 2) <= 0) { /* standard conversion? */ - lauxlib.luaL_checkany(L, 1); - if (lua.lua_type(L, 1) === lua.LUA_TNUMBER) { /* already a number? */ - lua.lua_settop(L, 1); + if (lua_type(L, 2) <= 0) { /* standard conversion? */ + luaL_checkany(L, 1); + if (lua_type(L, 1) === LUA_TNUMBER) { /* already a number? */ + lua_settop(L, 1); return 1; } else { - let s = lua.lua_tostring(L, 1); - if (s !== null && lua.lua_stringtonumber(L, s) === s.length+1) + let s = lua_tostring(L, 1); + if (s !== null && lua_stringtonumber(L, s) === s.length+1) return 1; /* successful conversion to number */ } } else { - let base = lauxlib.luaL_checkinteger(L, 2); - lauxlib.luaL_checktype(L, 1, lua.LUA_TSTRING); /* no numbers as strings */ - let s = lua.lua_tostring(L, 1); - lauxlib.luaL_argcheck(L, 2 <= base && base <= 36, 2, lua.to_luastring("base out of range", true)); + let base = luaL_checkinteger(L, 2); + luaL_checktype(L, 1, LUA_TSTRING); /* no numbers as strings */ + let s = lua_tostring(L, 1); + luaL_argcheck(L, 2 <= base && base <= 36, 2, to_luastring("base out of range", true)); let n = b_str2int(s, base); if (n !== null) { - lua.lua_pushinteger(L, n); + lua_pushinteger(L, n); return 1; } } - lua.lua_pushnil(L); + lua_pushnil(L); return 1; }; const luaB_error = function(L) { - let level = lauxlib.luaL_optinteger(L, 2, 1); - lua.lua_settop(L, 1); - if (lua.lua_type(L, 1) === lua.LUA_TSTRING && level > 0) { - lauxlib.luaL_where(L, level); /* add extra information */ - lua.lua_pushvalue(L, 1); - lua.lua_concat(L, 2); + let level = luaL_optinteger(L, 2, 1); + lua_settop(L, 1); + if (lua_type(L, 1) === LUA_TSTRING && level > 0) { + luaL_where(L, level); /* add extra information */ + lua_pushvalue(L, 1); + lua_concat(L, 2); } - return lua.lua_error(L); + return lua_error(L); }; const luaB_assert = function(L) { - if (lua.lua_toboolean(L, 1)) /* condition is true? */ - return lua.lua_gettop(L); /* return all arguments */ + if (lua_toboolean(L, 1)) /* condition is true? */ + return lua_gettop(L); /* return all arguments */ else { - lauxlib.luaL_checkany(L, 1); /* there must be a condition */ - lua.lua_remove(L, 1); /* remove it */ - lua.lua_pushliteral(L, "assertion failed!"); /* default message */ - lua.lua_settop(L, 1); /* leave only message (default if no other one) */ + luaL_checkany(L, 1); /* there must be a condition */ + lua_remove(L, 1); /* remove it */ + lua_pushliteral(L, "assertion failed!"); /* default message */ + lua_settop(L, 1); /* leave only message (default if no other one) */ return luaB_error(L); /* call 'error' */ } }; const luaB_select = function(L) { - let n = lua.lua_gettop(L); - if (lua.lua_type(L, 1) === lua.LUA_TSTRING && lua.lua_tostring(L, 1)[0] === "#".charCodeAt(0)) { - lua.lua_pushinteger(L, n - 1); + let n = lua_gettop(L); + if (lua_type(L, 1) === LUA_TSTRING && lua_tostring(L, 1)[0] === 35 /* '#'.charCodeAt(0) */) { + lua_pushinteger(L, n - 1); return 1; } else { - let i = lauxlib.luaL_checkinteger(L, 1); + let i = luaL_checkinteger(L, 1); if (i < 0) i = n + i; else if (i > n) i = n; - lauxlib.luaL_argcheck(L, 1 <= i, 1, lua.to_luastring("index out of range", true)); + luaL_argcheck(L, 1 <= i, 1, to_luastring("index out of range", true)); return n - i; } }; @@ -266,19 +351,19 @@ const luaB_select = function(L) { ** ignored). */ const finishpcall = function(L, status, extra) { - if (status !== lua.LUA_OK && status !== lua.LUA_YIELD) { /* error? */ - lua.lua_pushboolean(L, 0); /* first result (false) */ - lua.lua_pushvalue(L, -2); /* error message */ + if (status !== LUA_OK && status !== LUA_YIELD) { /* error? */ + lua_pushboolean(L, 0); /* first result (false) */ + lua_pushvalue(L, -2); /* error message */ return 2; /* return false, msg */ } else - return lua.lua_gettop(L) - extra; + return lua_gettop(L) - extra; }; const luaB_pcall = function(L) { - lauxlib.luaL_checkany(L, 1); - lua.lua_pushboolean(L, 1); /* first result if no errors */ - lua.lua_insert(L, 1); /* put it in place */ - let status = lua.lua_pcallk(L, lua.lua_gettop(L) - 2, lua.LUA_MULTRET, 0, 0, finishpcall); + luaL_checkany(L, 1); + lua_pushboolean(L, 1); /* first result if no errors */ + lua_insert(L, 1); /* put it in place */ + let status = lua_pcallk(L, lua_gettop(L) - 2, LUA_MULTRET, 0, 0, finishpcall); return finishpcall(L, status, 0); }; @@ -288,27 +373,27 @@ const luaB_pcall = function(L) { ** 2 to 'finishpcall' to skip the 2 first values when returning results. */ const luaB_xpcall = function(L) { - let n = lua.lua_gettop(L); - lauxlib.luaL_checktype(L, 2, lua.LUA_TFUNCTION); /* check error function */ - lua.lua_pushboolean(L, 1); /* first result */ - lua.lua_pushvalue(L, 1); /* function */ - lua.lua_rotate(L, 3, 2); /* move them below function's arguments */ - let status = lua.lua_pcallk(L, n - 2, lua.LUA_MULTRET, 2, 2, finishpcall); + let n = lua_gettop(L); + luaL_checktype(L, 2, LUA_TFUNCTION); /* check error function */ + lua_pushboolean(L, 1); /* first result */ + lua_pushvalue(L, 1); /* function */ + lua_rotate(L, 3, 2); /* move them below function's arguments */ + let status = lua_pcallk(L, n - 2, LUA_MULTRET, 2, 2, finishpcall); return finishpcall(L, status, 2); }; // TODO: does it overwrite the upvalue of the previous closure ? const load_aux = function(L, status, envidx) { - if (status === lua.LUA_OK) { + if (status === LUA_OK) { if (envidx !== 0) { /* 'env' parameter? */ - lua.lua_pushvalue(L, envidx); /* environment for loaded function */ - if (!lua.lua_setupvalue(L, -2, 1)) /* set it as 1st upvalue */ - lua.lua_pop(L, 1); /* remove 'env' if not used by previous call */ + lua_pushvalue(L, envidx); /* environment for loaded function */ + if (!lua_setupvalue(L, -2, 1)) /* set it as 1st upvalue */ + lua_pop(L, 1); /* remove 'env' if not used by previous call */ } return 1; } else { /* error (message is on top of the stack) */ - lua.lua_pushnil(L); - lua.lua_insert(L, -2); /* put before error message */ + lua_pushnil(L); + lua_insert(L, -2); /* put before error message */ return 2; /* return nil plus error message */ } }; @@ -327,53 +412,53 @@ const RESERVEDSLOT = 5; ** reserved slot inside the stack. */ const generic_reader = function(L, ud) { - lauxlib.luaL_checkstack(L, 2, lua.to_luastring("too many nested functions", true)); - lua.lua_pushvalue(L, 1); /* get function */ - lua.lua_call(L, 0, 1); /* call it */ - if (lua.lua_isnil(L, -1)) { - lua.lua_pop(L, 1); /* pop result */ + luaL_checkstack(L, 2, to_luastring("too many nested functions", true)); + lua_pushvalue(L, 1); /* get function */ + lua_call(L, 0, 1); /* call it */ + if (lua_isnil(L, -1)) { + lua_pop(L, 1); /* pop result */ return null; - } else if (!lua.lua_isstring(L, -1)) - lauxlib.luaL_error(L, lua.to_luastring("reader function must return a string", true)); - lua.lua_replace(L, RESERVEDSLOT); /* save string in reserved slot */ - return lua.lua_tostring(L, RESERVEDSLOT); + } else if (!lua_isstring(L, -1)) + luaL_error(L, to_luastring("reader function must return a string", true)); + lua_replace(L, RESERVEDSLOT); /* save string in reserved slot */ + return lua_tostring(L, RESERVEDSLOT); }; const luaB_load = function(L) { - let s = lua.lua_tostring(L, 1); - let mode = lauxlib.luaL_optstring(L, 3, lua.to_luastring("bt", true)); - let env = !lua.lua_isnone(L, 4) ? 4 : 0; /* 'env' index or 0 if no 'env' */ + let s = lua_tostring(L, 1); + let mode = luaL_optstring(L, 3, to_luastring("bt", true)); + let env = !lua_isnone(L, 4) ? 4 : 0; /* 'env' index or 0 if no 'env' */ let status; if (s !== null) { /* loading a string? */ - let chunkname = lauxlib.luaL_optstring(L, 2, s); - status = lauxlib.luaL_loadbufferx(L, s, s.length, chunkname, mode); + let chunkname = luaL_optstring(L, 2, s); + status = luaL_loadbufferx(L, s, s.length, chunkname, mode); } else { /* loading from a reader function */ - let chunkname = lauxlib.luaL_optstring(L, 2, lua.to_luastring("=(load)", true)); - lauxlib.luaL_checktype(L, 1, lua.LUA_TFUNCTION); - lua.lua_settop(L, RESERVEDSLOT); /* create reserved slot */ - status = lua.lua_load(L, generic_reader, null, chunkname, mode); + let chunkname = luaL_optstring(L, 2, to_luastring("=(load)", true)); + luaL_checktype(L, 1, LUA_TFUNCTION); + lua_settop(L, RESERVEDSLOT); /* create reserved slot */ + status = lua_load(L, generic_reader, null, chunkname, mode); } return load_aux(L, status, env); }; const luaB_loadfile = function(L) { - let fname = lauxlib.luaL_optstring(L, 1, null); - let mode = lauxlib.luaL_optstring(L, 2, null); - let env = !lua.lua_isnone(L, 3) ? 3 : 0; /* 'env' index or 0 if no 'env' */ - let status = lauxlib.luaL_loadfilex(L, fname, mode); + let fname = luaL_optstring(L, 1, null); + let mode = luaL_optstring(L, 2, null); + let env = !lua_isnone(L, 3) ? 3 : 0; /* 'env' index or 0 if no 'env' */ + let status = luaL_loadfilex(L, fname, mode); return load_aux(L, status, env); }; const dofilecont = function(L, d1, d2) { - return lua.lua_gettop(L) - 1; + return lua_gettop(L) - 1; }; const luaB_dofile = function(L) { - let fname = lauxlib.luaL_optstring(L, 1, null); - lua.lua_settop(L, 1); - if (lauxlib.luaL_loadfile(L, fname) !== lua.LUA_OK) - return lua.lua_error(L); - lua.lua_callk(L, 0, lua.LUA_MULTRET, 0, dofilecont); + let fname = luaL_optstring(L, 1, null); + lua_settop(L, 1); + if (luaL_loadfile(L, fname) !== LUA_OK) + return lua_error(L); + lua_callk(L, 0, LUA_MULTRET, 0, dofilecont); return dofilecont(L, 0, 0); }; @@ -404,14 +489,14 @@ const base_funcs = { const luaopen_base = function(L) { /* open lib into global table */ - lua.lua_pushglobaltable(L); - lauxlib.luaL_setfuncs(L, base_funcs, 0); + lua_pushglobaltable(L); + luaL_setfuncs(L, base_funcs, 0); /* set global _G */ - lua.lua_pushvalue(L, -1); - lua.lua_setfield(L, -2, lua.to_luastring("_G", true)); + lua_pushvalue(L, -1); + lua_setfield(L, -2, to_luastring("_G", true)); /* set global _VERSION */ - lua.lua_pushliteral(L, lua.LUA_VERSION); - lua.lua_setfield(L, -2, lua.to_luastring("_VERSION", true)); + lua_pushliteral(L, LUA_VERSION); + lua_setfield(L, -2, to_luastring("_VERSION", true)); return 1; }; diff --git a/src/lcode.js b/src/lcode.js index e7259f2..4d9689a 100644 --- a/src/lcode.js +++ b/src/lcode.js @@ -1,8 +1,30 @@ "use strict"; -const assert = require('assert'); - -const defs = require('./defs.js'); +const { + LUA_MULTRET, + LUA_OPADD, + LUA_OPBAND, + LUA_OPBNOT, + LUA_OPBOR, + LUA_OPBXOR, + LUA_OPDIV, + LUA_OPIDIV, + LUA_OPMOD, + LUA_OPSHL, + LUA_OPSHR, + LUA_OPUNM, + constant_types: { + LUA_TBOOLEAN, + LUA_TLIGHTUSERDATA, + LUA_TLNGSTR, + LUA_TNIL, + LUA_TNUMFLT, + LUA_TNUMINT, + LUA_TTABLE + }, + to_luastring +} = require('./defs.js'); +const { lua_assert } = require("./llimits.js"); const llex = require('./llex.js'); const lobject = require('./lobject.js'); const lopcodes = require('./lopcodes.js'); @@ -10,7 +32,6 @@ const lparser = require('./lparser.js'); const ltable = require('./ltable.js'); const lvm = require('./lvm.js'); -const CT = defs.CT; const OpCodesI = lopcodes.OpCodesI; const TValue = lobject.TValue; @@ -71,12 +92,12 @@ const tonumeral = function(e, make_tvalue) { switch (e.k) { case ek.VKINT: if (make_tvalue) { - return new TValue(CT.LUA_TNUMINT, e.u.ival); + return new TValue(LUA_TNUMINT, e.u.ival); } return true; case ek.VKFLT: if (make_tvalue) { - return new TValue(CT.LUA_TNUMFLT, e.u.nval); + return new TValue(LUA_TNUMFLT, e.u.nval); } return true; default: return false; @@ -133,9 +154,9 @@ const getjump = function(fs, pc) { const fixjump = function(fs, pc, dest) { let jmp = fs.f.code[pc]; let offset = dest - (pc + 1); - assert(dest !== NO_JUMP); + lua_assert(dest !== NO_JUMP); if (Math.abs(offset) > lopcodes.MAXARG_sBx) - llex.luaX_syntaxerror(fs.ls, defs.to_luastring("control structure too long", true)); + llex.luaX_syntaxerror(fs.ls, to_luastring("control structure too long", true)); lopcodes.SETARG_sBx(jmp, offset); }; @@ -291,7 +312,7 @@ const luaK_patchlist = function(fs, list, target) { if (target === fs.pc) /* 'target' is current position? */ luaK_patchtohere(fs, list); /* add list to pending jumps */ else { - assert(target < fs.pc); + lua_assert(target < fs.pc); patchlistaux(fs, list, target, lopcodes.NO_REG, target); } }; @@ -305,7 +326,7 @@ const luaK_patchclose = function(fs, list, level) { level++; /* argument is +1 to reserve 0 as non-op */ for (; list !== NO_JUMP; list = getjump(fs, list)) { let ins = fs.f.code[list]; - assert(ins.opcode === OpCodesI.OP_JMP && (ins.A === 0 || ins.A >= level)); + lua_assert(ins.opcode === OpCodesI.OP_JMP && (ins.A === 0 || ins.A >= level)); lopcodes.SETARG_A(ins, level); } }; @@ -328,10 +349,10 @@ const luaK_code = function(fs, i) { ** of parameters versus opcode.) */ const luaK_codeABC = function(fs, o, a, b, c) { - assert(lopcodes.getOpMode(o) === lopcodes.iABC); - assert(lopcodes.getBMode(o) !== lopcodes.OpArgN || b === 0); - assert(lopcodes.getCMode(o) !== lopcodes.OpArgN || c === 0); - assert(a <= lopcodes.MAXARG_A && b <= lopcodes.MAXARG_B && c <= lopcodes.MAXARG_C); + lua_assert(lopcodes.getOpMode(o) === lopcodes.iABC); + lua_assert(lopcodes.getBMode(o) !== lopcodes.OpArgN || b === 0); + lua_assert(lopcodes.getCMode(o) !== lopcodes.OpArgN || c === 0); + lua_assert(a <= lopcodes.MAXARG_A && b <= lopcodes.MAXARG_B && c <= lopcodes.MAXARG_C); return luaK_code(fs, lopcodes.CREATE_ABC(o, a, b, c)); }; @@ -339,9 +360,9 @@ const luaK_codeABC = function(fs, o, a, b, c) { ** Format and emit an 'iABx' instruction. */ const luaK_codeABx = function(fs, o, a, bc) { - assert(lopcodes.getOpMode(o) === lopcodes.iABx || lopcodes.getOpMode(o) === lopcodes.iAsBx); - assert(lopcodes.getCMode(o) === lopcodes.OpArgN); - assert(a <= lopcodes.MAXARG_A && bc <= lopcodes.MAXARG_Bx); + lua_assert(lopcodes.getOpMode(o) === lopcodes.iABx || lopcodes.getOpMode(o) === lopcodes.iAsBx); + lua_assert(lopcodes.getCMode(o) === lopcodes.OpArgN); + lua_assert(a <= lopcodes.MAXARG_A && bc <= lopcodes.MAXARG_Bx); return luaK_code(fs, lopcodes.CREATE_ABx(o, a, bc)); }; @@ -353,7 +374,7 @@ const luaK_codeAsBx = function(fs,o,A,sBx) { ** Emit an "extra argument" instruction (format 'iAx') */ const codeextraarg = function(fs, a) { - assert(a <= lopcodes.MAXARG_Ax); + lua_assert(a <= lopcodes.MAXARG_Ax); return luaK_code(fs, lopcodes.CREATE_Ax(OpCodesI.OP_EXTRAARG, a)); }; @@ -380,7 +401,7 @@ const luaK_checkstack = function(fs, n) { let newstack = fs.freereg + n; if (newstack > fs.f.maxstacksize) { if (newstack >= MAXREGS) - llex.luaX_syntaxerror(fs.ls, defs.to_luastring("function or expression needs too many registers", true)); + llex.luaX_syntaxerror(fs.ls, to_luastring("function or expression needs too many registers", true)); fs.f.maxstacksize = newstack; } }; @@ -400,7 +421,7 @@ const luaK_reserveregs = function(fs, n) { const freereg = function(fs, reg) { if (!lopcodes.ISK(reg) && reg >= fs.nactvar) { fs.freereg--; - assert(reg === fs.freereg); + lua_assert(reg === fs.freereg); } }; @@ -458,7 +479,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); + let o = new TValue(LUA_TLNGSTR, s); return addk(fs, o, o); /* use string itself as key */ }; @@ -469,8 +490,8 @@ const luaK_stringK = function(fs, s) { ** same value. */ const luaK_intK = function(fs, n) { - let k = new TValue(CT.LUA_TLIGHTUSERDATA, n); - let o = new TValue(CT.LUA_TNUMINT, n); + let k = new TValue(LUA_TLIGHTUSERDATA, n); + let o = new TValue(LUA_TNUMINT, n); return addk(fs, k, o); }; @@ -478,7 +499,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); + let o = new TValue(LUA_TNUMFLT, r); return addk(fs, o, o); /* use number itself as key */ }; @@ -487,7 +508,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); + let o = new TValue(LUA_TBOOLEAN, b); return addk(fs, o, o); /* use boolean itself as key */ }; @@ -496,8 +517,8 @@ const boolK = function(fs, b) { ** Add nil to list of constants and return its index. */ const nilK = function(fs) { - let v = new TValue(CT.LUA_TNIL, null); - let k = new TValue(CT.LUA_TTABLE, fs.ls.h); + let v = new TValue(LUA_TNIL, null); + let k = new TValue(LUA_TTABLE, fs.ls.h); /* cannot use nil as key; instead use table itself to represent nil */ return addk(fs, k, v); }; @@ -518,11 +539,11 @@ const luaK_setreturns = function(fs, e, nresults) { lopcodes.SETARG_A(pc, fs.freereg); luaK_reserveregs(fs, 1); } - else assert(nresults === defs.LUA_MULTRET); + else lua_assert(nresults === LUA_MULTRET); }; const luaK_setmultret = function(fs, e) { - luaK_setreturns(fs, e, defs.LUA_MULTRET); + luaK_setreturns(fs, e, LUA_MULTRET); }; /* @@ -539,7 +560,7 @@ const luaK_setoneret = function(fs, e) { let ek = lparser.expkind; if (e.k === ek.VCALL) { /* expression is an open function call? */ /* already returns 1 value */ - assert(getinstruction(fs, e).C === 2); + lua_assert(getinstruction(fs, e).C === 2); e.k = ek.VNONRELOC; /* result has fixed position */ e.u.info = getinstruction(fs, e).A; } else if (e.k === ek.VVARARG) { @@ -571,7 +592,7 @@ const luaK_dischargevars = function(fs, e) { freereg(fs, e.u.ind.t); op = OpCodesI.OP_GETTABLE; } else { - assert(e.u.ind.vt === ek.VUPVAL); + lua_assert(e.u.ind.vt === ek.VUPVAL); op = OpCodesI.OP_GETTABUP; /* 't' is in an upvalue */ } e.u.info = luaK_codeABC(fs, op, 0, e.u.ind.t, e.u.ind.idx); @@ -630,7 +651,7 @@ const discharge2reg = function(fs, e, reg) { break; } default: { - assert(e.k === ek.VJMP); + lua_assert(e.k === ek.VJMP); return; /* nothing to do... */ } } @@ -817,7 +838,7 @@ const luaK_self = function(fs, e, key) { */ const negatecondition = function(fs, e) { let pc = getjumpcontrol(fs, e.u.info); - assert(lopcodes.testTMode(pc.opcode) && pc.opcode !== OpCodesI.OP_TESTSET && pc.opcode !== OpCodesI.OP_TEST); + lua_assert(lopcodes.testTMode(pc.opcode) && pc.opcode !== OpCodesI.OP_TESTSET && pc.opcode !== OpCodesI.OP_TEST); lopcodes.SETARG_A(pc, !(pc.A)); }; @@ -934,7 +955,7 @@ const codenot = function(fs, e) { */ const luaK_indexed = function(fs, t, k) { let ek = lparser.expkind; - assert(!hasjumps(t) && (lparser.vkisinreg(t.k) || t.k === ek.VUPVAL)); + lua_assert(!hasjumps(t) && (lparser.vkisinreg(t.k) || t.k === ek.VUPVAL)); t.u.ind.t = t.u.info; /* register or upvalue index */ t.u.ind.idx = luaK_exp2RK(fs, k); /* R/K index for key */ t.u.ind.vt = (t.k === ek.VUPVAL) ? ek.VUPVAL : ek.VLOCAL; @@ -948,11 +969,11 @@ const luaK_indexed = function(fs, t, k) { */ const validop = function(op, v1, v2) { switch (op) { - case defs.LUA_OPBAND: case defs.LUA_OPBOR: case defs.LUA_OPBXOR: - case defs.LUA_OPSHL: case defs.LUA_OPSHR: case defs.LUA_OPBNOT: { /* conversion errors */ + case LUA_OPBAND: case LUA_OPBOR: case LUA_OPBXOR: + case LUA_OPSHL: case LUA_OPSHR: case LUA_OPBNOT: { /* conversion errors */ return (lvm.tointeger(v1) !== false && lvm.tointeger(v2) !== false); } - case defs.LUA_OPDIV: case defs.LUA_OPIDIV: case defs.LUA_OPMOD: /* division by 0 */ + case LUA_OPDIV: case LUA_OPIDIV: case LUA_OPMOD: /* division by 0 */ return (v2.value !== 0); default: return 1; /* everything else is valid */ } @@ -1026,7 +1047,7 @@ const codecomp = function(fs, opr, e1, e2) { if (e1.k === ek.VK) rk1 = lopcodes.RKASK(e1.u.info); else { - assert(e1.k === ek.VNONRELOC); + lua_assert(e1.k === ek.VNONRELOC); rk1 = e1.u.info; } @@ -1063,7 +1084,7 @@ const luaK_prefix = function(fs, op, e, line) { ef.f = NO_JUMP; switch (op) { case UnOpr.OPR_MINUS: case UnOpr.OPR_BNOT: /* use 'ef' as fake 2nd operand */ - if (constfolding(op + defs.LUA_OPUNM, e, ef)) + if (constfolding(op + LUA_OPUNM, e, ef)) break; /* FALLTHROUGH */ case UnOpr.OPR_LEN: @@ -1118,14 +1139,14 @@ const luaK_posfix = function(fs, op, e1, e2, line) { let ek = lparser.expkind; switch (op) { case BinOpr.OPR_AND: { - assert(e1.t === NO_JUMP); /* list closed by 'luK_infix' */ + lua_assert(e1.t === NO_JUMP); /* list closed by 'luK_infix' */ luaK_dischargevars(fs, e2); e2.f = luaK_concat(fs, e2.f, e1.f); e1.to(e2); break; } case BinOpr.OPR_OR: { - assert(e1.f === NO_JUMP); /* list closed by 'luK_infix' */ + lua_assert(e1.f === NO_JUMP); /* list closed by 'luK_infix' */ luaK_dischargevars(fs, e2); e2.t = luaK_concat(fs, e2.t, e1.t); e1.to(e2); @@ -1135,7 +1156,7 @@ const luaK_posfix = function(fs, op, e1, e2, line) { luaK_exp2val(fs, e2); let ins = getinstruction(fs, e2); if (e2.k === ek.VRELOCABLE && ins.opcode === OpCodesI.OP_CONCAT) { - assert(e1.u.info === ins.B - 1); + lua_assert(e1.u.info === ins.B - 1); freeexp(fs, e1); lopcodes.SETARG_B(ins, e1.u.info); e1.k = ek.VRELOCABLE; e1.u.info = e2.u.info; @@ -1150,7 +1171,7 @@ const luaK_posfix = function(fs, op, e1, e2, line) { case BinOpr.OPR_IDIV: case BinOpr.OPR_MOD: case BinOpr.OPR_POW: case BinOpr.OPR_BAND: case BinOpr.OPR_BOR: case BinOpr.OPR_BXOR: case BinOpr.OPR_SHL: case BinOpr.OPR_SHR: { - if (!constfolding(op + defs.LUA_OPADD, e1, e2)) + if (!constfolding(op + LUA_OPADD, e1, e2)) codebinexpval(fs, op + OpCodesI.OP_ADD, e1, e2, line); break; } @@ -1180,8 +1201,8 @@ const luaK_fixline = function(fs, line) { */ const luaK_setlist = function(fs, base, nelems, tostore) { let c = (nelems - 1)/lopcodes.LFIELDS_PER_FLUSH + 1; - let b = (tostore === defs.LUA_MULTRET) ? 0 : tostore; - assert(tostore !== 0 && tostore <= lopcodes.LFIELDS_PER_FLUSH); + let b = (tostore === LUA_MULTRET) ? 0 : tostore; + lua_assert(tostore !== 0 && tostore <= lopcodes.LFIELDS_PER_FLUSH); if (c <= lopcodes.MAXARG_C) luaK_codeABC(fs, OpCodesI.OP_SETLIST, base, b, c); else if (c <= lopcodes.MAXARG_Ax) { @@ -1189,7 +1210,7 @@ const luaK_setlist = function(fs, base, nelems, tostore) { codeextraarg(fs, c); } else - llex.luaX_syntaxerror(fs.ls, defs.to_luastring("constructor too long", true)); + llex.luaX_syntaxerror(fs.ls, to_luastring("constructor too long", true)); fs.freereg = base + 1; /* free registers with list values */ }; diff --git a/src/lcorolib.js b/src/lcorolib.js index a72d22b..eb402b8 100644 --- a/src/lcorolib.js +++ b/src/lcorolib.js @@ -1,111 +1,144 @@ "use strict"; -const lua = require('./lua.js'); -const lauxlib = require('./lauxlib.js'); +const { + LUA_OK, + LUA_TFUNCTION, + LUA_TSTRING, + LUA_YIELD, + lua_Debug, + lua_checkstack, + lua_concat, + lua_error, + lua_getstack, + lua_gettop, + lua_insert, + lua_isyieldable, + lua_newthread, + lua_pop, + lua_pushboolean, + lua_pushcclosure, + lua_pushliteral, + lua_pushthread, + lua_pushvalue, + lua_resume, + lua_status, + lua_tothread, + lua_type, + lua_upvalueindex, + lua_xmove, + lua_yield +} = require('./lua.js'); +const { + luaL_argcheck, + luaL_checktype, + luaL_newlib, + luaL_where +} = require('./lauxlib.js'); +const { to_luastring } = require("./fengaricore.js"); const getco = function(L) { - let co = lua.lua_tothread(L, 1); - lauxlib.luaL_argcheck(L, co, 1, lua.to_luastring("thread expected", true)); + let co = lua_tothread(L, 1); + luaL_argcheck(L, co, 1, to_luastring("thread expected", true)); return co; }; const auxresume = function(L, co, narg) { - if (!lua.lua_checkstack(co, narg)) { - lua.lua_pushliteral(L, "too many arguments to resume"); + if (!lua_checkstack(co, narg)) { + lua_pushliteral(L, "too many arguments to resume"); return -1; /* error flag */ } - if (lua.lua_status(co) === lua.LUA_OK && lua.lua_gettop(co) === 0) { - lua.lua_pushliteral(L, "cannot resume dead coroutine"); + if (lua_status(co) === LUA_OK && lua_gettop(co) === 0) { + lua_pushliteral(L, "cannot resume dead coroutine"); return -1; /* error flag */ } - lua.lua_xmove(L, co, narg); - let status = lua.lua_resume(co, L, narg); - if (status === lua.LUA_OK || status === lua.LUA_YIELD) { - let nres = lua.lua_gettop(co); - if (!lua.lua_checkstack(L, nres + 1)) { - lua.lua_pop(co, nres); /* remove results anyway */ - lua.lua_pushliteral(L, "too many results to resume"); + lua_xmove(L, co, narg); + let status = lua_resume(co, L, narg); + if (status === LUA_OK || status === LUA_YIELD) { + let nres = lua_gettop(co); + if (!lua_checkstack(L, nres + 1)) { + lua_pop(co, nres); /* remove results anyway */ + lua_pushliteral(L, "too many results to resume"); return -1; /* error flag */ } - lua.lua_xmove(co, L, nres); /* move yielded values */ + lua_xmove(co, L, nres); /* move yielded values */ return nres; } else { - lua.lua_xmove(co, L, 1); /* move error message */ + lua_xmove(co, L, 1); /* move error message */ return -1; /* error flag */ } }; const luaB_coresume = function(L) { let co = getco(L); - let r = auxresume(L, co, lua.lua_gettop(L) - 1); + let r = auxresume(L, co, lua_gettop(L) - 1); if (r < 0) { - lua.lua_pushboolean(L, 0); - lua.lua_insert(L, -2); + lua_pushboolean(L, 0); + lua_insert(L, -2); return 2; /* return false + error message */ } else { - lua.lua_pushboolean(L, 1); - lua.lua_insert(L, -(r + 1)); + lua_pushboolean(L, 1); + lua_insert(L, -(r + 1)); return r + 1; /* return true + 'resume' returns */ } }; const luaB_auxwrap = function(L) { - let co = lua.lua_tothread(L, lua.lua_upvalueindex(1)); - let r = auxresume(L, co, lua.lua_gettop(L)); + let co = lua_tothread(L, lua_upvalueindex(1)); + let r = auxresume(L, co, lua_gettop(L)); if (r < 0) { - if (lua.lua_type(L, -1) === lua.LUA_TSTRING) { /* error object is a string? */ - lauxlib.luaL_where(L, 1); /* add extra info */ - lua.lua_insert(L, -2); - lua.lua_concat(L, 2); + if (lua_type(L, -1) === LUA_TSTRING) { /* error object is a string? */ + luaL_where(L, 1); /* add extra info */ + lua_insert(L, -2); + lua_concat(L, 2); } - return lua.lua_error(L); /* propagate error */ + return lua_error(L); /* propagate error */ } return r; }; const luaB_cocreate = function(L) { - lauxlib.luaL_checktype(L, 1, lua.LUA_TFUNCTION); - let NL = lua.lua_newthread(L); - lua.lua_pushvalue(L, 1); /* move function to top */ - lua.lua_xmove(L, NL, 1); /* move function from L to NL */ + luaL_checktype(L, 1, LUA_TFUNCTION); + let NL = lua_newthread(L); + lua_pushvalue(L, 1); /* move function to top */ + lua_xmove(L, NL, 1); /* move function from L to NL */ return 1; }; const luaB_cowrap = function(L) { luaB_cocreate(L); - lua.lua_pushcclosure(L, luaB_auxwrap, 1); + lua_pushcclosure(L, luaB_auxwrap, 1); return 1; }; const luaB_yield = function(L) { - return lua.lua_yield(L, lua.lua_gettop(L)); + return lua_yield(L, lua_gettop(L)); }; const luaB_costatus = function(L) { let co = getco(L); - if (L === co) lua.lua_pushliteral(L, "running"); + if (L === co) lua_pushliteral(L, "running"); else { - switch (lua.lua_status(co)) { - case lua.LUA_YIELD: - lua.lua_pushliteral(L, "suspended"); + switch (lua_status(co)) { + case LUA_YIELD: + lua_pushliteral(L, "suspended"); break; - case lua.LUA_OK: { - let ar = new lua.lua_Debug(); - if (lua.lua_getstack(co, 0, ar) > 0) /* does it have frames? */ - lua.lua_pushliteral(L, "normal"); /* it is running */ - else if (lua.lua_gettop(co) === 0) - lua.lua_pushliteral(L, "dead"); + case LUA_OK: { + let ar = new lua_Debug(); + if (lua_getstack(co, 0, ar) > 0) /* does it have frames? */ + lua_pushliteral(L, "normal"); /* it is running */ + else if (lua_gettop(co) === 0) + lua_pushliteral(L, "dead"); else - lua.lua_pushliteral(L, "suspended"); /* initial state */ + lua_pushliteral(L, "suspended"); /* initial state */ break; } default: /* some error occurred */ - lua.lua_pushliteral(L, "dead"); + lua_pushliteral(L, "dead"); break; } } @@ -114,12 +147,12 @@ const luaB_costatus = function(L) { }; const luaB_yieldable = function(L) { - lua.lua_pushboolean(L, lua.lua_isyieldable(L)); + lua_pushboolean(L, lua_isyieldable(L)); return 1; }; const luaB_corunning = function(L) { - lua.lua_pushboolean(L, lua.lua_pushthread(L)); + lua_pushboolean(L, lua_pushthread(L)); return 2; }; @@ -134,7 +167,7 @@ const co_funcs = { }; const luaopen_coroutine = function(L) { - lauxlib.luaL_newlib(L, co_funcs); + luaL_newlib(L, co_funcs); return 1; }; diff --git a/src/ldblib.js b/src/ldblib.js index e687ec1..991f8cd 100644 --- a/src/ldblib.js +++ b/src/ldblib.js @@ -1,9 +1,86 @@ "use strict"; -const assert = require('assert'); - -const lua = require('./lua.js'); -const lauxlib = require('./lauxlib.js'); +const { + LUA_MASKCALL, + LUA_MASKCOUNT, + LUA_MASKLINE, + LUA_MASKRET, + LUA_REGISTRYINDEX, + LUA_TFUNCTION, + LUA_TNIL, + LUA_TTABLE, + LUA_TUSERDATA, + lua_Debug, + lua_call, + lua_checkstack, + lua_createtable, + lua_gethook, + lua_gethookcount, + lua_gethookmask, + lua_getinfo, + lua_getlocal, + lua_getmetatable, + lua_getstack, + lua_getupvalue, + lua_getuservalue, + lua_insert, + lua_iscfunction, + lua_isfunction, + lua_isnoneornil, + lua_isthread, + lua_newtable, + lua_pcall, + lua_pop, + lua_pushboolean, + lua_pushfstring, + lua_pushinteger, + lua_pushlightuserdata, + lua_pushliteral, + lua_pushnil, + lua_pushstring, + lua_pushthread, + lua_pushvalue, + lua_rawget, + lua_rawgetp, + lua_rawset, + lua_rawsetp, + lua_remove, + lua_rotate, + lua_setfield, + lua_sethook, + lua_setlocal, + lua_setmetatable, + lua_settop, + lua_setupvalue, + lua_setuservalue, + lua_tojsstring, + lua_tostring, + lua_tothread, + lua_type, + lua_upvalueid, + lua_upvaluejoin, + lua_xmove +} = require('./lua.js'); +const { + luaL_argcheck, + luaL_argerror, + luaL_checkany, + luaL_checkinteger, + luaL_checkstring, + luaL_checktype, + luaL_error, + luaL_loadbuffer, + luaL_newlib, + luaL_optinteger, + luaL_optstring, + luaL_traceback, + lua_writestringerror +} = require('./lauxlib.js'); +const lualib = require('./lualib.js'); +const { + luastring_indexOf, + to_luastring +} = require("./fengaricore.js"); /* ** If L1 != L, L1 can be in any state, and therefore there are no @@ -11,45 +88,45 @@ const lauxlib = require('./lauxlib.js'); ** checked. */ const checkstack = function(L, L1, n) { - if (L !== L1 && !lua.lua_checkstack(L1, n)) - lauxlib.luaL_error(L, lua.to_luastring("stack overflow", true)); + if (L !== L1 && !lua_checkstack(L1, n)) + luaL_error(L, to_luastring("stack overflow", true)); }; const db_getregistry = function(L) { - lua.lua_pushvalue(L, lua.LUA_REGISTRYINDEX); + lua_pushvalue(L, LUA_REGISTRYINDEX); return 1; }; const db_getmetatable = function(L) { - lauxlib.luaL_checkany(L, 1); - if (!lua.lua_getmetatable(L, 1)) { - lua.lua_pushnil(L); /* no metatable */ + luaL_checkany(L, 1); + if (!lua_getmetatable(L, 1)) { + lua_pushnil(L); /* no metatable */ } return 1; }; const db_setmetatable = function(L) { - const t = lua.lua_type(L, 2); - lauxlib.luaL_argcheck(L, t == lua.LUA_TNIL || t == lua.LUA_TTABLE, 2, lua.to_luastring("nil or table expected", true)); - lua.lua_settop(L, 2); - lua.lua_setmetatable(L, 1); + const t = lua_type(L, 2); + luaL_argcheck(L, t == LUA_TNIL || t == LUA_TTABLE, 2, to_luastring("nil or table expected", true)); + lua_settop(L, 2); + lua_setmetatable(L, 1); return 1; /* return 1st argument */ }; const db_getuservalue = function(L) { - if (lua.lua_type(L, 1) !== lua.LUA_TUSERDATA) - lua.lua_pushnil(L); + if (lua_type(L, 1) !== LUA_TUSERDATA) + lua_pushnil(L); else - lua.lua_getuservalue(L, 1); + lua_getuservalue(L, 1); return 1; }; const db_setuservalue = function(L) { - lauxlib.luaL_checktype(L, 1, lua.LUA_TUSERDATA); - lauxlib.luaL_checkany(L, 2); - lua.lua_settop(L, 2); - lua.lua_setuservalue(L, 1); + luaL_checktype(L, 1, LUA_TUSERDATA); + luaL_checkany(L, 2); + lua_settop(L, 2); + lua_setuservalue(L, 1); return 1; }; @@ -60,10 +137,10 @@ const db_setuservalue = function(L) { ** access their other arguments) */ const getthread = function(L) { - if (lua.lua_isthread(L, 1)) { + if (lua_isthread(L, 1)) { return { arg: 1, - thread: lua.lua_tothread(L, 1) + thread: lua_tothread(L, 1) }; } else { return { @@ -79,18 +156,18 @@ const getthread = function(L) { ** value can be a string, an int, or a boolean. */ const settabss = function(L, k, v) { - lua.lua_pushstring(L, v); - lua.lua_setfield(L, -2, k); + lua_pushstring(L, v); + lua_setfield(L, -2, k); }; const settabsi = function(L, k, v) { - lua.lua_pushinteger(L, v); - lua.lua_setfield(L, -2, k); + lua_pushinteger(L, v); + lua_setfield(L, -2, k); }; const settabsb = function(L, k, v) { - lua.lua_pushboolean(L, v); - lua.lua_setfield(L, -2, k); + lua_pushboolean(L, v); + lua_setfield(L, -2, k); }; @@ -103,10 +180,10 @@ const settabsb = function(L, k, v) { */ const treatstackoption = function(L, L1, fname) { if (L == L1) - lua.lua_rotate(L, -2, 1); /* exchange object and table */ + lua_rotate(L, -2, 1); /* exchange object and table */ else - lua.lua_xmove(L1, L, 1); /* move object to the "main" stack */ - lua.lua_setfield(L, -2, fname); /* put object into table */ + lua_xmove(L1, L, 1); /* move object to the "main" stack */ + lua_setfield(L, -2, fname); /* put object into table */ }; /* @@ -116,50 +193,50 @@ const treatstackoption = function(L, L1, fname) { ** 'lua_getinfo'. */ const db_getinfo = function(L) { - let ar = new lua.lua_Debug(); + let ar = new lua_Debug(); let thread = getthread(L); let arg = thread.arg; let L1 = thread.thread; - let options = lauxlib.luaL_optstring(L, arg + 2, lua.to_luastring("flnStu", true)); + let options = luaL_optstring(L, arg + 2, to_luastring("flnStu", true)); checkstack(L, L1, 3); - if (lua.lua_isfunction(L, arg + 1)) { /* info about a function? */ - options = lua.lua_pushfstring(L, lua.to_luastring(">%s"), options); /* add '>' to 'options' */ - lua.lua_pushvalue(L, arg + 1); /* move function to 'L1' stack */ - lua.lua_xmove(L, L1, 1); + if (lua_isfunction(L, arg + 1)) { /* info about a function? */ + options = lua_pushfstring(L, to_luastring(">%s"), options); /* add '>' to 'options' */ + lua_pushvalue(L, arg + 1); /* move function to 'L1' stack */ + lua_xmove(L, L1, 1); } else { /* stack level */ - if (!lua.lua_getstack(L1, lauxlib.luaL_checkinteger(L, arg + 1), ar)) { - lua.lua_pushnil(L); /* level out of range */ + if (!lua_getstack(L1, luaL_checkinteger(L, arg + 1), ar)) { + lua_pushnil(L); /* level out of range */ return 1; } } - if (!lua.lua_getinfo(L1, options, ar)) - lauxlib.luaL_argerror(L, arg + 2, lua.to_luastring("invalid option", true)); - lua.lua_newtable(L); /* table to collect results */ - if (options.indexOf('S'.charCodeAt(0)) > -1) { - settabss(L, lua.to_luastring("source", true), ar.source); - settabss(L, lua.to_luastring("short_src", true), ar.short_src); - settabsi(L, lua.to_luastring("linedefined", true), ar.linedefined); - settabsi(L, lua.to_luastring("lastlinedefined", true), ar.lastlinedefined); - settabss(L, lua.to_luastring("what", true), ar.what); + if (!lua_getinfo(L1, options, ar)) + luaL_argerror(L, arg + 2, to_luastring("invalid option", true)); + lua_newtable(L); /* table to collect results */ + if (luastring_indexOf(options, 83 /* 'S'.charCodeAt(0) */) > -1) { + settabss(L, to_luastring("source", true), ar.source); + settabss(L, to_luastring("short_src", true), ar.short_src); + settabsi(L, to_luastring("linedefined", true), ar.linedefined); + settabsi(L, to_luastring("lastlinedefined", true), ar.lastlinedefined); + settabss(L, to_luastring("what", true), ar.what); } - if (options.indexOf('l'.charCodeAt(0)) > -1) - settabsi(L, lua.to_luastring("currentline", true), ar.currentline); - if (options.indexOf('u'.charCodeAt(0)) > -1) { - settabsi(L, lua.to_luastring("nups", true), ar.nups); - settabsi(L, lua.to_luastring("nparams", true), ar.nparams); - settabsb(L, lua.to_luastring("isvararg", true), ar.isvararg); + if (luastring_indexOf(options, 108 /* 'l'.charCodeAt(0) */) > -1) + settabsi(L, to_luastring("currentline", true), ar.currentline); + if (luastring_indexOf(options, 117 /* 'u'.charCodeAt(0) */) > -1) { + settabsi(L, to_luastring("nups", true), ar.nups); + settabsi(L, to_luastring("nparams", true), ar.nparams); + settabsb(L, to_luastring("isvararg", true), ar.isvararg); } - if (options.indexOf('n'.charCodeAt(0)) > - 1) { - settabss(L, lua.to_luastring("name", true), ar.name); - settabss(L, lua.to_luastring("namewhat", true), ar.namewhat); + if (luastring_indexOf(options, 110 /* 'n'.charCodeAt(0) */) > -1) { + settabss(L, to_luastring("name", true), ar.name); + settabss(L, to_luastring("namewhat", true), ar.namewhat); } - if (options.indexOf('t'.charCodeAt(0)) > - 1) - settabsb(L, lua.to_luastring("istailcall", true), ar.istailcall); - if (options.indexOf('L'.charCodeAt(0)) > - 1) - treatstackoption(L, L1, lua.to_luastring("activelines", true)); - if (options.indexOf('f'.charCodeAt(0)) > - 1) - treatstackoption(L, L1, lua.to_luastring("func", true)); + if (luastring_indexOf(options, 116 /* 't'.charCodeAt(0) */) > -1) + settabsb(L, to_luastring("istailcall", true), ar.istailcall); + if (luastring_indexOf(options, 76 /* 'L'.charCodeAt(0) */) > -1) + treatstackoption(L, L1, to_luastring("activelines", true)); + if (luastring_indexOf(options, 102 /* 'f'.charCodeAt(0) */) > -1) + treatstackoption(L, L1, to_luastring("func", true)); return 1; /* return table */ }; @@ -167,26 +244,26 @@ const db_getlocal = function(L) { let thread = getthread(L); let L1 = thread.thread; let arg = thread.arg; - let ar = new lua.lua_Debug(); - let nvar = lauxlib.luaL_checkinteger(L, arg + 2); /* local-variable index */ - if (lua.lua_isfunction(L, arg + 1)) { - lua.lua_pushvalue(L, arg + 1); /* push function */ - lua.lua_pushstring(L, lua.lua_getlocal(L, null, nvar)); /* push local name */ + let ar = new lua_Debug(); + let nvar = luaL_checkinteger(L, arg + 2); /* local-variable index */ + if (lua_isfunction(L, arg + 1)) { + lua_pushvalue(L, arg + 1); /* push function */ + lua_pushstring(L, lua_getlocal(L, null, nvar)); /* push local name */ return 1; /* return only name (there is no value) */ } else { /* stack-level argument */ - let level = lauxlib.luaL_checkinteger(L, arg + 1); - if (!lua.lua_getstack(L1, level, ar)) /* out of range? */ - return lauxlib.luaL_argerror(L, arg+1, lua.to_luastring("level out of range", true)); + let level = luaL_checkinteger(L, arg + 1); + if (!lua_getstack(L1, level, ar)) /* out of range? */ + return luaL_argerror(L, arg+1, to_luastring("level out of range", true)); checkstack(L, L1, 1); - let name = lua.lua_getlocal(L1, ar, nvar); + let name = lua_getlocal(L1, ar, nvar); if (name) { - lua.lua_xmove(L1, L, 1); /* move local value */ - lua.lua_pushstring(L, name); /* push name */ - lua.lua_rotate(L, -2, 1); /* re-order */ + lua_xmove(L1, L, 1); /* move local value */ + lua_pushstring(L, name); /* push name */ + lua_rotate(L, -2, 1); /* re-order */ return 2; } else { - lua.lua_pushnil(L); /* no name (nor value) */ + lua_pushnil(L); /* no name (nor value) */ return 1; } } @@ -196,19 +273,19 @@ const db_setlocal = function(L) { let thread = getthread(L); let L1 = thread.thread; let arg = thread.arg; - let ar = new lua.lua_Debug(); - let level = lauxlib.luaL_checkinteger(L, arg + 1); - let nvar = lauxlib.luaL_checkinteger(L, arg + 2); - if (!lua.lua_getstack(L1, level, ar)) /* out of range? */ - return lauxlib.luaL_argerror(L, arg + 1, lua.to_luastring("level out of range", true)); - lauxlib.luaL_checkany(L, arg + 3); - lua.lua_settop(L, arg + 3); + let ar = new lua_Debug(); + let level = luaL_checkinteger(L, arg + 1); + let nvar = luaL_checkinteger(L, arg + 2); + if (!lua_getstack(L1, level, ar)) /* out of range? */ + return luaL_argerror(L, arg + 1, to_luastring("level out of range", true)); + luaL_checkany(L, arg + 3); + lua_settop(L, arg + 3); checkstack(L, L1, 1); - lua.lua_xmove(L, L1, 1); - let name = lua.lua_setlocal(L1, ar, nvar); + lua_xmove(L, L1, 1); + let name = lua_setlocal(L1, ar, nvar); if (name === null) - lua.lua_pop(L1, 1); /* pop value (if not popped by 'lua_setlocal') */ - lua.lua_pushstring(L, name); + lua_pop(L1, 1); /* pop value (if not popped by 'lua_setlocal') */ + lua_pushstring(L, name); return 1; }; @@ -216,12 +293,12 @@ const db_setlocal = function(L) { ** get (if 'get' is true) or set an upvalue from a closure */ const auxupvalue = function(L, get) { - let n = lauxlib.luaL_checkinteger(L, 2); /* upvalue index */ - lauxlib.luaL_checktype(L, 1, lua.LUA_TFUNCTION); /* closure */ - let name = get ? lua.lua_getupvalue(L, 1, n) : lua.lua_setupvalue(L, 1, n); + let n = luaL_checkinteger(L, 2); /* upvalue index */ + luaL_checktype(L, 1, LUA_TFUNCTION); /* closure */ + let name = get ? lua_getupvalue(L, 1, n) : lua_setupvalue(L, 1, n); if (name === null) return 0; - lua.lua_pushstring(L, name); - lua.lua_insert(L, -(get+1)); /* no-op if get is false */ + lua_pushstring(L, name); + lua_insert(L, -(get+1)); /* no-op if get is false */ return get + 1; }; @@ -231,7 +308,7 @@ const db_getupvalue = function(L) { }; const db_setupvalue = function(L) { - lauxlib.luaL_checkany(L, 3); + luaL_checkany(L, 3); return auxupvalue(L, 0); }; @@ -240,24 +317,24 @@ const db_setupvalue = function(L) { ** returns its index */ const checkupval = function(L, argf, argnup) { - let nup = lauxlib.luaL_checkinteger(L, argnup); /* upvalue index */ - lauxlib.luaL_checktype(L, argf, lua.LUA_TFUNCTION); /* closure */ - lauxlib.luaL_argcheck(L, (lua.lua_getupvalue(L, argf, nup) !== null), argnup, lua.to_luastring("invalid upvalue index", true)); + let nup = luaL_checkinteger(L, argnup); /* upvalue index */ + luaL_checktype(L, argf, LUA_TFUNCTION); /* closure */ + luaL_argcheck(L, (lua_getupvalue(L, argf, nup) !== null), argnup, to_luastring("invalid upvalue index", true)); return nup; }; const db_upvalueid = function(L) { let n = checkupval(L, 1, 2); - lua.lua_pushlightuserdata(L, lua.lua_upvalueid(L, 1, n)); + lua_pushlightuserdata(L, lua_upvalueid(L, 1, n)); return 1; }; const db_upvaluejoin = function(L) { let n1 = checkupval(L, 1, 2); let n2 = checkupval(L, 3, 4); - lauxlib.luaL_argcheck(L, !lua.lua_iscfunction(L, 1), 1, lua.to_luastring("Lua function expected", true)); - lauxlib.luaL_argcheck(L, !lua.lua_iscfunction(L, 3), 3, lua.to_luastring("Lua function expected", true)); - lua.lua_upvaluejoin(L, 1, n1, 3, n2); + luaL_argcheck(L, !lua_iscfunction(L, 1), 1, to_luastring("Lua function expected", true)); + luaL_argcheck(L, !lua_iscfunction(L, 3), 3, to_luastring("Lua function expected", true)); + lua_upvaluejoin(L, 1, n1, 3, n2); return 0; }; @@ -265,24 +342,24 @@ const db_upvaluejoin = function(L) { ** The hook table at registry[HOOKKEY] maps threads to their current ** hook function. (We only need the unique address of 'HOOKKEY'.) */ -const HOOKKEY = lua.to_luastring("__hooks__", true); +const HOOKKEY = to_luastring("__hooks__", true); -const hooknames = ["call", "return", "line", "count", "tail call"].map(e => lua.to_luastring(e)); +const hooknames = ["call", "return", "line", "count", "tail call"].map(e => to_luastring(e)); /* ** Call hook function registered at hook table for the current ** thread (if there is one) */ const hookf = function(L, ar) { - lua.lua_rawgetp(L, lua.LUA_REGISTRYINDEX, HOOKKEY); - lua.lua_pushthread(L); - if (lua.lua_rawget(L, -2) === lua.LUA_TFUNCTION) { /* is there a hook function? */ - lua.lua_pushstring(L, hooknames[ar.event]); /* push event name */ + lua_rawgetp(L, LUA_REGISTRYINDEX, HOOKKEY); + lua_pushthread(L); + if (lua_rawget(L, -2) === LUA_TFUNCTION) { /* is there a hook function? */ + lua_pushstring(L, hooknames[ar.event]); /* push event name */ if (ar.currentline >= 0) - lua.lua_pushinteger(L, ar.currentline); /* push current line */ - else lua.lua_pushnil(L); - assert(lua.lua_getinfo(L, lua.to_luastring("lS"), ar)); - lua.lua_call(L, 2, 0); /* call hook function */ + lua_pushinteger(L, ar.currentline); /* push current line */ + else lua_pushnil(L); + lualib.lua_assert(lua_getinfo(L, to_luastring("lS"), ar)); + lua_call(L, 2, 0); /* call hook function */ } }; @@ -291,10 +368,10 @@ const hookf = function(L, ar) { */ const makemask = function(smask, count) { let mask = 0; - if (smask.indexOf("c".charCodeAt(0)) > -1) mask |= lua.LUA_MASKCALL; - if (smask.indexOf("r".charCodeAt(0)) > -1) mask |= lua.LUA_MASKRET; - if (smask.indexOf("l".charCodeAt(0)) > -1) mask |= lua.LUA_MASKLINE; - if (count > 0) mask |= lua.LUA_MASKCOUNT; + if (luastring_indexOf(smask, 99 /* 'c'.charCodeAt(0) */) > -1) mask |= LUA_MASKCALL; + if (luastring_indexOf(smask, 114 /* 'r'.charCodeAt(0) */) > -1) mask |= LUA_MASKRET; + if (luastring_indexOf(smask, 108 /* 'l'.charCodeAt(0) */) > -1) mask |= LUA_MASKLINE; + if (count > 0) mask |= LUA_MASKCOUNT; return mask; }; @@ -303,9 +380,9 @@ const makemask = function(smask, count) { */ const unmakemask = function(mask, smask) { let i = 0; - if (mask & lua.LUA_MASKCALL) smask[i++] = "c".charCodeAt(0); - if (mask & lua.LUA_MASKRET) smask[i++] = "r".charCodeAt(0); - if (mask & lua.LUA_MASKLINE) smask[i++] = "l".charCodeAt(0); + if (mask & LUA_MASKCALL) smask[i++] = 99 /* 'c'.charCodeAt(0) */; + if (mask & LUA_MASKRET) smask[i++] = 114 /* 'r'.charCodeAt(0) */; + if (mask & LUA_MASKLINE) smask[i++] = 108 /* 'l'.charCodeAt(0) */; return smask.subarray(0, i); }; @@ -314,30 +391,30 @@ const db_sethook = function(L) { let thread = getthread(L); let L1 = thread.thread; let arg = thread.arg; - if (lua.lua_isnoneornil(L, arg+1)) { /* no hook? */ - lua.lua_settop(L, arg+1); + if (lua_isnoneornil(L, arg+1)) { /* no hook? */ + lua_settop(L, arg+1); func = null; mask = 0; count = 0; /* turn off hooks */ } else { - const smask = lauxlib.luaL_checkstring(L, arg + 2); - lauxlib.luaL_checktype(L, arg+1, lua.LUA_TFUNCTION); - count = lauxlib.luaL_optinteger(L, arg + 3, 0); + const smask = luaL_checkstring(L, arg + 2); + luaL_checktype(L, arg+1, LUA_TFUNCTION); + count = luaL_optinteger(L, arg + 3, 0); func = hookf; mask = makemask(smask, count); } - if (lua.lua_rawgetp(L, lua.LUA_REGISTRYINDEX, HOOKKEY) === lua.LUA_TNIL) { - lua.lua_createtable(L, 0, 2); /* create a hook table */ - lua.lua_pushvalue(L, -1); - lua.lua_rawsetp(L, lua.LUA_REGISTRYINDEX, HOOKKEY); /* set it in position */ - lua.lua_pushstring(L, lua.to_luastring("k")); - lua.lua_setfield(L, -2, lua.to_luastring("__mode", true)); /** hooktable.__mode = "k" */ - lua.lua_pushvalue(L, -1); - lua.lua_setmetatable(L, -2); /* setmetatable(hooktable) = hooktable */ + if (lua_rawgetp(L, LUA_REGISTRYINDEX, HOOKKEY) === LUA_TNIL) { + lua_createtable(L, 0, 2); /* create a hook table */ + lua_pushvalue(L, -1); + lua_rawsetp(L, LUA_REGISTRYINDEX, HOOKKEY); /* set it in position */ + lua_pushstring(L, to_luastring("k")); + lua_setfield(L, -2, to_luastring("__mode", true)); /** hooktable.__mode = "k" */ + lua_pushvalue(L, -1); + lua_setmetatable(L, -2); /* setmetatable(hooktable) = hooktable */ } checkstack(L, L1, 1); - lua.lua_pushthread(L1); lua.lua_xmove(L1, L, 1); /* key (thread) */ - lua.lua_pushvalue(L, arg + 1); /* value (hook function) */ - lua.lua_rawset(L, -3); /* hooktable[L1] = new Lua hook */ - lua.lua_sethook(L1, func, mask, count); + lua_pushthread(L1); lua_xmove(L1, L, 1); /* key (thread) */ + lua_pushvalue(L, arg + 1); /* value (hook function) */ + lua_rawset(L, -3); /* hooktable[L1] = new Lua hook */ + lua_sethook(L1, func, mask, count); return 0; }; @@ -345,21 +422,21 @@ const db_gethook = function(L) { let thread = getthread(L); let L1 = thread.thread; let buff = new Uint8Array(5); - let mask = lua.lua_gethookmask(L1); - let hook = lua.lua_gethook(L1); + let mask = lua_gethookmask(L1); + let hook = lua_gethook(L1); if (hook === null) /* no hook? */ - lua.lua_pushnil(L); + lua_pushnil(L); else if (hook !== hookf) /* external hook? */ - lua.lua_pushliteral(L, "external hook"); + lua_pushliteral(L, "external hook"); else { /* hook table must exist */ - lua.lua_rawgetp(L, lua.LUA_REGISTRYINDEX, HOOKKEY); + lua_rawgetp(L, LUA_REGISTRYINDEX, HOOKKEY); checkstack(L, L1, 1); - lua.lua_pushthread(L1); lua.lua_xmove(L1, L, 1); - lua.lua_rawget(L, -2); /* 1st result = hooktable[L1] */ - lua.lua_remove(L, -2); /* remove hook table */ + lua_pushthread(L1); lua_xmove(L1, L, 1); + lua_rawget(L, -2); /* 1st result = hooktable[L1] */ + lua_remove(L, -2); /* remove hook table */ } - lua.lua_pushstring(L, unmakemask(mask, buff)); /* 2nd result = mask */ - lua.lua_pushinteger(L, lua.lua_gethookcount(L1)); /* 3rd result = count */ + lua_pushstring(L, unmakemask(mask, buff)); /* 2nd result = mask */ + lua_pushinteger(L, lua_gethookcount(L1)); /* 3rd result = count */ return 3; }; @@ -367,12 +444,12 @@ const db_traceback = function(L) { let thread = getthread(L); let L1 = thread.thread; let arg = thread.arg; - let msg = lua.lua_tostring(L, arg + 1); - if (msg === null && !lua.lua_isnoneornil(L, arg + 1)) /* non-string 'msg'? */ - lua.lua_pushvalue(L, arg + 1); /* return it untouched */ + let msg = lua_tostring(L, arg + 1); + if (msg === null && !lua_isnoneornil(L, arg + 1)) /* non-string 'msg'? */ + lua_pushvalue(L, arg + 1); /* return it untouched */ else { - let level = lauxlib.luaL_optinteger(L, arg + 2, L === L1 ? 1 : 0); - lauxlib.luaL_traceback(L, L1, msg, level); + let level = luaL_optinteger(L, arg + 2, L === L1 ? 1 : 0); + luaL_traceback(L, L1, msg, level); } return 1; }; @@ -424,18 +501,18 @@ if (getinput) { if (input.length === 0) continue; - let buffer = lua.to_luastring(input); - if (lauxlib.luaL_loadbuffer(L, buffer, buffer.length, lua.to_luastring("=(debug command)", true)) - || lua.lua_pcall(L, 0, 0, 0)) { - lauxlib.lua_writestringerror(lua.lua_tojsstring(L, -1), "\n"); + let buffer = to_luastring(input); + if (luaL_loadbuffer(L, buffer, buffer.length, to_luastring("=(debug command)", true)) + || lua_pcall(L, 0, 0, 0)) { + lua_writestringerror(lua_tojsstring(L, -1), "\n"); } - lua.lua_settop(L, 0); /* remove eventual returns */ + lua_settop(L, 0); /* remove eventual returns */ } }; } const luaopen_debug = function(L) { - lauxlib.luaL_newlib(L, dblib); + luaL_newlib(L, dblib); return 1; }; diff --git a/src/ldebug.js b/src/ldebug.js index 1bb7a8a..a471c75 100644 --- a/src/ldebug.js +++ b/src/ldebug.js @@ -1,8 +1,30 @@ "use strict"; -const assert = require('assert'); - -const defs = require('./defs.js'); +const { + LUA_HOOKCOUNT, + LUA_HOOKLINE, + LUA_MASKCOUNT, + LUA_MASKLINE, + constant_types: { + LUA_TBOOLEAN, + LUA_TNIL, + LUA_TTABLE + }, + thread_status: { + LUA_ERRRUN, + LUA_YIELD + }, + from_userstring, + luastring_eq, + luastring_indexOf, + to_luastring +} = require('./defs.js'); +const { + api_check, + lua_assert +} = require('./llimits.js'); +const { LUA_IDSIZE } = require('./luaconf.js'); +const lapi = require('./lapi.js'); const ldo = require('./ldo.js'); const lfunc = require('./lfunc.js'); const llex = require('./llex.js'); @@ -11,14 +33,10 @@ const lopcodes = require('./lopcodes.js'); const lstate = require('./lstate.js'); const ltable = require('./ltable.js'); const ltm = require('./ltm.js'); -const luaconf = require('./luaconf.js'); const lvm = require('./lvm.js'); -const CT = defs.constant_types; -const TS = defs.thread_status; - const currentpc = function(ci) { - assert(ci.callstatus & lstate.CIST_LUA); + lua_assert(ci.callstatus & lstate.CIST_LUA); return ci.l_savedpc - 1; }; @@ -33,7 +51,7 @@ const currentline = function(ci) { ** after debugging, it also "re-restores" ** 'func' to its altered value. */ const swapextra = function(L) { - if (L.status === TS.LUA_YIELD) { + if (L.status === LUA_YIELD) { let ci = L.ci; /* get function that yielded */ let temp = ci.funcOff; /* exchange its 'func' and 'extra' values */ ci.func = L.stack[ci.extra]; @@ -84,9 +102,9 @@ const lua_getstack = function(L, level, ar) { }; const upvalname = function(p, uv) { - assert(uv < p.upvalues.length); + lua_assert(uv < p.upvalues.length); let s = p.upvalues[uv].name; - if (s === null) return defs.to_luastring("?", true); + if (s === null) return to_luastring("?", true); return s.getstr(); }; @@ -97,7 +115,7 @@ const findvararg = function(ci, n) { else { return { pos: ci.funcOff + nparams + n, - name: defs.to_luastring("(*vararg)", true) /* generic name for any vararg */ + name: to_luastring("(*vararg)", true) /* generic name for any vararg */ }; } }; @@ -118,7 +136,7 @@ const findlocal = function(L, ci, n) { if (name === null) { /* no 'standard' name? */ let limit = ci === L.ci ? L.top : ci.next.funcOff; if (limit - base >= n && n > 0) /* is 'n' inside 'ci' stack? */ - name = defs.to_luastring("(*temporary)", true); /* generic name for any valid slot */ + name = to_luastring("(*temporary)", true); /* generic name for any valid slot */ else return null; /* no name */ } @@ -141,7 +159,7 @@ const lua_getlocal = function(L, ar, n) { if (local) { name = local.name; lobject.pushobj2s(L, L.stack[local.pos]); - assert(L.top <= L.ci.top, "stack overflow"); + api_check(L, L.top <= L.ci.top, "stack overflow"); } else { name = null; } @@ -167,33 +185,31 @@ const lua_setlocal = function(L, ar, n) { const funcinfo = function(ar, cl) { if (cl === null || cl instanceof lobject.CClosure) { - ar.source = defs.to_luastring("=[JS]", true); + ar.source = to_luastring("=[JS]", true); ar.linedefined = -1; ar.lastlinedefined = -1; - ar.what = defs.to_luastring("J", true); + ar.what = to_luastring("J", true); } else { let p = cl.p; - ar.source = p.source ? p.source.getstr() : defs.to_luastring("=?", true); + ar.source = p.source ? p.source.getstr() : to_luastring("=?", true); ar.linedefined = p.linedefined; ar.lastlinedefined = p.lastlinedefined; - ar.what = ar.linedefined === 0 ? defs.to_luastring("main", true) : defs.to_luastring("Lua", true); + ar.what = ar.linedefined === 0 ? to_luastring("main", true) : to_luastring("Lua", true); } - ar.short_src = lobject.luaO_chunkid(ar.source, luaconf.LUA_IDSIZE); + ar.short_src = lobject.luaO_chunkid(ar.source, LUA_IDSIZE); }; const collectvalidlines = function(L, f) { if (f === null || f instanceof lobject.CClosure) { - L.stack[L.top] = new lobject.TValue(CT.LUA_TNIL, null); - L.top++; - assert(L.top <= L.ci.top, "stack overflow"); + L.stack[L.top] = new lobject.TValue(LUA_TNIL, null); + lapi.api_incr_top(L); } else { let lineinfo = f.p.lineinfo; let t = ltable.luaH_new(L); - L.stack[L.top] = new lobject.TValue(CT.LUA_TTABLE, t); - L.top++; - assert(L.top <= L.ci.top, "stack overflow"); - let v = new lobject.TValue(CT.LUA_TBOOLEAN, true); + L.stack[L.top] = new lobject.TValue(LUA_TTABLE, t); + lapi.api_incr_top(L); + let v = new lobject.TValue(LUA_TBOOLEAN, true); for (let i = 0; i < lineinfo.length; i++) ltable.luaH_setint(t, lineinfo[i], v); } @@ -207,8 +223,8 @@ const getfuncname = function(L, ci) { if (ci === null) return null; else if (ci.callstatus & lstate.CIST_FIN) { /* is this a finalizer? */ - r.name = defs.to_luastring("__gc", true); - r.funcname = defs.to_luastring("metamethod", true); /* report it as such */ + r.name = to_luastring("__gc", true); + r.funcname = to_luastring("metamethod", true); /* report it as such */ return r; } /* calling function is a known Lua function? */ @@ -219,17 +235,17 @@ const getfuncname = function(L, ci) { const auxgetinfo = function(L, what, ar, f, ci) { let status = 1; - for (; what.length > 0; what = what.slice(1)) { - switch (String.fromCharCode(what[0])) { - case 'S': { + for (; what.length > 0; what = what.subarray(1)) { + switch (what[0]) { + case 83 /* ('S').charCodeAt(0) */: { funcinfo(ar, f); break; } - case 'l': { + case 108 /* ('l').charCodeAt(0) */: { ar.currentline = ci && ci.callstatus & lstate.CIST_LUA ? currentline(ci) : -1; break; } - case 'u': { + case 117 /* ('u').charCodeAt(0) */: { ar.nups = f === null ? 0 : f.nupvalues; if (f === null || f instanceof lobject.CClosure) { ar.isvararg = true; @@ -240,14 +256,14 @@ const auxgetinfo = function(L, what, ar, f, ci) { } break; } - case 't': { + case 116 /* ('t').charCodeAt(0) */: { ar.istailcall = ci ? ci.callstatus & lstate.CIST_TAIL : 0; break; } - case 'n': { + case 110 /* ('n').charCodeAt(0) */: { let r = getfuncname(L, ci); if (r === null) { - ar.namewhat = defs.to_luastring("", true); + ar.namewhat = to_luastring("", true); ar.name = null; } else { ar.namewhat = r.funcname; @@ -255,8 +271,8 @@ const auxgetinfo = function(L, what, ar, f, ci) { } break; } - case 'L': - case 'f': /* handled by lua_getinfo */ + case 76 /* ('L').charCodeAt(0) */: + case 102 /* ('f').charCodeAt(0) */: /* handled by lua_getinfo */ break; default: status = 0; /* invalid option */ } @@ -266,30 +282,30 @@ const auxgetinfo = function(L, what, ar, f, ci) { }; const lua_getinfo = function(L, what, ar) { - what = defs.from_userstring(what); + what = from_userstring(what); let status, cl, ci, func; swapextra(L); - if (what[0] === '>'.charCodeAt(0)) { + if (what[0] === 62 /* ('>').charCodeAt(0) */) { ci = null; func = L.stack[L.top - 1]; - assert(L, func.ttisfunction(), "function expected"); - what = what.slice(1); /* skip the '>' */ + api_check(L, func.ttisfunction(), "function expected"); + what = what.subarray(1); /* skip the '>' */ L.top--; /* pop function */ } else { ci = ar.i_ci; func = ci.func; - assert(ci.func.ttisfunction()); + lua_assert(ci.func.ttisfunction()); } cl = func.ttisclosure() ? func.value : null; status = auxgetinfo(L, what, ar, cl, ci); - if (what.indexOf('f'.charCodeAt(0)) >= 0) { + if (luastring_indexOf(what, 102 /* ('f').charCodeAt(0) */) >= 0) { lobject.pushobj2s(L, func); - assert(L.top <= L.ci.top, "stack overflow"); + api_check(L, L.top <= L.ci.top, "stack overflow"); } swapextra(L); - if (what.indexOf('L'.charCodeAt(0)) >= 0) + if (luastring_indexOf(what, 76 /* ('L').charCodeAt(0) */) >= 0) collectvalidlines(L, cl); return status; @@ -310,12 +326,12 @@ const kname = function(p, pc, c) { /* else no reasonable name found */ } else { /* 'c' is a register */ let what = getobjname(p, pc, c); /* search for 'c' */ - if (what && what.funcname[0] === 'c'.charCodeAt(0)) { /* found a constant name? */ + if (what && what.funcname[0] === 99 /* ('c').charCodeAt(0) */) { /* found a constant name? */ return what; /* 'name' already filled */ } /* else no reasonable name found */ } - r.name = defs.to_luastring("?", true); + r.name = to_luastring("?", true); return r; /* no reasonable name found */ }; @@ -381,7 +397,7 @@ const getobjname = function(p, lastpc, reg) { }; if (r.name) { /* is a local? */ - r.funcname = defs.to_luastring("local", true); + r.funcname = to_luastring("local", true); return r; } @@ -403,12 +419,12 @@ const getobjname = function(p, lastpc, reg) { let t = i.B; /* table index */ let vn = i.opcode === OCi.OP_GETTABLE ? lfunc.luaF_getlocalname(p, t + 1, pc) : upvalname(p, t); r.name = kname(p, pc, k).name; - r.funcname = (vn && defs.luastring_cmp(vn, llex.LUA_ENV)) ? defs.to_luastring("global", true) : defs.to_luastring("field", true); + r.funcname = (vn && luastring_eq(vn, llex.LUA_ENV)) ? to_luastring("global", true) : to_luastring("field", true); return r; } case OCi.OP_GETUPVAL: { r.name = upvalname(p, i.B); - r.funcname = defs.to_luastring("upvalue", true); + r.funcname = to_luastring("upvalue", true); return r; } case OCi.OP_LOADK: @@ -416,7 +432,7 @@ const getobjname = function(p, lastpc, reg) { let b = i.opcode === OCi.OP_LOADK ? i.Bx : p.code[pc + 1].Ax; if (p.k[b].ttisstring()) { r.name = p.k[b].svalue(); - r.funcname = defs.to_luastring("constant", true); + r.funcname = to_luastring("constant", true); return r; } break; @@ -424,7 +440,7 @@ const getobjname = function(p, lastpc, reg) { case OCi.OP_SELF: { let k = i.C; r.name = kname(p, pc, k).name; - r.funcname = defs.to_luastring("method", true); + r.funcname = to_luastring("method", true); return r; } default: break; @@ -453,8 +469,8 @@ const funcnamefromcode = function(L, ci) { let OCi = lopcodes.OpCodesI; if (ci.callstatus & lstate.CIST_HOOKED) { - r.name = defs.to_luastring("?", true); - r.funcname = defs.to_luastring("hook", true); + r.name = to_luastring("?", true); + r.funcname = to_luastring("hook", true); return r; } @@ -463,8 +479,8 @@ const funcnamefromcode = function(L, ci) { case OCi.OP_TAILCALL: return getobjname(p, pc, i.A); /* get function name */ case OCi.OP_TFORCALL: - r.name = defs.to_luastring("for iterator", true); - r.funcname = defs.to_luastring("for iterator", true); + r.name = to_luastring("for iterator", true); + r.funcname = to_luastring("for iterator", true); return r; /* other instructions can do calls through metamethods */ case OCi.OP_SELF: @@ -500,7 +516,7 @@ const funcnamefromcode = function(L, ci) { } r.name = L.l_G.tmname[tm].getstr(); - r.funcname = defs.to_luastring("metamethod", true); + r.funcname = to_luastring("metamethod", true); return r; }; @@ -521,10 +537,10 @@ const isinstack = function(L, ci, o) { const getupvalname = function(L, ci, o) { let c = ci.func.value; for (let i = 0; i < c.nupvalues; i++) { - if (c.upvals[i].v === o) { + if (c.upvals[i] === o) { return { name: upvalname(c.p, i), - funcname: defs.to_luastring('upvalue', true) + funcname: to_luastring('upvalue', true) }; } } @@ -542,17 +558,17 @@ const varinfo = function(L, o) { kind = getobjname(ci.func.value.p, currentpc(ci), stkid - ci.l_base); } - return kind ? lobject.luaO_pushfstring(L, defs.to_luastring(" (%s '%s')", true), kind.funcname, kind.name) : defs.to_luastring("", true); + return kind ? lobject.luaO_pushfstring(L, to_luastring(" (%s '%s')", true), kind.funcname, kind.name) : to_luastring("", true); }; const luaG_typeerror = function(L, o, op) { let t = ltm.luaT_objtypename(L, o); - luaG_runerror(L, defs.to_luastring("attempt to %s a %s value%s", true), op, t, varinfo(L, o)); + luaG_runerror(L, to_luastring("attempt to %s a %s value%s", true), op, t, varinfo(L, o)); }; const luaG_concaterror = function(L, p1, p2) { if (p1.ttisstring() || lvm.cvt2str(p1)) p1 = p2; - luaG_typeerror(L, p1, defs.to_luastring('concatenate', true)); + luaG_typeerror(L, p1, to_luastring('concatenate', true)); }; /* @@ -567,21 +583,21 @@ const luaG_opinterror = function(L, p1, p2, msg) { const luaG_ordererror = function(L, p1, p2) { let t1 = ltm.luaT_objtypename(L, p1); let t2 = ltm.luaT_objtypename(L, p2); - if (defs.luastring_cmp(t1, t2)) - luaG_runerror(L, defs.to_luastring("attempt to compare two %s values", true), t1); + if (luastring_eq(t1, t2)) + luaG_runerror(L, to_luastring("attempt to compare two %s values", true), t1); else - luaG_runerror(L, defs.to_luastring("attempt to compare %s with %s", true), t1, t2); + luaG_runerror(L, to_luastring("attempt to compare %s with %s", true), t1, t2); }; /* add src:line information to 'msg' */ const luaG_addinfo = function(L, msg, src, line) { let buff; if (src) - buff = lobject.luaO_chunkid(src.getstr(), luaconf.LUA_IDSIZE); + buff = lobject.luaO_chunkid(src.getstr(), LUA_IDSIZE); else - buff = defs.to_luastring("?", true); + buff = to_luastring("?", true); - return lobject.luaO_pushfstring(L, defs.to_luastring("%s:%d: %s", true), buff, line, msg); + return lobject.luaO_pushfstring(L, to_luastring("%s:%d: %s", true), buff, line, msg); }; const luaG_runerror = function(L, fmt, ...argp) { @@ -600,7 +616,7 @@ const luaG_errormsg = function(L) { ldo.luaD_callnoyield(L, L.top - 2, 1); } - ldo.luaD_throw(L, TS.LUA_ERRRUN); + ldo.luaD_throw(L, LUA_ERRRUN); }; /* @@ -610,41 +626,41 @@ const luaG_tointerror = function(L, p1, p2) { let temp = lvm.tointeger(p1); if (temp === false) p2 = p1; - luaG_runerror(L, defs.to_luastring("number%s has no integer representation", true), varinfo(L, p2)); + luaG_runerror(L, to_luastring("number%s has no integer representation", true), varinfo(L, p2)); }; const luaG_traceexec = function(L) { let ci = L.ci; let mask = L.hookmask; - let counthook = (--L.hookcount === 0 && (mask & defs.LUA_MASKCOUNT)); + let counthook = (--L.hookcount === 0 && (mask & LUA_MASKCOUNT)); if (counthook) L.hookcount = L.basehookcount; /* reset count */ - else if (!(mask & defs.LUA_MASKLINE)) + else if (!(mask & LUA_MASKLINE)) return; /* no line hook and count != 0; nothing to be done */ if (ci.callstatus & lstate.CIST_HOOKYIELD) { /* called hook last time? */ ci.callstatus &= ~lstate.CIST_HOOKYIELD; /* erase mark */ return; /* do not call hook again (VM yielded, so it did not move) */ } if (counthook) - ldo.luaD_hook(L, defs.LUA_HOOKCOUNT, -1); /* call count hook */ - if (mask & defs.LUA_MASKLINE) { + ldo.luaD_hook(L, LUA_HOOKCOUNT, -1); /* call count hook */ + if (mask & LUA_MASKLINE) { let p = ci.func.value.p; let npc = ci.l_savedpc - 1; // pcRel(ci.u.l.savedpc, p); let newline = p.lineinfo.length !== 0 ? p.lineinfo[npc] : -1; if (npc === 0 || /* call linehook when enter a new function, */ ci.l_savedpc <= L.oldpc || /* when jump back (loop), or when */ newline !== (p.lineinfo.length !== 0 ? p.lineinfo[L.oldpc - 1] : -1)) /* enter a new line */ - ldo.luaD_hook(L, defs.LUA_HOOKLINE, newline); /* call line hook */ + ldo.luaD_hook(L, LUA_HOOKLINE, newline); /* call line hook */ } L.oldpc = ci.l_savedpc; - if (L.status === TS.LUA_YIELD) { /* did hook yield? */ + if (L.status === LUA_YIELD) { /* did hook yield? */ if (counthook) L.hookcount = 1; /* undo decrement to zero */ ci.l_savedpc--; /* undo increment (resume will increment it again) */ ci.callstatus |= lstate.CIST_HOOKYIELD; /* mark that it yielded */ ci.funcOff = L.top - 1; /* protect stack below results */ ci.func = L.stack[ci.funcOff]; - ldo.luaD_throw(L, TS.LUA_YIELD); + ldo.luaD_throw(L, LUA_YIELD); } }; @@ -1,30 +1,56 @@ "use strict"; -const assert = require('assert'); - -const defs = require('./defs.js'); +const { + LUA_HOOKCALL, + LUA_HOOKRET, + LUA_HOOKTAILCALL, + LUA_MASKCALL, + LUA_MASKLINE, + LUA_MASKRET, + LUA_MINSTACK, + LUA_MULTRET, + LUA_SIGNATURE, + constant_types: { + LUA_TCCL, + LUA_TLCF, + LUA_TLCL, + LUA_TNIL + }, + thread_status: { + LUA_ERRMEM, + LUA_ERRERR, + LUA_ERRRUN, + LUA_ERRSYNTAX, + LUA_OK, + LUA_YIELD + }, + lua_Debug, + luastring_indexOf, + to_luastring +} = require('./defs.js'); const lapi = require('./lapi.js'); const ldebug = require('./ldebug.js'); const lfunc = require('./lfunc.js'); -const llimits = require('./llimits.js'); +const { + api_check, + lua_assert, + LUAI_MAXCCALLS +} = require('./llimits.js'); const lobject = require('./lobject.js'); const lopcodes = require('./lopcodes.js'); const lparser = require('./lparser.js'); const lstate = require('./lstate.js'); -const lstring = require('./lstring.js'); +const { luaS_newliteral } = require('./lstring.js'); const ltm = require('./ltm.js'); -const luaconf = require('./luaconf.js'); +const { LUAI_MAXSTACK } = require('./luaconf.js'); const lundump = require('./lundump.js'); const lvm = require('./lvm.js'); -const lzio = require('./lzio.js'); - -const CT = defs.constant_types; -const TS = defs.thread_status; +const { MBuffer } = require('./lzio.js'); const adjust_top = function(L, newtop) { if (L.top < newtop) { while (L.top < newtop) - L.stack[L.top++] = new lobject.TValue(CT.LUA_TNIL, null); + L.stack[L.top++] = new lobject.TValue(LUA_TNIL, null); } else { while (L.top > newtop) delete L.stack[--L.top]; @@ -36,15 +62,15 @@ const seterrorobj = function(L, errcode, oldtop) { /* extend stack so that L.stack[oldtop] is sure to exist */ while (L.top < oldtop + 1) - L.stack[L.top++] = new lobject.TValue(CT.LUA_TNIL, null); + L.stack[L.top++] = new lobject.TValue(LUA_TNIL, null); switch (errcode) { - case TS.LUA_ERRMEM: { - lobject.setsvalue2s(L, oldtop, lstring.luaS_newliteral(L, "not enough memory")); + case LUA_ERRMEM: { + lobject.setsvalue2s(L, oldtop, luaS_newliteral(L, "not enough memory")); break; } - case TS.LUA_ERRERR: { - lobject.setsvalue2s(L, oldtop, lstring.luaS_newliteral(L, "error in error handling")); + case LUA_ERRERR: { + lobject.setsvalue2s(L, oldtop, luaS_newliteral(L, "error in error handling")); break; } default: { @@ -56,27 +82,27 @@ const seterrorobj = function(L, errcode, oldtop) { delete L.stack[--L.top]; }; -const ERRORSTACKSIZE = luaconf.LUAI_MAXSTACK + 200; +const ERRORSTACKSIZE = LUAI_MAXSTACK + 200; const luaD_reallocstack = function(L, newsize) { - assert(newsize <= luaconf.LUAI_MAXSTACK || newsize == ERRORSTACKSIZE); - assert(L.stack_last == L.stack.length - lstate.EXTRA_STACK); + lua_assert(newsize <= LUAI_MAXSTACK || newsize == ERRORSTACKSIZE); + lua_assert(L.stack_last == L.stack.length - lstate.EXTRA_STACK); L.stack.length = newsize; L.stack_last = newsize - lstate.EXTRA_STACK; }; const luaD_growstack = function(L, n) { let size = L.stack.length; - if (size > luaconf.LUAI_MAXSTACK) - luaD_throw(L, TS.LUA_ERRERR); + if (size > LUAI_MAXSTACK) + luaD_throw(L, LUA_ERRERR); else { let needed = L.top + n + lstate.EXTRA_STACK; let newsize = 2 * size; - if (newsize > luaconf.LUAI_MAXSTACK) newsize = luaconf.LUAI_MAXSTACK; + if (newsize > LUAI_MAXSTACK) newsize = LUAI_MAXSTACK; if (newsize < needed) newsize = needed; - if (newsize > luaconf.LUAI_MAXSTACK) { /* stack overflow? */ + if (newsize > LUAI_MAXSTACK) { /* stack overflow? */ luaD_reallocstack(L, ERRORSTACKSIZE); - ldebug.luaG_runerror(L, defs.to_luastring("stack overflow", true)); + ldebug.luaG_runerror(L, to_luastring("stack overflow", true)); } else luaD_reallocstack(L, newsize); @@ -93,26 +119,26 @@ const stackinuse = function(L) { for (let ci = L.ci; ci !== null; ci = ci.previous) { if (lim < ci.top) lim = ci.top; } - assert(lim <= L.stack_last); + lua_assert(lim <= L.stack_last); return lim + 1; /* part of stack in use */ }; const luaD_shrinkstack = function(L) { let inuse = stackinuse(L); let goodsize = inuse + Math.floor(inuse / 8) + 2*lstate.EXTRA_STACK; - if (goodsize > luaconf.LUAI_MAXSTACK) - goodsize = luaconf.LUAI_MAXSTACK; /* respect stack limit */ - if (L.stack.length > luaconf.LUAI_MAXSTACK) /* had been handling stack overflow? */ + if (goodsize > LUAI_MAXSTACK) + goodsize = LUAI_MAXSTACK; /* respect stack limit */ + if (L.stack.length > LUAI_MAXSTACK) /* had been handling stack overflow? */ lstate.luaE_freeCI(L); /* free all CIs (list grew because of an error) */ /* if thread is currently not handling a stack overflow and its good size is smaller than current size, shrink its stack */ - if (inuse <= (luaconf.LUAI_MAXSTACK - lstate.EXTRA_STACK) && goodsize < L.stack.length) + if (inuse <= (LUAI_MAXSTACK - lstate.EXTRA_STACK) && goodsize < L.stack.length) luaD_reallocstack(L, goodsize); }; const luaD_inctop = function(L) { luaD_checkstack(L, 1); - L.stack[L.top++] = new lobject.TValue(CT.LUA_TNIL, null); + L.stack[L.top++] = new lobject.TValue(LUA_TNIL, null); }; /* @@ -126,30 +152,30 @@ const luaD_precall = function(L, off, nresults) { let func = L.stack[off]; switch(func.type) { - case CT.LUA_TCCL: - case CT.LUA_TLCF: { - let f = func.type === CT.LUA_TCCL ? func.value.f : func.value; + case LUA_TCCL: + case LUA_TLCF: { + let f = func.type === LUA_TCCL ? func.value.f : func.value; - luaD_checkstack(L, defs.LUA_MINSTACK); + luaD_checkstack(L, LUA_MINSTACK); let ci = lstate.luaE_extendCI(L); ci.funcOff = off; ci.nresults = nresults; ci.func = func; - ci.top = L.top + defs.LUA_MINSTACK; - assert(ci.top <= L.stack_last); + ci.top = L.top + LUA_MINSTACK; + lua_assert(ci.top <= L.stack_last); ci.callstatus = 0; - if (L.hookmask & defs.LUA_MASKCALL) - luaD_hook(L, defs.LUA_HOOKCALL, -1); + if (L.hookmask & LUA_MASKCALL) + luaD_hook(L, LUA_HOOKCALL, -1); let n = f(L); /* do the actual call */ - - assert(typeof n == "number" && n >= 0 && (n|0) === n, "invalid return value from JS function (expected integer)"); - assert(n < L.top - L.ci.funcOff, "not enough elements in the stack"); + if (typeof n !== "number" || n < 0 || (n|0) !== n) + throw Error("invalid return value from JS function (expected integer)"); + lapi.api_checknelems(L, n); luaD_poscall(L, ci, L.top - n, n); return true; } - case CT.LUA_TLCL: { + case LUA_TLCL: { let base; let p = func.value.p; let n = L.top - off - 1; @@ -159,7 +185,7 @@ const luaD_precall = function(L, off, nresults) { base = adjust_varargs(L, p, n); } else { for (; n < p.numparams; n++) - L.stack[L.top++] = new lobject.TValue(CT.LUA_TNIL, null); // complete missing arguments + L.stack[L.top++] = new lobject.TValue(LUA_TNIL, null); // complete missing arguments base = off + 1; } @@ -173,7 +199,7 @@ const luaD_precall = function(L, off, nresults) { ci.l_code = p.code; ci.l_savedpc = 0; ci.callstatus = lstate.CIST_LUA; - if (L.hookmask & defs.LUA_MASKCALL) + if (L.hookmask & LUA_MASKCALL) callhook(L, ci); return false; } @@ -187,9 +213,9 @@ const luaD_precall = function(L, off, nresults) { const luaD_poscall = function(L, ci, firstResult, nres) { let wanted = ci.nresults; - if (L.hookmask & (defs.LUA_MASKRET | defs.LUA_MASKLINE)) { - if (L.hookmask & defs.LUA_MASKRET) - luaD_hook(L, defs.LUA_HOOKRET, -1); + if (L.hookmask & (LUA_MASKRET | LUA_MASKLINE)) { + if (L.hookmask & LUA_MASKRET) + luaD_hook(L, LUA_HOOKRET, -1); L.oldpc = ci.previous.l_savedpc; /* 'oldpc' for caller function */ } @@ -211,7 +237,7 @@ const moveresults = function(L, firstResult, res, nres, wanted) { } break; } - case defs.LUA_MULTRET: { + case LUA_MULTRET: { for (let i = 0; i < nres; i++) lobject.setobjs2s(L, res + i, firstResult + i); for (let i=L.top; i>=(res + nres); i--) @@ -229,7 +255,7 @@ const moveresults = function(L, firstResult, res, nres, wanted) { lobject.setobjs2s(L, res + i, firstResult + i); for (; i < wanted; i++) { if (res+i >= L.top) - L.stack[res + i] = new lobject.TValue(CT.LUAT_NIL, null); + L.stack[res + i] = new lobject.TValue(LUA_TNIL, null); else L.stack[res + i].setnilvalue(); } @@ -255,17 +281,17 @@ const luaD_hook = function(L, event, line) { let ci = L.ci; let top = L.top; let ci_top = ci.top; - let ar = new defs.lua_Debug(); + let ar = new lua_Debug(); ar.event = event; ar.currentline = line; ar.i_ci = ci; - luaD_checkstack(L, defs.LUA_MINSTACK); /* ensure minimum stack size */ - ci.top = L.top + defs.LUA_MINSTACK; - assert(ci.top <= L.stack_last); + luaD_checkstack(L, LUA_MINSTACK); /* ensure minimum stack size */ + ci.top = L.top + LUA_MINSTACK; + lua_assert(ci.top <= L.stack_last); L.allowhook = 0; /* cannot call hooks inside a hook */ ci.callstatus |= lstate.CIST_HOOKED; hook(L, ar); - assert(!L.allowhook); + lua_assert(!L.allowhook); L.allowhook = 1; ci.top = ci_top; adjust_top(L, top); @@ -274,12 +300,12 @@ const luaD_hook = function(L, event, line) { }; const callhook = function(L, ci) { - let hook = defs.LUA_HOOKCALL; + let hook = LUA_HOOKCALL; ci.l_savedpc++; /* hooks assume 'pc' is already incremented */ if ((ci.previous.callstatus & lstate.CIST_LUA) && ci.previous.l_code[ci.previous.l_savedpc - 1].opcode == lopcodes.OpCodesI.OP_TAILCALL) { ci.callstatus |= lstate.CIST_TAIL; - hook = defs.LUA_HOOKTAILCALL; + hook = LUA_HOOKTAILCALL; } luaD_hook(L, hook, -1); ci.l_savedpc--; /* correct 'pc' */ @@ -298,7 +324,7 @@ const adjust_varargs = function(L, p, actual) { } for (; i < nfixargs; i++) - L.stack[L.top++] = new lobject.TValue(CT.LUA_TNIL, null); + L.stack[L.top++] = new lobject.TValue(LUA_TNIL, null); return base; }; @@ -306,7 +332,7 @@ const adjust_varargs = function(L, p, actual) { const tryfuncTM = function(L, off, func) { let tm = ltm.luaT_gettmbyobj(L, func, ltm.TMS.TM_CALL); if (!tm.ttisfunction(tm)) - ldebug.luaG_typeerror(L, func, defs.to_luastring("call", true)); + ldebug.luaG_typeerror(L, func, to_luastring("call", true)); /* Open a hole inside the stack at 'func' */ lobject.pushobj2s(L, L.stack[L.top-1]); /* push top of stack again */ for (let p = L.top-2; p > off; p--) @@ -322,10 +348,10 @@ const tryfuncTM = function(L, off, func) { ** allow overflow handling to work) */ const stackerror = function(L) { - if (L.nCcalls === llimits.LUAI_MAXCCALLS) - ldebug.luaG_runerror(L, defs.to_luastring("JS stack overflow", true)); - else if (L.nCcalls >= llimits.LUAI_MAXCCALLS + (llimits.LUAI_MAXCCALLS >> 3)) - luaD_throw(L, TS.LUA_ERRERR); /* error while handing stack error */ + if (L.nCcalls === LUAI_MAXCCALLS) + ldebug.luaG_runerror(L, to_luastring("JS stack overflow", true)); + else if (L.nCcalls >= LUAI_MAXCCALLS + (LUAI_MAXCCALLS >> 3)) + luaD_throw(L, LUA_ERRERR); /* error while handing stack error */ }; /* @@ -335,7 +361,7 @@ const stackerror = function(L) { ** function position. */ const luaD_call = function(L, off, nResults) { - if (++L.nCcalls >= llimits.LUAI_MAXCCALLS) + if (++L.nCcalls >= LUAI_MAXCCALLS) stackerror(L); if (!luaD_precall(L, off, nResults)) lvm.luaV_execute(L); @@ -368,7 +394,7 @@ const luaD_throw = function(L, errcode) { const luaD_rawrunprotected = function(L, f, ud) { let oldnCcalls = L.nCcalls; let lj = { // TODO: necessary when using try/catch ? (ldo.c:47-52) - status: TS.LUA_OK, + status: LUA_OK, previous: L.errorJmp /* chain new error handler */ }; L.errorJmp = lj; @@ -376,13 +402,13 @@ const luaD_rawrunprotected = function(L, f, ud) { try { f(L, ud); } catch (e) { - if (lj.status === TS.LUA_OK) { + if (lj.status === LUA_OK) { /* error was not thrown via luaD_throw, i.e. it is a JS error */ /* run user error handler (if it exists) */ let atnativeerror = L.l_G.atnativeerror; if (atnativeerror) { try { - lj.status = TS.LUA_OK; + lj.status = LUA_OK; lapi.lua_pushcfunction(L, atnativeerror); lapi.lua_pushlightuserdata(L, e); @@ -397,9 +423,9 @@ const luaD_rawrunprotected = function(L, f, ud) { luaD_callnoyield(L, L.top - 2, 1); } - lj.status = TS.LUA_ERRRUN; + lj.status = LUA_ERRRUN; } catch(e2) { - if (lj.status === TS.LUA_OK) { + if (lj.status === LUA_OK) { /* also failed */ lj.status = -1; } @@ -425,21 +451,21 @@ const finishCcall = function(L, status) { let ci = L.ci; /* must have a continuation and must be able to call it */ - assert(ci.c_k !== null && L.nny === 0); + lua_assert(ci.c_k !== null && L.nny === 0); /* error status can only happen in a protected call */ - assert(ci.callstatus & lstate.CIST_YPCALL || status === TS.LUA_YIELD); + lua_assert(ci.callstatus & lstate.CIST_YPCALL || status === LUA_YIELD); - if (ci.callstatus & TS.CIST_YPCALL) { /* was inside a pcall? */ - ci.callstatus &= ~TS.CIST_YPCALL; /* continuation is also inside it */ + if (ci.callstatus & lstate.CIST_YPCALL) { /* was inside a pcall? */ + ci.callstatus &= ~lstate.CIST_YPCALL; /* continuation is also inside it */ L.errfunc = ci.c_old_errfunc; /* with the same error function */ } /* finish 'lua_callk'/'lua_pcall'; CIST_YPCALL and 'errfunc' already handled */ - if (ci.nresults === defs.LUA_MULTRET && L.ci.top < L.top) L.ci.top = L.top; + if (ci.nresults === LUA_MULTRET && L.ci.top < L.top) L.ci.top = L.top; let c_k = ci.c_k; /* don't want to call as method */ let n = c_k(L, status, ci.c_ctx); /* call continuation function */ - assert(n < (L.top - L.ci.funcOff), "not enough elements in the stack"); + lapi.api_checknelems(L, n); luaD_poscall(L, ci, L.top - n, n); /* finish 'luaD_precall' */ }; @@ -457,7 +483,7 @@ const unroll = function(L, ud) { while (L.ci !== L.base_ci) { /* something in the stack */ if (!(L.ci.callstatus & lstate.CIST_LUA)) /* C function? */ - finishCcall(L, TS.LUA_YIELD); /* complete its execution */ + finishCcall(L, LUA_YIELD); /* complete its execution */ else { /* Lua function */ lvm.luaV_finishOp(L); /* finish interrupted instruction */ lvm.luaV_execute(L); /* execute down to higher C 'boundary' */ @@ -504,17 +530,17 @@ const recover = function(L, status) { ** coroutine error handler and should not kill the coroutine.) */ const resume_error = function(L, msg, narg) { - let ts = lstring.luaS_newliteral(L, msg); + let ts = luaS_newliteral(L, msg); if (narg === 0) { lobject.pushsvalue2s(L, ts); - assert(L.top <= L.ci.top, "stack overflow"); + api_check(L, L.top <= L.ci.top, "stack overflow"); } else { /* remove args from the stack */ for (let i=1; i<narg; i++) delete L.stack[--L.top]; lobject.setsvalue2s(L, L.top-1, ts); /* push error message */ } - return TS.LUA_ERRRUN; + return LUA_ERRRUN; }; /* @@ -527,12 +553,12 @@ const resume_error = function(L, msg, narg) { const resume = function(L, n) { let firstArg = L.top - n; /* first argument */ let ci = L.ci; - if (L.status === TS.LUA_OK) { /* starting a coroutine? */ - if (!luaD_precall(L, firstArg - 1, defs.LUA_MULTRET)) /* Lua function? */ + if (L.status === LUA_OK) { /* starting a coroutine? */ + if (!luaD_precall(L, firstArg - 1, LUA_MULTRET)) /* Lua function? */ lvm.luaV_execute(L); /* call it */ } else { /* resuming from previous yield */ - assert(L.status === TS.LUA_YIELD); - L.status = TS.LUA_OK; /* mark that it is running (again) */ + lua_assert(L.status === LUA_YIELD); + L.status = LUA_OK; /* mark that it is running (again) */ ci.funcOff = ci.extra; ci.func = L.stack[ci.funcOff]; @@ -540,8 +566,8 @@ const resume = function(L, n) { lvm.luaV_execute(L); /* just continue running Lua code */ else { /* 'common' yield */ if (ci.c_k !== null) { /* does it have a continuation function? */ - n = ci.c_k(L, TS.LUA_YIELD, ci.c_ctx); /* call continuation */ - assert(n < (L.top - L.ci.funcOff), "not enough elements in the stack"); + n = ci.c_k(L, LUA_YIELD, ci.c_ctx); /* call continuation */ + lapi.api_checknelems(L, n); firstArg = L.top - n; /* yield results come from continuation */ } @@ -555,41 +581,40 @@ const resume = function(L, n) { const lua_resume = function(L, from, nargs) { let oldnny = L.nny; /* save "number of non-yieldable" calls */ - if (L.status === TS.LUA_OK) { /* may be starting a coroutine */ + if (L.status === LUA_OK) { /* may be starting a coroutine */ if (L.ci !== L.base_ci) /* not in base level? */ return resume_error(L, "cannot resume non-suspended coroutine", nargs); - } else if (L.status !== TS.LUA_YIELD) + } else if (L.status !== LUA_YIELD) return resume_error(L, "cannot resume dead coroutine", nargs); L.nCcalls = from ? from.nCcalls + 1 : 1; - if (L.nCcalls >= llimits.LUAI_MAXCCALLS) + if (L.nCcalls >= LUAI_MAXCCALLS) return resume_error(L, "JS stack overflow", nargs); L.nny = 0; /* allow yields */ - assert((L.status === TS.LUA_OK ? nargs + 1: nargs) < (L.top - L.ci.funcOff), - "not enough elements in the stack"); + lapi.api_checknelems(L, L.status === LUA_OK ? nargs + 1: nargs); let status = luaD_rawrunprotected(L, resume, nargs); if (status === -1) /* error calling 'lua_resume'? */ - status = TS.LUA_ERRRUN; + status = LUA_ERRRUN; else { /* continue running after recoverable errors */ - while (status > TS.LUA_YIELD && recover(L, status)) { + while (status > LUA_YIELD && recover(L, status)) { /* unroll continuation */ status = luaD_rawrunprotected(L, unroll, status); } - if (status > TS.LUA_YIELD) { /* unrecoverable error? */ + if (status > LUA_YIELD) { /* unrecoverable error? */ L.status = status; /* mark thread as 'dead' */ seterrorobj(L, status, L.top); /* push error message */ L.ci.top = L.top; } else - assert(status === L.status); /* normal end or yield */ + lua_assert(status === L.status); /* normal end or yield */ } L.nny = oldnny; /* restore 'nny' */ L.nCcalls--; - assert(L.nCcalls === (from ? from.nCcalls : 0)); + lua_assert(L.nCcalls === (from ? from.nCcalls : 0)); return status; }; @@ -599,29 +624,29 @@ const lua_isyieldable = function(L) { const lua_yieldk = function(L, nresults, ctx, k) { let ci = L.ci; - assert(nresults < (L.top - L.ci.funcOff), "not enough elements in the stack"); + lapi.api_checknelems(L, nresults); if (L.nny > 0) { if (L !== L.l_G.mainthread) - ldebug.luaG_runerror(L, defs.to_luastring("attempt to yield across a JS-call boundary", true)); + ldebug.luaG_runerror(L, to_luastring("attempt to yield across a JS-call boundary", true)); else - ldebug.luaG_runerror(L, defs.to_luastring("attempt to yield from outside a coroutine", true)); + ldebug.luaG_runerror(L, to_luastring("attempt to yield from outside a coroutine", true)); } - L.status = TS.LUA_YIELD; + L.status = LUA_YIELD; ci.extra = ci.funcOff; /* save current 'func' */ if (ci.callstatus & lstate.CIST_LUA) /* inside a hook? */ - assert(k === null, "hooks cannot continue after yielding"); + api_check(L, k === null, "hooks cannot continue after yielding"); else { ci.c_k = k; if (k !== null) /* is there a continuation? */ ci.c_ctx = ctx; /* save context */ ci.funcOff = L.top - nresults - 1; /* protect stack below results */ ci.func = L.stack[ci.funcOff]; - luaD_throw(L, TS.LUA_YIELD); + luaD_throw(L, LUA_YIELD); } - assert(ci.callstatus & lstate.CIST_HOOKED); /* must be inside a hook */ + lua_assert(ci.callstatus & lstate.CIST_HOOKED); /* must be inside a hook */ return 0; /* return to 'luaD_hook' */ }; @@ -638,7 +663,7 @@ const luaD_pcall = function(L, func, u, old_top, ef) { let status = luaD_rawrunprotected(L, func, u); - if (status !== TS.LUA_OK) { + if (status !== LUA_OK) { lfunc.luaF_close(L, old_top); seterrorobj(L, status, old_top); L.ci = old_ci; @@ -667,7 +692,7 @@ const luaD_callnoyield = function(L, off, nResults) { class SParser { constructor(z, name, mode) { /* data to 'f_parser' */ this.z = z; - this.buff = new lzio.MBuffer(); /* dynamic structure used by the scanner */ + this.buff = new MBuffer(); /* dynamic structure used by the scanner */ this.dyd = new lparser.Dyndata(); /* dynamic structures used by the parser */ this.mode = mode; this.name = name; @@ -675,25 +700,25 @@ class SParser { } const checkmode = function(L, mode, x) { - if (mode && mode.indexOf(x[0]) === -1) { + if (mode && luastring_indexOf(mode, x[0]) === -1) { lobject.luaO_pushfstring(L, - defs.to_luastring("attempt to load a %s chunk (mode is '%s')"), x, mode); - luaD_throw(L, TS.LUA_ERRSYNTAX); + to_luastring("attempt to load a %s chunk (mode is '%s')"), x, mode); + luaD_throw(L, LUA_ERRSYNTAX); } }; const f_parser = function(L, p) { let cl; let c = p.z.zgetc(); /* read first character */ - if (c === defs.LUA_SIGNATURE.charCodeAt(0)) { - checkmode(L, p.mode, defs.to_luastring("binary", true)); + if (c === LUA_SIGNATURE[0]) { + checkmode(L, p.mode, to_luastring("binary", true)); cl = lundump.luaU_undump(L, p.z, p.name); } else { - checkmode(L, p.mode, defs.to_luastring("text", true)); + checkmode(L, p.mode, to_luastring("text", true)); cl = lparser.luaY_parser(L, p.z, p.buff, p.dyd, p.name, c); } - assert(cl.nupvalues === cl.p.upvalues.length); + lua_assert(cl.nupvalues === cl.p.upvalues.length); lfunc.luaF_initupvals(L, cl); }; diff --git a/src/ldump.js b/src/ldump.js index 7e62da3..596a319 100644 --- a/src/ldump.js +++ b/src/ldump.js @@ -1,12 +1,24 @@ "use strict"; -const defs = require('./defs.js'); -const CT = defs.constant_types; - -const LUAC_DATA = defs.string_of(25, 147, 13, 10, 26, 10); +const { + LUA_SIGNATURE, + LUA_VERSION_MAJOR, + LUA_VERSION_MINOR, + constant_types: { + LUA_TBOOLEAN, + LUA_TLNGSTR, + LUA_TNIL, + LUA_TNUMFLT, + LUA_TNUMINT, + LUA_TSHRSTR + }, + luastring_of +} = require('./defs.js'); + +const LUAC_DATA = luastring_of(25, 147, 13, 10, 26, 10); const LUAC_INT = 0x5678; const LUAC_NUM = 370.5; -const LUAC_VERSION = Number.parseInt(defs.LUA_VERSION_MAJOR) * 16 + Number.parseInt(defs.LUA_VERSION_MINOR); +const LUAC_VERSION = Number(LUA_VERSION_MAJOR) * 16 + Number(LUA_VERSION_MINOR); const LUAC_FORMAT = 0; /* this is the official format */ class DumpState { @@ -24,13 +36,8 @@ const DumpBlock = function(b, size, D) { D.status = D.writer(D.L, b, size, D.data); }; -const DumpLiteral = function(s, D) { - s = defs.to_luastring(s); - DumpBlock(s, s.length, D); -}; - const DumpByte = function(y, D) { - DumpBlock(defs.string_of(y), 1, D); + DumpBlock(luastring_of(y), 1, D); }; const DumpInt = function(x, D) { @@ -88,19 +95,19 @@ const DumpConstants = function(f, D) { let o = f.k[i]; DumpByte(o.ttype(), D); switch (o.ttype()) { - case CT.LUA_TNIL: + case LUA_TNIL: break; - case CT.LUA_TBOOLEAN: + case LUA_TBOOLEAN: DumpByte(o.value ? 1 : 0, D); break; - case CT.LUA_TNUMFLT: + case LUA_TNUMFLT: DumpNumber(o.value, D); break; - case CT.LUA_TNUMINT: + case LUA_TNUMINT: DumpInteger(o.value, D); break; - case CT.LUA_TSHRSTR: - case CT.LUA_TLNGSTR: + case LUA_TSHRSTR: + case LUA_TLNGSTR: DumpString(o.tsvalue(), D); break; } @@ -159,7 +166,7 @@ const DumpFunction = function(f, psource, D) { }; const DumpHeader = function(D) { - DumpLiteral(defs.LUA_SIGNATURE, D); + DumpBlock(LUA_SIGNATURE, LUA_SIGNATURE.length, D); DumpByte(LUAC_VERSION, D); DumpByte(LUAC_FORMAT, D); DumpBlock(LUAC_DATA, LUAC_DATA.length, D); diff --git a/src/lfunc.js b/src/lfunc.js index b07b803..9290f4b 100644 --- a/src/lfunc.js +++ b/src/lfunc.js @@ -1,13 +1,9 @@ "use strict"; -const assert = require('assert'); - -const defs = require('./defs.js'); +const { constant_types: { LUA_TNIL } } = require('./defs.js'); const lobject = require('./lobject.js'); -const CT = defs.constant_types; class Proto { - constructor(L) { this.id = L.l_G.id_counter++; this.k = []; // constants used by the function @@ -24,81 +20,32 @@ class Proto { this.lastlinedefined = 0; // debug information this.source = null; // used for debug information } - -} - -class UpVal { - - constructor(L) { - this.id = L.l_G.id_counter++; - this.v = void 0; /* if open: reference to TValue on stack. if closed: TValue */ - this.vOff = void 0; /* if open: index on stack. if closed: undefined */ - this.refcount = 0; - this.open_next = null; /* linked list (when open) */ - } - - isopen() { - return this.vOff !== void 0; - } - } const luaF_newLclosure = function(L, n) { - let c = new lobject.LClosure(L, n); - return c; + return new lobject.LClosure(L, n); }; const luaF_findupval = function(L, level) { - let prevp; - let p = L.openupval; - while (p !== null && p.vOff >= level) { - assert(p.isopen()); - if (p.vOff === level) /* found a corresponding upvalue? */ - return p; /* return it */ - prevp = p; - p = p.open_next; - } - /* not found: create a new upvalue */ - let uv = new UpVal(L); - /* link it to list of open upvalues */ - uv.open_next = p; - if (prevp) - prevp.open_next = uv; - else - L.openupval = uv; - uv.v = L.stack[level]; /* current value lives in the stack */ - uv.vOff = level; - return uv; + return L.stack[level]; }; const luaF_close = function(L, level) { - while (L.openupval !== null && L.openupval.vOff >= level) { - let uv = L.openupval; - assert(uv.isopen()); - L.openupval = uv.open_next; /* remove from 'open' list */ - if (uv.refcount === 0) { /* no references? */ - /* free upvalue */ - uv.v = void 0; - uv.open_next = null; - } else { - let from = uv.v; - uv.v = new lobject.TValue(from.type, from.value); - } - uv.vOff = void 0; + /* Create new TValues on stack; + * any closures will keep referencing old TValues */ + for (let i=level; i<L.top; i++) { + let old = L.stack[i]; + L.stack[i] = new lobject.TValue(old.type, old.value); } }; /* -** fill a closure with new closed upvalues +** fill a closure with new upvalues */ const luaF_initupvals = function(L, cl) { - for (let i = 0; i < cl.nupvalues; i++) { - let uv = new UpVal(L); - uv.refcount = 1; - uv.v = new lobject.TValue(CT.LUA_TNIL, null); - cl.upvals[i] = uv; - } + for (let i = 0; i < cl.nupvalues; i++) + cl.upvals[i] = new lobject.TValue(LUA_TNIL, null); }; /* @@ -116,10 +63,8 @@ const luaF_getlocalname = function(f, local_number, pc) { return null; /* not found */ }; - module.exports.MAXUPVAL = 255; module.exports.Proto = Proto; -module.exports.UpVal = UpVal; module.exports.luaF_findupval = luaF_findupval; module.exports.luaF_close = luaF_close; module.exports.luaF_getlocalname = luaF_getlocalname; diff --git a/src/linit.js b/src/linit.js index 97cbfc9..a265045 100644 --- a/src/linit.js +++ b/src/linit.js @@ -1,38 +1,40 @@ "use strict"; -const lua = require('./lua.js'); -const lauxlib = require('./lauxlib.js'); -const lbaselib = require('./lbaselib.js'); -const lcorolib = require('./lcorolib.js'); -const lmathlib = require('./lmathlib.js'); -const lstrlib = require('./lstrlib.js'); -const ltablib = require('./ltablib.js'); -const lutf8lib = require('./lutf8lib.js'); -const ldblib = require('./ldblib.js'); -const loslib = require('./loslib.js'); -const loadlib = require('./loadlib.js'); -const lualib = require('./lualib.js'); +const { lua_pop } = require('./lua.js'); +const { luaL_requiref } = require('./lauxlib.js'); +const { to_luastring } = require("./fengaricore.js"); -const luaL_openlibs = function(L) { - const loadedlibs = { - [lualib.LUA_LOADLIBNAME]: loadlib.luaopen_package, - [lualib.LUA_COLIBNAME]: lcorolib.luaopen_coroutine, - [lualib.LUA_DBLIBNAME]: ldblib.luaopen_debug, - [lualib.LUA_MATHLIBNAME]: lmathlib.luaopen_math, - [lualib.LUA_OSLIBNAME]: loslib.luaopen_os, - [lualib.LUA_STRLIBNAME]: lstrlib.luaopen_string, - [lualib.LUA_TABLIBNAME]: ltablib.luaopen_table, - [lualib.LUA_UTF8LIBNAME]: lutf8lib.luaopen_utf8, - "_G": lbaselib.luaopen_base - }; - - if (typeof process !== "undefined") loadedlibs[lualib.LUA_IOLIBNAME] = require('./liolib.js').luaopen_io; +const loadedlibs = {}; +/* export before requiring lualib.js */ +const luaL_openlibs = function(L) { /* "require" functions from 'loadedlibs' and set results to global table */ for (let lib in loadedlibs) { - lauxlib.luaL_requiref(L, lua.to_luastring(lib), loadedlibs[lib], 1); - lua.lua_pop(L, 1); /* remove lib */ + luaL_requiref(L, to_luastring(lib), loadedlibs[lib], 1); + lua_pop(L, 1); /* remove lib */ } }; - module.exports.luaL_openlibs = luaL_openlibs; + +const lualib = require('./lualib.js'); +const { luaopen_base } = require('./lbaselib.js'); +const { luaopen_coroutine } = require('./lcorolib.js'); +const { luaopen_debug } = require('./ldblib.js'); +const { luaopen_math } = require('./lmathlib.js'); +const { luaopen_package } = require('./loadlib.js'); +const { luaopen_os } = require('./loslib.js'); +const { luaopen_string } = require('./lstrlib.js'); +const { luaopen_table } = require('./ltablib.js'); +const { luaopen_utf8 } = require('./lutf8lib.js'); + +loadedlibs["_G"] = luaopen_base, +loadedlibs[lualib.LUA_LOADLIBNAME] = luaopen_package; +loadedlibs[lualib.LUA_COLIBNAME] = luaopen_coroutine; +loadedlibs[lualib.LUA_TABLIBNAME] = luaopen_table; +loadedlibs[lualib.LUA_OSLIBNAME] = luaopen_os; +loadedlibs[lualib.LUA_STRLIBNAME] = luaopen_string; +loadedlibs[lualib.LUA_MATHLIBNAME] = luaopen_math; +loadedlibs[lualib.LUA_UTF8LIBNAME] = luaopen_utf8; +loadedlibs[lualib.LUA_DBLIBNAME] = luaopen_debug; +if (typeof process !== "undefined") + loadedlibs[lualib.LUA_IOLIBNAME] = require('./liolib.js').luaopen_io; diff --git a/src/liolib.js b/src/liolib.js index 3241011..bd78f87 100644 --- a/src/liolib.js +++ b/src/liolib.js @@ -1,18 +1,46 @@ "use strict"; -const assert = require('assert'); const fs = require('fs'); -const lua = require('./lua.js'); -const lauxlib = require('./lauxlib.js'); +const { + LUA_REGISTRYINDEX, + lua_getfield, + lua_gettop, + lua_isnone, + lua_isnoneornil, + lua_newuserdata, + lua_pop, + lua_pushliteral, + lua_pushnil, + lua_pushstring, + lua_pushvalue, + lua_setfield, + lua_tostring, + lua_touserdata +} = require('./lua.js'); +const { + LUA_FILEHANDLE, + luaL_checkany, + luaL_checklstring, + luaL_checkudata, + luaL_error, + luaL_fileresult, + luaL_newlib, + luaL_newmetatable, + luaL_setfuncs, + luaL_setmetatable, + luaL_testudata +} = require('./lauxlib.js'); +const lualib = require('./lualib.js'); +const { to_luastring } = require("./fengaricore.js"); const IO_PREFIX = "_IO_"; const IOPREF_LEN = IO_PREFIX.length; -const IO_INPUT = lua.to_luastring(IO_PREFIX + "input"); -const IO_OUTPUT = lua.to_luastring(IO_PREFIX + "output"); +const IO_INPUT = to_luastring(IO_PREFIX + "input"); +const IO_OUTPUT = to_luastring(IO_PREFIX + "output"); const tolstream = function(L) { - return lauxlib.luaL_checkudata(L, 1, lauxlib.LUA_FILEHANDLE); + return luaL_checkudata(L, 1, LUA_FILEHANDLE); }; const isclosed = function(p) { @@ -20,39 +48,39 @@ const isclosed = function(p) { }; const io_type = function(L) { - lauxlib.luaL_checkany(L, 1); - let p = lauxlib.luaL_testudata(L, 1, lauxlib.LUA_FILEHANDLE); + luaL_checkany(L, 1); + let p = luaL_testudata(L, 1, LUA_FILEHANDLE); if (p === null) - lua.lua_pushnil(L); /* not a file */ + lua_pushnil(L); /* not a file */ else if (isclosed(p)) - lua.lua_pushliteral(L, "closed file"); + lua_pushliteral(L, "closed file"); else - lua.lua_pushliteral(L, "file"); + lua_pushliteral(L, "file"); return 1; }; const f_tostring = function(L) { let p = tolstream(L); if (isclosed(p)) - lua.lua_pushliteral(L, "file (closed)"); + lua_pushliteral(L, "file (closed)"); else - lua.lua_pushstring(L, lua.to_luastring(`file (${p.f.toString()})`)); + lua_pushstring(L, to_luastring(`file (${p.f.toString()})`)); return 1; }; const tofile = function(L) { let p = tolstream(L); if (isclosed(p)) - lauxlib.luaL_error(L, lua.to_luastring("attempt to use a closed file")); - assert(p.f); + luaL_error(L, to_luastring("attempt to use a closed file")); + lualib.lua_assert(p.f); return p.f; }; const newprefile = function(L) { - let p = lua.lua_newuserdata(L); + let p = lua_newuserdata(L); p.f = null; p.closef = null; - lauxlib.luaL_setmetatable(L, lauxlib.LUA_FILEHANDLE); + luaL_setmetatable(L, LUA_FILEHANDLE); return p; }; @@ -64,33 +92,33 @@ const aux_close = function(L) { }; const io_close = function(L) { - if (lua.lua_isnone(L, 1)) /* no argument? */ - lua.lua_getfield(L, lua.LUA_REGISTRYINDEX, IO_OUTPUT); /* use standard output */ + if (lua_isnone(L, 1)) /* no argument? */ + lua_getfield(L, LUA_REGISTRYINDEX, IO_OUTPUT); /* use standard output */ tofile(L); /* make sure argument is an open stream */ return aux_close(L); }; const getiofile = function(L, findex) { - lua.lua_getfield(L, lua.LUA_REGISTRYINDEX, findex); - let p = lua.lua_touserdata(L, -1); + lua_getfield(L, LUA_REGISTRYINDEX, findex); + let p = lua_touserdata(L, -1); if (isclosed(p)) - lauxlib.luaL_error(L, lua.to_luastring("standard %s file is closed"), findex.slice(IOPREF_LEN)); + luaL_error(L, to_luastring("standard %s file is closed"), findex.subarray(IOPREF_LEN)); return p.f; }; const g_iofile = function(L, f, mode) { - if (!lua.lua_isnoneornil(L, 1)) { - let filename = lua.lua_tostring(L, 1); + if (!lua_isnoneornil(L, 1)) { + let filename = lua_tostring(L, 1); if (filename) - lauxlib.luaL_error(L, lua.to_luastring("opening files not yet implemented")); + luaL_error(L, to_luastring("opening files not yet implemented")); else { tofile(L); /* check that it's a valid file handle */ - lua.lua_pushvalue(L, 1); + lua_pushvalue(L, 1); } - lua.lua_setfield(L, lua.LUA_REGISTRYINDEX, f); + lua_setfield(L, LUA_REGISTRYINDEX, f); } /* return current value */ - lua.lua_getfield(L, lua.LUA_REGISTRYINDEX, f); + lua_getfield(L, LUA_REGISTRYINDEX, f); return 1; }; @@ -103,11 +131,11 @@ const io_output = function(L) { }; const g_write = function(L, f, arg) { - let nargs = lua.lua_gettop(L) - arg; + let nargs = lua_gettop(L) - arg; let status = true; let err; for (; nargs--; arg++) { - let s = lauxlib.luaL_checklstring(L, arg); + let s = luaL_checklstring(L, arg); try { status = status && (fs.writeSync(f.fd, Uint8Array.from(s)) === s.length); } catch (e) { @@ -116,7 +144,7 @@ const g_write = function(L, f, arg) { } } if (status) return 1; /* file handle already on stack top */ - else return lauxlib.luaL_fileresult(L, status, null, err); + else return luaL_fileresult(L, status, null, err); }; const io_write = function(L) { @@ -125,20 +153,20 @@ const io_write = function(L) { const f_write = function(L) { let f = tofile(L); - lua.lua_pushvalue(L, 1); /* push file at the stack top (to be returned) */ + lua_pushvalue(L, 1); /* push file at the stack top (to be returned) */ return g_write(L, f, 2); }; const io_flush = function (L) { /* stub, as node doesn't have synchronized buffered IO */ getiofile(L, IO_OUTPUT); - return lauxlib.luaL_fileresult(L, true, null, null); + return luaL_fileresult(L, true, null, null); }; const f_flush = function (L) { /* stub, as node doesn't have synchronized buffered IO */ tofile(L); - return lauxlib.luaL_fileresult(L, true, null, null); + return luaL_fileresult(L, true, null, null); }; const iolib = { @@ -158,18 +186,18 @@ const flib = { }; const createmeta = function(L) { - lauxlib.luaL_newmetatable(L, lauxlib.LUA_FILEHANDLE); /* create metatable for file handles */ - lua.lua_pushvalue(L, -1); /* push metatable */ - lua.lua_setfield(L, -2, lua.to_luastring("__index", true)); /* metatable.__index = metatable */ - lauxlib.luaL_setfuncs(L, flib, 0); /* add file methods to new metatable */ - lua.lua_pop(L, 1); /* pop new metatable */ + luaL_newmetatable(L, LUA_FILEHANDLE); /* create metatable for file handles */ + lua_pushvalue(L, -1); /* push metatable */ + lua_setfield(L, -2, to_luastring("__index", true)); /* metatable.__index = metatable */ + luaL_setfuncs(L, flib, 0); /* add file methods to new metatable */ + lua_pop(L, 1); /* pop new metatable */ }; const io_noclose = function(L) { let p = tolstream(L); p.closef = io_noclose; - lua.lua_pushnil(L); - lua.lua_pushliteral(L, "cannot close standard file"); + lua_pushnil(L); + lua_pushliteral(L, "cannot close standard file"); return 2; }; @@ -178,19 +206,19 @@ const createstdfile = function(L, f, k, fname) { p.f = f; p.closef = io_noclose; if (k !== null) { - lua.lua_pushvalue(L, -1); - lua.lua_setfield(L, lua.LUA_REGISTRYINDEX, k); /* add file to registry */ + lua_pushvalue(L, -1); + lua_setfield(L, LUA_REGISTRYINDEX, k); /* add file to registry */ } - lua.lua_setfield(L, -2, fname); /* add file to module */ + lua_setfield(L, -2, fname); /* add file to module */ }; const luaopen_io = function(L) { - lauxlib.luaL_newlib(L, iolib); + luaL_newlib(L, iolib); createmeta(L); /* create (and set) default files */ - createstdfile(L, process.stdin, IO_INPUT, lua.to_luastring("stdin")); - createstdfile(L, process.stdout, IO_OUTPUT, lua.to_luastring("stdout")); - createstdfile(L, process.stderr, null, lua.to_luastring("stderr")); + createstdfile(L, process.stdin, IO_INPUT, to_luastring("stdin")); + createstdfile(L, process.stdout, IO_OUTPUT, to_luastring("stdout")); + createstdfile(L, process.stderr, null, to_luastring("stderr")); return 1; }; diff --git a/src/llex.js b/src/llex.js index 438f288..360e3d7 100644 --- a/src/llex.js +++ b/src/llex.js @@ -1,67 +1,124 @@ "use strict"; -const assert = require('assert'); - -const defs = require('./defs.js'); +const { + constant_types: { LUA_TLNGSTR }, + thread_status: { LUA_ERRSYNTAX }, + to_luastring +} = require('./defs.js'); +const { + LUA_MINBUFFER, + MAX_INT, + lua_assert +} = require('./llimits.js'); const ldebug = require('./ldebug.js'); const ldo = require('./ldo.js'); -const ljstype = require('./ljstype.js'); +const { + lisdigit, + lislalnum, + lislalpha, + lisspace, + lisxdigit +} = require('./ljstype.js'); const lobject = require('./lobject.js'); -const lstring = require('./lstring.js'); +const { + luaS_bless, + luaS_hash, + luaS_hashlongstr, + luaS_new +} = require('./lstring.js'); const ltable = require('./ltable.js'); -const llimits = require('./llimits.js'); -const lzio = require('./lzio.js'); -const TS = defs.thread_status; -const char = defs.char; +const { + EOZ, + luaZ_buffer, + luaZ_buffremove, + luaZ_resetbuffer, + luaZ_resizebuffer +} = require('./lzio.js'); const FIRST_RESERVED = 257; -const LUA_ENV = defs.to_luastring("_ENV", true); +const LUA_ENV = to_luastring("_ENV", true); + +/* terminal symbols denoted by reserved words */ +const TK_AND = FIRST_RESERVED; +const TK_BREAK = FIRST_RESERVED + 1; +const TK_DO = FIRST_RESERVED + 2; +const TK_ELSE = FIRST_RESERVED + 3; +const TK_ELSEIF = FIRST_RESERVED + 4; +const TK_END = FIRST_RESERVED + 5; +const TK_FALSE = FIRST_RESERVED + 6; +const TK_FOR = FIRST_RESERVED + 7; +const TK_FUNCTION = FIRST_RESERVED + 8; +const TK_GOTO = FIRST_RESERVED + 9; +const TK_IF = FIRST_RESERVED + 10; +const TK_IN = FIRST_RESERVED + 11; +const TK_LOCAL = FIRST_RESERVED + 12; +const TK_NIL = FIRST_RESERVED + 13; +const TK_NOT = FIRST_RESERVED + 14; +const TK_OR = FIRST_RESERVED + 15; +const TK_REPEAT = FIRST_RESERVED + 16; +const TK_RETURN = FIRST_RESERVED + 17; +const TK_THEN = FIRST_RESERVED + 18; +const TK_TRUE = FIRST_RESERVED + 19; +const TK_UNTIL = FIRST_RESERVED + 20; +const TK_WHILE = FIRST_RESERVED + 21; +/* other terminal symbols */ +const TK_IDIV = FIRST_RESERVED + 22; +const TK_CONCAT = FIRST_RESERVED + 23; +const TK_DOTS = FIRST_RESERVED + 24; +const TK_EQ = FIRST_RESERVED + 25; +const TK_GE = FIRST_RESERVED + 26; +const TK_LE = FIRST_RESERVED + 27; +const TK_NE = FIRST_RESERVED + 28; +const TK_SHL = FIRST_RESERVED + 29; +const TK_SHR = FIRST_RESERVED + 30; +const TK_DBCOLON = FIRST_RESERVED + 31; +const TK_EOS = FIRST_RESERVED + 32; +const TK_FLT = FIRST_RESERVED + 33; +const TK_INT = FIRST_RESERVED + 34; +const TK_NAME = FIRST_RESERVED + 35; +const TK_STRING = FIRST_RESERVED + 36; const RESERVED = { - /* terminal symbols denoted by reserved words */ - TK_AND: FIRST_RESERVED, - TK_BREAK: FIRST_RESERVED + 1, - TK_DO: FIRST_RESERVED + 2, - TK_ELSE: FIRST_RESERVED + 3, - TK_ELSEIF: FIRST_RESERVED + 4, - TK_END: FIRST_RESERVED + 5, - TK_FALSE: FIRST_RESERVED + 6, - TK_FOR: FIRST_RESERVED + 7, - TK_FUNCTION: FIRST_RESERVED + 8, - TK_GOTO: FIRST_RESERVED + 9, - TK_IF: FIRST_RESERVED + 10, - TK_IN: FIRST_RESERVED + 11, - TK_LOCAL: FIRST_RESERVED + 12, - TK_NIL: FIRST_RESERVED + 13, - TK_NOT: FIRST_RESERVED + 14, - TK_OR: FIRST_RESERVED + 15, - TK_REPEAT: FIRST_RESERVED + 16, - TK_RETURN: FIRST_RESERVED + 17, - TK_THEN: FIRST_RESERVED + 18, - TK_TRUE: FIRST_RESERVED + 19, - TK_UNTIL: FIRST_RESERVED + 20, - TK_WHILE: FIRST_RESERVED + 21, - /* other terminal symbols */ - TK_IDIV: FIRST_RESERVED + 22, - TK_CONCAT: FIRST_RESERVED + 23, - TK_DOTS: FIRST_RESERVED + 24, - TK_EQ: FIRST_RESERVED + 25, - TK_GE: FIRST_RESERVED + 26, - TK_LE: FIRST_RESERVED + 27, - TK_NE: FIRST_RESERVED + 28, - TK_SHL: FIRST_RESERVED + 29, - TK_SHR: FIRST_RESERVED + 30, - TK_DBCOLON: FIRST_RESERVED + 31, - TK_EOS: FIRST_RESERVED + 32, - TK_FLT: FIRST_RESERVED + 33, - TK_INT: FIRST_RESERVED + 34, - TK_NAME: FIRST_RESERVED + 35, - TK_STRING: FIRST_RESERVED + 36 + "TK_AND": TK_AND, + "TK_BREAK": TK_BREAK, + "TK_DO": TK_DO, + "TK_ELSE": TK_ELSE, + "TK_ELSEIF": TK_ELSEIF, + "TK_END": TK_END, + "TK_FALSE": TK_FALSE, + "TK_FOR": TK_FOR, + "TK_FUNCTION": TK_FUNCTION, + "TK_GOTO": TK_GOTO, + "TK_IF": TK_IF, + "TK_IN": TK_IN, + "TK_LOCAL": TK_LOCAL, + "TK_NIL": TK_NIL, + "TK_NOT": TK_NOT, + "TK_OR": TK_OR, + "TK_REPEAT": TK_REPEAT, + "TK_RETURN": TK_RETURN, + "TK_THEN": TK_THEN, + "TK_TRUE": TK_TRUE, + "TK_UNTIL": TK_UNTIL, + "TK_WHILE": TK_WHILE, + "TK_IDIV": TK_IDIV, + "TK_CONCAT": TK_CONCAT, + "TK_DOTS": TK_DOTS, + "TK_EQ": TK_EQ, + "TK_GE": TK_GE, + "TK_LE": TK_LE, + "TK_NE": TK_NE, + "TK_SHL": TK_SHL, + "TK_SHR": TK_SHR, + "TK_DBCOLON": TK_DBCOLON, + "TK_EOS": TK_EOS, + "TK_FLT": TK_FLT, + "TK_INT": TK_INT, + "TK_NAME": TK_NAME, + "TK_STRING": TK_STRING }; -const R = RESERVED; - const luaX_tokens = [ "and", "break", "do", "else", "elseif", "end", "false", "for", "function", "goto", "if", @@ -70,7 +127,7 @@ const luaX_tokens = [ "//", "..", "...", "==", ">=", "<=", "~=", "<<", ">>", "::", "<eof>", "<number>", "<integer>", "<name>", "<string>" -]; +].map((e, i)=>to_luastring(e)); class SemInfo { constructor() { @@ -110,28 +167,28 @@ class LexState { const save = function(ls, c) { let b = ls.buff; if (b.n + 1 > b.buffer.length) { - if (b.buffer.length >= llimits.MAX_INT/2) - lexerror(ls, defs.to_luastring("lexical element too long", true), 0); + if (b.buffer.length >= MAX_INT/2) + lexerror(ls, to_luastring("lexical element too long", true), 0); let newsize = b.buffer.length*2; - lzio.luaZ_resizebuffer(ls.L, b, newsize); + luaZ_resizebuffer(ls.L, b, newsize); } b.buffer[b.n++] = c < 0 ? 255 + c + 1 : c; }; const luaX_token2str = function(ls, token) { if (token < FIRST_RESERVED) { /* single-byte symbols? */ - return lobject.luaO_pushfstring(ls.L, defs.to_luastring("'%c'", true), token); + return lobject.luaO_pushfstring(ls.L, to_luastring("'%c'", true), token); } else { let s = luaX_tokens[token - FIRST_RESERVED]; - if (token < R.TK_EOS) /* fixed format (symbols and reserved words)? */ - return lobject.luaO_pushfstring(ls.L, defs.to_luastring("'%s'", true), defs.to_luastring(s)); + if (token < TK_EOS) /* fixed format (symbols and reserved words)? */ + return lobject.luaO_pushfstring(ls.L, to_luastring("'%s'", true), s); else /* names, strings, and numerals */ - return defs.to_luastring(s); + return s; } }; const currIsNewline = function(ls) { - return ls.current === char['\n'] || ls.current === char['\r']; + return ls.current === 10 /* ('\n').charCodeAt(0) */ || ls.current === 13 /* ('\r').charCodeAt(0) */; }; const next = function(ls) { @@ -150,14 +207,14 @@ const save_and_next = function(ls) { */ const luaX_newstring = function(ls, str) { let L = ls.L; - let ts = lstring.luaS_new(L, str); - let o = ltable.luaH_set(L, ls.h, new lobject.TValue(defs.CT.LUA_TLNGSTR, ts)); + let ts = luaS_new(L, str); + let o = ltable.luaH_set(L, ls.h, new lobject.TValue(LUA_TLNGSTR, ts)); if (o.ttisnil()) { /* not in use yet? */ o.setbvalue(true); } else { /* string already present */ /* HACK: Workaround lack of ltable 'keyfromval' */ - let tpair = ls.h.strong.get(lstring.luaS_hashlongstr(ts)); - assert(tpair.value == o); + let tpair = ls.h.strong.get(luaS_hashlongstr(ts)); + lua_assert(tpair.value == o); /* fengari addition */ ts = tpair.key.tsvalue(); /* re-use value previously stored */ } return ts; @@ -169,12 +226,12 @@ const luaX_newstring = function(ls, str) { */ const inclinenumber = function(ls) { let old = ls.current; - assert(currIsNewline(ls)); + lua_assert(currIsNewline(ls)); next(ls); /* skip '\n' or '\r' */ if (currIsNewline(ls) && ls.current !== old) next(ls); /* skip '\n\r' or '\r\n' */ - if (++ls.linenumber >= llimits.MAX_INT) - lexerror(ls, defs.to_luastring("chunk has too many lines", true), 0); + if (++ls.linenumber >= MAX_INT) + lexerror(ls, to_luastring("chunk has too many lines", true), 0); }; const luaX_setinput = function(L, ls, z, source, firstchar) { @@ -185,7 +242,7 @@ const luaX_setinput = function(L, ls, z, source, firstchar) { ls.L = L; ls.current = firstchar; ls.lookahead = { - token: R.TK_EOS, + token: TK_EOS, seminfo: new SemInfo() }; ls.z = z; @@ -193,12 +250,12 @@ const luaX_setinput = function(L, ls, z, source, firstchar) { ls.linenumber = 1; ls.lastline = 1; ls.source = source; - ls.envn = lstring.luaS_bless(L, LUA_ENV); - lzio.luaZ_resizebuffer(L, ls.buff, llimits.LUA_MINBUFFER); /* initialize buffer */ + ls.envn = luaS_bless(L, LUA_ENV); + luaZ_resizebuffer(L, ls.buff, LUA_MINBUFFER); /* initialize buffer */ }; const check_next1 = function(ls, c) { - if (ls.current === c.charCodeAt(0)) { + if (ls.current === c) { next(ls); return true; } @@ -222,17 +279,17 @@ const check_next2 = function(ls, set) { const read_numeral = function(ls, seminfo) { let expo = "Ee"; let first = ls.current; - assert(ljstype.lisdigit(ls.current)); + lua_assert(lisdigit(ls.current)); save_and_next(ls); - if (first === char['0'] && check_next2(ls, "xX")) /* hexadecimal? */ + if (first === 48 /* ('0').charCodeAt(0) */ && check_next2(ls, "xX")) /* hexadecimal? */ expo = "Pp"; for (;;) { if (check_next2(ls, expo)) /* exponent part? */ check_next2(ls, "-+"); /* optional exponent sign */ - if (ljstype.lisxdigit(ls.current)) + if (lisxdigit(ls.current)) save_and_next(ls); - else if (ls.current === char['.']) + else if (ls.current === 46 /* ('.').charCodeAt(0) */) save_and_next(ls); else break; } @@ -240,24 +297,24 @@ const read_numeral = function(ls, seminfo) { // save(ls, 0); let obj = new lobject.TValue(); - if (lobject.luaO_str2num(lzio.luaZ_buffer(ls.buff), obj) === 0) /* format error? */ - lexerror(ls, defs.to_luastring("malformed number", true), R.TK_FLT); + if (lobject.luaO_str2num(luaZ_buffer(ls.buff), obj) === 0) /* format error? */ + lexerror(ls, to_luastring("malformed number", true), TK_FLT); if (obj.ttisinteger()) { seminfo.i = obj.value; - return R.TK_INT; + return TK_INT; } else { - assert(obj.ttisfloat()); + lua_assert(obj.ttisfloat()); seminfo.r = obj.value; - return R.TK_FLT; + return TK_FLT; } }; const txtToken = function(ls, token) { switch (token) { - case R.TK_NAME: case R.TK_STRING: - case R.TK_FLT: case R.TK_INT: + case TK_NAME: case TK_STRING: + case TK_FLT: case TK_INT: // save(ls, 0); - return lobject.luaO_pushfstring(ls.L, defs.to_luastring("'%s'", true), lzio.luaZ_buffer(ls.buff)); + return lobject.luaO_pushfstring(ls.L, to_luastring("'%s'", true), luaZ_buffer(ls.buff)); default: return luaX_token2str(ls, token); } @@ -266,8 +323,8 @@ const txtToken = function(ls, token) { const lexerror = function(ls, msg, token) { msg = ldebug.luaG_addinfo(ls.L, msg, ls.source, ls.linenumber); if (token) - lobject.luaO_pushfstring(ls.L, defs.to_luastring("%s near %s"), msg, txtToken(ls, token)); - ldo.luaD_throw(ls.L, TS.LUA_ERRSYNTAX); + lobject.luaO_pushfstring(ls.L, to_luastring("%s near %s"), msg, txtToken(ls, token)); + ldo.luaD_throw(ls.L, LUA_ERRSYNTAX); }; const luaX_syntaxerror = function(ls, msg) { @@ -282,9 +339,9 @@ const luaX_syntaxerror = function(ls, msg) { const skip_sep = function(ls) { let count = 0; let s = ls.current; - assert(s === char['['] || s === char[']']); + lua_assert(s === 91 /* ('[').charCodeAt(0) */ || s === 93 /* (']').charCodeAt(0) */); save_and_next(ls); - while (ls.current === char['=']) { + while (ls.current === 61 /* ('=').charCodeAt(0) */) { save_and_next(ls); count++; } @@ -301,23 +358,24 @@ const read_long_string = function(ls, seminfo, sep) { let skip = false; for (; !skip ;) { switch (ls.current) { - case lzio.EOZ: { /* error */ + case EOZ: { /* error */ let what = seminfo ? "string" : "comment"; let msg = `unfinished long ${what} (starting at line ${line})`; - lexerror(ls, defs.to_luastring(msg), R.TK_EOS); + lexerror(ls, to_luastring(msg), TK_EOS); break; } - case char[']']: { + case 93 /* (']').charCodeAt(0) */: { if (skip_sep(ls) === sep) { save_and_next(ls); /* skip 2nd ']' */ skip = true; } break; } - case char['\n']: case char['\r']: { - save(ls, char['\n']); + case 10 /* ('\n').charCodeAt(0) */: + case 13 /* ('\r').charCodeAt(0) */: { + save(ls, 10 /* ('\n').charCodeAt(0) */); inclinenumber(ls); - if (!seminfo) lzio.luaZ_resetbuffer(ls.buff); + if (!seminfo) luaZ_resetbuffer(ls.buff); break; } default: { @@ -333,41 +391,41 @@ const read_long_string = function(ls, seminfo, sep) { const esccheck = function(ls, c, msg) { if (!c) { - if (ls.current !== lzio.EOZ) + if (ls.current !== EOZ) save_and_next(ls); /* add current to buffer for error message */ - lexerror(ls, msg, R.TK_STRING); + lexerror(ls, msg, TK_STRING); } }; const gethexa = function(ls) { save_and_next(ls); - esccheck(ls, ljstype.lisxdigit(ls.current), defs.to_luastring("hexadecimal digit expected", true)); + esccheck(ls, lisxdigit(ls.current), to_luastring("hexadecimal digit expected", true)); return lobject.luaO_hexavalue(ls.current); }; const readhexaesc = function(ls) { let r = gethexa(ls); r = (r << 4) + gethexa(ls); - lzio.luaZ_buffremove(ls.buff, 2); /* remove saved chars from buffer */ + luaZ_buffremove(ls.buff, 2); /* remove saved chars from buffer */ return r; }; const readutf8desc = function(ls) { let i = 4; /* chars to be removed: '\', 'u', '{', and first digit */ save_and_next(ls); /* skip 'u' */ - esccheck(ls, ls.current === char['{'], defs.to_luastring("missing '{'", true)); + esccheck(ls, ls.current === 123 /* ('{').charCodeAt(0) */, to_luastring("missing '{'", true)); let r = gethexa(ls); /* must have at least one digit */ save_and_next(ls); - while (ljstype.lisxdigit(ls.current)) { + while (lisxdigit(ls.current)) { i++; r = (r << 4) + lobject.luaO_hexavalue(ls.current); - esccheck(ls, r <= 0x10FFFF, defs.to_luastring("UTF-8 value too large", true)); + esccheck(ls, r <= 0x10FFFF, to_luastring("UTF-8 value too large", true)); save_and_next(ls); } - esccheck(ls, ls.current === char['}'], defs.to_luastring("missing '}'", true)); + esccheck(ls, ls.current === 125 /* ('}').charCodeAt(0) */, to_luastring("missing '}'", true)); next(ls); /* skip '}' */ - lzio.luaZ_buffremove(ls.buff, i); /* remove saved chars from buffer */ + luaZ_buffremove(ls.buff, i); /* remove saved chars from buffer */ return r; }; @@ -381,12 +439,12 @@ const utf8esc = function(ls) { const readdecesc = function(ls) { let r = 0; /* result accumulator */ let i; - for (i = 0; i < 3 && ljstype.lisdigit(ls.current); i++) { /* read up to 3 digits */ - r = 10 * r + ls.current - char['0']; + for (i = 0; i < 3 && lisdigit(ls.current); i++) { /* read up to 3 digits */ + r = 10 * r + ls.current - 48 /* ('0').charCodeAt(0) */; save_and_next(ls); } - esccheck(ls, r <= 255, defs.to_luastring("decimal escape too large", true)); - lzio.luaZ_buffremove(ls.buff, i); /* remove read digits from buffer */ + esccheck(ls, r <= 255, to_luastring("decimal escape too large", true)); + luaZ_buffremove(ls.buff, i); /* remove read digits from buffer */ return r; }; @@ -395,43 +453,46 @@ const read_string = function(ls, del, seminfo) { while (ls.current !== del) { switch (ls.current) { - case lzio.EOZ: - lexerror(ls, defs.to_luastring("unfinished string", true), R.TK_EOS); + case EOZ: + lexerror(ls, to_luastring("unfinished string", true), TK_EOS); break; - case char['\n']: - case char['\r']: - lexerror(ls, defs.to_luastring("unfinished string", true), R.TK_STRING); + case 10 /* ('\n').charCodeAt(0) */: + case 13 /* ('\r').charCodeAt(0) */: + lexerror(ls, to_luastring("unfinished string", true), TK_STRING); break; - case char['\\']: { /* escape sequences */ + case 92 /* ('\\').charCodeAt(0) */: { /* escape sequences */ save_and_next(ls); /* keep '\\' for error messages */ let will; let c; switch(ls.current) { - case char['a']: c = 7 /* \a isn't valid JS */; will = 'read_save'; break; - case char['b']: c = char['\b']; will = 'read_save'; break; - case char['f']: c = char['\f']; will = 'read_save'; break; - case char['n']: c = char['\n']; will = 'read_save'; break; - case char['r']: c = char['\r']; will = 'read_save'; break; - case char['t']: c = char['\t']; will = 'read_save'; break; - case char['v']: c = char['\v']; will = 'read_save'; break; - case char['x']: c = readhexaesc(ls); will = 'read_save'; break; - case char['u']: utf8esc(ls); will = 'no_save'; break; - case char['\n']: case char['\r']: - inclinenumber(ls); c = char['\n']; will = 'only_save'; break; - case char['\\']: case char['"']: case char['\'']: + case 97 /* ('a').charCodeAt(0) */: c = 7 /* \a isn't valid JS */; will = 'read_save'; break; + case 98 /* ('b').charCodeAt(0) */: c = 8 /* ('\b').charCodeAt(0) */; will = 'read_save'; break; + case 102 /* ('f').charCodeAt(0) */: c = 12 /* ('\f').charCodeAt(0) */; will = 'read_save'; break; + case 110 /* ('n').charCodeAt(0) */: c = 10 /* ('\n').charCodeAt(0) */; will = 'read_save'; break; + case 114 /* ('r').charCodeAt(0) */: c = 13 /* ('\r').charCodeAt(0) */; will = 'read_save'; break; + case 116 /* ('t').charCodeAt(0) */: c = 9 /* ('\t').charCodeAt(0) */; will = 'read_save'; break; + case 118 /* ('v').charCodeAt(0) */: c = 11 /* ('\v').charCodeAt(0) */; will = 'read_save'; break; + case 120 /* ('x').charCodeAt(0) */: c = readhexaesc(ls); will = 'read_save'; break; + case 117 /* ('u').charCodeAt(0) */: utf8esc(ls); will = 'no_save'; break; + case 10 /* ('\n').charCodeAt(0) */: + case 13 /* ('\r').charCodeAt(0) */: + inclinenumber(ls); c = 10 /* ('\n').charCodeAt(0) */; will = 'only_save'; break; + case 92 /* ('\\').charCodeAt(0) */: + case 34 /* ('"').charCodeAt(0) */: + case 39 /* ('\'').charCodeAt(0) */: c = ls.current; will = 'read_save'; break; - case lzio.EOZ: will = 'no_save'; break; /* will raise an error next loop */ - case char['z']: { /* zap following span of spaces */ - lzio.luaZ_buffremove(ls.buff, 1); /* remove '\\' */ + case EOZ: will = 'no_save'; break; /* will raise an error next loop */ + case 122 /* ('z').charCodeAt(0) */: { /* zap following span of spaces */ + luaZ_buffremove(ls.buff, 1); /* remove '\\' */ next(ls); /* skip the 'z' */ - while (ljstype.lisspace(ls.current)) { + while (lisspace(ls.current)) { if (currIsNewline(ls)) inclinenumber(ls); else next(ls); } will = 'no_save'; break; } default: { - esccheck(ls, ljstype.lisdigit(ls.current), defs.to_luastring("invalid escape sequence", true)); + esccheck(ls, lisdigit(ls.current), to_luastring("invalid escape sequence", true)); c = readdecesc(ls); /* digital escape '\ddd' */ will = 'only_save'; break; } @@ -441,7 +502,7 @@ const read_string = function(ls, del, seminfo) { next(ls); if (will === 'read_save' || will === 'only_save') { - lzio.luaZ_buffremove(ls.buff, 1); /* remove '\\' */ + luaZ_buffremove(ls.buff, 1); /* remove '\\' */ save(ls, c); } @@ -457,120 +518,125 @@ const read_string = function(ls, del, seminfo) { }; const token_to_index = Object.create(null); /* don't want to return true for e.g. 'hasOwnProperty' */ -luaX_tokens.forEach((e, i)=>token_to_index[lstring.luaS_hash(defs.to_luastring(e))] = i); +luaX_tokens.forEach((e, i)=>token_to_index[luaS_hash(e)] = i); const isreserved = function(w) { - let kidx = token_to_index[lstring.luaS_hashlongstr(w)]; + let kidx = token_to_index[luaS_hashlongstr(w)]; return kidx !== void 0 && kidx <= 22; }; const llex = function(ls, seminfo) { - lzio.luaZ_resetbuffer(ls.buff); + luaZ_resetbuffer(ls.buff); for (;;) { - assert(typeof ls.current == "number"); + lua_assert(typeof ls.current == "number"); /* fengari addition */ switch (ls.current) { - case char['\n']: case char['\r']: { /* line breaks */ + case 10 /* ('\n').charCodeAt(0) */: + case 13 /* ('\r').charCodeAt(0) */: { /* line breaks */ inclinenumber(ls); break; } - case char[' ']: case char['\f']: case char['\t']: case char['\v']: { /* spaces */ + case 32 /* (' ').charCodeAt(0) */: + case 12 /* ('\f').charCodeAt(0) */: + case 9 /* ('\t').charCodeAt(0) */: + case 11 /* ('\v').charCodeAt(0) */: { /* spaces */ next(ls); break; } - case char['-']: { /* '-' or '--' (comment) */ + case 45 /* ('-').charCodeAt(0) */: { /* '-' or '--' (comment) */ next(ls); - if (ls.current !== char['-']) return char['-']; + if (ls.current !== 45 /* ('-').charCodeAt(0) */) return 45 /* ('-').charCodeAt(0) */; /* else is a comment */ next(ls); - if (ls.current === char['[']) { /* long comment? */ + if (ls.current === 91 /* ('[').charCodeAt(0) */) { /* long comment? */ let sep = skip_sep(ls); - lzio.luaZ_resetbuffer(ls.buff); /* 'skip_sep' may dirty the buffer */ + luaZ_resetbuffer(ls.buff); /* 'skip_sep' may dirty the buffer */ if (sep >= 0) { read_long_string(ls, null, sep); /* skip long comment */ - lzio.luaZ_resetbuffer(ls.buff); /* previous call may dirty the buff. */ + luaZ_resetbuffer(ls.buff); /* previous call may dirty the buff. */ break; } } /* else short comment */ - while (!currIsNewline(ls) && ls.current !== lzio.EOZ) + while (!currIsNewline(ls) && ls.current !== EOZ) next(ls); /* skip until end of line (or end of file) */ break; } - case char['[']: { /* long string or simply '[' */ + case 91 /* ('[').charCodeAt(0) */: { /* long string or simply '[' */ let sep = skip_sep(ls); if (sep >= 0) { read_long_string(ls, seminfo, sep); - return R.TK_STRING; + return TK_STRING; } else if (sep !== -1) /* '[=...' missing second bracket */ - lexerror(ls, defs.to_luastring("invalid long string delimiter", true), R.TK_STRING); - return char['[']; + lexerror(ls, to_luastring("invalid long string delimiter", true), TK_STRING); + return 91 /* ('[').charCodeAt(0) */; } - case char['=']: { + case 61 /* ('=').charCodeAt(0) */: { next(ls); - if (check_next1(ls, '=')) return R.TK_EQ; - else return char['=']; + if (check_next1(ls, 61 /* ('=').charCodeAt(0) */)) return TK_EQ; + else return 61 /* ('=').charCodeAt(0) */; } - case char['<']: { + case 60 /* ('<').charCodeAt(0) */: { next(ls); - if (check_next1(ls, '=')) return R.TK_LE; - else if (check_next1(ls, '<')) return R.TK_SHL; - else return char['<']; + if (check_next1(ls, 61 /* ('=').charCodeAt(0) */)) return TK_LE; + else if (check_next1(ls, 60 /* ('<').charCodeAt(0) */)) return TK_SHL; + else return 60 /* ('<').charCodeAt(0) */; } - case char['>']: { + case 62 /* ('>').charCodeAt(0) */: { next(ls); - if (check_next1(ls, '=')) return R.TK_GE; - else if (check_next1(ls, '>')) return R.TK_SHR; - else return char['>']; + if (check_next1(ls, 61 /* ('=').charCodeAt(0) */)) return TK_GE; + else if (check_next1(ls, 62 /* ('>').charCodeAt(0) */)) return TK_SHR; + else return 62 /* ('>').charCodeAt(0) */; } - case char['/']: { + case 47 /* ('/').charCodeAt(0) */: { next(ls); - if (check_next1(ls, '/')) return R.TK_IDIV; - else return char['/']; + if (check_next1(ls, 47 /* ('/').charCodeAt(0) */)) return TK_IDIV; + else return 47 /* ('/').charCodeAt(0) */; } - case char['~']: { + case 126 /* ('~').charCodeAt(0) */: { next(ls); - if (check_next1(ls, '=')) return R.TK_NE; - else return char['~']; + if (check_next1(ls, 61 /* ('=').charCodeAt(0) */)) return TK_NE; + else return 126 /* ('~').charCodeAt(0) */; } - case char[':']: { + case 58 /* (':').charCodeAt(0) */: { next(ls); - if (check_next1(ls, ':')) return R.TK_DBCOLON; - else return char[':']; + if (check_next1(ls, 58 /* (':').charCodeAt(0) */)) return TK_DBCOLON; + else return 58 /* (':').charCodeAt(0) */; } - case char['"']: case char['\'']: { /* short literal strings */ + case 34 /* ('"').charCodeAt(0) */: + case 39 /* ('\'').charCodeAt(0) */: { /* short literal strings */ read_string(ls, ls.current, seminfo); - return R.TK_STRING; + return TK_STRING; } - case char['.']: { /* '.', '..', '...', or number */ + case 46 /* ('.').charCodeAt(0) */: { /* '.', '..', '...', or number */ save_and_next(ls); - if (check_next1(ls, '.')) { - if (check_next1(ls, '.')) - return R.TK_DOTS; /* '...' */ - else return R.TK_CONCAT; /* '..' */ + if (check_next1(ls, 46 /* ('.').charCodeAt(0) */)) { + if (check_next1(ls, 46 /* ('.').charCodeAt(0) */)) + return TK_DOTS; /* '...' */ + else return TK_CONCAT; /* '..' */ } - else if (!ljstype.lisdigit(ls.current)) return char['.']; + else if (!lisdigit(ls.current)) return 46 /* ('.').charCodeAt(0) */; else return read_numeral(ls, seminfo); } - case char['0']: case char['1']: case char['2']: case char['3']: case char['4']: - case char['5']: case char['6']: case char['7']: case char['8']: case char['9']: { + case 48 /* ('0').charCodeAt(0) */: case 49 /* ('1').charCodeAt(0) */: case 50 /* ('2').charCodeAt(0) */: case 51 /* ('3').charCodeAt(0) */: case 52 /* ('4').charCodeAt(0) */: + case 53 /* ('5').charCodeAt(0) */: case 54 /* ('6').charCodeAt(0) */: case 55 /* ('7').charCodeAt(0) */: case 56 /* ('8').charCodeAt(0) */: case 57 /* ('9').charCodeAt(0) */: { return read_numeral(ls, seminfo); } - case lzio.EOZ: { - return R.TK_EOS; + case EOZ: { + return TK_EOS; } default: { - if (ljstype.lislalpha(ls.current)) { /* identifier or reserved word? */ + if (lislalpha(ls.current)) { /* identifier or reserved word? */ do { save_and_next(ls); - } while (ljstype.lislalnum(ls.current)); - let ts = luaX_newstring(ls, lzio.luaZ_buffer(ls.buff)); + } while (lislalnum(ls.current)); + let ts = luaX_newstring(ls, luaZ_buffer(ls.buff)); seminfo.ts = ts; - let kidx = token_to_index[lstring.luaS_hashlongstr(ts)]; + let kidx = token_to_index[luaS_hashlongstr(ts)]; if (kidx !== void 0 && kidx <= 22) /* reserved word? */ return kidx + FIRST_RESERVED; else - return R.TK_NAME; + return TK_NAME; } else { /* single-char tokens (+ - / ...) */ let c = ls.current; next(ls); @@ -583,18 +649,18 @@ const llex = function(ls, seminfo) { const luaX_next = function(ls) { ls.lastline = ls.linenumber; - if (ls.lookahead.token !== R.TK_EOS) { /* is there a look-ahead token? */ + if (ls.lookahead.token !== TK_EOS) { /* is there a look-ahead token? */ ls.t.token = ls.lookahead.token; /* use this one */ ls.t.seminfo.i = ls.lookahead.seminfo.i; ls.t.seminfo.r = ls.lookahead.seminfo.r; ls.t.seminfo.ts = ls.lookahead.seminfo.ts; // TODO ? - ls.lookahead.token = R.TK_EOS; /* and discharge it */ + ls.lookahead.token = TK_EOS; /* and discharge it */ } else ls.t.token = llex(ls, ls.t.seminfo); /* read next token */ }; const luaX_lookahead = function(ls) { - assert(ls.lookahead.token === R.TK_EOS); + lua_assert(ls.lookahead.token === TK_EOS); ls.lookahead.token = llex(ls, ls.lookahead.seminfo); return ls.lookahead.token; }; diff --git a/src/llimits.js b/src/llimits.js index 4a76bbe..2e7b892 100644 --- a/src/llimits.js +++ b/src/llimits.js @@ -1,5 +1,19 @@ "use strict"; +const { luai_apicheck } = require("./luaconf.js"); + +const lua_assert = function(c) { + if (!c) throw Error("assertion failed"); +}; +module.exports.lua_assert = lua_assert; + +module.exports.luai_apicheck = luai_apicheck || function(l, e) { return lua_assert(e); }; + +const api_check = function(l, e, msg) { + return luai_apicheck(l, e && msg); +}; +module.exports.api_check = api_check; + const LUAI_MAXCCALLS = 200; module.exports.LUAI_MAXCCALLS = LUAI_MAXCCALLS; diff --git a/src/lmathlib.js b/src/lmathlib.js index e056fd8..301aa02 100644 --- a/src/lmathlib.js +++ b/src/lmathlib.js @@ -1,138 +1,170 @@ "use strict"; -const lua = require('./lua.js'); -const lauxlib = require('./lauxlib.js'); -const luaconf = require('./luaconf.js'); +const { + LUA_OPLT, + LUA_TNUMBER, + lua_compare, + lua_gettop, + lua_isinteger, + lua_isnoneornil, + lua_pushboolean, + lua_pushinteger, + lua_pushliteral, + lua_pushnil, + lua_pushnumber, + lua_pushvalue, + lua_setfield, + lua_settop, + lua_tointeger, + lua_tointegerx, + lua_type +} = require('./lua.js'); +const { + luaL_argcheck, + luaL_argerror, + luaL_checkany, + luaL_checkinteger, + luaL_checknumber, + luaL_error, + luaL_newlib, + luaL_optnumber +} = require('./lauxlib.js'); +const { + LUA_MAXINTEGER, + LUA_MININTEGER, + lua_numbertointeger +} = require('./luaconf.js'); +const { to_luastring } = require("./fengaricore.js"); const math_random = function(L) { let low, up; let r = Math.random(); - switch (lua.lua_gettop(L)) { /* check number of arguments */ + switch (lua_gettop(L)) { /* check number of arguments */ case 0: - lua.lua_pushnumber(L, r); /* Number between 0 and 1 */ + lua_pushnumber(L, r); /* Number between 0 and 1 */ return 1; case 1: { low = 1; - up = lauxlib.luaL_checkinteger(L, 1); + up = luaL_checkinteger(L, 1); break; } case 2: { - low = lauxlib.luaL_checkinteger(L, 1); - up = lauxlib.luaL_checkinteger(L, 2); + low = luaL_checkinteger(L, 1); + up = luaL_checkinteger(L, 2); break; } - default: return lauxlib.luaL_error(L, lua.to_luastring("wrong number of arguments", true)); + default: return luaL_error(L, to_luastring("wrong number of arguments", true)); } /* random integer in the interval [low, up] */ - lauxlib.luaL_argcheck(L, low <= up, 1, lua.to_luastring("interval is empty", true)); - lauxlib.luaL_argcheck(L, low >= 0 || up <= luaconf.LUA_MAXINTEGER + low, 1, - lua.to_luastring("interval too large", true)); + luaL_argcheck(L, low <= up, 1, to_luastring("interval is empty", true)); + luaL_argcheck(L, low >= 0 || up <= LUA_MAXINTEGER + low, 1, + to_luastring("interval too large", true)); r *= (up - low) + 1; - lua.lua_pushinteger(L, Math.floor(r) + low); + lua_pushinteger(L, Math.floor(r) + low); return 1; }; const math_abs = function(L) { - if (lua.lua_isinteger(L, 1)) { - let n = lua.lua_tointeger(L, 1); + if (lua_isinteger(L, 1)) { + let n = lua_tointeger(L, 1); if (n < 0) n = (-n)|0; - lua.lua_pushinteger(L, n); + lua_pushinteger(L, n); } else - lua.lua_pushnumber(L, Math.abs(lauxlib.luaL_checknumber(L, 1))); + lua_pushnumber(L, Math.abs(luaL_checknumber(L, 1))); return 1; }; const math_sin = function(L) { - lua.lua_pushnumber(L, Math.sin(lauxlib.luaL_checknumber(L, 1))); + lua_pushnumber(L, Math.sin(luaL_checknumber(L, 1))); return 1; }; const math_cos = function(L) { - lua.lua_pushnumber(L, Math.cos(lauxlib.luaL_checknumber(L, 1))); + lua_pushnumber(L, Math.cos(luaL_checknumber(L, 1))); return 1; }; const math_tan = function(L) { - lua.lua_pushnumber(L, Math.tan(lauxlib.luaL_checknumber(L, 1))); + lua_pushnumber(L, Math.tan(luaL_checknumber(L, 1))); return 1; }; const math_asin = function(L) { - lua.lua_pushnumber(L, Math.asin(lauxlib.luaL_checknumber(L, 1))); + lua_pushnumber(L, Math.asin(luaL_checknumber(L, 1))); return 1; }; const math_acos = function(L) { - lua.lua_pushnumber(L, Math.acos(lauxlib.luaL_checknumber(L, 1))); + lua_pushnumber(L, Math.acos(luaL_checknumber(L, 1))); return 1; }; const math_atan = function(L) { - let y = lauxlib.luaL_checknumber(L, 1); - let x = lauxlib.luaL_optnumber(L, 2, 1); - lua.lua_pushnumber(L, Math.atan2(y, x)); + let y = luaL_checknumber(L, 1); + let x = luaL_optnumber(L, 2, 1); + lua_pushnumber(L, Math.atan2(y, x)); return 1; }; const math_toint = function(L) { - let n = lua.lua_tointegerx(L, 1); + let n = lua_tointegerx(L, 1); if (n !== false) - lua.lua_pushinteger(L, n); + lua_pushinteger(L, n); else { - lauxlib.luaL_checkany(L, 1); - lua.lua_pushnil(L); /* value is not convertible to integer */ + luaL_checkany(L, 1); + lua_pushnil(L); /* value is not convertible to integer */ } return 1; }; const pushnumint = function(L, d) { - let n = luaconf.lua_numbertointeger(d); + let n = lua_numbertointeger(d); if (n !== false) /* does 'd' fit in an integer? */ - lua.lua_pushinteger(L, n); /* result is integer */ + lua_pushinteger(L, n); /* result is integer */ else - lua.lua_pushnumber(L, d); /* result is float */ + lua_pushnumber(L, d); /* result is float */ }; const math_floor = function(L) { - if (lua.lua_isinteger(L, 1)) - lua.lua_settop(L, 1); + if (lua_isinteger(L, 1)) + lua_settop(L, 1); else - pushnumint(L, Math.floor(lauxlib.luaL_checknumber(L, 1))); + pushnumint(L, Math.floor(luaL_checknumber(L, 1))); return 1; }; const math_ceil = function(L) { - if (lua.lua_isinteger(L, 1)) - lua.lua_settop(L, 1); + if (lua_isinteger(L, 1)) + lua_settop(L, 1); else - pushnumint(L, Math.ceil(lauxlib.luaL_checknumber(L, 1))); + pushnumint(L, Math.ceil(luaL_checknumber(L, 1))); return 1; }; const math_sqrt = function(L) { - lua.lua_pushnumber(L, Math.sqrt(lauxlib.luaL_checknumber(L, 1))); + lua_pushnumber(L, Math.sqrt(luaL_checknumber(L, 1))); return 1; }; const math_ult = function(L) { - let a = lauxlib.luaL_checkinteger(L, 1); - let b = lauxlib.luaL_checkinteger(L, 2); - lua.lua_pushboolean(L, (a >= 0)?(b<0 || a<b):(b<0 && a<b)); + let a = luaL_checkinteger(L, 1); + let b = luaL_checkinteger(L, 2); + lua_pushboolean(L, (a >= 0)?(b<0 || a<b):(b<0 && a<b)); return 1; }; const math_log = function(L) { - let x = lauxlib.luaL_checknumber(L, 1); + let x = luaL_checknumber(L, 1); let res; - if (lua.lua_isnoneornil(L, 2)) + if (lua_isnoneornil(L, 2)) res = Math.log(x); else { - let base = lauxlib.luaL_checknumber(L, 2); + let base = luaL_checknumber(L, 2); if (base === 2) res = Math.log2(x); else if (base === 10) @@ -140,87 +172,87 @@ const math_log = function(L) { else res = Math.log(x)/Math.log(base); } - lua.lua_pushnumber(L, res); + lua_pushnumber(L, res); return 1; }; const math_exp = function(L) { - lua.lua_pushnumber(L, Math.exp(lauxlib.luaL_checknumber(L, 1))); + lua_pushnumber(L, Math.exp(luaL_checknumber(L, 1))); return 1; }; const math_deg = function(L) { - lua.lua_pushnumber(L, lauxlib.luaL_checknumber(L, 1) * (180 / Math.PI)); + lua_pushnumber(L, luaL_checknumber(L, 1) * (180 / Math.PI)); return 1; }; const math_rad = function(L) { - lua.lua_pushnumber(L, lauxlib.luaL_checknumber(L, 1) * (Math.PI / 180)); + lua_pushnumber(L, luaL_checknumber(L, 1) * (Math.PI / 180)); return 1; }; const math_min = function(L) { - let n = lua.lua_gettop(L); /* number of arguments */ + let n = lua_gettop(L); /* number of arguments */ let imin = 1; /* index of current minimum value */ - lauxlib.luaL_argcheck(L, n >= 1, 1, lua.to_luastring("value expected", true)); + luaL_argcheck(L, n >= 1, 1, to_luastring("value expected", true)); for (let i = 2; i <= n; i++){ - if (lua.lua_compare(L, i, imin, lua.LUA_OPLT)) + if (lua_compare(L, i, imin, LUA_OPLT)) imin = i; } - lua.lua_pushvalue(L, imin); + lua_pushvalue(L, imin); return 1; }; const math_max = function(L) { - let n = lua.lua_gettop(L); /* number of arguments */ + let n = lua_gettop(L); /* number of arguments */ let imax = 1; /* index of current minimum value */ - lauxlib.luaL_argcheck(L, n >= 1, 1, lua.to_luastring("value expected", true)); + luaL_argcheck(L, n >= 1, 1, to_luastring("value expected", true)); for (let i = 2; i <= n; i++){ - if (lua.lua_compare(L, imax, i, lua.LUA_OPLT)) + if (lua_compare(L, imax, i, LUA_OPLT)) imax = i; } - lua.lua_pushvalue(L, imax); + lua_pushvalue(L, imax); return 1; }; const math_type = function(L) { - if (lua.lua_type(L, 1) === lua.LUA_TNUMBER) { - if (lua.lua_isinteger(L, 1)) - lua.lua_pushliteral(L, "integer"); + if (lua_type(L, 1) === LUA_TNUMBER) { + if (lua_isinteger(L, 1)) + lua_pushliteral(L, "integer"); else - lua.lua_pushliteral(L, "float"); + lua_pushliteral(L, "float"); } else { - lauxlib.luaL_checkany(L, 1); - lua.lua_pushnil(L); + luaL_checkany(L, 1); + lua_pushnil(L); } return 1; }; const math_fmod = function(L) { - if (lua.lua_isinteger(L, 1) && lua.lua_isinteger(L, 2)) { - let d = lua.lua_tointeger(L, 2); + if (lua_isinteger(L, 1) && lua_isinteger(L, 2)) { + let d = lua_tointeger(L, 2); /* no special case needed for -1 in javascript */ if (d === 0) { - lauxlib.luaL_argerror(L, 2, lua.to_luastring("zero", true)); + luaL_argerror(L, 2, to_luastring("zero", true)); } else - lua.lua_pushinteger(L, (lua.lua_tointeger(L, 1) % d)|0); + lua_pushinteger(L, (lua_tointeger(L, 1) % d)|0); } else { - let a = lauxlib.luaL_checknumber(L, 1); - let b = lauxlib.luaL_checknumber(L, 2); - lua.lua_pushnumber(L, a%b); + let a = luaL_checknumber(L, 1); + let b = luaL_checknumber(L, 2); + lua_pushnumber(L, a%b); } return 1; }; const math_modf = function(L) { - if (lua.lua_isinteger(L, 1)) { - lua.lua_settop(L, 1); /* number is its own integer part */ - lua.lua_pushnumber(L, 0); /* no fractional part */ + if (lua_isinteger(L, 1)) { + lua_settop(L, 1); /* number is its own integer part */ + lua_pushnumber(L, 0); /* no fractional part */ } else { - let n = lauxlib.luaL_checknumber(L, 1); + let n = luaL_checknumber(L, 1); let ip = n < 0 ? Math.ceil(n) : Math.floor(n); pushnumint(L, ip); - lua.lua_pushnumber(L, n === ip ? 0 : n - ip); + lua_pushnumber(L, n === ip ? 0 : n - ip); } return 2; }; @@ -251,15 +283,15 @@ const mathlib = { }; const luaopen_math = function(L) { - lauxlib.luaL_newlib(L, mathlib); - lua.lua_pushnumber(L, Math.PI); - lua.lua_setfield(L, -2, lua.to_luastring("pi", true)); - lua.lua_pushnumber(L, Infinity); - lua.lua_setfield(L, -2, lua.to_luastring("huge", true)); - lua.lua_pushinteger(L, luaconf.LUA_MAXINTEGER); - lua.lua_setfield(L, -2, lua.to_luastring("maxinteger", true)); - lua.lua_pushinteger(L, luaconf.LUA_MININTEGER); - lua.lua_setfield(L, -2, lua.to_luastring("mininteger", true)); + luaL_newlib(L, mathlib); + lua_pushnumber(L, Math.PI); + lua_setfield(L, -2, to_luastring("pi", true)); + lua_pushnumber(L, Infinity); + lua_setfield(L, -2, to_luastring("huge", true)); + lua_pushinteger(L, LUA_MAXINTEGER); + lua_setfield(L, -2, to_luastring("maxinteger", true)); + lua_pushinteger(L, LUA_MININTEGER); + lua_setfield(L, -2, to_luastring("mininteger", true)); return 1; }; diff --git a/src/loadlib.js b/src/loadlib.js index 0be1742..99540e4 100644 --- a/src/loadlib.js +++ b/src/loadlib.js @@ -1,8 +1,74 @@ "use strict"; +const { + LUA_CPATH_DEFAULT, + LUA_DIRSEP, + LUA_EXEC_DIR, + LUA_OK, + LUA_PATH_DEFAULT, + LUA_PATH_MARK, + LUA_PATH_SEP, + LUA_REGISTRYINDEX, + LUA_TNIL, + LUA_TTABLE, + LUA_VERSUFFIX, + lua_callk, + lua_createtable, + lua_getfield, + lua_insert, + lua_isfunction, + lua_isnil, + lua_isstring, + lua_newtable, + lua_pop, + lua_pushboolean, + lua_pushcclosure, + lua_pushcfunction, + lua_pushfstring, + lua_pushglobaltable, + lua_pushlightuserdata, + lua_pushliteral, + lua_pushlstring, + lua_pushnil, + lua_pushstring, + lua_pushvalue, + lua_rawgeti, + lua_rawgetp, + lua_rawseti, + lua_rawsetp, + lua_remove, + lua_setfield, + lua_setmetatable, + lua_settop, + lua_toboolean, + lua_tostring, + lua_touserdata, + lua_upvalueindex +} = require('./lua.js'); +const { + LUA_LOADED_TABLE, + LUA_PRELOAD_TABLE, + luaL_Buffer, + luaL_addvalue, + luaL_buffinit, + luaL_checkstring, + luaL_error, + luaL_getsubtable, + luaL_gsub, + luaL_len, + luaL_loadfile, + luaL_newlib, + luaL_optstring, + luaL_pushresult, + luaL_setfuncs +} = require('./lauxlib.js'); +const { + luastring_indexOf, + to_jsstring, + to_luastring, + to_uristring +} = require("./fengaricore.js"); const fengari = require('./fengari.js'); -const lua = require('./lua.js'); -const lauxlib = require('./lauxlib.js'); const global_env = (function() { /* global WorkerGlobalScope */ /* see https://github.com/sindresorhus/globals/issues/127 */ @@ -21,7 +87,7 @@ const global_env = (function() { } })(); -const CLIBS = lua.to_luastring("__CLIBS__", true); +const CLIBS = to_luastring("__CLIBS__"); const LUA_PATH_VAR = "LUA_PATH"; const LUA_CPATH_VAR = "LUA_CPATH"; @@ -33,17 +99,17 @@ const LUA_IGMARK = "-"; ** LUA_LSUBSEP is the character that replaces dots in submodule names ** when searching for a Lua loader. */ -const LUA_CSUBSEP = lua.LUA_DIRSEP; -const LUA_LSUBSEP = lua.LUA_DIRSEP; +const LUA_CSUBSEP = LUA_DIRSEP; +const LUA_LSUBSEP = LUA_DIRSEP; /* prefix for open functions in C libraries */ -const LUA_POF = lua.to_luastring("luaopen_"); +const LUA_POF = to_luastring("luaopen_"); /* separator for open functions in C libraries */ -const LUA_OFSEP = lua.to_luastring("_"); +const LUA_OFSEP = to_luastring("_"); const LIB_FAIL = "open"; -const AUXMARK = lua.to_luastring("\x01"); +const AUXMARK = to_luastring("\x01"); /* @@ -55,13 +121,13 @@ const AUXMARK = lua.to_luastring("\x01"); let lsys_load; if (typeof process === "undefined") { lsys_load = function(L, path, seeglb) { - path = lua.to_uristring(path); + path = to_uristring(path); let xhr = new XMLHttpRequest(); xhr.open("GET", path, false); xhr.send(); if (xhr.status < 200 || xhr.status >= 300) { - lua.lua_pushstring(L, lua.to_luastring(`${xhr.status}: ${xhr.statusText}`)); + lua_pushstring(L, to_luastring(`${xhr.status}: ${xhr.statusText}`)); return null; } @@ -73,7 +139,7 @@ if (typeof process === "undefined") { try { func = Function("fengari", code); } catch (e) { - lua.lua_pushstring(L, lua.to_luastring(`${e.name}: ${e.message}`)); + lua_pushstring(L, to_luastring(`${e.name}: ${e.message}`)); return null; } let res = func(fengari); @@ -82,20 +148,20 @@ if (typeof process === "undefined") { } else if (res === void 0) { /* assume library added symbols to global environment */ return global_env; } else { - lua.lua_pushstring(L, lua.to_luastring(`library returned unexpected type (${typeof res})`)); + lua_pushstring(L, to_luastring(`library returned unexpected type (${typeof res})`)); return null; } }; } else { const pathlib = require('path'); lsys_load = function(L, path, seeglb) { - path = lua.to_jsstring(path); + path = to_jsstring(path); /* relative paths should be relative to cwd, not this js file */ path = pathlib.resolve(process.cwd(), path); try { return require(path); } catch (e) { - lua.lua_pushstring(L, lua.to_luastring(e.message)); + lua_pushstring(L, to_luastring(e.message)); return null; } }; @@ -107,12 +173,12 @@ if (typeof process === "undefined") { ** error string in the stack. */ const lsys_sym = function(L, lib, sym) { - let f = lib[lua.to_jsstring(sym)]; + let f = lib[to_jsstring(sym)]; if (f && typeof f === 'function') return f; else { - lua.lua_pushfstring(L, lua.to_luastring("undefined symbol: %s"), sym); + lua_pushfstring(L, to_luastring("undefined symbol: %s"), sym); return null; } }; @@ -121,9 +187,9 @@ const lsys_sym = function(L, lib, sym) { ** return registry.LUA_NOENV as a boolean */ const noenv = function(L) { - lua.lua_getfield(L, lua.LUA_REGISTRYINDEX, lua.to_luastring("LUA_NOENV")); - let b = lua.lua_toboolean(L, -1); - lua.lua_pop(L, 1); /* remove value */ + lua_getfield(L, LUA_REGISTRYINDEX, to_luastring("LUA_NOENV")); + let b = lua_toboolean(L, -1); + lua_pop(L, 1); /* remove value */ return b; }; @@ -143,7 +209,7 @@ if (typeof process !== "undefined") { // Only with Node } else { /* TODO: use async/await ? */ readable = function(path) { - path = lua.to_uristring(path); + path = to_uristring(path); let xhr = new XMLHttpRequest(); /* Following GET request done by searcher_Web will be cached */ xhr.open("GET", path, false); @@ -177,28 +243,28 @@ const lookforfunc = function(L, path, sym) { addtoclib(L, path, reg); } if (sym[0] === '*'.charCodeAt(0)) { /* loading only library (no function)? */ - lua.lua_pushboolean(L, 1); /* return 'true' */ + lua_pushboolean(L, 1); /* return 'true' */ return 0; /* no errors */ } else { let f = lsys_sym(L, reg, sym); if (f === null) return ERRFUNC; /* unable to find function */ - lua.lua_pushcfunction(L, f); /* else create new function */ + lua_pushcfunction(L, f); /* else create new function */ return 0; /* no errors */ } }; const ll_loadlib = function(L) { - let path = lauxlib.luaL_checkstring(L, 1); - let init = lauxlib.luaL_checkstring(L, 2); + let path = luaL_checkstring(L, 1); + let init = luaL_checkstring(L, 2); let stat = lookforfunc(L, path, init); if (stat === 0) /* no errors? */ return 1; /* return the loaded function */ else { /* error; error message is on stack top */ - lua.lua_pushnil(L); - lua.lua_insert(L, -2); - lua.lua_pushliteral(L, (stat === ERRLIB) ? LIB_FAIL : "init"); + lua_pushnil(L); + lua_insert(L, -2); + lua_pushliteral(L, (stat === ERRLIB) ? LIB_FAIL : "init"); return 3; /* return nil, error message, and where */ } }; @@ -216,36 +282,36 @@ const env = (function() { ** Set a path */ const setpath = function(L, fieldname, envname, dft) { - let nver = `${envname}${lua.LUA_VERSUFFIX}`; - lua.lua_pushstring(L, lua.to_luastring(nver)); + let nver = `${envname}${LUA_VERSUFFIX}`; + lua_pushstring(L, to_luastring(nver)); let path = env[nver]; /* use versioned name */ if (path === undefined) /* no environment variable? */ path = env[envname]; /* try unversioned name */ if (path === undefined || noenv(L)) /* no environment variable? */ - lua.lua_pushstring(L, lua.to_luastring(dft)); /* use default */ + lua_pushstring(L, dft); /* use default */ else { /* replace ";;" by ";AUXMARK;" and then AUXMARK by default path */ - path = lauxlib.luaL_gsub( + path = luaL_gsub( L, - lua.to_luastring(path), - lua.to_luastring(lua.LUA_PATH_SEP + lua.LUA_PATH_SEP, true), - lua.to_luastring(lua.LUA_PATH_SEP + lua.to_jsstring(AUXMARK) + lua.LUA_PATH_SEP, true) + to_luastring(path), + to_luastring(LUA_PATH_SEP + LUA_PATH_SEP, true), + to_luastring(LUA_PATH_SEP + to_jsstring(AUXMARK) + LUA_PATH_SEP, true) ); - lauxlib.luaL_gsub(L, path, AUXMARK, lua.to_luastring(dft)); - lua.lua_remove(L, -2); /* remove result from 1st 'gsub' */ + luaL_gsub(L, path, AUXMARK, dft); + lua_remove(L, -2); /* remove result from 1st 'gsub' */ } - lua.lua_setfield(L, -3, fieldname); /* package[fieldname] = path value */ - lua.lua_pop(L, 1); /* pop versioned variable name */ + lua_setfield(L, -3, fieldname); /* package[fieldname] = path value */ + lua_pop(L, 1); /* pop versioned variable name */ }; /* ** return registry.CLIBS[path] */ const checkclib = function(L, path) { - lua.lua_rawgetp(L, lua.LUA_REGISTRYINDEX, CLIBS); - lua.lua_getfield(L, -1, path); - let plib = lua.lua_touserdata(L, -1); /* plib = CLIBS[path] */ - lua.lua_pop(L, 2); /* pop CLIBS table and 'plib' */ + lua_rawgetp(L, LUA_REGISTRYINDEX, CLIBS); + lua_getfield(L, -1, path); + let plib = lua_touserdata(L, -1); /* plib = CLIBS[path] */ + lua_pop(L, 2); /* pop CLIBS table and 'plib' */ return plib; }; @@ -254,79 +320,79 @@ const checkclib = function(L, path) { ** registry.CLIBS[#CLIBS + 1] = plib -- also keep a list of all libraries */ const addtoclib = function(L, path, plib) { - lua.lua_rawgetp(L, lua.LUA_REGISTRYINDEX, CLIBS); - lua.lua_pushlightuserdata(L, plib); - lua.lua_pushvalue(L, -1); - lua.lua_setfield(L, -3, path); /* CLIBS[path] = plib */ - lua.lua_rawseti(L, -2, lauxlib.luaL_len(L, -2) + 1); /* CLIBS[#CLIBS + 1] = plib */ - lua.lua_pop(L, 1); /* pop CLIBS table */ + lua_rawgetp(L, LUA_REGISTRYINDEX, CLIBS); + lua_pushlightuserdata(L, plib); + lua_pushvalue(L, -1); + lua_setfield(L, -3, path); /* CLIBS[path] = plib */ + lua_rawseti(L, -2, luaL_len(L, -2) + 1); /* CLIBS[#CLIBS + 1] = plib */ + lua_pop(L, 1); /* pop CLIBS table */ }; const pushnexttemplate = function(L, path) { - while (path[0] === lua.LUA_PATH_SEP.charCodeAt(0)) path = path.slice(1); /* skip separators */ + while (path[0] === LUA_PATH_SEP.charCodeAt(0)) path = path.subarray(1); /* skip separators */ if (path.length === 0) return null; /* no more templates */ - let l = path.indexOf(lua.LUA_PATH_SEP.charCodeAt(0)); /* find next separator */ + let l = luastring_indexOf(path, LUA_PATH_SEP.charCodeAt(0)); /* find next separator */ if (l < 0) l = path.length; - lua.lua_pushlstring(L, path, l); /* template */ - return path.slice(l); + lua_pushlstring(L, path, l); /* template */ + return path.subarray(l); }; const searchpath = function(L, name, path, sep, dirsep) { - let msg = new lauxlib.luaL_Buffer(); /* to build error message */ - lauxlib.luaL_buffinit(L, msg); + let msg = new luaL_Buffer(); /* to build error message */ + luaL_buffinit(L, msg); if (sep[0] !== 0) /* non-empty separator? */ - name = lauxlib.luaL_gsub(L, name, sep, dirsep); /* replace it by 'dirsep' */ + name = luaL_gsub(L, name, sep, dirsep); /* replace it by 'dirsep' */ while ((path = pushnexttemplate(L, path)) !== null) { - let filename = lauxlib.luaL_gsub(L, lua.lua_tostring(L, -1), lua.to_luastring(lua.LUA_PATH_MARK, true), name); - lua.lua_remove(L, -2); /* remove path template */ + let filename = luaL_gsub(L, lua_tostring(L, -1), to_luastring(LUA_PATH_MARK, true), name); + lua_remove(L, -2); /* remove path template */ if (readable(filename)) /* does file exist and is readable? */ return filename; /* return that file name */ - lua.lua_pushfstring(L, lua.to_luastring("\n\tno file '%s'"), filename); - lua.lua_remove(L, -2); /* remove file name */ - lauxlib.luaL_addvalue(msg); + lua_pushfstring(L, to_luastring("\n\tno file '%s'"), filename); + lua_remove(L, -2); /* remove file name */ + luaL_addvalue(msg); } - lauxlib.luaL_pushresult(msg); /* create error message */ + luaL_pushresult(msg); /* create error message */ return null; /* not found */ }; const ll_searchpath = function(L) { let f = searchpath( L, - lauxlib.luaL_checkstring(L, 1), - lauxlib.luaL_checkstring(L, 2), - lauxlib.luaL_optstring(L, 3, lua.to_luastring(".")), - lauxlib.luaL_optstring(L, 4, lua.to_luastring(lua.LUA_DIRSEP)) + luaL_checkstring(L, 1), + luaL_checkstring(L, 2), + luaL_optstring(L, 3, to_luastring(".")), + luaL_optstring(L, 4, to_luastring(LUA_DIRSEP)) ); if (f !== null) return 1; else { /* error message is on top of the stack */ - lua.lua_pushnil(L); - lua.lua_insert(L, -2); + lua_pushnil(L); + lua_insert(L, -2); return 2; /* return nil + error message */ } }; const findfile = function(L, name, pname, dirsep) { - lua.lua_getfield(L, lua.lua_upvalueindex(1), pname); - let path = lua.lua_tostring(L, -1); + lua_getfield(L, lua_upvalueindex(1), pname); + let path = lua_tostring(L, -1); if (path === null) - lauxlib.luaL_error(L, lua.to_luastring("'package.%s' must be a string"), pname); - return searchpath(L, name, path, lua.to_luastring("."), dirsep); + luaL_error(L, to_luastring("'package.%s' must be a string"), pname); + return searchpath(L, name, path, to_luastring("."), dirsep); }; const checkload = function(L, stat, filename) { if (stat) { /* module loaded successfully? */ - lua.lua_pushstring(L, filename); /* will be 2nd argument to module */ + lua_pushstring(L, filename); /* will be 2nd argument to module */ return 2; /* return open function and file name */ } else - return lauxlib.luaL_error(L, lua.to_luastring("error loading module '%s' from file '%s':\n\t%s"), - lua.lua_tostring(L, 1), filename, lua.lua_tostring(L, -1)); + return luaL_error(L, to_luastring("error loading module '%s' from file '%s':\n\t%s"), + lua_tostring(L, 1), filename, lua_tostring(L, -1)); }; const searcher_Lua = function(L) { - let name = lauxlib.luaL_checkstring(L, 1); - let filename = findfile(L, name, lua.to_luastring("path", true), lua.to_luastring(LUA_LSUBSEP, true)); + let name = luaL_checkstring(L, 1); + let filename = findfile(L, name, to_luastring("path", true), to_luastring(LUA_LSUBSEP, true)); if (filename === null) return 1; /* module not found in this path */ - return checkload(L, lauxlib.luaL_loadfile(L, filename) === lua.LUA_OK, filename); + return checkload(L, luaL_loadfile(L, filename) === LUA_OK, filename); }; /* @@ -339,119 +405,119 @@ const searcher_Lua = function(L) { */ const loadfunc = function(L, filename, modname) { let openfunc; - modname = lauxlib.luaL_gsub(L, modname, lua.to_luastring("."), LUA_OFSEP); - let mark = modname.indexOf(LUA_IGMARK.charCodeAt(0)); + modname = luaL_gsub(L, modname, to_luastring("."), LUA_OFSEP); + let mark = luastring_indexOf(modname, LUA_IGMARK.charCodeAt(0)); if (mark >= 0) { - openfunc = lua.lua_pushlstring(L, modname, mark); - openfunc = lua.lua_pushfstring(L, lua.to_luastring("%s%s"), LUA_POF, openfunc); + openfunc = lua_pushlstring(L, modname, mark); + openfunc = lua_pushfstring(L, to_luastring("%s%s"), LUA_POF, openfunc); let stat = lookforfunc(L, filename, openfunc); if (stat !== ERRFUNC) return stat; modname = mark + 1; /* else go ahead and try old-style name */ } - openfunc = lua.lua_pushfstring(L, lua.to_luastring("%s%s"), LUA_POF, modname); + openfunc = lua_pushfstring(L, to_luastring("%s%s"), LUA_POF, modname); return lookforfunc(L, filename, openfunc); }; const searcher_C = function(L) { - let name = lauxlib.luaL_checkstring(L, 1); - let filename = findfile(L, name, lua.to_luastring("cpath", true), lua.to_luastring(LUA_CSUBSEP, true)); + let name = luaL_checkstring(L, 1); + let filename = findfile(L, name, to_luastring("cpath", true), to_luastring(LUA_CSUBSEP, true)); if (filename === null) return 1; /* module not found in this path */ return checkload(L, (loadfunc(L, filename, name) === 0), filename); }; const searcher_Croot = function(L) { - let name = lauxlib.luaL_checkstring(L, 1); - let p = name.indexOf('.'.charCodeAt(0)); + let name = luaL_checkstring(L, 1); + let p = luastring_indexOf(name, '.'.charCodeAt(0)); let stat; if (p < 0) return 0; /* is root */ - lua.lua_pushlstring(L, name, p); - let filename = findfile(L, lua.lua_tostring(L, -1), lua.to_luastring("cpath", true), lua.to_luastring(LUA_CSUBSEP, true)); + lua_pushlstring(L, name, p); + let filename = findfile(L, lua_tostring(L, -1), to_luastring("cpath", true), to_luastring(LUA_CSUBSEP, true)); if (filename === null) return 1; /* root not found */ if ((stat = loadfunc(L, filename, name)) !== 0) { if (stat != ERRFUNC) return checkload(L, 0, filename); /* real error */ else { /* open function not found */ - lua.lua_pushstring(L, lua.to_luastring("\n\tno module '%s' in file '%s'"), name, filename); + lua_pushstring(L, to_luastring("\n\tno module '%s' in file '%s'"), name, filename); return 1; } } - lua.lua_pushstring(L, filename); /* will be 2nd argument to module */ + lua_pushstring(L, filename); /* will be 2nd argument to module */ return 2; }; const searcher_preload = function(L) { - let name = lauxlib.luaL_checkstring(L, 1); - lua.lua_getfield(L, lua.LUA_REGISTRYINDEX, lauxlib.LUA_PRELOAD_TABLE); - if (lua.lua_getfield(L, -1, name) === lua.LUA_TNIL) /* not found? */ - lua.lua_pushfstring(L, lua.to_luastring("\n\tno field package.preload['%s']"), name); + let name = luaL_checkstring(L, 1); + lua_getfield(L, LUA_REGISTRYINDEX, LUA_PRELOAD_TABLE); + if (lua_getfield(L, -1, name) === LUA_TNIL) /* not found? */ + lua_pushfstring(L, to_luastring("\n\tno field package.preload['%s']"), name); return 1; }; const findloader = function(L, name, ctx, k) { - let msg = new lauxlib.luaL_Buffer(); /* to build error message */ - lauxlib.luaL_buffinit(L, msg); + let msg = new luaL_Buffer(); /* to build error message */ + luaL_buffinit(L, msg); /* push 'package.searchers' to index 3 in the stack */ - if (lua.lua_getfield(L, lua.lua_upvalueindex(1), lua.to_luastring("searchers", true)) !== lua.LUA_TTABLE) - lauxlib.luaL_error(L, lua.to_luastring("'package.searchers' must be a table")); + if (lua_getfield(L, lua_upvalueindex(1), to_luastring("searchers", true)) !== LUA_TTABLE) + luaL_error(L, to_luastring("'package.searchers' must be a table")); let ctx2 = {name: name, i: 1, msg: msg, ctx: ctx, k: k}; - return findloader_cont(L, lua.LUA_OK, ctx2); + return findloader_cont(L, LUA_OK, ctx2); }; const findloader_cont = function(L, status, ctx) { /* iterate over available searchers to find a loader */ for (; ; ctx.i++) { - if (status === lua.LUA_OK) { - if (lua.lua_rawgeti(L, 3, ctx.i) === lua.LUA_TNIL) { /* no more searchers? */ - lua.lua_pop(L, 1); /* remove nil */ - lauxlib.luaL_pushresult(ctx.msg); /* create error message */ - lauxlib.luaL_error(L, lua.to_luastring("module '%s' not found:%s"), ctx.name, lua.lua_tostring(L, -1)); + if (status === LUA_OK) { + if (lua_rawgeti(L, 3, ctx.i) === LUA_TNIL) { /* no more searchers? */ + lua_pop(L, 1); /* remove nil */ + luaL_pushresult(ctx.msg); /* create error message */ + luaL_error(L, to_luastring("module '%s' not found:%s"), ctx.name, lua_tostring(L, -1)); } - lua.lua_pushstring(L, ctx.name); - lua.lua_callk(L, 1, 2, ctx, findloader_cont); /* call it */ + lua_pushstring(L, ctx.name); + lua_callk(L, 1, 2, ctx, findloader_cont); /* call it */ } else { - status = lua.LUA_OK; + status = LUA_OK; } - if (lua.lua_isfunction(L, -2)) /* did it find a loader? */ + if (lua_isfunction(L, -2)) /* did it find a loader? */ break; /* module loader found */ - else if (lua.lua_isstring(L, -2)) { /* searcher returned error message? */ - lua.lua_pop(L, 1); /* remove extra return */ - lauxlib.luaL_addvalue(ctx.msg); /* concatenate error message */ + else if (lua_isstring(L, -2)) { /* searcher returned error message? */ + lua_pop(L, 1); /* remove extra return */ + luaL_addvalue(ctx.msg); /* concatenate error message */ } else - lua.lua_pop(L, 2); /* remove both returns */ + lua_pop(L, 2); /* remove both returns */ } - return ctx.k(L, lua.LUA_OK, ctx.ctx); + return ctx.k(L, LUA_OK, ctx.ctx); }; const ll_require = function(L) { - let name = lauxlib.luaL_checkstring(L, 1); - lua.lua_settop(L, 1); /* LOADED table will be at index 2 */ - lua.lua_getfield(L, lua.LUA_REGISTRYINDEX, lauxlib.LUA_LOADED_TABLE); - lua.lua_getfield(L, 2, name); /* LOADED[name] */ - if (lua.lua_toboolean(L, -1)) /* is it there? */ + let name = luaL_checkstring(L, 1); + lua_settop(L, 1); /* LOADED table will be at index 2 */ + lua_getfield(L, LUA_REGISTRYINDEX, LUA_LOADED_TABLE); + lua_getfield(L, 2, name); /* LOADED[name] */ + if (lua_toboolean(L, -1)) /* is it there? */ return 1; /* package is already loaded */ /* else must load package */ - lua.lua_pop(L, 1); /* remove 'getfield' result */ + lua_pop(L, 1); /* remove 'getfield' result */ let ctx = name; return findloader(L, name, ctx, ll_require_cont); }; const ll_require_cont = function(L, status, ctx) { let name = ctx; - lua.lua_pushstring(L, name); /* pass name as argument to module loader */ - lua.lua_insert(L, -2); /* name is 1st argument (before search data) */ - lua.lua_callk(L, 2, 1, ctx, ll_require_cont2); - return ll_require_cont2(L, lua.LUA_OK, ctx); /* run loader to load module */ + lua_pushstring(L, name); /* pass name as argument to module loader */ + lua_insert(L, -2); /* name is 1st argument (before search data) */ + lua_callk(L, 2, 1, ctx, ll_require_cont2); + return ll_require_cont2(L, LUA_OK, ctx); /* run loader to load module */ }; const ll_require_cont2 = function(L, status, ctx) { let name = ctx; - if (!lua.lua_isnil(L, -1)) /* non-nil return? */ - lua.lua_setfield(L, 2, name); /* LOADED[name] = returned value */ - if (lua.lua_getfield(L, 2, name) == lua.LUA_TNIL) { /* module set no value? */ - lua.lua_pushboolean(L, 1); /* use true as result */ - lua.lua_pushvalue(L, -1); /* extra copy to be returned */ - lua.lua_setfield(L, 2, name); /* LOADED[name] = true */ + if (!lua_isnil(L, -1)) /* non-nil return? */ + lua_setfield(L, 2, name); /* LOADED[name] = returned value */ + if (lua_getfield(L, 2, name) == LUA_TNIL) { /* module set no value? */ + lua_pushboolean(L, 1); /* use true as result */ + lua_pushvalue(L, -1); /* extra copy to be returned */ + lua_setfield(L, 2, name); /* LOADED[name] = true */ } return 1; }; @@ -468,14 +534,14 @@ const ll_funcs = { const createsearcherstable = function(L) { let searchers = [searcher_preload, searcher_Lua, searcher_C, searcher_Croot, null]; /* create 'searchers' table */ - lua.lua_createtable(L); + lua_createtable(L); /* fill it with predefined searchers */ for (let i = 0; searchers[i]; i++) { - lua.lua_pushvalue(L, -2); /* set 'package' as upvalue for all searchers */ - lua.lua_pushcclosure(L, searchers[i], 1); - lua.lua_rawseti(L, -2, i+1); + lua_pushvalue(L, -2); /* set 'package' as upvalue for all searchers */ + lua_pushcclosure(L, searchers[i], 1); + lua_rawseti(L, -2, i+1); } - lua.lua_setfield(L, -2, lua.to_luastring("searchers", true)); /* put it in field 'searchers' */ + lua_setfield(L, -2, to_luastring("searchers", true)); /* put it in field 'searchers' */ }; /* @@ -483,33 +549,33 @@ const createsearcherstable = function(L) { ** setting a finalizer to close all libraries when closing state. */ const createclibstable = function(L) { - lua.lua_newtable(L); /* create CLIBS table */ - lua.lua_createtable(L, 0, 1); /* create metatable for CLIBS */ - lua.lua_setmetatable(L, -2); - lua.lua_rawsetp(L, lua.LUA_REGISTRYINDEX, CLIBS); /* set CLIBS table in registry */ + lua_newtable(L); /* create CLIBS table */ + lua_createtable(L, 0, 1); /* create metatable for CLIBS */ + lua_setmetatable(L, -2); + lua_rawsetp(L, LUA_REGISTRYINDEX, CLIBS); /* set CLIBS table in registry */ }; const luaopen_package = function(L) { createclibstable(L); - lauxlib.luaL_newlib(L, pk_funcs); /* create 'package' table */ + luaL_newlib(L, pk_funcs); /* create 'package' table */ createsearcherstable(L); /* set paths */ - setpath(L, lua.to_luastring("path", true), LUA_PATH_VAR, lua.LUA_PATH_DEFAULT); - setpath(L, lua.to_luastring("cpath", true), LUA_CPATH_VAR, lua.LUA_CPATH_DEFAULT); + setpath(L, to_luastring("path", true), LUA_PATH_VAR, LUA_PATH_DEFAULT); + setpath(L, to_luastring("cpath", true), LUA_CPATH_VAR, LUA_CPATH_DEFAULT); /* store config information */ - lua.lua_pushliteral(L, lua.LUA_DIRSEP + "\n" + lua.LUA_PATH_SEP + "\n" + lua.LUA_PATH_MARK + "\n" + - lua.LUA_EXEC_DIR + "\n" + LUA_IGMARK + "\n"); - lua.lua_setfield(L, -2, lua.to_luastring("config", true)); + lua_pushliteral(L, LUA_DIRSEP + "\n" + LUA_PATH_SEP + "\n" + LUA_PATH_MARK + "\n" + + LUA_EXEC_DIR + "\n" + LUA_IGMARK + "\n"); + lua_setfield(L, -2, to_luastring("config", true)); /* set field 'loaded' */ - lauxlib.luaL_getsubtable(L, lua.LUA_REGISTRYINDEX, lauxlib.LUA_LOADED_TABLE); - lua.lua_setfield(L, -2, lua.to_luastring("loaded", true)); + luaL_getsubtable(L, LUA_REGISTRYINDEX, LUA_LOADED_TABLE); + lua_setfield(L, -2, to_luastring("loaded", true)); /* set field 'preload' */ - lauxlib.luaL_getsubtable(L, lua.LUA_REGISTRYINDEX, lauxlib.LUA_PRELOAD_TABLE); - lua.lua_setfield(L, -2, lua.to_luastring("preload", true)); - lua.lua_pushglobaltable(L); - lua.lua_pushvalue(L, -2); /* set 'package' as upvalue for next lib */ - lauxlib.luaL_setfuncs(L, ll_funcs, 1); /* open lib into global table */ - lua.lua_pop(L, 1); /* pop global table */ + luaL_getsubtable(L, LUA_REGISTRYINDEX, LUA_PRELOAD_TABLE); + lua_setfield(L, -2, to_luastring("preload", true)); + lua_pushglobaltable(L); + lua_pushvalue(L, -2); /* set 'package' as upvalue for next lib */ + luaL_setfuncs(L, ll_funcs, 1); /* open lib into global table */ + lua_pop(L, 1); /* pop global table */ return 1; /* return 'package' table */ }; diff --git a/src/lobject.js b/src/lobject.js index 37419a9..4b3d0aa 100644 --- a/src/lobject.js +++ b/src/lobject.js @@ -1,24 +1,75 @@ "use strict"; -const assert = require('assert'); - -const defs = require('./defs.js'); -const ljstype = require('./ljstype.js'); +const { + LUA_OPADD, + LUA_OPBAND, + LUA_OPBNOT, + LUA_OPBOR, + LUA_OPBXOR, + LUA_OPDIV, + LUA_OPIDIV, + LUA_OPMOD, + LUA_OPMUL, + LUA_OPPOW, + LUA_OPSHL, + LUA_OPSHR, + LUA_OPSUB, + LUA_OPUNM, + constant_types: { + LUA_NUMTAGS, + LUA_TBOOLEAN, + LUA_TCCL, + LUA_TFUNCTION, + LUA_TLCF, + LUA_TLCL, + LUA_TLIGHTUSERDATA, + LUA_TLNGSTR, + LUA_TNIL, + LUA_TNUMBER, + LUA_TNUMFLT, + LUA_TNUMINT, + LUA_TSHRSTR, + LUA_TSTRING, + LUA_TTABLE, + LUA_TTHREAD, + LUA_TUSERDATA + }, + from_userstring, + luastring_indexOf, + luastring_of, + to_jsstring, + to_luastring +} = require('./defs.js'); +const { + lisdigit, + lisprint, + lisspace, + lisxdigit +} = require('./ljstype.js'); const ldebug = require('./ldebug.js'); const ldo = require('./ldo.js'); -const lfunc = require('./lfunc.js'); const lstate = require('./lstate.js'); -const lstring = require('./lstring.js'); +const { + luaS_bless, + luaS_new +} = require('./lstring.js'); const ltable = require('./ltable.js'); -const luaconf = require('./luaconf.js'); +const { + ldexp, + lua_getlocaledecpoint, + lua_integer2str, + lua_number2str +} = require('./luaconf.js'); const lvm = require('./lvm.js'); -const llimits = require('./llimits.js'); +const { + MAX_INT, + luai_nummod, + lua_assert +} = require("./llimits.js"); const ltm = require('./ltm.js'); -const CT = defs.constant_types; -const char = defs.char; -const LUA_TPROTO = CT.LUA_NUMTAGS; -const LUA_TDEADKEY = CT.LUA_NUMTAGS+1; +const LUA_TPROTO = LUA_NUMTAGS; +const LUA_TDEADKEY = LUA_NUMTAGS+1; class TValue { @@ -46,71 +97,71 @@ class TValue { } ttisnumber() { - return this.checktype(CT.LUA_TNUMBER); + return this.checktype(LUA_TNUMBER); } ttisfloat() { - return this.checktag(CT.LUA_TNUMFLT); + return this.checktag(LUA_TNUMFLT); } ttisinteger() { - return this.checktag(CT.LUA_TNUMINT); + return this.checktag(LUA_TNUMINT); } ttisnil() { - return this.checktag(CT.LUA_TNIL); + return this.checktag(LUA_TNIL); } ttisboolean() { - return this.checktag(CT.LUA_TBOOLEAN); + return this.checktag(LUA_TBOOLEAN); } ttislightuserdata() { - return this.checktag(CT.LUA_TLIGHTUSERDATA); + return this.checktag(LUA_TLIGHTUSERDATA); } ttisstring() { - return this.checktype(CT.LUA_TSTRING); + return this.checktype(LUA_TSTRING); } ttisshrstring() { - return this.checktag(CT.LUA_TSHRSTR); + return this.checktag(LUA_TSHRSTR); } ttislngstring() { - return this.checktag(CT.LUA_TLNGSTR); + return this.checktag(LUA_TLNGSTR); } ttistable() { - return this.checktag(CT.LUA_TTABLE); + return this.checktag(LUA_TTABLE); } ttisfunction() { - return this.checktype(CT.LUA_TFUNCTION); + return this.checktype(LUA_TFUNCTION); } ttisclosure() { - return (this.type & 0x1F) === CT.LUA_TFUNCTION; + return (this.type & 0x1F) === LUA_TFUNCTION; } ttisCclosure() { - return this.checktag(CT.LUA_TCCL); + return this.checktag(LUA_TCCL); } ttisLclosure() { - return this.checktag(CT.LUA_TLCL); + return this.checktag(LUA_TLCL); } ttislcf() { - return this.checktag(CT.LUA_TLCF); + return this.checktag(LUA_TLCF); } ttisfulluserdata() { - return this.checktag(CT.LUA_TUSERDATA); + return this.checktag(LUA_TUSERDATA); } ttisthread() { - return this.checktag(CT.LUA_TTHREAD); + return this.checktag(LUA_TTHREAD); } ttisdeadkey() { @@ -122,72 +173,72 @@ class TValue { } setfltvalue(x) { - this.type = CT.LUA_TNUMFLT; + this.type = LUA_TNUMFLT; this.value = x; } chgfltvalue(x) { - assert(this.type == CT.LUA_TNUMFLT); + lua_assert(this.type == LUA_TNUMFLT); this.value = x; } setivalue(x) { - this.type = CT.LUA_TNUMINT; + this.type = LUA_TNUMINT; this.value = x; } chgivalue(x) { - assert(this.type == CT.LUA_TNUMINT); + lua_assert(this.type == LUA_TNUMINT); this.value = x; } setnilvalue() { - this.type = CT.LUA_TNIL; - this.value = void 0; + this.type = LUA_TNIL; + this.value = null; } setfvalue(x) { - this.type = CT.LUA_TLCF; + this.type = LUA_TLCF; this.value = x; } setpvalue(x) { - this.type = CT.LUA_TLIGHTUSERDATA; + this.type = LUA_TLIGHTUSERDATA; this.value = x; } setbvalue(x) { - this.type = CT.LUA_TBOOLEAN; + this.type = LUA_TBOOLEAN; this.value = x; } setsvalue(x) { - this.type = CT.LUA_TLNGSTR; /* LUA_TSHRSTR? */ + this.type = LUA_TLNGSTR; /* LUA_TSHRSTR? */ this.value = x; } setuvalue(x) { - this.type = CT.LUA_TUSERDATA; + this.type = LUA_TUSERDATA; this.value = x; } setthvalue(x) { - this.type = CT.LUA_TTHREAD; + this.type = LUA_TTHREAD; this.value = x; } setclLvalue(x) { - this.type = CT.LUA_TLCL; + this.type = LUA_TLCL; this.value = x; } setclCvalue(x) { - this.type = CT.LUA_TCCL; + this.type = LUA_TCCL; this.value = x; } sethvalue(x) { - this.type = CT.LUA_TTABLE; + this.type = LUA_TTABLE; this.value = x; } @@ -202,7 +253,7 @@ class TValue { } tsvalue() { - assert(this.ttisstring()); + lua_assert(this.ttisstring()); return this.value; } @@ -215,7 +266,7 @@ class TValue { } jsstring(from, to) { - return defs.to_jsstring(this.svalue(), from, to); + return to_jsstring(this.svalue(), from, to); } } @@ -224,7 +275,7 @@ const pushobj2s = function(L, tv) { L.stack[L.top++] = new TValue(tv.type, tv.value); }; const pushsvalue2s = function(L, ts) { - L.stack[L.top++] = new TValue(CT.LUA_TLNGSTR, ts); + L.stack[L.top++] = new TValue(LUA_TLNGSTR, ts); }; /* from stack to (same) stack */ const setobjs2s = function(L, newidx, oldidx) { @@ -238,7 +289,7 @@ const setsvalue2s = function(L, newidx, ts) { L.stack[newidx].setsvalue(ts); }; -const luaO_nilobject = new TValue(CT.LUA_TNIL, null); +const luaO_nilobject = new TValue(LUA_TNIL, null); Object.freeze(luaO_nilobject); module.exports.luaO_nilobject = luaO_nilobject; @@ -249,7 +300,7 @@ class LClosure { this.p = null; this.nupvalues = n; - this.upvals = new Array(n); /* list of upvalues as UpVals. initialised in luaF_initupvals */ + this.upvals = new Array(n); /* list of upvalues. initialised in luaF_initupvals */ } } @@ -263,7 +314,7 @@ class CClosure { this.nupvalues = n; this.upvalue = new Array(n); /* list of upvalues as TValues */ while (n--) { - this.upvalue[n] = new TValue(CT.LUA_TNIL, null); + this.upvalue[n] = new TValue(LUA_TNIL, null); } } @@ -275,7 +326,7 @@ class Udata { this.id = L.l_G.id_counter++; this.metatable = null; - this.uservalue = new TValue(CT.LUA_TNIL, null); + this.uservalue = new TValue(LUA_TNIL, null); this.len = size; this.data = Object.create(null); // ignores size argument } @@ -294,23 +345,26 @@ class LocVar { } } -const RETS = defs.to_luastring("..."); -const PRE = defs.to_luastring("[string \""); -const POS = defs.to_luastring("\"]"); +const RETS = to_luastring("..."); +const PRE = to_luastring("[string \""); +const POS = to_luastring("\"]"); const luaO_chunkid = function(source, bufflen) { let l = source.length; let out; - if (source[0] === char['=']) { /* 'literal' source */ - if (l < bufflen) /* small enough? */ - out = source.slice(1); - else { /* truncate it */ - out = source.slice(1, bufflen+1); + if (source[0] === 61 /* ('=').charCodeAt(0) */) { /* 'literal' source */ + if (l < bufflen) { /* small enough? */ + out = new Uint8Array(l-1); + out.set(source.subarray(1)); + } else { /* truncate it */ + out = new Uint8Array(bufflen); + out.set(source.subarray(1, bufflen+1)); } - } else if (source[0] === char['@']) { /* file name */ - if (l <= bufflen) /* small enough? */ - out = source.slice(1); - else { /* add '...' before rest of name */ + } else if (source[0] === 64 /* ('@').charCodeAt(0) */) { /* file name */ + if (l <= bufflen) { /* small enough? */ + out = new Uint8Array(l-1); + out.set(source.subarray(1)); + } else { /* add '...' before rest of name */ out = new Uint8Array(bufflen); out.set(RETS); bufflen -= RETS.length; @@ -318,7 +372,7 @@ const luaO_chunkid = function(source, bufflen) { } } else { /* string; format as [string "source"] */ out = new Uint8Array(bufflen); - let nli = source.indexOf(char['\n']); /* find first new line (if any) */ + let nli = luastring_indexOf(source, 10 /* ('\n').charCodeAt(0) */); /* find first new line (if any) */ out.set(PRE); /* add prefix */ let out_i = PRE.length; bufflen -= PRE.length + RETS.length + POS.length; /* save space for prefix+suffix */ @@ -341,15 +395,15 @@ const luaO_chunkid = function(source, bufflen) { }; const luaO_hexavalue = function(c) { - if (ljstype.lisdigit(c)) return c - char['0']; - else return (String.fromCharCode(c).toLowerCase().charCodeAt(0) - char['a']) + 10; + if (lisdigit(c)) return c - 48; + else return (c & 0xdf) - 55; }; const UTF8BUFFSZ = 8; const luaO_utf8esc = function(buff, x) { let n = 1; /* number of bytes put in buffer (backwards) */ - assert(x <= 0x10FFFF); + lua_assert(x <= 0x10FFFF); if (x < 0x80) /* ascii? */ buff[UTF8BUFFSZ - 1] = x; else { /* need continuation bytes */ @@ -374,24 +428,24 @@ const MAXSIGDIG = 30; */ const lua_strx2number = function(s) { let i = 0; - let dot = char[luaconf.lua_getlocaledecpoint()]; + let dot = lua_getlocaledecpoint(); let r = 0.0; /* result (accumulator) */ let sigdig = 0; /* number of significant digits */ let nosigdig = 0; /* number of non-significant digits */ let e = 0; /* exponent correction */ let neg; /* 1 if number is negative */ let hasdot = false; /* true after seen a dot */ - while (ljstype.lisspace(s[i])) i++; /* skip initial spaces */ - if ((neg = (s[i] === char['-']))) i++; /* check signal */ - else if (s[i] === char['+']) i++; - if (!(s[i] === char['0'] && (s[i+1] === char['x'] || s[i+1] === char['X']))) /* check '0x' */ + while (lisspace(s[i])) i++; /* skip initial spaces */ + if ((neg = (s[i] === 45 /* ('-').charCodeAt(0) */))) i++; /* check signal */ + else if (s[i] === 43 /* ('+').charCodeAt(0) */) i++; + if (!(s[i] === 48 /* ('0').charCodeAt(0) */ && (s[i+1] === 120 /* ('x').charCodeAt(0) */ || s[i+1] === 88 /* ('X').charCodeAt(0) */))) /* check '0x' */ return null; /* invalid format (no '0x') */ for (i += 2; ; i++) { /* skip '0x' and read numeral */ if (s[i] === dot) { if (hasdot) break; /* second dot? stop loop */ else hasdot = true; - } else if (ljstype.lisxdigit(s[i])) { - if (sigdig === 0 && s[i] === char['0']) /* non-significant digit (zero)? */ + } else if (lisxdigit(s[i])) { + if (sigdig === 0 && s[i] === 48 /* ('0').charCodeAt(0) */) /* non-significant digit (zero)? */ nosigdig++; else if (++sigdig <= MAXSIGDIG) /* can read it without overflow? */ r = (r * 16) + luaO_hexavalue(s[i]); @@ -403,29 +457,29 @@ const lua_strx2number = function(s) { if (nosigdig + sigdig === 0) /* no digits? */ return null; /* invalid format */ e *= 4; /* each digit multiplies/divides value by 2^4 */ - if (s[i] === char['p'] || s[i] === char['P']) { /* exponent part? */ + if (s[i] === 112 /* ('p').charCodeAt(0) */ || s[i] === 80 /* ('P').charCodeAt(0) */) { /* exponent part? */ let exp1 = 0; /* exponent value */ let neg1; /* exponent signal */ i++; /* skip 'p' */ - if ((neg1 = (s[i] === char['-']))) i++; /* signal */ - else if (s[i] === char['+']) i++; - if (!ljstype.lisdigit(s[i])) + if ((neg1 = (s[i] === 45 /* ('-').charCodeAt(0) */))) i++; /* signal */ + else if (s[i] === 43 /* ('+').charCodeAt(0) */) i++; + if (!lisdigit(s[i])) return null; /* invalid; must have at least one digit */ - while (ljstype.lisdigit(s[i])) /* read exponent */ - exp1 = exp1 * 10 + s[i++] - char['0']; + while (lisdigit(s[i])) /* read exponent */ + exp1 = exp1 * 10 + s[i++] - 48 /* ('0').charCodeAt(0) */; if (neg1) exp1 = -exp1; e += exp1; } if (neg) r = -r; return { - n: luaconf.ldexp(r, e), + n: ldexp(r, e), i: i }; }; const lua_str2number = function(s) { try { - s = defs.to_jsstring(s); + s = to_jsstring(s); } catch (e) { return null; } @@ -441,26 +495,46 @@ const lua_str2number = function(s) { const l_str2dloc = function(s, mode) { let result = mode === 'x' ? lua_strx2number(s) : lua_str2number(s); /* try to convert */ if (result === null) return null; - while (ljstype.lisspace(s[result.i])) result.i++; /* skip trailing spaces */ + while (lisspace(s[result.i])) result.i++; /* skip trailing spaces */ return (result.i === s.length || s[result.i] === 0) ? result : null; /* OK if no trailing characters */ }; +const SIGILS = [ + 46 /* (".").charCodeAt(0) */, + 120 /* ("x").charCodeAt(0) */, + 88 /* ("X").charCodeAt(0) */, + 110 /* ("n").charCodeAt(0) */, + 78 /* ("N").charCodeAt(0) */ +]; +const modes = { + [ 46]: ".", + [120]: "x", + [ 88]: "x", + [110]: "n", + [ 78]: "n" +}; const l_str2d = function(s) { - let pidx = /[.xXnN]/g.exec(String.fromCharCode(...s)); - pidx = pidx ? pidx.index : null; - let pmode = pidx ? s[pidx] : null; - let mode = pmode ? String.fromCharCode(pmode).toLowerCase() : 0; + let l = s.length; + let pmode = 0; + for (let i=0; i<l; i++) { + let v = s[i]; + if (SIGILS.indexOf(v) !== -1) { + pmode = v; + break; + } + } + let mode = modes[pmode]; if (mode === 'n') /* reject 'inf' and 'nan' */ return null; let end = l_str2dloc(s, mode); /* try to convert */ - if (end === null) { /* failed? may be a different locale */ - // throw new Error("Locale not available to handle number"); // TODO - } + // if (end === null) { /* failed? may be a different locale */ + // throw new Error("Locale not available to handle number"); // TODO + // } return end; }; -const MAXBY10 = Math.floor(llimits.MAX_INT / 10); -const MAXLASTD = llimits.MAX_INT % 10; +const MAXBY10 = Math.floor(MAX_INT / 10); +const MAXLASTD = MAX_INT % 10; const l_str2int = function(s) { let i = 0; @@ -468,26 +542,25 @@ const l_str2int = function(s) { let empty = true; let neg; - while (ljstype.lisspace(s[i])) i++; /* skip initial spaces */ - if ((neg = (s[i] === char['-']))) i++; - else if (s[i] === char['+']) i++; - if (s[i] === char['0'] && (s[i+1] === char['x'] || s[i+1] === char['X'])) { /* hex? */ + while (lisspace(s[i])) i++; /* skip initial spaces */ + if ((neg = (s[i] === 45 /* ('-').charCodeAt(0) */))) i++; + else if (s[i] === 43 /* ('+').charCodeAt(0) */) i++; + if (s[i] === 48 /* ('0').charCodeAt(0) */ && (s[i+1] === 120 /* ('x').charCodeAt(0) */ || s[i+1] === 88 /* ('X').charCodeAt(0) */)) { /* hex? */ i += 2; /* skip '0x' */ - - for (; i < s.length && ljstype.lisxdigit(s[i]); i++) { + for (; i < s.length && lisxdigit(s[i]); i++) { a = (a * 16 + luaO_hexavalue(s[i]))|0; empty = false; } } else { /* decimal */ - for (; i < s.length && ljstype.lisdigit(s[i]); i++) { - let d = s[i] - char['0']; + for (; i < s.length && lisdigit(s[i]); i++) { + let d = s[i] - 48 /* ('0').charCodeAt(0) */; if (a >= MAXBY10 && (a > MAXBY10 || d > MAXLASTD + neg)) /* overflow? */ return null; /* do not accept it (as integer) */ a = (a * 10 + d)|0; empty = false; } } - while (i < s.length && ljstype.lisspace(s[i])) i++; /* skip trailing spaces */ + while (i < s.length && lisspace(s[i])) i++; /* skip trailing spaces */ if (empty || (i !== s.length && s[i] !== 0)) return null; /* something wrong in the numeral */ else { return { @@ -516,21 +589,21 @@ const luaO_str2num = function(s, o) { const luaO_tostring = function(L, obj) { let buff; if (obj.ttisinteger()) - buff = defs.to_luastring(luaconf.lua_integer2str(obj.value)); + buff = to_luastring(lua_integer2str(obj.value)); else { - let str = luaconf.lua_number2str(obj.value); + let str = lua_number2str(obj.value); // Assume no LUA_COMPAT_FLOATSTRING if (/^[-0123456789]+$/.test(str)) { /* looks like an int? */ - str += luaconf.lua_getlocaledecpoint() + '0'; /* adds '.0' to result */ + str += String.fromCharCode(lua_getlocaledecpoint()) + '0'; /* adds '.0' to result */ } - buff = defs.to_luastring(str); + buff = to_luastring(str); } - obj.setsvalue(lstring.luaS_bless(L, buff)); + obj.setsvalue(luaS_bless(L, buff)); }; const pushstr = function(L, str) { ldo.luaD_inctop(L); - setsvalue2s(L, L.top-1, lstring.luaS_new(L, str)); + setsvalue2s(L, L.top-1, luaS_new(L, str)); }; const luaO_pushvfstring = function(L, fmt, argp) { @@ -539,82 +612,96 @@ const luaO_pushvfstring = function(L, fmt, argp) { let a = 0; let e; for (;;) { - e = fmt.indexOf(char['%'], i); + e = luastring_indexOf(fmt, 37 /* ('%').charCodeAt(0) */, i); if (e == -1) break; pushstr(L, fmt.subarray(i, e)); switch(fmt[e+1]) { - case char['s']: { + case 115 /* ('s').charCodeAt(0) */: { let s = argp[a++]; - if (s === null) s = defs.to_luastring("(null)", true); + if (s === null) s = to_luastring("(null)", true); else { - s = defs.from_userstring(s); + s = from_userstring(s); /* respect null terminator */ - let i = s.indexOf(0); + let i = luastring_indexOf(s, 0); if (i !== -1) s = s.subarray(0, i); } pushstr(L, s); break; } - case char['c']: { + case 99 /* ('c').charCodeAt(0) */: { let buff = argp[a++]; - if (ljstype.lisprint(buff)) - pushstr(L, defs.string_of(buff)); + if (lisprint(buff)) + pushstr(L, luastring_of(buff)); else - luaO_pushfstring(L, defs.to_luastring("<\\%d>", true), buff); + luaO_pushfstring(L, to_luastring("<\\%d>", true), buff); break; } - case char['d']: - case char['I']: + case 100 /* ('d').charCodeAt(0) */: + case 73 /* ('I').charCodeAt(0) */: ldo.luaD_inctop(L); L.stack[L.top-1].setivalue(argp[a++]); luaO_tostring(L, L.stack[L.top-1]); break; - case char['f']: + case 102 /* ('f').charCodeAt(0) */: ldo.luaD_inctop(L); L.stack[L.top-1].setfltvalue(argp[a++]); luaO_tostring(L, L.stack[L.top-1]); break; - case char['p']: { + case 112 /* ('p').charCodeAt(0) */: { let v = argp[a++]; if (v instanceof lstate.lua_State || v instanceof ltable.Table || v instanceof Udata || v instanceof LClosure || - v instanceof CClosure || - v instanceof lfunc.UpVal) { - pushstr(L, defs.to_luastring("0x"+v.id.toString(16))); - } else if (v === null) { /* handle null before checking for typeof == object */ - pushstr(L, defs.to_luastring("null")); - } else if (typeof v === "function" || typeof v === "object") { - let id = L.l_G.ids.get(v); - if (!id) { - id = L.l_G.id_counter++; - L.l_G.ids.set(v, id); + v instanceof CClosure) { + pushstr(L, to_luastring("0x"+v.id.toString(16))); + } + switch(typeof v) { + case "undefined": + pushstr(L, to_luastring("undefined")); + break; + case "number": /* before check object as null is an object */ + pushstr(L, to_luastring("Number("+v+")")); + break; + case "string": /* before check object as null is an object */ + pushstr(L, to_luastring("String("+JSON.stringify(v)+")")); + break; + case "boolean": /* before check object as null is an object */ + pushstr(L, to_luastring(v?"Boolean(true)":"Boolean(false)")); + break; + case "object": + if (v === null) { /* null is special */ + pushstr(L, to_luastring("null")); + break; + } + /* fall through */ + case "function": { + let id = L.l_G.ids.get(v); + if (!id) { + id = L.l_G.id_counter++; + L.l_G.ids.set(v, id); + } + pushstr(L, to_luastring("0x"+id.toString(16))); + break; } - pushstr(L, defs.to_luastring("0x"+id.toString(16))); - } else if (v === void 0) { - pushstr(L, defs.to_luastring("undefined")); - } else if (typeof v === "number") { /* before check object as null is an object */ - pushstr(L, defs.to_luastring("Number("+v+")")); - } else if (typeof v === "string") { /* before check object as null is an object */ - pushstr(L, defs.to_luastring("String("+JSON.stringify(v)+")")); - } else if (typeof v === "boolean") { /* before check object as null is an object */ - pushstr(L, defs.to_luastring(v?"Boolean(true)":"Boolean(false)")); - } else { - /* user provided object. no id available */ - pushstr(L, defs.to_luastring("<id NYI>")); + default: + /* user provided object. no id available */ + pushstr(L, to_luastring("<id NYI>")); } break; } - case char['U']: - pushstr(L, defs.to_luastring(String.fromCodePoint(argp[a++]))); + case 85 /* ('U').charCodeAt(0) */: { + let buff = new Uint8Array(UTF8BUFFSZ); + let l = luaO_utf8esc(buff, argp[a++]); + pushstr(L, buff.subarray(UTF8BUFFSZ - l)); break; - case char['%']: - pushstr(L, defs.to_luastring("%", true)); + } + case 37 /* ('%').charCodeAt(0) */: + pushstr(L, to_luastring("%", true)); break; default: - ldebug.luaG_runerror(L, defs.to_luastring("invalid option '%%%c' to 'lua_pushfstring'"), fmt[e + 1]); + ldebug.luaG_runerror(L, to_luastring("invalid option '%%%c' to 'lua_pushfstring'"), fmt[e + 1]); } n += 2; i = e + 2; @@ -651,34 +738,34 @@ const luaO_int2fb = function(x) { const intarith = function(L, op, v1, v2) { switch (op) { - case defs.LUA_OPADD: return (v1 + v2)|0; - case defs.LUA_OPSUB: return (v1 - v2)|0; - case defs.LUA_OPMUL: return Math.imul(v1, v2); - case defs.LUA_OPMOD: return lvm.luaV_mod(L, v1, v2); - case defs.LUA_OPIDIV: return lvm.luaV_div(L, v1, v2); - case defs.LUA_OPBAND: return (v1 & v2); - case defs.LUA_OPBOR: return (v1 | v2); - case defs.LUA_OPBXOR: return (v1 ^ v2); - case defs.LUA_OPSHL: return lvm.luaV_shiftl(v1, v2); - case defs.LUA_OPSHR: return lvm.luaV_shiftl(v1, -v2); - case defs.LUA_OPUNM: return (0 - v1)|0; - case defs.LUA_OPBNOT: return (~0 ^ v1); - default: assert(0); + case LUA_OPADD: return (v1 + v2)|0; + case LUA_OPSUB: return (v1 - v2)|0; + case LUA_OPMUL: return lvm.luaV_imul(v1, v2); + case LUA_OPMOD: return lvm.luaV_mod(L, v1, v2); + case LUA_OPIDIV: return lvm.luaV_div(L, v1, v2); + case LUA_OPBAND: return (v1 & v2); + case LUA_OPBOR: return (v1 | v2); + case LUA_OPBXOR: return (v1 ^ v2); + case LUA_OPSHL: return lvm.luaV_shiftl(v1, v2); + case LUA_OPSHR: return lvm.luaV_shiftl(v1, -v2); + case LUA_OPUNM: return (0 - v1)|0; + case LUA_OPBNOT: return (~0 ^ v1); + default: lua_assert(0); } }; const numarith = function(L, op, v1, v2) { switch (op) { - case defs.LUA_OPADD: return v1 + v2; - case defs.LUA_OPSUB: return v1 - v2; - case defs.LUA_OPMUL: return v1 * v2; - case defs.LUA_OPDIV: return v1 / v2; - case defs.LUA_OPPOW: return Math.pow(v1, v2); - case defs.LUA_OPIDIV: return Math.floor(v1 / v2); - case defs.LUA_OPUNM: return -v1; - case defs.LUA_OPMOD: return llimits.luai_nummod(L, v1, v2); - default: assert(0); + case LUA_OPADD: return v1 + v2; + case LUA_OPSUB: return v1 - v2; + case LUA_OPMUL: return v1 * v2; + case LUA_OPDIV: return v1 / v2; + case LUA_OPPOW: return Math.pow(v1, v2); + case LUA_OPIDIV: return Math.floor(v1 / v2); + case LUA_OPUNM: return -v1; + case LUA_OPMOD: return luai_nummod(L, v1, v2); + default: lua_assert(0); } }; @@ -686,9 +773,9 @@ const luaO_arith = function(L, op, p1, p2, p3) { let res = (typeof p3 === "number") ? L.stack[p3] : p3; /* FIXME */ switch (op) { - case defs.LUA_OPBAND: case defs.LUA_OPBOR: case defs.LUA_OPBXOR: - case defs.LUA_OPSHL: case defs.LUA_OPSHR: - case defs.LUA_OPBNOT: { /* operate only on integers */ + case LUA_OPBAND: case LUA_OPBOR: case LUA_OPBXOR: + case LUA_OPSHL: case LUA_OPSHR: + case LUA_OPBNOT: { /* operate only on integers */ let i1, i2; if ((i1 = lvm.tointeger(p1)) !== false && (i2 = lvm.tointeger(p2)) !== false) { res.setivalue(intarith(L, op, i1, i2)); @@ -696,7 +783,7 @@ const luaO_arith = function(L, op, p1, p2, p3) { } else break; /* go to the end */ } - case defs.LUA_OPDIV: case defs.LUA_OPPOW: { /* operate only on floats */ + case LUA_OPDIV: case LUA_OPPOW: { /* operate only on floats */ let n1, n2; if ((n1 = lvm.tonumber(p1)) !== false && (n2 = lvm.tonumber(p2)) !== false) { res.setfltvalue(numarith(L, op, n1, n2)); @@ -718,8 +805,8 @@ const luaO_arith = function(L, op, p1, p2, p3) { } } /* could not perform raw operation; try metamethod */ - assert(L !== null); /* should not fail when folding (compile time) */ - ltm.luaT_trybinTM(L, p1, p2, p3, (op - defs.LUA_OPADD) + ltm.TMS.TM_ADD); + lua_assert(L !== null); /* should not fail when folding (compile time) */ + ltm.luaT_trybinTM(L, p1, p2, p3, (op - LUA_OPADD) + ltm.TMS.TM_ADD); }; diff --git a/src/loslib.js b/src/loslib.js index ecd42f1..9a8a327 100644 --- a/src/loslib.js +++ b/src/loslib.js @@ -1,26 +1,70 @@ "use strict"; -const lua = require('./lua.js'); -const lauxlib = require('./lauxlib.js'); +const { + LUA_TNIL, + LUA_TTABLE, + lua_close, + lua_createtable, + lua_getfield, + lua_isboolean, + lua_isnoneornil, + lua_pop, + lua_pushboolean, + lua_pushfstring, + lua_pushinteger, + lua_pushliteral, + lua_pushnil, + lua_pushnumber, + lua_pushstring, + lua_setfield, + lua_settop, + lua_toboolean, + lua_tointegerx +} = require('./lua.js'); +const { + luaL_Buffer, + luaL_addchar, + luaL_addstring, + // luaL_argcheck, + luaL_argerror, + luaL_buffinit, + luaL_checkinteger, + luaL_checkstring, + luaL_checktype, + luaL_error, + luaL_execresult, + luaL_fileresult, + luaL_newlib, + luaL_opt, + luaL_optinteger, + luaL_optlstring, + luaL_optstring, + luaL_pushresult +} = require('./lauxlib.js'); +const { + luastring_indexOf, + to_jsstring, + to_luastring +} = require("./fengaricore.js"); const strftime = require('strftime'); /* options for ANSI C 89 (only 1-char options) */ -const L_STRFTIMEC89 = lua.to_luastring("aAbBcdHIjmMpSUwWxXyYZ%"); +const L_STRFTIMEC89 = to_luastring("aAbBcdHIjmMpSUwWxXyYZ%"); const LUA_STRFTIMEOPTIONS = L_STRFTIMEC89; /* options for ISO C 99 and POSIX */ -// const L_STRFTIMEC99 = lua.to_luastring("aAbBcCdDeFgGhHIjmMnprRStTuUVwWxXyYzZ%||EcECExEXEyEYOdOeOHOIOmOMOSOuOUOVOwOWOy"); /* two-char options */ +// const L_STRFTIMEC99 = to_luastring("aAbBcCdDeFgGhHIjmMnprRStTuUVwWxXyYzZ%||EcECExEXEyEYOdOeOHOIOmOMOSOuOUOVOwOWOy"); /* two-char options */ // const LUA_STRFTIMEOPTIONS = L_STRFTIMEC99; /* options for Windows */ -// const L_STRFTIMEWIN = lua.to_luastring("aAbBcdHIjmMpSUwWxXyYzZ%||#c#x#d#H#I#j#m#M#S#U#w#W#y#Y"); /* two-char options */ +// const L_STRFTIMEWIN = to_luastring("aAbBcdHIjmMpSUwWxXyYzZ%||#c#x#d#H#I#j#m#M#S#U#w#W#y#Y"); /* two-char options */ // const LUA_STRFTIMEOPTIONS = L_STRFTIMEWIN; const setfield = function(L, key, value) { - lua.lua_pushinteger(L, value); - lua.lua_setfield(L, -2, lua.to_luastring(key, true)); + lua_pushinteger(L, value); + lua_setfield(L, -2, to_luastring(key, true)); }; const setallfields = function(L, time, utc) { @@ -39,21 +83,21 @@ const setallfields = function(L, time, utc) { const L_MAXDATEFIELD = (Number.MAX_SAFE_INTEGER / 2); const getfield = function(L, key, d, delta) { - let t = lua.lua_getfield(L, -1, lua.to_luastring(key, true)); /* get field and its type */ - let res = lua.lua_tointegerx(L, -1); + let t = lua_getfield(L, -1, to_luastring(key, true)); /* get field and its type */ + let res = lua_tointegerx(L, -1); if (res === false) { /* field is not an integer? */ - if (t !== lua.LUA_TNIL) /* some other value? */ - return lauxlib.luaL_error(L, lua.to_luastring("field '%s' is not an integer"), key); + if (t !== LUA_TNIL) /* some other value? */ + return luaL_error(L, to_luastring("field '%s' is not an integer"), key); else if (d < 0) /* absent field; no default? */ - return lauxlib.luaL_error(L, lua.to_luastring("field '%s' missing in date table"), key); + return luaL_error(L, to_luastring("field '%s' missing in date table"), key); res = d; } else { if (!(-L_MAXDATEFIELD <= res && res <= L_MAXDATEFIELD)) - return lauxlib.luaL_error(L, lua.to_luastring("field '%s' is out-of-bound"), key); + return luaL_error(L, to_luastring("field '%s' is out-of-bound"), key); res -= delta; } - lua.lua_pop(L, 1); + lua_pop(L, 1); return res; }; @@ -73,12 +117,12 @@ const checkoption = function(L, conv, i, buff) { if (option[o] === '|'.charCodeAt(0)) /* next block? */ oplen++; /* will check options with next length (+1) */ else if (array_cmp(conv, i, option, o, oplen)) { /* match? */ - buff.set(conv.slice(i, i+oplen)); /* copy valid option to buffer */ + buff.set(conv.subarray(i, i+oplen)); /* copy valid option to buffer */ return i + oplen; /* return next item */ } } - lauxlib.luaL_argerror(L, 1, - lua.lua_pushfstring(L, lua.to_luastring("invalid conversion specifier '%%%s'"), conv)); + luaL_argerror(L, 1, + lua_pushfstring(L, to_luastring("invalid conversion specifier '%%%s'"), conv)); }; /* maximum size for an individual 'strftime' item */ @@ -86,8 +130,8 @@ const checkoption = function(L, conv, i, buff) { const os_date = function(L) { - let s = lauxlib.luaL_optlstring(L, 1, lua.to_luastring("%c")); - let t = lauxlib.luaL_opt(L, l_checktime, 2, new Date().getTime() / 1000) * 1000; + let s = luaL_optlstring(L, 1, to_luastring("%c")); + let t = luaL_opt(L, l_checktime, 2, new Date().getTime() / 1000) * 1000; let stm = new Date(t); let utc = false; let i = 0; @@ -97,38 +141,38 @@ const os_date = function(L) { } if (stm === null) /* invalid date? */ - lauxlib.luaL_error(L, lua.to_luastring("time result cannot be represented in this installation", true)); + luaL_error(L, to_luastring("time result cannot be represented in this installation", true)); if (s[i] === "*".charCodeAt(0) && s[i+1] === "t".charCodeAt(0)) { - lua.lua_createtable(L, 0, 9); /* 9 = number of fields */ + lua_createtable(L, 0, 9); /* 9 = number of fields */ setallfields(L, stm, utc); } else { let cc = new Uint8Array(4); cc[0] = "%".charCodeAt(0); - let b = new lauxlib.luaL_Buffer(); - lauxlib.luaL_buffinit(L, b); + let b = new luaL_Buffer(); + luaL_buffinit(L, b); while (i < s.length) { if (s[i] !== '%'.charCodeAt(0)) { /* not a conversion specifier? */ - lauxlib.luaL_addchar(b, s[i++]); + luaL_addchar(b, s[i++]); } else { i++; /* skip '%' */ i = checkoption(L, s, i, cc.subarray(1)); /* copy specifier to 'cc' */ - let len = cc.indexOf(0); + let len = luastring_indexOf(cc, 0); if (len !== -1) cc = cc.subarray(0, len); - let buff = strftime(lua.to_jsstring(cc), stm); - lauxlib.luaL_addstring(b, lua.to_luastring(buff)); + let buff = strftime(to_jsstring(cc), stm); + luaL_addstring(b, to_luastring(buff)); } } - lauxlib.luaL_pushresult(b); + luaL_pushresult(b); } return 1; }; const os_time = function(L) { let t = new Date(); - if (!lua.lua_isnoneornil(L, 1)) /* called with arg */{ - lauxlib.luaL_checktype(L, 1, lua.LUA_TTABLE); /* make sure table is at the top */ - lua.lua_settop(L, 1); + if (!lua_isnoneornil(L, 1)) /* called with arg */{ + luaL_checktype(L, 1, LUA_TTABLE); /* make sure table is at the top */ + lua_settop(L, 1); t.setSeconds(getfield(L, "sec", 0, 0)); t.setMinutes(getfield(L, "min", 0, 0)); t.setHours(getfield(L, "hour", 12, 0)); @@ -138,20 +182,20 @@ const os_time = function(L) { setallfields(L, t); } - lua.lua_pushinteger(L, Math.floor(t / 1000)); + lua_pushinteger(L, Math.floor(t / 1000)); return 1; }; const l_checktime = function(L, arg) { - let t = lauxlib.luaL_checkinteger(L, arg); - // lauxlib.luaL_argcheck(L, t, arg, lua.to_luastring("time out-of-bounds")); + let t = luaL_checkinteger(L, arg); + // luaL_argcheck(L, t, arg, to_luastring("time out-of-bounds")); return t; }; const os_difftime = function(L) { let t1 = l_checktime(L, 1); let t2 = l_checktime(L, 2); - lua.lua_pushnumber(L, new Date(t1) - new Date(t2)); + lua_pushnumber(L, new Date(t1) - new Date(t2)); return 1; }; @@ -163,7 +207,7 @@ const syslib = { if (typeof process === "undefined") { syslib.clock = function(L) { - lua.lua_pushnumber(L, performance.now()/1000); + lua_pushnumber(L, performance.now()/1000); return 1; }; } else { @@ -174,29 +218,29 @@ if (typeof process === "undefined") { syslib.exit = function(L) { let status; - if (lua.lua_isboolean(L, 1)) - status = (lua.lua_toboolean(L, 1) ? 0 : 1); + if (lua_isboolean(L, 1)) + status = (lua_toboolean(L, 1) ? 0 : 1); else - status = lauxlib.luaL_optinteger(L, 1, 0); - if (lua.lua_toboolean(L, 2)) - lua.lua_close(L); + status = luaL_optinteger(L, 1, 0); + if (lua_toboolean(L, 2)) + lua_close(L); if (L) process.exit(status); /* 'if' to avoid warnings for unreachable 'return' */ return 0; }; syslib.getenv = function(L) { - let key = lauxlib.luaL_checkstring(L, 1); - key = lua.to_jsstring(key); /* https://github.com/nodejs/node/issues/16961 */ + let key = luaL_checkstring(L, 1); + key = to_jsstring(key); /* https://github.com/nodejs/node/issues/16961 */ if (Object.prototype.hasOwnProperty.call(process.env, key)) { - lua.lua_pushliteral(L, process.env[key]); + lua_pushliteral(L, process.env[key]); } else { - lua.lua_pushnil(L); + lua_pushnil(L); } return 1; }; syslib.clock = function(L) { - lua.lua_pushnumber(L, process.uptime()); + lua_pushnumber(L, process.uptime()); return 1; }; @@ -206,7 +250,7 @@ if (typeof process === "undefined") { }; syslib.remove = function(L) { - let filename = lauxlib.luaL_checkstring(L, 1); + let filename = luaL_checkstring(L, 1); try { if (fs.lstatSync(filename).isDirectory()) { fs.rmdirSync(filename); @@ -214,32 +258,32 @@ if (typeof process === "undefined") { fs.unlinkSync(filename); } } catch (e) { - return lauxlib.luaL_fileresult(L, false, filename, e); + return luaL_fileresult(L, false, filename, e); } - return lauxlib.luaL_fileresult(L, true); + return luaL_fileresult(L, true); }; syslib.rename = function(L) { - let fromname = lauxlib.luaL_checkstring(L, 1); - let toname = lauxlib.luaL_checkstring(L, 2); + let fromname = luaL_checkstring(L, 1); + let toname = luaL_checkstring(L, 2); try { fs.renameSync(fromname, toname); } catch (e) { - return lauxlib.luaL_fileresult(L, false, false, e); + return luaL_fileresult(L, false, false, e); } - return lauxlib.luaL_fileresult(L, true); + return luaL_fileresult(L, true); }; syslib.tmpname = function(L) { let name = lua_tmpname(); if (!name) - return lauxlib.luaL_error(L, lua.to_luastring("unable to generate a unique filename")); - lua.lua_pushstring(L, lua.to_luastring(name)); + return luaL_error(L, to_luastring("unable to generate a unique filename")); + lua_pushstring(L, to_luastring(name)); return 1; }; syslib.execute = function(L) { - let cmd = lauxlib.luaL_optstring(L, 1, null); + let cmd = luaL_optstring(L, 1, null); if (cmd !== null) { try { child_process.execSync( @@ -249,23 +293,23 @@ if (typeof process === "undefined") { } ); } catch (e) { - return lauxlib.luaL_execresult(L, e); + return luaL_execresult(L, e); } - return lauxlib.luaL_execresult(L, null); + return luaL_execresult(L, null); } else { /* Assume a shell is available. If it's good enough for musl it's good enough for us. http://git.musl-libc.org/cgit/musl/tree/src/process/system.c?id=ac45692a53a1b8d2ede329d91652d43c1fb5dc8d#n22 */ - lua.lua_pushboolean(L, 1); + lua_pushboolean(L, 1); return 1; } }; } const luaopen_os = function(L) { - lauxlib.luaL_newlib(L, syslib); + luaL_newlib(L, syslib); return 1; }; diff --git a/src/lparser.js b/src/lparser.js index d183d25..a427424 100644 --- a/src/lparser.js +++ b/src/lparser.js @@ -1,23 +1,117 @@ "use strict"; -const assert = require('assert'); - -const defs = require('./defs.js'); -const lcode = require('./lcode.js'); +const { + LUA_MULTRET, + to_luastring +} = require('./defs.js'); +const { + BinOpr: { + OPR_ADD, + OPR_AND, + OPR_BAND, + OPR_BOR, + OPR_BXOR, + OPR_CONCAT, + OPR_DIV, + OPR_EQ, + OPR_GE, + OPR_GT, + OPR_IDIV, + OPR_LE, + OPR_LT, + OPR_MOD, + OPR_MUL, + OPR_NE, + OPR_NOBINOPR, + OPR_OR, + OPR_POW, + OPR_SHL, + OPR_SHR, + OPR_SUB + }, + UnOpr: { + OPR_BNOT, + OPR_LEN, + OPR_MINUS, + OPR_NOT, + OPR_NOUNOPR + }, + NO_JUMP, + getinstruction, + luaK_checkstack, + luaK_codeABC, + luaK_codeABx, + luaK_codeAsBx, + luaK_codek, + luaK_concat, + luaK_dischargevars, + luaK_exp2RK, + luaK_exp2anyreg, + luaK_exp2anyregup, + luaK_exp2nextreg, + luaK_exp2val, + luaK_fixline, + luaK_getlabel, + luaK_goiffalse, + luaK_goiftrue, + luaK_indexed, + luaK_infix, + luaK_intK, + luaK_jump, + luaK_jumpto, + luaK_nil, + luaK_patchclose, + luaK_patchlist, + luaK_patchtohere, + luaK_posfix, + luaK_prefix, + luaK_reserveregs, + luaK_ret, + luaK_self, + luaK_setlist, + luaK_setmultret, + luaK_setoneret, + luaK_setreturns, + luaK_storevar, + luaK_stringK +} = require('./lcode.js'); const ldo = require('./ldo.js'); const lfunc = require('./lfunc.js'); const llex = require('./llex.js'); -const llimits = require('./llimits.js'); +const { + LUAI_MAXCCALLS, + MAX_INT, + lua_assert +} = require('./llimits.js'); const lobject = require('./lobject.js'); -const lopcodes = require('./lopcodes.js'); -const lstring = require('./lstring.js'); +const { + OpCodesI: { + OP_CALL, + OP_CLOSURE, + OP_FORLOOP, + OP_FORPREP, + OP_GETUPVAL, + OP_MOVE, + OP_NEWTABLE, + OP_SETTABLE, + OP_TAILCALL, + OP_TFORCALL, + OP_TFORLOOP, + OP_VARARG + }, + LFIELDS_PER_FLUSH, + SETARG_B, + SETARG_C, + SET_OPCODE +} = require('./lopcodes.js'); +const { + luaS_eqlngstr, + luaS_new, + luaS_newliteral +} = require('./lstring.js'); const ltable = require('./ltable.js'); -const BinOpr = lcode.BinOpr; -const OpCodesI = lopcodes.OpCodesI; const Proto = lfunc.Proto; const R = llex.RESERVED; -const UnOpr = lcode.UnOpr; -const char = defs.char; const MAXVARS = 200; @@ -27,7 +121,7 @@ const hasmultret = function(k) { const eqstr = function(a, b) { /* TODO: use plain equality as strings are cached */ - return lstring.luaS_eqlngstr(a, b); + return luaS_eqlngstr(a, b); }; class BlockCnt { @@ -165,16 +259,16 @@ const semerror = function(ls, msg) { }; const error_expected = function(ls, token) { - llex.luaX_syntaxerror(ls, lobject.luaO_pushfstring(ls.L, defs.to_luastring("%s expected", true), llex.luaX_token2str(ls, token))); + llex.luaX_syntaxerror(ls, lobject.luaO_pushfstring(ls.L, to_luastring("%s expected", true), llex.luaX_token2str(ls, token))); }; const errorlimit = function(fs, limit, what) { let L = fs.ls.L; let line = fs.f.linedefined; let where = (line === 0) - ? defs.to_luastring("main function", true) - : lobject.luaO_pushfstring(L, defs.to_luastring("function at line %d", true), line); - let msg = lobject.luaO_pushfstring(L, defs.to_luastring("too many %s (limit is %d) in %s", true), + ? to_luastring("main function", true) + : lobject.luaO_pushfstring(L, to_luastring("function at line %d", true), line); + let msg = lobject.luaO_pushfstring(L, to_luastring("too many %s (limit is %d) in %s", true), what, limit, where); llex.luaX_syntaxerror(fs.ls, msg); }; @@ -213,7 +307,7 @@ const check_match = function(ls, what, who, where) { error_expected(ls, what); else llex.luaX_syntaxerror(ls, lobject.luaO_pushfstring(ls.L, - defs.to_luastring("%s expected (to close %s at line %d)"), + to_luastring("%s expected (to close %s at line %d)"), llex.luaX_token2str(ls, what), llex.luaX_token2str(ls, who), where)); } }; @@ -226,13 +320,13 @@ const str_checkname = function(ls) { }; const init_exp = function(e, k, i) { - e.f = e.t = lcode.NO_JUMP; + e.f = e.t = NO_JUMP; e.k = k; e.u.info = i; }; const codestring = function(ls, e, s) { - init_exp(e, expkind.VK, lcode.luaK_stringK(ls.fs, s)); + init_exp(e, expkind.VK, luaK_stringK(ls.fs, s)); }; const checkname = function(ls, e) { @@ -251,19 +345,19 @@ const new_localvar = function(ls, name) { let fs = ls.fs; let dyd = ls.dyd; let reg = registerlocalvar(ls, name); - checklimit(fs, dyd.actvar.n + 1 - fs.firstlocal, MAXVARS, defs.to_luastring("local variables", true)); + checklimit(fs, dyd.actvar.n + 1 - fs.firstlocal, MAXVARS, to_luastring("local variables", true)); dyd.actvar.arr[dyd.actvar.n] = new Vardesc(); dyd.actvar.arr[dyd.actvar.n].idx = reg; dyd.actvar.n++; }; const new_localvarliteral = function(ls, name) { - new_localvar(ls, llex.luaX_newstring(ls, defs.to_luastring(name, true))); + new_localvar(ls, llex.luaX_newstring(ls, to_luastring(name, true))); }; const getlocvar = function(fs, i) { let idx = fs.ls.dyd.actvar.arr[fs.firstlocal + i].idx; - assert(idx < fs.nlocvars); + lua_assert(idx < fs.nlocvars); return fs.f.locvars[idx]; }; @@ -291,7 +385,7 @@ const searchupvalue = function(fs, name) { const newupvalue = function(fs, name, v) { let f = fs.f; - checklimit(fs, fs.nups + 1, lfunc.MAXUPVAL, defs.to_luastring("upvalues", true)); + checklimit(fs, fs.nups + 1, lfunc.MAXUPVAL, to_luastring("upvalues", true)); f.upvalues[fs.nups] = { instack: v.k === expkind.VLOCAL, idx: v.u.info, @@ -354,9 +448,9 @@ const singlevar = function(ls, vr) { if (vr.k === expkind.VVOID) { /* is global name? */ let key = new expdesc(); singlevaraux(fs, ls.envn, vr, 1); /* get environment variable */ - assert(vr.k !== expkind.VVOID); /* this one must exist */ + lua_assert(vr.k !== expkind.VVOID); /* this one must exist */ codestring(ls, key, varname); /* key is variable name */ - lcode.luaK_indexed(fs, vr, key); /* env[varname] */ + luaK_indexed(fs, vr, key); /* env[varname] */ } }; @@ -366,14 +460,14 @@ const adjust_assign = function(ls, nvars, nexps, e) { if (hasmultret(e.k)) { extra++; /* includes call itself */ if (extra < 0) extra = 0; - lcode.luaK_setreturns(fs, e, extra); /* last exp. provides the difference */ - if (extra > 1) lcode.luaK_reserveregs(fs, extra - 1); + luaK_setreturns(fs, e, extra); /* last exp. provides the difference */ + if (extra > 1) luaK_reserveregs(fs, extra - 1); } else { - if (e.k !== expkind.VVOID) lcode.luaK_exp2nextreg(fs, e); /* close last expression */ + if (e.k !== expkind.VVOID) luaK_exp2nextreg(fs, e); /* close last expression */ if (extra > 0) { let reg = fs.freereg; - lcode.luaK_reserveregs(fs, extra); - lcode.luaK_nil(fs, reg, extra); + luaK_reserveregs(fs, extra); + luaK_nil(fs, reg, extra); } } if (nexps > nvars) @@ -383,7 +477,7 @@ const adjust_assign = function(ls, nvars, nexps, e) { const enterlevel = function(ls) { let L = ls.L; ++L.nCcalls; - checklimit(ls.fs, L.nCcalls, llimits.LUAI_MAXCCALLS, defs.to_luastring("JS levels", true)); + checklimit(ls.fs, L.nCcalls, LUAI_MAXCCALLS, to_luastring("JS levels", true)); }; const leavelevel = function(ls) { @@ -394,15 +488,15 @@ const closegoto = function(ls, g, label) { let fs = ls.fs; let gl = ls.dyd.gt; let gt = gl.arr[g]; - assert(eqstr(gt.name, label.name)); + lua_assert(eqstr(gt.name, label.name)); if (gt.nactvar < label.nactvar) { let vname = getlocvar(fs, gt.nactvar).varname; let msg = lobject.luaO_pushfstring(ls.L, - defs.to_luastring("<goto %s> at line %d jumps into the scope of local '%s'"), + to_luastring("<goto %s> at line %d jumps into the scope of local '%s'"), gt.name.getstr(), gt.line, vname.getstr()); semerror(ls, msg); } - lcode.luaK_patchlist(fs, gt.pc, label.pc); + luaK_patchlist(fs, gt.pc, label.pc); /* remove goto from pending list */ for (let i = g; i < gl.n - 1; i++) gl.arr[i] = gl.arr[i + 1]; @@ -421,7 +515,7 @@ const findlabel = function(ls, g) { let lb = dyd.label.arr[i]; if (eqstr(lb.name, gt.name)) { /* correct label? */ if (gt.nactvar > lb.nactvar && (bl.upval || dyd.label.n > bl.firstlabel)) - lcode.luaK_patchclose(ls.fs, gt.pc, lb.nactvar); + luaK_patchclose(ls.fs, gt.pc, lb.nactvar); closegoto(ls, g, lb); /* close it */ return true; } @@ -470,7 +564,7 @@ const movegotosout = function(fs, bl) { let gt = gl.arr[i]; if (gt.nactvar > bl.nactvar) { if (bl.upval) - lcode.luaK_patchclose(fs, gt.pc, bl.nactvar); + luaK_patchclose(fs, gt.pc, bl.nactvar); gt.nactvar = bl.nactvar; } if (!findlabel(fs.ls, i)) @@ -486,14 +580,14 @@ const enterblock = function(fs, bl, isloop) { bl.upval = 0; bl.previous = fs.bl; fs.bl = bl; - assert(fs.freereg === fs.nactvar); + lua_assert(fs.freereg === fs.nactvar); }; /* ** create a label named 'break' to resolve break statements */ const breaklabel = function(ls) { - let n = lstring.luaS_newliteral(ls.L, "break"); + let n = luaS_newliteral(ls.L, "break"); let l = newlabelentry(ls, ls.dyd.label, n, 0, ls.fs.pc); findgotos(ls, ls.dyd.label.arr[l]); }; @@ -506,7 +600,7 @@ const undefgoto = function(ls, gt) { let msg = llex.isreserved(gt.name) ? "<%s> at line %d not inside a loop" : "no visible label '%s' for <goto> at line %d"; - msg = lobject.luaO_pushfstring(ls.L, defs.to_luastring(msg), gt.name.getstr(), gt.line); + msg = lobject.luaO_pushfstring(ls.L, to_luastring(msg), gt.name.getstr(), gt.line); semerror(ls, msg); }; @@ -527,8 +621,8 @@ const addprototype = function(ls) { */ const codeclosure = function(ls, v) { let fs = ls.fs.prev; - init_exp(v, expkind.VRELOCABLE, lcode.luaK_codeABx(fs, OpCodesI.OP_CLOSURE, 0, fs.np -1)); - lcode.luaK_exp2nextreg(fs, v); /* fix it at the last register */ + init_exp(v, expkind.VRELOCABLE, luaK_codeABx(fs, OP_CLOSURE, 0, fs.np -1)); + luaK_exp2nextreg(fs, v); /* fix it at the last register */ }; const open_func = function(ls, fs, bl) { @@ -537,7 +631,7 @@ const open_func = function(ls, fs, bl) { ls.fs = fs; fs.pc = 0; fs.lasttarget = 0; - fs.jpc = lcode.NO_JUMP; + fs.jpc = NO_JUMP; fs.freereg = 0; fs.nk = 0; fs.np = 0; @@ -558,9 +652,9 @@ const leaveblock = function(fs) { let ls = fs.ls; if (bl.previous && bl.upval) { /* create a 'jump to here' to close upvalues */ - let j = lcode.luaK_jump(fs); - lcode.luaK_patchclose(fs, j , bl.nactvar); - lcode.luaK_patchtohere(fs, j); + let j = luaK_jump(fs); + luaK_patchclose(fs, j , bl.nactvar); + luaK_patchtohere(fs, j); } if (bl.isloop) @@ -568,7 +662,7 @@ const leaveblock = function(fs) { fs.bl = bl.previous; removevars(fs, bl.nactvar); - assert(bl.nactvar === fs.nactvar); + lua_assert(bl.nactvar === fs.nactvar); fs.freereg = fs.nactvar; /* free registers */ ls.dyd.label.n = bl.firstlabel; /* remove local labels */ if (bl.previous) /* inner block? */ @@ -579,9 +673,9 @@ const leaveblock = function(fs) { const close_func = function(ls) { let fs = ls.fs; - lcode.luaK_ret(fs, 0, 0); /* final return */ + luaK_ret(fs, 0, 0); /* final return */ leaveblock(fs); - assert(fs.bl === null); + lua_assert(fs.bl === null); ls.fs = fs.prev; }; @@ -614,18 +708,18 @@ const fieldsel = function(ls, v) { /* fieldsel -> ['.' | ':'] NAME */ let fs = ls.fs; let key = new expdesc(); - lcode.luaK_exp2anyregup(fs, v); + luaK_exp2anyregup(fs, v); llex.luaX_next(ls); /* skip the dot or colon */ checkname(ls, key); - lcode.luaK_indexed(fs, v, key); + luaK_indexed(fs, v, key); }; const yindex = function(ls, v) { /* index -> '[' expr ']' */ llex.luaX_next(ls); /* skip the '[' */ expr(ls, v); - lcode.luaK_exp2val(ls.fs, v); - checknext(ls, char[']']); + luaK_exp2val(ls.fs, v); + checknext(ls, 93 /* (']').charCodeAt(0) */); }; /* @@ -652,24 +746,24 @@ const recfield = function(ls, cc) { let val = new expdesc(); if (ls.t.token === R.TK_NAME) { - checklimit(fs, cc.nh, llimits.MAX_INT, defs.to_luastring("items in a constructor", true)); + checklimit(fs, cc.nh, MAX_INT, to_luastring("items in a constructor", true)); checkname(ls, key); } else /* ls->t.token === '[' */ yindex(ls, key); cc.nh++; - checknext(ls, char['=']); - let rkkey = lcode.luaK_exp2RK(fs, key); + checknext(ls, 61 /* ('=').charCodeAt(0) */); + let rkkey = luaK_exp2RK(fs, key); expr(ls, val); - lcode.luaK_codeABC(fs, OpCodesI.OP_SETTABLE, cc.t.u.info, rkkey, lcode.luaK_exp2RK(fs, val)); + luaK_codeABC(fs, OP_SETTABLE, cc.t.u.info, rkkey, luaK_exp2RK(fs, val)); fs.freereg = reg; /* free registers */ }; const closelistfield = function(fs, cc) { if (cc.v.k === expkind.VVOID) return; /* there is no list item */ - lcode.luaK_exp2nextreg(fs, cc.v); + luaK_exp2nextreg(fs, cc.v); cc.v.k = expkind.VVOID; - if (cc.tostore === lopcodes.LFIELDS_PER_FLUSH) { - lcode.luaK_setlist(fs, cc.t.u.info, cc.na, cc.tostore); /* flush */ + if (cc.tostore === LFIELDS_PER_FLUSH) { + luaK_setlist(fs, cc.t.u.info, cc.na, cc.tostore); /* flush */ cc.tostore = 0; /* no more items pending */ } }; @@ -677,20 +771,20 @@ const closelistfield = function(fs, cc) { const lastlistfield = function(fs, cc) { if (cc.tostore === 0) return; if (hasmultret(cc.v.k)) { - lcode.luaK_setmultret(fs, cc.v); - lcode.luaK_setlist(fs, cc.t.u.info, cc.na, defs.LUA_MULTRET); + luaK_setmultret(fs, cc.v); + luaK_setlist(fs, cc.t.u.info, cc.na, LUA_MULTRET); cc.na--; /* do not count last expression (unknown number of elements) */ } else { if (cc.v.k !== expkind.VVOID) - lcode.luaK_exp2nextreg(fs, cc.v); - lcode.luaK_setlist(fs, cc.t.u.info, cc.na, cc.tostore); + luaK_exp2nextreg(fs, cc.v); + luaK_setlist(fs, cc.t.u.info, cc.na, cc.tostore); } }; const listfield = function(ls, cc) { /* listfield -> exp */ expr(ls, cc.v); - checklimit(ls.fs, cc.na, llimits.MAX_INT, defs.to_luastring("items in a constructor", true)); + checklimit(ls.fs, cc.na, MAX_INT, to_luastring("items in a constructor", true)); cc.na++; cc.tostore++; }; @@ -699,13 +793,13 @@ const field = function(ls, cc) { /* field -> listfield | recfield */ switch (ls.t.token) { case R.TK_NAME: { /* may be 'listfield' or 'recfield' */ - if (llex.luaX_lookahead(ls) !== char['=']) /* expression? */ + if (llex.luaX_lookahead(ls) !== 61 /* ('=').charCodeAt(0) */) /* expression? */ listfield(ls, cc); else recfield(ls, cc); break; } - case char['[']: { + case 91 /* ('[').charCodeAt(0) */: { recfield(ls, cc); break; } @@ -721,24 +815,24 @@ const constructor = function(ls, t) { sep -> ',' | ';' */ let fs = ls.fs; let line = ls.linenumber; - let pc = lcode.luaK_codeABC(fs, OpCodesI.OP_NEWTABLE, 0, 0, 0); + let pc = luaK_codeABC(fs, OP_NEWTABLE, 0, 0, 0); let cc = new ConsControl(); cc.na = cc.nh = cc.tostore = 0; cc.t = t; init_exp(t, expkind.VRELOCABLE, pc); init_exp(cc.v, expkind.VVOID, 0); /* no value (yet) */ - lcode.luaK_exp2nextreg(ls.fs, t); /* fix it at stack top */ - checknext(ls, char['{']); + luaK_exp2nextreg(ls.fs, t); /* fix it at stack top */ + checknext(ls, 123 /* ('{').charCodeAt(0) */); do { - assert(cc.v.k === expkind.VVOID || cc.tostore > 0); - if (ls.t.token === char['}']) break; + lua_assert(cc.v.k === expkind.VVOID || cc.tostore > 0); + if (ls.t.token === 125 /* ('}').charCodeAt(0) */) break; closelistfield(fs, cc); field(ls, cc); - } while (testnext(ls, char[',']) || testnext(ls, char[';'])); - check_match(ls, char['}'], char['{'], line); + } while (testnext(ls, 44 /* (',').charCodeAt(0) */) || testnext(ls, 59 /* (';').charCodeAt(0) */)); + check_match(ls, 125 /* ('}').charCodeAt(0) */, 123 /* ('{').charCodeAt(0) */, line); lastlistfield(fs, cc); - lopcodes.SETARG_B(fs.f.code[pc], lobject.luaO_int2fb(cc.na)); /* set initial array size */ - lopcodes.SETARG_C(fs.f.code[pc], lobject.luaO_int2fb(cc.nh)); /* set initial table size */ + SETARG_B(fs.f.code[pc], lobject.luaO_int2fb(cc.na)); /* set initial array size */ + SETARG_C(fs.f.code[pc], lobject.luaO_int2fb(cc.nh)); /* set initial table size */ }; /* }====================================================================== */ @@ -749,7 +843,7 @@ const parlist = function(ls) { let f = fs.f; let nparams = 0; f.is_vararg = false; - if (ls.t.token !== char[')']) { /* is 'parlist' not empty? */ + if (ls.t.token !== 41 /* (')').charCodeAt(0) */) { /* is 'parlist' not empty? */ do { switch (ls.t.token) { case R.TK_NAME: { /* param -> NAME */ @@ -762,13 +856,13 @@ const parlist = function(ls) { f.is_vararg = true; /* declared vararg */ break; } - default: llex.luaX_syntaxerror(ls, defs.to_luastring("<name> or '...' expected", true)); + default: llex.luaX_syntaxerror(ls, to_luastring("<name> or '...' expected", true)); } - } while(!f.is_vararg && testnext(ls, char[','])); + } while(!f.is_vararg && testnext(ls, 44 /* (',').charCodeAt(0) */)); } adjustlocalvars(ls, nparams); f.numparams = fs.nactvar; - lcode.luaK_reserveregs(fs, fs.nactvar); /* reserve register for parameters */ + luaK_reserveregs(fs, fs.nactvar); /* reserve register for parameters */ }; const body = function(ls, e, ismethod, line) { @@ -778,13 +872,13 @@ const body = function(ls, e, ismethod, line) { new_fs.f = addprototype(ls); new_fs.f.linedefined = line; open_func(ls, new_fs, bl); - checknext(ls, char['(']); + checknext(ls, 40 /* ('(').charCodeAt(0) */); if (ismethod) { new_localvarliteral(ls, "self"); /* create 'self' parameter */ adjustlocalvars(ls, 1); } parlist(ls); - checknext(ls, char[')']); + checknext(ls, 41 /* (')').charCodeAt(0) */); statlist(ls); new_fs.f.lastlinedefined = ls.linenumber; check_match(ls, R.TK_END, R.TK_FUNCTION, line); @@ -796,8 +890,8 @@ const explist = function(ls, v) { /* explist -> expr { ',' expr } */ let n = 1; /* at least one expression */ expr(ls, v); - while (testnext(ls, char[','])) { - lcode.luaK_exp2nextreg(ls.fs, v); + while (testnext(ls, 44 /* (',').charCodeAt(0) */)) { + luaK_exp2nextreg(ls.fs, v); expr(ls, v); n++; } @@ -808,18 +902,18 @@ const funcargs = function(ls, f, line) { let fs = ls.fs; let args = new expdesc(); switch (ls.t.token) { - case char['(']: { /* funcargs -> '(' [ explist ] ')' */ + case 40 /* ('(').charCodeAt(0) */: { /* funcargs -> '(' [ explist ] ')' */ llex.luaX_next(ls); - if (ls.t.token === char[')']) /* arg list is empty? */ + if (ls.t.token === 41 /* (')').charCodeAt(0) */) /* arg list is empty? */ args.k = expkind.VVOID; else { explist(ls, args); - lcode.luaK_setmultret(fs, args); + luaK_setmultret(fs, args); } - check_match(ls, char[')'], char['('], line); + check_match(ls, 41 /* (')').charCodeAt(0) */, 40 /* ('(').charCodeAt(0) */, line); break; } - case char['{']: { /* funcargs -> constructor */ + case 123 /* ('{').charCodeAt(0) */: { /* funcargs -> constructor */ constructor(ls, args); break; } @@ -829,21 +923,21 @@ const funcargs = function(ls, f, line) { break; } default: { - llex.luaX_syntaxerror(ls, defs.to_luastring("function arguments expected", true)); + llex.luaX_syntaxerror(ls, to_luastring("function arguments expected", true)); } } - assert(f.k === expkind.VNONRELOC); + lua_assert(f.k === expkind.VNONRELOC); let nparams; let base = f.u.info; /* base register for call */ if (hasmultret(args.k)) - nparams = defs.LUA_MULTRET; /* open call */ + nparams = LUA_MULTRET; /* open call */ else { if (args.k !== expkind.VVOID) - lcode.luaK_exp2nextreg(fs, args); /* close last argument */ + luaK_exp2nextreg(fs, args); /* close last argument */ nparams = fs.freereg - (base+1); } - init_exp(f, expkind.VCALL, lcode.luaK_codeABC(fs, OpCodesI.OP_CALL, base, nparams+1, 2)); - lcode.luaK_fixline(fs, line); + init_exp(f, expkind.VCALL, luaK_codeABC(fs, OP_CALL, base, nparams+1, 2)); + luaK_fixline(fs, line); fs.freereg = base + 1; /* call remove function and arguments and leaves (unless changed) one result */ }; @@ -856,12 +950,12 @@ const funcargs = function(ls, f, line) { const primaryexp = function(ls, v) { /* primaryexp -> NAME | '(' expr ')' */ switch (ls.t.token) { - case char['(']: { + case 40 /* ('(').charCodeAt(0) */: { let line = ls.linenumber; llex.luaX_next(ls); expr(ls, v); - check_match(ls, char[')'], char['('], line); - lcode.luaK_dischargevars(ls.fs, v); + check_match(ls, 41 /* (')').charCodeAt(0) */, 40 /* ('(').charCodeAt(0) */, line); + luaK_dischargevars(ls.fs, v); return; } case R.TK_NAME: { @@ -869,7 +963,7 @@ const primaryexp = function(ls, v) { return; } default: { - llex.luaX_syntaxerror(ls, defs.to_luastring("unexpected symbol", true)); + llex.luaX_syntaxerror(ls, to_luastring("unexpected symbol", true)); } } }; @@ -882,27 +976,27 @@ const suffixedexp = function(ls, v) { primaryexp(ls, v); for (;;) { switch (ls.t.token) { - case char['.']: { /* fieldsel */ + case 46 /* ('.').charCodeAt(0) */: { /* fieldsel */ fieldsel(ls, v); break; } - case char['[']: { /* '[' exp1 ']' */ + case 91 /* ('[').charCodeAt(0) */: { /* '[' exp1 ']' */ let key = new expdesc(); - lcode.luaK_exp2anyregup(fs, v); + luaK_exp2anyregup(fs, v); yindex(ls, key); - lcode.luaK_indexed(fs, v, key); + luaK_indexed(fs, v, key); break; } - case char[':']: { /* ':' NAME funcargs */ + case 58 /* (':').charCodeAt(0) */: { /* ':' NAME funcargs */ let key = new expdesc(); llex.luaX_next(ls); checkname(ls, key); - lcode.luaK_self(fs, v, key); + luaK_self(fs, v, key); funcargs(ls, v, line); break; } - case char['(']: case R.TK_STRING: case char['{']: { /* funcargs */ - lcode.luaK_exp2nextreg(fs, v); + case 40 /* ('(').charCodeAt(0) */: case R.TK_STRING: case 123 /* ('{').charCodeAt(0) */: { /* funcargs */ + luaK_exp2nextreg(fs, v); funcargs(ls, v, line); break; } @@ -943,11 +1037,11 @@ const simpleexp = function(ls, v) { } case R.TK_DOTS: { /* vararg */ let fs = ls.fs; - check_condition(ls, fs.f.is_vararg, defs.to_luastring("cannot use '...' outside a vararg function", true)); - init_exp(v, expkind.VVARARG, lcode.luaK_codeABC(fs, OpCodesI.OP_VARARG, 0, 1, 0)); + check_condition(ls, fs.f.is_vararg, to_luastring("cannot use '...' outside a vararg function", true)); + init_exp(v, expkind.VVARARG, luaK_codeABC(fs, OP_VARARG, 0, 1, 0)); break; } - case char['{']: { /* constructor */ + case 123 /* ('{').charCodeAt(0) */: { /* constructor */ constructor(ls, v); return; } @@ -966,38 +1060,38 @@ const simpleexp = function(ls, v) { const getunopr = function(op) { switch (op) { - case R.TK_NOT: return UnOpr.OPR_NOT; - case char['-']: return UnOpr.OPR_MINUS; - case char['~']: return UnOpr.OPR_BNOT; - case char['#']: return UnOpr.OPR_LEN; - default: return UnOpr.OPR_NOUNOPR; + case R.TK_NOT: return OPR_NOT; + case 45 /* ('-').charCodeAt(0) */: return OPR_MINUS; + case 126 /* ('~').charCodeAt(0) */: return OPR_BNOT; + case 35 /* ('#').charCodeAt(0) */: return OPR_LEN; + default: return OPR_NOUNOPR; } }; const getbinopr = function(op) { switch (op) { - case char['+']: return BinOpr.OPR_ADD; - case char['-']: return BinOpr.OPR_SUB; - case char['*']: return BinOpr.OPR_MUL; - case char['%']: return BinOpr.OPR_MOD; - case char['^']: return BinOpr.OPR_POW; - case char['/']: return BinOpr.OPR_DIV; - case R.TK_IDIV: return BinOpr.OPR_IDIV; - case char['&']: return BinOpr.OPR_BAND; - case char['|']: return BinOpr.OPR_BOR; - case char['~']: return BinOpr.OPR_BXOR; - case R.TK_SHL: return BinOpr.OPR_SHL; - case R.TK_SHR: return BinOpr.OPR_SHR; - case R.TK_CONCAT: return BinOpr.OPR_CONCAT; - case R.TK_NE: return BinOpr.OPR_NE; - case R.TK_EQ: return BinOpr.OPR_EQ; - case char['<']: return BinOpr.OPR_LT; - case R.TK_LE: return BinOpr.OPR_LE; - case char['>']: return BinOpr.OPR_GT; - case R.TK_GE: return BinOpr.OPR_GE; - case R.TK_AND: return BinOpr.OPR_AND; - case R.TK_OR: return BinOpr.OPR_OR; - default: return BinOpr.OPR_NOBINOPR; + case 43 /* ('+').charCodeAt(0) */: return OPR_ADD; + case 45 /* ('-').charCodeAt(0) */: return OPR_SUB; + case 42 /* ('*').charCodeAt(0) */: return OPR_MUL; + case 37 /* ('%').charCodeAt(0) */: return OPR_MOD; + case 94 /* ('^').charCodeAt(0) */: return OPR_POW; + case 47 /* ('/').charCodeAt(0) */: return OPR_DIV; + case R.TK_IDIV: return OPR_IDIV; + case 38 /* ('&').charCodeAt(0) */: return OPR_BAND; + case 124 /* ('|').charCodeAt(0) */: return OPR_BOR; + case 126 /* ('~').charCodeAt(0) */: return OPR_BXOR; + case R.TK_SHL: return OPR_SHL; + case R.TK_SHR: return OPR_SHR; + case R.TK_CONCAT: return OPR_CONCAT; + case R.TK_NE: return OPR_NE; + case R.TK_EQ: return OPR_EQ; + case 60 /* ('<').charCodeAt(0) */: return OPR_LT; + case R.TK_LE: return OPR_LE; + case 62 /* ('>').charCodeAt(0) */: return OPR_GT; + case R.TK_GE: return OPR_GE; + case R.TK_AND: return OPR_AND; + case R.TK_OR: return OPR_OR; + default: return OPR_NOBINOPR; } }; @@ -1023,23 +1117,23 @@ const UNARY_PRIORITY = 12; const subexpr = function(ls, v, limit) { enterlevel(ls); let uop = getunopr(ls.t.token); - if (uop !== UnOpr.OPR_NOUNOPR) { + if (uop !== OPR_NOUNOPR) { let line = ls.linenumber; llex.luaX_next(ls); subexpr(ls, v, UNARY_PRIORITY); - lcode.luaK_prefix(ls.fs, uop, v, line); + luaK_prefix(ls.fs, uop, v, line); } else simpleexp(ls, v); /* expand while operators have priorities higher than 'limit' */ let op = getbinopr(ls.t.token); - while (op !== BinOpr.OPR_NOBINOPR && priority[op].left > limit) { + while (op !== OPR_NOBINOPR && priority[op].left > limit) { let v2 = new expdesc(); let line = ls.linenumber; llex.luaX_next(ls); - lcode.luaK_infix(ls.fs, op, v); + luaK_infix(ls.fs, op, v); /* read sub-expression with higher priority */ let nextop = subexpr(ls, v2, priority[op].right); - lcode.luaK_posfix(ls.fs, op, v, v2, line); + luaK_posfix(ls.fs, op, v, v2, line); op = nextop; } leavelevel(ls); @@ -1107,36 +1201,36 @@ const check_conflict = function(ls, lh, v) { } if (conflict) { /* copy upvalue/local value to a temporary (in position 'extra') */ - let op = v.k === expkind.VLOCAL ? OpCodesI.OP_MOVE : OpCodesI.OP_GETUPVAL; - lcode.luaK_codeABC(fs, op, extra, v.u.info, 0); - lcode.luaK_reserveregs(fs, 1); + let op = v.k === expkind.VLOCAL ? OP_MOVE : OP_GETUPVAL; + luaK_codeABC(fs, op, extra, v.u.info, 0); + luaK_reserveregs(fs, 1); } }; const assignment = function(ls, lh, nvars) { let e = new expdesc(); - check_condition(ls, vkisvar(lh.v.k), defs.to_luastring("syntax error", true)); - if (testnext(ls, char[','])) { /* assignment -> ',' suffixedexp assignment */ + check_condition(ls, vkisvar(lh.v.k), to_luastring("syntax error", true)); + if (testnext(ls, 44 /* (',').charCodeAt(0) */)) { /* assignment -> ',' suffixedexp assignment */ let nv = new LHS_assign(); nv.prev = lh; suffixedexp(ls, nv.v); if (nv.v.k !== expkind.VINDEXED) check_conflict(ls, lh, nv.v); - checklimit(ls.fs, nvars + ls.L.nCcalls, llimits.LUAI_MAXCCALLS, defs.to_luastring("JS levels", true)); + checklimit(ls.fs, nvars + ls.L.nCcalls, LUAI_MAXCCALLS, to_luastring("JS levels", true)); assignment(ls, nv, nvars + 1); } else { /* assignment -> '=' explist */ - checknext(ls, char['=']); + checknext(ls, 61 /* ('=').charCodeAt(0) */); let nexps = explist(ls, e); if (nexps !== nvars) adjust_assign(ls, nvars, nexps, e); else { - lcode.luaK_setoneret(ls.fs, e); /* close last expression */ - lcode.luaK_storevar(ls.fs, lh.v, e); + luaK_setoneret(ls.fs, e); /* close last expression */ + luaK_storevar(ls.fs, lh.v, e); return; /* avoid default */ } } init_exp(e, expkind.VNONRELOC, ls.fs.freereg-1); /* default assignment */ - lcode.luaK_storevar(ls.fs, lh.v, e); + luaK_storevar(ls.fs, lh.v, e); }; const cond = function(ls) { @@ -1144,7 +1238,7 @@ const cond = function(ls) { let v = new expdesc(); expr(ls, v); /* read condition */ if (v.k === expkind.VNIL) v.k = expkind.VFALSE; /* 'falses' are all equal here */ - lcode.luaK_goiftrue(ls.fs, v); + luaK_goiftrue(ls.fs, v); return v.f; }; @@ -1155,7 +1249,7 @@ const gotostat = function(ls, pc) { label = str_checkname(ls); else { llex.luaX_next(ls); /* skip break */ - label = lstring.luaS_newliteral(ls.L, "break"); + label = luaS_newliteral(ls.L, "break"); } let g = newlabelentry(ls, ls.dyd.gt, label, line, pc); findlabel(ls, g); /* close it if label already defined */ @@ -1166,7 +1260,7 @@ const checkrepeated = function(fs, ll, label) { for (let i = fs.bl.firstlabel; i < ll.n; i++) { if (eqstr(label, ll.arr[i].name)) { let msg = lobject.luaO_pushfstring(fs.ls.L, - defs.to_luastring("label '%s' already defined on line %d", true), + to_luastring("label '%s' already defined on line %d", true), label.getstr(), ll.arr[i].line); semerror(fs.ls, msg); } @@ -1175,7 +1269,7 @@ const checkrepeated = function(fs, ll, label) { /* skip no-op statements */ const skipnoopstat = function(ls) { - while (ls.t.token === char[';'] || ls.t.token === R.TK_DBCOLON) + while (ls.t.token === 59 /* (';').charCodeAt(0) */ || ls.t.token === R.TK_DBCOLON) statement(ls); }; @@ -1187,7 +1281,7 @@ const labelstat = function(ls, label, line) { checkrepeated(fs, ll, label); /* check for repeated labels */ checknext(ls, R.TK_DBCOLON); /* skip double colon */ /* create new entry for this label */ - l = newlabelentry(ls, ll, label, line, lcode.luaK_getlabel(fs)); + l = newlabelentry(ls, ll, label, line, luaK_getlabel(fs)); skipnoopstat(ls); /* skip other no-op statements */ if (block_follow(ls, 0)) { /* label is last no-op statement in the block? */ /* assume that locals are already out of scope */ @@ -1201,21 +1295,21 @@ const whilestat = function(ls, line) { let fs = ls.fs; let bl = new BlockCnt(); llex.luaX_next(ls); /* skip WHILE */ - let whileinit = lcode.luaK_getlabel(fs); + let whileinit = luaK_getlabel(fs); let condexit = cond(ls); enterblock(fs, bl, 1); checknext(ls, R.TK_DO); block(ls); - lcode.luaK_jumpto(fs, whileinit); + luaK_jumpto(fs, whileinit); check_match(ls, R.TK_END, R.TK_WHILE, line); leaveblock(fs); - lcode.luaK_patchtohere(fs, condexit); /* false conditions finish the loop */ + luaK_patchtohere(fs, condexit); /* false conditions finish the loop */ }; const repeatstat = function(ls, line) { /* repeatstat -> REPEAT block UNTIL cond */ let fs = ls.fs; - let repeat_init = lcode.luaK_getlabel(fs); + let repeat_init = luaK_getlabel(fs); let bl1 = new BlockCnt(); let bl2 = new BlockCnt(); enterblock(fs, bl1, 1); /* loop block */ @@ -1225,17 +1319,17 @@ const repeatstat = function(ls, line) { check_match(ls, R.TK_UNTIL, R.TK_REPEAT, line); let condexit = cond(ls); /* read condition (inside scope block) */ if (bl2.upval) /* upvalues? */ - lcode.luaK_patchclose(fs, condexit, bl2.nactvar); + luaK_patchclose(fs, condexit, bl2.nactvar); leaveblock(fs); /* finish scope */ - lcode.luaK_patchlist(fs, condexit, repeat_init); /* close the loop */ + luaK_patchlist(fs, condexit, repeat_init); /* close the loop */ leaveblock(fs); /* finish loop */ }; const exp1 = function(ls) { let e = new expdesc(); expr(ls, e); - lcode.luaK_exp2nextreg(ls.fs, e); - assert(e.k === expkind.VNONRELOC); + luaK_exp2nextreg(ls.fs, e); + lua_assert(e.k === expkind.VNONRELOC); let reg = e.u.info; return reg; }; @@ -1247,22 +1341,22 @@ const forbody = function(ls, base, line, nvars, isnum) { let endfor; adjustlocalvars(ls, 3); /* control variables */ checknext(ls, R.TK_DO); - let prep = isnum ? lcode.luaK_codeAsBx(fs, OpCodesI.OP_FORPREP, base, lcode.NO_JUMP) : lcode.luaK_jump(fs); + let prep = isnum ? luaK_codeAsBx(fs, OP_FORPREP, base, NO_JUMP) : luaK_jump(fs); enterblock(fs, bl, 0); /* scope for declared variables */ adjustlocalvars(ls, nvars); - lcode.luaK_reserveregs(fs, nvars); + luaK_reserveregs(fs, nvars); block(ls); leaveblock(fs); /* end of scope for declared variables */ - lcode.luaK_patchtohere(fs, prep); + luaK_patchtohere(fs, prep); if (isnum) /* end of scope for declared variables */ - endfor = lcode.luaK_codeAsBx(fs, OpCodesI.OP_FORLOOP, base, lcode.NO_JUMP); + endfor = luaK_codeAsBx(fs, OP_FORLOOP, base, NO_JUMP); else { /* generic for */ - lcode.luaK_codeABC(fs, OpCodesI.OP_TFORCALL, base, 0, nvars); - lcode.luaK_fixline(fs, line); - endfor = lcode.luaK_codeAsBx(fs, OpCodesI.OP_TFORLOOP, base + 2, lcode.NO_JUMP); + luaK_codeABC(fs, OP_TFORCALL, base, 0, nvars); + luaK_fixline(fs, line); + endfor = luaK_codeAsBx(fs, OP_TFORLOOP, base + 2, NO_JUMP); } - lcode.luaK_patchlist(fs, endfor, prep + 1); - lcode.luaK_fixline(fs, line); + luaK_patchlist(fs, endfor, prep + 1); + luaK_fixline(fs, line); }; const fornum = function(ls, varname, line) { @@ -1273,15 +1367,15 @@ const fornum = function(ls, varname, line) { new_localvarliteral(ls, "(for limit)"); new_localvarliteral(ls, "(for step)"); new_localvar(ls, varname); - checknext(ls, char['=']); + checknext(ls, 61 /* ('=').charCodeAt(0) */); exp1(ls); /* initial value */ - checknext(ls, char[',']); + checknext(ls, 44 /* (',').charCodeAt(0) */); exp1(ls); /* limit */ - if (testnext(ls, char[','])) + if (testnext(ls, 44 /* (',').charCodeAt(0) */)) exp1(ls); /* optional step */ else { /* default step = 1 */ - lcode.luaK_codek(fs, fs.freereg, lcode.luaK_intK(fs, 1)); - lcode.luaK_reserveregs(fs, 1); + luaK_codek(fs, fs.freereg, luaK_intK(fs, 1)); + luaK_reserveregs(fs, 1); } forbody(ls, base, line, 1, 1); }; @@ -1298,14 +1392,14 @@ const forlist = function(ls, indexname) { new_localvarliteral(ls, "(for control)"); /* create declared variables */ new_localvar(ls, indexname); - while (testnext(ls, char[','])) { + while (testnext(ls, 44 /* (',').charCodeAt(0) */)) { new_localvar(ls, str_checkname(ls)); nvars++; } checknext(ls, R.TK_IN); let line = ls.linenumber; adjust_assign(ls, 3, explist(ls, e), e); - lcode.luaK_checkstack(fs, 3); /* extra space to call generator */ + luaK_checkstack(fs, 3); /* extra space to call generator */ forbody(ls, base, line, nvars - 3, 0); }; @@ -1317,9 +1411,9 @@ const forstat = function(ls, line) { llex.luaX_next(ls); /* skip 'for' */ let varname = str_checkname(ls); /* first variable name */ switch (ls.t.token) { - case char['=']: fornum(ls, varname, line); break; - case char[',']: case R.TK_IN: forlist(ls, varname); break; - default: llex.luaX_syntaxerror(ls, defs.to_luastring("'=' or 'in' expected", true)); + case 61 /* ('=').charCodeAt(0) */: fornum(ls, varname, line); break; + case 44 /* (',').charCodeAt(0) */: case R.TK_IN: forlist(ls, varname); break; + default: llex.luaX_syntaxerror(ls, to_luastring("'=' or 'in' expected", true)); } check_match(ls, R.TK_END, R.TK_FOR, line); leaveblock(fs); /* loop scope ('break' jumps to this point) */ @@ -1337,17 +1431,17 @@ const test_then_block = function(ls, escapelist) { checknext(ls, R.TK_THEN); if (ls.t.token === R.TK_GOTO || ls.t.token === R.TK_BREAK) { - lcode.luaK_goiffalse(ls.fs, v); /* will jump to label if condition is true */ + luaK_goiffalse(ls.fs, v); /* will jump to label if condition is true */ enterblock(fs, bl, false); /* must enter block before 'goto' */ gotostat(ls, v.t); /* handle goto/break */ - while (testnext(ls, char[';'])); /* skip colons */ + while (testnext(ls, 59 /* (';').charCodeAt(0) */)); /* skip colons */ if (block_follow(ls, 0)) { /* 'goto' is the entire block? */ leaveblock(fs); return escapelist; /* and that is it */ } else /* must skip over 'then' part if condition is false */ - jf = lcode.luaK_jump(fs); + jf = luaK_jump(fs); } else { /* regular case (not goto/break) */ - lcode.luaK_goiftrue(ls.fs, v); /* skip over block if condition is false */ + luaK_goiftrue(ls.fs, v); /* skip over block if condition is false */ enterblock(fs, bl, false); jf = v.f; } @@ -1355,8 +1449,8 @@ const test_then_block = function(ls, escapelist) { statlist(ls); /* 'then' part */ leaveblock(fs); if (ls.t.token === R.TK_ELSE || ls.t.token === R.TK_ELSEIF) /* followed by 'else'/'elseif'? */ - escapelist = lcode.luaK_concat(fs, escapelist, lcode.luaK_jump(fs)); /* must jump over it */ - lcode.luaK_patchtohere(fs, jf); + escapelist = luaK_concat(fs, escapelist, luaK_jump(fs)); /* must jump over it */ + luaK_patchtohere(fs, jf); return escapelist; }; @@ -1364,14 +1458,14 @@ const test_then_block = function(ls, escapelist) { const ifstat = function(ls, line) { /* ifstat -> IF cond THEN block {ELSEIF cond THEN block} [ELSE block] END */ let fs = ls.fs; - let escapelist = lcode.NO_JUMP; /* exit list for finished parts */ + let escapelist = NO_JUMP; /* exit list for finished parts */ escapelist = test_then_block(ls, escapelist); /* IF cond THEN block */ while (ls.t.token === R.TK_ELSEIF) escapelist = test_then_block(ls, escapelist); /* ELSEIF cond THEN block */ if (testnext(ls, R.TK_ELSE)) block(ls); /* 'else' part */ check_match(ls, R.TK_END, R.TK_IF, line); - lcode.luaK_patchtohere(fs, escapelist); /* patch escape list to 'if' end */ + luaK_patchtohere(fs, escapelist); /* patch escape list to 'if' end */ }; const localfunc = function(ls) { @@ -1392,8 +1486,8 @@ const localstat = function(ls) { do { new_localvar(ls, str_checkname(ls)); nvars++; - } while (testnext(ls, char[','])); - if (testnext(ls, char['='])) + } while (testnext(ls, 44 /* (',').charCodeAt(0) */)); + if (testnext(ls, 61 /* ('=').charCodeAt(0) */)) nexps = explist(ls, e); else { e.k = expkind.VVOID; @@ -1407,9 +1501,9 @@ const funcname = function(ls, v) { /* funcname -> NAME {fieldsel} [':' NAME] */ let ismethod = 0; singlevar(ls, v); - while (ls.t.token === char['.']) + while (ls.t.token === 46 /* ('.').charCodeAt(0) */) fieldsel(ls, v); - if (ls.t.token === char[':']) { + if (ls.t.token === 58 /* (':').charCodeAt(0) */) { ismethod = 1; fieldsel(ls, v); } @@ -1423,8 +1517,8 @@ const funcstat = function(ls, line) { llex.luaX_next(ls); /* skip FUNCTION */ let ismethod = funcname(ls, v); body(ls, b, ismethod, line); - lcode.luaK_storevar(ls.fs, v, b); - lcode.luaK_fixline(ls.fs, line); /* definition "happens" in the first line */ + luaK_storevar(ls.fs, v, b); + luaK_fixline(ls.fs, line); /* definition "happens" in the first line */ }; const exprstat= function(ls) { @@ -1432,13 +1526,13 @@ const exprstat= function(ls) { let fs = ls.fs; let v = new LHS_assign(); suffixedexp(ls, v.v); - if (ls.t.token === char['='] || ls.t.token === char[',']) { /* stat . assignment ? */ + if (ls.t.token === 61 /* ('=').charCodeAt(0) */ || ls.t.token === 44 /* (',').charCodeAt(0) */) { /* stat . assignment ? */ v.prev = null; assignment(ls, v, 1); } else { /* stat -> func */ - check_condition(ls, v.v.k === expkind.VCALL, defs.to_luastring("syntax error", true)); - lopcodes.SETARG_C(lcode.getinstruction(fs, v.v), 1); /* call statement uses no results */ + check_condition(ls, v.v.k === expkind.VCALL, to_luastring("syntax error", true)); + SETARG_C(getinstruction(fs, v.v), 1); /* call statement uses no results */ } }; @@ -1447,37 +1541,37 @@ const retstat = function(ls) { let fs = ls.fs; let e = new expdesc(); let first, nret; /* registers with returned values */ - if (block_follow(ls, 1) || ls.t.token === char[';']) + if (block_follow(ls, 1) || ls.t.token === 59 /* (';').charCodeAt(0) */) first = nret = 0; /* return no values */ else { nret = explist(ls, e); /* optional return values */ if (hasmultret(e.k)) { - lcode.luaK_setmultret(fs, e); + luaK_setmultret(fs, e); if (e.k === expkind.VCALL && nret === 1) { /* tail call? */ - lopcodes.SET_OPCODE(lcode.getinstruction(fs, e), OpCodesI.OP_TAILCALL); - assert(lcode.getinstruction(fs, e).A === fs.nactvar); + SET_OPCODE(getinstruction(fs, e), OP_TAILCALL); + lua_assert(getinstruction(fs, e).A === fs.nactvar); } first = fs.nactvar; - nret = defs.LUA_MULTRET; /* return all values */ + nret = LUA_MULTRET; /* return all values */ } else { if (nret === 1) /* only one single value? */ - first = lcode.luaK_exp2anyreg(fs, e); + first = luaK_exp2anyreg(fs, e); else { - lcode.luaK_exp2nextreg(fs, e); /* values must go to the stack */ + luaK_exp2nextreg(fs, e); /* values must go to the stack */ first = fs.nactvar; /* return all active values */ - assert(nret === fs.freereg - first); + lua_assert(nret === fs.freereg - first); } } } - lcode.luaK_ret(fs, first, nret); - testnext(ls, char[';']); /* skip optional semicolon */ + luaK_ret(fs, first, nret); + testnext(ls, 59 /* (';').charCodeAt(0) */); /* skip optional semicolon */ }; const statement = function(ls) { let line = ls.linenumber; /* may be needed for error messages */ enterlevel(ls); switch(ls.t.token) { - case char[';']: { /* stat -> ';' (empty statement) */ + case 59 /* (';').charCodeAt(0) */: { /* stat -> ';' (empty statement) */ llex.luaX_next(ls); /* skip ';' */ break; } @@ -1527,7 +1621,7 @@ const statement = function(ls) { } case R.TK_BREAK: /* stat -> breakstat */ case R.TK_GOTO: { /* stat -> 'goto' NAME */ - gotostat(ls, lcode.luaK_jump(ls.fs)); + gotostat(ls, luaK_jump(ls.fs)); break; } default: { /* stat -> func | assignment */ @@ -1535,8 +1629,7 @@ const statement = function(ls) { break; } } - - assert(ls.fs.f.maxstacksize >= ls.fs.freereg && ls.fs.freereg >= ls.fs.nactvar); + lua_assert(ls.fs.f.maxstacksize >= ls.fs.freereg && ls.fs.freereg >= ls.fs.nactvar); ls.fs.freereg = ls.fs.nactvar; /* free registers */ leavelevel(ls); }; @@ -1568,15 +1661,15 @@ const luaY_parser = function(L, z, buff, dyd, name, firstchar) { ldo.luaD_inctop(L); L.stack[L.top-1].sethvalue(lexstate.h); funcstate.f = cl.p = new Proto(L); - funcstate.f.source = lstring.luaS_new(L, name); + funcstate.f.source = luaS_new(L, name); lexstate.buff = buff; lexstate.dyd = dyd; dyd.actvar.n = dyd.gt.n = dyd.label.n = 0; llex.luaX_setinput(L, lexstate, z, funcstate.f.source, firstchar); mainfunc(lexstate, funcstate); - assert(!funcstate.prev && funcstate.nups === 1 && !lexstate.fs); + lua_assert(!funcstate.prev && funcstate.nups === 1 && !lexstate.fs); /* all scopes should be correctly finished */ - assert(dyd.actvar.n === 0 && dyd.gt.n === 0 && dyd.label.n === 0); + lua_assert(dyd.actvar.n === 0 && dyd.gt.n === 0 && dyd.label.n === 0); delete L.stack[--L.top]; /* remove scanner's table */ return cl; /* closure is on the stack, too */ }; diff --git a/src/lstate.js b/src/lstate.js index db046dc..0c44f3c 100644 --- a/src/lstate.js +++ b/src/lstate.js @@ -1,21 +1,28 @@ "use strict"; -const assert = require('assert'); - -const defs = require('./defs.js'); +const { + LUA_MINSTACK, + LUA_RIDX_GLOBALS, + LUA_RIDX_MAINTHREAD, + constant_types: { + LUA_NUMTAGS, + LUA_TNIL, + LUA_TTABLE, + LUA_TTHREAD + }, + thread_status: { + LUA_OK + } +} = require('./defs.js'); const lobject = require('./lobject.js'); const ldo = require('./ldo.js'); const lapi = require('./lapi.js'); const ltable = require('./ltable.js'); -const lfunc = require('./lfunc.js'); const ltm = require('./ltm.js'); -const CT = defs.constant_types; -const TS = defs.thread_status; -const LUA_NUMTAGS = CT.LUA_NUMTAGS; const EXTRA_STACK = 5; -const BASIC_STACK_SIZE = 2 * defs.LUA_MINSTACK; +const BASIC_STACK_SIZE = 2 * LUA_MINSTACK; class CallInfo { @@ -62,9 +69,8 @@ class lua_State { this.basehookcount = 0; this.allowhook = 1; this.hookcount = this.basehookcount; - this.openupval = null; this.nny = 1; - this.status = TS.LUA_OK; + this.status = LUA_OK; this.errfunc = 0; } @@ -77,7 +83,7 @@ class global_State { this.ids = new WeakMap(); this.mainthread = null; - this.l_registry = new lobject.TValue(CT.LUA_TNIL, null); + this.l_registry = new lobject.TValue(LUA_TNIL, null); this.panic = null; this.atnativeerror = null; this.version = null; @@ -111,8 +117,8 @@ const stack_init = function(L1, L) { ci.callstatus = 0; ci.funcOff = L1.top; ci.func = L1.stack[L1.top]; - L1.stack[L1.top++] = new lobject.TValue(CT.LUA_TNIL, null); - ci.top = L1.top + defs.LUA_MINSTACK; + L1.stack[L1.top++] = new lobject.TValue(LUA_TNIL, null); + ci.top = L1.top + LUA_MINSTACK; L1.ci = ci; }; @@ -128,8 +134,8 @@ const freestack = function(L) { const init_registry = function(L, g) { let registry = ltable.luaH_new(L); g.l_registry.sethvalue(registry); - ltable.luaH_setint(registry, defs.LUA_RIDX_MAINTHREAD, new lobject.TValue(CT.LUA_TTHREAD, L)); - ltable.luaH_setint(registry, defs.LUA_RIDX_GLOBALS, new lobject.TValue(CT.LUA_TTABLE, ltable.luaH_new(L))); + ltable.luaH_setint(registry, LUA_RIDX_MAINTHREAD, new lobject.TValue(LUA_TTHREAD, L)); + ltable.luaH_setint(registry, LUA_RIDX_GLOBALS, new lobject.TValue(LUA_TTABLE, ltable.luaH_new(L))); }; /* @@ -147,9 +153,8 @@ const f_luaopen = function(L) { const lua_newthread = function(L) { let g = L.l_G; let L1 = new lua_State(g); - L.stack[L.top] = new lobject.TValue(CT.LUA_TTHREAD, L1); - L.top++; - assert(L.top <= L.ci.top, "stack overflow"); + L.stack[L.top] = new lobject.TValue(LUA_TTHREAD, L1); + lapi.api_incr_top(L); L1.hookmask = L.hookmask; L1.basehookcount = L.basehookcount; L1.hook = L.hook; @@ -159,7 +164,6 @@ const lua_newthread = function(L) { }; const luaE_freethread = function(L, L1) { - lfunc.luaF_close(L1, L1.stack); freestack(L1); }; @@ -168,7 +172,7 @@ const lua_newstate = function() { let L = new lua_State(g); g.mainthread = L; - if (ldo.luaD_rawrunprotected(L, f_luaopen, null) !== TS.LUA_OK) { + if (ldo.luaD_rawrunprotected(L, f_luaopen, null) !== LUA_OK) { L = null; } @@ -176,7 +180,6 @@ const lua_newstate = function() { }; const close_state = function(L) { - lfunc.luaF_close(L, L.stack); /* close all upvalues for this thread */ freestack(L); }; diff --git a/src/lstring.js b/src/lstring.js index c8da56a..4769866 100644 --- a/src/lstring.js +++ b/src/lstring.js @@ -1,8 +1,12 @@ "use strict"; -const assert = require("assert"); - -const defs = require('./defs.js'); +const { + is_luastring, + luastring_eq, + luastring_from, + to_luastring +} = require('./defs.js'); +const { lua_assert } = require("./llimits.js"); class TString { @@ -22,20 +26,24 @@ class TString { } const luaS_eqlngstr = function(a, b) { - assert(a instanceof TString); - assert(b instanceof TString); - return a == b || defs.luastring_cmp(a.realstring, b.realstring); + lua_assert(a instanceof TString); + lua_assert(b instanceof TString); + return a == b || luastring_eq(a.realstring, b.realstring); }; /* converts strings (arrays) to a consistent map key make sure this doesn't conflict with any of the anti-collision strategies in ltable */ const luaS_hash = function(str) { - assert(defs.is_luastring(str)); - return '|'+str.join('|'); + lua_assert(is_luastring(str)); + let len = str.length; + let s = "|"; + for (let i=0; i<len; i++) + s += str[i].toString(16); + return s; }; const luaS_hashlongstr = function(ts) { - assert(ts instanceof TString); + lua_assert(ts instanceof TString); if(ts.hash === null) { ts.hash = luaS_hash(ts.getstr()); } @@ -44,18 +52,18 @@ const luaS_hashlongstr = function(ts) { /* variant that takes ownership of array */ const luaS_bless = function(L, str) { - assert(str instanceof Uint8Array); + lua_assert(str instanceof Uint8Array); return new TString(L, str); }; /* makes a copy */ const luaS_new = function(L, str) { - return luaS_bless(L, Uint8Array.from(str)); + return luaS_bless(L, luastring_from(str)); }; /* takes a js string */ const luaS_newliteral = function(L, str) { - return luaS_bless(L, defs.to_luastring(str)); + return luaS_bless(L, to_luastring(str)); }; module.exports.luaS_eqlngstr = luaS_eqlngstr; diff --git a/src/lstrlib.js b/src/lstrlib.js index 362942d..fcaea79 100644 --- a/src/lstrlib.js +++ b/src/lstrlib.js @@ -1,11 +1,84 @@ "use strict"; -const assert = require('assert'); -const sprintf = require('sprintf-js').sprintf; - -const lauxlib = require('./lauxlib.js'); -const lua = require('./lua.js'); -const luaconf = require('./luaconf.js'); +const { sprintf } = require('sprintf-js'); + +const { + LUA_INTEGER_FMT, + LUA_INTEGER_FRMLEN, + LUA_MININTEGER, + LUA_NUMBER_FMT, + LUA_NUMBER_FRMLEN, + frexp, + lua_getlocaledecpoint +} = require('./luaconf.js'); +const { + LUA_TBOOLEAN, + LUA_TFUNCTION, + LUA_TNIL, + LUA_TNUMBER, + LUA_TSTRING, + LUA_TTABLE, + lua_call, + lua_createtable, + lua_dump, + lua_gettable, + lua_gettop, + lua_isinteger, + lua_isstring, + lua_pop, + lua_pushcclosure, + lua_pushinteger, + lua_pushlightuserdata, + lua_pushliteral, + lua_pushlstring, + lua_pushnil, + lua_pushnumber, + lua_pushstring, + lua_pushvalue, + lua_remove, + lua_setfield, + lua_setmetatable, + lua_settop, + lua_toboolean, + lua_tointeger, + lua_tonumber, + lua_tostring, + lua_touserdata, + lua_type, + lua_upvalueindex +} = require('./lua.js'); +const { + luaL_Buffer, + luaL_addchar, + luaL_addlstring, + luaL_addsize, + luaL_addstring, + luaL_addvalue, + luaL_argcheck, + luaL_argerror, + luaL_buffinit, + luaL_buffinitsize, + luaL_checkinteger, + luaL_checknumber, + luaL_checkstack, + luaL_checkstring, + luaL_checktype, + luaL_error, + luaL_newlib, + luaL_optinteger, + luaL_optstring, + luaL_prepbuffsize, + luaL_pushresult, + luaL_pushresultsize, + luaL_tolstring, + luaL_typename +} = require('./lauxlib.js'); +const lualib = require('./lualib.js'); +const { + luastring_indexOf, + to_jsstring, + to_luastring +} = require("./fengaricore.js"); const sL_ESC = '%'; const L_ESC = sL_ESC.charCodeAt(0); @@ -22,7 +95,7 @@ const MAXSIZE = 2147483647; /* Give natural (i.e. strings end at the first \0) length of a string represented by an array of bytes */ const strlen = function(s) { - let len = s.indexOf(0); + let len = luastring_indexOf(s, 0); return len > -1 ? len : s.length; }; @@ -34,74 +107,74 @@ const posrelat = function(pos, len) { }; const str_sub = function(L) { - let s = lauxlib.luaL_checkstring(L, 1); + let s = luaL_checkstring(L, 1); let l = s.length; - let start = posrelat(lauxlib.luaL_checkinteger(L, 2), l); - let end = posrelat(lauxlib.luaL_optinteger(L, 3, -1), l); + let start = posrelat(luaL_checkinteger(L, 2), l); + let end = posrelat(luaL_optinteger(L, 3, -1), l); if (start < 1) start = 1; if (end > l) end = l; if (start <= end) - lua.lua_pushstring(L, s.slice(start - 1, (start - 1) + (end - start + 1))); - else lua.lua_pushliteral(L, ""); + lua_pushstring(L, s.subarray(start - 1, (start - 1) + (end - start + 1))); + else lua_pushliteral(L, ""); return 1; }; const str_len = function(L) { - lua.lua_pushinteger(L, lauxlib.luaL_checkstring(L, 1).length); + lua_pushinteger(L, luaL_checkstring(L, 1).length); return 1; }; const str_char = function(L) { - let n = lua.lua_gettop(L); /* number of arguments */ - let b = new lauxlib.luaL_Buffer(); - let p = lauxlib.luaL_buffinitsize(L, b, n); + let n = lua_gettop(L); /* number of arguments */ + let b = new luaL_Buffer(); + let p = luaL_buffinitsize(L, b, n); for (let i = 1; i <= n; i++) { - let c = lauxlib.luaL_checkinteger(L, i); - lauxlib.luaL_argcheck(L, c >= 0 && c <= 255, "value out of range"); // Strings are 8-bit clean + let c = luaL_checkinteger(L, i); + luaL_argcheck(L, c >= 0 && c <= 255, "value out of range"); // Strings are 8-bit clean p[i-1] = c; } - lauxlib.luaL_pushresultsize(b, n); + luaL_pushresultsize(b, n); return 1; }; const writer = function(L, b, size, B) { - lauxlib.luaL_addlstring(B, b, size); + luaL_addlstring(B, b, size); return 0; }; const str_dump = function(L) { - let b = new lauxlib.luaL_Buffer(); - let strip = lua.lua_toboolean(L, 2); - lauxlib.luaL_checktype(L, 1, lua.LUA_TFUNCTION); - lua.lua_settop(L, 1); - lauxlib.luaL_buffinit(L, b); - if (lua.lua_dump(L, writer, b, strip) !== 0) - return lauxlib.luaL_error(L, lua.to_luastring("unable to dump given function")); - lauxlib.luaL_pushresult(b); + let b = new luaL_Buffer(); + let strip = lua_toboolean(L, 2); + luaL_checktype(L, 1, LUA_TFUNCTION); + lua_settop(L, 1); + luaL_buffinit(L, b); + if (lua_dump(L, writer, b, strip) !== 0) + return luaL_error(L, to_luastring("unable to dump given function")); + luaL_pushresult(b); return 1; }; -const SIZELENMOD = luaconf.LUA_NUMBER_FRMLEN.length + 1; +const SIZELENMOD = LUA_NUMBER_FRMLEN.length + 1; const L_NBFD = 1; const num2straux = function(x) { /* if 'inf' or 'NaN', format it like '%g' */ if (Object.is(x, Infinity)) - return lua.to_luastring('inf', true).slice(0); + return to_luastring('inf'); else if (Object.is(x, -Infinity)) - return lua.to_luastring('-inf', true).slice(0); + return to_luastring('-inf'); else if (Number.isNaN(x)) - return lua.to_luastring('nan', true).slice(0); + return to_luastring('nan'); else if (x === 0) { /* can be -0... */ /* create "0" or "-0" followed by exponent */ - let zero = sprintf(luaconf.LUA_NUMBER_FMT + "x0p+0", x); + let zero = sprintf(LUA_NUMBER_FMT + "x0p+0", x); if (Object.is(x, -0)) zero = "-" + zero; - return lua.to_luastring(zero); + return to_luastring(zero); } else { let buff = ""; - let fe = luaconf.frexp(x); /* 'x' fraction and exponent */ + let fe = frexp(x); /* 'x' fraction and exponent */ let m = fe[0]; let e = fe[1]; if (m < 0) { /* is number negative? */ @@ -112,17 +185,20 @@ const num2straux = function(x) { buff += (m * (1<<L_NBFD)).toString(16); e -= L_NBFD; /* this digit goes before the radix point */ buff += sprintf("p%+d", e); /* add exponent */ - return lua.to_luastring(buff); + return to_luastring(buff); } }; const lua_number2strx = function(L, fmt, x) { let buff = num2straux(x); - if (fmt[SIZELENMOD] === 'A'.charCodeAt(0)) { - for (let i = 0; i < buff.length; i++) - buff[i] = String.fromCharCode(buff[i]).toUpperCase().charCodeAt(0); - } else if (fmt[SIZELENMOD] !== 'a'.charCodeAt(0)) - lauxlib.luaL_error(L, lua.to_luastring("modifiers for format '%%a'/'%%A' not implemented")); + if (fmt[SIZELENMOD] === 65 /* 'A'.charCodeAt(0) */) { + for (let i = 0; i < buff.length; i++) { + let c = buff[i]; + if (c >= 97) /* toupper */ + buff[i] = c & 0xdf; + } + } else if (fmt[SIZELENMOD] !== 97 /* 'a'.charCodeAt(0) */) + luaL_error(L, to_luastring("modifiers for format '%%a'/'%%A' not implemented")); return buff; }; @@ -137,106 +213,105 @@ const lua_number2strx = function(L, fmt, x) { /* valid flags in a format specification */ -const FLAGS = ["-".charCodeAt(0), "+".charCodeAt(0), " ".charCodeAt(0), "#".charCodeAt(0), "0".charCodeAt(0)]; +const FLAGS = to_luastring("-+ #0"); /* ** maximum size of each format specification (such as "%-099.99d") */ // const MAX_FORMAT = 32; -// TODO: locale ? and do it better -const isalpha = e => ('a'.charCodeAt(0) <= e && e <= 'z'.charCodeAt(0)) || (e >= 'A'.charCodeAt(0) && e <= 'Z'.charCodeAt(0)); -const isdigit = e => '0'.charCodeAt(0) <= e && e <= '9'.charCodeAt(0); +const isalpha = e => (97 <= e && e <= 122) || (65 <= e && e <= 90); +const isdigit = e => 48 <= e && e <= 57; const iscntrl = e => (0x00 <= e && e <= 0x1f) || e === 0x7f; -const isgraph = e => e > 32 && e < 127; // TODO: Will only work for ASCII -const islower = e => /^[a-z]$/.test(String.fromCharCode(e)); -const isupper = e => /^[A-Z]$/.test(String.fromCharCode(e)); -const isalnum = e => /^[a-zA-Z0-9]$/.test(String.fromCharCode(e)); +const isgraph = e => 33 <= e && e <= 126; +const islower = e => 97 <= e && e <= 122; +const isupper = e => 65 <= e && e <= 90; +const isalnum = e => (97 <= e && e <= 122) || (65 <= e && e <= 90) || (48 <= e && e <= 57); const ispunct = e => isgraph(e) && !isalnum(e); -const isspace = e => /^\s$/.test(String.fromCharCode(e)); -const isxdigit = e => /^[0-9A-Fa-f]$/.test(String.fromCharCode(e)); +const isspace = e => e === 32 || (e >= 9 && e <= 13); +const isxdigit = e => (48 <= e && e <= 57) || (65 <= e && e <= 70) || (97 <= e && e <= 102); const addquoted = function(b, s, len) { - lauxlib.luaL_addchar(b, '"'.charCodeAt(0)); + luaL_addchar(b, 34 /* '"'.charCodeAt(0) */); let i = 0; while (len--) { - if (s[i] === '"'.charCodeAt(0) || s[i] === '\\'.charCodeAt(0) || s[i] === '\n'.charCodeAt(0)) { - lauxlib.luaL_addchar(b, '\\'.charCodeAt(0)); - lauxlib.luaL_addchar(b, s[i]); + if (s[i] === 34 /* '"'.charCodeAt(0) */ || + s[i] === 92 /* '\\'.charCodeAt(0) */ || + s[i] === 10 /* '\n'.charCodeAt(0) */) { + luaL_addchar(b, 92 /* '\\'.charCodeAt(0) */); + luaL_addchar(b, s[i]); } else if (iscntrl(s[i])) { - let buff; - if (!isdigit(s[i+1])) - buff = lua.to_luastring(sprintf("\\%d", s[i])); - else - buff = lua.to_luastring(sprintf("\\%03d", s[i])); - lauxlib.luaL_addstring(b, buff); + let buff = ''+s[i]; + if (isdigit(s[i+1])) + buff = '0'.repeat(3-buff.length) + buff; /* pad to 3 '0's */ + luaL_addstring(b, to_luastring("\\" + buff)); } else - lauxlib.luaL_addchar(b, s[i]); + luaL_addchar(b, s[i]); i++; } - lauxlib.luaL_addchar(b, '"'.charCodeAt(0)); + luaL_addchar(b, 34 /* '"'.charCodeAt(0) */); }; /* ** Ensures the 'buff' string uses a dot as the radix character. */ const checkdp = function(buff) { - if (buff.indexOf('.'.charCodeAt(0)) < 0) { /* no dot? */ - let point = luaconf.lua_getlocaledecpoint().charCodeAt(0); /* try locale point */ - let ppoint = buff.indexOf(point); - if (ppoint) buff[ppoint] = '.'; /* change it to a dot */ + if (luastring_indexOf(buff, 46 /* ('.').charCodeAt(0) */) < 0) { /* no dot? */ + let point = lua_getlocaledecpoint(); /* try locale point */ + let ppoint = luastring_indexOf(buff, point); + if (ppoint) buff[ppoint] = 46 /* ('.').charCodeAt(0) */; /* change it to a dot */ } }; const addliteral = function(L, b, arg) { - switch(lua.lua_type(L, arg)) { - case lua.LUA_TSTRING: { - let s = lua.lua_tostring(L, arg); + switch(lua_type(L, arg)) { + case LUA_TSTRING: { + let s = lua_tostring(L, arg); addquoted(b, s, s.length); break; } - case lua.LUA_TNUMBER: { + case LUA_TNUMBER: { let buff; - if (!lua.lua_isinteger(L, arg)) { /* float? */ - let n = lua.lua_tonumber(L, arg); /* write as hexa ('%a') */ - buff = lua_number2strx(L, lua.to_luastring(`%${luaconf.LUA_INTEGER_FRMLEN}a`), n); + if (!lua_isinteger(L, arg)) { /* float? */ + let n = lua_tonumber(L, arg); /* write as hexa ('%a') */ + buff = lua_number2strx(L, to_luastring(`%${LUA_INTEGER_FRMLEN}a`), n); checkdp(buff); /* ensure it uses a dot */ } else { /* integers */ - let n = lua.lua_tointeger(L, arg); - let format = (n === luaconf.LUA_MININTEGER) /* corner case? */ - ? "0x%" + luaconf.LUA_INTEGER_FRMLEN + "x" /* use hexa */ - : luaconf.LUA_INTEGER_FMT; /* else use default format */ - buff = lua.to_luastring(sprintf(format, n)); + let n = lua_tointeger(L, arg); + let format = (n === LUA_MININTEGER) /* corner case? */ + ? "0x%" + LUA_INTEGER_FRMLEN + "x" /* use hexa */ + : LUA_INTEGER_FMT; /* else use default format */ + buff = to_luastring(sprintf(format, n)); } - lauxlib.luaL_addstring(b, buff); + luaL_addstring(b, buff); break; } - case lua.LUA_TNIL: case lua.LUA_TBOOLEAN: { - lauxlib.luaL_tolstring(L, arg); - lauxlib.luaL_addvalue(b); + case LUA_TNIL: case LUA_TBOOLEAN: { + luaL_tolstring(L, arg); + luaL_addvalue(b); break; } default: { - lauxlib.luaL_argerror(L, arg, lua.to_luastring("value has no literal form", true)); + luaL_argerror(L, arg, to_luastring("value has no literal form", true)); } } }; const scanformat = function(L, strfrmt, i, form) { let p = i; - while (strfrmt[p] !== 0 && FLAGS.indexOf(strfrmt[p]) >= 0) p++; /* skip flags */ + while (strfrmt[p] !== 0 && luastring_indexOf(FLAGS, strfrmt[p]) >= 0) p++; /* skip flags */ if (p - i >= FLAGS.length) - lauxlib.luaL_error(L, lua.to_luastring("invalid format (repeated flags)", true)); + luaL_error(L, to_luastring("invalid format (repeated flags)", true)); if (isdigit(strfrmt[p])) p++; /* skip width */ if (isdigit(strfrmt[p])) p++; /* (2 digits at most) */ - if (strfrmt[p] === '.'.charCodeAt(0)) { + if (strfrmt[p] === 46 /* '.'.charCodeAt(0) */) { p++; if (isdigit(strfrmt[p])) p++; /* skip precision */ if (isdigit(strfrmt[p])) p++; /* (2 digits at most) */ } if (isdigit(strfrmt[p])) - lauxlib.luaL_error(L, lua.to_luastring("invalid format (width or precision too long)", true)); - form[0] = "%".charCodeAt(0); + luaL_error(L, to_luastring("invalid format (width or precision too long)", true)); + form[0] = 37 /* "%".charCodeAt(0) */; for (let j = 0; j < p - i + 1; j++) form[j+1] = strfrmt[i+j]; return p; @@ -249,52 +324,52 @@ const addlenmod = function(form, lenmod) { let l = form.length; let lm = lenmod.length; let spec = form[l - 1]; - for (let i = 0; i < lenmod.length; i++) + for (let i = 0; i < lm; i++) form[i + l - 1] = lenmod[i]; form[l + lm - 1] = spec; // form[l + lm] = 0; }; const str_format = function(L) { - let top = lua.lua_gettop(L); + let top = lua_gettop(L); let arg = 1; - let strfrmt = lauxlib.luaL_checkstring(L, arg); + let strfrmt = luaL_checkstring(L, arg); let i = 0; - let b = new lauxlib.luaL_Buffer(); - lauxlib.luaL_buffinit(L, b); + let b = new luaL_Buffer(); + luaL_buffinit(L, b); while (i < strfrmt.length) { if (strfrmt[i] !== L_ESC) { - lauxlib.luaL_addchar(b, strfrmt[i++]); + luaL_addchar(b, strfrmt[i++]); } else if (strfrmt[++i] === L_ESC) { - lauxlib.luaL_addchar(b, strfrmt[i++]); /* %% */ + luaL_addchar(b, strfrmt[i++]); /* %% */ } else { /* format item */ let form = []; /* to store the format ('%...') */ if (++arg > top) - lauxlib.luaL_argerror(L, arg, lua.to_luastring("no value", true)); + luaL_argerror(L, arg, to_luastring("no value", true)); i = scanformat(L, strfrmt, i, form); switch (String.fromCharCode(strfrmt[i++])) { case 'c': { - // sprintf(String.fromCharCode(...form), lauxlib.luaL_checkinteger(L, arg)); - lauxlib.luaL_addchar(b, lauxlib.luaL_checkinteger(L, arg)); + // sprintf(String.fromCharCode(...form), luaL_checkinteger(L, arg)); + luaL_addchar(b, luaL_checkinteger(L, arg)); break; } case 'd': case 'i': case 'o': case 'u': case 'x': case 'X': { - let n = lauxlib.luaL_checkinteger(L, arg); - addlenmod(form, luaconf.LUA_INTEGER_FRMLEN.split('').map(e => e.charCodeAt(0))); - lauxlib.luaL_addstring(b, lua.to_luastring(sprintf(String.fromCharCode(...form), n))); + let n = luaL_checkinteger(L, arg); + addlenmod(form, to_luastring(LUA_INTEGER_FRMLEN, true)); + luaL_addstring(b, to_luastring(sprintf(String.fromCharCode(...form), n))); break; } case 'a': case 'A': { - addlenmod(form, luaconf.LUA_INTEGER_FRMLEN.split('').map(e => e.charCodeAt(0))); - lauxlib.luaL_addstring(b, lua_number2strx(L, form, lauxlib.luaL_checknumber(L, arg))); + addlenmod(form, to_luastring(LUA_INTEGER_FRMLEN, true)); + luaL_addstring(b, lua_number2strx(L, form, luaL_checknumber(L, arg))); break; } case 'e': case 'E': case 'f': case 'g': case 'G': { - let n = lauxlib.luaL_checknumber(L, arg); - addlenmod(form, luaconf.LUA_INTEGER_FRMLEN.split('').map(e => e.charCodeAt(0))); - lauxlib.luaL_addstring(b, lua.to_luastring(sprintf(String.fromCharCode(...form), n))); + let n = luaL_checknumber(L, arg); + addlenmod(form, to_luastring(LUA_INTEGER_FRMLEN, true)); + luaL_addstring(b, to_luastring(sprintf(String.fromCharCode(...form), n))); break; } case 'q': { @@ -302,29 +377,29 @@ const str_format = function(L) { break; } case 's': { - let s = lauxlib.luaL_tolstring(L, arg); + let s = luaL_tolstring(L, arg); if (form.length <= 2 || form[2] === 0) { /* no modifiers? */ - lauxlib.luaL_addvalue(b); /* keep entire string */ + luaL_addvalue(b); /* keep entire string */ } else { - lauxlib.luaL_argcheck(L, s.length === strlen(s), arg, lua.to_luastring("string contains zeros", true)); - if (form.indexOf('.'.charCodeAt(0)) < 0 && s.length >= 100) { + luaL_argcheck(L, s.length === strlen(s), arg, to_luastring("string contains zeros", true)); + if (luastring_indexOf(form, 46 /* '.'.charCodeAt(0) */) < 0 && s.length >= 100) { /* no precision and string is too long to be formatted */ - lauxlib.luaL_addvalue(b); /* keep entire string */ + luaL_addvalue(b); /* keep entire string */ } else { /* format the string into 'buff' */ // TODO: will fail if s is not valid UTF-8 - lauxlib.luaL_addstring(b, lua.to_luastring(sprintf(String.fromCharCode(...form), lua.to_jsstring(s)))); - lua.lua_pop(L, 1); /* remove result from 'luaL_tolstring' */ + luaL_addstring(b, to_luastring(sprintf(String.fromCharCode(...form), to_jsstring(s)))); + lua_pop(L, 1); /* remove result from 'luaL_tolstring' */ } } break; } default: { /* also treat cases 'pnLlh' */ - return lauxlib.luaL_error(L, lua.to_luastring("invalid option '%%%c' to 'format'"), strfrmt[i-1]); + return luaL_error(L, to_luastring("invalid option '%%%c' to 'format'"), strfrmt[i-1]); } } } } - lauxlib.luaL_pushresult(b); + luaL_pushresult(b); return 1; }; @@ -358,21 +433,17 @@ class Header { /* ** options for pack/unpack */ -const KOption = { - Kint: 0, /* signed integers */ - Kuint: 1, /* unsigned integers */ - Kfloat: 2, /* floating-point numbers */ - Kchar: 3, /* fixed-length strings */ - Kstring: 4, /* strings with prefixed length */ - Kzstr: 5, /* zero-terminated strings */ - Kpadding: 6, /* padding */ - Kpaddalign: 7, /* padding for alignment */ - Knop: 8 /* no-op (configuration or spaces) */ -}; - -const digit = function(c) { - return '0'.charCodeAt(0) <= c && c <= '9'.charCodeAt(0); -}; +const Kint = 0; /* signed integers */ +const Kuint = 1; /* unsigned integers */ +const Kfloat = 2; /* floating-point numbers */ +const Kchar = 3; /* fixed-length strings */ +const Kstring = 4; /* strings with prefixed length */ +const Kzstr = 5; /* zero-terminated strings */ +const Kpadding = 6; /* padding */ +const Kpaddalign = 7; /* padding for alignment */ +const Knop = 8; /* no-op (configuration or spaces) */ + +const digit = isdigit; const getnum = function(fmt, df) { if (fmt.off >= fmt.s.length || !digit(fmt.s[fmt.off])) /* no number? */ @@ -380,7 +451,7 @@ const getnum = function(fmt, df) { else { let a = 0; do { - a = a * 10 + (fmt.s[fmt.off++] - '0'.charCodeAt(0)); + a = a * 10 + (fmt.s[fmt.off++] - 48 /* '0'.charCodeAt(0) */); } while (fmt.off < fmt.s.length && digit(fmt.s[fmt.off]) && a <= (MAXSIZE - 9)/10); return a; } @@ -393,7 +464,7 @@ const getnum = function(fmt, df) { const getnumlimit = function(h, fmt, df) { let sz = getnum(fmt, df); if (sz > MAXINTSIZE || sz <= 0) - lauxlib.luaL_error(h.L, lua.to_luastring("integral size (%d) out of limits [1,%d]"), sz, MAXINTSIZE); + luaL_error(h.L, to_luastring("integral size (%d) out of limits [1,%d]"), sz, MAXINTSIZE); return sz; }; @@ -402,47 +473,43 @@ const getnumlimit = function(h, fmt, df) { */ const getoption = function(h, fmt) { let r = { - opt: NaN, - size: NaN + opt: fmt.s[fmt.off++], + size: 0 /* default */ }; - - r.opt = fmt.s[fmt.off++]; - r.size = 0; /* default */ switch (r.opt) { - case 'b'.charCodeAt(0): r.size = 1; r.opt = KOption.Kint; return r; // sizeof(char): 1 - case 'B'.charCodeAt(0): r.size = 1; r.opt = KOption.Kuint; return r; - case 'h'.charCodeAt(0): r.size = 2; r.opt = KOption.Kint; return r; // sizeof(short): 2 - case 'H'.charCodeAt(0): r.size = 2; r.opt = KOption.Kuint; return r; - case 'l'.charCodeAt(0): r.size = 4; r.opt = KOption.Kint; return r; // sizeof(long): 4 - case 'L'.charCodeAt(0): r.size = 4; r.opt = KOption.Kuint; return r; - case 'j'.charCodeAt(0): r.size = 4; r.opt = KOption.Kint; return r; // sizeof(lua_Integer): 4 - case 'J'.charCodeAt(0): r.size = 4; r.opt = KOption.Kuint; return r; - case 'T'.charCodeAt(0): r.size = 4; r.opt = KOption.Kuint; return r; // sizeof(size_t): 4 - case 'f'.charCodeAt(0): r.size = 4; r.opt = KOption.Kfloat; return r; // sizeof(float): 4 - case 'd'.charCodeAt(0): r.size = 8; r.opt = KOption.Kfloat; return r; // sizeof(double): 8 - case 'n'.charCodeAt(0): r.size = 8; r.opt = KOption.Kfloat; return r; // sizeof(lua_Number): 8 - case 'i'.charCodeAt(0): r.size = getnumlimit(h, fmt, 4); r.opt = KOption.Kint; return r; // sizeof(int): 4 - case 'I'.charCodeAt(0): r.size = getnumlimit(h, fmt, 4); r.opt = KOption.Kuint; return r; - case 's'.charCodeAt(0): r.size = getnumlimit(h, fmt, 4); r.opt = KOption.Kstring; return r; - case 'c'.charCodeAt(0): { + case 98 /*'b'*/: r.size = 1; r.opt = Kint; return r; // sizeof(char): 1 + case 66 /*'B'*/: r.size = 1; r.opt = Kuint; return r; + case 104 /*'h'*/: r.size = 2; r.opt = Kint; return r; // sizeof(short): 2 + case 72 /*'H'*/: r.size = 2; r.opt = Kuint; return r; + case 108 /*'l'*/: r.size = 4; r.opt = Kint; return r; // sizeof(long): 4 + case 76 /*'L'*/: r.size = 4; r.opt = Kuint; return r; + case 106 /*'j'*/: r.size = 4; r.opt = Kint; return r; // sizeof(lua_Integer): 4 + case 74 /*'J'*/: r.size = 4; r.opt = Kuint; return r; + case 84 /*'T'*/: r.size = 4; r.opt = Kuint; return r; // sizeof(size_t): 4 + case 102 /*'f'*/: r.size = 4; r.opt = Kfloat; return r; // sizeof(float): 4 + case 100 /*'d'*/: r.size = 8; r.opt = Kfloat; return r; // sizeof(double): 8 + case 110 /*'n'*/: r.size = 8; r.opt = Kfloat; return r; // sizeof(lua_Number): 8 + case 105 /*'i'*/: r.size = getnumlimit(h, fmt, 4); r.opt = Kint; return r; // sizeof(int): 4 + case 73 /*'I'*/: r.size = getnumlimit(h, fmt, 4); r.opt = Kuint; return r; + case 115 /*'s'*/: r.size = getnumlimit(h, fmt, 4); r.opt = Kstring; return r; + case 99 /*'c'*/: { r.size = getnum(fmt, -1); if (r.size === -1) - lauxlib.luaL_error(h.L, lua.to_luastring("missing size for format option 'c'")); - r.opt = KOption.Kchar; + luaL_error(h.L, to_luastring("missing size for format option 'c'")); + r.opt = Kchar; return r; } - case 'z'.charCodeAt(0): r.opt = KOption.Kzstr; return r; - case 'x'.charCodeAt(0): r.size = 1; r.opt = KOption.Kpadding; return r; - case 'X'.charCodeAt(0): r.opt = KOption.Kpaddalign; return r; - case ' '.charCodeAt(0): break; - case '<'.charCodeAt(0): h.islittle = true; break; - case '>'.charCodeAt(0): h.islittle = false; break; - case '='.charCodeAt(0): h.islittle = true; break; - case '!'.charCodeAt(0): h.maxalign = getnumlimit(h, fmt, MAXALIGN); break; - default: lauxlib.luaL_error(h.L, lua.to_luastring("invalid format option '%c'"), r.opt); + case 122 /*'z'*/: r.opt = Kzstr; return r; + case 120 /*'x'*/: r.size = 1; r.opt = Kpadding; return r; + case 88 /*'X'*/: r.opt = Kpaddalign; return r; + case 32 /*' '*/: break; + case 60 /*'<'*/: h.islittle = true; break; + case 62 /*'>'*/: h.islittle = false; break; + case 61 /*'='*/: h.islittle = true; break; + case 33 /*'!'*/: h.maxalign = getnumlimit(h, fmt, MAXALIGN); break; + default: luaL_error(h.L, to_luastring("invalid format option '%c'"), r.opt); } - - r.opt = KOption.Knop; + r.opt = Knop; return r; }; @@ -466,24 +533,24 @@ const getdetails = function(h, totalsize, fmt) { r.size = opt.size; r.opt = opt.opt; let align = r.size; /* usually, alignment follows size */ - if (r.opt === KOption.Kpaddalign) { /* 'X' gets alignment from following option */ + if (r.opt === Kpaddalign) { /* 'X' gets alignment from following option */ if (fmt.off >= fmt.s.length || fmt.s[fmt.off] === 0) - lauxlib.luaL_argerror(h.L, 1, lua.to_luastring("invalid next option for option 'X'", true)); + luaL_argerror(h.L, 1, to_luastring("invalid next option for option 'X'", true)); else { let o = getoption(h, fmt); align = o.size; o = o.opt; - if (o === KOption.Kchar || align === 0) - lauxlib.luaL_argerror(h.L, 1, lua.to_luastring("invalid next option for option 'X'", true)); + if (o === Kchar || align === 0) + luaL_argerror(h.L, 1, to_luastring("invalid next option for option 'X'", true)); } } - if (align <= 1 || r.opt === KOption.Kchar) /* need no alignment? */ + if (align <= 1 || r.opt === Kchar) /* need no alignment? */ r.ntoalign = 0; else { if (align > h.maxalign) /* enforce maximum alignment */ align = h.maxalign; if ((align & (align -1)) !== 0) /* is 'align' not a power of 2? */ - lauxlib.luaL_argerror(h.L, 1, lua.to_luastring("format asks for alignment not power of 2", true)); + luaL_argerror(h.L, 1, to_luastring("format asks for alignment not power of 2", true)); r.ntoalign = (align - (totalsize & (align - 1))) & (align - 1); } return r; @@ -496,7 +563,7 @@ const getdetails = function(h, totalsize, fmt) { ** bytes if necessary (by default they would be zeros). */ const packint = function(b, n, islittle, size, neg) { - let buff = lauxlib.luaL_prepbuffsize(b, size); + let buff = luaL_prepbuffsize(b, size); buff[islittle ? 0 : size - 1] = n & MC; /* first byte */ for (let i = 1; i < size; i++) { n >>= NB; @@ -506,20 +573,20 @@ const packint = function(b, n, islittle, size, neg) { for (let i = SZINT; i < size; i++) /* correct extra bytes */ buff[islittle ? i : size - 1 - i] = MC; } - lauxlib.luaL_addsize(b, size); /* add result to buffer */ + luaL_addsize(b, size); /* add result to buffer */ }; const str_pack = function(L) { - let b = new lauxlib.luaL_Buffer(); + let b = new luaL_Buffer(); let h = new Header(L); let fmt = { - s: lauxlib.luaL_checkstring(L, 1), /* format string */ + s: luaL_checkstring(L, 1), /* format string */ off: 0 }; let arg = 1; /* current argument to pack */ let totalsize = 0; /* accumulate total size of result */ - lua.lua_pushnil(L); /* mark to separate arguments from string buffer */ - lauxlib.luaL_buffinit(L, b); + lua_pushnil(L); /* mark to separate arguments from string buffer */ + luaL_buffinit(L, b); while (fmt.off < fmt.s.length) { let details = getdetails(h, totalsize, fmt); let opt = details.opt; @@ -527,105 +594,124 @@ const str_pack = function(L) { let ntoalign = details.ntoalign; totalsize += ntoalign + size; while (ntoalign-- > 0) - lauxlib.luaL_addchar(b, LUAL_PACKPADBYTE); /* fill alignment */ + luaL_addchar(b, LUAL_PACKPADBYTE); /* fill alignment */ arg++; switch (opt) { - case KOption.Kint: { /* signed integers */ - let n = lauxlib.luaL_checkinteger(L, arg); + case Kint: { /* signed integers */ + let n = luaL_checkinteger(L, arg); if (size < SZINT) { /* need overflow check? */ let lim = 1 << (size * 8) - 1; - lauxlib.luaL_argcheck(L, -lim <= n && n < lim, arg, lua.to_luastring("integer overflow", true)); + luaL_argcheck(L, -lim <= n && n < lim, arg, to_luastring("integer overflow", true)); } packint(b, n, h.islittle, size, n < 0); break; } - case KOption.Kuint: { /* unsigned integers */ - let n = lauxlib.luaL_checkinteger(L, arg); + case Kuint: { /* unsigned integers */ + let n = luaL_checkinteger(L, arg); if (size < SZINT) - lauxlib.luaL_argcheck(L, (n>>>0) < (1 << (size * NB)), arg, lua.to_luastring("unsigned overflow", true)); + luaL_argcheck(L, (n>>>0) < (1 << (size * NB)), arg, to_luastring("unsigned overflow", true)); packint(b, n>>>0, h.islittle, size, false); break; } - case KOption.Kfloat: { /* floating-point options */ - let buff = lauxlib.luaL_prepbuffsize(b, size); - let n = lauxlib.luaL_checknumber(L, arg); /* get argument */ - let dv = new DataView(buff.buffer); + case Kfloat: { /* floating-point options */ + let buff = luaL_prepbuffsize(b, size); + let n = luaL_checknumber(L, arg); /* get argument */ + let dv = new DataView(buff.buffer, buff.byteOffset, buff.byteLength); if (size === 4) dv.setFloat32(0, n, h.islittle); else dv.setFloat64(0, n, h.islittle); - lauxlib.luaL_addsize(b, size); + luaL_addsize(b, size); break; } - case KOption.Kchar: { /* fixed-size string */ - let s = lauxlib.luaL_checkstring(L, arg); + case Kchar: { /* fixed-size string */ + let s = luaL_checkstring(L, arg); let len = s.length; - lauxlib.luaL_argcheck(L, len <= size, arg, lua.to_luastring("string longer than given size", true)); - lauxlib.luaL_addlstring(b, s, len); /* add string */ + luaL_argcheck(L, len <= size, arg, to_luastring("string longer than given size", true)); + luaL_addlstring(b, s, len); /* add string */ while (len++ < size) /* pad extra space */ - lauxlib.luaL_addchar(b, LUAL_PACKPADBYTE); + luaL_addchar(b, LUAL_PACKPADBYTE); break; } - case KOption.Kstring: { /* strings with length count */ - let s = lauxlib.luaL_checkstring(L, arg); + case Kstring: { /* strings with length count */ + let s = luaL_checkstring(L, arg); let len = s.length; - lauxlib.luaL_argcheck(L, + luaL_argcheck(L, size >= 4 /* sizeof(size_t) */ || len < (1 << (size * NB)), - arg, lua.to_luastring("string length does not fit in given size", true)); + arg, to_luastring("string length does not fit in given size", true)); packint(b, len, h.islittle, size, 0); /* pack length */ - lauxlib.luaL_addlstring(b, s, len); + luaL_addlstring(b, s, len); totalsize += len; break; } - case KOption.Kzstr: { /* zero-terminated string */ - let s = lauxlib.luaL_checkstring(L, arg); + case Kzstr: { /* zero-terminated string */ + let s = luaL_checkstring(L, arg); let len = s.length; - lauxlib.luaL_argcheck(L, s.indexOf(0) < 0, arg, lua.to_luastring("strings contains zeros", true)); - lauxlib.luaL_addlstring(b, s, len); - lauxlib.luaL_addchar(b, 0); /* add zero at the end */ + luaL_argcheck(L, luastring_indexOf(s, 0) < 0, arg, to_luastring("strings contains zeros", true)); + luaL_addlstring(b, s, len); + luaL_addchar(b, 0); /* add zero at the end */ totalsize += len + 1; break; } - case KOption.Kpadding: lauxlib.luaL_addchar(b, LUAL_PACKPADBYTE); /* fall through */ - case KOption.Kpaddalign: case KOption.Knop: + case Kpadding: luaL_addchar(b, LUAL_PACKPADBYTE); /* fall through */ + case Kpaddalign: case Knop: arg--; /* undo increment */ break; } } - lauxlib.luaL_pushresult(b); + luaL_pushresult(b); return 1; }; const str_reverse = function(L) { - lua.lua_pushstring(L, lauxlib.luaL_checkstring(L, 1).slice(0).reverse()); + let s = luaL_checkstring(L, 1); + let l = s.length; + let r = new Uint8Array(l); + for (let i=0; i<l; i++) + r[i] = s[l-1-i]; + lua_pushstring(L, r); return 1; }; const str_lower = function(L) { - let s = lauxlib.luaL_checkstring(L, 1); - // TODO: will fail on invalid UTF-8 - lua.lua_pushstring(L, lua.to_luastring(lua.to_jsstring(s).toLowerCase())); + let s = luaL_checkstring(L, 1); + let l = s.length; + let r = new Uint8Array(l); + for (let i=0; i<l; i++) { + let c = s[i]; + if (isupper(c)) + c = c | 0x20; + r[i] = c; + } + lua_pushstring(L, r); return 1; }; const str_upper = function(L) { - let s = lauxlib.luaL_checkstring(L, 1); - // TODO: will fail on invalid UTF-8 - lua.lua_pushstring(L, lua.to_luastring(lua.to_jsstring(s).toUpperCase())); + let s = luaL_checkstring(L, 1); + let l = s.length; + let r = new Uint8Array(l); + for (let i=0; i<l; i++) { + let c = s[i]; + if (islower(c)) + c = c & 0xdf; + r[i] = c; + } + lua_pushstring(L, r); return 1; }; const str_rep = function(L) { - let s = lauxlib.luaL_checkstring(L, 1); + let s = luaL_checkstring(L, 1); let l = s.length; - let n = lauxlib.luaL_checkinteger(L, 2); - let sep = lauxlib.luaL_optstring(L, 3, lua.to_luastring("")); + let n = luaL_checkinteger(L, 2); + let sep = luaL_optstring(L, 3, to_luastring("")); let lsep = sep.length; - if (n <= 0) lua.lua_pushliteral(L, ""); + if (n <= 0) lua_pushliteral(L, ""); else if (l + lsep < l || l + lsep > MAXSIZE / n) /* may overflow? */ - return lauxlib.luaL_error(L, lua.to_luastring("resulting string too large")); + return luaL_error(L, to_luastring("resulting string too large")); else { let totallen = n * l + (n - 1) * lsep; - let b = new lauxlib.luaL_Buffer(); - let p = lauxlib.luaL_buffinitsize(L, b, totallen); + let b = new luaL_Buffer(); + let p = luaL_buffinitsize(L, b, totallen); let pi = 0; while (n-- > 1) { /* first n-1 copies (followed by separator) */ p.set(s, pi); @@ -636,34 +722,34 @@ const str_rep = function(L) { } } p.set(s, pi); /* last copy (not followed by separator) */ - lauxlib.luaL_pushresultsize(b, totallen); + luaL_pushresultsize(b, totallen); } return 1; }; const str_byte = function(L) { - let s = lauxlib.luaL_checkstring(L, 1); + let s = luaL_checkstring(L, 1); let l = s.length; - let posi = posrelat(lauxlib.luaL_optinteger(L, 2, 1), l); - let pose = posrelat(lauxlib.luaL_optinteger(L, 3, posi), l); + let posi = posrelat(luaL_optinteger(L, 2, 1), l); + let pose = posrelat(luaL_optinteger(L, 3, posi), l); if (posi < 1) posi = 1; if (pose > l) pose = l; if (posi > pose) return 0; /* empty interval; return no values */ if (pose - posi >= Number.MAX_SAFE_INTEGER) /* arithmetic overflow? */ - return lauxlib.luaL_error(L, lua.to_luastring("string slice too long", true)); + return luaL_error(L, to_luastring("string slice too long", true)); let n = (pose - posi) + 1; - lauxlib.luaL_checkstack(L, n, lua.to_luastring("string slice too long", true)); + luaL_checkstack(L, n, to_luastring("string slice too long", true)); for (let i = 0; i < n; i++) - lua.lua_pushinteger(L, s[posi + i - 1]); + lua_pushinteger(L, s[posi + i - 1]); return n; }; const str_packsize = function(L) { let h = new Header(L); let fmt = { - s: lauxlib.luaL_checkstring(L, 1), + s: luaL_checkstring(L, 1), off: 0 }; let totalsize = 0; /* accumulate total size of result */ @@ -673,17 +759,17 @@ const str_packsize = function(L) { let size = details.size; let ntoalign = details.ntoalign; size += ntoalign; /* total space used by option */ - lauxlib.luaL_argcheck(L, totalsize <= MAXSIZE - size, 1, lua.to_luastring("format result too large", true)); + luaL_argcheck(L, totalsize <= MAXSIZE - size, 1, to_luastring("format result too large", true)); totalsize += size; switch (opt) { - case KOption.Kstring: /* strings with length count */ - case KOption.Kzstr: /* zero-terminated string */ - lauxlib.luaL_argerror(L, 1, lua.to_luastring("variable-length format", true)); + case Kstring: /* strings with length count */ + case Kzstr: /* zero-terminated string */ + luaL_argerror(L, 1, to_luastring("variable-length format", true)); /* call never return, but to avoid warnings: *//* fall through */ default: break; } } - lua.lua_pushinteger(L, totalsize); + lua_pushinteger(L, totalsize); return 1; }; @@ -711,14 +797,14 @@ const unpackint = function(L, str, islittle, size, issigned) { let mask = !issigned || res >= 0 ? 0 : MC; for (let i = limit; i < size; i++) { if (str[islittle ? i : size - 1 - i] !== mask) - lauxlib.luaL_error(L, lua.to_luastring("%d-byte integer does not fit into Lua Integer"), size); + luaL_error(L, to_luastring("%d-byte integer does not fit into Lua Integer"), size); } } return res; }; const unpacknum = function(L, b, islittle, size) { - assert(b.length >= size); + lualib.lua_assert(b.length >= size); let dv = new DataView(new ArrayBuffer(size)); for (let i = 0; i < size; i++) @@ -731,68 +817,69 @@ const unpacknum = function(L, b, islittle, size) { const str_unpack = function(L) { let h = new Header(L); let fmt = { - s: lauxlib.luaL_checkstring(L, 1), + s: luaL_checkstring(L, 1), off: 0 }; - let data = lauxlib.luaL_checkstring(L, 2); + let data = luaL_checkstring(L, 2); let ld = data.length; - let pos = posrelat(lauxlib.luaL_optinteger(L, 3, 1), ld) - 1; + let pos = posrelat(luaL_optinteger(L, 3, 1), ld) - 1; let n = 0; /* number of results */ - lauxlib.luaL_argcheck(L, pos <= ld && pos >= 0, 3, lua.to_luastring("initial position out of string", true)); + luaL_argcheck(L, pos <= ld && pos >= 0, 3, to_luastring("initial position out of string", true)); while (fmt.off < fmt.s.length) { let details = getdetails(h, pos, fmt); let opt = details.opt; let size = details.size; let ntoalign = details.ntoalign; if (/*ntoalign + size > ~pos ||*/ pos + ntoalign + size > ld) - lauxlib.luaL_argerror(L, 2, lua.to_luastring("data string too short", true)); + luaL_argerror(L, 2, to_luastring("data string too short", true)); pos += ntoalign; /* skip alignment */ /* stack space for item + next position */ - lauxlib.luaL_checkstack(L, 2, lua.to_luastring("too many results", true)); + luaL_checkstack(L, 2, to_luastring("too many results", true)); n++; switch (opt) { - case KOption.Kint: - case KOption.Kuint: { - let res = unpackint(L, data.slice(pos), h.islittle, size, opt === KOption.Kint); - lua.lua_pushinteger(L, res); + case Kint: + case Kuint: { + let res = unpackint(L, data.subarray(pos), h.islittle, size, opt === Kint); + lua_pushinteger(L, res); break; } - case KOption.Kfloat: { - let res = unpacknum(L, data.slice(pos), h.islittle, size); - lua.lua_pushnumber(L, res); + case Kfloat: { + let res = unpacknum(L, data.subarray(pos), h.islittle, size); + lua_pushnumber(L, res); break; } - case KOption.Kchar: { - lua.lua_pushstring(L, data.slice(pos, pos + size)); + case Kchar: { + lua_pushstring(L, data.subarray(pos, pos + size)); break; } - case KOption.Kstring: { - let len = unpackint(L, data.slice(pos), h.islittle, size, 0); - lauxlib.luaL_argcheck(L, pos + len + size <= ld, 2, lua.to_luastring("data string too short", true)); - lua.lua_pushstring(L, data.slice(pos + size, pos + size + len)); + case Kstring: { + let len = unpackint(L, data.subarray(pos), h.islittle, size, 0); + luaL_argcheck(L, pos + len + size <= ld, 2, to_luastring("data string too short", true)); + lua_pushstring(L, data.subarray(pos + size, pos + size + len)); pos += len; /* skip string */ break; } - case KOption.Kzstr: { - let len = data.slice(pos).indexOf(0); - lua.lua_pushstring(L, data.slice(pos, pos + len)); - pos += len + 1; /* skip string plus final '\0' */ + case Kzstr: { + let e = luastring_indexOf(data, 0, pos); + if (e === -1) e = data.length - pos; + lua_pushstring(L, data.subarray(pos, e)); + pos = e + 1; /* skip string plus final '\0' */ break; } - case KOption.Kpaddalign: case KOption.Kpadding: case KOption.Knop: + case Kpaddalign: case Kpadding: case Knop: n--; /* undo increment */ break; } pos += size; } - lua.lua_pushinteger(L, pos + 1); /* next position */ + lua_pushinteger(L, pos + 1); /* next position */ return n + 1; }; const CAP_UNFINISHED = -1; const CAP_POSITION = -2; const MAXCCALLS = 200; -const SPECIALS = ["^".charCodeAt(0), "$".charCodeAt(0), "*".charCodeAt(0), "+".charCodeAt(0), "?".charCodeAt(0), ".".charCodeAt(0), "(".charCodeAt(0), "[".charCodeAt(0), "%".charCodeAt(0), "-".charCodeAt(0)]; +const SPECIALS = to_luastring("^$*+?.([%-"); class MatchState { constructor(L) { @@ -809,9 +896,9 @@ class MatchState { } const check_capture = function(ms, l) { - l = l - '1'.charCodeAt(0); + l = l - 49 /* '1'.charCodeAt(0) */; if (l < 0 || l >= ms.level || ms.capture[l].len === CAP_UNFINISHED) - return lauxlib.luaL_error(ms.L, lua.to_luastring("invalid capture index %%%d"), l + 1); + return luaL_error(ms.L, to_luastring("invalid capture index %%%d"), l + 1); return l; }; @@ -819,24 +906,24 @@ const capture_to_close = function(ms) { let level = ms.level; for (level--; level >= 0; level--) if (ms.capture[level].len === CAP_UNFINISHED) return level; - return lauxlib.luaL_error(ms.L, lua.to_luastring("invalid pattern capture")); + return luaL_error(ms.L, to_luastring("invalid pattern capture")); }; const classend = function(ms, p) { switch(ms.p[p++]) { case L_ESC: { if (p === ms.p_end) - lauxlib.luaL_error(ms.L, lua.to_luastring("malformed pattern (ends with '%%')")); + luaL_error(ms.L, to_luastring("malformed pattern (ends with '%%')")); return p + 1; } - case '['.charCodeAt(0): { - if (ms.p[p] === '^'.charCodeAt(0)) p++; + case 91 /* '['.charCodeAt(0) */: { + if (ms.p[p] === 94 /* '^'.charCodeAt(0) */) p++; do { /* look for a ']' */ if (p === ms.p_end) - lauxlib.luaL_error(ms.L, lua.to_luastring("malformed pattern (missing ']')")); + luaL_error(ms.L, to_luastring("malformed pattern (missing ']')")); if (ms.p[p++] === L_ESC && p < ms.p_end) p++; /* skip escapes (e.g. '%]') */ - } while (ms.p[p] !== ']'.charCodeAt(0)); + } while (ms.p[p] !== 93 /* ']'.charCodeAt(0) */); return p + 1; } default: { @@ -846,27 +933,36 @@ const classend = function(ms, p) { }; const match_class = function(c, cl) { - let res; - switch (String.fromCharCode(cl).toLowerCase().charCodeAt(0)) { - case 'a'.charCodeAt(0) : res = isalpha(c); break; - case 'c'.charCodeAt(0) : res = iscntrl(c); break; - case 'd'.charCodeAt(0) : res = isdigit(c); break; - case 'g'.charCodeAt(0) : res = isgraph(c); break; - case 'l'.charCodeAt(0) : res = islower(c); break; - case 'p'.charCodeAt(0) : res = ispunct(c); break; - case 's'.charCodeAt(0) : res = isspace(c); break; - case 'u'.charCodeAt(0) : res = isupper(c); break; - case 'w'.charCodeAt(0) : res = isalnum(c); break; - case 'x'.charCodeAt(0) : res = isxdigit(c); break; - case 'z'.charCodeAt(0) : res = (c === 0); break; /* deprecated option */ + switch (cl) { + case 97 /* 'a'.charCodeAt(0) */: return isalpha(c); + case 65 /* 'A'.charCodeAt(0) */: return !isalpha(c); + case 99 /* 'c'.charCodeAt(0) */: return iscntrl(c); + case 67 /* 'C'.charCodeAt(0) */: return !iscntrl(c); + case 100 /* 'd'.charCodeAt(0) */: return isdigit(c); + case 68 /* 'D'.charCodeAt(0) */: return !isdigit(c); + case 103 /* 'g'.charCodeAt(0) */: return isgraph(c); + case 71 /* 'G'.charCodeAt(0) */: return !isgraph(c); + case 108 /* 'l'.charCodeAt(0) */: return islower(c); + case 76 /* 'L'.charCodeAt(0) */: return !islower(c); + case 112 /* 'p'.charCodeAt(0) */: return ispunct(c); + case 80 /* 'P'.charCodeAt(0) */: return !ispunct(c); + case 115 /* 's'.charCodeAt(0) */: return isspace(c); + case 83 /* 'S'.charCodeAt(0) */: return !isspace(c); + case 117 /* 'u'.charCodeAt(0) */: return isupper(c); + case 85 /* 'U'.charCodeAt(0) */: return !isupper(c); + case 119 /* 'w'.charCodeAt(0) */: return isalnum(c); + case 87 /* 'W'.charCodeAt(0) */: return !isalnum(c); + case 120 /* 'x'.charCodeAt(0) */: return isxdigit(c); + case 88 /* 'X'.charCodeAt(0) */: return !isxdigit(c); + case 122 /* 'z'.charCodeAt(0) */: return (c === 0); /* deprecated option */ + case 90 /* 'z'.charCodeAt(0) */: return (c !== 0); /* deprecated option */ default: return (cl === c); } - return (islower(cl) ? res : !res); }; const matchbracketclass = function(ms, c, p, ec) { let sig = true; - if (ms.p[p + 1] === '^'.charCodeAt(0)) { + if (ms.p[p + 1] === 94 /* '^'.charCodeAt(0) */) { sig = false; p++; /* skip the '^' */ } @@ -875,7 +971,7 @@ const matchbracketclass = function(ms, c, p, ec) { p++; if (match_class(c, ms.p[p])) return sig; - } else if (ms.p[p + 1] === '-'.charCodeAt(0) && p + 2 < ec) { + } else if (ms.p[p + 1] === 45 /* '-'.charCodeAt(0) */ && p + 2 < ec) { p += 2; if (ms.p[p - 2] <= c && c <= ms.p[p]) return sig; @@ -890,9 +986,9 @@ const singlematch = function(ms, s, p, ep) { else { let c = ms.src[s]; switch (ms.p[p]) { - case '.'.charCodeAt(0): return true; /* matches any char */ + case 46 /* '.'.charCodeAt(0) */: return true; /* matches any char */ case L_ESC: return match_class(c, ms.p[p + 1]); - case '['.charCodeAt(0): return matchbracketclass(ms, c, p, ep - 1); + case 91 /* '['.charCodeAt(0) */: return matchbracketclass(ms, c, p, ep - 1); default: return ms.p[p] === c; } } @@ -900,7 +996,7 @@ const singlematch = function(ms, s, p, ep) { const matchbalance = function(ms, s, p) { if (p >= ms.p_end - 1) - lauxlib.luaL_error(ms.L, lua.to_luastring("malformed pattern (missing arguments to '%%b'")); + luaL_error(ms.L, to_luastring("malformed pattern (missing arguments to '%%b'")); if (ms.src[s] !== ms.p[p]) return null; else { @@ -943,7 +1039,7 @@ const min_expand = function(ms, s, p, ep) { const start_capture = function(ms, s, p, what) { let level = ms.level; - if (level >= LUA_MAXCAPTURES) lauxlib.luaL_error(ms.L, lua.to_luastring("too many captures", true)); + if (level >= LUA_MAXCAPTURES) luaL_error(ms.L, to_luastring("too many captures", true)); ms.capture[level] = ms.capture[level] ? ms.capture[level] : {}; ms.capture[level].init = s; ms.capture[level].len = what; @@ -969,7 +1065,7 @@ const array_cmp = function(a, ai, b, bi, len) { return true; let aj = ai+len; loop: for (;;) { - ai = a.indexOf(b[bi], ai); + ai = luastring_indexOf(a, b[bi], ai); if (ai === -1 || ai >= aj) return false; for (let j = 1; j < len; j++) { @@ -995,24 +1091,24 @@ const match = function(ms, s, p) { let gotoinit = true; if (ms.matchdepth-- === 0) - lauxlib.luaL_error(ms.L, lua.to_luastring("pattern too complex", true)); + luaL_error(ms.L, to_luastring("pattern too complex", true)); while (gotoinit || gotodefault) { gotoinit = false; if (p !== ms.p_end) { /* end of pattern? */ - switch (gotodefault ? 'x'.charCodeAt(0) : ms.p[p]) { - case '('.charCodeAt(0): { /* start capture */ - if (ms.p[p + 1] === ')'.charCodeAt(0)) /* position capture? */ + switch (gotodefault ? void 0 : ms.p[p]) { + case 40 /* '('.charCodeAt(0) */: { /* start capture */ + if (ms.p[p + 1] === 41 /* ')'.charCodeAt(0) */) /* position capture? */ s = start_capture(ms, s, p + 2, CAP_POSITION); else s = start_capture(ms, s, p + 1, CAP_UNFINISHED); break; } - case ')'.charCodeAt(0): { /* end capture */ + case 41 /* ')'.charCodeAt(0) */: { /* end capture */ s = end_capture(ms, s, p + 1); break; } - case '$'.charCodeAt(0): { + case 36 /* '$'.charCodeAt(0) */: { if (p + 1 !== ms.p_end) { /* is the '$' the last char in pattern? */ gotodefault = true; /* no; go to default */ break; @@ -1022,7 +1118,7 @@ const match = function(ms, s, p) { } case L_ESC: { /* escaped sequences not in the format class[*+?-]? */ switch (ms.p[p + 1]) { - case 'b'.charCodeAt(0): { /* balanced string? */ + case 98 /* 'b'.charCodeAt(0) */: { /* balanced string? */ s = matchbalance(ms, s, p + 2); if (s !== null) { p += 4; @@ -1030,10 +1126,10 @@ const match = function(ms, s, p) { } break; } - case 'f'.charCodeAt(0): { /* frontier? */ + case 102 /* 'f'.charCodeAt(0) */: { /* frontier? */ p += 2; - if (ms.p[p] !== '['.charCodeAt(0)) - lauxlib.luaL_error(ms.L, lua.to_luastring("missing '[' after '%%f' in pattern")); + if (ms.p[p] !== 91 /* '['.charCodeAt(0) */) + luaL_error(ms.L, to_luastring("missing '[' after '%%f' in pattern")); let ep = classend(ms, p); /* points to what is next */ let previous = s === ms.src_init ? 0 : ms.src[s-1]; if (!matchbracketclass(ms, previous, p, ep - 1) && matchbracketclass(ms, (s===ms.src_end)?0:ms.src[s], p, ep - 1)) { @@ -1042,9 +1138,8 @@ const match = function(ms, s, p) { s = null; /* match failed */ break; } - case '0'.charCodeAt(0): case '1'.charCodeAt(0): case '2'.charCodeAt(0): case '3'.charCodeAt(0): - case '4'.charCodeAt(0): case '5'.charCodeAt(0): case '6'.charCodeAt(0): case '7'.charCodeAt(0): - case '8'.charCodeAt(0): case '9'.charCodeAt(0): { /* capture results (%0-%9)? */ + case 48: case 49: case 50: case 51: case 52: + case 53: case 54: case 55: case 56: case 57: { /* capture results (%0-%9)? */ s = match_capture(ms, s, ms.p[p + 1]); if (s !== null) { p += 2; gotoinit = true; @@ -1060,13 +1155,16 @@ const match = function(ms, s, p) { let ep = classend(ms, p); /* points to optional suffix */ /* does not match at least once? */ if (!singlematch(ms, s, p, ep)) { - if (ms.p[ep] === '*'.charCodeAt(0) || ms.p[ep] === '?'.charCodeAt(0) || ms.p[ep] === '-'.charCodeAt(0)) { /* accept empty? */ + if (ms.p[ep] === 42 /* '*'.charCodeAt(0) */ || + ms.p[ep] === 63 /* '?'.charCodeAt(0) */ || + ms.p[ep] === 45 /* '-'.charCodeAt(0) */ + ) { /* accept empty? */ p = ep + 1; gotoinit = true; break; } else /* '+' or no suffix */ s = null; /* fail */ } else { /* matched once */ switch (ms.p[ep]) { /* handle optional suffix */ - case '?'.charCodeAt(0): { /* optional */ + case 63 /* '?'.charCodeAt(0) */: { /* optional */ let res; if ((res = match(ms, s + 1, ep + 1)) !== null) s = res; @@ -1075,13 +1173,13 @@ const match = function(ms, s, p) { } break; } - case '+'.charCodeAt(0): /* 1 or more repetitions */ + case 43 /* '+'.charCodeAt(0) */: /* 1 or more repetitions */ s++; /* 1 match already done */ /* fall through */ - case '*'.charCodeAt(0): /* 0 or more repetitions */ + case 42 /* '*'.charCodeAt(0) */: /* 0 or more repetitions */ s = max_expand(ms, s, p, ep); break; - case '-'.charCodeAt(0): /* 0 or more repetitions (minimum) */ + case 45 /* '-'.charCodeAt(0) */: /* 0 or more repetitions (minimum) */ s = min_expand(ms, s, p, ep); break; default: /* no suffix */ @@ -1100,22 +1198,22 @@ const match = function(ms, s, p) { const push_onecapture = function(ms, i, s, e) { if (i >= ms.level) { if (i === 0) - lua.lua_pushlstring(ms.L, ms.src.slice(s, e), e - s); /* add whole match */ + lua_pushlstring(ms.L, ms.src.subarray(s, e), e - s); /* add whole match */ else - lauxlib.luaL_error(ms.L, lua.to_luastring("invalid capture index %%%d"), i + 1); + luaL_error(ms.L, to_luastring("invalid capture index %%%d"), i + 1); } else { let l = ms.capture[i].len; - if (l === CAP_UNFINISHED) lauxlib.luaL_error(ms.L, lua.to_luastring("unfinished capture", true)); + if (l === CAP_UNFINISHED) luaL_error(ms.L, to_luastring("unfinished capture", true)); if (l === CAP_POSITION) - lua.lua_pushinteger(ms.L, ms.capture[i].init - ms.src_init + 1); + lua_pushinteger(ms.L, ms.capture[i].init - ms.src_init + 1); else - lua.lua_pushlstring(ms.L, ms.src.slice(ms.capture[i].init), l); + lua_pushlstring(ms.L, ms.src.subarray(ms.capture[i].init), l); } }; const push_captures = function(ms, s, e) { - let nlevels = ms.level === 0 && ms.src.slice(s) ? 1 : ms.level; - lauxlib.luaL_checkstack(ms.L, nlevels, lua.to_luastring("too many catpures", true)); + let nlevels = ms.level === 0 && ms.src.subarray(s) ? 1 : ms.level; + luaL_checkstack(ms.L, nlevels, to_luastring("too many catpures", true)); for (let i = 0; i < nlevels; i++) push_onecapture(ms, i, s, e); return nlevels; /* number of strings pushed */ @@ -1123,7 +1221,7 @@ const push_captures = function(ms, s, e) { const nospecials = function(p, l) { for (let i=0; i<l; i++) { - if (SPECIALS.indexOf(p[i]) !== -1) + if (luastring_indexOf(SPECIALS, p[i]) !== -1) return false; } return true; @@ -1141,7 +1239,7 @@ const prepstate = function(ms, L, s, ls, p, lp) { const reprepstate = function(ms) { ms.level = 0; - assert(ms.matchdepth === MAXCCALLS); + lualib.lua_assert(ms.matchdepth === MAXCCALLS); }; const find_subarray = function(arr, subarr, from_index) { @@ -1166,31 +1264,31 @@ const find_subarray = function(arr, subarr, from_index) { }; const str_find_aux = function(L, find) { - let s = lauxlib.luaL_checkstring(L, 1); - let p = lauxlib.luaL_checkstring(L, 2); + let s = luaL_checkstring(L, 1); + let p = luaL_checkstring(L, 2); let ls = s.length; let lp = p.length; - let init = posrelat(lauxlib.luaL_optinteger(L, 3, 1), ls); + let init = posrelat(luaL_optinteger(L, 3, 1), ls); if (init < 1) init = 1; else if (init > ls + 1) { /* start after string's end? */ - lua.lua_pushnil(L); /* cannot find anything */ + lua_pushnil(L); /* cannot find anything */ return 1; } /* explicit request or no special characters? */ - if (find && (lua.lua_toboolean(L, 4) || nospecials(p, lp))) { + if (find && (lua_toboolean(L, 4) || nospecials(p, lp))) { /* do a plain search */ - let f = find_subarray(s.slice(init - 1), p, 0); + let f = find_subarray(s.subarray(init - 1), p, 0); if (f > -1) { - lua.lua_pushinteger(L, init + f); - lua.lua_pushinteger(L, init + f + lp - 1); + lua_pushinteger(L, init + f); + lua_pushinteger(L, init + f + lp - 1); return 2; } } else { let ms = new MatchState(L); let s1 = init - 1; - let anchor = p[0] === '^'.charCodeAt(0); + let anchor = p[0] === 94 /* '^'.charCodeAt(0) */; if (anchor) { - p = p.slice(1); lp--; /* skip anchor character */ + p = p.subarray(1); lp--; /* skip anchor character */ } prepstate(ms, L, s, ls, p, lp); do { @@ -1198,15 +1296,15 @@ const str_find_aux = function(L, find) { reprepstate(ms); if ((res = match(ms, s1, 0)) !== null) { if (find) { - lua.lua_pushinteger(L, s1 + 1); /* start */ - lua.lua_pushinteger(L, res); /* end */ + lua_pushinteger(L, s1 + 1); /* start */ + lua_pushinteger(L, res); /* end */ return push_captures(ms, null, 0) + 2; } else return push_captures(ms, s1, res); } } while (s1++ < ms.src_end && !anchor); } - lua.lua_pushnil(L); /* not found */ + lua_pushnil(L); /* not found */ return 1; }; @@ -1229,7 +1327,7 @@ class GMatchState { } const gmatch_aux = function(L) { - let gm = lua.lua_touserdata(L, lua.lua_upvalueindex(3)); + let gm = lua_touserdata(L, lua_upvalueindex(3)); gm.ms.L = L; for (let src = gm.src; src <= gm.ms.src_end; src++) { reprepstate(gm.ms); @@ -1243,41 +1341,41 @@ const gmatch_aux = function(L) { }; const str_gmatch = function(L) { - let s = lauxlib.luaL_checkstring(L, 1); - let p = lauxlib.luaL_checkstring(L, 2); + let s = luaL_checkstring(L, 1); + let p = luaL_checkstring(L, 2); let ls = s.length; let lp = p.length; - lua.lua_settop(L, 2); /* keep them on closure to avoid being collected */ + lua_settop(L, 2); /* keep them on closure to avoid being collected */ let gm = new GMatchState(); - lua.lua_pushlightuserdata(L, gm); + lua_pushlightuserdata(L, gm); prepstate(gm.ms, L, s, ls, p, lp); gm.src = 0; gm.p = 0; gm.lastmatch = null; - lua.lua_pushcclosure(L, gmatch_aux, 3); + lua_pushcclosure(L, gmatch_aux, 3); return 1; }; const add_s = function(ms, b, s, e) { let L = ms.L; - let news = lua.lua_tostring(L, 3); + let news = lua_tostring(L, 3); let l = news.length; for (let i = 0; i < l; i++) { if (news[i] !== L_ESC) - lauxlib.luaL_addchar(b, news[i]); + luaL_addchar(b, news[i]); else { i++; /* skip ESC */ if (!isdigit(news[i])) { if (news[i] !== L_ESC) - lauxlib.luaL_error(L, lua.to_luastring("invalid use of '%c' in replacement string"), L_ESC); - lauxlib.luaL_addchar(b, news[i]); - } else if (news[i] === '0'.charCodeAt(0)) - lauxlib.luaL_addlstring(b, ms.src.slice(s), e - s); + luaL_error(L, to_luastring("invalid use of '%c' in replacement string"), L_ESC); + luaL_addchar(b, news[i]); + } else if (news[i] === 48 /* '0'.charCodeAt(0) */) + luaL_addlstring(b, ms.src.subarray(s, e), e - s); else { - push_onecapture(ms, news[i] - '1'.charCodeAt(0), s, e); - lauxlib.luaL_tolstring(L, -1); - lua.lua_remove(L, -2); /* remove original value */ - lauxlib.luaL_addvalue(b); /* add capture to accumulated result */ + push_onecapture(ms, news[i] - 49 /* '1'.charCodeAt(0) */, s, e); + luaL_tolstring(L, -1); + lua_remove(L, -2); /* remove original value */ + luaL_addvalue(b); /* add capture to accumulated result */ } } } @@ -1286,15 +1384,15 @@ const add_s = function(ms, b, s, e) { const add_value = function(ms, b, s, e, tr) { let L = ms.L; switch (tr) { - case lua.LUA_TFUNCTION: { - lua.lua_pushvalue(L, 3); + case LUA_TFUNCTION: { + lua_pushvalue(L, 3); let n = push_captures(ms, s, e); - lua.lua_call(L, n, 1); + lua_call(L, n, 1); break; } - case lua.LUA_TTABLE: { + case LUA_TTABLE: { push_onecapture(ms, 0, s, e); - lua.lua_gettable(L, 3); + lua_gettable(L, 3); break; } default: { /* LUA_TNUMBER or LUA_TSTRING */ @@ -1302,31 +1400,31 @@ const add_value = function(ms, b, s, e, tr) { return; } } - if (!lua.lua_toboolean(L, -1)) { /* nil or false? */ - lua.lua_pop(L, 1); - lua.lua_pushlstring(L, ms.src.slice(s, e), e - s); /* keep original text */ - } else if (!lua.lua_isstring(L, -1)) - lauxlib.luaL_error(L, lua.to_luastring("invalid replacement value (a %s)"), lauxlib.luaL_typename(L, -1)); - lauxlib.luaL_addvalue(b); /* add result to accumulator */ + if (!lua_toboolean(L, -1)) { /* nil or false? */ + lua_pop(L, 1); + lua_pushlstring(L, ms.src.subarray(s, e), e - s); /* keep original text */ + } else if (!lua_isstring(L, -1)) + luaL_error(L, to_luastring("invalid replacement value (a %s)"), luaL_typename(L, -1)); + luaL_addvalue(b); /* add result to accumulator */ }; const str_gsub = function(L) { - let src = lauxlib.luaL_checkstring(L, 1); /* subject */ + let src = luaL_checkstring(L, 1); /* subject */ let srcl = src.length; - let p = lauxlib.luaL_checkstring(L, 2); /* pattern */ + let p = luaL_checkstring(L, 2); /* pattern */ let lp = p.length; let lastmatch = null; /* end of last match */ - let tr = lua.lua_type(L, 3); /* replacement type */ - let max_s = lauxlib.luaL_optinteger(L, 4, srcl + 1); /* max replacements */ - let anchor = p[0] === '^'.charCodeAt(0); + let tr = lua_type(L, 3); /* replacement type */ + let max_s = luaL_optinteger(L, 4, srcl + 1); /* max replacements */ + let anchor = p[0] === 94 /* '^'.charCodeAt(0) */; let n = 0; /* replacement count */ let ms = new MatchState(L); - let b = new lauxlib.luaL_Buffer(); - lauxlib.luaL_argcheck(L, tr === lua.LUA_TNUMBER || tr === lua.LUA_TSTRING || tr === lua.LUA_TFUNCTION || tr === lua.LUA_TTABLE, 3, - lua.to_luastring("string/function/table expected", true)); - lauxlib.luaL_buffinit(L, b); + let b = new luaL_Buffer(); + luaL_argcheck(L, tr === LUA_TNUMBER || tr === LUA_TSTRING || tr === LUA_TFUNCTION || tr === LUA_TTABLE, 3, + to_luastring("string/function/table expected", true)); + luaL_buffinit(L, b); if (anchor) { - p = p.slice(1); lp--; /* skip anchor character */ + p = p.subarray(1); lp--; /* skip anchor character */ } prepstate(ms, L, src, srcl, p, lp); src = 0; p = 0; @@ -1338,13 +1436,13 @@ const str_gsub = function(L) { add_value(ms, b, src, e, tr); /* add replacement to buffer */ src = lastmatch = e; } else if (src < ms.src_end) /* otherwise, skip one character */ - lauxlib.luaL_addchar(b, ms.src[src++]); + luaL_addchar(b, ms.src[src++]); else break; /* end of subject */ if (anchor) break; } - lauxlib.luaL_addlstring(b, ms.src.slice(src), ms.src_end - src); - lauxlib.luaL_pushresult(b); - lua.lua_pushinteger(L, n); /* number of substitutions */ + luaL_addlstring(b, ms.src.subarray(src, ms.src_end), ms.src_end - src); + luaL_pushresult(b); + lua_pushinteger(L, n); /* number of substitutions */ return 2; }; @@ -1369,18 +1467,18 @@ const strlib = { }; const createmetatable = function(L) { - lua.lua_createtable(L, 0, 1); /* table to be metatable for strings */ - lua.lua_pushliteral(L, ""); /* dummy string */ - lua.lua_pushvalue(L, -2); /* copy table */ - lua.lua_setmetatable(L, -2); /* set table as metatable for strings */ - lua.lua_pop(L, 1); /* pop dummy string */ - lua.lua_pushvalue(L, -2); /* get string library */ - lua.lua_setfield(L, -2, lua.to_luastring("__index", true)); /* metatable.__index = string */ - lua.lua_pop(L, 1); /* pop metatable */ + lua_createtable(L, 0, 1); /* table to be metatable for strings */ + lua_pushliteral(L, ""); /* dummy string */ + lua_pushvalue(L, -2); /* copy table */ + lua_setmetatable(L, -2); /* set table as metatable for strings */ + lua_pop(L, 1); /* pop dummy string */ + lua_pushvalue(L, -2); /* get string library */ + lua_setfield(L, -2, to_luastring("__index", true)); /* metatable.__index = string */ + lua_pop(L, 1); /* pop metatable */ }; const luaopen_string = function(L) { - lauxlib.luaL_newlib(L, strlib); + luaL_newlib(L, strlib); createmetatable(L); return 1; }; diff --git a/src/ltable.js b/src/ltable.js index cf8b1da..d5ae6e6 100644 --- a/src/ltable.js +++ b/src/ltable.js @@ -1,13 +1,31 @@ "use strict"; -const assert = require('assert'); - -const defs = require('./defs.js'); +const { + constant_types: { + LUA_TBOOLEAN, + LUA_TCCL, + LUA_TLCF, + LUA_TLCL, + LUA_TLIGHTUSERDATA, + LUA_TLNGSTR, + LUA_TNIL, + LUA_TNUMFLT, + LUA_TNUMINT, + LUA_TSHRSTR, + LUA_TTABLE, + LUA_TTHREAD, + LUA_TUSERDATA + }, + to_luastring +} = require('./defs.js'); +const { lua_assert } = require('./llimits.js'); const ldebug = require('./ldebug.js'); const lobject = require('./lobject.js'); -const lstring = require('./lstring.js'); +const { + luaS_hashlongstr, + TString +} = require('./lstring.js'); const lstate = require('./lstate.js'); -const CT = defs.constant_types; /* used to prevent conflicts with lightuserdata keys */ let lightuserdata_hashes = new WeakMap(); @@ -24,25 +42,25 @@ const get_lightuserdata_hash = function(v) { const table_hash = function(L, key) { switch(key.type) { - case CT.LUA_TNIL: - return ldebug.luaG_runerror(L, defs.to_luastring("table index is nil", true)); - case CT.LUA_TNUMFLT: + case LUA_TNIL: + return ldebug.luaG_runerror(L, to_luastring("table index is nil", true)); + case LUA_TNUMFLT: if (isNaN(key.value)) - return ldebug.luaG_runerror(L, defs.to_luastring("table index is NaN", true)); + return ldebug.luaG_runerror(L, to_luastring("table index is NaN", true)); /* fall through */ - case CT.LUA_TNUMINT: /* takes advantage of floats and integers being same in JS */ - case CT.LUA_TBOOLEAN: - case CT.LUA_TTABLE: - case CT.LUA_TLCL: - case CT.LUA_TLCF: - case CT.LUA_TCCL: - case CT.LUA_TUSERDATA: - case CT.LUA_TTHREAD: + case LUA_TNUMINT: /* takes advantage of floats and integers being same in JS */ + case LUA_TBOOLEAN: + case LUA_TTABLE: + case LUA_TLCL: + case LUA_TLCF: + case LUA_TCCL: + case LUA_TUSERDATA: + case LUA_TTHREAD: return key.value; - case CT.LUA_TSHRSTR: - case CT.LUA_TLNGSTR: - return lstring.luaS_hashlongstr(key.tsvalue()); - case CT.LUA_TLIGHTUSERDATA: { + case LUA_TSHRSTR: + case LUA_TLNGSTR: + return luaS_hashlongstr(key.tsvalue()); + case LUA_TLIGHTUSERDATA: { let v = key.value; switch(typeof v) { case "string": @@ -151,17 +169,17 @@ const getgeneric = function(t, hash) { }; const luaH_getint = function(t, key) { - assert(typeof key == "number" && (key|0) === key); + lua_assert(typeof key == "number" && (key|0) === key); return getgeneric(t, key); }; const luaH_getstr = function(t, key) { - assert(key instanceof lstring.TString); - return getgeneric(t, lstring.luaS_hashlongstr(key)); + lua_assert(key instanceof TString); + return getgeneric(t, luaS_hashlongstr(key)); }; const luaH_get = function(L, t, key) { - assert(key instanceof lobject.TValue); + lua_assert(key instanceof lobject.TValue); if (key.ttisnil() || (key.ttisfloat() && isNaN(key.value))) return lobject.luaO_nilobject; return getgeneric(t, table_hash(L, key)); @@ -175,17 +193,17 @@ const setgeneric = function(t, hash, key) { let kv = key.value; if ((key.ttisfloat() && (kv|0) === kv)) { /* does index fit in an integer? */ /* insert it as an integer */ - key = new lobject.TValue(CT.LUA_TNUMINT, kv); + key = new lobject.TValue(LUA_TNUMINT, kv); } else { key = new lobject.TValue(key.type, kv); } - let tv = new lobject.TValue(CT.LUA_TNIL, null); + let tv = new lobject.TValue(LUA_TNIL, null); add(t, hash, key, tv); return tv; }; const luaH_setint = function(t, key, value) { - assert(typeof key == "number" && (key|0) === key && value instanceof lobject.TValue); + lua_assert(typeof key == "number" && (key|0) === key && value instanceof lobject.TValue); let hash = key; /* table_hash known result */ if (value.ttisnil()) { mark_dead(t, hash); @@ -196,20 +214,20 @@ const luaH_setint = function(t, key, value) { let tv = v.value; tv.setfrom(value); } else { - let k = new lobject.TValue(CT.LUA_TNUMINT, key); + let k = new lobject.TValue(LUA_TNUMINT, key); let v = new lobject.TValue(value.type, value.value); add(t, hash, k, v); } }; const luaH_set = function(L, t, key) { - assert(key instanceof lobject.TValue); + lua_assert(key instanceof lobject.TValue); let hash = table_hash(L, key); return setgeneric(t, hash, key); }; const luaH_delete = function(L, t, key) { - assert(key instanceof lobject.TValue); + lua_assert(key instanceof lobject.TValue); let hash = table_hash(L, key); return mark_dead(t, hash); }; @@ -234,7 +252,7 @@ const luaH_next = function(L, table, keyI) { let keyO = L.stack[keyI]; let entry; - if (keyO.type === CT.LUA_TNIL) { + if (keyO.type === LUA_TNIL) { entry = table.f; if (!entry) return false; @@ -252,7 +270,7 @@ const luaH_next = function(L, table, keyI) { entry = (table.dead_weak && table.dead_weak.get(hash)) || table.dead_strong.get(hash); if (!entry) /* item not in table */ - return ldebug.luaG_runerror(L, defs.to_luastring("invalid key to 'next'")); + return ldebug.luaG_runerror(L, to_luastring("invalid key to 'next'")); /* Iterate until either out of keys, or until finding a non-dead key */ do { entry = entry.n; diff --git a/src/ltablib.js b/src/ltablib.js index 70ff595..6f408da 100644 --- a/src/ltablib.js +++ b/src/ltablib.js @@ -1,11 +1,54 @@ "use strict"; -const assert = require('assert'); - -const lua = require('./lua.js'); -const lauxlib = require('./lauxlib.js'); -const luaconf = require('./luaconf.js'); - +const { LUA_MAXINTEGER } = require('./luaconf.js'); +const { + LUA_OPEQ, + LUA_OPLT, + LUA_TFUNCTION, + LUA_TNIL, + LUA_TTABLE, + lua_call, + lua_checkstack, + lua_compare, + lua_createtable, + lua_geti, + lua_getmetatable, + lua_gettop, + lua_insert, + lua_isnil, + lua_isnoneornil, + lua_isstring, + lua_pop, + lua_pushinteger, + lua_pushnil, + lua_pushstring, + lua_pushvalue, + lua_rawget, + lua_setfield, + lua_seti, + lua_settop, + lua_toboolean, + lua_type +} = require('./lua.js'); +const { + luaL_Buffer, + luaL_addlstring, + luaL_addvalue, + luaL_argcheck, + luaL_buffinit, + luaL_checkinteger, + luaL_checktype, + luaL_error, + luaL_len, + luaL_newlib, + luaL_opt, + luaL_optinteger, + luaL_optlstring, + luaL_pushresult, + luaL_typename +} = require('./lauxlib.js'); +const lualib = require('./lualib.js'); +const { to_luastring } = require("./fengaricore.js"); /* ** Operations that an object must define to mimic a table @@ -17,8 +60,8 @@ const TAB_L = 4; /* length */ const TAB_RW = (TAB_R | TAB_W); /* read/write */ const checkfield = function(L, key, n) { - lua.lua_pushstring(L, key); - return lua.lua_rawget(L, -n) !== lua.LUA_TNIL; + lua_pushstring(L, key); + return lua_rawget(L, -n) !== LUA_TNIL; }; /* @@ -26,70 +69,70 @@ const checkfield = function(L, key, n) { ** has a metatable with the required metamethods) */ const checktab = function(L, arg, what) { - if (lua.lua_type(L, arg) !== lua.LUA_TTABLE) { /* is it not a table? */ + if (lua_type(L, arg) !== LUA_TTABLE) { /* is it not a table? */ let n = 1; - if (lua.lua_getmetatable(L, arg) && /* must have metatable */ - (!(what & TAB_R) || checkfield(L, lua.to_luastring("__index", true), ++n)) && - (!(what & TAB_W) || checkfield(L, lua.to_luastring("__newindex", true), ++n)) && - (!(what & TAB_L) || checkfield(L, lua.to_luastring("__len", true), ++n))) { - lua.lua_pop(L, n); /* pop metatable and tested metamethods */ + if (lua_getmetatable(L, arg) && /* must have metatable */ + (!(what & TAB_R) || checkfield(L, to_luastring("__index", true), ++n)) && + (!(what & TAB_W) || checkfield(L, to_luastring("__newindex", true), ++n)) && + (!(what & TAB_L) || checkfield(L, to_luastring("__len", true), ++n))) { + lua_pop(L, n); /* pop metatable and tested metamethods */ } else - lauxlib.luaL_checktype(L, arg, lua.LUA_TTABLE); /* force an error */ + luaL_checktype(L, arg, LUA_TTABLE); /* force an error */ } }; const aux_getn = function(L, n, w) { checktab(L, n, w | TAB_L); - return lauxlib.luaL_len(L, n); + return luaL_len(L, n); }; const addfield = function(L, b, i) { - lua.lua_geti(L, 1, i); - if (!lua.lua_isstring(L, -1)) - lauxlib.luaL_error(L, lua.to_luastring("invalid value (%s) at index %d in table for 'concat'"), - lauxlib.luaL_typename(L, -1), i); + lua_geti(L, 1, i); + if (!lua_isstring(L, -1)) + luaL_error(L, to_luastring("invalid value (%s) at index %d in table for 'concat'"), + luaL_typename(L, -1), i); - lauxlib.luaL_addvalue(b); + luaL_addvalue(b); }; const tinsert = function(L) { let e = aux_getn(L, 1, TAB_RW) + 1; /* first empty element */ let pos; - switch (lua.lua_gettop(L)) { + switch (lua_gettop(L)) { case 2: pos = e; break; case 3: { - pos = lauxlib.luaL_checkinteger(L, 2); /* 2nd argument is the position */ - lauxlib.luaL_argcheck(L, 1 <= pos && pos <= e, 2, lua.to_luastring("position out of bounds", true)); + pos = luaL_checkinteger(L, 2); /* 2nd argument is the position */ + luaL_argcheck(L, 1 <= pos && pos <= e, 2, to_luastring("position out of bounds", true)); for (let i = e; i > pos; i--) { /* move up elements */ - lua.lua_geti(L, 1, i - 1); - lua.lua_seti(L, 1, i); /* t[i] = t[i - 1] */ + lua_geti(L, 1, i - 1); + lua_seti(L, 1, i); /* t[i] = t[i - 1] */ } break; } default: { - return lauxlib.luaL_error(L, lua.to_luastring("wrong number of arguments to 'insert'", true)); + return luaL_error(L, to_luastring("wrong number of arguments to 'insert'", true)); } } - lua.lua_seti(L, 1, pos); /* t[pos] = v */ + lua_seti(L, 1, pos); /* t[pos] = v */ return 0; }; const tremove = function(L) { let size = aux_getn(L, 1, TAB_RW); - let pos = lauxlib.luaL_optinteger(L, 2, size); + let pos = luaL_optinteger(L, 2, size); if (pos !== size) /* validate 'pos' if given */ - lauxlib.luaL_argcheck(L, 1 <= pos && pos <= size + 1, 1, lua.to_luastring("position out of bounds", true)); - lua.lua_geti(L, 1, pos); /* result = t[pos] */ + luaL_argcheck(L, 1 <= pos && pos <= size + 1, 1, to_luastring("position out of bounds", true)); + lua_geti(L, 1, pos); /* result = t[pos] */ for (; pos < size; pos++) { - lua.lua_geti(L, 1, pos + 1); - lua.lua_seti(L, 1, pos); /* t[pos] = t[pos + 1] */ + lua_geti(L, 1, pos + 1); + lua_seti(L, 1, pos); /* t[pos] = t[pos + 1] */ } - lua.lua_pushnil(L); - lua.lua_seti(L, 1, pos); /* t[pos] = nil */ + lua_pushnil(L); + lua_seti(L, 1, pos); /* t[pos] = nil */ return 1; }; @@ -100,77 +143,78 @@ const tremove = function(L) { ** than origin, or copying to another table. */ const tmove = function(L) { - let f = lauxlib.luaL_checkinteger(L, 2); - let e = lauxlib.luaL_checkinteger(L, 3); - let t = lauxlib.luaL_checkinteger(L, 4); - let tt = !lua.lua_isnoneornil(L, 5) ? 5 : 1; /* destination table */ + let f = luaL_checkinteger(L, 2); + let e = luaL_checkinteger(L, 3); + let t = luaL_checkinteger(L, 4); + let tt = !lua_isnoneornil(L, 5) ? 5 : 1; /* destination table */ checktab(L, 1, TAB_R); checktab(L, tt, TAB_W); if (e >= f) { /* otherwise, nothing to move */ - lauxlib.luaL_argcheck(L, f > 0 || e < luaconf.LUA_MAXINTEGER + f, 3, lua.to_luastring("too many elements to move", true)); + luaL_argcheck(L, f > 0 || e < LUA_MAXINTEGER + f, 3, to_luastring("too many elements to move", true)); let n = e - f + 1; /* number of elements to move */ - lauxlib.luaL_argcheck(L, t <= luaconf.LUA_MAXINTEGER - n + 1, 4, lua.to_luastring("destination wrap around", true)); + luaL_argcheck(L, t <= LUA_MAXINTEGER - n + 1, 4, to_luastring("destination wrap around", true)); - if (t > e || t <= f || (tt !== 1 && lua.lua_compare(L, 1, tt, lua.LUA_OPEQ) !== 1)) { + if (t > e || t <= f || (tt !== 1 && lua_compare(L, 1, tt, LUA_OPEQ) !== 1)) { for (let i = 0; i < n; i++) { - lua.lua_geti(L, 1, f + i); - lua.lua_seti(L, tt, t + i); + lua_geti(L, 1, f + i); + lua_seti(L, tt, t + i); } } else { for (let i = n - 1; i >= 0; i--) { - lua.lua_geti(L, 1, f + i); - lua.lua_seti(L, tt, t + i); + lua_geti(L, 1, f + i); + lua_seti(L, tt, t + i); } } } - lua.lua_pushvalue(L, tt); /* return destination table */ + lua_pushvalue(L, tt); /* return destination table */ return 1; }; const tconcat = function(L) { let last = aux_getn(L, 1, TAB_R); - let sep = lauxlib.luaL_optlstring(L, 2, lua.to_luastring("")); - let i = lauxlib.luaL_optinteger(L, 3, 1); - last = lauxlib.luaL_optinteger(L, 4, last); + let sep = luaL_optlstring(L, 2, to_luastring("")); + let lsep = sep.length; + let i = luaL_optinteger(L, 3, 1); + last = luaL_optinteger(L, 4, last); - let b = new lauxlib.luaL_Buffer(); - lauxlib.luaL_buffinit(L, b); + let b = new luaL_Buffer(); + luaL_buffinit(L, b); for (; i < last; i++) { addfield(L, b, i); - lauxlib.luaL_addlstring(b, sep); + luaL_addlstring(b, sep, lsep); } if (i === last) addfield(L, b, i); - lauxlib.luaL_pushresult(b); + luaL_pushresult(b); return 1; }; const pack = function(L) { - let n = lua.lua_gettop(L); /* number of elements to pack */ - lua.lua_createtable(L, n, 1); /* create result table */ - lua.lua_insert(L, 1); /* put it at index 1 */ + let n = lua_gettop(L); /* number of elements to pack */ + lua_createtable(L, n, 1); /* create result table */ + lua_insert(L, 1); /* put it at index 1 */ for (let i = n; i >= 1; i--) /* assign elements */ - lua.lua_seti(L, 1, i); - lua.lua_pushinteger(L, n); - lua.lua_setfield(L, 1, lua.to_luastring("n")); /* t.n = number of elements */ + lua_seti(L, 1, i); + lua_pushinteger(L, n); + lua_setfield(L, 1, to_luastring("n")); /* t.n = number of elements */ return 1; /* return table */ }; const unpack = function(L) { - let i = lauxlib.luaL_optinteger(L, 2, 1); - let e = lauxlib.luaL_opt(L, lauxlib.luaL_checkinteger, 3, lauxlib.luaL_len(L, 1)); + let i = luaL_optinteger(L, 2, 1); + let e = luaL_opt(L, luaL_checkinteger, 3, luaL_len(L, 1)); if (i > e) return 0; /* empty range */ let n = e - i; /* number of elements minus 1 (avoid overflows) */ - if (n >= Number.MAX_SAFE_INTEGER || !lua.lua_checkstack(L, ++n)) - return lauxlib.luaL_error(L, lua.to_luastring("too many results to unpack", true)); + if (n >= Number.MAX_SAFE_INTEGER || !lua_checkstack(L, ++n)) + return luaL_error(L, to_luastring("too many results to unpack", true)); for (; i < e; i++) /* push arg[i..e - 1] (to avoid overflows) */ - lua.lua_geti(L, 1, i); - lua.lua_geti(L, 1, e); /* push last element */ + lua_geti(L, 1, i); + lua_geti(L, 1, e); /* push last element */ return n; }; @@ -181,20 +225,20 @@ const l_randomizePivot = function() { const RANLIMIT = 100; const set2 = function(L, i, j) { - lua.lua_seti(L, 1, i); - lua.lua_seti(L, 1, j); + lua_seti(L, 1, i); + lua_seti(L, 1, j); }; const sort_comp = function(L, a, b) { - if (lua.lua_isnil(L, 2)) /* no function? */ - return lua.lua_compare(L, a, b, lua.LUA_OPLT); /* a < b */ + if (lua_isnil(L, 2)) /* no function? */ + return lua_compare(L, a, b, LUA_OPLT); /* a < b */ else { /* function */ - lua.lua_pushvalue(L, 2); /* push function */ - lua.lua_pushvalue(L, a-1); /* -1 to compensate function */ - lua.lua_pushvalue(L, b-2); /* -2 to compensate function and 'a' */ - lua.lua_call(L, 2, 1); /* call function */ - let res = lua.lua_toboolean(L, -1); /* get result */ - lua.lua_pop(L, 1); /* pop result */ + lua_pushvalue(L, 2); /* push function */ + lua_pushvalue(L, a-1); /* -1 to compensate function */ + lua_pushvalue(L, b-2); /* -2 to compensate function and 'a' */ + lua_call(L, 2, 1); /* call function */ + let res = lua_toboolean(L, -1); /* get result */ + lua_pop(L, 1); /* pop result */ return res; } }; @@ -205,22 +249,22 @@ const partition = function(L, lo, up) { /* loop invariant: a[lo .. i] <= P <= a[j .. up] */ for (;;) { /* next loop: repeat ++i while a[i] < P */ - while (lua.lua_geti(L, 1, ++i), sort_comp(L, -1, -2)) { + while (lua_geti(L, 1, ++i), sort_comp(L, -1, -2)) { if (i == up - 1) /* a[i] < P but a[up - 1] == P ?? */ - lauxlib.luaL_error(L, lua.to_luastring("invalid order function for sorting")); - lua.lua_pop(L, 1); /* remove a[i] */ + luaL_error(L, to_luastring("invalid order function for sorting")); + lua_pop(L, 1); /* remove a[i] */ } /* after the loop, a[i] >= P and a[lo .. i - 1] < P */ /* next loop: repeat --j while P < a[j] */ - while (lua.lua_geti(L, 1, --j), sort_comp(L, -3, -1)) { + while (lua_geti(L, 1, --j), sort_comp(L, -3, -1)) { if (j < i) /* j < i but a[j] > P ?? */ - lauxlib.luaL_error(L, lua.to_luastring("invalid order function for sorting")); - lua.lua_pop(L, 1); /* remove a[j] */ + luaL_error(L, to_luastring("invalid order function for sorting")); + lua_pop(L, 1); /* remove a[j] */ } /* after the loop, a[j] <= P and a[j + 1 .. up] >= P */ if (j < i) { /* no elements out of place? */ /* a[lo .. i - 1] <= P <= a[j + 1 .. i .. up] */ - lua.lua_pop(L, 1); /* pop a[j] */ + lua_pop(L, 1); /* pop a[j] */ /* swap pivot (a[up - 1]) with a[i] to satisfy pos-condition */ set2(L, up - 1, i); return i; @@ -233,19 +277,19 @@ const partition = function(L, lo, up) { const choosePivot = function(lo, up, rnd) { let r4 = Math.floor((up - lo) / 4); /* range/4 */ let p = rnd % (r4 * 2) + (lo + r4); - assert(lo + r4 <= p && p <= up - r4); + lualib.lua_assert(lo + r4 <= p && p <= up - r4); return p; }; const auxsort = function(L, lo, up, rnd) { while (lo < up) { /* loop for tail recursion */ /* sort elements 'lo', 'p', and 'up' */ - lua.lua_geti(L, 1, lo); - lua.lua_geti(L, 1, up); + lua_geti(L, 1, lo); + lua_geti(L, 1, up); if (sort_comp(L, -1, -2)) /* a[up] < a[lo]? */ set2(L, lo, up); /* swap a[lo] - a[up] */ else - lua.lua_pop(L, 2); /* remove both values */ + lua_pop(L, 2); /* remove both values */ if (up - lo == 1) /* only 2 elements? */ return; /* already sorted */ let p; /* Pivot index */ @@ -253,23 +297,23 @@ const auxsort = function(L, lo, up, rnd) { p = Math.floor((lo + up)/2); /* middle element is a good pivot */ else /* for larger intervals, it is worth a random pivot */ p = choosePivot(lo, up, rnd); - lua.lua_geti(L, 1, p); - lua.lua_geti(L, 1, lo); + lua_geti(L, 1, p); + lua_geti(L, 1, lo); if (sort_comp(L, -2, -1)) /* a[p] < a[lo]? */ set2(L, p, lo); /* swap a[p] - a[lo] */ else { - lua.lua_pop(L, 1); /* remove a[lo] */ - lua.lua_geti(L, 1, up); + lua_pop(L, 1); /* remove a[lo] */ + lua_geti(L, 1, up); if (sort_comp(L, -1, -2)) /* a[up] < a[p]? */ set2(L, p, up); /* swap a[up] - a[p] */ else - lua.lua_pop(L, 2); + lua_pop(L, 2); } if (up - lo == 2) /* only 3 elements? */ return; /* already sorted */ - lua.lua_geti(L, 1, p); /* get middle element (Pivot) */ - lua.lua_pushvalue(L, -1); /* push Pivot */ - lua.lua_geti(L, 1, up - 1); /* push a[up - 1] */ + lua_geti(L, 1, p); /* get middle element (Pivot) */ + lua_pushvalue(L, -1); /* push Pivot */ + lua_geti(L, 1, up - 1); /* push a[up - 1] */ set2(L, p, up - 1); /* swap Pivot (a[p]) with a[up - 1] */ p = partition(L, lo, up); let n; @@ -291,10 +335,10 @@ const auxsort = function(L, lo, up, rnd) { const sort = function(L) { let n = aux_getn(L, 1, TAB_RW); if (n > 1) { /* non-trivial interval? */ - lauxlib.luaL_argcheck(L, n < luaconf.LUA_MAXINTEGER, 1, lua.to_luastring("array too big", true)); - if (!lua.lua_isnoneornil(L, 2)) /* is there a 2nd argument? */ - lauxlib.luaL_checktype(L, 2, lua.LUA_TFUNCTION); /* must be a function */ - lua.lua_settop(L, 2); /* make sure there are two arguments */ + luaL_argcheck(L, n < LUA_MAXINTEGER, 1, to_luastring("array too big", true)); + if (!lua_isnoneornil(L, 2)) /* is there a 2nd argument? */ + luaL_checktype(L, 2, LUA_TFUNCTION); /* must be a function */ + lua_settop(L, 2); /* make sure there are two arguments */ auxsort(L, 1, n, 0); } return 0; @@ -311,7 +355,7 @@ const tab_funcs = { }; const luaopen_table = function(L) { - lauxlib.luaL_newlib(L, tab_funcs); + luaL_newlib(L, tab_funcs); return 1; }; @@ -1,16 +1,23 @@ "use strict"; -const assert = require('assert'); - -const defs = require('./defs.js'); +const { + constant_types: { + LUA_TTABLE, + LUA_TUSERDATA + }, + to_luastring +} = require('./defs.js'); +const { lua_assert } = require('./llimits.js'); const lobject = require('./lobject.js'); const ldo = require('./ldo.js'); const lstate = require('./lstate.js'); -const lstring = require('./lstring.js'); +const { + luaS_bless, + luaS_new +} = require('./lstring.js'); const ltable = require('./ltable.js'); const ldebug = require('./ldebug.js'); const lvm = require('./lvm.js'); -const CT = defs.constant_types; const luaT_typenames_ = [ "no value", @@ -24,7 +31,7 @@ const luaT_typenames_ = [ "userdata", "thread", "proto" /* this last case is used for tests only */ -].map(e => defs.to_luastring(e)); +].map(e => to_luastring(e)); const ttypename = function(t) { return luaT_typenames_[t + 1]; @@ -64,42 +71,42 @@ const TMS = { }; const luaT_init = function(L) { - L.l_G.tmname[TMS.TM_INDEX] = new lstring.luaS_new(L, defs.to_luastring("__index", true)); - L.l_G.tmname[TMS.TM_NEWINDEX] = new lstring.luaS_new(L, defs.to_luastring("__newindex", true)); - L.l_G.tmname[TMS.TM_GC] = new lstring.luaS_new(L, defs.to_luastring("__gc", true)); - L.l_G.tmname[TMS.TM_MODE] = new lstring.luaS_new(L, defs.to_luastring("__mode", true)); - L.l_G.tmname[TMS.TM_LEN] = new lstring.luaS_new(L, defs.to_luastring("__len", true)); - L.l_G.tmname[TMS.TM_EQ] = new lstring.luaS_new(L, defs.to_luastring("__eq", true)); - L.l_G.tmname[TMS.TM_ADD] = new lstring.luaS_new(L, defs.to_luastring("__add", true)); - L.l_G.tmname[TMS.TM_SUB] = new lstring.luaS_new(L, defs.to_luastring("__sub", true)); - L.l_G.tmname[TMS.TM_MUL] = new lstring.luaS_new(L, defs.to_luastring("__mul", true)); - L.l_G.tmname[TMS.TM_MOD] = new lstring.luaS_new(L, defs.to_luastring("__mod", true)); - L.l_G.tmname[TMS.TM_POW] = new lstring.luaS_new(L, defs.to_luastring("__pow", true)); - L.l_G.tmname[TMS.TM_DIV] = new lstring.luaS_new(L, defs.to_luastring("__div", true)); - L.l_G.tmname[TMS.TM_IDIV] = new lstring.luaS_new(L, defs.to_luastring("__idiv", true)); - L.l_G.tmname[TMS.TM_BAND] = new lstring.luaS_new(L, defs.to_luastring("__band", true)); - L.l_G.tmname[TMS.TM_BOR] = new lstring.luaS_new(L, defs.to_luastring("__bor", true)); - L.l_G.tmname[TMS.TM_BXOR] = new lstring.luaS_new(L, defs.to_luastring("__bxor", true)); - L.l_G.tmname[TMS.TM_SHL] = new lstring.luaS_new(L, defs.to_luastring("__shl", true)); - L.l_G.tmname[TMS.TM_SHR] = new lstring.luaS_new(L, defs.to_luastring("__shr", true)); - L.l_G.tmname[TMS.TM_UNM] = new lstring.luaS_new(L, defs.to_luastring("__unm", true)); - L.l_G.tmname[TMS.TM_BNOT] = new lstring.luaS_new(L, defs.to_luastring("__bnot", true)); - L.l_G.tmname[TMS.TM_LT] = new lstring.luaS_new(L, defs.to_luastring("__lt", true)); - L.l_G.tmname[TMS.TM_LE] = new lstring.luaS_new(L, defs.to_luastring("__le", true)); - L.l_G.tmname[TMS.TM_CONCAT] = new lstring.luaS_new(L, defs.to_luastring("__concat", true)); - L.l_G.tmname[TMS.TM_CALL] = new lstring.luaS_new(L, defs.to_luastring("__call", true)); + L.l_G.tmname[TMS.TM_INDEX] = new luaS_new(L, to_luastring("__index", true)); + L.l_G.tmname[TMS.TM_NEWINDEX] = new luaS_new(L, to_luastring("__newindex", true)); + L.l_G.tmname[TMS.TM_GC] = new luaS_new(L, to_luastring("__gc", true)); + L.l_G.tmname[TMS.TM_MODE] = new luaS_new(L, to_luastring("__mode", true)); + L.l_G.tmname[TMS.TM_LEN] = new luaS_new(L, to_luastring("__len", true)); + L.l_G.tmname[TMS.TM_EQ] = new luaS_new(L, to_luastring("__eq", true)); + L.l_G.tmname[TMS.TM_ADD] = new luaS_new(L, to_luastring("__add", true)); + L.l_G.tmname[TMS.TM_SUB] = new luaS_new(L, to_luastring("__sub", true)); + L.l_G.tmname[TMS.TM_MUL] = new luaS_new(L, to_luastring("__mul", true)); + L.l_G.tmname[TMS.TM_MOD] = new luaS_new(L, to_luastring("__mod", true)); + L.l_G.tmname[TMS.TM_POW] = new luaS_new(L, to_luastring("__pow", true)); + L.l_G.tmname[TMS.TM_DIV] = new luaS_new(L, to_luastring("__div", true)); + L.l_G.tmname[TMS.TM_IDIV] = new luaS_new(L, to_luastring("__idiv", true)); + L.l_G.tmname[TMS.TM_BAND] = new luaS_new(L, to_luastring("__band", true)); + L.l_G.tmname[TMS.TM_BOR] = new luaS_new(L, to_luastring("__bor", true)); + L.l_G.tmname[TMS.TM_BXOR] = new luaS_new(L, to_luastring("__bxor", true)); + L.l_G.tmname[TMS.TM_SHL] = new luaS_new(L, to_luastring("__shl", true)); + L.l_G.tmname[TMS.TM_SHR] = new luaS_new(L, to_luastring("__shr", true)); + L.l_G.tmname[TMS.TM_UNM] = new luaS_new(L, to_luastring("__unm", true)); + L.l_G.tmname[TMS.TM_BNOT] = new luaS_new(L, to_luastring("__bnot", true)); + L.l_G.tmname[TMS.TM_LT] = new luaS_new(L, to_luastring("__lt", true)); + L.l_G.tmname[TMS.TM_LE] = new luaS_new(L, to_luastring("__le", true)); + L.l_G.tmname[TMS.TM_CONCAT] = new luaS_new(L, to_luastring("__concat", true)); + L.l_G.tmname[TMS.TM_CALL] = new luaS_new(L, to_luastring("__call", true)); }; /* ** Return the name of the type of an object. For tables and userdata ** with metatable, use their '__name' metafield, if present. */ -const __name = defs.to_luastring('__name', true); +const __name = to_luastring('__name', true); const luaT_objtypename = function(L, o) { let mt; if ((o.ttistable() && (mt = o.value.metatable) !== null) || (o.ttisfulluserdata() && (mt = o.value.metatable) !== null)) { - let name = ltable.luaH_getstr(mt, lstring.luaS_bless(L, __name)); + let name = ltable.luaH_getstr(mt, luaS_bless(L, __name)); if (name.ttisstring()) return name.svalue(); } @@ -149,10 +156,10 @@ const luaT_trybinTM = function(L, p1, p2, res, event) { if (n1 !== false && n2 !== false) return ldebug.luaG_tointerror(L, p1, p2); else - return ldebug.luaG_opinterror(L, p1, p2, defs.to_luastring("perform bitwise operation on", true)); + return ldebug.luaG_opinterror(L, p1, p2, to_luastring("perform bitwise operation on", true)); } default: - return ldebug.luaG_opinterror(L, p1, p2, defs.to_luastring("perform arithmetic on", true)); + return ldebug.luaG_opinterror(L, p1, p2, to_luastring("perform arithmetic on", true)); } } }; @@ -172,7 +179,7 @@ const fasttm = function(l, et, e) { const luaT_gettm = function(events, event, ename) { const tm = ltable.luaH_getstr(events, ename); - assert(event <= TMS.TM_EQ); + lua_assert(event <= TMS.TM_EQ); if (tm.ttisnil()) { /* no tag method? */ events.flags |= 1<<event; /* cache this fact */ return null; @@ -183,8 +190,8 @@ const luaT_gettm = function(events, event, ename) { const luaT_gettmbyobj = function(L, o, event) { let mt; switch(o.ttnov()) { - case CT.LUA_TTABLE: - case CT.LUA_TUSERDATA: + case LUA_TTABLE: + case LUA_TUSERDATA: mt = o.value.metatable; break; default: @@ -6,14 +6,6 @@ const ldebug = require("./ldebug.js"); const ldo = require("./ldo.js"); const lstate = require("./lstate.js"); -module.exports.FENGARI_AUTHORS = defs.FENGARI_AUTHORS; -module.exports.FENGARI_COPYRIGHT = defs.FENGARI_COPYRIGHT; -module.exports.FENGARI_RELEASE = defs.FENGARI_RELEASE; -module.exports.FENGARI_VERSION = defs.FENGARI_VERSION; -module.exports.FENGARI_VERSION_MAJOR = defs.FENGARI_VERSION_MAJOR; -module.exports.FENGARI_VERSION_MINOR = defs.FENGARI_VERSION_MINOR; -module.exports.FENGARI_VERSION_NUM = defs.FENGARI_VERSION_NUM; -module.exports.FENGARI_VERSION_RELEASE = defs.FENGARI_VERSION_RELEASE; module.exports.LUA_AUTHORS = defs.LUA_AUTHORS; module.exports.LUA_COPYRIGHT = defs.LUA_COPYRIGHT; module.exports.LUA_ERRERR = defs.thread_status.LUA_ERRERR; @@ -34,7 +26,7 @@ module.exports.LUA_MASKLINE = defs.LUA_MASKLINE; module.exports.LUA_MASKRET = defs.LUA_MASKRET; module.exports.LUA_MINSTACK = defs.LUA_MINSTACK; module.exports.LUA_MULTRET = defs.LUA_MULTRET; -module.exports.LUA_NUMTAGS = defs.LUA_NUMTAGS; +module.exports.LUA_NUMTAGS = defs.constant_types.LUA_NUMTAGS; module.exports.LUA_OK = defs.thread_status.LUA_OK; module.exports.LUA_OPADD = defs.LUA_OPADD; module.exports.LUA_OPBAND = defs.LUA_OPBAND; @@ -59,16 +51,16 @@ module.exports.LUA_RIDX_GLOBALS = defs.LUA_RIDX_GLOBALS; module.exports.LUA_RIDX_LAST = defs.LUA_RIDX_LAST; module.exports.LUA_RIDX_MAINTHREAD = defs.LUA_RIDX_MAINTHREAD; module.exports.LUA_SIGNATURE = defs.LUA_SIGNATURE; -module.exports.LUA_TNONE = defs.CT.LUA_TNONE; -module.exports.LUA_TNIL = defs.CT.LUA_TNIL; -module.exports.LUA_TBOOLEAN = defs.CT.LUA_TBOOLEAN; -module.exports.LUA_TLIGHTUSERDATA = defs.CT.LUA_TLIGHTUSERDATA; -module.exports.LUA_TNUMBER = defs.CT.LUA_TNUMBER; -module.exports.LUA_TSTRING = defs.CT.LUA_TSTRING; -module.exports.LUA_TTABLE = defs.CT.LUA_TTABLE; -module.exports.LUA_TFUNCTION = defs.CT.LUA_TFUNCTION; -module.exports.LUA_TUSERDATA = defs.CT.LUA_TUSERDATA; -module.exports.LUA_TTHREAD = defs.CT.LUA_TTHREAD; +module.exports.LUA_TNONE = defs.constant_types.LUA_TNONE; +module.exports.LUA_TNIL = defs.constant_types.LUA_TNIL; +module.exports.LUA_TBOOLEAN = defs.constant_types.LUA_TBOOLEAN; +module.exports.LUA_TLIGHTUSERDATA = defs.constant_types.LUA_TLIGHTUSERDATA; +module.exports.LUA_TNUMBER = defs.constant_types.LUA_TNUMBER; +module.exports.LUA_TSTRING = defs.constant_types.LUA_TSTRING; +module.exports.LUA_TTABLE = defs.constant_types.LUA_TTABLE; +module.exports.LUA_TFUNCTION = defs.constant_types.LUA_TFUNCTION; +module.exports.LUA_TUSERDATA = defs.constant_types.LUA_TUSERDATA; +module.exports.LUA_TTHREAD = defs.constant_types.LUA_TTHREAD; module.exports.LUA_VERSION = defs.LUA_VERSION; module.exports.LUA_VERSION_MAJOR = defs.LUA_VERSION_MAJOR; module.exports.LUA_VERSION_MINOR = defs.LUA_VERSION_MINOR; @@ -78,9 +70,6 @@ module.exports.LUA_VERSUFFIX = defs.LUA_VERSUFFIX; module.exports.LUA_YIELD = defs.thread_status.LUA_YIELD; module.exports.lua_Debug = defs.lua_Debug; module.exports.lua_upvalueindex = defs.lua_upvalueindex; -module.exports.to_jsstring = defs.to_jsstring; -module.exports.to_luastring = defs.to_luastring; -module.exports.to_uristring = defs.to_uristring; module.exports.LUA_CDIR = defs.LUA_CDIR; module.exports.LUA_CPATH_DEFAULT = defs.LUA_CPATH_DEFAULT; module.exports.LUA_EXEC_DIR = defs.LUA_EXEC_DIR; diff --git a/src/luaconf.js b/src/luaconf.js index 4bf8583..533e316 100644 --- a/src/luaconf.js +++ b/src/luaconf.js @@ -38,7 +38,11 @@ const LUA_INTEGER_FMT = `%${LUA_INTEGER_FRMLEN}d`; const LUA_NUMBER_FMT = "%.14g"; const lua_getlocaledecpoint = function() { - return (1.1).toLocaleString().substring(1, 2); + return (1.1).toLocaleString().charCodeAt(1); +}; + +const luai_apicheck = function(l, e) { + if (!e) throw Error(e); }; // See: http://croquetweak.blogspot.fr/2014/08/deconstructing-floats-frexp-and-ldexp.html @@ -78,3 +82,4 @@ module.exports.lua_getlocaledecpoint = lua_getlocaledecpoint; module.exports.lua_integer2str = lua_integer2str; module.exports.lua_number2str = lua_number2str; module.exports.lua_numbertointeger = lua_numbertointeger; +module.exports.luai_apicheck = luai_apicheck; diff --git a/src/lualib.js b/src/lualib.js index 4fbae44..78f441f 100644 --- a/src/lualib.js +++ b/src/lualib.js @@ -1,11 +1,15 @@ "use strict"; -const lua = require("./lua.js"); -const linit = require('./linit.js'); +const { + LUA_VERSION_MAJOR, + LUA_VERSION_MINOR +} = require("./lua.js"); -const LUA_VERSUFFIX = "_" + lua.LUA_VERSION_MAJOR + "_" + lua.LUA_VERSION_MINOR; +const LUA_VERSUFFIX = "_" + LUA_VERSION_MAJOR + "_" + LUA_VERSION_MINOR; module.exports.LUA_VERSUFFIX = LUA_VERSUFFIX; +module.exports.lua_assert = function(c) {}; + const LUA_COLIBNAME = "coroutine"; module.exports.LUA_COLIBNAME = LUA_COLIBNAME; module.exports.luaopen_coroutine = require("./lcorolib.js").luaopen_coroutine; @@ -48,4 +52,5 @@ const LUA_LOADLIBNAME = "package"; module.exports.LUA_LOADLIBNAME = LUA_LOADLIBNAME; module.exports.luaopen_package = require("./loadlib.js").luaopen_package; +const linit = require('./linit.js'); module.exports.luaL_openlibs = linit.luaL_openlibs; diff --git a/src/lundump.js b/src/lundump.js index e49c376..cf3fafa 100644 --- a/src/lundump.js +++ b/src/lundump.js @@ -1,16 +1,46 @@ "use strict"; -const assert = require('assert'); - -const defs = require('./defs.js'); +const { + LUA_SIGNATURE, + constant_types: { + LUA_TBOOLEAN, + LUA_TLNGSTR, + LUA_TNIL, + LUA_TNUMFLT, + LUA_TNUMINT, + LUA_TSHRSTR + }, + thread_status: { LUA_ERRSYNTAX }, + is_luastring, + luastring_eq, + to_luastring +} = require('./defs.js'); const ldo = require('./ldo.js'); const lfunc = require('./lfunc.js'); const lobject = require('./lobject.js'); -const lopcodes = require('./lopcodes.js'); -const lstring = require('./lstring.js'); -const lzio = require('./lzio.js'); - -let LUAC_DATA = [0x19, 0x93, defs.char["\r"], defs.char["\n"], 0x1a, defs.char["\n"]]; +const { + MAXARG_sBx, + POS_A, + POS_Ax, + POS_B, + POS_Bx, + POS_C, + POS_OP, + SIZE_A, + SIZE_Ax, + SIZE_B, + SIZE_Bx, + SIZE_C, + SIZE_OP +} = require('./lopcodes.js'); +const { lua_assert } = require("./llimits.js"); +const { luaS_bless } = require('./lstring.js'); +const { + luaZ_read, + ZIO +} = require('./lzio.js'); + +let LUAC_DATA = [0x19, 0x93, 13, 10, 0x1a, 10]; class BytecodeParser { @@ -21,13 +51,13 @@ class BytecodeParser { this.integerSize = 4; this.numberSize = 8; - assert(Z instanceof lzio.ZIO, "BytecodeParser only operates on a ZIO"); - assert(defs.is_luastring(name)); + lua_assert(Z instanceof ZIO, "BytecodeParser only operates on a ZIO"); + lua_assert(is_luastring(name)); - if (name[0] == defs.char["@"] || name[0] == defs.char["="]) + if (name[0] === 64 /* ('@').charCodeAt(0) */ || name[0] === 61 /* ('=').charCodeAt(0) */) this.name = name.subarray(1); - else if (name[0] == defs.LUA_SIGNATURE.charCodeAt(0)) - this.name = defs.to_luastring("binary string", true); + else if (name[0] == LUA_SIGNATURE[0]) + this.name = to_luastring("binary string", true); else this.name = name; @@ -44,19 +74,19 @@ class BytecodeParser { read(size) { let u8 = new Uint8Array(size); - if(lzio.luaZ_read(this.Z, u8, 0, size) !== 0) + if(luaZ_read(this.Z, u8, 0, size) !== 0) this.error("truncated"); return u8; } readByte() { - if (lzio.luaZ_read(this.Z, this.u8, 0, 1) !== 0) + if (luaZ_read(this.Z, this.u8, 0, 1) !== 0) this.error("truncated"); return this.u8[0]; } readInteger() { - if (lzio.luaZ_read(this.Z, this.u8, 0, this.integerSize) !== 0) + if (luaZ_read(this.Z, this.u8, 0, this.integerSize) !== 0) this.error("truncated"); return this.dv.getInt32(0, true); } @@ -66,13 +96,13 @@ class BytecodeParser { } readInt() { - if (lzio.luaZ_read(this.Z, this.u8, 0, this.intSize) !== 0) + if (luaZ_read(this.Z, this.u8, 0, this.intSize) !== 0) this.error("truncated"); return this.dv.getInt32(0, true); } readNumber() { - if (lzio.luaZ_read(this.Z, this.u8, 0, this.numberSize) !== 0) + if (luaZ_read(this.Z, this.u8, 0, this.numberSize) !== 0) this.error("truncated"); return this.dv.getFloat64(0, true); } @@ -87,7 +117,7 @@ class BytecodeParser { return null; } - return lstring.luaS_bless(this.L, this.read(size)); + return luaS_bless(this.L, this.read(size)); } /* creates a mask with 'n' 1 bits at position 'p' */ @@ -101,27 +131,26 @@ class BytecodeParser { } readInstruction() { - if (lzio.luaZ_read(this.Z, this.u8, 0, this.instructionSize) !== 0) + if (luaZ_read(this.Z, this.u8, 0, this.instructionSize) !== 0) this.error("truncated"); return this.dv.getUint32(0, true); } readCode(f) { let n = this.readInt(); - let o = lopcodes; let p = BytecodeParser; for (let i = 0; i < n; i++) { let ins = this.readInstruction(); f.code[i] = { code: ins, - opcode: (ins >> o.POS_OP) & p.MASK1(o.SIZE_OP, 0), - A: (ins >> o.POS_A) & p.MASK1(o.SIZE_A, 0), - B: (ins >> o.POS_B) & p.MASK1(o.SIZE_B, 0), - C: (ins >> o.POS_C) & p.MASK1(o.SIZE_C, 0), - Bx: (ins >> o.POS_Bx) & p.MASK1(o.SIZE_Bx, 0), - Ax: (ins >> o.POS_Ax) & p.MASK1(o.SIZE_Ax, 0), - sBx: ((ins >> o.POS_Bx) & p.MASK1(o.SIZE_Bx, 0)) - o.MAXARG_sBx + opcode: (ins >> POS_OP) & p.MASK1(SIZE_OP, 0), + A: (ins >> POS_A) & p.MASK1(SIZE_A, 0), + B: (ins >> POS_B) & p.MASK1(SIZE_B, 0), + C: (ins >> POS_C) & p.MASK1(SIZE_C, 0), + Bx: (ins >> POS_Bx) & p.MASK1(SIZE_Bx, 0), + Ax: (ins >> POS_Ax) & p.MASK1(SIZE_Ax, 0), + sBx: ((ins >> POS_Bx) & p.MASK1(SIZE_Bx, 0)) - MAXARG_sBx }; } } @@ -145,21 +174,21 @@ class BytecodeParser { let t = this.readByte(); switch (t) { - case defs.CT.LUA_TNIL: - f.k.push(new lobject.TValue(defs.CT.LUA_TNIL, null)); + case LUA_TNIL: + f.k.push(new lobject.TValue(LUA_TNIL, null)); break; - case defs.CT.LUA_TBOOLEAN: - f.k.push(new lobject.TValue(defs.CT.LUA_TBOOLEAN, this.readByte() !== 0)); + case LUA_TBOOLEAN: + f.k.push(new lobject.TValue(LUA_TBOOLEAN, this.readByte() !== 0)); break; - case defs.CT.LUA_TNUMFLT: - f.k.push(new lobject.TValue(defs.CT.LUA_TNUMFLT, this.readNumber())); + case LUA_TNUMFLT: + f.k.push(new lobject.TValue(LUA_TNUMFLT, this.readNumber())); break; - case defs.CT.LUA_TNUMINT: - f.k.push(new lobject.TValue(defs.CT.LUA_TNUMINT, this.readInteger())); + case LUA_TNUMINT: + f.k.push(new lobject.TValue(LUA_TNUMINT, this.readInteger())); break; - case defs.CT.LUA_TSHRSTR: - case defs.CT.LUA_TLNGSTR: - f.k.push(new lobject.TValue(defs.CT.LUA_TLNGSTR, this.readString())); + case LUA_TSHRSTR: + case LUA_TLNGSTR: + f.k.push(new lobject.TValue(LUA_TLNGSTR, this.readString())); break; default: this.error(`unrecognized constant '${t}'`); @@ -214,12 +243,12 @@ class BytecodeParser { checkliteral(s, msg) { let buff = this.read(s.length); - if (!defs.luastring_cmp(buff, s)) + if (!luastring_eq(buff, s)) this.error(msg); } checkHeader() { - this.checkliteral(defs.to_luastring(defs.LUA_SIGNATURE.substring(1)), "not a"); /* 1st char already checked */ + this.checkliteral(LUA_SIGNATURE.subarray(1), "not a"); /* 1st char already checked */ if (this.readByte() !== 0x53) this.error("version mismatch in"); @@ -250,8 +279,8 @@ class BytecodeParser { } error(why) { - lobject.luaO_pushfstring(this.L, defs.to_luastring("%s: %s precompiled chunk"), this.name, defs.to_luastring(why)); - ldo.luaD_throw(this.L, defs.thread_status.LUA_ERRSYNTAX); + lobject.luaO_pushfstring(this.L, to_luastring("%s: %s precompiled chunk"), this.name, to_luastring(why)); + ldo.luaD_throw(this.L, LUA_ERRSYNTAX); } checksize(byte, size, tname) { @@ -268,7 +297,7 @@ const luaU_undump = function(L, Z, name) { L.stack[L.top-1].setclLvalue(cl); cl.p = new lfunc.Proto(L); S.readFunction(cl.p, null); - assert(cl.nupvalues === cl.p.upvalues.length); + lua_assert(cl.nupvalues === cl.p.upvalues.length); /* luai_verifycode */ return cl; }; diff --git a/src/lutf8lib.js b/src/lutf8lib.js index f581a9e..3e3e194 100644 --- a/src/lutf8lib.js +++ b/src/lutf8lib.js @@ -1,7 +1,33 @@ "use strict"; -const lua = require('./lua.js'); -const lauxlib = require('./lauxlib.js'); +const { + lua_gettop, + lua_pushcfunction, + lua_pushfstring, + lua_pushinteger, + lua_pushnil, + lua_pushstring, + lua_pushvalue, + lua_setfield, + lua_tointeger +} = require('./lua.js'); +const { + luaL_Buffer, + luaL_addvalue, + luaL_argcheck, + luaL_buffinit, + luaL_checkinteger, + luaL_checkstack, + luaL_checkstring, + luaL_error, + luaL_newlib, + luaL_optinteger, + luaL_pushresult +} = require('./lauxlib.js'); +const { + luastring_of, + to_luastring +} = require("./fengaricore.js"); const MAXUNICODE = 0x10FFFF; @@ -54,49 +80,50 @@ const utf8_decode = function(s, pos) { */ const utflen = function(L) { let n = 0; - let s = lauxlib.luaL_checkstring(L, 1); + let s = luaL_checkstring(L, 1); let len = s.length; - let posi = u_posrelat(lauxlib.luaL_optinteger(L, 2, 1), len); - let posj = u_posrelat(lauxlib.luaL_optinteger(L, 3, -1), len); + let posi = u_posrelat(luaL_optinteger(L, 2, 1), len); + let posj = u_posrelat(luaL_optinteger(L, 3, -1), len); - lauxlib.luaL_argcheck(L, 1 <= posi && --posi <= len, 2, lua.to_luastring("initial position out of string")); - lauxlib.luaL_argcheck(L, --posj < len, 3, lua.to_luastring("final position out of string")); + luaL_argcheck(L, 1 <= posi && --posi <= len, 2, to_luastring("initial position out of string")); + luaL_argcheck(L, --posj < len, 3, to_luastring("final position out of string")); while (posi <= posj) { let dec = utf8_decode(s, posi); if (dec === null) { /* conversion error? */ - lua.lua_pushnil(L); /* return nil ... */ - lua.lua_pushinteger(L, posi + 1); /* ... and current position */ + lua_pushnil(L); /* return nil ... */ + lua_pushinteger(L, posi + 1); /* ... and current position */ return 2; } posi = dec.pos; n++; } - lua.lua_pushinteger(L, n); + lua_pushinteger(L, n); return 1; }; +const p_U = to_luastring("%U"); const pushutfchar = function(L, arg) { - let code = lauxlib.luaL_checkinteger(L, arg); - lauxlib.luaL_argcheck(L, 0 <= code && code <= MAXUNICODE, arg, lua.to_luastring("value out of range", true)); - lua.lua_pushstring(L, lua.to_luastring(String.fromCodePoint(code))); + let code = luaL_checkinteger(L, arg); + luaL_argcheck(L, 0 <= code && code <= MAXUNICODE, arg, to_luastring("value out of range", true)); + lua_pushfstring(L, p_U, code); }; /* ** utfchar(n1, n2, ...) -> char(n1)..char(n2)... */ const utfchar = function(L) { - let n = lua.lua_gettop(L); /* number of arguments */ + let n = lua_gettop(L); /* number of arguments */ if (n === 1) /* optimize common case of single char */ pushutfchar(L, 1); else { - let b = new lauxlib.luaL_Buffer(); - lauxlib.luaL_buffinit(L, b); + let b = new luaL_Buffer(); + luaL_buffinit(L, b); for (let i = 1; i <= n; i++) { pushutfchar(L, i); - lauxlib.luaL_addvalue(b); + luaL_addvalue(b); } - lauxlib.luaL_pushresult(b); + luaL_pushresult(b); } return 1; }; @@ -106,19 +133,19 @@ const utfchar = function(L) { ** position 'i' starts; 0 means character at 'i'. */ const byteoffset = function(L) { - let s = lauxlib.luaL_checkstring(L, 1); - let n = lauxlib.luaL_checkinteger(L, 2); + let s = luaL_checkstring(L, 1); + let n = luaL_checkinteger(L, 2); let posi = n >= 0 ? 1 : s.length + 1; - posi = u_posrelat(lauxlib.luaL_optinteger(L, 3, posi), s.length); + posi = u_posrelat(luaL_optinteger(L, 3, posi), s.length); - lauxlib.luaL_argcheck(L, 1 <= posi && --posi <= s.length, 3, lua.to_luastring("position out of range", true)); + luaL_argcheck(L, 1 <= posi && --posi <= s.length, 3, to_luastring("position out of range", true)); if (n === 0) { /* find beginning of current byte sequence */ while (posi > 0 && iscont(s[posi])) posi--; } else { if (iscont(s[posi])) - lauxlib.luaL_error(L, lua.to_luastring("initial position is a continuation byte", true)); + luaL_error(L, to_luastring("initial position is a continuation byte", true)); if (n < 0) { while (n < 0 && posi > 0) { /* move back */ @@ -139,9 +166,9 @@ const byteoffset = function(L) { } if (n === 0) /* did it find given character? */ - lua.lua_pushinteger(L, posi + 1); + lua_pushinteger(L, posi + 1); else /* no such character */ - lua.lua_pushnil(L); + lua_pushnil(L); return 1; }; @@ -151,24 +178,24 @@ const byteoffset = function(L) { ** that start in the range [i,j] */ const codepoint = function(L) { - let s = lauxlib.luaL_checkstring(L, 1); - let posi = u_posrelat(lauxlib.luaL_optinteger(L, 2, 1), s.length); - let pose = u_posrelat(lauxlib.luaL_optinteger(L, 3, posi), s.length); + let s = luaL_checkstring(L, 1); + let posi = u_posrelat(luaL_optinteger(L, 2, 1), s.length); + let pose = u_posrelat(luaL_optinteger(L, 3, posi), s.length); - lauxlib.luaL_argcheck(L, posi >= 1, 2, lua.to_luastring("out of range", true)); - lauxlib.luaL_argcheck(L, pose <= s.length, 3, lua.to_luastring("out of range", true)); + luaL_argcheck(L, posi >= 1, 2, to_luastring("out of range", true)); + luaL_argcheck(L, pose <= s.length, 3, to_luastring("out of range", true)); if (posi > pose) return 0; /* empty interval; return no values */ if (pose - posi >= Number.MAX_SAFE_INTEGER) - return lauxlib.luaL_error(L, lua.to_luastring("string slice too long", true)); + return luaL_error(L, to_luastring("string slice too long", true)); let n = (pose - posi) + 1; - lauxlib.luaL_checkstack(L, n, lua.to_luastring("string slice too long", true)); + luaL_checkstack(L, n, to_luastring("string slice too long", true)); n = 0; for (posi -= 1; posi < pose;) { let dec = utf8_decode(s, posi); if (dec === null) - return lauxlib.luaL_error(L, lua.to_luastring("invalid UTF-8 code", true)); - lua.lua_pushinteger(L, dec.code); + return luaL_error(L, to_luastring("invalid UTF-8 code", true)); + lua_pushinteger(L, dec.code); posi = dec.pos; n++; } @@ -176,9 +203,9 @@ const codepoint = function(L) { }; const iter_aux = function(L) { - let s = lauxlib.luaL_checkstring(L, 1); + let s = luaL_checkstring(L, 1); let len = s.length; - let n = lua.lua_tointeger(L, 2) - 1; + let n = lua_tointeger(L, 2) - 1; if (n < 0) /* first iteration? */ n = 0; /* start from here */ @@ -192,18 +219,18 @@ const iter_aux = function(L) { else { let dec = utf8_decode(s, n); if (dec === null || iscont(s[dec.pos])) - return lauxlib.luaL_error(L, lua.to_luastring("invalid UTF-8 code", true)); - lua.lua_pushinteger(L, n + 1); - lua.lua_pushinteger(L, dec.code); + return luaL_error(L, to_luastring("invalid UTF-8 code", true)); + lua_pushinteger(L, n + 1); + lua_pushinteger(L, dec.code); return 2; } }; const iter_codes = function(L) { - lauxlib.luaL_checkstring(L, 1); - lua.lua_pushcfunction(L, iter_aux); - lua.lua_pushvalue(L, 1); - lua.lua_pushinteger(L, 0); + luaL_checkstring(L, 1); + lua_pushcfunction(L, iter_aux); + lua_pushvalue(L, 1); + lua_pushinteger(L, 0); return 3; }; @@ -216,12 +243,12 @@ const funcs = { }; /* pattern to match a single UTF-8 character */ -const UTF8PATT = Uint8Array.of(91, 0, 45, 127, 194, 45, 244, 93, 91, 128, 45, 191, 93, 42); +const UTF8PATT = luastring_of(91, 0, 45, 127, 194, 45, 244, 93, 91, 128, 45, 191, 93, 42); const luaopen_utf8 = function(L) { - lauxlib.luaL_newlib(L, funcs); - lua.lua_pushstring(L, UTF8PATT); - lua.lua_setfield(L, -2, lua.to_luastring("charpattern", true)); + luaL_newlib(L, funcs); + lua_pushstring(L, UTF8PATT); + lua_setfield(L, -2, to_luastring("charpattern", true)); return 1; }; @@ -1,56 +1,133 @@ "use strict"; -const assert = require('assert'); - -const defs = require('./defs.js'); -const lopcodes = require('./lopcodes.js'); -const luaconf = require('./luaconf.js'); -const lobject = require('./lobject.js'); -const lfunc = require('./lfunc.js'); -const lstate = require('./lstate.js'); -const lstring = require('./lstring.js'); -const llimits = require('./llimits.js'); -const ldo = require('./ldo.js'); -const ltm = require('./ltm.js'); -const ltable = require('./ltable.js'); -const ldebug = require('./ldebug.js'); -const CT = defs.constant_types; -const LUA_MULTRET = defs.LUA_MULTRET; +const { + LUA_MASKLINE, + LUA_MASKCOUNT, + LUA_MULTRET, + constant_types: { + LUA_TBOOLEAN, + LUA_TLCF, + LUA_TLIGHTUSERDATA, + LUA_TLNGSTR, + LUA_TNIL, + LUA_TNUMBER, + LUA_TNUMFLT, + LUA_TNUMINT, + LUA_TSHRSTR, + LUA_TTABLE, + LUA_TUSERDATA + }, + to_luastring +} = require('./defs.js'); +const { + INDEXK, + ISK, + LFIELDS_PER_FLUSH, + OpCodesI: { + OP_ADD, + OP_BAND, + OP_BNOT, + OP_BOR, + OP_BXOR, + OP_CALL, + OP_CLOSURE, + OP_CONCAT, + OP_DIV, + OP_EQ, + OP_EXTRAARG, + OP_FORLOOP, + OP_FORPREP, + OP_GETTABLE, + OP_GETTABUP, + OP_GETUPVAL, + OP_IDIV, + OP_JMP, + OP_LE, + OP_LEN, + OP_LOADBOOL, + OP_LOADK, + OP_LOADKX, + OP_LOADNIL, + OP_LT, + OP_MOD, + OP_MOVE, + OP_MUL, + OP_NEWTABLE, + OP_NOT, + OP_POW, + OP_RETURN, + OP_SELF, + OP_SETLIST, + OP_SETTABLE, + OP_SETTABUP, + OP_SETUPVAL, + OP_SHL, + OP_SHR, + OP_SUB, + OP_TAILCALL, + OP_TEST, + OP_TESTSET, + OP_TFORCALL, + OP_TFORLOOP, + OP_UNM, + OP_VARARG + } +} = require('./lopcodes.js'); +const { + LUA_MAXINTEGER, + LUA_MININTEGER, + lua_numbertointeger +} = require('./luaconf.js'); +const { + lua_assert, + luai_nummod +} = require('./llimits.js'); +const lobject = require('./lobject.js'); +const lfunc = require('./lfunc.js'); +const lstate = require('./lstate.js'); +const { + luaS_bless, + luaS_eqlngstr, + luaS_hashlongstr +} = require('./lstring.js'); +const ldo = require('./ldo.js'); +const ltm = require('./ltm.js'); +const ltable = require('./ltable.js'); +const ldebug = require('./ldebug.js'); /* ** finish execution of an opcode interrupted by an yield */ const luaV_finishOp = function(L) { let ci = L.ci; - let OCi = lopcodes.OpCodesI; let base = ci.l_base; let inst = ci.l_code[ci.l_savedpc - 1]; /* interrupted instruction */ let op = inst.opcode; switch (op) { /* finish its execution */ - case OCi.OP_ADD: case OCi.OP_SUB: case OCi.OP_MUL: case OCi.OP_DIV: case OCi.OP_IDIV: - case OCi.OP_BAND: case OCi.OP_BOR: case OCi.OP_BXOR: case OCi.OP_SHL: case OCi.OP_SHR: - case OCi.OP_MOD: case OCi.OP_POW: - case OCi.OP_UNM: case OCi.OP_BNOT: case OCi.OP_LEN: - case OCi.OP_GETTABUP: case OCi.OP_GETTABLE: case OCi.OP_SELF: { + case OP_ADD: case OP_SUB: case OP_MUL: case OP_DIV: case OP_IDIV: + case OP_BAND: case OP_BOR: case OP_BXOR: case OP_SHL: case OP_SHR: + case OP_MOD: case OP_POW: + case OP_UNM: case OP_BNOT: case OP_LEN: + case OP_GETTABUP: case OP_GETTABLE: case OP_SELF: { lobject.setobjs2s(L, base + inst.A, L.top-1); delete L.stack[--L.top]; break; } - case OCi.OP_LE: case OCi.OP_LT: case OCi.OP_EQ: { + case OP_LE: case OP_LT: case OP_EQ: { let res = !L.stack[L.top - 1].l_isfalse(); delete L.stack[--L.top]; if (ci.callstatus & lstate.CIST_LEQ) { /* "<=" using "<" instead? */ - assert(op === OCi.OP_LE); + lua_assert(op === OP_LE); ci.callstatus ^= lstate.CIST_LEQ; /* clear mark */ res = !res; /* negate result */ } - assert(ci.l_code[ci.l_savedpc].opcode === OCi.OP_JMP); + lua_assert(ci.l_code[ci.l_savedpc].opcode === OP_JMP); if (res !== (inst.A ? true : false)) /* condition failed? */ ci.l_savedpc++; /* skip jump instruction */ break; } - case OCi.OP_CONCAT: { + case OP_CONCAT: { let top = L.top - 1; /* top when 'luaT_trybinTM' was called */ let b = inst.B; /* first element to concatenate */ let total = top - 1 - (base + b); /* yet to concatenate */ @@ -64,12 +141,12 @@ const luaV_finishOp = function(L) { ldo.adjust_top(L, ci.top); /* restore top */ break; } - case OCi.OP_TFORCALL: { - assert(ci.l_code[ci.l_savedpc].opcode === OCi.OP_TFORLOOP); + case OP_TFORCALL: { + lua_assert(ci.l_code[ci.l_savedpc].opcode === OP_TFORLOOP); ldo.adjust_top(L, ci.top); /* correct top */ break; } - case OCi.OP_CALL: { + case OP_CALL: { if (inst.C - 1 >= 0) /* nresults >= 0? */ ldo.adjust_top(L, ci.top); /* adjust results */ break; @@ -90,28 +167,27 @@ const RB = function(L, base, i) { // }; const RKB = function(L, base, k, i) { - return lopcodes.ISK(i.B) ? k[lopcodes.INDEXK(i.B)] : L.stack[base + i.B]; + return ISK(i.B) ? k[INDEXK(i.B)] : L.stack[base + i.B]; }; const RKC = function(L, base, k, i) { - return lopcodes.ISK(i.C) ? k[lopcodes.INDEXK(i.C)] : L.stack[base + i.C]; + return ISK(i.C) ? k[INDEXK(i.C)] : L.stack[base + i.C]; }; const luaV_execute = function(L) { - const OCi = lopcodes.OpCodesI; let ci = L.ci; ci.callstatus |= lstate.CIST_FRESH; newframe: for (;;) { - assert(ci === L.ci); + lua_assert(ci === L.ci); let cl = ci.func.value; let k = cl.p.k; let base = ci.l_base; let i = ci.l_code[ci.l_savedpc++]; - if (L.hookmask & (defs.LUA_MASKLINE | defs.LUA_MASKCOUNT)) { + if (L.hookmask & (LUA_MASKLINE | LUA_MASKCOUNT)) { ldebug.luaG_traceexec(L); } @@ -119,22 +195,22 @@ const luaV_execute = function(L) { let opcode = i.opcode; switch (opcode) { - case OCi.OP_MOVE: { + case OP_MOVE: { lobject.setobjs2s(L, ra, RB(L, base, i)); break; } - case OCi.OP_LOADK: { + case OP_LOADK: { let konst = k[i.Bx]; lobject.setobj2s(L, ra, konst); break; } - case OCi.OP_LOADKX: { - assert(ci.l_code[ci.l_savedpc].opcode === OCi.OP_EXTRAARG); + case OP_LOADKX: { + lua_assert(ci.l_code[ci.l_savedpc].opcode === OP_EXTRAARG); let konst = k[ci.l_code[ci.l_savedpc++].Ax]; lobject.setobj2s(L, ra, konst); break; } - case OCi.OP_LOADBOOL: { + case OP_LOADBOOL: { L.stack[ra].setbvalue(i.B !== 0); if (i.C !== 0) @@ -142,41 +218,41 @@ const luaV_execute = function(L) { break; } - case OCi.OP_LOADNIL: { + case OP_LOADNIL: { for (let j = 0; j <= i.B; j++) L.stack[ra + j].setnilvalue(); break; } - case OCi.OP_GETUPVAL: { + case OP_GETUPVAL: { let b = i.B; - lobject.setobj2s(L, ra, cl.upvals[b].v); + lobject.setobj2s(L, ra, cl.upvals[b]); break; } - case OCi.OP_GETTABUP: { - let upval = cl.upvals[i.B].v; + case OP_GETTABUP: { + let upval = cl.upvals[i.B]; let rc = RKC(L, base, k, i); luaV_gettable(L, upval, rc, ra); break; } - case OCi.OP_GETTABLE: { + case OP_GETTABLE: { let rb = L.stack[RB(L, base, i)]; let rc = RKC(L, base, k, i); luaV_gettable(L, rb, rc, ra); break; } - case OCi.OP_SETTABUP: { - let upval = cl.upvals[i.A].v; + case OP_SETTABUP: { + let upval = cl.upvals[i.A]; let rb = RKB(L, base, k, i); let rc = RKC(L, base, k, i); settable(L, upval, rb, rc); break; } - case OCi.OP_SETUPVAL: { + case OP_SETUPVAL: { let uv = cl.upvals[i.B]; - uv.v.setfrom(L.stack[ra]); + uv.setfrom(L.stack[ra]); break; } - case OCi.OP_SETTABLE: { + case OP_SETTABLE: { let table = L.stack[ra]; let key = RKB(L, base, k, i); let v = RKC(L, base, k, i); @@ -184,18 +260,18 @@ const luaV_execute = function(L) { settable(L, table, key, v); break; } - case OCi.OP_NEWTABLE: { + case OP_NEWTABLE: { L.stack[ra].sethvalue(ltable.luaH_new(L)); break; } - case OCi.OP_SELF: { + case OP_SELF: { let rb = RB(L, base, i); let rc = RKC(L, base, k, i); lobject.setobjs2s(L, ra + 1, rb); luaV_gettable(L, L.stack[rb], rc, ra); break; } - case OCi.OP_ADD: { + case OP_ADD: { let op1 = RKB(L, base, k, i); let op2 = RKC(L, base, k, i); let numberop1, numberop2; @@ -209,7 +285,7 @@ const luaV_execute = function(L) { } break; } - case OCi.OP_SUB: { + case OP_SUB: { let op1 = RKB(L, base, k, i); let op2 = RKC(L, base, k, i); let numberop1, numberop2; @@ -223,13 +299,13 @@ const luaV_execute = function(L) { } break; } - case OCi.OP_MUL: { + case OP_MUL: { let op1 = RKB(L, base, k, i); let op2 = RKC(L, base, k, i); let numberop1, numberop2; if (op1.ttisinteger() && op2.ttisinteger()) { - L.stack[ra].setivalue(Math.imul(op1.value, op2.value)); + L.stack[ra].setivalue(luaV_imul(op1.value, op2.value)); } else if ((numberop1 = tonumber(op1)) !== false && (numberop2 = tonumber(op2)) !== false) { L.stack[ra].setfltvalue(numberop1 * numberop2); } else { @@ -237,7 +313,7 @@ const luaV_execute = function(L) { } break; } - case OCi.OP_MOD: { + case OP_MOD: { let op1 = RKB(L, base, k, i); let op2 = RKC(L, base, k, i); let numberop1, numberop2; @@ -245,13 +321,13 @@ const luaV_execute = function(L) { if (op1.ttisinteger() && op2.ttisinteger()) { L.stack[ra].setivalue(luaV_mod(L, op1.value, op2.value)); } else if ((numberop1 = tonumber(op1)) !== false && (numberop2 = tonumber(op2)) !== false) { - L.stack[ra].setfltvalue(llimits.luai_nummod(L, numberop1, numberop2)); + L.stack[ra].setfltvalue(luai_nummod(L, numberop1, numberop2)); } else { ltm.luaT_trybinTM(L, op1, op2, L.stack[ra], ltm.TMS.TM_MOD); } break; } - case OCi.OP_POW: { + case OP_POW: { let op1 = RKB(L, base, k, i); let op2 = RKC(L, base, k, i); let numberop1, numberop2; @@ -263,7 +339,7 @@ const luaV_execute = function(L) { } break; } - case OCi.OP_DIV: { + case OP_DIV: { let op1 = RKB(L, base, k, i); let op2 = RKC(L, base, k, i); let numberop1, numberop2; @@ -275,7 +351,7 @@ const luaV_execute = function(L) { } break; } - case OCi.OP_IDIV: { + case OP_IDIV: { let op1 = RKB(L, base, k, i); let op2 = RKC(L, base, k, i); let numberop1, numberop2; @@ -289,7 +365,7 @@ const luaV_execute = function(L) { } break; } - case OCi.OP_BAND: { + case OP_BAND: { let op1 = RKB(L, base, k, i); let op2 = RKC(L, base, k, i); let numberop1, numberop2; @@ -301,7 +377,7 @@ const luaV_execute = function(L) { } break; } - case OCi.OP_BOR: { + case OP_BOR: { let op1 = RKB(L, base, k, i); let op2 = RKC(L, base, k, i); let numberop1, numberop2; @@ -313,7 +389,7 @@ const luaV_execute = function(L) { } break; } - case OCi.OP_BXOR: { + case OP_BXOR: { let op1 = RKB(L, base, k, i); let op2 = RKC(L, base, k, i); let numberop1, numberop2; @@ -325,7 +401,7 @@ const luaV_execute = function(L) { } break; } - case OCi.OP_SHL: { + case OP_SHL: { let op1 = RKB(L, base, k, i); let op2 = RKC(L, base, k, i); let numberop1, numberop2; @@ -337,7 +413,7 @@ const luaV_execute = function(L) { } break; } - case OCi.OP_SHR: { + case OP_SHR: { let op1 = RKB(L, base, k, i); let op2 = RKC(L, base, k, i); let numberop1, numberop2; @@ -349,7 +425,7 @@ const luaV_execute = function(L) { } break; } - case OCi.OP_UNM: { + case OP_UNM: { let op = L.stack[RB(L, base, i)]; let numberop; @@ -362,7 +438,7 @@ const luaV_execute = function(L) { } break; } - case OCi.OP_BNOT: { + case OP_BNOT: { let op = L.stack[RB(L, base, i)]; if (op.ttisinteger()) { @@ -372,16 +448,16 @@ const luaV_execute = function(L) { } break; } - case OCi.OP_NOT: { + case OP_NOT: { let op = L.stack[RB(L, base, i)]; L.stack[ra].setbvalue(op.l_isfalse()); break; } - case OCi.OP_LEN: { + case OP_LEN: { luaV_objlen(L, L.stack[ra], L.stack[RB(L, base, i)]); break; } - case OCi.OP_CONCAT: { + case OP_CONCAT: { let b = i.B; let c = i.C; L.top = base + c + 1; /* mark the end of concat operands */ @@ -391,39 +467,39 @@ const luaV_execute = function(L) { ldo.adjust_top(L, ci.top); /* restore top */ break; } - case OCi.OP_JMP: { + case OP_JMP: { dojump(L, ci, i, 0); break; } - case OCi.OP_EQ: { + case OP_EQ: { if (luaV_equalobj(L, RKB(L, base, k, i), RKC(L, base, k, i)) !== i.A) ci.l_savedpc++; else donextjump(L, ci); break; } - case OCi.OP_LT: { + case OP_LT: { if (luaV_lessthan(L, RKB(L, base, k, i), RKC(L, base, k, i)) !== i.A) ci.l_savedpc++; else donextjump(L, ci); break; } - case OCi.OP_LE: { + case OP_LE: { if (luaV_lessequal(L, RKB(L, base, k, i), RKC(L, base, k, i)) !== i.A) ci.l_savedpc++; else donextjump(L, ci); break; } - case OCi.OP_TEST: { + case OP_TEST: { if (i.C ? L.stack[ra].l_isfalse() : !L.stack[ra].l_isfalse()) ci.l_savedpc++; else donextjump(L, ci); break; } - case OCi.OP_TESTSET: { + case OP_TESTSET: { let rbIdx = RB(L, base, i); let rb = L.stack[rbIdx]; if (i.C ? rb.l_isfalse() : !rb.l_isfalse()) @@ -434,7 +510,7 @@ const luaV_execute = function(L) { } break; } - case OCi.OP_CALL: { + case OP_CALL: { let b = i.B; let nresults = i.C - 1; if (b !== 0) ldo.adjust_top(L, ra+b); /* else previous instruction set top */ @@ -448,7 +524,7 @@ const luaV_execute = function(L) { break; } - case OCi.OP_TAILCALL: { + case OP_TAILCALL: { let b = i.B; if (b !== 0) ldo.adjust_top(L, ra+b); /* else previous instruction set top */ if (ldo.luaD_precall(L, ra, LUA_MULTRET)) { // JS function @@ -472,13 +548,13 @@ const luaV_execute = function(L) { oci.next = null; ci = L.ci = oci; - assert(L.top === oci.l_base + L.stack[ofuncOff].value.p.maxstacksize); + lua_assert(L.top === oci.l_base + L.stack[ofuncOff].value.p.maxstacksize); continue newframe; } break; } - case OCi.OP_RETURN: { + case OP_RETURN: { if (cl.p.p.length > 0) lfunc.luaF_close(L, base); let b = ldo.luaD_poscall(L, ci, ra, (i.B !== 0 ? i.B - 1 : L.top - ra)); @@ -487,11 +563,11 @@ const luaV_execute = function(L) { /* invocation via reentry: continue execution */ ci = L.ci; if (b) ldo.adjust_top(L, ci.top); - assert(ci.callstatus & lstate.CIST_LUA); - assert(ci.l_code[ci.l_savedpc - 1].opcode === OCi.OP_CALL); + lua_assert(ci.callstatus & lstate.CIST_LUA); + lua_assert(ci.l_code[ci.l_savedpc - 1].opcode === OP_CALL); continue newframe; } - case OCi.OP_FORLOOP: { + case OP_FORLOOP: { if (L.stack[ra].ttisinteger()) { /* integer loop? */ let step = L.stack[ra + 2].value; let idx = (L.stack[ra].value + step)|0; @@ -515,7 +591,7 @@ const luaV_execute = function(L) { } break; } - case OCi.OP_FORPREP: { + case OP_FORPREP: { let init = L.stack[ra]; let plimit = L.stack[ra + 1]; let pstep = L.stack[ra + 2]; @@ -529,20 +605,20 @@ const luaV_execute = function(L) { } else { /* try making all values floats */ let nlimit, nstep, ninit; if ((nlimit = tonumber(plimit)) === false) - ldebug.luaG_runerror(L, defs.to_luastring("'for' limit must be a number", true)); + ldebug.luaG_runerror(L, to_luastring("'for' limit must be a number", true)); L.stack[ra + 1].setfltvalue(nlimit); if ((nstep = tonumber(pstep)) === false) - ldebug.luaG_runerror(L, defs.to_luastring("'for' step must be a number", true)); + ldebug.luaG_runerror(L, to_luastring("'for' step must be a number", true)); L.stack[ra + 2].setfltvalue(nstep); if ((ninit = tonumber(init)) === false) - ldebug.luaG_runerror(L, defs.to_luastring("'for' initial value must be a number", true)); + ldebug.luaG_runerror(L, to_luastring("'for' initial value must be a number", true)); L.stack[ra].setfltvalue(ninit - nstep); } ci.l_savedpc += i.sBx; break; } - case OCi.OP_TFORCALL: { + case OP_TFORCALL: { let cb = ra + 3; /* call base */ lobject.setobjs2s(L, cb+2, ra+2); lobject.setobjs2s(L, cb+1, ra+1); @@ -553,29 +629,29 @@ const luaV_execute = function(L) { /* go straight to OP_TFORLOOP */ i = ci.l_code[ci.l_savedpc++]; ra = RA(L, base, i); - assert(i.opcode === OCi.OP_TFORLOOP); + lua_assert(i.opcode === OP_TFORLOOP); } /* fall through */ - case OCi.OP_TFORLOOP: { + case OP_TFORLOOP: { if (!L.stack[ra + 1].ttisnil()) { /* continue loop? */ lobject.setobjs2s(L, ra, ra + 1); /* save control variable */ ci.l_savedpc += i.sBx; /* jump back */ } break; } - case OCi.OP_SETLIST: { + case OP_SETLIST: { let n = i.B; let c = i.C; if (n === 0) n = L.top - ra - 1; if (c === 0) { - assert(ci.l_code[ci.l_savedpc].opcode === OCi.OP_EXTRAARG); + lua_assert(ci.l_code[ci.l_savedpc].opcode === OP_EXTRAARG); c = ci.l_code[ci.l_savedpc++].Ax; } let h = L.stack[ra].value; - let last = ((c - 1) * lopcodes.LFIELDS_PER_FLUSH) + n; + let last = ((c - 1) * LFIELDS_PER_FLUSH) + n; for (; n > 0; n--) { ltable.luaH_setint(h, last--, L.stack[ra + n]); @@ -583,7 +659,7 @@ const luaV_execute = function(L) { ldo.adjust_top(L, ci.top); /* correct top (in case of previous open call) */ break; } - case OCi.OP_CLOSURE: { + case OP_CLOSURE: { let p = cl.p.p[i.Bx]; let ncl = getcached(p, cl.upvals, L.stack, base); /* cached closure */ if (ncl === null) /* no match? */ @@ -592,7 +668,7 @@ const luaV_execute = function(L) { L.stack[ra].setclLvalue(ncl); break; } - case OCi.OP_VARARG: { + case OP_VARARG: { let b = i.B - 1; let n = base - ci.funcOff - cl.p.numparams - 1; let j; @@ -613,7 +689,7 @@ const luaV_execute = function(L) { L.stack[ra + j].setnilvalue(); break; } - case OCi.OP_EXTRAARG: { + case OP_EXTRAARG: { throw Error("invalid opcode"); } } @@ -667,7 +743,7 @@ const luaV_lessequal = function(L, l, r) { const luaV_equalobj = function(L, t1, t2) { if (t1.ttype() !== t2.ttype()) { /* not the same variant? */ - if (t1.ttnov() !== t2.ttnov() || t1.ttnov() !== CT.LUA_TNUMBER) + if (t1.ttnov() !== t2.ttnov() || t1.ttnov() !== LUA_TNUMBER) return 0; /* only numbers can be equal with different variants */ else { /* two numbers with different variants */ /* OPTIMIZATION: instead of calling luaV_tointeger we can just let JS do the comparison */ @@ -679,21 +755,21 @@ const luaV_equalobj = function(L, t1, t2) { /* values have same type and same variant */ switch(t1.ttype()) { - case CT.LUA_TNIL: + case LUA_TNIL: return 1; - case CT.LUA_TBOOLEAN: + case LUA_TBOOLEAN: return t1.value == t2.value ? 1 : 0; // Might be 1 or true - case CT.LUA_TLIGHTUSERDATA: - case CT.LUA_TNUMINT: - case CT.LUA_TNUMFLT: - case CT.LUA_TLCF: + case LUA_TLIGHTUSERDATA: + case LUA_TNUMINT: + case LUA_TNUMFLT: + case LUA_TLCF: return t1.value === t2.value ? 1 : 0; - case CT.LUA_TSHRSTR: - case CT.LUA_TLNGSTR: { - return lstring.luaS_eqlngstr(t1.tsvalue(), t2.tsvalue()) ? 1 : 0; + case LUA_TSHRSTR: + case LUA_TLNGSTR: { + return luaS_eqlngstr(t1.tsvalue(), t2.tsvalue()) ? 1 : 0; } - case CT.LUA_TUSERDATA: - case CT.LUA_TTABLE: + case LUA_TUSERDATA: + case LUA_TTABLE: if (t1.value === t2.value) return 1; else if (L === null) return 0; @@ -726,10 +802,10 @@ const forlimit = function(obj, step) { return false; if (0 < n) { - ilimit = luaconf.LUA_MAXINTEGER; + ilimit = LUA_MAXINTEGER; if (step < 0) stopnow = true; } else { - ilimit = luaconf.LUA_MININTEGER; + ilimit = LUA_MININTEGER; if (step >= 0) stopnow = true; } } @@ -758,7 +834,7 @@ const luaV_tointeger = function(obj, mode) { f += 1; /* convert floor to ceil (remember: n !== f) */ } - return luaconf.lua_numbertointeger(f); + return lua_numbertointeger(f); } else if (obj.ttisinteger()) { return obj.value; } else if (cvt2num(obj)) { @@ -775,7 +851,7 @@ const tointeger = function(o) { }; const tonumber = function(o) { - if (o.ttnov() === CT.LUA_TNUMBER) + if (o.ttnov() === LUA_TNUMBER) return o.value; if (cvt2num(o)) { /* string convertible to number? */ @@ -808,8 +884,8 @@ const LEnum = function(l, r) { ** -larger than zero if 'ls' is smaller-equal-larger than 'rs'. */ const l_strcmp = function(ls, rs) { - let l = lstring.luaS_hashlongstr(ls); - let r = lstring.luaS_hashlongstr(rs); + let l = luaS_hashlongstr(ls); + let r = luaS_hashlongstr(rs); /* In fengari we assume string hash has same collation as byte values */ if (l === r) return 0; @@ -825,21 +901,21 @@ const l_strcmp = function(ls, rs) { const luaV_objlen = function(L, ra, rb) { let tm; switch(rb.ttype()) { - case CT.LUA_TTABLE: { + case LUA_TTABLE: { let h = rb.value; tm = ltm.fasttm(L, h.metatable, ltm.TMS.TM_LEN); if (tm !== null) break; /* metamethod? break switch to call it */ ra.setivalue(ltable.luaH_getn(h)); /* else primitive len */ return; } - case CT.LUA_TSHRSTR: - case CT.LUA_TLNGSTR: + case LUA_TSHRSTR: + case LUA_TLNGSTR: ra.setivalue(rb.vslen()); return; default: { tm = ltm.luaT_gettmbyobj(L, rb, ltm.TMS.TM_LEN); if (tm.ttisnil()) - ldebug.luaG_typeerror(L, rb, defs.to_luastring("get length of", true)); + ldebug.luaG_typeerror(L, rb, to_luastring("get length of", true)); break; } } @@ -847,16 +923,29 @@ const luaV_objlen = function(L, ra, rb) { ltm.luaT_callTM(L, tm, rb, rb, ra, 1); }; +/* Shim taken from https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/imul */ +const luaV_imul = Math.imul || function(a, b) { + let aHi = (a >>> 16) & 0xffff; + let aLo = a & 0xffff; + let bHi = (b >>> 16) & 0xffff; + let bLo = b & 0xffff; + /* + ** the shift by 0 fixes the sign on the high part + ** the final |0 converts the unsigned value into a signed value + */ + return ((aLo * bLo) + (((aHi * bLo + aLo * bHi) << 16) >>> 0) | 0); +}; + const luaV_div = function(L, m, n) { if (n === 0) - ldebug.luaG_runerror(L, defs.to_luastring("attempt to divide by zero")); + ldebug.luaG_runerror(L, to_luastring("attempt to divide by zero")); return Math.floor(m / n)|0; }; // % semantic on negative numbers is different in js const luaV_mod = function(L, m, n) { if (n === 0) - ldebug.luaG_runerror(L, defs.to_luastring("attempt to perform 'n%%0'")); + ldebug.luaG_runerror(L, to_luastring("attempt to perform 'n%%0'")); return (m - Math.floor(m / n) * n)|0; }; @@ -884,8 +973,8 @@ const getcached = function(p, encup, stack, base) { let uv = p.upvalues; let nup = uv.length; for (let i = 0; i < nup; i++) { /* check whether it has right upvalues */ - let v = uv[i].instack ? stack[base + uv[i].idx] : encup[uv[i].idx].v; - if (c.upvals[i].v !== v) + let v = uv[i].instack ? stack[base + uv[i].idx] : encup[uv[i].idx]; + if (c.upvals[i] !== v) return null; /* wrong upvalue; cannot reuse closure */ } } @@ -907,7 +996,6 @@ const pushclosure = function(L, p, encup, base, ra) { ncl.upvals[i] = lfunc.luaF_findupval(L, base + uv[i].idx); else ncl.upvals[i] = encup[uv[i].idx]; - ncl.upvals[i].refcount++; } p.cache = ncl; /* save it on cache for reuse */ }; @@ -954,7 +1042,7 @@ const copy2buff = function(L, top, n, buff) { ** from 'L->top - total' up to 'L->top - 1'. */ const luaV_concat = function(L, total) { - assert(total >= 2); + lua_assert(total >= 2); do { let top = L.top; let n = 2; /* number of elements handled in this pass (at least 2) */ @@ -975,7 +1063,7 @@ const luaV_concat = function(L, total) { } let buff = new Uint8Array(tl); copy2buff(L, top, n, buff); - let ts = lstring.luaS_bless(L, buff); + let ts = luaS_bless(L, buff); lobject.setsvalue2s(L, top - n, ts); } total -= n - 1; /* got 'n' strings to create 1 new */ @@ -994,7 +1082,7 @@ const luaV_gettable = function(L, t, key, ra) { if (!t.ttistable()) { tm = ltm.luaT_gettmbyobj(L, t, ltm.TMS.TM_INDEX); if (tm.ttisnil()) - ldebug.luaG_typeerror(L, t, defs.to_luastring('index', true)); /* no metamethod */ + ldebug.luaG_typeerror(L, t, to_luastring('index', true)); /* no metamethod */ /* else will try the metamethod */ } else { let slot = ltable.luaH_get(L, t.value, key); @@ -1017,7 +1105,7 @@ const luaV_gettable = function(L, t, key, ra) { t = tm; /* else try to access 'tm[key]' */ } - ldebug.luaG_runerror(L, defs.to_luastring("'__index' chain too long; possible loop", true)); + ldebug.luaG_runerror(L, to_luastring("'__index' chain too long; possible loop", true)); }; const settable = function(L, t, key, val) { @@ -1037,7 +1125,7 @@ const settable = function(L, t, key, val) { /* else will try the metamethod */ } else { /* not a table; check metamethod */ if ((tm = ltm.luaT_gettmbyobj(L, t, ltm.TMS.TM_NEWINDEX)).ttisnil()) - ldebug.luaG_typeerror(L, t, defs.to_luastring('index', true)); + ldebug.luaG_typeerror(L, t, to_luastring('index', true)); } /* try the metamethod */ if (tm.ttisfunction()) { @@ -1047,7 +1135,7 @@ const settable = function(L, t, key, val) { t = tm; /* else repeat assignment over 'tm' */ } - ldebug.luaG_runerror(L, defs.to_luastring("'__newindex' chain too long; possible loop", true)); + ldebug.luaG_runerror(L, to_luastring("'__newindex' chain too long; possible loop", true)); }; @@ -1059,6 +1147,7 @@ module.exports.luaV_div = luaV_div; module.exports.luaV_equalobj = luaV_equalobj; module.exports.luaV_execute = luaV_execute; module.exports.luaV_finishOp = luaV_finishOp; +module.exports.luaV_imul = luaV_imul; module.exports.luaV_lessequal = luaV_lessequal; module.exports.luaV_lessthan = luaV_lessthan; module.exports.luaV_mod = luaV_mod; diff --git a/src/lzio.js b/src/lzio.js index a00a24b..b9081a7 100644 --- a/src/lzio.js +++ b/src/lzio.js @@ -1,7 +1,6 @@ "use strict"; -const assert = require('assert'); - +const { lua_assert } = require("./llimits.js"); class MBuffer { constructor() { @@ -32,7 +31,7 @@ const luaZ_resizebuffer = function(L, buff, size) { class ZIO { constructor(L, reader, data) { this.L = L; /* Lua state (for reader) */ - assert(typeof reader == "function", "ZIO requires a reader"); + lua_assert(typeof reader == "function", "ZIO requires a reader"); this.reader = reader; /* reader function */ this.data = data; /* additional data */ this.n = 0; /* bytes still unread */ @@ -51,7 +50,7 @@ const luaZ_fill = function(z) { let buff = z.reader(z.L, z.data); if (buff === null) return EOZ; - assert(buff instanceof Uint8Array, "Should only load binary of array of bytes"); + lua_assert(buff instanceof Uint8Array, "Should only load binary of array of bytes"); let size = buff.length; if (size === 0) return EOZ; diff --git a/tests/defs.js b/tests/defs.js index 1a935d6..f24dee0 100644 --- a/tests/defs.js +++ b/tests/defs.js @@ -6,37 +6,37 @@ const unicode_tests = [ { description: "Convert normal ascii string", literal: "foo", - byte_array: defs.string_of("f".charCodeAt(0), "o".charCodeAt(0), "o".charCodeAt(0)) + byte_array: defs.luastring_of("f".charCodeAt(0), "o".charCodeAt(0), "o".charCodeAt(0)) }, { description: "Convert ascii string containing null byte", literal: "fo\0o", - byte_array: defs.string_of("f".charCodeAt(0), "o".charCodeAt(0), 0, "o".charCodeAt(0)) + byte_array: defs.luastring_of("f".charCodeAt(0), "o".charCodeAt(0), 0, "o".charCodeAt(0)) }, { description: "Convert string with BMP unicode chars", literal: "Café", - byte_array: defs.string_of(67, 97, 102, 195, 169) + byte_array: defs.luastring_of(67, 97, 102, 195, 169) }, { description: "Convert string with codepoint in PUA (U+E000 to U+F8FF)", literal: "", - byte_array: defs.string_of(239, 163, 191) + byte_array: defs.luastring_of(239, 163, 191) }, { description: "Convert string with surrogate pair", literal: "❤️🍾", - byte_array: defs.string_of(226, 157, 164, 239, 184, 143, 240, 159, 141, 190) + byte_array: defs.luastring_of(226, 157, 164, 239, 184, 143, 240, 159, 141, 190) }, { description: "Convert string with broken surrogate pair", literal: "\uD800a", - byte_array: defs.string_of(237, 160, 128, 97) + byte_array: defs.luastring_of(237, 160, 128, 97) }, { description: "Convert string with broken surrogate pair at end of string", literal: "\uD823", - byte_array: defs.string_of(237, 160, 163) + byte_array: defs.luastring_of(237, 160, 163) } ]; diff --git a/tests/lapi.js b/tests/lapi.js index a63ae66..56859d8 100644 --- a/tests/lapi.js +++ b/tests/lapi.js @@ -5,8 +5,9 @@ const test = require('tape'); const tests = require("./tests.js"); const toByteCode = tests.toByteCode; -const lauxlib = require("../src/lauxlib.js"); const lua = require('../src/lua.js'); +const lauxlib = require("../src/lauxlib.js"); +const {to_luastring} = require("../src/fengaricore.js"); test('luaL_newstate, lua_pushnil, luaL_typename', function (t) { let L; @@ -369,7 +370,7 @@ test('lua_load with no chunkname', function (t) { t.doesNotThrow(function () { L = lauxlib.luaL_newstate(); - lua.lua_load(L, function(L, s) { let r = s.code; s.code = null; return r; }, {code: lua.to_luastring("return 'hello'")}, null, null); + lua.lua_load(L, function(L, s) { let r = s.code; s.code = null; return r; }, {code: to_luastring("return 'hello'")}, null, null); lua.lua_call(L, 0, 1); }, "JS Lua program ran without error"); @@ -395,7 +396,7 @@ test('lua_load and lua_call it', function (t) { L = lauxlib.luaL_newstate(); - lua.lua_load(L, function(L, s) { let r = s.bc; s.bc = null; return r; }, {bc: bc}, lua.to_luastring("test-lua_load"), lua.to_luastring("binary")); + lua.lua_load(L, function(L, s) { let r = s.bc; s.bc = null; return r; }, {bc: bc}, to_luastring("test-lua_load"), to_luastring("binary")); lua.lua_call(L, 0, 1); @@ -420,10 +421,10 @@ test('lua script reads js upvalues', function (t) { L = lauxlib.luaL_newstate(); - lauxlib.luaL_loadstring(L, lua.to_luastring(luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(luaCode)); lua.lua_pushliteral(L, "hello"); - lua.lua_setglobal(L, lua.to_luastring("js")); + lua.lua_setglobal(L, to_luastring("js")); lua.lua_call(L, 0, 1); @@ -518,7 +519,7 @@ test('lua_atnativeerror', function(t) { lua.lua_atnativeerror(L, function(L) { let e = lua.lua_touserdata(L, 1); t.strictEqual(e, errob); - lua.lua_pushstring(L, lua.to_luastring("runtime error!")); + lua.lua_pushstring(L, to_luastring("runtime error!")); return 1; }); lua.lua_pushcfunction(L, function(L) { @@ -532,7 +533,7 @@ test('lua_atnativeerror', function(t) { lua.lua_atnativeerror(L, function(L) { let e = lua.lua_touserdata(L, 1); t.strictEqual(e, errob); - lauxlib.luaL_error(L, lua.to_luastring("runtime error!")); + lauxlib.luaL_error(L, to_luastring("runtime error!")); }); lua.lua_pushcfunction(L, function(L) { throw errob; diff --git a/tests/lauxlib.js b/tests/lauxlib.js index d484edb..8d57ecb 100644 --- a/tests/lauxlib.js +++ b/tests/lauxlib.js @@ -1,9 +1,10 @@ "use strict"; -const test = require('tape'); +const test = require('tape'); -const lua = require('../src/lua.js'); -const lauxlib = require("../src/lauxlib.js"); +const lua = require('../src/lua.js'); +const lauxlib = require("../src/lauxlib.js"); +const {to_luastring} = require("../src/fengaricore.js"); test('luaL_ref, lua_rawgeti, luaL_unref, LUA_REGISTRYINDEX', function (t) { let L; @@ -12,7 +13,7 @@ test('luaL_ref, lua_rawgeti, luaL_unref, LUA_REGISTRYINDEX', function (t) { t.doesNotThrow(function () { L = lauxlib.luaL_newstate(); - lua.lua_pushstring(L, lua.to_luastring("hello references!")); + lua.lua_pushstring(L, to_luastring("hello references!")); let r = lauxlib.luaL_ref(L, lua.LUA_REGISTRYINDEX); // pops a value, stores it and returns a reference lua.lua_rawgeti(L, lua.LUA_REGISTRYINDEX, r); // pushes a value associated with the reference diff --git a/tests/lbaselib.js b/tests/lbaselib.js index 6558c1f..6bef0d8 100644 --- a/tests/lbaselib.js +++ b/tests/lbaselib.js @@ -5,6 +5,7 @@ const test = require('tape'); const lua = require('../src/lua.js'); const lauxlib = require('../src/lauxlib.js'); const lualib = require('../src/lualib.js'); +const {to_luastring} = require("../src/fengaricore.js"); test('print', function (t) { @@ -20,7 +21,7 @@ test('print', function (t) { lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(luaCode)); lua.lua_call(L, 0, -1); @@ -52,7 +53,7 @@ test('setmetatable, getmetatable', function (t) { lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(luaCode)); lua.lua_call(L, 0, -1); @@ -95,7 +96,7 @@ test('rawequal', function (t) { lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(luaCode)); lua.lua_call(L, 0, -1); @@ -139,7 +140,7 @@ test('rawset, rawget', function (t) { lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(luaCode)); lua.lua_call(L, 0, -1); @@ -184,7 +185,7 @@ test('type', function (t) { lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(luaCode)); lua.lua_call(L, 0, -1); @@ -235,7 +236,7 @@ test('error', function (t) { lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(luaCode)); lua.lua_call(L, 0, -1); @@ -256,7 +257,7 @@ test('error, protected', function (t) { lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(luaCode)); lua.lua_pcall(L, 0, -1, 0); @@ -286,7 +287,7 @@ test('pcall', function (t) { lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(luaCode)); lua.lua_call(L, 0, -1); @@ -320,7 +321,7 @@ test('xpcall', function (t) { lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(luaCode)); lua.lua_call(L, 0, -1); @@ -358,7 +359,7 @@ test('ipairs', function (t) { lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(luaCode)); lua.lua_call(L, 0, -1); @@ -385,7 +386,7 @@ test('select', function (t) { lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(luaCode)); lua.lua_call(L, 0, -1); @@ -428,7 +429,7 @@ test('tonumber', function (t) { lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(luaCode)); lua.lua_call(L, 0, -1); @@ -478,7 +479,7 @@ test('assert', function (t) { lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(luaCode)); lua.lua_pcall(L, 0, -1, 0); @@ -504,7 +505,7 @@ test('rawlen', function (t) { lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(luaCode)); lua.lua_call(L, 0, -1); @@ -549,7 +550,7 @@ test('next', function (t) { lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(luaCode)); lua.lua_call(L, 0, -1); @@ -588,7 +589,7 @@ test('pairs', function (t) { lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(luaCode)); lua.lua_call(L, 0, -1); @@ -636,7 +637,7 @@ test('pairs with __pairs', function (t) { lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(luaCode)); lua.lua_call(L, 0, -1); diff --git a/tests/lcorolib.js b/tests/lcorolib.js index e1868b2..42f9677 100644 --- a/tests/lcorolib.js +++ b/tests/lcorolib.js @@ -6,7 +6,7 @@ const lua = require('../src/lua.js'); const lauxlib = require('../src/lauxlib.js'); const lualib = require('../src/lualib.js'); const lstate = require('../src/lstate.js'); - +const {to_luastring} = require("../src/fengaricore.js"); test('coroutine.create, coroutine.yield, coroutine.resume', function (t) { let luaCode = ` @@ -29,7 +29,7 @@ test('coroutine.create, coroutine.yield, coroutine.resume', function (t) { lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(luaCode)); lua.lua_call(L, 0, -1); @@ -70,7 +70,7 @@ test('coroutine.status', function (t) { lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(luaCode)); lua.lua_call(L, 0, -1); @@ -109,7 +109,7 @@ test('coroutine.isyieldable', function (t) { lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(luaCode)); lua.lua_call(L, 0, -1); @@ -148,7 +148,7 @@ test('coroutine.running', function (t) { lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(luaCode)); lua.lua_call(L, 0, -1); @@ -187,7 +187,7 @@ test('coroutine.wrap', function (t) { lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(luaCode)); lua.lua_call(L, 0, -1); diff --git a/tests/ldblib.js b/tests/ldblib.js index 209e60e..8a30e48 100644 --- a/tests/ldblib.js +++ b/tests/ldblib.js @@ -5,7 +5,7 @@ const test = require('tape'); const lua = require('../src/lua.js'); const lauxlib = require('../src/lauxlib.js'); const lualib = require('../src/lualib.js'); - +const {to_luastring} = require("../src/fengaricore.js"); test('debug.sethook', function (t) { let luaCode = ` @@ -32,7 +32,7 @@ test('debug.sethook', function (t) { lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(luaCode)); }, "Lua program loaded without error"); @@ -75,7 +75,7 @@ test('debug.gethook', function (t) { lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(luaCode)); }, "Lua program loaded without error"); @@ -87,7 +87,7 @@ test('debug.gethook', function (t) { t.deepEqual( lua.lua_typename(L, lua.lua_type(L, -3)), - lua.to_luastring("function"), + to_luastring("function"), "Correct element(s) on the stack" ); @@ -134,7 +134,7 @@ test('debug.getlocal', function (t) { lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(luaCode)); }, "Lua program loaded without error"); @@ -181,7 +181,7 @@ test('debug.setlocal', function (t) { lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(luaCode)); }, "Lua program loaded without error"); @@ -235,7 +235,7 @@ test('debug.upvalueid', function (t) { lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(luaCode)); }, "Lua program loaded without error"); @@ -278,7 +278,7 @@ test('debug.upvaluejoin', function (t) { lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(luaCode)); }, "Lua program loaded without error"); @@ -322,8 +322,8 @@ test('debug.traceback (with a global)', function (t) { lualib.luaL_openlibs(L); - luaCode = lua.to_luastring(luaCode); - lauxlib.luaL_loadbuffer(L, luaCode, luaCode.length, lua.to_luastring("traceback-test")); + luaCode = to_luastring(luaCode); + lauxlib.luaL_loadbuffer(L, luaCode, luaCode.length, to_luastring("traceback-test")); }, "Lua program loaded without error"); @@ -379,8 +379,8 @@ test('debug.traceback (with a upvalue)', function (t) { lualib.luaL_openlibs(L); - luaCode = lua.to_luastring(luaCode); - lauxlib.luaL_loadbuffer(L, luaCode, luaCode.length, lua.to_luastring("traceback-test")); + luaCode = to_luastring(luaCode); + lauxlib.luaL_loadbuffer(L, luaCode, luaCode.length, to_luastring("traceback-test")); }, "Lua program loaded without error"); @@ -431,8 +431,8 @@ test('debug.getinfo', function (t) { lualib.luaL_openlibs(L); - luaCode = lua.to_luastring(luaCode); - lauxlib.luaL_loadbuffer(L, luaCode, luaCode.length, lua.to_luastring("getinfo-test")); + luaCode = to_luastring(luaCode); + lauxlib.luaL_loadbuffer(L, luaCode, luaCode.length, to_luastring("getinfo-test")); }, "Lua program loaded without error"); diff --git a/tests/ldebug.js b/tests/ldebug.js index 857345e..49474e9 100644 --- a/tests/ldebug.js +++ b/tests/ldebug.js @@ -5,6 +5,7 @@ const test = require('tape'); const lua = require('../src/lua.js'); const lauxlib = require('../src/lauxlib.js'); const lualib = require('../src/lualib.js'); +const {to_luastring} = require("../src/fengaricore.js"); test('luaG_typeerror', function (t) { let luaCode = ` @@ -20,7 +21,7 @@ test('luaG_typeerror', function (t) { lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(luaCode)); lua.lua_pcall(L, 0, -1, 0); @@ -48,7 +49,7 @@ test('luaG_typeerror', function (t) { lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(luaCode)); lua.lua_pcall(L, 0, -1, 0); @@ -75,7 +76,7 @@ test('luaG_typeerror', function (t) { lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(luaCode)); lua.lua_pcall(L, 0, -1, 0); @@ -102,7 +103,7 @@ test('luaG_typeerror', function (t) { lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(luaCode)); lua.lua_pcall(L, 0, -1, 0); @@ -128,7 +129,7 @@ test('luaG_concaterror', function (t) { lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(luaCode)); lua.lua_pcall(L, 0, -1, 0); @@ -154,7 +155,7 @@ test('luaG_opinterror', function (t) { lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(luaCode)); lua.lua_pcall(L, 0, -1, 0); @@ -180,7 +181,7 @@ test('luaG_tointerror', function (t) { lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(luaCode)); lua.lua_pcall(L, 0, -1, 0); diff --git a/tests/lexparse.js b/tests/lexparse.js index ca57605..e9087ee 100644 --- a/tests/lexparse.js +++ b/tests/lexparse.js @@ -5,9 +5,8 @@ const test = require('tape'); const lua = require('../src/lua.js'); const lauxlib = require('../src/lauxlib.js'); const lualib = require('../src/lualib.js'); -const lapi = require('../src/lapi.js'); const lstring = require("../src/lstring.js"); - +const {to_luastring} = require("../src/fengaricore.js"); // Roughly the same tests as test/lvm.js to cover all opcodes test('LOADK, RETURN', function (t) { @@ -27,10 +26,10 @@ test('LOADK, RETURN', function (t) { let reader = function(L, data) { let code = luaCode ? luaCode.trim() : null; luaCode = null; - return code ? lua.to_luastring(code) : null; + return code ? to_luastring(code) : null; }; - lua.lua_load(L, reader, luaCode, lua.to_luastring("test"), lua.to_luastring("text")); + lua.lua_load(L, reader, luaCode, to_luastring("test"), to_luastring("text")); }, "Lua program loaded without error"); @@ -67,10 +66,10 @@ test('MOVE', function (t) { let reader = function(L, data) { let code = luaCode ? luaCode.trim() : null; luaCode = null; - return code ? lua.to_luastring(code) : null; + return code ? to_luastring(code) : null; }; - lua.lua_load(L, reader, luaCode, lua.to_luastring("test"), lua.to_luastring("text")); + lua.lua_load(L, reader, luaCode, to_luastring("test"), to_luastring("text")); }, "Lua program loaded without error"); @@ -107,10 +106,10 @@ test('Binary op', function (t) { let reader = function(L, data) { let code = luaCode ? luaCode.trim() : null; luaCode = null; - return code ? lua.to_luastring(code) : null; + return code ? to_luastring(code) : null; }; - lua.lua_load(L, reader, luaCode, lua.to_luastring("test"), lua.to_luastring("text")); + lua.lua_load(L, reader, luaCode, to_luastring("test"), to_luastring("text")); }, "Lua program loaded without error"); @@ -147,10 +146,10 @@ test('Unary op, LOADBOOL', function (t) { let reader = function(L, data) { let code = luaCode ? luaCode.trim() : null; luaCode = null; - return code ? lua.to_luastring(code) : null; + return code ? to_luastring(code) : null; }; - lua.lua_load(L, reader, luaCode, lua.to_luastring("test"), lua.to_luastring("text")); + lua.lua_load(L, reader, luaCode, to_luastring("test"), to_luastring("text")); }, "Lua program loaded without error"); @@ -185,10 +184,10 @@ test('NEWTABLE', function (t) { let reader = function(L, data) { let code = luaCode ? luaCode.trim() : null; luaCode = null; - return code ? lua.to_luastring(code) : null; + return code ? to_luastring(code) : null; }; - lua.lua_load(L, reader, luaCode, lua.to_luastring("test"), lua.to_luastring("text")); + lua.lua_load(L, reader, luaCode, to_luastring("test"), to_luastring("text")); }, "Lua program loaded without error"); @@ -199,7 +198,7 @@ test('NEWTABLE', function (t) { }, "Lua program ran without error"); t.ok( - L.stack[lapi.index2addr_(L, -1)].ttistable(), + lua.lua_type(L, -1) === lua.LUA_TTABLE, "Program output is correct" ); }); @@ -227,10 +226,10 @@ test('CALL', function (t) { let reader = function(L, data) { let code = luaCode ? luaCode.trim() : null; luaCode = null; - return code ? lua.to_luastring(code) : null; + return code ? to_luastring(code) : null; }; - lua.lua_load(L, reader, luaCode, lua.to_luastring("test"), lua.to_luastring("text")); + lua.lua_load(L, reader, luaCode, to_luastring("test"), to_luastring("text")); }, "Lua program loaded without error"); @@ -273,10 +272,10 @@ test('Multiple return', function (t) { let reader = function(L, data) { let code = luaCode ? luaCode.trim() : null; luaCode = null; - return code ? lua.to_luastring(code) : null; + return code ? to_luastring(code) : null; }; - lua.lua_load(L, reader, luaCode, lua.to_luastring("test"), lua.to_luastring("text")); + lua.lua_load(L, reader, luaCode, to_luastring("test"), to_luastring("text")); }, "Lua program loaded without error"); @@ -314,10 +313,10 @@ test('TAILCALL', function (t) { let reader = function(L, data) { let code = luaCode ? luaCode.trim() : null; luaCode = null; - return code ? lua.to_luastring(code) : null; + return code ? to_luastring(code) : null; }; - lua.lua_load(L, reader, luaCode, lua.to_luastring("test"), lua.to_luastring("text")); + lua.lua_load(L, reader, luaCode, to_luastring("test"), to_luastring("text")); }, "Lua program loaded without error"); @@ -355,10 +354,10 @@ test('VARARG', function (t) { let reader = function(L, data) { let code = luaCode ? luaCode.trim() : null; luaCode = null; - return code ? lua.to_luastring(code) : null; + return code ? to_luastring(code) : null; }; - lua.lua_load(L, reader, luaCode, lua.to_luastring("test"), lua.to_luastring("text")); + lua.lua_load(L, reader, luaCode, to_luastring("test"), to_luastring("text")); }, "Lua program loaded without error"); @@ -394,10 +393,10 @@ test('LE, JMP', function (t) { let reader = function(L, data) { let code = luaCode ? luaCode.trim() : null; luaCode = null; - return code ? lua.to_luastring(code) : null; + return code ? to_luastring(code) : null; }; - lua.lua_load(L, reader, luaCode, lua.to_luastring("test"), lua.to_luastring("text")); + lua.lua_load(L, reader, luaCode, to_luastring("test"), to_luastring("text")); }, "Lua program loaded without error"); @@ -433,10 +432,10 @@ test('LT', function (t) { let reader = function(L, data) { let code = luaCode ? luaCode.trim() : null; luaCode = null; - return code ? lua.to_luastring(code) : null; + return code ? to_luastring(code) : null; }; - lua.lua_load(L, reader, luaCode, lua.to_luastring("test"), lua.to_luastring("text")); + lua.lua_load(L, reader, luaCode, to_luastring("test"), to_luastring("text")); }, "Lua program loaded without error"); @@ -472,10 +471,10 @@ test('EQ', function (t) { let reader = function(L, data) { let code = luaCode ? luaCode.trim() : null; luaCode = null; - return code ? lua.to_luastring(code) : null; + return code ? to_luastring(code) : null; }; - lua.lua_load(L, reader, luaCode, lua.to_luastring("test"), lua.to_luastring("text")); + lua.lua_load(L, reader, luaCode, to_luastring("test"), to_luastring("text")); }, "Lua program loaded without error"); @@ -512,10 +511,10 @@ test('TESTSET (and)', function (t) { let reader = function(L, data) { let code = luaCode ? luaCode.trim() : null; luaCode = null; - return code ? lua.to_luastring(code) : null; + return code ? to_luastring(code) : null; }; - lua.lua_load(L, reader, luaCode, lua.to_luastring("test"), lua.to_luastring("text")); + lua.lua_load(L, reader, luaCode, to_luastring("test"), to_luastring("text")); }, "Lua program loaded without error"); @@ -552,10 +551,10 @@ test('TESTSET (or)', function (t) { let reader = function(L, data) { let code = luaCode ? luaCode.trim() : null; luaCode = null; - return code ? lua.to_luastring(code) : null; + return code ? to_luastring(code) : null; }; - lua.lua_load(L, reader, luaCode, lua.to_luastring("test"), lua.to_luastring("text")); + lua.lua_load(L, reader, luaCode, to_luastring("test"), to_luastring("text")); }, "Lua program loaded without error"); @@ -596,10 +595,10 @@ test('TEST (false)', function (t) { let reader = function(L, data) { let code = luaCode ? luaCode.trim() : null; luaCode = null; - return code ? lua.to_luastring(code) : null; + return code ? to_luastring(code) : null; }; - lua.lua_load(L, reader, luaCode, lua.to_luastring("test"), lua.to_luastring("text")); + lua.lua_load(L, reader, luaCode, to_luastring("test"), to_luastring("text")); }, "Lua program loaded without error"); @@ -639,10 +638,10 @@ test('FORPREP, FORLOOP (int)', function (t) { let reader = function(L, data) { let code = luaCode ? luaCode.trim() : null; luaCode = null; - return code ? lua.to_luastring(code) : null; + return code ? to_luastring(code) : null; }; - lua.lua_load(L, reader, luaCode, lua.to_luastring("test"), lua.to_luastring("text")); + lua.lua_load(L, reader, luaCode, to_luastring("test"), to_luastring("text")); }, "Lua program loaded without error"); @@ -682,10 +681,10 @@ test('FORPREP, FORLOOP (float)', function (t) { let reader = function(L, data) { let code = luaCode ? luaCode.trim() : null; luaCode = null; - return code ? lua.to_luastring(code) : null; + return code ? to_luastring(code) : null; }; - lua.lua_load(L, reader, luaCode, lua.to_luastring("test"), lua.to_luastring("text")); + lua.lua_load(L, reader, luaCode, to_luastring("test"), to_luastring("text")); }, "Lua program loaded without error"); @@ -724,10 +723,10 @@ test('SETTABLE, GETTABLE', function (t) { let reader = function(L, data) { let code = luaCode ? luaCode.trim() : null; luaCode = null; - return code ? lua.to_luastring(code) : null; + return code ? to_luastring(code) : null; }; - lua.lua_load(L, reader, luaCode, lua.to_luastring("test"), lua.to_luastring("text")); + lua.lua_load(L, reader, luaCode, to_luastring("test"), to_luastring("text")); }, "Lua program loaded without error"); @@ -744,7 +743,7 @@ test('SETTABLE, GETTABLE', function (t) { ); t.strictEqual( - lua.lua_topointer(L, -1).strong.get(lstring.luaS_hash(lua.to_luastring("two"))).value.jsstring(), + lua.lua_topointer(L, -1).strong.get(lstring.luaS_hash(to_luastring("two"))).value.jsstring(), "world", "Program output is correct" ); @@ -775,10 +774,10 @@ test('SETUPVAL, GETUPVAL', function (t) { let reader = function(L, data) { let code = luaCode ? luaCode.trim() : null; luaCode = null; - return code ? lua.to_luastring(code) : null; + return code ? to_luastring(code) : null; }; - lua.lua_load(L, reader, luaCode, lua.to_luastring("test"), lua.to_luastring("text")); + lua.lua_load(L, reader, luaCode, to_luastring("test"), to_luastring("text")); }, "Lua program loaded without error"); @@ -817,10 +816,10 @@ test('SETTABUP, GETTABUP', function (t) { let reader = function(L, data) { let code = luaCode ? luaCode.trim() : null; luaCode = null; - return code ? lua.to_luastring(code) : null; + return code ? to_luastring(code) : null; }; - lua.lua_load(L, reader, luaCode, lua.to_luastring("test"), lua.to_luastring("text")); + lua.lua_load(L, reader, luaCode, to_luastring("test"), to_luastring("text")); }, "Lua program loaded without error"); @@ -837,7 +836,7 @@ test('SETTABUP, GETTABUP', function (t) { ); t.strictEqual( - lua.lua_topointer(L, -1).strong.get(lstring.luaS_hash(lua.to_luastring("two"))).value.jsstring(), + lua.lua_topointer(L, -1).strong.get(lstring.luaS_hash(to_luastring("two"))).value.jsstring(), "world", "Program output is correct" ); @@ -867,10 +866,10 @@ test('SELF', function (t) { let reader = function(L, data) { let code = luaCode ? luaCode.trim() : null; luaCode = null; - return code ? lua.to_luastring(code) : null; + return code ? to_luastring(code) : null; }; - lua.lua_load(L, reader, luaCode, lua.to_luastring("test"), lua.to_luastring("text")); + lua.lua_load(L, reader, luaCode, to_luastring("test"), to_luastring("text")); }, "Lua program loaded without error"); @@ -906,10 +905,10 @@ test('SETLIST', function (t) { let reader = function(L, data) { let code = luaCode ? luaCode.trim() : null; luaCode = null; - return code ? lua.to_luastring(code) : null; + return code ? to_luastring(code) : null; }; - lua.lua_load(L, reader, luaCode, lua.to_luastring("test"), lua.to_luastring("text")); + lua.lua_load(L, reader, luaCode, to_luastring("test"), to_luastring("text")); }, "Lua program loaded without error"); @@ -949,10 +948,10 @@ test('Variable SETLIST', function (t) { let reader = function(L, data) { let code = luaCode ? luaCode.trim() : null; luaCode = null; - return code ? lua.to_luastring(code) : null; + return code ? to_luastring(code) : null; }; - lua.lua_load(L, reader, luaCode, lua.to_luastring("test"), lua.to_luastring("text")); + lua.lua_load(L, reader, luaCode, to_luastring("test"), to_luastring("text")); }, "Lua program loaded without error"); @@ -987,10 +986,10 @@ test('Long SETLIST', function (t) { let reader = function(L, data) { let code = luaCode ? luaCode.trim() : null; luaCode = null; - return code ? lua.to_luastring(code) : null; + return code ? to_luastring(code) : null; }; - lua.lua_load(L, reader, luaCode, lua.to_luastring("test"), lua.to_luastring("text")); + lua.lua_load(L, reader, luaCode, to_luastring("test"), to_luastring("text")); }, "Lua program loaded without error"); @@ -1042,10 +1041,10 @@ test('TFORCALL, TFORLOOP', function (t) { let reader = function(L, data) { let code = luaCode ? luaCode.trim() : null; luaCode = null; - return code ? lua.to_luastring(code) : null; + return code ? to_luastring(code) : null; }; - lua.lua_load(L, reader, luaCode, lua.to_luastring("test"), lua.to_luastring("text")); + lua.lua_load(L, reader, luaCode, to_luastring("test"), to_luastring("text")); }, "Lua program loaded without error"); @@ -1083,10 +1082,10 @@ test('LEN', function (t) { let reader = function(L, data) { let code = luaCode ? luaCode.trim() : null; luaCode = null; - return code ? lua.to_luastring(code) : null; + return code ? to_luastring(code) : null; }; - lua.lua_load(L, reader, luaCode, lua.to_luastring("test"), lua.to_luastring("text")); + lua.lua_load(L, reader, luaCode, to_luastring("test"), to_luastring("text")); }, "Lua program loaded without error"); @@ -1132,10 +1131,10 @@ test('CONCAT', function (t) { let reader = function(L, data) { let code = luaCode ? luaCode.trim() : null; luaCode = null; - return code ? lua.to_luastring(code) : null; + return code ? to_luastring(code) : null; }; - lua.lua_load(L, reader, luaCode, lua.to_luastring("test"), lua.to_luastring("text")); + lua.lua_load(L, reader, luaCode, to_luastring("test"), to_luastring("text")); }, "Lua program loaded without error"); diff --git a/tests/lmathlib.js b/tests/lmathlib.js index a06812c..b50c59c 100644 --- a/tests/lmathlib.js +++ b/tests/lmathlib.js @@ -5,7 +5,7 @@ const test = require('tape'); const lua = require('../src/lua.js'); const lauxlib = require('../src/lauxlib.js'); const lualib = require('../src/lualib.js'); - +const {to_luastring} = require("../src/fengaricore.js"); test('math.abs, math.sin, math.cos, math.tan, math.asin, math.acos, math.atan', function (t) { let luaCode = ` @@ -21,7 +21,7 @@ test('math.abs, math.sin, math.cos, math.tan, math.asin, math.acos, math.atan', lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(luaCode)); lua.lua_call(L, 0, -1); @@ -84,7 +84,7 @@ test('math.ceil, math.floor', function (t) { lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(luaCode)); lua.lua_call(L, 0, -1); @@ -117,7 +117,7 @@ test('math.deg, math.rad', function (t) { lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(luaCode)); lua.lua_call(L, 0, -1); @@ -150,7 +150,7 @@ test('math.log', function (t) { lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(luaCode)); lua.lua_call(L, 0, -1); @@ -189,7 +189,7 @@ test('math.exp', function (t) { lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(luaCode)); lua.lua_call(L, 0, -1); @@ -216,7 +216,7 @@ test('math.min, math.max', function (t) { lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(luaCode)); lua.lua_call(L, 0, -1); @@ -249,7 +249,7 @@ test('math.random', function (t) { lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(luaCode)); lua.lua_call(L, 0, -1); @@ -280,7 +280,7 @@ test('math.sqrt', function (t) { lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(luaCode)); lua.lua_call(L, 0, -1); @@ -307,7 +307,7 @@ test('math.tointeger', function (t) { lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(luaCode)); lua.lua_call(L, 0, -1); @@ -334,7 +334,7 @@ test('math.type', function (t) { lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(luaCode)); lua.lua_call(L, 0, -1); @@ -373,7 +373,7 @@ test('math.ult', function (t) { lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(luaCode)); lua.lua_call(L, 0, -1); @@ -400,7 +400,7 @@ test('math.fmod', function (t) { lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(luaCode)); lua.lua_call(L, 0, -1); @@ -427,7 +427,7 @@ test('math.modf', function (t) { lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(luaCode)); lua.lua_call(L, 0, -1); diff --git a/tests/load.js b/tests/load.js index 49756a5..8555014 100644 --- a/tests/load.js +++ b/tests/load.js @@ -8,7 +8,7 @@ const toByteCode = tests.toByteCode; const lua = require('../src/lua.js'); const lauxlib = require('../src/lauxlib.js'); const lualib = require('../src/lualib.js'); - +const {to_luastring} = require("../src/fengaricore.js"); test('luaL_loadstring', function (t) { let luaCode = ` @@ -24,7 +24,7 @@ test('luaL_loadstring', function (t) { lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(luaCode)); }, "Lua program loaded without error"); @@ -56,7 +56,7 @@ test('load', function (t) { lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(luaCode)); }, "Lua program loaded without error"); @@ -90,7 +90,7 @@ test('luaL_loadbuffer', function (t) { lualib.luaL_openlibs(L); - lauxlib.luaL_loadbuffer(L, bc, null, lua.to_luastring("test")); + lauxlib.luaL_loadbuffer(L, bc, null, to_luastring("test")); }, "Lua program loaded without error"); @@ -122,7 +122,7 @@ test('loadfile', function (t) { lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(luaCode)); }, "Lua program loaded without error"); @@ -154,7 +154,7 @@ test('loadfile (binary)', function (t) { lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(luaCode)); }, "Lua program loaded without error"); @@ -185,7 +185,7 @@ test('dofile', function (t) { lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(luaCode)); }, "Lua program loaded without error"); diff --git a/tests/loadlib.js b/tests/loadlib.js index c4c98ea..dba2a3a 100644 --- a/tests/loadlib.js +++ b/tests/loadlib.js @@ -5,7 +5,7 @@ const test = require('tape'); const lua = require('../src/lua.js'); const lauxlib = require('../src/lauxlib.js'); const lualib = require('../src/lualib.js'); - +const {to_luastring} = require("../src/fengaricore.js"); test('require an existing module', function (t) { let luaCode = ` @@ -20,7 +20,7 @@ test('require an existing module', function (t) { lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(luaCode)); }, "Lua program loaded without error"); @@ -50,7 +50,7 @@ test('require a file', function (t) { lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(luaCode)); }, "Lua program loaded without error"); @@ -81,7 +81,7 @@ test('package.loadlib', function (t) { lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(luaCode)); }, "Lua program loaded without error"); @@ -112,7 +112,7 @@ test('package.searchpath', function (t) { lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(luaCode)); }, "Lua program loaded without error"); diff --git a/tests/loslib.js b/tests/loslib.js index 83d6c81..904ca9c 100644 --- a/tests/loslib.js +++ b/tests/loslib.js @@ -5,7 +5,7 @@ const test = require('tape'); const lua = require('../src/lua.js'); const lauxlib = require('../src/lauxlib.js'); const lualib = require('../src/lualib.js'); - +const {to_luastring} = require("../src/fengaricore.js"); test('os.time', function (t) { let luaCode = ` @@ -20,7 +20,7 @@ test('os.time', function (t) { lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(luaCode)); }, "Lua program loaded without error"); @@ -54,7 +54,7 @@ test('os.time (with format)', function (t) { lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(luaCode)); }, "Lua program loaded without error"); @@ -87,7 +87,7 @@ test('os.difftime', function (t) { lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(luaCode)); }, "Lua program loaded without error"); @@ -121,7 +121,7 @@ test('os.date', function (t) { lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(luaCode)); }, "Lua program loaded without error"); @@ -152,7 +152,7 @@ test('os.getenv', function (t) { lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(luaCode)); }, "Lua program loaded without error"); diff --git a/tests/lstrlib.js b/tests/lstrlib.js index bdf68d8..50e9996 100644 --- a/tests/lstrlib.js +++ b/tests/lstrlib.js @@ -5,7 +5,7 @@ const test = require('tape'); const lua = require('../src/lua.js'); const lauxlib = require('../src/lauxlib.js'); const lualib = require('../src/lualib.js'); - +const {to_luastring} = require("../src/fengaricore.js"); test('string.len', function (t) { let luaCode = ` @@ -21,7 +21,7 @@ test('string.len', function (t) { lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(luaCode)); }, "Lua program loaded without error"); @@ -59,7 +59,7 @@ test('string.char', function (t) { lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(luaCode)); }, "Lua program loaded without error"); @@ -90,7 +90,7 @@ test('string.upper, string.lower', function (t) { lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(luaCode)); }, "Lua program loaded without error"); @@ -127,7 +127,7 @@ test('string.rep', function (t) { lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(luaCode)); }, "Lua program loaded without error"); @@ -158,7 +158,7 @@ test('string.reverse', function (t) { lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(luaCode)); }, "Lua program loaded without error"); @@ -189,7 +189,7 @@ test('string.byte', function (t) { lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(luaCode)); }, "Lua program loaded without error"); @@ -232,7 +232,7 @@ test('string.format', function (t) { lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(luaCode)); }, "Lua program loaded without error"); @@ -263,7 +263,7 @@ test('string.format', function (t) { lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(luaCode)); }, "Lua program loaded without error"); @@ -294,7 +294,7 @@ test('string.format', function (t) { lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(luaCode)); }, "Lua program loaded without error"); @@ -335,7 +335,7 @@ test('string.sub', function (t) { lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(luaCode)); }, "Lua program loaded without error"); @@ -434,7 +434,7 @@ test('string.dump', function (t) { lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(luaCode.trim())); + lauxlib.luaL_loadstring(L, to_luastring(luaCode.trim())); }, "Lua program loaded without error"); @@ -444,7 +444,7 @@ test('string.dump', function (t) { let str = lua.lua_tostring(L, -1); - lua.lua_load(L, function(L, s) { let r = s.str; s.str = null; return r; }, {str: str}, lua.to_luastring("test"), lua.to_luastring("binary")); + lua.lua_load(L, function(L, s) { let r = s.str; s.str = null; return r; }, {str: str}, to_luastring("test"), to_luastring("binary")); lua.lua_call(L, 0, -1); @@ -474,7 +474,7 @@ test('string.pack/unpack/packsize', function (t) { lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(luaCode)); }, "Lua program loaded without error"); @@ -510,7 +510,7 @@ test('string.find without pattern', function (t) { lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(luaCode)); }, "Lua program loaded without error"); @@ -547,7 +547,7 @@ test('string.match', function (t) { lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(luaCode)); }, "Lua program loaded without error"); @@ -584,7 +584,7 @@ test('string.find', function (t) { lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(luaCode)); }, "Lua program loaded without error"); @@ -640,7 +640,7 @@ test('string.gmatch', function (t) { lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(luaCode)); }, "Lua program loaded without error"); @@ -689,7 +689,7 @@ test('string.gsub', function (t) { lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(luaCode)); }, "Lua program loaded without error"); @@ -726,7 +726,7 @@ test('string.gsub (number)', function (t) { lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(luaCode)); }, "Lua program loaded without error"); @@ -763,7 +763,7 @@ test('string.gsub (pattern)', function (t) { lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(luaCode)); }, "Lua program loaded without error"); @@ -802,7 +802,7 @@ test('string.gsub (function)', function (t) { lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(luaCode)); }, "Lua program loaded without error"); @@ -841,7 +841,7 @@ test('string.gsub (table)', function (t) { lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(luaCode)); }, "Lua program loaded without error"); diff --git a/tests/ltablib.js b/tests/ltablib.js index 2adf1fe..660ac85 100644 --- a/tests/ltablib.js +++ b/tests/ltablib.js @@ -5,7 +5,7 @@ const test = require('tape'); const lua = require('../src/lua.js'); const lauxlib = require('../src/lauxlib.js'); const lualib = require('../src/lualib.js'); - +const {to_luastring} = require("../src/fengaricore.js"); const inttable2array = function(t) { let a = []; @@ -31,7 +31,7 @@ test('table.concat', function (t) { lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(luaCode)); lua.lua_call(L, 0, -1); @@ -58,7 +58,7 @@ test('table.pack', function (t) { lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(luaCode)); lua.lua_call(L, 0, -1); @@ -87,7 +87,7 @@ test('table.unpack', function (t) { lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(luaCode)); lua.lua_call(L, 0, -1); @@ -129,7 +129,7 @@ test('table.insert', function (t) { lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(luaCode)); lua.lua_call(L, 0, -1); @@ -161,7 +161,7 @@ test('table.remove', function (t) { lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(luaCode)); lua.lua_call(L, 0, -1); @@ -192,7 +192,7 @@ test('table.move', function (t) { lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(luaCode)); lua.lua_call(L, 0, -1); @@ -223,7 +223,7 @@ test('table.sort (<)', function (t) { lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(luaCode)); lua.lua_call(L, 0, -1); @@ -254,7 +254,7 @@ test('table.sort with cmp function', function (t) { lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(luaCode)); lua.lua_call(L, 0, -1); diff --git a/tests/ltm.js b/tests/ltm.js index 0d9bc1a..156d63b 100644 --- a/tests/ltm.js +++ b/tests/ltm.js @@ -5,7 +5,7 @@ const test = require('tape'); const lua = require('../src/lua.js'); const lauxlib = require('../src/lauxlib.js'); const lualib = require('../src/lualib.js'); - +const {to_luastring} = require("../src/fengaricore.js"); test('__index, __newindex: with actual table', function (t) { let luaCode = ` @@ -20,7 +20,7 @@ test('__index, __newindex: with actual table', function (t) { lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(luaCode)); lua.lua_call(L, 0, -1); }, "Program executed without errors"); @@ -50,7 +50,7 @@ test('__newindex: with non table', function (t) { lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(luaCode)); }, "Bytecode parsed without errors"); t.throws(function () { @@ -81,7 +81,7 @@ test('__index function in metatable', function (t) { lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(luaCode)); }, "Bytecode parsed without errors"); @@ -121,7 +121,7 @@ test('__newindex function in metatable', function (t) { lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(luaCode)); }, "Bytecode parsed without errors"); t.doesNotThrow(function () { @@ -159,7 +159,7 @@ test('__index table in metatable', function (t) { lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(luaCode)); }, "Bytecode parsed without errors"); t.doesNotThrow(function () { @@ -200,7 +200,7 @@ test('__newindex table in metatable', function (t) { lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(luaCode)); }, "Bytecode parsed without errors"); t.doesNotThrow(function () { @@ -252,7 +252,7 @@ test('__index table with own metatable', function (t) { lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(luaCode)); }, "Bytecode parsed without errors"); t.doesNotThrow(function () { @@ -303,7 +303,7 @@ test('__newindex table with own metatable', function (t) { lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(luaCode)); }, "Bytecode parsed without errors"); t.doesNotThrow(function () { @@ -402,7 +402,7 @@ test('binary __xxx functions in metatable', function (t) { lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(luaCode)); }, "Bytecode parsed without errors"); t.doesNotThrow(function () { @@ -452,7 +452,7 @@ test('__eq', function (t) { lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(luaCode)); }, "Bytecode parsed without errors"); t.doesNotThrow(function () { @@ -488,7 +488,7 @@ test('__lt', function (t) { lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(luaCode)); }, "Bytecode parsed without errors"); t.doesNotThrow(function () { @@ -524,7 +524,7 @@ test('__le', function (t) { lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(luaCode)); }, "Bytecode parsed without errors"); t.doesNotThrow(function () { @@ -560,7 +560,7 @@ test('__le that uses __lt', function (t) { lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(luaCode)); }, "Bytecode parsed without errors"); t.doesNotThrow(function () { @@ -600,7 +600,7 @@ test('__unm, __bnot', function (t) { lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(luaCode)); }, "Bytecode parsed without errors"); t.doesNotThrow(function () { @@ -643,7 +643,7 @@ test('__len', function (t) { lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(luaCode)); }, "Bytecode parsed without errors"); t.doesNotThrow(function () { @@ -680,7 +680,7 @@ test('__concat', function (t) { lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(luaCode)); }, "Bytecode parsed without errors"); t.doesNotThrow(function () { @@ -717,7 +717,7 @@ test('__call', function (t) { lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(luaCode)); }, "Bytecode parsed without errors"); t.doesNotThrow(function () { diff --git a/tests/lua.js b/tests/lua.js index 82df6ff..0d9cf2e 100644 --- a/tests/lua.js +++ b/tests/lua.js @@ -5,8 +5,7 @@ const test = require('tape'); const lua = require('../src/lua.js'); const lauxlib = require('../src/lauxlib.js'); const lualib = require('../src/lualib.js'); -const lapi = require('../src/lapi.js'); - +const {to_luastring} = require("../src/fengaricore.js"); // TODO: remove test.skip('locals.lua', function (t) { @@ -24,13 +23,13 @@ test.skip('locals.lua', function (t) { lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(luaCode)); }, "Lua program loaded without error"); t.doesNotThrow(function () { - lapi.lua_call(L, 0, -1); + lua.lua_call(L, 0, -1); }, "Lua program ran without error"); }); @@ -51,13 +50,13 @@ test.skip('constructs.lua', function (t) { lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(luaCode)); }, "Lua program loaded without error"); t.doesNotThrow(function () { - lapi.lua_call(L, 0, -1); + lua.lua_call(L, 0, -1); }, "Lua program ran without error"); }); @@ -76,13 +75,13 @@ test.skip('strings.lua', function (t) { lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(luaCode)); }, "Lua program loaded without error"); t.doesNotThrow(function () { - lapi.lua_call(L, 0, -1); + lua.lua_call(L, 0, -1); }, "Lua program ran without error"); }); diff --git a/tests/lutf8lib.js b/tests/lutf8lib.js index ae40d3c..baccceb 100644 --- a/tests/lutf8lib.js +++ b/tests/lutf8lib.js @@ -5,6 +5,7 @@ const test = require('tape'); const lua = require("../src/lua.js"); const lauxlib = require("../src/lauxlib.js"); const lualib = require("../src/lualib.js"); +const {to_luastring} = require("../src/fengaricore.js"); test('utf8.offset', function (t) { let luaCode = ` @@ -19,7 +20,7 @@ test('utf8.offset', function (t) { lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(luaCode)); }, "Lua program loaded without error"); @@ -50,7 +51,7 @@ test('utf8.codepoint', function (t) { lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(luaCode)); }, "Lua program loaded without error"); @@ -93,7 +94,7 @@ test('utf8.char', function (t) { lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(luaCode)); }, "Lua program loaded without error"); @@ -124,7 +125,7 @@ test('utf8.len', function (t) { lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(luaCode)); }, "Lua program loaded without error"); @@ -160,7 +161,7 @@ test('utf8.codes', function (t) { lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(luaCode)); }, "Lua program loaded without error"); diff --git a/tests/lvm.js b/tests/lvm.js index 08c0c5e..7fba553 100644 --- a/tests/lvm.js +++ b/tests/lvm.js @@ -4,6 +4,7 @@ const test = require('tape'); const lua = require("../src/lua.js"); const lstring = require("../src/lstring.js"); +const {to_luastring} = require("../src/fengaricore.js"); const getState = require("./tests.js").getState; @@ -459,7 +460,7 @@ test('SETTABLE, GETTABLE', function (t) { ); t.deepEqual( - L.stack[L.top - 1].value.strong.get(lstring.luaS_hash(lua.to_luastring("two"))).value.jsstring(), // "two" + L.stack[L.top - 1].value.strong.get(lstring.luaS_hash(to_luastring("two"))).value.jsstring(), // "two" "world", "Program output is correct" ); @@ -518,7 +519,7 @@ test('SETTABUP, GETTABUP', function (t) { ); t.deepEqual( - L.stack[L.top - 1].value.strong.get(lstring.luaS_hash(lua.to_luastring("two"))).value.jsstring(), // "two" + L.stack[L.top - 1].value.strong.get(lstring.luaS_hash(to_luastring("two"))).value.jsstring(), // "two" "world", // "world" "Program output is correct" ); diff --git a/tests/manual-tests/debug-cli.js b/tests/manual-tests/debug-cli.js index 3feb981..dc49a0e 100755 --- a/tests/manual-tests/debug-cli.js +++ b/tests/manual-tests/debug-cli.js @@ -4,6 +4,7 @@ const lua = require('../../src/lua.js'); const lauxlib = require('../../src/lauxlib.js'); const lualib = require('../../src/lualib.js'); +const {to_luastring} = require("../../src/fengaricore.js"); let luaCode = ` a = "debug me" @@ -14,6 +15,6 @@ L = lauxlib.luaL_newstate(); lualib.luaL_openlibs(L); -lauxlib.luaL_loadstring(L, lua.to_luastring(luaCode)); +lauxlib.luaL_loadstring(L, to_luastring(luaCode)); lua.lua_call(L, 0, 0); diff --git a/tests/test-suite/api.js b/tests/test-suite/api.js index b5f45c3..0061c88 100644 --- a/tests/test-suite/api.js +++ b/tests/test-suite/api.js @@ -5,6 +5,7 @@ const test = require('tape'); const lua = require('../../src/lua.js'); const lauxlib = require('../../src/lauxlib.js'); const lualib = require('../../src/lualib.js'); +const {to_luastring} = require("../../src/fengaricore.js"); const ltests = require('./ltests.js'); @@ -32,7 +33,7 @@ test("[test-suite] api: registry", function (t) { a = T.testC("pushvalue R; return 1") assert(a == debug.getregistry()) `, L; - + t.plan(2); t.doesNotThrow(function () { @@ -43,7 +44,7 @@ test("[test-suite] api: registry", function (t) { ltests.luaopen_tests(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(prefix + luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(prefix + luaCode)); }, "Lua program loaded without error"); @@ -62,7 +63,7 @@ test("[test-suite] api: absindex", function (t) { assert(T.testC("settop 10; absindex 1; return 1") == 1) assert(T.testC("settop 10; absindex R; return 1") < -10) `, L; - + t.plan(2); t.doesNotThrow(function () { @@ -73,7 +74,7 @@ test("[test-suite] api: absindex", function (t) { ltests.luaopen_tests(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(prefix + luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(prefix + luaCode)); }, "Lua program loaded without error"); @@ -99,7 +100,7 @@ test("[test-suite] api: testing alignment", function (t) { a,b,c = f() assert(a == 2 and b == 3 and not c) `, L; - + t.plan(2); t.doesNotThrow(function () { @@ -110,7 +111,7 @@ test("[test-suite] api: testing alignment", function (t) { ltests.luaopen_tests(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(prefix + luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(prefix + luaCode)); }, "Lua program loaded without error"); @@ -164,7 +165,7 @@ test("[test-suite] api: test that all trues are equal", function (t) { t = pack(T.testC("copy -3 -1; return *", 2, 3, 4, 5)) tcheck(t, {n=4,2,3,4,3}) `, L; - + t.plan(2); t.doesNotThrow(function () { @@ -175,7 +176,7 @@ test("[test-suite] api: test that all trues are equal", function (t) { ltests.luaopen_tests(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(prefix + luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(prefix + luaCode)); }, "Lua program loaded without error"); @@ -212,7 +213,7 @@ test("[test-suite] api: testing 'rotate'", function (t) { tcheck(t, {10, 20, 30, 40}) end `, L; - + t.plan(2); t.doesNotThrow(function () { @@ -223,7 +224,7 @@ test("[test-suite] api: testing 'rotate'", function (t) { ltests.luaopen_tests(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(prefix + luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(prefix + luaCode)); }, "Lua program loaded without error"); @@ -265,7 +266,7 @@ test("[test-suite] api: testing non-function message handlers", function (t) { t = pack(T.testC("concat 5; return *", "alo", 2, 3, "joao", 12)) tcheck(t, {n=1,"alo23joao12"}) `, L; - + t.plan(2); t.doesNotThrow(function () { @@ -276,7 +277,7 @@ test("[test-suite] api: testing non-function message handlers", function (t) { ltests.luaopen_tests(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(prefix + luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(prefix + luaCode)); }, "Lua program loaded without error"); @@ -294,7 +295,7 @@ test("[test-suite] api: testing MULTRET", function (t) { function (a,b) return 1,2,3,4,a,b end, "alo", "joao")) tcheck(t, {n=6,1,2,3,4,"alo", "joao"}) `, L; - + t.plan(2); t.doesNotThrow(function () { @@ -305,7 +306,7 @@ test("[test-suite] api: testing MULTRET", function (t) { ltests.luaopen_tests(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(prefix + luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(prefix + luaCode)); }, "Lua program loaded without error"); @@ -327,7 +328,7 @@ test("[test-suite] api: test returning more results than fit in the caller stack assert(b == "10") end `, L; - + t.plan(2); t.doesNotThrow(function () { @@ -338,7 +339,7 @@ test("[test-suite] api: test returning more results than fit in the caller stack ltests.luaopen_tests(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(prefix + luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(prefix + luaCode)); }, "Lua program loaded without error"); @@ -362,7 +363,7 @@ test("[test-suite] api: testing globals", function (t) { ]]} assert(a[2] == 14 and a[3] == "a31" and a[4] == nil and _G.a == "a31") `, L; - + t.plan(2); t.doesNotThrow(function () { @@ -373,7 +374,7 @@ test("[test-suite] api: testing globals", function (t) { ltests.luaopen_tests(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(prefix + luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(prefix + luaCode)); }, "Lua program loaded without error"); @@ -420,7 +421,7 @@ test("[test-suite] api: testing arith", function (t) { assert(T.testC("arith _; arith +; arith %; return 1", b, a, c)[1] == 8 % (4 + (-3)*2)) `, L; - + t.plan(2); t.doesNotThrow(function () { @@ -431,7 +432,7 @@ test("[test-suite] api: testing arith", function (t) { ltests.luaopen_tests(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(prefix + luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(prefix + luaCode)); }, "Lua program loaded without error"); @@ -448,7 +449,7 @@ test("[test-suite] api: errors in arithmetic", function (t) { checkerr("divide by zero", T.testC, "arith \\\\", 10, 0) checkerr("%%0", T.testC, "arith %", 10, 0) `, L; - + t.plan(2); t.doesNotThrow(function () { @@ -459,7 +460,7 @@ test("[test-suite] api: errors in arithmetic", function (t) { ltests.luaopen_tests(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(prefix + luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(prefix + luaCode)); }, "Lua program loaded without error"); @@ -481,7 +482,7 @@ test("[test-suite] api: testing lessthan and lessequal", function (t) { assert(not T.testC("compare LT 2 -3, return 1", "4", "2", "2", "3", "2", "2")) assert(not T.testC("compare LT -3 2, return 1", "3", "2", "2", "4", "2", "2")) `, L; - + t.plan(2); t.doesNotThrow(function () { @@ -492,7 +493,7 @@ test("[test-suite] api: testing lessthan and lessequal", function (t) { ltests.luaopen_tests(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(prefix + luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(prefix + luaCode)); }, "Lua program loaded without error"); @@ -524,7 +525,7 @@ test("[test-suite] api: non-valid indices produce false", function (t) { a,b = T.testC("compare LE 5 -6, return 2", a1, 2, 2, a1, 2, 20) assert(a == 20 and b == true) `, L; - + t.plan(2); t.doesNotThrow(function () { @@ -535,7 +536,7 @@ test("[test-suite] api: non-valid indices produce false", function (t) { ltests.luaopen_tests(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(prefix + luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(prefix + luaCode)); }, "Lua program loaded without error"); @@ -575,7 +576,7 @@ test("[test-suite] api: testing length", function (t) { ]], t) assert(a == print and c == 1) `, L; - + t.plan(2); t.doesNotThrow(function () { @@ -586,7 +587,7 @@ test("[test-suite] api: testing length", function (t) { ltests.luaopen_tests(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(prefix + luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(prefix + luaCode)); }, "Lua program loaded without error"); @@ -617,7 +618,7 @@ test("[test-suite] api: testing __concat", function (t) { -- concat with 1 element assert(T.testC("concat 1; return 1", "xuxu") == "xuxu") `, L; - + t.plan(2); t.doesNotThrow(function () { @@ -628,7 +629,7 @@ test("[test-suite] api: testing __concat", function (t) { ltests.luaopen_tests(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(prefix + luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(prefix + luaCode)); }, "Lua program loaded without error"); @@ -672,7 +673,7 @@ test("[test-suite] api: testing lua_is", function (t) { assert(count(io.stdin) == 1) assert(count(nil, 15) == 100) `, L; - + t.plan(2); t.doesNotThrow(function () { @@ -683,7 +684,7 @@ test("[test-suite] api: testing lua_is", function (t) { ltests.luaopen_tests(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(prefix + luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(prefix + luaCode)); }, "Lua program loaded without error"); @@ -733,7 +734,7 @@ test("[test-suite] api: testing lua_to...", function (t) { a = to("tocfunction", math.deg) assert(a(3) == math.deg(3) and a == math.deg) `, L; - + t.plan(2); t.doesNotThrow(function () { @@ -744,7 +745,7 @@ test("[test-suite] api: testing lua_to...", function (t) { ltests.luaopen_tests(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(prefix + luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(prefix + luaCode)); }, "Lua program loaded without error"); @@ -771,7 +772,7 @@ test("[test-suite] api: testing panic function", function (t) { -- "argerror" without frames assert(T.checkpanic("loadstring 4") == "bad argument #4 (string expected, got no value)") - + --[[ TODO: T.totalmem -- memory error @@ -792,7 +793,7 @@ test("[test-suite] api: testing panic function", function (t) { end `, L; - + t.plan(2); t.doesNotThrow(function () { @@ -803,7 +804,7 @@ test("[test-suite] api: testing panic function", function (t) { ltests.luaopen_tests(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(luaCode)); }, "Lua program loaded without error"); @@ -848,7 +849,7 @@ test("[test-suite] api: testing deep JS stack", { skip: true }, function (t) { assert(next(t) == nil) prog, g, t = nil `, L; - + t.plan(2); t.doesNotThrow(function () { @@ -859,7 +860,7 @@ test("[test-suite] api: testing deep JS stack", { skip: true }, function (t) { ltests.luaopen_tests(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(prefix + luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(prefix + luaCode)); }, "Lua program loaded without error"); @@ -891,7 +892,7 @@ test("[test-suite] api: testing errors", function (t) { check3("%.", T.testC("loadfile 2; return *", ".")) check3("xxxx", T.testC("loadfile 2; return *", "xxxx")) `, L; - + t.plan(2); t.doesNotThrow(function () { @@ -902,7 +903,7 @@ test("[test-suite] api: testing errors", function (t) { ltests.luaopen_tests(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(prefix + luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(prefix + luaCode)); }, "Lua program loaded without error"); @@ -929,7 +930,7 @@ test("[test-suite] api: test errors in non protected threads", { skip: true }, f checkerrnopro("getglobal 'f'; call 0 0;", "stack overflow") end `, L; - + t.plan(2); t.doesNotThrow(function () { @@ -940,7 +941,7 @@ test("[test-suite] api: test errors in non protected threads", { skip: true }, f ltests.luaopen_tests(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(prefix + luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(prefix + luaCode)); }, "Lua program loaded without error"); @@ -992,7 +993,7 @@ test("[test-suite] api: testing table access", function (t) { assert(a[b] == 19) `, L; - + t.plan(2); t.doesNotThrow(function () { @@ -1003,7 +1004,7 @@ test("[test-suite] api: testing table access", function (t) { ltests.luaopen_tests(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(prefix + luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(prefix + luaCode)); }, "Lua program loaded without error"); @@ -1032,7 +1033,7 @@ test("[test-suite] api: testing getfield/setfield with long keys", function (t) _012345678901234567890123456789012345678901234567890123456789 = nil end `, L; - + t.plan(2); t.doesNotThrow(function () { @@ -1043,7 +1044,7 @@ test("[test-suite] api: testing getfield/setfield with long keys", function (t) ltests.luaopen_tests(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(prefix + luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(prefix + luaCode)); }, "Lua program loaded without error"); @@ -1066,7 +1067,7 @@ test("[test-suite] api: testing next", function (t) { t = pack(T.testC("next; pop 1; next; return *", a, nil)) tcheck(t, {n=1,a}) `, L; - + t.plan(2); t.doesNotThrow(function () { @@ -1077,7 +1078,7 @@ test("[test-suite] api: testing next", function (t) { ltests.luaopen_tests(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(prefix + luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(prefix + luaCode)); }, "Lua program loaded without error"); @@ -1106,7 +1107,7 @@ test("[test-suite] api: testing upvalues", function (t) { -- T.checkmemory() end `, L; - + t.plan(2); t.doesNotThrow(function () { @@ -1117,7 +1118,7 @@ test("[test-suite] api: testing upvalues", function (t) { ltests.luaopen_tests(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(prefix + luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(prefix + luaCode)); }, "Lua program loaded without error"); @@ -1142,7 +1143,7 @@ test("[test-suite] api: testing absent upvalues from JS-function pointers", func T.upvalue(f, 2, "xuxu") assert(T.upvalue(f, 2) == "xuxu") `, L; - + t.plan(2); t.doesNotThrow(function () { @@ -1153,7 +1154,7 @@ test("[test-suite] api: testing absent upvalues from JS-function pointers", func ltests.luaopen_tests(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(prefix + luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(prefix + luaCode)); }, "Lua program loaded without error"); @@ -1179,7 +1180,7 @@ test("[test-suite] api: large closures", function (t) { assert(not A("isnil U256; return 1")) end `, L; - + t.plan(2); t.doesNotThrow(function () { @@ -1190,7 +1191,7 @@ test("[test-suite] api: large closures", function (t) { ltests.luaopen_tests(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(prefix + luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(prefix + luaCode)); }, "Lua program loaded without error"); @@ -1226,7 +1227,7 @@ test("[test-suite] api: testing get/setuservalue", function (t) { -- collectgarbage() -- number should not be a problem for collector assert(debug.getuservalue(b) == 134) `, L; - + t.plan(2); t.doesNotThrow(function () { @@ -1237,7 +1238,7 @@ test("[test-suite] api: testing get/setuservalue", function (t) { ltests.luaopen_tests(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(prefix + luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(prefix + luaCode)); }, "Lua program loaded without error"); @@ -1257,7 +1258,7 @@ test("[test-suite] api: testing get/setuservalue", { skip: true }, function (t) T.gcstate("pause") -- complete collection assert(debug.getuservalue(b).x == 100) -- uvalue should be there `, L; - + t.plan(2); t.doesNotThrow(function () { @@ -1268,7 +1269,7 @@ test("[test-suite] api: testing get/setuservalue", { skip: true }, function (t) ltests.luaopen_tests(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(prefix + luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(prefix + luaCode)); }, "Lua program loaded without error"); @@ -1294,7 +1295,7 @@ test("[test-suite] api: long chain of userdata", { skip: true }, function (t) { assert(debug.getuservalue(b).x == 100) b = nil `, L; - + t.plan(2); t.doesNotThrow(function () { @@ -1305,7 +1306,7 @@ test("[test-suite] api: long chain of userdata", { skip: true }, function (t) { ltests.luaopen_tests(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(prefix + luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(prefix + luaCode)); }, "Lua program loaded without error"); @@ -1366,7 +1367,7 @@ test("[test-suite] api: reuse of references", { skip: true }, function (t) { assert(type(T.getref(a)) == 'table') `, L; - + t.plan(2); t.doesNotThrow(function () { @@ -1377,7 +1378,7 @@ test("[test-suite] api: reuse of references", { skip: true }, function (t) { ltests.luaopen_tests(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(prefix + luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(prefix + luaCode)); }, "Lua program loaded without error"); @@ -1494,7 +1495,7 @@ test("[test-suite] api: collect in cl the `val' of all collected userdata", { sk collectgarbage() assert(#cl == 1 and cl[1] == x) -- old 'x' must be collected `, L; - + t.plan(2); t.doesNotThrow(function () { @@ -1505,7 +1506,7 @@ test("[test-suite] api: collect in cl the `val' of all collected userdata", { sk ltests.luaopen_tests(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(prefix + luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(prefix + luaCode)); }, "Lua program loaded without error"); @@ -1550,7 +1551,7 @@ test("[test-suite] api: test whether udate collection frees memory in the right collectgarbage("restart") end `, L; - + t.plan(2); t.doesNotThrow(function () { @@ -1561,7 +1562,7 @@ test("[test-suite] api: test whether udate collection frees memory in the right ltests.luaopen_tests(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(prefix + luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(prefix + luaCode)); }, "Lua program loaded without error"); @@ -1582,7 +1583,7 @@ test("[test-suite] api: testing lua_equal", function (t) { assert(not T.testC("compare EQ 2 3; return 1")) assert(not T.testC("compare EQ 2 3; return 1", 3)) `, L; - + t.plan(2); t.doesNotThrow(function () { @@ -1593,7 +1594,7 @@ test("[test-suite] api: testing lua_equal", function (t) { ltests.luaopen_tests(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(prefix + luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(prefix + luaCode)); }, "Lua program loaded without error"); @@ -1624,7 +1625,7 @@ test("[test-suite] api: testing lua_equal with fallbacks", function (t) { assert(f(10) ~= f(10)) end `, L; - + t.plan(2); t.doesNotThrow(function () { @@ -1635,7 +1636,7 @@ test("[test-suite] api: testing lua_equal with fallbacks", function (t) { ltests.luaopen_tests(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(prefix + luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(prefix + luaCode)); }, "Lua program loaded without error"); @@ -1670,7 +1671,7 @@ test("[test-suite] api: testing changing hooks during hooks", function (t) { assert(t[5] == "line" and t[6] == line + 2) assert(t[7] == nil) `, L; - + t.plan(2); t.doesNotThrow(function () { @@ -1681,7 +1682,7 @@ test("[test-suite] api: testing changing hooks during hooks", function (t) { ltests.luaopen_tests(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(prefix + luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(prefix + luaCode)); }, "Lua program loaded without error"); @@ -1722,7 +1723,7 @@ test("[test-suite] api: testing errors during GC", { skip: true }, function (t) assert(A == 10) -- number of normal collections end `, L; - + t.plan(2); t.doesNotThrow(function () { @@ -1733,7 +1734,7 @@ test("[test-suite] api: testing errors during GC", { skip: true }, function (t) ltests.luaopen_tests(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(prefix + luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(prefix + luaCode)); }, "Lua program loaded without error"); @@ -1757,7 +1758,7 @@ test("[test-suite] api: test for userdata vals", function (t) { assert(type(tostring(a[1])) == "string") end `, L; - + t.plan(2); t.doesNotThrow(function () { @@ -1768,7 +1769,7 @@ test("[test-suite] api: test for userdata vals", function (t) { ltests.luaopen_tests(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(prefix + luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(prefix + luaCode)); }, "Lua program loaded without error"); @@ -1828,7 +1829,7 @@ test("[test-suite] api: testing multiple states", function (t) { T.closestate(L1) `, L; - + t.plan(2); t.doesNotThrow(function () { @@ -1839,7 +1840,7 @@ test("[test-suite] api: testing multiple states", function (t) { ltests.luaopen_tests(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(prefix + luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(prefix + luaCode)); }, "Lua program loaded without error"); @@ -1859,7 +1860,7 @@ test("[test-suite] api: testing memory limits", { skip: true }, function (t) { checkerr("not enough memory", load"local a={}; for i=1,100000 do a[i]=i end") T.totalmem(0) -- restore high limit `, L; - + t.plan(2); t.doesNotThrow(function () { @@ -1870,7 +1871,7 @@ test("[test-suite] api: testing memory limits", { skip: true }, function (t) { ltests.luaopen_tests(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(prefix + luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(prefix + luaCode)); }, "Lua program loaded without error"); @@ -1914,7 +1915,7 @@ test("[test-suite] api: testing memory errors when creating a new state", { skip b = testamem("state creation", T.newstate) T.closestate(b); -- close new state `, L; - + t.plan(2); t.doesNotThrow(function () { @@ -1925,7 +1926,7 @@ test("[test-suite] api: testing memory errors when creating a new state", { skip ltests.luaopen_tests(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(prefix + memprefix + luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(prefix + memprefix + luaCode)); }, "Lua program loaded without error"); @@ -1936,13 +1937,35 @@ test("[test-suite] api: testing memory errors when creating a new state", { skip }, "Lua program ran without error"); }); -test("[test-suite] api: get main thread from registry (at index LUA_RIDX_MAINTHREAD == 1)", { skip: true }, function (t) { +test("[test-suite] api: get main thread from registry (at index LUA_RIDX_MAINTHREAD == 1)", function (t) { let luaCode = ` mt = T.testC("rawgeti R 1; return 1") assert(type(mt) == "thread" and coroutine.running() == mt) + `, L; + + t.plan(2); + + t.doesNotThrow(function () { + + L = lauxlib.luaL_newstate(); + + lualib.luaL_openlibs(L); + ltests.luaopen_tests(L); + + lauxlib.luaL_loadstring(L, to_luastring(prefix + memprefix + luaCode)); + }, "Lua program loaded without error"); + + t.doesNotThrow(function () { + lua.lua_call(L, 0, -1); + + }, "Lua program ran without error"); +}); + +test("[test-suite] api: test thread creation after stressing GC", { skip: true }, function (t) { + let luaCode = ` function expand (n,s) if n==0 then return "" end local e = string.rep("=", n) @@ -1958,7 +1981,7 @@ test("[test-suite] api: get main thread from registry (at index LUA_RIDX_MAINTHR return T.doonnewstack("x=1") == 0 -- try to create thread end) `, L; - + t.plan(2); t.doesNotThrow(function () { @@ -1969,7 +1992,7 @@ test("[test-suite] api: get main thread from registry (at index LUA_RIDX_MAINTHR ltests.luaopen_tests(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(prefix + memprefix + luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(prefix + memprefix + luaCode)); }, "Lua program loaded without error"); @@ -1987,7 +2010,7 @@ test("[test-suite] api: testing memory x compiler", { skip: true }, function (t) return load("x=1") -- try to do load a string end) `, L; - + t.plan(2); t.doesNotThrow(function () { @@ -1998,7 +2021,7 @@ test("[test-suite] api: testing memory x compiler", { skip: true }, function (t) ltests.luaopen_tests(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(prefix + memprefix + luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(prefix + memprefix + luaCode)); }, "Lua program loaded without error"); @@ -2033,7 +2056,7 @@ test("[test-suite] api: testing memory x dofile", { skip: true }, function (t) { assert(os.remove(t)) assert(_G.a == "aaax") `, L; - + t.plan(2); t.doesNotThrow(function () { @@ -2044,7 +2067,7 @@ test("[test-suite] api: testing memory x dofile", { skip: true }, function (t) { ltests.luaopen_tests(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(prefix + memprefix + luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(prefix + memprefix + luaCode)); }, "Lua program loaded without error"); @@ -2116,7 +2139,7 @@ test("[test-suite] api: other generic tests", { skip: true }, function (t) { end) end `, L; - + t.plan(2); t.doesNotThrow(function () { @@ -2127,7 +2150,7 @@ test("[test-suite] api: other generic tests", { skip: true }, function (t) { ltests.luaopen_tests(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(prefix + memprefix + luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(prefix + memprefix + luaCode)); }, "Lua program loaded without error"); @@ -2153,7 +2176,7 @@ test("[test-suite] api: testing some auxlib functions", function (t) { assert(gsub("...", ".", "/.") == "/././.") assert(gsub("...", "...", "") == "") `, L; - + t.plan(2); t.doesNotThrow(function () { @@ -2164,7 +2187,7 @@ test("[test-suite] api: testing some auxlib functions", function (t) { ltests.luaopen_tests(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(prefix + luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(prefix + luaCode)); }, "Lua program loaded without error"); @@ -2225,7 +2248,7 @@ test("[test-suite] api: testing luaL_newmetatable", function (t) { r.xuxu = nil; r.xuxu1 = nil end `, L; - + t.plan(2); t.doesNotThrow(function () { @@ -2236,7 +2259,7 @@ test("[test-suite] api: testing luaL_newmetatable", function (t) { ltests.luaopen_tests(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(prefix + luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(prefix + luaCode)); }, "Lua program loaded without error"); diff --git a/tests/test-suite/attrib.js b/tests/test-suite/attrib.js index fcd3271..7445a5e 100644 --- a/tests/test-suite/attrib.js +++ b/tests/test-suite/attrib.js @@ -5,7 +5,7 @@ const test = require('tape'); const lua = require('../../src/lua.js'); const lauxlib = require('../../src/lauxlib.js'); const lualib = require('../../src/lualib.js'); - +const {to_luastring} = require("../../src/fengaricore.js"); test("[test-suite] attrib: testing require", function (t) { let luaCode = ` @@ -53,7 +53,7 @@ test("[test-suite] attrib: testing require", function (t) { package.path = oldpath end `, L; - + t.plan(2); t.doesNotThrow(function () { @@ -62,7 +62,7 @@ test("[test-suite] attrib: testing require", function (t) { lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(luaCode)); }, "Lua program loaded without error"); @@ -169,7 +169,7 @@ test("[test-suite] attrib: testing assignments, logical operators, and construct a[1], f(a)[2], b, c = {['alo']=assert}, 10, a[1], a[f], 6, 10, 23, f(a), 2 a[1].alo(a[2]==10 and b==10 and c==print) `, L; - + t.plan(2); t.doesNotThrow(function () { @@ -178,7 +178,7 @@ test("[test-suite] attrib: testing assignments, logical operators, and construct lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(luaCode)); }, "Lua program loaded without error"); @@ -245,7 +245,7 @@ test("[test-suite] attrib: test of large float/integer indices ", function (t) { assert(a[maxintF] == 20 and a[maxintF - 1.0] == 11 and a[-maxintF] == 22 and a[-maxintF + 1.0] == 13) `, L; - + t.plan(2); t.doesNotThrow(function () { @@ -254,7 +254,7 @@ test("[test-suite] attrib: test of large float/integer indices ", function (t) { lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(luaCode)); }, "Lua program loaded without error"); @@ -277,7 +277,7 @@ test("[test-suite] attrib: test conflicts in multiple assignment", function (t) b[3] == 1) end `, L; - + t.plan(2); t.doesNotThrow(function () { @@ -286,7 +286,7 @@ test("[test-suite] attrib: test conflicts in multiple assignment", function (t) lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(luaCode)); }, "Lua program loaded without error"); @@ -315,7 +315,7 @@ test("[test-suite] attrib: repeat test with upvalues", function (t) { assert(t[1] == 10) end `, L; - + t.plan(2); t.doesNotThrow(function () { @@ -324,7 +324,7 @@ test("[test-suite] attrib: repeat test with upvalues", function (t) { lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(luaCode)); }, "Lua program loaded without error"); @@ -351,7 +351,7 @@ test("[test-suite] attrib: bug in 5.2 beta", function (t) { local a, b = foo()() assert(a == 3 and b == 14) `, L; - + t.plan(2); t.doesNotThrow(function () { @@ -360,7 +360,7 @@ test("[test-suite] attrib: bug in 5.2 beta", function (t) { lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(luaCode)); }, "Lua program loaded without error"); diff --git a/tests/test-suite/bitwise.js b/tests/test-suite/bitwise.js index df57f15..17e3c84 100644 --- a/tests/test-suite/bitwise.js +++ b/tests/test-suite/bitwise.js @@ -5,7 +5,7 @@ const test = require('tape'); const lua = require('../../src/lua.js'); const lauxlib = require('../../src/lauxlib.js'); const lualib = require('../../src/lualib.js'); - +const {to_luastring} = require("../../src/fengaricore.js"); const prefix = ` package.preload.bit32 = function () --{ @@ -176,7 +176,7 @@ test("[test-suite] bitwise: testing bitwise operations", function (t) { -- embedded zeros assert(not pcall(function () return "0xffffffffffffffff\\0" | 0 end)) `, L; - + t.plan(2); t.doesNotThrow(function () { @@ -185,7 +185,7 @@ test("[test-suite] bitwise: testing bitwise operations", function (t) { lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(prefix + luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(prefix + luaCode)); }, "Lua program loaded without error"); @@ -208,7 +208,7 @@ test("[test-suite] bitwise: testing bitwise library", function (t) { assert(bit32.band() == bit32.band(0xffffffff)) assert(bit32.band(1,2) == 0) `, L; - + t.plan(2); t.doesNotThrow(function () { @@ -217,7 +217,7 @@ test("[test-suite] bitwise: testing bitwise library", function (t) { lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(prefix + luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(prefix + luaCode)); }, "Lua program loaded without error"); @@ -285,7 +285,7 @@ test("[test-suite] bitwise: out-of-range numbers", function (t) { assert(0x12345678 >> 32 == 0) assert(0x12345678 >> -32 == 0x1234567800000000) `, L; - + t.plan(2); t.doesNotThrow(function () { @@ -294,7 +294,7 @@ test("[test-suite] bitwise: out-of-range numbers", function (t) { lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(prefix + luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(prefix + luaCode)); }, "Lua program loaded without error"); @@ -340,7 +340,7 @@ test("[test-suite] bitwise: some special cases", function (t) { assert(bit32.rshift(bit32.rshift(b, 4), -4) == bit32.band(b, bit32.bnot(0xf))) end `, L; - + t.plan(2); t.doesNotThrow(function () { @@ -349,7 +349,7 @@ test("[test-suite] bitwise: some special cases", function (t) { lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(prefix + luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(prefix + luaCode)); }, "Lua program loaded without error"); @@ -379,7 +379,7 @@ test("[test-suite] bitwise: for this test, use at most 24 bits (mantissa of a si assert(not pcall(bit32.lshift, 45, print)) assert(not pcall(bit32.rshift, 45, print)) `, L; - + t.plan(2); t.doesNotThrow(function () { @@ -388,7 +388,7 @@ test("[test-suite] bitwise: for this test, use at most 24 bits (mantissa of a si lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(prefix + luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(prefix + luaCode)); }, "Lua program loaded without error"); @@ -422,7 +422,7 @@ test("[test-suite] bitwise: testing extract/replace", function (t) { assert(bit32.replace(-1, 0, 31) == (1 << 31) - 1) assert(bit32.replace(-1, 0, 1, 2) == (1 << 32) - 7) `, L; - + t.plan(2); t.doesNotThrow(function () { @@ -431,7 +431,7 @@ test("[test-suite] bitwise: testing extract/replace", function (t) { lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(prefix + luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(prefix + luaCode)); }, "Lua program loaded without error"); @@ -449,7 +449,7 @@ test("[test-suite] bitwise: testing conversion of floats", function (t) { assert(bit32.bor(3.0) == 3) assert(bit32.bor(-4.0) == 0xfffffffc) `, L; - + t.plan(2); t.doesNotThrow(function () { @@ -458,7 +458,7 @@ test("[test-suite] bitwise: testing conversion of floats", function (t) { lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(prefix + luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(prefix + luaCode)); }, "Lua program loaded without error"); @@ -480,7 +480,7 @@ test("[test-suite] bitwise: large floats and large-enough integers?", function ( assert(bit32.bor(-2.0^48 - 6.0) == 0xfffffffa) end `, L; - + t.plan(2); t.doesNotThrow(function () { @@ -489,7 +489,7 @@ test("[test-suite] bitwise: large floats and large-enough integers?", function ( lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(prefix + luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(prefix + luaCode)); }, "Lua program loaded without error"); diff --git a/tests/test-suite/calls.js b/tests/test-suite/calls.js index fdd5eac..2044e5c 100644 --- a/tests/test-suite/calls.js +++ b/tests/test-suite/calls.js @@ -5,7 +5,7 @@ const test = require('tape'); const lua = require('../../src/lua.js'); const lauxlib = require('../../src/lauxlib.js'); const lualib = require('../../src/lualib.js'); - +const {to_luastring} = require("../../src/fengaricore.js"); test("[test-suite] calls: test 'type'", function (t) { let luaCode = ` @@ -22,7 +22,7 @@ test("[test-suite] calls: test 'type'", function (t) { assert(type(f) == 'function') assert(not pcall(type)) `, L; - + t.plan(2); t.doesNotThrow(function () { @@ -31,7 +31,7 @@ test("[test-suite] calls: test 'type'", function (t) { lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(luaCode)); }, "Lua program loaded without error"); @@ -56,11 +56,11 @@ test("[test-suite] calls: test error in 'print'", function (t) { _ENV.tostring = function () return {} end local st, msg = pcall(print, 1) assert(st == false and string.find(msg, "must return a string")) - + _ENV.tostring = tostring end `, L; - + t.plan(2); t.doesNotThrow(function () { @@ -69,7 +69,7 @@ test("[test-suite] calls: test error in 'print'", function (t) { lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(luaCode)); }, "Lua program loaded without error"); @@ -96,7 +96,7 @@ test("[test-suite] calls: testing local-function recursion", function (t) { end assert(fact == false) `, L; - + t.plan(2); t.doesNotThrow(function () { @@ -105,7 +105,7 @@ test("[test-suite] calls: testing local-function recursion", function (t) { lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(luaCode)); }, "Lua program loaded without error"); @@ -203,7 +203,7 @@ test("[test-suite] calls: testing declarations", function (t) { (function (x) a=x end)(23) assert(a == 23 and (function (x) return x*2 end)(20) == 40) `, L; - + t.plan(2); t.doesNotThrow(function () { @@ -212,7 +212,7 @@ test("[test-suite] calls: testing declarations", function (t) { lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(luaCode)); }, "Lua program loaded without error"); @@ -261,7 +261,7 @@ test("[test-suite] calls: testing closures", function (t) { Z, F, f = nil `, L; - + t.plan(2); t.doesNotThrow(function () { @@ -270,7 +270,7 @@ test("[test-suite] calls: testing closures", function (t) { lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(luaCode)); }, "Lua program loaded without error"); @@ -319,7 +319,7 @@ test("[test-suite] calls: testing multiple returns", function (t) { a = ret2{ unlpack{1,2,3}, unlpack{3,2,1}, unlpack{"a", "b"}} assert(a[1] == 1 and a[2] == 3 and a[3] == "a" and a[4] == "b") `, L; - + t.plan(2); t.doesNotThrow(function () { @@ -328,7 +328,7 @@ test("[test-suite] calls: testing multiple returns", function (t) { lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(luaCode)); }, "Lua program loaded without error"); @@ -348,7 +348,7 @@ test("[test-suite] calls: testing calls with 'incorrect' arguments", function (t assert(math.sin(1,2) == math.sin(1)) table.sort({10,9,8,4,19,23,0,0}, function (a,b) return a<b end, "extra arg") `, L; - + t.plan(2); t.doesNotThrow(function () { @@ -357,7 +357,7 @@ test("[test-suite] calls: testing calls with 'incorrect' arguments", function (t lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(luaCode)); }, "Lua program loaded without error"); @@ -420,7 +420,7 @@ test("[test-suite] calls: test for generic load", function (t) { cannotload("unexpected symbol", load("*a = 123")) cannotload("hhi", load(function () error("hhi") end)) `, L; - + t.plan(2); t.doesNotThrow(function () { @@ -429,7 +429,7 @@ test("[test-suite] calls: test for generic load", function (t) { lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(luaCode)); }, "Lua program loaded without error"); @@ -446,7 +446,7 @@ test("[test-suite] calls: any value is valid for _ENV", function (t) { let luaCode = ` assert(load("return _ENV", nil, nil, 123)() == 123) `, L; - + t.plan(2); t.doesNotThrow(function () { @@ -455,7 +455,7 @@ test("[test-suite] calls: any value is valid for _ENV", function (t) { lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(luaCode)); }, "Lua program loaded without error"); @@ -483,7 +483,7 @@ test("[test-suite] calls: load when _ENV is not first upvalue", function (t) { assert(assert(load("return XX + ...", nil, nil, {XX = 13}))(4) == 17) `, L; - + t.plan(2); t.doesNotThrow(function () { @@ -492,7 +492,7 @@ test("[test-suite] calls: load when _ENV is not first upvalue", function (t) { lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(luaCode)); }, "Lua program loaded without error"); @@ -528,7 +528,7 @@ test("[test-suite] calls: test generic load with nested functions", function (t) a = assert(load(read1(x))) assert(a()(2)(3)(10) == 15) `, L; - + t.plan(2); t.doesNotThrow(function () { @@ -537,7 +537,7 @@ test("[test-suite] calls: test generic load with nested functions", function (t) lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(luaCode)); }, "Lua program loaded without error"); @@ -568,7 +568,7 @@ test("[test-suite] calls: test for dump/undump with upvalues", function (t) { x("set") assert(x() == 24) `, L; - + t.plan(2); t.doesNotThrow(function () { @@ -577,7 +577,7 @@ test("[test-suite] calls: test for dump/undump with upvalues", function (t) { lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(luaCode)); }, "Lua program loaded without error"); @@ -615,7 +615,7 @@ test("[test-suite] calls: test for dump/undump with many upvalues", function (t) assert(f() == 10 * nup) end `, L; - + t.plan(2); t.doesNotThrow(function () { @@ -624,7 +624,7 @@ test("[test-suite] calls: test for dump/undump with many upvalues", function (t) lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(luaCode)); }, "Lua program loaded without error"); @@ -647,7 +647,7 @@ test("[test-suite] calls: test for long method names", function (t) { assert(t:_012345678901234567890123456789012345678901234567890123456789() == 1) end `, L; - + t.plan(2); t.doesNotThrow(function () { @@ -656,7 +656,7 @@ test("[test-suite] calls: test for long method names", function (t) { lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(luaCode)); }, "Lua program loaded without error"); @@ -675,7 +675,7 @@ test("[test-suite] calls: test for bug in parameter adjustment", function (t) { assert((function () local a; return a end)(4) == nil) assert((function (a) return a end)() == nil) `, L; - + t.plan(2); t.doesNotThrow(function () { @@ -684,7 +684,7 @@ test("[test-suite] calls: test for bug in parameter adjustment", function (t) { lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(luaCode)); }, "Lua program loaded without error"); @@ -734,7 +734,7 @@ test("[test-suite] calls: testing binary chunks", function (t) { assert(assert(load(c))() == 10) end `, L; - + t.plan(2); t.doesNotThrow(function () { @@ -743,7 +743,7 @@ test("[test-suite] calls: testing binary chunks", function (t) { lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(luaCode)); }, "Lua program loaded without error"); diff --git a/tests/test-suite/closure.js b/tests/test-suite/closure.js index 464a5b5..79a2226 100644 --- a/tests/test-suite/closure.js +++ b/tests/test-suite/closure.js @@ -5,6 +5,7 @@ const test = require('tape'); const lua = require('../../src/lua.js'); const lauxlib = require('../../src/lauxlib.js'); const lualib = require('../../src/lualib.js'); +const {to_luastring} = require("../../src/fengaricore.js"); test("[test-suite] closure: testing equality", function (t) { let luaCode = ` @@ -20,7 +21,7 @@ test("[test-suite] closure: testing equality", function (t) { end assert(f() == f()) `, L; - + t.plan(2); t.doesNotThrow(function () { @@ -29,7 +30,7 @@ test("[test-suite] closure: testing equality", function (t) { lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(luaCode)); }, "Lua program loaded without error"); @@ -73,7 +74,7 @@ test("[test-suite] closure: testing closures with 'for' control variable", funct r,s = a[2].get() assert(r == "a" and s == "b") `, L; - + t.plan(2); t.doesNotThrow(function () { @@ -82,7 +83,7 @@ test("[test-suite] closure: testing closures with 'for' control variable", funct lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(luaCode)); }, "Lua program loaded without error"); @@ -113,7 +114,7 @@ test("[test-suite] closure: testing closures with 'for' control variable x break assert(({f()})[1] == 1) assert(({f()})[2] == "a") `, L; - + t.plan(2); t.doesNotThrow(function () { @@ -122,7 +123,7 @@ test("[test-suite] closure: testing closures with 'for' control variable x break lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(luaCode)); }, "Lua program loaded without error"); @@ -169,7 +170,7 @@ test("[test-suite] closure: testing closure x break x return x errors", function assert(b('get') == 'xuxu') b('set', 10); assert(b('get') == 14) `, L; - + t.plan(2); t.doesNotThrow(function () { @@ -178,7 +179,7 @@ test("[test-suite] closure: testing closure x break x return x errors", function lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(luaCode)); }, "Lua program loaded without error"); @@ -204,7 +205,7 @@ test("[test-suite] closure: testing multi-level closure", function (t) { w = 1.345 assert(y(20)(30) == 60+w) `, L; - + t.plan(2); t.doesNotThrow(function () { @@ -213,7 +214,7 @@ test("[test-suite] closure: testing multi-level closure", function (t) { lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(luaCode)); }, "Lua program loaded without error"); @@ -236,7 +237,7 @@ test("[test-suite] closure: testing closures x repeat-until", function (t) { until i > 10 or a[i]() ~= x assert(i == 11 and a[1]() == 1 and a[3]() == 3 and i == 4) `, L; - + t.plan(2); t.doesNotThrow(function () { @@ -245,7 +246,7 @@ test("[test-suite] closure: testing closures x repeat-until", function (t) { lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(luaCode)); }, "Lua program loaded without error"); @@ -289,7 +290,7 @@ test("[test-suite] closure: testing closures created in 'then' and 'else' parts assert(a[i](i * 10) == i % 3 and a[i]() == i * 10) end `, L; - + t.plan(2); t.doesNotThrow(function () { @@ -298,7 +299,7 @@ test("[test-suite] closure: testing closures created in 'then' and 'else' parts lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(luaCode)); }, "Lua program loaded without error"); @@ -321,7 +322,7 @@ test("[test-suite] closure: test for correctly closing upvalues in tail calls of end t() `, L; - + t.plan(2); t.doesNotThrow(function () { @@ -330,7 +331,7 @@ test("[test-suite] closure: test for correctly closing upvalues in tail calls of lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(luaCode)); }, "Lua program loaded without error"); diff --git a/tests/test-suite/code.js b/tests/test-suite/code.js index 26ca021..57c97cb 100644 --- a/tests/test-suite/code.js +++ b/tests/test-suite/code.js @@ -5,10 +5,10 @@ const test = require('tape'); const lua = require('../../src/lua.js'); const lauxlib = require('../../src/lauxlib.js'); const lualib = require('../../src/lualib.js'); +const {to_luastring} = require("../../src/fengaricore.js"); const ltests = require('./ltests.js'); - test("[test-suite] code: testing reuse in constant table", function (t) { let luaCode = ` local function checkKlist (func, list) @@ -31,7 +31,7 @@ test("[test-suite] code: testing reuse in constant table", function (t) { checkKlist(foo, {3, 0, 0.0, 3.78/4, -3.78/4, -3.79/4, 3.0}) `, L; - + t.plan(2); t.doesNotThrow(function () { @@ -42,7 +42,7 @@ test("[test-suite] code: testing reuse in constant table", function (t) { ltests.luaopen_tests(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(luaCode)); }, "Lua program loaded without error"); @@ -83,7 +83,7 @@ test("[test-suite] code: some basic instructions", function (t) { (function () end){f()} end, 'CLOSURE', 'NEWTABLE', 'GETTABUP', 'CALL', 'SETLIST', 'CALL', 'RETURN') `, L; - + t.plan(2); t.doesNotThrow(function () { @@ -94,7 +94,7 @@ test("[test-suite] code: some basic instructions", function (t) { ltests.luaopen_tests(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(prefix + luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(prefix + luaCode)); }, "Lua program loaded without error"); @@ -126,7 +126,7 @@ test("[test-suite] code: sequence of LOADNILs", function (t) { assert(a == nil and b == nil and c == nil and d == nil) end `, L; - + t.plan(2); t.doesNotThrow(function () { @@ -137,7 +137,7 @@ test("[test-suite] code: sequence of LOADNILs", function (t) { ltests.luaopen_tests(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(prefix + luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(prefix + luaCode)); }, "Lua program loaded without error"); @@ -153,7 +153,7 @@ test("[test-suite] code: single return", function (t) { let luaCode = ` check (function (a,b,c) return a end, 'RETURN') `, L; - + t.plan(2); t.doesNotThrow(function () { @@ -164,7 +164,7 @@ test("[test-suite] code: single return", function (t) { ltests.luaopen_tests(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(prefix + luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(prefix + luaCode)); }, "Lua program loaded without error"); @@ -187,7 +187,7 @@ test("[test-suite] code: infinite loops", function (t) { check(function () repeat local x = 1 until true end, 'LOADK', 'RETURN') `, L; - + t.plan(2); t.doesNotThrow(function () { @@ -198,7 +198,7 @@ test("[test-suite] code: infinite loops", function (t) { ltests.luaopen_tests(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(prefix + luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(prefix + luaCode)); }, "Lua program loaded without error"); @@ -215,7 +215,7 @@ test("[test-suite] code: concat optimization", function (t) { check(function (a,b,c,d) return a..b..c..d end, 'MOVE', 'MOVE', 'MOVE', 'MOVE', 'CONCAT', 'RETURN') `, L; - + t.plan(2); t.doesNotThrow(function () { @@ -226,7 +226,7 @@ test("[test-suite] code: concat optimization", function (t) { ltests.luaopen_tests(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(prefix + luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(prefix + luaCode)); }, "Lua program loaded without error"); @@ -245,7 +245,7 @@ test("[test-suite] code: not", function (t) { check(function () return not not true end, 'LOADBOOL', 'RETURN') check(function () return not not 1 end, 'LOADBOOL', 'RETURN') `, L; - + t.plan(2); t.doesNotThrow(function () { @@ -256,7 +256,7 @@ test("[test-suite] code: not", function (t) { ltests.luaopen_tests(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(prefix + luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(prefix + luaCode)); }, "Lua program loaded without error"); @@ -280,7 +280,7 @@ test("[test-suite] code: direct access to locals", function (t) { 'DIV', 'ADD', 'GETTABLE', 'SUB', 'GETTABLE', 'POW', 'UNM', 'SETTABLE', 'SETTABLE', 'RETURN') `, L; - + t.plan(2); t.doesNotThrow(function () { @@ -291,7 +291,7 @@ test("[test-suite] code: direct access to locals", function (t) { ltests.luaopen_tests(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(prefix + luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(prefix + luaCode)); }, "Lua program loaded without error"); @@ -327,7 +327,7 @@ test("[test-suite] code: direct access to constants", function (t) { end, 'LOADNIL', 'SETTABLE', 'RETURN') `, L; - + t.plan(2); t.doesNotThrow(function () { @@ -338,7 +338,7 @@ test("[test-suite] code: direct access to constants", function (t) { ltests.luaopen_tests(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(prefix + luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(prefix + luaCode)); }, "Lua program loaded without error"); @@ -373,7 +373,7 @@ test("[test-suite] code: constant folding", function (t) { checkK(function () return ~~-100024.0 end, -100024) checkK(function () return ((100 << 6) << -4) >> 2 end, 100) `, L; - + t.plan(2); t.doesNotThrow(function () { @@ -384,7 +384,7 @@ test("[test-suite] code: constant folding", function (t) { ltests.luaopen_tests(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(prefix + luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(prefix + luaCode)); }, "Lua program loaded without error"); @@ -403,7 +403,7 @@ test("[test-suite] code: no folding", function (t) { check(function () return 0%0 end, 'MOD', 'RETURN') check(function () return -4//0 end, 'IDIV', 'RETURN') `, L; - + t.plan(2); t.doesNotThrow(function () { @@ -414,7 +414,7 @@ test("[test-suite] code: no folding", function (t) { ltests.luaopen_tests(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(prefix + luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(prefix + luaCode)); }, "Lua program loaded without error"); @@ -437,7 +437,7 @@ test("[test-suite] code: bug in constant folding for 5.1", function (t) { b[a], a = c, b a, b = c, a a = a - end, + end, 'LOADNIL', 'MOVE', 'MOVE', 'SETTABLE', 'MOVE', 'MOVE', 'MOVE', 'SETTABLE', @@ -445,7 +445,7 @@ test("[test-suite] code: bug in constant folding for 5.1", function (t) { -- no code for a = a 'RETURN') `, L; - + t.plan(2); t.doesNotThrow(function () { @@ -456,7 +456,7 @@ test("[test-suite] code: bug in constant folding for 5.1", function (t) { ltests.luaopen_tests(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(prefix + luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(prefix + luaCode)); }, "Lua program loaded without error"); @@ -482,7 +482,7 @@ test("[test-suite] code: x == nil , x ~= nil", function (t) { checkequal(function (l) local a; return 0 <= a and a <= l end, function (l) local a; return not (not(a >= 0) or not(a <= l)) end) `, L; - + t.plan(2); t.doesNotThrow(function () { @@ -493,7 +493,7 @@ test("[test-suite] code: x == nil , x ~= nil", function (t) { ltests.luaopen_tests(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(prefix + luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(prefix + luaCode)); }, "Lua program loaded without error"); @@ -515,7 +515,7 @@ test("[test-suite] code: if-goto optimizations", function (t) { else goto l3 end end - ::l1:: ::l2:: ::l3:: ::l4:: + ::l1:: ::l2:: ::l3:: ::l4:: end, 'EQ', 'JMP', 'EQ', 'JMP', 'EQ', 'JMP', 'EQ', 'JMP', 'JMP', 'RETURN') checkequal( @@ -529,7 +529,7 @@ test("[test-suite] code: if-goto optimizations", function (t) { function (a) while true do if not(a < 10) then break end; a = a + 1; end end ) `, L; - + t.plan(2); t.doesNotThrow(function () { @@ -540,7 +540,7 @@ test("[test-suite] code: if-goto optimizations", function (t) { ltests.luaopen_tests(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(prefix + luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(prefix + luaCode)); }, "Lua program loaded without error"); diff --git a/tests/test-suite/constructs.js b/tests/test-suite/constructs.js index 89bcce7..93bbf1a 100644 --- a/tests/test-suite/constructs.js +++ b/tests/test-suite/constructs.js @@ -5,7 +5,7 @@ const test = require('tape'); const lua = require('../../src/lua.js'); const lauxlib = require('../../src/lauxlib.js'); const lualib = require('../../src/lualib.js'); - +const {to_luastring} = require("../../src/fengaricore.js"); const checkload = ` local function checkload (s, msg) @@ -28,7 +28,7 @@ test('[test-suite] constructs: testing semicolons', function (t) { lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(checkload + luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(checkload + luaCode)); }, "Lua program loaded without error"); @@ -54,7 +54,7 @@ test('[test-suite] constructs: invalid operations should not raise errors when n lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(checkload + luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(checkload + luaCode)); }, "Lua program loaded without error"); @@ -119,7 +119,7 @@ test('[test-suite] constructs: testing priorities', function (t) { lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(checkload + luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(checkload + luaCode)); }, "Lua program loaded without error"); @@ -305,7 +305,7 @@ test('[test-suite] constructs: silly loops', function (t) { lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(checkload + luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(checkload + luaCode)); }, "Lua program loaded without error"); @@ -392,7 +392,7 @@ test.skip('[test-suite] constructs: huge loops, upvalue', function (t) { lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(checkload + luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(checkload + luaCode)); }, "Lua program loaded without error"); @@ -428,7 +428,7 @@ test("[test-suite] constructs: testing some syntax errors (chosen through 'gcov' lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(checkload + luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(checkload + luaCode)); }, "Lua program loaded without error"); diff --git a/tests/test-suite/coroutine.js b/tests/test-suite/coroutine.js index b85f0de..969c65e 100644 --- a/tests/test-suite/coroutine.js +++ b/tests/test-suite/coroutine.js @@ -5,6 +5,7 @@ const test = require('tape'); const lua = require('../../src/lua.js'); const lauxlib = require('../../src/lauxlib.js'); const lualib = require('../../src/lualib.js'); +const {to_luastring} = require("../../src/fengaricore.js"); const ltests = require('./ltests.js'); @@ -64,7 +65,7 @@ test("[test-suite] coroutine: is main thread", function (t) { assert(not coroutine.isyieldable()) assert(not pcall(coroutine.yield)) `, L; - + t.plan(2); t.doesNotThrow(function () { @@ -73,7 +74,7 @@ test("[test-suite] coroutine: is main thread", function (t) { lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(luaCode)); }, "Lua program loaded without error"); @@ -91,7 +92,7 @@ test("[test-suite] coroutine: trivial errors", function (t) { assert(not pcall(coroutine.resume, 0)) assert(not pcall(coroutine.status, 0)) `, L; - + t.plan(2); t.doesNotThrow(function () { @@ -100,7 +101,7 @@ test("[test-suite] coroutine: trivial errors", function (t) { lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(luaCode)); }, "Lua program loaded without error"); @@ -158,7 +159,7 @@ test("[test-suite] coroutine: tests for multiple yield/resume arguments", functi s, a = coroutine.resume(f, "xuxu") assert(not s and string.find(a, "dead") and coroutine.status(f) == "dead") `, L; - + t.plan(2); t.doesNotThrow(function () { @@ -167,7 +168,7 @@ test("[test-suite] coroutine: tests for multiple yield/resume arguments", functi lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(luaCode)); }, "Lua program loaded without error"); @@ -192,7 +193,7 @@ test("[test-suite] coroutine: yields in tail calls", function (t) { for i=1,10 do _G.x = i; assert(f(i) == i) end _G.x = 'xuxu'; assert(f('xuxu') == 'a') `, L; - + t.plan(2); t.doesNotThrow(function () { @@ -201,7 +202,7 @@ test("[test-suite] coroutine: yields in tail calls", function (t) { lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(luaCode)); }, "Lua program loaded without error"); @@ -228,7 +229,7 @@ test("[test-suite] coroutine: recursive", function (t) { s = s*i end `, L; - + t.plan(2); t.doesNotThrow(function () { @@ -237,7 +238,7 @@ test("[test-suite] coroutine: recursive", function (t) { lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(luaCode)); }, "Lua program loaded without error"); @@ -281,7 +282,7 @@ test("[test-suite] coroutine: sieve", function (t) { assert(#a == 25 and a[#a] == 97) x, a = nil `, L; - + t.plan(2); t.doesNotThrow(function () { @@ -290,7 +291,7 @@ test("[test-suite] coroutine: sieve", function (t) { lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(luaCode)); }, "Lua program loaded without error"); @@ -333,7 +334,7 @@ test("[test-suite] coroutine: yielding across JS boundaries", function (t) { r, msg = co(100) assert(not r and msg == 240) `, L; - + t.plan(2); t.doesNotThrow(function () { @@ -342,7 +343,7 @@ test("[test-suite] coroutine: yielding across JS boundaries", function (t) { lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(luaCode)); }, "Lua program loaded without error"); @@ -371,7 +372,7 @@ test("[test-suite] coroutine: unyieldable JS call", function (t) { assert(co() == "aa") end `, L; - + t.plan(2); t.doesNotThrow(function () { @@ -380,7 +381,7 @@ test("[test-suite] coroutine: unyieldable JS call", function (t) { lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(luaCode)); }, "Lua program loaded without error"); @@ -416,7 +417,7 @@ test("[test-suite] coroutine: errors in coroutines", function (t) { a,b = coroutine.resume(x) assert(not a and string.find(b, "dead") and coroutine.status(x) == "dead") `, L; - + t.plan(2); t.doesNotThrow(function () { @@ -425,7 +426,7 @@ test("[test-suite] coroutine: errors in coroutines", function (t) { lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(luaCode)); }, "Lua program loaded without error"); @@ -456,7 +457,7 @@ test("[test-suite] coroutine: co-routines x for loop", function (t) { end assert(a == 5^4) `, L; - + t.plan(2); t.doesNotThrow(function () { @@ -465,7 +466,7 @@ test("[test-suite] coroutine: co-routines x for loop", function (t) { lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(luaCode)); }, "Lua program loaded without error"); @@ -499,7 +500,7 @@ test("[test-suite] coroutine: old bug: attempt to resume itself", function (t) { assert(coroutine.resume(co, co) == false) assert(coroutine.resume(co, co) == false) `, L; - + t.plan(2); t.doesNotThrow(function () { @@ -508,7 +509,7 @@ test("[test-suite] coroutine: old bug: attempt to resume itself", function (t) { lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(luaCode)); }, "Lua program loaded without error"); @@ -534,7 +535,7 @@ test("[test-suite] coroutine: old bug: other old bug when attempting to resume i assert(not st and string.find(res, "non%-suspended")) end `, L; - + t.plan(2); t.doesNotThrow(function () { @@ -543,7 +544,7 @@ test("[test-suite] coroutine: old bug: other old bug when attempting to resume i lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(luaCode)); }, "Lua program loaded without error"); @@ -570,7 +571,7 @@ test("[test-suite] coroutine: attempt to resume 'normal' coroutine", function (t assert(a and b == 3) assert(coroutine.status(co1) == 'dead') `, L; - + t.plan(2); t.doesNotThrow(function () { @@ -579,7 +580,7 @@ test("[test-suite] coroutine: attempt to resume 'normal' coroutine", function (t lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(luaCode)); }, "Lua program loaded without error"); @@ -598,7 +599,7 @@ test("[test-suite] coroutine: infinite recursion of coroutines", function (t) { assert(not pcall(a, a)) a = nil `, L; - + t.plan(2); t.doesNotThrow(function () { @@ -607,7 +608,7 @@ test("[test-suite] coroutine: infinite recursion of coroutines", function (t) { lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(luaCode)); }, "Lua program loaded without error"); @@ -634,7 +635,7 @@ test("[test-suite] coroutine: access to locals of erroneous coroutines", functio assert(_G.f() == 11) assert(_G.f() == 12) `, L; - + t.plan(2); t.doesNotThrow(function () { @@ -643,7 +644,7 @@ test("[test-suite] coroutine: access to locals of erroneous coroutines", functio lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(luaCode)); }, "Lua program loaded without error"); @@ -665,7 +666,7 @@ test("[test-suite] coroutine: leaving a pending coroutine open", function (t) { _X() `, L; - + t.plan(2); t.doesNotThrow(function () { @@ -674,7 +675,7 @@ test("[test-suite] coroutine: leaving a pending coroutine open", function (t) { lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(luaCode)); }, "Lua program loaded without error"); @@ -714,7 +715,7 @@ test("[test-suite] coroutine: stack overflow", function (t) { lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(luaCode)); }, "Lua program loaded without error"); @@ -774,7 +775,7 @@ test("[test-suite] coroutine: testing yields inside metamethods", function (t) { lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(prefix + luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(prefix + luaCode)); }, "Lua program loaded without error"); @@ -812,7 +813,7 @@ test("[test-suite] coroutine: tests for comparsion operators", function (t) { until res ~= 10 return res end - + local function test () local a1 = setmetatable({x=1}, mt1) local a2 = setmetatable({x=2}, mt2) @@ -824,7 +825,7 @@ test("[test-suite] coroutine: tests for comparsion operators", function (t) { assert(2 >= a2) return true end - + run(test) end @@ -838,7 +839,7 @@ test("[test-suite] coroutine: tests for comparsion operators", function (t) { lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(luaCode)); }, "Lua program loaded without error"); @@ -870,7 +871,7 @@ test("[test-suite] coroutine: getuptable & setuptable", function (t) { lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(prefix + luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(prefix + luaCode)); }, "Lua program loaded without error"); @@ -905,7 +906,7 @@ test("[test-suite] coroutine: testing yields inside 'for' iterators", function ( lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(prefix + luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(prefix + luaCode)); }, "Lua program loaded without error"); @@ -950,7 +951,7 @@ test("[test-suite] coroutine: testing yields inside hooks", function (t) { assert(B // A == 7) -- fact(7) // fact(6) `, L; - + t.plan(2); t.doesNotThrow(function () { @@ -961,7 +962,7 @@ test("[test-suite] coroutine: testing yields inside hooks", function (t) { ltests.luaopen_tests(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(jsprefix + luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(jsprefix + luaCode)); }, "Lua program loaded without error"); @@ -993,7 +994,7 @@ test("[test-suite] coroutine: testing yields inside line hook", function (t) { _G.X = nil; co(); assert(_G.X == line + 3 and _G.XX == 20) assert(co() == 10) `, L; - + t.plan(2); t.doesNotThrow(function () { @@ -1004,7 +1005,7 @@ test("[test-suite] coroutine: testing yields inside line hook", function (t) { ltests.luaopen_tests(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(jsprefix + luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(jsprefix + luaCode)); }, "Lua program loaded without error"); @@ -1034,7 +1035,7 @@ test("[test-suite] coroutine: testing yields in count hook", function (t) { repeat c = c + 1; local a = co() until a == 10 assert(_G.XX == 20 and c >= 5) `, L; - + t.plan(2); t.doesNotThrow(function () { @@ -1045,7 +1046,7 @@ test("[test-suite] coroutine: testing yields in count hook", function (t) { ltests.luaopen_tests(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(jsprefix + luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(jsprefix + luaCode)); }, "Lua program loaded without error"); @@ -1084,7 +1085,7 @@ test("[test-suite] coroutine: testing yields inside line hook", function (t) { assert(_G.XX == 20 and c >= 5) _G.X = nil; _G.XX = nil `, L; - + t.plan(2); t.doesNotThrow(function () { @@ -1095,7 +1096,7 @@ test("[test-suite] coroutine: testing yields inside line hook", function (t) { ltests.luaopen_tests(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(jsprefix + luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(jsprefix + luaCode)); }, "Lua program loaded without error"); @@ -1136,7 +1137,7 @@ test("[test-suite] coroutine: testing debug library on a coroutine suspended ins assert(not coroutine.resume(c)) end `, L; - + t.plan(2); t.doesNotThrow(function () { @@ -1147,7 +1148,7 @@ test("[test-suite] coroutine: testing debug library on a coroutine suspended ins ltests.luaopen_tests(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(luaCode)); }, "Lua program loaded without error"); @@ -1172,7 +1173,7 @@ test("[test-suite] coroutine: testing debug library on last function in a suspen assert(b == 10) end `, L; - + t.plan(2); t.doesNotThrow(function () { @@ -1183,7 +1184,7 @@ test("[test-suite] coroutine: testing debug library on last function in a suspen ltests.luaopen_tests(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(luaCode)); }, "Lua program loaded without error"); @@ -1218,7 +1219,7 @@ test("[test-suite] coroutine: reusing a thread", function (t) { assert(X == 'a a a' and Y == 'OK') `, L; - + t.plan(2); t.doesNotThrow(function () { @@ -1229,7 +1230,7 @@ test("[test-suite] coroutine: reusing a thread", function (t) { ltests.luaopen_tests(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(luaCode)); }, "Lua program loaded without error"); @@ -1267,7 +1268,7 @@ test("[test-suite] coroutine: resuming running coroutine", function (t) { assert(a == coroutine.running() and string.find(b, "non%-suspended") and c == "ERRRUN" and d == 4) `, L; - + t.plan(2); t.doesNotThrow(function () { @@ -1278,7 +1279,7 @@ test("[test-suite] coroutine: resuming running coroutine", function (t) { ltests.luaopen_tests(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(luaCode)); }, "Lua program loaded without error"); @@ -1322,7 +1323,7 @@ test("[test-suite] coroutine: using a main thread as a coroutine", function (t) T.closestate(state) `, L; - + t.plan(2); t.doesNotThrow(function () { @@ -1333,7 +1334,7 @@ test("[test-suite] coroutine: using a main thread as a coroutine", function (t) ltests.luaopen_tests(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(luaCode)); }, "Lua program loaded without error"); @@ -1386,7 +1387,7 @@ test("[test-suite] coroutine: tests for coroutine API", function (t) { a[9] == "YIELD" and a[10] == 4) assert(not pcall(co)) -- coroutine is dead now `, L; - + t.plan(2); t.doesNotThrow(function () { @@ -1397,7 +1398,7 @@ test("[test-suite] coroutine: tests for coroutine API", function (t) { ltests.luaopen_tests(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(luaCode)); }, "Lua program loaded without error"); @@ -1419,7 +1420,7 @@ test("[test-suite] coroutine: tests for coroutine API", function (t) { assert(co(23,16) == 5) assert(co(23,16) == 10) `, L; - + t.plan(2); t.doesNotThrow(function () { @@ -1430,7 +1431,7 @@ test("[test-suite] coroutine: tests for coroutine API", function (t) { ltests.luaopen_tests(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(luaCode)); }, "Lua program loaded without error"); @@ -1476,7 +1477,7 @@ test("[test-suite] coroutine: testing coroutines with C bodies", function (t) { assert(a == 'YIELD' and b == 'a' and c == 102 and d == 'OK') `, L; - + t.plan(2); t.doesNotThrow(function () { @@ -1487,7 +1488,7 @@ test("[test-suite] coroutine: testing coroutines with C bodies", function (t) { ltests.luaopen_tests(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(luaCode)); }, "Lua program loaded without error"); @@ -1531,7 +1532,7 @@ test("[test-suite] coroutine: testing chain of suspendable C calls", function (t -- three '34's (one from each pending C call) assert(#a == 3 and a[1] == a[2] and a[2] == a[3] and a[3] == 34) `, L; - + t.plan(2); t.doesNotThrow(function () { @@ -1542,7 +1543,7 @@ test("[test-suite] coroutine: testing chain of suspendable C calls", function (t ltests.luaopen_tests(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(luaCode)); }, "Lua program loaded without error"); @@ -1562,11 +1563,11 @@ test("[test-suite] coroutine: testing yields with continuations", function (t) { cannot be here! ]], [[ # 1st continuation - yieldk 0 3 + yieldk 0 3 cannot be here! ]], [[ # 2nd continuation - yieldk 0 4 + yieldk 0 4 cannot be here! ]], [[ # 3th continuation @@ -1608,7 +1609,7 @@ test("[test-suite] coroutine: testing yields with continuations", function (t) { assert(not pcall(co)) -- coroutine should be dead `, L; - + t.plan(2); t.doesNotThrow(function () { @@ -1619,7 +1620,7 @@ test("[test-suite] coroutine: testing yields with continuations", function (t) { ltests.luaopen_tests(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(luaCode)); }, "Lua program loaded without error"); @@ -1641,7 +1642,7 @@ test("[test-suite] coroutine: bug in nCcalls", function (t) { local a = {co()} assert(a[10] == "hi") `, L; - + t.plan(2); t.doesNotThrow(function () { @@ -1652,7 +1653,7 @@ test("[test-suite] coroutine: bug in nCcalls", function (t) { ltests.luaopen_tests(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(luaCode)); }, "Lua program loaded without error"); diff --git a/tests/test-suite/db.js b/tests/test-suite/db.js index ff13ecb..9209ab9 100644 --- a/tests/test-suite/db.js +++ b/tests/test-suite/db.js @@ -5,7 +5,7 @@ const test = require('tape'); const lua = require('../../src/lua.js'); const lauxlib = require('../../src/lauxlib.js'); const lualib = require('../../src/lualib.js'); - +const {to_luastring} = require("../../src/fengaricore.js"); const prefix = ` local function dostring(s) return assert(load(s))() end @@ -51,7 +51,7 @@ test("[test-suite] db: getinfo, ...line...", function (t) { lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(prefix + luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(prefix + luaCode)); }, "Lua program loaded without error"); @@ -99,7 +99,7 @@ test("[test-suite] db: test file and string names truncation", function (t) { lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(luaCode)); }, "Lua program loaded without error"); @@ -158,7 +158,7 @@ test("[test-suite] db: local", function (t) { lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(luaCode)); }, "Lua program loaded without error"); @@ -236,7 +236,7 @@ test("[test-suite] db: line hook", function (t) { lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(prefix + luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(prefix + luaCode)); }, "Lua program loaded without error"); @@ -263,7 +263,7 @@ test("[test-suite] db: invalid levels in [gs]etlocal", function (t) { lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(luaCode)); }, "Lua program loaded without error"); @@ -299,7 +299,7 @@ test("[test-suite] db: parameter names", function (t) { lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(luaCode)); }, "Lua program loaded without error"); @@ -348,7 +348,7 @@ test("[test-suite] db: vararg", function (t) { lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(luaCode)); }, "Lua program loaded without error"); @@ -375,7 +375,7 @@ test("[test-suite] db: access to vararg in non-vararg function", function (t) { lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(luaCode)); }, "Lua program loaded without error"); @@ -483,7 +483,7 @@ test("[test-suite] db: test hook presence in debug info", function (t) { lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(luaCode)); }, "Lua program loaded without error"); @@ -529,7 +529,7 @@ test("[test-suite] db: tests for manipulating non-registered locals (C and Lua t lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(luaCode)); }, "Lua program loaded without error"); @@ -590,7 +590,7 @@ test("[test-suite] db: testing access to function arguments", function (t) { lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(prefix + luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(prefix + luaCode)); }, "Lua program loaded without error"); @@ -649,7 +649,7 @@ test("[test-suite] db: testing access to local variables in return hook (bug in lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(luaCode)); }, "Lua program loaded without error"); @@ -701,7 +701,7 @@ test("[test-suite] db: testing upvalue access", function (t) { lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(luaCode)); }, "Lua program loaded without error"); @@ -743,7 +743,7 @@ test("[test-suite] db: testing count hooks", function (t) { lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(luaCode)); }, "Lua program loaded without error"); @@ -822,7 +822,7 @@ test("[test-suite] db: tests for tail calls", function (t) { lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(luaCode)); }, "Lua program loaded without error"); @@ -864,7 +864,7 @@ test("[test-suite] db: testing local function information", function (t) { lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(luaCode)); }, "Lua program loaded without error"); @@ -901,7 +901,7 @@ test("[test-suite] db: testing traceback", function (t) { lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(luaCode)); }, "Lua program loaded without error"); @@ -938,7 +938,7 @@ test("[test-suite] db: testing nparams, nups e isvararg", function (t) { lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(luaCode)); }, "Lua program loaded without error"); @@ -1028,8 +1028,8 @@ test("[test-suite] db: testing debugging of coroutines", function (t) { lualib.luaL_openlibs(L); - let b = lua.to_luastring(luaCode); - if (lauxlib.luaL_loadbuffer(L, b, b.length, lua.to_luastring("@db.lua")) !== lua.LUA_OK) + let b = to_luastring(luaCode); + if (lauxlib.luaL_loadbuffer(L, b, b.length, to_luastring("@db.lua")) !== lua.LUA_OK) throw Error(lua.lua_tojsstring(L, -1)); }, "Lua program loaded without error"); @@ -1069,7 +1069,7 @@ test("[test-suite] db: check get/setlocal in coroutines", function (t) { lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(luaCode)); }, "Lua program loaded without error"); @@ -1116,7 +1116,7 @@ test("[test-suite] db: check traceback of suspended (or dead with error) corouti lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(luaCode)); }, "Lua program loaded without error"); @@ -1159,7 +1159,7 @@ test("[test-suite] db: check test acessing line numbers of a coroutine from a re lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(luaCode)); }, "Lua program loaded without error"); @@ -1211,7 +1211,7 @@ test("[test-suite] db: test tagmethod information", function (t) { lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(luaCode)); }, "Lua program loaded without error"); @@ -1243,7 +1243,7 @@ test("[test-suite] db: testing for-iterator name", function (t) { lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(luaCode)); }, "Lua program loaded without error"); @@ -1302,8 +1302,8 @@ test("[test-suite] db: testing traceback sizes", function (t) { lualib.luaL_openlibs(L); - let b = lua.to_luastring(luaCode); - if (lauxlib.luaL_loadbuffer(L, b, b.length, lua.to_luastring("@db.lua")) !== lua.LUA_OK) + let b = to_luastring(luaCode); + if (lauxlib.luaL_loadbuffer(L, b, b.length, to_luastring("@db.lua")) !== lua.LUA_OK) throw Error(lua.lua_tojsstring(L, -1)); }, "Lua program loaded without error"); @@ -1371,7 +1371,7 @@ test("[test-suite] db: testing debug functions on chunk without debug info", fun lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(luaCode)); }, "Lua program loaded without error"); @@ -1427,7 +1427,7 @@ test("[test-suite] db: tests for 'source' in binary dumps", function (t) { lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(luaCode)); }, "Lua program loaded without error"); diff --git a/tests/test-suite/errors.js b/tests/test-suite/errors.js index a6bc351..0b05e9d 100644 --- a/tests/test-suite/errors.js +++ b/tests/test-suite/errors.js @@ -5,7 +5,7 @@ const test = require('tape'); const lua = require('../../src/lua.js'); const lauxlib = require('../../src/lauxlib.js'); const lualib = require('../../src/lualib.js'); - +const {to_luastring} = require("../../src/fengaricore.js"); const prefix = ` -- avoid problems with 'strict' module (which may generate other error messages) @@ -48,7 +48,7 @@ test("[test-suite] errors: test error message with no extra info", function (t) let luaCode = ` assert(doit("error('hi', 0)") == 'hi') `, L; - + t.plan(2); t.doesNotThrow(function () { @@ -57,7 +57,7 @@ test("[test-suite] errors: test error message with no extra info", function (t) lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(prefix + luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(prefix + luaCode)); }, "Lua program loaded without error"); @@ -74,7 +74,7 @@ test("[test-suite] errors: test error message with no info", function (t) { let luaCode = ` assert(doit("error()") == nil) `, L; - + t.plan(2); t.doesNotThrow(function () { @@ -83,7 +83,7 @@ test("[test-suite] errors: test error message with no info", function (t) { lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(prefix + luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(prefix + luaCode)); }, "Lua program loaded without error"); @@ -115,7 +115,7 @@ test("[test-suite] errors: test common errors/errors that crashed in the past", ]], "'}' expected (to close '{' at line 1)", "<eof>", 3) `, L; - + t.plan(2); t.doesNotThrow(function () { @@ -124,7 +124,7 @@ test("[test-suite] errors: test common errors/errors that crashed in the past", lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(prefix + luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(prefix + luaCode)); }, "Lua program loaded without error"); @@ -161,7 +161,7 @@ test("[test-suite] errors: tests for better error messages", function (t) { checkmessage("local a,b,c; (function () a = b+1 end)()", "upvalue 'b'") assert(not doit"local aaa={bbb={ddd=next}}; aaa.bbb:ddd(nil)") `, L; - + t.plan(2); t.doesNotThrow(function () { @@ -170,7 +170,7 @@ test("[test-suite] errors: tests for better error messages", function (t) { lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(prefix + luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(prefix + luaCode)); }, "Lua program loaded without error"); @@ -195,7 +195,7 @@ test("[test-suite] errors: upvalues being indexed do not go to the stack", funct checkmessage("aaa='2'; b=nil;x=aaa*b", "global 'b'") checkmessage("aaa={}; x=-aaa", "global 'aaa'") `, L; - + t.plan(2); t.doesNotThrow(function () { @@ -204,7 +204,7 @@ test("[test-suite] errors: upvalues being indexed do not go to the stack", funct lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(prefix + luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(prefix + luaCode)); }, "Lua program loaded without error"); @@ -232,7 +232,7 @@ test("[test-suite] errors: short circuit", function (t) { checkmessage("print('10' < 10)", "string with number") checkmessage("print(10 < '23')", "number with string") `, L; - + t.plan(2); t.doesNotThrow(function () { @@ -241,7 +241,7 @@ test("[test-suite] errors: short circuit", function (t) { lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(prefix + luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(prefix + luaCode)); }, "Lua program loaded without error"); @@ -274,7 +274,7 @@ test("[test-suite] errors: float->integer conversions", function (t) { checkmessage("a = 24 // 0", "divide by zero") checkmessage("a = 1 % 0", "'n%0'") `, L; - + t.plan(2); t.doesNotThrow(function () { @@ -283,7 +283,7 @@ test("[test-suite] errors: float->integer conversions", function (t) { lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(prefix + luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(prefix + luaCode)); }, "Lua program loaded without error"); @@ -306,7 +306,7 @@ test("[test-suite] errors: passing light userdata instead of full userdata", fun ]], "light userdata") _G.D = nil `, L; - + t.plan(2); t.doesNotThrow(function () { @@ -315,7 +315,7 @@ test("[test-suite] errors: passing light userdata instead of full userdata", fun lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(prefix + luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(prefix + luaCode)); }, "Lua program loaded without error"); @@ -343,7 +343,7 @@ test("[test-suite] errors: named objects (field '__name')", function (t) { _G.XX = nil end `, L; - + t.plan(2); t.doesNotThrow(function () { @@ -352,7 +352,7 @@ test("[test-suite] errors: named objects (field '__name')", function (t) { lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(prefix + luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(prefix + luaCode)); }, "Lua program loaded without error"); @@ -370,7 +370,7 @@ test("[test-suite] errors: global functions", function (t) { checkmessage("(io.write or print){}", "io.write") checkmessage("(collectgarbage or print){}", "collectgarbage") `, L; - + t.plan(2); t.doesNotThrow(function () { @@ -379,7 +379,7 @@ test("[test-suite] errors: global functions", function (t) { lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(prefix + luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(prefix + luaCode)); }, "Lua program loaded without error"); @@ -408,7 +408,7 @@ test("[test-suite] errors: errors in functions without debug info", function (t) checkerr("^%?:%-1:.*table value", f) end `, L; - + t.plan(2); t.doesNotThrow(function () { @@ -417,7 +417,7 @@ test("[test-suite] errors: errors in functions without debug info", function (t) lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(prefix + luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(prefix + luaCode)); }, "Lua program loaded without error"); @@ -443,7 +443,7 @@ test("[test-suite] errors: tests for field accesses after RK limit", function (t checkmessage(s.."; local t = {}; a = t.bbb + 1", "field 'bbb'") checkmessage(s.."; local t = {}; t:bbb()", "method 'bbb'") `, L; - + t.plan(2); t.doesNotThrow(function () { @@ -452,7 +452,7 @@ test("[test-suite] errors: tests for field accesses after RK limit", function (t lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(prefix + luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(prefix + luaCode)); }, "Lua program loaded without error"); @@ -478,7 +478,7 @@ test("[test-suite] errors: global", function (t) { {d = x and aaa[x or y]}} ]], "global 'aaa'") `, L; - + t.plan(2); t.doesNotThrow(function () { @@ -487,7 +487,7 @@ test("[test-suite] errors: global", function (t) { lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(prefix + luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(prefix + luaCode)); }, "Lua program loaded without error"); @@ -507,7 +507,7 @@ test("[test-suite] errors: field", function (t) { if math.sin(1) == 0 then return 3 end -- return x.a()]], "field 'a'") `, L; - + t.plan(2); t.doesNotThrow(function () { @@ -516,7 +516,7 @@ test("[test-suite] errors: field", function (t) { lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(prefix + luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(prefix + luaCode)); }, "Lua program loaded without error"); @@ -540,7 +540,7 @@ test("[test-suite] errors: global insert", function (t) { insert(prefix, a) end]], "global 'insert'") `, L; - + t.plan(2); t.doesNotThrow(function () { @@ -549,7 +549,7 @@ test("[test-suite] errors: global insert", function (t) { lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(prefix + luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(prefix + luaCode)); }, "Lua program loaded without error"); @@ -568,7 +568,7 @@ test("[test-suite] errors: sin", function (t) { return math.sin("a") ]], "'sin'") `, L; - + t.plan(2); t.doesNotThrow(function () { @@ -577,7 +577,7 @@ test("[test-suite] errors: sin", function (t) { lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(prefix + luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(prefix + luaCode)); }, "Lua program loaded without error"); @@ -596,7 +596,7 @@ test("[test-suite] errors: concatenate", function (t) { checkmessage([[x = "a" .. false]], "concatenate") checkmessage([[x = {} .. 2]], "concatenate") `, L; - + t.plan(2); t.doesNotThrow(function () { @@ -605,7 +605,7 @@ test("[test-suite] errors: concatenate", function (t) { lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(prefix + luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(prefix + luaCode)); }, "Lua program loaded without error"); @@ -628,7 +628,7 @@ test("[test-suite] errors: unknown global", function (t) { main() ]], "global 'NoSuchName'") `, L; - + t.plan(2); t.doesNotThrow(function () { @@ -637,7 +637,7 @@ test("[test-suite] errors: unknown global", function (t) { lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(prefix + luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(prefix + luaCode)); }, "Lua program loaded without error"); @@ -660,7 +660,7 @@ test("[test-suite] errors: __index", function (t) { checkmessage("table.sort({1,2,3}, table.sort)", "'table.sort'") checkmessage("string.gsub('s', 's', setmetatable)", "'setmetatable'") `, L; - + t.plan(2); t.doesNotThrow(function () { @@ -669,7 +669,7 @@ test("[test-suite] errors: __index", function (t) { lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(prefix + luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(prefix + luaCode)); }, "Lua program loaded without error"); @@ -696,7 +696,7 @@ test("[test-suite] errors: tests for errors in coroutines", function (t) { f = coroutine.wrap(function () table.sort({1,2,3}, coroutine.yield) end) checkerr("yield across", f) `, L; - + t.plan(2); t.doesNotThrow(function () { @@ -705,7 +705,7 @@ test("[test-suite] errors: tests for errors in coroutines", function (t) { lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(prefix + luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(prefix + luaCode)); }, "Lua program loaded without error"); @@ -735,7 +735,7 @@ test("[test-suite] errors: testing size of 'source' info", function (t) { end `, L; - + t.plan(2); t.doesNotThrow(function () { @@ -744,7 +744,7 @@ test("[test-suite] errors: testing size of 'source' info", function (t) { lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(prefix + luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(prefix + luaCode)); }, "Lua program loaded without error"); @@ -812,7 +812,7 @@ test("[test-suite] errors: testing line error", function (t) { X=1;lineerror((p), 2) X=2;lineerror((p), 1) `, L; - + t.plan(2); t.doesNotThrow(function () { @@ -821,7 +821,7 @@ test("[test-suite] errors: testing line error", function (t) { lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(prefix + luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(prefix + luaCode)); }, "Lua program loaded without error"); @@ -847,7 +847,7 @@ test("[test-suite] errors: several tests that exhaust the Lua stack", function ( assert(checkstackmessage(doit('y()'))) assert(checkstackmessage(doit('y()'))) `, L; - + t.plan(2); t.doesNotThrow(function () { @@ -856,7 +856,7 @@ test("[test-suite] errors: several tests that exhaust the Lua stack", function ( lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(prefix + luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(prefix + luaCode)); }, "Lua program loaded without error"); @@ -890,7 +890,7 @@ test("[test-suite] errors: error lines in stack overflow", function (t) { end assert(i > 15) `, L; - + t.plan(2); t.doesNotThrow(function () { @@ -899,7 +899,7 @@ test("[test-suite] errors: error lines in stack overflow", function (t) { lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(prefix + luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(prefix + luaCode)); }, "Lua program loaded without error"); @@ -927,7 +927,7 @@ test("[test-suite] errors: error in error handling", function (t) { end f(3) `, L; - + t.plan(2); t.doesNotThrow(function () { @@ -936,7 +936,7 @@ test("[test-suite] errors: error in error handling", function (t) { lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(prefix + luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(prefix + luaCode)); }, "Lua program loaded without error"); @@ -966,7 +966,7 @@ test("[test-suite] errors: too many results", function (t) { end checkerr("too many results", f) `, L; - + t.plan(2); t.doesNotThrow(function () { @@ -975,7 +975,7 @@ test("[test-suite] errors: too many results", function (t) { lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(prefix + luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(prefix + luaCode)); }, "Lua program loaded without error"); @@ -1006,7 +1006,7 @@ test("[test-suite] errors: non string messages", function (t) { -- 'assert' with extra arguments res, msg = pcall(assert, false, "X", t) assert(not res and msg == "X") - + -- 'assert' with no message res, msg = pcall(function () assert(false) end) local line = string.match(msg, "%w+%.lua:(%d+): assertion failed!$") @@ -1024,7 +1024,7 @@ test("[test-suite] errors: non string messages", function (t) { assert(not res and string.find(msg, "value expected")) end `, L; - + t.plan(2); t.doesNotThrow(function () { @@ -1033,7 +1033,7 @@ test("[test-suite] errors: non string messages", function (t) { lualib.luaL_openlibs(L); - lauxlib.luaL_loadbuffer(L, lua.to_luastring(prefix + luaCode), null, lua.to_luastring("@errors.lua")); + lauxlib.luaL_loadbuffer(L, to_luastring(prefix + luaCode), null, to_luastring("@errors.lua")); }, "Lua program loaded without error"); @@ -1053,7 +1053,7 @@ test("[test-suite] errors: xpcall with arguments", function (t) { a, b, c = xpcall(string.find, function (x) return {} end, true, "al") assert(not a and type(b) == "table" and c == nil) `, L; - + t.plan(2); t.doesNotThrow(function () { @@ -1062,7 +1062,7 @@ test("[test-suite] errors: xpcall with arguments", function (t) { lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(prefix + luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(prefix + luaCode)); }, "Lua program loaded without error"); @@ -1084,7 +1084,7 @@ test("[test-suite] errors: testing tokens in error messages", function (t) { checksyntax("while << do end", "", "<<", 1) checksyntax("for >> do end", "", ">>", 1) `, L; - + t.plan(2); t.doesNotThrow(function () { @@ -1093,7 +1093,7 @@ test("[test-suite] errors: testing tokens in error messages", function (t) { lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(prefix + luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(prefix + luaCode)); }, "Lua program loaded without error"); @@ -1110,7 +1110,7 @@ test("[test-suite] errors: test invalid non-printable char in a chunk", function let luaCode = ` checksyntax("a\\1a = 1", "", "<\\\\1>", 1) `, L; - + t.plan(2); t.doesNotThrow(function () { @@ -1119,7 +1119,7 @@ test("[test-suite] errors: test invalid non-printable char in a chunk", function lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(prefix + luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(prefix + luaCode)); }, "Lua program loaded without error"); @@ -1139,7 +1139,7 @@ test("[test-suite] errors: test 255 as first char in a chunk", function (t) { doit('I = load("a=9+"); a=3') assert(a==3 and I == nil) `, L; - + t.plan(2); t.doesNotThrow(function () { @@ -1148,7 +1148,7 @@ test("[test-suite] errors: test 255 as first char in a chunk", function (t) { lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(prefix + luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(prefix + luaCode)); }, "Lua program loaded without error"); @@ -1170,7 +1170,7 @@ test("[test-suite] errors: lots of errors", function (t) { doit('a = 4+nil') end `, L; - + t.plan(2); t.doesNotThrow(function () { @@ -1179,7 +1179,7 @@ test("[test-suite] errors: lots of errors", function (t) { lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(prefix + luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(prefix + luaCode)); }, "Lua program loaded without error"); @@ -1217,7 +1217,7 @@ test("[test-suite] errors: testing syntax limits", function (t) { checkmessage("a = f(x" .. string.rep(",x", 260) .. ")", "too many registers") `, L; - + t.plan(2); t.doesNotThrow(function () { @@ -1226,7 +1226,7 @@ test("[test-suite] errors: testing syntax limits", function (t) { lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(prefix + luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(prefix + luaCode)); }, "Lua program loaded without error"); @@ -1263,7 +1263,7 @@ test("[test-suite] errors: upvalues limit", function (t) { assert(c > 255 and string.find(b, "too many upvalues") and string.find(b, "line 5")) `, L; - + t.plan(2); t.doesNotThrow(function () { @@ -1272,7 +1272,7 @@ test("[test-suite] errors: upvalues limit", function (t) { lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(prefix + luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(prefix + luaCode)); }, "Lua program loaded without error"); @@ -1295,7 +1295,7 @@ test("[test-suite] errors: local variables limit", function (t) { local a,b = load(s) assert(string.find(b, "line 2") and string.find(b, "too many local variables")) `, L; - + t.plan(2); t.doesNotThrow(function () { @@ -1304,7 +1304,7 @@ test("[test-suite] errors: local variables limit", function (t) { lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(prefix + luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(prefix + luaCode)); }, "Lua program loaded without error"); diff --git a/tests/test-suite/events.js b/tests/test-suite/events.js index 9a15e93..143bdf5 100644 --- a/tests/test-suite/events.js +++ b/tests/test-suite/events.js @@ -5,10 +5,10 @@ const test = require('tape'); const lua = require('../../src/lua.js'); const lauxlib = require('../../src/lauxlib.js'); const lualib = require('../../src/lualib.js'); +const {to_luastring} = require("../../src/fengaricore.js"); const ltests = require('./ltests.js'); - test("[test-suite] events: testing metatable", function (t) { let luaCode = ` X = 20; B = 30 @@ -182,7 +182,7 @@ test("[test-suite] events: testing metatable", function (t) { assert(1.5 >> a == 1.5) assert(cap[0] == "shr" and cap[1] == 1.5 and cap[2] == a) `, L; - + t.plan(2); t.doesNotThrow(function () { @@ -191,7 +191,7 @@ test("[test-suite] events: testing metatable", function (t) { lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(luaCode)); }, "Lua program loaded without error"); @@ -216,7 +216,7 @@ test("[test-suite] events: test for rawlen", function (t) { -- rawlen for long strings assert(rawlen(string.rep('a', 1000)) == 1000) `, L; - + t.plan(2); t.doesNotThrow(function () { @@ -225,7 +225,7 @@ test("[test-suite] events: test for rawlen", function (t) { lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(luaCode)); }, "Lua program loaded without error"); @@ -277,7 +277,7 @@ test("[test-suite] events: test comparison", function (t) { test() -- retest comparisons, now using both 'lt' and 'le' `, L; - + t.plan(2); t.doesNotThrow(function () { @@ -286,7 +286,7 @@ test("[test-suite] events: test comparison", function (t) { lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(luaCode)); }, "Lua program loaded without error"); @@ -360,7 +360,7 @@ test("[test-suite] events: test 'partial order'", function (t) { t[Set{1,3,5}] = 1 assert(t[Set{1,3,5}] == nil) `, L; - + t.plan(2); t.doesNotThrow(function () { @@ -369,7 +369,7 @@ test("[test-suite] events: test 'partial order'", function (t) { lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(luaCode)); }, "Lua program loaded without error"); @@ -403,7 +403,7 @@ test("[test-suite] events: __eq between userdata", function (t) { assert(u2 == u1 and u2 == u3 and u3 == u2) assert(u2 ~= {}) -- different types cannot be equal `, L; - + t.plan(2); t.doesNotThrow(function () { @@ -414,7 +414,7 @@ test("[test-suite] events: __eq between userdata", function (t) { ltests.luaopen_tests(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(luaCode)); }, "Lua program loaded without error"); @@ -455,7 +455,7 @@ test("[test-suite] events: concat", function (t) { x = 0 .."a".."b"..c..d.."e".."f".."g" assert(x.val == "0abcdefg") `, L; - + t.plan(2); t.doesNotThrow(function () { @@ -466,7 +466,7 @@ test("[test-suite] events: concat", function (t) { ltests.luaopen_tests(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(luaCode)); }, "Lua program loaded without error"); @@ -490,7 +490,7 @@ test("[test-suite] events: concat metamethod x numbers (bug in 5.1.1)", function assert(c..5 == c and 5 .. c == c) assert(4 .. c .. 5 == c and 4 .. 5 .. 6 .. 7 .. c == c) `, L; - + t.plan(2); t.doesNotThrow(function () { @@ -501,7 +501,7 @@ test("[test-suite] events: concat metamethod x numbers (bug in 5.1.1)", function ltests.luaopen_tests(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(luaCode)); }, "Lua program loaded without error"); @@ -529,7 +529,7 @@ test("[test-suite] events: test comparison compatibilities", function (t) { setmetatable(d, t2) assert(c == d and c < d and not(d <= c)) `, L; - + t.plan(2); t.doesNotThrow(function () { @@ -540,7 +540,7 @@ test("[test-suite] events: test comparison compatibilities", function (t) { ltests.luaopen_tests(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(luaCode)); }, "Lua program loaded without error"); @@ -564,16 +564,16 @@ test("[test-suite] events: test for several levels of callstest for several leve end end } - + local a = setmetatable({}, tt) local b = setmetatable({f=a}, tt) local c = setmetatable({f=b}, tt) - + i = 0 x = c(3,4,5) assert(i == 3 and x[1] == 3 and x[3] == 5) `, L; - + t.plan(2); t.doesNotThrow(function () { @@ -584,7 +584,7 @@ test("[test-suite] events: test for several levels of callstest for several leve ltests.luaopen_tests(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(luaCode)); }, "Lua program loaded without error"); @@ -606,7 +606,7 @@ test("[test-suite] events: __index on _ENV", function (t) { rawset(a, "x", 1, 2, 3) assert(a.x == 1 and rawget(a, "x", 3) == 1) `, L; - + t.plan(2); t.doesNotThrow(function () { @@ -617,7 +617,7 @@ test("[test-suite] events: __index on _ENV", function (t) { ltests.luaopen_tests(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(luaCode)); }, "Lua program loaded without error"); @@ -661,7 +661,7 @@ test("[test-suite] events: testing metatables for basic types", function (t) { debug.setmetatable(nil, {}) `, L; - + t.plan(2); t.doesNotThrow(function () { @@ -672,7 +672,7 @@ test("[test-suite] events: testing metatables for basic types", function (t) { ltests.luaopen_tests(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(luaCode)); }, "Lua program loaded without error"); @@ -691,7 +691,7 @@ test("[test-suite] events: loops in delegation", function (t) { assert(not pcall(function (a,b) return a[b] end, a, 10)) assert(not pcall(function (a,b,c) a[b] = c end, a, 10, true)) `, L; - + t.plan(2); t.doesNotThrow(function () { @@ -702,7 +702,7 @@ test("[test-suite] events: loops in delegation", function (t) { ltests.luaopen_tests(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(luaCode)); }, "Lua program loaded without error"); @@ -729,7 +729,7 @@ test("[test-suite] events: bug in 5.1", function (t) { child.foo = 10 --> CRASH (on some machines) assert(T == parent and K == "foo" and V == 10) `, L; - + t.plan(2); t.doesNotThrow(function () { @@ -740,7 +740,7 @@ test("[test-suite] events: bug in 5.1", function (t) { ltests.luaopen_tests(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(luaCode)); }, "Lua program loaded without error"); diff --git a/tests/test-suite/goto.js b/tests/test-suite/goto.js index 5acf633..dc52c73 100644 --- a/tests/test-suite/goto.js +++ b/tests/test-suite/goto.js @@ -5,7 +5,7 @@ const test = require('tape'); const lua = require('../../src/lua.js'); const lauxlib = require('../../src/lauxlib.js'); const lualib = require('../../src/lualib.js'); - +const {to_luastring} = require("../../src/fengaricore.js"); test("[test-suite] goto: error messages", function (t) { let luaCode = ` @@ -45,7 +45,7 @@ test("[test-suite] goto: error messages", function (t) { until xuxu < x ]], "local 'xuxu'") `, L; - + t.plan(2); t.doesNotThrow(function () { @@ -54,7 +54,7 @@ test("[test-suite] goto: error messages", function (t) { lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(luaCode)); }, "Lua program loaded without error"); @@ -124,7 +124,7 @@ test("[test-suite] goto", function (t) { ::l1:: ; ::l2:: ;; else end `, L; - + t.plan(2); t.doesNotThrow(function () { @@ -133,7 +133,7 @@ test("[test-suite] goto", function (t) { lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(luaCode)); }, "Lua program loaded without error"); @@ -164,7 +164,7 @@ test("[test-suite] goto: to repeat a label in a different function is OK", funct ::l6:: foo() `, L; - + t.plan(2); t.doesNotThrow(function () { @@ -173,7 +173,7 @@ test("[test-suite] goto: to repeat a label in a different function is OK", funct lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(luaCode)); }, "Lua program loaded without error"); @@ -203,7 +203,7 @@ test("[test-suite] goto: bug in 5.2 -> 5.3.2", function (t) { assert(x == 2 and y == true) end `, L; - + t.plan(2); t.doesNotThrow(function () { @@ -212,7 +212,7 @@ test("[test-suite] goto: bug in 5.2 -> 5.3.2", function (t) { lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(luaCode)); }, "Lua program loaded without error"); @@ -288,7 +288,7 @@ test("[test-suite] goto: testing closing of upvalues", function (t) { end end `, L; - + t.plan(2); t.doesNotThrow(function () { @@ -297,7 +297,7 @@ test("[test-suite] goto: testing closing of upvalues", function (t) { lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(luaCode)); }, "Lua program loaded without error"); @@ -342,7 +342,7 @@ test("[test-suite] goto: testing if x goto optimizations", function (t) { assert(testG(4) == 5) assert(testG(5) == 10) `, L; - + t.plan(2); t.doesNotThrow(function () { @@ -351,7 +351,7 @@ test("[test-suite] goto: testing if x goto optimizations", function (t) { lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(luaCode)); }, "Lua program loaded without error"); diff --git a/tests/test-suite/literals.js b/tests/test-suite/literals.js index 0078cf8..6e3205e 100644 --- a/tests/test-suite/literals.js +++ b/tests/test-suite/literals.js @@ -5,7 +5,7 @@ const test = require('tape'); const lua = require('../../src/lua.js'); const lauxlib = require('../../src/lauxlib.js'); const lualib = require('../../src/lualib.js'); - +const {to_luastring} = require("../../src/fengaricore.js"); const dostring = ` local function dostring (x) return assert(load(x), "")() end @@ -16,7 +16,7 @@ test("[test-suite] literals: dostring", function (t) { dostring("x \\v\\f = \\t\\r 'a\\0a' \\v\\f\\f") assert(x == 'a\\0a' and string.len(x) == 3) `, L; - + t.plan(2); t.doesNotThrow(function () { @@ -25,7 +25,7 @@ test("[test-suite] literals: dostring", function (t) { lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(dostring + luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(dostring + luaCode)); }, "Lua program loaded without error"); @@ -46,7 +46,7 @@ test("[test-suite] literals: escape sequences", function (t) { "'\\]]) assert(string.find("\\b\\f\\n\\r\\t\\v", "^%c%c%c%c%c%c$")) `, L; - + t.plan(2); t.doesNotThrow(function () { @@ -55,7 +55,7 @@ test("[test-suite] literals: escape sequences", function (t) { lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(luaCode)); }, "Lua program loaded without error"); @@ -78,7 +78,7 @@ test("[test-suite] literals: assume ASCII just for tests", function (t) { assert(010 .. 020 .. -030 == "1020-30") `, L; - + t.plan(2); t.doesNotThrow(function () { @@ -87,7 +87,7 @@ test("[test-suite] literals: assume ASCII just for tests", function (t) { lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(luaCode)); }, "Lua program loaded without error"); @@ -125,7 +125,7 @@ assert("abc\\z ghi\\z " == 'abcdefghi') `, L; - + t.plan(2); t.doesNotThrow(function () { @@ -134,7 +134,7 @@ assert("abc\\z lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(luaCode)); }, "Lua program loaded without error"); @@ -163,7 +163,7 @@ test("[test-suite] literals: UTF-8 sequences", function (t) { -- limits for 4-byte sequences assert("\\u{10000}\\u{10FFFF}" == "\\xF0\\x90\\x80\\x80\\z\\xF4\\x8F\\xBF\\xBF") `, L; - + t.plan(2); t.doesNotThrow(function () { @@ -172,7 +172,7 @@ test("[test-suite] literals: UTF-8 sequences", function (t) { lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(luaCode)); }, "Lua program loaded without error"); @@ -229,7 +229,7 @@ test("[test-suite] literals: Error in escape sequences", function (t) { lexerror("'alo \\\\z", "<eof>") lexerror([['alo \\98]], "<eof>") `, L; - + t.plan(2); t.doesNotThrow(function () { @@ -238,7 +238,7 @@ test("[test-suite] literals: Error in escape sequences", function (t) { lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(luaCode)); }, "Lua program loaded without error"); @@ -260,7 +260,7 @@ test("[test-suite] literals: valid characters in variable names", function (t) { not load("a" .. s .. "1 = 1", "")) end `, L; - + t.plan(2); t.doesNotThrow(function () { @@ -269,7 +269,7 @@ test("[test-suite] literals: valid characters in variable names", function (t) { lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(luaCode)); }, "Lua program loaded without error"); @@ -295,7 +295,7 @@ test("[test-suite] literals: long variable names", function (t) { assert(_G[var1] == 5 and _G[var2] == 6 and f() == -1) var1, var2, f = nil `, L; - + t.plan(2); t.doesNotThrow(function () { @@ -304,7 +304,7 @@ test("[test-suite] literals: long variable names", function (t) { lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(dostring + luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(dostring + luaCode)); }, "Lua program loaded without error"); @@ -321,7 +321,7 @@ test("[test-suite] literals: escapes", function (t) { let luaCode = `assert("\\n\\t" == [[\n\n\t]]) assert([[\n\n $debug]] == "\\n $debug") assert([[ [ ]] ~= [[ ] ]])`, L; - + t.plan(2); t.doesNotThrow(function () { @@ -330,7 +330,7 @@ assert([[ [ ]] ~= [[ ] ]])`, L; lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(dostring + luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(dostring + luaCode)); }, "Lua program loaded without error"); @@ -396,7 +396,7 @@ assert(x) prog = nil a = nil b = nil`, L; - + t.plan(2); t.doesNotThrow(function () { @@ -405,7 +405,7 @@ b = nil`, L; lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(dostring + luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(dostring + luaCode)); }, "Lua program loaded without error"); @@ -438,7 +438,7 @@ for _, n in pairs{"\\n", "\\r", "\\n\\r", "\\r\\n"} do assert(dostring(prog) == nn) assert(_G.x == "hi\\n" and _G.y == "\\nhello\\r\\n\\n") end`, L; - + t.plan(2); t.doesNotThrow(function () { @@ -447,7 +447,7 @@ end`, L; lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(dostring + luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(dostring + luaCode)); }, "Lua program loaded without error"); @@ -480,7 +480,7 @@ x y z [==[ blu foo ] ]=]==] error error]=]===]`, L; - + t.plan(2); t.doesNotThrow(function () { @@ -489,7 +489,7 @@ error error]=]===]`, L; lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(dostring + luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(dostring + luaCode)); }, "Lua program loaded without error"); @@ -518,7 +518,7 @@ end for s in coroutine.wrap(function () gen("", len) end) do assert(s == load("return [====[\\n"..s.."]====]", "")()) end`, L; - + t.plan(2); t.doesNotThrow(function () { @@ -527,7 +527,7 @@ end`, L; lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(dostring + luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(dostring + luaCode)); }, "Lua program loaded without error"); @@ -547,7 +547,7 @@ test("[test-suite] literals: testing %q x line ends", function (t) { local c = string.format("return %q", s) assert(assert(load(c))() == s) `, L; - + t.plan(2); t.doesNotThrow(function () { @@ -556,7 +556,7 @@ test("[test-suite] literals: testing %q x line ends", function (t) { lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(dostring + luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(dostring + luaCode)); }, "Lua program loaded without error"); @@ -577,7 +577,7 @@ test("[test-suite] literals: testing errors", function (t) { assert(not load"a = '\\\\345'") assert(not load"a = [=x]") `, L; - + t.plan(2); t.doesNotThrow(function () { @@ -586,7 +586,7 @@ test("[test-suite] literals: testing errors", function (t) { lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(dostring + luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(dostring + luaCode)); }, "Lua program loaded without error"); diff --git a/tests/test-suite/locals.js b/tests/test-suite/locals.js index cc82e38..d1dc3e4 100644 --- a/tests/test-suite/locals.js +++ b/tests/test-suite/locals.js @@ -5,7 +5,7 @@ const test = require('tape'); const lua = require('../../src/lua.js'); const lauxlib = require('../../src/lauxlib.js'); const lualib = require('../../src/lualib.js'); - +const {to_luastring} = require("../../src/fengaricore.js"); test('[test-suite] locals: bug in 5.1', function (t) { let luaCode = ` @@ -18,7 +18,7 @@ test('[test-suite] locals: bug in 5.1', function (t) { local function f(x) x = nil; local y; return x, y end assert(f(10) == nil and select(2, f(20)) == nil) `, L; - + t.plan(2); t.doesNotThrow(function () { @@ -27,7 +27,7 @@ test('[test-suite] locals: bug in 5.1', function (t) { lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(luaCode)); }, "Lua program loaded without error"); @@ -90,7 +90,7 @@ test('[test-suite] locals: local scope', function (t) { f(2) assert(type(f) == 'function') `, L; - + t.plan(2); t.doesNotThrow(function () { @@ -99,7 +99,7 @@ test('[test-suite] locals: local scope', function (t) { lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(luaCode)); }, "Lua program loaded without error"); @@ -130,7 +130,7 @@ test('[test-suite] locals: test for global table of loaded chunks', function (t) f() assert(c.a == 3) `, L; - + t.plan(2); t.doesNotThrow(function () { @@ -139,7 +139,7 @@ test('[test-suite] locals: test for global table of loaded chunks', function (t) lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(getenv + luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(getenv + luaCode)); }, "Lua program loaded without error"); @@ -173,7 +173,7 @@ test('[test-suite] locals: old test for limits for special instructions (now jus until p <= 0 end `, L; - + t.plan(2); t.doesNotThrow(function () { @@ -182,7 +182,7 @@ test('[test-suite] locals: old test for limits for special instructions (now jus lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(luaCode)); }, "Lua program loaded without error"); @@ -202,7 +202,7 @@ test('[test-suite] locals: testing lexical environments', function (t) { do local dummy local _ENV = (function (...) return ... end)(_G, dummy) -- { - + do local _ENV = {assert=assert}; assert(true) end mt = {_G = _G} local foo,x @@ -217,7 +217,7 @@ test('[test-suite] locals: testing lexical environments', function (t) { assert(getenv(foo) == mt) x = foo('hi'); assert(mt.A == 'hi' and A == 1000) assert(x('*') == mt.A .. '*') - + do local _ENV = {assert=assert, A=10}; do local _ENV = {assert=assert, A=20}; assert(A==20);x=A @@ -227,7 +227,7 @@ test('[test-suite] locals: testing lexical environments', function (t) { assert(x==20) end `, L; - + t.plan(2); t.doesNotThrow(function () { @@ -236,7 +236,7 @@ test('[test-suite] locals: testing lexical environments', function (t) { lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(getenv + luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(getenv + luaCode)); }, "Lua program loaded without error"); diff --git a/tests/test-suite/ltests.js b/tests/test-suite/ltests.js index 08bb603..11de5c3 100644 --- a/tests/test-suite/ltests.js +++ b/tests/test-suite/ltests.js @@ -4,6 +4,7 @@ const assert = require("assert"); const lua = require('../../src/lua.js'); const lauxlib = require('../../src/lauxlib.js'); +const {luastring_indexOf, to_jsstring, to_luastring} = require("../../src/fengaricore.js"); const ljstype = require('../../src/ljstype.js'); const lopcodes = require('../../src/lopcodes.js'); const sprintf = require('sprintf-js').sprintf; @@ -40,7 +41,7 @@ const getnum = function(L, L1, pc) { pc.offset++; } if (!ljstype.lisdigit(pc.script[pc.offset])) - lauxlib.luaL_error(L, lua.to_luastring("number expected (%s)"), pc.script); + lauxlib.luaL_error(L, to_luastring("number expected (%s)"), pc.script); while (ljstype.lisdigit(pc.script[pc.offset])) res = res*10 + pc.script[pc.offset++] - '0'.charCodeAt(0); return sig*res; }; @@ -52,7 +53,7 @@ const getstring = function(L, buff, pc) { let quote = pc.script[pc.offset++]; while (pc.script[pc.offset] !== quote) { if (pc.script[pc.offset] === 0 || pc.offset >= pc.script.length) - lauxlib.luaL_error(L, lua.to_luastring("unfinished string in JS script", true)); + lauxlib.luaL_error(L, to_luastring("unfinished string in JS script", true)); buff[i++] = pc.script[pc.offset++]; } pc.offset++; @@ -67,13 +68,13 @@ const getindex = function(L, L1, pc) { skip(pc); switch (pc.script[pc.offset++]) { case 'R'.charCodeAt(0): return lua.LUA_REGISTRYINDEX; - case 'G'.charCodeAt(0): return lauxlib.luaL_error(L, lua.to_luastring("deprecated index 'G'", true)); + case 'G'.charCodeAt(0): return lauxlib.luaL_error(L, to_luastring("deprecated index 'G'", true)); case 'U'.charCodeAt(0): return lua.lua_upvalueindex(getnum(L, L1, pc)); default: pc.offset--; return getnum(L, L1, pc); } }; -const codes = ["OK", "YIELD", "ERRRUN", "ERRSYNTAX", "ERRMEM", "ERRGCMM", "ERRERR"].map(e => lua.to_luastring(e)); +const codes = ["OK", "YIELD", "ERRRUN", "ERRSYNTAX", "ERRMEM", "ERRGCMM", "ERRERR"].map(e => to_luastring(e)); const pushcode = function(L, code) { lua.lua_pushstring(L, codes[code]); @@ -82,7 +83,7 @@ const pushcode = function(L, code) { const printstack = function(L) { let n = lua.lua_gettop(L); for (let i = 1; i <= n; i++) { - console.log("${i}: %{lua.to_jsstring(lauxlib.luaL_tolstring(L, i, null))}\n"); + console.log("${i}: %{to_jsstring(lauxlib.luaL_tolstring(L, i, null))}\n"); lua.lua_pop(L, 1); } console.log(""); @@ -101,9 +102,9 @@ const ops = "+-*%^/\\&|~<>_!".split('').map(e => e.charCodeAt(0)); const runJS = function(L, L1, pc) { let buff = new Uint8Array(300); let status = 0; - if (!pc || !pc.script) return lauxlib.luaL_error(L, lua.to_luastring("attempt to runJS null script")); + if (!pc || !pc.script) return lauxlib.luaL_error(L, to_luastring("attempt to runJS null script")); for (;;) { - let inst = lua.to_jsstring(getstring(L, buff, pc)); + let inst = to_jsstring(getstring(L, buff, pc)); if (inst.length === 0) return 0; switch (inst) { case "absindex": { @@ -475,7 +476,7 @@ const runJS = function(L, L1, pc) { return lua.lua_yieldk(L1, nres, i, Cfunck); } default: - lauxlib.luaL_error(L, lua.to_luastring("unknown instruction %s"), buff); + lauxlib.luaL_error(L, to_luastring("unknown instruction %s"), buff); } } }; @@ -552,7 +553,7 @@ const newstate = function(L) { const getstate = function(L) { let L1 = lua.lua_touserdata(L, 1); - lauxlib.luaL_argcheck(L, L1 !== null, 1, lua.to_luastring("state expected", true)); + lauxlib.luaL_argcheck(L, L1 !== null, 1, to_luastring("state expected", true)); return L1; }; @@ -578,16 +579,16 @@ const loadlib = function(L) { "table": luaopen_table }; let L1 = getstate(L); - lauxlib.luaL_requiref(L1, lua.to_luastring("package", true), luaopen_package, 0); + lauxlib.luaL_requiref(L1, to_luastring("package", true), luaopen_package, 0); assert(lua.lua_type(L1, -1) == lua.LUA_TTABLE); /* 'requiref' should not reload module already loaded... */ - lauxlib.luaL_requiref(L1, lua.to_luastring("package", true), null, 1); /* seg. fault if it reloads */ + lauxlib.luaL_requiref(L1, to_luastring("package", true), null, 1); /* seg. fault if it reloads */ /* ...but should return the same module */ assert(lua.lua_compare(L1, -1, -2, lua.LUA_OPEQ)); lauxlib.luaL_getsubtable(L1, lua.LUA_REGISTRYINDEX, lauxlib.LUA_PRELOAD_TABLE); for (let name in libs) { lua.lua_pushcfunction(L1, libs[name]); - lua.lua_setfield(L1, -2, lua.to_luastring(name, true)); + lua.lua_setfield(L1, -2, to_luastring(name, true)); } return 0; }; @@ -637,8 +638,8 @@ const newuserdata = function(L) { */ const Chook = function(L, ar) { let scpt; - let events = ["call", "ret", "line", "count", "tailcall"].map(e => lua.to_luastring(e)); - lua.lua_getfield(L, lua.LUA_REGISTRYINDEX, lua.to_luastring("JS_HOOK", true)); + let events = ["call", "ret", "line", "count", "tailcall"].map(e => to_luastring(e)); + lua.lua_getfield(L, lua.LUA_REGISTRYINDEX, to_luastring("JS_HOOK", true)); lua.lua_pushlightuserdata(L, L); lua.lua_gettable(L, -2); /* get C_HOOK[L] (script saved by sethookaux) */ scpt = lua.lua_tostring(L, -1); /* not very religious (string will be popped) */ @@ -661,7 +662,7 @@ class Aux { const panicback = function(L) { let b = new Aux(); lua.lua_checkstack(L, 1); /* open space for 'Aux' struct */ - lua.lua_getfield(L, lua.LUA_REGISTRYINDEX, lua.to_luastring("_jmpbuf", true)); /* get 'Aux' struct */ + lua.lua_getfield(L, lua.LUA_REGISTRYINDEX, to_luastring("_jmpbuf", true)); /* get 'Aux' struct */ b = lua.lua_touserdata(L, -1); lua.lua_pop(L, 1); /* remove 'Aux' struct */ runJS(b.L, L, { script: b.paniccode, offset: 0 }); /* run optional panic code */ @@ -671,7 +672,7 @@ const panicback = function(L) { const checkpanic = function(L) { let b = new Aux(); let code = lauxlib.luaL_checkstring(L, 1); - b.paniccode = lauxlib.luaL_optstring(L, 2, lua.to_luastring("", true)); + b.paniccode = lauxlib.luaL_optstring(L, 2, to_luastring("", true)); b.L = L; let L1 = lua.lua_newstate(); /* create new state */ if (L1 === null) { /* error? */ @@ -680,7 +681,7 @@ const checkpanic = function(L) { } lua.lua_atpanic(L1, panicback); /* set its panic function */ lua.lua_pushlightuserdata(L1, b); - lua.lua_setfield(L1, lua.LUA_REGISTRYINDEX, lua.to_luastring("_jmpbuf", true)); /* store 'Aux' struct */ + lua.lua_setfield(L1, lua.LUA_REGISTRYINDEX, to_luastring("_jmpbuf", true)); /* store 'Aux' struct */ try { /* set jump buffer */ runJS(L, L1, { script: code, offset: 0 }); /* run code unprotected */ lua.lua_pushliteral(L, "no errors"); @@ -700,12 +701,12 @@ const sethookaux = function(L, mask, count, scpt) { lua.lua_sethook(L, null, 0, 0); /* turn off hooks */ return; } - lua.lua_getfield(L, lua.LUA_REGISTRYINDEX, lua.to_luastring("JS_HOOK", true)); /* get C_HOOK table */ + lua.lua_getfield(L, lua.LUA_REGISTRYINDEX, to_luastring("JS_HOOK", true)); /* get C_HOOK table */ if (!lua.lua_istable(L, -1)) { /* no hook table? */ lua.lua_pop(L, 1); /* remove previous value */ lua.lua_newtable(L); /* create new C_HOOK table */ lua.lua_pushvalue(L, -1); - lua.lua_setfield(L, lua.LUA_REGISTRYINDEX, lua.to_luastring("JS_HOOK", true)); /* register it */ + lua.lua_setfield(L, lua.LUA_REGISTRYINDEX, to_luastring("JS_HOOK", true)); /* register it */ } lua.lua_pushlightuserdata(L, L); lua.lua_pushstring(L, scpt); @@ -721,9 +722,9 @@ const sethook = function(L) { const smask = lauxlib.luaL_checkstring(L, 2); let count = lauxlib.luaL_optinteger(L, 3, 0); let mask = 0; - if (smask.indexOf('c'.charCodeAt(0)) >= 0) mask |= lua.LUA_MASKCALL; - if (smask.indexOf('r'.charCodeAt(0)) >= 0) mask |= lua.LUA_MASKRET; - if (smask.indexOf('l'.charCodeAt(0)) >= 0) mask |= lua.LUA_MASKLINE; + if (luastring_indexOf(smask, 'c'.charCodeAt(0)) >= 0) mask |= lua.LUA_MASKCALL; + if (luastring_indexOf(smask, 'r'.charCodeAt(0)) >= 0) mask |= lua.LUA_MASKRET; + if (luastring_indexOf(smask, 'l'.charCodeAt(0)) >= 0) mask |= lua.LUA_MASKLINE; if (count > 0) mask |= lua.LUA_MASKCOUNT; sethookaux(L, mask, count, scpt); } @@ -736,9 +737,9 @@ const Cfunc = function(L) { const Cfunck = function(L, status, ctx) { pushcode(L, status); - lua.lua_setglobal(L, lua.to_luastring("status", true)); + lua.lua_setglobal(L, to_luastring("status", true)); lua.lua_pushinteger(L, ctx); - lua.lua_setglobal(L, lua.to_luastring("ctx", true)); + lua.lua_setglobal(L, to_luastring("ctx", true)); return runJS(L, L, { script: lua.lua_tostring(L, ctx), offset: 0 }); }; @@ -751,7 +752,7 @@ const makeCfunc = function(L) { const coresume = function(L) { let status; let co = lua.lua_tothread(L, 1); - lauxlib.luaL_argcheck(L, co, 1, lua.to_luastring("coroutine expected", true)); + lauxlib.luaL_argcheck(L, co, 1, to_luastring("coroutine expected", true)); status = lua.lua_resume(co, L, 0); if (status != lua.LUA_OK && status !== lua.LUA_YIELD) { lua.lua_pushboolean(L, 0); @@ -800,16 +801,16 @@ const buildop = function(p, pc) { break; } - return lua.to_luastring(result); + return to_luastring(result); }; const listcode = function(L) { lauxlib.luaL_argcheck(L, lua.lua_isfunction(L, 1) && !lua.lua_iscfunction(L, 1), - 1, lua.to_luastring("Lua function expected", true)); + 1, to_luastring("Lua function expected", true)); let p = obj_at(L, 1); lua.lua_newtable(L); - setnameval(L, lua.to_luastring("maxstack", true), p.maxstacksize); - setnameval(L, lua.to_luastring("numparams", true), p.numparams); + setnameval(L, to_luastring("maxstack", true), p.maxstacksize); + setnameval(L, to_luastring("numparams", true), p.numparams); for (let pc = 0; pc < p.code.length; pc++) { lua.lua_pushinteger(L, pc+1); lua.lua_pushstring(L, buildop(p, pc)); @@ -821,7 +822,7 @@ const listcode = function(L) { const listk = function(L) { lauxlib.luaL_argcheck(L, lua.lua_isfunction(L, 1) && !lua.lua_iscfunction(L, 1), - 1, lua.to_luastring("Lua function expected"), true); + 1, to_luastring("Lua function expected"), true); let p = obj_at(L, 1); lua.lua_createtable(L, p.k.length, 0); for (let i = 0; i < p.k.length; i++) { @@ -859,7 +860,7 @@ const luaB_opentests = function(L) { }; const luaopen_tests = function(L) { - lauxlib.luaL_requiref(L, lua.to_luastring("T"), luaB_opentests, 1); + lauxlib.luaL_requiref(L, to_luastring("T"), luaB_opentests, 1); lua.lua_pop(L, 1); /* remove lib */ }; diff --git a/tests/test-suite/math.js b/tests/test-suite/math.js index 0052bc2..9fb6fa5 100644 --- a/tests/test-suite/math.js +++ b/tests/test-suite/math.js @@ -5,7 +5,7 @@ const test = require('tape'); const lua = require('../../src/lua.js'); const lauxlib = require('../../src/lauxlib.js'); const lualib = require('../../src/lualib.js'); - +const {to_luastring} = require("../../src/fengaricore.js"); const prefix = ` local minint = math.mininteger @@ -59,7 +59,7 @@ test("[test-suite] math: int bits", function (t) { assert(minint == 1 << (intbits - 1)) assert(maxint == minint - 1) `, L; - + t.plan(2); t.doesNotThrow(function () { @@ -68,7 +68,7 @@ test("[test-suite] math: int bits", function (t) { lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(prefix + luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(prefix + luaCode)); }, "Lua program loaded without error"); @@ -98,7 +98,7 @@ test("[test-suite] math: number of bits in the mantissa of a floating-point numb assert(math.type(0) == "integer" and math.type(0.0) == "float" and math.type("10") == nil) `, L; - + t.plan(2); t.doesNotThrow(function () { @@ -107,7 +107,7 @@ test("[test-suite] math: number of bits in the mantissa of a floating-point numb lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(prefix + luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(prefix + luaCode)); }, "Lua program loaded without error"); @@ -162,7 +162,7 @@ test("[test-suite] math: basic float notation", function (t) { assert(eqT(a, minint) and eqT(b, 0.0)) end `, L; - + t.plan(2); t.doesNotThrow(function () { @@ -171,7 +171,7 @@ test("[test-suite] math: basic float notation", function (t) { lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(prefix + luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(prefix + luaCode)); }, "Lua program loaded without error"); @@ -189,7 +189,7 @@ test("[test-suite] math: math.huge", function (t) { assert(math.huge > 10e30) assert(-math.huge < -10e30) `, L; - + t.plan(2); t.doesNotThrow(function () { @@ -198,7 +198,7 @@ test("[test-suite] math: math.huge", function (t) { lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(prefix + luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(prefix + luaCode)); }, "Lua program loaded without error"); @@ -219,7 +219,7 @@ test("[test-suite] math: integer arithmetic", function (t) { assert(minint * minint == 0) assert(maxint * maxint * maxint == maxint) `, L; - + t.plan(2); t.doesNotThrow(function () { @@ -228,7 +228,7 @@ test("[test-suite] math: integer arithmetic", function (t) { lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(prefix + luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(prefix + luaCode)); }, "Lua program loaded without error"); @@ -274,7 +274,7 @@ test("[test-suite] math: testing floor division and conversions", function (t) { assert(minint // -2 == 2^(intbits - 2)) assert(maxint // -1 == -maxint) `, L; - + t.plan(2); t.doesNotThrow(function () { @@ -283,7 +283,7 @@ test("[test-suite] math: testing floor division and conversions", function (t) { lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(prefix + luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(prefix + luaCode)); }, "Lua program loaded without error"); @@ -311,7 +311,7 @@ test("[test-suite] math: negative exponents", function (t) { end end `, L; - + t.plan(2); t.doesNotThrow(function () { @@ -320,7 +320,7 @@ test("[test-suite] math: negative exponents", function (t) { lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(prefix + luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(prefix + luaCode)); }, "Lua program loaded without error"); @@ -351,7 +351,7 @@ test("[test-suite] math: comparison between floats and integers (border cases)", assert(minint + 0.0 == minint) assert(minint + 0.0 == -2.0^(intbits - 1)) `, L; - + t.plan(2); t.doesNotThrow(function () { @@ -360,7 +360,7 @@ test("[test-suite] math: comparison between floats and integers (border cases)", lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(prefix + luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(prefix + luaCode)); }, "Lua program loaded without error"); @@ -460,7 +460,7 @@ test("[test-suite] math: order between floats and integers", function (t) { assert(not (minint < NaN)) end `, L; - + t.plan(2); t.doesNotThrow(function () { @@ -469,7 +469,7 @@ test("[test-suite] math: order between floats and integers", function (t) { lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(prefix + luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(prefix + luaCode)); }, "Lua program loaded without error"); @@ -491,7 +491,7 @@ test("[test-suite] math: avoiding errors at compile time", function (t) { checkcompt(msgf2i, ("return 1 | 2.0^%d"):format(intbits - 1)) checkcompt(msgf2i, "return 2.3 ~ '0.0'") `, L; - + t.plan(2); t.doesNotThrow(function () { @@ -500,7 +500,7 @@ test("[test-suite] math: avoiding errors at compile time", function (t) { lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(prefix + luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(prefix + luaCode)); }, "Lua program loaded without error"); @@ -544,7 +544,7 @@ test("[test-suite] math: testing overflow errors when converting from float to i -- 'minint' should be representable as a float no matter the precision assert(f2i(minint + 0.0) == minint) `, L; - + t.plan(2); t.doesNotThrow(function () { @@ -553,7 +553,7 @@ test("[test-suite] math: testing overflow errors when converting from float to i lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(prefix + luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(prefix + luaCode)); }, "Lua program loaded without error"); @@ -573,7 +573,7 @@ test("[test-suite] math: testing numeric strings", function (t) { assert(" -2 " + 1 == -1) assert(" -0xa " + 1 == -9) `, L; - + t.plan(2); t.doesNotThrow(function () { @@ -582,7 +582,7 @@ test("[test-suite] math: testing numeric strings", function (t) { lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(prefix + luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(prefix + luaCode)); }, "Lua program loaded without error"); @@ -631,7 +631,7 @@ test("[test-suite] math: Literal integer Overflows (new behavior in 5.3.3)", fun assert(eqT(-10000000000000000000000.0, -10000000000000000000000)) end `, L; - + t.plan(2); t.doesNotThrow(function () { @@ -640,7 +640,7 @@ test("[test-suite] math: Literal integer Overflows (new behavior in 5.3.3)", fun lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(prefix + luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(prefix + luaCode)); }, "Lua program loaded without error"); @@ -660,7 +660,7 @@ test("[test-suite] math: 'tonumber' with numbers", function (t) { assert(eqT(tonumber(maxint), maxint) and eqT(tonumber(minint), minint)) assert(tonumber(1/0) == 1/0) `, L; - + t.plan(2); t.doesNotThrow(function () { @@ -669,7 +669,7 @@ test("[test-suite] math: 'tonumber' with numbers", function (t) { lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(prefix + luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(prefix + luaCode)); }, "Lua program loaded without error"); @@ -722,7 +722,7 @@ test("[test-suite] math: 'tonumber' with strings", function (t) { assert(tonumber('\\t10000000000\\t', i) == i10) end `, L; - + t.plan(2); t.doesNotThrow(function () { @@ -731,7 +731,7 @@ test("[test-suite] math: 'tonumber' with strings", function (t) { lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(prefix + luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(prefix + luaCode)); }, "Lua program loaded without error"); @@ -760,7 +760,7 @@ test("[test-suite] math: tests with very long numerals", function (t) { assert(tonumber('0xe03' .. string.rep('0', 1000) .. 'p-4000') == 3587.0) assert(tonumber('0x.' .. string.rep('0', 1000) .. '74p4004') == 0x7.4) `, L; - + t.plan(2); t.doesNotThrow(function () { @@ -769,7 +769,7 @@ test("[test-suite] math: tests with very long numerals", function (t) { lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(prefix + luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(prefix + luaCode)); }, "Lua program loaded without error"); @@ -816,7 +816,7 @@ test("[test-suite] math: testing 'tonumber' for invalid formats", function (t) { assert(f(tonumber('e 1')) == nil) assert(f(tonumber(' 3.4.5 ')) == nil) `, L; - + t.plan(2); t.doesNotThrow(function () { @@ -825,7 +825,7 @@ test("[test-suite] math: testing 'tonumber' for invalid formats", function (t) { lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(prefix + luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(prefix + luaCode)); }, "Lua program loaded without error"); @@ -853,7 +853,7 @@ test("[test-suite] math: testing 'tonumber' for invalid hexadecimal formats", fu assert(tonumber('0x0.51p') == nil) assert(tonumber('0x5p+-2') == nil) `, L; - + t.plan(2); t.doesNotThrow(function () { @@ -862,7 +862,7 @@ test("[test-suite] math: testing 'tonumber' for invalid hexadecimal formats", fu lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(prefix + luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(prefix + luaCode)); }, "Lua program loaded without error"); @@ -887,7 +887,7 @@ test("[test-suite] math: testing hexadecimal numerals", function (t) { -- possible confusion with decimal exponent assert(0E+1 == 0 and 0xE+1 == 15 and 0xe-1 == 13) `, L; - + t.plan(2); t.doesNotThrow(function () { @@ -896,7 +896,7 @@ test("[test-suite] math: testing hexadecimal numerals", function (t) { lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(prefix + luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(prefix + luaCode)); }, "Lua program loaded without error"); @@ -935,7 +935,7 @@ test("[test-suite] math: floating hexas", function (t) { assert(tonumber('+1.23E18') == 1.23*10.0^18) `, L; - + t.plan(2); t.doesNotThrow(function () { @@ -944,7 +944,7 @@ test("[test-suite] math: floating hexas", function (t) { lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(prefix + luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(prefix + luaCode)); }, "Lua program loaded without error"); @@ -969,7 +969,7 @@ test("[test-suite] math: testing order operators", function (t) { assert(('a'>='a') and not('a'>='b') and ('b'>='a')) assert(1.3 < 1.4 and 1.3 <= 1.4 and not (1.3 < 1.3) and 1.3 <= 1.3) `, L; - + t.plan(2); t.doesNotThrow(function () { @@ -978,7 +978,7 @@ test("[test-suite] math: testing order operators", function (t) { lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(prefix + luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(prefix + luaCode)); }, "Lua program loaded without error"); @@ -1010,7 +1010,7 @@ test("[test-suite] math: testing mod operator", function (t) { assert(minint % -2 == 0) assert(maxint % -2 == -1) `, L; - + t.plan(2); t.doesNotThrow(function () { @@ -1019,7 +1019,7 @@ test("[test-suite] math: testing mod operator", function (t) { lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(prefix + luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(prefix + luaCode)); }, "Lua program loaded without error"); @@ -1047,7 +1047,7 @@ test("[test-suite] math: non-portable tests because Windows C library cannot com assert(-1 % math.huge == math.huge) assert(-1 % -math.huge == -1) `, L; - + t.plan(2); t.doesNotThrow(function () { @@ -1056,7 +1056,7 @@ test("[test-suite] math: non-portable tests because Windows C library cannot com lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(prefix + luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(prefix + luaCode)); }, "Lua program loaded without error"); @@ -1103,7 +1103,7 @@ test("[test-suite] math: testing unsigned comparisons", function (t) { assert(tonumber(' 1.3e-2 ') == 1.3e-2) assert(tonumber(' -1.00000000000001 ') == -1.00000000000001) `, L; - + t.plan(2); t.doesNotThrow(function () { @@ -1112,7 +1112,7 @@ test("[test-suite] math: testing unsigned comparisons", function (t) { lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(prefix + luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(prefix + luaCode)); }, "Lua program loaded without error"); @@ -1131,7 +1131,7 @@ test("[test-suite] math: testing constant limits", function (t) { assert(8388608 + -8388608 == 0) assert(8388607 + -8388607 == 0) `, L; - + t.plan(2); t.doesNotThrow(function () { @@ -1140,7 +1140,7 @@ test("[test-suite] math: testing constant limits", function (t) { lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(prefix + luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(prefix + luaCode)); }, "Lua program loaded without error"); @@ -1198,7 +1198,7 @@ test("[test-suite] math: testing floor & ceil", function (t) { assert(math.tointeger(0/0) == nil) -- NaN end `, L; - + t.plan(2); t.doesNotThrow(function () { @@ -1207,7 +1207,7 @@ test("[test-suite] math: testing floor & ceil", function (t) { lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(prefix + luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(prefix + luaCode)); }, "Lua program loaded without error"); @@ -1242,7 +1242,7 @@ test("[test-suite] math: testing fmod for integers", function (t) { checkerror("zero", math.fmod, 3, 0) `, L; - + t.plan(2); t.doesNotThrow(function () { @@ -1251,7 +1251,7 @@ test("[test-suite] math: testing fmod for integers", function (t) { lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(prefix + luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(prefix + luaCode)); }, "Lua program loaded without error"); @@ -1282,7 +1282,7 @@ test("[test-suite] math: testing max/min", function (t) { assert(eqT(math.min(maxint - 2, maxint, maxint - 1), maxint - 2)) end `, L; - + t.plan(2); t.doesNotThrow(function () { @@ -1291,7 +1291,7 @@ test("[test-suite] math: testing max/min", function (t) { lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(prefix + luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(prefix + luaCode)); }, "Lua program loaded without error"); @@ -1310,7 +1310,7 @@ test("[test-suite] math: testing implicit convertions", function (t) { assert(a*b == 200 and a+b == 30 and a-b == -10 and a/b == 0.5 and -b == -20) assert(a == '10' and b == '20') `, L; - + t.plan(2); t.doesNotThrow(function () { @@ -1319,7 +1319,7 @@ test("[test-suite] math: testing implicit convertions", function (t) { lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(prefix + luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(prefix + luaCode)); }, "Lua program loaded without error"); @@ -1369,7 +1369,7 @@ test("[test-suite] math: testing -0 and NaN", function (t) { assert(a3 == a5) end `, L; - + t.plan(2); t.doesNotThrow(function () { @@ -1378,7 +1378,7 @@ test("[test-suite] math: testing -0 and NaN", function (t) { lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(prefix + luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(prefix + luaCode)); }, "Lua program loaded without error"); @@ -1410,7 +1410,7 @@ test("[test-suite] math: test random for floats", function (t) { ::ok:: end `, L; - + t.plan(2); t.doesNotThrow(function () { @@ -1419,7 +1419,7 @@ test("[test-suite] math: test random for floats", function (t) { lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(prefix + luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(prefix + luaCode)); }, "Lua program loaded without error"); @@ -1466,7 +1466,7 @@ test("[test-suite] math: test random for small intervals", function (t) { aux({maxint - 3, maxint}) end `, L; - + t.plan(2); t.doesNotThrow(function () { @@ -1475,7 +1475,7 @@ test("[test-suite] math: test random for small intervals", function (t) { lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(prefix + luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(prefix + luaCode)); }, "Lua program loaded without error"); @@ -1524,7 +1524,7 @@ test("[test-suite] math: test random for large intervals", function (t) { assert(not pcall(math.random, 1, 2, 3)) -- too many arguments `, L; - + t.plan(2); t.doesNotThrow(function () { @@ -1533,7 +1533,7 @@ test("[test-suite] math: test random for large intervals", function (t) { lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(prefix + luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(prefix + luaCode)); }, "Lua program loaded without error"); @@ -1552,7 +1552,7 @@ test("[test-suite] math: test random for empty interval", function (t) { assert(not pcall(math.random, maxint, maxint - 1)) assert(not pcall(math.random, maxint, minint)) `, L; - + t.plan(2); t.doesNotThrow(function () { @@ -1561,7 +1561,7 @@ test("[test-suite] math: test random for empty interval", function (t) { lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(prefix + luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(prefix + luaCode)); }, "Lua program loaded without error"); @@ -1580,7 +1580,7 @@ test("[test-suite] math: interval too large", function (t) { assert(not pcall(math.random, -1, maxint)) assert(not pcall(math.random, minint // 2, maxint // 2 + 1)) `, L; - + t.plan(2); t.doesNotThrow(function () { @@ -1589,7 +1589,7 @@ test("[test-suite] math: interval too large", function (t) { lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(prefix + luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(prefix + luaCode)); }, "Lua program loaded without error"); diff --git a/tests/test-suite/nextvar.js b/tests/test-suite/nextvar.js index ad75f93..3e05490 100644 --- a/tests/test-suite/nextvar.js +++ b/tests/test-suite/nextvar.js @@ -5,7 +5,7 @@ const test = require('tape'); const lua = require('../../src/lua.js'); const lauxlib = require('../../src/lauxlib.js'); const lualib = require('../../src/lualib.js'); - +const {to_luastring} = require("../../src/fengaricore.js"); const prefix = ` local function checkerror (msg, f, ...) @@ -27,7 +27,7 @@ test("[test-suite] nextvar: testing size operator", function (t) { assert(#a == i) end `, L; - + t.plan(2); t.doesNotThrow(function () { @@ -36,7 +36,7 @@ test("[test-suite] nextvar: testing size operator", function (t) { lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(prefix + luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(prefix + luaCode)); }, "Lua program loaded without error"); @@ -59,7 +59,7 @@ test("[test-suite] nextvar: testing ipairs", function (t) { for _ in ipairs{x=12, y=24} do assert(nil) end `, L; - + t.plan(2); t.doesNotThrow(function () { @@ -68,7 +68,7 @@ test("[test-suite] nextvar: testing ipairs", function (t) { lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(prefix + luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(prefix + luaCode)); }, "Lua program loaded without error"); @@ -92,7 +92,7 @@ test("[test-suite] nextvar: test for 'false' x ipair", function (t) { end assert(i == 4) `, L; - + t.plan(2); t.doesNotThrow(function () { @@ -101,7 +101,7 @@ test("[test-suite] nextvar: test for 'false' x ipair", function (t) { lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(prefix + luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(prefix + luaCode)); }, "Lua program loaded without error"); @@ -118,7 +118,7 @@ test("[test-suite] nextvar: iterator function is always the same", function (t) let luaCode = ` assert(type(ipairs{}) == 'function' and ipairs{} == ipairs{}) `, L; - + t.plan(2); t.doesNotThrow(function () { @@ -127,7 +127,7 @@ test("[test-suite] nextvar: iterator function is always the same", function (t) lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(prefix + luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(prefix + luaCode)); }, "Lua program loaded without error"); @@ -171,7 +171,7 @@ test("[test-suite] nextvar: JS tests", { skip: true }, function (t) { a = math.ceil(a*1.3) end - + local function check (t, na, nh) local a, h = T.querytab(t) if a ~= na or h ~= nh then @@ -195,7 +195,7 @@ test("[test-suite] nextvar: JS tests", { skip: true }, function (t) { for i=1,lim do s = s..i..',' local s = s - for k=0,lim do + for k=0,lim do local t = load(s..'}', '')() assert(#t == i) check(t, fb(i), mp2(k)) @@ -272,7 +272,7 @@ test("[test-suite] nextvar: JS tests", { skip: true }, function (t) { local a = {} for i=1,lim do a[i] = true; foo(i, table.unpack(a)) end `, L; - + t.plan(2); t.doesNotThrow(function () { @@ -281,7 +281,7 @@ test("[test-suite] nextvar: JS tests", { skip: true }, function (t) { lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(prefix + luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(prefix + luaCode)); }, "Lua program loaded without error"); @@ -302,7 +302,7 @@ test("[test-suite] nextvar: test size operation on empty tables", function (t) { assert(#{nil, nil, nil} == 0) assert(#{nil, nil, nil, nil} == 0) `, L; - + t.plan(2); t.doesNotThrow(function () { @@ -311,7 +311,7 @@ test("[test-suite] nextvar: test size operation on empty tables", function (t) { lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(prefix + luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(prefix + luaCode)); }, "Lua program loaded without error"); @@ -332,7 +332,7 @@ test("[test-suite] nextvar: test size operation on empty tables", function (t) { assert(#{nil, nil, nil} == 0) assert(#{nil, nil, nil, nil} == 0) `, L; - + t.plan(2); t.doesNotThrow(function () { @@ -341,7 +341,7 @@ test("[test-suite] nextvar: test size operation on empty tables", function (t) { lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(prefix + luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(prefix + luaCode)); }, "Lua program loaded without error"); @@ -393,7 +393,7 @@ test("[test-suite] nextvar: next uses always the same iteration function", funct _G["xxx"] = 1 assert(xxx==find("xxx")) `, L; - + t.plan(2); t.doesNotThrow(function () { @@ -402,7 +402,7 @@ test("[test-suite] nextvar: next uses always the same iteration function", funct lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(prefix + luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(prefix + luaCode)); }, "Lua program loaded without error"); @@ -419,7 +419,7 @@ test("[test-suite] nextvar: invalid key to 'next'", function (t) { let luaCode = ` checkerror("invalid key", next, {10,20}, 3) `, L; - + t.plan(2); t.doesNotThrow(function () { @@ -428,7 +428,7 @@ test("[test-suite] nextvar: invalid key to 'next'", function (t) { lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(prefix + luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(prefix + luaCode)); }, "Lua program loaded without error"); @@ -446,7 +446,7 @@ test("[test-suite] nextvar: both 'pairs' and 'ipairs' need an argument", functio checkerror("bad argument", pairs) checkerror("bad argument", ipairs) `, L; - + t.plan(2); t.doesNotThrow(function () { @@ -455,7 +455,7 @@ test("[test-suite] nextvar: both 'pairs' and 'ipairs' need an argument", functio lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(prefix + luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(prefix + luaCode)); }, "Lua program loaded without error"); @@ -485,7 +485,7 @@ test("[test-suite] nextvar: fmod table", function (t) { assert(n.n == 9000) a = nil `, L; - + t.plan(2); t.doesNotThrow(function () { @@ -494,7 +494,7 @@ test("[test-suite] nextvar: fmod table", function (t) { lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(prefix + luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(prefix + luaCode)); }, "Lua program loaded without error"); @@ -522,7 +522,7 @@ test("[test-suite] nextvar: check next", function (t) { checknext{1,2,3,4,x=1,y=2,z=3} checknext{1,2,3,4,5,x=1,y=2,z=3} `, L; - + t.plan(2); t.doesNotThrow(function () { @@ -531,7 +531,7 @@ test("[test-suite] nextvar: check next", function (t) { lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(prefix + luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(prefix + luaCode)); }, "Lua program loaded without error"); @@ -555,7 +555,7 @@ test("[test-suite] nextvar: # operator", function (t) { assert(#a == i) end `, L; - + t.plan(2); t.doesNotThrow(function () { @@ -564,7 +564,7 @@ test("[test-suite] nextvar: # operator", function (t) { lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(prefix + luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(prefix + luaCode)); }, "Lua program loaded without error"); @@ -596,7 +596,7 @@ test("[test-suite] nextvar: maxn", function (t) { table.maxn = nil `, L; - + t.plan(2); t.doesNotThrow(function () { @@ -605,7 +605,7 @@ test("[test-suite] nextvar: maxn", function (t) { lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(prefix + luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(prefix + luaCode)); }, "Lua program loaded without error"); @@ -624,7 +624,7 @@ test("[test-suite] nextvar: int overflow", function (t) { for i=0,50 do a[2^i] = true end assert(a[#a]) `, L; - + t.plan(2); t.doesNotThrow(function () { @@ -633,7 +633,7 @@ test("[test-suite] nextvar: int overflow", function (t) { lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(prefix + luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(prefix + luaCode)); }, "Lua program loaded without error"); @@ -721,7 +721,7 @@ test("[test-suite] nextvar: erasing values", function (t) { assert(table.remove(a, 2) == 20) assert(a[#a] == 30 and #a == 2) `, L; - + t.plan(2); t.doesNotThrow(function () { @@ -730,7 +730,7 @@ test("[test-suite] nextvar: erasing values", function (t) { lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(prefix + luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(prefix + luaCode)); }, "Lua program loaded without error"); @@ -791,7 +791,7 @@ test("[test-suite] nextvar: testing table library with metamethods", function (t end `, L; - + t.plan(2); t.doesNotThrow(function () { @@ -800,7 +800,7 @@ test("[test-suite] nextvar: testing table library with metamethods", function (t lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(prefix + luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(prefix + luaCode)); }, "Lua program loaded without error"); @@ -839,12 +839,12 @@ test("[test-suite] nextvar: JS tests", { skip: true }, function (t) { mt.__newindex = nil mt.__len = nil local tab2 = {} - local u2 = T.newuserdata(0) + local u2 = T.newuserdata(0) debug.setmetatable(u2, {__newindex = function (_, k, v) tab2[k] = v end}) table.move(u, 1, 4, 1, u2) assert(#tab2 == 4 and tab2[1] == tab[1] and tab2[4] == tab[4]) `, L; - + t.plan(2); t.doesNotThrow(function () { @@ -853,7 +853,7 @@ test("[test-suite] nextvar: JS tests", { skip: true }, function (t) { lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(prefix + luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(prefix + luaCode)); }, "Lua program loaded without error"); @@ -883,7 +883,7 @@ test("[test-suite] nextvar: next", function (t) { a = nil; for i=1,1 do assert(not a); a=1 end; assert(a) a = nil; for i=1,1,-1 do assert(not a); a=1 end; assert(a) `, L; - + t.plan(2); t.doesNotThrow(function () { @@ -892,7 +892,7 @@ test("[test-suite] nextvar: next", function (t) { lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(prefix + luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(prefix + luaCode)); }, "Lua program loaded without error"); @@ -926,7 +926,7 @@ test("[test-suite] nextvar: testing floats in numeric for", function (t) { a = 0; for i=1.0, 0.99999, -1 do a=a+1 end; assert(a==1) end `, L; - + t.plan(2); t.doesNotThrow(function () { @@ -935,7 +935,7 @@ test("[test-suite] nextvar: testing floats in numeric for", function (t) { lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(prefix + luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(prefix + luaCode)); }, "Lua program loaded without error"); @@ -952,7 +952,7 @@ test("[test-suite] nextvar: conversion", function (t) { let luaCode = ` a = 0; for i="10","1","-2" do a=a+1 end; assert(a==5) `, L; - + t.plan(2); t.doesNotThrow(function () { @@ -961,7 +961,7 @@ test("[test-suite] nextvar: conversion", function (t) { lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(prefix + luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(prefix + luaCode)); }, "Lua program loaded without error"); @@ -1030,7 +1030,7 @@ test("[test-suite] nextvar: checking types", function (t) { end `, L; - + t.plan(2); t.doesNotThrow(function () { @@ -1039,7 +1039,7 @@ test("[test-suite] nextvar: checking types", function (t) { lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(prefix + luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(prefix + luaCode)); }, "Lua program loaded without error"); @@ -1071,7 +1071,7 @@ test("[test-suite] nextvar: testing generic 'for'", function (t) { end assert(x == 5) `, L; - + t.plan(2); t.doesNotThrow(function () { @@ -1080,7 +1080,7 @@ test("[test-suite] nextvar: testing generic 'for'", function (t) { lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(prefix + luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(prefix + luaCode)); }, "Lua program loaded without error"); @@ -1123,7 +1123,7 @@ test("[test-suite] nextvar: testing __pairs and __ipairs metamethod", function ( a.n = 5 a[3] = 30 `, L; - + t.plan(2); t.doesNotThrow(function () { @@ -1132,7 +1132,7 @@ test("[test-suite] nextvar: testing __pairs and __ipairs metamethod", function ( lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(prefix + luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(prefix + luaCode)); }, "Lua program loaded without error"); @@ -1149,7 +1149,7 @@ test("[test-suite] nextvar: testing ipairs with metamethods", function (t) { let luaCode = ` a = {n=10} setmetatable(a, { __index = function (t,k) - if k <= t.n then return k * 10 end + if k <= t.n then return k * 10 end end}) i = 0 for k,v in ipairs(a) do @@ -1158,7 +1158,7 @@ test("[test-suite] nextvar: testing ipairs with metamethods", function (t) { end assert(i == a.n) `, L; - + t.plan(2); t.doesNotThrow(function () { @@ -1167,7 +1167,7 @@ test("[test-suite] nextvar: testing ipairs with metamethods", function (t) { lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(prefix + luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(prefix + luaCode)); }, "Lua program loaded without error"); diff --git a/tests/test-suite/pm.js b/tests/test-suite/pm.js index ae3512e..214d498 100644 --- a/tests/test-suite/pm.js +++ b/tests/test-suite/pm.js @@ -5,7 +5,7 @@ const test = require('tape'); const lua = require('../../src/lua.js'); const lauxlib = require('../../src/lauxlib.js'); const lualib = require('../../src/lualib.js'); - +const {to_luastring} = require("../../src/fengaricore.js"); test("[test-suite] pm: pattern matching", function (t) { let luaCode = ` @@ -86,7 +86,7 @@ test("[test-suite] pm: pattern matching", function (t) { assert(f("0alo alo", "%x*") == "0a") assert(f("alo alo", "%C+") == "alo alo") `, L; - + t.plan(2); t.doesNotThrow(function () { @@ -95,7 +95,7 @@ test("[test-suite] pm: pattern matching", function (t) { lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(luaCode)); }, "Lua program loaded without error"); @@ -125,7 +125,7 @@ test("[test-suite] pm: tonumber", function (t) { -- assert(f1('=======', '^(=*)=%1$') == '=======') assert(string.match('==========', '^([=]*)=%1$') == nil) `, L; - + t.plan(2); t.doesNotThrow(function () { @@ -134,7 +134,7 @@ test("[test-suite] pm: tonumber", function (t) { lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(luaCode)); }, "Lua program loaded without error"); @@ -177,7 +177,7 @@ test("[test-suite] pm: range", function (t) { assert(strset('%Z') == strset('[\\1-\\255]')) assert(strset('.') == strset('[\\1-\\255%z]')) `, L; - + t.plan(2); t.doesNotThrow(function () { @@ -186,7 +186,7 @@ test("[test-suite] pm: range", function (t) { lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(luaCode)); }, "Lua program loaded without error"); @@ -210,7 +210,7 @@ test("[test-suite] pm: classes", function (t) { lualib.luaL_openlibs(L); - lauxlib.luaL_loadfile(L, lua.to_luastring("tests/test-suite/pm-classes.lua")); + lauxlib.luaL_loadfile(L, to_luastring("tests/test-suite/pm-classes.lua")); }, "Lua program loaded without error"); @@ -234,7 +234,7 @@ test("[test-suite] pm: gsub", function (t) { lualib.luaL_openlibs(L); - lauxlib.luaL_loadfile(L, lua.to_luastring("tests/test-suite/pm-gsub.lua")); + lauxlib.luaL_loadfile(L, to_luastring("tests/test-suite/pm-gsub.lua")); }, "Lua program loaded without error"); @@ -262,7 +262,7 @@ test("[test-suite] pm: empty matches", function (t) { assert(res == "-a-b-c-d-") end `, L; - + t.plan(2); t.doesNotThrow(function () { @@ -271,7 +271,7 @@ test("[test-suite] pm: empty matches", function (t) { lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(luaCode)); }, "Lua program loaded without error"); @@ -316,7 +316,7 @@ test("[test-suite] pm: gsub", function (t) { end) assert(s == r and t[1] == 1 and t[3] == 3 and t[7] == 4 and t[13] == 4) `, L; - + t.plan(2); t.doesNotThrow(function () { @@ -325,7 +325,7 @@ test("[test-suite] pm: gsub", function (t) { lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(luaCode)); }, "Lua program loaded without error"); @@ -348,7 +348,7 @@ test("[test-suite] pm: gsub isbalanced", function (t) { assert(not isbalanced("(9 ((8) 7) a b (\\0 c) a")) assert(string.gsub("alo 'oi' alo", "%b''", '"') == 'alo " alo') `, L; - + t.plan(2); t.doesNotThrow(function () { @@ -357,7 +357,7 @@ test("[test-suite] pm: gsub isbalanced", function (t) { lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(luaCode)); }, "Lua program loaded without error"); @@ -397,7 +397,7 @@ test("[test-suite] pm: capture", function (t) { checkerror("invalid capture index %%1", string.gsub, "alo", "(%1)", "a") checkerror("invalid use of '%%'", string.gsub, "alo", ".", "%x") `, L; - + t.plan(2); t.doesNotThrow(function () { @@ -406,7 +406,7 @@ test("[test-suite] pm: capture", function (t) { lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(luaCode)); }, "Lua program loaded without error"); @@ -434,7 +434,7 @@ test("[test-suite] pm: bug since 2.5 (C-stack overflow) (TODO: _soft)", function assert(not r and string.find(m, "too complex")) end `, L; - + t.plan(2); t.doesNotThrow(function () { @@ -443,7 +443,7 @@ test("[test-suite] pm: bug since 2.5 (C-stack overflow) (TODO: _soft)", function lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(luaCode)); }, "Lua program loaded without error"); @@ -471,7 +471,7 @@ test("[test-suite] pm: big strings (TODO: _soft)", function (t) { assert(not pcall(string.gsub, a, 'b')) end `, L; - + t.plan(2); t.doesNotThrow(function () { @@ -480,7 +480,7 @@ test("[test-suite] pm: big strings (TODO: _soft)", function (t) { lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(luaCode)); }, "Lua program loaded without error"); @@ -502,7 +502,7 @@ test("[test-suite] pm: recursive nest of gsubs", function (t) { local x = "abcdef" assert(rev(rev(x)) == x) `, L; - + t.plan(2); t.doesNotThrow(function () { @@ -511,7 +511,7 @@ test("[test-suite] pm: recursive nest of gsubs", function (t) { lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(luaCode)); }, "Lua program loaded without error"); @@ -536,7 +536,7 @@ test("[test-suite] pm: gsub with tables", function (t) { t = {}; setmetatable(t, {__index = function (t,s) return string.upper(s) end}) assert(string.gsub("a alo b hi", "%w%w+", t) == "a ALO b HI") `, L; - + t.plan(2); t.doesNotThrow(function () { @@ -545,7 +545,7 @@ test("[test-suite] pm: gsub with tables", function (t) { lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(luaCode)); }, "Lua program loaded without error"); @@ -584,7 +584,7 @@ test("[test-suite] pm: gmatch", function (t) { for k,v in pairs(t) do assert(k+1 == v+0); a=a+1 end assert(a == 3) `, L; - + t.plan(2); t.doesNotThrow(function () { @@ -593,7 +593,7 @@ test("[test-suite] pm: gmatch", function (t) { lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(luaCode)); }, "Lua program loaded without error"); @@ -634,7 +634,7 @@ test("[test-suite] pm: tests for '%f' ('frontiers')", function (t) { end assert(#a == 0) `, L; - + t.plan(2); t.doesNotThrow(function () { @@ -643,7 +643,7 @@ test("[test-suite] pm: tests for '%f' ('frontiers')", function (t) { lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(luaCode)); }, "Lua program loaded without error"); @@ -676,7 +676,7 @@ test("[test-suite] pm: malformed patterns", function (t) { malform("%") malform("%f", "missing") `, L; - + t.plan(2); t.doesNotThrow(function () { @@ -685,7 +685,7 @@ test("[test-suite] pm: malformed patterns", function (t) { lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(luaCode)); }, "Lua program loaded without error"); @@ -708,7 +708,7 @@ test("[test-suite] pm: \\0 in patterns", function (t) { assert(string.match("abc\\0\\0\\0", "%\\0+") == "\\0\\0\\0") assert(string.match("abc\\0\\0\\0", "%\\0%\\0?") == "\\0\\0") `, L; - + t.plan(2); t.doesNotThrow(function () { @@ -717,7 +717,7 @@ test("[test-suite] pm: \\0 in patterns", function (t) { lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(luaCode)); }, "Lua program loaded without error"); @@ -735,7 +735,7 @@ test("[test-suite] pm: magic char after \\0", function (t) { assert(string.find("abc\\0\\0","\\0.") == 4) assert(string.find("abcx\\0\\0abc\\0abc","x\\0\\0abc\\0a.") == 4) `, L; - + t.plan(2); t.doesNotThrow(function () { @@ -744,7 +744,7 @@ test("[test-suite] pm: magic char after \\0", function (t) { lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(luaCode)); }, "Lua program loaded without error"); diff --git a/tests/test-suite/sort.js b/tests/test-suite/sort.js index 9cee400..c52f30c 100644 --- a/tests/test-suite/sort.js +++ b/tests/test-suite/sort.js @@ -5,7 +5,7 @@ const test = require('tape'); const lua = require('../../src/lua.js'); const lauxlib = require('../../src/lauxlib.js'); const lualib = require('../../src/lualib.js'); - +const {to_luastring} = require("../../src/fengaricore.js"); const prefix = ` local unpack = table.unpack @@ -59,7 +59,7 @@ test("[test-suite] sort: testing unpack", function (t) { a,x = unpack({1,2}, 1, 1) assert(a==1 and x==nil) `, L; - + t.plan(2); t.doesNotThrow(function () { @@ -68,7 +68,7 @@ test("[test-suite] sort: testing unpack", function (t) { lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(prefix + luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(prefix + luaCode)); }, "Lua program loaded without error"); @@ -111,7 +111,7 @@ test("[test-suite] sort: testing unpack", function (t) { a, b = unpack(t, minI + 1, minI); assert(a == nil and b == nil) end `, L; - + t.plan(2); t.doesNotThrow(function () { @@ -120,7 +120,7 @@ test("[test-suite] sort: testing unpack", function (t) { lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(prefix + luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(prefix + luaCode)); }, "Lua program loaded without error"); @@ -141,7 +141,7 @@ test("[test-suite] sort: testing unpack", function (t) { checkerror("object length is not an integer", table.insert, t, 1) end `, L; - + t.plan(2); t.doesNotThrow(function () { @@ -150,7 +150,7 @@ test("[test-suite] sort: testing unpack", function (t) { lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(prefix + luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(prefix + luaCode)); }, "Lua program loaded without error"); @@ -166,7 +166,7 @@ test("[test-suite] sort: testing unpack", function (t) { test("[test-suite] sort: testing pack", function (t) { let luaCode = ` a = table.pack() - assert(a[1] == nil and a.n == 0) + assert(a[1] == nil and a.n == 0) a = table.pack(table) assert(a[1] == table and a.n == 1) @@ -174,7 +174,7 @@ test("[test-suite] sort: testing pack", function (t) { a = table.pack(nil, nil, nil, nil) assert(a[1] == nil and a.n == 4) `, L; - + t.plan(2); t.doesNotThrow(function () { @@ -183,7 +183,7 @@ test("[test-suite] sort: testing pack", function (t) { lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(prefix + luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(prefix + luaCode)); }, "Lua program loaded without error"); @@ -203,8 +203,8 @@ test("[test-suite] sort: testing move", function (t) { checkerror("table expected", table.move, 1, 2, 3, 4) local function eqT (a, b) - for k, v in pairs(a) do assert(b[k] == v) end - for k, v in pairs(b) do assert(a[k] == v) end + for k, v in pairs(a) do assert(b[k] == v) end + for k, v in pairs(b) do assert(a[k] == v) end end local a = table.move({10,20,30}, 1, 3, 2) -- move forward @@ -269,7 +269,7 @@ test("[test-suite] sort: testing move", function (t) { assert(not stat and msg == b) end `, L; - + t.plan(2); t.doesNotThrow(function () { @@ -278,7 +278,7 @@ test("[test-suite] sort: testing move", function (t) { lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(prefix + luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(prefix + luaCode)); }, "Lua program loaded without error"); @@ -320,7 +320,7 @@ test("[test-suite] sort: testing long move", function (t) { checkerror("wrap around", table.move, {}, 1, 2, maxI) checkerror("wrap around", table.move, {}, minI, -2, 2) `, L; - + t.plan(2); t.doesNotThrow(function () { @@ -329,7 +329,7 @@ test("[test-suite] sort: testing long move", function (t) { lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(prefix + luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(prefix + luaCode)); }, "Lua program loaded without error"); @@ -350,7 +350,7 @@ test("[test-suite] sort: testing sort, strange lengths", function (t) { a = setmetatable({}, {__len = function () return maxI end}) checkerror("too big", table.sort, a) `, L; - + t.plan(2); t.doesNotThrow(function () { @@ -359,7 +359,7 @@ test("[test-suite] sort: testing sort, strange lengths", function (t) { lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(prefix + luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(prefix + luaCode)); }, "Lua program loaded without error"); @@ -383,7 +383,7 @@ test("[test-suite] sort: test checks for invalid order functions", function (t) check{1,2,3,4,5} check{1,2,3,4,5,6} `, L; - + t.plan(2); t.doesNotThrow(function () { @@ -392,7 +392,7 @@ test("[test-suite] sort: test checks for invalid order functions", function (t) lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(prefix + luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(prefix + luaCode)); }, "Lua program loaded without error"); @@ -420,7 +420,7 @@ test("[test-suite] sort: sort alpha", function (t) { table.sort(a) check(a) `, L; - + t.plan(2); t.doesNotThrow(function () { @@ -429,7 +429,7 @@ test("[test-suite] sort: sort alpha", function (t) { lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(prefix + luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(prefix + luaCode)); }, "Lua program loaded without error"); @@ -477,7 +477,7 @@ test("[test-suite] sort: sort perm", function (t) { perm{1,2,3,4,5,6} perm{2,2,3,3,5,6} `, L; - + t.plan(2); t.doesNotThrow(function () { @@ -486,7 +486,7 @@ test("[test-suite] sort: sort perm", function (t) { lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(prefix + luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(prefix + luaCode)); }, "Lua program loaded without error"); @@ -527,7 +527,7 @@ test("[test-suite] sort: Invert-sorting", function (t) { for i,v in pairs(a) do assert(v == false) end `, L; - + t.plan(2); t.doesNotThrow(function () { @@ -536,7 +536,7 @@ test("[test-suite] sort: Invert-sorting", function (t) { lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(prefix + luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(prefix + luaCode)); }, "Lua program loaded without error"); @@ -576,7 +576,7 @@ test("[test-suite] sort: sorting", function (t) { check(a, tt.__lt) check(a) `, L; - + t.plan(2); t.doesNotThrow(function () { @@ -585,7 +585,7 @@ test("[test-suite] sort: sorting", function (t) { lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(prefix + luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(prefix + luaCode)); }, "Lua program loaded without error"); diff --git a/tests/test-suite/strings.js b/tests/test-suite/strings.js index 0efedcb..cbffe5c 100644 --- a/tests/test-suite/strings.js +++ b/tests/test-suite/strings.js @@ -5,7 +5,7 @@ const test = require('tape'); const lua = require('../../src/lua.js'); const lauxlib = require('../../src/lauxlib.js'); const lualib = require('../../src/lualib.js'); - +const {to_luastring} = require("../../src/fengaricore.js"); const checkerror = ` local maxi, mini = math.maxinteger, math.mininteger @@ -45,7 +45,7 @@ test('[test-suite] strings: string comparisons', function (t) { lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(checkerror + luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(checkerror + luaCode)); }, "Lua program loaded without error"); @@ -87,7 +87,7 @@ test('[test-suite] strings: string.sub', function (t) { lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(checkerror + luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(checkerror + luaCode)); }, "Lua program loaded without error"); @@ -125,7 +125,7 @@ test('[test-suite] strings: string.find', function (t) { lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(checkerror + luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(checkerror + luaCode)); }, "Lua program loaded without error"); @@ -157,7 +157,7 @@ test('[test-suite] strings: string.len and #', function (t) { lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(checkerror + luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(checkerror + luaCode)); }, "Lua program loaded without error"); @@ -214,7 +214,7 @@ test('[test-suite] strings: string.byte/string.char', function (t) { lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(checkerror + luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(checkerror + luaCode)); }, "Lua program loaded without error"); @@ -251,7 +251,7 @@ test('[test-suite] strings: repetitions with separator', function (t) { lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(checkerror + luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(checkerror + luaCode)); }, "Lua program loaded without error"); @@ -303,7 +303,7 @@ test('[test-suite] strings: tostring', function (t) { lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(checkerror + luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(checkerror + luaCode)); }, "Lua program loaded without error"); @@ -350,7 +350,7 @@ test('[test-suite] strings: string.format', function (t) { lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(checkerror + luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(checkerror + luaCode)); }, "Lua program loaded without error"); @@ -391,7 +391,7 @@ test('[test-suite] strings: %q', function (t) { lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(checkerror + luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(checkerror + luaCode)); }, "Lua program loaded without error"); @@ -418,7 +418,7 @@ test('[test-suite] strings: embedded zeros error', function (t) { lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(checkerror + luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(checkerror + luaCode)); }, "Lua program loaded without error"); @@ -461,7 +461,7 @@ test('[test-suite] strings: format x tostring', function (t) { lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(checkerror + luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(checkerror + luaCode)); }, "Lua program loaded without error"); @@ -498,7 +498,7 @@ test('[test-suite] strings: longest number that can be formatted', function (t) lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(checkerror + luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(checkerror + luaCode)); }, "Lua program loaded without error"); @@ -547,7 +547,7 @@ test('[test-suite] strings: large numbers for format', function (t) { lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(checkerror + luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(checkerror + luaCode)); }, "Lua program loaded without error"); @@ -604,7 +604,7 @@ test("[test-suite] strings: 'format %a %A'", function (t) { lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(checkerror + luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(checkerror + luaCode)); }, "Lua program loaded without error"); @@ -644,7 +644,7 @@ test("[test-suite] strings: errors in format", function (t) { lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(checkerror + luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(checkerror + luaCode)); }, "Lua program loaded without error"); @@ -695,7 +695,7 @@ test("[test-suite] strings: table.concat", function (t) { lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(checkerror + luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(checkerror + luaCode)); }, "Lua program loaded without error"); @@ -751,7 +751,7 @@ test.skip("[test-suite] strings: locale", function (t) { lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(checkerror + luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(checkerror + luaCode)); }, "Lua program loaded without error"); @@ -782,7 +782,7 @@ test("[test-suite] strings: bug in Lua 5.3.2: 'gmatch' iterator does not work ac lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(checkerror + luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(checkerror + luaCode)); }, "Lua program loaded without error"); diff --git a/tests/test-suite/tpack.js b/tests/test-suite/tpack.js index ebce4e4..745c151 100644 --- a/tests/test-suite/tpack.js +++ b/tests/test-suite/tpack.js @@ -5,7 +5,7 @@ const test = require('tape'); const lua = require('../../src/lua.js'); const lauxlib = require('../../src/lauxlib.js'); const lualib = require('../../src/lualib.js'); - +const {to_luastring} = require("../../src/fengaricore.js"); const prefix = ` local pack = string.pack @@ -55,7 +55,7 @@ test("[test-suite] tpack: maximum size for integers", function (t) { lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(prefix + luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(prefix + luaCode)); }, "Lua program loaded without error"); @@ -91,7 +91,7 @@ test("[test-suite] tpack: minimum behavior for integer formats", function (t) { lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(prefix + luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(prefix + luaCode)); }, "Lua program loaded without error"); @@ -130,7 +130,7 @@ test("[test-suite] tpack: minimum behavior for integer formats", function (t) { lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(prefix + luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(prefix + luaCode)); }, "Lua program loaded without error"); @@ -175,7 +175,7 @@ test("[test-suite] tpack: minimum behavior for integer formats", function (t) { lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(prefix + luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(prefix + luaCode)); }, "Lua program loaded without error"); @@ -209,7 +209,7 @@ test("[test-suite] tpack: minimum behavior for integer formats", function (t) { lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(prefix + luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(prefix + luaCode)); }, "Lua program loaded without error"); @@ -242,7 +242,7 @@ test("[test-suite] tpack: sign extension", function (t) { lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(prefix + luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(prefix + luaCode)); }, "Lua program loaded without error"); @@ -273,7 +273,7 @@ test("[test-suite] tpack: mixed endianness", function (t) { lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(prefix + luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(prefix + luaCode)); }, "Lua program loaded without error"); @@ -308,7 +308,7 @@ test("[test-suite] tpack: testing invalid formats", function (t) { lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(prefix + luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(prefix + luaCode)); }, "Lua program loaded without error"); @@ -343,7 +343,7 @@ test("[test-suite] tpack: overflow in option size (error will be in digit after lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(prefix + luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(prefix + luaCode)); }, "Lua program loaded without error"); @@ -384,7 +384,7 @@ test("[test-suite] tpack: overflow in packing", function (t) { lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(prefix + luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(prefix + luaCode)); }, "Lua program loaded without error"); @@ -418,7 +418,7 @@ test("[test-suite] tpack: Lua integer size", function (t) { lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(prefix + luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(prefix + luaCode)); }, "Lua program loaded without error"); @@ -458,7 +458,7 @@ test("[test-suite] tpack: testing pack/unpack of floating-point numbers", functi lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(prefix + luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(prefix + luaCode)); }, "Lua program loaded without error"); @@ -524,7 +524,7 @@ test("[test-suite] tpack: testing pack/unpack of strings", function (t) { lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(prefix + luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(prefix + luaCode)); }, "Lua program loaded without error"); @@ -544,7 +544,7 @@ test("[test-suite] tpack: testing multiple types and sequence", function (t) { assert(#x == packsize("<b h b f d f n i")) local a, b, c, d, e, f, g, h = unpack("<b h b f d f n i", x) assert(a == 1 and b == 2 and c == 3 and d == 4 and e == 5 and f == 6 and - g == 7 and h == 8) + g == 7 and h == 8) end `, L; @@ -556,7 +556,7 @@ test("[test-suite] tpack: testing multiple types and sequence", function (t) { lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(prefix + luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(prefix + luaCode)); }, "Lua program loaded without error"); @@ -577,7 +577,7 @@ test("[test-suite] tpack: testing alignment", function (t) { assert(#x == packsize(">!8 b Xh i4 i8 c1 Xi8")) assert(x == "\\xf4" .. "\\0\\0\\0" .. "\\0\\0\\0\\100" .. - "\\0\\0\\0\\0\\0\\0\\0\\xC8" .. + "\\0\\0\\0\\0\\0\\0\\0\\xC8" .. "\\xEC" .. "\\0\\0\\0\\0\\0\\0\\0") local a, b, c, d, pos = unpack(">!8 c1 Xh i4 i8 b Xi8 XI XH", x) assert(a == "\\xF4" and b == 100 and c == 200 and d == -20 and (pos - 1) == #x) @@ -622,7 +622,7 @@ test("[test-suite] tpack: testing alignment", function (t) { lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(prefix + luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(prefix + luaCode)); }, "Lua program loaded without error"); @@ -665,7 +665,7 @@ test("[test-suite] tpack: testing initial position", function (t) { checkerror("out of string", unpack, "c0", x, 0) checkerror("out of string", unpack, "c0", x, #x + 2) checkerror("out of string", unpack, "c0", x, -(#x + 1)) - + end `, L; @@ -677,7 +677,7 @@ test("[test-suite] tpack: testing initial position", function (t) { lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(prefix + luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(prefix + luaCode)); }, "Lua program loaded without error"); diff --git a/tests/test-suite/utf8.js b/tests/test-suite/utf8.js index 11f699d..173dffd 100644 --- a/tests/test-suite/utf8.js +++ b/tests/test-suite/utf8.js @@ -5,7 +5,7 @@ const test = require('tape'); const lua = require('../../src/lua.js'); const lauxlib = require('../../src/lauxlib.js'); const lualib = require('../../src/lualib.js'); - +const {to_luastring} = require("../../src/fengaricore.js"); const prefix = ` local function checkerror (msg, f, ...) @@ -30,7 +30,7 @@ const prefix = ` end -- 't' is the list of codepoints of 's' local function check (s, t) - local l = utf8.len(s) + local l = utf8.len(s) assert(#t == l and len(s) == l) assert(utf8.char(table.unpack(t)) == s) @@ -49,7 +49,7 @@ const prefix = ` assert(utf8.offset(s, -1, pi1) == pi) assert(utf8.offset(s, i - l - 1) == pi) assert(pi1 - pi == #utf8.char(utf8.codepoint(s, pi))) - for j = pi, pi1 - 1 do + for j = pi, pi1 - 1 do assert(utf8.offset(s, 0, j) == pi) end for j = pi + 1, pi1 - 1 do @@ -73,7 +73,7 @@ const prefix = ` i = 0 for p, c in utf8.codes(s) do i = i + 1 - assert(c == t[i] and p == utf8.offset(s, i)) + assert(c == t[i] and p == utf8.offset(s, i)) end assert(i == #t) @@ -97,33 +97,28 @@ const prefix = ` `; test("[test-suite] utf8: offset", function (t) { - let luaCode = ` + let luaCode = prefix + ` assert(utf8.offset("alo", 5) == nil) assert(utf8.offset("alo", -4) == nil) `, L; - + t.plan(2); t.doesNotThrow(function () { - L = lauxlib.luaL_newstate(); - lualib.luaL_openlibs(L); - - lauxlib.luaL_loadstring(L, lua.to_luastring(prefix + luaCode)); - + if (lauxlib.luaL_loadstring(L, to_luastring(luaCode)) === lua.LUA_ERRSYNTAX) + throw new SyntaxError(lua.lua_tojsstring(L, -1)); }, "Lua program loaded without error"); t.doesNotThrow(function () { - lua.lua_call(L, 0, -1); - }, "Lua program ran without error"); }); test("[test-suite] utf8: error indication in utf8.len", function (t) { - let luaCode = ` + let luaCode = prefix + ` do local function check (s, p) local a, b = utf8.len(s) @@ -135,29 +130,24 @@ test("[test-suite] utf8: error indication in utf8.len", function (t) { check("\\xF4\\x9F\\xBF\\xBF", 1) end `, L; - + t.plan(2); t.doesNotThrow(function () { - L = lauxlib.luaL_newstate(); - lualib.luaL_openlibs(L); - - lauxlib.luaL_loadstring(L, lua.to_luastring(prefix + luaCode)); - + if (lauxlib.luaL_loadstring(L, to_luastring(luaCode)) === lua.LUA_ERRSYNTAX) + throw new SyntaxError(lua.lua_tojsstring(L, -1)); }, "Lua program loaded without error"); t.doesNotThrow(function () { - lua.lua_call(L, 0, -1); - }, "Lua program ran without error"); }); test("[test-suite] utf8: error in initial position for offset", function (t) { - let luaCode = ` + let luaCode = prefix + ` checkerror("position out of range", utf8.offset, "abc", 1, 5) checkerror("position out of range", utf8.offset, "abc", 1, -4) checkerror("position out of range", utf8.offset, "", 1, 2) @@ -166,29 +156,24 @@ test("[test-suite] utf8: error in initial position for offset", function (t) { checkerror("continuation byte", utf8.offset, "𦧺", 1, 2) checkerror("continuation byte", utf8.offset, "\\x80", 1) `, L; - + t.plan(2); t.doesNotThrow(function () { - L = lauxlib.luaL_newstate(); - lualib.luaL_openlibs(L); - - lauxlib.luaL_loadstring(L, lua.to_luastring(prefix + luaCode)); - + if (lauxlib.luaL_loadstring(L, to_luastring(luaCode)) === lua.LUA_ERRSYNTAX) + throw new SyntaxError(lua.lua_tojsstring(L, -1)); }, "Lua program loaded without error"); t.doesNotThrow(function () { - lua.lua_call(L, 0, -1); - }, "Lua program ran without error"); }); test("[test-suite] utf8: codepoints", function (t) { - let luaCode = ` + let luaCode = prefix + ` local s = "hello World" local t = {string.byte(s, 1, -1)} for i = 1, utf8.len(s) do assert(t[i] == string.byte(s, i)) end @@ -215,135 +200,110 @@ test("[test-suite] utf8: codepoints", function (t) { checkerror("value out of range", utf8.char, 0x10FFFF + 1) `, L; - + t.plan(2); t.doesNotThrow(function () { - L = lauxlib.luaL_newstate(); - lualib.luaL_openlibs(L); - - lauxlib.luaL_loadstring(L, lua.to_luastring(prefix + luaCode)); - + if (lauxlib.luaL_loadstring(L, to_luastring(luaCode)) === lua.LUA_ERRSYNTAX) + throw new SyntaxError(lua.lua_tojsstring(L, -1)); }, "Lua program loaded without error"); t.doesNotThrow(function () { - lua.lua_call(L, 0, -1); - }, "Lua program ran without error"); }); test("[test-suite] utf8: UTF-8 representation for 0x11ffff (value out of valid range)", function (t) { - let luaCode = ` + let luaCode = prefix + ` invalid("\\xF4\\x9F\\xBF\\xBF") `, L; - + t.plan(2); t.doesNotThrow(function () { - L = lauxlib.luaL_newstate(); - lualib.luaL_openlibs(L); - - lauxlib.luaL_loadstring(L, lua.to_luastring(prefix + luaCode)); - + if (lauxlib.luaL_loadstring(L, to_luastring(luaCode)) === lua.LUA_ERRSYNTAX) + throw new SyntaxError(lua.lua_tojsstring(L, -1)); }, "Lua program loaded without error"); t.doesNotThrow(function () { - lua.lua_call(L, 0, -1); - }, "Lua program ran without error"); }); test("[test-suite] utf8: overlong sequences", function (t) { - let luaCode = ` + let luaCode = prefix + ` invalid("\\xC0\\x80") -- zero invalid("\\xC1\\xBF") -- 0x7F (should be coded in 1 byte) invalid("\\xE0\\x9F\\xBF") -- 0x7FF (should be coded in 2 bytes) invalid("\\xF0\\x8F\\xBF\\xBF") -- 0xFFFF (should be coded in 3 bytes) `, L; - + t.plan(2); t.doesNotThrow(function () { - L = lauxlib.luaL_newstate(); - lualib.luaL_openlibs(L); - - lauxlib.luaL_loadstring(L, lua.to_luastring(prefix + luaCode)); - + if (lauxlib.luaL_loadstring(L, to_luastring(luaCode)) === lua.LUA_ERRSYNTAX) + throw new SyntaxError(lua.lua_tojsstring(L, -1)); }, "Lua program loaded without error"); t.doesNotThrow(function () { - lua.lua_call(L, 0, -1); - }, "Lua program ran without error"); }); test("[test-suite] utf8: invalid bytes", function (t) { - let luaCode = ` + let luaCode = prefix + ` invalid("\\x80") -- continuation byte invalid("\\xBF") -- continuation byte invalid("\\xFE") -- invalid byte invalid("\\xFF") -- invalid byte `, L; - + t.plan(2); t.doesNotThrow(function () { - L = lauxlib.luaL_newstate(); - lualib.luaL_openlibs(L); - - lauxlib.luaL_loadstring(L, lua.to_luastring(prefix + luaCode)); - + if (lauxlib.luaL_loadstring(L, to_luastring(luaCode)) === lua.LUA_ERRSYNTAX) + throw new SyntaxError(lua.lua_tojsstring(L, -1)); }, "Lua program loaded without error"); t.doesNotThrow(function () { - lua.lua_call(L, 0, -1); - }, "Lua program ran without error"); }); test("[test-suite] utf8: empty strings", function (t) { - let luaCode = ` + let luaCode = prefix + ` check("", {}) `, L; - + t.plan(2); t.doesNotThrow(function () { - L = lauxlib.luaL_newstate(); - lualib.luaL_openlibs(L); - - lauxlib.luaL_loadstring(L, lua.to_luastring(prefix + luaCode)); - + if (lauxlib.luaL_loadstring(L, to_luastring(luaCode)) === lua.LUA_ERRSYNTAX) + throw new SyntaxError(lua.lua_tojsstring(L, -1)); }, "Lua program loaded without error"); t.doesNotThrow(function () { - lua.lua_call(L, 0, -1); - }, "Lua program ran without error"); }); test("[test-suite] utf8: minimum and maximum values for each sequence size", function (t) { - let luaCode = ` + let luaCode = prefix + ` s = "\\0 \\x7F\\z \\xC2\\x80 \\xDF\\xBF\\z \\xE0\\xA0\\x80 \\xEF\\xBF\\xBF\\z @@ -377,18 +337,13 @@ test("[test-suite] utf8: minimum and maximum values for each sequence size", fun t.plan(2); t.doesNotThrow(function () { - L = lauxlib.luaL_newstate(); - lualib.luaL_openlibs(L); - - lauxlib.luaL_loadstring(L, lua.to_luastring(prefix + luaCode)); - + if (lauxlib.luaL_loadstring(L, to_luastring(luaCode)) === lua.LUA_ERRSYNTAX) + throw new SyntaxError(lua.lua_tojsstring(L, -1)); }, "Lua program loaded without error"); t.doesNotThrow(function () { - lua.lua_call(L, 0, -1); - }, "Lua program ran without error"); }); diff --git a/tests/test-suite/vararg.js b/tests/test-suite/vararg.js index dc90248..1cc5ace 100644 --- a/tests/test-suite/vararg.js +++ b/tests/test-suite/vararg.js @@ -5,7 +5,7 @@ const test = require('tape'); const lua = require('../../src/lua.js'); const lauxlib = require('../../src/lauxlib.js'); const lualib = require('../../src/lualib.js'); - +const {to_luastring} = require("../../src/fengaricore.js"); test("[test-suite] vararg: testing vararg", function (t) { let luaCode = ` @@ -73,7 +73,7 @@ test("[test-suite] vararg: testing vararg", function (t) { while i <= lim do a[i] = i; i=i+1 end assert(call(math.max, a) == lim) `, L; - + t.plan(2); t.doesNotThrow(function () { @@ -82,7 +82,7 @@ test("[test-suite] vararg: testing vararg", function (t) { lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(luaCode)); }, "Lua program loaded without error"); @@ -118,7 +118,7 @@ test("[test-suite] vararg: new-style varargs", function (t) { a,b,c,d,e = f(4) assert(a==nil and b==nil and c==nil and d==nil and e==nil) `, L; - + t.plan(2); t.doesNotThrow(function () { @@ -127,7 +127,7 @@ test("[test-suite] vararg: new-style varargs", function (t) { lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(luaCode)); }, "Lua program loaded without error"); @@ -168,7 +168,7 @@ test("[test-suite] vararg: varargs for main chunks", function (t) { pcall(select, 10000) pcall(select, -10000) `, L; - + t.plan(2); t.doesNotThrow(function () { @@ -177,7 +177,7 @@ test("[test-suite] vararg: varargs for main chunks", function (t) { lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(luaCode)); }, "Lua program loaded without error"); @@ -204,7 +204,7 @@ test("[test-suite] vararg: bug in 5.2.2", function (t) { -- assertion fail here f() `, L; - + t.plan(2); t.doesNotThrow(function () { @@ -213,7 +213,7 @@ test("[test-suite] vararg: bug in 5.2.2", function (t) { lualib.luaL_openlibs(L); - lauxlib.luaL_loadstring(L, lua.to_luastring(luaCode)); + lauxlib.luaL_loadstring(L, to_luastring(luaCode)); }, "Lua program loaded without error"); diff --git a/tests/tests.js b/tests/tests.js index 1ad9900..778cbef 100644 --- a/tests/tests.js +++ b/tests/tests.js @@ -2,6 +2,7 @@ const lua = require("../src/lua.js"); const lauxlib = require("../src/lauxlib.js"); +const {to_luastring} = require("../src/fengaricore.js"); const toByteCode = function(luaCode) { let L = getState(luaCode); @@ -19,7 +20,7 @@ const getState = function(luaCode) { if (!L) throw Error("unable to create lua_State"); - if (lauxlib.luaL_loadstring(L, lua.to_luastring(luaCode)) !== lua.LUA_OK) + if (lauxlib.luaL_loadstring(L, to_luastring(luaCode)) !== lua.LUA_OK) throw Error(lua.lua_tojsstring(L, -1)); return L; |