aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lapi.c15
-rw-r--r--lcode.c47
-rw-r--r--lobject.c47
-rw-r--r--lobject.h5
4 files changed, 83 insertions, 31 deletions
diff --git a/lapi.c b/lapi.c
index e870afd2..b8c11eef 100644
--- a/lapi.c
+++ b/lapi.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lapi.c,v 2.177 2013/04/26 19:51:17 roberto Exp roberto $ 2** $Id: lapi.c,v 2.178 2013/04/29 17:12:50 roberto Exp roberto $
3** Lua API 3** Lua API
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -297,9 +297,6 @@ LUA_API int lua_rawequal (lua_State *L, int index1, int index2) {
297 297
298 298
299LUA_API void lua_arith (lua_State *L, int op) { 299LUA_API void lua_arith (lua_State *L, int op) {
300 StkId o1; /* 1st operand */
301 StkId o2; /* 2nd operand */
302 lua_Number n1, n2;
303 lua_lock(L); 300 lua_lock(L);
304 if (op != LUA_OPUNM) /* all other operations expect two operands */ 301 if (op != LUA_OPUNM) /* all other operations expect two operands */
305 api_checknelems(L, 2); 302 api_checknelems(L, 2);
@@ -308,13 +305,9 @@ LUA_API void lua_arith (lua_State *L, int op) {
308 setobjs2s(L, L->top, L->top - 1); 305 setobjs2s(L, L->top, L->top - 1);
309 L->top++; 306 L->top++;
310 } 307 }
311 o1 = L->top - 2; 308 /* first operand at top - 2, second at top - 1; result go to top - 2 */
312 o2 = L->top - 1; 309 luaO_arith(L, op, L->top - 2, L->top - 1, L->top - 2);
313 if (tonumber(o1, &n1) && tonumber(o2, &n2)) { 310 L->top--; /* remove second operand */
314 setnvalue(o1, luaO_numarith(op, n1, n2));
315 }
316 else luaT_trybinTM(L, o1, o2, o1, cast(TMS, op - LUA_OPADD + TM_ADD));
317 L->top--;
318 lua_unlock(L); 311 lua_unlock(L);
319} 312}
320 313
diff --git a/lcode.c b/lcode.c
index f53722ff..ded49b0e 100644
--- a/lcode.c
+++ b/lcode.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lcode.c,v 2.66 2013/04/26 13:07:53 roberto Exp roberto $ 2** $Id: lcode.c,v 2.67 2013/04/29 16:57:48 roberto Exp roberto $
3** Code generator for Lua 3** Code generator for Lua
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -29,8 +29,18 @@
29#define hasjumps(e) ((e)->t != (e)->f) 29#define hasjumps(e) ((e)->t != (e)->f)
30 30
31 31
32static int isnumeral(expdesc *e) { 32static int tonumeral(expdesc *e, TValue *v) {
33 return (e->k == VKFLT && e->t == NO_JUMP && e->f == NO_JUMP); 33 if (e->t != NO_JUMP || e->f != NO_JUMP)
34 return 0; /* not a numeral */
35 switch (e->k) {
36 case VKINT:
37 if (v) setivalue(v, e->u.ival);
38 return 1;
39 case VKFLT:
40 if (v) setnvalue(v, e->u.nval);
41 return 1;
42 default: return 0;
43 }
34} 44}
35 45
36 46
@@ -730,21 +740,28 @@ void luaK_indexed (FuncState *fs, expdesc *t, expdesc *k) {
730 740
731 741
732static int constfolding (OpCode op, expdesc *e1, expdesc *e2) { 742static int constfolding (OpCode op, expdesc *e1, expdesc *e2) {
733 lua_Number r; 743 TValue v1, v2, res;
734 if (!isnumeral(e1) || !isnumeral(e2)) return 0; 744 lua_Integer i2;
735 if ((op == OP_DIV || op == OP_IDIV || op == OP_MOD) && e2->u.nval == 0) 745 if (!tonumeral(e1, &v1) || !tonumeral(e2, &v2))
736 return 0; /* do not attempt to divide by 0 */ 746 return 0;
737 r = luaO_numarith(op - OP_ADD + LUA_OPADD, e1->u.nval, e2->u.nval); 747 if ((op == OP_IDIV || op == OP_MOD) && tointeger(&v2, &i2) && i2 == 0)
738 e1->u.nval = r; 748 return 0; /* avoid division by 0 at compile time */
749 luaO_arith(NULL, op - OP_ADD + LUA_OPADD, &v1, &v2, &res);
750 if (ttisinteger(&res)) {
751 e1->k = VKINT;
752 e1->u.ival = ivalue(&res);
753 }
754 else {
755 e1->k = VKFLT;
756 e1->u.nval = fltvalue(&res);
757 }
739 return 1; 758 return 1;
740} 759}
741 760
742 761
743static void codearith (FuncState *fs, OpCode op, 762static void codearith (FuncState *fs, OpCode op,
744 expdesc *e1, expdesc *e2, int line) { 763 expdesc *e1, expdesc *e2, int line) {
745 if (constfolding(op, e1, e2)) 764 if (!constfolding(op, e1, e2)) { /* could not fold operation? */
746 return;
747 else {
748 int o2 = (op != OP_UNM && op != OP_LEN) ? luaK_exp2RK(fs, e2) : 0; 765 int o2 = (op != OP_UNM && op != OP_LEN) ? luaK_exp2RK(fs, e2) : 0;
749 int o1 = luaK_exp2RK(fs, e1); 766 int o1 = luaK_exp2RK(fs, e1);
750 if (o1 > o2) { 767 if (o1 > o2) {
@@ -783,9 +800,7 @@ void luaK_prefix (FuncState *fs, UnOpr op, expdesc *e, int line) {
783 e2.t = e2.f = NO_JUMP; e2.k = VKFLT; e2.u.nval = 0; 800 e2.t = e2.f = NO_JUMP; e2.k = VKFLT; e2.u.nval = 0;
784 switch (op) { 801 switch (op) {
785 case OPR_MINUS: { 802 case OPR_MINUS: {
786 if (isnumeral(e)) /* minus constant? */ 803 if (!constfolding(OP_UNM, e, e)) { /* cannot fold it? */
787 e->u.nval = luai_numunm(NULL, e->u.nval); /* fold it */
788 else {
789 luaK_exp2anyreg(fs, e); 804 luaK_exp2anyreg(fs, e);
790 codearith(fs, OP_UNM, e, &e2, line); 805 codearith(fs, OP_UNM, e, &e2, line);
791 } 806 }
@@ -819,7 +834,7 @@ void luaK_infix (FuncState *fs, BinOpr op, expdesc *v) {
819 case OPR_ADD: case OPR_SUB: 834 case OPR_ADD: case OPR_SUB:
820 case OPR_MUL: case OPR_DIV: case OPR_IDIV: 835 case OPR_MUL: case OPR_DIV: case OPR_IDIV:
821 case OPR_MOD: case OPR_POW: { 836 case OPR_MOD: case OPR_POW: {
822 if (!isnumeral(v)) luaK_exp2RK(fs, v); 837 if (!tonumeral(v, NULL)) luaK_exp2RK(fs, v);
823 break; 838 break;
824 } 839 }
825 default: { 840 default: {
diff --git a/lobject.c b/lobject.c
index 1f028057..e2af0f33 100644
--- a/lobject.c
+++ b/lobject.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lobject.c,v 2.60 2013/04/25 13:53:13 roberto Exp roberto $ 2** $Id: lobject.c,v 2.61 2013/04/29 16:57:28 roberto Exp roberto $
3** Some generic functions over Lua objects 3** Some generic functions over Lua objects
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -70,7 +70,21 @@ int luaO_ceillog2 (unsigned int x) {
70} 70}
71 71
72 72
73lua_Number luaO_numarith (int op, lua_Number v1, lua_Number v2) { 73static lua_Integer intarith (lua_State *L, int op, lua_Integer v1,
74 lua_Integer v2) {
75 switch (op) {
76 case LUA_OPADD: return intop(+, v1, v2);
77 case LUA_OPSUB:return intop(-, v1, v2);
78 case LUA_OPMUL:return intop(*, v1, v2);
79 case LUA_OPMOD: return luaV_mod(L, v1, v2);
80 case LUA_OPPOW: return luaV_pow(v1, v2);
81 case LUA_OPUNM: return -v1;
82 default: lua_assert(0); return 0;
83 }
84}
85
86
87static lua_Number numarith (int op, lua_Number v1, lua_Number v2) {
74 switch (op) { 88 switch (op) {
75 case LUA_OPADD: return luai_numadd(NULL, v1, v2); 89 case LUA_OPADD: return luai_numadd(NULL, v1, v2);
76 case LUA_OPSUB: return luai_numsub(NULL, v1, v2); 90 case LUA_OPSUB: return luai_numsub(NULL, v1, v2);
@@ -84,6 +98,35 @@ lua_Number luaO_numarith (int op, lua_Number v1, lua_Number v2) {
84} 98}
85 99
86 100
101void luaO_arith (lua_State *L, int op, const TValue *p1, const TValue *p2,
102 TValue *res) {
103 if (op == LUA_OPIDIV) { /* operates only on integers */
104 lua_Integer i1; lua_Integer i2;
105 if (tointeger(p1, &i1) && tointeger(p2, &i2)) {
106 setivalue(res, luaV_div(L, i1, i2));
107 return;
108 }
109 /* else go to the end */
110 }
111 else { /* other operations */
112 lua_Number n1; lua_Number n2;
113 if (ttisinteger(p1) && ttisinteger(p2) && op != LUA_OPDIV &&
114 (op != LUA_OPPOW || ivalue(p2) >= 0)) {
115 setivalue(res, intarith(L, op, ivalue(p1), ivalue(p2)));
116 return;
117 }
118 else if (tonumber(p1, &n1) && tonumber(p2, &n2)) {
119 setnvalue(res, numarith(op, n1, n2));
120 return;
121 }
122 /* else go to the end */
123 }
124 /* could not perform raw operation; try metmethod */
125 lua_assert(L != NULL); /* cannot fail when folding (compile time) */
126 luaT_trybinTM(L, p1, p2, res, cast(TMS, op - LUA_OPADD + TM_ADD));
127}
128
129
87int luaO_hexavalue (int c) { 130int luaO_hexavalue (int c) {
88 if (lisdigit(c)) return c - '0'; 131 if (lisdigit(c)) return c - '0';
89 else return ltolower(c) - 'a' + 10; 132 else return ltolower(c) - 'a' + 10;
diff --git a/lobject.h b/lobject.h
index 90931a64..3d03744f 100644
--- a/lobject.h
+++ b/lobject.h
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lobject.h,v 2.74 2013/04/16 18:46:28 roberto Exp roberto $ 2** $Id: lobject.h,v 2.75 2013/04/29 16:57:28 roberto Exp roberto $
3** Type definitions for Lua objects 3** Type definitions for Lua objects
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -496,7 +496,8 @@ LUAI_DDEC const TValue luaO_nilobject_;
496LUAI_FUNC int luaO_int2fb (unsigned int x); 496LUAI_FUNC int luaO_int2fb (unsigned int x);
497LUAI_FUNC int luaO_fb2int (int x); 497LUAI_FUNC int luaO_fb2int (int x);
498LUAI_FUNC int luaO_ceillog2 (unsigned int x); 498LUAI_FUNC int luaO_ceillog2 (unsigned int x);
499LUAI_FUNC lua_Number luaO_numarith (int op, lua_Number v1, lua_Number v2); 499LUAI_FUNC void luaO_arith (lua_State *L, int op, const TValue *p1,
500 const TValue *p2, TValue *res);
500LUAI_FUNC int luaO_str2d (const char *s, size_t len, lua_Number *result); 501LUAI_FUNC int luaO_str2d (const char *s, size_t len, lua_Number *result);
501LUAI_FUNC int luaO_str2int (const char *s, lua_Integer *result); 502LUAI_FUNC int luaO_str2int (const char *s, lua_Integer *result);
502LUAI_FUNC int luaO_hexavalue (int c); 503LUAI_FUNC int luaO_hexavalue (int c);