aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lcode.c46
-rw-r--r--ldebug.c21
-rw-r--r--ljumptab.h3
-rw-r--r--lopcodes.c3
-rw-r--r--lopcodes.h4
-rw-r--r--lopnames.h3
-rw-r--r--ltm.c4
-rw-r--r--ltm.h2
-rw-r--r--lvm.c85
-rw-r--r--testes/code.lua63
-rw-r--r--testes/coroutine.lua2
11 files changed, 132 insertions, 104 deletions
diff --git a/lcode.c b/lcode.c
index c2b5fc6d..a1b27a00 100644
--- a/lcode.c
+++ b/lcode.c
@@ -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*/
1344static void finishbinexpval (FuncState *fs, expdesc *e1, expdesc *e2, 1341static 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);
1350if (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,
1359static void codebinexpval (FuncState *fs, OpCode op, 1361static 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*/
1369static void codebini (FuncState *fs, OpCode op, 1373static 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*/
1386static void codearith (FuncState *fs, OpCode op, 1391static 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*/
1408static void codecommutative (FuncState *fs, OpCode op, 1415static 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);
diff --git a/ldebug.c b/ldebug.c
index 9593039b..4e1dc6b9 100644
--- a/ldebug.c
+++ b/ldebug.c
@@ -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;
diff --git a/ljumptab.h b/ljumptab.h
index 2d4cf28b..1832c809 100644
--- a/ljumptab.h
+++ b/ljumptab.h
@@ -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,
diff --git a/lopcodes.c b/lopcodes.c
index ee795786..aede93a5 100644
--- a/lopcodes.c
+++ b/lopcodes.c
@@ -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 */
diff --git a/lopcodes.h b/lopcodes.h
index 26b1850d..fd578c68 100644
--- a/lopcodes.h
+++ b/lopcodes.h
@@ -255,6 +255,10 @@ OP_BXOR,/* A B C R(A) := R(B) ~ R(C) */
255OP_SHL,/* A B C R(A) := R(B) << R(C) */ 255OP_SHL,/* A B C R(A) := R(B) << R(C) */
256OP_SHR,/* A B C R(A) := R(B) >> R(C) */ 256OP_SHR,/* A B C R(A) := R(B) >> R(C) */
257 257
258OP_MMBIN,/* A B C call B metamethod for previous bin. operation */
259OP_MMBINI,/* A B C call B metamethod for previous binI. operation */
260OP_MMBINK,/* A B C call B metamethod for previous binK. operation */
261
258OP_UNM,/* A B R(A) := -R(B) */ 262OP_UNM,/* A B R(A) := -R(B) */
259OP_BNOT,/* A B R(A) := ~R(B) */ 263OP_BNOT,/* A B R(A) := ~R(B) */
260OP_NOT,/* A B R(A) := not R(B) */ 264OP_NOT,/* A B R(A) := not R(B) */
diff --git a/lopnames.h b/lopnames.h
index 28535fe2..0fc1da1f 100644
--- a/lopnames.h
+++ b/lopnames.h
@@ -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",
diff --git a/ltm.c b/ltm.c
index 19233a87..991e62c1 100644
--- a/ltm.c
+++ b/ltm.c
@@ -173,7 +173,7 @@ void luaT_tryconcatTM (lua_State *L) {
173 173
174 174
175void luaT_trybinassocTM (lua_State *L, const TValue *p1, const TValue *p2, 175void 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
diff --git a/ltm.h b/ltm.h
index 51dfe793..9621e68e 100644
--- a/ltm.h
+++ b/ltm.h
@@ -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);
78LUAI_FUNC void luaT_tryconcatTM (lua_State *L); 78LUAI_FUNC void luaT_tryconcatTM (lua_State *L);
79LUAI_FUNC void luaT_trybinassocTM (lua_State *L, const TValue *p1, 79LUAI_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);
81LUAI_FUNC void luaT_trybiniTM (lua_State *L, const TValue *p1, lua_Integer i2, 81LUAI_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);
83LUAI_FUNC int luaT_callorderTM (lua_State *L, const TValue *p1, 83LUAI_FUNC int luaT_callorderTM (lua_State *L, const TValue *p1,
diff --git a/lvm.c b/lvm.c
index 907417e3..a9e8455e 100644
--- a/lvm.c
+++ b/lvm.c
@@ -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
157end, 157end,
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
190end, 190end,
191 'LOADNIL', 'SUB', 'DIV', 'LOADI', 'RETURN0') 191 'LOADNIL', 'SUB', 'MMBIN', 'DIV', 'MMBIN', 'LOADI', 'RETURN0')
192 192
193check(function () 193check(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
295checkR(function (x) return x + k1 end, 10, 11, 'ADDI', 'RETURN1') 295checkR(function (x) return x + k1 end, 10, 11, 'ADDI', 'MMBINI', 'RETURN1')
296checkR(function (x) return 128 + x end, 0.0, 128.0, 'ADDI', 'RETURN1') 296checkR(function (x) return 128 + x end, 0.0, 128.0,
297checkR(function (x) return x * -127 end, -1.0, 127.0, 'MULI', 'RETURN1') 297 'ADDI', 'MMBINI', 'RETURN1')
298checkR(function (x) return 20 * x end, 2, 40, 'MULI', 'RETURN1') 298checkR(function (x) return x * -127 end, -1.0, 127.0,
299checkR(function (x) return x ^ -2 end, 2, 0.25, 'POWI', 'RETURN1') 299 'MULI', 'MMBINI', 'RETURN1')
300checkR(function (x) return x / 40 end, 40, 1.0, 'DIVI', 'RETURN1') 300checkR(function (x) return 20 * x end, 2, 40, 'MULI', 'MMBINI', 'RETURN1')
301checkR(function (x) return x // 1 end, 10.0, 10.0, 'IDIVI', 'RETURN1') 301checkR(function (x) return x ^ -2 end, 2, 0.25, 'POWI', 'MMBINI', 'RETURN1')
302checkR(function (x) return x % (100 - 10) end, 91, 1, 'MODI', 'RETURN1') 302checkR(function (x) return x / 40 end, 40, 1.0, 'DIVI', 'MMBINI', 'RETURN1')
303checkR(function (x) return x // 1 end, 10.0, 10.0,
304 'IDIVI', 'MMBINI', 'RETURN1')
305checkR(function (x) return x % (100 - 10) end, 91, 1,
306 'MODI', 'MMBINI', 'RETURN1')
303checkR(function (x) return k1 << x end, 3, 8, 'SHLI', 'RETURN1') 307checkR(function (x) return k1 << x end, 3, 8, 'SHLI', 'RETURN1')
304checkR(function (x) return x << 2 end, 10, 40, 'SHRI', 'RETURN1') 308checkR(function (x) return x << 2 end, 10, 40, 'SHRI', 'RETURN1')
305checkR(function (x) return x >> 2 end, 8, 2, 'SHRI', 'RETURN1') 309checkR(function (x) return x >> 2 end, 8, 2, 'SHRI', 'RETURN1')
306checkR(function (x) return x & 1 end, 9, 1, 'BANDK', 'RETURN1') 310checkR(function (x) return x & 1 end, 9, 1, 'BANDK', 'MMBINK', 'RETURN1')
307checkR(function (x) return 10 | x end, 1, 11, 'BORK', 'RETURN1') 311checkR(function (x) return 10 | x end, 1, 11, 'BORK', 'MMBINK', 'RETURN1')
308checkR(function (x) return -10 ~ x end, -1, 9, 'BXORK', 'RETURN1') 312checkR(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
311checkR(function (x) return x + 0.0 end, 1, 1.0, 'ADDK', 'RETURN1') 315checkR(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')
313checkR(function (x) return x * -10000 end, 2, -20000, 'MULK', 'RETURN1') 317checkR(function (x) return x * -10000 end, 2, -20000,
314-- check(function (x) return 20 * x end, 'MULK', 'RETURN1') 318 'MULK', 'MMBINK', 'RETURN1')
315checkR(function (x) return x ^ 0.5 end, 4, 2.0, 'POWK', 'RETURN1') 319-- check(function (x) return 20 * x end, 'MULK', 'MMBINK', 'RETURN1')
316checkR(function (x) return x / 2.0 end, 4, 2.0, 'DIVK', 'RETURN1') 320checkR(function (x) return x ^ 0.5 end, 4, 2.0, 'POWK', 'MMBINK', 'RETURN1')
317checkR(function (x) return x // 10000 end, 10000, 1, 'IDIVK', 'RETURN1') 321checkR(function (x) return x / 2.0 end, 4, 2.0, 'DIVK', 'MMBINK', 'RETURN1')
318checkR(function (x) return x % (100.0 - 10) end, 91, 1.0, 'MODK', 'RETURN1') 322checkR(function (x) return x // 10000 end, 10000, 1,
323 'IDIVK', 'MMBINK', 'RETURN1')
324checkR(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)
321check(function () return -0.0 end, 'LOADF', 'UNM', 'RETURN1') 328check(function () return -0.0 end, 'LOADF', 'UNM', 'RETURN1')
322check(function () return k3/0 end, 'LOADI', 'DIVI', 'RETURN1') 329check(function () return k3/0 end, 'LOADI', 'DIVI', 'MMBINI', 'RETURN1')
323check(function () return 0%0 end, 'LOADI', 'MODI', 'RETURN1') 330check(function () return 0%0 end, 'LOADI', 'MODI', 'MMBINI', 'RETURN1')
324check(function () return -4//0 end, 'LOADI', 'IDIVI', 'RETURN1') 331check(function () return -4//0 end, 'LOADI', 'IDIVI', 'MMBINI', 'RETURN1')
325check(function (x) return x >> 2.0 end, 'LOADF', 'SHR', 'RETURN1') 332check(function (x) return x >> 2.0 end, 'LOADF', 'SHR', 'RETURN1')
326check(function (x) return x & 2.0 end, 'LOADF', 'BAND', 'RETURN1') 333check(function (x) return x & 2.0 end, 'LOADF', 'BAND', 'MMBIN', 'RETURN1')
327 334
328-- basic 'for' loops 335-- basic 'for' loops
329check(function () for i = -10, 10.5 do end end, 336check(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
384checkequal( 391checkequal(
385function (a) while a < 10 do a = a + 1 end end, 392function (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)
751assert(run(function () return 1 >> a end, {"shr"}) == 1 >> 10) 751assert(run(function () return 1 >> a end, {"shr"}) == 1 >> 10)
752assert(run(function () return a << 2 end, {"shl"}) == 10 << 2) 752assert(run(function () return a << 2 end, {"shl"}) == 10 << 2)
753assert(run(function () return 1 << a end, {"shl"}) == 1 << 10) 753assert(run(function () return 1 << a end, {"shl"}) == 1 << 10)
754assert(run(function () return a ~ 2 end, {"bxor"}) == 10 ~ 2) 754assert(run(function () return 2 ~ a end, {"bxor"}) == 2 ~ 10)
755 755
756 756
757assert(run(function () return a..b end, {"concat"}) == "1012") 757assert(run(function () return a..b end, {"concat"}) == "1012")