diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/lapi.js | 17 | ||||
-rw-r--r-- | src/lcode.js | 47 | ||||
-rw-r--r-- | src/lobject.js | 53 | ||||
-rw-r--r-- | src/lua.js | 1 |
4 files changed, 67 insertions, 51 deletions
diff --git a/src/lapi.js b/src/lapi.js index 9fc1cc7..4d2f288 100644 --- a/src/lapi.js +++ b/src/lapi.js @@ -857,6 +857,18 @@ const lua_rawequal = function(L, index1, index2) { return isvalid(o1) && isvalid(o2) ? lvm.luaV_equalobj(null, o1, o2) : 0; // TODO: isvalid ? }; +const lua_arith = function(L, op) { + if (op !== defs.LUA_OPUNM && op !== defs.LUA_OPBNOT) + assert(2 < L.top - L.ci.funcOff, "not enough elements in the stack"); /* all other operations expect two operands */ + else { /* for unary operations, add fake 2nd operand */ + assert(1 < L.top - L.ci.funcOff, "not enough elements in the stack"); + L.stack[L.top++] = L.stack[L.top - 1]; + } + /* first operand at top - 2, second at top - 1; result go to top - 2 */ + lobject.luaO_arith(L, op, L.stack[L.top - 2], L.stack[L.top - 1], L.stack[L.top - 2]); + L.op--; /* remove second operand */ +}; + /* ** 'load' and 'call' functions (run Lua code) */ @@ -1069,6 +1081,7 @@ const lua_getextraspace = function () { module.exports.index2addr = index2addr; module.exports.index2addr_ = index2addr_; module.exports.lua_absindex = lua_absindex; +module.exports.lua_arith = lua_arith; module.exports.lua_atpanic = lua_atpanic; module.exports.lua_call = lua_call; module.exports.lua_callk = lua_callk; @@ -1115,6 +1128,7 @@ module.exports.lua_pop = lua_pop; module.exports.lua_pushboolean = lua_pushboolean; module.exports.lua_pushcclosure = lua_pushcclosure; module.exports.lua_pushcfunction = lua_pushcfunction; +module.exports.lua_pushfstring = lua_pushfstring; module.exports.lua_pushglobaltable = lua_pushglobaltable; module.exports.lua_pushinteger = lua_pushinteger; module.exports.lua_pushjsclosure = lua_pushjsclosure; @@ -1125,10 +1139,9 @@ module.exports.lua_pushlstring = lua_pushlstring; module.exports.lua_pushnil = lua_pushnil; module.exports.lua_pushnumber = lua_pushnumber; module.exports.lua_pushstring = lua_pushstring; -module.exports.lua_pushfstring = lua_pushfstring; -module.exports.lua_pushvfstring = lua_pushvfstring; module.exports.lua_pushthread = lua_pushthread; module.exports.lua_pushvalue = lua_pushvalue; +module.exports.lua_pushvfstring = lua_pushvfstring; module.exports.lua_rawequal = lua_rawequal; module.exports.lua_rawget = lua_rawget; module.exports.lua_rawgeti = lua_rawgeti; diff --git a/src/lcode.js b/src/lcode.js index 2887e6d..34d21c1 100644 --- a/src/lcode.js +++ b/src/lcode.js @@ -16,51 +16,6 @@ const CT = defs.CT; const OpCodesI = lopcodes.OpCodesI; const TValue = lobject.TValue; -const luaO_arith = function(L, op, p1, p2, res) { - switch (op) { - case defs.LUA_OPBAND: case defs.LUA_OPBOR: case defs.LUA_OPBXOR: - case defs.LUA_OPSHL: case defs.LUA_OPSHR: - case defs.LUA_OPBNOT: { /* operate only on integers */ - let i1 = lvm.tointeger(p1); - let i2 = lvm.tointeger(p2); - if (i1 !== false && i2 !== false) { - res.type = CT.LUA_TNUMINT; - res.value = lobject.intarith(L, op, i1, i2); - return; - } - else break; /* go to the end */ - } - case defs.LUA_OPDIV: case defs.LUA_OPPOW: { /* operate only on floats */ - let n1 = lvm.tonumber(p1); - let n2 = lvm.tonumber(p2); - if (n1 !== false && n2 !== false) { - res.type = CT.LUA_TNUMFLT; - res.value = lobject.numarith(L, op, n1, n2); - return; - } - else break; /* go to the end */ - } - default: { /* other operations */ - let n1 = lvm.tonumber(p1); - let n2 = lvm.tonumber(p2); - if (p1.ttisinteger() && p2.ttisinteger()) { - res.type = CT.LUA_TNUMINT; - res.value = lobject.intarith(L, op, p1.value, p2.value); - return; - } - else if (n1 !== false && n2 !== false) { - res.type = CT.LUA_TNUMFLT; - res.value = lobject.numarith(L, op, n1, n2); - return; - } - else break; /* go to the end */ - } - } - /* could not perform raw operation; try metamethod */ - assert(L !== null); /* should not fail when folding (compile time) */ - ltm.luaT_trybinTM(L, p1, p2, res, (op - defs.LUA_OPADD) + ltm.TMS.TM_ADD); -}; - /* Maximum number of registers in a Lua function (must fit in 8 bits) */ const MAXREGS = 255; @@ -1016,7 +971,7 @@ const constfolding = function(fs, op, e1, e2) { let res = new TValue(); if (!tonumeral(e1, v1) || !tonumeral(e2, v2) || !validop(op, v1, v2)) return 0; /* non-numeric operands or not safe to fold */ - luaO_arith(fs.ls.L, op, v1, v2, res); /* does operation */ + lobject.luaO_arith(fs.ls.L, op, v1, v2, res); /* does operation */ if (res.ttisinteger()) { e1.k = ek.VKINT; e1.u.ival = res.value; diff --git a/src/lobject.js b/src/lobject.js index f926e85..9790d23 100644 --- a/src/lobject.js +++ b/src/lobject.js @@ -10,6 +10,7 @@ const lstring = require('./lstring.js'); const luaconf = require('./luaconf.js'); const lvm = require('./lvm.js'); const llimit = require('./llimit.js'); +const ltm = require('./ltm.js'); const CT = defs.constant_types; const char = defs.char; @@ -547,14 +548,60 @@ const numarith = function(L, op, v1, v2) { } }; -module.exports.LUA_TPROTO = LUA_TPROTO; -module.exports.LUA_TDEADKEY = LUA_TDEADKEY; +const luaO_arith = function(L, op, p1, p2, res) { + switch (op) { + case defs.LUA_OPBAND: case defs.LUA_OPBOR: case defs.LUA_OPBXOR: + case defs.LUA_OPSHL: case defs.LUA_OPSHR: + case defs.LUA_OPBNOT: { /* operate only on integers */ + let i1 = lvm.tointeger(p1); + let i2 = lvm.tointeger(p2); + if (i1 !== false && i2 !== false) { + res.type = CT.LUA_TNUMINT; + res.value = intarith(L, op, i1, i2); + return; + } + else break; /* go to the end */ + } + case defs.LUA_OPDIV: case defs.LUA_OPPOW: { /* operate only on floats */ + let n1 = lvm.tonumber(p1); + let n2 = lvm.tonumber(p2); + if (n1 !== false && n2 !== false) { + res.type = CT.LUA_TNUMFLT; + res.value = numarith(L, op, n1, n2); + return; + } + else break; /* go to the end */ + } + default: { /* other operations */ + let n1 = lvm.tonumber(p1); + let n2 = lvm.tonumber(p2); + if (p1.ttisinteger() && p2.ttisinteger()) { + res.type = CT.LUA_TNUMINT; + res.value = intarith(L, op, p1.value, p2.value); + return; + } + else if (n1 !== false && n2 !== false) { + res.type = CT.LUA_TNUMFLT; + res.value = numarith(L, op, n1, n2); + return; + } + else break; /* go to the end */ + } + } + /* could not perform raw operation; try metamethod */ + assert(L !== null); /* should not fail when folding (compile time) */ + ltm.luaT_trybinTM(L, p1, p2, res, (op - defs.LUA_OPADD) + ltm.TMS.TM_ADD); +}; + + module.exports.CClosure = CClosure; module.exports.LClosure = LClosure; +module.exports.LUA_TDEADKEY = LUA_TDEADKEY; +module.exports.LUA_TPROTO = LUA_TPROTO; module.exports.LocVar = LocVar; module.exports.TValue = TValue; module.exports.UTF8BUFFSZ = UTF8BUFFSZ; -module.exports.intarith = intarith; +module.exports.luaO_arith = luaO_arith; module.exports.luaO_chunkid = luaO_chunkid; module.exports.luaO_hexavalue = luaO_hexavalue; module.exports.luaO_int2fb = luaO_int2fb; @@ -173,6 +173,7 @@ module.exports.lua_rawset = lapi.lua_rawset; module.exports.lua_rawsetp = lapi.lua_rawsetp; module.exports.lua_remove = lapi.lua_remove; module.exports.lua_replace = lapi.lua_replace; +module.exports.lua_arith = lapi.lua_arith; module.exports.lua_resume = ldo.lua_resume; module.exports.lua_rotate = lapi.lua_rotate; module.exports.lua_setfield = lapi.lua_setfield; |