From 6be8db07196c407cd321a7b04f5022939c4ffce3 Mon Sep 17 00:00:00 2001 From: Benoit Giannangeli Date: Tue, 18 Apr 2017 11:38:21 +0200 Subject: Cache all to_luastring of internal literals --- src/lapi.js | 4 ++-- src/lauxlib.js | 36 ++++++++++++++-------------- src/lbaselib.js | 34 +++++++++++++------------- src/lcode.js | 6 ++--- src/lcorolib.js | 2 +- src/ldblib.js | 48 ++++++++++++++++++------------------- src/ldebug.js | 36 ++++++++++++++-------------- src/ldo.js | 12 +++++----- src/llex.js | 26 ++++++++++---------- src/lmathlib.js | 20 ++++++++-------- src/lobject.js | 2 +- src/lparser.js | 44 +++++++++++++++++----------------- src/lstrlib.js | 74 ++++++++++++++++++++++++++++----------------------------- src/ltablib.js | 20 ++++++++-------- src/ltm.js | 54 ++++++++++++++++++++--------------------- src/lua.js | 11 ++++++++- src/lutf8lib.js | 20 ++++++++-------- src/lvm.js | 16 ++++++------- 18 files changed, 237 insertions(+), 228 deletions(-) (limited to 'src') diff --git a/src/lapi.js b/src/lapi.js index bf9b381..72c35f0 100644 --- a/src/lapi.js +++ b/src/lapi.js @@ -221,7 +221,7 @@ const lua_pushlstring = function(L, s, len) { assert(Array.isArray(s), "lua_pushlstring expects array of byte"); assert(typeof len === "number"); - let ts = len === 0 ? L.l_G.intern(lua.to_luastring("")) : new TValue(CT.LUA_TLNGSTR, s.slice(0, len)); + let ts = len === 0 ? L.l_G.intern(lua.to_luastring("", true)) : new TValue(CT.LUA_TLNGSTR, s.slice(0, len)); L.stack[L.top++] = ts; assert(L.top <= L.ci.top, "stack overflow"); @@ -938,7 +938,7 @@ const lua_concat = function(L, n) { if (n >= 2) lvm.luaV_concat(L, n); else if (n === 0) { - L.stack[L.top++] = L.l_G.intern(lua.to_luastring("")); + L.stack[L.top++] = L.l_G.intern(lua.to_luastring("", true)); assert(L.top <= L.ci.top, "stack overflow"); } }; diff --git a/src/lauxlib.js b/src/lauxlib.js index 311e2eb..064e229 100644 --- a/src/lauxlib.js +++ b/src/lauxlib.js @@ -59,7 +59,7 @@ const findfield = function(L, objidx, level) { const pushglobalfuncname = function(L, ar) { let top = lapi.lua_gettop(L); ldebug.lua_getinfo(L, [char['f']], ar); /* push function */ - lapi.lua_getfield(L, lua.LUA_REGISTRYINDEX, lua.to_luastring(LUA_LOADED_TABLE)); + lapi.lua_getfield(L, lua.LUA_REGISTRYINDEX, lua.to_luastring(LUA_LOADED_TABLE, true)); if (findfield(L, top + 1, 2)) { let name = lapi.lua_tostring(L, -1); if (lobject.jsstring(name).startsWith("_G.")) { /* name start with '_G.'? */ @@ -79,7 +79,7 @@ const sv = s => s ? s : []; const pushfuncname = function(L, ar) { if (pushglobalfuncname(L, ar)) { /* try first a global name */ - lapi.lua_pushstring(L, lua.to_luastring("function '").concat(lapi.lua_tostring(L, -1)).concat([char["'"]])); + lapi.lua_pushstring(L, lua.to_luastring("function '", true).concat(lapi.lua_tostring(L, -1)).concat([char["'"]])); lapi.lua_remove(L, -2); /* remove name */ } else if (ar.namewhat) /* is there a name from code? */ @@ -87,7 +87,7 @@ const pushfuncname = function(L, ar) { else if (ar.what && ar.what[0] === char['m']) /* main? */ lapi.lua_pushliteral(L, "main chunk"); else if (ar.what && ar.what[0] != char['C']) /* for Lua functions, use */ - lapi.lua_pushstring(L, lua.to_luastring("function <").concat(...sv(ar.short_src), char[':'], ...lua.to_luastring(`${ar.linedefined}>`))); + lapi.lua_pushstring(L, lua.to_luastring("function <", true).concat(...sv(ar.short_src), char[':'], ...lua.to_luastring(`${ar.linedefined}>`))); else /* nothing left... */ lapi.lua_pushliteral(L, "?"); }; @@ -121,7 +121,7 @@ const luaL_traceback = function(L, L1, msg, level) { lapi.lua_pushliteral(L, "\n\t..."); /* add a '...' */ level = last - LEVELS2 + 1; /* and skip to last ones */ } else { - ldebug.lua_getinfo(L1, lua.to_luastring("Slnt"), ar); + ldebug.lua_getinfo(L1, lua.to_luastring("Slnt", true), ar); lapi.lua_pushstring(L, [char['\n'], char['\t'], char['.'], char['.'], char['.']].concat(ar.short_src)); if (ar.currentline > 0) lapi.lua_pushliteral(L, `${ar.currentline}:`); @@ -147,7 +147,7 @@ const luaL_argerror = function(L, arg, extramsg) { ldebug.lua_getinfo(L, 'n', ar); - if (ar.namewhat === lua.to_luastring('method')) { + if (ar.namewhat === lua.to_luastring('method', true)) { arg--; /* do not count 'self' */ if (arg === 0) /* error is in the self argument itself? */ return luaL_error(L, lua.to_luastring(`calling '${lobject.jsstring(ar.name)}' on bad self (${lobject.jsstring(extramsg)})`)); @@ -161,10 +161,10 @@ const luaL_argerror = function(L, arg, extramsg) { const typeerror = function(L, arg, tname) { let typearg; - if (luaL_getmetafield(L, arg, lua.to_luastring("__name")) === CT.LUA_TSTRING) + if (luaL_getmetafield(L, arg, lua.to_luastring("__name", true)) === CT.LUA_TSTRING) typearg = lapi.lua_tostring(L, -1); else if (lapi.lua_type(L, arg) === CT.LUA_TLIGHTUSERDATA) - typearg = lua.to_luastring("light userdata"); + typearg = lua.to_luastring("light userdata", true); else typearg = luaL_typename(L, arg); @@ -175,7 +175,7 @@ const typeerror = function(L, arg, tname) { const luaL_where = function(L, level) { let ar = new lua.lua_Debug(); if (ldebug.lua_getstack(L, level, ar)) { - ldebug.lua_getinfo(L, lua.to_luastring("Sl"), ar); + ldebug.lua_getinfo(L, lua.to_luastring("Sl", true), ar); if (ar.currentline > 0) { lapi.lua_pushstring(L, lua.to_luastring(`${lobject.jsstring(ar.short_src)}:${ar.currentline}:`)); return; @@ -220,7 +220,7 @@ const luaL_argcheck = function(L, cond, arg, extramsg) { const luaL_checkany = function(L, arg) { if (lapi.lua_type(L, arg) === CT.LUA_TNONE) - luaL_argerror(L, arg, lua.to_luastring("value expected")); + luaL_argerror(L, arg, lua.to_luastring("value expected", true)); }; const luaL_checktype = function(L, arg, t) { @@ -248,7 +248,7 @@ const luaL_optstring = luaL_optlstring; const interror = function(L, arg) { if (lapi.lua_isnumber(L, arg)) - luaL_argerror(L, arg, lua.to_luastring("number has no integer representation")); + luaL_argerror(L, arg, lua.to_luastring("number has no integer representation", true)); else tag_error(L, arg, CT.LUA_TNUMBER); }; @@ -357,15 +357,15 @@ const luaL_len = function(L, idx) { lapi.lua_len(L, idx); let l = lapi.lua_tointegerx(L, -1); if (l === false) - luaL_error(L, lua.to_luastring("object length is not an integer")); + luaL_error(L, lua.to_luastring("object length is not an integer", true)); lapi.lua_pop(L, 1); /* remove object */ return l; }; const luaL_tolstring = function(L, idx) { - if (luaL_callmeta(L, idx, lua.to_luastring("__tostring"))) { + if (luaL_callmeta(L, idx, lua.to_luastring("__tostring", true))) { if (!lapi.lua_isstring(L, -1)) - luaL_error(L, lua.to_luastring("'__tostring' must return a string")); + luaL_error(L, lua.to_luastring("'__tostring' must return a string", true)); } else { switch(lapi.lua_type(L, idx)) { case CT.LUA_TNUMBER: @@ -379,7 +379,7 @@ const luaL_tolstring = function(L, idx) { lapi.lua_pushstring(L, lua.to_luastring(`nil`)); break; default: - let tt = luaL_getmetafield(L, idx, lua.to_luastring("__name")); + let tt = luaL_getmetafield(L, idx, lua.to_luastring("__name", true)); let kind = tt === CT.LUA_TSTRING ? lapi.lua_tostring(L, -1) : luaL_typename(L, idx); lapi.lua_pushstring(L, lua.to_luastring(`${lobject.jsstring(kind)}: 0x${lapi.index2addr(L, -1).id.toString(16)}`)); if (tt !== CT.LUA_TNIL) @@ -438,7 +438,7 @@ 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")); + luaL_checkstack(L, nup, lua.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 */ lapi.lua_pushvalue(L, -nup); @@ -460,7 +460,7 @@ const luaL_checkstack = function(L, space, msg) { if (msg) luaL_error(L, lua.to_luastring(`stack overflow (${lobject.jsstring(msg)})`)); else - luaL_error(L, lua.to_luastring('stack overflow')); + luaL_error(L, lua.to_luastring('stack overflow', true)); } }; @@ -578,7 +578,7 @@ if (typeof require === "function") { try { lf.f = fs.openSync(jsfilename, "r"); } catch (e) { - return errfile(L, lua.to_luastring("open"), fnameindex, e); + return errfile(L, lua.to_luastring("open", true), fnameindex, e); } } @@ -597,7 +597,7 @@ if (typeof require === "function") { return status; } catch (err) { lapi.lua_settop(L, fnameindex); /* ignore results from 'lua_load' */ - return errfile(L, lua.to_luastring("read"), fnameindex); + return errfile(L, lua.to_luastring("read", true), fnameindex); } }; diff --git a/src/lbaselib.js b/src/lbaselib.js index 931a285..af7c3cc 100644 --- a/src/lbaselib.js +++ b/src/lbaselib.js @@ -13,14 +13,14 @@ const luaB_print = function(L) { let n = lapi.lua_gettop(L); /* number of arguments */ let str = []; - lapi.lua_getglobal(L, lua.to_luastring("tostring")); + lapi.lua_getglobal(L, lua.to_luastring("tostring", true)); for (let i = 1; i <= n; i++) { lapi.lua_pushvalue(L, -1); /* function to be called */ lapi.lua_pushvalue(L, i); /* value to print */ lapi.lua_call(L, 1, 1); let s = lapi.lua_tolstring(L, -1); if (s === null) - return lauxlib.luaL_error(L, lua.to_luastring("'tostring' must return a string to 'print'")); + return lauxlib.luaL_error(L, lua.to_luastring("'tostring' must return a string to 'print'", true)); if (i > 1) s = ["\t".charCodeAt(0)].concat(s); str = str.concat(s); lapi.lua_pop(L, 1); @@ -45,16 +45,16 @@ const luaB_getmetatable = function(L) { lapi.lua_pushnil(L); return 1; /* no metatable */ } - lauxlib.luaL_getmetafield(L, 1, lua.to_luastring("__metatable")); + lauxlib.luaL_getmetafield(L, 1, lua.to_luastring("__metatable", true)); return 1; /* returns either __metatable field (if present) or metatable */ }; const luaB_setmetatable = function(L) { let t = lapi.lua_type(L, 2); lauxlib.luaL_checktype(L, 1, CT.LUA_TTABLE); - lauxlib.luaL_argcheck(L, t === CT.LUA_TNIL || t === CT.LUA_TTABLE, 2, lua.to_luastring("nil or table expected")); - if (lauxlib.luaL_getmetafield(L, 1, lua.to_luastring("__metatable")) !== CT.LUA_TNIL) - return lauxlib.luaL_error(L, lua.to_luastring("cannot change a protected metatable")); + lauxlib.luaL_argcheck(L, t === CT.LUA_TNIL || t === CT.LUA_TTABLE, 2, lua.to_luastring("nil or table expected", true)); + if (lauxlib.luaL_getmetafield(L, 1, lua.to_luastring("__metatable", true)) !== CT.LUA_TNIL) + return lauxlib.luaL_error(L, lua.to_luastring("cannot change a protected metatable", true)); lapi.lua_settop(L, 2); lapi.lua_setmetatable(L, 1); return 1; @@ -69,7 +69,7 @@ const luaB_rawequal = function(L) { const luaB_rawlen = function(L) { let t = lapi.lua_type(L, 1); - lauxlib.luaL_argcheck(L, t === CT.LUA_TTABLE || t === CT.LUA_TSTRING, 1, lua.to_luastring("table or string expected")); + lauxlib.luaL_argcheck(L, t === CT.LUA_TTABLE || t === CT.LUA_TSTRING, 1, lua.to_luastring("table or string expected", true)); lapi.lua_pushinteger(L, lapi.lua_rawlen(L, 1)); return 1; }; @@ -93,7 +93,7 @@ const luaB_rawset = function(L) { const luaB_type = function(L) { let t = lapi.lua_type(L, 1); - lauxlib.luaL_argcheck(L, t !== CT.LUA_TNONE, 1, lua.to_luastring("value expected")); + lauxlib.luaL_argcheck(L, t !== CT.LUA_TNONE, 1, lua.to_luastring("value expected", true)); lapi.lua_pushstring(L, lapi.lua_typename(L, t)); return 1; }; @@ -124,7 +124,7 @@ const luaB_next = function(L) { }; const luaB_pairs = function(L) { - return pairsmeta(L, lua.to_luastring("__pairs"), 0, luaB_next); + return pairsmeta(L, lua.to_luastring("__pairs", true), 0, luaB_next); }; /* @@ -166,7 +166,7 @@ const luaB_tonumber = function(L) { let base = lauxlib.luaL_checkinteger(L, 2); lauxlib.luaL_checktype(L, 1, CT.LUA_TSTRING); /* no numbers as strings */ let s = lapi.lua_tostring(L, 1); - lauxlib.luaL_argcheck(L, 2 <= base && base <= 36, 2, lua.to_luastring("base out of range")); + lauxlib.luaL_argcheck(L, 2 <= base && base <= 36, 2, lua.to_luastring("base out of range", true)); let n = parseInt(lobject.jsstring(s), base); if (!isNaN(n)) { lapi.lua_pushinteger(L, n); @@ -210,7 +210,7 @@ const luaB_select = function(L) { let i = lauxlib.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")); + lauxlib.luaL_argcheck(L, 1 <= i, 1, lua.to_luastring("index out of range", true)); return n - i; } }; @@ -284,28 +284,28 @@ 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")); + lauxlib.luaL_checkstack(L, 2, lua.to_luastring("too many nested functions", true)); lapi.lua_pushvalue(L, 1); /* get function */ lapi.lua_call(L, 0, 1); /* call it */ if (lapi.lua_isnil(L, -1)) { lapi.lua_pop(L, 1); /* pop result */ return null; } else if (!lapi.lua_isstring(L, -1)) - lauxlib.luaL_error(L, lua.to_luastring("reader function must return a string")); + lauxlib.luaL_error(L, lua.to_luastring("reader function must return a string", true)); lapi.lua_replace(L, RESERVEDSLOT); /* save string in reserved slot */ return lapi.lua_tostring(L, RESERVEDSLOT); }; const luaB_load = function(L) { let s = lapi.lua_tostring(L, 1); - let mode = lauxlib.luaL_optstring(L, 3, lua.to_luastring("bt")); + let mode = lauxlib.luaL_optstring(L, 3, lua.to_luastring("bt", true)); let env = !lapi.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, chunkname, mode); } else { /* loading from a reader function */ - let chunkname = lauxlib.luaL_optstring(L, 2, lua.to_luastring("=(load)")); + let chunkname = lauxlib.luaL_optstring(L, 2, lua.to_luastring("=(load)", true)); lauxlib.luaL_checktype(L, 1, CT.LUA_TFUNCTION); lapi.lua_settop(L, RESERVEDSLOT); /* create reserved slot */ status = lapi.lua_load(L, generic_reader, null, chunkname, mode); @@ -378,10 +378,10 @@ const luaopen_base = function(L) { lauxlib.luaL_setfuncs(L, base_funcs, 0); /* set global _G */ lapi.lua_pushvalue(L, -1); - lapi.lua_setfield(L, -2, lua.to_luastring("_G")); + lapi.lua_setfield(L, -2, lua.to_luastring("_G", true)); /* set global _VERSION */ lapi.lua_pushliteral(L, lua.LUA_VERSION); - lapi.lua_setfield(L, -2, lua.to_luastring("_VERSION")); + lapi.lua_setfield(L, -2, lua.to_luastring("_VERSION", true)); return 1; }; diff --git a/src/lcode.js b/src/lcode.js index 0b3d9bd..ec233c6 100644 --- a/src/lcode.js +++ b/src/lcode.js @@ -183,7 +183,7 @@ const fixjump = function(fs, pc, dest) { let offset = dest - (pc + 1); assert(dest !== NO_JUMP); if (Math.abs(offset) > lopcode.MAXARG_sBx) - llex.luaX_syntaxerror(fs.ls, lua.to_luastring("control structure too long")); + llex.luaX_syntaxerror(fs.ls, lua.to_luastring("control structure too long", true)); lopcode.SETARG_sBx(jmp, offset); }; @@ -424,7 +424,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, lua.to_luastring("function or expression needs to many registers")); + llex.luaX_syntaxerror(fs.ls, lua.to_luastring("function or expression needs to many registers", true)); fs.f.maxstacksize = newstack; } }; @@ -1230,7 +1230,7 @@ const luaK_setlist = function(fs, base, nelems, tostore) { codeextraarg(fs, c); } else - llex.luaX_syntaxerror(fs.ls, lua.to_luastring("constructor too long")); + llex.luaX_syntaxerror(fs.ls, lua.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 58d061c..b7c4555 100644 --- a/src/lcorolib.js +++ b/src/lcorolib.js @@ -14,7 +14,7 @@ const TS = lua.thread_status; const getco = function(L) { let co = lapi.lua_tothread(L, 1); - lauxlib.luaL_argcheck(L, co, 1, lua.to_luastring("thread expected")); + lauxlib.luaL_argcheck(L, co, 1, lua.to_luastring("thread expected", true)); return co; }; diff --git a/src/ldblib.js b/src/ldblib.js index dfc7819..c637af2 100644 --- a/src/ldblib.js +++ b/src/ldblib.js @@ -33,7 +33,7 @@ const db_getmetatable = function(L) { const db_setmetatable = function(L) { const t = lapi.lua_type(L, 2); - lauxlib.luaL_argcheck(L, t == lua.CT.LUA_TNIL || t == lua.CT.LUA_TTABLE, 2, lua.to_luastring("nil or table expected")); + lauxlib.luaL_argcheck(L, t == lua.CT.LUA_TNIL || t == lua.CT.LUA_TTABLE, 2, lua.to_luastring("nil or table expected", true)); lapi.lua_settop(L, 2); lapi.lua_setmetatable(L, 1); return 1; /* return 1st argument */ @@ -123,7 +123,7 @@ const db_getinfo = function(L) { let thread = getthread(L); let arg = thread.arg; let L1 = thread.thread; - let options = lauxlib.luaL_optstring(L, arg + 2, lua.to_luastring("flnStu")); + let options = lauxlib.luaL_optstring(L, arg + 2, lua.to_luastring("flnStu", true)); checkstack(L, L1, 3); if (lapi.lua_isfunction(L, arg + 1)) { /* info about a function? */ options = [char['>']].concat(options); /* add '>' to 'options' */ @@ -137,31 +137,31 @@ const db_getinfo = function(L) { } if (!ldebug.lua_getinfo(L1, options, ar)) - lauxlib.luaL_argerror(L, arg + 2, lua.to_luastring("invalid option")); + lauxlib.luaL_argerror(L, arg + 2, lua.to_luastring("invalid option", true)); lapi.lua_newtable(L); /* table to collect results */ if (options.indexOf(char['S']) > -1) { - settabss(L, lua.to_luastring("source"), ar.source.value); - settabss(L, lua.to_luastring("short_src"), ar.short_src); - settabss(L, lua.to_luastring("linedefined"), lua.to_luastring(`${ar.linedefined}`)); - settabss(L, lua.to_luastring("lastlinedefined"), lua.to_luastring(`${ar.lastlinedefined}`)); - settabss(L, lua.to_luastring("what"), ar.what); + settabss(L, lua.to_luastring("source", true), ar.source.value); + settabss(L, lua.to_luastring("short_src", true), ar.short_src); + settabss(L, lua.to_luastring("linedefined", true), lua.to_luastring(`${ar.linedefined}`)); + settabss(L, lua.to_luastring("lastlinedefined", true), lua.to_luastring(`${ar.lastlinedefined}`)); + settabss(L, lua.to_luastring("what", true), ar.what); } if (options.indexOf(char['l']) > -1) - settabsi(L, lua.to_luastring("currentline"), ar.currentline); + settabsi(L, lua.to_luastring("currentline", true), ar.currentline); if (options.indexOf(char['u']) > -1) - settabsi(L, lua.to_luastring("nups"), ar.nups); - settabsi(L, lua.to_luastring("nparams"), ar.nparams); - settabsb(L, lua.to_luastring("isvararg"), ar.isvararg); + 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 (options.indexOf(char['n']) > - 1) { - settabss(L, lua.to_luastring("name"), ar.name ? ar.name : null); - settabss(L, lua.to_luastring("namewhat"), ar.namewhat ? ar.namewhat : null); + settabss(L, lua.to_luastring("name", true), ar.name ? ar.name : null); + settabss(L, lua.to_luastring("namewhat", true), ar.namewhat ? ar.namewhat : null); } if (options.indexOf(char['t']) > - 1) - settabsb(L, lua.to_luastring("istailcall"), ar.istailcall); + settabsb(L, lua.to_luastring("istailcall", true), ar.istailcall); if (options.indexOf(char['L']) > - 1) - treatstackoption(L, L1, lua.to_luastring("activelines")); + treatstackoption(L, L1, lua.to_luastring("activelines", true)); if (options.indexOf(char['f']) > - 1) - treatstackoption(L, L1, lua.to_luastring("func")); + treatstackoption(L, L1, lua.to_luastring("func", true)); return 1; /* return table */ }; @@ -178,7 +178,7 @@ const db_getlocal = function(L) { } else { /* stack-level argument */ let level = lauxlib.luaL_checkinteger(L, arg + 1); if (!ldebug.lua_getstack(L1, level, ar)) /* out of range? */ - return lauxlib.luaL_argerror(L, arg+1, lapi.to_luastring("level out of range")); + return lauxlib.luaL_argerror(L, arg+1, lapi.to_luastring("level out of range", true)); checkstack(L, L1, 1); let name = ldebug.lua_getlocal(L1, ar, nvar); if (name) { @@ -244,7 +244,7 @@ const db_setupvalue = function(L) { const checkupval = function(L, argf, argnup) { let nup = lauxlib.luaL_checkinteger(L, argnup); /* upvalue index */ lauxlib.luaL_checktype(L, argf, lua.CT.LUA_TFUNCTION); /* closure */ - lauxlib.luaL_argcheck(L, (lapi.lua_getupvalue(L, argf, nup) !== null), argnup, lua.to_luastring("invalid upvalue index")); + lauxlib.luaL_argcheck(L, (lapi.lua_getupvalue(L, argf, nup) !== null), argnup, lua.to_luastring("invalid upvalue index", true)); return nup; }; @@ -257,8 +257,8 @@ const db_upvalueid = function(L) { const db_upvaluejoin = function(L) { let n1 = checkupval(L, 1, 2); let n2 = checkupval(L, 3, 4); - lauxlib.luaL_argcheck(L, !lapi.lua_iscfunction(L, 1), 1, lua.to_luastring("Lua function expected")); - lauxlib.luaL_argcheck(L, !lapi.lua_iscfunction(L, 3), 3, lua.to_luastring("Lua function expected")); + lauxlib.luaL_argcheck(L, !lapi.lua_iscfunction(L, 1), 1, lua.to_luastring("Lua function expected", true)); + lauxlib.luaL_argcheck(L, !lapi.lua_iscfunction(L, 3), 3, lua.to_luastring("Lua function expected", true)); lapi.lua_upvaluejoin(L, 1, n1, 3, n2); return 0; }; @@ -267,7 +267,7 @@ 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__"); +const HOOKKEY = lua.to_luastring("__hooks__", true); const hooknames = ["call", "return", "line", "count", "tail call"].map(e => lua.to_luastring(e)); @@ -331,7 +331,7 @@ const db_sethook = function(L) { lapi.lua_pushvalue(L, -1); lapi.lua_rawsetp(L, lua.LUA_REGISTRYINDEX, HOOKKEY); /* set it in position */ lapi.lua_pushstring(L, [char["k"]]); - lapi.lua_setfield(L, -2, lua.to_luastring("__mode")); /** hooktable.__mode = "k" */ + lapi.lua_setfield(L, -2, lua.to_luastring("__mode", true)); /** hooktable.__mode = "k" */ lapi.lua_pushvalue(L, -1); lapi.lua_setmetatable(L, -2); /* setmetatable(hooktable) = hooktable */ } @@ -423,7 +423,7 @@ if (typeof require === "function") { continue; let buffer = lua.to_luastring(input); - if (lauxlib.luaL_loadbuffer(L, buffer, buffer.length, lua.to_luastring("=(debug command)")) + if (lauxlib.luaL_loadbuffer(L, buffer, buffer.length, lua.to_luastring("=(debug command)", true)) || lapi.lua_pcall(L, 0, 0, 0)) { lauxlib.lua_writestringerror(`${lapi.lua_tojsstring(L, -1)}\n`); } diff --git a/src/ldebug.js b/src/ldebug.js index d769500..16449e2 100644 --- a/src/ldebug.js +++ b/src/ldebug.js @@ -94,7 +94,7 @@ const findvararg = function(ci, n, pos) { else { return { pos: ci.funcOff + nparams + n, - name: lua.to_luastring("(*vararg)") /* generic name for any vararg */ + name: lua.to_luastring("(*vararg)", true) /* generic name for any vararg */ }; } }; @@ -115,7 +115,7 @@ const findlocal = function(L, ci, n) { if (name === null) { /* no 'standard' name? */ let limit = ci === L.ci ? L.top : ci.next.func; if (limit - base >= n && n > 0) /* is 'n' inside 'ci' stack? */ - name = lua.to_luastring("(*temporary)"); /* generic name for any valid slot */ + name = lua.to_luastring("(*temporary)", true); /* generic name for any valid slot */ else return null; /* no name */ } @@ -160,16 +160,16 @@ const lua_setlocal = function(L, ar, n) { const funcinfo = function(ar, cl) { if (cl === null || cl.type === CT.LUA_TCCL) { - ar.source = lua.to_luastring("=[JS]"); + ar.source = lua.to_luastring("=[JS]", true); ar.linedefined = -1; ar.lastlinedefined = -1; ar.what = "J"; } else { let p = cl.p; - ar.source = p.source ? p.source : lua.to_luastring("=?"); + ar.source = p.source ? p.source : lua.to_luastring("=?", true); ar.linedefined = p.linedefined; ar.lastlinedefined = p.lastlinedefined; - ar.what = ar.linedefined === 0 ? lua.to_luastring("main") : lua.to_luastring("Lua"); + ar.what = ar.linedefined === 0 ? lua.to_luastring("main", true) : lua.to_luastring("Lua", true); } ar.short_src = lobject.luaO_chunkid(ar.source, luaconf.LUA_IDSIZE); @@ -198,8 +198,8 @@ const getfuncname = function(L, ci) { if (ci === null) return null; else if (ci.callstatus & lstate.CIST_FIN) { /* is this a finalizer? */ - r.name = lua.to_luastring("__gc"); - r.funcname = lua.to_luastring("metamethod"); /* report it as such */ + r.name = lua.to_luastring("__gc", true); + r.funcname = lua.to_luastring("metamethod", true); /* report it as such */ return r; } /* calling function is a known Lua function? */ @@ -373,7 +373,7 @@ const getobjname = function(p, lastpc, reg) { }; if (r.name) { /* is a local? */ - r.funcname = lua.to_luastring("local"); + r.funcname = lua.to_luastring("local", true); return r; } @@ -396,12 +396,12 @@ const getobjname = function(p, lastpc, reg) { let vn = op === 'OP_GETTABLE' ? lfunc.luaF_getlocalname(p, t + 1, pc) : upvalname(p, t); vn = vn ? vn.jsstring() : null; r.name = kname(p, pc, k).name; - r.funcname = vn && vn === "_ENV" ? lua.to_luastring("global") : lua.to_luastring("field"); + r.funcname = vn && vn === "_ENV" ? lua.to_luastring("global", true) : lua.to_luastring("field", true); return r; } case 'OP_GETUPVAL': { r.name = upvalname(p, i.B); - r.funcname = lua.to_luastring("upvalue"); + r.funcname = lua.to_luastring("upvalue", true); return r; } case 'OP_LOADK': @@ -409,7 +409,7 @@ const getobjname = function(p, lastpc, reg) { let b = op === 'OP_LOADK' ? i.Bx : p.code[pc + 1].Ax; if (p.k[b].ttisstring()) { r.name = p.k[b].value; - r.funcname = lua.to_luastring("constant"); + r.funcname = lua.to_luastring("constant", true); return r; } break; @@ -417,7 +417,7 @@ const getobjname = function(p, lastpc, reg) { case 'OP_SELF': { let k = i.C; r.name = kname(p, pc, k).name; - r.funcname = lua.to_luastring("method"); + r.funcname = lua.to_luastring("method", true); return r; } default: break; @@ -446,7 +446,7 @@ const funcnamefromcode = function(L, ci) { if (ci.callstatus & lstate.CIST_HOOKED) { r.name = [lua.char["?"]]; - r.funcname = lua.to_luastring("hook"); + r.funcname = lua.to_luastring("hook", true); return r; } @@ -455,8 +455,8 @@ const funcnamefromcode = function(L, ci) { case 'OP_TAILCALL': return getobjname(p, pc, i.A); /* get function name */ case 'OP_TFORCALL': - r.name = lua.to_luastring("for iterator"); - r.funcname = lua.to_luastring("for iterator"); + r.name = lua.to_luastring("for iterator", true); + r.funcname = lua.to_luastring("for iterator", true); return r; /* other instructions can do calls through metamethods */ case 'OP_SELF': @@ -492,7 +492,7 @@ const funcnamefromcode = function(L, ci) { } r.name = L.l_G.tmname[tm]; - r.funcname = lua.to_luastring("metamethod"); + r.funcname = lua.to_luastring("metamethod", true); return r; }; @@ -516,7 +516,7 @@ const getupvalname = function(L, ci, o, name) { if (c.upvals[i].val(L) === o) { return { name: upvalname(c.p, i), - funcname: lua.to_luastring('upvalue') + funcname: lua.to_luastring('upvalue', true) }; } } @@ -544,7 +544,7 @@ const luaG_typeerror = function(L, o, op) { const luaG_concaterror = function(L, p1, p2) { if (p1.ttisstring() || p1.ttisnumber()) p1 = p2; - luaG_typeerror(L, p1, lua.to_luastring('concatenate')); + luaG_typeerror(L, p1, lua.to_luastring('concatenate', true)); }; /* diff --git a/src/ldo.js b/src/ldo.js index 0fcbf0e..a3521c8 100644 --- a/src/ldo.js +++ b/src/ldo.js @@ -23,11 +23,11 @@ const TValue = lobject.TValue; const seterrorobj = function(L, errcode, oldtop) { switch (errcode) { case TS.LUA_ERRMEM: { - L.stack[oldtop] = L.l_G.intern(lua.to_luastring("not enough memory")); + L.stack[oldtop] = L.l_G.intern(lua.to_luastring("not enough memory", true)); break; } case TS.LUA_ERRERR: { - L.stack[oldtop] = L.l_G.intern(lua.to_luastring("error in error handling")); + L.stack[oldtop] = L.l_G.intern(lua.to_luastring("error in error handling", true)); break; } default: { @@ -483,9 +483,9 @@ const lua_yieldk = function(L, nresults, ctx, k) { if (L.nny > 0) { if (L !== L.l_G.mainthread) - ldebug.luaG_runerror(L, lua.to_luastring("attempt to yield across a JS-call boundary")); + ldebug.luaG_runerror(L, lua.to_luastring("attempt to yield across a JS-call boundary", true)); else - ldebug.luaG_runerror(L, lua.to_luastring("attempt to yield from outside a coroutine")); + ldebug.luaG_runerror(L, lua.to_luastring("attempt to yield from outside a coroutine", true)); } L.status = TS.LUA_YIELD; @@ -564,10 +564,10 @@ const f_parser = function(L, p) { let cl; let c = p.z.getc(); /* read first character */ if (c === lua.LUA_SIGNATURE.charCodeAt(0)) { - checkmode(L, p.mode, lua.to_luastring("binary")); + checkmode(L, p.mode, lua.to_luastring("binary", true)); cl = new BytecodeParser(L, p.z.buffer).luaU_undump(); } else { - checkmode(L, p.mode, lua.to_luastring("text")); + checkmode(L, p.mode, lua.to_luastring("text", true)); cl = lparser.luaY_parser(L, p.z, p.buff, p.dyd, p.name, c); } diff --git a/src/llex.js b/src/llex.js index 3ed0e56..b038619 100644 --- a/src/llex.js +++ b/src/llex.js @@ -152,7 +152,7 @@ const save = function(ls, c) { let b = ls.buff; if (b.n + 1 > b.buffer.length) { if (b.buffer.length >= Number.MAX_SAFE_INTEGER/2) - lexerror(ls, lua.to_luastring("lexical element too long"), 0); + lexerror(ls, lua.to_luastring("lexical element too long", true), 0); } b.buffer[b.n++] = c < 0 ? 255 + c + 1 : c; }; @@ -193,7 +193,7 @@ const inclinenumber = function(ls) { if (currIsNewline(ls) && ls.current !== old) next(ls); /* skip '\n\r' or '\r\n' */ if (++ls.linenumber >= Number.MAX_SAFE_INTEGER) - lexerror(ls, lua.to_luastring("chunk has too many lines"), 0); + lexerror(ls, lua.to_luastring("chunk has too many lines", true), 0); }; const luaX_setinput = function(L, ls, z, source, firstchar) { @@ -220,7 +220,7 @@ const luaX_setinput = function(L, ls, z, source, firstchar) { ls.linenumber = 1; ls.lastline = 1; ls.source = source; - ls.envn = L.l_G.intern(lua.to_luastring("_ENV")); + ls.envn = L.l_G.intern(lua.to_luastring("_ENV", true)); }; const check_next1 = function(ls, c) { @@ -267,7 +267,7 @@ const read_numeral = function(ls, seminfo) { let obj = lobject.luaO_str2num(ls.buff.buffer); if (obj === false) /* format error? */ - lexerror(ls, lua.to_luastring("malformed number"), R.TK_FLT); + lexerror(ls, lua.to_luastring("malformed number", true), R.TK_FLT); if (obj.ttisinteger()) { seminfo.i = obj.value; return R.TK_INT; @@ -373,7 +373,7 @@ const esccheck = function(ls, c, msg) { const gethexa = function(ls) { save_and_next(ls); - esccheck(ls, ljstype.lisxdigit(ls.current), lua.to_luastring("hexadecimal digit expected")); + esccheck(ls, ljstype.lisxdigit(ls.current), lua.to_luastring("hexadecimal digit expected", true)); return lobject.luaO_hexavalue(ls.current); }; @@ -387,17 +387,17 @@ const readhexaesc = function(ls) { 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['{'], lua.to_luastring("missing '{'")); + esccheck(ls, ls.current === char['{'], lua.to_luastring("missing '{'", true)); let r = gethexa(ls); /* must have at least one digit */ save_and_next(ls); while (ljstype.lisxdigit(ls.current)) { i++; r = (r << 4) + lobject.luaO_hexavalue(ls.current); - esccheck(ls, r <= 0x10FFFF, lua.to_luastring("UTF-8 value too large")); + esccheck(ls, r <= 0x10FFFF, lua.to_luastring("UTF-8 value too large", true)); save_and_next(ls); } - esccheck(ls, ls.current === char['}'], lua.to_luastring("missing '}'")); + esccheck(ls, ls.current === char['}'], lua.to_luastring("missing '}'", true)); next(ls); /* skip '}' */ ls.buff.n -= i; /* remove saved chars from buffer */ return r; @@ -417,7 +417,7 @@ const readdecesc = function(ls) { r = 10 * r + ls.current - char['0']; save_and_next(ls); } - esccheck(ls, r <= 255, lua.to_luastring("decimal escape too large")); + esccheck(ls, r <= 255, lua.to_luastring("decimal escape too large", true)); ls.buff.n -= i; /* remove read digits from buffer */ return r; }; @@ -428,11 +428,11 @@ const read_string = function(ls, del, seminfo) { while (ls.current !== del) { switch (ls.current) { case -1: - lexerror(ls, lua.to_luastring("unfinished string"), R.TK_EOS); + lexerror(ls, lua.to_luastring("unfinished string", true), R.TK_EOS); break; case char['\n']: case char['\r']: - lexerror(ls, lua.to_luastring("unfinished string"), R.TK_STRING); + lexerror(ls, lua.to_luastring("unfinished string", true), R.TK_STRING); break; case char['\\']: { /* escape sequences */ save_and_next(ls); /* keep '\\' for error messages */ @@ -463,7 +463,7 @@ const read_string = function(ls, del, seminfo) { will = 'no_save'; break; } default: { - esccheck(ls, ljstype.lisdigit(ls.current), lua.to_luastring("invalid escape sequence")); + esccheck(ls, ljstype.lisdigit(ls.current), lua.to_luastring("invalid escape sequence", true)); c = readdecesc(ls); /* digital escape '\ddd' */ will = 'only_save'; break; } @@ -537,7 +537,7 @@ const llex = function(ls, seminfo) { read_long_string(ls, seminfo, sep); return R.TK_STRING; } else if (sep !== -1) /* '[=...' missing second bracket */ - lexerror(ls, lua.to_luastring("invalid long string delimiter"), R.TK_STRING); + lexerror(ls, lua.to_luastring("invalid long string delimiter", true), R.TK_STRING); return char['[']; } case char['=']: { diff --git a/src/lmathlib.js b/src/lmathlib.js index 500331b..c052fcb 100644 --- a/src/lmathlib.js +++ b/src/lmathlib.js @@ -37,13 +37,13 @@ const math_random = function(L) { up = lauxlib.luaL_checkinteger(L, 2); break; } - default: return lauxlib.luaL_error(L, lua.to_luastring("wrong number of arguments")); + default: return lauxlib.luaL_error(L, lua.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")); + lauxlib.luaL_argcheck(L, low <= up, 1, lua.to_luastring("interval is empty", true)); lauxlib.luaL_argcheck(L, low >= 0 || up <= Number.MAX_SAFE_INTEGER + low, 1, - lua.to_luastring("interval too large")); + lua.to_luastring("interval too large", true)); r *= (up - low) + 1; lapi.lua_pushinteger(L, r + low); @@ -173,7 +173,7 @@ const math_rad = function(L) { const math_min = function(L) { let n = lapi.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")); + lauxlib.luaL_argcheck(L, n >= 1, 1, lua.to_luastring("value expected", true)); for (let i = 2; i <= n; i++){ if (lapi.lua_compare(L, i, imin, lua.LUA_OPLT)) imin = i; @@ -185,7 +185,7 @@ const math_min = function(L) { const math_max = function(L) { let n = lapi.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")); + lauxlib.luaL_argcheck(L, n >= 1, 1, lua.to_luastring("value expected", true)); for (let i = 2; i <= n; i++){ if (lapi.lua_compare(L, imax, i, lua.LUA_OPLT)) imax = i; @@ -211,7 +211,7 @@ const math_fmod = function(L) { if (lapi.lua_isinteger(L, 1) && lapi.lua_isinteger(L, 2)) { let d = lapi.lua_tointeger(L, 2); if (Math.abs(d) + 1 <= 1) { - lauxlib.luaL_argcheck(L, d !== 0, 2, lua.to_luastring("zero")); + lauxlib.luaL_argcheck(L, d !== 0, 2, lua.to_luastring("zero", true)); lapi.lua_pushinteger(L, 0); } else lapi.lua_pushinteger(L, lapi.lua_tointeger(L, 1) % d); @@ -265,13 +265,13 @@ const mathlib = { const luaopen_math = function(L) { lauxlib.luaL_newlib(L, mathlib); lapi.lua_pushnumber(L, Math.PI); - lapi.lua_setfield(L, -2, lua.to_luastring("pi")); + lapi.lua_setfield(L, -2, lua.to_luastring("pi", true)); lapi.lua_pushnumber(L, Number.MAX_VALUE); - lapi.lua_setfield(L, -2, lua.to_luastring("huge")); + lapi.lua_setfield(L, -2, lua.to_luastring("huge", true)); lapi.lua_pushinteger(L, Number.MAX_SAFE_INTEGER); - lapi.lua_setfield(L, -2, lua.to_luastring("maxinteger")); + lapi.lua_setfield(L, -2, lua.to_luastring("maxinteger", true)); lapi.lua_pushinteger(L, Number.MIN_SAFE_INTEGER); - lapi.lua_setfield(L, -2, lua.to_luastring("mininteger")); + lapi.lua_setfield(L, -2, lua.to_luastring("mininteger", true)); return 1; }; diff --git a/src/lobject.js b/src/lobject.js index 78434ae..52ca385 100644 --- a/src/lobject.js +++ b/src/lobject.js @@ -274,7 +274,7 @@ class LocVar { } } -const RETS = lua.to_luastring("..."); +const RETS = lua.to_luastring("...", true); const PRE = lua.to_luastring("[string \""); const POS = lua.to_luastring("\"]"); diff --git a/src/lparser.js b/src/lparser.js index bdaa160..cf5f55b 100644 --- a/src/lparser.js +++ b/src/lparser.js @@ -242,7 +242,7 @@ 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, lua.to_luastring("local variables")); + checklimit(fs, dyd.actvar.n + 1 - fs.firstlocal, MAXVARS, lua.to_luastring("local variables", true)); dyd.actvar.arr[dyd.actvar.n] = new Vardesc(); dyd.actvar.arr[dyd.actvar.n].idx = reg; dyd.actvar.n++; @@ -282,7 +282,7 @@ const searchupvalue = function(fs, name) { const newupvalue = function(fs, name, v) { let f = fs.f; - checklimit(fs, fs.nups + 1, lfunc.MAXUPVAL, lua.to_luastring("upvalues")); + checklimit(fs, fs.nups + 1, lfunc.MAXUPVAL, lua.to_luastring("upvalues", true)); f.upvalues[fs.nups] = new UpVal(fs.ls.L); f.upvalues[fs.nups].instack = v.k === expkind.VLOCAL; f.upvalues[fs.nups].idx = v.u.info; @@ -373,7 +373,7 @@ const adjust_assign = function(ls, nvars, nexps, e) { const enterlevel = function(ls) { let L = ls.L; ++L.nCcalls; - checklimit(ls.fs, L.nCcalls, llimit.LUAI_MAXCCALLS, lua.to_luastring("JS levels")); + checklimit(ls.fs, L.nCcalls, llimit.LUAI_MAXCCALLS, lua.to_luastring("JS levels", true)); }; const leavelevel = function(ls) { @@ -480,7 +480,7 @@ const enterblock = function(fs, bl, isloop) { ** create a label named 'break' to resolve break statements */ const breaklabel = function(ls) { - let n = new TValue(lua.CT.LUA_TLNGSTR, lua.to_luastring("break")); + let n = new TValue(lua.CT.LUA_TLNGSTR, lua.to_luastring("break", true)); let l = newlabelentry(ls, ls.dyd.label, n, 0, ls.fs.pc); findgotos(ls, ls.dyd.label.arr[l]); }; @@ -639,7 +639,7 @@ const recfield = function(ls, cc) { let val = new expdesc(); if (ls.t.token === R.TK_NAME) { - checklimit(fs, cc.nh, Number.MAX_SAFE_INTEGER, lua.to_luastring("items in a constructor")); + checklimit(fs, cc.nh, Number.MAX_SAFE_INTEGER, lua.to_luastring("items in a constructor", true)); checkname(ls, key); } else /* ls->t.token === '[' */ yindex(ls, key); @@ -677,7 +677,7 @@ const lastlistfield = function(fs, cc) { const listfield = function(ls, cc) { /* listfield -> exp */ expr(ls, cc.v); - checklimit(ls.fs, cc.na, Number.MAX_SAFE_INTEGER, lua.to_luastring("items in a constructor")); + checklimit(ls.fs, cc.na, Number.MAX_SAFE_INTEGER, lua.to_luastring("items in a constructor", true)); cc.na++; cc.tostore++; }; @@ -749,7 +749,7 @@ const parlist = function(ls) { f.is_vararg = 1; /* declared vararg */ break; } - default: llex.luaX_syntaxerror(ls, lua.to_luastring(" or '...' expected")); + default: llex.luaX_syntaxerror(ls, lua.to_luastring(" or '...' expected", true)); } } while(!f.is_vararg && testnext(ls, char[','])); } @@ -767,7 +767,7 @@ const body = function(ls, e, ismethod, line) { open_func(ls, new_fs, bl); checknext(ls, char['(']); if (ismethod) { - new_localvarliteral(ls, lua.to_luastring("self")); /* create 'self' parameter */ + new_localvarliteral(ls, lua.to_luastring("self", true)); /* create 'self' parameter */ adjustlocalvars(ls, 1); } parlist(ls); @@ -816,7 +816,7 @@ const funcargs = function(ls, f, line) { break; } default: { - llex.luaX_syntaxerror(ls, lua.to_luastring("function arguments expected")); + llex.luaX_syntaxerror(ls, lua.to_luastring("function arguments expected", true)); } } assert(f.k === expkind.VNONRELOC); @@ -856,7 +856,7 @@ const primaryexp = function(ls, v) { return; } default: { - llex.luaX_syntaxerror(ls, lua.to_luastring("unexpected symbol")); + llex.luaX_syntaxerror(ls, lua.to_luastring("unexpected symbol", true)); } } }; @@ -930,7 +930,7 @@ const simpleexp = function(ls, v) { } case R.TK_DOTS: { /* vararg */ let fs = ls.fs; - check_condition(ls, fs.f.is_vararg, lua.to_luastring("cannot use '...' outside a vararg function")); + check_condition(ls, fs.f.is_vararg, lua.to_luastring("cannot use '...' outside a vararg function", true)); init_exp(v, expkind.VVARARG, lcode.luaK_codeABC(fs, OpCodesI.OP_VARARG, 0, 1, 0)); break; } @@ -1102,14 +1102,14 @@ const check_conflict = function(ls, lh, v) { const assignment = function(ls, lh, nvars) { let e = new expdesc(); - check_condition(ls, vkisvar(lh.v.k), lua.to_luastring("syntax error")); + check_condition(ls, vkisvar(lh.v.k), lua.to_luastring("syntax error", true)); if (testnext(ls, char[','])) { /* 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, llimit.LUAI_MAXCCALLS, lua.to_luastring("JS levels")); + checklimit(ls.fs, nvars + ls.L.nCcalls, llimit.LUAI_MAXCCALLS, lua.to_luastring("JS levels", true)); assignment(ls, nv, nvars + 1); } else { /* assignment -> '=' explist */ checknext(ls, char['=']); @@ -1142,7 +1142,7 @@ const gotostat = function(ls, pc) { label = str_checkname(ls); else { llex.luaX_next(ls); /* skip break */ - label = new TValue(lua.CT.LUA_TLNGSTR, lua.to_luastring("break")); + label = new TValue(lua.CT.LUA_TLNGSTR, lua.to_luastring("break", true)); } let g = newlabelentry(ls, ls.dyd.gt, label, line, pc); findlabel(ls, g); /* close it if label already defined */ @@ -1253,9 +1253,9 @@ const fornum = function(ls, varname, line) { /* fornum -> NAME = exp1,exp1[,exp1] forbody */ let fs = ls.fs; let base = fs.freereg; - new_localvarliteral(ls, lua.to_luastring("(for index)")); - new_localvarliteral(ls, lua.to_luastring("(for limit)")); - new_localvarliteral(ls, lua.to_luastring("(for step)")); + new_localvarliteral(ls, lua.to_luastring("(for index)", true)); + new_localvarliteral(ls, lua.to_luastring("(for limit)", true)); + new_localvarliteral(ls, lua.to_luastring("(for step)", true)); new_localvar(ls, varname); checknext(ls, char['=']); exp1(ls); /* initial value */ @@ -1277,9 +1277,9 @@ const forlist = function(ls, indexname) { let nvars = 4; /* gen, state, control, plus at least one declared var */ let base = fs.freereg; /* create control variables */ - new_localvarliteral(ls, lua.to_luastring("(for generator)")); - new_localvarliteral(ls, lua.to_luastring("(for state)")); - new_localvarliteral(ls, lua.to_luastring("(for control)")); + new_localvarliteral(ls, lua.to_luastring("(for generator)", true)); + new_localvarliteral(ls, lua.to_luastring("(for state)", true)); + new_localvarliteral(ls, lua.to_luastring("(for control)", true)); /* create declared variables */ new_localvar(ls, indexname); while (testnext(ls, char[','])) { @@ -1303,7 +1303,7 @@ const forstat = function(ls, line) { 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, lua.to_luastring("'=' or 'in' expected")); + default: llex.luaX_syntaxerror(ls, lua.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) */ @@ -1421,7 +1421,7 @@ const exprstat= function(ls) { assignment(ls, v, 1); } else { /* stat -> func */ - check_condition(ls, v.v.k === expkind.VCALL, lua.to_luastring("syntax error")); + check_condition(ls, v.v.k === expkind.VCALL, lua.to_luastring("syntax error", true)); lopcode.SETARG_C(lcode.getinstruction(fs, v.v), 1); /* call statement uses no results */ } }; diff --git a/src/lstrlib.js b/src/lstrlib.js index 73fc068..c2ee817 100644 --- a/src/lstrlib.js +++ b/src/lstrlib.js @@ -103,11 +103,11 @@ const num2straux = function(x) { let buff = []; /* if 'inf' or 'NaN', format it like '%g' */ if (Object.is(x, Infinity)) - return lua.to_luastring('inf'); + return lua.to_luastring('inf', true); else if (Object.is(x, -Infinity)) - return lua.to_luastring('-inf'); + return lua.to_luastring('-inf', true); else if (Number.isNaN(x)) - return lua.to_luastring('nan'); + return lua.to_luastring('nan', true); else if (x === 0) { /* can be -0... */ /* create "0" or "-0" followed by exponent */ let zero = sprintf(luaconf.LUA_NUMBER_FMT + "x0p+0", x).split('').map(e => e.charCodeAt(0)); @@ -144,7 +144,7 @@ const lua_number2strx = function(L, fmt, x) { for (let i = 0; i < buff.length; i++) buff[i] = char[String.fromCharCode(buff[i]).toUpperCase()]; } else if (fmt[SIZELENMOD] !== char['a']) - lauxlib.luaL_error(L, lua.to_luastring("modifiers for format '%a'/'%A' not implemented")); + lauxlib.luaL_error(L, lua.to_luastring("modifiers for format '%a'/'%A' not implemented", true)); return buff; }; @@ -239,7 +239,7 @@ const addliteral = function(L, b, arg) { break; } default: { - lauxlib.luaL_argerror(L, arg, lua.to_luastring("value has no literal form")); + lauxlib.luaL_argerror(L, arg, lua.to_luastring("value has no literal form", true)); } } }; @@ -248,7 +248,7 @@ const scanformat = function(L, strfrmt, form) { let p = strfrmt; while (p[0] !== 0 && FLAGS.indexOf(p[0]) >= 0) p = p.slice(1); /* skip flags */ if (strfrmt.length - p.length >= FLAGS.length) - lauxlib.luaL_error(L, lua.to_luastring("invalid format (repeated flags)")); + lauxlib.luaL_error(L, lua.to_luastring("invalid format (repeated flags)", true)); if (isdigit(p[0])) p = p.slice(1); /* skip width */ if (isdigit(p[0])) p = p.slice(1); /* (2 digits at most) */ if (p[0] === char['.']) { @@ -257,7 +257,7 @@ const scanformat = function(L, strfrmt, form) { if (isdigit(p[0])) p = p.slice(1); /* (2 digits at most) */ } if (isdigit(p[0])) - lauxlib.luaL_error(L, lua.to_luastring("invalid format (width or precision too long)")); + lauxlib.luaL_error(L, lua.to_luastring("invalid format (width or precision too long)", true)); form[0] = char["%"]; for (let i = 0; i < strfrmt.length - p.length + 1; i++) form[i + 1] = strfrmt[i]; @@ -298,7 +298,7 @@ const str_format = function(L) { } else { /* format item */ let form = []; /* to store the format ('%...') */ if (++arg > top) - lauxlib.luaL_argerror(L, arg, lua.to_luastring("no value")); + lauxlib.luaL_argerror(L, arg, lua.to_luastring("no value", true)); let f = scanformat(L, strfrmt, form); strfrmt = f.p; form = f.form; @@ -343,7 +343,7 @@ const str_format = function(L) { concat(b, s); /* keep entire string */ lapi.lua_pop(L, 1); /* remove result from 'luaL_tolstring' */ } else { - lauxlib.luaL_argcheck(L, s.length === strlen(s), arg, lua.to_luastring("string contains zeros")); + lauxlib.luaL_argcheck(L, s.length === strlen(s), arg, lua.to_luastring("string contains zeros", true)); if (form.indexOf(char['.']) < 0 && s.length >= 100) { /* no precision and string is too long to be formatted */ concat(b, s); /* keep entire string */ @@ -468,7 +468,7 @@ const getoption = function(h, fmt) { case char['c']: { r.size = getnum(fmt, -1); if (r.size === -1) - lauxlib.luaL_error(h.L, lua.to_luastring("missing size for format option 'c'")); + lauxlib.luaL_error(h.L, lua.to_luastring("missing size for format option 'c'", true)); r.opt = KOption.Kchar; return r; } @@ -509,13 +509,13 @@ const getdetails = function(h, totalsize, fmt) { let align = r.size; /* usually, alignment follows size */ if (r.opt === KOption.Kpaddalign) { /* 'X' gets alignment from following option */ if (fmt.s[0] === 0) - lauxlib.luaL_argerror(h.L, 1, lua.to_luastring("invalid next option for option 'X'")); + lauxlib.luaL_argerror(h.L, 1, lua.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'")); + lauxlib.luaL_argerror(h.L, 1, lua.to_luastring("invalid next option for option 'X'", true)); } } if (align <= 1 || r.opt === KOption.Kchar) /* need no alignment? */ @@ -524,7 +524,7 @@ const getdetails = function(h, totalsize, fmt) { 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")); + lauxlib.luaL_argerror(h.L, 1, lua.to_luastring("format asks for alignment not power of 2", true)); r.ntoalign = (align - (totalsize & (align - 1))) & (align - 1); } return r; @@ -585,7 +585,7 @@ const str_pack = function(L) { let n = lauxlib.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")); + lauxlib.luaL_argcheck(L, -lim <= n && n < lim, arg, lua.to_luastring("integer overflow", true)); } packint(b, n, h.islittle, size, n < 0); break; @@ -593,7 +593,7 @@ const str_pack = function(L) { case KOption.Kuint: { /* unsigned integers */ let n = lauxlib.luaL_checkinteger(L, arg); if (size < SZINT) - lauxlib.luaL_argcheck(L, n < (1 << (size * NB)), arg, lua.to_luastring("unsigned overflow")); + lauxlib.luaL_argcheck(L, n < (1 << (size * NB)), arg, lua.to_luastring("unsigned overflow", true)); packint(b, n, h.islittle, size, false); break; } @@ -605,7 +605,7 @@ const str_pack = function(L) { case KOption.Kchar: { /* fixed-size string */ let s = lauxlib.luaL_checkstring(L, arg); let len = s.length; - lauxlib.luaL_argcheck(L, len <= size, arg, lua.to_luastring("string long than given size")); + lauxlib.luaL_argcheck(L, len <= size, arg, lua.to_luastring("string long than given size", true)); b.push(...s); /* add string */ while (len++ < size) /* pad extra space */ b.push(LUAL_PACKPADBYTE); @@ -614,7 +614,7 @@ const str_pack = function(L) { case KOption.Kstring: { /* strings with length count */ let s = lauxlib.luaL_checkstring(L, arg); let len = s.length; - lauxlib.luaL_argcheck(L, size >= NB || len < (1 << size * NB), arg, lua.to_luastring("string length does not fit in given size")); + lauxlib.luaL_argcheck(L, size >= NB || len < (1 << size * NB), arg, lua.to_luastring("string length does not fit in given size", true)); packint(b, len, h.islittle, size, 0); /* pack length */ b.push(...s); totalsize += len; @@ -623,7 +623,7 @@ const str_pack = function(L) { case KOption.Kzstr: { /* zero-terminated string */ let s = lauxlib.luaL_checkstring(L, arg); let len = s.length; - lauxlib.luaL_argcheck(L, s.length === String.fromCharCode(...s).length, arg, lua.to_luastring("strings contains zeros")); + lauxlib.luaL_argcheck(L, s.length === String.fromCharCode(...s).length, arg, lua.to_luastring("strings contains zeros", true)); b.push(...s); b.push(0); /* add zero at the end */ totalsize += len + 1; @@ -662,7 +662,7 @@ const str_rep = function(L) { let sep = lauxlib.luaL_optstring(L, 3, []); if (s.length + sep.length < s.length || s.length + sep.length > MAXSIZE / n) /* may overflow? */ - return lauxlib.luaL_error(L, lua.to_luastring("resulting string too large")); + return lauxlib.luaL_error(L, lua.to_luastring("resulting string too large", true)); let r = []; for (let i = 0; i < n - 1; i++) @@ -683,10 +683,10 @@ const str_byte = function(L) { 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")); + return lauxlib.luaL_error(L, lua.to_luastring("string slice too long", true)); let n = (pose - posi) + 1; - lauxlib.luaL_checkstack(L, n, lua.to_luastring("string slice too long")); + lauxlib.luaL_checkstack(L, n, lua.to_luastring("string slice too long", true)); for (let i = 0; i < n; i++) lapi.lua_pushinteger(L, s[posi + i - 1]); return n; @@ -707,12 +707,12 @@ 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")); + lauxlib.luaL_argcheck(L, totalsize <= MAXSIZE - size - 1, lua.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")); + lauxlib.luaL_argerror(L, 1, lua.to_luastring("variable-length format", true)); default: break; } } @@ -771,17 +771,17 @@ const str_unpack = function(L) { let ld = data.length; let pos = posrelat(lauxlib.luaL_optinteger(L, 3, 1), ld) - 1; let n = 0; /* number of results */ - lauxlib.luaL_argcheck(L, pos <= ld, 3, lua.to_luastring("initial position out of string")); + lauxlib.luaL_argcheck(L, pos <= ld, 3, lua.to_luastring("initial position out of string", true)); while (fmt.s.length - 1 > 0) { 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")); + lauxlib.luaL_argerror(L, 2, lua.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")); + lauxlib.luaL_checkstack(L, 2, lua.to_luastring("too many results", true)); n++; switch (opt) { case KOption.Kint: @@ -801,7 +801,7 @@ const str_unpack = function(L) { } 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")); + lauxlib.luaL_argcheck(L, pos + len + size <= ld, 2, lua.to_luastring("data string too short", true)); lapi.lua_pushstring(L, data.slice(pos + size, pos + size + len)); pos += len; /* skip string */ break; @@ -852,21 +852,21 @@ 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 lauxlib.luaL_error(ms.L, lua.to_luastring("invalid pattern capture", true)); }; 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 '%')")); + lauxlib.luaL_error(ms.L, lua.to_luastring("malformed pattern (ends with '%')", true)); return p + 1; } case char['[']: { if (ms.p[p] === char['^']) p++; do { /* look for a ']' */ if (p === ms.p_end) - lauxlib.luaL_error(ms.L, lua.to_luastring("malformed pattern (missing ']')")); + lauxlib.luaL_error(ms.L, lua.to_luastring("malformed pattern (missing ']')", true)); if (ms.p[p++] === L_ESC && p < ms.p_end) p++; /* skip escapes (e.g. '%]') */ } while (ms.p[p] !== char[']']); @@ -933,7 +933,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'")); + lauxlib.luaL_error(ms.L, lua.to_luastring("malformed pattern (missing arguments to '%b'", true)); if (ms.src[s] !== ms.p[p]) return null; else { @@ -976,7 +976,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")); + if (level >= LUA_MAXCAPTURES) lauxlib.luaL_error(ms.L, lua.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; @@ -1009,7 +1009,7 @@ const match = function(ms, s, p) { let gotoinit = true; if (ms.matchdepth-- === 0) - lauxlib.luaL_error(ms.L, lua.to_luastring("pattern too complex")); + lauxlib.luaL_error(ms.L, lua.to_luastring("pattern too complex", true)); while (gotoinit || gotodefault) { gotoinit = false; @@ -1118,7 +1118,7 @@ const push_onecapture = function(ms, i, s, e) { lauxlib.luaL_error(ms.L, lua.to_luastring(`invalid capture index %${i + 1}`)); } else { let l = ms.capture[i].len; - if (l === CAP_UNFINISHED) lauxlib.luaL_error(ms.L, lua.to_luastring("unfinished capture")); + if (l === CAP_UNFINISHED) lauxlib.luaL_error(ms.L, lua.to_luastring("unfinished capture", true)); if (l === CAP_POSITION) lapi.lua_pushinteger(ms.L, ms.src_init + 1); else @@ -1128,7 +1128,7 @@ const push_onecapture = function(ms, i, s, e) { 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")); + lauxlib.luaL_checkstack(ms.L, nlevels, lua.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 */ @@ -1340,7 +1340,7 @@ const str_gsub = function(L) { let ms = new MatchState(L); let b = new lauxlib.luaL_Buffer(L); lauxlib.luaL_argcheck(L, tr === CT.LUA_TNUMBER || tr === CT.LUA_TSTRING || tr === CT.LUA_TFUNCTION || tr === CT.LUA_TTABLE, 3, - lua.to_luastring("string/function/table expected")); + lua.to_luastring("string/function/table expected", true)); lauxlib.luaL_buffinit(L, b); if (anchor) { p = p.slice(1); lp--; /* skip anchor character */ @@ -1392,7 +1392,7 @@ const createmetatable = function(L) { lapi.lua_setmetatable(L, -2); /* set table as metatable for strings */ lapi.lua_pop(L, 1); /* pop dummy string */ lapi.lua_pushvalue(L, -2); /* get string library */ - lapi.lua_setfield(L, -2, lua.to_luastring("__index")); /* metatable.__index = string */ + lapi.lua_setfield(L, -2, lua.to_luastring("__index", true)); /* metatable.__index = string */ lapi.lua_pop(L, 1); /* pop metatable */ }; diff --git a/src/ltablib.js b/src/ltablib.js index 210a119..0794887 100644 --- a/src/ltablib.js +++ b/src/ltablib.js @@ -36,9 +36,9 @@ const checktab = function(L, arg, what) { if (lapi.lua_type(L, arg) !== CT.LUA_TTABLE) { /* is it not a table? */ let n = 1; if (lapi.lua_getmetatable(L, arg) && /* must have metatable */ - (!(what & TAB_R) || checkfield(L, lua.to_luastring("__index"), ++n)) && - (!(what & TAB_W) || checkfield(L, lua.to_luastring("__newindex"), ++n)) && - (!(what & TAB_L) || checkfield(L, lua.to_luastring("__len"), ++n))) { + (!(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))) { lapi.lua_pop(L, n); /* pop metatable and tested metamethods */ } else @@ -68,7 +68,7 @@ const tinsert = function(L) { 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")); + lauxlib.luaL_argcheck(L, 1 <= pos && pos <= e, 2, lua.to_luastring("position out of bounds", true)); for (let i = e; i > pos; i--) { /* move up elements */ lapi.lua_geti(L, 1, i - 1); lapi.lua_seti(L, 1, i); /* t[i] = t[i - 1] */ @@ -76,7 +76,7 @@ const tinsert = function(L) { break; } default: { - return lauxlib.luaL_error(L, lua.to_luastring("wrong number of arguments to 'insert'")); + return lauxlib.luaL_error(L, lua.to_luastring("wrong number of arguments to 'insert'", true)); } } @@ -88,7 +88,7 @@ const tremove = function(L) { let size = aux_getn(L, 1, TAB_RW); let pos = lauxlib.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")); + lauxlib.luaL_argcheck(L, 1 <= pos && pos <= size + 1, 1, lua.to_luastring("position out of bounds", true)); lapi.lua_geti(L, 1, pos); /* result = t[pos] */ for (; pos < size; pos++) { lapi.lua_geti(L, 1, pos + 1); @@ -113,9 +113,9 @@ const tmove = function(L) { checktab(L, 1, TAB_R); checktab(L, tt, TAB_W); if (e >= f) { /* otherwise, nothing to move */ - lauxlib.luaL_argcheck(L, f > 0 || e < llimit.LUA_MAXINTEGER + f, 3, lua.to_luastring("too many elements to move")); + lauxlib.luaL_argcheck(L, f > 0 || e < llimit.LUA_MAXINTEGER + f, 3, lua.to_luastring("too many elements to move", true)); let n = e - f + 1; /* number of elements to move */ - lauxlib.luaL_argcheck(L, t <= llimit.LUA_MAXINTEGER - n + 1, 4, lua.to_luastring("destination wrap around")); + lauxlib.luaL_argcheck(L, t <= llimit.LUA_MAXINTEGER - n + 1, 4, lua.to_luastring("destination wrap around", true)); if (t > e || t <= f || (tt !== 1 && lapi.lua_compare(L, 1, tt, lua.LUA_OPEQ) !== 1)) { for (let i = 0; i < n; i++) { @@ -173,7 +173,7 @@ const unpack = function(L) { if (i > e) return 0; /* empty range */ let n = e - i; /* number of elements minus 1 (avoid overflows) */ if (n >= Number.MAX_SAFE_INTEGER || !lapi.lua_checkstack(L, ++n)) - return lauxlib.luaL_error(L, lua.to_luastring("too many results to unpack")); + return lauxlib.luaL_error(L, lua.to_luastring("too many results to unpack", true)); for (; i < e; i++) /* push arg[i..e - 1] (to avoid overflows) */ lapi.lua_geti(L, 1, i); lapi.lua_geti(L, 1, e); /* push last element */ @@ -214,7 +214,7 @@ const auxsort = function(L) { const sort = function(L) { let n = aux_getn(L, 1, TAB_RW); if (n > 1) { /* non-trivial interval? */ - lauxlib.luaL_argcheck(L, n < Number.MAX_SAFE_INTEGER, 1, lua.to_luastring("array too big")); + lauxlib.luaL_argcheck(L, n < Number.MAX_SAFE_INTEGER, 1, lua.to_luastring("array too big", true)); if (!lapi.lua_isnoneornil(L, 2)) /* is there a 2nd argument? */ lauxlib.luaL_checktype(L, 2, CT.LUA_TFUNCTION); /* must be a function */ lapi.lua_settop(L, 2); /* make sure there are two arguments */ diff --git a/src/ltm.js b/src/ltm.js index 4a90f6d..57c2e3f 100644 --- a/src/ltm.js +++ b/src/ltm.js @@ -15,30 +15,30 @@ const CT = lua.constant_types; const TMS = { - TM_INDEX: lua.to_luastring("__index"), - TM_NEWINDEX: lua.to_luastring("__newindex"), - TM_GC: lua.to_luastring("__gc"), - TM_MODE: lua.to_luastring("__mode"), - TM_LEN: lua.to_luastring("__len"), - TM_EQ: lua.to_luastring("__eq"), /* last tag method with fast access */ - TM_ADD: lua.to_luastring("__add"), - TM_SUB: lua.to_luastring("__sub"), - TM_MUL: lua.to_luastring("__mul"), - TM_MOD: lua.to_luastring("__mod"), - TM_POW: lua.to_luastring("__pow"), - TM_DIV: lua.to_luastring("__div"), - TM_IDIV: lua.to_luastring("__idiv"), - TM_BAND: lua.to_luastring("__band"), - TM_BOR: lua.to_luastring("__bor"), - TM_BXOR: lua.to_luastring("__bxor"), - TM_SHL: lua.to_luastring("__shl"), - TM_SHR: lua.to_luastring("__shr"), - TM_UNM: lua.to_luastring("__unm"), - TM_BNOT: lua.to_luastring("__bnot"), - TM_LT: lua.to_luastring("__lt"), - TM_LE: lua.to_luastring("__le"), - TM_CONCAT: lua.to_luastring("__concat"), - TM_CALL: lua.to_luastring("__call") + TM_INDEX: lua.to_luastring("__index", true), + TM_NEWINDEX: lua.to_luastring("__newindex", true), + TM_GC: lua.to_luastring("__gc", true), + TM_MODE: lua.to_luastring("__mode", true), + TM_LEN: lua.to_luastring("__len", true), + TM_EQ: lua.to_luastring("__eq", true), /* last tag method with fast access */ + TM_ADD: lua.to_luastring("__add", true), + TM_SUB: lua.to_luastring("__sub", true), + TM_MUL: lua.to_luastring("__mul", true), + TM_MOD: lua.to_luastring("__mod", true), + TM_POW: lua.to_luastring("__pow", true), + TM_DIV: lua.to_luastring("__div", true), + TM_IDIV: lua.to_luastring("__idiv", true), + TM_BAND: lua.to_luastring("__band", true), + TM_BOR: lua.to_luastring("__bor", true), + TM_BXOR: lua.to_luastring("__bxor", true), + TM_SHL: lua.to_luastring("__shl", true), + TM_SHR: lua.to_luastring("__shr", true), + TM_UNM: lua.to_luastring("__unm", true), + TM_BNOT: lua.to_luastring("__bnot", true), + TM_LT: lua.to_luastring("__lt", true), + TM_LE: lua.to_luastring("__le", true), + TM_CONCAT: lua.to_luastring("__concat", true), + TM_CALL: lua.to_luastring("__call", true) }; const luaT_typenames_ = [ @@ -71,7 +71,7 @@ const luaT_init = function(L) { */ const luaT_objtypename = function(L, o) { if ((o.ttistable() && o.metatable !== null) || (o.ttisfulluserdata() && o.metatable !== null)) { - let name = o.__index(o, lua.to_luastring('__name')); + let name = o.__index(o, lua.to_luastring('__name', true)); if (name.ttisstring()) return name.jsstring(); } @@ -123,10 +123,10 @@ const luaT_trybinTM = function(L, p1, p2, res, event) { if (n1 !== false && n2 !== false) ldebug.luaG_tointerror(L, p1, p2); else - ldebug.luaG_opinterror(L, p1, p2, lua.to_luastring("perform bitwise operation on")); + ldebug.luaG_opinterror(L, p1, p2, lua.to_luastring("perform bitwise operation on", true)); } default: - ldebug.luaG_opinterror(L, p1, p2, lua.to_luastring("perform arithmetic on")); + ldebug.luaG_opinterror(L, p1, p2, lua.to_luastring("perform arithmetic on", true)); } } }; diff --git a/src/lua.js b/src/lua.js index 1423750..5175bfb 100644 --- a/src/lua.js +++ b/src/lua.js @@ -140,9 +140,16 @@ class lua_Debug { } -const to_luastring = function(str, maxBytesToWrite) { +const to_luastring_cache = {}; + +const to_luastring = function(str, cache, maxBytesToWrite) { assert(typeof str === "string", "to_luastring expect a js string"); + if (cache) { + let cached = to_luastring_cache[str]; + if (Array.isArray(cached)) return cached; + } + maxBytesToWrite = maxBytesToWrite !== undefined ? maxBytesToWrite : Number.MAX_SAFE_INTEGER; let outU8Array = []; @@ -195,6 +202,8 @@ const to_luastring = function(str, maxBytesToWrite) { } // Null-terminate the pointer to the buffer. // outU8Array[outIdx] = 0; + + if (cache) to_luastring_cache[str] = outU8Array; return outU8Array; }; diff --git a/src/lutf8lib.js b/src/lutf8lib.js index ef9739f..f58223a 100644 --- a/src/lutf8lib.js +++ b/src/lutf8lib.js @@ -87,7 +87,7 @@ const utflen = function(L) { 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")); + lauxlib.luaL_argcheck(L, 0 <= code && code <= MAXUNICODE, arg, lua.to_luastring("value out of range", true)); lapi.lua_pushstring(L, lua.to_luastring(String.fromCharCode(code))); }; @@ -121,14 +121,14 @@ const byteoffset = function(L) { let posi = n >= 0 ? 1 : s.length + 1; posi = u_posrelat(lauxlib.luaL_optinteger(L, 3, posi), s.length); - lauxlib.luaL_argcheck(L, 1 <= posi && --posi <= s.length, 3, lua.to_luastring("position ot ouf range")); + lauxlib.luaL_argcheck(L, 1 <= posi && --posi <= s.length, 3, lua.to_luastring("position ot ouf 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")); + lauxlib.luaL_error(L, lua.to_luastring("initial position is a continuation byte", true)); if (n < 0) { while (n < 0 && posi > 0) { /* move back */ @@ -166,19 +166,19 @@ const codepoint = function(L) { let posi = u_posrelat(lauxlib.luaL_optinteger(L, 2, 1), s.length); let pose = u_posrelat(lauxlib.luaL_optinteger(L, 3, posi), s.length); - lauxlib.luaL_argcheck(L, posi >= 1, 2, lua.to_luastring("out of range")); - lauxlib.luaL_argcheck(L, pose <= s.length, 3, lua.to_luastring("out of range")); + 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)); 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")); + return lauxlib.luaL_error(L, lua.to_luastring("string slice too long", true)); let n = (pose - posi) + 1; - lauxlib.luaL_checkstack(L, n, lua.to_luastring("string slice too long")); + lauxlib.luaL_checkstack(L, n, lua.to_luastring("string slice too long", true)); n = 0; for (s = s.slice(posi - 1); n < pose - posi;) { let dec = utf8_decode(s); if (dec === null) - return lauxlib.luaL_error(L, lua.to_luastring("invalid UTF-8 code")); + return lauxlib.luaL_error(L, lua.to_luastring("invalid UTF-8 code", true)); s = dec.string; let code = dec.code; lapi.lua_pushinteger(L, code); @@ -207,7 +207,7 @@ const iter_aux = function(L) { let code = dec ? dec.code : null; let next = dec ? dec.string : null; if (next === null || iscont(next[0])) - return lauxlib.luaL_error(L, lua.to_luastring("invalid UTF-8 code")); + return lauxlib.luaL_error(L, lua.to_luastring("invalid UTF-8 code", true)); lapi.lua_pushinteger(L, n + 1); lapi.lua_pushinteger(L, code); return 2; @@ -236,7 +236,7 @@ const UTF8PATT = "[\0-\x7F\xC2-\xF4][\x80-\xBF]*"; const luaopen_utf8 = function(L) { lauxlib.luaL_newlib(L, funcs); lapi.lua_pushstring(L, lua.to_luastring(UTF8PATT)); - lapi.lua_setfield(L, -2, lua.to_luastring("charpattern")); + lapi.lua_setfield(L, -2, lua.to_luastring("charpattern", true)); return 1; }; diff --git a/src/lvm.js b/src/lvm.js index efbb7e7..1d131cf 100644 --- a/src/lvm.js +++ b/src/lvm.js @@ -602,19 +602,19 @@ const luaV_execute = function(L) { let nstep = tonumber(pstep); if (nlimit === false) - ldebug.luaG_runerror(L, lua.to_luastring("'for' limit must be a number")); + ldebug.luaG_runerror(L, lua.to_luastring("'for' limit must be a number", true)); plimit.type = CT.LUA_TNUMFLT; plimit.value = nlimit; if (nstep === false) - ldebug.luaG_runerror(L, lua.to_luastring("'for' step must be a number")); + ldebug.luaG_runerror(L, lua.to_luastring("'for' step must be a number", true)); pstep.type = CT.LUA_TNUMFLT; pstep.value = nstep; if (ninit === false) - ldebug.luaG_runerror(L, lua.to_luastring("'for' initial value must be a number")); + ldebug.luaG_runerror(L, lua.to_luastring("'for' initial value must be a number", true)); init.type = CT.LUA_TNUMFLT; init.value = ninit - nstep; @@ -988,7 +988,7 @@ const luaV_objlen = function(L, ra, rb) { default: { tm = ltm.luaT_gettmbyobj(L, rb, ltm.TMS.TM_LEN); if (tm.ttisnil()) - ldebug.luaG_typeerror(L, rb, lua.to_luastring("get length of")); + ldebug.luaG_typeerror(L, rb, lua.to_luastring("get length of", true)); break; } } @@ -1053,7 +1053,7 @@ const gettable = function(L, table, key, ra, recur) { recur = recur ? recur : 0; if (recur >= MAXTAGRECUR) - ldebug.luaG_runerror(L, lua.to_luastring("'__index' chain too long; possible loop")); + ldebug.luaG_runerror(L, lua.to_luastring("'__index' chain too long; possible loop", true)); if (table.ttistable()) { let element = table.__index(table, key); @@ -1074,7 +1074,7 @@ const luaV_finishget = function(L, t, key, val, slot, recur) { assert(!t.ttistable()); tm = ltm.luaT_gettmbyobj(L, t, ltm.TMS.TM_INDEX); if (tm.ttisnil()) - ldebug.luaG_typeerror(L, t, lua.to_luastring('index')); + ldebug.luaG_typeerror(L, t, lua.to_luastring('index', true)); } else { /* 't' is a table */ assert(slot.ttisnil()); tm = ltm.luaT_gettmbyobj(L, t, ltm.TMS.TM_INDEX); // TODO: fasttm @@ -1096,7 +1096,7 @@ const settable = function(L, table, key, v, recur) { recur = recur ? recur : 0; if (recur >= MAXTAGRECUR) - ldebug.luaG_runerror(L, lua.to_luastring("'__newindex' chain too long; possible loop")); + ldebug.luaG_runerror(L, lua.to_luastring("'__newindex' chain too long; possible loop", true)); if (table.ttistable()) { let element = table.__index(table, key); @@ -1123,7 +1123,7 @@ const luaV_finishset = function(L, t, key, val, slot, recur) { } else { /* not a table; check metamethod */ tm = ltm.luaT_gettmbyobj(L, t, ltm.TMS.TM_NEWINDEX); if (tm.ttisnil()) - ldebug.luaG_typeerror(L, t, lua.to_luastring('index')); + ldebug.luaG_typeerror(L, t, lua.to_luastring('index', true)); } if (tm.ttisfunction()) { -- cgit v1.2.3-70-g09d2