aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lcode.c73
-rw-r--r--lopcodes.c4
-rw-r--r--lopcodes.h3
-rw-r--r--lvm.c13
4 files changed, 68 insertions, 25 deletions
diff --git a/lcode.c b/lcode.c
index ccd25711..08e92ea1 100644
--- a/lcode.c
+++ b/lcode.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lcode.c,v 2.132 2017/11/08 14:50:23 roberto Exp roberto $ 2** $Id: lcode.c,v 2.133 2017/11/16 12:59:14 roberto Exp roberto $
3** Code generator for Lua 3** Code generator for Lua
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -607,12 +607,17 @@ void luaK_int (FuncState *fs, int reg, lua_Integer i) {
607} 607}
608 608
609 609
610static void luaK_float (FuncState *fs, int reg, lua_Number f) { 610static int floatI (lua_Number f, lua_Integer *fi) {
611 TValue v; 611 TValue v;
612 lua_Integer fi;
613 setfltvalue(&v, f); 612 setfltvalue(&v, f);
614 if (luaV_flttointeger(&v, &fi, 0) && 613 return (luaV_flttointeger(&v, fi, 0) &&
615 l_castS2U(fi) + MAXARG_sBx <= l_castS2U(MAXARG_Bx)) 614 l_castS2U(*fi) + MAXARG_sBx <= l_castS2U(MAXARG_Bx));
615}
616
617
618static void luaK_float (FuncState *fs, int reg, lua_Number f) {
619 lua_Integer fi;
620 if (floatI(f, &fi))
616 luaK_codeAsBx(fs, OP_LOADF, reg, cast_int(fi)); 621 luaK_codeAsBx(fs, OP_LOADF, reg, cast_int(fi));
617 else 622 else
618 luaK_codek(fs, reg, luaK_numberK(fs, f)); 623 luaK_codek(fs, reg, luaK_numberK(fs, f));
@@ -1107,6 +1112,20 @@ static int isSCint (expdesc *e) {
1107 1112
1108 1113
1109/* 1114/*
1115** Check whether expression 'e' is a literal integer or float in
1116** proper range to fit in register sC
1117*/
1118static int isSCnumber (expdesc *e, lua_Integer *i) {
1119 if (e->k == VKINT)
1120 *i = e->u.ival;
1121 else if (!(e->k == VKFLT && floatI(e->u.nval, i)))
1122 return 0; /* not a number */
1123 *i += MAXARG_sC;
1124 return (!hasjumps(e) && l_castS2U(*i) <= l_castS2U(MAXARG_C));
1125}
1126
1127
1128/*
1110** Create expression 't[k]'. 't' must have its final result already in a 1129** Create expression 't[k]'. 't' must have its final result already in a
1111** register or upvalue. Upvalues can only be indexed by literal strings. 1130** register or upvalue. Upvalues can only be indexed by literal strings.
1112** Keys can be literal strings in the constant table or arbitrary 1131** Keys can be literal strings in the constant table or arbitrary
@@ -1235,6 +1254,11 @@ static void codearith (FuncState *fs, OpCode op,
1235} 1254}
1236 1255
1237 1256
1257static void swapexps (expdesc *e1, expdesc *e2) {
1258 expdesc temp = *e1; *e1 = *e2; *e2 = temp; /* swap 'e1' and 'e2' */
1259}
1260
1261
1238/* 1262/*
1239** Code commutative operators ('+', '*'). If first operand is a 1263** Code commutative operators ('+', '*'). If first operand is a
1240** constant, change order of operands to use immediate operator. 1264** constant, change order of operands to use immediate operator.
@@ -1243,7 +1267,7 @@ static void codecommutative (FuncState *fs, OpCode op,
1243 expdesc *e1, expdesc *e2, int line) { 1267 expdesc *e1, expdesc *e2, int line) {
1244 int flip = 0; 1268 int flip = 0;
1245 if (isSCint(e1)) { 1269 if (isSCint(e1)) {
1246 expdesc temp = *e1; *e1 = *e2; *e2 = temp; /* swap 'e1' and 'e2' */ 1270 swapexps(e1, e2);
1247 flip = 1; 1271 flip = 1;
1248 } 1272 }
1249 codearith(fs, op, e1, e2, flip, line); 1273 codearith(fs, op, e1, e2, flip, line);
@@ -1259,10 +1283,6 @@ static void codeorder (FuncState *fs, BinOpr opr, expdesc *e1, expdesc *e2) {
1259 int rk2 = luaK_exp2anyreg(fs, e2); 1283 int rk2 = luaK_exp2anyreg(fs, e2);
1260 freeexps(fs, e1, e2); 1284 freeexps(fs, e1, e2);
1261 switch (opr) { 1285 switch (opr) {
1262 case OPR_NE: { /* '(a ~= b)' ==> 'not (a == b)' */
1263 e1->u.info = condjump(fs, OP_EQ, 0, rk1, rk2);
1264 break;
1265 }
1266 case OPR_GT: case OPR_GE: { 1286 case OPR_GT: case OPR_GE: {
1267 /* '(a > b)' ==> '(b < a)'; '(a >= b)' ==> '(b <= a)' */ 1287 /* '(a > b)' ==> '(b < a)'; '(a >= b)' ==> '(b <= a)' */
1268 OpCode op = cast(OpCode, (opr - OPR_NE) + OP_EQ); 1288 OpCode op = cast(OpCode, (opr - OPR_NE) + OP_EQ);
@@ -1284,21 +1304,28 @@ static void codeorder (FuncState *fs, BinOpr opr, expdesc *e1, expdesc *e2) {
1284** 'e1' was already put as RK by 'luaK_infix'. 1304** 'e1' was already put as RK by 'luaK_infix'.
1285*/ 1305*/
1286static void codeeq (FuncState *fs, BinOpr opr, expdesc *e1, expdesc *e2) { 1306static void codeeq (FuncState *fs, BinOpr opr, expdesc *e1, expdesc *e2) {
1287 int r1, rk2; 1307 int r1, r2;
1288 OpCode op = OP_EQK; /* will try first to use a constant */ 1308 lua_Integer im;
1289 if (e1->k == VK) { /* 1st expression is constant? */ 1309 OpCode op;
1290 rk2 = e1->u.info; /* constant index */ 1310 if (e1->k != VNONRELOC) {
1291 r1 = luaK_exp2anyreg(fs, e2); /* 2nd expression must be in register */ 1311 lua_assert(e1->k == VK || e1->k == VKINT || e1->k == VKFLT);
1312 swapexps(e1, e2);
1313 }
1314 r1 = luaK_exp2anyreg(fs, e1); /* 1nd expression must be in register */
1315 if (isSCnumber(e2, &im)) {
1316 op = OP_EQI;
1317 r2 = cast_int(im); /* immediate operand */
1318 }
1319 else if (luaK_exp2RK(fs, e2)) { /* 1st expression is constant? */
1320 op = OP_EQK;
1321 r2 = e2->u.info; /* constant index */
1292 } 1322 }
1293 else { 1323 else {
1294 lua_assert(e1->k == VNONRELOC); /* 1st expression is in a register */ 1324 op = OP_EQ; /* will compare two registers */
1295 r1 = e1->u.info; 1325 r2 = luaK_exp2anyreg(fs, e2);
1296 if (!luaK_exp2RK(fs, e2)) /* 2nd expression is not constant? */
1297 op = OP_EQ; /* will compare two registers */
1298 rk2 = e2->u.info; /* constant/register index */
1299 } 1326 }
1300 freeexps(fs, e1, e2); 1327 freeexps(fs, e1, e2);
1301 e1->u.info = condjump(fs, op, (opr == OPR_EQ), r1, rk2); 1328 e1->u.info = condjump(fs, op, (opr == OPR_EQ), r1, r2);
1302 e1->k = VJMP; 1329 e1->k = VJMP;
1303} 1330}
1304 1331
@@ -1351,7 +1378,9 @@ void luaK_infix (FuncState *fs, BinOpr op, expdesc *v) {
1351 break; 1378 break;
1352 } 1379 }
1353 case OPR_EQ: case OPR_NE: { 1380 case OPR_EQ: case OPR_NE: {
1354 luaK_exp2RK(fs, v); 1381 if (!tonumeral(v, NULL))
1382 luaK_exp2RK(fs, v);
1383 /* else keep numeral, which may be an immediate operand */
1355 break; 1384 break;
1356 } 1385 }
1357 case OPR_LT: case OPR_LE: 1386 case OPR_LT: case OPR_LE:
diff --git a/lopcodes.c b/lopcodes.c
index 87408752..05700950 100644
--- a/lopcodes.c
+++ b/lopcodes.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lopcodes.c,v 1.67 2017/11/07 17:20:42 roberto Exp roberto $ 2** $Id: lopcodes.c,v 1.68 2017/11/16 12:59:14 roberto Exp roberto $
3** Opcodes for Lua virtual machine 3** Opcodes for Lua virtual machine
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -67,6 +67,7 @@ LUAI_DDEF const char *const luaP_opnames[NUM_OPCODES+1] = {
67 "LT", 67 "LT",
68 "LE", 68 "LE",
69 "EQK", 69 "EQK",
70 "EQI",
70 "TEST", 71 "TEST",
71 "TESTSET", 72 "TESTSET",
72 "CALL", 73 "CALL",
@@ -135,6 +136,7 @@ LUAI_DDEF const lu_byte luaP_opmodes[NUM_OPCODES] = {
135 ,opmode(1, 0, iABC) /* OP_LT */ 136 ,opmode(1, 0, iABC) /* OP_LT */
136 ,opmode(1, 0, iABC) /* OP_LE */ 137 ,opmode(1, 0, iABC) /* OP_LE */
137 ,opmode(1, 0, iABC) /* OP_EQK */ 138 ,opmode(1, 0, iABC) /* OP_EQK */
139 ,opmode(1, 0, iABC) /* OP_EQI */
138 ,opmode(1, 0, iABC) /* OP_TEST */ 140 ,opmode(1, 0, iABC) /* OP_TEST */
139 ,opmode(1, 1, iABC) /* OP_TESTSET */ 141 ,opmode(1, 1, iABC) /* OP_TESTSET */
140 ,opmode(0, 1, iABC) /* OP_CALL */ 142 ,opmode(0, 1, iABC) /* OP_CALL */
diff --git a/lopcodes.h b/lopcodes.h
index a805ba63..6829711c 100644
--- a/lopcodes.h
+++ b/lopcodes.h
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lopcodes.h,v 1.167 2017/11/07 17:20:42 roberto Exp roberto $ 2** $Id: lopcodes.h,v 1.168 2017/11/16 12:59:14 roberto Exp roberto $
3** Opcodes for Lua virtual machine 3** Opcodes for Lua virtual machine
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -241,6 +241,7 @@ OP_LT,/* A B C if ((R(B) < R(C)) ~= A) then pc++ */
241OP_LE,/* A B C if ((R(B) <= R(C)) ~= A) then pc++ */ 241OP_LE,/* A B C if ((R(B) <= R(C)) ~= A) then pc++ */
242 242
243OP_EQK,/* A B C if ((R(B) == K(C)) ~= A) then pc++ */ 243OP_EQK,/* A B C if ((R(B) == K(C)) ~= A) then pc++ */
244OP_EQI,/* A B C if ((R(B) == C) ~= A) then pc++ */
244 245
245OP_TEST,/* A C if not (R(A) <=> C) then pc++ */ 246OP_TEST,/* A C if not (R(A) <=> C) then pc++ */
246OP_TESTSET,/* A B C if (R(B) <=> C) then R(A) := R(B) else pc++ */ 247OP_TESTSET,/* A B C if (R(B) <=> C) then R(A) := R(B) else pc++ */
diff --git a/lvm.c b/lvm.c
index b673db91..6c4bab08 100644
--- a/lvm.c
+++ b/lvm.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lvm.c,v 2.312 2017/11/20 12:57:39 roberto Exp roberto $ 2** $Id: lvm.c,v 2.313 2017/11/21 14:17:35 roberto Exp $
3** Lua virtual machine 3** Lua virtual machine
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -1392,6 +1392,17 @@ void luaV_execute (lua_State *L) {
1392 donextjump(ci); 1392 donextjump(ci);
1393 vmbreak; 1393 vmbreak;
1394 } 1394 }
1395 vmcase(OP_EQI) {
1396 TValue *rb = vRB(i);
1397 int ic = GETARG_sC(i);
1398 if ((ttisinteger(rb) ? (ivalue(rb) == ic)
1399 :ttisfloat(rb) ? luai_numeq(fltvalue(rb), cast_num(ic))
1400 : 0) != GETARG_A(i))
1401 pc++;
1402 else
1403 donextjump(ci);
1404 vmbreak;
1405 }
1395 vmcase(OP_TEST) { 1406 vmcase(OP_TEST) {
1396 if (GETARG_C(i) ? l_isfalse(s2v(ra)) : !l_isfalse(s2v(ra))) 1407 if (GETARG_C(i) ? l_isfalse(s2v(ra)) : !l_isfalse(s2v(ra)))
1397 pc++; 1408 pc++;