Showing the changes to src/lcode.c (1 of 57 files). Show all
Unified · Split
| @@ -1,16 +1,18 @@ | ||
| 1 | 1 | /* |
| 2 | −** $Id: lcode.c,v 2.90 2014/05/08 18:58:46 roberto Exp $ | |
| 2 | +** $Id: lcode.c,v 2.97 2014/11/24 14:59:22 roberto Exp $ | |
| 3 | 3 | ** Code generator for Lua |
| 4 | 4 | ** See Copyright Notice in lua.h |
| 5 | 5 | */ |
| 6 | 6 | |
| 7 | +#define lcode_c | |
| 8 | +#define LUA_CORE | |
| 9 | + | |
| 10 | +#include "lprefix.h" | |
| 11 | + | |
| 7 | 12 | |
| 8 | 13 | #include <math.h> |
| 9 | 14 | #include <stdlib.h> |
| 10 | 15 | |
| 11 | −#define lcode_c | |
| 12 | −#define LUA_CORE | |
| 13 | − | |
| 14 | 16 | #include "lua.h" |
| 15 | 17 | |
| 16 | 18 | #include "lcode.h" |
| @@ -27,7 +29,11 @@ · 10 unmodified lines | ||
| 27 | 29 | #include "lvm.h" |
| 28 | 30 | |
| 29 | 31 | |
| 30 | −/* test for x == -0 */ | |
| 32 | +/* Maximum number of registers in a Lua function */ | |
| 33 | +#define MAXREGS 250 | |
| 34 | + | |
| 35 | + | |
| 36 | +/* test for x == -0 ('signbit' needs 'math.h') */ | |
| 31 | 37 | #if defined(signbit) |
| 32 | 38 | #define isminuszero(x) ((x) == 0.0 && signbit(x)) |
| 33 | 39 | #else |
| @@ -107,7 +113,7 @@ static void fixjump (FuncState *fs, int pc, int dest) { · 73 unmodified lines | ||
| 107 | 113 | |
| 108 | 114 | |
| 109 | 115 | /* |
| 110 | −** returns current `pc' and marks it as a jump target (to avoid wrong | |
| 116 | +** returns current 'pc' and marks it as a jump target (to avoid wrong | |
| 111 | 117 | ** optimizations with consecutive instructions not in the same basic block). |
| 112 | 118 | */ |
| 113 | 119 | int luaK_getlabel (FuncState *fs) { |
| @@ -230,7 +236,7 @@ void luaK_concat (FuncState *fs, int *l1, int l2) { · 116 unmodified lines | ||
| 230 | 236 | |
| 231 | 237 | static int luaK_code (FuncState *fs, Instruction i) { |
| 232 | 238 | Proto *f = fs->f; |
| 233 | − dischargejpc(fs); /* `pc' will change */ | |
| 239 | + dischargejpc(fs); /* 'pc' will change */ | |
| 234 | 240 | /* put new instruction in code array */ |
| 235 | 241 | luaM_growvector(fs->ls->L, f->code, fs->pc, f->sizecode, Instruction, |
| 236 | 242 | MAX_INT, "opcodes"); |
| @@ -280,7 +286,7 @@ int luaK_codek (FuncState *fs, int reg, int k) { · 43 unmodified lines | ||
| 280 | 286 | void luaK_checkstack (FuncState *fs, int n) { |
| 281 | 287 | int newstack = fs->freereg + n; |
| 282 | 288 | if (newstack > fs->f->maxstacksize) { |
| 283 | − if (newstack >= MAXSTACK) | |
| 289 | + if (newstack >= MAXREGS) | |
| 284 | 290 | luaX_syntaxerror(fs->ls, "function or expression too complex"); |
| 285 | 291 | fs->f->maxstacksize = cast_byte(newstack); |
| 286 | 292 | } |
| @@ -503,7 +509,7 @@ static void discharge2anyreg (FuncState *fs, expdesc *e) { · 216 unmodified lines | ||
| 503 | 509 | static void exp2reg (FuncState *fs, expdesc *e, int reg) { |
| 504 | 510 | discharge2reg(fs, e, reg); |
| 505 | 511 | if (e->k == VJMP) |
| 506 | − luaK_concat(fs, &e->t, e->u.info); /* put this jump in `t' list */ | |
| 512 | + luaK_concat(fs, &e->t, e->u.info); /* put this jump in 't' list */ | |
| 507 | 513 | if (hasjumps(e)) { |
| 508 | 514 | int final; /* position after whole expression */ |
| 509 | 515 | int p_f = NO_JUMP; /* position of an eventual LOAD false */ |
| @@ -585,7 +591,7 @@ int luaK_exp2RK (FuncState *fs, expdesc *e) { · 75 unmodified lines | ||
| 585 | 591 | } |
| 586 | 592 | case VK: { |
| 587 | 593 | vk: |
| 588 | − if (e->u.info <= MAXINDEXRK) /* constant fits in argC? */ | |
| 594 | + if (e->u.info <= MAXINDEXRK) /* constant fits in 'argC'? */ | |
| 589 | 595 | return RKASK(e->u.info); |
| 590 | 596 | else break; |
| 591 | 597 | } |
| @@ -677,7 +683,7 @@ void luaK_goiftrue (FuncState *fs, expdesc *e) { · 85 unmodified lines | ||
| 677 | 683 | break; |
| 678 | 684 | } |
| 679 | 685 | } |
| 680 | − luaK_concat(fs, &e->f, pc); /* insert last jump in `f' list */ | |
| 686 | + luaK_concat(fs, &e->f, pc); /* insert last jump in 'f' list */ | |
| 681 | 687 | luaK_patchtohere(fs, e->t); |
| 682 | 688 | e->t = NO_JUMP; |
| 683 | 689 | } |
| @@ -700,7 +706,7 @@ void luaK_goiffalse (FuncState *fs, expdesc *e) { · 16 unmodified lines | ||
| 700 | 706 | break; |
| 701 | 707 | } |
| 702 | 708 | } |
| 703 | − luaK_concat(fs, &e->t, pc); /* insert last jump in `t' list */ | |
| 709 | + luaK_concat(fs, &e->t, pc); /* insert last jump in 't' list */ | |
| 704 | 710 | luaK_patchtohere(fs, e->f); |
| 705 | 711 | e->f = NO_JUMP; |
| 706 | 712 | } |
| @@ -762,12 +768,10 @@ static int validop (int op, TValue *v1, TValue *v2) { · 55 unmodified lines | ||
| 762 | 768 | (cast_void(tonumber(v2, &b)), b))) |
| 763 | 769 | return 0; |
| 764 | 770 | switch (op) { |
| 765 | − case LUA_OPIDIV: /* division by 0 and conversion errors */ | |
| 766 | − return (tointeger(v1, &i) && tointeger(v2, &i) && i != 0); | |
| 767 | 771 | case LUA_OPBAND: case LUA_OPBOR: case LUA_OPBXOR: |
| 768 | 772 | case LUA_OPSHL: case LUA_OPSHR: case LUA_OPBNOT: /* conversion errors */ |
| 769 | 773 | return (tointeger(v1, &i) && tointeger(v2, &i)); |
| 770 | − case LUA_OPMOD: /* integer module by 0 */ | |
| 774 | + case LUA_OPIDIV: case LUA_OPMOD: /* integer division by 0 */ | |
| 771 | 775 | return !(ttisinteger(v1) && ttisinteger(v2) && ivalue(v2) == 0); |
| 772 | 776 | default: return 1; /* everything else is valid */ |
| 773 | 777 | } |
| @@ -797,19 +801,30 @@ static int constfolding (FuncState *fs, int op, expdesc *e1, expdesc *e2) { · 23 unmodified lines | ||
| 797 | 801 | } |
| 798 | 802 | |
| 799 | 803 | |
| 800 | −static void codearith (FuncState *fs, OpCode op, | |
| 801 | − expdesc *e1, expdesc *e2, int line) { | |
| 802 | − if (!constfolding(fs, op - OP_ADD + LUA_OPADD, e1, e2)) { | |
| 804 | +/* | |
| 805 | +** Code for binary and unary expressions that "produce values" | |
| 806 | +** (arithmetic operations, bitwise operations, concat, length). First | |
| 807 | +** try to do constant folding (only for numeric [arithmetic and | |
| 808 | +** bitwise] operations, which is what 'lua_arith' accepts). | |
| 809 | +** Expression to produce final result will be encoded in 'e1'. | |
| 810 | +*/ | |
| 811 | +static void codeexpval (FuncState *fs, OpCode op, | |
| 812 | + expdesc *e1, expdesc *e2, int line) { | |
| 813 | + lua_assert(op >= OP_ADD); | |
| 814 | + if (op <= OP_BNOT && constfolding(fs, op - OP_ADD + LUA_OPADD, e1, e2)) | |
| 815 | + return; /* result has been folded */ | |
| 816 | + else { | |
| 803 | 817 | int o1, o2; |
| 804 | − if (op == OP_UNM || op == OP_BNOT || op == OP_LEN) { | |
| 805 | − o2 = 0; | |
| 818 | + /* move operands to registers (if needed) */ | |
| 819 | + if (op == OP_UNM || op == OP_BNOT || op == OP_LEN) { /* unary op? */ | |
| 820 | + o2 = 0; /* no second expression */ | |
| 806 | 821 | o1 = luaK_exp2anyreg(fs, e1); /* cannot operate on constants */ |
| 807 | 822 | } |
| 808 | 823 | else { /* regular case (binary operators) */ |
| 809 | − o2 = luaK_exp2RK(fs, e2); | |
| 824 | + o2 = luaK_exp2RK(fs, e2); /* both operands are "RK" */ | |
| 810 | 825 | o1 = luaK_exp2RK(fs, e1); |
| 811 | 826 | } |
| 812 | − if (o1 > o2) { | |
| 827 | + if (o1 > o2) { /* free registers in proper order */ | |
| 813 | 828 | freeexp(fs, e1); |
| 814 | 829 | freeexp(fs, e2); |
| 815 | 830 | } |
| @@ -817,8 +832,8 @@ static void codearith (FuncState *fs, OpCode op, · 1 unmodified line | ||
| 817 | 832 | freeexp(fs, e2); |
| 818 | 833 | freeexp(fs, e1); |
| 819 | 834 | } |
| 820 | − e1->u.info = luaK_codeABC(fs, op, 0, o1, o2); | |
| 821 | − e1->k = VRELOCABLE; | |
| 835 | + e1->u.info = luaK_codeABC(fs, op, 0, o1, o2); /* generate opcode */ | |
| 836 | + e1->k = VRELOCABLE; /* all those operations are relocable */ | |
| 822 | 837 | luaK_fixline(fs, line); |
| 823 | 838 | } |
| 824 | 839 | } |
| @@ -831,7 +846,7 @@ static void codecomp (FuncState *fs, OpCode op, int cond, expdesc *e1, · 6 unmodified lines | ||
| 831 | 846 | freeexp(fs, e2); |
| 832 | 847 | freeexp(fs, e1); |
| 833 | 848 | if (cond == 0 && op != OP_EQ) { |
| 834 | − int temp; /* exchange args to replace by `<' or `<=' */ | |
| 849 | + int temp; /* exchange args to replace by '<' or '<=' */ | |
| 835 | 850 | temp = o1; o1 = o2; o2 = temp; /* o1 <==> o2 */ |
| 836 | 851 | cond = 1; |
| 837 | 852 | } |
| @@ -845,7 +860,7 @@ void luaK_prefix (FuncState *fs, UnOpr op, expdesc *e, int line) { · 7 unmodified lines | ||
| 845 | 860 | e2.t = e2.f = NO_JUMP; e2.k = VKINT; e2.u.ival = 0; |
| 846 | 861 | switch (op) { |
| 847 | 862 | case OPR_MINUS: case OPR_BNOT: case OPR_LEN: { |
| 848 | − codearith(fs, cast(OpCode, (op - OPR_MINUS) + OP_UNM), e, &e2, line); | |
| 863 | + codeexpval(fs, cast(OpCode, (op - OPR_MINUS) + OP_UNM), e, &e2, line); | |
| 849 | 864 | break; |
| 850 | 865 | } |
| 851 | 866 | case OPR_NOT: codenot(fs, e); break; |
| @@ -865,7 +880,7 @@ void luaK_infix (FuncState *fs, BinOpr op, expdesc *v) { · 13 unmodified lines | ||
| 865 | 880 | break; |
| 866 | 881 | } |
| 867 | 882 | case OPR_CONCAT: { |
| 868 | − luaK_exp2nextreg(fs, v); /* operand must be on the `stack' */ | |
| 883 | + luaK_exp2nextreg(fs, v); /* operand must be on the 'stack' */ | |
| 869 | 884 | break; |
| 870 | 885 | } |
| 871 | 886 | case OPR_ADD: case OPR_SUB: |
| @@ -911,7 +926,7 @@ void luaK_posfix (FuncState *fs, BinOpr op, · 39 unmodified lines | ||
| 911 | 926 | } |
| 912 | 927 | else { |
| 913 | 928 | luaK_exp2nextreg(fs, e2); /* operand must be on the 'stack' */ |
| 914 | − codearith(fs, OP_CONCAT, e1, e2, line); | |
| 929 | + codeexpval(fs, OP_CONCAT, e1, e2, line); | |
| 915 | 930 | } |
| 916 | 931 | break; |
| 917 | 932 | } |
| @@ -919,7 +934,7 @@ void luaK_posfix (FuncState *fs, BinOpr op, · 1 unmodified line | ||
| 919 | 934 | case OPR_IDIV: case OPR_MOD: case OPR_POW: |
| 920 | 935 | case OPR_BAND: case OPR_BOR: case OPR_BXOR: |
| 921 | 936 | case OPR_SHL: case OPR_SHR: { |
| 922 | − codearith(fs, cast(OpCode, (op - OPR_ADD) + OP_ADD), e1, e2, line); | |
| 937 | + codeexpval(fs, cast(OpCode, (op - OPR_ADD) + OP_ADD), e1, e2, line); | |
| 923 | 938 | break; |
| 924 | 939 | } |
| 925 | 940 | case OPR_EQ: case OPR_LT: case OPR_LE: { |