summaryrefslogtreecommitdiff
path: root/libs/liblua/src/lvm.c
diff options
context:
space:
mode:
Diffstat (limited to 'libs/liblua/src/lvm.c')
-rw-r--r--libs/liblua/src/lvm.c73
1 files changed, 40 insertions, 33 deletions
diff --git a/libs/liblua/src/lvm.c b/libs/liblua/src/lvm.c
index aa3b22bf73..c9729bcca0 100644
--- a/libs/liblua/src/lvm.c
+++ b/libs/liblua/src/lvm.c
@@ -235,11 +235,11 @@ static int forprep (lua_State *L, StkId ra) {
}
else { /* try making all values floats */
lua_Number init; lua_Number limit; lua_Number step;
- if (unlikely(!tonumber(plimit, &limit)))
+ if (l_unlikely(!tonumber(plimit, &limit)))
luaG_forerror(L, plimit, "limit");
- if (unlikely(!tonumber(pstep, &step)))
+ if (l_unlikely(!tonumber(pstep, &step)))
luaG_forerror(L, pstep, "step");
- if (unlikely(!tonumber(pinit, &init)))
+ if (l_unlikely(!tonumber(pinit, &init)))
luaG_forerror(L, pinit, "initial value");
if (step == 0)
luaG_runerror(L, "'for' step is zero");
@@ -292,7 +292,7 @@ void luaV_finishget (lua_State *L, const TValue *t, TValue *key, StkId val,
if (slot == NULL) { /* 't' is not a table? */
lua_assert(!ttistable(t));
tm = luaT_gettmbyobj(L, t, TM_INDEX);
- if (unlikely(notm(tm)))
+ if (l_unlikely(notm(tm)))
luaG_typeerror(L, t, "index"); /* no metamethod */
/* else will try the metamethod */
}
@@ -337,10 +337,7 @@ void luaV_finishset (lua_State *L, const TValue *t, TValue *key,
lua_assert(isempty(slot)); /* slot must be empty */
tm = fasttm(L, h->metatable, TM_NEWINDEX); /* get metamethod */
if (tm == NULL) { /* no metamethod? */
- if (isabstkey(slot)) /* no previous entry? */
- slot = luaH_newkey(L, h, key); /* create one */
- /* no metamethod and (now) there is an entry with given key */
- setobj2t(L, cast(TValue *, slot), val); /* set its new value */
+ luaH_finishset(L, h, key, slot, val); /* set new value */
invalidateTMcache(h);
luaC_barrierback(L, obj2gco(h), val);
return;
@@ -349,7 +346,7 @@ void luaV_finishset (lua_State *L, const TValue *t, TValue *key,
}
else { /* not a table; check metamethod */
tm = luaT_gettmbyobj(L, t, TM_NEWINDEX);
- if (unlikely(notm(tm)))
+ if (l_unlikely(notm(tm)))
luaG_typeerror(L, t, "index");
}
/* try the metamethod */
@@ -571,8 +568,13 @@ int luaV_equalobj (lua_State *L, const TValue *t1, const TValue *t2) {
if (ttype(t1) != ttype(t2) || ttype(t1) != LUA_TNUMBER)
return 0; /* only numbers can be equal with different variants */
else { /* two numbers with different variants */
- lua_Integer i1, i2; /* compare them as integers */
- return (tointegerns(t1, &i1) && tointegerns(t2, &i2) && i1 == i2);
+ /* One of them is an integer. If the other does not have an
+ integer value, they cannot be equal; otherwise, compare their
+ integer values. */
+ lua_Integer i1, i2;
+ return (luaV_tointegerns(t1, &i1, F2Ieq) &&
+ luaV_tointegerns(t2, &i2, F2Ieq) &&
+ i1 == i2);
}
}
/* values have same type and same variant */
@@ -654,7 +656,7 @@ void luaV_concat (lua_State *L, int total) {
/* collect total length and number of strings */
for (n = 1; n < total && tostring(L, s2v(top - n - 1)); n++) {
size_t l = vslen(s2v(top - n - 1));
- if (unlikely(l >= (MAX_SIZE/sizeof(char)) - tl))
+ if (l_unlikely(l >= (MAX_SIZE/sizeof(char)) - tl))
luaG_runerror(L, "string length overflow");
tl += l;
}
@@ -698,7 +700,7 @@ void luaV_objlen (lua_State *L, StkId ra, const TValue *rb) {
}
default: { /* try metamethod */
tm = luaT_gettmbyobj(L, rb, TM_LEN);
- if (unlikely(notm(tm))) /* no metamethod? */
+ if (l_unlikely(notm(tm))) /* no metamethod? */
luaG_typeerror(L, rb, "get length of");
break;
}
@@ -714,7 +716,7 @@ void luaV_objlen (lua_State *L, StkId ra, const TValue *rb) {
** otherwise 'floor(q) == trunc(q) - 1'.
*/
lua_Integer luaV_idiv (lua_State *L, lua_Integer m, lua_Integer n) {
- if (unlikely(l_castS2U(n) + 1u <= 1u)) { /* special cases: -1 or 0 */
+ if (l_unlikely(l_castS2U(n) + 1u <= 1u)) { /* special cases: -1 or 0 */
if (n == 0)
luaG_runerror(L, "attempt to divide by zero");
return intop(-, 0, m); /* n==-1; avoid overflow with 0x80000...//-1 */
@@ -734,7 +736,7 @@ lua_Integer luaV_idiv (lua_State *L, lua_Integer m, lua_Integer n) {
** about luaV_idiv.)
*/
lua_Integer luaV_mod (lua_State *L, lua_Integer m, lua_Integer n) {
- if (unlikely(l_castS2U(n) + 1u <= 1u)) { /* special cases: -1 or 0 */
+ if (l_unlikely(l_castS2U(n) + 1u <= 1u)) { /* special cases: -1 or 0 */
if (n == 0)
luaG_runerror(L, "attempt to perform 'n%%0'");
return 0; /* m % -1 == 0; avoid overflow with 0x80000...%-1 */
@@ -845,6 +847,10 @@ void luaV_finishOp (lua_State *L) {
luaV_concat(L, total); /* concat them (may yield again) */
break;
}
+ case OP_CLOSE: case OP_RETURN: { /* yielded closing variables */
+ ci->u.l.savedpc--; /* repeat instruction to close other vars. */
+ break;
+ }
default: {
/* only these other opcodes can yield */
lua_assert(op == OP_TFORCALL || op == OP_CALL ||
@@ -920,7 +926,7 @@ void luaV_finishOp (lua_State *L) {
*/
#define op_arithfK(L,fop) { \
TValue *v1 = vRB(i); \
- TValue *v2 = KC(i); \
+ TValue *v2 = KC(i); lua_assert(ttisnumber(v2)); \
op_arithf_aux(L, v1, v2, fop); }
@@ -949,7 +955,7 @@ void luaV_finishOp (lua_State *L) {
*/
#define op_arithK(L,iop,fop) { \
TValue *v1 = vRB(i); \
- TValue *v2 = KC(i); \
+ TValue *v2 = KC(i); lua_assert(ttisnumber(v2)); \
op_arith_aux(L, v1, v2, iop, fop); }
@@ -1048,7 +1054,8 @@ void luaV_finishOp (lua_State *L) {
#define updatebase(ci) (base = ci->func + 1)
-#define updatestack(ci) { if (trap) { updatebase(ci); ra = RA(i); } }
+#define updatestack(ci) \
+ { if (l_unlikely(trap)) { updatebase(ci); ra = RA(i); } }
/*
@@ -1106,7 +1113,7 @@ void luaV_finishOp (lua_State *L) {
/* fetch an instruction and prepare its execution */
#define vmfetch() { \
- if (trap) { /* stack reallocation or hooks? */ \
+ if (l_unlikely(trap)) { /* stack reallocation or hooks? */ \
trap = luaG_traceexec(L, pc); /* handle hooks */ \
updatebase(ci); /* correct stack */ \
} \
@@ -1134,7 +1141,7 @@ void luaV_execute (lua_State *L, CallInfo *ci) {
cl = clLvalue(s2v(ci->func));
k = cl->p->k;
pc = ci->u.l.savedpc;
- if (trap) {
+ if (l_unlikely(trap)) {
if (pc == cl->p->code) { /* first instruction (not resuming)? */
if (cl->p->is_vararg)
trap = 0; /* hooks will start after VARARGPREP instruction */
@@ -1149,6 +1156,8 @@ void luaV_execute (lua_State *L, CallInfo *ci) {
Instruction i; /* instruction being executed */
StkId ra; /* instruction's A register */
vmfetch();
+// low-level line tracing for debugging Lua
+// printf("line: %d\n", luaG_getfuncline(cl->p, pcRel(pc, cl->p)));
lua_assert(base == ci->func + 1);
lua_assert(base <= L->top && L->top < L->stack_last);
/* invalidate top for instructions not expecting it */
@@ -1527,7 +1536,7 @@ void luaV_execute (lua_State *L, CallInfo *ci) {
vmbreak;
}
vmcase(OP_CLOSE) {
- Protect(luaF_close(L, ra, LUA_OK));
+ Protect(luaF_close(L, ra, LUA_OK, 1));
vmbreak;
}
vmcase(OP_TBC) {
@@ -1632,10 +1641,8 @@ void luaV_execute (lua_State *L, CallInfo *ci) {
b = cast_int(L->top - ra);
savepc(ci); /* several calls here can raise errors */
if (TESTARG_k(i)) {
- /* close upvalues from current call; the compiler ensures
- that there are no to-be-closed variables here, so this
- call cannot change the stack */
- luaF_close(L, base, NOCLOSINGMETH);
+ luaF_closeupval(L, base); /* close upvalues from current call */
+ lua_assert(L->tbclist < base); /* no pending tbc variables */
lua_assert(base == ci->func + 1);
}
while (!ttisfunction(s2v(ra))) { /* not a function? */
@@ -1665,7 +1672,7 @@ void luaV_execute (lua_State *L, CallInfo *ci) {
if (TESTARG_k(i)) { /* may there be open upvalues? */
if (L->top < ci->top)
L->top = ci->top;
- luaF_close(L, base, LUA_OK);
+ luaF_close(L, base, CLOSEKTOP, 1);
updatetrap(ci);
updatestack(ci);
}
@@ -1677,23 +1684,23 @@ void luaV_execute (lua_State *L, CallInfo *ci) {
goto ret;
}
vmcase(OP_RETURN0) {
- if (L->hookmask) {
+ if (l_unlikely(L->hookmask)) {
L->top = ra;
savepc(ci);
luaD_poscall(L, ci, 0); /* no hurry... */
trap = 1;
}
else { /* do the 'poscall' here */
- int nres = ci->nresults;
+ int nres;
L->ci = ci->previous; /* back to caller */
L->top = base - 1;
- while (nres-- > 0)
+ for (nres = ci->nresults; l_unlikely(nres > 0); nres--)
setnilvalue(s2v(L->top++)); /* all results are nil */
}
goto ret;
}
vmcase(OP_RETURN1) {
- if (L->hookmask) {
+ if (l_unlikely(L->hookmask)) {
L->top = ra + 1;
savepc(ci);
luaD_poscall(L, ci, 1); /* no hurry... */
@@ -1707,8 +1714,8 @@ void luaV_execute (lua_State *L, CallInfo *ci) {
else {
setobjs2s(L, base - 1, ra); /* at least this result */
L->top = base;
- while (--nres > 0) /* complete missing results */
- setnilvalue(s2v(L->top++));
+ for (; l_unlikely(nres > 1); nres--)
+ setnilvalue(s2v(L->top++)); /* complete missing results */
}
}
ret: /* return from a Lua function */
@@ -1811,7 +1818,7 @@ void luaV_execute (lua_State *L, CallInfo *ci) {
}
vmcase(OP_VARARGPREP) {
ProtectNT(luaT_adjustvarargs(L, GETARG_A(i), ci, cl->p));
- if (trap) {
+ if (l_unlikely(trap)) { /* previous "Protect" updated trap */
luaD_hookcall(L, ci);
L->oldpc = 1; /* next opcode will be seen as a "new" line */
}