aboutsummaryrefslogtreecommitdiff
path: root/ldo.c
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 /ldo.c
parent0050d983fc2f3cc56442cadd73a93823643ac53d (diff)
downloadlua-2d2d45976ce41de04e9007c8a78a8ba244d1fdc5.tar.gz
lua-2d2d45976ce41de04e9007c8a78a8ba244d1fdc5.tar.bz2
lua-2d2d45976ce41de04e9007c8a78a8ba244d1fdc5.zip
separated control over C recursion level
Diffstat (limited to 'ldo.c')
-rw-r--r--ldo.c31
1 files changed, 19 insertions, 12 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;