diff options
| -rw-r--r-- | lcode.c | 126 | ||||
| -rw-r--r-- | ldebug.c | 10 | ||||
| -rw-r--r-- | ljumptab.h | 7 | ||||
| -rw-r--r-- | lopcodes.c | 7 | ||||
| -rw-r--r-- | lopcodes.h | 10 | ||||
| -rw-r--r-- | lopnames.h | 7 | ||||
| -rw-r--r-- | ltests.h | 1 | ||||
| -rw-r--r-- | lvm.c | 61 | ||||
| -rw-r--r-- | testes/code.lua | 82 | ||||
| -rw-r--r-- | testes/db.lua | 2 | ||||
| -rw-r--r-- | testes/events.lua | 2 |
11 files changed, 228 insertions, 87 deletions
| @@ -371,10 +371,6 @@ int luaK_codeABCk (FuncState *fs, OpCode o, int a, int b, int c, int k) { | |||
| 371 | } | 371 | } |
| 372 | 372 | ||
| 373 | 373 | ||
| 374 | #define codeABsC(fs,o,a,b,c,k) luaK_codeABCk(fs,o,a,b,((c) + OFFSET_sC),k) | ||
| 375 | |||
| 376 | |||
| 377 | |||
| 378 | /* | 374 | /* |
| 379 | ** Format and emit an 'iABx' instruction. | 375 | ** Format and emit an 'iABx' instruction. |
| 380 | */ | 376 | */ |
| @@ -885,30 +881,45 @@ void luaK_exp2val (FuncState *fs, expdesc *e) { | |||
| 885 | 881 | ||
| 886 | 882 | ||
| 887 | /* | 883 | /* |
| 884 | ** Try to make 'e' a K expression with an index in the range of R/K | ||
| 885 | ** indices. Return true iff succeeded. | ||
| 886 | */ | ||
| 887 | static int luaK_exp2K (FuncState *fs, expdesc *e) { | ||
| 888 | if (!hasjumps(e)) { | ||
| 889 | int info; | ||
| 890 | switch (e->k) { /* move constants to 'k' */ | ||
| 891 | case VTRUE: info = boolK(fs, 1); break; | ||
| 892 | case VFALSE: info = boolK(fs, 0); break; | ||
| 893 | case VNIL: info = nilK(fs); break; | ||
| 894 | case VKINT: info = luaK_intK(fs, e->u.ival); break; | ||
| 895 | case VKFLT: info = luaK_numberK(fs, e->u.nval); break; | ||
| 896 | case VK: info = e->u.info; break; | ||
| 897 | default: return 0; /* not a constant */ | ||
| 898 | } | ||
| 899 | if (info <= MAXINDEXRK) { /* does constant fit in 'argC'? */ | ||
| 900 | e->k = VK; /* make expression a 'K' expression */ | ||
| 901 | e->u.info = info; | ||
| 902 | return 1; | ||
| 903 | } | ||
| 904 | } | ||
| 905 | /* else, expression doesn't fit; leave it unchanged */ | ||
| 906 | return 0; | ||
| 907 | } | ||
| 908 | |||
| 909 | |||
| 910 | /* | ||
| 888 | ** Ensures final expression result is in a valid R/K index | 911 | ** Ensures final expression result is in a valid R/K index |
| 889 | ** (that is, it is either in a register or in 'k' with an index | 912 | ** (that is, it is either in a register or in 'k' with an index |
| 890 | ** in the range of R/K indices). | 913 | ** in the range of R/K indices). |
| 891 | ** Returns 1 if expression is K, 0 otherwise. | 914 | ** Returns 1 iff expression is K. |
| 892 | */ | 915 | */ |
| 893 | int luaK_exp2RK (FuncState *fs, expdesc *e) { | 916 | int luaK_exp2RK (FuncState *fs, expdesc *e) { |
| 894 | luaK_exp2val(fs, e); | 917 | if (luaK_exp2K(fs, e)) |
| 895 | switch (e->k) { /* move constants to 'k' */ | 918 | return 1; |
| 896 | case VTRUE: e->u.info = boolK(fs, 1); goto vk; | 919 | else { /* not a constant in the right range: put it in a register */ |
| 897 | case VFALSE: e->u.info = boolK(fs, 0); goto vk; | 920 | luaK_exp2anyreg(fs, e); |
| 898 | case VNIL: e->u.info = nilK(fs); goto vk; | 921 | return 0; |
| 899 | case VKINT: e->u.info = luaK_intK(fs, e->u.ival); goto vk; | ||
| 900 | case VKFLT: e->u.info = luaK_numberK(fs, e->u.nval); goto vk; | ||
| 901 | case VK: | ||
| 902 | vk: | ||
| 903 | e->k = VK; | ||
| 904 | if (e->u.info <= MAXINDEXRK) /* constant fits in 'argC'? */ | ||
| 905 | return 1; | ||
| 906 | else break; | ||
| 907 | default: break; | ||
| 908 | } | 922 | } |
| 909 | /* not a constant in the right range: put it in a register */ | ||
| 910 | luaK_exp2anyreg(fs, e); | ||
| 911 | return 0; | ||
| 912 | } | 923 | } |
| 913 | 924 | ||
| 914 | 925 | ||
| @@ -1232,8 +1243,19 @@ static void codeunexpval (FuncState *fs, OpCode op, expdesc *e, int line) { | |||
| 1232 | } | 1243 | } |
| 1233 | 1244 | ||
| 1234 | 1245 | ||
| 1246 | /* | ||
| 1247 | ** Emit code for binary expressions that "produce values" | ||
| 1248 | ** (everything but logical operators 'and'/'or' and comparison | ||
| 1249 | ** operators). | ||
| 1250 | ** Expression to produce final result will be encoded in 'e1'. | ||
| 1251 | ** Because 'luaK_exp2anyreg' can free registers, its calls must be | ||
| 1252 | ** in "stack order" (that is, first on 'e2', which may have more | ||
| 1253 | ** recent registers to be released). | ||
| 1254 | */ | ||
| 1235 | static void finishbinexpval (FuncState *fs, expdesc *e1, expdesc *e2, | 1255 | static void finishbinexpval (FuncState *fs, expdesc *e1, expdesc *e2, |
| 1236 | int pc, int line) { | 1256 | OpCode op, int v2, int k, int line) { |
| 1257 | int v1 = luaK_exp2anyreg(fs, e1); | ||
| 1258 | int pc = luaK_codeABCk(fs, op, 0, v1, v2, k); | ||
| 1237 | freeexps(fs, e1, e2); | 1259 | freeexps(fs, e1, e2); |
| 1238 | e1->u.info = pc; | 1260 | e1->u.info = pc; |
| 1239 | e1->k = VRELOC; /* all those operations are relocatable */ | 1261 | e1->k = VRELOC; /* all those operations are relocatable */ |
| @@ -1242,20 +1264,13 @@ static void finishbinexpval (FuncState *fs, expdesc *e1, expdesc *e2, | |||
| 1242 | 1264 | ||
| 1243 | 1265 | ||
| 1244 | /* | 1266 | /* |
| 1245 | ** Emit code for binary expressions that "produce values" | 1267 | ** Emit code for binary expressions that "produce values" over |
| 1246 | ** (everything but logical operators 'and'/'or' and comparison | 1268 | ** two registers. |
| 1247 | ** operators). | ||
| 1248 | ** Expression to produce final result will be encoded in 'e1'. | ||
| 1249 | ** Because 'luaK_exp2anyreg' can free registers, its calls must be | ||
| 1250 | ** in "stack order" (that is, first on 'e2', which may have more | ||
| 1251 | ** recent registers to be released). | ||
| 1252 | */ | 1269 | */ |
| 1253 | static void codebinexpval (FuncState *fs, OpCode op, | 1270 | static void codebinexpval (FuncState *fs, OpCode op, |
| 1254 | expdesc *e1, expdesc *e2, int line) { | 1271 | expdesc *e1, expdesc *e2, int line) { |
| 1255 | int v2 = luaK_exp2anyreg(fs, e2); /* both operands are in registers */ | 1272 | int v2 = luaK_exp2anyreg(fs, e2); /* both operands are in registers */ |
| 1256 | int v1 = luaK_exp2anyreg(fs, e1); | 1273 | finishbinexpval(fs, e1, e2, op, v2, 0, line); |
| 1257 | int pc = luaK_codeABC(fs, op, 0, v1, v2); /* generate opcode */ | ||
| 1258 | finishbinexpval(fs, e1, e2, pc, line); | ||
| 1259 | } | 1274 | } |
| 1260 | 1275 | ||
| 1261 | 1276 | ||
| @@ -1264,41 +1279,48 @@ static void codebinexpval (FuncState *fs, OpCode op, | |||
| 1264 | */ | 1279 | */ |
| 1265 | static void codebini (FuncState *fs, OpCode op, | 1280 | static void codebini (FuncState *fs, OpCode op, |
| 1266 | expdesc *e1, expdesc *e2, int k, int line) { | 1281 | expdesc *e1, expdesc *e2, int k, int line) { |
| 1267 | int v2 = cast_int(e2->u.ival); /* immediate operand */ | 1282 | int v2 = cast_int(e2->u.ival) + OFFSET_sC; /* immediate operand */ |
| 1268 | int v1 = luaK_exp2anyreg(fs, e1); | 1283 | finishbinexpval(fs, e1, e2, op, v2, k, line); |
| 1269 | int pc = codeABsC(fs, op, 0, v1, v2, k); /* generate opcode */ | 1284 | } |
| 1270 | finishbinexpval(fs, e1, e2, pc, line); | 1285 | |
| 1286 | |||
| 1287 | static void swapexps (expdesc *e1, expdesc *e2) { | ||
| 1288 | expdesc temp = *e1; *e1 = *e2; *e2 = temp; /* swap 'e1' and 'e2' */ | ||
| 1271 | } | 1289 | } |
| 1272 | 1290 | ||
| 1273 | 1291 | ||
| 1274 | /* | 1292 | /* |
| 1275 | ** Code arithmetic operators ('+', '-', ...). If second operand is a | 1293 | ** Code arithmetic operators ('+', '-', ...). If second operand is a |
| 1276 | ** constant in the proper range, use variant opcodes with immediate | 1294 | ** constant in the proper range, use variant opcodes with immediate |
| 1277 | ** operands. | 1295 | ** operands or K operands. |
| 1278 | */ | 1296 | */ |
| 1279 | static void codearith (FuncState *fs, OpCode op, | 1297 | static void codearith (FuncState *fs, OpCode op, |
| 1280 | expdesc *e1, expdesc *e2, int flip, int line) { | 1298 | expdesc *e1, expdesc *e2, int flip, int line) { |
| 1281 | if (!isSCint(e2)) | 1299 | if (isSCint(e2)) /* immediate operand? */ |
| 1282 | codebinexpval(fs, op, e1, e2, line); /* use standard operators */ | ||
| 1283 | else /* use immediate operators */ | ||
| 1284 | codebini(fs, cast(OpCode, op - OP_ADD + OP_ADDI), e1, e2, flip, line); | 1300 | codebini(fs, cast(OpCode, op - OP_ADD + OP_ADDI), e1, e2, flip, line); |
| 1285 | } | 1301 | else if (tonumeral(e2, NULL) && luaK_exp2K(fs, e2)) { /* K operand? */ |
| 1286 | 1302 | int v2 = e2->u.info; /* K index */ | |
| 1287 | 1303 | op = cast(OpCode, op - OP_ADD + OP_ADDK); | |
| 1288 | static void swapexps (expdesc *e1, expdesc *e2) { | 1304 | finishbinexpval(fs, e1, e2, op, v2, flip, line); |
| 1289 | expdesc temp = *e1; *e1 = *e2; *e2 = temp; /* swap 'e1' and 'e2' */ | 1305 | } |
| 1306 | else { /* 'e2' is neither an immediate nor a K operand */ | ||
| 1307 | if (flip) | ||
| 1308 | swapexps(e1, e2); /* back to original order */ | ||
| 1309 | codebinexpval(fs, op, e1, e2, line); /* use standard operators */ | ||
| 1310 | } | ||
| 1290 | } | 1311 | } |
| 1291 | 1312 | ||
| 1292 | 1313 | ||
| 1293 | /* | 1314 | /* |
| 1294 | ** Code commutative operators ('+', '*'). If first operand is a | 1315 | ** Code commutative operators ('+', '*'). If first operand is a |
| 1295 | ** constant, change order of operands to use immediate operator. | 1316 | ** numeric constant, change order of operands to try to use an |
| 1317 | ** immediate or K operator. | ||
| 1296 | */ | 1318 | */ |
| 1297 | static void codecommutative (FuncState *fs, OpCode op, | 1319 | static void codecommutative (FuncState *fs, OpCode op, |
| 1298 | expdesc *e1, expdesc *e2, int line) { | 1320 | expdesc *e1, expdesc *e2, int line) { |
| 1299 | int flip = 0; | 1321 | int flip = 0; |
| 1300 | if (isSCint(e1)) { | 1322 | if (tonumeral(e1, NULL)) { /* is first operand a numeric constant? */ |
| 1301 | swapexps(e1, e2); | 1323 | swapexps(e1, e2); /* change order */ |
| 1302 | flip = 1; | 1324 | flip = 1; |
| 1303 | } | 1325 | } |
| 1304 | codearith(fs, op, e1, e2, flip, line); | 1326 | codearith(fs, op, e1, e2, flip, line); |
| @@ -1312,7 +1334,7 @@ static void codecommutative (FuncState *fs, OpCode op, | |||
| 1312 | static void codebitwise (FuncState *fs, BinOpr opr, | 1334 | static void codebitwise (FuncState *fs, BinOpr opr, |
| 1313 | expdesc *e1, expdesc *e2, int line) { | 1335 | expdesc *e1, expdesc *e2, int line) { |
| 1314 | int inv = 0; | 1336 | int inv = 0; |
| 1315 | int v1, v2, pc; | 1337 | int v2; |
| 1316 | OpCode op; | 1338 | OpCode op; |
| 1317 | if (e1->k == VKINT && luaK_exp2RK(fs, e1)) { | 1339 | if (e1->k == VKINT && luaK_exp2RK(fs, e1)) { |
| 1318 | swapexps(e1, e2); /* 'e2' will be the constant operand */ | 1340 | swapexps(e1, e2); /* 'e2' will be the constant operand */ |
| @@ -1323,12 +1345,10 @@ static void codebitwise (FuncState *fs, BinOpr opr, | |||
| 1323 | codebinexpval(fs, op, e1, e2, line); /* all-register opcodes */ | 1345 | codebinexpval(fs, op, e1, e2, line); /* all-register opcodes */ |
| 1324 | return; | 1346 | return; |
| 1325 | } | 1347 | } |
| 1326 | v1 = luaK_exp2anyreg(fs, e1); | ||
| 1327 | v2 = e2->u.info; /* index in K array */ | 1348 | v2 = e2->u.info; /* index in K array */ |
| 1328 | op = cast(OpCode, opr - OPR_BAND + OP_BANDK); | 1349 | op = cast(OpCode, opr - OPR_BAND + OP_BANDK); |
| 1329 | lua_assert(ttisinteger(&fs->f->k[v2])); | 1350 | lua_assert(ttisinteger(&fs->f->k[v2])); |
| 1330 | pc = luaK_codeABCk(fs, op, 0, v1, v2, inv); | 1351 | finishbinexpval(fs, e1, e2, op, v2, inv, line); |
| 1331 | finishbinexpval(fs, e1, e2, pc, line); | ||
| 1332 | } | 1352 | } |
| 1333 | 1353 | ||
| 1334 | 1354 | ||
| @@ -610,12 +610,18 @@ static const char *funcnamefromcode (lua_State *L, CallInfo *ci, | |||
| 610 | tm = TM_NEWINDEX; | 610 | tm = TM_NEWINDEX; |
| 611 | break; | 611 | break; |
| 612 | case OP_ADDI: case OP_SUBI: case OP_MULI: case OP_MODI: | 612 | case OP_ADDI: case OP_SUBI: case OP_MULI: case OP_MODI: |
| 613 | case OP_POWI: case OP_DIVI: case OP_IDIVI: | 613 | case OP_POWI: case OP_DIVI: case OP_IDIVI: { |
| 614 | case OP_BANDK: case OP_BORK: case OP_BXORK: { | ||
| 615 | int offset = GET_OPCODE(i) - OP_ADDI; /* ORDER OP */ | 614 | int offset = GET_OPCODE(i) - OP_ADDI; /* ORDER OP */ |
| 616 | tm = cast(TMS, offset + TM_ADD); /* ORDER TM */ | 615 | tm = cast(TMS, offset + TM_ADD); /* ORDER TM */ |
| 617 | break; | 616 | break; |
| 618 | } | 617 | } |
| 618 | case OP_ADDK: case OP_SUBK: case OP_MULK: case OP_MODK: | ||
| 619 | case OP_POWK: case OP_DIVK: case OP_IDIVK: | ||
| 620 | case OP_BANDK: case OP_BORK: case OP_BXORK: { | ||
| 621 | int offset = GET_OPCODE(i) - OP_ADDK; /* ORDER OP */ | ||
| 622 | tm = cast(TMS, offset + TM_ADD); /* ORDER TM */ | ||
| 623 | break; | ||
| 624 | } | ||
| 619 | case OP_ADD: case OP_SUB: case OP_MUL: case OP_MOD: | 625 | case OP_ADD: case OP_SUB: case OP_MUL: case OP_MOD: |
| 620 | case OP_POW: case OP_DIV: case OP_IDIV: case OP_BAND: | 626 | case OP_POW: case OP_DIV: case OP_IDIV: case OP_BAND: |
| 621 | case OP_BOR: case OP_BXOR: case OP_SHL: case OP_SHR: { | 627 | case OP_BOR: case OP_BXOR: case OP_SHL: case OP_SHR: { |
| @@ -51,6 +51,13 @@ static void *disptab[] = { | |||
| 51 | &&L_OP_POWI, | 51 | &&L_OP_POWI, |
| 52 | &&L_OP_DIVI, | 52 | &&L_OP_DIVI, |
| 53 | &&L_OP_IDIVI, | 53 | &&L_OP_IDIVI, |
| 54 | &&L_OP_ADDK, | ||
| 55 | &&L_OP_SUBK, | ||
| 56 | &&L_OP_MULK, | ||
| 57 | &&L_OP_MODK, | ||
| 58 | &&L_OP_POWK, | ||
| 59 | &&L_OP_DIVK, | ||
| 60 | &&L_OP_IDIVK, | ||
| 54 | &&L_OP_BANDK, | 61 | &&L_OP_BANDK, |
| 55 | &&L_OP_BORK, | 62 | &&L_OP_BORK, |
| 56 | &&L_OP_BXORK, | 63 | &&L_OP_BXORK, |
| @@ -45,6 +45,13 @@ LUAI_DDEF const lu_byte luaP_opmodes[NUM_OPCODES] = { | |||
| 45 | ,opmode(0, 0, 0, 1, iABC) /* OP_POWI */ | 45 | ,opmode(0, 0, 0, 1, iABC) /* OP_POWI */ |
| 46 | ,opmode(0, 0, 0, 1, iABC) /* OP_DIVI */ | 46 | ,opmode(0, 0, 0, 1, iABC) /* OP_DIVI */ |
| 47 | ,opmode(0, 0, 0, 1, iABC) /* OP_IDIVI */ | 47 | ,opmode(0, 0, 0, 1, iABC) /* OP_IDIVI */ |
| 48 | ,opmode(0, 0, 0, 1, iABC) /* OP_ADDK */ | ||
| 49 | ,opmode(0, 0, 0, 1, iABC) /* OP_SUBK */ | ||
| 50 | ,opmode(0, 0, 0, 1, iABC) /* OP_MULK */ | ||
| 51 | ,opmode(0, 0, 0, 1, iABC) /* OP_MODK */ | ||
| 52 | ,opmode(0, 0, 0, 1, iABC) /* OP_POWK */ | ||
| 53 | ,opmode(0, 0, 0, 1, iABC) /* OP_DIVK */ | ||
| 54 | ,opmode(0, 0, 0, 1, iABC) /* OP_IDIVK */ | ||
| 48 | ,opmode(0, 0, 0, 1, iABC) /* OP_BANDK */ | 55 | ,opmode(0, 0, 0, 1, iABC) /* OP_BANDK */ |
| 49 | ,opmode(0, 0, 0, 1, iABC) /* OP_BORK */ | 56 | ,opmode(0, 0, 0, 1, iABC) /* OP_BORK */ |
| 50 | ,opmode(0, 0, 0, 1, iABC) /* OP_BXORK */ | 57 | ,opmode(0, 0, 0, 1, iABC) /* OP_BXORK */ |
| @@ -221,6 +221,14 @@ OP_POWI,/* A B sC R(A) := R(B) ^ C */ | |||
| 221 | OP_DIVI,/* A B sC R(A) := R(B) / C */ | 221 | OP_DIVI,/* A B sC R(A) := R(B) / C */ |
| 222 | OP_IDIVI,/* A B sC R(A) := R(B) // C */ | 222 | OP_IDIVI,/* A B sC R(A) := R(B) // C */ |
| 223 | 223 | ||
| 224 | OP_ADDK,/* A B C R(A) := R(B) + K(C) */ | ||
| 225 | OP_SUBK,/* A B C R(A) := R(B) - K(C) */ | ||
| 226 | OP_MULK,/* A B C R(A) := R(B) * K(C) */ | ||
| 227 | OP_MODK,/* A B C R(A) := R(B) % K(C) */ | ||
| 228 | OP_POWK,/* A B C R(A) := R(B) ^ K(C) */ | ||
| 229 | OP_DIVK,/* A B C R(A) := R(B) / K(C) */ | ||
| 230 | OP_IDIVK,/* A B C R(A) := R(B) // K(C) */ | ||
| 231 | |||
| 224 | OP_BANDK,/* A B C R(A) := R(B) & K(C):integer */ | 232 | OP_BANDK,/* A B C R(A) := R(B) & K(C):integer */ |
| 225 | OP_BORK,/* A B C R(A) := R(B) | K(C):integer */ | 233 | OP_BORK,/* A B C R(A) := R(B) | K(C):integer */ |
| 226 | OP_BXORK,/* A B C R(A) := R(B) ~ K(C):integer */ | 234 | OP_BXORK,/* A B C R(A) := R(B) ~ K(C):integer */ |
| @@ -235,11 +243,13 @@ OP_MOD,/* A B C R(A) := R(B) % R(C) */ | |||
| 235 | OP_POW,/* A B C R(A) := R(B) ^ R(C) */ | 243 | OP_POW,/* A B C R(A) := R(B) ^ R(C) */ |
| 236 | OP_DIV,/* A B C R(A) := R(B) / R(C) */ | 244 | OP_DIV,/* A B C R(A) := R(B) / R(C) */ |
| 237 | OP_IDIV,/* A B C R(A) := R(B) // R(C) */ | 245 | OP_IDIV,/* A B C R(A) := R(B) // R(C) */ |
| 246 | |||
| 238 | OP_BAND,/* A B C R(A) := R(B) & R(C) */ | 247 | OP_BAND,/* A B C R(A) := R(B) & R(C) */ |
| 239 | OP_BOR,/* A B C R(A) := R(B) | R(C) */ | 248 | OP_BOR,/* A B C R(A) := R(B) | R(C) */ |
| 240 | OP_BXOR,/* A B C R(A) := R(B) ~ R(C) */ | 249 | OP_BXOR,/* A B C R(A) := R(B) ~ R(C) */ |
| 241 | OP_SHL,/* A B C R(A) := R(B) << R(C) */ | 250 | OP_SHL,/* A B C R(A) := R(B) << R(C) */ |
| 242 | OP_SHR,/* A B C R(A) := R(B) >> R(C) */ | 251 | OP_SHR,/* A B C R(A) := R(B) >> R(C) */ |
| 252 | |||
| 243 | OP_UNM,/* A B R(A) := -R(B) */ | 253 | OP_UNM,/* A B R(A) := -R(B) */ |
| 244 | OP_BNOT,/* A B R(A) := ~R(B) */ | 254 | OP_BNOT,/* A B R(A) := ~R(B) */ |
| 245 | OP_NOT,/* A B R(A) := not R(B) */ | 255 | OP_NOT,/* A B R(A) := not R(B) */ |
| @@ -36,6 +36,13 @@ static const char *const opnames[] = { | |||
| 36 | "POWI", | 36 | "POWI", |
| 37 | "DIVI", | 37 | "DIVI", |
| 38 | "IDIVI", | 38 | "IDIVI", |
| 39 | "ADDK", | ||
| 40 | "SUBK", | ||
| 41 | "MULK", | ||
| 42 | "MODK", | ||
| 43 | "POWK", | ||
| 44 | "DIVK", | ||
| 45 | "IDIVK", | ||
| 39 | "BANDK", | 46 | "BANDK", |
| 40 | "BORK", | 47 | "BORK", |
| 41 | "BXORK", | 48 | "BXORK", |
| @@ -119,7 +119,6 @@ LUA_API void *debug_realloc (void *ud, void *block, | |||
| 119 | #undef LUAL_BUFFERSIZE | 119 | #undef LUAL_BUFFERSIZE |
| 120 | #define LUAL_BUFFERSIZE 23 | 120 | #define LUAL_BUFFERSIZE 23 |
| 121 | #define MINSTRTABSIZE 2 | 121 | #define MINSTRTABSIZE 2 |
| 122 | #define MAXINDEXRK 1 | ||
| 123 | #define MAXIWTHABS 3 | 122 | #define MAXIWTHABS 3 |
| 124 | 123 | ||
| 125 | 124 | ||
| @@ -856,6 +856,39 @@ void luaV_finishOp (lua_State *L) { | |||
| 856 | 856 | ||
| 857 | 857 | ||
| 858 | /* | 858 | /* |
| 859 | ** Arithmetic operations with K operands. | ||
| 860 | */ | ||
| 861 | #define op_arithK(L,iop,fop,tm,flip) { \ | ||
| 862 | TValue *v1 = vRB(i); \ | ||
| 863 | TValue *v2 = KC(i); \ | ||
| 864 | if (ttisinteger(v1) && ttisinteger(v2)) { \ | ||
| 865 | lua_Integer i1 = ivalue(v1); lua_Integer i2 = ivalue(v2); \ | ||
| 866 | setivalue(s2v(ra), iop(L, i1, i2)); \ | ||
| 867 | } \ | ||
| 868 | else { \ | ||
| 869 | lua_Number n1; lua_Number n2; \ | ||
| 870 | if (tonumberns(v1, n1) && tonumberns(v2, n2)) { \ | ||
| 871 | setfltvalue(s2v(ra), fop(L, n1, n2)); \ | ||
| 872 | } \ | ||
| 873 | else \ | ||
| 874 | Protect(luaT_trybinassocTM(L, v1, v2, ra, flip, tm)); } } | ||
| 875 | |||
| 876 | |||
| 877 | /* | ||
| 878 | ** Arithmetic operations with K operands for floats. | ||
| 879 | */ | ||
| 880 | #define op_arithfK(L,fop,tm) { \ | ||
| 881 | TValue *v1 = vRB(i); \ | ||
| 882 | TValue *v2 = KC(i); \ | ||
| 883 | lua_Number n1; lua_Number n2; \ | ||
| 884 | if (tonumberns(v1, n1) && tonumberns(v2, n2)) { \ | ||
| 885 | setfltvalue(s2v(ra), fop(L, n1, n2)); \ | ||
| 886 | } \ | ||
| 887 | else \ | ||
| 888 | Protect(luaT_trybinTM(L, v1, v2, ra, tm)); } | ||
| 889 | |||
| 890 | |||
| 891 | /* | ||
| 859 | ** Bitwise operations with constant operand. | 892 | ** Bitwise operations with constant operand. |
| 860 | */ | 893 | */ |
| 861 | #define op_bitwiseK(L,op,tm) { \ | 894 | #define op_bitwiseK(L,op,tm) { \ |
| @@ -1219,6 +1252,34 @@ void luaV_execute (lua_State *L, CallInfo *ci) { | |||
| 1219 | op_arithI(L, luaV_idiv, luai_numidiv, TM_IDIV, 0); | 1252 | op_arithI(L, luaV_idiv, luai_numidiv, TM_IDIV, 0); |
| 1220 | vmbreak; | 1253 | vmbreak; |
| 1221 | } | 1254 | } |
| 1255 | vmcase(OP_ADDK) { | ||
| 1256 | op_arithK(L, l_addi, luai_numadd, TM_ADD, GETARG_k(i)); | ||
| 1257 | vmbreak; | ||
| 1258 | } | ||
| 1259 | vmcase(OP_SUBK) { | ||
| 1260 | op_arithK(L, l_subi, luai_numsub, TM_SUB, 0); | ||
| 1261 | vmbreak; | ||
| 1262 | } | ||
| 1263 | vmcase(OP_MULK) { | ||
| 1264 | op_arithK(L, l_muli, luai_nummul, TM_MUL, GETARG_k(i)); | ||
| 1265 | vmbreak; | ||
| 1266 | } | ||
| 1267 | vmcase(OP_MODK) { | ||
| 1268 | op_arithK(L, luaV_mod, luaV_modf, TM_MOD, 0); | ||
| 1269 | vmbreak; | ||
| 1270 | } | ||
| 1271 | vmcase(OP_POWK) { | ||
| 1272 | op_arithfK(L, luai_numpow, TM_POW); | ||
| 1273 | vmbreak; | ||
| 1274 | } | ||
| 1275 | vmcase(OP_DIVK) { | ||
| 1276 | op_arithfK(L, luai_numdiv, TM_DIV); | ||
| 1277 | vmbreak; | ||
| 1278 | } | ||
| 1279 | vmcase(OP_IDIVK) { | ||
| 1280 | op_arithK(L, luaV_idiv, luai_numidiv, TM_IDIV, 0); | ||
| 1281 | vmbreak; | ||
| 1282 | } | ||
| 1222 | vmcase(OP_ADD) { | 1283 | vmcase(OP_ADD) { |
| 1223 | op_arith(L, l_addi, luai_numadd, TM_ADD); | 1284 | op_arith(L, l_addi, luai_numadd, TM_ADD); |
| 1224 | vmbreak; | 1285 | vmbreak; |
diff --git a/testes/code.lua b/testes/code.lua index 4d44fa6a..834ff5e2 100644 --- a/testes/code.lua +++ b/testes/code.lua | |||
| @@ -40,6 +40,7 @@ checkKlist(foo, {3.78/4, -3.78/4, -3.79/4}) | |||
| 40 | 40 | ||
| 41 | -- testing opcodes | 41 | -- testing opcodes |
| 42 | 42 | ||
| 43 | -- check that 'f' opcodes match '...' | ||
| 43 | function check (f, ...) | 44 | function check (f, ...) |
| 44 | local arg = {...} | 45 | local arg = {...} |
| 45 | local c = T.listcode(f) | 46 | local c = T.listcode(f) |
| @@ -52,9 +53,19 @@ function check (f, ...) | |||
| 52 | end | 53 | end |
| 53 | 54 | ||
| 54 | 55 | ||
| 56 | -- check that 'f' opcodes match '...' and that 'f(p) == r'. | ||
| 57 | function checkR (f, p, r, ...) | ||
| 58 | local r1 = f(p) | ||
| 59 | assert(r == r1 and math.type(r) == math.type(r1)) | ||
| 60 | check(f, ...) | ||
| 61 | end | ||
| 62 | |||
| 63 | |||
| 64 | -- check that 'a' and 'b' has the same opcodes | ||
| 55 | function checkequal (a, b) | 65 | function checkequal (a, b) |
| 56 | a = T.listcode(a) | 66 | a = T.listcode(a) |
| 57 | b = T.listcode(b) | 67 | b = T.listcode(b) |
| 68 | assert(#a == #b) | ||
| 58 | for i = 1, #a do | 69 | for i = 1, #a do |
| 59 | a[i] = string.gsub(a[i], '%b()', '') -- remove line number | 70 | a[i] = string.gsub(a[i], '%b()', '') -- remove line number |
| 60 | b[i] = string.gsub(b[i], '%b()', '') -- remove line number | 71 | b[i] = string.gsub(b[i], '%b()', '') -- remove line number |
| @@ -165,65 +176,64 @@ end, | |||
| 165 | 176 | ||
| 166 | 177 | ||
| 167 | -- equalities | 178 | -- equalities |
| 168 | check(function (a) if a == 1 then return 2 end end, | 179 | checkR(function (a) if a == 1 then return 2 end end, 1, 2, |
| 169 | 'EQI', 'JMP', 'LOADI', 'RETURN1') | 180 | 'EQI', 'JMP', 'LOADI', 'RETURN1') |
| 170 | 181 | ||
| 171 | check(function (a) if -4.0 == a then return 2 end end, | 182 | checkR(function (a) if -4.0 == a then return 2 end end, -4, 2, |
| 172 | 'EQI', 'JMP', 'LOADI', 'RETURN1') | 183 | 'EQI', 'JMP', 'LOADI', 'RETURN1') |
| 173 | 184 | ||
| 174 | check(function (a) if a == "hi" then return 2 end end, | 185 | checkR(function (a) if a == "hi" then return 2 end end, 10, nil, |
| 175 | 'EQK', 'JMP', 'LOADI', 'RETURN1') | 186 | 'EQK', 'JMP', 'LOADI', 'RETURN1') |
| 176 | 187 | ||
| 177 | check(function (a) if a == 10000 then return 2 end end, | 188 | checkR(function (a) if a == 10000 then return 2 end end, 1, nil, |
| 178 | 'EQK', 'JMP', 'LOADI', 'RETURN1') -- number too large | 189 | 'EQK', 'JMP', 'LOADI', 'RETURN1') -- number too large |
| 179 | 190 | ||
| 180 | check(function (a) if -10000 == a then return 2 end end, | 191 | checkR(function (a) if -10000 == a then return 2 end end, -10000, 2, |
| 181 | 'EQK', 'JMP', 'LOADI', 'RETURN1') -- number too large | 192 | 'EQK', 'JMP', 'LOADI', 'RETURN1') -- number too large |
| 182 | 193 | ||
| 183 | -- comparisons | 194 | -- comparisons |
| 184 | 195 | ||
| 185 | check(function (a) if -10 <= a then return 2 end end, | 196 | checkR(function (a) if -10 <= a then return 2 end end, -10, 2, |
| 186 | 'GEI', 'JMP', 'LOADI', 'RETURN1') | 197 | 'GEI', 'JMP', 'LOADI', 'RETURN1') |
| 187 | 198 | ||
| 188 | check(function (a) if 128.0 > a then return 2 end end, | 199 | checkR(function (a) if 128.0 > a then return 2 end end, 129, nil, |
| 189 | 'LTI', 'JMP', 'LOADI', 'RETURN1') | 200 | 'LTI', 'JMP', 'LOADI', 'RETURN1') |
| 190 | 201 | ||
| 191 | check(function (a) if -127.0 < a then return 2 end end, | 202 | checkR(function (a) if -127.0 < a then return 2 end end, -127, nil, |
| 192 | 'GTI', 'JMP', 'LOADI', 'RETURN1') | 203 | 'GTI', 'JMP', 'LOADI', 'RETURN1') |
| 193 | 204 | ||
| 194 | check(function (a) if 10 < a then return 2 end end, | 205 | checkR(function (a) if 10 < a then return 2 end end, 11, 2, |
| 195 | 'GTI', 'JMP', 'LOADI', 'RETURN1') | 206 | 'GTI', 'JMP', 'LOADI', 'RETURN1') |
| 196 | 207 | ||
| 197 | check(function (a) if 129 < a then return 2 end end, | 208 | checkR(function (a) if 129 < a then return 2 end end, 130, 2, |
| 198 | 'LOADI', 'LT', 'JMP', 'LOADI', 'RETURN1') | 209 | 'LOADI', 'LT', 'JMP', 'LOADI', 'RETURN1') |
| 199 | 210 | ||
| 200 | check(function (a) if a >= 23.0 then return 2 end end, | 211 | checkR(function (a) if a >= 23.0 then return 2 end end, 25, 2, |
| 201 | 'GEI', 'JMP', 'LOADI', 'RETURN1') | 212 | 'GEI', 'JMP', 'LOADI', 'RETURN1') |
| 202 | 213 | ||
| 203 | check(function (a) if a >= 23.1 then return 2 end end, | 214 | checkR(function (a) if a >= 23.1 then return 2 end end, 0, nil, |
| 204 | 'LOADK', 'LE', 'JMP', 'LOADI', 'RETURN1') | 215 | 'LOADK', 'LE', 'JMP', 'LOADI', 'RETURN1') |
| 205 | 216 | ||
| 206 | check(function (a) if a > 2300.0 then return 2 end end, | 217 | checkR(function (a) if a > 2300.0 then return 2 end end, 0, nil, |
| 207 | 'LOADF', 'LT', 'JMP', 'LOADI', 'RETURN1') | 218 | 'LOADF', 'LT', 'JMP', 'LOADI', 'RETURN1') |
| 208 | 219 | ||
| 209 | 220 | ||
| 210 | -- constant folding | 221 | -- constant folding |
| 211 | local function checkK (func, val) | 222 | local function checkK (func, val) |
| 212 | check(func, 'LOADK', 'RETURN1') | 223 | check(func, 'LOADK', 'RETURN1') |
| 213 | local k = T.listk(func) | 224 | checkKlist(func, {val}) |
| 214 | assert(#k == 1 and k[1] == val and math.type(k[1]) == math.type(val)) | ||
| 215 | assert(func() == val) | 225 | assert(func() == val) |
| 216 | end | 226 | end |
| 217 | 227 | ||
| 218 | local function checkI (func, val) | 228 | local function checkI (func, val) |
| 219 | check(func, 'LOADI', 'RETURN1') | 229 | check(func, 'LOADI', 'RETURN1') |
| 220 | assert(#T.listk(func) == 0) | 230 | checkKlist(func, {}) |
| 221 | assert(func() == val) | 231 | assert(func() == val) |
| 222 | end | 232 | end |
| 223 | 233 | ||
| 224 | local function checkF (func, val) | 234 | local function checkF (func, val) |
| 225 | check(func, 'LOADF', 'RETURN1') | 235 | check(func, 'LOADF', 'RETURN1') |
| 226 | assert(#T.listk(func) == 0) | 236 | checkKlist(func, {}) |
| 227 | assert(func() == val) | 237 | assert(func() == val) |
| 228 | end | 238 | end |
| 229 | 239 | ||
| @@ -258,20 +268,30 @@ checkK(function () return -65536.0 end, -(sbx + 1.0)) | |||
| 258 | 268 | ||
| 259 | 269 | ||
| 260 | -- immediate operands | 270 | -- immediate operands |
| 261 | check(function (x) return x + 1 end, 'ADDI', 'RETURN1') | 271 | checkR(function (x) return x + 1 end, 10, 11, 'ADDI', 'RETURN1') |
| 262 | check(function (x) return 128 + x end, 'ADDI', 'RETURN1') | 272 | checkR(function (x) return 128 + x end, 0.0, 128.0, 'ADDI', 'RETURN1') |
| 263 | check(function (x) return x * -127 end, 'MULI', 'RETURN1') | 273 | checkR(function (x) return x * -127 end, -1.0, 127.0, 'MULI', 'RETURN1') |
| 264 | check(function (x) return 20 * x end, 'MULI', 'RETURN1') | 274 | checkR(function (x) return 20 * x end, 2, 40, 'MULI', 'RETURN1') |
| 265 | check(function (x) return x ^ -2 end, 'POWI', 'RETURN1') | 275 | checkR(function (x) return x ^ -2 end, 2, 0.25, 'POWI', 'RETURN1') |
| 266 | check(function (x) return x / 40 end, 'DIVI', 'RETURN1') | 276 | checkR(function (x) return x / 40 end, 40, 1.0, 'DIVI', 'RETURN1') |
| 267 | check(function (x) return x // 1 end, 'IDIVI', 'RETURN1') | 277 | checkR(function (x) return x // 1 end, 10.0, 10.0, 'IDIVI', 'RETURN1') |
| 268 | check(function (x) return x % (100 - 10) end, 'MODI', 'RETURN1') | 278 | checkR(function (x) return x % (100 - 10) end, 91, 1, 'MODI', 'RETURN1') |
| 269 | check(function (x) return 1 << x end, 'SHLI', 'RETURN1') | 279 | checkR(function (x) return 1 << x end, 3, 8, 'SHLI', 'RETURN1') |
| 270 | check(function (x) return x << 2 end, 'SHRI', 'RETURN1') | 280 | checkR(function (x) return x << 2 end, 10, 40, 'SHRI', 'RETURN1') |
| 271 | check(function (x) return x >> 2 end, 'SHRI', 'RETURN1') | 281 | checkR(function (x) return x >> 2 end, 8, 2, 'SHRI', 'RETURN1') |
| 272 | check(function (x) return x & 1 end, 'BANDK', 'RETURN1') | 282 | checkR(function (x) return x & 1 end, 9, 1, 'BANDK', 'RETURN1') |
| 273 | check(function (x) return 10 | x end, 'BORK', 'RETURN1') | 283 | checkR(function (x) return 10 | x end, 1, 11, 'BORK', 'RETURN1') |
| 274 | check(function (x) return -10 ~ x end, 'BXORK', 'RETURN1') | 284 | checkR(function (x) return -10 ~ x end, -1, 9, 'BXORK', 'RETURN1') |
| 285 | |||
| 286 | -- K operands in arithmetic operations | ||
| 287 | checkR(function (x) return x + 0.0 end, 1, 1.0, 'ADDK', 'RETURN1') | ||
| 288 | -- check(function (x) return 128 + x end, 'ADDK', 'RETURN1') | ||
| 289 | checkR(function (x) return x * -10000 end, 2, -20000, 'MULK', 'RETURN1') | ||
| 290 | -- check(function (x) return 20 * x end, 'MULK', 'RETURN1') | ||
| 291 | checkR(function (x) return x ^ 0.5 end, 4, 2.0, 'POWK', 'RETURN1') | ||
| 292 | checkR(function (x) return x / 2.0 end, 4, 2.0, 'DIVK', 'RETURN1') | ||
| 293 | checkR(function (x) return x // 10000 end, 10000, 1, 'IDIVK', 'RETURN1') | ||
| 294 | checkR(function (x) return x % (100.0 - 10) end, 91, 1.0, 'MODK', 'RETURN1') | ||
| 275 | 295 | ||
| 276 | -- no foldings (and immediate operands) | 296 | -- no foldings (and immediate operands) |
| 277 | check(function () return -0.0 end, 'LOADF', 'UNM', 'RETURN1') | 297 | check(function () return -0.0 end, 'LOADF', 'UNM', 'RETURN1') |
diff --git a/testes/db.lua b/testes/db.lua index 9da68210..5b243c39 100644 --- a/testes/db.lua +++ b/testes/db.lua | |||
| @@ -794,6 +794,8 @@ assert(a[3] == "index" and a^3 == "pow" and a..a == "concat") | |||
| 794 | assert(a/3 == "div" and 3%a == "mod") | 794 | assert(a/3 == "div" and 3%a == "mod") |
| 795 | assert(a+3 == "add" and 3-a == "sub" and a*3 == "mul" and | 795 | assert(a+3 == "add" and 3-a == "sub" and a*3 == "mul" and |
| 796 | -a == "unm" and #a == "len" and a&3 == "band") | 796 | -a == "unm" and #a == "len" and a&3 == "band") |
| 797 | assert(a + 30000 == "add" and a - 3.0 == "sub" and a * 3.0 == "mul" and | ||
| 798 | -a == "unm" and #a == "len" and a & 3 == "band") | ||
| 797 | assert(a|3 == "bor" and 3~a == "bxor" and a<<3 == "shift" and | 799 | assert(a|3 == "bor" and 3~a == "bxor" and a<<3 == "shift" and |
| 798 | a>>1 == "shift") | 800 | a>>1 == "shift") |
| 799 | assert (a==b and a.op == "eq") | 801 | assert (a==b and a.op == "eq") |
diff --git a/testes/events.lua b/testes/events.lua index b071c2a3..ac630d89 100644 --- a/testes/events.lua +++ b/testes/events.lua | |||
| @@ -144,6 +144,8 @@ t.__bnot = f("bnot") | |||
| 144 | -- when the constant table is very small. | 144 | -- when the constant table is very small. |
| 145 | assert(b+5 == b) | 145 | assert(b+5 == b) |
| 146 | assert(cap[0] == "add" and cap[1] == b and cap[2] == 5 and cap[3]==undef) | 146 | assert(cap[0] == "add" and cap[1] == b and cap[2] == 5 and cap[3]==undef) |
| 147 | assert(5.2 + b == 5.2) | ||
| 148 | assert(cap[0] == "add" and cap[1] == 5.2 and cap[2] == b and cap[3]==undef) | ||
| 147 | assert(b+'5' == b) | 149 | assert(b+'5' == b) |
| 148 | assert(cap[0] == "add" and cap[1] == b and cap[2] == '5' and cap[3]==undef) | 150 | assert(cap[0] == "add" and cap[1] == b and cap[2] == '5' and cap[3]==undef) |
| 149 | assert(5+b == 5) | 151 | assert(5+b == 5) |
