From 7e886ba08a443d9653c3033901ae8c83108d3701 Mon Sep 17 00:00:00 2001 From: daurnimator Date: Mon, 22 May 2017 21:17:26 +1000 Subject: src/lapi.js: Simplify+optimise lua_rotate --- src/lapi.js | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'src/lapi.js') diff --git a/src/lapi.js b/src/lapi.js index ca5a8a0..f06fc65 100644 --- a/src/lapi.js +++ b/src/lapi.js @@ -181,14 +181,14 @@ const reverse = function(L, from, to) { ** rotate x n === BA. But BA === (A^r . B^r)^r. */ const lua_rotate = function(L, idx, n) { - let t = L.stack[L.top - 1]; - let p = index2addr(L, idx); + let t = L.top - 1; let pIdx = index2addr_(L, idx); + let p = L.stack[pIdx]; - assert(p !== lobject.luaO_nilobject && idx > defs.LUA_REGISTRYINDEX, "index not in the stack"); - assert((n >= 0 ? n : -n) <= (L.top - idx), "invalid 'n'"); + assert(isvalid(p) && idx > defs.LUA_REGISTRYINDEX, "index not in the stack"); + assert((n >= 0 ? n : -n) <= (t - pIdx + 1), "invalid 'n'"); - let m = n >= 0 ? L.top - 1 - n : pIdx - n - 1; /* end of prefix */ + let m = n >= 0 ? t - n : pIdx - n - 1; /* end of prefix */ reverse(L, pIdx, m); reverse(L, m + 1, L.top - 1); -- cgit v1.2.3-70-g09d2 From e4c9580d20924a0db1ff7ed0d30da9b71dbb5066 Mon Sep 17 00:00:00 2001 From: daurnimator Date: Mon, 22 May 2017 21:21:50 +1000 Subject: Introduce lvm.cvt2str In future this could be configurable --- src/lapi.js | 16 +++++++++++----- src/ldebug.js | 2 +- src/lvm.js | 9 +++++++-- 3 files changed, 19 insertions(+), 8 deletions(-) (limited to 'src/lapi.js') diff --git a/src/lapi.js b/src/lapi.js index f06fc65..f7ef82e 100644 --- a/src/lapi.js +++ b/src/lapi.js @@ -667,8 +667,11 @@ const lua_toboolean = function(L, idx) { const lua_tolstring = function(L, idx) { let o = index2addr(L, idx); - if ((!o.ttisstring() && !o.ttisnumber())) - return null; + if (!o.ttisstring()) { + if (!lvm.cvt2str(o)) { /* not convertible? */ + return null; + } + } return o.ttisstring() ? o.svalue() : defs.to_luastring(`${o.value}`); }; @@ -678,8 +681,11 @@ const lua_tostring = lua_tolstring; const lua_toljsstring = function(L, idx) { let o = index2addr(L, idx); - if ((!o.ttisstring() && !o.ttisnumber())) - return null; + if (!o.ttisstring()) { + if (!lvm.cvt2str(o)) { /* not convertible? */ + return null; + } + } return o.ttisstring() ? o.jsstring() : `${o.value}`; }; @@ -872,7 +878,7 @@ const lua_isnumber = function(L, idx) { const lua_isstring = function(L, idx) { let o = index2addr(L, idx); - return o.ttisstring() || o.ttisnumber(); + return o.ttisstring() || lvm.cvt2str(o); }; const lua_isuserdata = function(L, idx) { diff --git a/src/ldebug.js b/src/ldebug.js index 1862e55..74a04db 100644 --- a/src/ldebug.js +++ b/src/ldebug.js @@ -546,7 +546,7 @@ const luaG_typeerror = function(L, o, op) { }; const luaG_concaterror = function(L, p1, p2) { - if (p1.ttisstring() || p1.ttisnumber()) p1 = p2; + if (p1.ttisstring() || lvm.cvt2str(p1)) p1 = p2; luaG_typeerror(L, p1, defs.to_luastring('concatenate', true)); }; diff --git a/src/lvm.js b/src/lvm.js index 4804cde..bd370a6 100644 --- a/src/lvm.js +++ b/src/lvm.js @@ -958,12 +958,16 @@ const luaV_shiftl = function(x, y) { } }; +const cvt2str = function(o) { + return o.ttisnumber(); +}; + const tostring = function(L, i) { let o = L.stack[i]; if (o.ttisstring()) return true; - if (o.ttisnumber() && !isNaN(o.value)) { + if (cvt2str(o) && !isNaN(o.value)) { L.stack[i] = new lobject.TValue(CT.LUA_TLNGSTR, lstring.luaS_bless(L, defs.to_luastring(`${o.value}`))); return true; } @@ -985,7 +989,7 @@ const luaV_concat = function(L, total) { let top = L.top; let n = 2; /* number of elements handled in this pass (at least 2) */ - if (!(L.stack[top-2].ttisstring() || L.stack[top-2].ttisnumber()) || !tostring(L, top - 1)) { + if (!(L.stack[top-2].ttisstring() || cvt2str(L.stack[top-2])) || !tostring(L, top - 1)) { ltm.luaT_trybinTM(L, L.stack[top-2], L.stack[top-1], top-2, ltm.TMS.TM_CONCAT); delete L.stack[top - 1]; } else if (isemptystr(L.stack[top-1])) { @@ -1090,6 +1094,7 @@ module.exports.RB = RB; module.exports.RC = RC; module.exports.RKB = RKB; module.exports.RKC = RKC; +module.exports.cvt2str = cvt2str; module.exports.dojump = dojump; module.exports.donextjump = donextjump; module.exports.forlimit = forlimit; -- cgit v1.2.3-70-g09d2 From 128ae8cc451126ee7201de7efb6cc0c39fb1a2b4 Mon Sep 17 00:00:00 2001 From: daurnimator Date: Mon, 22 May 2017 23:19:22 +1000 Subject: Introduce luaO_tostring --- src/lapi.js | 8 ++++---- src/lobject.js | 17 ++++++++++++++++- src/lvm.js | 4 ++-- 3 files changed, 22 insertions(+), 7 deletions(-) (limited to 'src/lapi.js') diff --git a/src/lapi.js b/src/lapi.js index f7ef82e..efc59aa 100644 --- a/src/lapi.js +++ b/src/lapi.js @@ -671,9 +671,9 @@ const lua_tolstring = function(L, idx) { if (!lvm.cvt2str(o)) { /* not convertible? */ return null; } + o = lobject.luaO_tostring(L, o); } - - return o.ttisstring() ? o.svalue() : defs.to_luastring(`${o.value}`); + return o.svalue(); }; const lua_tostring = lua_tolstring; @@ -685,9 +685,9 @@ const lua_toljsstring = function(L, idx) { if (!lvm.cvt2str(o)) { /* not convertible? */ return null; } + o = lobject.luaO_tostring(L, o); } - - return o.ttisstring() ? o.jsstring() : `${o.value}`; + return o.jsstring(); }; const lua_tojsstring = lua_toljsstring; diff --git a/src/lobject.js b/src/lobject.js index 41c3a84..e7b716e 100644 --- a/src/lobject.js +++ b/src/lobject.js @@ -448,6 +448,18 @@ const luaO_utf8esc = function(x) { }; }; +/* this currently returns new TValue instead of modifying */ +const luaO_tostring = function(L, obj) { + let buff; + if (obj.ttisinteger()) + buff = defs.to_luastring(luaconf.lua_integer2str(obj.value)); + else { + let str = luaconf.lua_number2str(obj.value); + buff = defs.to_luastring(str); + } + return new TValue(CT.LUA_TLNGSTR, lstring.luaS_bless(L, buff)); +}; + const pushstr = function(L, str) { L.stack[L.top++] = new TValue(CT.LUA_TLNGSTR, lstring.luaS_new(L, str)); }; @@ -476,8 +488,10 @@ const luaO_pushvfstring = function(L, fmt, argp) { break; case char['d']: case char['I']: + L.stack[L.top++] = luaO_tostring(L, new TValue(CT.LUA_TNUMINT, argp[a++])); + break; case char['f']: - pushstr(L, defs.to_luastring(''+argp[a++])); + L.stack[L.top++] = luaO_tostring(L, new TValue(CT.LUA_TNUMFLT, argp[a++])); break; // case char['p']: case char['U']: @@ -616,6 +630,7 @@ module.exports.luaO_int2fb = luaO_int2fb; module.exports.luaO_pushfstring = luaO_pushfstring; module.exports.luaO_pushvfstring = luaO_pushvfstring; module.exports.luaO_str2num = luaO_str2num; +module.exports.luaO_tostring = luaO_tostring; module.exports.luaO_utf8desc = luaO_utf8desc; module.exports.luaO_utf8esc = luaO_utf8esc; module.exports.numarith = numarith; diff --git a/src/lvm.js b/src/lvm.js index 83feb9b..0081376 100644 --- a/src/lvm.js +++ b/src/lvm.js @@ -973,8 +973,8 @@ const tostring = function(L, i) { if (o.ttisstring()) return true; - if (cvt2str(o) && !isNaN(o.value)) { - L.stack[i] = new lobject.TValue(CT.LUA_TLNGSTR, lstring.luaS_bless(L, defs.to_luastring(`${o.value}`))); + if (cvt2str(o)) { + L.stack[i] = lobject.luaO_tostring(L, o); return true; } -- cgit v1.2.3-70-g09d2 From f83115f90039666b9dc19c3ee9972a3aa98d28e7 Mon Sep 17 00:00:00 2001 From: daurnimator Date: Mon, 22 May 2017 23:34:25 +1000 Subject: src/lapi.js: Throw errors when attempting to use pseudo-index with index2addr_ --- src/lapi.js | 14 +++----------- 1 file changed, 3 insertions(+), 11 deletions(-) (limited to 'src/lapi.js') diff --git a/src/lapi.js b/src/lapi.js index efc59aa..8e0c491 100644 --- a/src/lapi.js +++ b/src/lapi.js @@ -66,7 +66,7 @@ const index2addr = function(L, idx) { } }; -// Like index2addr but returns the index on stack +// Like index2addr but returns the index on stack; doesn't allow pseudo indices const index2addr_ = function(L, idx) { let ci = L.ci; if (idx > 0) { @@ -77,16 +77,8 @@ const index2addr_ = function(L, idx) { } else if (idx > defs.LUA_REGISTRYINDEX) { assert(idx !== 0 && -idx <= L.top, "invalid index"); return L.top + idx; - } else if (idx === defs.LUA_REGISTRYINDEX) { - return null; - } else { /* upvalues */ - idx = defs.LUA_REGISTRYINDEX - idx; - assert(idx <= MAXUPVAL + 1, "upvalue index too large"); - if (ci.func.ttislcf()) /* light C function? */ - return null; /* it has no upvalues */ - else { - return idx <= ci.func.nupvalues ? idx - 1 : null; - } + } else { /* registry or upvalue */ + throw Error("attempt to use pseudo-index"); } }; -- cgit v1.2.3-70-g09d2