summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorBenoit Giannangeli <giann008@gmail.com>2017-03-29 14:39:57 +0200
committerBenoit Giannangeli <giann008@gmail.com>2017-03-30 09:57:53 +0200
commit456ab7b69f88859683c60cc2261e70d6dbadd8e8 (patch)
tree12baf4ae489e7afd4819ec94bc413c1c2a1db05d /src
parent2e5b595a2e04fe72555a565af4aae43560946473 (diff)
downloadfengari-456ab7b69f88859683c60cc2261e70d6dbadd8e8.tar.gz
fengari-456ab7b69f88859683c60cc2261e70d6dbadd8e8.tar.bz2
fengari-456ab7b69f88859683c60cc2261e70d6dbadd8e8.zip
8-bit string internally tests
Lexing/Parsing is done on byte rather than js strings
Diffstat (limited to 'src')
-rw-r--r--src/lapi.js4
-rw-r--r--src/lauxlib.js11
-rw-r--r--src/lbaselib.js4
-rw-r--r--src/lcode.js2
-rw-r--r--src/ldebug.js4
-rw-r--r--src/ldo.js10
-rw-r--r--src/linit.js5
-rw-r--r--src/llex.js113
-rw-r--r--src/lobject.js6
-rw-r--r--src/lparser.js124
-rw-r--r--src/lstrlib.js2
-rw-r--r--src/ltablib.js2
-rw-r--r--src/ltm.js2
-rw-r--r--src/lua.js2
-rw-r--r--src/lundump.js30
-rw-r--r--src/lutf8lib.js63
-rw-r--r--src/lvm.js16
17 files changed, 201 insertions, 199 deletions
diff --git a/src/lapi.js b/src/lapi.js
index 6e1471d..e7fbf4f 100644
--- a/src/lapi.js
+++ b/src/lapi.js
@@ -678,7 +678,7 @@ const lua_compare_ = function(L, o1, o2, op) {
};
const lua_stringtonumber = function(L, s) {
- let number = parseFloat(s);
+ let number = parseFloat(lobject.jsstring(s));
L.stack[L.top++] = new TValue(number % 1 !== 0 ? CT.LUA_TNUMFLT : CT.LUA_TNUMINT, number);
assert(L.top <= L.ci.top, "stack overflow");
return s.length;
@@ -980,6 +980,8 @@ module.exports.lua_toboolean = lua_toboolean;
module.exports.lua_todataview = lua_todataview;
module.exports.lua_tointeger = lua_tointeger;
module.exports.lua_tointegerx = lua_tointegerx;
+module.exports.lua_tojsstring = lua_tojsstring;
+module.exports.lua_toljsstring = lua_toljsstring;
module.exports.lua_tolstring = lua_tolstring;
module.exports.lua_tonumber = lua_tonumber;
module.exports.lua_topointer = lua_topointer;
diff --git a/src/lauxlib.js b/src/lauxlib.js
index f60bd8c..9813095 100644
--- a/src/lauxlib.js
+++ b/src/lauxlib.js
@@ -55,7 +55,7 @@ const findfield = function(L, objidx, level) {
const pushglobalfuncname = function(L, ar) {
let top = lapi.lua_gettop(L);
ldebug.lua_getinfo(L, 'f', ar); /* push function */
- lapi.lua_getfield(L, lua.LUA_REGISTRYINDEX, LUA_LOADED_TABLE);
+ lapi.lua_getfield(L, lua.LUA_REGISTRYINDEX, lua.to_luastring(LUA_LOADED_TABLE));
if (findfield(L, top + 1, 2)) {
let name = lapi.lua_tostring(L, -1);
if (name.jsstring().startsWith("_G.")) {
@@ -333,7 +333,7 @@ const luaL_tolstring = function(L, idx) {
** Leaves resulting module on the top.
*/
const luaL_requiref = function(L, modname, openf, glb) {
- luaL_getsubtable(L, lua.LUA_REGISTRYINDEX, LUA_LOADED_TABLE);
+ luaL_getsubtable(L, lua.LUA_REGISTRYINDEX, lua.to_luastring(LUA_LOADED_TABLE));
lapi.lua_getfield(L, -1, modname); /* LOADED[modname] */
if (!lapi.lua_toboolean(L, -1)) { /* package not already loaded? */
lapi.lua_pop(L, 1); /* remove field */
@@ -441,7 +441,7 @@ if (typeof require === "function") {
lf.pos += bytes;
}
if (bytes > 0)
- return lf.binary ? toDataView(lf.buff) : lf.buff;
+ return lf.binary ? toDataView(lf.buff) : lf.buff.slice(0, bytes);
else return null;
};
@@ -502,15 +502,16 @@ if (typeof require === "function") {
};
const luaL_loadfilex = function(L, filename, mode) {
+ let jsfilename = lobject.jsstring(filename);
let lf = new LoadF();
let fnameindex = lapi.lua_gettop(L) + 1; /* index of filename on the stack */
if (filename === null) {
lapi.lua_pushliteral(L, "=stdin");
lf.f = process.stdin.fd;
} else {
- lapi.lua_pushliteral(L, `@${filename}`);
+ lapi.lua_pushliteral(L, `@${jsfilename}`);
try {
- lf.f = fs.openSync(filename, "r");
+ lf.f = fs.openSync(jsfilename, "r");
} catch (e) {
return errfile(L, lua.to_luastring("open"), fnameindex, e);
}
diff --git a/src/lbaselib.js b/src/lbaselib.js
index 8420672..4d0fb9c 100644
--- a/src/lbaselib.js
+++ b/src/lbaselib.js
@@ -11,7 +11,7 @@ const TS = lua.thread_status;
const luaB_print = function(L) {
let n = lapi.lua_gettop(L); /* number of arguments */
- let str = "";
+ let str = [];
lapi.lua_getglobal(L, lua.to_luastring("tostring"));
for (let i = 1; i <= n; i++) {
@@ -201,7 +201,7 @@ const luaB_assert = function(L) {
const luaB_select = function(L) {
let n = lapi.lua_gettop(L);
- if (lapi.lua_type(L, 1) === CT.LUA_TSTRING && lapi.lua_tostring(L, 1) === "#") {
+ if (lapi.lua_type(L, 1) === CT.LUA_TSTRING && lapi.lua_tostring(L, 1)[0] === "#".charCodeAt(0)) {
lapi.lua_pushinteger(L, n - 1);
return 1;
} else {
diff --git a/src/lcode.js b/src/lcode.js
index 8b4a57c..752eedf 100644
--- a/src/lcode.js
+++ b/src/lcode.js
@@ -1231,7 +1231,7 @@ const luaK_setlist = function(fs, base, nelems, tostore) {
codeextraarg(fs, c);
}
else
- llex.luaX_syntaxerror(fs.ls, "constructor too long");
+ llex.luaX_syntaxerror(fs.ls, lua.to_luastring("constructor too long"));
fs.freereg = base + 1; /* free registers with list values */
};
diff --git a/src/ldebug.js b/src/ldebug.js
index 507e764..0fba4cb 100644
--- a/src/ldebug.js
+++ b/src/ldebug.js
@@ -431,7 +431,7 @@ const varinfo = function(L, o) {
kind = getobjname(ci.func.p, ci.pcOff, stkid - ci.u.l.base);
}
- return lua.to_luastring(kind ? ` (${lobject.jsstring(kind.funcname)} '${lobject.jsstring(kind.name)}')` : ``);
+ return lua.to_luastring(kind ? ` (${lobject.jsstring(kind.funcname)} '${kind.name.jsstring()}')` : ``);
};
const luaG_typeerror = function(L, o, op) {
@@ -457,7 +457,7 @@ const luaG_opinterror = function(L, p1, p2, msg) {
const luaG_ordererror = function(L, p1, p2) {
let t1 = ltm.luaT_objtypename(L, p1);
let t2 = ltm.luaT_objtypename(L, p2);
- if (t1 === t2)
+ if (t1.join() === t2.join())
luaG_runerror(L, lua.to_luastring(`attempt to compare two ${lobject.jsstring(t1)} values`));
else
luaG_runerror(L, lua.to_luastring(`attempt to compare ${lobject.jsstring(t1)} with ${lobject.jsstring(t2)}`));
diff --git a/src/ldo.js b/src/ldo.js
index 54d1ac0..6a74cad 100644
--- a/src/ldo.js
+++ b/src/ldo.js
@@ -519,8 +519,8 @@ class SParser {
}
const checkmode = function(L, mode, x) {
- 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}')`));
+ if (mode && mode.indexOf(x[0]) === -1) {
+ lapi.lua_pushstring(L, lua.to_luastring(`attempt to load a ${lobject.jsstring(x)} chunk (mode is '${lobject.jsstring(mode)}')`));
luaD_throw(L, TS.LUA_ERRSYNTAX);
}
};
@@ -528,11 +528,11 @@ const checkmode = function(L, mode, x) {
const f_parser = function(L, p) {
let cl;
let c = p.z.getc(); /* read first character */
- if (String.fromCharCode(c) === lua.LUA_SIGNATURE.charAt(0)) {
- checkmode(L, p.mode, "binary");
+ if (c === lua.LUA_SIGNATURE.charCodeAt(0)) {
+ checkmode(L, p.mode, lua.to_luastring("binary"));
cl = new BytecodeParser(L, p.z.buffer).luaU_undump();
} else {
- checkmode(L, p.mode, "text");
+ checkmode(L, p.mode, lua.to_luastring("text"));
cl = lparser.luaY_parser(L, p.z, p.buff, p.dyd, p.name, c);
}
diff --git a/src/linit.js b/src/linit.js
index 4d50f8b..3e9b1af 100644
--- a/src/linit.js
+++ b/src/linit.js
@@ -2,6 +2,7 @@
const assert = require('assert');
+const lua = require('./lua.js');
const lapi = require('./lapi.js');
const lauxlib = require('./lauxlib.js');
const lbaselib = require('./lbaselib.js');
@@ -24,9 +25,9 @@ const loadedlibs = {
const luaL_openlibs = function(L) {
/* "require" functions from 'loadedlibs' and set results to global table */
for (let lib in loadedlibs) {
- lauxlib.luaL_requiref(L, lib, loadedlibs[lib], 1);
+ lauxlib.luaL_requiref(L, lua.to_luastring(lib), loadedlibs[lib], 1);
lapi.lua_pop(L, 1); /* remove lib */
}
};
-module.exports.luaL_openlibs = luaL_openlibs; \ No newline at end of file
+module.exports.luaL_openlibs = luaL_openlibs;
diff --git a/src/llex.js b/src/llex.js
index 9b81cd7..e043c17 100644
--- a/src/llex.js
+++ b/src/llex.js
@@ -15,6 +15,12 @@ const TS = lua.thread_status;
const FIRST_RESERVED = 257;
+// To avoid charCodeAt everywhere
+const char = [];
+for (let i = 0; i < 127; i++)
+ char[String.fromCharCode(i)] = i;
+module.exports.char = char;
+
const RESERVED = {
/* terminal symbols denoted by reserved words */
TK_AND: FIRST_RESERVED,
@@ -157,7 +163,7 @@ const save = function(ls, c) {
const luaX_token2str = function(ls, token) {
if (typeof token === "string" || token < FIRST_RESERVED) { /* single-byte symbols? */
- return lua.to_luastring(`'${typeof token === "string" ? token : lobject.jsstring(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)? */
@@ -168,7 +174,7 @@ const luaX_token2str = function(ls, token) {
};
const currIsNewline = function(ls) {
- return ls.current === '\n'.charCodeAt(0) || ls.current === '\r'.charCodeAt(0);
+ return ls.current === char['\n'] || ls.current === char['\r'];
};
const next = function(ls) {
@@ -235,7 +241,7 @@ const check_next1 = function(ls, c) {
** saves it
*/
const check_next2 = function(ls, set) {
- if (ls.current === set.charAt(0).charCodeAt(0) || ls.current === set.charAt(1).charCodeAt(0)) {
+ if (ls.current === set[0].charCodeAt(0) || ls.current === set[1].charCodeAt(0)) {
save_and_next(ls);
return true;
}
@@ -248,7 +254,7 @@ const read_numeral = function(ls, seminfo) {
let first = ls.current;
assert(ljstype.lisdigit(ls.current));
save_and_next(ls);
- if (first === '0' && check_next2(ls, "xX")) /* hexadecimal? */
+ if (first === char['0'] && check_next2(ls, "xX")) /* hexadecimal? */
expo = "Pp";
for (;;) {
@@ -256,7 +262,7 @@ const read_numeral = function(ls, seminfo) {
check_next2(ls, "-+"); /* optional exponent sign */
if (ljstype.lisxdigit(ls.current))
save_and_next(ls);
- else if (ls.current === '.')
+ else if (ls.current === char['.'])
save_and_next(ls);
else break;
}
@@ -295,7 +301,6 @@ const lexerror = function(ls, msg, token) {
};
const luaX_syntaxerror = function(ls, msg) {
- msg = msg instanceof TValue ? msg.value : lua.to_luastring(msg);
lexerror(ls, msg, ls.t.token);
};
@@ -307,9 +312,9 @@ const luaX_syntaxerror = function(ls, msg) {
const skip_sep = function(ls) {
let count = 0;
let s = ls.current;
- assert(s === '['.charCodeAt(0) || s === ']'.charCodeAt(0));
+ assert(s === char['['] || s === char[']']);
save_and_next(ls);
- while (ls.current === '='.charCodeAt(0)) {
+ while (ls.current === char['=']) {
save_and_next(ls);
count++;
}
@@ -332,15 +337,15 @@ const read_long_string = function(ls, seminfo, sep) {
lexerror(ls, lua.to_luastring(msg), R.TK_EOS);
break;
}
- case ']'.charCodeAt(0): {
+ case char[']']: {
if (skip_sep(ls) === sep) {
save_and_next(ls); /* skip 2nd ']' */
skip = true;
}
break;
}
- case '\n'.charCodeAt(0): case '\r'.charCodeAt(0): {
- save(ls, '\n'.charCodeAt(0));
+ case char['\n']: case char['\r']: {
+ save(ls, char['\n']);
inclinenumber(ls);
if (!seminfo) {
ls.buff.n = 0;
@@ -386,7 +391,7 @@ 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 === '{'.charCodeAt(0), lua.to_luastring("missing '{'"));
+ esccheck(ls, ls.current === char['{'], lua.to_luastring("missing '{'"));
let r = gethexa(ls); /* must have at least one digit */
save_and_next(ls);
@@ -396,7 +401,7 @@ const readutf8desc = function(ls) {
esccheck(ls, r <= 0x10FFFF, lua.to_luastring("UTF-8 value too large"));
save_and_next(ls);
}
- esccheck(ls, ls.current === '}'.charCodeAt(0), lua.to_luastring("missing '}'"));
+ esccheck(ls, ls.current === char['}'], lua.to_luastring("missing '}'"));
next(ls); /* skip '}' */
ls.buff.n -= i; /* remove saved chars from buffer */
return r;
@@ -429,30 +434,30 @@ const read_string = function(ls, del, seminfo) {
case -1:
lexerror(ls, lua.to_luastring("unfinished string"), R.TK_EOS);
break;
- case '\n'.charCodeAt(0):
- case '\r'.charCodeAt(0):
+ case char['\n']:
+ case char['\r']:
lexerror(ls, lua.to_luastring("unfinished string"), R.TK_STRING);
break;
- case '\\'.charCodeAt(0): { /* escape sequences */
+ case char['\\']: { /* escape sequences */
save_and_next(ls); /* keep '\\' for error messages */
let will;
let c;
switch(ls.current) {
- 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'.charCodeAt(0): case '\r'.charCodeAt(0):
- inclinenumber(ls); c = '\n'; will = 'only_save'; break;
- case '\\'.charCodeAt(0): case '\"'.charCodeAt(0): case '\''.charCodeAt(0):
+ case char['a']: c = char['\a']; will = 'read_save'; break;
+ case char['b']: c = char['\b']; will = 'read_save'; break;
+ case char['f']: c = char['\f']; will = 'read_save'; break;
+ case char['n']: c = char['\n']; will = 'read_save'; break;
+ case char['r']: c = char['\r']; will = 'read_save'; break;
+ case char['t']: c = char['\t']; will = 'read_save'; break;
+ case char['v']: c = char['\v']; will = 'read_save'; break;
+ case char['x']: c = readhexaesc(ls); will = 'read_save'; break;
+ case char['u']: utf8esc(ls); will = 'no_save'; break;
+ case char['\n']: case char['\r']:
+ inclinenumber(ls); c = char['\n']; will = 'only_save'; break;
+ case char['\\']: case char['\"']: case char['\'']:
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 */
+ case char['z']: { /* zap following span of spaces */
ls.buff.n -= 1; /* remove '\\' */
next(ls); /* skip the 'z' */
while (ljstype.lisspace(ls.current)) {
@@ -500,20 +505,20 @@ const llex = function(ls, seminfo) {
for (;;) {
switch (ls.current) {
- case '\n'.charCodeAt(0): case '\r'.charCodeAt(0): { /* line breaks */
+ case char['\n']: case char['\r']: { /* line breaks */
inclinenumber(ls);
break;
}
- case ' '.charCodeAt(0): case '\f'.charCodeAt(0): case '\t'.charCodeAt(0): case '\v'.charCodeAt(0): { /* spaces */
+ case char[' ']: case char['\f']: case char['\t']: case char['\v']: { /* spaces */
next(ls);
break;
}
- case '-'.charCodeAt(0): { /* '-' or '--' (comment) */
+ case char['-']: { /* '-' or '--' (comment) */
next(ls);
- if (ls.current !== '-'.charCodeAt(0)) return '-';
+ if (ls.current !== char['-']) return char['-'];
/* else is a comment */
next(ls);
- if (ls.current === '['.charCodeAt(0)) { /* long comment? */
+ if (ls.current === char['[']) { /* long comment? */
let sep = skip_sep(ls);
ls.buff.n = 0; /* 'skip_sep' may dirty the buffer */
ls.buff.buffer = [];
@@ -530,63 +535,63 @@ const llex = function(ls, seminfo) {
next(ls); /* skip until end of line (or end of file) */
break;
}
- case '['.charCodeAt(0): { /* long string or simply '[' */
+ case char['[']: { /* 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, lua.to_luastring("invalid long string delimiter"), R.TK_STRING);
- return '[';
+ return char['['];
}
- case '='.charCodeAt(0): {
+ case char['=']: {
next(ls);
if (check_next1(ls, '=')) return R.TK_EQ;
- else return '=';
+ else return char['='];
}
- case '<'.charCodeAt(0): {
+ case char['<']: {
next(ls);
if (check_next1(ls, '=')) return R.TK_LE;
else if (check_next1(ls, '<')) return R.TK_SHL;
- else return '<';
+ else return char['<'];
}
- case '>'.charCodeAt(0): {
+ case char['>']: {
next(ls);
if (check_next1(ls, '=')) return R.TK_GE;
else if (check_next1(ls, '>')) return R.TK_SHR;
- else return '>';
+ else return char['>'];
}
- case '/'.charCodeAt(0): {
+ case char['/']: {
next(ls);
if (check_next1(ls, '/')) return R.TK_IDIV;
- else return '/';
+ else return char['/'];
}
- case '~'.charCodeAt(0): {
+ case char['~']: {
next(ls);
if (check_next1(ls, '=')) return R.TK_NE;
- else return '~';
+ else return char['~'];
}
- case ':'.charCodeAt(0): {
+ case char[':']: {
next(ls);
if (check_next1(ls, ':')) return R.TK_DBCOLON;
- else return ':';
+ else return char[':'];
}
- case '"'.charCodeAt(0): case '\''.charCodeAt(0): { /* short literal strings */
+ case char['"']: case char['\'']: { /* short literal strings */
read_string(ls, ls.current, seminfo);
return R.TK_STRING;
}
- case '.'.charCodeAt(0): { /* '.', '..', '...', or number */
+ case char['.']: { /* '.', '..', '...', or number */
save_and_next(ls);
if (check_next1(ls, '.')) {
if (check_next1(ls, '.'))
return R.TK_DOTS; /* '...' */
else return R.TK_CONCAT; /* '..' */
}
- else if (!ljstype.lisdigit(ls.current)) return '.';
+ else if (!ljstype.lisdigit(ls.current)) return char['.'];
else return read_numeral(ls, seminfo);
}
- case '0': case '1': case '2': case '3': case '4':
- case '5': case '6': case '7': case '8': case '9': {
+ case char['0']: case char['1']: case char['2']: case char['3']: case char['4']:
+ case char['5']: case char['6']: case char['7']: case char['8']: case char['9']: {
return read_numeral(ls, seminfo);
}
case -1: {
@@ -598,7 +603,7 @@ const llex = function(ls, seminfo) {
save_and_next(ls);
} while (ljstype.lislalnum(ls.current));
- let ts = new TValue(CT.LUA_TLNGSTR, lua.to_luastring(ls.buff.buffer.join('')));
+ let ts = new TValue(CT.LUA_TLNGSTR, ls.buff.buffer);
seminfo.ts = ts;
let kidx = luaX_tokens.slice(0, 22).indexOf(ts.jsstring());
if (kidx >= 0) /* reserved word? */
diff --git a/src/lobject.js b/src/lobject.js
index 812ac6a..e958975 100644
--- a/src/lobject.js
+++ b/src/lobject.js
@@ -132,6 +132,8 @@ const luaO_nilobject = new TValue(CT.LUA_TNIL, null);
module.exports.luaO_nilobject = luaO_nilobject;
const jsstring = function(value, from, to) {
+ assert(Array.isArray(value), "jsstring expect a array of bytes");
+
let u0, u1, u2, u3, u4, u5;
let idx = 0;
value = value.slice(from ? from : 0, to);
@@ -194,6 +196,8 @@ class Table extends TValue {
}
} else if (typeof key === "string") { // To avoid
key = lua.to_luastring(key).map(e => `${e}|`).join('');
+ } else if (Array.isArray(key)) {
+ key = key.map(e => `${e}|`).join('');
}
return key;
@@ -293,7 +297,7 @@ const luaO_chunkid = function(source, bufflen) {
else { /* truncate it */
out = out.concat(source.slice(1, bufflen));
}
- } else if (source.charAt(0) === '@') { /* file name */
+ } else if (source[0] === '@'.charCodeAt(0)) { /* file name */
if (l <= bufflen) /* small enough? */
out = source.slice(1);
else { /* add '...' before rest of name */
diff --git a/src/lparser.js b/src/lparser.js
index 01b9a08..249d51f 100644
--- a/src/lparser.js
+++ b/src/lparser.js
@@ -18,6 +18,8 @@ const Table = lobject.Table;
const UnOpr = lcode.UnOpr;
const UpVal = lfunc.UpVal;
+const char = llex.char;
+
const MAXVARS = 200;
const hasmultret = function(k) {
@@ -248,7 +250,7 @@ const new_localvar = function(ls, name) {
};
const new_localvarliteral = function(ls, name) {
- new_localvar(ls, new TValue(lua.CT.LUA_TLNGSTR, lua.to_luastring(name)));
+ new_localvar(ls, new TValue(lua.CT.LUA_TLNGSTR, name));
};
const getlocvar = function(fs, i) {
@@ -273,7 +275,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.join() === name.join())
+ if (up[i].name.value.join() === name.value.join())
return i;
}
return -1; /* not found */
@@ -291,7 +293,7 @@ const newupvalue = function(fs, name, v) {
const searchvar = function(fs, n) {
for (let i = fs.nactvar - 1; i >= 0; i--) {
- if (n.join() === getlocvar(fs, i).varname.join())
+ if (n.value.join() === getlocvar(fs, i).varname.value.join())
return i;
}
@@ -611,7 +613,7 @@ const yindex = function(ls, v) {
llex.luaX_next(ls); /* skip the '[' */
expr(ls, v);
lcode.luaK_exp2val(ls.fs, v);
- checknext(ls, ']');
+ checknext(ls, char[']']);
};
/*
@@ -643,7 +645,7 @@ const recfield = function(ls, cc) {
} else /* ls->t.token === '[' */
yindex(ls, key);
cc.nh++;
- checknext(ls, '=');
+ checknext(ls, char['=']);
let rkkey = lcode.luaK_exp2RK(fs, key);
expr(ls, val);
lcode.luaK_codeABC(fs, OpCodesI.OP_SETTABLE, cc.t.u.info, rkkey, lcode.luaK_exp2RK(fs, val));
@@ -685,13 +687,13 @@ const field = function(ls, cc) {
/* field -> listfield | recfield */
switch (ls.t.token) {
case R.TK_NAME: { /* may be 'listfield' or 'recfield' */
- if (llex.luaX_lookahead(ls) !== '=') /* expression? */
+ if (llex.luaX_lookahead(ls) !== char['=']) /* expression? */
listfield(ls, cc);
else
recfield(ls, cc);
break;
}
- case '[': {
+ case char['[']: {
recfield(ls, cc);
break;
}
@@ -714,14 +716,14 @@ const constructor = function(ls, t) {
init_exp(t, expkind.VRELOCABLE, pc);
init_exp(cc.v, expkind.VVOID, 0); /* no value (yet) */
lcode.luaK_exp2nextreg(ls.fs, t); /* fix it at stack top */
- checknext(ls, '{');
+ checknext(ls, char['{']);
do {
assert(cc.v.k === expkind.VVOID || cc.tostore > 0);
- if (ls.t.token === '}') break;
+ if (ls.t.token === char['}']) break;
closelistfield(fs, cc);
field(ls, cc);
- } while (testnext(ls, ',') || testnext(ls, ';'));
- check_match(ls, '}', '{', line);
+ } while (testnext(ls, char[',']) || testnext(ls, char[';']));
+ check_match(ls, char['}'], char['{'], line);
lastlistfield(fs, cc);
lopcode.SETARG_B(fs.f.code[pc], lobject.luaO_int2fb(cc.na)); /* set initial array size */
lopcode.SETARG_C(fs.f.code[pc], lobject.luaO_int2fb(cc.nh)); /* set initial table size */
@@ -735,7 +737,7 @@ const parlist = function(ls) {
let f = fs.f;
let nparams = 0;
f.is_vararg = 0;
- if (ls.t.token !== ')') { /* is 'parlist' not empty? */
+ if (ls.t.token !== char[')']) { /* is 'parlist' not empty? */
do {
switch (ls.t.token) {
case R.TK_NAME: { /* param -> NAME */
@@ -750,7 +752,7 @@ const parlist = function(ls) {
}
default: llex.luaX_syntaxerror(ls, lua.to_luastring("<name> or '...' expected"));
}
- } while(!f.is_vararg && testnext(ls, ','));
+ } while(!f.is_vararg && testnext(ls, char[',']));
}
adjustlocalvars(ls, nparams);
f.numparams = fs.nactvar;
@@ -764,13 +766,13 @@ const body = function(ls, e, ismethod, line) {
new_fs.f = addprototype(ls);
new_fs.f.linedefined = line;
open_func(ls, new_fs, bl);
- checknext(ls, '(');
+ checknext(ls, char['(']);
if (ismethod) {
new_localvarliteral(ls, lua.to_luastring("self")); /* create 'self' parameter */
adjustlocalvars(ls, 1);
}
parlist(ls);
- checknext(ls, ')');
+ checknext(ls, char[')']);
statlist(ls);
new_fs.f.lastlinedefined = ls.linenumber;
check_match(ls, R.TK_END, R.TK_FUNCTION, line);
@@ -782,7 +784,7 @@ const explist = function(ls, v) {
/* explist -> expr { ',' expr } */
let n = 1; /* at least one expression */
expr(ls, v);
- while (testnext(ls, ',')) {
+ while (testnext(ls, char[','])) {
lcode.luaK_exp2nextreg(ls.fs, v);
expr(ls, v);
n++;
@@ -794,18 +796,18 @@ const funcargs = function(ls, f, line) {
let fs = ls.fs;
let args = new expdesc();
switch (ls.t.token) {
- case '(': { /* funcargs -> '(' [ explist ] ')' */
+ case char['(']: { /* funcargs -> '(' [ explist ] ')' */
llex.luaX_next(ls);
- if (ls.t.token === ')') /* arg list is empty? */
+ if (ls.t.token === char[')']) /* arg list is empty? */
args.k = expkind.VVOID;
else {
explist(ls, args);
lcode.luaK_setmultret(fs, args);
}
- check_match(ls, ')', '(', line);
+ check_match(ls, char[')'], char['('], line);
break;
}
- case '{': { /* funcargs -> constructor */
+ case char['{']: { /* funcargs -> constructor */
constructor(ls, args);
break;
}
@@ -842,11 +844,11 @@ const funcargs = function(ls, f, line) {
const primaryexp = function(ls, v) {
/* primaryexp -> NAME | '(' expr ')' */
switch (ls.t.token) {
- case '(': {
+ case char['(']: {
let line = ls.linenumber;
llex.luaX_next(ls);
expr(ls, v);
- check_match(ls, ')', '(', line);
+ check_match(ls, char[')'], char['('], line);
lcode.luaK_dischargevars(ls.fs, v);
return;
}
@@ -868,18 +870,18 @@ const suffixedexp = function(ls, v) {
primaryexp(ls, v);
for (;;) {
switch (ls.t.token) {
- case '.': { /* fieldsel */
+ case char['.']: { /* fieldsel */
fieldsel(ls, v);
break;
}
- case '[': { /* '[' exp1 ']' */
+ case char['[']: { /* '[' exp1 ']' */
let key = new expdesc();
lcode.luaK_exp2anyregup(fs, v);
yindex(ls, key);
lcode.luaK_indexed(fs, v, key);
break;
}
- case ':': { /* ':' NAME funcargs */
+ case char[':']: { /* ':' NAME funcargs */
let key = new expdesc();
llex.luaX_next(ls);
checkname(ls, key);
@@ -887,7 +889,7 @@ const suffixedexp = function(ls, v) {
funcargs(ls, v, line);
break;
}
- case '(': case R.TK_STRING: case '{': { /* funcargs */
+ case char['(']: case R.TK_STRING: case char['{']: { /* funcargs */
lcode.luaK_exp2nextreg(fs, v);
funcargs(ls, v, line);
break;
@@ -933,7 +935,7 @@ const simpleexp = function(ls, v) {
init_exp(v, expkind.VVARARG, lcode.luaK_codeABC(fs, OpCodesI.OP_VARARG, 0, 1, 0));
break;
}
- case '{': { /* constructor */
+ case char['{']: { /* constructor */
constructor(ls, v);
return;
}
@@ -952,34 +954,34 @@ const simpleexp = function(ls, v) {
const getunopr = function(op) {
switch (op) {
- case R.TK_NOT: return UnOpr.OPR_NOT;
- case '-': return UnOpr.OPR_MINUS;
- case '~': return UnOpr.OPR_BNOT;
- case '#': return UnOpr.OPR_LEN;
- default: return UnOpr.OPR_NOUNOPR;
+ case R.TK_NOT: return UnOpr.OPR_NOT;
+ case char['-']: return UnOpr.OPR_MINUS;
+ case char['~']: return UnOpr.OPR_BNOT;
+ case char['#']: return UnOpr.OPR_LEN;
+ default: return UnOpr.OPR_NOUNOPR;
}
};
const getbinopr = function(op) {
switch (op) {
- case '+': return BinOpr.OPR_ADD;
- case '-': return BinOpr.OPR_SUB;
- case '*': return BinOpr.OPR_MUL;
- case '%': return BinOpr.OPR_MOD;
- case '^': return BinOpr.OPR_POW;
- case '/': return BinOpr.OPR_DIV;
+ case char['+']: return BinOpr.OPR_ADD;
+ case char['-']: return BinOpr.OPR_SUB;
+ case char['*']: return BinOpr.OPR_MUL;
+ case char['%']: return BinOpr.OPR_MOD;
+ case char['^']: return BinOpr.OPR_POW;
+ case char['/']: return BinOpr.OPR_DIV;
case R.TK_IDIV: return BinOpr.OPR_IDIV;
- case '&': return BinOpr.OPR_BAND;
- case '|': return BinOpr.OPR_BOR;
- case '~': return BinOpr.OPR_BXOR;
+ case char['&']: return BinOpr.OPR_BAND;
+ case char['|']: return BinOpr.OPR_BOR;
+ case char['~']: return BinOpr.OPR_BXOR;
case R.TK_SHL: return BinOpr.OPR_SHL;
case R.TK_SHR: return BinOpr.OPR_SHR;
case R.TK_CONCAT: return BinOpr.OPR_CONCAT;
case R.TK_NE: return BinOpr.OPR_NE;
case R.TK_EQ: return BinOpr.OPR_EQ;
- case '<': return BinOpr.OPR_LT;
+ case char['<']: return BinOpr.OPR_LT;
case R.TK_LE: return BinOpr.OPR_LE;
- case '>': return BinOpr.OPR_GT;
+ case char['>']: return BinOpr.OPR_GT;
case R.TK_GE: return BinOpr.OPR_GE;
case R.TK_AND: return BinOpr.OPR_AND;
case R.TK_OR: return BinOpr.OPR_OR;
@@ -1102,7 +1104,7 @@ 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"));
- if (testnext(ls, ',')) { /* assignment -> ',' suffixedexp assignment */
+ if (testnext(ls, char[','])) { /* assignment -> ',' suffixedexp assignment */
let nv = new LHS_assign();
nv.prev = lh;
suffixedexp(ls, nv.v);
@@ -1111,7 +1113,7 @@ const assignment = function(ls, lh, nvars) {
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, '=');
+ checknext(ls, char['=']);
let nexps = explist(ls, e);
if (nexps !== nvars)
adjust_assign(ls, nvars, nexps, e);
@@ -1158,7 +1160,7 @@ const checkrepeated = function(fs, ll, label) {
/* skip no-op statements */
const skipnoopstat = function(ls) {
- while (ls.t.token === ';' || ls.t.token === R.TK_DBCOLON)
+ while (ls.t.token === char[';'] || ls.t.token === R.TK_DBCOLON)
statement(ls);
};
@@ -1256,11 +1258,11 @@ const fornum = function(ls, varname, line) {
new_localvarliteral(ls, lua.to_luastring("(for limit)"));
new_localvarliteral(ls, lua.to_luastring("(for step)"));
new_localvar(ls, varname);
- checknext(ls, '=');
+ checknext(ls, char['=']);
exp1(ls); /* initial value */
- checknext(ls, ',');
+ checknext(ls, char[',']);
exp1(ls); /* limit */
- if (testnext(ls, ','))
+ if (testnext(ls, char[',']))
exp1(ls); /* optional step */
else { /* default step = 1 */
lcode.luaK_codek(fs, fs.freereg, lcode.luaK_intK(fs, 1));
@@ -1281,7 +1283,7 @@ const forlist = function(ls, indexname) {
new_localvarliteral(ls, lua.to_luastring("(for control)"));
/* create declared variables */
new_localvar(ls, indexname);
- while (testnext(ls, ',')) {
+ while (testnext(ls, char[','])) {
new_localvar(ls, str_checkname(ls));
nvars++;
}
@@ -1300,8 +1302,8 @@ const forstat = function(ls, line) {
llex.luaX_next(ls); /* skip 'for' */
let varname = str_checkname(ls); /* first variable name */
switch (ls.t.token) {
- case '=': fornum(ls, varname, line); break;
- case ',': case R.TK_IN: forlist(ls, varname); break;
+ 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"));
}
check_match(ls, R.TK_END, R.TK_FOR, line);
@@ -1373,8 +1375,8 @@ const localstat = function(ls) {
do {
new_localvar(ls, str_checkname(ls));
nvars++;
- } while (testnext(ls, ','));
- if (testnext(ls, '='))
+ } while (testnext(ls, char[',']));
+ if (testnext(ls, char['=']))
nexps = explist(ls, e);
else {
e.k = expkind.VVOID;
@@ -1388,9 +1390,9 @@ const funcname = function(ls, v) {
/* funcname -> NAME {fieldsel} [':' NAME] */
let ismethod = 0;
singlevar(ls, v);
- while (ls.t.token === '.')
+ while (ls.t.token === char['.'])
fieldsel(ls, v);
- if (ls.t.token === ':') {
+ if (ls.t.token === char[':']) {
ismethod = 1;
fieldsel(ls, v);
}
@@ -1413,7 +1415,7 @@ const exprstat= function(ls) {
let fs = ls.fs;
let v = new LHS_assign();
suffixedexp(ls, v.v);
- if (ls.t.token === '=' || ls.t.token === ',') { /* stat . assignment ? */
+ if (ls.t.token === char['='] || ls.t.token === char[',']) { /* stat . assignment ? */
v.prev = null;
assignment(ls, v, 1);
}
@@ -1428,7 +1430,7 @@ const retstat = function(ls) {
let fs = ls.fs;
let e = new expdesc();
let first, nret; /* registers with returned values */
- if (block_follow(ls, 1) || ls.t.token === ';')
+ if (block_follow(ls, 1) || ls.t.token === char[';'])
first = nret = 0; /* return no values */
else {
nret = explist(ls, e); /* optional return values */
@@ -1451,14 +1453,14 @@ const retstat = function(ls) {
}
}
lcode.luaK_ret(fs, first, nret);
- testnext(ls, ';'); /* skip optional semicolon */
+ testnext(ls, char[';']); /* skip optional semicolon */
};
const statement = function(ls) {
let line = ls.linenumber; /* may be needed for error messages */
enterlevel(ls);
switch(ls.t.token) {
- case ';': { /* stat -> ';' (empty statement) */
+ case char[';']: { /* stat -> ';' (empty statement) */
llex.luaX_next(ls); /* skip ';' */
break;
}
@@ -1547,7 +1549,7 @@ const luaY_parser = function(L, z, buff, dyd, name, firstchar) {
lexstate.h = new Table(); /* create table for scanner */
L.stack[L.top++] = lexstate.h;
funcstate.f = cl.p = new Proto(L);
- funcstate.f.source = new TValue(lua.CT.LUA_TLNGSTR, lua.to_luastring(name));
+ funcstate.f.source = new TValue(lua.CT.LUA_TLNGSTR, name);
lexstate.buff = buff;
lexstate.dyd = dyd;
dyd.actvar.n = dyd.gt.n = dyd.label.n = 0;
diff --git a/src/lstrlib.js b/src/lstrlib.js
index 471187b..e163485 100644
--- a/src/lstrlib.js
+++ b/src/lstrlib.js
@@ -1372,7 +1372,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, "__index"); /* metatable.__index = string */
+ lapi.lua_setfield(L, -2, lua.to_luastring("__index")); /* metatable.__index = string */
lapi.lua_pop(L, 1); /* pop metatable */
};
diff --git a/src/ltablib.js b/src/ltablib.js
index c45f7e5..eaaf24d 100644
--- a/src/ltablib.js
+++ b/src/ltablib.js
@@ -163,7 +163,7 @@ const pack = function(L) {
for (let i = n; i >= 1; i--) /* assign elements */
lapi.lua_seti(L, 1, i);
lapi.lua_pushinteger(L, n);
- lapi.lua_setfield(L, 1, "n"); /* t.n = number of elements */
+ lapi.lua_setfield(L, 1, ["n".charCodeAt(0)]); /* t.n = number of elements */
return 1; /* return table */
};
diff --git a/src/ltm.js b/src/ltm.js
index d2df961..4a90f6d 100644
--- a/src/ltm.js
+++ b/src/ltm.js
@@ -53,7 +53,7 @@ const luaT_typenames_ = [
"userdata",
"thread",
"proto" /* this last case is used for tests only */
-];
+].map(e => lua.to_luastring(e));
const ttypename = function(t) {
return luaT_typenames_[t + 1];
diff --git a/src/lua.js b/src/lua.js
index 4710ded..85d4b64 100644
--- a/src/lua.js
+++ b/src/lua.js
@@ -135,6 +135,8 @@ class lua_Debug {
}
const to_luastring = function(str, maxBytesToWrite) {
+ assert(typeof str === "string", "to_luastring expect a js string");
+
maxBytesToWrite = maxBytesToWrite !== undefined ? maxBytesToWrite : Number.MAX_SAFE_INTEGER;
let outU8Array = [];
diff --git a/src/lundump.js b/src/lundump.js
index 7452c43..36fd674 100644
--- a/src/lundump.js
+++ b/src/lundump.js
@@ -5,10 +5,8 @@ const fs = require('fs');
const assert = require('assert');
const lua = require('./lua.js');
-const LClosure = require('./lobject.js').LClosure;
-const TValue = require('./lobject.js').TValue;
+const lobject = require('./lobject.js');
const Proto = require('./lfunc.js').Proto;
-const constant_types = require('./lua.js').constant_types;
const OpCodes = require('./lopcodes.js');
const LUAI_MAXSHORTLEN = 40;
@@ -167,20 +165,20 @@ class BytecodeParser {
let t = this.readByte();
switch (t) {
- case constant_types.LUA_TNIL:
- f.k.push(new TValue(constant_types.LUA_TNIL, null));
+ case lua.CT.LUA_TNIL:
+ f.k.push(new lobject.TValue(lua.CT.LUA_TNIL, null));
break;
- case constant_types.LUA_TBOOLEAN:
- f.k.push(new TValue(constant_types.LUA_TBOOLEAN, this.readByte()));
+ case lua.CT.LUA_TBOOLEAN:
+ f.k.push(new lobject.TValue(lua.CT.LUA_TBOOLEAN, this.readByte()));
break;
- case constant_types.LUA_TNUMFLT:
- f.k.push(new TValue(constant_types.LUA_TNUMFLT, this.readNumber()));
+ case lua.CT.LUA_TNUMFLT:
+ f.k.push(new lobject.TValue(lua.CT.LUA_TNUMFLT, this.readNumber()));
break;
- case constant_types.LUA_TNUMINT:
- f.k.push(new TValue(constant_types.LUA_TNUMINT, this.readInteger()));
+ case lua.CT.LUA_TNUMINT:
+ f.k.push(new lobject.TValue(lua.CT.LUA_TNUMINT, this.readInteger()));
break;
- case constant_types.LUA_TSHRSTR:
- case constant_types.LUA_TLNGSTR:
+ case lua.CT.LUA_TSHRSTR:
+ case lua.CT.LUA_TLNGSTR:
f.k.push(this.L.l_G.intern(this.read8bitString()));
break;
default:
@@ -206,7 +204,7 @@ class BytecodeParser {
n = this.readInt();
for (let i = 0; i < n; i++) {
f.locvars[i] = {
- varname: this.readString(),
+ varname: new lobject.TValue(lua.CT.LUA_TLNGSTR, lua.to_luastring(this.readString())),
startpc: this.readInt(),
endpc: this.readInt()
};
@@ -264,7 +262,7 @@ class BytecodeParser {
luaU_undump() {
this.checkHeader();
- let cl = new LClosure(this.L, this.readByte());
+ let cl = new lobject.LClosure(this.L, this.readByte());
this.L.stack[this.L.top] = cl;
this.L.top++;
@@ -280,4 +278,4 @@ class BytecodeParser {
}
-module.exports = BytecodeParser; \ No newline at end of file
+module.exports = BytecodeParser;
diff --git a/src/lutf8lib.js b/src/lutf8lib.js
index 1df6096..ef9739f 100644
--- a/src/lutf8lib.js
+++ b/src/lutf8lib.js
@@ -58,50 +58,37 @@ const utf8_decode = function(s, val) {
** range [i,j], or nil + current position if 's' is not well formed in
** that interval
*/
-// const utflen = function(L) {
-// let n = 0;
-// let s = lauxlib.luaL_checkstring(L, 1);
-// s = L.stack[lapi.index2addr_(L, 1)].value;
-// let len = s.length;
-// let posi = u_posrelat(lauxlib.luaL_optinteger(L, 2, 1), len);
-// let posj = u_posrelat(lauxlib.luaL_optinteger(L, 3, -1), len);
-//
-// lauxlib.luaL_argcheck(L, 1 <= posi && --posi <= len, 2, "initial position out of string");
-// lauxlib.luaL_argcheck(L, --posj < len, 3, "final position out of string");
-//
-// while (posi <= posj) {
-// let dec = utf8_decode(s[posi]);
-// let s1 = dec ? dec.string : null;
-// if (s1 === null) {
-// /* conversion error? */
-// lapi.lua_pushnil(L); /* return nil ... */
-// lapi.lua_pushinteger(L, posi + 1); /* ... and current position */
-// return 2;
-// }
-// posi = dec.pos;
-// n++;
-// }
-// lapi.lua_pushinteger(L, n);
-// return 1;
-// };
-
-// Shorter JSesque solution but doesn't take invalid UTF-8 sequence (but how can we get one ?)
const utflen = function(L) {
+ let n = 0;
let s = lauxlib.luaL_checkstring(L, 1);
- 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, 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);
+ s = L.stack[lapi.index2addr_(L, 1)].value;
+ let len = s.length;
+ let posi = u_posrelat(lauxlib.luaL_optinteger(L, 2, 1), len);
+ let posj = u_posrelat(lauxlib.luaL_optinteger(L, 3, -1), len);
+
+ lauxlib.luaL_argcheck(L, 1 <= posi && --posi <= len, 2, "initial position out of string");
+ lauxlib.luaL_argcheck(L, --posj < len, 3, "final position out of string");
+
+ while (posi <= posj) {
+ let dec = utf8_decode(s.slice(posi));
+ let s1 = dec ? dec.string : null;
+ if (s1 === null) {
+ /* conversion error? */
+ lapi.lua_pushnil(L); /* return nil ... */
+ lapi.lua_pushinteger(L, posi + 1); /* ... and current position */
+ return 2;
+ }
+ posi = s.length - s1.length;
+ n++;
+ }
+ lapi.lua_pushinteger(L, n);
return 1;
};
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"));
- lapi.lua_pushstring(L, `${String.fromCharCode(code)}`);
+ lapi.lua_pushstring(L, lua.to_luastring(String.fromCharCode(code)));
};
/*
@@ -248,8 +235,8 @@ const UTF8PATT = "[\0-\x7F\xC2-\xF4][\x80-\xBF]*";
const luaopen_utf8 = function(L) {
lauxlib.luaL_newlib(L, funcs);
- lapi.lua_pushstring(L, UTF8PATT);
- lapi.lua_setfield(L, -2, "charpattern");
+ lapi.lua_pushstring(L, lua.to_luastring(UTF8PATT));
+ lapi.lua_setfield(L, -2, lua.to_luastring("charpattern"));
return 1;
};
diff --git a/src/lvm.js b/src/lvm.js
index 53e1584..6f49ad3 100644
--- a/src/lvm.js
+++ b/src/lvm.js
@@ -592,19 +592,19 @@ const luaV_execute = function(L) {
let nstep = tonumber(pstep);
if (nlimit === false)
- ldebug.luaG_runerror(L, "'for' limit must be a number");
+ ldebug.luaG_runerror(L, lua.to_luastring("'for' limit must be a number"));
plimit.type = CT.LUA_TNUMFLT;
plimit.value = nlimit;
if (nstep === false)
- ldebug.luaG_runerror(L, "'for' step must be a number");
+ ldebug.luaG_runerror(L, lua.to_luastring("'for' step must be a number"));
pstep.type = CT.LUA_TNUMFLT;
pstep.value = nstep;
if (ninit === false)
- ldebug.luaG_runerror(L, "'for' initial value must be a number");
+ ldebug.luaG_runerror(L, lua.to_luastring("'for' initial value must be a number"));
init.type = CT.LUA_TNUMFLT;
init.value = ninit - nstep;
@@ -977,7 +977,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, "get length of");
+ ldebug.luaG_typeerror(L, rb, lua.to_luastring("get length of"));
break;
}
}
@@ -1042,7 +1042,7 @@ const gettable = function(L, table, key, ra, recur) {
recur = recur ? recur : 0;
if (recur >= MAXTAGRECUR)
- ldebug.luaG_runerror(L, "'__index' chain too long; possible loop");
+ ldebug.luaG_runerror(L, lua.to_luastring("'__index' chain too long; possible loop"));
if (table.ttistable()) {
let element = table.__index(table, key);
@@ -1063,7 +1063,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, 'index');
+ ldebug.luaG_typeerror(L, t, lua.to_luastring('index'));
} else { /* 't' is a table */
assert(slot.ttisnil());
tm = ltm.luaT_gettmbyobj(L, t, ltm.TMS.TM_INDEX); // TODO: fasttm
@@ -1085,7 +1085,7 @@ const settable = function(L, table, key, v, recur) {
recur = recur ? recur : 0;
if (recur >= MAXTAGRECUR)
- ldebug.luaG_runerror(L, "'__newindex' chain too long; possible loop");
+ ldebug.luaG_runerror(L, lua.to_luastring("'__newindex' chain too long; possible loop"));
if (table.ttistable()) {
let element = table.__index(table, key);
@@ -1112,7 +1112,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, 'index');
+ ldebug.luaG_typeerror(L, t, lua.to_luastring('index'));
}
if (tm.ttisfunction()) {