diff options
Diffstat (limited to '3rdparty/lua/src/lvm.c')
-rw-r--r-- | 3rdparty/lua/src/lvm.c | 309 |
1 files changed, 184 insertions, 125 deletions
diff --git a/3rdparty/lua/src/lvm.c b/3rdparty/lua/src/lvm.c index 2ec34400319..fcd24e11dc8 100644 --- a/3rdparty/lua/src/lvm.c +++ b/3rdparty/lua/src/lvm.c @@ -91,8 +91,10 @@ static int l_strton (const TValue *obj, TValue *result) { lua_assert(obj != result); if (!cvt2num(obj)) /* is object not a string? */ return 0; - else - return (luaO_str2num(svalue(obj), result) == vslen(obj) + 1); + else { + TString *st = tsvalue(obj); + return (luaO_str2num(getstr(st), result) == tsslen(st) + 1); + } } @@ -366,30 +368,32 @@ void luaV_finishset (lua_State *L, const TValue *t, TValue *key, /* -** Compare two strings 'ls' x 'rs', returning an integer less-equal- -** -greater than zero if 'ls' is less-equal-greater than 'rs'. +** Compare two strings 'ts1' x 'ts2', returning an integer less-equal- +** -greater than zero if 'ts1' is less-equal-greater than 'ts2'. ** The code is a little tricky because it allows '\0' in the strings -** and it uses 'strcoll' (to respect locales) for each segments -** of the strings. +** and it uses 'strcoll' (to respect locales) for each segment +** of the strings. Note that segments can compare equal but still +** have different lengths. */ -static int l_strcmp (const TString *ls, const TString *rs) { - const char *l = getstr(ls); - size_t ll = tsslen(ls); - const char *r = getstr(rs); - size_t lr = tsslen(rs); +static int l_strcmp (const TString *ts1, const TString *ts2) { + const char *s1 = getstr(ts1); + size_t rl1 = tsslen(ts1); /* real length */ + const char *s2 = getstr(ts2); + size_t rl2 = tsslen(ts2); for (;;) { /* for each segment */ - int temp = strcoll(l, r); + int temp = strcoll(s1, s2); if (temp != 0) /* not equal? */ return temp; /* done */ else { /* strings are equal up to a '\0' */ - size_t len = strlen(l); /* index of first '\0' in both strings */ - if (len == lr) /* 'rs' is finished? */ - return (len == ll) ? 0 : 1; /* check 'ls' */ - else if (len == ll) /* 'ls' is finished? */ - return -1; /* 'ls' is less than 'rs' ('rs' is not finished) */ - /* both strings longer than 'len'; go on comparing after the '\0' */ - len++; - l += len; ll -= len; r += len; lr -= len; + size_t zl1 = strlen(s1); /* index of first '\0' in 's1' */ + size_t zl2 = strlen(s2); /* index of first '\0' in 's2' */ + if (zl2 == rl2) /* 's2' is finished? */ + return (zl1 == rl1) ? 0 : 1; /* check 's1' */ + else if (zl1 == rl1) /* 's1' is finished? */ + return -1; /* 's1' is less than 's2' ('s2' is not finished) */ + /* both strings longer than 'zl'; go on comparing after the '\0' */ + zl1++; zl2++; + s1 += zl1; rl1 -= zl1; s2 += zl2; rl2 -= zl2; } } } @@ -608,8 +612,8 @@ int luaV_equalobj (lua_State *L, const TValue *t1, const TValue *t2) { if (tm == NULL) /* no TM? */ return 0; /* objects are different */ else { - luaT_callTMres(L, tm, t1, t2, L->top); /* call TM */ - return !l_isfalse(s2v(L->top)); + luaT_callTMres(L, tm, t1, t2, L->top.p); /* call TM */ + return !l_isfalse(s2v(L->top.p)); } } @@ -624,8 +628,9 @@ int luaV_equalobj (lua_State *L, const TValue *t1, const TValue *t2) { static void copy2buff (StkId top, int n, char *buff) { size_t tl = 0; /* size already copied */ do { - size_t l = vslen(s2v(top - n)); /* length of string being copied */ - memcpy(buff + tl, svalue(s2v(top - n)), l * sizeof(char)); + TString *st = tsvalue(s2v(top - n)); + size_t l = tsslen(st); /* length of string being copied */ + memcpy(buff + tl, getstr(st), l * sizeof(char)); tl += l; } while (--n > 0); } @@ -633,17 +638,17 @@ static void copy2buff (StkId top, int n, char *buff) { /* ** Main operation for concatenation: concat 'total' values in the stack, -** from 'L->top - total' up to 'L->top - 1'. +** from 'L->top.p - total' up to 'L->top.p - 1'. */ void luaV_concat (lua_State *L, int total) { if (total == 1) return; /* "all" values already concatenated */ do { - StkId top = L->top; + StkId top = L->top.p; int n = 2; /* number of elements handled in this pass (at least 2) */ if (!(ttisstring(s2v(top - 2)) || cvt2str(s2v(top - 2))) || !tostring(L, s2v(top - 1))) - luaT_tryconcatTM(L); + luaT_tryconcatTM(L); /* may invalidate 'top' */ else if (isemptystr(s2v(top - 1))) /* second operand is empty? */ cast_void(tostring(L, s2v(top - 2))); /* result is first operand */ else if (isemptystr(s2v(top - 2))) { /* first operand is empty string? */ @@ -651,13 +656,15 @@ void luaV_concat (lua_State *L, int total) { } else { /* at least two non-empty string values; get as many as possible */ - size_t tl = vslen(s2v(top - 1)); + size_t tl = tsslen(tsvalue(s2v(top - 1))); TString *ts; /* 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 (l_unlikely(l >= (MAX_SIZE/sizeof(char)) - tl)) + size_t l = tsslen(tsvalue(s2v(top - n - 1))); + if (l_unlikely(l >= MAX_SIZE - sizeof(TString) - tl)) { + L->top.p = top - total; /* pop strings to avoid wasting stack */ luaG_runerror(L, "string length overflow"); + } tl += l; } if (tl <= LUAI_MAXSHORTLEN) { /* is result a short string? */ @@ -667,12 +674,12 @@ void luaV_concat (lua_State *L, int total) { } else { /* long string; copy strings directly to final result */ ts = luaS_createlngstrobj(L, tl); - copy2buff(top, n, getstr(ts)); + copy2buff(top, n, getlngstr(ts)); } setsvalue2s(L, top - n, ts); /* create result */ } - total -= n-1; /* got 'n' strings to create 1 new */ - L->top -= n-1; /* popped 'n' strings and pushed one */ + total -= n - 1; /* got 'n' strings to create one new */ + L->top.p -= n - 1; /* popped 'n' strings and pushed one */ } while (total > 1); /* repeat until only 1 result left */ } @@ -763,12 +770,10 @@ lua_Number luaV_modf (lua_State *L, lua_Number m, lua_Number n) { /* number of bits in an integer */ #define NBITS cast_int(sizeof(lua_Integer) * CHAR_BIT) + /* ** Shift left operation. (Shift right just negates 'y'.) */ -#define luaV_shiftr(x,y) luaV_shiftl(x,intop(-, 0, y)) - - lua_Integer luaV_shiftl (lua_Integer x, lua_Integer y) { if (y < 0) { /* shift right? */ if (y <= -NBITS) return 0; @@ -808,26 +813,26 @@ static void pushclosure (lua_State *L, Proto *p, UpVal **encup, StkId base, */ void luaV_finishOp (lua_State *L) { CallInfo *ci = L->ci; - StkId base = ci->func + 1; + StkId base = ci->func.p + 1; Instruction inst = *(ci->u.l.savedpc - 1); /* interrupted instruction */ OpCode op = GET_OPCODE(inst); switch (op) { /* finish its execution */ case OP_MMBIN: case OP_MMBINI: case OP_MMBINK: { - setobjs2s(L, base + GETARG_A(*(ci->u.l.savedpc - 2)), --L->top); + setobjs2s(L, base + GETARG_A(*(ci->u.l.savedpc - 2)), --L->top.p); break; } case OP_UNM: case OP_BNOT: case OP_LEN: case OP_GETTABUP: case OP_GETTABLE: case OP_GETI: case OP_GETFIELD: case OP_SELF: { - setobjs2s(L, base + GETARG_A(inst), --L->top); + setobjs2s(L, base + GETARG_A(inst), --L->top.p); break; } case OP_LT: case OP_LE: case OP_LTI: case OP_LEI: case OP_GTI: case OP_GEI: case OP_EQ: { /* note that 'OP_EQI'/'OP_EQK' cannot yield */ - int res = !l_isfalse(s2v(L->top - 1)); - L->top--; + int res = !l_isfalse(s2v(L->top.p - 1)); + L->top.p--; #if defined(LUA_COMPAT_LT_LE) if (ci->callstatus & CIST_LEQ) { /* "<=" using "<" instead? */ ci->callstatus ^= CIST_LEQ; /* clear mark */ @@ -840,11 +845,11 @@ void luaV_finishOp (lua_State *L) { break; } case OP_CONCAT: { - StkId top = L->top - 1; /* top when 'luaT_tryconcatTM' was called */ + StkId top = L->top.p - 1; /* top when 'luaT_tryconcatTM' was called */ int a = GETARG_A(inst); /* first element to concatenate */ int total = cast_int(top - 1 - (base + a)); /* yet to concatenate */ setobjs2s(L, top - 2, top); /* put TM result in proper position */ - L->top = top - 1; /* top is one after last element (at top-2) */ + L->top.p = top - 1; /* top is one after last element (at top-2) */ luaV_concat(L, total); /* concat them (may yield again) */ break; } @@ -856,7 +861,7 @@ void luaV_finishOp (lua_State *L) { StkId ra = base + GETARG_A(inst); /* adjust top to signal correct number of returns, in case the return is "up to top" ('isIT') */ - L->top = ra + ci->u2.nres; + L->top.p = ra + ci->u2.nres; /* repeat instruction to close other vars. and complete the return */ ci->u.l.savedpc--; break; @@ -898,6 +903,7 @@ void luaV_finishOp (lua_State *L) { ** operation, 'fop' is the float operation. */ #define op_arithI(L,iop,fop) { \ + StkId ra = RA(i); \ TValue *v1 = vRB(i); \ int imm = GETARG_sC(i); \ if (ttisinteger(v1)) { \ @@ -926,6 +932,7 @@ void luaV_finishOp (lua_State *L) { ** Arithmetic operations over floats and others with register operands. */ #define op_arithf(L,fop) { \ + StkId ra = RA(i); \ TValue *v1 = vRB(i); \ TValue *v2 = vRC(i); \ op_arithf_aux(L, v1, v2, fop); } @@ -935,6 +942,7 @@ void luaV_finishOp (lua_State *L) { ** Arithmetic operations with K operands for floats. */ #define op_arithfK(L,fop) { \ + StkId ra = RA(i); \ TValue *v1 = vRB(i); \ TValue *v2 = KC(i); lua_assert(ttisnumber(v2)); \ op_arithf_aux(L, v1, v2, fop); } @@ -944,6 +952,7 @@ void luaV_finishOp (lua_State *L) { ** Arithmetic operations over integers and floats. */ #define op_arith_aux(L,v1,v2,iop,fop) { \ + StkId ra = RA(i); \ if (ttisinteger(v1) && ttisinteger(v2)) { \ lua_Integer i1 = ivalue(v1); lua_Integer i2 = ivalue(v2); \ pc++; setivalue(s2v(ra), iop(L, i1, i2)); \ @@ -973,6 +982,7 @@ void luaV_finishOp (lua_State *L) { ** Bitwise operations with constant operand. */ #define op_bitwiseK(L,op) { \ + StkId ra = RA(i); \ TValue *v1 = vRB(i); \ TValue *v2 = KC(i); \ lua_Integer i1; \ @@ -986,6 +996,7 @@ void luaV_finishOp (lua_State *L) { ** Bitwise operations with register operands. */ #define op_bitwise(L,op) { \ + StkId ra = RA(i); \ TValue *v1 = vRB(i); \ TValue *v2 = vRC(i); \ lua_Integer i1; lua_Integer i2; \ @@ -1000,18 +1011,19 @@ void luaV_finishOp (lua_State *L) { ** integers. */ #define op_order(L,opi,opn,other) { \ - int cond; \ - TValue *rb = vRB(i); \ - if (ttisinteger(s2v(ra)) && ttisinteger(rb)) { \ - lua_Integer ia = ivalue(s2v(ra)); \ - lua_Integer ib = ivalue(rb); \ - cond = opi(ia, ib); \ - } \ - else if (ttisnumber(s2v(ra)) && ttisnumber(rb)) \ - cond = opn(s2v(ra), rb); \ - else \ - Protect(cond = other(L, s2v(ra), rb)); \ - docondjump(); } + StkId ra = RA(i); \ + int cond; \ + TValue *rb = vRB(i); \ + if (ttisinteger(s2v(ra)) && ttisinteger(rb)) { \ + lua_Integer ia = ivalue(s2v(ra)); \ + lua_Integer ib = ivalue(rb); \ + cond = opi(ia, ib); \ + } \ + else if (ttisnumber(s2v(ra)) && ttisnumber(rb)) \ + cond = opn(s2v(ra), rb); \ + else \ + Protect(cond = other(L, s2v(ra), rb)); \ + docondjump(); } /* @@ -1019,20 +1031,21 @@ void luaV_finishOp (lua_State *L) { ** always small enough to have an exact representation as a float.) */ #define op_orderI(L,opi,opf,inv,tm) { \ - int cond; \ - int im = GETARG_sB(i); \ - if (ttisinteger(s2v(ra))) \ - cond = opi(ivalue(s2v(ra)), im); \ - else if (ttisfloat(s2v(ra))) { \ - lua_Number fa = fltvalue(s2v(ra)); \ - lua_Number fim = cast_num(im); \ - cond = opf(fa, fim); \ - } \ - else { \ - int isf = GETARG_C(i); \ - Protect(cond = luaT_callorderiTM(L, s2v(ra), im, inv, isf, tm)); \ - } \ - docondjump(); } + StkId ra = RA(i); \ + int cond; \ + int im = GETARG_sB(i); \ + if (ttisinteger(s2v(ra))) \ + cond = opi(ivalue(s2v(ra)), im); \ + else if (ttisfloat(s2v(ra))) { \ + lua_Number fa = fltvalue(s2v(ra)); \ + lua_Number fim = cast_num(im); \ + cond = opf(fa, fim); \ + } \ + else { \ + int isf = GETARG_C(i); \ + Protect(cond = luaT_callorderiTM(L, s2v(ra), im, inv, isf, tm)); \ + } \ + docondjump(); } /* }================================================================== */ @@ -1061,7 +1074,7 @@ void luaV_finishOp (lua_State *L) { #define updatetrap(ci) (trap = ci->u.l.trap) -#define updatebase(ci) (base = ci->func + 1) +#define updatebase(ci) (base = ci->func.p + 1) #define updatestack(ci) \ @@ -1096,7 +1109,7 @@ void luaV_finishOp (lua_State *L) { ** Whenever code can raise errors, the global 'pc' and the global ** 'top' must be correct to report occasional errors. */ -#define savestate(L,ci) (savepc(L), L->top = ci->top) +#define savestate(L,ci) (savepc(L), L->top.p = ci->top.p) /* @@ -1116,7 +1129,7 @@ void luaV_finishOp (lua_State *L) { /* 'c' is the limit of live values in the stack */ #define checkGC(L,c) \ - { luaC_condGC(L, (savepc(L), L->top = (c)), \ + { luaC_condGC(L, (savepc(L), L->top.p = (c)), \ updatetrap(ci)); \ luai_threadyield(L); } @@ -1128,7 +1141,6 @@ void luaV_finishOp (lua_State *L) { updatebase(ci); /* correct stack */ \ } \ i = *(pc++); \ - ra = RA(i); /* WARNING: any stack reallocation invalidates 'ra' */ \ } #define vmdispatch(o) switch(o) @@ -1148,72 +1160,73 @@ void luaV_execute (lua_State *L, CallInfo *ci) { startfunc: trap = L->hookmask; returning: /* trap already set */ - cl = clLvalue(s2v(ci->func)); + cl = ci_func(ci); k = cl->p->k; pc = ci->u.l.savedpc; - 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 */ - else /* check 'call' hook */ - luaD_hookcall(L, ci); - } - ci->u.l.trap = 1; /* assume trap is on, for now */ - } - base = ci->func + 1; + if (l_unlikely(trap)) + trap = luaG_tracecall(L); + base = ci->func.p + 1; /* main loop of interpreter */ for (;;) { Instruction i; /* instruction being executed */ - StkId ra; /* instruction's A register */ vmfetch(); #if 0 /* low-level line tracing for debugging Lua */ printf("line: %d\n", luaG_getfuncline(cl->p, pcRel(pc, cl->p))); #endif - lua_assert(base == ci->func + 1); - lua_assert(base <= L->top && L->top < L->stack_last); + lua_assert(base == ci->func.p + 1); + lua_assert(base <= L->top.p && L->top.p <= L->stack_last.p); /* invalidate top for instructions not expecting it */ - lua_assert(isIT(i) || (cast_void(L->top = base), 1)); + lua_assert(isIT(i) || (cast_void(L->top.p = base), 1)); vmdispatch (GET_OPCODE(i)) { vmcase(OP_MOVE) { + StkId ra = RA(i); setobjs2s(L, ra, RB(i)); vmbreak; } vmcase(OP_LOADI) { + StkId ra = RA(i); lua_Integer b = GETARG_sBx(i); setivalue(s2v(ra), b); vmbreak; } vmcase(OP_LOADF) { + StkId ra = RA(i); int b = GETARG_sBx(i); setfltvalue(s2v(ra), cast_num(b)); vmbreak; } vmcase(OP_LOADK) { + StkId ra = RA(i); TValue *rb = k + GETARG_Bx(i); setobj2s(L, ra, rb); vmbreak; } vmcase(OP_LOADKX) { + StkId ra = RA(i); TValue *rb; rb = k + GETARG_Ax(*pc); pc++; setobj2s(L, ra, rb); vmbreak; } vmcase(OP_LOADFALSE) { + StkId ra = RA(i); setbfvalue(s2v(ra)); vmbreak; } vmcase(OP_LFALSESKIP) { + StkId ra = RA(i); setbfvalue(s2v(ra)); pc++; /* skip next instruction */ vmbreak; } vmcase(OP_LOADTRUE) { + StkId ra = RA(i); setbtvalue(s2v(ra)); vmbreak; } vmcase(OP_LOADNIL) { + StkId ra = RA(i); int b = GETARG_B(i); do { setnilvalue(s2v(ra++)); @@ -1221,21 +1234,24 @@ void luaV_execute (lua_State *L, CallInfo *ci) { vmbreak; } vmcase(OP_GETUPVAL) { + StkId ra = RA(i); int b = GETARG_B(i); - setobj2s(L, ra, cl->upvals[b]->v); + setobj2s(L, ra, cl->upvals[b]->v.p); vmbreak; } vmcase(OP_SETUPVAL) { + StkId ra = RA(i); UpVal *uv = cl->upvals[GETARG_B(i)]; - setobj(L, uv->v, s2v(ra)); + setobj(L, uv->v.p, s2v(ra)); luaC_barrier(L, uv, s2v(ra)); vmbreak; } vmcase(OP_GETTABUP) { + StkId ra = RA(i); const TValue *slot; - TValue *upval = cl->upvals[GETARG_B(i)]->v; + TValue *upval = cl->upvals[GETARG_B(i)]->v.p; TValue *rc = KC(i); - TString *key = tsvalue(rc); /* key must be a string */ + TString *key = tsvalue(rc); /* key must be a short string */ if (luaV_fastget(L, upval, key, slot, luaH_getshortstr)) { setobj2s(L, ra, slot); } @@ -1244,6 +1260,7 @@ void luaV_execute (lua_State *L, CallInfo *ci) { vmbreak; } vmcase(OP_GETTABLE) { + StkId ra = RA(i); const TValue *slot; TValue *rb = vRB(i); TValue *rc = vRC(i); @@ -1258,6 +1275,7 @@ void luaV_execute (lua_State *L, CallInfo *ci) { vmbreak; } vmcase(OP_GETI) { + StkId ra = RA(i); const TValue *slot; TValue *rb = vRB(i); int c = GETARG_C(i); @@ -1272,10 +1290,11 @@ void luaV_execute (lua_State *L, CallInfo *ci) { vmbreak; } vmcase(OP_GETFIELD) { + StkId ra = RA(i); const TValue *slot; TValue *rb = vRB(i); TValue *rc = KC(i); - TString *key = tsvalue(rc); /* key must be a string */ + TString *key = tsvalue(rc); /* key must be a short string */ if (luaV_fastget(L, rb, key, slot, luaH_getshortstr)) { setobj2s(L, ra, slot); } @@ -1285,10 +1304,10 @@ void luaV_execute (lua_State *L, CallInfo *ci) { } vmcase(OP_SETTABUP) { const TValue *slot; - TValue *upval = cl->upvals[GETARG_A(i)]->v; + TValue *upval = cl->upvals[GETARG_A(i)]->v.p; TValue *rb = KB(i); TValue *rc = RKC(i); - TString *key = tsvalue(rb); /* key must be a string */ + TString *key = tsvalue(rb); /* key must be a short string */ if (luaV_fastget(L, upval, key, slot, luaH_getshortstr)) { luaV_finishfastset(L, upval, slot, rc); } @@ -1297,6 +1316,7 @@ void luaV_execute (lua_State *L, CallInfo *ci) { vmbreak; } vmcase(OP_SETTABLE) { + StkId ra = RA(i); const TValue *slot; TValue *rb = vRB(i); /* key (table is in 'ra') */ TValue *rc = RKC(i); /* value */ @@ -1311,6 +1331,7 @@ void luaV_execute (lua_State *L, CallInfo *ci) { vmbreak; } vmcase(OP_SETI) { + StkId ra = RA(i); const TValue *slot; int c = GETARG_B(i); TValue *rc = RKC(i); @@ -1325,10 +1346,11 @@ void luaV_execute (lua_State *L, CallInfo *ci) { vmbreak; } vmcase(OP_SETFIELD) { + StkId ra = RA(i); const TValue *slot; TValue *rb = KB(i); TValue *rc = RKC(i); - TString *key = tsvalue(rb); /* key must be a string */ + TString *key = tsvalue(rb); /* key must be a short string */ if (luaV_fastget(L, s2v(ra), key, slot, luaH_getshortstr)) { luaV_finishfastset(L, s2v(ra), slot, rc); } @@ -1337,6 +1359,7 @@ void luaV_execute (lua_State *L, CallInfo *ci) { vmbreak; } vmcase(OP_NEWTABLE) { + StkId ra = RA(i); int b = GETARG_B(i); /* log2(hash size) + 1 */ int c = GETARG_C(i); /* array size */ Table *t; @@ -1346,7 +1369,7 @@ void luaV_execute (lua_State *L, CallInfo *ci) { if (TESTARG_k(i)) /* non-zero extra argument? */ c += GETARG_Ax(*pc) * (MAXARG_C + 1); /* add it to size */ pc++; /* skip extra argument */ - L->top = ra + 1; /* correct top in case of emergency GC */ + L->top.p = ra + 1; /* correct top in case of emergency GC */ t = luaH_new(L); /* memory allocation */ sethvalue2s(L, ra, t); if (b != 0 || c != 0) @@ -1355,6 +1378,7 @@ void luaV_execute (lua_State *L, CallInfo *ci) { vmbreak; } vmcase(OP_SELF) { + StkId ra = RA(i); const TValue *slot; TValue *rb = vRB(i); TValue *rc = RKC(i); @@ -1384,6 +1408,7 @@ void luaV_execute (lua_State *L, CallInfo *ci) { vmbreak; } vmcase(OP_MODK) { + savestate(L, ci); /* in case of division by 0 */ op_arithK(L, luaV_mod, luaV_modf); vmbreak; } @@ -1396,6 +1421,7 @@ void luaV_execute (lua_State *L, CallInfo *ci) { vmbreak; } vmcase(OP_IDIVK) { + savestate(L, ci); /* in case of division by 0 */ op_arithK(L, luaV_idiv, luai_numidiv); vmbreak; } @@ -1412,6 +1438,7 @@ void luaV_execute (lua_State *L, CallInfo *ci) { vmbreak; } vmcase(OP_SHRI) { + StkId ra = RA(i); TValue *rb = vRB(i); int ic = GETARG_sC(i); lua_Integer ib; @@ -1421,6 +1448,7 @@ void luaV_execute (lua_State *L, CallInfo *ci) { vmbreak; } vmcase(OP_SHLI) { + StkId ra = RA(i); TValue *rb = vRB(i); int ic = GETARG_sC(i); lua_Integer ib; @@ -1442,6 +1470,7 @@ void luaV_execute (lua_State *L, CallInfo *ci) { vmbreak; } vmcase(OP_MOD) { + savestate(L, ci); /* in case of division by 0 */ op_arith(L, luaV_mod, luaV_modf); vmbreak; } @@ -1454,6 +1483,7 @@ void luaV_execute (lua_State *L, CallInfo *ci) { vmbreak; } vmcase(OP_IDIV) { /* floor division */ + savestate(L, ci); /* in case of division by 0 */ op_arith(L, luaV_idiv, luai_numidiv); vmbreak; } @@ -1478,6 +1508,7 @@ void luaV_execute (lua_State *L, CallInfo *ci) { vmbreak; } vmcase(OP_MMBIN) { + StkId ra = RA(i); Instruction pi = *(pc - 2); /* original arith. expression */ TValue *rb = vRB(i); TMS tm = (TMS)GETARG_C(i); @@ -1487,6 +1518,7 @@ void luaV_execute (lua_State *L, CallInfo *ci) { vmbreak; } vmcase(OP_MMBINI) { + StkId ra = RA(i); Instruction pi = *(pc - 2); /* original arith. expression */ int imm = GETARG_sB(i); TMS tm = (TMS)GETARG_C(i); @@ -1496,6 +1528,7 @@ void luaV_execute (lua_State *L, CallInfo *ci) { vmbreak; } vmcase(OP_MMBINK) { + StkId ra = RA(i); Instruction pi = *(pc - 2); /* original arith. expression */ TValue *imm = KB(i); TMS tm = (TMS)GETARG_C(i); @@ -1505,6 +1538,7 @@ void luaV_execute (lua_State *L, CallInfo *ci) { vmbreak; } vmcase(OP_UNM) { + StkId ra = RA(i); TValue *rb = vRB(i); lua_Number nb; if (ttisinteger(rb)) { @@ -1519,6 +1553,7 @@ void luaV_execute (lua_State *L, CallInfo *ci) { vmbreak; } vmcase(OP_BNOT) { + StkId ra = RA(i); TValue *rb = vRB(i); lua_Integer ib; if (tointegerns(rb, &ib)) { @@ -1529,6 +1564,7 @@ void luaV_execute (lua_State *L, CallInfo *ci) { vmbreak; } vmcase(OP_NOT) { + StkId ra = RA(i); TValue *rb = vRB(i); if (l_isfalse(rb)) setbtvalue(s2v(ra)); @@ -1537,21 +1573,25 @@ void luaV_execute (lua_State *L, CallInfo *ci) { vmbreak; } vmcase(OP_LEN) { + StkId ra = RA(i); Protect(luaV_objlen(L, ra, vRB(i))); vmbreak; } vmcase(OP_CONCAT) { + StkId ra = RA(i); int n = GETARG_B(i); /* number of elements to concatenate */ - L->top = ra + n; /* mark the end of concat operands */ + L->top.p = ra + n; /* mark the end of concat operands */ ProtectNT(luaV_concat(L, n)); - checkGC(L, L->top); /* 'luaV_concat' ensures correct top */ + checkGC(L, L->top.p); /* 'luaV_concat' ensures correct top */ vmbreak; } vmcase(OP_CLOSE) { + StkId ra = RA(i); Protect(luaF_close(L, ra, LUA_OK, 1)); vmbreak; } vmcase(OP_TBC) { + StkId ra = RA(i); /* create new to-be-closed upvalue */ halfProtect(luaF_newtbcupval(L, ra)); vmbreak; @@ -1561,6 +1601,7 @@ void luaV_execute (lua_State *L, CallInfo *ci) { vmbreak; } vmcase(OP_EQ) { + StkId ra = RA(i); int cond; TValue *rb = vRB(i); Protect(cond = luaV_equalobj(L, s2v(ra), rb)); @@ -1576,6 +1617,7 @@ void luaV_execute (lua_State *L, CallInfo *ci) { vmbreak; } vmcase(OP_EQK) { + StkId ra = RA(i); TValue *rb = KB(i); /* basic types do not use '__eq'; we can use raw equality */ int cond = luaV_rawequalobj(s2v(ra), rb); @@ -1583,6 +1625,7 @@ void luaV_execute (lua_State *L, CallInfo *ci) { vmbreak; } vmcase(OP_EQI) { + StkId ra = RA(i); int cond; int im = GETARG_sB(i); if (ttisinteger(s2v(ra))) @@ -1611,11 +1654,13 @@ void luaV_execute (lua_State *L, CallInfo *ci) { vmbreak; } vmcase(OP_TEST) { + StkId ra = RA(i); int cond = !l_isfalse(s2v(ra)); docondjump(); vmbreak; } vmcase(OP_TESTSET) { + StkId ra = RA(i); TValue *rb = vRB(i); if (l_isfalse(rb) == GETARG_k(i)) pc++; @@ -1626,11 +1671,12 @@ void luaV_execute (lua_State *L, CallInfo *ci) { vmbreak; } vmcase(OP_CALL) { + StkId ra = RA(i); CallInfo *newci; int b = GETARG_B(i); int nresults = GETARG_C(i) - 1; if (b != 0) /* fixed number of arguments? */ - L->top = ra + b; /* top signals number of arguments */ + L->top.p = ra + b; /* top signals number of arguments */ /* else previous instruction set top */ savepc(L); /* in case of errors */ if ((newci = luaD_precall(L, ra, nresults)) == NULL) @@ -1642,54 +1688,57 @@ void luaV_execute (lua_State *L, CallInfo *ci) { vmbreak; } vmcase(OP_TAILCALL) { + StkId ra = RA(i); int b = GETARG_B(i); /* number of arguments + 1 (function) */ int n; /* number of results when calling a C function */ int nparams1 = GETARG_C(i); /* delta is virtual 'func' - real 'func' (vararg functions) */ int delta = (nparams1) ? ci->u.l.nextraargs + nparams1 : 0; if (b != 0) - L->top = ra + b; + L->top.p = ra + b; else /* previous instruction set top */ - b = cast_int(L->top - ra); + b = cast_int(L->top.p - ra); savepc(ci); /* several calls here can raise errors */ if (TESTARG_k(i)) { luaF_closeupval(L, base); /* close upvalues from current call */ - lua_assert(L->tbclist < base); /* no pending tbc variables */ - lua_assert(base == ci->func + 1); + lua_assert(L->tbclist.p < base); /* no pending tbc variables */ + lua_assert(base == ci->func.p + 1); } if ((n = luaD_pretailcall(L, ci, ra, b, delta)) < 0) /* Lua function? */ goto startfunc; /* execute the callee */ else { /* C function? */ - ci->func -= delta; /* restore 'func' (if vararg) */ + ci->func.p -= delta; /* restore 'func' (if vararg) */ luaD_poscall(L, ci, n); /* finish caller */ updatetrap(ci); /* 'luaD_poscall' can change hooks */ goto ret; /* caller returns after the tail call */ } } vmcase(OP_RETURN) { + StkId ra = RA(i); int n = GETARG_B(i) - 1; /* number of results */ int nparams1 = GETARG_C(i); if (n < 0) /* not fixed? */ - n = cast_int(L->top - ra); /* get what is available */ + n = cast_int(L->top.p - ra); /* get what is available */ savepc(ci); if (TESTARG_k(i)) { /* may there be open upvalues? */ ci->u2.nres = n; /* save number of returns */ - if (L->top < ci->top) - L->top = ci->top; + if (L->top.p < ci->top.p) + L->top.p = ci->top.p; luaF_close(L, base, CLOSEKTOP, 1); updatetrap(ci); updatestack(ci); } if (nparams1) /* vararg function? */ - ci->func -= ci->u.l.nextraargs + nparams1; - L->top = ra + n; /* set call for 'luaD_poscall' */ + ci->func.p -= ci->u.l.nextraargs + nparams1; + L->top.p = ra + n; /* set call for 'luaD_poscall' */ luaD_poscall(L, ci, n); updatetrap(ci); /* 'luaD_poscall' can change hooks */ goto ret; } vmcase(OP_RETURN0) { if (l_unlikely(L->hookmask)) { - L->top = ra; + StkId ra = RA(i); + L->top.p = ra; savepc(ci); luaD_poscall(L, ci, 0); /* no hurry... */ trap = 1; @@ -1697,15 +1746,16 @@ void luaV_execute (lua_State *L, CallInfo *ci) { else { /* do the 'poscall' here */ int nres; L->ci = ci->previous; /* back to caller */ - L->top = base - 1; + L->top.p = base - 1; for (nres = ci->nresults; l_unlikely(nres > 0); nres--) - setnilvalue(s2v(L->top++)); /* all results are nil */ + setnilvalue(s2v(L->top.p++)); /* all results are nil */ } goto ret; } vmcase(OP_RETURN1) { if (l_unlikely(L->hookmask)) { - L->top = ra + 1; + StkId ra = RA(i); + L->top.p = ra + 1; savepc(ci); luaD_poscall(L, ci, 1); /* no hurry... */ trap = 1; @@ -1714,12 +1764,13 @@ void luaV_execute (lua_State *L, CallInfo *ci) { int nres = ci->nresults; L->ci = ci->previous; /* back to caller */ if (nres == 0) - L->top = base - 1; /* asked for no results */ + L->top.p = base - 1; /* asked for no results */ else { + StkId ra = RA(i); setobjs2s(L, base - 1, ra); /* at least this result */ - L->top = base; + L->top.p = base; for (; l_unlikely(nres > 1); nres--) - setnilvalue(s2v(L->top++)); /* complete missing results */ + setnilvalue(s2v(L->top.p++)); /* complete missing results */ } } ret: /* return from a Lua function */ @@ -1731,6 +1782,7 @@ void luaV_execute (lua_State *L, CallInfo *ci) { } } vmcase(OP_FORLOOP) { + StkId ra = RA(i); if (ttisinteger(s2v(ra + 2))) { /* integer loop? */ lua_Unsigned count = l_castS2U(ivalue(s2v(ra + 1))); if (count > 0) { /* still more iterations? */ @@ -1749,12 +1801,14 @@ void luaV_execute (lua_State *L, CallInfo *ci) { vmbreak; } vmcase(OP_FORPREP) { + StkId ra = RA(i); savestate(L, ci); /* in case of errors */ if (forprep(L, ra)) pc += GETARG_Bx(i) + 1; /* skip the loop */ vmbreak; } vmcase(OP_TFORPREP) { + StkId ra = RA(i); /* create to-be-closed upvalue (if needed) */ halfProtect(luaF_newtbcupval(L, ra + 3)); pc += GETARG_Bx(i); @@ -1763,7 +1817,8 @@ void luaV_execute (lua_State *L, CallInfo *ci) { goto l_tforcall; } vmcase(OP_TFORCALL) { - l_tforcall: + l_tforcall: { + StkId ra = RA(i); /* 'ra' has the iterator function, 'ra + 1' has the state, 'ra + 2' has the control variable, and 'ra + 3' has the to-be-closed variable. The call will use the stack after @@ -1771,29 +1826,31 @@ void luaV_execute (lua_State *L, CallInfo *ci) { */ /* push function, state, and control variable */ memcpy(ra + 4, ra, 3 * sizeof(*ra)); - L->top = ra + 4 + 3; + L->top.p = ra + 4 + 3; ProtectNT(luaD_call(L, ra + 4, GETARG_C(i))); /* do the call */ updatestack(ci); /* stack may have changed */ i = *(pc++); /* go to next instruction */ lua_assert(GET_OPCODE(i) == OP_TFORLOOP && ra == RA(i)); goto l_tforloop; - } + }} vmcase(OP_TFORLOOP) { - l_tforloop: + l_tforloop: { + StkId ra = RA(i); if (!ttisnil(s2v(ra + 4))) { /* continue loop? */ setobjs2s(L, ra + 2, ra + 4); /* save control variable */ pc -= GETARG_Bx(i); /* jump back */ } vmbreak; - } + }} vmcase(OP_SETLIST) { + StkId ra = RA(i); int n = GETARG_B(i); unsigned int last = GETARG_C(i); Table *h = hvalue(s2v(ra)); if (n == 0) - n = cast_int(L->top - ra) - 1; /* get up to the top */ + n = cast_int(L->top.p - ra) - 1; /* get up to the top */ else - L->top = ci->top; /* correct top in case of emergency GC */ + L->top.p = ci->top.p; /* correct top in case of emergency GC */ last += n; if (TESTARG_k(i)) { last += GETARG_Ax(*pc) * (MAXARG_C + 1); @@ -1810,12 +1867,14 @@ void luaV_execute (lua_State *L, CallInfo *ci) { vmbreak; } vmcase(OP_CLOSURE) { + StkId ra = RA(i); Proto *p = cl->p->p[GETARG_Bx(i)]; halfProtect(pushclosure(L, p, cl->upvals, base, ra)); checkGC(L, ra + 1); vmbreak; } vmcase(OP_VARARG) { + StkId ra = RA(i); int n = GETARG_C(i) - 1; /* required results */ Protect(luaT_getvarargs(L, ci, ra, n)); vmbreak; |