summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lvm.c84
-rw-r--r--lvm.h5
2 files changed, 83 insertions, 6 deletions
diff --git a/lvm.c b/lvm.c
index 96628872..212583f6 100644
--- a/lvm.c
+++ b/lvm.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lvm.c,v 2.159 2013/04/25 15:59:42 roberto Exp roberto $ 2** $Id: lvm.c,v 2.160 2013/04/25 16:07:52 roberto Exp roberto $
3** Lua virtual machine 3** Lua virtual machine
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -150,7 +150,9 @@ static int l_strcmp (const TString *ls, const TString *rs) {
150 150
151int luaV_lessthan (lua_State *L, const TValue *l, const TValue *r) { 151int luaV_lessthan (lua_State *L, const TValue *l, const TValue *r) {
152 int res; 152 int res;
153 if (ttisnumber(l) && ttisnumber(r)) 153 if (ttisinteger(l) && ttisinteger(r))
154 return (ivalue(l) < ivalue(r));
155 else if (ttisnumber(l) && ttisnumber(r))
154 return luai_numlt(L, nvalue(l), nvalue(r)); 156 return luai_numlt(L, nvalue(l), nvalue(r));
155 else if (ttisstring(l) && ttisstring(r)) 157 else if (ttisstring(l) && ttisstring(r))
156 return l_strcmp(rawtsvalue(l), rawtsvalue(r)) < 0; 158 return l_strcmp(rawtsvalue(l), rawtsvalue(r)) < 0;
@@ -162,7 +164,9 @@ int luaV_lessthan (lua_State *L, const TValue *l, const TValue *r) {
162 164
163int luaV_lessequal (lua_State *L, const TValue *l, const TValue *r) { 165int luaV_lessequal (lua_State *L, const TValue *l, const TValue *r) {
164 int res; 166 int res;
165 if (ttisnumber(l) && ttisnumber(r)) 167 if (ttisinteger(l) && ttisinteger(r))
168 return (ivalue(l) <= ivalue(r));
169 else if (ttisnumber(l) && ttisnumber(r))
166 return luai_numle(L, nvalue(l), nvalue(r)); 170 return luai_numle(L, nvalue(l), nvalue(r));
167 else if (ttisstring(l) && ttisstring(r)) 171 else if (ttisstring(l) && ttisstring(r))
168 return l_strcmp(rawtsvalue(l), rawtsvalue(r)) <= 0; 172 return l_strcmp(rawtsvalue(l), rawtsvalue(r)) <= 0;
@@ -283,6 +287,54 @@ void luaV_objlen (lua_State *L, StkId ra, const TValue *rb) {
283} 287}
284 288
285 289
290lua_Integer luaV_div (lua_State *L, lua_Integer x, lua_Integer y) {
291 if (cast_unsigned(y) + 1 <= 1U) { /* special cases: -1 or 0 */
292 if (y == 0)
293 luaG_runerror(L, "attempt to divide by zero");
294 else /* -1 */
295 return -x; /* avoid overflow with 0x80000... */
296 }
297 else {
298 lua_Integer d = x / y; /* perform division */
299 if ((x ^ y) >= 0 || x % y == 0) /* same signal or no rest? */
300 return d;
301 else
302 return d - 1; /* correct 'div' for negative case */
303 }
304}
305
306
307lua_Integer luaV_mod (lua_State *L, lua_Integer x, lua_Integer y) {
308 if (cast_unsigned(y) + 1 <= 1U) { /* special cases: -1 or 0 */
309 if (y == 0)
310 luaG_runerror(L, "attempt to divide by zero (in '%%')");
311 else /* -1 */
312 return 0; /* avoid overflow with 0x80000... */
313 }
314 else {
315 lua_Integer r = x % y;
316 if (r == 0 || (x ^ y) >= 0)
317 return r;
318 else
319 return r + y; /* correct 'mod' for negative case */
320 }
321}
322
323
324lua_Integer luaV_pow (lua_Integer x, lua_Integer y) {
325 lua_Integer r = 1;
326 lua_assert(y >= 0);
327 if (y == 0) return r;
328 for (; y > 1; y >>= 1) {
329 if (y & 1)
330 r = cast_integer(cast_unsigned(r) * cast_unsigned(x));
331 x = cast_integer(cast_unsigned(x) * cast_unsigned(x));
332 }
333 r = cast_integer(cast_unsigned(r) * cast_unsigned(x));
334 return r;
335}
336
337
286void luaV_arith (lua_State *L, StkId ra, const TValue *rb, 338void luaV_arith (lua_State *L, StkId ra, const TValue *rb,
287 const TValue *rc, TMS op) { 339 const TValue *rc, TMS op) {
288 TValue tempb, tempc; 340 TValue tempb, tempc;
@@ -589,10 +641,32 @@ void luaV_execute (lua_State *L) {
589 else { Protect(luaV_arith(L, ra, rb, rc, TM_DIV)); } 641 else { Protect(luaV_arith(L, ra, rb, rc, TM_DIV)); }
590 ) 642 )
591 vmcase(OP_MOD, 643 vmcase(OP_MOD,
592 arith_op(luai_nummod, TM_MOD); 644 TValue *rb = RKB(i);
645 TValue *rc = RKC(i);
646 if (ttisinteger(rb) && ttisinteger(rc)) {
647 lua_Integer ib = ivalue(rb); lua_Integer ic = ivalue(rc);
648 setivalue(ra, luaV_mod(L, ib, ic));
649 }
650 else if (ttisnumber(rb) && ttisnumber(rc)) {
651 lua_Number nb = nvalue(rb); lua_Number nc = nvalue(rc);
652 setnvalue(ra, luai_nummod(L, nb, nc));
653 }
654 else { Protect(luaV_arith(L, ra, rb, rc, TM_MOD)); }
593 ) 655 )
594 vmcase(OP_POW, 656 vmcase(OP_POW,
595 arith_op(luai_numpow, TM_POW); 657 TValue *rb = RKB(i);
658 TValue *rc = RKC(i);
659 lua_Integer ic;
660 if (ttisinteger(rb) && ttisinteger(rc) &&
661 (ic = ivalue(rc)) >= 0) {
662 lua_Integer ib = ivalue(rb);
663 setivalue(ra, luaV_pow(ib, ic));
664 }
665 else if (ttisnumber(rb) && ttisnumber(rc)) {
666 lua_Number nb = nvalue(rb); lua_Number nc = nvalue(rc);
667 setnvalue(ra, luai_numpow(L, nb, nc));
668 }
669 else { Protect(luaV_arith(L, ra, rb, rc, TM_POW)); }
596 ) 670 )
597 vmcase(OP_UNM, 671 vmcase(OP_UNM,
598 TValue *rb = RB(i); 672 TValue *rb = RB(i);
diff --git a/lvm.h b/lvm.h
index 365e4a48..07235f19 100644
--- a/lvm.h
+++ b/lvm.h
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lvm.h,v 2.17 2011/05/31 18:27:56 roberto Exp $ 2** $Id: lvm.h,v 2.19 2013/04/15 15:44:46 roberto Exp roberto $
3** Lua virtual machine 3** Lua virtual machine
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -33,6 +33,9 @@ LUAI_FUNC void luaV_settable (lua_State *L, const TValue *t, TValue *key,
33LUAI_FUNC void luaV_finishOp (lua_State *L); 33LUAI_FUNC void luaV_finishOp (lua_State *L);
34LUAI_FUNC void luaV_execute (lua_State *L); 34LUAI_FUNC void luaV_execute (lua_State *L);
35LUAI_FUNC void luaV_concat (lua_State *L, int total); 35LUAI_FUNC void luaV_concat (lua_State *L, int total);
36LUAI_FUNC lua_Integer luaV_div (lua_State *L, lua_Integer x, lua_Integer y);
37LUAI_FUNC lua_Integer luaV_mod (lua_State *L, lua_Integer x, lua_Integer y);
38LUAI_FUNC lua_Integer luaV_pow (lua_Integer x, lua_Integer y);
36LUAI_FUNC void luaV_arith (lua_State *L, StkId ra, const TValue *rb, 39LUAI_FUNC void luaV_arith (lua_State *L, StkId ra, const TValue *rb,
37 const TValue *rc, TMS op); 40 const TValue *rc, TMS op);
38LUAI_FUNC void luaV_objlen (lua_State *L, StkId ra, const TValue *rb); 41LUAI_FUNC void luaV_objlen (lua_State *L, StkId ra, const TValue *rb);