diff options
| author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2019-03-22 13:37:17 -0300 |
|---|---|---|
| committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2019-03-22 13:37:17 -0300 |
| commit | 23e6bac8a0bbb9e5df43cbc0b7634b6d1395b0ff (patch) | |
| tree | b8f01be3b195252ecb414092dce98299fc325a54 /lvm.c | |
| parent | 682054920ddc434fd4a7f8cc78027dbb03f47f00 (diff) | |
| download | lua-23e6bac8a0bbb9e5df43cbc0b7634b6d1395b0ff.tar.gz lua-23e6bac8a0bbb9e5df43cbc0b7634b6d1395b0ff.tar.bz2 lua-23e6bac8a0bbb9e5df43cbc0b7634b6d1395b0ff.zip | |
Keep correct type for immediate operands in comparisons
When calling metamethods for things like 'a < 3.0', which generates
the opcode OP_LTI, the C register tells that the operand was
converted to an integer, so that it can be corrected to float when
calling a metamethod.
This commit also includes some other stuff:
- file 'onelua.c' added to the project
- opcode OP_PREPVARARG renamed to OP_VARARGPREP
- comparison opcodes rewritten through macros
Diffstat (limited to 'lvm.c')
| -rw-r--r-- | lvm.c | 96 |
1 files changed, 44 insertions, 52 deletions
| @@ -772,11 +772,10 @@ void luaV_finishOp (lua_State *L) { | |||
| 772 | 772 | ||
| 773 | /* | 773 | /* |
| 774 | ** {================================================================== | 774 | ** {================================================================== |
| 775 | ** Macros for arithmetic/bitwise opcodes in 'luaV_execute' | 775 | ** Macros for arithmetic/bitwise/comparison opcodes in 'luaV_execute' |
| 776 | ** =================================================================== | 776 | ** =================================================================== |
| 777 | */ | 777 | */ |
| 778 | 778 | ||
| 779 | |||
| 780 | #define l_addi(L,a,b) intop(+, a, b) | 779 | #define l_addi(L,a,b) intop(+, a, b) |
| 781 | #define l_subi(L,a,b) intop(-, a, b) | 780 | #define l_subi(L,a,b) intop(-, a, b) |
| 782 | #define l_muli(L,a,b) intop(*, a, b) | 781 | #define l_muli(L,a,b) intop(*, a, b) |
| @@ -784,6 +783,11 @@ void luaV_finishOp (lua_State *L) { | |||
| 784 | #define l_bor(L,a,b) intop(|, a, b) | 783 | #define l_bor(L,a,b) intop(|, a, b) |
| 785 | #define l_bxor(L,a,b) intop(^, a, b) | 784 | #define l_bxor(L,a,b) intop(^, a, b) |
| 786 | 785 | ||
| 786 | #define l_lti(a,b) (a < b) | ||
| 787 | #define l_lei(a,b) (a <= b) | ||
| 788 | #define l_gti(a,b) (a > b) | ||
| 789 | #define l_gei(a,b) (a >= b) | ||
| 790 | |||
| 787 | 791 | ||
| 788 | /* | 792 | /* |
| 789 | ** Auxiliary macro for arithmetic operations over floats and others | 793 | ** Auxiliary macro for arithmetic operations over floats and others |
| @@ -916,6 +920,36 @@ void luaV_finishOp (lua_State *L) { | |||
| 916 | else \ | 920 | else \ |
| 917 | Protect(luaT_trybinTM(L, v1, v2, ra, tm)); } | 921 | Protect(luaT_trybinTM(L, v1, v2, ra, tm)); } |
| 918 | 922 | ||
| 923 | |||
| 924 | /* | ||
| 925 | ** Order operations with register operands. | ||
| 926 | */ | ||
| 927 | #define op_order(L,opi,opf,other) { \ | ||
| 928 | TValue *rb = vRB(i); \ | ||
| 929 | if (ttisinteger(s2v(ra)) && ttisinteger(rb)) \ | ||
| 930 | cond = opi(ivalue(s2v(ra)), ivalue(rb)); \ | ||
| 931 | else if (ttisnumber(s2v(ra)) && ttisnumber(rb)) \ | ||
| 932 | cond = opf(s2v(ra), rb); \ | ||
| 933 | else \ | ||
| 934 | Protect(cond = other(L, s2v(ra), rb)); \ | ||
| 935 | docondjump(); } | ||
| 936 | |||
| 937 | |||
| 938 | /* | ||
| 939 | ** Order operations with immediate operand. | ||
| 940 | */ | ||
| 941 | #define op_orderI(L,opi,opf,inv,tm) { \ | ||
| 942 | int im = GETARG_sB(i); \ | ||
| 943 | if (ttisinteger(s2v(ra))) \ | ||
| 944 | cond = opi(ivalue(s2v(ra)), im); \ | ||
| 945 | else if (ttisfloat(s2v(ra))) \ | ||
| 946 | cond = opf(fltvalue(s2v(ra)), cast_num(im)); \ | ||
| 947 | else { \ | ||
| 948 | int isf = GETARG_C(i); \ | ||
| 949 | Protect(cond = luaT_callorderiTM(L, s2v(ra), im, inv, isf, tm)); \ | ||
| 950 | } \ | ||
| 951 | docondjump(); } | ||
| 952 | |||
| 919 | /* }================================================================== */ | 953 | /* }================================================================== */ |
| 920 | 954 | ||
| 921 | 955 | ||
| @@ -1034,7 +1068,7 @@ void luaV_execute (lua_State *L, CallInfo *ci) { | |||
| 1034 | pc = ci->u.l.savedpc; | 1068 | pc = ci->u.l.savedpc; |
| 1035 | if (trap) { | 1069 | if (trap) { |
| 1036 | if (cl->p->is_vararg) | 1070 | if (cl->p->is_vararg) |
| 1037 | trap = 0; /* hooks will start after PREPVARARG instruction */ | 1071 | trap = 0; /* hooks will start after VARARGPREP instruction */ |
| 1038 | else if (pc == cl->p->code) /* first instruction (not resuming)? */ | 1072 | else if (pc == cl->p->code) /* first instruction (not resuming)? */ |
| 1039 | luaD_hookcall(L, ci); | 1073 | luaD_hookcall(L, ci); |
| 1040 | ci->u.l.trap = 1; /* there may be other hooks */ | 1074 | ci->u.l.trap = 1; /* there may be other hooks */ |
| @@ -1447,25 +1481,11 @@ void luaV_execute (lua_State *L, CallInfo *ci) { | |||
| 1447 | vmbreak; | 1481 | vmbreak; |
| 1448 | } | 1482 | } |
| 1449 | vmcase(OP_LT) { | 1483 | vmcase(OP_LT) { |
| 1450 | TValue *rb = vRB(i); | 1484 | op_order(L, l_lti, LTnum, lessthanothers); |
| 1451 | if (ttisinteger(s2v(ra)) && ttisinteger(rb)) | ||
| 1452 | cond = (ivalue(s2v(ra)) < ivalue(rb)); | ||
| 1453 | else if (ttisnumber(s2v(ra)) && ttisnumber(rb)) | ||
| 1454 | cond = LTnum(s2v(ra), rb); | ||
| 1455 | else | ||
| 1456 | Protect(cond = lessthanothers(L, s2v(ra), rb)); | ||
| 1457 | docondjump(); | ||
| 1458 | vmbreak; | 1485 | vmbreak; |
| 1459 | } | 1486 | } |
| 1460 | vmcase(OP_LE) { | 1487 | vmcase(OP_LE) { |
| 1461 | TValue *rb = vRB(i); | 1488 | op_order(L, l_lei, LEnum, lessequalothers); |
| 1462 | if (ttisinteger(s2v(ra)) && ttisinteger(rb)) | ||
| 1463 | cond = (ivalue(s2v(ra)) <= ivalue(rb)); | ||
| 1464 | else if (ttisnumber(s2v(ra)) && ttisnumber(rb)) | ||
| 1465 | cond = LEnum(s2v(ra), rb); | ||
| 1466 | else | ||
| 1467 | Protect(cond = lessequalothers(L, s2v(ra), rb)); | ||
| 1468 | docondjump(); | ||
| 1469 | vmbreak; | 1489 | vmbreak; |
| 1470 | } | 1490 | } |
| 1471 | vmcase(OP_EQK) { | 1491 | vmcase(OP_EQK) { |
| @@ -1487,47 +1507,19 @@ void luaV_execute (lua_State *L, CallInfo *ci) { | |||
| 1487 | vmbreak; | 1507 | vmbreak; |
| 1488 | } | 1508 | } |
| 1489 | vmcase(OP_LTI) { | 1509 | vmcase(OP_LTI) { |
| 1490 | int im = GETARG_sB(i); | 1510 | op_orderI(L, l_lti, luai_numlt, 0, TM_LT); |
| 1491 | if (ttisinteger(s2v(ra))) | ||
| 1492 | cond = (ivalue(s2v(ra)) < im); | ||
| 1493 | else if (ttisfloat(s2v(ra))) | ||
| 1494 | cond = luai_numlt(fltvalue(s2v(ra)), cast_num(im)); | ||
| 1495 | else | ||
| 1496 | Protect(cond = luaT_callorderiTM(L, s2v(ra), im, 0, TM_LT)); | ||
| 1497 | docondjump(); | ||
| 1498 | vmbreak; | 1511 | vmbreak; |
| 1499 | } | 1512 | } |
| 1500 | vmcase(OP_LEI) { | 1513 | vmcase(OP_LEI) { |
| 1501 | int im = GETARG_sB(i); | 1514 | op_orderI(L, l_lei, luai_numle, 0, TM_LE); |
| 1502 | if (ttisinteger(s2v(ra))) | ||
| 1503 | cond = (ivalue(s2v(ra)) <= im); | ||
| 1504 | else if (ttisfloat(s2v(ra))) | ||
| 1505 | cond = luai_numle(fltvalue(s2v(ra)), cast_num(im)); | ||
| 1506 | else | ||
| 1507 | Protect(cond = luaT_callorderiTM(L, s2v(ra), im, 0, TM_LE)); | ||
| 1508 | docondjump(); | ||
| 1509 | vmbreak; | 1515 | vmbreak; |
| 1510 | } | 1516 | } |
| 1511 | vmcase(OP_GTI) { | 1517 | vmcase(OP_GTI) { |
| 1512 | int im = GETARG_sB(i); | 1518 | op_orderI(L, l_gti, luai_numgt, 1, TM_LT); |
| 1513 | if (ttisinteger(s2v(ra))) | ||
| 1514 | cond = (im < ivalue(s2v(ra))); | ||
| 1515 | else if (ttisfloat(s2v(ra))) | ||
| 1516 | cond = luai_numlt(cast_num(im), fltvalue(s2v(ra))); | ||
| 1517 | else | ||
| 1518 | Protect(cond = luaT_callorderiTM(L, s2v(ra), im, 1, TM_LT)); | ||
| 1519 | docondjump(); | ||
| 1520 | vmbreak; | 1519 | vmbreak; |
| 1521 | } | 1520 | } |
| 1522 | vmcase(OP_GEI) { | 1521 | vmcase(OP_GEI) { |
| 1523 | int im = GETARG_sB(i); | 1522 | op_orderI(L, l_gei, luai_numge, 1, TM_LE); |
| 1524 | if (ttisinteger(s2v(ra))) | ||
| 1525 | cond = (im <= ivalue(s2v(ra))); | ||
| 1526 | else if (ttisfloat(s2v(ra))) | ||
| 1527 | cond = luai_numle(cast_num(im), fltvalue(s2v(ra))); | ||
| 1528 | else | ||
| 1529 | Protect(cond = luaT_callorderiTM(L, s2v(ra), im, 1, TM_LE)); | ||
| 1530 | docondjump(); | ||
| 1531 | vmbreak; | 1523 | vmbreak; |
| 1532 | } | 1524 | } |
| 1533 | vmcase(OP_TEST) { | 1525 | vmcase(OP_TEST) { |
| @@ -1787,7 +1779,7 @@ void luaV_execute (lua_State *L, CallInfo *ci) { | |||
| 1787 | Protect(luaT_getvarargs(L, ci, ra, n)); | 1779 | Protect(luaT_getvarargs(L, ci, ra, n)); |
| 1788 | vmbreak; | 1780 | vmbreak; |
| 1789 | } | 1781 | } |
| 1790 | vmcase(OP_PREPVARARG) { | 1782 | vmcase(OP_VARARGPREP) { |
| 1791 | luaT_adjustvarargs(L, GETARG_A(i), ci, cl->p); | 1783 | luaT_adjustvarargs(L, GETARG_A(i), ci, cl->p); |
| 1792 | updatetrap(ci); | 1784 | updatetrap(ci); |
| 1793 | if (trap) { | 1785 | if (trap) { |
