diff options
Diffstat (limited to 'ldo.c')
-rw-r--r-- | ldo.c | 30 |
1 files changed, 19 insertions, 11 deletions
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: ldo.c,v 2.38 2006/06/05 19:36:14 roberto Exp roberto $ | 2 | ** $Id: ldo.c,v 2.39 2006/07/11 15:53: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 | */ |
@@ -83,7 +83,6 @@ static void resetstack (lua_State *L, int status) { | |||
83 | L->base = L->ci->base; | 83 | L->base = L->ci->base; |
84 | luaF_close(L, L->base); /* close possible pending closures */ | 84 | luaF_close(L, L->base); /* close possible pending closures */ |
85 | luaD_seterrorobj(L, status, L->base); | 85 | luaD_seterrorobj(L, status, L->base); |
86 | L->nCcalls = 0; | ||
87 | L->allowhook = 1; | 86 | L->allowhook = 1; |
88 | restore_stack_limit(L); | 87 | restore_stack_limit(L); |
89 | L->errfunc = 0; | 88 | L->errfunc = 0; |
@@ -109,6 +108,7 @@ void luaD_throw (lua_State *L, int errcode) { | |||
109 | 108 | ||
110 | 109 | ||
111 | int luaD_rawrunprotected (lua_State *L, Pfunc f, void *ud) { | 110 | int luaD_rawrunprotected (lua_State *L, Pfunc f, void *ud) { |
111 | unsigned short oldnCcalls = G(L)->nCcalls; | ||
112 | struct lua_longjmp lj; | 112 | struct lua_longjmp lj; |
113 | lj.status = 0; | 113 | lj.status = 0; |
114 | lj.previous = L->errorJmp; /* chain new error handler */ | 114 | lj.previous = L->errorJmp; /* chain new error handler */ |
@@ -117,6 +117,7 @@ int luaD_rawrunprotected (lua_State *L, Pfunc f, void *ud) { | |||
117 | (*f)(L, ud); | 117 | (*f)(L, ud); |
118 | ); | 118 | ); |
119 | L->errorJmp = lj.previous; /* restore old error handler */ | 119 | L->errorJmp = lj.previous; /* restore old error handler */ |
120 | G(L)->nCcalls = oldnCcalls; | ||
120 | return lj.status; | 121 | return lj.status; |
121 | } | 122 | } |
122 | 123 | ||
@@ -369,15 +370,17 @@ int luaD_poscall (lua_State *L, StkId firstResult) { | |||
369 | ** function position. | 370 | ** function position. |
370 | */ | 371 | */ |
371 | void luaD_call (lua_State *L, StkId func, int nResults) { | 372 | void luaD_call (lua_State *L, StkId func, int nResults) { |
372 | if (++L->nCcalls >= LUAI_MAXCCALLS) { | 373 | global_State *g = G(L); |
373 | if (L->nCcalls == LUAI_MAXCCALLS) | 374 | lua_assert(g->nCcalls >= L->baseCcalls); |
375 | if (++g->nCcalls >= LUAI_MAXCCALLS) { | ||
376 | if (g->nCcalls == LUAI_MAXCCALLS) | ||
374 | luaG_runerror(L, "C stack overflow"); | 377 | luaG_runerror(L, "C stack overflow"); |
375 | else if (L->nCcalls >= (LUAI_MAXCCALLS + (LUAI_MAXCCALLS>>3))) | 378 | else if (g->nCcalls >= (LUAI_MAXCCALLS + (LUAI_MAXCCALLS>>3))) |
376 | luaD_throw(L, LUA_ERRERR); /* error while handing stack error */ | 379 | luaD_throw(L, LUA_ERRERR); /* error while handing stack error */ |
377 | } | 380 | } |
378 | if (luaD_precall(L, func, nResults) == PCRLUA) /* is a Lua function? */ | 381 | if (luaD_precall(L, func, nResults) == PCRLUA) /* is a Lua function? */ |
379 | luaV_execute(L, 1); /* call it */ | 382 | luaV_execute(L, 1); /* call it */ |
380 | L->nCcalls--; | 383 | g->nCcalls--; |
381 | luaC_checkGC(L); | 384 | luaC_checkGC(L); |
382 | } | 385 | } |
383 | 386 | ||
@@ -426,15 +429,22 @@ LUA_API int lua_resume (lua_State *L, int nargs) { | |||
426 | return resume_error(L, "cannot resume non-suspended coroutine"); | 429 | return resume_error(L, "cannot resume non-suspended coroutine"); |
427 | } | 430 | } |
428 | luai_userstateresume(L, nargs); | 431 | luai_userstateresume(L, nargs); |
429 | lua_assert(L->errfunc == 0 && L->nCcalls == 0); | 432 | lua_assert(L->errfunc == 0 && L->baseCcalls == 0); |
433 | if (G(L)->nCcalls >= LUAI_MAXCCALLS) | ||
434 | return resume_error(L, "C stack overflow"); | ||
435 | L->baseCcalls = ++G(L)->nCcalls; | ||
430 | status = luaD_rawrunprotected(L, resume, L->top - nargs); | 436 | status = luaD_rawrunprotected(L, resume, L->top - nargs); |
431 | if (status != 0) { /* error? */ | 437 | if (status != 0) { /* error? */ |
432 | L->status = cast_byte(status); /* mark thread as `dead' */ | 438 | L->status = cast_byte(status); /* mark thread as `dead' */ |
433 | luaD_seterrorobj(L, status, L->top); | 439 | luaD_seterrorobj(L, status, L->top); |
434 | L->ci->top = L->top; | 440 | L->ci->top = L->top; |
435 | } | 441 | } |
436 | else | 442 | else { |
443 | lua_assert(L->baseCcalls == G(L)->nCcalls); | ||
437 | status = L->status; | 444 | status = L->status; |
445 | } | ||
446 | --G(L)->nCcalls; | ||
447 | L->baseCcalls = 0; | ||
438 | lua_unlock(L); | 448 | lua_unlock(L); |
439 | return status; | 449 | return status; |
440 | } | 450 | } |
@@ -443,7 +453,7 @@ LUA_API int lua_resume (lua_State *L, int nargs) { | |||
443 | LUA_API int lua_yield (lua_State *L, int nresults) { | 453 | LUA_API int lua_yield (lua_State *L, int nresults) { |
444 | luai_userstateyield(L, nresults); | 454 | luai_userstateyield(L, nresults); |
445 | lua_lock(L); | 455 | lua_lock(L); |
446 | if (L->nCcalls > 0) | 456 | if (G(L)->nCcalls > L->baseCcalls) |
447 | luaG_runerror(L, "attempt to yield across metamethod/C-call boundary"); | 457 | luaG_runerror(L, "attempt to yield across metamethod/C-call boundary"); |
448 | L->base = L->top - nresults; /* protect stack slots below */ | 458 | L->base = L->top - nresults; /* protect stack slots below */ |
449 | L->status = LUA_YIELD; | 459 | L->status = LUA_YIELD; |
@@ -455,7 +465,6 @@ LUA_API int lua_yield (lua_State *L, int nresults) { | |||
455 | int luaD_pcall (lua_State *L, Pfunc func, void *u, | 465 | int luaD_pcall (lua_State *L, Pfunc func, void *u, |
456 | ptrdiff_t old_top, ptrdiff_t ef) { | 466 | ptrdiff_t old_top, ptrdiff_t ef) { |
457 | int status; | 467 | int status; |
458 | unsigned short oldnCcalls = L->nCcalls; | ||
459 | ptrdiff_t old_ci = saveci(L, L->ci); | 468 | ptrdiff_t old_ci = saveci(L, L->ci); |
460 | lu_byte old_allowhooks = L->allowhook; | 469 | lu_byte old_allowhooks = L->allowhook; |
461 | ptrdiff_t old_errfunc = L->errfunc; | 470 | ptrdiff_t old_errfunc = L->errfunc; |
@@ -465,7 +474,6 @@ int luaD_pcall (lua_State *L, Pfunc func, void *u, | |||
465 | StkId oldtop = restorestack(L, old_top); | 474 | StkId oldtop = restorestack(L, old_top); |
466 | luaF_close(L, oldtop); /* close possible pending closures */ | 475 | luaF_close(L, oldtop); /* close possible pending closures */ |
467 | luaD_seterrorobj(L, status, oldtop); | 476 | luaD_seterrorobj(L, status, oldtop); |
468 | L->nCcalls = oldnCcalls; | ||
469 | L->ci = restoreci(L, old_ci); | 477 | L->ci = restoreci(L, old_ci); |
470 | L->base = L->ci->base; | 478 | L->base = L->ci->base; |
471 | L->savedpc = L->ci->savedpc; | 479 | L->savedpc = L->ci->savedpc; |