aboutsummaryrefslogtreecommitdiff
path: root/src/lua/ldo.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/lua/ldo.c')
-rw-r--r--src/lua/ldo.c299
1 files changed, 174 insertions, 125 deletions
diff --git a/src/lua/ldo.c b/src/lua/ldo.c
index aa159cf..7135079 100644
--- a/src/lua/ldo.c
+++ b/src/lua/ldo.c
@@ -160,9 +160,8 @@ int luaD_rawrunprotected (lua_State *L, Pfunc f, void *ud) {
160static void correctstack (lua_State *L, StkId oldstack, StkId newstack) { 160static void correctstack (lua_State *L, StkId oldstack, StkId newstack) {
161 CallInfo *ci; 161 CallInfo *ci;
162 UpVal *up; 162 UpVal *up;
163 if (oldstack == newstack)
164 return; /* stack address did not change */
165 L->top = (L->top - oldstack) + newstack; 163 L->top = (L->top - oldstack) + newstack;
164 L->tbclist = (L->tbclist - oldstack) + newstack;
166 for (up = L->openupval; up != NULL; up = up->u.open.next) 165 for (up = L->openupval; up != NULL; up = up->u.open.next)
167 up->v = s2v((uplevel(up) - oldstack) + newstack); 166 up->v = s2v((uplevel(up) - oldstack) + newstack);
168 for (ci = L->ci; ci != NULL; ci = ci->previous) { 167 for (ci = L->ci; ci != NULL; ci = ci->previous) {
@@ -178,19 +177,35 @@ static void correctstack (lua_State *L, StkId oldstack, StkId newstack) {
178#define ERRORSTACKSIZE (LUAI_MAXSTACK + 200) 177#define ERRORSTACKSIZE (LUAI_MAXSTACK + 200)
179 178
180 179
180/*
181** Reallocate the stack to a new size, correcting all pointers into
182** it. (There are pointers to a stack from its upvalues, from its list
183** of call infos, plus a few individual pointers.) The reallocation is
184** done in two steps (allocation + free) because the correction must be
185** done while both addresses (the old stack and the new one) are valid.
186** (In ISO C, any pointer use after the pointer has been deallocated is
187** undefined behavior.)
188** In case of allocation error, raise an error or return false according
189** to 'raiseerror'.
190*/
181int luaD_reallocstack (lua_State *L, int newsize, int raiseerror) { 191int luaD_reallocstack (lua_State *L, int newsize, int raiseerror) {
182 int lim = stacksize(L); 192 int oldsize = stacksize(L);
183 StkId newstack = luaM_reallocvector(L, L->stack, 193 int i;
184 lim + EXTRA_STACK, newsize + EXTRA_STACK, StackValue); 194 StkId newstack = luaM_reallocvector(L, NULL, 0,
195 newsize + EXTRA_STACK, StackValue);
185 lua_assert(newsize <= LUAI_MAXSTACK || newsize == ERRORSTACKSIZE); 196 lua_assert(newsize <= LUAI_MAXSTACK || newsize == ERRORSTACKSIZE);
186 if (unlikely(newstack == NULL)) { /* reallocation failed? */ 197 if (l_unlikely(newstack == NULL)) { /* reallocation failed? */
187 if (raiseerror) 198 if (raiseerror)
188 luaM_error(L); 199 luaM_error(L);
189 else return 0; /* do not raise an error */ 200 else return 0; /* do not raise an error */
190 } 201 }
191 for (; lim < newsize; lim++) 202 /* number of elements to be copied to the new stack */
192 setnilvalue(s2v(newstack + lim + EXTRA_STACK)); /* erase new segment */ 203 i = ((oldsize <= newsize) ? oldsize : newsize) + EXTRA_STACK;
204 memcpy(newstack, L->stack, i * sizeof(StackValue));
205 for (; i < newsize + EXTRA_STACK; i++)
206 setnilvalue(s2v(newstack + i)); /* erase new segment */
193 correctstack(L, L->stack, newstack); 207 correctstack(L, L->stack, newstack);
208 luaM_freearray(L, L->stack, oldsize + EXTRA_STACK);
194 L->stack = newstack; 209 L->stack = newstack;
195 L->stack_last = L->stack + newsize; 210 L->stack_last = L->stack + newsize;
196 return 1; 211 return 1;
@@ -203,7 +218,7 @@ int luaD_reallocstack (lua_State *L, int newsize, int raiseerror) {
203*/ 218*/
204int luaD_growstack (lua_State *L, int n, int raiseerror) { 219int luaD_growstack (lua_State *L, int n, int raiseerror) {
205 int size = stacksize(L); 220 int size = stacksize(L);
206 if (unlikely(size > LUAI_MAXSTACK)) { 221 if (l_unlikely(size > LUAI_MAXSTACK)) {
207 /* if stack is larger than maximum, thread is already using the 222 /* if stack is larger than maximum, thread is already using the
208 extra space reserved for errors, that is, thread is handling 223 extra space reserved for errors, that is, thread is handling
209 a stack error; cannot grow further than that. */ 224 a stack error; cannot grow further than that. */
@@ -219,7 +234,7 @@ int luaD_growstack (lua_State *L, int n, int raiseerror) {
219 newsize = LUAI_MAXSTACK; 234 newsize = LUAI_MAXSTACK;
220 if (newsize < needed) /* but must respect what was asked for */ 235 if (newsize < needed) /* but must respect what was asked for */
221 newsize = needed; 236 newsize = needed;
222 if (likely(newsize <= LUAI_MAXSTACK)) 237 if (l_likely(newsize <= LUAI_MAXSTACK))
223 return luaD_reallocstack(L, newsize, raiseerror); 238 return luaD_reallocstack(L, newsize, raiseerror);
224 else { /* stack overflow */ 239 else { /* stack overflow */
225 /* add extra size to be able to handle the error message */ 240 /* add extra size to be able to handle the error message */
@@ -294,8 +309,8 @@ void luaD_hook (lua_State *L, int event, int line,
294 if (hook && L->allowhook) { /* make sure there is a hook */ 309 if (hook && L->allowhook) { /* make sure there is a hook */
295 int mask = CIST_HOOKED; 310 int mask = CIST_HOOKED;
296 CallInfo *ci = L->ci; 311 CallInfo *ci = L->ci;
297 ptrdiff_t top = savestack(L, L->top); 312 ptrdiff_t top = savestack(L, L->top); /* preserve original 'top' */
298 ptrdiff_t ci_top = savestack(L, ci->top); 313 ptrdiff_t ci_top = savestack(L, ci->top); /* idem for 'ci->top' */
299 lua_Debug ar; 314 lua_Debug ar;
300 ar.event = event; 315 ar.event = event;
301 ar.currentline = line; 316 ar.currentline = line;
@@ -305,8 +320,10 @@ void luaD_hook (lua_State *L, int event, int line,
305 ci->u2.transferinfo.ftransfer = ftransfer; 320 ci->u2.transferinfo.ftransfer = ftransfer;
306 ci->u2.transferinfo.ntransfer = ntransfer; 321 ci->u2.transferinfo.ntransfer = ntransfer;
307 } 322 }
323 if (isLua(ci) && L->top < ci->top)
324 L->top = ci->top; /* protect entire activation register */
308 luaD_checkstack(L, LUA_MINSTACK); /* ensure minimum stack size */ 325 luaD_checkstack(L, LUA_MINSTACK); /* ensure minimum stack size */
309 if (L->top + LUA_MINSTACK > ci->top) 326 if (ci->top < L->top + LUA_MINSTACK)
310 ci->top = L->top + LUA_MINSTACK; 327 ci->top = L->top + LUA_MINSTACK;
311 L->allowhook = 0; /* cannot call hooks inside a hook */ 328 L->allowhook = 0; /* cannot call hooks inside a hook */
312 ci->callstatus |= mask; 329 ci->callstatus |= mask;
@@ -328,38 +345,40 @@ void luaD_hook (lua_State *L, int event, int line,
328** active. 345** active.
329*/ 346*/
330void luaD_hookcall (lua_State *L, CallInfo *ci) { 347void luaD_hookcall (lua_State *L, CallInfo *ci) {
331 int hook = (ci->callstatus & CIST_TAIL) ? LUA_HOOKTAILCALL : LUA_HOOKCALL; 348 L->oldpc = 0; /* set 'oldpc' for new function */
332 Proto *p; 349 if (L->hookmask & LUA_MASKCALL) { /* is call hook on? */
333 if (!(L->hookmask & LUA_MASKCALL)) /* some other hook? */ 350 int event = (ci->callstatus & CIST_TAIL) ? LUA_HOOKTAILCALL
334 return; /* don't call hook */ 351 : LUA_HOOKCALL;
335 p = clLvalue(s2v(ci->func))->p;
336 L->top = ci->top; /* prepare top */
337 ci->u.l.savedpc++; /* hooks assume 'pc' is already incremented */
338 luaD_hook(L, hook, -1, 1, p->numparams);
339 ci->u.l.savedpc--; /* correct 'pc' */
340}
341
342
343static StkId rethook (lua_State *L, CallInfo *ci, StkId firstres, int nres) {
344 ptrdiff_t oldtop = savestack(L, L->top); /* hook may change top */
345 int delta = 0;
346 if (isLuacode(ci)) {
347 Proto *p = ci_func(ci)->p; 352 Proto *p = ci_func(ci)->p;
348 if (p->is_vararg) 353 ci->u.l.savedpc++; /* hooks assume 'pc' is already incremented */
349 delta = ci->u.l.nextraargs + p->numparams + 1; 354 luaD_hook(L, event, -1, 1, p->numparams);
350 if (L->top < ci->top) 355 ci->u.l.savedpc--; /* correct 'pc' */
351 L->top = ci->top; /* correct top to run hook */
352 } 356 }
357}
358
359
360/*
361** Executes a return hook for Lua and C functions and sets/corrects
362** 'oldpc'. (Note that this correction is needed by the line hook, so it
363** is done even when return hooks are off.)
364*/
365static void rethook (lua_State *L, CallInfo *ci, int nres) {
353 if (L->hookmask & LUA_MASKRET) { /* is return hook on? */ 366 if (L->hookmask & LUA_MASKRET) { /* is return hook on? */
367 StkId firstres = L->top - nres; /* index of first result */
368 int delta = 0; /* correction for vararg functions */
354 int ftransfer; 369 int ftransfer;
370 if (isLua(ci)) {
371 Proto *p = ci_func(ci)->p;
372 if (p->is_vararg)
373 delta = ci->u.l.nextraargs + p->numparams + 1;
374 }
355 ci->func += delta; /* if vararg, back to virtual 'func' */ 375 ci->func += delta; /* if vararg, back to virtual 'func' */
356 ftransfer = cast(unsigned short, firstres - ci->func); 376 ftransfer = cast(unsigned short, firstres - ci->func);
357 luaD_hook(L, LUA_HOOKRET, -1, ftransfer, nres); /* call it */ 377 luaD_hook(L, LUA_HOOKRET, -1, ftransfer, nres); /* call it */
358 ci->func -= delta; 378 ci->func -= delta;
359 } 379 }
360 if (isLua(ci = ci->previous)) 380 if (isLua(ci = ci->previous))
361 L->oldpc = pcRel(ci->u.l.savedpc, ci_func(ci)->p); /* update 'oldpc' */ 381 L->oldpc = pcRel(ci->u.l.savedpc, ci_func(ci)->p); /* set 'oldpc' */
362 return restorestack(L, oldtop);
363} 382}
364 383
365 384
@@ -371,7 +390,7 @@ static StkId rethook (lua_State *L, CallInfo *ci, StkId firstres, int nres) {
371void luaD_tryfuncTM (lua_State *L, StkId func) { 390void luaD_tryfuncTM (lua_State *L, StkId func) {
372 const TValue *tm = luaT_gettmbyobj(L, s2v(func), TM_CALL); 391 const TValue *tm = luaT_gettmbyobj(L, s2v(func), TM_CALL);
373 StkId p; 392 StkId p;
374 if (unlikely(ttisnil(tm))) 393 if (l_unlikely(ttisnil(tm)))
375 luaG_callerror(L, s2v(func)); /* nothing to call */ 394 luaG_callerror(L, s2v(func)); /* nothing to call */
376 for (p = L->top; p > func; p--) /* open space for metamethod */ 395 for (p = L->top; p > func; p--) /* open space for metamethod */
377 setobjs2s(L, p, p-1); 396 setobjs2s(L, p, p-1);
@@ -396,27 +415,34 @@ static void moveresults (lua_State *L, StkId res, int nres, int wanted) {
396 case 1: /* one value needed */ 415 case 1: /* one value needed */
397 if (nres == 0) /* no results? */ 416 if (nres == 0) /* no results? */
398 setnilvalue(s2v(res)); /* adjust with nil */ 417 setnilvalue(s2v(res)); /* adjust with nil */
399 else 418 else /* at least one result */
400 setobjs2s(L, res, L->top - nres); /* move it to proper place */ 419 setobjs2s(L, res, L->top - nres); /* move it to proper place */
401 L->top = res + 1; 420 L->top = res + 1;
402 return; 421 return;
403 case LUA_MULTRET: 422 case LUA_MULTRET:
404 wanted = nres; /* we want all results */ 423 wanted = nres; /* we want all results */
405 break; 424 break;
406 default: /* multiple results (or to-be-closed variables) */ 425 default: /* two/more results and/or to-be-closed variables */
407 if (hastocloseCfunc(wanted)) { /* to-be-closed variables? */ 426 if (hastocloseCfunc(wanted)) { /* to-be-closed variables? */
408 ptrdiff_t savedres = savestack(L, res); 427 ptrdiff_t savedres = savestack(L, res);
409 luaF_close(L, res, CLOSEKTOP, 0); /* may change the stack */ 428 L->ci->callstatus |= CIST_CLSRET; /* in case of yields */
410 res = restorestack(L, savedres); 429 L->ci->u2.nres = nres;
411 wanted = codeNresults(wanted); /* correct value */ 430 luaF_close(L, res, CLOSEKTOP, 1);
431 L->ci->callstatus &= ~CIST_CLSRET;
432 if (L->hookmask) /* if needed, call hook after '__close's */
433 rethook(L, L->ci, nres);
434 res = restorestack(L, savedres); /* close and hook can move stack */
435 wanted = decodeNresults(wanted);
412 if (wanted == LUA_MULTRET) 436 if (wanted == LUA_MULTRET)
413 wanted = nres; 437 wanted = nres; /* we want all results */
414 } 438 }
415 break; 439 break;
416 } 440 }
441 /* generic case */
417 firstresult = L->top - nres; /* index of first result */ 442 firstresult = L->top - nres; /* index of first result */
418 /* move all results to correct place */ 443 if (nres > wanted) /* extra results? */
419 for (i = 0; i < nres && i < wanted; i++) 444 nres = wanted; /* don't need them */
445 for (i = 0; i < nres; i++) /* move all results to correct place */
420 setobjs2s(L, res + i, firstresult + i); 446 setobjs2s(L, res + i, firstresult + i);
421 for (; i < wanted; i++) /* complete wanted number of results */ 447 for (; i < wanted; i++) /* complete wanted number of results */
422 setnilvalue(s2v(res + i)); 448 setnilvalue(s2v(res + i));
@@ -425,15 +451,21 @@ static void moveresults (lua_State *L, StkId res, int nres, int wanted) {
425 451
426 452
427/* 453/*
428** Finishes a function call: calls hook if necessary, removes CallInfo, 454** Finishes a function call: calls hook if necessary, moves current
429** moves current number of results to proper place. 455** number of results to proper place, and returns to previous call
456** info. If function has to close variables, hook must be called after
457** that.
430*/ 458*/
431void luaD_poscall (lua_State *L, CallInfo *ci, int nres) { 459void luaD_poscall (lua_State *L, CallInfo *ci, int nres) {
432 if (L->hookmask) 460 int wanted = ci->nresults;
433 L->top = rethook(L, ci, L->top - nres, nres); 461 if (l_unlikely(L->hookmask && !hastocloseCfunc(wanted)))
434 L->ci = ci->previous; /* back to caller */ 462 rethook(L, ci, nres);
435 /* move results to proper place */ 463 /* move results to proper place */
436 moveresults(L, ci->func, nres, ci->nresults); 464 moveresults(L, ci->func, nres, wanted);
465 /* function cannot be in any of these cases when returning */
466 lua_assert(!(ci->callstatus &
467 (CIST_HOOKED | CIST_YPCALL | CIST_FIN | CIST_TRAN | CIST_CLSRET)));
468 L->ci = ci->previous; /* back to caller (after closing variables) */
437} 469}
438 470
439 471
@@ -492,7 +524,7 @@ CallInfo *luaD_precall (lua_State *L, StkId func, int nresults) {
492 ci->top = L->top + LUA_MINSTACK; 524 ci->top = L->top + LUA_MINSTACK;
493 ci->func = func; 525 ci->func = func;
494 lua_assert(ci->top <= L->stack_last); 526 lua_assert(ci->top <= L->stack_last);
495 if (L->hookmask & LUA_MASKCALL) { 527 if (l_unlikely(L->hookmask & LUA_MASKCALL)) {
496 int narg = cast_int(L->top - func) - 1; 528 int narg = cast_int(L->top - func) - 1;
497 luaD_hook(L, LUA_HOOKCALL, -1, 1, narg); 529 luaD_hook(L, LUA_HOOKCALL, -1, 1, narg);
498 } 530 }
@@ -538,7 +570,7 @@ CallInfo *luaD_precall (lua_State *L, StkId func, int nresults) {
538static void ccall (lua_State *L, StkId func, int nResults, int inc) { 570static void ccall (lua_State *L, StkId func, int nResults, int inc) {
539 CallInfo *ci; 571 CallInfo *ci;
540 L->nCcalls += inc; 572 L->nCcalls += inc;
541 if (unlikely(getCcalls(L) >= LUAI_MAXCCALLS)) 573 if (l_unlikely(getCcalls(L) >= LUAI_MAXCCALLS))
542 luaE_checkcstack(L); 574 luaE_checkcstack(L);
543 if ((ci = luaD_precall(L, func, nResults)) != NULL) { /* Lua function? */ 575 if ((ci = luaD_precall(L, func, nResults)) != NULL) { /* Lua function? */
544 ci->callstatus = CIST_FRESH; /* mark that it is a "fresh" execute */ 576 ci->callstatus = CIST_FRESH; /* mark that it is a "fresh" execute */
@@ -565,27 +597,74 @@ void luaD_callnoyield (lua_State *L, StkId func, int nResults) {
565 597
566 598
567/* 599/*
568** Completes the execution of an interrupted C function, calling its 600** Finish the job of 'lua_pcallk' after it was interrupted by an yield.
569** continuation function. 601** (The caller, 'finishCcall', does the final call to 'adjustresults'.)
602** The main job is to complete the 'luaD_pcall' called by 'lua_pcallk'.
603** If a '__close' method yields here, eventually control will be back
604** to 'finishCcall' (when that '__close' method finally returns) and
605** 'finishpcallk' will run again and close any still pending '__close'
606** methods. Similarly, if a '__close' method errs, 'precover' calls
607** 'unroll' which calls ''finishCcall' and we are back here again, to
608** close any pending '__close' methods.
609** Note that, up to the call to 'luaF_close', the corresponding
610** 'CallInfo' is not modified, so that this repeated run works like the
611** first one (except that it has at least one less '__close' to do). In
612** particular, field CIST_RECST preserves the error status across these
613** multiple runs, changing only if there is a new error.
570*/ 614*/
571static void finishCcall (lua_State *L, int status) { 615static int finishpcallk (lua_State *L, CallInfo *ci) {
572 CallInfo *ci = L->ci; 616 int status = getcistrecst(ci); /* get original status */
573 int n; 617 if (l_likely(status == LUA_OK)) /* no error? */
574 /* must have a continuation and must be able to call it */ 618 status = LUA_YIELD; /* was interrupted by an yield */
575 lua_assert(ci->u.c.k != NULL && yieldable(L)); 619 else { /* error */
576 /* error status can only happen in a protected call */ 620 StkId func = restorestack(L, ci->u2.funcidx);
577 lua_assert((ci->callstatus & CIST_YPCALL) || status == LUA_YIELD); 621 L->allowhook = getoah(ci->callstatus); /* restore 'allowhook' */
578 if (ci->callstatus & CIST_YPCALL) { /* was inside a pcall? */ 622 luaF_close(L, func, status, 1); /* can yield or raise an error */
579 ci->callstatus &= ~CIST_YPCALL; /* continuation is also inside it */ 623 func = restorestack(L, ci->u2.funcidx); /* stack may be moved */
580 L->errfunc = ci->u.c.old_errfunc; /* with the same error function */ 624 luaD_seterrorobj(L, status, func);
581 } 625 luaD_shrinkstack(L); /* restore stack size in case of overflow */
582 /* finish 'lua_callk'/'lua_pcall'; CIST_YPCALL and 'errfunc' already 626 setcistrecst(ci, LUA_OK); /* clear original status */
583 handled */ 627 }
584 adjustresults(L, ci->nresults); 628 ci->callstatus &= ~CIST_YPCALL;
585 lua_unlock(L); 629 L->errfunc = ci->u.c.old_errfunc;
586 n = (*ci->u.c.k)(L, status, ci->u.c.ctx); /* call continuation function */ 630 /* if it is here, there were errors or yields; unlike 'lua_pcallk',
587 lua_lock(L); 631 do not change status */
588 api_checknelems(L, n); 632 return status;
633}
634
635
636/*
637** Completes the execution of a C function interrupted by an yield.
638** The interruption must have happened while the function was either
639** closing its tbc variables in 'moveresults' or executing
640** 'lua_callk'/'lua_pcallk'. In the first case, it just redoes
641** 'luaD_poscall'. In the second case, the call to 'finishpcallk'
642** finishes the interrupted execution of 'lua_pcallk'. After that, it
643** calls the continuation of the interrupted function and finally it
644** completes the job of the 'luaD_call' that called the function. In
645** the call to 'adjustresults', we do not know the number of results
646** of the function called by 'lua_callk'/'lua_pcallk', so we are
647** conservative and use LUA_MULTRET (always adjust).
648*/
649static void finishCcall (lua_State *L, CallInfo *ci) {
650 int n; /* actual number of results from C function */
651 if (ci->callstatus & CIST_CLSRET) { /* was returning? */
652 lua_assert(hastocloseCfunc(ci->nresults));
653 n = ci->u2.nres; /* just redo 'luaD_poscall' */
654 /* don't need to reset CIST_CLSRET, as it will be set again anyway */
655 }
656 else {
657 int status = LUA_YIELD; /* default if there were no errors */
658 /* must have a continuation and must be able to call it */
659 lua_assert(ci->u.c.k != NULL && yieldable(L));
660 if (ci->callstatus & CIST_YPCALL) /* was inside a 'lua_pcallk'? */
661 status = finishpcallk(L, ci); /* finish it */
662 adjustresults(L, LUA_MULTRET); /* finish 'lua_callk' */
663 lua_unlock(L);
664 n = (*ci->u.c.k)(L, status, ci->u.c.ctx); /* call continuation */
665 lua_lock(L);
666 api_checknelems(L, n);
667 }
589 luaD_poscall(L, ci, n); /* finish 'luaD_call' */ 668 luaD_poscall(L, ci, n); /* finish 'luaD_call' */
590} 669}
591 670
@@ -600,7 +679,7 @@ static void unroll (lua_State *L, void *ud) {
600 UNUSED(ud); 679 UNUSED(ud);
601 while ((ci = L->ci) != &L->base_ci) { /* something in the stack */ 680 while ((ci = L->ci) != &L->base_ci) { /* something in the stack */
602 if (!isLua(ci)) /* C function? */ 681 if (!isLua(ci)) /* C function? */
603 finishCcall(L, LUA_YIELD); /* complete its execution */ 682 finishCcall(L, ci); /* complete its execution */
604 else { /* Lua function */ 683 else { /* Lua function */
605 luaV_finishOp(L); /* finish interrupted instruction */ 684 luaV_finishOp(L); /* finish interrupted instruction */
606 luaV_execute(L, ci); /* execute down to higher C 'boundary' */ 685 luaV_execute(L, ci); /* execute down to higher C 'boundary' */
@@ -624,40 +703,6 @@ static CallInfo *findpcall (lua_State *L) {
624 703
625 704
626/* 705/*
627** Auxiliary structure to call 'recover' in protected mode.
628*/
629struct RecoverS {
630 int status;
631 CallInfo *ci;
632};
633
634
635/*
636** Recovers from an error in a coroutine: completes the execution of the
637** interrupted 'luaD_pcall', completes the interrupted C function which
638** called 'lua_pcallk', and continues running the coroutine. If there is
639** an error in 'luaF_close', this function will be called again and the
640** coroutine will continue from where it left.
641*/
642static void recover (lua_State *L, void *ud) {
643 struct RecoverS *r = cast(struct RecoverS *, ud);
644 int status = r->status;
645 CallInfo *ci = r->ci; /* recover point */
646 StkId func = restorestack(L, ci->u2.funcidx);
647 /* "finish" luaD_pcall */
648 L->ci = ci;
649 L->allowhook = getoah(ci->callstatus); /* restore original 'allowhook' */
650 luaF_close(L, func, status, 0); /* may change the stack */
651 func = restorestack(L, ci->u2.funcidx);
652 luaD_seterrorobj(L, status, func);
653 luaD_shrinkstack(L); /* restore stack size in case of overflow */
654 L->errfunc = ci->u.c.old_errfunc;
655 finishCcall(L, status); /* finish 'lua_pcallk' callee */
656 unroll(L, NULL); /* continue running the coroutine */
657}
658
659
660/*
661** Signal an error in the call to 'lua_resume', not in the execution 706** Signal an error in the call to 'lua_resume', not in the execution
662** of the coroutine itself. (Such errors should not be handled by any 707** of the coroutine itself. (Such errors should not be handled by any
663** coroutine error handler and should not kill the coroutine.) 708** coroutine error handler and should not kill the coroutine.)
@@ -688,8 +733,10 @@ static void resume (lua_State *L, void *ud) {
688 lua_assert(L->status == LUA_YIELD); 733 lua_assert(L->status == LUA_YIELD);
689 L->status = LUA_OK; /* mark that it is running (again) */ 734 L->status = LUA_OK; /* mark that it is running (again) */
690 luaE_incCstack(L); /* control the C stack */ 735 luaE_incCstack(L); /* control the C stack */
691 if (isLua(ci)) /* yielded inside a hook? */ 736 if (isLua(ci)) { /* yielded inside a hook? */
737 L->top = firstArg; /* discard arguments */
692 luaV_execute(L, ci); /* just continue running Lua code */ 738 luaV_execute(L, ci); /* just continue running Lua code */
739 }
693 else { /* 'common' yield */ 740 else { /* 'common' yield */
694 if (ci->u.c.k != NULL) { /* does it have a continuation function? */ 741 if (ci->u.c.k != NULL) { /* does it have a continuation function? */
695 lua_unlock(L); 742 lua_unlock(L);
@@ -705,19 +752,21 @@ static void resume (lua_State *L, void *ud) {
705 752
706 753
707/* 754/*
708** Calls 'recover' in protected mode, repeating while there are 755** Unrolls a coroutine in protected mode while there are recoverable
709** recoverable errors, that is, errors inside a protected call. (Any 756** errors, that is, errors inside a protected call. (Any error
710** error interrupts 'recover', and this loop protects it again so it 757** interrupts 'unroll', and this loop protects it again so it can
711** can continue.) Stops with a normal end (status == LUA_OK), an yield 758** continue.) Stops with a normal end (status == LUA_OK), an yield
712** (status == LUA_YIELD), or an unprotected error ('findpcall' doesn't 759** (status == LUA_YIELD), or an unprotected error ('findpcall' doesn't
713** find a recover point). 760** find a recover point).
714*/ 761*/
715static int p_recover (lua_State *L, int status) { 762static int precover (lua_State *L, int status) {
716 struct RecoverS r; 763 CallInfo *ci;
717 r.status = status; 764 while (errorstatus(status) && (ci = findpcall(L)) != NULL) {
718 while (errorstatus(status) && (r.ci = findpcall(L)) != NULL) 765 L->ci = ci; /* go down to recovery functions */
719 r.status = luaD_rawrunprotected(L, recover, &r); 766 setcistrecst(ci, status); /* status to finish 'pcall' */
720 return r.status; 767 status = luaD_rawrunprotected(L, unroll, NULL);
768 }
769 return status;
721} 770}
722 771
723 772
@@ -738,8 +787,8 @@ LUA_API int lua_resume (lua_State *L, lua_State *from, int nargs,
738 api_checknelems(L, (L->status == LUA_OK) ? nargs + 1 : nargs); 787 api_checknelems(L, (L->status == LUA_OK) ? nargs + 1 : nargs);
739 status = luaD_rawrunprotected(L, resume, &nargs); 788 status = luaD_rawrunprotected(L, resume, &nargs);
740 /* continue running after recoverable errors */ 789 /* continue running after recoverable errors */
741 status = p_recover(L, status); 790 status = precover(L, status);
742 if (likely(!errorstatus(status))) 791 if (l_likely(!errorstatus(status)))
743 lua_assert(status == L->status); /* normal end or yield */ 792 lua_assert(status == L->status); /* normal end or yield */
744 else { /* unrecoverable error */ 793 else { /* unrecoverable error */
745 L->status = cast_byte(status); /* mark thread as 'dead' */ 794 L->status = cast_byte(status); /* mark thread as 'dead' */
@@ -765,22 +814,22 @@ LUA_API int lua_yieldk (lua_State *L, int nresults, lua_KContext ctx,
765 lua_lock(L); 814 lua_lock(L);
766 ci = L->ci; 815 ci = L->ci;
767 api_checknelems(L, nresults); 816 api_checknelems(L, nresults);
768 if (unlikely(!yieldable(L))) { 817 if (l_unlikely(!yieldable(L))) {
769 if (L != G(L)->mainthread) 818 if (L != G(L)->mainthread)
770 luaG_runerror(L, "attempt to yield across a C-call boundary"); 819 luaG_runerror(L, "attempt to yield across a C-call boundary");
771 else 820 else
772 luaG_runerror(L, "attempt to yield from outside a coroutine"); 821 luaG_runerror(L, "attempt to yield from outside a coroutine");
773 } 822 }
774 L->status = LUA_YIELD; 823 L->status = LUA_YIELD;
824 ci->u2.nyield = nresults; /* save number of results */
775 if (isLua(ci)) { /* inside a hook? */ 825 if (isLua(ci)) { /* inside a hook? */
776 lua_assert(!isLuacode(ci)); 826 lua_assert(!isLuacode(ci));
827 api_check(L, nresults == 0, "hooks cannot yield values");
777 api_check(L, k == NULL, "hooks cannot continue after yielding"); 828 api_check(L, k == NULL, "hooks cannot continue after yielding");
778 ci->u2.nyield = 0; /* no results */
779 } 829 }
780 else { 830 else {
781 if ((ci->u.c.k = k) != NULL) /* is there a continuation? */ 831 if ((ci->u.c.k = k) != NULL) /* is there a continuation? */
782 ci->u.c.ctx = ctx; /* save context */ 832 ci->u.c.ctx = ctx; /* save context */
783 ci->u2.nyield = nresults; /* save number of results */
784 luaD_throw(L, LUA_YIELD); 833 luaD_throw(L, LUA_YIELD);
785 } 834 }
786 lua_assert(ci->callstatus & CIST_HOOKED); /* must be inside a hook */ 835 lua_assert(ci->callstatus & CIST_HOOKED); /* must be inside a hook */
@@ -818,7 +867,7 @@ int luaD_closeprotected (lua_State *L, ptrdiff_t level, int status) {
818 struct CloseP pcl; 867 struct CloseP pcl;
819 pcl.level = restorestack(L, level); pcl.status = status; 868 pcl.level = restorestack(L, level); pcl.status = status;
820 status = luaD_rawrunprotected(L, &closepaux, &pcl); 869 status = luaD_rawrunprotected(L, &closepaux, &pcl);
821 if (likely(status == LUA_OK)) /* no more errors? */ 870 if (l_likely(status == LUA_OK)) /* no more errors? */
822 return pcl.status; 871 return pcl.status;
823 else { /* an error occurred; restore saved state and repeat */ 872 else { /* an error occurred; restore saved state and repeat */
824 L->ci = old_ci; 873 L->ci = old_ci;
@@ -841,7 +890,7 @@ int luaD_pcall (lua_State *L, Pfunc func, void *u,
841 ptrdiff_t old_errfunc = L->errfunc; 890 ptrdiff_t old_errfunc = L->errfunc;
842 L->errfunc = ef; 891 L->errfunc = ef;
843 status = luaD_rawrunprotected(L, func, u); 892 status = luaD_rawrunprotected(L, func, u);
844 if (unlikely(status != LUA_OK)) { /* an error occurred? */ 893 if (l_unlikely(status != LUA_OK)) { /* an error occurred? */
845 L->ci = old_ci; 894 L->ci = old_ci;
846 L->allowhook = old_allowhooks; 895 L->allowhook = old_allowhooks;
847 status = luaD_closeprotected(L, old_top, status); 896 status = luaD_closeprotected(L, old_top, status);