aboutsummaryrefslogtreecommitdiff
path: root/src/lua/lstate.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/lua/lstate.c')
-rw-r--r--src/lua/lstate.c96
1 files changed, 30 insertions, 66 deletions
diff --git a/src/lua/lstate.c b/src/lua/lstate.c
index 86b3761..4227429 100644
--- a/src/lua/lstate.c
+++ b/src/lua/lstate.c
@@ -76,7 +76,7 @@ static unsigned int luai_makeseed (lua_State *L) {
76 addbuff(buff, p, &h); /* local variable */ 76 addbuff(buff, p, &h); /* local variable */
77 addbuff(buff, p, &lua_newstate); /* public function */ 77 addbuff(buff, p, &lua_newstate); /* public function */
78 lua_assert(p == sizeof(buff)); 78 lua_assert(p == sizeof(buff));
79 return luaS_hash(buff, p, h, 1); 79 return luaS_hash(buff, p, h);
80} 80}
81 81
82#endif 82#endif
@@ -97,66 +97,14 @@ void luaE_setdebt (global_State *g, l_mem debt) {
97 97
98 98
99LUA_API int lua_setcstacklimit (lua_State *L, unsigned int limit) { 99LUA_API int lua_setcstacklimit (lua_State *L, unsigned int limit) {
100 global_State *g = G(L); 100 UNUSED(L); UNUSED(limit);
101 int ccalls; 101 return LUAI_MAXCCALLS; /* warning?? */
102 luaE_freeCI(L); /* release unused CIs */
103 ccalls = getCcalls(L);
104 if (limit >= 40000)
105 return 0; /* out of bounds */
106 limit += CSTACKERR;
107 if (L != g-> mainthread)
108 return 0; /* only main thread can change the C stack */
109 else if (ccalls <= CSTACKERR)
110 return 0; /* handling overflow */
111 else {
112 int diff = limit - g->Cstacklimit;
113 if (ccalls + diff <= CSTACKERR)
114 return 0; /* new limit would cause an overflow */
115 g->Cstacklimit = limit; /* set new limit */
116 L->nCcalls += diff; /* correct 'nCcalls' */
117 return limit - diff - CSTACKERR; /* success; return previous limit */
118 }
119}
120
121
122/*
123** Decrement count of "C calls" and check for overflows. In case of
124** a stack overflow, check appropriate error ("regular" overflow or
125** overflow while handling stack overflow). If 'nCcalls' is smaller
126** than CSTACKERR but larger than CSTACKMARK, it means it has just
127** entered the "overflow zone", so the function raises an overflow
128** error. If 'nCcalls' is smaller than CSTACKMARK (which means it is
129** already handling an overflow) but larger than CSTACKERRMARK, does
130** not report an error (to allow message handling to work). Otherwise,
131** report a stack overflow while handling a stack overflow (probably
132** caused by a repeating error in the message handling function).
133*/
134
135void luaE_enterCcall (lua_State *L) {
136 int ncalls = getCcalls(L);
137 L->nCcalls--;
138 if (ncalls <= CSTACKERR) { /* possible overflow? */
139 luaE_freeCI(L); /* release unused CIs */
140 ncalls = getCcalls(L); /* update call count */
141 if (ncalls <= CSTACKERR) { /* still overflow? */
142 if (ncalls <= CSTACKERRMARK) /* below error-handling zone? */
143 luaD_throw(L, LUA_ERRERR); /* error while handling stack error */
144 else if (ncalls >= CSTACKMARK) {
145 /* not in error-handling zone; raise the error now */
146 L->nCcalls = (CSTACKMARK - 1); /* enter error-handling zone */
147 luaG_runerror(L, "C stack overflow");
148 }
149 /* else stack is in the error-handling zone;
150 allow message handler to work */
151 }
152 }
153} 102}
154 103
155 104
156CallInfo *luaE_extendCI (lua_State *L) { 105CallInfo *luaE_extendCI (lua_State *L) {
157 CallInfo *ci; 106 CallInfo *ci;
158 lua_assert(L->ci->next == NULL); 107 lua_assert(L->ci->next == NULL);
159 luaE_enterCcall(L);
160 ci = luaM_new(L, CallInfo); 108 ci = luaM_new(L, CallInfo);
161 lua_assert(L->ci->next == NULL); 109 lua_assert(L->ci->next == NULL);
162 L->ci->next = ci; 110 L->ci->next = ci;
@@ -175,13 +123,11 @@ void luaE_freeCI (lua_State *L) {
175 CallInfo *ci = L->ci; 123 CallInfo *ci = L->ci;
176 CallInfo *next = ci->next; 124 CallInfo *next = ci->next;
177 ci->next = NULL; 125 ci->next = NULL;
178 L->nCcalls += L->nci; /* add removed elements back to 'nCcalls' */
179 while ((ci = next) != NULL) { 126 while ((ci = next) != NULL) {
180 next = ci->next; 127 next = ci->next;
181 luaM_free(L, ci); 128 luaM_free(L, ci);
182 L->nci--; 129 L->nci--;
183 } 130 }
184 L->nCcalls -= L->nci; /* adjust result */
185} 131}
186 132
187 133
@@ -194,7 +140,6 @@ void luaE_shrinkCI (lua_State *L) {
194 CallInfo *next; 140 CallInfo *next;
195 if (ci == NULL) 141 if (ci == NULL)
196 return; /* no extra elements */ 142 return; /* no extra elements */
197 L->nCcalls += L->nci; /* add removed elements back to 'nCcalls' */
198 while ((next = ci->next) != NULL) { /* two extra elements? */ 143 while ((next = ci->next) != NULL) { /* two extra elements? */
199 CallInfo *next2 = next->next; /* next's next */ 144 CallInfo *next2 = next->next; /* next's next */
200 ci->next = next2; /* remove next from the list */ 145 ci->next = next2; /* remove next from the list */
@@ -207,19 +152,39 @@ void luaE_shrinkCI (lua_State *L) {
207 ci = next2; /* continue */ 152 ci = next2; /* continue */
208 } 153 }
209 } 154 }
210 L->nCcalls -= L->nci; /* adjust result */ 155}
156
157
158/*
159** Called when 'getCcalls(L)' larger or equal to LUAI_MAXCCALLS.
160** If equal, raises an overflow error. If value is larger than
161** LUAI_MAXCCALLS (which means it is handling an overflow) but
162** not much larger, does not report an error (to allow overflow
163** handling to work).
164*/
165void luaE_checkcstack (lua_State *L) {
166 if (getCcalls(L) == LUAI_MAXCCALLS)
167 luaG_runerror(L, "C stack overflow");
168 else if (getCcalls(L) >= (LUAI_MAXCCALLS / 10 * 11))
169 luaD_throw(L, LUA_ERRERR); /* error while handing stack error */
170}
171
172
173LUAI_FUNC void luaE_incCstack (lua_State *L) {
174 L->nCcalls++;
175 if (unlikely(getCcalls(L) >= LUAI_MAXCCALLS))
176 luaE_checkcstack(L);
211} 177}
212 178
213 179
214static void stack_init (lua_State *L1, lua_State *L) { 180static void stack_init (lua_State *L1, lua_State *L) {
215 int i; CallInfo *ci; 181 int i; CallInfo *ci;
216 /* initialize stack array */ 182 /* initialize stack array */
217 L1->stack = luaM_newvector(L, BASIC_STACK_SIZE, StackValue); 183 L1->stack = luaM_newvector(L, BASIC_STACK_SIZE + EXTRA_STACK, StackValue);
218 L1->stacksize = BASIC_STACK_SIZE;
219 for (i = 0; i < BASIC_STACK_SIZE; i++) 184 for (i = 0; i < BASIC_STACK_SIZE; i++)
220 setnilvalue(s2v(L1->stack + i)); /* erase new stack */ 185 setnilvalue(s2v(L1->stack + i)); /* erase new stack */
221 L1->top = L1->stack; 186 L1->top = L1->stack;
222 L1->stack_last = L1->stack + L1->stacksize - EXTRA_STACK; 187 L1->stack_last = L1->stack + BASIC_STACK_SIZE;
223 /* initialize first ci */ 188 /* initialize first ci */
224 ci = &L1->base_ci; 189 ci = &L1->base_ci;
225 ci->next = ci->previous = NULL; 190 ci->next = ci->previous = NULL;
@@ -240,7 +205,7 @@ static void freestack (lua_State *L) {
240 L->ci = &L->base_ci; /* free the entire 'ci' list */ 205 L->ci = &L->base_ci; /* free the entire 'ci' list */
241 luaE_freeCI(L); 206 luaE_freeCI(L);
242 lua_assert(L->nci == 0); 207 lua_assert(L->nci == 0);
243 luaM_freearray(L, L->stack, L->stacksize); /* free stack array */ 208 luaM_freearray(L, L->stack, stacksize(L) + EXTRA_STACK); /* free stack */
244} 209}
245 210
246 211
@@ -290,7 +255,6 @@ static void preinit_thread (lua_State *L, global_State *g) {
290 L->stack = NULL; 255 L->stack = NULL;
291 L->ci = NULL; 256 L->ci = NULL;
292 L->nci = 0; 257 L->nci = 0;
293 L->stacksize = 0;
294 L->twups = L; /* thread has no upvalues */ 258 L->twups = L; /* thread has no upvalues */
295 L->errorJmp = NULL; 259 L->errorJmp = NULL;
296 L->hook = NULL; 260 L->hook = NULL;
@@ -335,7 +299,7 @@ LUA_API lua_State *lua_newthread (lua_State *L) {
335 setthvalue2s(L, L->top, L1); 299 setthvalue2s(L, L->top, L1);
336 api_incr_top(L); 300 api_incr_top(L);
337 preinit_thread(L1, g); 301 preinit_thread(L1, g);
338 L1->nCcalls = getCcalls(L); 302 L1->nCcalls = 0;
339 L1->hookmask = L->hookmask; 303 L1->hookmask = L->hookmask;
340 L1->basehookcount = L->basehookcount; 304 L1->basehookcount = L->basehookcount;
341 L1->hook = L->hook; 305 L1->hook = L->hook;
@@ -396,7 +360,7 @@ LUA_API lua_State *lua_newstate (lua_Alloc f, void *ud) {
396 preinit_thread(L, g); 360 preinit_thread(L, g);
397 g->allgc = obj2gco(L); /* by now, only object is the main thread */ 361 g->allgc = obj2gco(L); /* by now, only object is the main thread */
398 L->next = NULL; 362 L->next = NULL;
399 g->Cstacklimit = L->nCcalls = LUAI_MAXCSTACK + CSTACKERR; 363 L->nCcalls = 0;
400 incnny(L); /* main thread is always non yieldable */ 364 incnny(L); /* main thread is always non yieldable */
401 g->frealloc = f; 365 g->frealloc = f;
402 g->ud = ud; 366 g->ud = ud;