History

Lua 5.3.0-work2

Lua Team committed 12 years ago

Commit ad386d91 parent b83a40a60 files · +3280 −2672Browse files

Showing the changes to src/lcode.c (1 of 60 files). Show all

Unified · Split

src/lcode.c+65−36
@@ -1,5 +1,5 @@
1/*1/*
2** $Id: lcode.c,v 2.71 2013/06/25 18:57:18 roberto Exp $2** $Id: lcode.c,v 2.85 2014/03/21 13:52:33 roberto Exp $
3** Code generator for Lua3** Code generator for Lua
4** See Copyright Notice in lua.h4** See Copyright Notice in lua.h
5*/5*/
@@ -307,17 +307,21 @@ static void freeexp (FuncState *fs, expdesc *e) { · 301 unmodified lines
307}307}
308 308
309 309
310/*
311** Use scanner's table to cache position of constants in constant list
312** and try to reuse constants
313*/
310static int addk (FuncState *fs, TValue *key, TValue *v) {314static int addk (FuncState *fs, TValue *key, TValue *v) {
311 lua_State *L = fs->ls->L;315 lua_State *L = fs->ls->L;
312 TValue *idx = luaH_set(L, fs->h, key);
313 Proto *f = fs->f;316 Proto *f = fs->f;
317 TValue *idx = luaH_set(L, fs->ls->h, key); /* index scanner table */
314 int k, oldsize;318 int k, oldsize;
315 if (ttisinteger(idx)) {319 if (ttisinteger(idx)) { /* is there an index there? */
316 k = ivalue(idx);320 k = ivalue(idx);
317 if (luaV_rawequalobj(&f->k[k], v))321 /* correct value? (warning: must distinguish floats from integers!) */
318 return k;322 if (k < fs->nk && ttype(&f->k[k]) == ttype(v) &&
319 /* else may be a collision (e.g., between 0.0 and "\0\0\0\0\0\0\0\0");323 luaV_rawequalobj(&f->k[k], v))
320 go through and create a new entry for this value */324 return k; /* reuse index */
321 }325 }
322 /* constant not found; create a new entry */326 /* constant not found; create a new entry */
323 oldsize = f->sizek;327 oldsize = f->sizek;
@@ -360,7 +364,7 @@ int luaK_intK (FuncState *fs, lua_Integer n) { · 36 unmodified lines
360*/ 364*/
361static int luaK_numberK (FuncState *fs, lua_Number r) {365static int luaK_numberK (FuncState *fs, lua_Number r) {
362 TValue o;366 TValue o;
363 lua_assert(!luai_numisnan(NULL, r) && !isminuszero(r));367 lua_assert(!luai_numisnan(r) && !isminuszero(r));
364 setnvalue(&o, r);368 setnvalue(&o, r);
365 return addk(fs, &o, &o);369 return addk(fs, &o, &o);
366}370}
@@ -377,7 +381,7 @@ static int nilK (FuncState *fs) { · 10 unmodified lines
377 TValue k, v;381 TValue k, v;
378 setnilvalue(&v);382 setnilvalue(&v);
379 /* cannot use nil as key; instead use table itself to represent nil */383 /* cannot use nil as key; instead use table itself to represent nil */
380 sethvalue(fs->ls->L, &k, fs->h);384 sethvalue(fs->ls->L, &k, fs->ls->h);
381 return addk(fs, &k, &v);385 return addk(fs, &k, &v);
382}386}
383 387
@@ -746,24 +750,46 @@ void luaK_indexed (FuncState *fs, expdesc *t, expdesc *k) { · 362 unmodified lines
746}750}
747 751
748 752
749static int constfolding (OpCode op, expdesc *e1, expdesc *e2) {753/*
750 TValue v1, v2, res;754** return false if folding can raise an error
755*/
756static int validop (int op, TValue *v1, TValue *v2) {
757 lua_Number a, b;
751 lua_Integer i;758 lua_Integer i;
752 if (!tonumeral(e1, &v1) || !tonumeral(e2, &v2))759 cast_void(a); cast_void(b); /* macro may not use its arguments */
760 if (luai_numinvalidop(op, (cast_void(tonumber(v1, &a)), a),
761 (cast_void(tonumber(v2, &b)), b)))
753 return 0;762 return 0;
754 if (op == OP_IDIV &&763 switch (op) {
755 (!tointeger(&v1, &i) || !tointeger(&v2, &i) || i == 0))764 case LUA_OPIDIV: /* division by 0 and conversion errors */
756 return 0; /* avoid division by 0 and conversion errors */765 return (tointeger(v1, &i) && tointeger(v2, &i) && i != 0);
757 if (op == OP_MOD && ttisinteger(&v1) && ttisinteger(&v2) && ivalue(&v2) == 0)766 case LUA_OPBAND: case LUA_OPBOR: case LUA_OPBXOR:
758 return 0; /* avoid module by 0 at compile time */767 case LUA_OPSHL: case LUA_OPSHR: case LUA_OPBNOT: /* conversion errors */
759 luaO_arith(NULL, op - OP_ADD + LUA_OPADD, &v1, &v2, &res);768 return (tointeger(v1, &i) && tointeger(v2, &i));
769 case LUA_OPMOD: /* integer module by 0 */
770 return !(ttisinteger(v1) && ttisinteger(v2) && ivalue(v2) == 0);
771 case LUA_OPPOW: /* negative integer exponentiation */
772 return !(ttisinteger(v1) && ttisinteger(v2) && ivalue(v2) < 0);
773 default: return 1; /* everything else is valid */
774 }
775}
776
777
778/*
779** Try to "constant-fold" an operation; return 1 iff successful
780*/
781static int constfolding (FuncState *fs, int op, expdesc *e1, expdesc *e2) {
782 TValue v1, v2, res;
783 if (!tonumeral(e1, &v1) || !tonumeral(e2, &v2) || !validop(op, &v1, &v2))
784 return 0; /* non-numeric operands or not safe to fold */
785 luaO_arith(fs->ls->L, op, &v1, &v2, &res);
760 if (ttisinteger(&res)) {786 if (ttisinteger(&res)) {
761 e1->k = VKINT;787 e1->k = VKINT;
762 e1->u.ival = ivalue(&res);788 e1->u.ival = ivalue(&res);
763 }789 }
764 else {790 else {
765 lua_Number n = fltvalue(&res);791 lua_Number n = fltvalue(&res);
766 if (luai_numisnan(NULL, n) || isminuszero(n))792 if (luai_numisnan(n) || isminuszero(n))
767 return 0; /* folds neither NaN nor -0 */793 return 0; /* folds neither NaN nor -0 */
768 e1->k = VKFLT;794 e1->k = VKFLT;
769 e1->u.nval = n;795 e1->u.nval = n;
@@ -774,9 +800,16 @@ static int constfolding (OpCode op, expdesc *e1, expdesc *e2) { · 4 unmodified lines
774 800
775static void codearith (FuncState *fs, OpCode op,801static void codearith (FuncState *fs, OpCode op,
776 expdesc *e1, expdesc *e2, int line) {802 expdesc *e1, expdesc *e2, int line) {
777 if (!constfolding(op, e1, e2)) { /* could not fold operation? */803 if (!constfolding(fs, op - OP_ADD + LUA_OPADD, e1, e2)) {
778 int o2 = (op != OP_UNM && op != OP_LEN) ? luaK_exp2RK(fs, e2) : 0;804 int o1, o2;
779 int o1 = luaK_exp2RK(fs, e1);805 if (op == OP_UNM || op == OP_BNOT || op == OP_LEN) {
806 o2 = 0;
807 o1 = luaK_exp2anyreg(fs, e1); /* cannot operate on constants */
808 }
809 else { /* regular case (binary operators) */
810 o2 = luaK_exp2RK(fs, e2);
811 o1 = luaK_exp2RK(fs, e1);
812 }
780 if (o1 > o2) {813 if (o1 > o2) {
781 freeexp(fs, e1);814 freeexp(fs, e1);
782 freeexp(fs, e2);815 freeexp(fs, e2);
@@ -810,21 +843,13 @@ static void codecomp (FuncState *fs, OpCode op, int cond, expdesc *e1, · 27 unmodified lines
810 843
811void luaK_prefix (FuncState *fs, UnOpr op, expdesc *e, int line) {844void luaK_prefix (FuncState *fs, UnOpr op, expdesc *e, int line) {
812 expdesc e2;845 expdesc e2;
813 e2.t = e2.f = NO_JUMP; e2.k = VKFLT; e2.u.nval = 0;846 e2.t = e2.f = NO_JUMP; e2.k = VKINT; e2.u.ival = 0;
814 switch (op) {847 switch (op) {
815 case OPR_MINUS: {848 case OPR_MINUS: case OPR_BNOT: case OPR_LEN: {
816 if (!constfolding(OP_UNM, e, e)) { /* cannot fold it? */849 codearith(fs, cast(OpCode, (op - OPR_MINUS) + OP_UNM), e, &e2, line);
817 luaK_exp2anyreg(fs, e);
818 codearith(fs, OP_UNM, e, &e2, line);
819 }
820 break;850 break;
821 }851 }
822 case OPR_NOT: codenot(fs, e); break;852 case OPR_NOT: codenot(fs, e); break;
823 case OPR_LEN: {
824 luaK_exp2anyreg(fs, e); /* cannot operate on constants */
825 codearith(fs, OP_LEN, e, &e2, line);
826 break;
827 }
828 default: lua_assert(0);853 default: lua_assert(0);
829 }854 }
830}855}
@@ -846,7 +871,9 @@ void luaK_infix (FuncState *fs, BinOpr op, expdesc *v) { · 15 unmodified lines
846 }871 }
847 case OPR_ADD: case OPR_SUB:872 case OPR_ADD: case OPR_SUB:
848 case OPR_MUL: case OPR_DIV: case OPR_IDIV:873 case OPR_MUL: case OPR_DIV: case OPR_IDIV:
849 case OPR_MOD: case OPR_POW: {874 case OPR_MOD: case OPR_POW:
875 case OPR_BAND: case OPR_BOR: case OPR_BXOR:
876 case OPR_SHL: case OPR_SHR: {
850 if (!tonumeral(v, NULL)) luaK_exp2RK(fs, v);877 if (!tonumeral(v, NULL)) luaK_exp2RK(fs, v);
851 break;878 break;
852 }879 }
@@ -890,8 +917,10 @@ void luaK_posfix (FuncState *fs, BinOpr op, · 37 unmodified lines
890 break;917 break;
891 }918 }
892 case OPR_ADD: case OPR_SUB: case OPR_MUL: case OPR_DIV:919 case OPR_ADD: case OPR_SUB: case OPR_MUL: case OPR_DIV:
893 case OPR_IDIV: case OPR_MOD: case OPR_POW: {920 case OPR_IDIV: case OPR_MOD: case OPR_POW:
894 codearith(fs, cast(OpCode, op - OPR_ADD + OP_ADD), e1, e2, line);921 case OPR_BAND: case OPR_BOR: case OPR_BXOR:
922 case OPR_SHL: case OPR_SHR: {
923 codearith(fs, cast(OpCode, (op - OPR_ADD) + OP_ADD), e1, e2, line);
895 break;924 break;
896 }925 }
897 case OPR_EQ: case OPR_LT: case OPR_LE: {926 case OPR_EQ: case OPR_LT: case OPR_LE: {