diff options
| -rw-r--r-- | src/lapi.js | 48 | ||||
| -rw-r--r-- | src/lauxlib.js | 74 | ||||
| -rw-r--r-- | src/lbaselib.js | 43 | ||||
| -rw-r--r-- | src/lcode.js | 6 | ||||
| -rw-r--r-- | src/lcorolib.js | 5 | ||||
| -rw-r--r-- | src/ldebug.js | 60 | ||||
| -rw-r--r-- | src/ldo.js | 8 | ||||
| -rw-r--r-- | src/ljstype.js | 12 | ||||
| -rw-r--r-- | src/llex.js | 125 | ||||
| -rw-r--r-- | src/lmathlib.js | 20 | ||||
| -rw-r--r-- | src/lobject.js | 84 | ||||
| -rw-r--r-- | src/lparser.js | 70 | ||||
| -rw-r--r-- | src/ltablib.js | 25 | ||||
| -rw-r--r-- | src/ltm.js | 90 | ||||
| -rw-r--r-- | src/lua.js | 2 | ||||
| -rw-r--r-- | src/lutf8lib.js | 24 | 
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; @@ -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; @@ -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"));          }      }  }; @@ -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; | 
