Showing the changes to src/lcode.c (1 of 60 files). Show all
Unified · Split
| @@ -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 Lua | 3 | ** Code generator for Lua |
| 4 | ** See Copyright Notice in lua.h | 4 | ** 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 | */ | ||
| 310 | static int addk (FuncState *fs, TValue *key, TValue *v) { | 314 | static 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 | */ |
| 361 | static int luaK_numberK (FuncState *fs, lua_Number r) { | 365 | static 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 | ||
| 749 | static int constfolding (OpCode op, expdesc *e1, expdesc *e2) { | 753 | /* |
| 750 | TValue v1, v2, res; | 754 | ** return false if folding can raise an error |
| 755 | */ | ||
| 756 | static 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 | */ | ||
| 781 | static 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 | ||
| 775 | static void codearith (FuncState *fs, OpCode op, | 801 | static 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 | ||
| 811 | void luaK_prefix (FuncState *fs, UnOpr op, expdesc *e, int line) { | 844 | void 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: { |