aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>2018-02-21 12:49:32 -0300
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>2018-02-21 12:49:32 -0300
commit212095a601ee68e99065b553f7b6bc216056d82e (patch)
tree3843f9dde40eeb71c56ac8a0be8d77c78272f6ef
parentc67603fafba7f982e92eb870ff4da6c6433c2a85 (diff)
downloadlua-212095a601ee68e99065b553f7b6bc216056d82e.tar.gz
lua-212095a601ee68e99065b553f7b6bc216056d82e.tar.bz2
lua-212095a601ee68e99065b553f7b6bc216056d82e.zip
new opcodes OP_GTI/OP_GEI
-rw-r--r--lcode.c30
-rw-r--r--lopcodes.c6
-rw-r--r--lopcodes.h9
-rw-r--r--ltm.c5
-rw-r--r--lvm.c45
5 files changed, 50 insertions, 45 deletions
diff --git a/lcode.c b/lcode.c
index c182794e..30bf13d8 100644
--- a/lcode.c
+++ b/lcode.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lcode.c,v 2.155 2018/02/17 19:20:00 roberto Exp roberto $ 2** $Id: lcode.c,v 2.156 2018/02/21 12:54:26 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*/
@@ -171,8 +171,8 @@ void luaK_ret (FuncState *fs, int first, int nret) {
171** Code a "conditional jump", that is, a test or comparison opcode 171** Code a "conditional jump", that is, a test or comparison opcode
172** followed by a jump. Return jump position. 172** followed by a jump. Return jump position.
173*/ 173*/
174static int condjump (FuncState *fs, OpCode op, int A, int B, int C, int k) { 174static int condjump (FuncState *fs, OpCode op, int A, int B, int k) {
175 luaK_codeABCk(fs, op, A, B, C, k); 175 luaK_codeABCk(fs, op, A, B, 0, k);
176 return luaK_jump(fs); 176 return luaK_jump(fs);
177} 177}
178 178
@@ -979,13 +979,13 @@ static int jumponcond (FuncState *fs, expdesc *e, int cond) {
979 Instruction ie = getinstruction(fs, e); 979 Instruction ie = getinstruction(fs, e);
980 if (GET_OPCODE(ie) == OP_NOT) { 980 if (GET_OPCODE(ie) == OP_NOT) {
981 fs->pc--; /* remove previous OP_NOT */ 981 fs->pc--; /* remove previous OP_NOT */
982 return condjump(fs, OP_TEST, GETARG_B(ie), 0, 0, !cond); 982 return condjump(fs, OP_TEST, GETARG_B(ie), 0, !cond);
983 } 983 }
984 /* else go through */ 984 /* else go through */
985 } 985 }
986 discharge2anyreg(fs, e); 986 discharge2anyreg(fs, e);
987 freeexp(fs, e); 987 freeexp(fs, e);
988 return condjump(fs, OP_TESTSET, NO_REG, e->u.info, 0, cond); 988 return condjump(fs, OP_TESTSET, NO_REG, e->u.info, cond);
989} 989}
990 990
991 991
@@ -1338,16 +1338,12 @@ static void codeshift (FuncState *fs, OpCode op,
1338 1338
1339/* 1339/*
1340** Emit code for order comparisons. 1340** Emit code for order comparisons.
1341** When the first operand is an integral value in the proper range, 1341** When the first operand A is an integral value in the proper range,
1342** change (A < B) to (!(B <= A)) and (A <= B) to (!(B < A)) so that 1342** change (A < B) to (B > A) and (A <= B) to (B >= A) so that
1343** it can use an immediate operand. In this case, C indicates this 1343** it can use an immediate operand.
1344** change, for cases that cannot assume a total order (NaN and
1345** metamethods).
1346*/ 1344*/
1347static void codeorder (FuncState *fs, OpCode op, expdesc *e1, expdesc *e2) { 1345static void codeorder (FuncState *fs, OpCode op, expdesc *e1, expdesc *e2) {
1348 int r1, r2; 1346 int r1, r2;
1349 int cond = 1;
1350 int C = 0;
1351 lua_Integer im; 1347 lua_Integer im;
1352 if (isSCnumber(e2, &im)) { 1348 if (isSCnumber(e2, &im)) {
1353 /* use immediate operand */ 1349 /* use immediate operand */
@@ -1356,19 +1352,17 @@ static void codeorder (FuncState *fs, OpCode op, expdesc *e1, expdesc *e2) {
1356 op = cast(OpCode, (op - OP_LT) + OP_LTI); 1352 op = cast(OpCode, (op - OP_LT) + OP_LTI);
1357 } 1353 }
1358 else if (isSCnumber(e1, &im)) { 1354 else if (isSCnumber(e1, &im)) {
1359 /* transform (A < B) to (!(B <= A)) and (A <= B) to (!(B < A)) */ 1355 /* transform (A < B) to (B > A) and (A <= B) to (B >= A) */
1360 r1 = luaK_exp2anyreg(fs, e2); 1356 r1 = luaK_exp2anyreg(fs, e2);
1361 r2 = cast_int(im); 1357 r2 = cast_int(im);
1362 op = (op == OP_LT) ? OP_LEI : OP_LTI; 1358 op = (op == OP_LT) ? OP_GTI : OP_GEI;
1363 cond = 0; /* negate original test */
1364 C = 1; /* indication that it used the transformations */
1365 } 1359 }
1366 else { /* regular case, compare two registers */ 1360 else { /* regular case, compare two registers */
1367 r1 = luaK_exp2anyreg(fs, e1); 1361 r1 = luaK_exp2anyreg(fs, e1);
1368 r2 = luaK_exp2anyreg(fs, e2); 1362 r2 = luaK_exp2anyreg(fs, e2);
1369 } 1363 }
1370 freeexps(fs, e1, e2); 1364 freeexps(fs, e1, e2);
1371 e1->u.info = condjump(fs, op, r1, r2, C, cond); 1365 e1->u.info = condjump(fs, op, r1, r2, 1);
1372 e1->k = VJMP; 1366 e1->k = VJMP;
1373} 1367}
1374 1368
@@ -1399,7 +1393,7 @@ static void codeeq (FuncState *fs, BinOpr opr, expdesc *e1, expdesc *e2) {
1399 r2 = luaK_exp2anyreg(fs, e2); 1393 r2 = luaK_exp2anyreg(fs, e2);
1400 } 1394 }
1401 freeexps(fs, e1, e2); 1395 freeexps(fs, e1, e2);
1402 e1->u.info = condjump(fs, op, r1, r2, 0, (opr == OPR_EQ)); 1396 e1->u.info = condjump(fs, op, r1, r2, (opr == OPR_EQ));
1403 e1->k = VJMP; 1397 e1->k = VJMP;
1404} 1398}
1405 1399
diff --git a/lopcodes.c b/lopcodes.c
index aa3055be..79d77cc1 100644
--- a/lopcodes.c
+++ b/lopcodes.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lopcodes.c,v 1.77 2018/02/09 15:16:06 roberto Exp roberto $ 2** $Id: lopcodes.c,v 1.78 2018/02/15 15:34:29 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*/
@@ -75,6 +75,8 @@ LUAI_DDEF const char *const luaP_opnames[NUM_OPCODES+1] = {
75 "EQI", 75 "EQI",
76 "LTI", 76 "LTI",
77 "LEI", 77 "LEI",
78 "GTI",
79 "GEI",
78 "TEST", 80 "TEST",
79 "TESTSET", 81 "TESTSET",
80 "CALL", 82 "CALL",
@@ -156,6 +158,8 @@ LUAI_DDEF const lu_byte luaP_opmodes[NUM_OPCODES] = {
156 ,opmode(0, 0, 1, 0, iABC) /* OP_EQI */ 158 ,opmode(0, 0, 1, 0, iABC) /* OP_EQI */
157 ,opmode(0, 0, 1, 0, iABC) /* OP_LTI */ 159 ,opmode(0, 0, 1, 0, iABC) /* OP_LTI */
158 ,opmode(0, 0, 1, 0, iABC) /* OP_LEI */ 160 ,opmode(0, 0, 1, 0, iABC) /* OP_LEI */
161 ,opmode(0, 0, 1, 0, iABC) /* OP_GTI */
162 ,opmode(0, 0, 1, 0, iABC) /* OP_GEI */
159 ,opmode(0, 0, 1, 0, iABC) /* OP_TEST */ 163 ,opmode(0, 0, 1, 0, iABC) /* OP_TEST */
160 ,opmode(0, 0, 1, 1, iABC) /* OP_TESTSET */ 164 ,opmode(0, 0, 1, 1, iABC) /* OP_TESTSET */
161 ,opmode(1, 1, 0, 1, iABC) /* OP_CALL */ 165 ,opmode(1, 1, 0, 1, iABC) /* OP_CALL */
diff --git a/lopcodes.h b/lopcodes.h
index b2e22c27..be7359e9 100644
--- a/lopcodes.h
+++ b/lopcodes.h
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lopcodes.h,v 1.187 2018/02/09 15:16:06 roberto Exp roberto $ 2** $Id: lopcodes.h,v 1.188 2018/02/15 15:34:29 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*/
@@ -260,6 +260,8 @@ OP_EQK,/* A B if ((R(A) == K(B)) ~= k) then pc++ */
260OP_EQI,/* A sB if ((R(A) == sB) ~= k) then pc++ */ 260OP_EQI,/* A sB if ((R(A) == sB) ~= k) then pc++ */
261OP_LTI,/* A sB if ((R(A) < sB) ~= k) then pc++ */ 261OP_LTI,/* A sB if ((R(A) < sB) ~= k) then pc++ */
262OP_LEI,/* A sB if ((R(A) <= sB) ~= k) then pc++ */ 262OP_LEI,/* A sB if ((R(A) <= sB) ~= k) then pc++ */
263OP_GTI,/* A sB if ((R(A) > sB) ~= k) then pc++ */
264OP_GEI,/* A sB if ((R(A) >= sB) ~= k) then pc++ */
263 265
264OP_TEST,/* A if (not R(A) == k) then pc++ */ 266OP_TEST,/* A if (not R(A) == k) then pc++ */
265OP_TESTSET,/* A B if (not R(B) == k) then R(A) := R(B) else pc++ */ 267OP_TESTSET,/* A B if (not R(B) == k) then R(A) := R(B) else pc++ */
@@ -317,11 +319,6 @@ OP_EXTRAARG/* Ax extra (larger) argument for previous opcode */
317 (*) For comparisons, k specifies what condition the test should accept 319 (*) For comparisons, k specifies what condition the test should accept
318 (true or false). 320 (true or false).
319 321
320 (*) For OP_LTI/OP_LEI, C indicates that the transformations
321 (A<B) => (!(B<=A)) or (A<=B) => (!(B<A)) were used to put the constant
322 operator on the right side. (Non-total orders with NaN or metamethods
323 use this indication to correct their behavior.)
324
325 (*) All 'skips' (pc++) assume that next instruction is a jump. 322 (*) All 'skips' (pc++) assume that next instruction is a jump.
326 323
327 (*) In instructions OP_RETURN/OP_TAILCALL, 'k' specifies that the 324 (*) In instructions OP_RETURN/OP_TAILCALL, 'k' specifies that the
diff --git a/ltm.c b/ltm.c
index e46cc150..3f29c83b 100644
--- a/ltm.c
+++ b/ltm.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: ltm.c,v 2.61 2018/02/15 15:34:29 roberto Exp roberto $ 2** $Id: ltm.c,v 2.62 2018/02/17 19:20:00 roberto Exp roberto $
3** Tag methods 3** Tag methods
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -208,11 +208,10 @@ int luaT_callorderiTM (lua_State *L, const TValue *p1, int v2,
208 setivalue(&aux, v2); 208 setivalue(&aux, v2);
209 if (inv) { /* arguments were exchanged? */ 209 if (inv) { /* arguments were exchanged? */
210 p2 = p1; p1 = &aux; /* correct them */ 210 p2 = p1; p1 = &aux; /* correct them */
211 event = (event == TM_LE) ? TM_LT : TM_LE;
212 } 211 }
213 else 212 else
214 p2 = &aux; 213 p2 = &aux;
215 return (luaT_callorderTM(L, p1, p2, event) != inv); 214 return luaT_callorderTM(L, p1, p2, event);
216} 215}
217 216
218 217
diff --git a/lvm.c b/lvm.c
index 76ce2636..f61069de 100644
--- a/lvm.c
+++ b/lvm.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lvm.c,v 2.343 2018/02/21 12:54:26 roberto Exp roberto $ 2** $Id: lvm.c,v 2.344 2018/02/21 13:47:03 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*/
@@ -731,18 +731,15 @@ void luaV_finishOp (lua_State *L) {
731 } 731 }
732 case OP_LT: case OP_LE: 732 case OP_LT: case OP_LE:
733 case OP_LTI: case OP_LEI: 733 case OP_LTI: case OP_LEI:
734 case OP_GTI: case OP_GEI:
734 case OP_EQ: { /* note that 'OP_EQI'/'OP_EQK' cannot yield */ 735 case OP_EQ: { /* note that 'OP_EQI'/'OP_EQK' cannot yield */
735 int res = !l_isfalse(s2v(L->top - 1)); 736 int res = !l_isfalse(s2v(L->top - 1));
736 L->top--; 737 L->top--;
737 if (ci->callstatus & CIST_LEQ) { /* "<=" using "<" instead? */ 738 if (ci->callstatus & CIST_LEQ) { /* "<=" using "<" instead? */
738 lua_assert(op == OP_LE ||
739 (op == OP_LTI && GETARG_C(inst)) ||
740 (op == OP_LEI && !GETARG_C(inst)));
741 ci->callstatus ^= CIST_LEQ; /* clear mark */ 739 ci->callstatus ^= CIST_LEQ; /* clear mark */
742 res = !res; /* negate result */ 740 res = !res; /* negate result */
743 } 741 }
744 lua_assert(GET_OPCODE(*ci->u.l.savedpc) == OP_JMP); 742 lua_assert(GET_OPCODE(*ci->u.l.savedpc) == OP_JMP);
745 if (GETARG_C(inst)) res = !res;
746 if (res != GETARG_k(inst)) /* condition failed? */ 743 if (res != GETARG_k(inst)) /* condition failed? */
747 ci->u.l.savedpc++; /* skip jump instruction */ 744 ci->u.l.savedpc++; /* skip jump instruction */
748 break; 745 break;
@@ -1473,26 +1470,40 @@ void luaV_execute (lua_State *L, CallInfo *ci) {
1473 int im = GETARG_sB(i); 1470 int im = GETARG_sB(i);
1474 if (ttisinteger(vra)) 1471 if (ttisinteger(vra))
1475 cond = (ivalue(vra) < im); 1472 cond = (ivalue(vra) < im);
1476 else if (ttisfloat(vra)) { 1473 else if (ttisfloat(vra))
1477 lua_Number f = fltvalue(vra); 1474 cond = luai_numlt(fltvalue(vra), cast_num(im));
1478 cond = (!luai_numisnan(f)) ? luai_numlt(f, cast_num(im))
1479 : GETARG_C(i); /* NaN */
1480 }
1481 else 1475 else
1482 Protect(cond = luaT_callorderiTM(L, vra, im, GETARG_C(i), TM_LT)); 1476 Protect(cond = luaT_callorderiTM(L, vra, im, 0, TM_LT));
1483 goto condjump; 1477 goto condjump;
1484 } 1478 }
1485 vmcase(OP_LEI) { 1479 vmcase(OP_LEI) {
1486 int im = GETARG_sB(i); 1480 int im = GETARG_sB(i);
1487 if (ttisinteger(vra)) 1481 if (ttisinteger(vra))
1488 cond = (ivalue(vra) <= im); 1482 cond = (ivalue(vra) <= im);
1489 else if (ttisfloat(vra)) { 1483 else if (ttisfloat(vra))
1490 lua_Number f = fltvalue(vra); 1484 cond = luai_numle(fltvalue(vra), cast_num(im));
1491 cond = (!luai_numisnan(f)) ? luai_numle(f, cast_num(im)) 1485 else
1492 : GETARG_C(i); /* NaN? */ 1486 Protect(cond = luaT_callorderiTM(L, vra, im, 0, TM_LE));
1493 } 1487 goto condjump;
1488 }
1489 vmcase(OP_GTI) {
1490 int im = GETARG_sB(i);
1491 if (ttisinteger(vra))
1492 cond = (im < ivalue(vra));
1493 else if (ttisfloat(vra))
1494 cond = luai_numlt(cast_num(im), fltvalue(vra));
1495 else
1496 Protect(cond = luaT_callorderiTM(L, vra, im, 1, TM_LT));
1497 goto condjump;
1498 }
1499 vmcase(OP_GEI) {
1500 int im = GETARG_sB(i);
1501 if (ttisinteger(vra))
1502 cond = (im <= ivalue(vra));
1503 else if (ttisfloat(vra))
1504 cond = luai_numle(cast_num(im), fltvalue(vra));
1494 else 1505 else
1495 Protect(cond = luaT_callorderiTM(L, vra, im, GETARG_C(i), TM_LE)); 1506 Protect(cond = luaT_callorderiTM(L, vra, im, 1, TM_LE));
1496 goto condjump; 1507 goto condjump;
1497 } 1508 }
1498 vmcase(OP_TEST) { 1509 vmcase(OP_TEST) {