diff options
-rw-r--r-- | lcode.c | 46 | ||||
-rw-r--r-- | ldebug.c | 21 | ||||
-rw-r--r-- | ljumptab.h | 3 | ||||
-rw-r--r-- | lopcodes.c | 3 | ||||
-rw-r--r-- | lopcodes.h | 4 | ||||
-rw-r--r-- | lopnames.h | 3 | ||||
-rw-r--r-- | ltm.c | 4 | ||||
-rw-r--r-- | ltm.h | 2 | ||||
-rw-r--r-- | lvm.c | 85 | ||||
-rw-r--r-- | testes/code.lua | 63 | ||||
-rw-r--r-- | testes/coroutine.lua | 2 |
11 files changed, 132 insertions, 104 deletions
@@ -1337,18 +1337,20 @@ static void codeunexpval (FuncState *fs, OpCode op, expdesc *e, int line) { | |||
1337 | ** (everything but logical operators 'and'/'or' and comparison | 1337 | ** (everything but logical operators 'and'/'or' and comparison |
1338 | ** operators). | 1338 | ** operators). |
1339 | ** Expression to produce final result will be encoded in 'e1'. | 1339 | ** Expression to produce final result will be encoded in 'e1'. |
1340 | ** Because 'luaK_exp2anyreg' can free registers, its calls must be | ||
1341 | ** in "stack order" (that is, first on 'e2', which may have more | ||
1342 | ** recent registers to be released). | ||
1343 | */ | 1340 | */ |
1344 | static void finishbinexpval (FuncState *fs, expdesc *e1, expdesc *e2, | 1341 | static void finishbinexpval (FuncState *fs, expdesc *e1, expdesc *e2, |
1345 | OpCode op, int v2, int k, int line) { | 1342 | OpCode op, int v2, int k, int line, |
1343 | OpCode mmop, TMS event) { | ||
1346 | int v1 = luaK_exp2anyreg(fs, e1); | 1344 | int v1 = luaK_exp2anyreg(fs, e1); |
1347 | int pc = luaK_codeABCk(fs, op, 0, v1, v2, k); | 1345 | int pc = luaK_codeABCk(fs, op, 0, v1, v2, k); |
1348 | freeexps(fs, e1, e2); | 1346 | freeexps(fs, e1, e2); |
1349 | e1->u.info = pc; | 1347 | e1->u.info = pc; |
1350 | e1->k = VRELOC; /* all those operations are relocatable */ | 1348 | e1->k = VRELOC; /* all those operations are relocatable */ |
1351 | luaK_fixline(fs, line); | 1349 | luaK_fixline(fs, line); |
1350 | if (event != TM_SHL && event != TM_SHR) { | ||
1351 | luaK_codeABCk(fs, mmop, v1, v2, event, k); /* to call metamethod */ | ||
1352 | luaK_fixline(fs, line); | ||
1353 | } | ||
1352 | } | 1354 | } |
1353 | 1355 | ||
1354 | 1356 | ||
@@ -1359,7 +1361,9 @@ static void finishbinexpval (FuncState *fs, expdesc *e1, expdesc *e2, | |||
1359 | static void codebinexpval (FuncState *fs, OpCode op, | 1361 | static void codebinexpval (FuncState *fs, OpCode op, |
1360 | expdesc *e1, expdesc *e2, int line) { | 1362 | expdesc *e1, expdesc *e2, int line) { |
1361 | int v2 = luaK_exp2anyreg(fs, e2); /* both operands are in registers */ | 1363 | int v2 = luaK_exp2anyreg(fs, e2); /* both operands are in registers */ |
1362 | finishbinexpval(fs, e1, e2, op, v2, 0, line); | 1364 | lua_assert(OP_ADD <= op && op <= OP_SHR); |
1365 | finishbinexpval(fs, e1, e2, op, v2, 0, line, OP_MMBIN, | ||
1366 | cast(TMS, (op - OP_ADD) + TM_ADD)); | ||
1363 | } | 1367 | } |
1364 | 1368 | ||
1365 | 1369 | ||
@@ -1367,9 +1371,10 @@ static void codebinexpval (FuncState *fs, OpCode op, | |||
1367 | ** Code binary operators ('+', '-', ...) with immediate operands. | 1371 | ** Code binary operators ('+', '-', ...) with immediate operands. |
1368 | */ | 1372 | */ |
1369 | static void codebini (FuncState *fs, OpCode op, | 1373 | static void codebini (FuncState *fs, OpCode op, |
1370 | expdesc *e1, expdesc *e2, int k, int line) { | 1374 | expdesc *e1, expdesc *e2, int k, int line, |
1375 | TMS event) { | ||
1371 | int v2 = cast_int(e2->u.ival) + OFFSET_sC; /* immediate operand */ | 1376 | int v2 = cast_int(e2->u.ival) + OFFSET_sC; /* immediate operand */ |
1372 | finishbinexpval(fs, e1, e2, op, v2, k, line); | 1377 | finishbinexpval(fs, e1, e2, op, v2, k, line, OP_MMBINI, event); |
1373 | } | 1378 | } |
1374 | 1379 | ||
1375 | 1380 | ||
@@ -1383,16 +1388,18 @@ static void swapexps (expdesc *e1, expdesc *e2) { | |||
1383 | ** constant in the proper range, use variant opcodes with immediate | 1388 | ** constant in the proper range, use variant opcodes with immediate |
1384 | ** operands or K operands. | 1389 | ** operands or K operands. |
1385 | */ | 1390 | */ |
1386 | static void codearith (FuncState *fs, OpCode op, | 1391 | static void codearith (FuncState *fs, BinOpr opr, |
1387 | expdesc *e1, expdesc *e2, int flip, int line) { | 1392 | expdesc *e1, expdesc *e2, int flip, int line) { |
1393 | TMS event = cast(TMS, opr + TM_ADD); | ||
1388 | if (isSCint(e2)) /* immediate operand? */ | 1394 | if (isSCint(e2)) /* immediate operand? */ |
1389 | codebini(fs, cast(OpCode, op - OP_ADD + OP_ADDI), e1, e2, flip, line); | 1395 | codebini(fs, cast(OpCode, opr + OP_ADDI), e1, e2, flip, line, event); |
1390 | else if (tonumeral(e2, NULL) && luaK_exp2K(fs, e2)) { /* K operand? */ | 1396 | else if (tonumeral(e2, NULL) && luaK_exp2K(fs, e2)) { /* K operand? */ |
1391 | int v2 = e2->u.info; /* K index */ | 1397 | int v2 = e2->u.info; /* K index */ |
1392 | op = cast(OpCode, op - OP_ADD + OP_ADDK); | 1398 | OpCode op = cast(OpCode, opr + OP_ADDK); |
1393 | finishbinexpval(fs, e1, e2, op, v2, flip, line); | 1399 | finishbinexpval(fs, e1, e2, op, v2, flip, line, OP_MMBINK, event); |
1394 | } | 1400 | } |
1395 | else { /* 'e2' is neither an immediate nor a K operand */ | 1401 | else { /* 'e2' is neither an immediate nor a K operand */ |
1402 | OpCode op = cast(OpCode, opr + OP_ADD); | ||
1396 | if (flip) | 1403 | if (flip) |
1397 | swapexps(e1, e2); /* back to original order */ | 1404 | swapexps(e1, e2); /* back to original order */ |
1398 | codebinexpval(fs, op, e1, e2, line); /* use standard operators */ | 1405 | codebinexpval(fs, op, e1, e2, line); /* use standard operators */ |
@@ -1405,7 +1412,7 @@ static void codearith (FuncState *fs, OpCode op, | |||
1405 | ** numeric constant, change order of operands to try to use an | 1412 | ** numeric constant, change order of operands to try to use an |
1406 | ** immediate or K operator. | 1413 | ** immediate or K operator. |
1407 | */ | 1414 | */ |
1408 | static void codecommutative (FuncState *fs, OpCode op, | 1415 | static void codecommutative (FuncState *fs, BinOpr op, |
1409 | expdesc *e1, expdesc *e2, int line) { | 1416 | expdesc *e1, expdesc *e2, int line) { |
1410 | int flip = 0; | 1417 | int flip = 0; |
1411 | if (tonumeral(e1, NULL)) { /* is first operand a numeric constant? */ | 1418 | if (tonumeral(e1, NULL)) { /* is first operand a numeric constant? */ |
@@ -1430,14 +1437,15 @@ static void codebitwise (FuncState *fs, BinOpr opr, | |||
1430 | inv = 1; | 1437 | inv = 1; |
1431 | } | 1438 | } |
1432 | else if (!(e2->k == VKINT && luaK_exp2RK(fs, e2))) { /* no constants? */ | 1439 | else if (!(e2->k == VKINT && luaK_exp2RK(fs, e2))) { /* no constants? */ |
1433 | op = cast(OpCode, opr - OPR_BAND + OP_BAND); | 1440 | op = cast(OpCode, opr + OP_ADD); |
1434 | codebinexpval(fs, op, e1, e2, line); /* all-register opcodes */ | 1441 | codebinexpval(fs, op, e1, e2, line); /* all-register opcodes */ |
1435 | return; | 1442 | return; |
1436 | } | 1443 | } |
1437 | v2 = e2->u.info; /* index in K array */ | 1444 | v2 = e2->u.info; /* index in K array */ |
1438 | op = cast(OpCode, opr - OPR_BAND + OP_BANDK); | 1445 | op = cast(OpCode, opr + OP_ADDK); |
1439 | lua_assert(ttisinteger(&fs->f->k[v2])); | 1446 | lua_assert(ttisinteger(&fs->f->k[v2])); |
1440 | finishbinexpval(fs, e1, e2, op, v2, inv, line); | 1447 | finishbinexpval(fs, e1, e2, op, v2, inv, line, OP_MMBINK, |
1448 | cast(TMS, opr + TM_ADD)); | ||
1441 | } | 1449 | } |
1442 | 1450 | ||
1443 | 1451 | ||
@@ -1453,7 +1461,7 @@ static void codeshift (FuncState *fs, OpCode op, | |||
1453 | changedir = 1; | 1461 | changedir = 1; |
1454 | e2->u.ival = -(e2->u.ival); | 1462 | e2->u.ival = -(e2->u.ival); |
1455 | } | 1463 | } |
1456 | codebini(fs, OP_SHRI, e1, e2, changedir, line); | 1464 | codebini(fs, OP_SHRI, e1, e2, changedir, line, TM_SHL); |
1457 | } | 1465 | } |
1458 | else | 1466 | else |
1459 | codebinexpval(fs, op, e1, e2, line); | 1467 | codebinexpval(fs, op, e1, e2, line); |
@@ -1638,13 +1646,13 @@ void luaK_posfix (FuncState *fs, BinOpr opr, | |||
1638 | } | 1646 | } |
1639 | case OPR_ADD: case OPR_MUL: { | 1647 | case OPR_ADD: case OPR_MUL: { |
1640 | if (!constfolding(fs, opr + LUA_OPADD, e1, e2)) | 1648 | if (!constfolding(fs, opr + LUA_OPADD, e1, e2)) |
1641 | codecommutative(fs, cast(OpCode, opr + OP_ADD), e1, e2, line); | 1649 | codecommutative(fs, opr, e1, e2, line); |
1642 | break; | 1650 | break; |
1643 | } | 1651 | } |
1644 | case OPR_SUB: case OPR_DIV: | 1652 | case OPR_SUB: case OPR_DIV: |
1645 | case OPR_IDIV: case OPR_MOD: case OPR_POW: { | 1653 | case OPR_IDIV: case OPR_MOD: case OPR_POW: { |
1646 | if (!constfolding(fs, opr + LUA_OPADD, e1, e2)) | 1654 | if (!constfolding(fs, opr + LUA_OPADD, e1, e2)) |
1647 | codearith(fs, cast(OpCode, opr + OP_ADD), e1, e2, 0, line); | 1655 | codearith(fs, opr, e1, e2, 0, line); |
1648 | break; | 1656 | break; |
1649 | } | 1657 | } |
1650 | case OPR_BAND: case OPR_BOR: case OPR_BXOR: { | 1658 | case OPR_BAND: case OPR_BOR: case OPR_BXOR: { |
@@ -1656,7 +1664,7 @@ void luaK_posfix (FuncState *fs, BinOpr opr, | |||
1656 | if (!constfolding(fs, LUA_OPSHL, e1, e2)) { | 1664 | if (!constfolding(fs, LUA_OPSHL, e1, e2)) { |
1657 | if (isSCint(e1)) { | 1665 | if (isSCint(e1)) { |
1658 | swapexps(e1, e2); | 1666 | swapexps(e1, e2); |
1659 | codebini(fs, OP_SHLI, e1, e2, 1, line); | 1667 | codebini(fs, OP_SHLI, e1, e2, 1, line, TM_SHL); |
1660 | } | 1668 | } |
1661 | else | 1669 | else |
1662 | codeshift(fs, OP_SHL, e1, e2, line); | 1670 | codeshift(fs, OP_SHL, e1, e2, line); |
@@ -471,6 +471,10 @@ static int findsetreg (const Proto *p, int lastpc, int reg) { | |||
471 | int pc; | 471 | int pc; |
472 | int setreg = -1; /* keep last instruction that changed 'reg' */ | 472 | int setreg = -1; /* keep last instruction that changed 'reg' */ |
473 | int jmptarget = 0; /* any code before this address is conditional */ | 473 | int jmptarget = 0; /* any code before this address is conditional */ |
474 | if (GET_OPCODE(p->code[lastpc]) == OP_MMBIN || | ||
475 | GET_OPCODE(p->code[lastpc]) == OP_MMBINI || | ||
476 | GET_OPCODE(p->code[lastpc]) == OP_MMBINK) | ||
477 | lastpc--; | ||
474 | for (pc = 0; pc < lastpc; pc++) { | 478 | for (pc = 0; pc < lastpc; pc++) { |
475 | Instruction i = p->code[pc]; | 479 | Instruction i = p->code[pc]; |
476 | OpCode op = GET_OPCODE(i); | 480 | OpCode op = GET_OPCODE(i); |
@@ -620,22 +624,11 @@ static const char *funcnamefromcode (lua_State *L, CallInfo *ci, | |||
620 | case OP_SETTABUP: case OP_SETTABLE: case OP_SETI: case OP_SETFIELD: | 624 | case OP_SETTABUP: case OP_SETTABLE: case OP_SETI: case OP_SETFIELD: |
621 | tm = TM_NEWINDEX; | 625 | tm = TM_NEWINDEX; |
622 | break; | 626 | break; |
623 | case OP_ADDI: case OP_SUBI: case OP_MULI: case OP_MODI: | 627 | case OP_MMBIN: case OP_MMBINI: case OP_MMBINK: { |
624 | case OP_POWI: case OP_DIVI: case OP_IDIVI: { | 628 | tm = cast(TMS, GETARG_C(i)); |
625 | int offset = GET_OPCODE(i) - OP_ADDI; /* ORDER OP */ | ||
626 | tm = cast(TMS, offset + TM_ADD); /* ORDER TM */ | ||
627 | break; | ||
628 | } | ||
629 | case OP_ADDK: case OP_SUBK: case OP_MULK: case OP_MODK: | ||
630 | case OP_POWK: case OP_DIVK: case OP_IDIVK: | ||
631 | case OP_BANDK: case OP_BORK: case OP_BXORK: { | ||
632 | int offset = GET_OPCODE(i) - OP_ADDK; /* ORDER OP */ | ||
633 | tm = cast(TMS, offset + TM_ADD); /* ORDER TM */ | ||
634 | break; | 629 | break; |
635 | } | 630 | } |
636 | case OP_ADD: case OP_SUB: case OP_MUL: case OP_MOD: | 631 | case OP_SHL: case OP_SHR: { |
637 | case OP_POW: case OP_DIV: case OP_IDIV: case OP_BAND: | ||
638 | case OP_BOR: case OP_BXOR: case OP_SHL: case OP_SHR: { | ||
639 | int offset = GET_OPCODE(i) - OP_ADD; /* ORDER OP */ | 632 | int offset = GET_OPCODE(i) - OP_ADD; /* ORDER OP */ |
640 | tm = cast(TMS, offset + TM_ADD); /* ORDER TM */ | 633 | tm = cast(TMS, offset + TM_ADD); /* ORDER TM */ |
641 | break; | 634 | break; |
@@ -75,6 +75,9 @@ static void *disptab[NUM_OPCODES] = { | |||
75 | &&L_OP_BXOR, | 75 | &&L_OP_BXOR, |
76 | &&L_OP_SHL, | 76 | &&L_OP_SHL, |
77 | &&L_OP_SHR, | 77 | &&L_OP_SHR, |
78 | &&L_OP_MMBIN, | ||
79 | &&L_OP_MMBINI, | ||
80 | &&L_OP_MMBINK, | ||
78 | &&L_OP_UNM, | 81 | &&L_OP_UNM, |
79 | &&L_OP_BNOT, | 82 | &&L_OP_BNOT, |
80 | &&L_OP_NOT, | 83 | &&L_OP_NOT, |
@@ -69,6 +69,9 @@ LUAI_DDEF const lu_byte luaP_opmodes[NUM_OPCODES] = { | |||
69 | ,opmode(0, 0, 0, 1, iABC) /* OP_BXOR */ | 69 | ,opmode(0, 0, 0, 1, iABC) /* OP_BXOR */ |
70 | ,opmode(0, 0, 0, 1, iABC) /* OP_SHL */ | 70 | ,opmode(0, 0, 0, 1, iABC) /* OP_SHL */ |
71 | ,opmode(0, 0, 0, 1, iABC) /* OP_SHR */ | 71 | ,opmode(0, 0, 0, 1, iABC) /* OP_SHR */ |
72 | ,opmode(0, 0, 0, 0, iABC) /* OP_MMBIN */ | ||
73 | ,opmode(0, 0, 0, 0, iABC) /* OP_MMBINI*/ | ||
74 | ,opmode(0, 0, 0, 0, iABC) /* OP_MMBINK*/ | ||
72 | ,opmode(0, 0, 0, 1, iABC) /* OP_UNM */ | 75 | ,opmode(0, 0, 0, 1, iABC) /* OP_UNM */ |
73 | ,opmode(0, 0, 0, 1, iABC) /* OP_BNOT */ | 76 | ,opmode(0, 0, 0, 1, iABC) /* OP_BNOT */ |
74 | ,opmode(0, 0, 0, 1, iABC) /* OP_NOT */ | 77 | ,opmode(0, 0, 0, 1, iABC) /* OP_NOT */ |
@@ -255,6 +255,10 @@ OP_BXOR,/* A B C R(A) := R(B) ~ R(C) */ | |||
255 | OP_SHL,/* A B C R(A) := R(B) << R(C) */ | 255 | OP_SHL,/* A B C R(A) := R(B) << R(C) */ |
256 | OP_SHR,/* A B C R(A) := R(B) >> R(C) */ | 256 | OP_SHR,/* A B C R(A) := R(B) >> R(C) */ |
257 | 257 | ||
258 | OP_MMBIN,/* A B C call B metamethod for previous bin. operation */ | ||
259 | OP_MMBINI,/* A B C call B metamethod for previous binI. operation */ | ||
260 | OP_MMBINK,/* A B C call B metamethod for previous binK. operation */ | ||
261 | |||
258 | OP_UNM,/* A B R(A) := -R(B) */ | 262 | OP_UNM,/* A B R(A) := -R(B) */ |
259 | OP_BNOT,/* A B R(A) := ~R(B) */ | 263 | OP_BNOT,/* A B R(A) := ~R(B) */ |
260 | OP_NOT,/* A B R(A) := not R(B) */ | 264 | OP_NOT,/* A B R(A) := not R(B) */ |
@@ -60,6 +60,9 @@ static const char *const opnames[] = { | |||
60 | "BXOR", | 60 | "BXOR", |
61 | "SHL", | 61 | "SHL", |
62 | "SHR", | 62 | "SHR", |
63 | "MMBIN", | ||
64 | "MMBINI", | ||
65 | "MMBINK", | ||
63 | "UNM", | 66 | "UNM", |
64 | "BNOT", | 67 | "BNOT", |
65 | "NOT", | 68 | "NOT", |
@@ -173,7 +173,7 @@ void luaT_tryconcatTM (lua_State *L) { | |||
173 | 173 | ||
174 | 174 | ||
175 | void luaT_trybinassocTM (lua_State *L, const TValue *p1, const TValue *p2, | 175 | void luaT_trybinassocTM (lua_State *L, const TValue *p1, const TValue *p2, |
176 | StkId res, int flip, TMS event) { | 176 | int flip, StkId res, TMS event) { |
177 | if (flip) | 177 | if (flip) |
178 | luaT_trybinTM(L, p2, p1, res, event); | 178 | luaT_trybinTM(L, p2, p1, res, event); |
179 | else | 179 | else |
@@ -185,7 +185,7 @@ void luaT_trybiniTM (lua_State *L, const TValue *p1, lua_Integer i2, | |||
185 | int flip, StkId res, TMS event) { | 185 | int flip, StkId res, TMS event) { |
186 | TValue aux; | 186 | TValue aux; |
187 | setivalue(&aux, i2); | 187 | setivalue(&aux, i2); |
188 | luaT_trybinassocTM(L, p1, &aux, res, flip, event); | 188 | luaT_trybinassocTM(L, p1, &aux, flip, res, event); |
189 | } | 189 | } |
190 | 190 | ||
191 | 191 | ||
@@ -77,7 +77,7 @@ LUAI_FUNC void luaT_trybinTM (lua_State *L, const TValue *p1, const TValue *p2, | |||
77 | StkId res, TMS event); | 77 | StkId res, TMS event); |
78 | LUAI_FUNC void luaT_tryconcatTM (lua_State *L); | 78 | LUAI_FUNC void luaT_tryconcatTM (lua_State *L); |
79 | LUAI_FUNC void luaT_trybinassocTM (lua_State *L, const TValue *p1, | 79 | LUAI_FUNC void luaT_trybinassocTM (lua_State *L, const TValue *p1, |
80 | const TValue *p2, StkId res, int inv, TMS event); | 80 | const TValue *p2, int inv, StkId res, TMS event); |
81 | LUAI_FUNC void luaT_trybiniTM (lua_State *L, const TValue *p1, lua_Integer i2, | 81 | LUAI_FUNC void luaT_trybiniTM (lua_State *L, const TValue *p1, lua_Integer i2, |
82 | int inv, StkId res, TMS event); | 82 | int inv, StkId res, TMS event); |
83 | LUAI_FUNC int luaT_callorderTM (lua_State *L, const TValue *p1, | 83 | LUAI_FUNC int luaT_callorderTM (lua_State *L, const TValue *p1, |
@@ -717,18 +717,11 @@ void luaV_finishOp (lua_State *L) { | |||
717 | Instruction inst = *(ci->u.l.savedpc - 1); /* interrupted instruction */ | 717 | Instruction inst = *(ci->u.l.savedpc - 1); /* interrupted instruction */ |
718 | OpCode op = GET_OPCODE(inst); | 718 | OpCode op = GET_OPCODE(inst); |
719 | switch (op) { /* finish its execution */ | 719 | switch (op) { /* finish its execution */ |
720 | case OP_ADDI: case OP_SUBI: | 720 | case OP_MMBIN: case OP_MMBINI: case OP_MMBINK: { |
721 | case OP_MULI: case OP_DIVI: case OP_IDIVI: | 721 | setobjs2s(L, base + GETARG_A(*(ci->u.l.savedpc - 2)), --L->top); |
722 | case OP_MODI: case OP_POWI: | 722 | break; |
723 | case OP_ADDK: case OP_SUBK: | 723 | } |
724 | case OP_MULK: case OP_DIVK: case OP_IDIVK: | ||
725 | case OP_MODK: case OP_POWK: | ||
726 | case OP_ADD: case OP_SUB: | ||
727 | case OP_MUL: case OP_DIV: case OP_IDIV: | ||
728 | case OP_BANDK: case OP_BORK: case OP_BXORK: | ||
729 | case OP_BAND: case OP_BOR: case OP_BXOR: | ||
730 | case OP_SHLI: case OP_SHRI: case OP_SHL: case OP_SHR: | 724 | case OP_SHLI: case OP_SHRI: case OP_SHL: case OP_SHR: |
731 | case OP_MOD: case OP_POW: | ||
732 | case OP_UNM: case OP_BNOT: case OP_LEN: | 725 | case OP_UNM: case OP_BNOT: case OP_LEN: |
733 | case OP_GETTABUP: case OP_GETTABLE: case OP_GETI: | 726 | case OP_GETTABUP: case OP_GETTABLE: case OP_GETI: |
734 | case OP_GETFIELD: case OP_SELF: { | 727 | case OP_GETFIELD: case OP_SELF: { |
@@ -804,10 +797,8 @@ void luaV_finishOp (lua_State *L) { | |||
804 | lua_Number nb; \ | 797 | lua_Number nb; \ |
805 | if (tonumberns(v1, nb)) { \ | 798 | if (tonumberns(v1, nb)) { \ |
806 | lua_Number fimm = cast_num(imm); \ | 799 | lua_Number fimm = cast_num(imm); \ |
807 | setfltvalue(s2v(ra), fop(L, nb, fimm)); \ | 800 | pc++; setfltvalue(s2v(ra), fop(L, nb, fimm)); \ |
808 | } \ | 801 | }} |
809 | else \ | ||
810 | ProtectNT(luaT_trybiniTM(L, v1, imm, flip, ra, tm)); } | ||
811 | 802 | ||
812 | 803 | ||
813 | /* | 804 | /* |
@@ -827,7 +818,7 @@ void luaV_finishOp (lua_State *L) { | |||
827 | int imm = GETARG_sC(i); \ | 818 | int imm = GETARG_sC(i); \ |
828 | if (ttisinteger(v1)) { \ | 819 | if (ttisinteger(v1)) { \ |
829 | lua_Integer iv1 = ivalue(v1); \ | 820 | lua_Integer iv1 = ivalue(v1); \ |
830 | setivalue(s2v(ra), iop(L, iv1, imm)); \ | 821 | pc++; setivalue(s2v(ra), iop(L, iv1, imm)); \ |
831 | } \ | 822 | } \ |
832 | else op_arithfI_aux(L, v1, imm, fop, tm, flip); } | 823 | else op_arithfI_aux(L, v1, imm, fop, tm, flip); } |
833 | 824 | ||
@@ -839,10 +830,8 @@ void luaV_finishOp (lua_State *L) { | |||
839 | #define op_arithf_aux(L,v1,v2,fop,tm) { \ | 830 | #define op_arithf_aux(L,v1,v2,fop,tm) { \ |
840 | lua_Number n1; lua_Number n2; \ | 831 | lua_Number n1; lua_Number n2; \ |
841 | if (tonumberns(v1, n1) && tonumberns(v2, n2)) { \ | 832 | if (tonumberns(v1, n1) && tonumberns(v2, n2)) { \ |
842 | setfltvalue(s2v(ra), fop(L, n1, n2)); \ | 833 | pc++; setfltvalue(s2v(ra), fop(L, n1, n2)); \ |
843 | } \ | 834 | }} |
844 | else \ | ||
845 | ProtectNT(luaT_trybinTM(L, v1, v2, ra, tm)); } | ||
846 | 835 | ||
847 | 836 | ||
848 | /* | 837 | /* |
@@ -862,7 +851,7 @@ void luaV_finishOp (lua_State *L) { | |||
862 | TValue *v2 = vRC(i); \ | 851 | TValue *v2 = vRC(i); \ |
863 | if (ttisinteger(v1) && ttisinteger(v2)) { \ | 852 | if (ttisinteger(v1) && ttisinteger(v2)) { \ |
864 | lua_Integer i1 = ivalue(v1); lua_Integer i2 = ivalue(v2); \ | 853 | lua_Integer i1 = ivalue(v1); lua_Integer i2 = ivalue(v2); \ |
865 | setivalue(s2v(ra), iop(L, i1, i2)); \ | 854 | pc++; setivalue(s2v(ra), iop(L, i1, i2)); \ |
866 | } \ | 855 | } \ |
867 | else op_arithf_aux(L, v1, v2, fop, tm); } | 856 | else op_arithf_aux(L, v1, v2, fop, tm); } |
868 | 857 | ||
@@ -875,15 +864,13 @@ void luaV_finishOp (lua_State *L) { | |||
875 | TValue *v2 = KC(i); \ | 864 | TValue *v2 = KC(i); \ |
876 | if (ttisinteger(v1) && ttisinteger(v2)) { \ | 865 | if (ttisinteger(v1) && ttisinteger(v2)) { \ |
877 | lua_Integer i1 = ivalue(v1); lua_Integer i2 = ivalue(v2); \ | 866 | lua_Integer i1 = ivalue(v1); lua_Integer i2 = ivalue(v2); \ |
878 | setivalue(s2v(ra), iop(L, i1, i2)); \ | 867 | pc++; setivalue(s2v(ra), iop(L, i1, i2)); \ |
879 | } \ | 868 | } \ |
880 | else { \ | 869 | else { \ |
881 | lua_Number n1; lua_Number n2; \ | 870 | lua_Number n1; lua_Number n2; \ |
882 | if (tonumberns(v1, n1) && tonumberns(v2, n2)) { \ | 871 | if (tonumberns(v1, n1) && tonumberns(v2, n2)) { \ |
883 | setfltvalue(s2v(ra), fop(L, n1, n2)); \ | 872 | pc++; setfltvalue(s2v(ra), fop(L, n1, n2)); \ |
884 | } \ | 873 | }}} |
885 | else \ | ||
886 | ProtectNT(luaT_trybinassocTM(L, v1, v2, ra, flip, tm)); } } | ||
887 | 874 | ||
888 | 875 | ||
889 | /* | 876 | /* |
@@ -894,10 +881,8 @@ void luaV_finishOp (lua_State *L) { | |||
894 | TValue *v2 = KC(i); \ | 881 | TValue *v2 = KC(i); \ |
895 | lua_Number n1; lua_Number n2; \ | 882 | lua_Number n1; lua_Number n2; \ |
896 | if (tonumberns(v1, n1) && tonumberns(v2, n2)) { \ | 883 | if (tonumberns(v1, n1) && tonumberns(v2, n2)) { \ |
897 | setfltvalue(s2v(ra), fop(L, n1, n2)); \ | 884 | pc++; setfltvalue(s2v(ra), fop(L, n1, n2)); \ |
898 | } \ | 885 | }} |
899 | else \ | ||
900 | ProtectNT(luaT_trybinTM(L, v1, v2, ra, tm)); } | ||
901 | 886 | ||
902 | 887 | ||
903 | /* | 888 | /* |
@@ -909,10 +894,8 @@ void luaV_finishOp (lua_State *L) { | |||
909 | lua_Integer i1; \ | 894 | lua_Integer i1; \ |
910 | lua_Integer i2 = ivalue(v2); \ | 895 | lua_Integer i2 = ivalue(v2); \ |
911 | if (tointegerns(v1, &i1)) { \ | 896 | if (tointegerns(v1, &i1)) { \ |
912 | setivalue(s2v(ra), op(L, i1, i2)); \ | 897 | pc++; setivalue(s2v(ra), op(L, i1, i2)); \ |
913 | } \ | 898 | }} |
914 | else \ | ||
915 | ProtectNT(luaT_trybiniTM(L, v1, i2, TESTARG_k(i), ra, tm)); } | ||
916 | 899 | ||
917 | 900 | ||
918 | /* | 901 | /* |
@@ -923,10 +906,8 @@ void luaV_finishOp (lua_State *L) { | |||
923 | TValue *v2 = vRC(i); \ | 906 | TValue *v2 = vRC(i); \ |
924 | lua_Integer i1; lua_Integer i2; \ | 907 | lua_Integer i1; lua_Integer i2; \ |
925 | if (tointegerns(v1, &i1) && tointegerns(v2, &i2)) { \ | 908 | if (tointegerns(v1, &i1) && tointegerns(v2, &i2)) { \ |
926 | setivalue(s2v(ra), op(L, i1, i2)); \ | 909 | pc++; setivalue(s2v(ra), op(L, i1, i2)); \ |
927 | } \ | 910 | }} |
928 | else \ | ||
929 | ProtectNT(luaT_trybinTM(L, v1, v2, ra, tm)); } | ||
930 | 911 | ||
931 | 912 | ||
932 | /* | 913 | /* |
@@ -1443,6 +1424,33 @@ void luaV_execute (lua_State *L, CallInfo *ci) { | |||
1443 | ProtectNT(luaT_trybinTM(L, rb, rc, ra, TM_SHL)); | 1424 | ProtectNT(luaT_trybinTM(L, rb, rc, ra, TM_SHL)); |
1444 | vmbreak; | 1425 | vmbreak; |
1445 | } | 1426 | } |
1427 | vmcase(OP_MMBIN) { | ||
1428 | Instruction pi = *(pc - 2); /* original arith. expression */ | ||
1429 | TValue *rb = vRB(i); | ||
1430 | TMS tm = (TMS)GETARG_C(i); | ||
1431 | StkId result = RA(pi); | ||
1432 | lua_assert(OP_ADD <= GET_OPCODE(pi) && GET_OPCODE(pi) <= OP_SHR); | ||
1433 | ProtectNT(luaT_trybinTM(L, s2v(ra), rb, result, tm)); | ||
1434 | vmbreak; | ||
1435 | } | ||
1436 | vmcase(OP_MMBINI) { | ||
1437 | Instruction pi = *(pc - 2); /* original arith. expression */ | ||
1438 | int imm = GETARG_sB(i); | ||
1439 | TMS tm = (TMS)GETARG_C(i); | ||
1440 | int flip = GETARG_k(i); | ||
1441 | StkId result = RA(pi); | ||
1442 | ProtectNT(luaT_trybiniTM(L, s2v(ra), imm, flip, result, tm)); | ||
1443 | vmbreak; | ||
1444 | } | ||
1445 | vmcase(OP_MMBINK) { | ||
1446 | Instruction pi = *(pc - 2); /* original arith. expression */ | ||
1447 | TValue *imm = KB(i); | ||
1448 | TMS tm = (TMS)GETARG_C(i); | ||
1449 | int flip = GETARG_k(i); | ||
1450 | StkId result = RA(pi); | ||
1451 | ProtectNT(luaT_trybinassocTM(L, s2v(ra), imm, flip, result, tm)); | ||
1452 | vmbreak; | ||
1453 | } | ||
1446 | vmcase(OP_UNM) { | 1454 | vmcase(OP_UNM) { |
1447 | TValue *rb = vRB(i); | 1455 | TValue *rb = vRB(i); |
1448 | lua_Number nb; | 1456 | lua_Number nb; |
@@ -1826,4 +1834,3 @@ void luaV_execute (lua_State *L, CallInfo *ci) { | |||
1826 | } | 1834 | } |
1827 | 1835 | ||
1828 | /* }================================================================== */ | 1836 | /* }================================================================== */ |
1829 | |||
diff --git a/testes/code.lua b/testes/code.lua index 3b768f33..fcb5c309 100644 --- a/testes/code.lua +++ b/testes/code.lua | |||
@@ -156,9 +156,9 @@ check(function () | |||
156 | c.x, a[b] = -((a + d/b - a[b]) ^ a.x), b | 156 | c.x, a[b] = -((a + d/b - a[b]) ^ a.x), b |
157 | end, | 157 | end, |
158 | 'LOADNIL', | 158 | 'LOADNIL', |
159 | 'MUL', | 159 | 'MUL', 'MMBIN', |
160 | 'DIV', 'ADD', 'GETTABLE', 'SUB', 'GETFIELD', 'POW', | 160 | 'DIV', 'MMBIN', 'ADD', 'MMBIN', 'GETTABLE', 'SUB', 'MMBIN', |
161 | 'UNM', 'SETTABLE', 'SETFIELD', 'RETURN0') | 161 | 'GETFIELD', 'POW', 'MMBIN', 'UNM', 'SETTABLE', 'SETFIELD', 'RETURN0') |
162 | 162 | ||
163 | 163 | ||
164 | -- direct access to constants | 164 | -- direct access to constants |
@@ -188,7 +188,7 @@ check(function () | |||
188 | b = a/a | 188 | b = a/a |
189 | b = 5-4 | 189 | b = 5-4 |
190 | end, | 190 | end, |
191 | 'LOADNIL', 'SUB', 'DIV', 'LOADI', 'RETURN0') | 191 | 'LOADNIL', 'SUB', 'MMBIN', 'DIV', 'MMBIN', 'LOADI', 'RETURN0') |
192 | 192 | ||
193 | check(function () | 193 | check(function () |
194 | local a,b | 194 | local a,b |
@@ -292,38 +292,45 @@ checkK(function () return -(border + 1) end, -(sbx + 1.0)) | |||
292 | 292 | ||
293 | 293 | ||
294 | -- immediate operands | 294 | -- immediate operands |
295 | checkR(function (x) return x + k1 end, 10, 11, 'ADDI', 'RETURN1') | 295 | checkR(function (x) return x + k1 end, 10, 11, 'ADDI', 'MMBINI', 'RETURN1') |
296 | checkR(function (x) return 128 + x end, 0.0, 128.0, 'ADDI', 'RETURN1') | 296 | checkR(function (x) return 128 + x end, 0.0, 128.0, |
297 | checkR(function (x) return x * -127 end, -1.0, 127.0, 'MULI', 'RETURN1') | 297 | 'ADDI', 'MMBINI', 'RETURN1') |
298 | checkR(function (x) return 20 * x end, 2, 40, 'MULI', 'RETURN1') | 298 | checkR(function (x) return x * -127 end, -1.0, 127.0, |
299 | checkR(function (x) return x ^ -2 end, 2, 0.25, 'POWI', 'RETURN1') | 299 | 'MULI', 'MMBINI', 'RETURN1') |
300 | checkR(function (x) return x / 40 end, 40, 1.0, 'DIVI', 'RETURN1') | 300 | checkR(function (x) return 20 * x end, 2, 40, 'MULI', 'MMBINI', 'RETURN1') |
301 | checkR(function (x) return x // 1 end, 10.0, 10.0, 'IDIVI', 'RETURN1') | 301 | checkR(function (x) return x ^ -2 end, 2, 0.25, 'POWI', 'MMBINI', 'RETURN1') |
302 | checkR(function (x) return x % (100 - 10) end, 91, 1, 'MODI', 'RETURN1') | 302 | checkR(function (x) return x / 40 end, 40, 1.0, 'DIVI', 'MMBINI', 'RETURN1') |
303 | checkR(function (x) return x // 1 end, 10.0, 10.0, | ||
304 | 'IDIVI', 'MMBINI', 'RETURN1') | ||
305 | checkR(function (x) return x % (100 - 10) end, 91, 1, | ||
306 | 'MODI', 'MMBINI', 'RETURN1') | ||
303 | checkR(function (x) return k1 << x end, 3, 8, 'SHLI', 'RETURN1') | 307 | checkR(function (x) return k1 << x end, 3, 8, 'SHLI', 'RETURN1') |
304 | checkR(function (x) return x << 2 end, 10, 40, 'SHRI', 'RETURN1') | 308 | checkR(function (x) return x << 2 end, 10, 40, 'SHRI', 'RETURN1') |
305 | checkR(function (x) return x >> 2 end, 8, 2, 'SHRI', 'RETURN1') | 309 | checkR(function (x) return x >> 2 end, 8, 2, 'SHRI', 'RETURN1') |
306 | checkR(function (x) return x & 1 end, 9, 1, 'BANDK', 'RETURN1') | 310 | checkR(function (x) return x & 1 end, 9, 1, 'BANDK', 'MMBINK', 'RETURN1') |
307 | checkR(function (x) return 10 | x end, 1, 11, 'BORK', 'RETURN1') | 311 | checkR(function (x) return 10 | x end, 1, 11, 'BORK', 'MMBINK', 'RETURN1') |
308 | checkR(function (x) return -10 ~ x end, -1, 9, 'BXORK', 'RETURN1') | 312 | checkR(function (x) return -10 ~ x end, -1, 9, 'BXORK', 'MMBINK', 'RETURN1') |
309 | 313 | ||
310 | -- K operands in arithmetic operations | 314 | -- K operands in arithmetic operations |
311 | checkR(function (x) return x + 0.0 end, 1, 1.0, 'ADDK', 'RETURN1') | 315 | checkR(function (x) return x + 0.0 end, 1, 1.0, 'ADDK', 'MMBINK', 'RETURN1') |
312 | -- check(function (x) return 128 + x end, 'ADDK', 'RETURN1') | 316 | -- check(function (x) return 128 + x end, 'ADDK', 'MMBINK', 'RETURN1') |
313 | checkR(function (x) return x * -10000 end, 2, -20000, 'MULK', 'RETURN1') | 317 | checkR(function (x) return x * -10000 end, 2, -20000, |
314 | -- check(function (x) return 20 * x end, 'MULK', 'RETURN1') | 318 | 'MULK', 'MMBINK', 'RETURN1') |
315 | checkR(function (x) return x ^ 0.5 end, 4, 2.0, 'POWK', 'RETURN1') | 319 | -- check(function (x) return 20 * x end, 'MULK', 'MMBINK', 'RETURN1') |
316 | checkR(function (x) return x / 2.0 end, 4, 2.0, 'DIVK', 'RETURN1') | 320 | checkR(function (x) return x ^ 0.5 end, 4, 2.0, 'POWK', 'MMBINK', 'RETURN1') |
317 | checkR(function (x) return x // 10000 end, 10000, 1, 'IDIVK', 'RETURN1') | 321 | checkR(function (x) return x / 2.0 end, 4, 2.0, 'DIVK', 'MMBINK', 'RETURN1') |
318 | checkR(function (x) return x % (100.0 - 10) end, 91, 1.0, 'MODK', 'RETURN1') | 322 | checkR(function (x) return x // 10000 end, 10000, 1, |
323 | 'IDIVK', 'MMBINK', 'RETURN1') | ||
324 | checkR(function (x) return x % (100.0 - 10) end, 91, 1.0, | ||
325 | 'MODK', 'MMBINK', 'RETURN1') | ||
319 | 326 | ||
320 | -- no foldings (and immediate operands) | 327 | -- no foldings (and immediate operands) |
321 | check(function () return -0.0 end, 'LOADF', 'UNM', 'RETURN1') | 328 | check(function () return -0.0 end, 'LOADF', 'UNM', 'RETURN1') |
322 | check(function () return k3/0 end, 'LOADI', 'DIVI', 'RETURN1') | 329 | check(function () return k3/0 end, 'LOADI', 'DIVI', 'MMBINI', 'RETURN1') |
323 | check(function () return 0%0 end, 'LOADI', 'MODI', 'RETURN1') | 330 | check(function () return 0%0 end, 'LOADI', 'MODI', 'MMBINI', 'RETURN1') |
324 | check(function () return -4//0 end, 'LOADI', 'IDIVI', 'RETURN1') | 331 | check(function () return -4//0 end, 'LOADI', 'IDIVI', 'MMBINI', 'RETURN1') |
325 | check(function (x) return x >> 2.0 end, 'LOADF', 'SHR', 'RETURN1') | 332 | check(function (x) return x >> 2.0 end, 'LOADF', 'SHR', 'RETURN1') |
326 | check(function (x) return x & 2.0 end, 'LOADF', 'BAND', 'RETURN1') | 333 | check(function (x) return x & 2.0 end, 'LOADF', 'BAND', 'MMBIN', 'RETURN1') |
327 | 334 | ||
328 | -- basic 'for' loops | 335 | -- basic 'for' loops |
329 | check(function () for i = -10, 10.5 do end end, | 336 | check(function () for i = -10, 10.5 do end end, |
@@ -379,7 +386,7 @@ check(function (a, b) | |||
379 | if b then break else a = a + 1 end | 386 | if b then break else a = a + 1 end |
380 | end | 387 | end |
381 | end, | 388 | end, |
382 | 'TEST', 'JMP', 'TEST', 'JMP', 'ADDI', 'JMP', 'RETURN0') | 389 | 'TEST', 'JMP', 'TEST', 'JMP', 'ADDI', 'MMBINI', 'JMP', 'RETURN0') |
383 | 390 | ||
384 | checkequal( | 391 | checkequal( |
385 | function (a) while a < 10 do a = a + 1 end end, | 392 | function (a) while a < 10 do a = a + 1 end end, |
diff --git a/testes/coroutine.lua b/testes/coroutine.lua index 48f4c5bf..81d848a3 100644 --- a/testes/coroutine.lua +++ b/testes/coroutine.lua | |||
@@ -751,7 +751,7 @@ assert(run(function () return a >> 2 end, {"shr"}) == 10 >> 2) | |||
751 | assert(run(function () return 1 >> a end, {"shr"}) == 1 >> 10) | 751 | assert(run(function () return 1 >> a end, {"shr"}) == 1 >> 10) |
752 | assert(run(function () return a << 2 end, {"shl"}) == 10 << 2) | 752 | assert(run(function () return a << 2 end, {"shl"}) == 10 << 2) |
753 | assert(run(function () return 1 << a end, {"shl"}) == 1 << 10) | 753 | assert(run(function () return 1 << a end, {"shl"}) == 1 << 10) |
754 | assert(run(function () return a ~ 2 end, {"bxor"}) == 10 ~ 2) | 754 | assert(run(function () return 2 ~ a end, {"bxor"}) == 2 ~ 10) |
755 | 755 | ||
756 | 756 | ||
757 | assert(run(function () return a..b end, {"concat"}) == "1012") | 757 | assert(run(function () return a..b end, {"concat"}) == "1012") |