static void callTMres (lua_State *L, const TObject *f, const TObject *p1, const TObject *p2) { setobj2s(L->top, f); /* push function */ setobj2s(L->top+1, p1); /* 1st argument */ setobj2s(L->top+2, p2); /* 2nd argument */ luaD_checkstack(L, 3); /* cannot check before (could invalidate p1, p2) */ L->top += 3; luaD_call(L, L->top - 3, 1); L->top--; /* result will be in L->top */ }
static void callTM (lua_State *L, const TValue *f, const TValue *p1, const TValue *p2, const TValue *p3) { setobj2s(L, L->top, f); /* push function */ setobj2s(L, L->top+1, p1); /* 1st argument */ setobj2s(L, L->top+2, p2); /* 2nd argument */ setobj2s(L, L->top+3, p3); /* 3th argument */ luaD_checkstack(L, 4); L->top += 4; luaD_call(L, L->top - 4, 0); }
/* ** Adjust stack. Set top to the given value, pushing NILs if needed. */ void luaD_adjusttop(StkId newtop) { int32 diff = newtop-(lua_state->stack.top-lua_state->stack.stack); if (diff <= 0) lua_state->stack.top += diff; else { luaD_checkstack(diff); while (diff--) ttype(lua_state->stack.top++) = LUA_T_NIL; } }
/* ** Adjust stack. Set top to base+extra, pushing NILs if needed. ** (we cannot add base+extra unless we are sure it fits in the stack; ** otherwise the result of such operation on pointers is undefined) */ void luaD_adjusttop (lua_State *L, StkId base, int extra) { int diff = extra-(L->top-base); if (diff <= 0) L->top = base+extra; else { luaD_checkstack(L, diff); while (diff--) ttype(L->top++) = LUA_TNIL; } }
static void callTM (lua_State *L, const TObject *f, const TObject *p1, const TObject *p2, const TObject *p3) { setobj2s(L->top, f); /* push function */ setobj2s(L->top+1, p1); /* 1st argument */ setobj2s(L->top+2, p2); /* 2nd argument */ setobj2s(L->top+3, p3); /* 3th argument */ luaD_checkstack(L, 4); /* cannot check before (could invalidate p1...p3) */ L->top += 4; luaD_call(L, L->top - 4, 0); }
static void luaB_sort (void) { lua_Object t = lua_getparam(1); Hash *a = gethash(1); int n = (int)getnarg(a); lua_Object func = lua_getparam(2); luaL_arg_check(func == LUA_NOOBJECT || lua_isfunction(func), 2, "function expected"); luaD_checkstack(4); /* for Pivot, f, a, b (sort_comp) */ auxsort(a, 1, n, func); lua_pushobject(t); }
static void dohook (lua_State *L, lua_Debug *ar, lua_Hook hook) { StkId old_Cbase = L->Cbase; StkId old_top = L->Cbase = L->top; luaD_checkstack(L, LUA_MINSTACK); /* ensure minimum stack size */ L->allowhooks = 0; /* cannot call hooks inside a hook */ (*hook)(L, ar); LUA_ASSERT(L->allowhooks == 0, "invalid allow"); L->allowhooks = 1; L->top = old_top; L->Cbase = old_Cbase; }
static StkId callCclosure (lua_State *L, const struct Closure *cl, StkId base) { int nup = cl->nupvalues; /* number of upvalues */ StkId old_Cbase = L->Cbase; int n; L->Cbase = base; /* new base for C function */ luaD_checkstack(L, nup+LUA_MINSTACK); /* ensure minimum stack size */ for (n=0; n<nup; n++) /* copy upvalues as extra arguments */ *(L->top++) = cl->upvalue[n]; n = (*cl->f.c)(L); /* do the actual call */ L->Cbase = old_Cbase; /* restore old C base */ return L->top - n; /* return index of first result */ }
static StkId callCclosure (struct Closure *cl, lua_CFunction f, StkId base) { TObject *pbase; int nup = cl->nelems; /* number of upvalues */ luaD_checkstack(nup); pbase = L->stack.stack+base; /* care: previous call may change this */ /* open space for upvalues as extra arguments */ luaO_memup(pbase+nup, pbase, (L->stack.top-pbase)*sizeof(TObject)); /* copy upvalues into stack */ memcpy(pbase, cl->consts+1, nup*sizeof(TObject)); L->stack.top += nup; return callC(f, base); }
static void cpu_limit_exceeded(lua_State *L) { luaD_checkstack(L, LUA_MINSTACK); /* ensure minimum stack size */ L->ci->top = L->top + LUA_MINSTACK; lua_assert(L->ci->top <= L->stack_last); lua_unlock(L); lua_set_cycles(L, 0xFFFFFF); if (G(L)->cpu_exceeded) G(L)->cpu_exceeded(L); else lua_pushliteral(L, "cycles exceeded"); lua_set_cycles(L, cpu_exceeded_grace_cycles); lua_error(L); }
static void callTMres (lua_State *L, StkId res, const TValue *f, const TValue *p1, const TValue *p2) { ptrdiff_t result = savestack(L, res); setobj2s(L, L->top, f); /* push function */ setobj2s(L, L->top+1, p1); /* 1st argument */ setobj2s(L, L->top+2, p2); /* 2nd argument */ luaD_checkstack(L, 3); L->top += 3; luaD_call(L, L->top - 3, 1); res = restorestack(L, result); L->top--; setobjs2s(L, res, L->top); }
LUA_API int lua_checkstack (lua_State *L, int size) { int res; lua_lock(L); if ((L->top - L->base + size) > LUA_MAXCSTACK) res = 0; /* stack overflow */ else { luaD_checkstack(L, size); if (L->ci->top < L->top + size) L->ci->top = L->top + size; res = 1; } lua_unlock(L); return res; }
int luaV_lessthan (lua_State *L, const TObject *l, const TObject *r, StkId top) { if (ttype(l) == LUA_TNUMBER && ttype(r) == LUA_TNUMBER) return (nvalue(l) < nvalue(r)); else if (ttype(l) == LUA_TSTRING && ttype(r) == LUA_TSTRING) return (luaV_strcomp(tsvalue(l), tsvalue(r)) < 0); else { /* call TM */ luaD_checkstack(L, 2); *top++ = *l; *top++ = *r; if (!call_binTM(L, top, TM_LT)) luaG_ordererror(L, top-2); L->top--; return (ttype(L->top) != LUA_TNIL); } }
static void callTM (lua_State *L, const TValue *f, const TValue *p1, const TValue *p2, TValue *p3, int hasres) { ptrdiff_t result = savestack(L, p3); setobj2s(L, L->top++, f); /* push function */ setobj2s(L, L->top++, p1); /* 1st argument */ setobj2s(L, L->top++, p2); /* 2nd argument */ if (!hasres) /* no result? 'p3' is third argument */ setobj2s(L, L->top++, p3); /* 3rd argument */ luaD_checkstack(L, 0); /* metamethod may yield only when called from Lua code */ luaD_call(L, L->top - (4 - hasres), hasres, isLua(L->ci)); if (hasres) { /* if has result, move it to its place */ p3 = restorestack(L, result); setobjs2s(L, p3, --L->top); } }
const TObject *luaV_getglobal (lua_State *L, TString *s) { const TObject *value = luaH_getstr(L->gt, s); Closure *tm = luaT_gettmbyObj(L, value, TM_GETGLOBAL); if (tm == NULL) /* is there a tag method? */ return value; /* default behavior */ else { /* tag method */ luaD_checkstack(L, 3); clvalue(L->top) = tm; ttype(L->top) = LUA_TFUNCTION; tsvalue(L->top+1) = s; /* global name */ ttype(L->top+1) = LUA_TSTRING; *(L->top+2) = *value; L->top += 3; luaD_call(L, L->top - 3, 1); return L->top - 1; } }
static void luaB_foreach (void) { Hash *a = gethash(1); int i; TObject f; /* see comment in 'foreachi' */ f = *luaA_Address(luaL_functionarg(2)); luaD_checkstack(3); /* for f, ref, and val */ for (i=0; i<a->nhash; i++) { Node *nd = &(a->node[i]); if (ttype(val(nd)) != LUA_T_NIL) { *(L->stack.top++) = f; *(L->stack.top++) = *ref(nd); *(L->stack.top++) = *val(nd); luaD_calln(2, 1); if (ttype(L->stack.top-1) != LUA_T_NIL) return; L->stack.top--; /* remove result */ } } }
static void luaB_foreachi (void) { Hash *t = gethash(1); int i; int n = (int)getnarg(t); TObject f; /* 'f' cannot be a pointer to TObject, because it is on the stack, and the stack may be reallocated by the call. Moreover, some C compilers do not initialize structs, so we must do the assignment after the declaration */ f = *luaA_Address(luaL_functionarg(2)); luaD_checkstack(3); /* for f, ref, and val */ for (i=1; i<=n; i++) { *(L->stack.top++) = f; ttype(L->stack.top) = LUA_T_NUMBER; nvalue(L->stack.top++) = i; *(L->stack.top++) = *luaH_getint(t, i); luaD_calln(2, 1); if (ttype(L->stack.top-1) != LUA_T_NIL) return; L->stack.top--; } }
/* ** Receives table at `t', key at `key' and value at top. */ void luaV_settable (lua_State *L, StkId t, StkId key) { int tg; if (ttype(t) == LUA_TTABLE && /* `t' is a table? */ ((tg = hvalue(t)->htag) == LUA_TTABLE || /* with default tag? */ luaT_gettm(L, tg, TM_SETTABLE) == NULL)) /* or no TM? */ *luaH_set(L, hvalue(t), key) = *(L->top-1); /* do a primitive set */ else { /* try a `settable' tag method */ Closure *tm = luaT_gettmbyObj(L, t, TM_SETTABLE); if (tm != NULL) { luaD_checkstack(L, 3); *(L->top+2) = *(L->top-1); *(L->top+1) = *key; *(L->top) = *t; clvalue(L->top-1) = tm; ttype(L->top-1) = LUA_TFUNCTION; L->top += 3; luaD_call(L, L->top - 4, 0); /* call `settable' tag method */ } else /* no tag method... */ luaG_typeerror(L, t, "index"); } }
void vm_OP_VARARG(lua_State *L, LClosure *cl, int a, int b) { TValue *base = L->base; TValue *ra = base + a; int j; CallInfo *ci = L->ci; int n = cast_int(ci->base - ci->func) - cl->p->numparams - 1; b -= 1; if (b == LUA_MULTRET) { Protect(luaD_checkstack(L, n)); ra = base + a; /* previous call may change the stack */ b = n; L->top = ra + n; } for (j = 0; j < b; j++) { if (j < n) { setobjs2s(L, ra + j, ci->base - n + j); } else { setnilvalue(ra + j); } } }
static void luaB_foreachvar (void) { GCnode *g; TObject f; /* see comment in 'foreachi' */ f = *luaA_Address(luaL_functionarg(1)); luaD_checkstack(4); /* for extra var name, f, var name, and globalval */ for (g = L->rootglobal.next; g; g = g->next) { TaggedString *s = (TaggedString *)g; if (s->u.s.globalval.ttype != LUA_T_NIL) { pushtagstring(s); /* keep (extra) s on stack to avoid GC */ *(L->stack.top++) = f; pushtagstring(s); *(L->stack.top++) = s->u.s.globalval; luaD_calln(2, 1); if (ttype(L->stack.top-1) != LUA_T_NIL) { L->stack.top--; *(L->stack.top-1) = *L->stack.top; /* remove extra s */ return; } L->stack.top-=2; /* remove result and extra s */ } } }
lua_Object lua_getglobal (char *name) { luaD_checkstack(2); /* may need that to call T.M. */ luaV_getglobal(luaS_new(name)); return put_luaObjectonTop(); }
/* ** Executes the given Lua function. Parameters are between [base,top). ** Returns n such that the the results are between [n,top). */ StkId luaV_execute (lua_State *L, const Closure *cl, StkId base) { const Proto *const tf = cl->f.l; StkId top; /* keep top local, for performance */ const Instruction *pc = tf->code; TString **const kstr = tf->kstr; const lua_Hook linehook = L->linehook; infovalue(base-1)->pc = &pc; luaD_checkstack(L, tf->maxstacksize+EXTRA_STACK); if (tf->is_vararg) /* varargs? */ adjust_varargs(L, base, tf->numparams); else luaD_adjusttop(L, base, tf->numparams); top = L->top; /* main loop of interpreter */ for (;;) { const Instruction i = *pc++; if (linehook) traceexec(L, base, top, linehook); switch (GET_OPCODE(i)) { case OP_END: { L->top = top; return top; } case OP_RETURN: { L->top = top; return base+GETARG_U(i); } case OP_CALL: { int nres = GETARG_B(i); if (nres == MULT_RET) nres = LUA_MULTRET; L->top = top; luaD_call(L, base+GETARG_A(i), nres); top = L->top; break; } case OP_TAILCALL: { L->top = top; luaD_call(L, base+GETARG_A(i), LUA_MULTRET); return base+GETARG_B(i); } case OP_PUSHNIL: { int n = GETARG_U(i); LUA_ASSERT(n>0, "invalid argument"); do { ttype(top++) = LUA_TNIL; } while (--n > 0); break; } case OP_POP: { top -= GETARG_U(i); break; } case OP_PUSHINT: { ttype(top) = LUA_TNUMBER; nvalue(top) = (Number)GETARG_S(i); top++; break; } case OP_PUSHSTRING: { ttype(top) = LUA_TSTRING; tsvalue(top) = kstr[GETARG_U(i)]; top++; break; } case OP_PUSHNUM: { ttype(top) = LUA_TNUMBER; nvalue(top) = tf->knum[GETARG_U(i)]; top++; break; } case OP_PUSHNEGNUM: { ttype(top) = LUA_TNUMBER; nvalue(top) = -tf->knum[GETARG_U(i)]; top++; break; } case OP_PUSHUPVALUE: { *top++ = cl->upvalue[GETARG_U(i)]; break; } case OP_GETLOCAL: { *top++ = *(base+GETARG_U(i)); break; } case OP_GETGLOBAL: { L->top = top; *top = *luaV_getglobal(L, kstr[GETARG_U(i)]); top++; break; } case OP_GETTABLE: { L->top = top; top--; *(top-1) = *luaV_gettable(L, top-1); break; } case OP_GETDOTTED: { ttype(top) = LUA_TSTRING; tsvalue(top) = kstr[GETARG_U(i)]; L->top = top+1; *(top-1) = *luaV_gettable(L, top-1); break; } case OP_GETINDEXED: { *top = *(base+GETARG_U(i)); L->top = top+1; *(top-1) = *luaV_gettable(L, top-1); break; } case OP_PUSHSELF: { TObject receiver; receiver = *(top-1); ttype(top) = LUA_TSTRING; tsvalue(top++) = kstr[GETARG_U(i)]; L->top = top; *(top-2) = *luaV_gettable(L, top-2); *(top-1) = receiver; break; } case OP_CREATETABLE: { L->top = top; luaC_checkGC(L); hvalue(top) = luaH_new(L, GETARG_U(i)); ttype(top) = LUA_TTABLE; top++; break; } case OP_SETLOCAL: { *(base+GETARG_U(i)) = *(--top); break; } case OP_SETGLOBAL: { L->top = top; luaV_setglobal(L, kstr[GETARG_U(i)]); top--; break; } case OP_SETTABLE: { StkId t = top-GETARG_A(i); L->top = top; luaV_settable(L, t, t+1); top -= GETARG_B(i); /* pop values */ break; } case OP_SETLIST: { int aux = GETARG_A(i) * LFIELDS_PER_FLUSH; int n = GETARG_B(i); Hash *arr = hvalue(top-n-1); L->top = top-n; /* final value of `top' (in case of errors) */ for (; n; n--) *luaH_setint(L, arr, n+aux) = *(--top); break; } case OP_SETMAP: { int n = GETARG_U(i); StkId finaltop = top-2*n; Hash *arr = hvalue(finaltop-1); L->top = finaltop; /* final value of `top' (in case of errors) */ for (; n; n--) { top-=2; *luaH_set(L, arr, top) = *(top+1); } break; } case OP_ADD: { if (tonumber(top-2) || tonumber(top-1)) call_arith(L, top, TM_ADD); else nvalue(top-2) += nvalue(top-1); top--; break; } case OP_ADDI: { if (tonumber(top-1)) { ttype(top) = LUA_TNUMBER; nvalue(top) = (Number)GETARG_S(i); call_arith(L, top+1, TM_ADD); } else nvalue(top-1) += (Number)GETARG_S(i); break; } case OP_SUB: { if (tonumber(top-2) || tonumber(top-1)) call_arith(L, top, TM_SUB); else nvalue(top-2) -= nvalue(top-1); top--; break; } case OP_MULT: { if (tonumber(top-2) || tonumber(top-1)) call_arith(L, top, TM_MUL); else nvalue(top-2) *= nvalue(top-1); top--; break; } case OP_DIV: { if (tonumber(top-2) || tonumber(top-1)) call_arith(L, top, TM_DIV); else nvalue(top-2) /= nvalue(top-1); top--; break; } case OP_POW: { if (!call_binTM(L, top, TM_POW)) lua_error(L, "undefined operation"); top--; break; } case OP_CONCAT: { int n = GETARG_U(i); luaV_strconc(L, n, top); top -= n-1; L->top = top; luaC_checkGC(L); break; } case OP_MINUS: { if (tonumber(top-1)) { ttype(top) = LUA_TNIL; call_arith(L, top+1, TM_UNM); } else nvalue(top-1) = -nvalue(top-1); break; } case OP_NOT: { ttype(top-1) = (ttype(top-1) == LUA_TNIL) ? LUA_TNUMBER : LUA_TNIL; nvalue(top-1) = 1; break; } case OP_JMPNE: { top -= 2; if (!luaO_equalObj(top, top+1)) dojump(pc, i); break; } case OP_JMPEQ: { top -= 2; if (luaO_equalObj(top, top+1)) dojump(pc, i); break; } case OP_JMPLT: { top -= 2; if (luaV_lessthan(L, top, top+1, top+2)) dojump(pc, i); break; } case OP_JMPLE: { /* a <= b === !(b<a) */ top -= 2; if (!luaV_lessthan(L, top+1, top, top+2)) dojump(pc, i); break; } case OP_JMPGT: { /* a > b === (b<a) */ top -= 2; if (luaV_lessthan(L, top+1, top, top+2)) dojump(pc, i); break; } case OP_JMPGE: { /* a >= b === !(a<b) */ top -= 2; if (!luaV_lessthan(L, top, top+1, top+2)) dojump(pc, i); break; } case OP_JMPT: { if (ttype(--top) != LUA_TNIL) dojump(pc, i); break; } case OP_JMPF: { if (ttype(--top) == LUA_TNIL) dojump(pc, i); break; } case OP_JMPONT: { if (ttype(top-1) == LUA_TNIL) top--; else dojump(pc, i); break; } case OP_JMPONF: { if (ttype(top-1) != LUA_TNIL) top--; else dojump(pc, i); break; } case OP_JMP: { dojump(pc, i); break; } case OP_PUSHNILJMP: { ttype(top++) = LUA_TNIL; pc++; break; } case OP_FORPREP: { if (tonumber(top-1)) lua_error(L, "`for' step must be a number"); if (tonumber(top-2)) lua_error(L, "`for' limit must be a number"); if (tonumber(top-3)) lua_error(L, "`for' initial value must be a number"); if (nvalue(top-1) > 0 ? nvalue(top-3) > nvalue(top-2) : nvalue(top-3) < nvalue(top-2)) { /* `empty' loop? */ top -= 3; /* remove control variables */ dojump(pc, i); /* jump to loop end */ } break; } case OP_FORLOOP: { LUA_ASSERT(ttype(top-1) == LUA_TNUMBER, "invalid step"); LUA_ASSERT(ttype(top-2) == LUA_TNUMBER, "invalid limit"); if (ttype(top-3) != LUA_TNUMBER) lua_error(L, "`for' index must be a number"); nvalue(top-3) += nvalue(top-1); /* increment index */ if (nvalue(top-1) > 0 ? nvalue(top-3) > nvalue(top-2) : nvalue(top-3) < nvalue(top-2)) top -= 3; /* end loop: remove control variables */ else dojump(pc, i); /* repeat loop */ break; } case OP_LFORPREP: { Node *node; if (ttype(top-1) != LUA_TTABLE) lua_error(L, "`for' table must be a table"); node = luaH_next(L, hvalue(top-1), &luaO_nilobject); if (node == NULL) { /* `empty' loop? */ top--; /* remove table */ dojump(pc, i); /* jump to loop end */ } else { top += 2; /* index,value */ *(top-2) = *key(node); *(top-1) = *val(node); } break; } case OP_LFORLOOP: { Node *node; LUA_ASSERT(ttype(top-3) == LUA_TTABLE, "invalid table"); node = luaH_next(L, hvalue(top-3), top-2); if (node == NULL) /* end loop? */ top -= 3; /* remove table, key, and value */ else { *(top-2) = *key(node); *(top-1) = *val(node); dojump(pc, i); /* repeat loop */ } break; } case OP_CLOSURE: { L->top = top; luaV_Lclosure(L, tf->kproto[GETARG_A(i)], GETARG_B(i)); top = L->top; luaC_checkGC(L); break; } } } }
static void f_checkstack (lua_State *L, void *ud) { int size = *cast(int *, ud); luaD_checkstack(L, size); if (L->ci->top < L->top + size) L->ci->top = L->top + size; }
StkId luaV_execute(lua_Task *task) { if (!task->some_flag) { luaD_checkstack((*task->pc++) + EXTRA_STACK); if (*task->pc < ZEROVARARG) { luaD_adjusttop(task->base + *(task->pc++)); } else { luaC_checkGC(); adjust_varargs(task->base + (*task->pc++) - ZEROVARARG); } task->some_flag = 1; } lua_state->state_counter2++; while (1) { switch ((OpCode)(task->aux = *task->pc++)) { case PUSHNIL0: ttype(task->S->top++) = LUA_T_NIL; break; case PUSHNIL: task->aux = *task->pc++; do { ttype(task->S->top++) = LUA_T_NIL; } while (task->aux--); break; case PUSHNUMBER: task->aux = *task->pc++; goto pushnumber; case PUSHNUMBERW: task->aux = next_word(task->pc); goto pushnumber; case PUSHNUMBER0: case PUSHNUMBER1: case PUSHNUMBER2: task->aux -= PUSHNUMBER0; pushnumber: ttype(task->S->top) = LUA_T_NUMBER; nvalue(task->S->top) = (float)task->aux; task->S->top++; break; case PUSHLOCAL: task->aux = *task->pc++; goto pushlocal; case PUSHLOCAL0: case PUSHLOCAL1: case PUSHLOCAL2: case PUSHLOCAL3: case PUSHLOCAL4: case PUSHLOCAL5: case PUSHLOCAL6: case PUSHLOCAL7: task->aux -= PUSHLOCAL0; pushlocal: *task->S->top++ = *((task->S->stack + task->base) + task->aux); break; case GETGLOBALW: task->aux = next_word(task->pc); goto getglobal; case GETGLOBAL: task->aux = *task->pc++; goto getglobal; case GETGLOBAL0: case GETGLOBAL1: case GETGLOBAL2: case GETGLOBAL3: case GETGLOBAL4: case GETGLOBAL5: case GETGLOBAL6: case GETGLOBAL7: task->aux -= GETGLOBAL0; getglobal: luaV_getglobal(tsvalue(&task->consts[task->aux])); break; case GETTABLE: luaV_gettable(); break; case GETDOTTEDW: task->aux = next_word(task->pc); goto getdotted; case GETDOTTED: task->aux = *task->pc++; goto getdotted; case GETDOTTED0: case GETDOTTED1: case GETDOTTED2: case GETDOTTED3: case GETDOTTED4: case GETDOTTED5: case GETDOTTED6: case GETDOTTED7: task->aux -= GETDOTTED0; getdotted: *task->S->top++ = task->consts[task->aux]; luaV_gettable(); break; case PUSHSELFW: task->aux = next_word(task->pc); goto pushself; case PUSHSELF: task->aux = *task->pc++; goto pushself; case PUSHSELF0: case PUSHSELF1: case PUSHSELF2: case PUSHSELF3: case PUSHSELF4: case PUSHSELF5: case PUSHSELF6: case PUSHSELF7: task->aux -= PUSHSELF0; pushself: { TObject receiver = *(task->S->top - 1); *task->S->top++ = task->consts[task->aux]; luaV_gettable(); *task->S->top++ = receiver; break; } case PUSHCONSTANTW: task->aux = next_word(task->pc); goto pushconstant; case PUSHCONSTANT: task->aux = *task->pc++; goto pushconstant; case PUSHCONSTANT0: case PUSHCONSTANT1: case PUSHCONSTANT2: case PUSHCONSTANT3: case PUSHCONSTANT4: case PUSHCONSTANT5: case PUSHCONSTANT6: case PUSHCONSTANT7: task->aux -= PUSHCONSTANT0; pushconstant: *task->S->top++ = task->consts[task->aux]; break; case PUSHUPVALUE: task->aux = *task->pc++; goto pushupvalue; case PUSHUPVALUE0: case PUSHUPVALUE1: task->aux -= PUSHUPVALUE0; pushupvalue: *task->S->top++ = task->cl->consts[task->aux + 1]; break; case SETLOCAL: task->aux = *task->pc++; goto setlocal; case SETLOCAL0: case SETLOCAL1: case SETLOCAL2: case SETLOCAL3: case SETLOCAL4: case SETLOCAL5: case SETLOCAL6: case SETLOCAL7: task->aux -= SETLOCAL0; setlocal: *((task->S->stack + task->base) + task->aux) = *(--task->S->top); break; case SETGLOBALW: task->aux = next_word(task->pc); goto setglobal; case SETGLOBAL: task->aux = *task->pc++; goto setglobal; case SETGLOBAL0: case SETGLOBAL1: case SETGLOBAL2: case SETGLOBAL3: case SETGLOBAL4: case SETGLOBAL5: case SETGLOBAL6: case SETGLOBAL7: task->aux -= SETGLOBAL0; setglobal: luaV_setglobal(tsvalue(&task->consts[task->aux])); break; case SETTABLE0: luaV_settable(task->S->top - 3, 1); break; case SETTABLE: luaV_settable(task->S->top - 3 - (*task->pc++), 2); break; case SETLISTW: task->aux = next_word(task->pc); task->aux *= LFIELDS_PER_FLUSH; goto setlist; case SETLIST: task->aux = *(task->pc++) * LFIELDS_PER_FLUSH; goto setlist; case SETLIST0: task->aux = 0; setlist: { int32 n = *(task->pc++); TObject *arr = task->S->top - n - 1; for (; n; n--) { ttype(task->S->top) = LUA_T_NUMBER; nvalue(task->S->top) = (float)(n + task->aux); *(luaH_set(avalue(arr), task->S->top)) = *(task->S->top - 1); task->S->top--; } break; } case SETMAP0: task->aux = 0; goto setmap; case SETMAP: task->aux = *task->pc++; setmap: { TObject *arr = task->S->top - (2 * task->aux) - 3; do { *(luaH_set(avalue(arr), task->S->top - 2)) = *(task->S->top - 1); task->S->top -= 2; } while (task->aux--); break; } case POP: task->aux = *task->pc++; goto pop; case POP0: case POP1: task->aux -= POP0; pop: task->S->top -= (task->aux + 1); break; case CREATEARRAYW: task->aux = next_word(task->pc); goto createarray; case CREATEARRAY0: case CREATEARRAY1: task->aux -= CREATEARRAY0; goto createarray; case CREATEARRAY: task->aux = *task->pc++; createarray: luaC_checkGC(); avalue(task->S->top) = luaH_new(task->aux); ttype(task->S->top) = LUA_T_ARRAY; task->S->top++; break; case EQOP: case NEQOP: { int32 res = luaO_equalObj(task->S->top - 2, task->S->top - 1); task->S->top--; if (task->aux == NEQOP) res = !res; ttype(task->S->top - 1) = res ? LUA_T_NUMBER : LUA_T_NIL; nvalue(task->S->top - 1) = 1; break; } case LTOP: comparison(LUA_T_NUMBER, LUA_T_NIL, LUA_T_NIL, IM_LT); break; case LEOP: comparison(LUA_T_NUMBER, LUA_T_NUMBER, LUA_T_NIL, IM_LE); break; case GTOP: comparison(LUA_T_NIL, LUA_T_NIL, LUA_T_NUMBER, IM_GT); break; case GEOP: comparison(LUA_T_NIL, LUA_T_NUMBER, LUA_T_NUMBER, IM_GE); break; case ADDOP: { TObject *l = task->S->top - 2; TObject *r = task->S->top - 1; if (tonumber(r) || tonumber(l)) call_arith(IM_ADD); else { nvalue(l) += nvalue(r); --task->S->top; } break; } case SUBOP: { TObject *l = task->S->top - 2; TObject *r = task->S->top - 1; if (tonumber(r) || tonumber(l)) call_arith(IM_SUB); else { nvalue(l) -= nvalue(r); --task->S->top; } break; } case MULTOP: { TObject *l = task->S->top - 2; TObject *r = task->S->top - 1; if (tonumber(r) || tonumber(l)) call_arith(IM_MUL); else { nvalue(l) *= nvalue(r); --task->S->top; } break; } case DIVOP: { TObject *l = task->S->top - 2; TObject *r = task->S->top - 1; if (tonumber(r) || tonumber(l)) call_arith(IM_DIV); else { nvalue(l) /= nvalue(r); --task->S->top; } break; } case POWOP: call_arith(IM_POW); break; case CONCOP: { TObject *l = task->S->top - 2; TObject *r = task->S->top - 1; if (tostring(l) || tostring(r)) call_binTM(IM_CONCAT, "unexpected type for concatenation"); else { tsvalue(l) = strconc(svalue(l), svalue(r)); --task->S->top; } luaC_checkGC(); break; } case MINUSOP: if (tonumber(task->S->top - 1)) { ttype(task->S->top) = LUA_T_NIL; task->S->top++; call_arith(IM_UNM); } else nvalue(task->S->top - 1) = -nvalue(task->S->top - 1); break; case NOTOP: ttype(task->S->top - 1) = (ttype(task->S->top - 1) == LUA_T_NIL) ? LUA_T_NUMBER : LUA_T_NIL; nvalue(task->S->top - 1) = 1; break; case ONTJMPW: task->aux = next_word(task->pc); goto ontjmp; case ONTJMP: task->aux = *task->pc++; ontjmp: if (ttype(task->S->top - 1) != LUA_T_NIL) task->pc += task->aux; else task->S->top--; break; case ONFJMPW: task->aux = next_word(task->pc); goto onfjmp; case ONFJMP: task->aux = *task->pc++; onfjmp: if (ttype(task->S->top - 1) == LUA_T_NIL) task->pc += task->aux; else task->S->top--; break; case JMPW: task->aux = next_word(task->pc); goto jmp; case JMP: task->aux = *task->pc++; jmp: task->pc += task->aux; break; case IFFJMPW: task->aux = next_word(task->pc); goto iffjmp; case IFFJMP: task->aux = *task->pc++; iffjmp: if (ttype(--task->S->top) == LUA_T_NIL) task->pc += task->aux; break; case IFTUPJMPW: task->aux = next_word(task->pc); goto iftupjmp; case IFTUPJMP: task->aux = *task->pc++; iftupjmp: if (ttype(--task->S->top) != LUA_T_NIL) task->pc -= task->aux; break; case IFFUPJMPW: task->aux = next_word(task->pc); goto iffupjmp; case IFFUPJMP: task->aux = *task->pc++; iffupjmp: if (ttype(--task->S->top) == LUA_T_NIL) task->pc -= task->aux; break; case CLOSURE: task->aux = *task->pc++; goto closure; case CLOSURE0: case CLOSURE1: task->aux -= CLOSURE0; closure: luaV_closure(task->aux); luaC_checkGC(); break; case CALLFUNC: task->aux = *task->pc++; goto callfunc; case CALLFUNC0: case CALLFUNC1: task->aux -= CALLFUNC0; callfunc: lua_state->state_counter2--; return -((task->S->top - task->S->stack) - (*task->pc++)); case ENDCODE: task->S->top = task->S->stack + task->base; // goes through case RETCODE: lua_state->state_counter2--; return (task->base + ((task->aux == 123) ? *task->pc : 0)); case SETLINEW: task->aux = next_word(task->pc); goto setline; case SETLINE: task->aux = *task->pc++; setline: if ((task->S->stack + task->base - 1)->ttype != LUA_T_LINE) { // open space for LINE value */ luaD_openstack((task->S->top - task->S->stack) - task->base); task->base++; (task->S->stack + task->base - 1)->ttype = LUA_T_LINE; } (task->S->stack + task->base - 1)->value.i = task->aux; if (lua_linehook) luaD_lineHook(task->aux); break; #ifdef LUA_DEBUG default: LUA_INTERNALERROR("internal error - opcode doesn't match"); #endif } } }
static void lll_checkstack(lua_State* L, int n) { luaD_checkstack(L, n); }
void lua_setglobal (char *name) { checkCparams(1); luaD_checkstack(2); /* may need that to call T.M. */ luaV_setglobal(luaS_new(name)); }
int32 luaA_passresults() { luaD_checkstack(lua_state->Cstack.num); memcpy(lua_state->stack.top, lua_state->Cstack.lua2C + lua_state->stack.stack, lua_state->Cstack.num * sizeof(TObject)); lua_state->stack.top += lua_state->Cstack.num; return lua_state->Cstack.num; }