diff options
author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2002-11-22 15:16:52 -0200 |
---|---|---|
committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2002-11-22 15:16:52 -0200 |
commit | 2d2d45976ce41de04e9007c8a78a8ba244d1fdc5 (patch) | |
tree | 0573761b205be9aa1471364159e559a2d5e80f9e | |
parent | 0050d983fc2f3cc56442cadd73a93823643ac53d (diff) | |
download | lua-2d2d45976ce41de04e9007c8a78a8ba244d1fdc5.tar.gz lua-2d2d45976ce41de04e9007c8a78a8ba244d1fdc5.tar.bz2 lua-2d2d45976ce41de04e9007c8a78a8ba244d1fdc5.zip |
separated control over C recursion level
-rw-r--r-- | ldo.c | 31 | ||||
-rw-r--r-- | llimits.h | 19 | ||||
-rw-r--r-- | lstate.c | 3 | ||||
-rw-r--r-- | lstate.h | 5 |
4 files changed, 40 insertions, 18 deletions
@@ -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) { | |||
126 | void luaD_reallocCI (lua_State *L, int newsize) { | 126 | void 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 | */ |
290 | void luaD_call (lua_State *L, StkId func, int nResults) { | 290 | void 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) { | |||
391 | int luaD_pcall (lua_State *L, int nargs, int nresults, ptrdiff_t errfunc) { | 396 | int 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; |
@@ -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; | |||
119 | typedef unsigned long Instruction; | 119 | typedef 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 |
@@ -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)); |
@@ -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; |