diff options
| -rw-r--r-- | lcode.c | 73 | ||||
| -rw-r--r-- | lopcodes.c | 4 | ||||
| -rw-r--r-- | lopcodes.h | 3 | ||||
| -rw-r--r-- | lvm.c | 13 |
4 files changed, 68 insertions, 25 deletions
| @@ -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 | ||
| 610 | static void luaK_float (FuncState *fs, int reg, lua_Number f) { | 610 | static 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 | |||
| 618 | static 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 | */ | ||
| 1118 | static 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 | ||
| 1257 | static 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 | */ |
| 1286 | static void codeeq (FuncState *fs, BinOpr opr, expdesc *e1, expdesc *e2) { | 1306 | static 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: |
| @@ -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 */ |
| @@ -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++ */ | |||
| 241 | OP_LE,/* A B C if ((R(B) <= R(C)) ~= A) then pc++ */ | 241 | OP_LE,/* A B C if ((R(B) <= R(C)) ~= A) then pc++ */ |
| 242 | 242 | ||
| 243 | OP_EQK,/* A B C if ((R(B) == K(C)) ~= A) then pc++ */ | 243 | OP_EQK,/* A B C if ((R(B) == K(C)) ~= A) then pc++ */ |
| 244 | OP_EQI,/* A B C if ((R(B) == C) ~= A) then pc++ */ | ||
| 244 | 245 | ||
| 245 | OP_TEST,/* A C if not (R(A) <=> C) then pc++ */ | 246 | OP_TEST,/* A C if not (R(A) <=> C) then pc++ */ |
| 246 | OP_TESTSET,/* A B C if (R(B) <=> C) then R(A) := R(B) else pc++ */ | 247 | OP_TESTSET,/* A B C if (R(B) <=> C) then R(A) := R(B) else pc++ */ |
| @@ -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++; |
