diff options
Diffstat (limited to 'src/lua/lvm.c')
-rw-r--r-- | src/lua/lvm.c | 60 |
1 files changed, 33 insertions, 27 deletions
diff --git a/src/lua/lvm.c b/src/lua/lvm.c index d6c05bb..c9729bc 100644 --- a/src/lua/lvm.c +++ b/src/lua/lvm.c | |||
@@ -235,11 +235,11 @@ static int forprep (lua_State *L, StkId ra) { | |||
235 | } | 235 | } |
236 | else { /* try making all values floats */ | 236 | else { /* try making all values floats */ |
237 | lua_Number init; lua_Number limit; lua_Number step; | 237 | lua_Number init; lua_Number limit; lua_Number step; |
238 | if (unlikely(!tonumber(plimit, &limit))) | 238 | if (l_unlikely(!tonumber(plimit, &limit))) |
239 | luaG_forerror(L, plimit, "limit"); | 239 | luaG_forerror(L, plimit, "limit"); |
240 | if (unlikely(!tonumber(pstep, &step))) | 240 | if (l_unlikely(!tonumber(pstep, &step))) |
241 | luaG_forerror(L, pstep, "step"); | 241 | luaG_forerror(L, pstep, "step"); |
242 | if (unlikely(!tonumber(pinit, &init))) | 242 | if (l_unlikely(!tonumber(pinit, &init))) |
243 | luaG_forerror(L, pinit, "initial value"); | 243 | luaG_forerror(L, pinit, "initial value"); |
244 | if (step == 0) | 244 | if (step == 0) |
245 | luaG_runerror(L, "'for' step is zero"); | 245 | luaG_runerror(L, "'for' step is zero"); |
@@ -292,7 +292,7 @@ void luaV_finishget (lua_State *L, const TValue *t, TValue *key, StkId val, | |||
292 | if (slot == NULL) { /* 't' is not a table? */ | 292 | if (slot == NULL) { /* 't' is not a table? */ |
293 | lua_assert(!ttistable(t)); | 293 | lua_assert(!ttistable(t)); |
294 | tm = luaT_gettmbyobj(L, t, TM_INDEX); | 294 | tm = luaT_gettmbyobj(L, t, TM_INDEX); |
295 | if (unlikely(notm(tm))) | 295 | if (l_unlikely(notm(tm))) |
296 | luaG_typeerror(L, t, "index"); /* no metamethod */ | 296 | luaG_typeerror(L, t, "index"); /* no metamethod */ |
297 | /* else will try the metamethod */ | 297 | /* else will try the metamethod */ |
298 | } | 298 | } |
@@ -346,7 +346,7 @@ void luaV_finishset (lua_State *L, const TValue *t, TValue *key, | |||
346 | } | 346 | } |
347 | else { /* not a table; check metamethod */ | 347 | else { /* not a table; check metamethod */ |
348 | tm = luaT_gettmbyobj(L, t, TM_NEWINDEX); | 348 | tm = luaT_gettmbyobj(L, t, TM_NEWINDEX); |
349 | if (unlikely(notm(tm))) | 349 | if (l_unlikely(notm(tm))) |
350 | luaG_typeerror(L, t, "index"); | 350 | luaG_typeerror(L, t, "index"); |
351 | } | 351 | } |
352 | /* try the metamethod */ | 352 | /* try the metamethod */ |
@@ -568,8 +568,13 @@ int luaV_equalobj (lua_State *L, const TValue *t1, const TValue *t2) { | |||
568 | if (ttype(t1) != ttype(t2) || ttype(t1) != LUA_TNUMBER) | 568 | if (ttype(t1) != ttype(t2) || ttype(t1) != LUA_TNUMBER) |
569 | return 0; /* only numbers can be equal with different variants */ | 569 | return 0; /* only numbers can be equal with different variants */ |
570 | else { /* two numbers with different variants */ | 570 | else { /* two numbers with different variants */ |
571 | lua_Integer i1, i2; /* compare them as integers */ | 571 | /* One of them is an integer. If the other does not have an |
572 | return (tointegerns(t1, &i1) && tointegerns(t2, &i2) && i1 == i2); | 572 | integer value, they cannot be equal; otherwise, compare their |
573 | integer values. */ | ||
574 | lua_Integer i1, i2; | ||
575 | return (luaV_tointegerns(t1, &i1, F2Ieq) && | ||
576 | luaV_tointegerns(t2, &i2, F2Ieq) && | ||
577 | i1 == i2); | ||
573 | } | 578 | } |
574 | } | 579 | } |
575 | /* values have same type and same variant */ | 580 | /* values have same type and same variant */ |
@@ -651,7 +656,7 @@ void luaV_concat (lua_State *L, int total) { | |||
651 | /* collect total length and number of strings */ | 656 | /* collect total length and number of strings */ |
652 | for (n = 1; n < total && tostring(L, s2v(top - n - 1)); n++) { | 657 | for (n = 1; n < total && tostring(L, s2v(top - n - 1)); n++) { |
653 | size_t l = vslen(s2v(top - n - 1)); | 658 | size_t l = vslen(s2v(top - n - 1)); |
654 | if (unlikely(l >= (MAX_SIZE/sizeof(char)) - tl)) | 659 | if (l_unlikely(l >= (MAX_SIZE/sizeof(char)) - tl)) |
655 | luaG_runerror(L, "string length overflow"); | 660 | luaG_runerror(L, "string length overflow"); |
656 | tl += l; | 661 | tl += l; |
657 | } | 662 | } |
@@ -695,7 +700,7 @@ void luaV_objlen (lua_State *L, StkId ra, const TValue *rb) { | |||
695 | } | 700 | } |
696 | default: { /* try metamethod */ | 701 | default: { /* try metamethod */ |
697 | tm = luaT_gettmbyobj(L, rb, TM_LEN); | 702 | tm = luaT_gettmbyobj(L, rb, TM_LEN); |
698 | if (unlikely(notm(tm))) /* no metamethod? */ | 703 | if (l_unlikely(notm(tm))) /* no metamethod? */ |
699 | luaG_typeerror(L, rb, "get length of"); | 704 | luaG_typeerror(L, rb, "get length of"); |
700 | break; | 705 | break; |
701 | } | 706 | } |
@@ -711,7 +716,7 @@ void luaV_objlen (lua_State *L, StkId ra, const TValue *rb) { | |||
711 | ** otherwise 'floor(q) == trunc(q) - 1'. | 716 | ** otherwise 'floor(q) == trunc(q) - 1'. |
712 | */ | 717 | */ |
713 | lua_Integer luaV_idiv (lua_State *L, lua_Integer m, lua_Integer n) { | 718 | lua_Integer luaV_idiv (lua_State *L, lua_Integer m, lua_Integer n) { |
714 | if (unlikely(l_castS2U(n) + 1u <= 1u)) { /* special cases: -1 or 0 */ | 719 | if (l_unlikely(l_castS2U(n) + 1u <= 1u)) { /* special cases: -1 or 0 */ |
715 | if (n == 0) | 720 | if (n == 0) |
716 | luaG_runerror(L, "attempt to divide by zero"); | 721 | luaG_runerror(L, "attempt to divide by zero"); |
717 | return intop(-, 0, m); /* n==-1; avoid overflow with 0x80000...//-1 */ | 722 | return intop(-, 0, m); /* n==-1; avoid overflow with 0x80000...//-1 */ |
@@ -731,7 +736,7 @@ lua_Integer luaV_idiv (lua_State *L, lua_Integer m, lua_Integer n) { | |||
731 | ** about luaV_idiv.) | 736 | ** about luaV_idiv.) |
732 | */ | 737 | */ |
733 | lua_Integer luaV_mod (lua_State *L, lua_Integer m, lua_Integer n) { | 738 | lua_Integer luaV_mod (lua_State *L, lua_Integer m, lua_Integer n) { |
734 | if (unlikely(l_castS2U(n) + 1u <= 1u)) { /* special cases: -1 or 0 */ | 739 | if (l_unlikely(l_castS2U(n) + 1u <= 1u)) { /* special cases: -1 or 0 */ |
735 | if (n == 0) | 740 | if (n == 0) |
736 | luaG_runerror(L, "attempt to perform 'n%%0'"); | 741 | luaG_runerror(L, "attempt to perform 'n%%0'"); |
737 | return 0; /* m % -1 == 0; avoid overflow with 0x80000...%-1 */ | 742 | return 0; /* m % -1 == 0; avoid overflow with 0x80000...%-1 */ |
@@ -921,7 +926,7 @@ void luaV_finishOp (lua_State *L) { | |||
921 | */ | 926 | */ |
922 | #define op_arithfK(L,fop) { \ | 927 | #define op_arithfK(L,fop) { \ |
923 | TValue *v1 = vRB(i); \ | 928 | TValue *v1 = vRB(i); \ |
924 | TValue *v2 = KC(i); \ | 929 | TValue *v2 = KC(i); lua_assert(ttisnumber(v2)); \ |
925 | op_arithf_aux(L, v1, v2, fop); } | 930 | op_arithf_aux(L, v1, v2, fop); } |
926 | 931 | ||
927 | 932 | ||
@@ -950,7 +955,7 @@ void luaV_finishOp (lua_State *L) { | |||
950 | */ | 955 | */ |
951 | #define op_arithK(L,iop,fop) { \ | 956 | #define op_arithK(L,iop,fop) { \ |
952 | TValue *v1 = vRB(i); \ | 957 | TValue *v1 = vRB(i); \ |
953 | TValue *v2 = KC(i); \ | 958 | TValue *v2 = KC(i); lua_assert(ttisnumber(v2)); \ |
954 | op_arith_aux(L, v1, v2, iop, fop); } | 959 | op_arith_aux(L, v1, v2, iop, fop); } |
955 | 960 | ||
956 | 961 | ||
@@ -1049,7 +1054,8 @@ void luaV_finishOp (lua_State *L) { | |||
1049 | #define updatebase(ci) (base = ci->func + 1) | 1054 | #define updatebase(ci) (base = ci->func + 1) |
1050 | 1055 | ||
1051 | 1056 | ||
1052 | #define updatestack(ci) { if (trap) { updatebase(ci); ra = RA(i); } } | 1057 | #define updatestack(ci) \ |
1058 | { if (l_unlikely(trap)) { updatebase(ci); ra = RA(i); } } | ||
1053 | 1059 | ||
1054 | 1060 | ||
1055 | /* | 1061 | /* |
@@ -1107,7 +1113,7 @@ void luaV_finishOp (lua_State *L) { | |||
1107 | 1113 | ||
1108 | /* fetch an instruction and prepare its execution */ | 1114 | /* fetch an instruction and prepare its execution */ |
1109 | #define vmfetch() { \ | 1115 | #define vmfetch() { \ |
1110 | if (trap) { /* stack reallocation or hooks? */ \ | 1116 | if (l_unlikely(trap)) { /* stack reallocation or hooks? */ \ |
1111 | trap = luaG_traceexec(L, pc); /* handle hooks */ \ | 1117 | trap = luaG_traceexec(L, pc); /* handle hooks */ \ |
1112 | updatebase(ci); /* correct stack */ \ | 1118 | updatebase(ci); /* correct stack */ \ |
1113 | } \ | 1119 | } \ |
@@ -1135,7 +1141,7 @@ void luaV_execute (lua_State *L, CallInfo *ci) { | |||
1135 | cl = clLvalue(s2v(ci->func)); | 1141 | cl = clLvalue(s2v(ci->func)); |
1136 | k = cl->p->k; | 1142 | k = cl->p->k; |
1137 | pc = ci->u.l.savedpc; | 1143 | pc = ci->u.l.savedpc; |
1138 | if (trap) { | 1144 | if (l_unlikely(trap)) { |
1139 | if (pc == cl->p->code) { /* first instruction (not resuming)? */ | 1145 | if (pc == cl->p->code) { /* first instruction (not resuming)? */ |
1140 | if (cl->p->is_vararg) | 1146 | if (cl->p->is_vararg) |
1141 | trap = 0; /* hooks will start after VARARGPREP instruction */ | 1147 | trap = 0; /* hooks will start after VARARGPREP instruction */ |
@@ -1150,6 +1156,8 @@ void luaV_execute (lua_State *L, CallInfo *ci) { | |||
1150 | Instruction i; /* instruction being executed */ | 1156 | Instruction i; /* instruction being executed */ |
1151 | StkId ra; /* instruction's A register */ | 1157 | StkId ra; /* instruction's A register */ |
1152 | vmfetch(); | 1158 | vmfetch(); |
1159 | // low-level line tracing for debugging Lua | ||
1160 | // printf("line: %d\n", luaG_getfuncline(cl->p, pcRel(pc, cl->p))); | ||
1153 | lua_assert(base == ci->func + 1); | 1161 | lua_assert(base == ci->func + 1); |
1154 | lua_assert(base <= L->top && L->top < L->stack_last); | 1162 | lua_assert(base <= L->top && L->top < L->stack_last); |
1155 | /* invalidate top for instructions not expecting it */ | 1163 | /* invalidate top for instructions not expecting it */ |
@@ -1633,10 +1641,8 @@ void luaV_execute (lua_State *L, CallInfo *ci) { | |||
1633 | b = cast_int(L->top - ra); | 1641 | b = cast_int(L->top - ra); |
1634 | savepc(ci); /* several calls here can raise errors */ | 1642 | savepc(ci); /* several calls here can raise errors */ |
1635 | if (TESTARG_k(i)) { | 1643 | if (TESTARG_k(i)) { |
1636 | /* close upvalues from current call; the compiler ensures | 1644 | luaF_closeupval(L, base); /* close upvalues from current call */ |
1637 | that there are no to-be-closed variables here, so this | 1645 | lua_assert(L->tbclist < base); /* no pending tbc variables */ |
1638 | call cannot change the stack */ | ||
1639 | luaF_close(L, base, NOCLOSINGMETH, 0); | ||
1640 | lua_assert(base == ci->func + 1); | 1646 | lua_assert(base == ci->func + 1); |
1641 | } | 1647 | } |
1642 | while (!ttisfunction(s2v(ra))) { /* not a function? */ | 1648 | while (!ttisfunction(s2v(ra))) { /* not a function? */ |
@@ -1678,23 +1684,23 @@ void luaV_execute (lua_State *L, CallInfo *ci) { | |||
1678 | goto ret; | 1684 | goto ret; |
1679 | } | 1685 | } |
1680 | vmcase(OP_RETURN0) { | 1686 | vmcase(OP_RETURN0) { |
1681 | if (L->hookmask) { | 1687 | if (l_unlikely(L->hookmask)) { |
1682 | L->top = ra; | 1688 | L->top = ra; |
1683 | savepc(ci); | 1689 | savepc(ci); |
1684 | luaD_poscall(L, ci, 0); /* no hurry... */ | 1690 | luaD_poscall(L, ci, 0); /* no hurry... */ |
1685 | trap = 1; | 1691 | trap = 1; |
1686 | } | 1692 | } |
1687 | else { /* do the 'poscall' here */ | 1693 | else { /* do the 'poscall' here */ |
1688 | int nres = ci->nresults; | 1694 | int nres; |
1689 | L->ci = ci->previous; /* back to caller */ | 1695 | L->ci = ci->previous; /* back to caller */ |
1690 | L->top = base - 1; | 1696 | L->top = base - 1; |
1691 | while (nres-- > 0) | 1697 | for (nres = ci->nresults; l_unlikely(nres > 0); nres--) |
1692 | setnilvalue(s2v(L->top++)); /* all results are nil */ | 1698 | setnilvalue(s2v(L->top++)); /* all results are nil */ |
1693 | } | 1699 | } |
1694 | goto ret; | 1700 | goto ret; |
1695 | } | 1701 | } |
1696 | vmcase(OP_RETURN1) { | 1702 | vmcase(OP_RETURN1) { |
1697 | if (L->hookmask) { | 1703 | if (l_unlikely(L->hookmask)) { |
1698 | L->top = ra + 1; | 1704 | L->top = ra + 1; |
1699 | savepc(ci); | 1705 | savepc(ci); |
1700 | luaD_poscall(L, ci, 1); /* no hurry... */ | 1706 | luaD_poscall(L, ci, 1); /* no hurry... */ |
@@ -1708,8 +1714,8 @@ void luaV_execute (lua_State *L, CallInfo *ci) { | |||
1708 | else { | 1714 | else { |
1709 | setobjs2s(L, base - 1, ra); /* at least this result */ | 1715 | setobjs2s(L, base - 1, ra); /* at least this result */ |
1710 | L->top = base; | 1716 | L->top = base; |
1711 | while (--nres > 0) /* complete missing results */ | 1717 | for (; l_unlikely(nres > 1); nres--) |
1712 | setnilvalue(s2v(L->top++)); | 1718 | setnilvalue(s2v(L->top++)); /* complete missing results */ |
1713 | } | 1719 | } |
1714 | } | 1720 | } |
1715 | ret: /* return from a Lua function */ | 1721 | ret: /* return from a Lua function */ |
@@ -1812,7 +1818,7 @@ void luaV_execute (lua_State *L, CallInfo *ci) { | |||
1812 | } | 1818 | } |
1813 | vmcase(OP_VARARGPREP) { | 1819 | vmcase(OP_VARARGPREP) { |
1814 | ProtectNT(luaT_adjustvarargs(L, GETARG_A(i), ci, cl->p)); | 1820 | ProtectNT(luaT_adjustvarargs(L, GETARG_A(i), ci, cl->p)); |
1815 | if (trap) { | 1821 | if (l_unlikely(trap)) { /* previous "Protect" updated trap */ |
1816 | luaD_hookcall(L, ci); | 1822 | luaD_hookcall(L, ci); |
1817 | L->oldpc = 1; /* next opcode will be seen as a "new" line */ | 1823 | L->oldpc = 1; /* next opcode will be seen as a "new" line */ |
1818 | } | 1824 | } |