diff options
Diffstat (limited to 'lcode.c')
-rw-r--r-- | lcode.c | 74 |
1 files changed, 45 insertions, 29 deletions
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: lcode.c,v 2.128 2017/10/02 22:50:57 roberto Exp roberto $ | 2 | ** $Id: lcode.c,v 2.129 2017/10/04 15:49:24 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 | */ |
@@ -202,7 +202,7 @@ static int patchtestreg (FuncState *fs, int node, int reg) { | |||
202 | else { | 202 | else { |
203 | /* no register to put value or register already has the value; | 203 | /* no register to put value or register already has the value; |
204 | change instruction to simple test */ | 204 | change instruction to simple test */ |
205 | *i = CREATE_ABC(OP_TEST, GETARG_B(*i), 0, GETARG_C(*i)); | 205 | *i = CREATE_ABCk(OP_TEST, GETARG_B(*i), 0, GETARG_C(*i), 0); |
206 | } | 206 | } |
207 | return 1; | 207 | return 1; |
208 | } | 208 | } |
@@ -365,13 +365,18 @@ static int luaK_code (FuncState *fs, Instruction i) { | |||
365 | ** Format and emit an 'iABC' instruction. (Assertions check consistency | 365 | ** Format and emit an 'iABC' instruction. (Assertions check consistency |
366 | ** of parameters versus opcode.) | 366 | ** of parameters versus opcode.) |
367 | */ | 367 | */ |
368 | int luaK_codeABC (FuncState *fs, OpCode o, int a, int b, int c) { | 368 | int luaK_codeABCk (FuncState *fs, OpCode o, int a, int b, int c, int k) { |
369 | lua_assert(getOpMode(o) == iABC); | 369 | lua_assert(getOpMode(o) == iABC); |
370 | lua_assert(a <= MAXARG_A && b <= MAXARG_B && c <= MAXARG_C); | 370 | lua_assert(a <= MAXARG_A && b <= MAXARG_B && |
371 | return luaK_code(fs, CREATE_ABC(o, a, b, c)); | 371 | c <= MAXARG_C && (k & ~1) == 0); |
372 | return luaK_code(fs, CREATE_ABCk(o, a, b, c, k)); | ||
372 | } | 373 | } |
373 | 374 | ||
374 | 375 | ||
376 | #define codeABsC(fs,o,a,b,c,k) luaK_codeABCk(fs,o,a,b,((c) + MAXARG_sC),k) | ||
377 | |||
378 | |||
379 | |||
375 | /* | 380 | /* |
376 | ** Format and emit an 'iABx' instruction. | 381 | ** Format and emit an 'iABx' instruction. |
377 | */ | 382 | */ |
@@ -448,7 +453,7 @@ void luaK_reserveregs (FuncState *fs, int n) { | |||
448 | ) | 453 | ) |
449 | */ | 454 | */ |
450 | static void freereg (FuncState *fs, int reg) { | 455 | static void freereg (FuncState *fs, int reg) { |
451 | if (!ISK(reg) && reg >= fs->nactvar) { | 456 | if (reg >= fs->nactvar) { |
452 | fs->freereg--; | 457 | fs->freereg--; |
453 | lua_assert(reg == fs->freereg); | 458 | lua_assert(reg == fs->freereg); |
454 | } | 459 | } |
@@ -853,7 +858,7 @@ void luaK_exp2val (FuncState *fs, expdesc *e) { | |||
853 | ** Ensures final expression result is in a valid R/K index | 858 | ** Ensures final expression result is in a valid R/K index |
854 | ** (that is, it is either in a register or in 'k' with an index | 859 | ** (that is, it is either in a register or in 'k' with an index |
855 | ** in the range of R/K indices). | 860 | ** in the range of R/K indices). |
856 | ** Returns R/K index. | 861 | ** Returns 1 if expression is K, 0 otherwise. |
857 | */ | 862 | */ |
858 | int luaK_exp2RK (FuncState *fs, expdesc *e) { | 863 | int luaK_exp2RK (FuncState *fs, expdesc *e) { |
859 | luaK_exp2val(fs, e); | 864 | luaK_exp2val(fs, e); |
@@ -867,12 +872,20 @@ int luaK_exp2RK (FuncState *fs, expdesc *e) { | |||
867 | vk: | 872 | vk: |
868 | e->k = VK; | 873 | e->k = VK; |
869 | if (e->u.info <= MAXINDEXRK) /* constant fits in 'argC'? */ | 874 | if (e->u.info <= MAXINDEXRK) /* constant fits in 'argC'? */ |
870 | return RKASK(e->u.info); | 875 | return 1; |
871 | else break; | 876 | else break; |
872 | default: break; | 877 | default: break; |
873 | } | 878 | } |
874 | /* not a constant in the right range: put it in a register */ | 879 | /* not a constant in the right range: put it in a register */ |
875 | return luaK_exp2anyreg(fs, e); | 880 | luaK_exp2anyreg(fs, e); |
881 | return 0; | ||
882 | } | ||
883 | |||
884 | |||
885 | static void codeABRK (FuncState *fs, OpCode o, int a, int b, | ||
886 | expdesc *ec) { | ||
887 | int k = luaK_exp2RK(fs, ec); | ||
888 | luaK_codeABCk(fs, o, a, b, ec->u.info, k); | ||
876 | } | 889 | } |
877 | 890 | ||
878 | 891 | ||
@@ -892,23 +905,19 @@ void luaK_storevar (FuncState *fs, expdesc *var, expdesc *ex) { | |||
892 | break; | 905 | break; |
893 | } | 906 | } |
894 | case VINDEXUP: { | 907 | case VINDEXUP: { |
895 | int e = luaK_exp2RK(fs, ex); | 908 | codeABRK(fs, OP_SETTABUP, var->u.ind.t, var->u.ind.idx, ex); |
896 | luaK_codeABC(fs, OP_SETTABUP, var->u.ind.t, var->u.ind.idx, e); | ||
897 | break; | 909 | break; |
898 | } | 910 | } |
899 | case VINDEXI: { | 911 | case VINDEXI: { |
900 | int e = luaK_exp2RK(fs, ex); | 912 | codeABRK(fs, OP_SETI, var->u.ind.t, var->u.ind.idx, ex); |
901 | luaK_codeABC(fs, OP_SETI, var->u.ind.t, var->u.ind.idx, e); | ||
902 | break; | 913 | break; |
903 | } | 914 | } |
904 | case VINDEXSTR: { | 915 | case VINDEXSTR: { |
905 | int e = luaK_exp2RK(fs, ex); | 916 | codeABRK(fs, OP_SETFIELD, var->u.ind.t, var->u.ind.idx, ex); |
906 | luaK_codeABC(fs, OP_SETFIELD, var->u.ind.t, var->u.ind.idx, e); | ||
907 | break; | 917 | break; |
908 | } | 918 | } |
909 | case VINDEXED: { | 919 | case VINDEXED: { |
910 | int e = luaK_exp2RK(fs, ex); | 920 | codeABRK(fs, OP_SETTABLE, var->u.ind.t, var->u.ind.idx, ex); |
911 | luaK_codeABC(fs, OP_SETTABLE, var->u.ind.t, var->u.ind.idx, e); | ||
912 | break; | 921 | break; |
913 | } | 922 | } |
914 | default: lua_assert(0); /* invalid var kind to store */ | 923 | default: lua_assert(0); /* invalid var kind to store */ |
@@ -928,7 +937,7 @@ void luaK_self (FuncState *fs, expdesc *e, expdesc *key) { | |||
928 | e->u.info = fs->freereg; /* base register for op_self */ | 937 | e->u.info = fs->freereg; /* base register for op_self */ |
929 | e->k = VNONRELOC; /* self expression has a fixed register */ | 938 | e->k = VNONRELOC; /* self expression has a fixed register */ |
930 | luaK_reserveregs(fs, 2); /* function and 'self' produced by op_self */ | 939 | luaK_reserveregs(fs, 2); /* function and 'self' produced by op_self */ |
931 | luaK_codeABC(fs, OP_SELF, e->u.info, ereg, luaK_exp2RK(fs, key)); | 940 | codeABRK(fs, OP_SELF, e->u.info, ereg, key); |
932 | freeexp(fs, key); | 941 | freeexp(fs, key); |
933 | } | 942 | } |
934 | 943 | ||
@@ -1064,11 +1073,21 @@ static int isKstr (FuncState *fs, expdesc *e) { | |||
1064 | 1073 | ||
1065 | /* | 1074 | /* |
1066 | ** Check whether expression 'e' is a literal integer in | 1075 | ** Check whether expression 'e' is a literal integer in |
1067 | ** proper range | 1076 | ** proper range to fit in register C |
1077 | */ | ||
1078 | static int isCint (expdesc *e) { | ||
1079 | return (e->k == VKINT && !hasjumps(e) && | ||
1080 | l_castS2U(e->u.ival) <= l_castS2U(MAXARG_C)); | ||
1081 | } | ||
1082 | |||
1083 | |||
1084 | /* | ||
1085 | ** Check whether expression 'e' is a literal integer in | ||
1086 | ** proper range to fit in register sC | ||
1068 | */ | 1087 | */ |
1069 | static int isKint (expdesc *e) { | 1088 | static int isSCint (expdesc *e) { |
1070 | return (e->k == VKINT && !hasjumps(e) && | 1089 | return (e->k == VKINT && !hasjumps(e) && |
1071 | l_castS2U(e->u.ival) <= l_castS2U(MAXARG_Cr)); | 1090 | l_castS2U(e->u.ival + MAXARG_sC) <= l_castS2U(MAXARG_C)); |
1072 | } | 1091 | } |
1073 | 1092 | ||
1074 | 1093 | ||
@@ -1091,7 +1110,7 @@ void luaK_indexed (FuncState *fs, expdesc *t, expdesc *k) { | |||
1091 | t->u.ind.idx = k->u.info; /* literal string */ | 1110 | t->u.ind.idx = k->u.info; /* literal string */ |
1092 | t->k = VINDEXSTR; | 1111 | t->k = VINDEXSTR; |
1093 | } | 1112 | } |
1094 | else if (isKint(k)) { | 1113 | else if (isCint(k)) { |
1095 | t->u.ind.idx = k->u.ival; /* integer constant */ | 1114 | t->u.ind.idx = k->u.ival; /* integer constant */ |
1096 | t->k = VINDEXI; | 1115 | t->k = VINDEXI; |
1097 | } | 1116 | } |
@@ -1187,16 +1206,14 @@ static void codebinexpval (FuncState *fs, OpCode op, | |||
1187 | */ | 1206 | */ |
1188 | static void codearith (FuncState *fs, OpCode op, | 1207 | static void codearith (FuncState *fs, OpCode op, |
1189 | expdesc *e1, expdesc *e2, int flip, int line) { | 1208 | expdesc *e1, expdesc *e2, int flip, int line) { |
1190 | if (!isKint(e2)) | 1209 | if (!isSCint(e2)) |
1191 | codebinexpval(fs, op, e1, e2, line); /* use standard operators */ | 1210 | codebinexpval(fs, op, e1, e2, line); /* use standard operators */ |
1192 | else { /* use immediate operators */ | 1211 | else { /* use immediate operators */ |
1193 | int v2 = cast_int(e2->u.ival); /* immediate operand */ | 1212 | int v2 = cast_int(e2->u.ival); /* immediate operand */ |
1194 | int v1 = luaK_exp2anyreg(fs, e1); | 1213 | int v1 = luaK_exp2anyreg(fs, e1); |
1195 | if (flip) | ||
1196 | v2 |= BITRK; /* signal that operands were flipped */ | ||
1197 | op = cast(OpCode, op - OP_ADD + OP_ADDI); | 1214 | op = cast(OpCode, op - OP_ADD + OP_ADDI); |
1198 | freeexp(fs, e1); | 1215 | freeexp(fs, e1); |
1199 | e1->u.info = luaK_codeABC(fs, op, 0, v1, v2); /* generate opcode */ | 1216 | e1->u.info = codeABsC(fs, op, 0, v1, v2, flip); /* generate opcode */ |
1200 | e1->k = VRELOCABLE; /* all those operations are relocatable */ | 1217 | e1->k = VRELOCABLE; /* all those operations are relocatable */ |
1201 | luaK_fixline(fs, line); | 1218 | luaK_fixline(fs, line); |
1202 | } | 1219 | } |
@@ -1210,7 +1227,7 @@ static void codearith (FuncState *fs, OpCode op, | |||
1210 | static void codecommutative (FuncState *fs, OpCode op, | 1227 | static void codecommutative (FuncState *fs, OpCode op, |
1211 | expdesc *e1, expdesc *e2, int line) { | 1228 | expdesc *e1, expdesc *e2, int line) { |
1212 | int flip = 0; | 1229 | int flip = 0; |
1213 | if (isKint(e1)) { | 1230 | if (isSCint(e1)) { |
1214 | expdesc temp = *e1; *e1 = *e2; *e2 = temp; /* swap 'e1' and 'e2' */ | 1231 | expdesc temp = *e1; *e1 = *e2; *e2 = temp; /* swap 'e1' and 'e2' */ |
1215 | flip = 1; | 1232 | flip = 1; |
1216 | } | 1233 | } |
@@ -1223,8 +1240,7 @@ static void codecommutative (FuncState *fs, OpCode op, | |||
1223 | ** 'e1' was already put in register by 'luaK_infix'. | 1240 | ** 'e1' was already put in register by 'luaK_infix'. |
1224 | */ | 1241 | */ |
1225 | static void codecomp (FuncState *fs, BinOpr opr, expdesc *e1, expdesc *e2) { | 1242 | static void codecomp (FuncState *fs, BinOpr opr, expdesc *e1, expdesc *e2) { |
1226 | int rk1 = (e1->k == VK) ? RKASK(e1->u.info) | 1243 | int rk1 = check_exp(e1->k == VNONRELOC, e1->u.info); |
1227 | : check_exp(e1->k == VNONRELOC, e1->u.info); | ||
1228 | int rk2 = luaK_exp2anyreg(fs, e2); | 1244 | int rk2 = luaK_exp2anyreg(fs, e2); |
1229 | freeexps(fs, e1, e2); | 1245 | freeexps(fs, e1, e2); |
1230 | switch (opr) { | 1246 | switch (opr) { |