diff options
| -rw-r--r-- | lcode.c | 30 | ||||
| -rw-r--r-- | lopcodes.c | 6 | ||||
| -rw-r--r-- | lopcodes.h | 9 | ||||
| -rw-r--r-- | ltm.c | 5 | ||||
| -rw-r--r-- | lvm.c | 45 |
5 files changed, 50 insertions, 45 deletions
| @@ -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 | */ |
| 174 | static int condjump (FuncState *fs, OpCode op, int A, int B, int C, int k) { | 174 | static 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 | */ |
| 1347 | static void codeorder (FuncState *fs, OpCode op, expdesc *e1, expdesc *e2) { | 1345 | static 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 | ||
| @@ -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 */ |
| @@ -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++ */ | |||
| 260 | OP_EQI,/* A sB if ((R(A) == sB) ~= k) then pc++ */ | 260 | OP_EQI,/* A sB if ((R(A) == sB) ~= k) then pc++ */ |
| 261 | OP_LTI,/* A sB if ((R(A) < sB) ~= k) then pc++ */ | 261 | OP_LTI,/* A sB if ((R(A) < sB) ~= k) then pc++ */ |
| 262 | OP_LEI,/* A sB if ((R(A) <= sB) ~= k) then pc++ */ | 262 | OP_LEI,/* A sB if ((R(A) <= sB) ~= k) then pc++ */ |
| 263 | OP_GTI,/* A sB if ((R(A) > sB) ~= k) then pc++ */ | ||
| 264 | OP_GEI,/* A sB if ((R(A) >= sB) ~= k) then pc++ */ | ||
| 263 | 265 | ||
| 264 | OP_TEST,/* A if (not R(A) == k) then pc++ */ | 266 | OP_TEST,/* A if (not R(A) == k) then pc++ */ |
| 265 | OP_TESTSET,/* A B if (not R(B) == k) then R(A) := R(B) else pc++ */ | 267 | OP_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 |
| @@ -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 | ||
| @@ -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) { |
