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) { |