aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lstate.c105
1 files changed, 53 insertions, 52 deletions
diff --git a/lstate.c b/lstate.c
index 6bed2e7c..dd80a7e1 100644
--- a/lstate.c
+++ b/lstate.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lstate.c,v 1.124 2003/07/16 20:49:02 roberto Exp roberto $ 2** $Id: lstate.c,v 1.125 2003/07/16 20:51:47 roberto Exp roberto $
3** Global State 3** Global State
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -34,10 +34,19 @@ union UEXTRASPACE {L_Umaxalign a; LUA_USERSTATE b;};
34#endif 34#endif
35 35
36 36
37/*
38** Main thread combines a thread state and the global state
39*/
40typedef struct LG {
41 lua_State l;
42 global_State g;
43} LG;
44
45
37 46
38 47
39static lua_State *mallocstate (lua_State *L) { 48static lua_State *mallocstate (lua_State *L, size_t size) {
40 lu_byte *block = (lu_byte *)luaM_malloc(L, sizeof(lua_State) + EXTRASPACE); 49 lu_byte *block = (lu_byte *)luaM_malloc(L, size + EXTRASPACE);
41 if (block == NULL) return NULL; 50 if (block == NULL) return NULL;
42 else { 51 else {
43 block += EXTRASPACE; 52 block += EXTRASPACE;
@@ -46,9 +55,9 @@ static lua_State *mallocstate (lua_State *L) {
46} 55}
47 56
48 57
49static void freestate (lua_State *L, lua_State *L1) { 58static void freestate (lua_State *L, lua_State *L1, size_t size) {
50 luaM_free(L, cast(lu_byte *, L1) - EXTRASPACE, 59 luaM_free(L, cast(lu_byte *, L1) - EXTRASPACE,
51 sizeof(lua_State) + EXTRASPACE); 60 size + EXTRASPACE);
52} 61}
53 62
54 63
@@ -77,27 +86,7 @@ static void freestack (lua_State *L, lua_State *L1) {
77** open parts that may cause memory-allocation errors 86** open parts that may cause memory-allocation errors
78*/ 87*/
79static void f_luaopen (lua_State *L, void *ud) { 88static void f_luaopen (lua_State *L, void *ud) {
80 /* create a new global state */
81 global_State *g = luaM_new(NULL, global_State);
82 UNUSED(ud); 89 UNUSED(ud);
83 if (g == NULL) luaD_throw(L, LUA_ERRMEM);
84 L->l_G = g;
85 g->mainthread = L;
86 g->GCthreshold = 0; /* mark it as unfinished state */
87 g->strt.size = 0;
88 g->strt.nuse = 0;
89 g->strt.hash = NULL;
90 setnilvalue(defaultmeta(L));
91 setnilvalue(registry(L));
92 luaZ_initbuffer(L, &g->buff);
93 g->panic = NULL;
94 g->rootgc = NULL;
95 g->rootudata = NULL;
96 g->tmudata = NULL;
97 setnilvalue(gkey(g->dummynode));
98 setnilvalue(gval(g->dummynode));
99 g->dummynode->next = NULL;
100 g->nblocks = sizeof(lua_State) + sizeof(global_State);
101 stack_init(L, L); /* init stack */ 90 stack_init(L, L); /* init stack */
102 /* create default meta table with a dummy table, and then close the loop */ 91 /* create default meta table with a dummy table, and then close the loop */
103 defaultmeta(L)->tt = LUA_TTABLE; 92 defaultmeta(L)->tt = LUA_TTABLE;
@@ -109,7 +98,7 @@ static void f_luaopen (lua_State *L, void *ud) {
109 luaT_init(L); 98 luaT_init(L);
110 luaX_init(L); 99 luaX_init(L);
111 luaS_fix(luaS_newliteral(L, MEMERRMSG)); 100 luaS_fix(luaS_newliteral(L, MEMERRMSG));
112 g->GCthreshold = 4*G(L)->nblocks; 101 G(L)->GCthreshold = 4*G(L)->nblocks;
113} 102}
114 103
115 104
@@ -134,24 +123,19 @@ static void preinit_state (lua_State *L) {
134 123
135static void close_state (lua_State *L) { 124static void close_state (lua_State *L) {
136 luaF_close(L, L->stack); /* close all upvalues for this thread */ 125 luaF_close(L, L->stack); /* close all upvalues for this thread */
137 if (G(L)) { /* close global state */ 126 luaC_sweep(L, 1); /* collect all elements */
138 luaC_sweep(L, 1); /* collect all elements */ 127 lua_assert(G(L)->rootgc == NULL);
139 lua_assert(G(L)->rootgc == NULL); 128 lua_assert(G(L)->rootudata == NULL);
140 lua_assert(G(L)->rootudata == NULL); 129 luaS_freeall(L);
141 luaS_freeall(L); 130 luaZ_freebuffer(L, &G(L)->buff);
142 luaZ_freebuffer(L, &G(L)->buff);
143 }
144 freestack(L, L); 131 freestack(L, L);
145 if (G(L)) { 132 lua_assert(G(L)->nblocks == sizeof(LG));
146 lua_assert(G(L)->nblocks == sizeof(lua_State) + sizeof(global_State)); 133 freestate(NULL, L, sizeof(LG));
147 luaM_freelem(NULL, G(L));
148 }
149 freestate(NULL, L);
150} 134}
151 135
152 136
153lua_State *luaE_newthread (lua_State *L) { 137lua_State *luaE_newthread (lua_State *L) {
154 lua_State *L1 = mallocstate(L); 138 lua_State *L1 = mallocstate(L, sizeof(lua_State));
155 luaC_link(L, valtogco(L1), LUA_TTHREAD); 139 luaC_link(L, valtogco(L1), LUA_TTHREAD);
156 preinit_state(L1); 140 preinit_state(L1);
157 L1->l_G = L->l_G; 141 L1->l_G = L->l_G;
@@ -165,23 +149,40 @@ void luaE_freethread (lua_State *L, lua_State *L1) {
165 luaF_close(L1, L1->stack); /* close all upvalues for this thread */ 149 luaF_close(L1, L1->stack); /* close all upvalues for this thread */
166 lua_assert(L1->openupval == NULL); 150 lua_assert(L1->openupval == NULL);
167 freestack(L, L1); 151 freestack(L, L1);
168 freestate(L, L1); 152 freestate(L, L1, sizeof(lua_State));
169} 153}
170 154
171 155
172LUA_API lua_State *lua_open (void) { 156LUA_API lua_State *lua_open (void) {
173 lua_State *L = mallocstate(NULL); 157 lua_State *L = mallocstate(NULL, sizeof(LG));
174 if (L) { /* allocation OK? */ 158 global_State *g;
175 L->tt = LUA_TTHREAD; 159 if (L == NULL) return NULL;
176 L->marked = 0; 160 g = &((LG *)L)->g;
177 L->next = L->gclist = NULL; 161 L->tt = LUA_TTHREAD;
178 preinit_state(L); 162 L->marked = 0;
179 L->l_G = NULL; 163 L->next = L->gclist = NULL;
180 if (luaD_rawrunprotected(L, f_luaopen, NULL) != 0) { 164 preinit_state(L);
181 /* memory allocation error: free partial state */ 165 L->l_G = g;
182 close_state(L); 166 g->mainthread = L;
183 L = NULL; 167 g->GCthreshold = 0; /* mark it as unfinished state */
184 } 168 g->strt.size = 0;
169 g->strt.nuse = 0;
170 g->strt.hash = NULL;
171 setnilvalue(defaultmeta(L));
172 setnilvalue(registry(L));
173 luaZ_initbuffer(L, &g->buff);
174 g->panic = NULL;
175 g->rootgc = NULL;
176 g->rootudata = NULL;
177 g->tmudata = NULL;
178 setnilvalue(gkey(g->dummynode));
179 setnilvalue(gval(g->dummynode));
180 g->dummynode->next = NULL;
181 g->nblocks = sizeof(LG);
182 if (luaD_rawrunprotected(L, f_luaopen, NULL) != 0) {
183 /* memory allocation error: free partial state */
184 close_state(L);
185 L = NULL;
185 } 186 }
186 lua_userstateopen(L); 187 lua_userstateopen(L);
187 return L; 188 return L;