aboutsummaryrefslogtreecommitdiff
path: root/ldo.c
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>1999-12-06 09:43:58 -0200
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>1999-12-06 09:43:58 -0200
commitf356eb010b6785cf22e8d5f1d4f7761e0789ae51 (patch)
tree0afc8ffc0f1e7337ce995e4d7bc78c92fb938329 /ldo.c
parent3e38fd24639bc7cd8afe063619d5ab4637db696f (diff)
downloadlua-f356eb010b6785cf22e8d5f1d4f7761e0789ae51.tar.gz
lua-f356eb010b6785cf22e8d5f1d4f7761e0789ae51.tar.bz2
lua-f356eb010b6785cf22e8d5f1d4f7761e0789ae51.zip
configurable stack size + some corrections in error recovery in
`protectedrun'
Diffstat (limited to 'ldo.c')
-rw-r--r--ldo.c59
1 files changed, 27 insertions, 32 deletions
diff --git a/ldo.c b/ldo.c
index 8e39ce3b..71e19e0f 100644
--- a/ldo.c
+++ b/ldo.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: ldo.c,v 1.55 1999/12/02 16:24:45 roberto Exp roberto $ 2** $Id: ldo.c,v 1.56 1999/12/02 16:41:29 roberto Exp roberto $
3** Stack and Call structure of Lua 3** Stack and Call structure of Lua
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -28,23 +28,19 @@
28#include "lzio.h" 28#include "lzio.h"
29 29
30 30
31
32#ifndef DEFAULT_STACK_SIZE
33#define DEFAULT_STACK_SIZE 1024
34#endif
35
36#define EXTRA_STACK 32 /* space to handle stack overflow errors */ 31#define EXTRA_STACK 32 /* space to handle stack overflow errors */
37 32
38/* 33/*
39** typical numer of recursive calls that fit in the stack 34** typical numer of stack slots used by a (big) function
40** (only for error messages) 35** (this constant is used only for choosing error messages)
41*/ 36*/
42#define REC_DEEP (DEFAULT_STACK_SIZE/20) 37#define SLOTS_PER_F 20
43 38
44 39
45void luaD_init (lua_State *L) { 40void luaD_init (lua_State *L, int stacksize) {
46 L->stack = luaM_newvector(L, DEFAULT_STACK_SIZE+EXTRA_STACK, TObject); 41 L->stack = luaM_newvector(L, stacksize+EXTRA_STACK, TObject);
47 L->stack_last = L->stack+(DEFAULT_STACK_SIZE-1); 42 L->stack_last = L->stack+(stacksize-1);
43 L->stacksize = stacksize;
48 L->Cstack.base = L->Cstack.lua2C = L->top = L->stack; 44 L->Cstack.base = L->Cstack.lua2C = L->top = L->stack;
49 L->Cstack.num = 0; 45 L->Cstack.num = 0;
50} 46}
@@ -52,15 +48,15 @@ void luaD_init (lua_State *L) {
52 48
53void luaD_checkstack (lua_State *L, int n) { 49void luaD_checkstack (lua_State *L, int n) {
54 if (L->stack_last-L->top <= n) { /* stack overflow? */ 50 if (L->stack_last-L->top <= n) { /* stack overflow? */
55 if (L->stack_last-L->stack > (DEFAULT_STACK_SIZE-1)) { 51 if (L->stack_last-L->stack > (L->stacksize-1)) {
56 /* overflow while handling overflow: do what?? */ 52 /* overflow while handling overflow: do what?? */
57 L->top -= EXTRA_STACK; 53 L->top -= EXTRA_STACK;
58 lua_error(L, "BAD STACK OVERFLOW! DATA CORRUPTED!!"); 54 lua_error(L, "BAD STACK OVERFLOW! DATA CORRUPTED!!");
59 } 55 }
60 else { 56 else {
61 L->stack_last += EXTRA_STACK; /* to be used by error message */ 57 L->stack_last += EXTRA_STACK; /* to be used by error message */
62 if (lua_stackedfunction(L, REC_DEEP) == LUA_NOOBJECT) { 58 if (lua_stackedfunction(L, L->stacksize/SLOTS_PER_F) == LUA_NOOBJECT) {
63 /* less than REC_DEEP funcs on stack: doesn't look like a rec. loop */ 59 /* too few funcs on stack: doesn't look like a rec. loop */
64 lua_error(L, "Lua2C - C2Lua overflow"); 60 lua_error(L, "Lua2C - C2Lua overflow");
65 } 61 }
66 else 62 else
@@ -71,8 +67,8 @@ void luaD_checkstack (lua_State *L, int n) {
71 67
72 68
73static void restore_stack_limit (lua_State *L) { 69static void restore_stack_limit (lua_State *L) {
74 if (L->top-L->stack < DEFAULT_STACK_SIZE-1) 70 if (L->top-L->stack < L->stacksize-1)
75 L->stack_last = L->stack+(DEFAULT_STACK_SIZE-1); 71 L->stack_last = L->stack+(L->stacksize-1);
76} 72}
77 73
78 74
@@ -145,7 +141,7 @@ static StkId callC (lua_State *L, lua_CFunction f, StkId base) {
145 if (L->callhook) 141 if (L->callhook)
146 luaD_callHook(L, base, NULL, 0); 142 luaD_callHook(L, base, NULL, 0);
147 (*f)(L); /* do the actual call */ 143 (*f)(L); /* do the actual call */
148 if (L->callhook) /* test again: `func' may have changed callhook */ 144 if (L->callhook) /* test again: `func' may change callhook */
149 luaD_callHook(L, base, NULL, 1); 145 luaD_callHook(L, base, NULL, 1);
150 firstResult = L->Cstack.base; 146 firstResult = L->Cstack.base;
151 L->Cstack = oldCLS; 147 L->Cstack = oldCLS;
@@ -201,7 +197,7 @@ void luaD_call (lua_State *L, StkId func, int nResults) {
201 luaV_execute(L, c, tfvalue(proto), func+1); 197 luaV_execute(L, c, tfvalue(proto), func+1);
202 break; 198 break;
203 } 199 }
204 default: { /* func is not a function */ 200 default: { /* `func' is not a function */
205 /* Check the tag method for invalid functions */ 201 /* Check the tag method for invalid functions */
206 const TObject *im = luaT_getimbyObj(L, func, IM_FUNCTION); 202 const TObject *im = luaT_getimbyObj(L, func, IM_FUNCTION);
207 if (ttype(im) == LUA_T_NIL) 203 if (ttype(im) == LUA_T_NIL)
@@ -251,13 +247,12 @@ void lua_error (lua_State *L, const char *s) {
251** parameters are on top of it. Leave nResults on the stack. 247** parameters are on top of it. Leave nResults on the stack.
252*/ 248*/
253int luaD_protectedrun (lua_State *L) { 249int luaD_protectedrun (lua_State *L) {
254 volatile struct C_Lua_Stack oldCLS = L->Cstack;
255 struct lua_longjmp myErrorJmp; 250 struct lua_longjmp myErrorJmp;
251 volatile StkId base = L->Cstack.base;
256 volatile int status; 252 volatile int status;
257 struct lua_longjmp *volatile oldErr = L->errorJmp; 253 struct lua_longjmp *volatile oldErr = L->errorJmp;
258 L->errorJmp = &myErrorJmp; 254 L->errorJmp = &myErrorJmp;
259 if (setjmp(myErrorJmp.b) == 0) { 255 if (setjmp(myErrorJmp.b) == 0) {
260 StkId base = L->Cstack.base;
261 luaD_call(L, base, MULT_RET); 256 luaD_call(L, base, MULT_RET);
262 L->Cstack.lua2C = base; /* position of the new results */ 257 L->Cstack.lua2C = base; /* position of the new results */
263 L->Cstack.num = L->top - base; 258 L->Cstack.num = L->top - base;
@@ -265,8 +260,8 @@ int luaD_protectedrun (lua_State *L) {
265 status = 0; 260 status = 0;
266 } 261 }
267 else { /* an error occurred: restore the stack */ 262 else { /* an error occurred: restore the stack */
268 L->Cstack = oldCLS; 263 L->Cstack.num = 0; /* no results */
269 L->top = L->Cstack.base; 264 L->top = L->Cstack.base = L->Cstack.lua2C = base;
270 restore_stack_limit(L); 265 restore_stack_limit(L);
271 status = 1; 266 status = 1;
272 } 267 }
@@ -279,29 +274,29 @@ int luaD_protectedrun (lua_State *L) {
279** returns 0 = chunk loaded; 1 = error; 2 = no more chunks to load 274** returns 0 = chunk loaded; 1 = error; 2 = no more chunks to load
280*/ 275*/
281static int protectedparser (lua_State *L, ZIO *z, int bin) { 276static int protectedparser (lua_State *L, ZIO *z, int bin) {
282 volatile struct C_Lua_Stack oldCLS = L->Cstack;
283 struct lua_longjmp myErrorJmp; 277 struct lua_longjmp myErrorJmp;
278 volatile StkId base = L->Cstack.base;
284 volatile int status; 279 volatile int status;
285 TProtoFunc *volatile tf; 280 TProtoFunc *volatile tf;
286 struct lua_longjmp *volatile oldErr = L->errorJmp; 281 struct lua_longjmp *volatile oldErr = L->errorJmp;
287 L->errorJmp = &myErrorJmp; 282 L->errorJmp = &myErrorJmp;
283 L->top = base; /* erase C2Lua */
288 if (setjmp(myErrorJmp.b) == 0) { 284 if (setjmp(myErrorJmp.b) == 0) {
289 tf = bin ? luaU_undump1(L, z) : luaY_parser(L, z); 285 tf = bin ? luaU_undump1(L, z) : luaY_parser(L, z);
290 status = 0; 286 status = 0;
291 } 287 }
292 else { /* an error occurred: restore L->Cstack and L->top */ 288 else { /* an error occurred: restore Cstack and top */
293 L->Cstack = oldCLS; 289 L->Cstack.num = 0; /* no results */
294 L->top = L->Cstack.base; 290 L->top = L->Cstack.base = L->Cstack.lua2C = base;
295 tf = NULL; 291 tf = NULL;
296 status = 1; 292 status = 1;
297 } 293 }
298 L->errorJmp = oldErr; 294 L->errorJmp = oldErr;
299 if (status) return 1; /* error code */ 295 if (status) return 1; /* error code */
300 if (tf == NULL) return 2; /* `natural' end */ 296 if (tf == NULL) return 2; /* `natural' end */
301 luaD_adjusttop(L, L->Cstack.base, 1); /* one slot for the pseudo-function */ 297 L->top->ttype = LUA_T_PROTO; /* push new function on the stack */
302 L->Cstack.base->ttype = LUA_T_PROTO; 298 L->top->value.tf = tf;
303 L->Cstack.base->value.tf = tf; 299 incr_top;
304 luaV_closure(L, 0);
305 return 0; 300 return 0;
306} 301}
307 302
@@ -313,7 +308,7 @@ static int do_main (lua_State *L, ZIO *z, int bin) {
313 long old_blocks = (luaC_checkGC(L), L->nblocks); 308 long old_blocks = (luaC_checkGC(L), L->nblocks);
314 status = protectedparser(L, z, bin); 309 status = protectedparser(L, z, bin);
315 if (status == 1) return 1; /* error */ 310 if (status == 1) return 1; /* error */
316 else if (status == 2) return 0; /* 'natural' end */ 311 else if (status == 2) return 0; /* `natural' end */
317 else { 312 else {
318 unsigned long newelems2 = 2*(L->nblocks-old_blocks); 313 unsigned long newelems2 = 2*(L->nblocks-old_blocks);
319 L->GCthreshold += newelems2; 314 L->GCthreshold += newelems2;