aboutsummaryrefslogtreecommitdiff
path: root/lvm.c
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>2019-03-22 13:37:17 -0300
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>2019-03-22 13:37:17 -0300
commit23e6bac8a0bbb9e5df43cbc0b7634b6d1395b0ff (patch)
treeb8f01be3b195252ecb414092dce98299fc325a54 /lvm.c
parent682054920ddc434fd4a7f8cc78027dbb03f47f00 (diff)
downloadlua-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.c96
1 files changed, 44 insertions, 52 deletions
diff --git a/lvm.c b/lvm.c
index 31b4dc36..47bc67c9 100644
--- a/lvm.c
+++ b/lvm.c
@@ -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) {