aboutsummaryrefslogtreecommitdiff
path: root/lstate.c
diff options
context:
space:
mode:
Diffstat (limited to 'lstate.c')
-rw-r--r--lstate.c103
1 files changed, 52 insertions, 51 deletions
diff --git a/lstate.c b/lstate.c
index 58631289..cac3293b 100644
--- a/lstate.c
+++ b/lstate.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lstate.c,v 1.106 2002/10/08 18:46:08 roberto Exp roberto $ 2** $Id: lstate.c,v 1.107 2002/10/22 17:58:14 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*/
@@ -19,11 +19,30 @@
19#include "ltm.h" 19#include "ltm.h"
20 20
21 21
22/*
23** macro to allow the inclusion of user information in Lua state
24*/
25#ifndef LUA_USERSTATE
26#define EXTRASPACE 0
27#else
28union UEXTRASPACE {L_Umaxalign a; LUA_USERSTATE b;};
29#define EXTRASPACE (sizeof(UEXTRASPACE))
30#endif
22 31
23 32
24static void close_state (lua_State *L); 33static void close_state (lua_State *L);
25 34
26 35
36static lua_State *newthread (lua_State *L) {
37 lu_byte *block = (lu_byte *)luaM_malloc(L, sizeof(lua_State) + EXTRASPACE);
38 if (block == NULL) return NULL;
39 else {
40 block += EXTRASPACE;
41 return cast(lua_State *, block);
42 }
43}
44
45
27/* 46/*
28** you can change this function through the official API: 47** you can change this function through the official API:
29** call `lua_setpanicf' 48** call `lua_setpanicf'
@@ -34,19 +53,19 @@ static int default_panic (lua_State *L) {
34} 53}
35 54
36 55
37static void stack_init (lua_State *L, lua_State *OL) { 56static void stack_init (lua_State *L1, lua_State *L) {
38 L->stack = luaM_newvector(OL, BASIC_STACK_SIZE + EXTRA_STACK, TObject); 57 L1->stack = luaM_newvector(L, BASIC_STACK_SIZE + EXTRA_STACK, TObject);
39 L->stacksize = BASIC_STACK_SIZE + EXTRA_STACK; 58 L1->stacksize = BASIC_STACK_SIZE + EXTRA_STACK;
40 L->top = L->stack; 59 L1->top = L1->stack;
41 L->stack_last = L->stack+(L->stacksize - EXTRA_STACK)-1; 60 L1->stack_last = L1->stack+(L1->stacksize - EXTRA_STACK)-1;
42 L->base_ci = luaM_newvector(OL, BASIC_CI_SIZE, CallInfo); 61 L1->base_ci = luaM_newvector(L, BASIC_CI_SIZE, CallInfo);
43 L->ci = L->base_ci; 62 L1->ci = L1->base_ci;
44 L->ci->state = CI_C; /* not a Lua function */ 63 L1->ci->state = CI_C; /* not a Lua function */
45 setnilvalue(L->top++); /* `function' entry for this `ci' */ 64 setnilvalue(L1->top++); /* `function' entry for this `ci' */
46 L->ci->base = L->top; 65 L1->ci->base = L1->top;
47 L->ci->top = L->top + LUA_MINSTACK; 66 L1->ci->top = L1->top + LUA_MINSTACK;
48 L->size_ci = BASIC_CI_SIZE; 67 L1->size_ci = BASIC_CI_SIZE;
49 L->end_ci = L->base_ci + L->size_ci; 68 L1->end_ci = L1->base_ci + L1->size_ci;
50} 69}
51 70
52 71
@@ -57,6 +76,7 @@ static void f_luaopen (lua_State *L, void *ud) {
57 UNUSED(ud); 76 UNUSED(ud);
58 /* create a new global state */ 77 /* create a new global state */
59 L->l_G = luaM_new(L, global_State); 78 L->l_G = luaM_new(L, global_State);
79 G(L)->mainthread = L;
60 G(L)->GCthreshold = 0; /* mark it as unfinished state */ 80 G(L)->GCthreshold = 0; /* mark it as unfinished state */
61 G(L)->strt.size = 0; 81 G(L)->strt.size = 0;
62 G(L)->strt.nuse = 0; 82 G(L)->strt.nuse = 0;
@@ -103,31 +123,22 @@ static void preinit_state (lua_State *L) {
103} 123}
104 124
105 125
106LUA_API lua_State *lua_newthread (lua_State *OL) { 126lua_State *luaE_newthread (lua_State *L) {
107 lua_State *L; 127 lua_State *L1 = newthread(L);
108 lua_lock(OL); 128 luaC_link(L, cast(GCObject *, L1), LUA_TTHREAD);
109 L = luaM_new(OL, lua_State); 129 preinit_state(L1);
110 preinit_state(L); 130 L1->l_G = L->l_G;
111 L->l_G = OL->l_G; 131 stack_init(L1, L); /* init stack */
112 OL->next->previous = L; /* insert L into linked list */ 132 setobj(gt(L1), gt(L)); /* share table of globals */
113 L->next = OL->next; 133 return L1;
114 OL->next = L;
115 L->previous = OL;
116 stack_init(L, OL); /* init stack */
117 setobj(gt(L), gt(OL)); /* share table of globals */
118 lua_unlock(OL);
119 lua_userstateopen(L);
120 return L;
121} 134}
122 135
123 136
124LUA_API lua_State *lua_open (void) { 137LUA_API lua_State *lua_open (void) {
125 lua_State *L; 138 lua_State *L = newthread(NULL);
126 L = luaM_new(NULL, lua_State);
127 if (L) { /* allocation OK? */ 139 if (L) { /* allocation OK? */
128 preinit_state(L); 140 preinit_state(L);
129 L->l_G = NULL; 141 L->l_G = NULL;
130 L->next = L->previous = L;
131 if (luaD_rawrunprotected(L, f_luaopen, NULL) != 0) { 142 if (luaD_rawrunprotected(L, f_luaopen, NULL) != 0) {
132 /* memory allocation error: free partial state */ 143 /* memory allocation error: free partial state */
133 close_state(L); 144 close_state(L);
@@ -139,14 +150,13 @@ LUA_API lua_State *lua_open (void) {
139} 150}
140 151
141 152
142void luaE_closethread (lua_State *OL, lua_State *L) { 153void luaE_freethread (lua_State *L, lua_State *L1) {
143 luaF_close(L, L->stack); /* close all upvalues for this thread */ 154 luaF_close(L1, L1->stack); /* close all upvalues for this thread */
144 lua_assert(L->openupval == NULL); 155 lua_assert(L1->openupval == NULL);
145 L->previous->next = L->next; 156 luaM_freearray(L, L1->base_ci, L1->size_ci, CallInfo);
146 L->next->previous = L->previous; 157 luaM_freearray(L, L1->stack, L1->stacksize, TObject);
147 luaM_freearray(OL, L->base_ci, L->size_ci, CallInfo); 158 luaM_free(L, cast(lu_byte *, L1) - EXTRASPACE,
148 luaM_freearray(OL, L->stack, L->stacksize, TObject); 159 sizeof(lua_State) + EXTRASPACE);
149 luaM_freelem(OL, L);
150} 160}
151 161
152 162
@@ -160,24 +170,15 @@ static void close_state (lua_State *L) {
160 luaZ_freebuffer(L, &G(L)->buff); 170 luaZ_freebuffer(L, &G(L)->buff);
161 luaM_freelem(NULL, L->l_G); 171 luaM_freelem(NULL, L->l_G);
162 } 172 }
163 luaE_closethread(NULL, L); 173 luaE_freethread(NULL, L);
164}
165
166
167LUA_API void lua_closethread (lua_State *L, lua_State *thread) {
168 lua_lock(L);
169 if (L == thread) luaG_runerror(L, "cannot close only thread of a state");
170 luaE_closethread(L, thread);
171 lua_unlock(L);
172} 174}
173 175
174 176
175LUA_API void lua_close (lua_State *L) { 177LUA_API void lua_close (lua_State *L) {
176 lua_lock(L); 178 lua_lock(L);
179 L = G(L)->mainthread; /* only the main thread can be closed */
177 luaC_callallgcTM(L); /* call GC tag methods for all udata */ 180 luaC_callallgcTM(L); /* call GC tag methods for all udata */
178 lua_assert(G(L)->tmudata == NULL); 181 lua_assert(G(L)->tmudata == NULL);
179 while (L->next != L) /* then, close all other threads */
180 luaE_closethread(L, L->next);
181 close_state(L); 182 close_state(L);
182} 183}
183 184