void lua_close() { TaggedString *alludata = luaS_collectudata(); GCthreshold = MAX_INT; // to avoid GC during GC luaC_hashcallIM((Hash *)roottable.next); // GC t.methods for tables luaC_strcallIM(alludata); // GC tag methods for userdata luaD_gcIM(&luaO_nilobject); // GC tag method for nil (signal end of GC) luaH_free((Hash *)roottable.next); luaF_freeproto((TProtoFunc *)rootproto.next); luaF_freeclosure((Closure *)rootcl.next); luaS_free(alludata); luaS_freeall(); luaM_free(IMtable); luaM_free(refArray); luaM_free(Mbuffer); LState *tmpState, *state; for (state = lua_rootState; state != nullptr;) { tmpState = state->next; lua_statedeinit(state); luaM_free(state); state = tmpState; } Mbuffer = nullptr; IMtable = nullptr; refArray = nullptr; lua_rootState = lua_state = nullptr; #ifdef LUA_DEBUG printf("total de blocos: %ld\n", numblocks); printf("total de memoria: %ld\n", totalmem); #endif }
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; } }
void stop_script() { lua_Object paramObj = lua_getparam(1); lua_Type type = ttype(Address(paramObj)); LState *state; if (paramObj == LUA_NOOBJECT || (type != LUA_T_CPROTO && type != LUA_T_PROTO && type != LUA_T_TASK)) lua_error("Bad argument to stop_script"); if (type == LUA_T_TASK) { uint32 task = (uint32)nvalue(Address(paramObj)); for (state = lua_rootState->next; state != NULL; state = state->next) { if (state->id == task) break; } if (state) { if (state != lua_state) { lua_statedeinit(state); luaM_free(state); } } } else if (type == LUA_T_PROTO || type == LUA_T_CPROTO) { for (state = lua_rootState->next; state != NULL;) { bool match; if (type == LUA_T_PROTO) { match = (state->taskFunc.ttype == type && tfvalue(&state->taskFunc) == tfvalue(Address(paramObj))); } else { match = (state->taskFunc.ttype == type && fvalue(&state->taskFunc) == fvalue(Address(paramObj))); } if (match && state != lua_state) { LState *tmp = state->next; lua_statedeinit(state); luaM_free(state); state = tmp; } else { state = state->next; } } } }