summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/lapi.js17
-rw-r--r--src/lcode.js47
-rw-r--r--src/lobject.js53
-rw-r--r--src/lua.js1
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;
diff --git a/src/lua.js b/src/lua.js
index ae93e58..2e86336 100644
--- a/src/lua.js
+++ b/src/lua.js
@@ -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;