aboutsummaryrefslogtreecommitdiff
path: root/lcode.c
diff options
context:
space:
mode:
Diffstat (limited to 'lcode.c')
-rw-r--r--lcode.c46
1 files changed, 27 insertions, 19 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);