void luaD_callTM (lua_State *L, Closure *f, int nParams, int nResults) { StkId base = L->top - nParams; luaD_openstack(L, base); clvalue(base) = f; ttype(base) = LUA_TFUNCTION; luaD_call(L, base, nResults); }
static void do_unprotectedrun (lua_CFunction f, int32 nParams, int32 nResults) { StkId base = (L->stack.top-L->stack.stack)-nParams; luaD_openstack(nParams); L->stack.stack[base].ttype = LUA_T_CPROTO; L->stack.stack[base].value.f = f; luaD_call(base+1, nResults); }
int32 lua_callfunction(lua_Object function) { if (function == LUA_NOOBJECT) { return 1; } else { luaD_openstack((lua_state->stack.top - lua_state->stack.stack) - lua_state->Cstack.base); set_normalized(lua_state->stack.stack + lua_state->Cstack.base, Address(function)); return luaD_protectedrun(MULT_RET); } }
void luaD_callTM(TObject *f, int32 nParams, int32 nResults) { luaD_openstack(nParams); *(lua_state->stack.top - nParams - 1) = *f; lua_state->state_counter1++; lua_state->state_counter2++; luaD_call((lua_state->stack.top - lua_state->stack.stack) - nParams, nResults); lua_state->state_counter2--; lua_state->state_counter1--; }
int lua_callfunction (lua_Object function) { if (function == LUA_NOOBJECT) return 1; else { luaD_openstack((L->stack.top-L->stack.stack)-L->Cstack.base); set_normalized(L->stack.stack+L->Cstack.base, Address(function)); return luaD_protectedrun(); } }
void runtasks(LState *const rootState) { lua_state = lua_state->next; while (lua_state) { LState *nextState = NULL; bool stillRunning; if (!lua_state->updated && !lua_state->paused) { jmp_buf errorJmp; lua_state->errorJmp = &errorJmp; if (setjmp(errorJmp)) { lua_Task *t, *m; for (t = lua_state->task; t != NULL;) { m = t->next; luaM_free(t); t = m; } stillRunning = false; lua_state->task = NULL; } else { if (lua_state->task) { stillRunning = luaD_call(lua_state->task->some_base, lua_state->task->some_results); } else { StkId base = lua_state->Cstack.base; luaD_openstack((lua_state->stack.top - lua_state->stack.stack) - base); set_normalized(lua_state->stack.stack + lua_state->Cstack.base, &lua_state->taskFunc); stillRunning = luaD_call(base + 1, 255); } } nextState = lua_state->next; // The state returned. Delete it if (!stillRunning) { lua_statedeinit(lua_state); luaM_free(lua_state); } else { lua_state->updated = true; } } else { nextState = lua_state->next; } lua_state = nextState; } // Restore the value of lua_state to the main script lua_state = rootState; // Check for states that may have been created in this run. LState *state = lua_state->next; while (state) { if (!state->paused && !state->updated) { // New state! Run a new pass. runtasks(rootState); return; } state = state->next; } }
/* ** Call a function (C or Lua). The function to be called is at *func. ** The arguments are on the stack, right after the function. ** When returns, the results are on the stack, starting at the original ** function position. ** The number of results is nResults, unless nResults=LUA_MULTRET. */ void luaD_call (lua_State *L, StkId func, int nResults) { lua_Hook callhook; StkId firstResult; CallInfo ci; Closure *cl; if (ttype(func) != LUA_TFUNCTION) { /* `func' is not a function; check the `function' tag method */ Closure *tm = luaT_gettmbyObj(L, func, TM_FUNCTION); if (tm == NULL) luaG_typeerror(L, func, "call"); luaD_openstack(L, func); clvalue(func) = tm; /* tag method is the new function to be called */ ttype(func) = LUA_TFUNCTION; } cl = clvalue(func); ci.func = cl; infovalue(func) = &ci; ttype(func) = LUA_TMARK; callhook = L->callhook; if (callhook) luaD_callHook(L, func, callhook, "call"); firstResult = (cl->isC ? callCclosure(L, cl, func+1) : luaV_execute(L, cl, func+1)); if (callhook) /* same hook that was active at entry */ luaD_callHook(L, func, callhook, "return"); LUA_ASSERT(ttype(func) == LUA_TMARK, "invalid tag"); /* move results to `func' (to erase parameters and function) */ if (nResults == LUA_MULTRET) { while (firstResult < L->top) /* copy all results */ *func++ = *firstResult++; L->top = func; } else { /* copy at most `nResults' */ for (; nResults > 0 && firstResult < L->top; nResults--) *func++ = *firstResult++; L->top = func; for (; nResults > 0; nResults--) { /* if there are not enough results */ ttype(L->top) = LUA_TNIL; /* adjust the stack */ incr_top; /* must check stack space */ } } luaC_checkGC(L); }
void luaD_callTM (TObject *f, int nParams, int nResults) { luaD_openstack(nParams); *(L->stack.top-nParams-1) = *f; luaD_calln(nParams, nResults); }
static lua_Object put_luaObjectonTop (void) { luaD_openstack((L->stack.top-L->stack.stack)-L->Cstack.base); L->stack.stack[L->Cstack.base++] = *(--L->stack.top); return L->Cstack.base; /* this is +1 real position (see Ref) */ }
static lua_Object put_luaObject (TObject *o) { luaD_openstack((L->stack.top-L->stack.stack)-L->Cstack.base); L->stack.stack[L->Cstack.base++] = *o; return L->Cstack.base; /* this is +1 real position (see Ref) */ }
static lua_Object put_luaObjectonTop() { luaD_openstack((lua_state->stack.top - lua_state->stack.stack) - lua_state->Cstack.base); lua_state->stack.stack[lua_state->Cstack.base++] = *(--lua_state->stack.top); return lua_state->Cstack.base; // this is +1 real position (see Ref) }
/* ** Execute the given opcode, until a RET. Parameters are between ** [stack+base,top). Returns n such that the the results are between ** [stack+n,top). */ StkId luaV_execute (struct CallInfo *ci) { /* Save index in case CallInfo array is realloc'd */ int32 ci_index = ci - L->base_ci; struct Stack *S = &L->stack; /* to optimize */ Closure *cl; TProtoFunc *tf; StkId base; Byte *pc; TObject *consts; newfunc: cl = L->ci->c; tf = L->ci->tf; base = L->ci->base; if (S->top-S->stack > base && ttype(S->stack+base) == LUA_T_LINE) base++; pc = L->ci->pc; consts = tf->consts; while (1) { int32 aux; switch ((OpCode)(aux = *pc++)) { case PUSHNIL0: ttype(S->top++) = LUA_T_NIL; break; case PUSHNIL: aux = *pc++; do { ttype(S->top++) = LUA_T_NIL; } while (aux--); break; case PUSHNUMBER: aux = *pc++; goto pushnumber; case PUSHNUMBERW: aux = next_word(pc); goto pushnumber; case PUSHNUMBER0: case PUSHNUMBER1: case PUSHNUMBER2: aux -= PUSHNUMBER0; pushnumber: ttype(S->top) = LUA_T_NUMBER; nvalue(S->top) = (real)aux; S->top++; break; case PUSHLOCAL: aux = *pc++; goto pushlocal; case PUSHLOCAL0: case PUSHLOCAL1: case PUSHLOCAL2: case PUSHLOCAL3: case PUSHLOCAL4: case PUSHLOCAL5: case PUSHLOCAL6: case PUSHLOCAL7: aux -= PUSHLOCAL0; pushlocal: *S->top++ = *((S->stack+base) + aux); break; case GETGLOBALW: aux = next_word(pc); goto getglobal; case GETGLOBAL: aux = *pc++; goto getglobal; case GETGLOBAL0: case GETGLOBAL1: case GETGLOBAL2: case GETGLOBAL3: case GETGLOBAL4: case GETGLOBAL5: case GETGLOBAL6: case GETGLOBAL7: aux -= GETGLOBAL0; getglobal: luaV_getglobal(tsvalue(&consts[aux])); break; case GETTABLE: luaV_gettable(); break; case GETDOTTEDW: aux = next_word(pc); goto getdotted; case GETDOTTED: aux = *pc++; goto getdotted; case GETDOTTED0: case GETDOTTED1: case GETDOTTED2: case GETDOTTED3: case GETDOTTED4: case GETDOTTED5: case GETDOTTED6: case GETDOTTED7: aux -= GETDOTTED0; getdotted: *S->top++ = consts[aux]; luaV_gettable(); break; case PUSHSELFW: aux = next_word(pc); goto pushself; case PUSHSELF: aux = *pc++; goto pushself; case PUSHSELF0: case PUSHSELF1: case PUSHSELF2: case PUSHSELF3: case PUSHSELF4: case PUSHSELF5: case PUSHSELF6: case PUSHSELF7: aux -= PUSHSELF0; pushself: { TObject receiver = *(S->top-1); *S->top++ = consts[aux]; luaV_gettable(); *S->top++ = receiver; break; } case PUSHCONSTANTW: aux = next_word(pc); goto pushconstant; case PUSHCONSTANT: aux = *pc++; goto pushconstant; case PUSHCONSTANT0: case PUSHCONSTANT1: case PUSHCONSTANT2: case PUSHCONSTANT3: case PUSHCONSTANT4: case PUSHCONSTANT5: case PUSHCONSTANT6: case PUSHCONSTANT7: aux -= PUSHCONSTANT0; pushconstant: *S->top++ = consts[aux]; break; case PUSHUPVALUE: aux = *pc++; goto pushupvalue; case PUSHUPVALUE0: case PUSHUPVALUE1: aux -= PUSHUPVALUE0; pushupvalue: *S->top++ = cl->consts[aux+1]; break; case SETLOCAL: aux = *pc++; goto setlocal; case SETLOCAL0: case SETLOCAL1: case SETLOCAL2: case SETLOCAL3: case SETLOCAL4: case SETLOCAL5: case SETLOCAL6: case SETLOCAL7: aux -= SETLOCAL0; setlocal: *((S->stack+base) + aux) = *(--S->top); break; case SETGLOBALW: aux = next_word(pc); goto setglobal; case SETGLOBAL: aux = *pc++; goto setglobal; case SETGLOBAL0: case SETGLOBAL1: case SETGLOBAL2: case SETGLOBAL3: case SETGLOBAL4: case SETGLOBAL5: case SETGLOBAL6: case SETGLOBAL7: aux -= SETGLOBAL0; setglobal: luaV_setglobal(tsvalue(&consts[aux])); break; case SETTABLE0: luaV_settable(S->top-3, 1); break; case SETTABLE: luaV_settable(S->top-3-(*pc++), 2); break; case SETLISTW: aux = next_word(pc); aux *= LFIELDS_PER_FLUSH; goto setlist; case SETLIST: aux = *(pc++) * LFIELDS_PER_FLUSH; goto setlist; case SETLIST0: aux = 0; setlist: { int32 n = *(pc++); TObject *arr = S->top-n-1; for (; n; n--) { ttype(S->top) = LUA_T_NUMBER; nvalue(S->top) = (real)(n+aux); *(luaH_set(avalue(arr), S->top)) = *(S->top-1); S->top--; } break; } case SETMAP0: aux = 0; goto setmap; case SETMAP: aux = *pc++; setmap: { TObject *arr = S->top-(2*aux)-3; do { *(luaH_set(avalue(arr), S->top-2)) = *(S->top-1); S->top-=2; } while (aux--); break; } case POP: aux = *pc++; goto pop; case POP0: case POP1: aux -= POP0; pop: S->top -= (aux+1); break; case CREATEARRAYW: aux = next_word(pc); goto createarray; case CREATEARRAY0: case CREATEARRAY1: aux -= CREATEARRAY0; goto createarray; case CREATEARRAY: aux = *pc++; createarray: luaC_checkGC(); avalue(S->top) = luaH_new(aux); ttype(S->top) = LUA_T_ARRAY; S->top++; break; case EQOP: case NEQOP: { int32 res = luaO_equalObj(S->top-2, S->top-1); S->top--; if (aux == NEQOP) res = !res; ttype(S->top-1) = res ? LUA_T_NUMBER : LUA_T_NIL; nvalue(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 = S->top-2; TObject *r = S->top-1; if (tonumber(r) || tonumber(l)) call_arith(IM_ADD); else { nvalue(l) += nvalue(r); --S->top; } break; } case SUBOP: { TObject *l = S->top-2; TObject *r = S->top-1; if (tonumber(r) || tonumber(l)) call_arith(IM_SUB); else { nvalue(l) -= nvalue(r); --S->top; } break; } case MULTOP: { TObject *l = S->top-2; TObject *r = S->top-1; if (tonumber(r) || tonumber(l)) call_arith(IM_MUL); else { nvalue(l) *= nvalue(r); --S->top; } break; } case DIVOP: { TObject *l = S->top-2; TObject *r = S->top-1; if (tonumber(r) || tonumber(l)) call_arith(IM_DIV); else { nvalue(l) /= nvalue(r); --S->top; } break; } case POWOP: call_binTM(IM_POW, "undefined operation"); break; case CONCOP: { TObject *l = S->top-2; TObject *r = S->top-1; if (tostring(l) || tostring(r)) call_binTM(IM_CONCAT, "unexpected type for concatenation"); else { tsvalue(l) = strconc(tsvalue(l), tsvalue(r)); --S->top; } luaC_checkGC(); break; } case MINUSOP: if (tonumber(S->top-1)) { ttype(S->top) = LUA_T_NIL; S->top++; call_arith(IM_UNM); } else nvalue(S->top-1) = - nvalue(S->top-1); break; case NOTOP: ttype(S->top-1) = (ttype(S->top-1) == LUA_T_NIL) ? LUA_T_NUMBER : LUA_T_NIL; nvalue(S->top-1) = 1; break; case ONTJMPW: aux = next_word(pc); goto ontjmp; case ONTJMP: aux = *pc++; ontjmp: if (ttype(S->top-1) != LUA_T_NIL) pc += aux; else S->top--; break; case ONFJMPW: aux = next_word(pc); goto onfjmp; case ONFJMP: aux = *pc++; onfjmp: if (ttype(S->top-1) == LUA_T_NIL) pc += aux; else S->top--; break; case JMPW: aux = next_word(pc); goto jmp; case JMP: aux = *pc++; jmp: pc += aux; break; case IFFJMPW: aux = next_word(pc); goto iffjmp; case IFFJMP: aux = *pc++; iffjmp: if (ttype(--S->top) == LUA_T_NIL) pc += aux; break; case IFTUPJMPW: aux = next_word(pc); goto iftupjmp; case IFTUPJMP: aux = *pc++; iftupjmp: if (ttype(--S->top) != LUA_T_NIL) pc -= aux; break; case IFFUPJMPW: aux = next_word(pc); goto iffupjmp; case IFFUPJMP: aux = *pc++; iffupjmp: if (ttype(--S->top) == LUA_T_NIL) pc -= aux; break; case CLOSURE: aux = *pc++; goto closure; case CLOSURE0: aux = 0; goto closure; case CLOSURE1: aux = 1; closure: luaV_closure(aux); luaC_checkGC(); break; case CALLFUNC: aux = *pc++; goto callfunc; case CALLFUNC0: case CALLFUNC1: aux -= CALLFUNC0; callfunc: { StkId newBase = (S->top-S->stack)-(*pc++); TObject *func = S->stack+newBase-1; L->ci->pc = pc; if (ttype(func) == LUA_T_PROTO || (ttype(func) == LUA_T_CLOSURE && ttype(&clvalue(func)->consts[0]) == LUA_T_PROTO)) { /* Calling another Lua function */ luaD_precall(func, newBase, aux); ttype(func) = (ttype(func) == LUA_T_PROTO) ? LUA_T_PMARK : LUA_T_CLMARK; goto newfunc; } luaD_call(newBase, aux); if (L->Tstate != RUN) { if (ci_index > 1) /* C functions detected by break_here */ lua_error("Cannot yield through method call"); return -1; } break; } case ENDCODE: S->top = S->stack + base; /* goes through */ case RETCODE: { StkId firstResult = (base + ((aux==RETCODE) ? *pc : 0)); if (lua_callhook) luaD_callHook(base, NULL, 1); /* If returning from the original stack frame, terminate */ if (L->ci == L->base_ci + ci_index) return firstResult; luaD_postret(firstResult); goto newfunc; } case SETLINEW: aux = next_word(pc); goto setline; case SETLINE: aux = *pc++; setline: if ((S->stack+base-1)->ttype != LUA_T_LINE) { /* open space for LINE value */ luaD_openstack((S->top-S->stack)-base); base++; (S->stack+base-1)->ttype = LUA_T_LINE; } (S->stack+base-1)->value.i = aux; if (lua_linehook) luaD_lineHook(aux); break; #ifdef DEBUG default: LUA_INTERNALERROR("opcode doesn't match"); #endif } } }
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 } } }