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 /ldo.c | |
| parent | 0050d983fc2f3cc56442cadd73a93823643ac53d (diff) | |
| download | lua-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.c | 31 |
1 files changed, 19 insertions, 12 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; |
