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 }
static void freeobj (lua_State *L, GCObject *o) { switch (o->gch.tt) { case LUA_TPROTO: luaF_freeproto(L, gcotop(o)); break; case LUA_TFUNCTION: luaF_freeclosure(L, gcotocl(o)); break; case LUA_TUPVAL: luaM_freelem(L, gcotouv(o)); break; case LUA_TTABLE: luaH_free(L, gcotoh(o)); break; case LUA_TTHREAD: { lua_assert(gcototh(o) != L && gcototh(o) != G(L)->mainthread); luaE_freethread(L, gcototh(o)); break; } case LUA_TSTRING: { luaM_free(L, o, sizestring(gcotots(o)->tsv.len)); break; } case LUA_TWSTRING: { luaM_free(L, o, sizewstring(gcototws(o)->tsv.len)); break; } case LUA_TUSERDATA: { luaM_free(L, o, sizeudata(gcotou(o)->uv.len)); break; } #if LUA_REFCOUNT case LUA_TNIL: { break; // Do nothing. } #endif LUA_REFCOUNT default: lua_assert(0); } }
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 luaS_freeall (void) { int i; for (i=0; i<NUM_HASHS; i++) { stringtable *tb = &L->string_root[i]; int j; for (j=0; j<tb->size; j++) { TaggedString *t = tb->hash[j]; if (t == &EMPTY) continue; luaM_free(t); } luaM_free(tb->hash); } luaM_free(L->string_root); }
static int ws2812_buffer_fill(lua_State* L) { ws2812_buffer * buffer = (ws2812_buffer*)lua_touserdata(L, 1); luaL_argcheck(L, buffer && buffer->canary == CANARY_VALUE, 1, "ws2812.buffer expected"); // Grab colors int i, j; int * colors = luaM_malloc(L, buffer->colorsPerLed * sizeof(int)); for (i = 0; i < buffer->colorsPerLed; i++) { colors[i] = luaL_checkinteger(L, 2+i); } // Fill buffer uint8_t * p = &buffer->values[0]; for(i = 0; i < buffer->size; i++) { for (j = 0; j < buffer->colorsPerLed; j++) { *p++ = colors[j]; } } // Free memory luaM_free(L, colors); return 0; }
/* ** Execute a protected call. Assumes that function is at lua_state->Cstack.base and ** parameters are on top of it. Leave nResults on the stack. */ int32 luaD_protectedrun(int32 nResults) { jmp_buf myErrorJmp; int32 status; struct C_Lua_Stack oldCLS = lua_state->Cstack; jmp_buf *oldErr = lua_state->errorJmp; lua_state->errorJmp = &myErrorJmp; lua_state->state_counter1++; lua_Task *tmpTask = lua_state->task; if (setjmp(myErrorJmp) == 0) { do_callinc(nResults); status = 0; } else { // an error occurred: restore lua_state->Cstack and lua_state->stack.top lua_state->Cstack = oldCLS; lua_state->stack.top = lua_state->stack.stack + lua_state->Cstack.base; while (tmpTask != lua_state->task) { lua_Task *t = lua_state->task; lua_state->task = lua_state->task->next; luaM_free(t); } status = 1; } lua_state->state_counter1--; lua_state->errorJmp = oldErr; return status; }
void luaF_freeclosure(Closure *l) { while (l) { Closure *next = (Closure *)l->head.next; nblocks -= gcsizeclosure(l); luaM_free(l); l = next; } }
void luaE_freethread (lua_State *L, lua_State *L1) { LX *l = fromstate(L1); luaF_close(L1, L1->stack); /* close all upvalues for this thread */ lua_assert(L1->openupval == NULL); luai_userstatefree(L, L1); freestack(L1); luaM_free(L, l); }
void lua_removelibslists() { luaL_libList *list = list_of_libs; while (list) { luaL_libList *nextList = list->next; luaM_free(list); list = nextList; } }
void luaS_free (TaggedString *l) { while (l) { TaggedString *next = (TaggedString *)l->head.next; L->nblocks -= (l->constindex == -1) ? 1 : gcsizestring(l->u.s.len); luaM_free(l); l = next; } }
void luaF_freeproto (lua_State *L, Proto *f) { luaM_freearray(L, f->code, f->sizecode); luaM_freearray(L, f->p, f->sizep); luaM_freearray(L, f->k, f->sizek); luaM_freearray(L, f->lineinfo, f->sizelineinfo); luaM_freearray(L, f->locvars, f->sizelocvars); luaM_freearray(L, f->upvalues, f->sizeupvalues); luaM_free(L, f); }
void luaE_freeCI (lua_State *L) { CallInfo *ci = L->ci; CallInfo *next = ci->next; ci->next = NULL; while ((ci = next) != NULL) { next = ci->next; luaM_free(L, ci); } }
static void block (LexState *ls) { /* block -> chunk */ FuncState *fs = ls->fs; BlockCnt *pbl = (BlockCnt*)luaM_malloc(ls->L,sizeof(BlockCnt)); enterblock(fs, pbl, 0); chunk(ls); lua_assert(pbl->breaklist == NO_JUMP); leaveblock(fs); luaM_free(ls->L,pbl); }
static void unpersiststring(UnpersistInfo *upi) { /* perms reftbl sptbl ref */ int length; char* string; verify(luaZ_read(&upi->zio, &length, sizeof(int)) == 0); string = (char *)luaM_malloc(upi->L, length); verify(luaZ_read(&upi->zio, string, length) == 0); lua_pushlstring(upi->L, string, length); /* perms reftbl sptbl ref str */ luaM_free(upi->L, string, length); }
/* ** free half of the CallInfo structures not in use by a thread */ void luaE_shrinkCI (lua_State *L) { CallInfo *ci = L->ci; while (ci->next != NULL) { /* while there is 'next' */ CallInfo *next2 = ci->next->next; /* next's next */ if (next2 == NULL) break; luaM_free(L, ci->next); /* remove next */ ci->next = next2; /* remove 'next' from the list */ next2->previous = ci; ci = next2; } }
/* ** free half of the CallInfo structures not in use by a thread */ void luaE_shrinkCI (lua_State *L) { CallInfo *ci = L->ci; CallInfo *next2; /* next's next */ /* while there are two nexts */ while (ci->next != NULL && (next2 = ci->next->next) != NULL) { luaM_free(L, ci->next); /* free next */ L->nci--; ci->next = next2; /* remove 'next' from the list */ next2->previous = ci; ci = next2; /* keep next's next */ } }
LUA_API void lua_close (lua_State *L) { LUA_ASSERT(L != lua_state || lua_gettop(L) == 0, "garbage in C stack"); luaC_collect(L, 1); /* collect all elements */ LUA_ASSERT(L->rootproto == NULL, "list should be empty"); LUA_ASSERT(L->rootcl == NULL, "list should be empty"); LUA_ASSERT(L->roottable == NULL, "list should be empty"); luaS_freeall(L); if (L->stack) L->nblocks -= (L->stack_last - L->stack + 1)*sizeof(TObject); luaM_free(L, L->stack); L->nblocks -= (L->last_tag+1)*sizeof(struct TM); luaM_free(L, L->TMtable); L->nblocks -= (L->refSize)*sizeof(struct Ref); luaM_free(L, L->refArray); L->nblocks -= (L->Mbuffsize)*sizeof(char); luaM_free(L, L->Mbuffer); LUA_ASSERT(L->nblocks == sizeof(lua_State), "wrong count for nblocks"); luaM_free(L, L); LUA_ASSERT(L != lua_state || memdebug_numblocks == 0, "memory leak!"); LUA_ASSERT(L != lua_state || memdebug_total == 0,"memory leak!"); }
void luaF_freeproto (lua_State *L, Proto *f) { if (f->ncode > 0) /* function was properly created? */ L->nblocks -= protosize(f); luaM_free(L, f->code); luaM_free(L, f->locvars); luaM_free(L, f->kstr); luaM_free(L, f->knum); luaM_free(L, f->kproto); luaM_free(L, f->lineinfo); luaM_free(L, f); }
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; } } } }
void luaF_close (lua_State *L, StkId level) { UpVal *uv; while (L->openupval != NULL && (uv = L->openupval)->v >= level) { lua_assert(upisopen(uv)); L->openupval = uv->u.open.next; /* remove from 'open' list */ if (uv->refcount == 0) /* no references? */ luaM_free(L, uv); /* free upvalue */ else { setobj(L, &uv->u.value, uv->v); /* move value to upvalue slot */ uv->v = &uv->u.value; /* now current value lives here */ luaC_upvalbarrier(L, uv); } } }
static void rehash(Hash *t) { int32 nold = nhash(t); Node *vold = nodevector(t); int32 i; if (!emptyslots(t)) nhash(t) = luaO_redimension(nhash(t)); nodevector(t) = hashnodecreate(nhash(t)); for (i = 0; i < nold; i++) { Node *n = vold + i; if (ttype(ref(n)) != LUA_T_NIL && ttype(val(n)) != LUA_T_NIL) *node(t, present(t, ref(n))) = *n; // copy old node to luaM_new hash } nblocks += gcsize(t->nhash) - gcsize(nold); luaM_free(vold); }
static void rehash (Hash *t) { int nold = nhash(t); Node *vold = nodevector(t); int nnew = newsize(t); int i; nodevector(t) = hashnodecreate(nnew); nhash(t) = nnew; for (i=0; i<nold; i++) { Node *n = vold+i; if (ttype(ref(n)) != LUA_T_NIL && ttype(val(n)) != LUA_T_NIL) *node(t, present(t, ref(n))) = *n; /* copy old node to luaM_new hash */ } L->nblocks += gcsize(nnew)-gcsize(nold); luaM_free(vold); }
static int delstr (lua_State *L, stringtable *tb, TString *ts) { TString *next, **p; unsigned long h = ts->u.s.hash; int h1 = h & (L->strt.size-1); p = &tb->hash[h1]; while ((next = *p) != NULL) { if (next == ts) { *p = next->nexthash; tb->nuse--; L->nblocks -= sizestring(next->len); luaM_free(L, next); return 1; } else p = &next->nexthash; } return 0; }
void reginfos_free (lua_State *L, Proto *f) { int i; RegInfo *reginfo, *tmp; for (i = 0; i < f->sizereginfos; i++) { reginfo = &(f->reginfos[i]); if (reginfo->state == RI_UNUSED || reginfo->state == RI_LOCAL_UNUSED) continue; reginfo = reginfo->next; while (reginfo != NULL) { tmp = reginfo; reginfo = reginfo->next; tmp->next = NULL; luaM_free(L, tmp); } } luaM_freearray(L, f->reginfos, f->sizereginfos); }
void lua_statedeinit(LState *state) { if (state->prev) state->prev->next = state->next; if (state->next) state->next->prev = state->prev; state->next = nullptr; state->prev = nullptr; if (state->task) { lua_Task *t, *m; for (t = state->task; t != nullptr;) { m = t->next; luaM_free(t); t = m; } } free(state->stack.stack); }
static void rehash (lua_State *L, Hash *t) { int oldsize = t->size; Node *nold = t->node; int nelems = numuse(t); int i; LUA_ASSERT(nelems<=oldsize, "wrong count"); if (nelems >= oldsize-oldsize/4) /* using more than 3/4? */ setnodevector(L, t, (lint32)oldsize*2); else if (nelems <= oldsize/4 && /* less than 1/4? */ oldsize > MINPOWER2) setnodevector(L, t, oldsize/2); else setnodevector(L, t, oldsize); for (i=0; i<oldsize; i++) { Node *old = nold+i; if (ttype(&old->val) != LUA_TNIL) *luaH_set(L, t, &old->key) = old->val; } luaM_free(L, nold); /* free old array */ }
static void forbody (LexState *ls, int base, int line, int nvars, int isnum) { /* forbody -> DO block */ BlockCnt *pbl = (BlockCnt*)luaM_malloc(ls->L,sizeof(BlockCnt)); FuncState *fs = ls->fs; int prep, endfor; adjustlocalvars(ls, 3); /* control variables */ checknext(ls, TK_DO); prep = isnum ? luaK_codeAsBx(fs, OP_FORPREP, base, NO_JUMP) : luaK_jump(fs); enterblock(fs, pbl, 0); /* scope for declared variables */ adjustlocalvars(ls, nvars); luaK_reserveregs(fs, nvars); block(ls); leaveblock(fs); /* end of scope for declared variables */ luaK_patchtohere(fs, prep); endfor = (isnum) ? luaK_codeAsBx(fs, OP_FORLOOP, base, NO_JUMP) : luaK_codeABC(fs, OP_TFORLOOP, base, 0, nvars); luaK_fixline(fs, line); /* pretend that `OP_FOR' starts the loop */ luaK_patchlist(fs, (isnum ? endfor : luaK_jump(fs)), prep + 1); luaM_free(ls->L,pbl); }
static void collectstrings (lua_State *L, int all) { int i; for (i=0; i<L->strt.size; i++) { /* for each list */ TString **p = &L->strt.hash[i]; TString *next; while ((next = *p) != NULL) { if (next->marked && !all) { /* preserve? */ if (next->marked < FIXMARK) /* does not change FIXMARKs */ next->marked = 0; p = &next->nexthash; } else { /* collect */ *p = next->nexthash; L->strt.nuse--; L->nblocks -= sizestring(next->len); luaM_free(L, next); } } } checktab(L, &L->strt); }
static void freestack (lua_State *L, lua_State *L1) { struct lua_longjmp *pj, *pprev, *pnext; luaM_freearray(L, L1->base_ci, L1->size_ci, CallInfo); luaM_freearray(L, L1->stack, L1->stacksize, TValue); /* free try-catch info */ pj = L->errorJmp; pnext = NULL; while (pj) { pprev = pj->previous; if (pj->type == JMPTYPE_TRY) { if (pnext == NULL) L->errorJmp = pprev; else pnext->previous = pprev; luaM_free(L, pj); } else pnext = pj; pj = pprev; } }
static void grow (stringtable *tb) { int ns = newsize(tb); TaggedString **newhash = luaM_newvector(ns, TaggedString *); int i; for (i=0; i<ns; i++) newhash[i] = NULL; /* rehash */ tb->nuse = 0; for (i=0; i<tb->size; i++) { if (tb->hash[i] != NULL && tb->hash[i] != &EMPTY) { int h = tb->hash[i]->hash%ns; while (newhash[h]) h = (h+1)%ns; newhash[h] = tb->hash[i]; tb->nuse++; } } luaM_free(tb->hash); tb->size = ns; tb->hash = newhash; }