aboutsummaryrefslogtreecommitdiff
path: root/lcode.c
diff options
context:
space:
mode:
Diffstat (limited to 'lcode.c')
-rw-r--r--lcode.c58
1 files changed, 25 insertions, 33 deletions
diff --git a/lcode.c b/lcode.c
index c48bc41e..053b66b2 100644
--- a/lcode.c
+++ b/lcode.c
@@ -627,7 +627,7 @@ static int nilK (FuncState *fs) {
627 627
628/* 628/*
629** Check whether 'i' can be stored in an 'sC' operand. 629** Check whether 'i' can be stored in an 'sC' operand.
630** Equivalent to (0 <= i + OFFSET_sC && i + OFFSET_sC <= MAXARG_C) 630** Equivalent to (0 <= int2sC(i) && int2sC(i) <= MAXARG_C)
631** but without risk of overflows in the addition. 631** but without risk of overflows in the addition.
632*/ 632*/
633static int fitsC (lua_Integer i) { 633static int fitsC (lua_Integer i) {
@@ -651,14 +651,9 @@ void luaK_int (FuncState *fs, int reg, lua_Integer i) {
651} 651}
652 652
653 653
654static int floatI (lua_Number f, lua_Integer *fi) {
655 return (luaV_flttointeger(f, fi, 0) && fitsBx(*fi));
656}
657
658
659static void luaK_float (FuncState *fs, int reg, lua_Number f) { 654static void luaK_float (FuncState *fs, int reg, lua_Number f) {
660 lua_Integer fi; 655 lua_Integer fi;
661 if (floatI(f, &fi)) 656 if (luaV_flttointeger(f, &fi, 0) && fitsBx(fi))
662 luaK_codeAsBx(fs, OP_LOADF, reg, cast_int(fi)); 657 luaK_codeAsBx(fs, OP_LOADF, reg, cast_int(fi));
663 else 658 else
664 luaK_codek(fs, reg, luaK_numberK(fs, f)); 659 luaK_codek(fs, reg, luaK_numberK(fs, f));
@@ -1221,15 +1216,16 @@ static int isSCint (expdesc *e) {
1221** Check whether expression 'e' is a literal integer or float in 1216** Check whether expression 'e' is a literal integer or float in
1222** proper range to fit in a register (sB or sC). 1217** proper range to fit in a register (sB or sC).
1223*/ 1218*/
1224static int isSCnumber (expdesc *e, lua_Integer *i, int *isfloat) { 1219static int isSCnumber (expdesc *e, int *pi, int *isfloat) {
1220 lua_Integer i;
1225 if (e->k == VKINT) 1221 if (e->k == VKINT)
1226 *i = e->u.ival; 1222 i = e->u.ival;
1227 else if (!(e->k == VKFLT && floatI(e->u.nval, i))) 1223 else if (e->k == VKFLT && luaV_flttointeger(e->u.nval, &i, 0))
1228 return 0; /* not a number */
1229 else
1230 *isfloat = 1; 1224 *isfloat = 1;
1231 if (!hasjumps(e) && fitsC(*i)) { 1225 else
1232 *i += OFFSET_sC; 1226 return 0; /* not a number */
1227 if (!hasjumps(e) && fitsC(i)) {
1228 *pi = int2sC(cast_int(i));
1233 return 1; 1229 return 1;
1234 } 1230 }
1235 else 1231 else
@@ -1347,12 +1343,6 @@ static void finishbinexpval (FuncState *fs, expdesc *e1, expdesc *e2,
1347 e1->u.info = pc; 1343 e1->u.info = pc;
1348 e1->k = VRELOC; /* all those operations are relocatable */ 1344 e1->k = VRELOC; /* all those operations are relocatable */
1349 luaK_fixline(fs, line); 1345 luaK_fixline(fs, line);
1350 if (op == OP_SHRI && flip) {
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 */ 1346 luaK_codeABCk(fs, mmop, v1, v2, event, flip); /* to call metamethod */
1357 luaK_fixline(fs, line); 1347 luaK_fixline(fs, line);
1358} 1348}
@@ -1377,7 +1367,8 @@ static void codebinexpval (FuncState *fs, OpCode op,
1377static void codebini (FuncState *fs, OpCode op, 1367static void codebini (FuncState *fs, OpCode op,
1378 expdesc *e1, expdesc *e2, int flip, int line, 1368 expdesc *e1, expdesc *e2, int flip, int line,
1379 TMS event) { 1369 TMS event) {
1380 int v2 = cast_int(e2->u.ival) + OFFSET_sC; /* immediate operand */ 1370 int v2 = int2sC(cast_int(e2->u.ival)); /* immediate operand */
1371 lua_assert(e2->k == VKINT);
1381 finishbinexpval(fs, e1, e2, op, v2, flip, line, OP_MMBINI, event); 1372 finishbinexpval(fs, e1, e2, op, v2, flip, line, OP_MMBINI, event);
1382} 1373}
1383 1374
@@ -1460,12 +1451,14 @@ static void codebitwise (FuncState *fs, BinOpr opr,
1460static void codeshift (FuncState *fs, OpCode op, 1451static void codeshift (FuncState *fs, OpCode op,
1461 expdesc *e1, expdesc *e2, int line) { 1452 expdesc *e1, expdesc *e2, int line) {
1462 if (isSCint(e2)) { 1453 if (isSCint(e2)) {
1463 int changedir = 0; 1454 if (op == OP_SHR)
1464 if (op == OP_SHL) { 1455 codebini(fs, OP_SHRI, e1, e2, 0, line, TM_SHR);
1465 changedir = 1; 1456 else {
1466 e2->u.ival = -(e2->u.ival); 1457 int offset = cast_int(e2->u.ival);
1458 finishbinexpval(fs, e1, e2, OP_SHRI, int2sC(offset),
1459 0, line, OP_MMBINI, TM_SHL);
1460 SETARG_C(fs->f->code[fs->pc - 2], int2sC(-offset));
1467 } 1461 }
1468 codebini(fs, OP_SHRI, e1, e2, changedir, line, TM_SHR);
1469 } 1462 }
1470 else 1463 else
1471 codebinexpval(fs, op, e1, e2, line); 1464 codebinexpval(fs, op, e1, e2, line);
@@ -1478,18 +1471,18 @@ static void codeshift (FuncState *fs, OpCode op,
1478*/ 1471*/
1479static void codeorder (FuncState *fs, OpCode op, expdesc *e1, expdesc *e2) { 1472static void codeorder (FuncState *fs, OpCode op, expdesc *e1, expdesc *e2) {
1480 int r1, r2; 1473 int r1, r2;
1481 lua_Integer im; 1474 int im;
1482 int isfloat = 0; 1475 int isfloat = 0;
1483 if (isSCnumber(e2, &im, &isfloat)) { 1476 if (isSCnumber(e2, &im, &isfloat)) {
1484 /* use immediate operand */ 1477 /* use immediate operand */
1485 r1 = luaK_exp2anyreg(fs, e1); 1478 r1 = luaK_exp2anyreg(fs, e1);
1486 r2 = cast_int(im); 1479 r2 = im;
1487 op = cast(OpCode, (op - OP_LT) + OP_LTI); 1480 op = cast(OpCode, (op - OP_LT) + OP_LTI);
1488 } 1481 }
1489 else if (isSCnumber(e1, &im, &isfloat)) { 1482 else if (isSCnumber(e1, &im, &isfloat)) {
1490 /* transform (A < B) to (B > A) and (A <= B) to (B >= A) */ 1483 /* transform (A < B) to (B > A) and (A <= B) to (B >= A) */
1491 r1 = luaK_exp2anyreg(fs, e2); 1484 r1 = luaK_exp2anyreg(fs, e2);
1492 r2 = cast_int(im); 1485 r2 = im;
1493 op = (op == OP_LT) ? OP_GTI : OP_GEI; 1486 op = (op == OP_LT) ? OP_GTI : OP_GEI;
1494 } 1487 }
1495 else { /* regular case, compare two registers */ 1488 else { /* regular case, compare two registers */
@@ -1508,7 +1501,7 @@ static void codeorder (FuncState *fs, OpCode op, expdesc *e1, expdesc *e2) {
1508*/ 1501*/
1509static void codeeq (FuncState *fs, BinOpr opr, expdesc *e1, expdesc *e2) { 1502static void codeeq (FuncState *fs, BinOpr opr, expdesc *e1, expdesc *e2) {
1510 int r1, r2; 1503 int r1, r2;
1511 lua_Integer im; 1504 int im;
1512 int isfloat = 0; /* not needed here, but kept for symmetry */ 1505 int isfloat = 0; /* not needed here, but kept for symmetry */
1513 OpCode op; 1506 OpCode op;
1514 if (e1->k != VNONRELOC) { 1507 if (e1->k != VNONRELOC) {
@@ -1518,7 +1511,7 @@ static void codeeq (FuncState *fs, BinOpr opr, expdesc *e1, expdesc *e2) {
1518 r1 = luaK_exp2anyreg(fs, e1); /* 1nd expression must be in register */ 1511 r1 = luaK_exp2anyreg(fs, e1); /* 1nd expression must be in register */
1519 if (isSCnumber(e2, &im, &isfloat)) { 1512 if (isSCnumber(e2, &im, &isfloat)) {
1520 op = OP_EQI; 1513 op = OP_EQI;
1521 r2 = cast_int(im); /* immediate operand */ 1514 r2 = im; /* immediate operand */
1522 } 1515 }
1523 else if (luaK_exp2RK(fs, e2)) { /* 1st expression is constant? */ 1516 else if (luaK_exp2RK(fs, e2)) { /* 1st expression is constant? */
1524 op = OP_EQK; 1517 op = OP_EQK;
@@ -1591,8 +1584,7 @@ void luaK_infix (FuncState *fs, BinOpr op, expdesc *v) {
1591 } 1584 }
1592 case OPR_LT: case OPR_LE: 1585 case OPR_LT: case OPR_LE:
1593 case OPR_GT: case OPR_GE: { 1586 case OPR_GT: case OPR_GE: {
1594 lua_Integer dummy; 1587 int dummy, dummy2;
1595 int dummy2;
1596 if (!isSCnumber(v, &dummy, &dummy2)) 1588 if (!isSCnumber(v, &dummy, &dummy2))
1597 luaK_exp2anyreg(fs, v); 1589 luaK_exp2anyreg(fs, v);
1598 /* else keep numeral, which may be an immediate operand */ 1590 /* else keep numeral, which may be an immediate operand */