aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authordaurnimator <quae@daurnimator.com>2017-05-21 19:07:37 +1000
committerdaurnimator <quae@daurnimator.com>2017-05-21 20:20:18 +1000
commit9bd802f91c02b7f9ed1241e7be1266a429ba0cf9 (patch)
treeff58c241d8d4c7d73593ab409b878d7fee743ca9
parentc09ab00b85677881f0ca0424b27ad14521e4a770 (diff)
downloadfengari-9bd802f91c02b7f9ed1241e7be1266a429ba0cf9.tar.gz
fengari-9bd802f91c02b7f9ed1241e7be1266a429ba0cf9.tar.bz2
fengari-9bd802f91c02b7f9ed1241e7be1266a429ba0cf9.zip
Centralise integer mod and div operations to luaV_mod and luaV_div
-rw-r--r--src/lobject.js4
-rw-r--r--src/lvm.js19
2 files changed, 19 insertions, 4 deletions
diff --git a/src/lobject.js b/src/lobject.js
index 6d86852..0898a15 100644
--- a/src/lobject.js
+++ b/src/lobject.js
@@ -522,8 +522,8 @@ const intarith = function(L, op, v1, v2) {
case defs.LUA_OPADD: return (v1 + v2)|0;
case defs.LUA_OPSUB: return (v1 - v2)|0;
case defs.LUA_OPMUL: return (v1 * v2)|0;
- case defs.LUA_OPMOD: return (v1 - Math.floor(v1 / v2) * v2)|0; // % semantic on negative numbers is different in js
- case defs.LUA_OPIDIV: return Math.floor(v1 / v2)|0;
+ case defs.LUA_OPMOD: return lvm.luaV_mod(L, v1, v2);
+ case defs.LUA_OPIDIV: return lvm.luaV_div(L, v1, v2);
case defs.LUA_OPBAND: return (v1 & v2);
case defs.LUA_OPBOR: return (v1 | v2);
case defs.LUA_OPBXOR: return (v1 ^ v2);
diff --git a/src/lvm.js b/src/lvm.js
index 6eea8f3..dfb2ed5 100644
--- a/src/lvm.js
+++ b/src/lvm.js
@@ -257,7 +257,7 @@ const luaV_execute = function(L) {
let numberop2 = tonumber(op2);
if (op1.ttisinteger() && op2.ttisinteger()) {
- L.stack[ra] = new lobject.TValue(CT.LUA_TNUMINT, (op1.value - Math.floor(op1.value / op2.value) * op2.value)|0);
+ L.stack[ra] = new lobject.TValue(CT.LUA_TNUMINT, luaV_mod(L, op1.value, op2.value));
} else if (numberop1 !== false && numberop2 !== false) {
L.stack[ra] = new lobject.TValue(CT.LUA_TNUMFLT, llimit.luai_nummod(L, numberop1, numberop2));
} else {
@@ -298,7 +298,7 @@ const luaV_execute = function(L) {
let numberop2 = tonumber(op2);
if (op1.ttisinteger() && op2.ttisinteger()) {
- L.stack[ra] = new lobject.TValue(CT.LUA_TNUMINT, Math.floor(op1.value / op2.value)|0);
+ L.stack[ra] = new lobject.TValue(CT.LUA_TNUMINT, luaV_div(L, op1.value, op2.value));
} else if (numberop1 !== false && numberop2 !== false) {
L.stack[ra] = new lobject.TValue(CT.LUA_TNUMFLT, Math.floor(numberop1 / numberop2));
} else {
@@ -932,6 +932,19 @@ const luaV_objlen = function(L, ra, rb) {
ltm.luaT_callTM(L, tm, rb, rb, ra, 1);
};
+const luaV_div = function(L, m, n) {
+ if (n === 0)
+ ldebug.luaG_runerror(L, defs.to_luastring("attempt to divide by zero"));
+ return Math.floor(m / n)|0;
+};
+
+// % semantic on negative numbers is different in js
+const luaV_mod = function(L, m, n) {
+ if (n === 0)
+ ldebug.luaG_runerror(L, defs.to_luastring("attempt to perform 'n%%0'"));
+ return (m - Math.floor(m / n) * n)|0;
+};
+
const NBITS = 32;
const luaV_shiftl = function(x, y) {
@@ -1111,12 +1124,14 @@ module.exports.forlimit = forlimit;
module.exports.gettable = gettable;
module.exports.l_strcmp = l_strcmp;
module.exports.luaV_concat = luaV_concat;
+module.exports.luaV_div = luaV_div;
module.exports.luaV_equalobj = luaV_equalobj;
module.exports.luaV_execute = luaV_execute;
module.exports.luaV_finishOp = luaV_finishOp;
module.exports.luaV_finishset = luaV_finishset;
module.exports.luaV_lessequal = luaV_lessequal;
module.exports.luaV_lessthan = luaV_lessthan;
+module.exports.luaV_mod = luaV_mod;
module.exports.luaV_objlen = luaV_objlen;
module.exports.luaV_rawequalobj = luaV_rawequalobj;
module.exports.luaV_shiftl = luaV_shiftl;