Mercurial > vba-clojure
diff src/lua/lstate.c @ 11:27763b933818
raise lua sources up one level
author | Robert McIntyre <rlm@mit.edu> |
---|---|
date | Sat, 03 Mar 2012 11:07:39 -0600 |
parents | src/lua/src/lstate.c@f9f4f1b99eed |
children |
line wrap: on
line diff
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/src/lua/lstate.c Sat Mar 03 11:07:39 2012 -0600 1.3 @@ -0,0 +1,214 @@ 1.4 +/* 1.5 +** $Id: lstate.c,v 2.36.1.2 2008/01/03 15:20:39 roberto Exp $ 1.6 +** Global State 1.7 +** See Copyright Notice in lua.h 1.8 +*/ 1.9 + 1.10 + 1.11 +#include <stddef.h> 1.12 + 1.13 +#define lstate_c 1.14 +#define LUA_CORE 1.15 + 1.16 +#include "lua.h" 1.17 + 1.18 +#include "ldebug.h" 1.19 +#include "ldo.h" 1.20 +#include "lfunc.h" 1.21 +#include "lgc.h" 1.22 +#include "llex.h" 1.23 +#include "lmem.h" 1.24 +#include "lstate.h" 1.25 +#include "lstring.h" 1.26 +#include "ltable.h" 1.27 +#include "ltm.h" 1.28 + 1.29 + 1.30 +#define state_size(x) (sizeof(x) + LUAI_EXTRASPACE) 1.31 +#define fromstate(l) (cast(lu_byte *, (l)) - LUAI_EXTRASPACE) 1.32 +#define tostate(l) (cast(lua_State *, cast(lu_byte *, l) + LUAI_EXTRASPACE)) 1.33 + 1.34 + 1.35 +/* 1.36 +** Main thread combines a thread state and the global state 1.37 +*/ 1.38 +typedef struct LG { 1.39 + lua_State l; 1.40 + global_State g; 1.41 +} LG; 1.42 + 1.43 + 1.44 + 1.45 +static void stack_init (lua_State *L1, lua_State *L) { 1.46 + /* initialize CallInfo array */ 1.47 + L1->base_ci = luaM_newvector(L, BASIC_CI_SIZE, CallInfo); 1.48 + L1->ci = L1->base_ci; 1.49 + L1->size_ci = BASIC_CI_SIZE; 1.50 + L1->end_ci = L1->base_ci + L1->size_ci - 1; 1.51 + /* initialize stack array */ 1.52 + L1->stack = luaM_newvector(L, BASIC_STACK_SIZE + EXTRA_STACK, TValue); 1.53 + L1->stacksize = BASIC_STACK_SIZE + EXTRA_STACK; 1.54 + L1->top = L1->stack; 1.55 + L1->stack_last = L1->stack+(L1->stacksize - EXTRA_STACK)-1; 1.56 + /* initialize first ci */ 1.57 + L1->ci->func = L1->top; 1.58 + setnilvalue(L1->top++); /* `function' entry for this `ci' */ 1.59 + L1->base = L1->ci->base = L1->top; 1.60 + L1->ci->top = L1->top + LUA_MINSTACK; 1.61 +} 1.62 + 1.63 + 1.64 +static void freestack (lua_State *L, lua_State *L1) { 1.65 + luaM_freearray(L, L1->base_ci, L1->size_ci, CallInfo); 1.66 + luaM_freearray(L, L1->stack, L1->stacksize, TValue); 1.67 +} 1.68 + 1.69 + 1.70 +/* 1.71 +** open parts that may cause memory-allocation errors 1.72 +*/ 1.73 +static void f_luaopen (lua_State *L, void *ud) { 1.74 + global_State *g = G(L); 1.75 + UNUSED(ud); 1.76 + stack_init(L, L); /* init stack */ 1.77 + sethvalue(L, gt(L), luaH_new(L, 0, 2)); /* table of globals */ 1.78 + sethvalue(L, registry(L), luaH_new(L, 0, 2)); /* registry */ 1.79 + luaS_resize(L, MINSTRTABSIZE); /* initial size of string table */ 1.80 + luaT_init(L); 1.81 + luaX_init(L); 1.82 + luaS_fix(luaS_newliteral(L, MEMERRMSG)); 1.83 + g->GCthreshold = 4*g->totalbytes; 1.84 +} 1.85 + 1.86 + 1.87 +static void preinit_state (lua_State *L, global_State *g) { 1.88 + G(L) = g; 1.89 + L->stack = NULL; 1.90 + L->stacksize = 0; 1.91 + L->errorJmp = NULL; 1.92 + L->hook = NULL; 1.93 + L->hookmask = 0; 1.94 + L->basehookcount = 0; 1.95 + L->allowhook = 1; 1.96 + resethookcount(L); 1.97 + L->openupval = NULL; 1.98 + L->size_ci = 0; 1.99 + L->nCcalls = L->baseCcalls = 0; 1.100 + L->status = 0; 1.101 + L->base_ci = L->ci = NULL; 1.102 + L->savedpc = NULL; 1.103 + L->errfunc = 0; 1.104 + setnilvalue(gt(L)); 1.105 +} 1.106 + 1.107 + 1.108 +static void close_state (lua_State *L) { 1.109 + global_State *g = G(L); 1.110 + luaF_close(L, L->stack); /* close all upvalues for this thread */ 1.111 + luaC_freeall(L); /* collect all objects */ 1.112 + lua_assert(g->rootgc == obj2gco(L)); 1.113 + lua_assert(g->strt.nuse == 0); 1.114 + luaM_freearray(L, G(L)->strt.hash, G(L)->strt.size, TString *); 1.115 + luaZ_freebuffer(L, &g->buff); 1.116 + freestack(L, L); 1.117 + lua_assert(g->totalbytes == sizeof(LG)); 1.118 + (*g->frealloc)(g->ud, fromstate(L), state_size(LG), 0); 1.119 +} 1.120 + 1.121 + 1.122 +lua_State *luaE_newthread (lua_State *L) { 1.123 + lua_State *L1 = tostate(luaM_malloc(L, state_size(lua_State))); 1.124 + luaC_link(L, obj2gco(L1), LUA_TTHREAD); 1.125 + preinit_state(L1, G(L)); 1.126 + stack_init(L1, L); /* init stack */ 1.127 + setobj2n(L, gt(L1), gt(L)); /* share table of globals */ 1.128 + L1->hookmask = L->hookmask; 1.129 + L1->basehookcount = L->basehookcount; 1.130 + L1->hook = L->hook; 1.131 + resethookcount(L1); 1.132 + lua_assert(iswhite(obj2gco(L1))); 1.133 + return L1; 1.134 +} 1.135 + 1.136 + 1.137 +void luaE_freethread (lua_State *L, lua_State *L1) { 1.138 + luaF_close(L1, L1->stack); /* close all upvalues for this thread */ 1.139 + lua_assert(L1->openupval == NULL); 1.140 + luai_userstatefree(L1); 1.141 + freestack(L, L1); 1.142 + luaM_freemem(L, fromstate(L1), state_size(lua_State)); 1.143 +} 1.144 + 1.145 + 1.146 +LUA_API lua_State *lua_newstate (lua_Alloc f, void *ud) { 1.147 + int i; 1.148 + lua_State *L; 1.149 + global_State *g; 1.150 + void *l = (*f)(ud, NULL, 0, state_size(LG)); 1.151 + if (l == NULL) return NULL; 1.152 + L = tostate(l); 1.153 + g = &((LG *)L)->g; 1.154 + L->next = NULL; 1.155 + L->tt = LUA_TTHREAD; 1.156 + g->currentwhite = bit2mask(WHITE0BIT, FIXEDBIT); 1.157 + L->marked = luaC_white(g); 1.158 + set2bits(L->marked, FIXEDBIT, SFIXEDBIT); 1.159 + preinit_state(L, g); 1.160 + g->frealloc = f; 1.161 + g->ud = ud; 1.162 + g->mainthread = L; 1.163 + g->uvhead.u.l.prev = &g->uvhead; 1.164 + g->uvhead.u.l.next = &g->uvhead; 1.165 + g->GCthreshold = 0; /* mark it as unfinished state */ 1.166 + g->strt.size = 0; 1.167 + g->strt.nuse = 0; 1.168 + g->strt.hash = NULL; 1.169 + setnilvalue(registry(L)); 1.170 + luaZ_initbuffer(L, &g->buff); 1.171 + g->panic = NULL; 1.172 + g->gcstate = GCSpause; 1.173 + g->rootgc = obj2gco(L); 1.174 + g->sweepstrgc = 0; 1.175 + g->sweepgc = &g->rootgc; 1.176 + g->gray = NULL; 1.177 + g->grayagain = NULL; 1.178 + g->weak = NULL; 1.179 + g->tmudata = NULL; 1.180 + g->totalbytes = sizeof(LG); 1.181 + g->gcpause = LUAI_GCPAUSE; 1.182 + g->gcstepmul = LUAI_GCMUL; 1.183 + g->gcdept = 0; 1.184 + for (i=0; i<NUM_TAGS; i++) g->mt[i] = NULL; 1.185 + if (luaD_rawrunprotected(L, f_luaopen, NULL) != 0) { 1.186 + /* memory allocation error: free partial state */ 1.187 + close_state(L); 1.188 + L = NULL; 1.189 + } 1.190 + else 1.191 + luai_userstateopen(L); 1.192 + return L; 1.193 +} 1.194 + 1.195 + 1.196 +static void callallgcTM (lua_State *L, void *ud) { 1.197 + UNUSED(ud); 1.198 + luaC_callGCTM(L); /* call GC metamethods for all udata */ 1.199 +} 1.200 + 1.201 + 1.202 +LUA_API void lua_close (lua_State *L) { 1.203 + L = G(L)->mainthread; /* only the main thread can be closed */ 1.204 + lua_lock(L); 1.205 + luaF_close(L, L->stack); /* close all upvalues for this thread */ 1.206 + luaC_separateudata(L, 1); /* separate udata that have GC metamethods */ 1.207 + L->errfunc = 0; /* no error function during GC metamethods */ 1.208 + do { /* repeat until no more errors */ 1.209 + L->ci = L->base_ci; 1.210 + L->base = L->top = L->ci->base; 1.211 + L->nCcalls = L->baseCcalls = 0; 1.212 + } while (luaD_rawrunprotected(L, callallgcTM, NULL) != 0); 1.213 + lua_assert(G(L)->tmudata == NULL); 1.214 + luai_userstateclose(L); 1.215 + close_state(L); 1.216 +} 1.217 +