176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/* 276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman** $Id: lstate.c,v 2.99.1.2 2013/11/08 17:45:31 roberto Exp $ 376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman** Global State 476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman** See Copyright Notice in lua.h 576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman*/ 676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#include <stddef.h> 976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#include <string.h> 1076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 1176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define lstate_c 1276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define LUA_CORE 1376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 1476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#include "lua.h" 1576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 1676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#include "lapi.h" 1776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#include "ldebug.h" 1876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#include "ldo.h" 1976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#include "lfunc.h" 2076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#include "lgc.h" 2176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#include "llex.h" 2276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#include "lmem.h" 2376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#include "lstate.h" 2476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#include "lstring.h" 2576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#include "ltable.h" 2676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#include "ltm.h" 2776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 2876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 2976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#if !defined(LUAI_GCPAUSE) 3076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define LUAI_GCPAUSE 200 /* 200% */ 3176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#endif 3276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 3376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#if !defined(LUAI_GCMAJOR) 3476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define LUAI_GCMAJOR 200 /* 200% */ 3576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#endif 3676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 3776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#if !defined(LUAI_GCMUL) 3876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define LUAI_GCMUL 200 /* GC runs 'twice the speed' of memory allocation */ 3976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#endif 4076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 4176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 4276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define MEMERRMSG "not enough memory" 4376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 4476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 4576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/* 4676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman** a macro to help the creation of a unique random seed when a state is 4776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman** created; the seed is used to randomize hashes. 4876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman*/ 4976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#if !defined(luai_makeseed) 5076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#ifndef SYSLINUX 5176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#include <time.h> 5276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define luai_makeseed() cast(unsigned int, time(NULL)) 5376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#else 5476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#include <sys/times.h> 5576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define luai_makeseed() cast(unsigned int, times(NULL)) 5676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#endif /* SYSLINUX */ 5776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#endif 5876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 5976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 6076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 6176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/* 6276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman** thread state + extra space 6376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman*/ 6476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmantypedef struct LX { 6576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#if defined(LUAI_EXTRASPACE) 6676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman char buff[LUAI_EXTRASPACE]; 6776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#endif 6876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman lua_State l; 6976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman} LX; 7076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 7176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 7276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/* 7376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman** Main thread combines a thread state and the global state 7476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman*/ 7576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmantypedef struct LG { 7676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman LX l; 7776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman global_State g; 7876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman} LG; 7976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 8076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 8176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 8276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define fromstate(L) (cast(LX *, cast(lu_byte *, (L)) - offsetof(LX, l))) 8376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 8476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 8576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/* 8676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman** Compute an initial seed as random as possible. In ANSI, rely on 8776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman** Address Space Layout Randomization (if present) to increase 8876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman** randomness.. 8976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman*/ 9076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define addbuff(b,p,e) \ 9176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman { size_t t = cast(size_t, e); \ 9276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman memcpy(buff + p, &t, sizeof(t)); p += sizeof(t); } 9376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 9476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic unsigned int makeseed (lua_State *L) { 9576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman char buff[4 * sizeof(size_t)]; 9676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman unsigned int h = luai_makeseed(); 9776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman int p = 0; 9876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman addbuff(buff, p, L); /* heap variable */ 9976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman addbuff(buff, p, &h); /* local variable */ 10076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman addbuff(buff, p, luaO_nilobject); /* global variable */ 10176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman addbuff(buff, p, &lua_newstate); /* public function */ 10276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman lua_assert(p == sizeof(buff)); 10376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman return luaS_hash(buff, p, h); 10476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman} 10576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 10676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 10776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/* 10876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman** set GCdebt to a new value keeping the value (totalbytes + GCdebt) 10976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman** invariant 11076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman*/ 11176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanvoid luaE_setdebt (global_State *g, l_mem debt) { 11276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman g->totalbytes -= (debt - g->GCdebt); 11376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman g->GCdebt = debt; 11476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman} 11576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 11676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 11776d05dc695b06c4e987bb8078f78032441e1430cGreg HartmanCallInfo *luaE_extendCI (lua_State *L) { 11876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman CallInfo *ci = luaM_new(L, CallInfo); 11976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman lua_assert(L->ci->next == NULL); 12076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman L->ci->next = ci; 12176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman ci->previous = L->ci; 12276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman ci->next = NULL; 12376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman return ci; 12476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman} 12576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 12676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 12776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanvoid luaE_freeCI (lua_State *L) { 12876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman CallInfo *ci = L->ci; 12976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman CallInfo *next = ci->next; 13076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman ci->next = NULL; 13176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman while ((ci = next) != NULL) { 13276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman next = ci->next; 13376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman luaM_free(L, ci); 13476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman } 13576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman} 13676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 13776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 13876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic void stack_init (lua_State *L1, lua_State *L) { 13976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman int i; CallInfo *ci; 14076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman /* initialize stack array */ 14176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman L1->stack = luaM_newvector(L, BASIC_STACK_SIZE, TValue); 14276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman L1->stacksize = BASIC_STACK_SIZE; 14376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman for (i = 0; i < BASIC_STACK_SIZE; i++) 14476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman setnilvalue(L1->stack + i); /* erase new stack */ 14576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman L1->top = L1->stack; 14676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman L1->stack_last = L1->stack + L1->stacksize - EXTRA_STACK; 14776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman /* initialize first ci */ 14876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman ci = &L1->base_ci; 14976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman ci->next = ci->previous = NULL; 15076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman ci->callstatus = 0; 15176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman ci->func = L1->top; 15276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman setnilvalue(L1->top++); /* 'function' entry for this 'ci' */ 15376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman ci->top = L1->top + LUA_MINSTACK; 15476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman L1->ci = ci; 15576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman} 15676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 15776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 15876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic void freestack (lua_State *L) { 15976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman if (L->stack == NULL) 16076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman return; /* stack not completely built yet */ 16176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman L->ci = &L->base_ci; /* free the entire 'ci' list */ 16276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman luaE_freeCI(L); 16376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman luaM_freearray(L, L->stack, L->stacksize); /* free stack array */ 16476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman} 16576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 16676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 16776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/* 16876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman** Create registry table and its predefined values 16976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman*/ 17076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic void init_registry (lua_State *L, global_State *g) { 17176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman TValue mt; 17276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman /* create registry */ 17376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman Table *registry = luaH_new(L); 17476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman sethvalue(L, &g->l_registry, registry); 17576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman luaH_resize(L, registry, LUA_RIDX_LAST, 0); 17676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman /* registry[LUA_RIDX_MAINTHREAD] = L */ 17776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman setthvalue(L, &mt, L); 17876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman luaH_setint(L, registry, LUA_RIDX_MAINTHREAD, &mt); 17976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman /* registry[LUA_RIDX_GLOBALS] = table of globals */ 18076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman sethvalue(L, &mt, luaH_new(L)); 18176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman luaH_setint(L, registry, LUA_RIDX_GLOBALS, &mt); 18276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman} 18376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 18476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 18576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/* 18676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman** open parts of the state that may cause memory-allocation errors 18776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman*/ 18876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic void f_luaopen (lua_State *L, void *ud) { 18976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman global_State *g = G(L); 19076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman UNUSED(ud); 19176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman stack_init(L, L); /* init stack */ 19276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman init_registry(L, g); 19376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman luaS_resize(L, MINSTRTABSIZE); /* initial size of string table */ 19476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman luaT_init(L); 19576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman luaX_init(L); 19676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman /* pre-create memory-error message */ 19776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman g->memerrmsg = luaS_newliteral(L, MEMERRMSG); 19876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman luaS_fix(g->memerrmsg); /* it should never be collected */ 19976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman g->gcrunning = 1; /* allow gc */ 20076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman g->version = lua_version(NULL); 20176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman luai_userstateopen(L); 20276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman} 20376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 20476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 20576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/* 20676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman** preinitialize a state with consistent values without allocating 20776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman** any memory (to avoid errors) 20876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman*/ 20976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic void preinit_state (lua_State *L, global_State *g) { 21076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman G(L) = g; 21176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman L->stack = NULL; 21276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman L->ci = NULL; 21376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman L->stacksize = 0; 21476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman L->errorJmp = NULL; 21576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman L->nCcalls = 0; 21676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman L->hook = NULL; 21776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman L->hookmask = 0; 21876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman L->basehookcount = 0; 21976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman L->allowhook = 1; 22076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman resethookcount(L); 22176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman L->openupval = NULL; 22276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman L->nny = 1; 22376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman L->status = LUA_OK; 22476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman L->errfunc = 0; 22576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman} 22676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 22776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 22876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic void close_state (lua_State *L) { 22976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman global_State *g = G(L); 23076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman luaF_close(L, L->stack); /* close all upvalues for this thread */ 23176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman luaC_freeallobjects(L); /* collect all objects */ 23276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman if (g->version) /* closing a fully built state? */ 23376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman luai_userstateclose(L); 23476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman luaM_freearray(L, G(L)->strt.hash, G(L)->strt.size); 23576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman luaZ_freebuffer(L, &g->buff); 23676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman freestack(L); 23776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman lua_assert(gettotalbytes(g) == sizeof(LG)); 23876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman (*g->frealloc)(g->ud, fromstate(L), sizeof(LG), 0); /* free main block */ 23976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman} 24076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 24176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 24276d05dc695b06c4e987bb8078f78032441e1430cGreg HartmanLUA_API lua_State *lua_newthread (lua_State *L) { 24376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman lua_State *L1; 24476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman lua_lock(L); 24576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman luaC_checkGC(L); 24676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman L1 = &luaC_newobj(L, LUA_TTHREAD, sizeof(LX), NULL, offsetof(LX, l))->th; 24776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman setthvalue(L, L->top, L1); 24876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman api_incr_top(L); 24976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman preinit_state(L1, G(L)); 25076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman L1->hookmask = L->hookmask; 25176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman L1->basehookcount = L->basehookcount; 25276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman L1->hook = L->hook; 25376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman resethookcount(L1); 25476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman luai_userstatethread(L, L1); 25576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman stack_init(L1, L); /* init stack */ 25676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman lua_unlock(L); 25776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman return L1; 25876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman} 25976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 26076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 26176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanvoid luaE_freethread (lua_State *L, lua_State *L1) { 26276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman LX *l = fromstate(L1); 26376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman luaF_close(L1, L1->stack); /* close all upvalues for this thread */ 26476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman lua_assert(L1->openupval == NULL); 26576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman luai_userstatefree(L, L1); 26676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman freestack(L1); 26776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman luaM_free(L, l); 26876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman} 26976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 27076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 27176d05dc695b06c4e987bb8078f78032441e1430cGreg HartmanLUA_API lua_State *lua_newstate (lua_Alloc f, void *ud) { 27276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman int i; 27376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman lua_State *L; 27476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman global_State *g; 27576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman LG *l = cast(LG *, (*f)(ud, NULL, LUA_TTHREAD, sizeof(LG))); 27676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman if (l == NULL) return NULL; 27776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman L = &l->l.l; 27876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman g = &l->g; 27976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman L->next = NULL; 28076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman L->tt = LUA_TTHREAD; 28176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman g->currentwhite = bit2mask(WHITE0BIT, FIXEDBIT); 28276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman L->marked = luaC_white(g); 28376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman g->gckind = KGC_NORMAL; 28476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman preinit_state(L, g); 28576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman g->frealloc = f; 28676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman g->ud = ud; 28776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman g->mainthread = L; 28876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman g->seed = makeseed(L); 28976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman g->uvhead.u.l.prev = &g->uvhead; 29076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman g->uvhead.u.l.next = &g->uvhead; 29176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman g->gcrunning = 0; /* no GC while building state */ 29276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman g->GCestimate = 0; 29376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman g->strt.size = 0; 29476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman g->strt.nuse = 0; 29576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman g->strt.hash = NULL; 29676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman setnilvalue(&g->l_registry); 29776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman luaZ_initbuffer(L, &g->buff); 29876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman g->panic = NULL; 29976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman g->version = NULL; 30076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman g->gcstate = GCSpause; 30176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman g->allgc = NULL; 30276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman g->finobj = NULL; 30376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman g->tobefnz = NULL; 30476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman g->sweepgc = g->sweepfin = NULL; 30576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman g->gray = g->grayagain = NULL; 30676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman g->weak = g->ephemeron = g->allweak = NULL; 30776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman g->totalbytes = sizeof(LG); 30876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman g->GCdebt = 0; 30976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman g->gcpause = LUAI_GCPAUSE; 31076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman g->gcmajorinc = LUAI_GCMAJOR; 31176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman g->gcstepmul = LUAI_GCMUL; 31276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman for (i=0; i < LUA_NUMTAGS; i++) g->mt[i] = NULL; 31376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman if (luaD_rawrunprotected(L, f_luaopen, NULL) != LUA_OK) { 31476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman /* memory allocation error: free partial state */ 31576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman close_state(L); 31676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman L = NULL; 31776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman } 31876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman return L; 31976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman} 32076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 32176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 32276d05dc695b06c4e987bb8078f78032441e1430cGreg HartmanLUA_API void lua_close (lua_State *L) { 32376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman L = G(L)->mainthread; /* only the main thread can be closed */ 32476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman lua_lock(L); 32576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman close_state(L); 32676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman} 32776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 32876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 329