aboutsummaryrefslogtreecommitdiff
path: root/lcode.c
diff options
context:
space:
mode:
Diffstat (limited to 'lcode.c')
-rw-r--r--lcode.c42
1 files changed, 23 insertions, 19 deletions
diff --git a/lcode.c b/lcode.c
index 1872ede2..1e36e584 100644
--- a/lcode.c
+++ b/lcode.c
@@ -179,8 +179,8 @@ void luaK_ret (FuncState *fs, int first, int nret) {
179** Code a "conditional jump", that is, a test or comparison opcode 179** Code a "conditional jump", that is, a test or comparison opcode
180** followed by a jump. Return jump position. 180** followed by a jump. Return jump position.
181*/ 181*/
182static int condjump (FuncState *fs, OpCode op, int A, int B, int k) { 182static int condjump (FuncState *fs, OpCode op, int A, int B, int C, int k) {
183 luaK_codeABCk(fs, op, A, B, 0, k); 183 luaK_codeABCk(fs, op, A, B, C, k);
184 return luaK_jump(fs); 184 return luaK_jump(fs);
185} 185}
186 186
@@ -799,7 +799,7 @@ static int need_value (FuncState *fs, int list) {
799 799
800/* 800/*
801** Ensures final expression result (which includes results from its 801** Ensures final expression result (which includes results from its
802** jump ** lists) is in register 'reg'. 802** jump lists) is in register 'reg'.
803** If expression has jumps, need to patch these jumps either to 803** If expression has jumps, need to patch these jumps either to
804** its final position or to "load" instructions (for those tests 804** its final position or to "load" instructions (for those tests
805** that do not produce values). 805** that do not produce values).
@@ -814,8 +814,9 @@ static void exp2reg (FuncState *fs, expdesc *e, int reg) {
814 int p_t = NO_JUMP; /* position of an eventual LOAD true */ 814 int p_t = NO_JUMP; /* position of an eventual LOAD true */
815 if (need_value(fs, e->t) || need_value(fs, e->f)) { 815 if (need_value(fs, e->t) || need_value(fs, e->f)) {
816 int fj = (e->k == VJMP) ? NO_JUMP : luaK_jump(fs); 816 int fj = (e->k == VJMP) ? NO_JUMP : luaK_jump(fs);
817 p_f = code_loadbool(fs, reg, 0, 1); 817 p_f = code_loadbool(fs, reg, 0, 1); /* load false and skip next i. */
818 p_t = code_loadbool(fs, reg, 1, 0); 818 p_t = code_loadbool(fs, reg, 1, 0); /* load true */
819 /* jump around these booleans if 'e' is not a test */
819 luaK_patchtohere(fs, fj); 820 luaK_patchtohere(fs, fj);
820 } 821 }
821 final = luaK_getlabel(fs); 822 final = luaK_getlabel(fs);
@@ -1005,13 +1006,13 @@ static int jumponcond (FuncState *fs, expdesc *e, int cond) {
1005 Instruction ie = getinstruction(fs, e); 1006 Instruction ie = getinstruction(fs, e);
1006 if (GET_OPCODE(ie) == OP_NOT) { 1007 if (GET_OPCODE(ie) == OP_NOT) {
1007 removelastinstruction(fs); /* remove previous OP_NOT */ 1008 removelastinstruction(fs); /* remove previous OP_NOT */
1008 return condjump(fs, OP_TEST, GETARG_B(ie), 0, !cond); 1009 return condjump(fs, OP_TEST, GETARG_B(ie), 0, 0, !cond);
1009 } 1010 }
1010 /* else go through */ 1011 /* else go through */
1011 } 1012 }
1012 discharge2anyreg(fs, e); 1013 discharge2anyreg(fs, e);
1013 freeexp(fs, e); 1014 freeexp(fs, e);
1014 return condjump(fs, OP_TESTSET, NO_REG, e->u.info, cond); 1015 return condjump(fs, OP_TESTSET, NO_REG, e->u.info, 0, cond);
1015} 1016}
1016 1017
1017 1018
@@ -1139,13 +1140,15 @@ static int isSCint (expdesc *e) {
1139 1140
1140/* 1141/*
1141** Check whether expression 'e' is a literal integer or float in 1142** Check whether expression 'e' is a literal integer or float in
1142** proper range to fit in register sC 1143** proper range to fit in a register (sB or sC).
1143*/ 1144*/
1144static int isSCnumber (expdesc *e, lua_Integer *i) { 1145static int isSCnumber (expdesc *e, lua_Integer *i, int *isfloat) {
1145 if (e->k == VKINT) 1146 if (e->k == VKINT)
1146 *i = e->u.ival; 1147 *i = e->u.ival;
1147 else if (!(e->k == VKFLT && floatI(e->u.nval, i))) 1148 else if (!(e->k == VKFLT && floatI(e->u.nval, i)))
1148 return 0; /* not a number */ 1149 return 0; /* not a number */
1150 else
1151 *isfloat = 1;
1149 if (!hasjumps(e) && fitsC(*i)) { 1152 if (!hasjumps(e) && fitsC(*i)) {
1150 *i += OFFSET_sC; 1153 *i += OFFSET_sC;
1151 return 1; 1154 return 1;
@@ -1372,21 +1375,20 @@ static void codeshift (FuncState *fs, OpCode op,
1372 1375
1373 1376
1374/* 1377/*
1375** Emit code for order comparisons. 1378** Emit code for order comparisons. When using an immediate operand,
1376** When the first operand A is an integral value in the proper range, 1379** 'isfloat' tells whether the original value was a float.
1377** change (A < B) to (B > A) and (A <= B) to (B >= A) so that
1378** it can use an immediate operand.
1379*/ 1380*/
1380static void codeorder (FuncState *fs, OpCode op, expdesc *e1, expdesc *e2) { 1381static void codeorder (FuncState *fs, OpCode op, expdesc *e1, expdesc *e2) {
1381 int r1, r2; 1382 int r1, r2;
1382 lua_Integer im; 1383 lua_Integer im;
1383 if (isSCnumber(e2, &im)) { 1384 int isfloat = 0;
1385 if (isSCnumber(e2, &im, &isfloat)) {
1384 /* use immediate operand */ 1386 /* use immediate operand */
1385 r1 = luaK_exp2anyreg(fs, e1); 1387 r1 = luaK_exp2anyreg(fs, e1);
1386 r2 = cast_int(im); 1388 r2 = cast_int(im);
1387 op = cast(OpCode, (op - OP_LT) + OP_LTI); 1389 op = cast(OpCode, (op - OP_LT) + OP_LTI);
1388 } 1390 }
1389 else if (isSCnumber(e1, &im)) { 1391 else if (isSCnumber(e1, &im, &isfloat)) {
1390 /* transform (A < B) to (B > A) and (A <= B) to (B >= A) */ 1392 /* transform (A < B) to (B > A) and (A <= B) to (B >= A) */
1391 r1 = luaK_exp2anyreg(fs, e2); 1393 r1 = luaK_exp2anyreg(fs, e2);
1392 r2 = cast_int(im); 1394 r2 = cast_int(im);
@@ -1397,7 +1399,7 @@ static void codeorder (FuncState *fs, OpCode op, expdesc *e1, expdesc *e2) {
1397 r2 = luaK_exp2anyreg(fs, e2); 1399 r2 = luaK_exp2anyreg(fs, e2);
1398 } 1400 }
1399 freeexps(fs, e1, e2); 1401 freeexps(fs, e1, e2);
1400 e1->u.info = condjump(fs, op, r1, r2, 1); 1402 e1->u.info = condjump(fs, op, r1, r2, isfloat, 1);
1401 e1->k = VJMP; 1403 e1->k = VJMP;
1402} 1404}
1403 1405
@@ -1409,13 +1411,14 @@ static void codeorder (FuncState *fs, OpCode op, expdesc *e1, expdesc *e2) {
1409static void codeeq (FuncState *fs, BinOpr opr, expdesc *e1, expdesc *e2) { 1411static void codeeq (FuncState *fs, BinOpr opr, expdesc *e1, expdesc *e2) {
1410 int r1, r2; 1412 int r1, r2;
1411 lua_Integer im; 1413 lua_Integer im;
1414 int isfloat = 0; /* not needed here, but kept for symmetry */
1412 OpCode op; 1415 OpCode op;
1413 if (e1->k != VNONRELOC) { 1416 if (e1->k != VNONRELOC) {
1414 lua_assert(e1->k == VK || e1->k == VKINT || e1->k == VKFLT); 1417 lua_assert(e1->k == VK || e1->k == VKINT || e1->k == VKFLT);
1415 swapexps(e1, e2); 1418 swapexps(e1, e2);
1416 } 1419 }
1417 r1 = luaK_exp2anyreg(fs, e1); /* 1nd expression must be in register */ 1420 r1 = luaK_exp2anyreg(fs, e1); /* 1nd expression must be in register */
1418 if (isSCnumber(e2, &im)) { 1421 if (isSCnumber(e2, &im, &isfloat)) {
1419 op = OP_EQI; 1422 op = OP_EQI;
1420 r2 = cast_int(im); /* immediate operand */ 1423 r2 = cast_int(im); /* immediate operand */
1421 } 1424 }
@@ -1428,7 +1431,7 @@ static void codeeq (FuncState *fs, BinOpr opr, expdesc *e1, expdesc *e2) {
1428 r2 = luaK_exp2anyreg(fs, e2); 1431 r2 = luaK_exp2anyreg(fs, e2);
1429 } 1432 }
1430 freeexps(fs, e1, e2); 1433 freeexps(fs, e1, e2);
1431 e1->u.info = condjump(fs, op, r1, r2, (opr == OPR_EQ)); 1434 e1->u.info = condjump(fs, op, r1, r2, isfloat, (opr == OPR_EQ));
1432 e1->k = VJMP; 1435 e1->k = VJMP;
1433} 1436}
1434 1437
@@ -1489,7 +1492,8 @@ void luaK_infix (FuncState *fs, BinOpr op, expdesc *v) {
1489 case OPR_LT: case OPR_LE: 1492 case OPR_LT: case OPR_LE:
1490 case OPR_GT: case OPR_GE: { 1493 case OPR_GT: case OPR_GE: {
1491 lua_Integer dummy; 1494 lua_Integer dummy;
1492 if (!isSCnumber(v, &dummy)) 1495 int dummy2;
1496 if (!isSCnumber(v, &dummy, &dummy2))
1493 luaK_exp2anyreg(fs, v); 1497 luaK_exp2anyreg(fs, v);
1494 /* else keep numeral, which may be an immediate operand */ 1498 /* else keep numeral, which may be an immediate operand */
1495 break; 1499 break;