From 1cab03b0f0675a86617a7de1749ef3d519a4c334 Mon Sep 17 00:00:00 2001 From: daurnimator Date: Fri, 5 May 2017 12:50:18 +1000 Subject: Don't wrap lexer/parser strings in a TValue Fixes issue where internal TValues get exposed via lua_Debug structure --- src/lapi.js | 4 ++-- src/lcode.js | 3 ++- src/ldblib.js | 4 ++-- src/ldebug.js | 4 +--- src/ldump.js | 4 ++-- src/llex.js | 25 ++++++++----------------- src/lparser.js | 52 ++++++++++++++++++++++++++++------------------------ src/lundump.js | 2 +- 8 files changed, 46 insertions(+), 52 deletions(-) diff --git a/src/lapi.js b/src/lapi.js index 4516fcc..78ae004 100644 --- a/src/lapi.js +++ b/src/lapi.js @@ -527,7 +527,7 @@ const lua_getupvalue = function(L, funcindex, n) { L.stack[L.top++] = new TValue(val.type, val.value); - return name.value; + return name; } return null; }; @@ -545,7 +545,7 @@ const lua_setupvalue = function(L, funcindex, n) { val.type = L.stack[L.top].type; val.value = L.stack[L.top].value; - return name.value; + return name; } return null; }; diff --git a/src/lcode.js b/src/lcode.js index 690d07c..c20c978 100644 --- a/src/lcode.js +++ b/src/lcode.js @@ -501,7 +501,8 @@ const addk = function(fs, key, v) { ** Add a string to list of constants and return its index. */ const luaK_stringK = function(fs, s) { - return addk(fs, s, s); /* use string itself as key */ + let o = new TValue(CT.LUA_TLNGSTR, s); + return addk(fs, o, o); /* use string itself as key */ }; diff --git a/src/ldblib.js b/src/ldblib.js index ce0e19d..fbf31e8 100644 --- a/src/ldblib.js +++ b/src/ldblib.js @@ -181,7 +181,7 @@ const db_getlocal = function(L) { let name = lua.lua_getlocal(L1, ar, nvar); if (name) { lua.lua_xmove(L1, L, 1); /* move local value */ - lua.lua_pushstring(L, name.value); /* push name */ + lua.lua_pushstring(L, name); /* push name */ lua.lua_rotate(L, -2, 1); /* re-order */ return 2; } @@ -208,7 +208,7 @@ const db_setlocal = function(L) { let name = lua.lua_setlocal(L1, ar, nvar); if (name === null) lua.lua_pop(L1, 1); /* pop value (if not popped by 'lua_setlocal') */ - lua.lua_pushstring(L, name.value); + lua.lua_pushstring(L, name); return 1; }; diff --git a/src/ldebug.js b/src/ldebug.js index ef0f719..b411e0a 100644 --- a/src/ldebug.js +++ b/src/ldebug.js @@ -78,7 +78,6 @@ const lua_getstack = function(L, level, ar) { return status; }; -// TODO: returns TValue or String array ? const upvalname = function(p, uv) { assert(uv < p.upvalues.length); let s = p.upvalues[uv].name; @@ -396,7 +395,6 @@ const getobjname = function(p, lastpc, reg) { let k = i.C; /* key index */ let t = i.B; /* table index */ let vn = op === 'OP_GETTABLE' ? lfunc.luaF_getlocalname(p, t + 1, pc) : upvalname(p, t); - vn = vn ? vn.jsstring() : null; r.name = kname(p, pc, k).name; r.funcname = vn && vn === "_ENV" ? defs.to_luastring("global", true) : defs.to_luastring("field", true); return r; @@ -536,7 +534,7 @@ const varinfo = function(L, o) { kind = getobjname(ci.func.value.p, ci.pcOff, stkid - ci.u.l.base); } - return defs.to_luastring(kind ? ` (${defs.to_jsstring(kind.funcname)} '${defs.to_jsstring(kind.name.value ? kind.name.value : kind.name)}')` : ``); + return kind ? lobject.luaO_pushfstring(L, defs.to_luastring(" (%s '%s')", true), kind.funcname, kind.name) : defs.to_luastring("", true); }; const luaG_typeerror = function(L, o, op) { diff --git a/src/ldump.js b/src/ldump.js index e26a214..1298a03 100644 --- a/src/ldump.js +++ b/src/ldump.js @@ -136,14 +136,14 @@ const DumpDebug = function(f, D) { n = D.strip ? 0 : f.locvars.length; DumpInt(n, D); for (let i = 0; i < n; i++) { - DumpString(f.locvars[i].varname.value, D); + DumpString(f.locvars[i].varname, D); DumpInt(f.locvars[i].startpc, D); DumpInt(f.locvars[i].endpc, D); } n = D.strip ? 0 : f.upvalues.length; DumpInt(n, D); for (let i = 0; i < n; i++) - DumpString(f.upvalues[i].name.value, D); + DumpString(f.upvalues[i].name, D); }; const DumpFunction = function(f, psource, D) { diff --git a/src/llex.js b/src/llex.js index ee7f993..8375ac6 100644 --- a/src/llex.js +++ b/src/llex.js @@ -3,14 +3,11 @@ const assert = require('assert'); const defs = require('./defs.js'); -const lapi = require('./lapi.js'); const ldebug = require('./ldebug.js'); const ldo = require('./ldo.js'); const ljstype = require('./ljstype'); const lobject = require('./lobject'); const llimit = require('./llimit.js'); -const TValue = lobject.TValue; -const CT = defs.constant_types; const TS = defs.thread_status; const char = defs.char; @@ -162,8 +159,8 @@ const save = function(ls, c) { }; const luaX_token2str = function(ls, token) { - if (typeof token === "string" || token < FIRST_RESERVED) { /* single-byte symbols? */ - return defs.to_luastring(`'${typeof token === "string" ? token : defs.to_jsstring([token])}'`); + if (token < FIRST_RESERVED) { /* single-byte symbols? */ + return lobject.luaO_pushfstring(ls.L, defs.to_luastring("'%c'", true), token); } else { let s = luaX_tokens[token - FIRST_RESERVED]; if (token < R.TK_EOS) /* fixed format (symbols and reserved words)? */ @@ -224,7 +221,7 @@ const luaX_setinput = function(L, ls, z, source, firstchar) { ls.linenumber = 1; ls.lastline = 1; ls.source = source; - ls.envn = L.l_G.intern(defs.to_luastring("_ENV", true)); + ls.envn = defs.to_luastring("_ENV", true); }; const check_next1 = function(ls, c) { @@ -296,7 +293,7 @@ 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, defs.to_luastring(`${msg instanceof TValue ? msg.jsstring() : msg} near ${defs.to_jsstring(txtToken(ls, token))}`)); + lobject.luaO_pushfstring(ls.L, defs.to_luastring("%s near %s"), msg, txtToken(ls, token)); ldo.luaD_throw(ls.L, TS.LUA_ERRSYNTAX); }; @@ -361,10 +358,7 @@ const read_long_string = function(ls, seminfo, sep) { } if (seminfo) - seminfo.ts = new TValue( - CT.LUA_TLNGSTR, - ls.buff.buffer.slice(2 + sep, 2 + sep - 2 * (2 + sep)) - ); + seminfo.ts = ls.buff.buffer.slice(2 + sep, 2 + sep - 2 * (2 + sep)); }; const esccheck = function(ls, c, msg) { @@ -489,10 +483,7 @@ const read_string = function(ls, del, seminfo) { } save_and_next(ls); /* skip delimiter */ - seminfo.ts = new TValue( - CT.LUA_TLNGSTR, - ls.buff.buffer.slice(1, ls.buff.n-1) - ); + seminfo.ts = ls.buff.buffer.slice(1, ls.buff.n-1); }; const isreserved = function(w) { @@ -604,9 +595,9 @@ const llex = function(ls, seminfo) { save_and_next(ls); } while (ljstype.lislalnum(ls.current)); - let ts = new TValue(CT.LUA_TLNGSTR, ls.buff.buffer); + let ts = ls.buff.buffer; seminfo.ts = ts; - let kidx = luaX_tokens.slice(0, 22).indexOf(ts.jsstring()); + let kidx = luaX_tokens.slice(0, 22).indexOf(defs.to_jsstring(ts)); if (kidx >= 0) /* reserved word? */ return kidx + FIRST_RESERVED; else diff --git a/src/lparser.js b/src/lparser.js index d27f67a..7b39701 100644 --- a/src/lparser.js +++ b/src/lparser.js @@ -160,7 +160,7 @@ const semerror = function(ls, msg) { }; const error_expected = function(ls, token) { - llex.luaX_syntaxerror(ls, defs.to_luastring(`${defs.to_jsstring(llex.luaX_token2str(ls, token))} expected`)); + llex.luaX_syntaxerror(ls, lobject.luaO_pushfstring(ls.L, defs.to_luastring("%s expected", true), llex.luaX_token2str(ls, token))); }; const errorlimit = function(fs, limit, what) { @@ -204,8 +204,9 @@ const check_match = function(ls, what, who, where) { if (where === ls.linenumber) error_expected(ls, what); else - llex.luaX_syntaxerror(ls, - defs.to_luastring(`${defs.to_jsstring(llex.luaX_token2str(ls, what))} expected (to close ${defs.to_jsstring(llex.luaX_token2str(ls, who))} at line ${where}`)); + llex.luaX_syntaxerror(ls, lobject.luaO_pushfstring(ls.L, + defs.to_luastring("%s expected (to close %s at line %d)"), + llex.luaX_token2str(ls, what), llex.luaX_token2str(ls, who), where)); } }; @@ -249,7 +250,7 @@ const new_localvar = function(ls, name) { }; const new_localvarliteral = function(ls, name) { - new_localvar(ls, new TValue(defs.CT.LUA_TLNGSTR, name)); + new_localvar(ls, defs.to_luastring(name, true)); }; const getlocvar = function(fs, i) { @@ -274,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.value.join() === name.value.join()) + if (up[i].name.join() === name.join()) return i; } return -1; /* not found */ @@ -292,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.value.join() === getlocvar(fs, i).varname.value.join()) + if (n.join() === getlocvar(fs, i).varname.join()) return i; } @@ -384,10 +385,12 @@ const closegoto = function(ls, g, label) { let fs = ls.fs; let gl = ls.dyd.gt; let gt = gl.arr[g]; - assert(gt.name.value.join() === label.name.value.join()); + assert(gt.name.join() === label.name.join()); if (gt.nactvar < label.nactvar) { let vname = getlocvar(fs, gt.nactvar).varname; - semerror(ls, defs.to_luastring(` at line ${gt.line} jumps into the scope of local '${vname.jsstring()}'`)); + let msg = lobject.luaO_pushfstring(ls.L, defs.to_luastring(" at line %d jumps into the scope of local '%s'"), + gt.name, gt.line, vname); + semerror(ls, msg); } lcode.luaK_patchlist(fs, gt.pc, label.pc); /* remove goto from pending list */ @@ -406,7 +409,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.value.join() === gt.name.value.join()) { /* correct label? */ + if (lb.name.join() === gt.name.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 */ @@ -435,7 +438,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.value.join() === lb.name.value.join()) + if (gl.arr[i].name.join() === lb.name.join()) closegoto(ls, i, lb); else i++; @@ -480,7 +483,7 @@ const enterblock = function(fs, bl, isloop) { ** create a label named 'break' to resolve break statements */ const breaklabel = function(ls) { - let n = new TValue(defs.CT.LUA_TLNGSTR, defs.to_luastring("break", true)); + let n = defs.to_luastring("break", true); let l = newlabelentry(ls, ls.dyd.label, n, 0, ls.fs.pc); findgotos(ls, ls.dyd.label.arr[l]); }; @@ -490,10 +493,11 @@ const breaklabel = function(ls) { ** message when label name is a reserved word (which can only be 'break') */ const undefgoto = function(ls, gt) { - const msg = llex.isreserved(gt.name.value) - ? `<${gt.name.jsstring()}> at line ${gt.line} not inside a loop` - : `no visible label '${gt.name.jsstring()}' for at line ${gt.line}`; - semerror(ls, defs.to_luastring(msg)); + let msg = llex.isreserved(gt.name) + ? "<%s> at line %d not inside a loop" + : "no visible label '%s' for at line %d"; + msg = lobject.luaO_pushfstring(ls.L, defs.to_luastring(msg), gt.name, gt.line); + semerror(ls, msg); }; /* @@ -767,7 +771,7 @@ const body = function(ls, e, ismethod, line) { open_func(ls, new_fs, bl); checknext(ls, char['(']); if (ismethod) { - new_localvarliteral(ls, defs.to_luastring("self", true)); /* create 'self' parameter */ + new_localvarliteral(ls, "self"); /* create 'self' parameter */ adjustlocalvars(ls, 1); } parlist(ls); @@ -1142,7 +1146,7 @@ const gotostat = function(ls, pc) { label = str_checkname(ls); else { llex.luaX_next(ls); /* skip break */ - label = new TValue(defs.CT.LUA_TLNGSTR, defs.to_luastring("break", true)); + label = defs.to_luastring("break", true); } let g = newlabelentry(ls, ls.dyd.gt, label, line, pc); findlabel(ls, g); /* close it if label already defined */ @@ -1151,7 +1155,7 @@ 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.value.join() === ll.arr[i].name.value.join()) { + if (label.join() === ll.arr[i].name.join()) { semerror(fs.ls, defs.to_luastring(`label '${label.jsstring()}' already defined on line ${ll.arr[i].line}`)); } } @@ -1253,9 +1257,9 @@ const fornum = function(ls, varname, line) { /* fornum -> NAME = exp1,exp1[,exp1] forbody */ let fs = ls.fs; let base = fs.freereg; - new_localvarliteral(ls, defs.to_luastring("(for index)", true)); - new_localvarliteral(ls, defs.to_luastring("(for limit)", true)); - new_localvarliteral(ls, defs.to_luastring("(for step)", true)); + new_localvarliteral(ls, "(for index)"); + new_localvarliteral(ls, "(for limit)"); + new_localvarliteral(ls, "(for step)"); new_localvar(ls, varname); checknext(ls, char['=']); exp1(ls); /* initial value */ @@ -1277,9 +1281,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, defs.to_luastring("(for generator)", true)); - new_localvarliteral(ls, defs.to_luastring("(for state)", true)); - new_localvarliteral(ls, defs.to_luastring("(for control)", true)); + new_localvarliteral(ls, "(for generator)"); + new_localvarliteral(ls, "(for state)"); + new_localvarliteral(ls, "(for control)"); /* create declared variables */ new_localvar(ls, indexname); while (testnext(ls, char[','])) { diff --git a/src/lundump.js b/src/lundump.js index 1d2d079..5d158bd 100644 --- a/src/lundump.js +++ b/src/lundump.js @@ -204,7 +204,7 @@ class BytecodeParser { n = this.readInt(); for (let i = 0; i < n; i++) { f.locvars[i] = { - varname: new lobject.TValue(defs.CT.LUA_TLNGSTR, defs.to_luastring(this.readString())), + varname: defs.to_luastring(this.readString()), startpc: this.readInt(), endpc: this.readInt() }; -- cgit v1.2.3-70-g09d2