summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBenoit Giannangeli <giann008@gmail.com>2017-03-29 11:57:43 +0200
committerBenoit Giannangeli <giann008@gmail.com>2017-03-29 14:37:07 +0200
commit2e5b595a2e04fe72555a565af4aae43560946473 (patch)
tree750e770114181283acb0fd78f7ad241c17c3d9a7
parent36f3247d47c1ad854fa89aabf17f6d954a6a6657 (diff)
downloadfengari-2e5b595a2e04fe72555a565af4aae43560946473.tar.gz
fengari-2e5b595a2e04fe72555a565af4aae43560946473.tar.bz2
fengari-2e5b595a2e04fe72555a565af4aae43560946473.zip
Never use js strings internally
-rw-r--r--src/lapi.js48
-rw-r--r--src/lauxlib.js74
-rw-r--r--src/lbaselib.js43
-rw-r--r--src/lcode.js6
-rw-r--r--src/lcorolib.js5
-rw-r--r--src/ldebug.js60
-rw-r--r--src/ldo.js8
-rw-r--r--src/ljstype.js12
-rw-r--r--src/llex.js125
-rw-r--r--src/lmathlib.js20
-rw-r--r--src/lobject.js84
-rw-r--r--src/lparser.js70
-rw-r--r--src/ltablib.js25
-rw-r--r--src/ltm.js90
-rw-r--r--src/lua.js2
-rw-r--r--src/lutf8lib.js24
16 files changed, 348 insertions, 348 deletions
diff --git a/src/lapi.js b/src/lapi.js
index 8cabf12..6e1471d 100644
--- a/src/lapi.js
+++ b/src/lapi.js
@@ -218,11 +218,11 @@ const lua_pushinteger = function(L, n) {
assert(L.top <= L.ci.top, "stack overflow");
};
-const lua_pushlstring = function(L, s, len) { // TODO: embedded \0
- assert(typeof s === "string");
+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("")) : L.l_G.intern(lua.to_luastring(s.substr(0, len)));
+ let ts = len === 0 ? L.l_G.intern(lua.to_luastring("")) : new TValue(CT.LUA_TLNGSTR, s.slice(0, len));
L.stack[L.top++] = ts;
assert(L.top <= L.ci.top, "stack overflow");
@@ -231,7 +231,24 @@ const lua_pushlstring = function(L, s, len) { // TODO: embedded \0
};
const lua_pushstring = function (L, s) {
- if (typeof s !== "string")
+ assert(Array.isArray(s), "lua_pushstring expects array of byte");
+
+ if (s === undefined || s === null)
+ L.stack[L.top] = new TValue(CT.LUA_TNIL, null);
+ else {
+ L.stack[L.top] = new TValue(CT.LUA_TLNGSTR, s);
+ }
+
+ L.top++;
+ assert(L.top <= L.ci.top, "stack overflow");
+
+ return s;
+};
+
+const lua_pushliteral = function (L, s) {
+ assert(typeof s === "string", "lua_pushliteral expects a JS string");
+
+ if (s === undefined || s === null)
L.stack[L.top] = new TValue(CT.LUA_TNIL, null);
else {
let ts = L.l_G.intern(lua.to_luastring(s));
@@ -244,8 +261,6 @@ const lua_pushstring = function (L, s) {
return s;
};
-const lua_pushliteral = lua_pushstring;
-
const lua_pushcclosure = function(L, fn, n) {
assert(typeof fn === "function");
assert(typeof n === "number");
@@ -315,7 +330,9 @@ 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 = L.l_G.intern(lua.to_luastring(k));
+ assert(Array.isArray(k), "key must be an array of bytes");
+
+ let str = L.l_G.intern(k);
assert(1 < L.top - L.ci.funcOff, "not enough elements in the stack");
@@ -392,7 +409,9 @@ const lua_rawset = function(L, idx) {
*/
const auxgetstr = function(L, t, k) {
- let str = L.l_G.intern(lua.to_luastring(k));
+ assert(Array.isArray(k), "key must be an array of bytes");
+
+ let str = L.l_G.intern(k);
let slot = t.__index(t, k);
if (t.ttistable() && !slot.ttisnil()) {
L.stack[L.top++] = slot;
@@ -553,11 +572,22 @@ const lua_tolstring = function(L, idx) {
if ((!o.ttisstring() && !o.ttisnumber()))
return null;
- return o.ttisstring() ? o.jsstring() : `${o.value}`;
+ return o.ttisstring() ? o.value : lua.to_luastring(`${o.value}`);
};
const lua_tostring = lua_tolstring;
+const lua_toljsstring = function(L, idx) {
+ let o = index2addr(L, idx);
+
+ if ((!o.ttisstring() && !o.ttisnumber()))
+ return null;
+
+ return o.ttisstring() ? o.jsstring() : `${o.value}`;
+};
+
+const lua_tojsstring = lua_toljsstring;
+
// Convert a string on the stack to a dataview, because lua_tostring will perform utf-8 to utf-16 conversion
const lua_todataview = function(L, idx) {
let o = index2addr(L, idx);
diff --git a/src/lauxlib.js b/src/lauxlib.js
index 8bda842..f60bd8c 100644
--- a/src/lauxlib.js
+++ b/src/lauxlib.js
@@ -58,7 +58,7 @@ const pushglobalfuncname = function(L, ar) {
lapi.lua_getfield(L, lua.LUA_REGISTRYINDEX, LUA_LOADED_TABLE);
if (findfield(L, top + 1, 2)) {
let name = lapi.lua_tostring(L, -1);
- if (name.startsWith("_G.")) {
+ if (name.jsstring().startsWith("_G.")) {
lapi.lua_pushstring(L, name.slice(3)); /* name start with '_G.'? */
lapi.lua_remove(L, -2); /* name start with '_G.'? */
}
@@ -71,61 +71,65 @@ const pushglobalfuncname = function(L, ar) {
};
const panic = function(L) {
- throw new Error(`PANIC: unprotected error in call to Lua API (${lapi.lua_tostring(L, -1)})`);
+ throw new Error(`PANIC: unprotected error in call to Lua API (${lapi.lua_tojsstring(L, -1)})`);
};
const luaL_argerror = function(L, arg, extramsg) {
let ar = new lua.lua_Debug();
if (!ldebug.lua_getstack(L, 0, ar)) /* no stack frame? */
- return luaL_error(L, 'bad argument #%d (%s)', arg, extramsg);
+ return luaL_error(L, lua.to_luastring(`bad argument #${arg} (${lobject.jsstring(extramsg)})`));
ldebug.lua_getinfo(L, 'n', ar);
if (ar.namewhat === 'method') {
arg--; /* do not count 'self' */
if (arg === 0) /* error is in the self argument itself? */
- return luaL_error(L, "calling '%s' on bad self (%s)", ar.name, extramsg);
+ return luaL_error(L, lua.to_luastring(`calling '${lobject.jsstring(ar.name)}' on bad self (${lobject.jsstring(extramsg)})`));
}
if (ar.name === null)
ar.name = pushglobalfuncname(L, ar) ? lapi.lua_tostring(L, -1) : "?";
- return luaL_error(L, `bad argument #${arg} to '${ar.name}' (${extramsg})`);
+ return luaL_error(L, lua.to_luastring(`bad argument #${arg} to '${lobject.jsstring(ar.name)}' (${lobject.jsstring(extramsg)})`));
};
const typeerror = function(L, arg, tname) {
let typearg;
- if (luaL_getmetafield(L, arg, "__name") === CT.LUA_TSTRING)
+ if (luaL_getmetafield(L, arg, lua.to_luastring("__name")) === CT.LUA_TSTRING)
typearg = lapi.lua_tostring(L, -1);
else if (lapi.lua_type(L, arg) === CT.LUA_TLIGHTUSERDATA)
- typearg = "light userdata";
+ typearg = lua.to_luastring("light userdata");
else
typearg = luaL_typename(L, arg);
- let msg = lapi.lua_pushstring(L, `${tname} expected, got ${typearg}`);
+ let msg = lapi.lua_pushstring(L, lua.to_luastring(`${lobject.jsstring(tname)} expected, got ${lobject.jsstring(typearg)}`));
return luaL_argerror(L, arg, msg);
};
const luaL_where = function(L, level) {
let ar = new lua.lua_Debug();
if (ldebug.lua_getstack(L, level, ar)) {
- ldebug.lua_getinfo(L, "Sl", ar);
+ ldebug.lua_getinfo(L, lua.to_luastring("Sl"), ar);
if (ar.currentline > 0) {
- lapi.lua_pushstring(L, `${ar.short_src}:${ar.currentline}:`);
+ lapi.lua_pushstring(L, lua.to_luastring(`${lobject.jsstring(ar.short_src)}:${ar.currentline}:`));
return;
}
}
- lapi.lua_pushstring(L, "");
+ lapi.lua_pushstring(L, []);
};
const luaL_error = function(L, fmt, ...args) {
let i = 0;
+ fmt = lobject.jsstring(fmt);
// TODO: bypassing lua_pushvstring for now
- lapi.lua_pushstring(L, fmt.replace(/(^%[sfIpdcU]|([^%])%[sfIpdcU])/g, function (m, p1, p2, off) {
+ fmt = fmt.replace(/(^%[sfIpdcU]|([^%])%[sfIpdcU])/g, function (m, p1, p2, off) {
return p2 ? p2 + args[i++] : args[i++];
- }));
+ });
+ fmt = lua.to_luastring(fmt);
+
+ lapi.lua_pushstring(L, fmt);
return lapi.lua_error(L);
};
@@ -151,7 +155,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, "value expected");
+ luaL_argerror(L, arg, lua.to_luastring("value expected"));
};
const luaL_checktype = function(L, arg, t) {
@@ -165,7 +169,7 @@ const luaL_checkstring = function(L, n) {
const luaL_checklstring = function(L, arg) {
let s = lapi.lua_tolstring(L, arg);
- if (typeof s !== "string") tag_error(L, arg, CT.LUA_TSTRING);
+ if (s === null || s === undefined) tag_error(L, arg, CT.LUA_TSTRING);
return s;
};
@@ -179,7 +183,7 @@ const luaL_optstring = luaL_optlstring;
const interror = function(L, arg) {
if (lapi.lua_isnumber(L, arg))
- luaL_argerror(L, arg, "number has no integer representation");
+ luaL_argerror(L, arg, lua.to_luastring("number has no integer representation"));
else
tag_error(L, arg, CT.LUA_TNUMBER);
};
@@ -208,7 +212,7 @@ const luaL_prepbuffsize = function(B, sz) {
const luaL_buffinit = function(L, B) {
B.L = L;
- B.b = "";
+ B.b = [];
};
const luaL_buffinitsize = function(L, B, sz) {
@@ -217,7 +221,7 @@ const luaL_buffinitsize = function(L, B, sz) {
};
const luaL_addlstring = function(B, s, l) {
- B.b += s.slice(0, l);
+ B.b = B.b.concat(s.slice(0, l));
};
const luaL_addstring = luaL_addlstring;
@@ -228,7 +232,7 @@ const luaL_pushresult = function(B) {
};
const luaL_addchar = function(B, c) {
- B.b += c;
+ B.b.push(c);
};
const luaL_addvalue = function(B) {
@@ -301,18 +305,18 @@ const luaL_tolstring = function(L, idx) {
switch(lapi.lua_type(L, idx)) {
case CT.LUA_TNUMBER:
case CT.LUA_TBOOLEAN:
- lapi.lua_pushstring(L, `${lapi.index2addr(L, idx).value}`);
+ lapi.lua_pushstring(L, lua.to_luastring(`${lapi.index2addr(L, idx).value}`));
break;
case CT.LUA_TSTRING:
- lapi.lua_pushstring(L, lapi.index2addr(L, idx).jsstring());
+ lapi.lua_pushstring(L, lapi.index2addr(L, idx).value);
break;
case CT.LUA_TNIL:
- lapi.lua_pushstring(L, `nil`);
+ lapi.lua_pushstring(L, lua.to_luastring(`nil`));
break;
default:
- let tt = luaL_getmetafield(L, idx, "__name");
+ let tt = luaL_getmetafield(L, idx, lua.to_luastring("__name"));
let kind = tt === CT.LUA_TSTRING ? lapi.lua_tostring(L, -1) : luaL_typename(L, idx);
- lapi.lua_pushstring(L, `${kind}: 0x${lapi.index2addr(L, -1).id.toString(16)}`);
+ lapi.lua_pushstring(L, lua.to_luastring(`${lobject.jsstring(kind)}: 0x${lapi.index2addr(L, -1).id.toString(16)}`));
if (tt !== CT.LUA_TNIL)
lapi.lua_remove(L, -2);
break;
@@ -369,12 +373,12 @@ 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, "too many upvalues");
+ luaL_checkstack(L, nup, lua.to_luastring("too many upvalues"));
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);
lapi.lua_pushcclosure(L, l[lib], nup); /* closure with those upvalues */
- lapi.lua_setfield(L, -(nup + 2), lib);
+ lapi.lua_setfield(L, -(nup + 2), lua.to_luastring(lib));
}
lapi.lua_pop(L, nup); /* remove upvalues */
};
@@ -389,9 +393,9 @@ const luaL_setfuncs = function(L, l, nup) {
const luaL_checkstack = function(L, space, msg) {
if (!lapi.lua_checkstack(L, space)) {
if (msg)
- luaL_error(L, `stack overflow (${msg})`);
+ luaL_error(L, lua.to_luastring(`stack overflow (${lobject.jsstring(msg)})`));
else
- luaL_error(L, 'stack overflow');
+ luaL_error(L, lua.to_luastring('stack overflow'));
}
};
@@ -437,14 +441,14 @@ if (typeof require === "function") {
lf.pos += bytes;
}
if (bytes > 0)
- return lf.binary ? toDataView(lf.buff) : lobject.jsstring(lf.buff, 0, bytes); // TODO: Here reading utf8 only
+ return lf.binary ? toDataView(lf.buff) : lf.buff;
else return null;
};
const errfile = function(L, what, fnameindex, error) {
let serr = error.message;
let filename = lapi.lua_tostring(L, fnameindex).slice(1);
- lapi.lua_pushstring(L, `cannot ${what} ${filename}: ${serr}`);
+ lapi.lua_pushstring(L, lua.to_luastring(`cannot ${lobject.jsstring(what)} ${lobject.jsstring(filename)}: ${lobject.jsstring(serr)}`));
lapi.lua_remove(L, fnameindex);
return lua.thread_status.LUA_ERRFILE;
};
@@ -457,12 +461,12 @@ if (typeof require === "function") {
};
const skipBOM = function(lf) {
- let p = "\xEF\xBB\xBF"; /* UTF-8 BOM mark */
+ let p = [0XEF, 0XBB, 0XBF]; /* UTF-8 BOM mark */
lf.n = 0;
let c;
do {
c = getc(lf);
- if (c === null || c !== p.charCodeAt(0)) return c;
+ if (c === null || c !== p[0]) return c;
p = p.slice(1);
lf.buff[lf.n++] = c; /* to be read by the parser */
} while (p.length > 0);
@@ -504,11 +508,11 @@ if (typeof require === "function") {
lapi.lua_pushliteral(L, "=stdin");
lf.f = process.stdin.fd;
} else {
- lapi.lua_pushstring(L, `@${filename}`);
+ lapi.lua_pushliteral(L, `@${filename}`);
try {
lf.f = fs.openSync(filename, "r");
} catch (e) {
- return errfile(L, "open", fnameindex, e);
+ return errfile(L, lua.to_luastring("open"), fnameindex, e);
}
}
@@ -527,7 +531,7 @@ if (typeof require === "function") {
return status;
} catch (err) {
lapi.lua_settop(L, fnameindex); /* ignore results from 'lua_load' */
- return errfile(L, "read", fnameindex);
+ return errfile(L, lua.to_luastring("read"), fnameindex);
}
};
diff --git a/src/lbaselib.js b/src/lbaselib.js
index a6f2ce8..8420672 100644
--- a/src/lbaselib.js
+++ b/src/lbaselib.js
@@ -5,6 +5,7 @@ const assert = require('assert');
const lua = require('./lua.js');
const lapi = require('./lapi.js');
const lauxlib = require('./lauxlib.js');
+const lobject = require('./lobject.js');
const CT = lua.constant_types;
const TS = lua.thread_status;
@@ -12,20 +13,20 @@ const luaB_print = function(L) {
let n = lapi.lua_gettop(L); /* number of arguments */
let str = "";
- lapi.lua_getglobal(L, "tostring");
+ lapi.lua_getglobal(L, lua.to_luastring("tostring"));
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, "'tostring' must return a string to 'print'");
- if (i > 1) s = `\t${s}`;
- str = `${str}${s}`;
+ return lauxlib.luaL_error(L, lua.to_luastring("'tostring' must return a string to 'print'"));
+ if (i > 1) s = ["\t".charCodeAt(0)].concat(s);
+ str = str.concat(s);
lapi.lua_pop(L, 1);
}
- console.log(str);
+ console.log(lobject.jsstring(str));
return 0;
};
@@ -42,16 +43,16 @@ const luaB_getmetatable = function(L) {
lapi.lua_pushnil(L);
return 1; /* no metatable */
}
- lauxlib.luaL_getmetafield(L, 1, "__metatable");
+ lauxlib.luaL_getmetafield(L, 1, lua.to_luastring("__metatable"));
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, "nil or table expected");
- if (lauxlib.luaL_getmetafield(L, 1, "__metatable") !== CT.LUA_TNIL)
- return lauxlib.luaL_error(L, "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"));
+ 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"));
lapi.lua_settop(L, 2);
lapi.lua_setmetatable(L, 1);
return 1;
@@ -66,7 +67,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, "table or string expected");
+ lauxlib.luaL_argcheck(L, t === CT.LUA_TTABLE || t === CT.LUA_TSTRING, 1, lua.to_luastring("table or string expected"));
lapi.lua_pushinteger(L, lapi.lua_rawlen(L, 1));
return 1;
};
@@ -90,7 +91,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, "value expected");
+ lauxlib.luaL_argcheck(L, t !== CT.LUA_TNONE, 1, lua.to_luastring("value expected"));
lapi.lua_pushstring(L, lapi.lua_typename(L, t));
return 1;
};
@@ -121,7 +122,7 @@ const luaB_next = function(L) {
};
const luaB_pairs = function(L) {
- return pairsmeta(L, "__pairs", 0, luaB_next);
+ return pairsmeta(L, lua.to_luastring("__pairs"), 0, luaB_next);
};
/*
@@ -163,8 +164,8 @@ 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, "base out of range");
- let n = parseInt(s, base);
+ lauxlib.luaL_argcheck(L, 2 <= base && base <= 36, 2, lua.to_luastring("base out of range"));
+ let n = parseInt(lobject.jsstring(s), base);
if (!isNaN(n)) {
lapi.lua_pushinteger(L, n);
return 1;
@@ -207,7 +208,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, "index out of range");
+ lauxlib.luaL_argcheck(L, 1 <= i, 1, lua.to_luastring("index out of range"));
return n - i;
}
};
@@ -281,28 +282,28 @@ const RESERVEDSLOT = 5;
** reserved slot inside the stack.
*/
const generic_reader = function(L, ud) {
- lauxlib.luaL_checkstack(L, 2, "too many nested functions");
+ lauxlib.luaL_checkstack(L, 2, lua.to_luastring("too many nested functions"));
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, "reader function must return a string");
+ lauxlib.luaL_error(L, lua.to_luastring("reader function must return a string"));
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, "bt");
+ let mode = lauxlib.luaL_optstring(L, 3, lua.to_luastring("bt"));
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, "=(load)");
+ let chunkname = lauxlib.luaL_optstring(L, 2, lua.to_luastring("=(load)"));
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);
@@ -375,10 +376,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, "_G");
+ lapi.lua_setfield(L, -2, lua.to_luastring("_G"));
/* set global _VERSION */
lapi.lua_pushliteral(L, lua.LUA_VERSION);
- lapi.lua_setfield(L, -2, "_VERSION");
+ lapi.lua_setfield(L, -2, lua.to_luastring("_VERSION"));
return 1;
};
diff --git a/src/lcode.js b/src/lcode.js
index c0ca1ff..8b4a57c 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, "control structure too long");
+ llex.luaX_syntaxerror(fs.ls, lua.to_luastring("control structure too long"));
lopcode.SETARG_sBx(jmp, offset);
};
@@ -425,7 +425,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, "function or expression needs to many registers");
+ llex.luaX_syntaxerror(fs.ls, lua.to_luastring("function or expression needs to many registers"));
fs.f.maxstacksize = newstack;
}
};
@@ -1277,4 +1277,4 @@ module.exports.luaK_setmultret = luaK_setmultret;
module.exports.luaK_setoneret = luaK_setoneret;
module.exports.luaK_setreturns = luaK_setreturns;
module.exports.luaK_storevar = luaK_storevar;
-module.exports.luaK_stringK = luaK_stringK; \ No newline at end of file
+module.exports.luaK_stringK = luaK_stringK;
diff --git a/src/lcorolib.js b/src/lcorolib.js
index b2d0de8..58d061c 100644
--- a/src/lcorolib.js
+++ b/src/lcorolib.js
@@ -8,12 +8,13 @@ const lauxlib = require('./lauxlib.js');
const lstate = require('./lstate.js');
const ldo = require('./ldo.js');
const ldebug = require('./ldebug.js');
+const lobject = require('./lobject.js');
const CT = lua.constant_types;
const TS = lua.thread_status;
const getco = function(L) {
let co = lapi.lua_tothread(L, 1);
- lauxlib.luaL_argcheck(L, co, 1, "thread expected");
+ lauxlib.luaL_argcheck(L, co, 1, lua.to_luastring("thread expected"));
return co;
};
@@ -146,4 +147,4 @@ const luaopen_coroutine = function(L) {
return 1;
};
-module.exports.luaopen_coroutine = luaopen_coroutine; \ No newline at end of file
+module.exports.luaopen_coroutine = luaopen_coroutine;
diff --git a/src/ldebug.js b/src/ldebug.js
index 7c892a5..507e764 100644
--- a/src/ldebug.js
+++ b/src/ldebug.js
@@ -55,22 +55,22 @@ const lua_getstack = function(L, level, ar) {
const upvalname = function(p, uv) {
assert(uv < p.upvalues.length);
let s = p.upvalues[uv].name;
- if (s === null) return "?";
+ if (s === null) return "?".charCodeAt(0);
return s;
};
const funcinfo = function(ar, cl) {
if (cl === null || cl.type === CT.LUA_TCCL) {
- ar.source = "=[JS]";
+ ar.source = lua.to_luastring("=[JS]");
ar.linedefined = -1;
ar.lastlinedefined = -1;
ar.what = "J";
} else {
let p = cl.p;
- ar.source = p.source ? p.source : "=?";
+ ar.source = p.source ? p.source : lua.to_luastring("=?");
ar.linedefined = p.linedefined;
ar.lastlinedefined = p.lastlinedefined;
- ar.what = ar.linedefined === 0 ? "main" : "Lua";
+ ar.what = ar.linedefined === 0 ? lua.to_luastring("main") : lua.to_luastring("Lua");
}
ar.short_src = lobject.luaO_chunkid(ar.source, luaconf.LUA_IDSIZE);
@@ -99,8 +99,8 @@ const getfuncname = function(L, ci) {
if (ci === null)
return null;
else if (ci.callstatus & lstate.CIST_FIN) { /* is this a finalizer? */
- r.name = "__gc";
- r.funcname = "metamethod"; /* report it as such */
+ r.name = lua.to_luastring("__gc");
+ r.funcname = lua.to_luastring("metamethod"); /* report it as such */
return r;
}
/* calling function is a known Lua function? */
@@ -112,7 +112,7 @@ 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 (what[0]) {
+ switch (String.fromCharCode(what[0])) {
case 'S': {
funcinfo(ar, f);
break;
@@ -139,7 +139,7 @@ const auxgetinfo = function(L, what, ar, f, ci) {
case 'n': {
ar.namewhat = getfuncname(L, ci, ar.name);
if (ar.namewhat === null) {
- ar.namewhat = "";
+ ar.namewhat = [];
ar.name = null;
}
break;
@@ -157,7 +157,7 @@ const auxgetinfo = function(L, what, ar, f, ci) {
const lua_getinfo = function(L, what, ar) {
let status, cl, ci, func, funcOff;
swapextra(L);
- if (what[0] === '>') {
+ if (what[0] === '>'.charCodeAt(0)) {
ci = null;
funcOff = L.top - 1;
func = L.stack[funcOff];
@@ -173,13 +173,13 @@ const lua_getinfo = function(L, what, ar) {
cl = func.ttisclosure() ? func : null;
status = auxgetinfo(L, what, ar, cl, ci);
- if (what.indexOf('f') >= 0) {
+ if (what.indexOf('f'.charCodeAt(0)) >= 0) {
L.stack[L.top++] = func;
assert(L.top <= L.ci.top, "stack overflow");
}
swapextra(L);
- if (what.indexOf('L') >= 0)
+ if (what.indexOf('L'.charCodeAt(0)) >= 0)
collectvalidlines(L, cl);
return status;
@@ -200,7 +200,7 @@ 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.name[0] === 'c') {
+ if (what && what.name[0] === 'c'.charCodeAt(0)) {
return what;
}
/* else no reasonable name found */
@@ -271,7 +271,7 @@ const getobjname = function(p, lastpc, reg) {
};
if (r.name) { /* is a local? */
- r.funcname = "local";
+ r.funcname = lua.to_luastring("local");
return r;
}
@@ -293,12 +293,12 @@ const getobjname = function(p, lastpc, reg) {
let t = i.B; /* table index */
let vn = op === 'OP_GETTABLE' ? lfunc.luaF_getlocalname(p, t + 1, pc) : upvalname(p, t);
r.name = kname(p, pc, k);
- r.funcname = vn && vn === "_ENV" ? "global" : "field";
+ r.funcname = vn && vn === lua.to_luastring("_ENV") ? lua.to_luastring("global") : lua.to_luastring("field");
return r;
}
case 'OP_GETUPVAL': {
r.name = upvalname(p, i.B);
- r.funcname = "upvalue";
+ r.funcname = lua.to_luastring("upvalue");
return r;
}
case 'OP_LOADK':
@@ -306,7 +306,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 = "constant";
+ r.funcname = lua.to_luastring("constant");
return r;
}
break;
@@ -314,7 +314,7 @@ const getobjname = function(p, lastpc, reg) {
case 'OP_SELF': {
let k = i.C;
r.name = kname(p, pc, k);
- r.funcname = "method";
+ r.funcname = lua.to_luastring("method");
return r;
}
default: break;
@@ -343,7 +343,7 @@ const funcnamefromcode = function(L, ci) {
if (ci.callstatus & lstate.CIST_HOOKED) {
r.name = "?";
- r.funcname = "hook";
+ r.funcname = lua.to_luastring("hook");
return r;
}
@@ -352,8 +352,8 @@ const funcnamefromcode = function(L, ci) {
case 'OP_TAILCALL':
return getobjname(p, pc, i.A); /* get function name */
case 'OP_TFORCALL':
- r.name = "for iterator";
- r.funcname = "for iterator";
+ r.name = lua.to_luastring("for iterator");
+ r.funcname = lua.to_luastring("for iterator");
return r;
/* other instructions can do calls through metamethods */
case 'OP_SELF':
@@ -389,7 +389,7 @@ const funcnamefromcode = function(L, ci) {
}
r.name = L.l_G.tmname[tm].jsstring();
- r.funcname = "metamethod";
+ r.funcname = lua.to_luastring("metamethod");
return r;
};
@@ -413,7 +413,7 @@ const getupvalname = function(L, ci, o, name) {
if (c.upvals[i].val(L) === o) {
return {
name: upvalname(c.p, i),
- funcname: 'upvalue'
+ funcname: lua.to_luastring('upvalue')
};
}
}
@@ -431,17 +431,17 @@ const varinfo = function(L, o) {
kind = getobjname(ci.func.p, ci.pcOff, stkid - ci.u.l.base);
}
- return kind ? ` (${kind.funcname} '${kind.name}')` : ``;
+ return lua.to_luastring(kind ? ` (${lobject.jsstring(kind.funcname)} '${lobject.jsstring(kind.name)}')` : ``);
};
const luaG_typeerror = function(L, o, op) {
let t = ltm.luaT_objtypename(L, o);
- luaG_runerror(L, `attempt to ${op} a ${t} value${varinfo(L, o)}`);
+ luaG_runerror(L, lua.to_luastring(`attempt to ${lobject.jsstring(op)} a ${lobject.jsstring(t)} value${lobject.jsstring(varinfo(L, o))}`));
};
const luaG_concaterror = function(L, p1, p2) {
if (p1.ttisstring() || p1.ttisnumber()) p1 = p2;
- luaG_typeerror(L, p1, 'concatenate');
+ luaG_typeerror(L, p1, lua.to_luastring('concatenate'));
};
/*
@@ -458,18 +458,18 @@ const luaG_ordererror = function(L, p1, p2) {
let t1 = ltm.luaT_objtypename(L, p1);
let t2 = ltm.luaT_objtypename(L, p2);
if (t1 === t2)
- luaG_runerror(L, `attempt to compare two ${t1} values`);
+ luaG_runerror(L, lua.to_luastring(`attempt to compare two ${lobject.jsstring(t1)} values`));
else
- luaG_runerror(L, `attempt to compare ${t1} with ${t2}`);
+ luaG_runerror(L, lua.to_luastring(`attempt to compare ${lobject.jsstring(t1)} with ${lobject.jsstring(t2)}`));
};
/* add src:line information to 'msg' */
const luaG_addinfo = function(L, msg, src, line) {
- let buff = '?';
+ let buff = ['?'.charCodeAt(0)];
if (src)
buff = lobject.luaO_chunkid(src, luaconf.LUA_IDSIZE);
- L.stack[L.top++] = L.l_G.intern(lua.to_luastring(`${buff}:${line}: ${msg}`)); // We don't need to check for overflow here
+ L.stack[L.top++] = L.l_G.intern(lua.to_luastring(`${lobject.jsstring(buff)}:${line}: ${lobject.jsstring(msg)}`));
return L.stack[L.top - 1];
};
@@ -500,7 +500,7 @@ const luaG_tointerror = function(L, p1, p2) {
let temp = lvm.tointeger(p1);
if (temp === false)
p2 = p1;
- luaG_runerror(L, `number${varinfo(L, p2)} has no integer representation`);
+ luaG_runerror(L, lua.to_luastring(`number${lobject.jsstring(varinfo(L, p2))} has no integer representation`));
};
module.exports.lua_getstack = lua_getstack;
diff --git a/src/ldo.js b/src/ldo.js
index 50d455e..54d1ac0 100644
--- a/src/ldo.js
+++ b/src/ldo.js
@@ -448,9 +448,9 @@ const lua_yieldk = function(L, nresults, ctx, k) {
if (L.nny > 0) {
if (L !== L.l_G.mainthread)
- ldebug.luaG_runerror(L, "attempt to yield across a JS-call boundary");
+ ldebug.luaG_runerror(L, lua.to_luastring("attempt to yield across a JS-call boundary"));
else
- ldebug.luaG_runerror(L, "attempt to yield from outside a coroutine");
+ ldebug.luaG_runerror(L, lua.to_luastring("attempt to yield from outside a coroutine"));
}
L.status = TS.LUA_YIELD;
@@ -519,8 +519,8 @@ class SParser {
}
const checkmode = function(L, mode, x) {
- if (mode && mode.indexOf(x.charAt(0)) === -1) {
- lapi.lua_pushstring(L, `attempt to load a ${x} chunk (mode is '${mode}')`);
+ if (mode && mode.indexOf(x.charCodeAt(0)) === -1) {
+ lapi.lua_pushstring(L, lua.to_luastring(`attempt to load a ${lobject.jsstring(x)} chunk (mode is '${mode}')`));
luaD_throw(L, TS.LUA_ERRSYNTAX);
}
};
diff --git a/src/ljstype.js b/src/ljstype.js
index 7de9d9a..6f371bb 100644
--- a/src/ljstype.js
+++ b/src/ljstype.js
@@ -3,27 +3,27 @@
const assert = require('assert');
const lisdigit = function(c) {
- return typeof c === 'string' && /^\d$/.test(c.charAt(0));
+ return /^\d$/.test(String.fromCharCode(c));
};
const lisxdigit = function(c) {
- return typeof c === 'string' && /^[0-9a-fA-F]$/.test(c.charAt(0));
+ return /^[0-9a-fA-F]$/.test(String.fromCharCode(c));
};
const lisspace = function(c) {
- return typeof c === 'string' && /^\s$/.test(c.charAt(0));
+ return /^\s$/.test(String.fromCharCode(c));
};
const lislalpha = function(c) {
- return typeof c === 'string' && /^[_a-zA-Z]$/.test(c.charAt(0));
+ return /^[_a-zA-Z]$/.test(String.fromCharCode(c));
};
const lislalnum = function(c) {
- return typeof c === 'string' && /^[_a-zA-Z0-9]$/.test(c.charAt(0));
+ return /^[_a-zA-Z0-9]$/.test(String.fromCharCode(c));
};
module.exports.lisdigit = lisdigit;
module.exports.lislalnum = lislalnum;
module.exports.lislalpha = lislalpha;
module.exports.lisspace = lisspace;
-module.exports.lisxdigit = lisxdigit; \ No newline at end of file
+module.exports.lisxdigit = lisxdigit;
diff --git a/src/llex.js b/src/llex.js
index 2d34b1f..9b81cd7 100644
--- a/src/llex.js
+++ b/src/llex.js
@@ -81,7 +81,7 @@ class MBuffer {
this.reader = reader ? reader : null;
if (!this.reader) {
- this.buffer = typeof data === "string" ? data.split('') : (data ? data : []);
+ this.buffer = typeof data === "string" ? lua.to_luastring(data) : (data ? data : []);
this.n = this.buffer instanceof DataView ? this.buffer.byteLength : this.buffer.length;
this.off = 0;
}
@@ -97,7 +97,7 @@ class MBuffer {
fill() {
if (this.reader) {
this.buffer = this.reader(this.L, this.data);
- this.buffer = typeof this.buffer === "string" ? this.buffer.split('') : this.buffer;
+ this.buffer = typeof this.buffer === "string" ? lua.to_luastring(this.buffer) : this.buffer;
if (this.buffer === null)
return -1;
this.n = this.buffer instanceof DataView ? this.buffer.byteLength - 1 : this.buffer.length - 1;
@@ -150,25 +150,25 @@ 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, "lexical element too long", 0);
+ lexerror(ls, lua.to_luastring("lexical element too long"), 0);
}
b.buffer[b.n++] = c < 0 ? 255 + c + 1 : c;
};
const luaX_token2str = function(ls, token) {
if (typeof token === "string" || token < FIRST_RESERVED) { /* single-byte symbols? */
- return `'${typeof token === "string" ? token : String.fromCharCode(token)}'`;
+ return lua.to_luastring(`'${typeof token === "string" ? token : lobject.jsstring(token)}'`);
} else {
let s = luaX_tokens[token - FIRST_RESERVED];
if (token < R.TK_EOS) /* fixed format (symbols and reserved words)? */
- return `'${s}'`;
+ return lua.to_luastring(`'${s}'`);
else /* names, strings, and numerals */
- return s;
+ return lua.to_luastring(s);
}
};
const currIsNewline = function(ls) {
- return ls.current === '\n' || ls.current === '\r';
+ return ls.current === '\n'.charCodeAt(0) || ls.current === '\r'.charCodeAt(0);
};
const next = function(ls) {
@@ -191,7 +191,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, "chunk has too many lines", 0);
+ lexerror(ls, lua.to_luastring("chunk has too many lines"), 0);
};
const luaX_setinput = function(L, ls, z, source, firstchar) {
@@ -222,7 +222,7 @@ const luaX_setinput = function(L, ls, z, source, firstchar) {
};
const check_next1 = function(ls, c) {
- if (ls.current === c) {
+ if (ls.current === c.charCodeAt(0)) {
next(ls);
return true;
}
@@ -235,7 +235,7 @@ const check_next1 = function(ls, c) {
** saves it
*/
const check_next2 = function(ls, set) {
- if (ls.current === set.charAt(0) || ls.current === set.charAt(1)) {
+ if (ls.current === set.charAt(0).charCodeAt(0) || ls.current === set.charAt(1).charCodeAt(0)) {
save_and_next(ls);
return true;
}
@@ -261,11 +261,11 @@ const read_numeral = function(ls, seminfo) {
else break;
}
- save(ls, '\0');
+ save(ls, 0);
let obj = lobject.luaO_str2num(ls.buff.buffer);
if (obj === false) /* format error? */
- lexerror(ls, "malformed number", R.TK_FLT);
+ lexerror(ls, lua.to_luastring("malformed number"), R.TK_FLT);
if (obj.ttisinteger()) {
seminfo.i = obj.value;
return R.TK_INT;
@@ -280,8 +280,8 @@ const txtToken = function(ls, token) {
switch (token) {
case R.TK_NAME: case R.TK_STRING:
case R.TK_FLT: case R.TK_INT:
- save(ls, '\0');
- return `'${ls.buff.buffer.join('')}'`;
+ save(ls, 0);
+ return lua.to_luastring(`'${lobject.jsstring(ls.buff.buffer)}'`);
default:
return luaX_token2str(ls, token);
}
@@ -290,12 +290,12 @@ const txtToken = function(ls, token) {
const lexerror = function(ls, msg, token) {
msg = ldebug.luaG_addinfo(ls.L, msg, ls.source, ls.linenumber);
if (token)
- lapi.lua_pushstring(ls.L, `${msg instanceof TValue ? msg.value : msg} near ${txtToken(ls, token)}`);
+ lapi.lua_pushstring(ls.L, lua.to_luastring(`${msg instanceof TValue ? msg.jsstring() : msg} near ${lobject.jsstring(txtToken(ls, token))}`));
ldo.luaD_throw(ls.L, TS.LUA_ERRSYNTAX);
};
const luaX_syntaxerror = function(ls, msg) {
- msg = msg instanceof TValue ? msg.value : msg;
+ msg = msg instanceof TValue ? msg.value : lua.to_luastring(msg);
lexerror(ls, msg, ls.t.token);
};
@@ -307,9 +307,9 @@ const luaX_syntaxerror = function(ls, msg) {
const skip_sep = function(ls) {
let count = 0;
let s = ls.current;
- assert(s === '[' || s === ']');
+ assert(s === '['.charCodeAt(0) || s === ']'.charCodeAt(0));
save_and_next(ls);
- while (ls.current === '=') {
+ while (ls.current === '='.charCodeAt(0)) {
save_and_next(ls);
count++;
}
@@ -329,18 +329,18 @@ const read_long_string = function(ls, seminfo, sep) {
case -1: { /* error */
let what = seminfo ? "string" : "comment";
let msg = `unfinished long ${what} (starting at line ${line})`;
- lexerror(ls, msg, R.TK_EOS);
+ lexerror(ls, lua.to_luastring(msg), R.TK_EOS);
break;
}
- case ']': {
+ case ']'.charCodeAt(0): {
if (skip_sep(ls) === sep) {
save_and_next(ls); /* skip 2nd ']' */
skip = true;
}
break;
}
- case '\n': case '\r': {
- save(ls, '\n');
+ case '\n'.charCodeAt(0): case '\r'.charCodeAt(0): {
+ save(ls, '\n'.charCodeAt(0));
inclinenumber(ls);
if (!seminfo) {
ls.buff.n = 0;
@@ -358,11 +358,7 @@ const read_long_string = function(ls, seminfo, sep) {
if (seminfo)
seminfo.ts = new TValue(
CT.LUA_TLNGSTR,
- lua.to_luastring(
- ls.buff.buffer
- .slice(2 + sep, 2 + sep - 2 * (2 + sep))
- .join('')
- )
+ ls.buff.buffer.slice(2 + sep, 2 + sep - 2 * (2 + sep))
);
};
@@ -376,7 +372,7 @@ const esccheck = function(ls, c, msg) {
const gethexa = function(ls) {
save_and_next(ls);
- esccheck(ls, ljstype.lisxdigit(ls.current), "hexadecimal digit expected");
+ esccheck(ls, ljstype.lisxdigit(ls.current), lua.to_luastring("hexadecimal digit expected"));
return lobject.luaO_hexavalue(ls.current);
};
@@ -390,17 +386,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 === '{', "missing '{'");
+ esccheck(ls, ls.current === '{'.charCodeAt(0), lua.to_luastring("missing '{'"));
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, "UTF-8 value too large");
+ esccheck(ls, r <= 0x10FFFF, lua.to_luastring("UTF-8 value too large"));
save_and_next(ls);
}
- esccheck(ls, ls.current === '}', "missing '}'");
+ esccheck(ls, ls.current === '}'.charCodeAt(0), lua.to_luastring("missing '}'"));
next(ls); /* skip '}' */
ls.buff.n -= i; /* remove saved chars from buffer */
return r;
@@ -420,7 +416,7 @@ const readdecesc = function(ls) {
r = 10 * r + parseInt(ls.current);
save_and_next(ls);
}
- esccheck(ls, r <= 255, "decimal escape too large");
+ esccheck(ls, r <= 255, lua.to_luastring("decimal escape too large"));
ls.buff.n -= i; /* remove read digits from buffer */
return r;
};
@@ -431,29 +427,29 @@ const read_string = function(ls, del, seminfo) {
while (ls.current !== del) {
switch (ls.current) {
case -1:
- lexerror(ls, "unfinished string", R.TK_EOS);
+ lexerror(ls, lua.to_luastring("unfinished string"), R.TK_EOS);
break;
- case '\n':
- case '\r':
- lexerror(ls, "unfinished string", R.TK_STRING);
+ case '\n'.charCodeAt(0):
+ case '\r'.charCodeAt(0):
+ lexerror(ls, lua.to_luastring("unfinished string"), R.TK_STRING);
break;
- case '\\': { /* escape sequences */
+ case '\\'.charCodeAt(0): { /* escape sequences */
save_and_next(ls); /* keep '\\' for error messages */
let will;
let c;
switch(ls.current) {
- case 'a': c = '\a'; will = 'read_save'; break;
- case 'b': c = '\b'; will = 'read_save'; break;
- case 'f': c = '\f'; will = 'read_save'; break;
- case 'n': c = '\n'; will = 'read_save'; break;
- case 'r': c = '\r'; will = 'read_save'; break;
- case 't': c = '\t'; will = 'read_save'; break;
- case 'v': c = '\v'; will = 'read_save'; break;
+ case 'a': c = '\a'.charCodeAt(0); will = 'read_save'; break;
+ case 'b': c = '\b'.charCodeAt(0); will = 'read_save'; break;
+ case 'f': c = '\f'.charCodeAt(0); will = 'read_save'; break;
+ case 'n': c = '\n'.charCodeAt(0); will = 'read_save'; break;
+ case 'r': c = '\r'.charCodeAt(0); will = 'read_save'; break;
+ case 't': c = '\t'.charCodeAt(0); will = 'read_save'; break;
+ case 'v': c = '\v'.charCodeAt(0); will = 'read_save'; break;
case 'x': c = readhexaesc(ls); will = 'read_save'; break;
case 'u': utf8esc(ls); will = 'no_save'; break;
- case '\n': case '\r':
+ case '\n'.charCodeAt(0): case '\r'.charCodeAt(0):
inclinenumber(ls); c = '\n'; will = 'only_save'; break;
- case '\\': case '\"': case '\'':
+ case '\\'.charCodeAt(0): case '\"'.charCodeAt(0): case '\''.charCodeAt(0):
c = ls.current; will = 'read_save'; break;
case -1: will = 'no_save'; break; /* will raise an error next loop */
case 'z': { /* zap following span of spaces */
@@ -466,7 +462,7 @@ const read_string = function(ls, del, seminfo) {
will = 'no_save'; break;
}
default: {
- esccheck(ls, ljstype.lisdigit(ls.current), "invalid escape sequence");
+ esccheck(ls, ljstype.lisdigit(ls.current), lua.to_luastring("invalid escape sequence"));
c = readdecesc(ls); /* digital escape '\ddd' */
will = 'only_save'; break;
}
@@ -490,10 +486,7 @@ const read_string = function(ls, del, seminfo) {
seminfo.ts = new TValue(
CT.LUA_TLNGSTR,
- ls.buff.buffer
- .slice(1, ls.buff.n-1)
- .map(e => typeof e === "string" ? lua.to_luastring(e) : [e])
- .reduce((acc, e) => acc = acc.concat(e), []) /* Hex value must not be converted */
+ ls.buff.buffer.slice(1, ls.buff.n-1)
);
};
@@ -507,20 +500,20 @@ const llex = function(ls, seminfo) {
for (;;) {
switch (ls.current) {
- case '\n': case '\r': { /* line breaks */
+ case '\n'.charCodeAt(0): case '\r'.charCodeAt(0): { /* line breaks */
inclinenumber(ls);
break;
}
- case ' ': case '\f': case '\t': case '\v': { /* spaces */
+ case ' '.charCodeAt(0): case '\f'.charCodeAt(0): case '\t'.charCodeAt(0): case '\v'.charCodeAt(0): { /* spaces */
next(ls);
break;
}
- case '-': { /* '-' or '--' (comment) */
+ case '-'.charCodeAt(0): { /* '-' or '--' (comment) */
next(ls);
- if (ls.current !== '-') return '-';
+ if (ls.current !== '-'.charCodeAt(0)) return '-';
/* else is a comment */
next(ls);
- if (ls.current === '[') { /* long comment? */
+ if (ls.current === '['.charCodeAt(0)) { /* long comment? */
let sep = skip_sep(ls);
ls.buff.n = 0; /* 'skip_sep' may dirty the buffer */
ls.buff.buffer = [];
@@ -537,52 +530,52 @@ const llex = function(ls, seminfo) {
next(ls); /* skip until end of line (or end of file) */
break;
}
- case '[': { /* long string or simply '[' */
+ case '['.charCodeAt(0): { /* long string or simply '[' */
let sep = skip_sep(ls);
if (sep >= 0) {
read_long_string(ls, seminfo, sep);
return R.TK_STRING;
} else if (sep !== -1) /* '[=...' missing second bracket */
- lexerror(ls, "invalid long string delimiter", R.TK_STRING);
+ lexerror(ls, lua.to_luastring("invalid long string delimiter"), R.TK_STRING);
return '[';
}
- case '=': {
+ case '='.charCodeAt(0): {
next(ls);
if (check_next1(ls, '=')) return R.TK_EQ;
else return '=';
}
- case '<': {
+ case '<'.charCodeAt(0): {
next(ls);
if (check_next1(ls, '=')) return R.TK_LE;
else if (check_next1(ls, '<')) return R.TK_SHL;
else return '<';
}
- case '>': {
+ case '>'.charCodeAt(0): {
next(ls);
if (check_next1(ls, '=')) return R.TK_GE;
else if (check_next1(ls, '>')) return R.TK_SHR;
else return '>';
}
- case '/': {
+ case '/'.charCodeAt(0): {
next(ls);
if (check_next1(ls, '/')) return R.TK_IDIV;
else return '/';
}
- case '~': {
+ case '~'.charCodeAt(0): {
next(ls);
if (check_next1(ls, '=')) return R.TK_NE;
else return '~';
}
- case ':': {
+ case ':'.charCodeAt(0): {
next(ls);
if (check_next1(ls, ':')) return R.TK_DBCOLON;
else return ':';
}
- case '"': case '\'': { /* short literal strings */
+ case '"'.charCodeAt(0): case '\''.charCodeAt(0): { /* short literal strings */
read_string(ls, ls.current, seminfo);
return R.TK_STRING;
}
- case '.': { /* '.', '..', '...', or number */
+ case '.'.charCodeAt(0): { /* '.', '..', '...', or number */
save_and_next(ls);
if (check_next1(ls, '.')) {
if (check_next1(ls, '.'))
diff --git a/src/lmathlib.js b/src/lmathlib.js
index 7553dfd..500331b 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, "wrong number of arguments");
+ default: return lauxlib.luaL_error(L, lua.to_luastring("wrong number of arguments"));
}
/* random integer in the interval [low, up] */
- lauxlib.luaL_argcheck(L, low <= up, 1, "interval is empty");
+ lauxlib.luaL_argcheck(L, low <= up, 1, lua.to_luastring("interval is empty"));
lauxlib.luaL_argcheck(L, low >= 0 || up <= Number.MAX_SAFE_INTEGER + low, 1,
- "interval too large");
+ lua.to_luastring("interval too large"));
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, "value expected");
+ lauxlib.luaL_argcheck(L, n >= 1, 1, lua.to_luastring("value expected"));
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, "value expected");
+ lauxlib.luaL_argcheck(L, n >= 1, 1, lua.to_luastring("value expected"));
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, "zero");
+ lauxlib.luaL_argcheck(L, d !== 0, 2, lua.to_luastring("zero"));
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, "pi");
+ lapi.lua_setfield(L, -2, lua.to_luastring("pi"));
lapi.lua_pushnumber(L, Number.MAX_VALUE);
- lapi.lua_setfield(L, -2, "huge");
+ lapi.lua_setfield(L, -2, lua.to_luastring("huge"));
lapi.lua_pushinteger(L, Number.MAX_SAFE_INTEGER);
- lapi.lua_setfield(L, -2, "maxinteger");
+ lapi.lua_setfield(L, -2, lua.to_luastring("maxinteger"));
lapi.lua_pushinteger(L, Number.MIN_SAFE_INTEGER);
- lapi.lua_setfield(L, -2, "mininteger");
+ lapi.lua_setfield(L, -2, lua.to_luastring("mininteger"));
return 1;
};
diff --git a/src/lobject.js b/src/lobject.js
index 966bdd8..812ac6a 100644
--- a/src/lobject.js
+++ b/src/lobject.js
@@ -278,49 +278,49 @@ class LocVar {
}
}
-const RETS = "...";
-const PRE = "[string \"";
-const POS = "\"]";
+const RETS = lua.to_luastring("...");
+const PRE = lua.to_luastring("[string \"");
+const POS = lua.to_luastring("\"]");
const luaO_chunkid = function(source, bufflen) {
- source = source instanceof TValue ? source.jsstring() : source;
+ source = source instanceof TValue ? source.value : source;
bufflen = bufflen instanceof TValue ? bufflen.value : bufflen;
let l = source.length;
- let out = "";
- if (source.charAt(0) === '=') { /* 'literal' source */
+ let out = [];
+ if (source[0] === '='.charCodeAt(0)) { /* 'literal' source */
if (l < bufflen) /* small enough? */
- out = `${source.slice(1)}`;
+ out = source.slice(1);
else { /* truncate it */
- out += `${source.slice(1, bufflen)}`;
+ out = out.concat(source.slice(1, bufflen));
}
} else if (source.charAt(0) === '@') { /* file name */
if (l <= bufflen) /* small enough? */
- out = `${source.slice(1)}`;
+ out = source.slice(1);
else { /* add '...' before rest of name */
bufflen -= RETS.length;
- out = `${RETS}${source.slice(1, l - bufflen)}`;
+ out = RETS.concat(source.slice(1, l - bufflen));
}
} else { /* string; format as [string "source"] */
let nli = source.indexOf('\n'); /* find first new line (if any) */
let nl = nli ? source.slice(nli) : null;
- out = `${PRE}`; /* add prefix */
+ out = PRE; /* add prefix */
bufflen -= PRE.length + RETS.length + POS.length + 1; /* save space for prefix+suffix+'\0' */
if (l < bufflen && nl === null) { /* small one-line source? */
- out += `${source}`; /* keep it */
+ out = out.conat(source); /* keep it */
} else {
if (nl !== null) l = nl.length - source.length; /* stop at first newline */
if (l > bufflen) l = bufflen;
- out += `${source}${RETS}`;
+ out = out.concat(source).concat(RETS);
}
- out += POS;
+ out = out.concat(POS);
}
return out;
};
const luaO_hexavalue = function(c) {
- if (ljstype.lisdigit(c)) return c.charCodeAt(0) - '0'.charCodeAt(0);
- else return (c.toLowerCase().charCodeAt(0) - 'a'.charCodeAt(0)) + 10;
+ if (ljstype.lisdigit(c)) return c - '0'.charCodeAt(0);
+ else return (String.fromCharCode(c).toLowerCase().charCodeAt(0) - 'a'.charCodeAt(0)) + 10;
};
const UTF8BUFFSZ = 8;
@@ -329,15 +329,15 @@ const luaO_utf8desc = function(buff, x) {
let n = 1; /* number of bytes put in buffer (backwards) */
assert(x <= 0x10FFFF);
if (x < 0x80) /* ascii? */
- buff[UTF8BUFFSZ - 1] = String.fromCharCode(x);
+ buff[UTF8BUFFSZ - 1] = x;
else { /* need continuation bytes */
let mfb = 0x3f; /* maximum that fits in first byte */
do {
- buff[UTF8BUFFSZ - (n++)] = String.fromCharCode(0x80 | (x & 0x3f));
+ buff[UTF8BUFFSZ - (n++)] = 0x80 | (x & 0x3f);
x >>= 6; /* remove added bits */
mfb >>= 1; /* now there is one less bit available in first byte */
} while (x > mfb); /* still needs continuation byte? */
- buff[UTF8BUFFSZ - n] = String.fromCharCode((~mfb << 1) | x); /* add first byte */
+ buff[UTF8BUFFSZ - n] = (~mfb << 1) | x; /* add first byte */
}
return n;
};
@@ -383,19 +383,19 @@ const lua_strx2number = function(s) {
let neg; /* 1 if number is negative */
let hasdot = false; /* true after seen a dot */
- while (ljstype.lisspace(s.charAt(0))) s = s.slice(1); /* skip initial spaces */
+ while (ljstype.lisspace(s)) s = s.slice(1); /* skip initial spaces */
- neg = s.charAt(0) === '-'; /* check signal */
- s = neg || s.charAt(0) === '+' ? s.slice(1) : s; /* skip sign if one */
- if (!(s.charAt(0) === '0' && (s.charAt(1) === 'x' || s.charAt(1) === 'X'))) /* check '0x' */
+ neg = s[0] === '-'.charCodeAt(0); /* check signal */
+ s = neg || s[0] === '+'.charCodeAt(0) ? s.slice(1) : s; /* skip sign if one */
+ if (!(s[0] === '0' && (s[1] === 'x'.charCodeAt(0) || s[1] === 'X'.charCodeAt(0)))) /* check '0x' */
return 0.0; /* invalid format (no '0x') */
for (s = s.slice(2); ; s = s.slice(1)) { /* skip '0x' and read numeral */
- if (s.charAt(0) === dot) {
+ if (s[0] === dot) {
if (hasdot) break; /* second dot? stop loop */
else hasdot = true;
- } else if (ljstype.lisxdigit(s.charAt(0))) {
- if (sigdig === 0 && s.charAt(0) === '0') /* non-significant digit (zero)? */
+ } else if (ljstype.lisxdigit(s[0])) {
+ if (sigdig === 0 && s[0] === '0'.charCodeAt(0)) /* non-significant digit (zero)? */
nosigdig++;
else if (++sigdig <= MAXSIGDIG) /* can read it without overflow? */
r = (r * 16) + luaO_hexavalue(s);
@@ -407,35 +407,35 @@ const lua_strx2number = function(s) {
if (nosigdig + sigdig === 0) /* no digits? */
return 0.0; /* invalid format */
e *= 4; /* each digit multiplies/divides value by 2^4 */
- if (s.charAt(0) === 'p' || s.charAt(0) === 'P') { /* exponent part? */
+ if (s[0] === 'p'.charCodeAt(0) || s[0] === 'P'.charCodeAt(0)) { /* exponent part? */
let exp1 = 0; /* exponent value */
let neg1; /* exponent signal */
s = s.slice(1); /* skip 'p' */
- neg1 = s.charAt(0) === '-'; /* check signal */
- s = neg1 || s.charAt(0) === '+' ? s.slice(1) : s; /* skip sign if one */
- if (!ljstype.lisdigit(s.charAt(0)))
+ neg1 = s[0] === '-'.charCodeAt(0); /* check signal */
+ s = neg1 || s[0] === '+'.charCodeAt(0) ? s.slice(1) : s; /* skip sign if one */
+ if (!ljstype.lisdigit(s[0]))
return 0.0; /* invalid; must have at least one digit */
- while (ljstype.lisdigit(s.charAt(0))) { /* read exponent */
- exp1 = exp1 * 10 + s.charCodeAt(0) - '0'.charCodeAt(0);
+ while (ljstype.lisdigit(s[0])) { /* read exponent */
+ exp1 = exp1 * 10 + s - '0'.charCodeAt(0);
s = s.slice(1);
}
if (neg1) exp1 = -exp1;
e += exp1;
}
if (neg) r = -r;
- return s.trim().search(/s/) < 0 ? ldexp(r, e) : null; /* Only valid if nothing left is s*/
+ return jsstring(s).trim().search(/s/) < 0 ? ldexp(r, e) : null; /* Only valid if nothing left is s*/
};
const l_str2dloc = function(s, mode) {
- let flt = mode === 'x' ? lua_strx2number(s) : parseFloat(s);
+ let flt = mode === 'x' ? lua_strx2number(s) : parseFloat(jsstring(s));
return !isNaN(flt) ? flt : null; /* OK if no trailing characters */
};
const l_str2d = function(s) {
- let pidx = /[.xXnN]/g.exec(s);
+ let pidx = /[.xXnN]/g.exec(String.fromCharCode(...s));
pidx = pidx ? pidx.index : null;
let pmode = pidx ? s[pidx] : null;
- let mode = pmode ? pmode.toLowerCase() : 0;
+ let mode = pmode ? String.fromCharCode(pmode).toLowerCase() : 0;
if (mode === 'n') /* reject 'inf' and 'nan' */
return null;
let end = l_str2dloc(s, mode); /* try to convert */
@@ -454,12 +454,12 @@ const l_str2int = function(s) {
let neg;
while (ljstype.lisspace(s[0])) s = s.slice(1); /* skip initial spaces */
- neg = s[0] === '-';
+ neg = s[0] === '-'.charCodeAt(0);
- if (neg || s[0] === '+')
+ if (neg || s[0] === '+'.charCodeAt(0))
s = s.slice(1);
- if (s[0] === '0' && (s[1] === 'x' || s[1] === 'X')) { /* hex? */
+ if (s[0] === '0'.charCodeAt(0) && (s[1] === 'x'.charCodeAt(0) || s[1] === 'X'.charCodeAt(0))) { /* hex? */
s = s.slice(2); /* skip '0x' */
for (; ljstype.lisxdigit(s[0]); s = s.slice(1)) {
@@ -468,7 +468,7 @@ const l_str2int = function(s) {
}
} else { /* decimal */
for (; ljstype.lisdigit(s[0]); s = s.slice(1)) {
- let d = parseInt(s[0]);
+ let d = s[0] - '0'.charCodeAt(0);
if (a >= MAXBY10 && (a > MAXBY10 || d > MAXLASTD + neg)) /* overflow? */
return null; /* do not accept it (as integer) */
a = a * 10 + d;
@@ -478,7 +478,7 @@ const l_str2int = function(s) {
while (ljstype.lisspace(s[0])) s = s.slice(1); /* skip trailing spaces */
- if (empty || s[0] !== "\0") return null; /* something wrong in the numeral */
+ if (empty || s[0] !== 0) return null; /* something wrong in the numeral */
else {
return neg ? -a : a;
}
@@ -490,7 +490,7 @@ const luaO_str2num = function(s) {
if (s2i !== null) { /* try as an integer */
return new TValue(CT.LUA_TNUMINT, s2i);
} else { /* else try as a float */
- s2i = l_str2d(s.join(''));
+ s2i = l_str2d(s);
if (s2i !== null) {
return new TValue(CT.LUA_TNUMFLT, s2i);
diff --git a/src/lparser.js b/src/lparser.js
index 1806bbe..01b9a08 100644
--- a/src/lparser.js
+++ b/src/lparser.js
@@ -159,7 +159,7 @@ const semerror = function(ls, msg) {
};
const error_expected = function(ls, token) {
- llex.luaX_syntaxerror(ls, `${llex.luaX_token2str(ls, token)} expected`);
+ llex.luaX_syntaxerror(ls, lua.to_luastring(`${lobject.jsstring(llex.luaX_token2str(ls, token))} expected`));
};
const errorlimit = function(fs, limit, what) {
@@ -167,7 +167,7 @@ const errorlimit = function(fs, limit, what) {
let line = fs.f.linedefined;
let where = (line === 0) ? "main function" : `function at line ${line}`;
let msg = `too many ${what} (limit is ${limit}) in ${where}`;
- llex.luaX_syntaxerror(fs.ls, msg);
+ llex.luaX_syntaxerror(fs.ls, lua.to_luastring(msg));
};
const checklimit = function(fs, v, l, what) {
@@ -204,7 +204,7 @@ const check_match = function(ls, what, who, where) {
error_expected(ls, what);
else
llex.luaX_syntaxerror(ls,
- `${llex.luaX_token2str(ls, what)} expected (to close ${llex.luaX_token2str(ls, who)} at line ${where}`);
+ lua.to_luastring(`${lobject.jsstring(llex.luaX_token2str(ls, what))} expected (to close ${lobject.jsstring(llex.luaX_token2str(ls, who))} at line ${where}`));
}
};
@@ -241,7 +241,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, "local variables");
+ checklimit(fs, dyd.actvar.n + 1 - fs.firstlocal, MAXVARS, lua.to_luastring("local variables"));
dyd.actvar.arr[dyd.actvar.n] = new Vardesc();
dyd.actvar.arr[dyd.actvar.n].idx = reg;
dyd.actvar.n++;
@@ -273,7 +273,7 @@ const removevars = function(fs, tolevel) {
const searchupvalue = function(fs, name) {
let up = fs.f.upvalues;
for (let i = 0; i < fs.nups; i++) {
- if (up[i].name.jsstring() === name.jsstring())
+ if (up[i].name.join() === name.join())
return i;
}
return -1; /* not found */
@@ -281,7 +281,7 @@ const searchupvalue = function(fs, name) {
const newupvalue = function(fs, name, v) {
let f = fs.f;
- checklimit(fs, fs.nups + 1, lfunc.MAXUPVAL, "upvalues");
+ checklimit(fs, fs.nups + 1, lfunc.MAXUPVAL, lua.to_luastring("upvalues"));
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;
@@ -291,7 +291,7 @@ const newupvalue = function(fs, name, v) {
const searchvar = function(fs, n) {
for (let i = fs.nactvar - 1; i >= 0; i--) {
- if (n.jsstring() === getlocvar(fs, i).varname.jsstring())
+ if (n.join() === getlocvar(fs, i).varname.join())
return i;
}
@@ -372,7 +372,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, "JS levels");
+ checklimit(ls.fs, L.nCcalls, llimit.LUAI_MAXCCALLS, lua.to_luastring("JS levels"));
};
const leavelevel = function(ls) {
@@ -383,10 +383,10 @@ const closegoto = function(ls, g, label) {
let fs = ls.fs;
let gl = ls.dyd.gt;
let gt = gl.arr[g];
- assert(gt.name.jsstring() === label.name.jsstring());
+ assert(gt.name.value.join() === label.name.value.join());
if (gt.nactvar < label.nactvar) {
let vname = getlocvar(fs, gt.nactvar).varname;
- semerror(ls, `<goto ${gt.name.value}> at line ${gt.line} jumps into the scope of local '${vname.value}'`);
+ semerror(ls, lua.to_luastring(`<goto ${gt.name.jsstring()}> at line ${gt.line} jumps into the scope of local '${vname.jsstring()}'`));
}
lcode.luaK_patchlist(fs, gt.pc, label.pc);
/* remove goto from pending list */
@@ -405,7 +405,7 @@ const findlabel = function(ls, g) {
/* check labels in current block for a match */
for (let i = bl.firstlabel; i < dyd.label.n; i++) {
let lb = dyd.label.arr[i];
- if (lb.name.jsstring() === gt.name.jsstring()) { /* correct label? */
+ if (lb.name.value.join() === gt.name.value.join()) { /* correct label? */
if (gt.nactvar > lb.nactvar && (bl.upval || dyd.label.n > bl.firstlabel))
lcode.luaK_patchclose(ls.fs, gt.pc, lb.nactvar);
closegoto(ls, g, lb); /* close it */
@@ -434,7 +434,7 @@ const findgotos = function(ls, lb) {
let gl = ls.dyd.gt;
let i = ls.fs.bl.firstgoto;
while (i < gl.n) {
- if (gl.arr[i].name.jsstring() === lb.name.jsstring())
+ if (gl.arr[i].name.value.join() === lb.name.value.join())
closegoto(ls, i, lb);
else
i++;
@@ -490,9 +490,9 @@ const breaklabel = function(ls) {
*/
const undefgoto = function(ls, gt) {
const msg = llex.isreserved(gt.name.value)
- ? `<${gt.name.value}> at line ${gt.line} not inside a loop`
- : `no visible label '${gt.name.value}' for <goto> at line ${gt.line}`;
- semerror(ls, msg);
+ ? `<${gt.name.jsstring()}> at line ${gt.line} not inside a loop`
+ : `no visible label '${gt.name.jsstring()}' for <goto> at line ${gt.line}`;
+ semerror(ls, lua.to_luastring(msg));
};
/*
@@ -638,7 +638,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, "items in a constructor");
+ checklimit(fs, cc.nh, Number.MAX_SAFE_INTEGER, lua.to_luastring("items in a constructor"));
checkname(ls, key);
} else /* ls->t.token === '[' */
yindex(ls, key);
@@ -676,7 +676,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, "items in a constructor");
+ checklimit(ls.fs, cc.na, Number.MAX_SAFE_INTEGER, lua.to_luastring("items in a constructor"));
cc.na++;
cc.tostore++;
};
@@ -748,7 +748,7 @@ const parlist = function(ls) {
f.is_vararg = 1; /* declared vararg */
break;
}
- default: llex.luaX_syntaxerror(ls, "<name> or '...' expected");
+ default: llex.luaX_syntaxerror(ls, lua.to_luastring("<name> or '...' expected"));
}
} while(!f.is_vararg && testnext(ls, ','));
}
@@ -766,7 +766,7 @@ const body = function(ls, e, ismethod, line) {
open_func(ls, new_fs, bl);
checknext(ls, '(');
if (ismethod) {
- new_localvarliteral(ls, "self"); /* create 'self' parameter */
+ new_localvarliteral(ls, lua.to_luastring("self")); /* create 'self' parameter */
adjustlocalvars(ls, 1);
}
parlist(ls);
@@ -815,7 +815,7 @@ const funcargs = function(ls, f, line) {
break;
}
default: {
- llex.luaX_syntaxerror(ls, "function arguments expected");
+ llex.luaX_syntaxerror(ls, lua.to_luastring("function arguments expected"));
}
}
assert(f.k === expkind.VNONRELOC);
@@ -855,7 +855,7 @@ const primaryexp = function(ls, v) {
return;
}
default: {
- llex.luaX_syntaxerror(ls, "unexpected symbol");
+ llex.luaX_syntaxerror(ls, lua.to_luastring("unexpected symbol"));
}
}
};
@@ -929,7 +929,7 @@ const simpleexp = function(ls, v) {
}
case R.TK_DOTS: { /* vararg */
let fs = ls.fs;
- check_condition(ls, fs.f.is_vararg, "cannot use '...' outside a vararg function");
+ check_condition(ls, fs.f.is_vararg, lua.to_luastring("cannot use '...' outside a vararg function"));
init_exp(v, expkind.VVARARG, lcode.luaK_codeABC(fs, OpCodesI.OP_VARARG, 0, 1, 0));
break;
}
@@ -1101,14 +1101,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), "syntax error");
+ check_condition(ls, vkisvar(lh.v.k), lua.to_luastring("syntax error"));
if (testnext(ls, ',')) { /* 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, "JS levels");
+ checklimit(ls.fs, nvars + ls.L.nCcalls, llimit.LUAI_MAXCCALLS, lua.to_luastring("JS levels"));
assignment(ls, nv, nvars + 1);
} else { /* assignment -> '=' explist */
checknext(ls, '=');
@@ -1150,8 +1150,8 @@ const gotostat = function(ls, pc) {
/* check for repeated labels on the same block */
const checkrepeated = function(fs, ll, label) {
for (let i = fs.bl.firstlabel; i < ll.n; i++) {
- if (label.jsstring() === ll.arr[i].name.jsstring()) {
- semerror(fs.ls, `label '${label}' already defined on line ${ll.arr[i].line}`);
+ if (label.value.join() === ll.arr[i].name.value.join()) {
+ semerror(fs.ls, lua.to_luastring(`label '${label.jsstring()}' already defined on line ${ll.arr[i].line}`));
}
}
};
@@ -1252,9 +1252,9 @@ const fornum = function(ls, varname, line) {
/* fornum -> NAME = exp1,exp1[,exp1] forbody */
let fs = ls.fs;
let base = fs.freereg;
- new_localvarliteral(ls, "(for index)");
- new_localvarliteral(ls, "(for limit)");
- new_localvarliteral(ls, "(for step)");
+ 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_localvar(ls, varname);
checknext(ls, '=');
exp1(ls); /* initial value */
@@ -1276,9 +1276,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, "(for generator)");
- new_localvarliteral(ls, "(for state)");
- new_localvarliteral(ls, "(for control)");
+ new_localvarliteral(ls, lua.to_luastring("(for generator)"));
+ new_localvarliteral(ls, lua.to_luastring("(for state)"));
+ new_localvarliteral(ls, lua.to_luastring("(for control)"));
/* create declared variables */
new_localvar(ls, indexname);
while (testnext(ls, ',')) {
@@ -1302,7 +1302,7 @@ const forstat = function(ls, line) {
switch (ls.t.token) {
case '=': fornum(ls, varname, line); break;
case ',': case R.TK_IN: forlist(ls, varname); break;
- default: llex.luaX_syntaxerror(ls, "'=' or 'in' expected");
+ default: llex.luaX_syntaxerror(ls, lua.to_luastring("'=' or 'in' expected"));
}
check_match(ls, R.TK_END, R.TK_FOR, line);
leaveblock(fs); /* loop scope ('break' jumps to this point) */
@@ -1418,7 +1418,7 @@ const exprstat= function(ls) {
assignment(ls, v, 1);
}
else { /* stat -> func */
- check_condition(ls, v.v.k === expkind.VCALL, "syntax error");
+ check_condition(ls, v.v.k === expkind.VCALL, lua.to_luastring("syntax error"));
lopcode.SETARG_C(lcode.getinstruction(fs, v.v), 1); /* call statement uses no results */
}
};
@@ -1565,4 +1565,4 @@ module.exports.Dyndata = Dyndata;
module.exports.expkind = expkind;
module.exports.expdesc = expdesc;
module.exports.luaY_parser = luaY_parser;
-module.exports.vkisinreg = vkisinreg; \ No newline at end of file
+module.exports.vkisinreg = vkisinreg;
diff --git a/src/ltablib.js b/src/ltablib.js
index 20fdf95..c45f7e5 100644
--- a/src/ltablib.js
+++ b/src/ltablib.js
@@ -9,6 +9,7 @@ const lstate = require('./lstate.js');
const ldo = require('./ldo.js');
const ldebug = require('./ldebug.js');
const llimit = require('./llimit.js');
+const lobject = require('./lobject.js');
const CT = lua.constant_types;
const TS = lua.thread_status;
@@ -35,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, "__index", ++n)) &&
- (!(what & TAB_W) || checkfield(L, "__newindex", ++n)) &&
- (!(what & TAB_L) || checkfield(L, "__len", ++n))) {
+ (!(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))) {
lapi.lua_pop(L, n); /* pop metatable and tested metamethods */
}
else
@@ -53,7 +54,7 @@ const aux_getn = function(L, n, w) {
const addfield = function(L, b, i) {
lapi.lua_geti(L, 1, i);
if (!lapi.lua_isstring(L, -1))
- lauxlib.luaL_error(L, `invalid value (${lauxlib.luaL_typename(L, -1)}) at index ${i} in table for 'concat'`);
+ lauxlib.luaL_error(L, lua.to_luastring(`invalid value (${lobject.jsstring(lauxlib.luaL_typename(L, -1))}) at index ${i} in table for 'concat'`));
lauxlib.luaL_addvalue(b);
};
@@ -67,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, "position out of bounds");
+ lauxlib.luaL_argcheck(L, 1 <= pos && pos <= e, 2, lua.to_luastring("position out of bounds"));
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] */
@@ -75,7 +76,7 @@ const tinsert = function(L) {
break;
}
default: {
- return lauxlib.luaL_error(L, "wrong number of arguments to 'insert'");
+ return lauxlib.luaL_error(L, lua.to_luastring("wrong number of arguments to 'insert'"));
}
}
@@ -87,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, "position out of bounds");
+ lauxlib.luaL_argcheck(L, 1 <= pos && pos <= size + 1, 1, lua.to_luastring("position out of bounds"));
lapi.lua_geti(L, 1, pos); /* result = t[pos] */
for (; pos < size; pos++) {
lapi.lua_geti(L, 1, pos + 1);
@@ -112,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, "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"));
let n = e - f + 1; /* number of elements to move */
- lauxlib.luaL_argcheck(L, t <= llimit.LUA_MAXINTEGER - n + 1, 4, "destination wrap around");
+ lauxlib.luaL_argcheck(L, t <= llimit.LUA_MAXINTEGER - n + 1, 4, lua.to_luastring("destination wrap around"));
if (t > e || t <= f || (tt !== 1 && lapi.lua_compare(L, 1, tt, lua.LUA_OPEQ) !== 1)) {
for (let i = 0; i < n; i++) {
@@ -172,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, "too many results to unpack");
+ return lauxlib.luaL_error(L, lua.to_luastring("too many results to unpack"));
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 */
@@ -213,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, "array too big");
+ lauxlib.luaL_argcheck(L, n < Number.MAX_SAFE_INTEGER, 1, lua.to_luastring("array too big"));
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 */
@@ -237,4 +238,4 @@ const luaopen_table = function(L) {
return 1;
};
-module.exports.luaopen_table = luaopen_table; \ No newline at end of file
+module.exports.luaopen_table = luaopen_table;
diff --git a/src/ltm.js b/src/ltm.js
index 7ef772f..d2df961 100644
--- a/src/ltm.js
+++ b/src/ltm.js
@@ -15,57 +15,30 @@ const CT = lua.constant_types;
const TMS = {
- TM_INDEX: "__index",
- TM_NEWINDEX: "__newindex",
- TM_GC: "__gc",
- TM_MODE: "__mode",
- TM_LEN: "__len",
- TM_EQ: "__eq", /* last tag method with fast access */
- TM_ADD: "__add",
- TM_SUB: "__sub",
- TM_MUL: "__mul",
- TM_MOD: "__mod",
- TM_POW: "__pow",
- TM_DIV: "__div",
- TM_IDIV: "__idiv",
- TM_BAND: "__band",
- TM_BOR: "__bor",
- TM_BXOR: "__bxor",
- TM_SHL: "__shl",
- TM_SHR: "__shr",
- TM_UNM: "__unm",
- TM_BNOT: "__bnot",
- TM_LT: "__lt",
- TM_LE: "__le",
- TM_CONCAT: "__concat",
- TM_CALL: "__call"
-};
-
-const TMS8 = {
- TM_INDEX: lua.to_luastring(TMS.TM_INDEX),
- TM_NEWINDEX: lua.to_luastring(TMS.TM_NEWINDEX),
- TM_GC: lua.to_luastring(TMS.TM_GC),
- TM_MODE: lua.to_luastring(TMS.TM_MODE),
- TM_LEN: lua.to_luastring(TMS.TM_LEN),
- TM_EQ: lua.to_luastring(TMS.TM_EQ), /* last tag method with fast access */
- TM_ADD: lua.to_luastring(TMS.TM_ADD),
- TM_SUB: lua.to_luastring(TMS.TM_SUB),
- TM_MUL: lua.to_luastring(TMS.TM_MUL),
- TM_MOD: lua.to_luastring(TMS.TM_MOD),
- TM_POW: lua.to_luastring(TMS.TM_POW),
- TM_DIV: lua.to_luastring(TMS.TM_DIV),
- TM_IDIV: lua.to_luastring(TMS.TM_IDIV),
- TM_BAND: lua.to_luastring(TMS.TM_BAND),
- TM_BOR: lua.to_luastring(TMS.TM_BOR),
- TM_BXOR: lua.to_luastring(TMS.TM_BXOR),
- TM_SHL: lua.to_luastring(TMS.TM_SHL),
- TM_SHR: lua.to_luastring(TMS.TM_SHR),
- TM_UNM: lua.to_luastring(TMS.TM_UNM),
- TM_BNOT: lua.to_luastring(TMS.TM_BNOT),
- TM_LT: lua.to_luastring(TMS.TM_LT),
- TM_LE: lua.to_luastring(TMS.TM_LE),
- TM_CONCAT: lua.to_luastring(TMS.TM_CONCAT),
- TM_CALL: lua.to_luastring(TMS.TM_CALL)
+ 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")
};
const luaT_typenames_ = [
@@ -88,10 +61,8 @@ const ttypename = function(t) {
const luaT_init = function(L) {
L.l_G.tmname = [];
- for (let event in TMS) {
- let name = lua.to_luastring(TMS[event]);
- L.l_G.tmname.push(L.l_G.intern(name)); // Strings are already interned by JS
- }
+ for (let event in TMS)
+ L.l_G.tmname.push(L.l_G.intern(TMS[event]));
};
/*
@@ -99,9 +70,8 @@ const luaT_init = function(L) {
** with metatable, use their '__name' metafield, if present.
*/
const luaT_objtypename = function(L, o) {
- if ((o.ttistable() && o.metatable !== null)
- || (o.ttisfulluserdata() && o.metatable !== null)) {
- let name = o.__index(o, '__name');
+ if ((o.ttistable() && o.metatable !== null) || (o.ttisfulluserdata() && o.metatable !== null)) {
+ let name = o.__index(o, lua.to_luastring('__name'));
if (name.ttisstring())
return name.jsstring();
}
@@ -153,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, "perform bitwise operation on");
+ ldebug.luaG_opinterror(L, p1, p2, lua.to_luastring("perform bitwise operation on"));
}
default:
- ldebug.luaG_opinterror(L, p1, p2, "perform arithmetic on");
+ ldebug.luaG_opinterror(L, p1, p2, lua.to_luastring("perform arithmetic on"));
}
}
};
diff --git a/src/lua.js b/src/lua.js
index b1faccd..4710ded 100644
--- a/src/lua.js
+++ b/src/lua.js
@@ -240,4 +240,4 @@ module.exports.lua_Debug = lua_Debug;
module.exports.lua_upvalueindex = lua_upvalueindex;
module.exports.print_version = print_version;
module.exports.thread_status = thread_status;
-module.exports.to_luastring = to_luastring; \ No newline at end of file
+module.exports.to_luastring = to_luastring;
diff --git a/src/lutf8lib.js b/src/lutf8lib.js
index 053fb56..1df6096 100644
--- a/src/lutf8lib.js
+++ b/src/lutf8lib.js
@@ -91,8 +91,8 @@ const utflen = function(L) {
let posi = u_posrelat(lauxlib.luaL_optinteger(L, 2, 1), s.length);
let posj = u_posrelat(lauxlib.luaL_optinteger(L, 3, -1), s.length);
- lauxlib.luaL_argcheck(L, 1 <= posi && --posi <= s.length, 2, "initial position out of string");
- lauxlib.luaL_argcheck(L, --posj < s.length, 3, "final position out of string");
+ lauxlib.luaL_argcheck(L, 1 <= posi && --posi <= s.length, 2, lua.to_luastring("initial position out of string"));
+ lauxlib.luaL_argcheck(L, --posj < s.length, 3, lua.to_luastring("final position out of string"));
lapi.lua_pushinteger(L, s.slice(posi, posj + 1).length);
return 1;
@@ -100,7 +100,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, "value out of range");
+ lauxlib.luaL_argcheck(L, 0 <= code && code <= MAXUNICODE, arg, lua.to_luastring("value out of range"));
lapi.lua_pushstring(L, `${String.fromCharCode(code)}`);
};
@@ -134,14 +134,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, "position ot ouf range");
+ lauxlib.luaL_argcheck(L, 1 <= posi && --posi <= s.length, 3, lua.to_luastring("position ot ouf range"));
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, "initial position is a continuation byte");
+ lauxlib.luaL_error(L, lua.to_luastring("initial position is a continuation byte"));
if (n < 0) {
while (n < 0 && posi > 0) { /* move back */
@@ -179,19 +179,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, "out of range");
- lauxlib.luaL_argcheck(L, pose <= s.length, 3, "out of range");
+ 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"));
if (posi > pose) return 0; /* empty interval; return no values */
if (pose - posi >= Number.MAX_SAFE_INTEGER)
- return lauxlib.luaL_error(L, "string slice too long");
+ return lauxlib.luaL_error(L, lua.to_luastring("string slice too long"));
let n = (pose - posi) + 1;
- lauxlib.luaL_checkstack(L, n, "string slice too long");
+ lauxlib.luaL_checkstack(L, n, lua.to_luastring("string slice too long"));
n = 0;
for (s = s.slice(posi - 1); n < pose - posi;) {
let dec = utf8_decode(s);
if (dec === null)
- return lauxlib.luaL_error(L, "invalid UTF-8 code");
+ return lauxlib.luaL_error(L, lua.to_luastring("invalid UTF-8 code"));
s = dec.string;
let code = dec.code;
lapi.lua_pushinteger(L, code);
@@ -220,7 +220,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, "invalid UTF-8 code");
+ return lauxlib.luaL_error(L, lua.to_luastring("invalid UTF-8 code"));
lapi.lua_pushinteger(L, n + 1);
lapi.lua_pushinteger(L, code);
return 2;
@@ -253,4 +253,4 @@ const luaopen_utf8 = function(L) {
return 1;
};
-module.exports.luaopen_utf8 = luaopen_utf8; \ No newline at end of file
+module.exports.luaopen_utf8 = luaopen_utf8;