diff options
author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2017-11-28 10:58:18 -0200 |
---|---|---|
committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2017-11-28 10:58:18 -0200 |
commit | ff5fe5104413cf2a5156f86479d4b9b130bad7a6 (patch) | |
tree | 7ab4b89eafe1d39962c1aca42d47b40159416854 | |
parent | dfd188ba12f22db8d31cb80426d568e97345e1e2 (diff) | |
download | lua-ff5fe5104413cf2a5156f86479d4b9b130bad7a6.tar.gz lua-ff5fe5104413cf2a5156f86479d4b9b130bad7a6.tar.bz2 lua-ff5fe5104413cf2a5156f86479d4b9b130bad7a6.zip |
using register 'k' for conditions in tests (we only need one bit there)
-rw-r--r-- | lcode.c | 94 | ||||
-rw-r--r-- | lopcodes.h | 30 | ||||
-rw-r--r-- | lvm.c | 88 |
3 files changed, 120 insertions, 92 deletions
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: lcode.c,v 2.135 2017/11/22 19:15:44 roberto Exp roberto $ | 2 | ** $Id: lcode.c,v 2.136 2017/11/23 19:29:04 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 | */ |
@@ -160,8 +160,8 @@ void luaK_ret (FuncState *fs, int first, int nret) { | |||
160 | ** Code a "conditional jump", that is, a test or comparison opcode | 160 | ** Code a "conditional jump", that is, a test or comparison opcode |
161 | ** followed by a jump. Return jump position. | 161 | ** followed by a jump. Return jump position. |
162 | */ | 162 | */ |
163 | static int condjump (FuncState *fs, OpCode op, int A, int B, int C) { | 163 | static int condjump (FuncState *fs, OpCode op, int A, int B, int C, int k) { |
164 | luaK_codeABC(fs, op, A, B, C); | 164 | luaK_codeABCk(fs, op, A, B, C, k); |
165 | return luaK_jump(fs); | 165 | return luaK_jump(fs); |
166 | } | 166 | } |
167 | 167 | ||
@@ -206,7 +206,7 @@ static int patchtestreg (FuncState *fs, int node, int reg) { | |||
206 | else { | 206 | else { |
207 | /* no register to put value or register already has the value; | 207 | /* no register to put value or register already has the value; |
208 | change instruction to simple test */ | 208 | change instruction to simple test */ |
209 | *i = CREATE_ABCk(OP_TEST, GETARG_B(*i), 0, GETARG_C(*i), 0); | 209 | *i = CREATE_ABCk(OP_TEST, GETARG_B(*i), 0, 0, GETARG_k(*i)); |
210 | } | 210 | } |
211 | return 1; | 211 | return 1; |
212 | } | 212 | } |
@@ -969,7 +969,7 @@ static void negatecondition (FuncState *fs, expdesc *e) { | |||
969 | Instruction *pc = getjumpcontrol(fs, e->u.info); | 969 | Instruction *pc = getjumpcontrol(fs, e->u.info); |
970 | lua_assert(testTMode(GET_OPCODE(*pc)) && GET_OPCODE(*pc) != OP_TESTSET && | 970 | lua_assert(testTMode(GET_OPCODE(*pc)) && GET_OPCODE(*pc) != OP_TESTSET && |
971 | GET_OPCODE(*pc) != OP_TEST); | 971 | GET_OPCODE(*pc) != OP_TEST); |
972 | SETARG_B(*pc, !(GETARG_B(*pc))); | 972 | SETARG_k(*pc, (GETARG_k(*pc) ^ 1)); |
973 | } | 973 | } |
974 | 974 | ||
975 | 975 | ||
@@ -984,13 +984,13 @@ static int jumponcond (FuncState *fs, expdesc *e, int cond) { | |||
984 | Instruction ie = getinstruction(fs, e); | 984 | Instruction ie = getinstruction(fs, e); |
985 | if (GET_OPCODE(ie) == OP_NOT) { | 985 | if (GET_OPCODE(ie) == OP_NOT) { |
986 | fs->pc--; /* remove previous OP_NOT */ | 986 | fs->pc--; /* remove previous OP_NOT */ |
987 | return condjump(fs, OP_TEST, GETARG_B(ie), 0, !cond); | 987 | return condjump(fs, OP_TEST, GETARG_B(ie), 0, 0, !cond); |
988 | } | 988 | } |
989 | /* else go through */ | 989 | /* else go through */ |
990 | } | 990 | } |
991 | discharge2anyreg(fs, e); | 991 | discharge2anyreg(fs, e); |
992 | freeexp(fs, e); | 992 | freeexp(fs, e); |
993 | return condjump(fs, OP_TESTSET, NO_REG, e->u.info, cond); | 993 | return condjump(fs, OP_TESTSET, NO_REG, e->u.info, 0, cond); |
994 | } | 994 | } |
995 | 995 | ||
996 | 996 | ||
@@ -1276,25 +1276,37 @@ static void codecommutative (FuncState *fs, OpCode op, | |||
1276 | 1276 | ||
1277 | /* | 1277 | /* |
1278 | ** Emit code for order comparisons. | 1278 | ** Emit code for order comparisons. |
1279 | ** 'e1' was already put in register by 'luaK_infix'. | 1279 | ** When the first operand is an integral value in the proper range, |
1280 | ** change (A < B) to (!(B <= A)) and (A <= B) to (!(B < A)) so that | ||
1281 | ** it can use an immediate operand. In this case, C indicates this | ||
1282 | ** change, for cases that cannot assume a total order (NaN and | ||
1283 | ** metamethods). | ||
1280 | */ | 1284 | */ |
1281 | static void codeorder (FuncState *fs, BinOpr opr, expdesc *e1, expdesc *e2) { | 1285 | static void codeorder (FuncState *fs, OpCode op, expdesc *e1, expdesc *e2) { |
1282 | int rk1 = check_exp(e1->k == VNONRELOC, e1->u.info); | 1286 | int r1, r2; |
1283 | int rk2 = luaK_exp2anyreg(fs, e2); | 1287 | int cond = 1; |
1284 | freeexps(fs, e1, e2); | 1288 | int C = 0; |
1285 | switch (opr) { | 1289 | lua_Integer im; |
1286 | case OPR_GT: case OPR_GE: { | 1290 | if (isSCnumber(e2, &im)) { |
1287 | /* '(a > b)' ==> '(b < a)'; '(a >= b)' ==> '(b <= a)' */ | 1291 | /* use immediate operand */ |
1288 | OpCode op = cast(OpCode, (opr - OPR_NE) + OP_EQ); | 1292 | r1 = luaK_exp2anyreg(fs, e1); |
1289 | e1->u.info = condjump(fs, op, rk2, 1, rk1); /* invert operands */ | 1293 | r2 = cast_int(im); |
1290 | break; | 1294 | op = cast(OpCode, (op - OP_LT) + OP_LTI); |
1291 | } | 1295 | } |
1292 | default: { /* '==', '<', '<=' use their own opcodes */ | 1296 | else if (isSCnumber(e1, &im)) { |
1293 | OpCode op = cast(OpCode, (opr - OPR_EQ) + OP_EQ); | 1297 | /* transform (A < B) to (!(B <= A)) and (A <= B) to (!(B < A)) */ |
1294 | e1->u.info = condjump(fs, op, rk1, 1, rk2); | 1298 | r1 = luaK_exp2anyreg(fs, e2); |
1295 | break; | 1299 | r2 = cast_int(im); |
1296 | } | 1300 | op = (op == OP_LT) ? OP_LEI : OP_LTI; |
1301 | cond = 0; /* negate original test */ | ||
1302 | C = 1; /* indication that it used the transformations */ | ||
1297 | } | 1303 | } |
1304 | else { /* regular case, compare two registers */ | ||
1305 | r1 = luaK_exp2anyreg(fs, e1); | ||
1306 | r2 = luaK_exp2anyreg(fs, e2); | ||
1307 | } | ||
1308 | freeexps(fs, e1, e2); | ||
1309 | e1->u.info = condjump(fs, op, r1, r2, C, cond); | ||
1298 | e1->k = VJMP; | 1310 | e1->k = VJMP; |
1299 | } | 1311 | } |
1300 | 1312 | ||
@@ -1325,7 +1337,7 @@ static void codeeq (FuncState *fs, BinOpr opr, expdesc *e1, expdesc *e2) { | |||
1325 | r2 = luaK_exp2anyreg(fs, e2); | 1337 | r2 = luaK_exp2anyreg(fs, e2); |
1326 | } | 1338 | } |
1327 | freeexps(fs, e1, e2); | 1339 | freeexps(fs, e1, e2); |
1328 | e1->u.info = condjump(fs, op, r1, (opr == OPR_EQ), r2); | 1340 | e1->u.info = condjump(fs, op, r1, r2, 0, (opr == OPR_EQ)); |
1329 | e1->k = VJMP; | 1341 | e1->k = VJMP; |
1330 | } | 1342 | } |
1331 | 1343 | ||
@@ -1385,7 +1397,10 @@ void luaK_infix (FuncState *fs, BinOpr op, expdesc *v) { | |||
1385 | } | 1397 | } |
1386 | case OPR_LT: case OPR_LE: | 1398 | case OPR_LT: case OPR_LE: |
1387 | case OPR_GT: case OPR_GE: { | 1399 | case OPR_GT: case OPR_GE: { |
1388 | luaK_exp2anyreg(fs, v); | 1400 | lua_Integer dummy; |
1401 | if (!isSCnumber(v, &dummy)) | ||
1402 | luaK_exp2RK(fs, v); | ||
1403 | /* else keep numeral, which may be an immediate operand */ | ||
1389 | break; | 1404 | break; |
1390 | } | 1405 | } |
1391 | default: lua_assert(0); | 1406 | default: lua_assert(0); |
@@ -1399,9 +1414,9 @@ void luaK_infix (FuncState *fs, BinOpr op, expdesc *v) { | |||
1399 | ** concatenation is right associative), merge second CONCAT into first | 1414 | ** concatenation is right associative), merge second CONCAT into first |
1400 | ** one. | 1415 | ** one. |
1401 | */ | 1416 | */ |
1402 | void luaK_posfix (FuncState *fs, BinOpr op, | 1417 | void luaK_posfix (FuncState *fs, BinOpr opr, |
1403 | expdesc *e1, expdesc *e2, int line) { | 1418 | expdesc *e1, expdesc *e2, int line) { |
1404 | switch (op) { | 1419 | switch (opr) { |
1405 | case OPR_AND: { | 1420 | case OPR_AND: { |
1406 | lua_assert(e1->t == NO_JUMP); /* list closed by 'luK_infix' */ | 1421 | lua_assert(e1->t == NO_JUMP); /* list closed by 'luK_infix' */ |
1407 | luaK_dischargevars(fs, e2); | 1422 | luaK_dischargevars(fs, e2); |
@@ -1432,28 +1447,35 @@ void luaK_posfix (FuncState *fs, BinOpr op, | |||
1432 | break; | 1447 | break; |
1433 | } | 1448 | } |
1434 | case OPR_ADD: case OPR_MUL: { | 1449 | case OPR_ADD: case OPR_MUL: { |
1435 | if (!constfolding(fs, op + LUA_OPADD, e1, e2)) | 1450 | if (!constfolding(fs, opr + LUA_OPADD, e1, e2)) |
1436 | codecommutative(fs, cast(OpCode, op + OP_ADD), e1, e2, line); | 1451 | codecommutative(fs, cast(OpCode, opr + OP_ADD), e1, e2, line); |
1437 | break; | 1452 | break; |
1438 | } | 1453 | } |
1439 | case OPR_SUB: case OPR_DIV: | 1454 | case OPR_SUB: case OPR_DIV: |
1440 | case OPR_IDIV: case OPR_MOD: case OPR_POW: { | 1455 | case OPR_IDIV: case OPR_MOD: case OPR_POW: { |
1441 | if (!constfolding(fs, op + LUA_OPADD, e1, e2)) | 1456 | if (!constfolding(fs, opr + LUA_OPADD, e1, e2)) |
1442 | codearith(fs, cast(OpCode, op + OP_ADD), e1, e2, 0, line); | 1457 | codearith(fs, cast(OpCode, opr + OP_ADD), e1, e2, 0, line); |
1443 | break; | 1458 | break; |
1444 | } | 1459 | } |
1445 | case OPR_BAND: case OPR_BOR: case OPR_BXOR: | 1460 | case OPR_BAND: case OPR_BOR: case OPR_BXOR: |
1446 | case OPR_SHL: case OPR_SHR: { | 1461 | case OPR_SHL: case OPR_SHR: { |
1447 | if (!constfolding(fs, op + LUA_OPADD, e1, e2)) | 1462 | if (!constfolding(fs, opr + LUA_OPADD, e1, e2)) |
1448 | codebinexpval(fs, cast(OpCode, op + OP_ADD), e1, e2, line); | 1463 | codebinexpval(fs, cast(OpCode, opr + OP_ADD), e1, e2, line); |
1449 | break; | 1464 | break; |
1450 | } | 1465 | } |
1451 | case OPR_EQ: case OPR_NE: { | 1466 | case OPR_EQ: case OPR_NE: { |
1452 | codeeq(fs, op, e1, e2); | 1467 | codeeq(fs, opr, e1, e2); |
1468 | break; | ||
1469 | } | ||
1470 | case OPR_LT: case OPR_LE: { | ||
1471 | OpCode op = cast(OpCode, (opr - OPR_EQ) + OP_EQ); | ||
1472 | codeorder(fs, op, e1, e2); | ||
1453 | break; | 1473 | break; |
1454 | } | 1474 | } |
1455 | case OPR_LT: case OPR_LE: | ||
1456 | case OPR_GT: case OPR_GE: { | 1475 | case OPR_GT: case OPR_GE: { |
1476 | /* '(a > b)' <=> '(b < a)'; '(a >= b)' <=> '(b <= a)' */ | ||
1477 | OpCode op = cast(OpCode, (opr - OPR_NE) + OP_EQ); | ||
1478 | swapexps(e1, e2); | ||
1457 | codeorder(fs, op, e1, e2); | 1479 | codeorder(fs, op, e1, e2); |
1458 | break; | 1480 | break; |
1459 | } | 1481 | } |
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: lopcodes.h,v 1.170 2017/11/22 19:15:44 roberto Exp roberto $ | 2 | ** $Id: lopcodes.h,v 1.171 2017/11/27 17:44:31 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 | */ |
@@ -114,13 +114,15 @@ enum OpMode {iABC, iABx, iAsBx, iAx, isJ}; /* basic instruction formats */ | |||
114 | #define SETARG_A(i,v) setarg(i, v, POS_A, SIZE_A) | 114 | #define SETARG_A(i,v) setarg(i, v, POS_A, SIZE_A) |
115 | 115 | ||
116 | #define GETARG_B(i) check_exp(checkopm(i, iABC), getarg(i, POS_B, SIZE_B)) | 116 | #define GETARG_B(i) check_exp(checkopm(i, iABC), getarg(i, POS_B, SIZE_B)) |
117 | #define GETARG_sB(i) (GETARG_B(i) - MAXARG_sC) | ||
117 | #define SETARG_B(i,v) setarg(i, v, POS_B, SIZE_B) | 118 | #define SETARG_B(i,v) setarg(i, v, POS_B, SIZE_B) |
118 | 119 | ||
119 | #define GETARG_C(i) check_exp(checkopm(i, iABC), getarg(i, POS_C, SIZE_C)) | 120 | #define GETARG_C(i) check_exp(checkopm(i, iABC), getarg(i, POS_C, SIZE_C)) |
120 | #define GETARG_sC(i) (GETARG_C(i) - MAXARG_sC) | 121 | #define GETARG_sC(i) (GETARG_C(i) - MAXARG_sC) |
121 | #define SETARG_C(i,v) setarg(i, v, POS_C, SIZE_C) | 122 | #define SETARG_C(i,v) setarg(i, v, POS_C, SIZE_C) |
122 | 123 | ||
123 | #define GETARG_k(i) (cast(int, ((i) & (1 << POS_k)))) | 124 | #define TESTARG_k(i) (cast(int, ((i) & (1 << POS_k)))) |
125 | #define GETARG_k(i) getarg(i, POS_k, 1) | ||
124 | #define SETARG_k(i,v) setarg(i, v, POS_k, 1) | 126 | #define SETARG_k(i,v) setarg(i, v, POS_k, 1) |
125 | 127 | ||
126 | #define GETARG_Bx(i) check_exp(checkopm(i, iABx), getarg(i, POS_Bx, SIZE_Bx)) | 128 | #define GETARG_Bx(i) check_exp(checkopm(i, iABx), getarg(i, POS_Bx, SIZE_Bx)) |
@@ -236,17 +238,17 @@ OP_CONCAT,/* A B C R(A) := R(B).. ... ..R(C) */ | |||
236 | 238 | ||
237 | OP_CLOSE,/* A close all upvalues >= R(A) */ | 239 | OP_CLOSE,/* A close all upvalues >= R(A) */ |
238 | OP_JMP,/* k sJ pc += sJ (k is used in code generation) */ | 240 | OP_JMP,/* k sJ pc += sJ (k is used in code generation) */ |
239 | OP_EQ,/* A B C if ((R(A) == R(C)) ~= B) then pc++ */ | 241 | OP_EQ,/* A B if ((R(A) == R(B)) ~= k) then pc++ */ |
240 | OP_LT,/* A B C if ((R(A) < R(C)) ~= B) then pc++ */ | 242 | OP_LT,/* A B if ((R(A) < R(B)) ~= k) then pc++ */ |
241 | OP_LE,/* A B C if ((R(A) <= R(C)) ~= B) then pc++ */ | 243 | OP_LE,/* A B if ((R(A) <= R(B)) ~= k) then pc++ */ |
242 | 244 | ||
243 | OP_EQK,/* A B C if ((R(A) == K(C)) ~= B) then pc++ */ | 245 | OP_EQK,/* A B if ((R(A) == K(B)) ~= k) then pc++ */ |
244 | OP_EQI,/* A B C if ((R(A) == C) ~= B) then pc++ */ | 246 | OP_EQI,/* A sB if ((R(A) == sB) ~= k) then pc++ */ |
245 | OP_LTI,/* A B C if ((R(A) < C) ~= B) then pc++ */ | 247 | OP_LTI,/* A sB if ((R(A) < sB) ~= k) then pc++ */ |
246 | OP_LEI,/* A B C if ((R(A) <= C) ~= B) then pc++ */ | 248 | OP_LEI,/* A sB if ((R(A) <= sB) ~= k) then pc++ */ |
247 | 249 | ||
248 | OP_TEST,/* A C if not (R(A) <=> C) then pc++ */ | 250 | OP_TEST,/* A if (not R(A) == k) then pc++ */ |
249 | OP_TESTSET,/* A B C if (R(B) <=> C) then R(A) := R(B) else pc++ */ | 251 | OP_TESTSET,/* A B if (not R(B) == k) then R(A) := R(B) else pc++ */ |
250 | 252 | ||
251 | OP_CALL,/* A B C R(A), ... ,R(A+C-2) := R(A)(R(A+1), ... ,R(A+B-1)) */ | 253 | OP_CALL,/* A B C R(A), ... ,R(A+C-2) := R(A)(R(A+1), ... ,R(A+B-1)) */ |
252 | OP_TAILCALL,/* A B C return R(A)(R(A+1), ... ,R(A+B-1)) */ | 254 | OP_TAILCALL,/* A B C return R(A)(R(A+1), ... ,R(A+B-1)) */ |
@@ -289,9 +291,13 @@ OP_EXTRAARG/* Ax extra (larger) argument for previous opcode */ | |||
289 | 291 | ||
290 | (*) In OP_LOADKX, the next 'instruction' is always EXTRAARG. | 292 | (*) In OP_LOADKX, the next 'instruction' is always EXTRAARG. |
291 | 293 | ||
292 | (*) For comparisons, A specifies what condition the test should accept | 294 | (*) For comparisons, k specifies what condition the test should accept |
293 | (true or false). | 295 | (true or false). |
294 | 296 | ||
297 | (*) For OP_LTI/OP_LEI, C indicates that the transformations | ||
298 | (A<B) => (!(B<=A)) or (A<=B) => (!(B<A)) were used to put the | ||
299 | constant operator on the right side. | ||
300 | |||
295 | (*) All 'skips' (pc++) assume that next instruction is a jump. | 301 | (*) All 'skips' (pc++) assume that next instruction is a jump. |
296 | 302 | ||
297 | ===========================================================================*/ | 303 | ===========================================================================*/ |
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: lvm.c,v 2.317 2017/11/23 19:18:10 roberto Exp roberto $ | 2 | ** $Id: lvm.c,v 2.318 2017/11/27 17:44:31 roberto Exp roberto $ |
3 | ** Lua virtual machine | 3 | ** Lua virtual machine |
4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
5 | */ | 5 | */ |
@@ -702,14 +702,14 @@ void luaV_finishOp (lua_State *L) { | |||
702 | L->top--; | 702 | L->top--; |
703 | if (ci->callstatus & CIST_LEQ) { /* "<=" using "<" instead? */ | 703 | if (ci->callstatus & CIST_LEQ) { /* "<=" using "<" instead? */ |
704 | lua_assert(op == OP_LE || | 704 | lua_assert(op == OP_LE || |
705 | (op == OP_LEI && !(GETARG_B(inst) & 2)) || | 705 | (op == OP_LTI && GETARG_C(inst)) || |
706 | (op == OP_LTI && GETARG_B(inst) & 2)); | 706 | (op == OP_LEI && !GETARG_C(inst))); |
707 | ci->callstatus ^= CIST_LEQ; /* clear mark */ | 707 | ci->callstatus ^= CIST_LEQ; /* clear mark */ |
708 | res = !res; /* negate result */ | 708 | res = !res; /* negate result */ |
709 | } | 709 | } |
710 | lua_assert(GET_OPCODE(*ci->u.l.savedpc) == OP_JMP); | 710 | lua_assert(GET_OPCODE(*ci->u.l.savedpc) == OP_JMP); |
711 | if (GETARG_B(inst) & 2) res = !res; | 711 | if (GETARG_C(inst)) res = !res; |
712 | if (res != (GETARG_B(inst) & 1)) /* condition failed? */ | 712 | if (res != GETARG_k(inst)) /* condition failed? */ |
713 | ci->u.l.savedpc++; /* skip jump instruction */ | 713 | ci->u.l.savedpc++; /* skip jump instruction */ |
714 | break; | 714 | break; |
715 | } | 715 | } |
@@ -766,7 +766,7 @@ void luaV_finishOp (lua_State *L) { | |||
766 | #define RC(i) (base+GETARG_C(i)) | 766 | #define RC(i) (base+GETARG_C(i)) |
767 | #define vRC(i) s2v(RC(i)) | 767 | #define vRC(i) s2v(RC(i)) |
768 | #define KC(i) (k+GETARG_C(i)) | 768 | #define KC(i) (k+GETARG_C(i)) |
769 | #define RKC(i) ((GETARG_k(i)) ? k + GETARG_C(i) : s2v(base + GETARG_C(i))) | 769 | #define RKC(i) ((TESTARG_k(i)) ? k + GETARG_C(i) : s2v(base + GETARG_C(i))) |
770 | 770 | ||
771 | 771 | ||
772 | 772 | ||
@@ -1326,59 +1326,59 @@ void luaV_execute (lua_State *L) { | |||
1326 | vmbreak; | 1326 | vmbreak; |
1327 | } | 1327 | } |
1328 | vmcase(OP_EQ) { | 1328 | vmcase(OP_EQ) { |
1329 | TValue *rc = vRC(i); | 1329 | TValue *rb = vRB(i); |
1330 | int res; | 1330 | int res; |
1331 | Protect(res = luaV_equalobj(L, s2v(ra), rc)); | 1331 | Protect(res = luaV_equalobj(L, s2v(ra), rb)); |
1332 | if (res != GETARG_B(i)) | 1332 | if (res != GETARG_k(i)) |
1333 | pc++; | 1333 | pc++; |
1334 | else | 1334 | else |
1335 | donextjump(ci); | 1335 | donextjump(ci); |
1336 | vmbreak; | 1336 | vmbreak; |
1337 | } | 1337 | } |
1338 | vmcase(OP_LT) { | 1338 | vmcase(OP_LT) { |
1339 | TValue *rc = vRC(i); | 1339 | TValue *rb = vRB(i); |
1340 | int res; | 1340 | int res; |
1341 | if (ttisinteger(s2v(ra)) && ttisinteger(rc)) | 1341 | if (ttisinteger(s2v(ra)) && ttisinteger(rb)) |
1342 | res = (ivalue(s2v(ra)) < ivalue(rc)); | 1342 | res = (ivalue(s2v(ra)) < ivalue(rb)); |
1343 | else if (ttisnumber(s2v(ra)) && ttisnumber(rc)) | 1343 | else if (ttisnumber(s2v(ra)) && ttisnumber(rb)) |
1344 | res = LTnum(s2v(ra), rc); | 1344 | res = LTnum(s2v(ra), rb); |
1345 | else | 1345 | else |
1346 | Protect(res = lessthanothers(L, s2v(ra), rc)); | 1346 | Protect(res = lessthanothers(L, s2v(ra), rb)); |
1347 | if (res != GETARG_B(i)) | 1347 | if (res != GETARG_k(i)) |
1348 | pc++; | 1348 | pc++; |
1349 | else | 1349 | else |
1350 | donextjump(ci); | 1350 | donextjump(ci); |
1351 | vmbreak; | 1351 | vmbreak; |
1352 | } | 1352 | } |
1353 | vmcase(OP_LE) { | 1353 | vmcase(OP_LE) { |
1354 | TValue *rc = vRC(i); | 1354 | TValue *rb = vRB(i); |
1355 | int res; | 1355 | int res; |
1356 | if (ttisinteger(s2v(ra)) && ttisinteger(rc)) | 1356 | if (ttisinteger(s2v(ra)) && ttisinteger(rb)) |
1357 | res = (ivalue(s2v(ra)) <= ivalue(rc)); | 1357 | res = (ivalue(s2v(ra)) <= ivalue(rb)); |
1358 | else if (ttisnumber(s2v(ra)) && ttisnumber(rc)) | 1358 | else if (ttisnumber(s2v(ra)) && ttisnumber(rb)) |
1359 | res = LEnum(s2v(ra), rc); | 1359 | res = LEnum(s2v(ra), rb); |
1360 | else | 1360 | else |
1361 | Protect(res = lessequalothers(L, s2v(ra), rc)); | 1361 | Protect(res = lessequalothers(L, s2v(ra), rb)); |
1362 | if (res != GETARG_B(i)) | 1362 | if (res != GETARG_k(i)) |
1363 | pc++; | 1363 | pc++; |
1364 | else | 1364 | else |
1365 | donextjump(ci); | 1365 | donextjump(ci); |
1366 | vmbreak; | 1366 | vmbreak; |
1367 | } | 1367 | } |
1368 | vmcase(OP_EQK) { | 1368 | vmcase(OP_EQK) { |
1369 | TValue *rc = KC(i); | 1369 | TValue *rb = KB(i); |
1370 | /* basic types do not use '__eq'; we can use raw equality */ | 1370 | /* basic types do not use '__eq'; we can use raw equality */ |
1371 | if (luaV_equalobj(NULL, s2v(ra), rc) != GETARG_B(i)) | 1371 | if (luaV_equalobj(NULL, s2v(ra), rb) != GETARG_k(i)) |
1372 | pc++; | 1372 | pc++; |
1373 | else | 1373 | else |
1374 | donextjump(ci); | 1374 | donextjump(ci); |
1375 | vmbreak; | 1375 | vmbreak; |
1376 | } | 1376 | } |
1377 | vmcase(OP_EQI) { | 1377 | vmcase(OP_EQI) { |
1378 | int ic = GETARG_sC(i); | 1378 | int im = GETARG_sB(i); |
1379 | if ((ttisinteger(s2v(ra)) ? (ivalue(s2v(ra)) == ic) | 1379 | if ((ttisinteger(s2v(ra)) ? (ivalue(s2v(ra)) == im) |
1380 | :ttisfloat(s2v(ra)) ? luai_numeq(fltvalue(s2v(ra)), cast_num(ic)) | 1380 | :ttisfloat(s2v(ra)) ? luai_numeq(fltvalue(s2v(ra)), cast_num(im)) |
1381 | : 0) != GETARG_B(i)) | 1381 | : 0) != GETARG_k(i)) |
1382 | pc++; | 1382 | pc++; |
1383 | else | 1383 | else |
1384 | donextjump(ci); | 1384 | donextjump(ci); |
@@ -1386,17 +1386,17 @@ void luaV_execute (lua_State *L) { | |||
1386 | } | 1386 | } |
1387 | vmcase(OP_LTI) { | 1387 | vmcase(OP_LTI) { |
1388 | int res; | 1388 | int res; |
1389 | int ic = GETARG_sC(i); | 1389 | int im = GETARG_sB(i); |
1390 | if (ttisinteger(s2v(ra))) | 1390 | if (ttisinteger(s2v(ra))) |
1391 | res = (ivalue(s2v(ra)) < ic); | 1391 | res = (ivalue(s2v(ra)) < im); |
1392 | else if (ttisfloat(s2v(ra))) { | 1392 | else if (ttisfloat(s2v(ra))) { |
1393 | lua_Number f = fltvalue(s2v(ra)); | 1393 | lua_Number f = fltvalue(s2v(ra)); |
1394 | res = (!luai_numisnan(f)) ? luai_numlt(f, cast_num(ic)) | 1394 | res = (!luai_numisnan(f)) ? luai_numlt(f, cast_num(im)) |
1395 | : GETARG_B(i) >> 1; /* NaN? */ | 1395 | : GETARG_C(i); /* NaN? */ |
1396 | } | 1396 | } |
1397 | else | 1397 | else |
1398 | Protect(res = luaT_callorderiTM(L, s2v(ra), ic, GETARG_B(i) >> 1, TM_LT)); | 1398 | Protect(res = luaT_callorderiTM(L, s2v(ra), im, GETARG_C(i), TM_LT)); |
1399 | if (res != (GETARG_B(i) & 1)) | 1399 | if (res != GETARG_k(i)) |
1400 | pc++; | 1400 | pc++; |
1401 | else | 1401 | else |
1402 | donextjump(ci); | 1402 | donextjump(ci); |
@@ -1404,32 +1404,32 @@ void luaV_execute (lua_State *L) { | |||
1404 | } | 1404 | } |
1405 | vmcase(OP_LEI) { | 1405 | vmcase(OP_LEI) { |
1406 | int res; | 1406 | int res; |
1407 | int ic = GETARG_sC(i); | 1407 | int im = GETARG_sB(i); |
1408 | if (ttisinteger(s2v(ra))) | 1408 | if (ttisinteger(s2v(ra))) |
1409 | res = (ivalue(s2v(ra)) <= ic); | 1409 | res = (ivalue(s2v(ra)) <= im); |
1410 | else if (ttisfloat(s2v(ra))) { | 1410 | else if (ttisfloat(s2v(ra))) { |
1411 | lua_Number f = fltvalue(s2v(ra)); | 1411 | lua_Number f = fltvalue(s2v(ra)); |
1412 | res = (!luai_numisnan(f)) ? luai_numle(f, cast_num(ic)) | 1412 | res = (!luai_numisnan(f)) ? luai_numle(f, cast_num(im)) |
1413 | : GETARG_B(i) >> 1; /* NaN? */ | 1413 | : GETARG_C(i); /* NaN? */ |
1414 | } | 1414 | } |
1415 | else | 1415 | else |
1416 | Protect(res = luaT_callorderiTM(L, s2v(ra), ic, GETARG_B(i) >> 1, TM_LE)); | 1416 | Protect(res = luaT_callorderiTM(L, s2v(ra), im, GETARG_C(i), TM_LE)); |
1417 | if (res != (GETARG_B(i) & 1)) | 1417 | if (res != GETARG_k(i)) |
1418 | pc++; | 1418 | pc++; |
1419 | else | 1419 | else |
1420 | donextjump(ci); | 1420 | donextjump(ci); |
1421 | vmbreak; | 1421 | vmbreak; |
1422 | } | 1422 | } |
1423 | vmcase(OP_TEST) { | 1423 | vmcase(OP_TEST) { |
1424 | if (GETARG_C(i) ? l_isfalse(s2v(ra)) : !l_isfalse(s2v(ra))) | 1424 | if (l_isfalse(s2v(ra)) == GETARG_k(i)) |
1425 | pc++; | 1425 | pc++; |
1426 | else | 1426 | else |
1427 | donextjump(ci); | 1427 | donextjump(ci); |
1428 | vmbreak; | 1428 | vmbreak; |
1429 | } | 1429 | } |
1430 | vmcase(OP_TESTSET) { | 1430 | vmcase(OP_TESTSET) { |
1431 | TValue *rb = vRB(i); | 1431 | TValue *rb = vRB(i); |
1432 | if (GETARG_C(i) ? l_isfalse(rb) : !l_isfalse(rb)) | 1432 | if (l_isfalse(rb) == GETARG_k(i)) |
1433 | pc++; | 1433 | pc++; |
1434 | else { | 1434 | else { |
1435 | setobj2s(L, ra, rb); | 1435 | setobj2s(L, ra, rb); |