aboutsummaryrefslogtreecommitdiff
path: root/ldo.c
diff options
context:
space:
mode:
Diffstat (limited to 'ldo.c')
-rw-r--r--ldo.c41
1 files changed, 21 insertions, 20 deletions
diff --git a/ldo.c b/ldo.c
index b41855c9..8adaefcd 100644
--- a/ldo.c
+++ b/ldo.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: ldo.c,v 2.117 2014/06/09 16:32:18 roberto Exp roberto $ 2** $Id: ldo.c,v 2.118 2014/06/10 17:41:38 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*/
@@ -416,7 +416,7 @@ void luaD_call (lua_State *L, StkId func, int nResults, int allowyield) {
416** Completes the execution of an interrupted C function, calling its 416** Completes the execution of an interrupted C function, calling its
417** continuation function. 417** continuation function.
418*/ 418*/
419static void finishCcall (lua_State *L) { 419static void finishCcall (lua_State *L, int status) {
420 CallInfo *ci = L->ci; 420 CallInfo *ci = L->ci;
421 int n; 421 int n;
422 lua_assert(ci->u.c.k != NULL); /* must have a continuation */ 422 lua_assert(ci->u.c.k != NULL); /* must have a continuation */
@@ -428,12 +428,9 @@ static void finishCcall (lua_State *L) {
428 /* finish 'lua_callk'/'lua_pcall' */ 428 /* finish 'lua_callk'/'lua_pcall' */
429 adjustresults(L, ci->nresults); 429 adjustresults(L, ci->nresults);
430 /* call continuation function */ 430 /* call continuation function */
431 if (!(ci->callstatus & CIST_STAT)) /* no call status? */ 431 ci->callstatus = (ci->callstatus & ~CIST_YPCALL) | CIST_YIELDED;
432 ci->u.c.status = LUA_YIELD; /* 'default' status */
433 lua_assert(ci->u.c.status != LUA_OK);
434 ci->callstatus = (ci->callstatus & ~(CIST_YPCALL | CIST_STAT)) | CIST_YIELDED;
435 lua_unlock(L); 432 lua_unlock(L);
436 n = (*ci->u.c.k)(L, ci->u.c.status, ci->u.c.ctx); 433 n = (*ci->u.c.k)(L, status, ci->u.c.ctx);
437 lua_lock(L); 434 lua_lock(L);
438 api_checknelems(L, n); 435 api_checknelems(L, n);
439 /* finish 'luaD_precall' */ 436 /* finish 'luaD_precall' */
@@ -444,13 +441,18 @@ static void finishCcall (lua_State *L) {
444/* 441/*
445** Executes "full continuation" (everything in the stack) of a 442** Executes "full continuation" (everything in the stack) of a
446** previously interrupted coroutine until the stack is empty (or another 443** previously interrupted coroutine until the stack is empty (or another
447** interruption long-jumps out of the loop) 444** interruption long-jumps out of the loop). If the coroutine is
445** recovering from an error, 'ud' points to the error status, which must
446** be passed to the first (only the first) continuation (otherwise the
447** default status is LUA_YIELD).
448*/ 448*/
449static void unroll (lua_State *L, void *ud) { 449static void unroll (lua_State *L, void *ud) {
450 UNUSED(ud); 450 int status = (ud) ? *(int *)ud : LUA_YIELD;
451 while (L->ci != &L->base_ci) { /* something in the stack */ 451 while (L->ci != &L->base_ci) { /* something in the stack */
452 if (!isLua(L->ci)) /* C function? */ 452 if (!isLua(L->ci)) { /* C function? */
453 finishCcall(L); /* complete its execution */ 453 finishCcall(L, status); /* complete its execution */
454 status = LUA_YIELD; /* back to default status */
455 }
454 else { /* Lua function */ 456 else { /* Lua function */
455 luaV_finishOp(L); /* finish interrupted instruction */ 457 luaV_finishOp(L); /* finish interrupted instruction */
456 luaV_execute(L); /* execute down to higher C 'boundary' */ 458 luaV_execute(L); /* execute down to higher C 'boundary' */
@@ -487,12 +489,10 @@ static int recover (lua_State *L, int status) {
487 luaF_close(L, oldtop); 489 luaF_close(L, oldtop);
488 seterrorobj(L, status, oldtop); 490 seterrorobj(L, status, oldtop);
489 L->ci = ci; 491 L->ci = ci;
490 L->allowhook = ci->u.c.old_allowhook; 492 L->allowhook = (ci->callstatus & CIST_OAH);
491 L->nny = 0; /* should be zero to be yieldable */ 493 L->nny = 0; /* should be zero to be yieldable */
492 luaD_shrinkstack(L); 494 luaD_shrinkstack(L);
493 L->errfunc = ci->u.c.old_errfunc; 495 L->errfunc = ci->u.c.old_errfunc;
494 ci->callstatus |= CIST_STAT; /* call has error status */
495 ci->u.c.status = status; /* (here it is) */
496 return 1; /* continue running the coroutine */ 496 return 1; /* continue running the coroutine */
497} 497}
498 498
@@ -536,10 +536,9 @@ static void resume (lua_State *L, void *ud) {
536 else { /* 'common' yield */ 536 else { /* 'common' yield */
537 if (ci->u.c.k != NULL) { /* does it have a continuation? */ 537 if (ci->u.c.k != NULL) { /* does it have a continuation? */
538 int n; 538 int n;
539 ci->u.c.status = LUA_YIELD; /* 'default' status */
540 ci->callstatus |= CIST_YIELDED; 539 ci->callstatus |= CIST_YIELDED;
541 lua_unlock(L); 540 lua_unlock(L);
542 n = (*ci->u.c.k)(L, ci->u.c.status, ci->u.c.ctx); /* call continuation */ 541 n = (*ci->u.c.k)(L, LUA_YIELD, ci->u.c.ctx); /* call continuation */
543 lua_lock(L); 542 lua_lock(L);
544 api_checknelems(L, n); 543 api_checknelems(L, n);
545 firstArg = L->top - n; /* yield results come from continuation */ 544 firstArg = L->top - n; /* yield results come from continuation */
@@ -563,15 +562,17 @@ LUA_API int lua_resume (lua_State *L, lua_State *from, int nargs) {
563 status = luaD_rawrunprotected(L, resume, L->top - nargs); 562 status = luaD_rawrunprotected(L, resume, L->top - nargs);
564 if (status == -1) /* error calling 'lua_resume'? */ 563 if (status == -1) /* error calling 'lua_resume'? */
565 status = LUA_ERRRUN; 564 status = LUA_ERRRUN;
566 else { /* yield or regular error */ 565 else { /* yield or error running coroutine */
567 while (status != LUA_OK && status != LUA_YIELD) { /* error? */ 566 while (status != LUA_OK && status != LUA_YIELD) { /* error? */
568 if (recover(L, status)) /* recover point? */ 567 if (recover(L, status)) { /* recover point? */
569 status = luaD_rawrunprotected(L, unroll, NULL); /* run continuation */ 568 /* unroll continuation */
569 status = luaD_rawrunprotected(L, unroll, &status);
570 }
570 else { /* unrecoverable error */ 571 else { /* unrecoverable error */
571 L->status = cast_byte(status); /* mark thread as `dead' */ 572 L->status = cast_byte(status); /* mark thread as `dead' */
572 seterrorobj(L, status, L->top); 573 seterrorobj(L, status, L->top);
573 L->ci->top = L->top; 574 L->ci->top = L->top;
574 break; 575 break; /* stop running it */
575 } 576 }
576 } 577 }
577 lua_assert(status == L->status); 578 lua_assert(status == L->status);