aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>2002-11-22 15:16:52 -0200
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>2002-11-22 15:16:52 -0200
commit2d2d45976ce41de04e9007c8a78a8ba244d1fdc5 (patch)
tree0573761b205be9aa1471364159e559a2d5e80f9e
parent0050d983fc2f3cc56442cadd73a93823643ac53d (diff)
downloadlua-2d2d45976ce41de04e9007c8a78a8ba244d1fdc5.tar.gz
lua-2d2d45976ce41de04e9007c8a78a8ba244d1fdc5.tar.bz2
lua-2d2d45976ce41de04e9007c8a78a8ba244d1fdc5.zip
separated control over C recursion level
-rw-r--r--ldo.c31
-rw-r--r--llimits.h19
-rw-r--r--lstate.c3
-rw-r--r--lstate.h5
4 files changed, 40 insertions, 18 deletions
diff --git a/ldo.c b/ldo.c
index 45d820c7..84c244e6 100644
--- a/ldo.c
+++ b/ldo.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: ldo.c,v 1.206 2002/11/21 15:46:44 roberto Exp roberto $ 2** $Id: ldo.c,v 1.207 2002/11/21 17:19:11 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*/
@@ -126,7 +126,7 @@ void luaD_reallocstack (lua_State *L, int newsize) {
126void luaD_reallocCI (lua_State *L, int newsize) { 126void luaD_reallocCI (lua_State *L, int newsize) {
127 CallInfo *oldci = L->base_ci; 127 CallInfo *oldci = L->base_ci;
128 luaM_reallocvector(L, L->base_ci, L->size_ci, newsize, CallInfo); 128 luaM_reallocvector(L, L->base_ci, L->size_ci, newsize, CallInfo);
129 L->size_ci = newsize; 129 L->size_ci = cast(unsigned short, newsize);
130 L->ci = (L->ci - oldci) + L->base_ci; 130 L->ci = (L->ci - oldci) + L->base_ci;
131 L->end_ci = L->base_ci + L->size_ci; 131 L->end_ci = L->base_ci + L->size_ci;
132} 132}
@@ -288,15 +288,18 @@ void luaD_poscall (lua_State *L, int wanted, StkId firstResult) {
288** function position. 288** function position.
289*/ 289*/
290void luaD_call (lua_State *L, StkId func, int nResults) { 290void luaD_call (lua_State *L, StkId func, int nResults) {
291 StkId firstResult = luaD_precall(L, func); 291 StkId firstResult;
292 if (firstResult == NULL) { /* is a Lua function? */ 292 if (++L->nCcalls >= LUA_MAXCCALLS) {
293 firstResult = luaV_execute(L); /* call it */ 293 if (L->nCcalls == LUA_MAXCCALLS)
294 if (firstResult == NULL) { 294 luaG_runerror(L, "stack overflow");
295 luaD_poscall(L, 0, L->top); 295 else if (L->nCcalls >= (LUA_MAXCCALLS + (LUA_MAXCCALLS>>3)))
296 luaG_runerror(L, "attempt to yield across tag-method/C-call boundary"); 296 luaD_throw(L, LUA_ERRERR); /* error while handing stack error */
297 }
298 } 297 }
298 firstResult = luaD_precall(L, func);
299 if (firstResult == NULL) /* is a Lua function? */
300 firstResult = luaV_execute(L); /* call it */
299 luaD_poscall(L, nResults, firstResult); 301 luaD_poscall(L, nResults, firstResult);
302 L->nCcalls--;
300} 303}
301 304
302 305
@@ -337,11 +340,12 @@ LUA_API int lua_resume (lua_State *L, int nargs) {
337 lu_byte old_allowhooks; 340 lu_byte old_allowhooks;
338 lua_lock(L); 341 lua_lock(L);
339 old_allowhooks = L->allowhook; 342 old_allowhooks = L->allowhook;
340 lua_assert(L->errfunc == 0); 343 lua_assert(L->errfunc == 0 && L->nCcalls == 0);
341 status = luaD_rawrunprotected(L, resume, &nargs); 344 status = luaD_rawrunprotected(L, resume, &nargs);
342 if (status != 0) { /* error? */ 345 if (status != 0) { /* error? */
343 L->ci = L->base_ci; /* go back to initial level */ 346 L->ci = L->base_ci; /* go back to initial level */
344 L->base = L->ci->base; 347 L->base = L->ci->base;
348 L->nCcalls = 0;
345 luaF_close(L, L->base); /* close eventual pending closures */ 349 luaF_close(L, L->base); /* close eventual pending closures */
346 seterrorobj(L, status, L->base); 350 seterrorobj(L, status, L->base);
347 L->allowhook = old_allowhooks; 351 L->allowhook = old_allowhooks;
@@ -356,6 +360,8 @@ LUA_API int lua_yield (lua_State *L, int nresults) {
356 CallInfo *ci; 360 CallInfo *ci;
357 lua_lock(L); 361 lua_lock(L);
358 ci = L->ci; 362 ci = L->ci;
363 if (L->nCcalls > 0)
364 luaG_runerror(L, "attempt to yield across metamethod/C-call boundary");
359 if (ci->state & CI_C) { /* usual yield */ 365 if (ci->state & CI_C) { /* usual yield */
360 if ((ci-1)->state & CI_C) 366 if ((ci-1)->state & CI_C)
361 luaG_runerror(L, "cannot yield a C function"); 367 luaG_runerror(L, "cannot yield a C function");
@@ -365,8 +371,7 @@ LUA_API int lua_yield (lua_State *L, int nresults) {
365 setobjs2s(L->base + i, L->top - nresults + i); 371 setobjs2s(L->base + i, L->top - nresults + i);
366 L->top = L->base + nresults; 372 L->top = L->base + nresults;
367 } 373 }
368 } 374 } /* else it's an yield inside a hook: nothing to do */
369 /* else it's an yield inside a hook: nothing to do */
370 ci->state |= CI_YIELD; 375 ci->state |= CI_YIELD;
371 lua_unlock(L); 376 lua_unlock(L);
372 return -1; 377 return -1;
@@ -391,6 +396,7 @@ static void f_call (lua_State *L, void *ud) {
391int luaD_pcall (lua_State *L, int nargs, int nresults, ptrdiff_t errfunc) { 396int luaD_pcall (lua_State *L, int nargs, int nresults, ptrdiff_t errfunc) {
392 struct CallS c; 397 struct CallS c;
393 int status; 398 int status;
399 unsigned short oldnCcalls = L->nCcalls;
394 ptrdiff_t old_top = savestack(L, L->top); 400 ptrdiff_t old_top = savestack(L, L->top);
395 ptrdiff_t old_ci = saveci(L, L->ci); 401 ptrdiff_t old_ci = saveci(L, L->ci);
396 lu_byte old_allowhooks = L->allowhook; 402 lu_byte old_allowhooks = L->allowhook;
@@ -403,6 +409,7 @@ int luaD_pcall (lua_State *L, int nargs, int nresults, ptrdiff_t errfunc) {
403 StkId oldtop = restorestack(L, old_top) - (nargs+1); 409 StkId oldtop = restorestack(L, old_top) - (nargs+1);
404 luaF_close(L, oldtop); /* close eventual pending closures */ 410 luaF_close(L, oldtop); /* close eventual pending closures */
405 seterrorobj(L, status, oldtop); 411 seterrorobj(L, status, oldtop);
412 L->nCcalls = oldnCcalls;
406 L->ci = restoreci(L, old_ci); 413 L->ci = restoreci(L, old_ci);
407 L->base = L->ci->base; 414 L->base = L->ci->base;
408 L->allowhook = old_allowhooks; 415 L->allowhook = old_allowhooks;
diff --git a/llimits.h b/llimits.h
index c14e0203..1e6171f3 100644
--- a/llimits.h
+++ b/llimits.h
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: llimits.h,v 1.47 2002/10/22 17:18:28 roberto Exp roberto $ 2** $Id: llimits.h,v 1.48 2002/11/22 16:35:20 roberto Exp roberto $
3** Limits, basic types, and some other `installation-dependent' definitions 3** Limits, basic types, and some other `installation-dependent' definitions
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -119,12 +119,22 @@ typedef LUA_UACNUMBER l_uacNumber;
119typedef unsigned long Instruction; 119typedef unsigned long Instruction;
120 120
121 121
122/* maximum depth for calls */ 122/* maximum depth for calls (unsigned short) */
123#ifndef LUA_MAXCALLS 123#ifndef LUA_MAXCALLS
124#define LUA_MAXCALLS 4096 124#define LUA_MAXCALLS 4096
125#endif 125#endif
126 126
127 127
128/*
129** maximum depth for C calls (unsigned short): Not too big, or may
130** overflow the C stack...
131*/
132
133#ifndef LUA_MAXCCALLS
134#define LUA_MAXCCALLS 200
135#endif
136
137
128/* maximum size for the C stack */ 138/* maximum size for the C stack */
129#ifndef LUA_MAXCSTACK 139#ifndef LUA_MAXCSTACK
130#define LUA_MAXCSTACK 2048 140#define LUA_MAXCSTACK 2048
@@ -165,7 +175,10 @@ typedef unsigned long Instruction;
165#endif 175#endif
166 176
167 177
168/* maximum number of syntactical nested non-terminals */ 178/*
179** maximum number of syntactical nested non-terminals: Not too big,
180** or may overflow the C stack...
181*/
169#ifndef LUA_MAXPARSERLEVEL 182#ifndef LUA_MAXPARSERLEVEL
170#define LUA_MAXPARSERLEVEL 200 183#define LUA_MAXPARSERLEVEL 200
171#endif 184#endif
diff --git a/lstate.c b/lstate.c
index 5257c3e2..988ae13c 100644
--- a/lstate.c
+++ b/lstate.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lstate.c,v 1.114 2002/11/21 14:14:42 roberto Exp roberto $ 2** $Id: lstate.c,v 1.115 2002/11/21 15:16:04 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*/
@@ -130,6 +130,7 @@ static void preinit_state (lua_State *L) {
130 resethookcount(L); 130 resethookcount(L);
131 L->openupval = NULL; 131 L->openupval = NULL;
132 L->size_ci = 0; 132 L->size_ci = 0;
133 L->nCcalls = 0;
133 L->base_ci = L->ci = NULL; 134 L->base_ci = L->ci = NULL;
134 L->errfunc = 0; 135 L->errfunc = 0;
135 setnilvalue(gt(L)); 136 setnilvalue(gt(L));
diff --git a/lstate.h b/lstate.h
index 507de477..770c16ca 100644
--- a/lstate.h
+++ b/lstate.h
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lstate.h,v 1.104 2002/11/21 15:16:04 roberto Exp roberto $ 2** $Id: lstate.h,v 1.105 2002/11/21 15:46:44 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*/
@@ -138,7 +138,8 @@ struct lua_State {
138 int stacksize; 138 int stacksize;
139 CallInfo *end_ci; /* points after end of ci array*/ 139 CallInfo *end_ci; /* points after end of ci array*/
140 CallInfo *base_ci; /* array of CallInfo's */ 140 CallInfo *base_ci; /* array of CallInfo's */
141 int size_ci; /* size of array `base_ci' */ 141 unsigned short size_ci; /* size of array `base_ci' */
142 unsigned short nCcalls; /* number of nested C calls */
142 lu_byte hookmask; 143 lu_byte hookmask;
143 lu_byte allowhook; 144 lu_byte allowhook;
144 lu_byte hookinit; 145 lu_byte hookinit;