aboutsummaryrefslogtreecommitdiff
path: root/lcode.c
diff options
context:
space:
mode:
Diffstat (limited to 'lcode.c')
-rw-r--r--lcode.c26
1 files changed, 15 insertions, 11 deletions
diff --git a/lcode.c b/lcode.c
index a1b27a00..2c08409b 100644
--- a/lcode.c
+++ b/lcode.c
@@ -1339,19 +1339,23 @@ static void codeunexpval (FuncState *fs, OpCode op, expdesc *e, int line) {
1339** Expression to produce final result will be encoded in 'e1'. 1339** Expression to produce final result will be encoded in 'e1'.
1340*/ 1340*/
1341static void finishbinexpval (FuncState *fs, expdesc *e1, expdesc *e2, 1341static void finishbinexpval (FuncState *fs, expdesc *e1, expdesc *e2,
1342 OpCode op, int v2, int k, int line, 1342 OpCode op, int v2, int flip, int line,
1343 OpCode mmop, TMS event) { 1343 OpCode mmop, TMS event) {
1344 int v1 = luaK_exp2anyreg(fs, e1); 1344 int v1 = luaK_exp2anyreg(fs, e1);
1345 int pc = luaK_codeABCk(fs, op, 0, v1, v2, k); 1345 int pc = luaK_codeABCk(fs, op, 0, v1, v2, flip);
1346 freeexps(fs, e1, e2); 1346 freeexps(fs, e1, e2);
1347 e1->u.info = pc; 1347 e1->u.info = pc;
1348 e1->k = VRELOC; /* all those operations are relocatable */ 1348 e1->k = VRELOC; /* all those operations are relocatable */
1349 luaK_fixline(fs, line); 1349 luaK_fixline(fs, line);
1350if (event != TM_SHL && event != TM_SHR) { 1350 if (op == OP_SHRI && flip) {
1351 luaK_codeABCk(fs, mmop, v1, v2, event, k); /* to call metamethod */ 1351 /* For the metamethod, undo the "changedir" did by 'codeshift' */
1352 event = TM_SHL;
1353 v2 = -(v2 - OFFSET_sC) + OFFSET_sC;
1354 flip = 0;
1355 }
1356 luaK_codeABCk(fs, mmop, v1, v2, event, flip); /* to call metamethod */
1352 luaK_fixline(fs, line); 1357 luaK_fixline(fs, line);
1353} 1358}
1354}
1355 1359
1356 1360
1357/* 1361/*
@@ -1371,10 +1375,10 @@ static void codebinexpval (FuncState *fs, OpCode op,
1371** Code binary operators ('+', '-', ...) with immediate operands. 1375** Code binary operators ('+', '-', ...) with immediate operands.
1372*/ 1376*/
1373static void codebini (FuncState *fs, OpCode op, 1377static void codebini (FuncState *fs, OpCode op,
1374 expdesc *e1, expdesc *e2, int k, int line, 1378 expdesc *e1, expdesc *e2, int flip, int line,
1375 TMS event) { 1379 TMS event) {
1376 int v2 = cast_int(e2->u.ival) + OFFSET_sC; /* immediate operand */ 1380 int v2 = cast_int(e2->u.ival) + OFFSET_sC; /* immediate operand */
1377 finishbinexpval(fs, e1, e2, op, v2, k, line, OP_MMBINI, event); 1381 finishbinexpval(fs, e1, e2, op, v2, flip, line, OP_MMBINI, event);
1378} 1382}
1379 1383
1380 1384
@@ -1429,12 +1433,12 @@ static void codecommutative (FuncState *fs, BinOpr op,
1429*/ 1433*/
1430static void codebitwise (FuncState *fs, BinOpr opr, 1434static void codebitwise (FuncState *fs, BinOpr opr,
1431 expdesc *e1, expdesc *e2, int line) { 1435 expdesc *e1, expdesc *e2, int line) {
1432 int inv = 0; 1436 int flip = 0;
1433 int v2; 1437 int v2;
1434 OpCode op; 1438 OpCode op;
1435 if (e1->k == VKINT && luaK_exp2RK(fs, e1)) { 1439 if (e1->k == VKINT && luaK_exp2RK(fs, e1)) {
1436 swapexps(e1, e2); /* 'e2' will be the constant operand */ 1440 swapexps(e1, e2); /* 'e2' will be the constant operand */
1437 inv = 1; 1441 flip = 1;
1438 } 1442 }
1439 else if (!(e2->k == VKINT && luaK_exp2RK(fs, e2))) { /* no constants? */ 1443 else if (!(e2->k == VKINT && luaK_exp2RK(fs, e2))) { /* no constants? */
1440 op = cast(OpCode, opr + OP_ADD); 1444 op = cast(OpCode, opr + OP_ADD);
@@ -1444,7 +1448,7 @@ static void codebitwise (FuncState *fs, BinOpr opr,
1444 v2 = e2->u.info; /* index in K array */ 1448 v2 = e2->u.info; /* index in K array */
1445 op = cast(OpCode, opr + OP_ADDK); 1449 op = cast(OpCode, opr + OP_ADDK);
1446 lua_assert(ttisinteger(&fs->f->k[v2])); 1450 lua_assert(ttisinteger(&fs->f->k[v2]));
1447 finishbinexpval(fs, e1, e2, op, v2, inv, line, OP_MMBINK, 1451 finishbinexpval(fs, e1, e2, op, v2, flip, line, OP_MMBINK,
1448 cast(TMS, opr + TM_ADD)); 1452 cast(TMS, opr + TM_ADD));
1449} 1453}
1450 1454
@@ -1461,7 +1465,7 @@ static void codeshift (FuncState *fs, OpCode op,
1461 changedir = 1; 1465 changedir = 1;
1462 e2->u.ival = -(e2->u.ival); 1466 e2->u.ival = -(e2->u.ival);
1463 } 1467 }
1464 codebini(fs, OP_SHRI, e1, e2, changedir, line, TM_SHL); 1468 codebini(fs, OP_SHRI, e1, e2, changedir, line, TM_SHR);
1465 } 1469 }
1466 else 1470 else
1467 codebinexpval(fs, op, e1, e2, line); 1471 codebinexpval(fs, op, e1, e2, line);