diff options
author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2017-11-07 11:25:26 -0200 |
---|---|---|
committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2017-11-07 11:25:26 -0200 |
commit | ad0704e40cc7b3135fedc6d40a522addb039e090 (patch) | |
tree | 4bcd104de4941239e09316efcee5e5e3566b8b81 /ldo.c | |
parent | 5a3f26f85558bedfa439027919d928abfdd00b6d (diff) | |
download | lua-ad0704e40cc7b3135fedc6d40a522addb039e090.tar.gz lua-ad0704e40cc7b3135fedc6d40a522addb039e090.tar.bz2 lua-ad0704e40cc7b3135fedc6d40a522addb039e090.zip |
back to 'CallInfo' (no gains with its removal)
Diffstat (limited to 'ldo.c')
-rw-r--r-- | ldo.c | 190 |
1 files changed, 95 insertions, 95 deletions
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: ldo.c,v 2.168 2017/11/03 20:41:05 roberto Exp roberto $ | 2 | ** $Id: ldo.c,v 2.165 2017/11/02 11:28:56 roberto Exp $ |
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 | */ |
@@ -123,8 +123,8 @@ l_noret luaD_throw (lua_State *L, int errcode) { | |||
123 | else { /* no handler at all; abort */ | 123 | else { /* no handler at all; abort */ |
124 | if (g->panic) { /* panic function? */ | 124 | if (g->panic) { /* panic function? */ |
125 | seterrorobj(L, errcode, L->top); /* assume EXTRA_STACK */ | 125 | seterrorobj(L, errcode, L->top); /* assume EXTRA_STACK */ |
126 | if (functop(L->func) < L->top) /* check invariant */ | 126 | if (L->ci->top < L->top) |
127 | setfunctop(L->func, L->top); | 127 | L->ci->top = L->top; /* pushing msg. can break this invariant */ |
128 | lua_unlock(L); | 128 | lua_unlock(L); |
129 | g->panic(L); /* call panic function (last chance to jump out) */ | 129 | g->panic(L); /* call panic function (last chance to jump out) */ |
130 | } | 130 | } |
@@ -157,11 +157,15 @@ int luaD_rawrunprotected (lua_State *L, Pfunc f, void *ud) { | |||
157 | ** =================================================================== | 157 | ** =================================================================== |
158 | */ | 158 | */ |
159 | static void correctstack (lua_State *L, StkId oldstack) { | 159 | static void correctstack (lua_State *L, StkId oldstack) { |
160 | CallInfo *ci; | ||
160 | UpVal *up; | 161 | UpVal *up; |
161 | L->top = (L->top - oldstack) + L->stack; | 162 | L->top = (L->top - oldstack) + L->stack; |
162 | L->func = (L->func - oldstack) + L->stack; | ||
163 | for (up = L->openupval; up != NULL; up = up->u.open.next) | 163 | for (up = L->openupval; up != NULL; up = up->u.open.next) |
164 | up->v = s2v((uplevel(up) - oldstack) + L->stack); | 164 | up->v = s2v((uplevel(up) - oldstack) + L->stack); |
165 | for (ci = L->ci; ci != NULL; ci = ci->previous) { | ||
166 | ci->top = (ci->top - oldstack) + L->stack; | ||
167 | ci->func = (ci->func - oldstack) + L->stack; | ||
168 | } | ||
165 | } | 169 | } |
166 | 170 | ||
167 | 171 | ||
@@ -203,11 +207,10 @@ void luaD_growstack (lua_State *L, int n) { | |||
203 | 207 | ||
204 | 208 | ||
205 | static int stackinuse (lua_State *L) { | 209 | static int stackinuse (lua_State *L) { |
210 | CallInfo *ci; | ||
206 | StkId lim = L->top; | 211 | StkId lim = L->top; |
207 | StkId func = L->func; | 212 | for (ci = L->ci; ci != NULL; ci = ci->previous) { |
208 | for (; func->stkci.previous != 0; func -= func->stkci.previous) { | 213 | if (lim < ci->top) lim = ci->top; |
209 | if (lim < functop(func)) | ||
210 | lim = functop(func); | ||
211 | } | 214 | } |
212 | lua_assert(lim <= L->stack_last); | 215 | lua_assert(lim <= L->stack_last); |
213 | return cast_int(lim - L->stack) + 1; /* part of stack in use */ | 216 | return cast_int(lim - L->stack) + 1; /* part of stack in use */ |
@@ -219,6 +222,10 @@ void luaD_shrinkstack (lua_State *L) { | |||
219 | int goodsize = inuse + (inuse / 8) + 2*EXTRA_STACK; | 222 | int goodsize = inuse + (inuse / 8) + 2*EXTRA_STACK; |
220 | if (goodsize > LUAI_MAXSTACK) | 223 | if (goodsize > LUAI_MAXSTACK) |
221 | goodsize = LUAI_MAXSTACK; /* respect stack limit */ | 224 | goodsize = LUAI_MAXSTACK; /* respect stack limit */ |
225 | if (L->stacksize > LUAI_MAXSTACK) /* had been handling stack overflow? */ | ||
226 | luaE_freeCI(L); /* free all CIs (list grew because of an error) */ | ||
227 | else | ||
228 | luaE_shrinkCI(L); /* shrink list */ | ||
222 | /* if thread is currently not handling a stack overflow and its | 229 | /* if thread is currently not handling a stack overflow and its |
223 | good size is smaller than current size, shrink its stack */ | 230 | good size is smaller than current size, shrink its stack */ |
224 | if (inuse <= (LUAI_MAXSTACK - EXTRA_STACK) && | 231 | if (inuse <= (LUAI_MAXSTACK - EXTRA_STACK) && |
@@ -245,46 +252,40 @@ void luaD_inctop (lua_State *L) { | |||
245 | void luaD_hook (lua_State *L, int event, int line) { | 252 | void luaD_hook (lua_State *L, int event, int line) { |
246 | lua_Hook hook = L->hook; | 253 | lua_Hook hook = L->hook; |
247 | if (hook && L->allowhook) { /* make sure there is a hook */ | 254 | if (hook && L->allowhook) { /* make sure there is a hook */ |
255 | CallInfo *ci = L->ci; | ||
248 | ptrdiff_t top = savestack(L, L->top); | 256 | ptrdiff_t top = savestack(L, L->top); |
249 | int origframesize = L->func->stkci.framesize; | 257 | ptrdiff_t ci_top = savestack(L, ci->top); |
250 | int tmpframesize; /* frame size to run hook */ | ||
251 | lua_Debug ar; | 258 | lua_Debug ar; |
252 | ar.event = event; | 259 | ar.event = event; |
253 | ar.currentline = line; | 260 | ar.currentline = line; |
254 | ar.i_actf = L->func - L->stack; | 261 | ar.i_ci = ci; |
255 | ar.i_actL = L; | ||
256 | luaD_checkstack(L, LUA_MINSTACK); /* ensure minimum stack size */ | 262 | luaD_checkstack(L, LUA_MINSTACK); /* ensure minimum stack size */ |
257 | tmpframesize = L->top - L->func + LUA_MINSTACK; | 263 | ci->top = L->top + LUA_MINSTACK; |
258 | if (tmpframesize > origframesize) /* need to grow frame? */ | 264 | lua_assert(ci->top <= L->stack_last); |
259 | L->func->stkci.framesize = tmpframesize; | ||
260 | lua_assert(functop(L->func) <= L->stack_last); | ||
261 | L->allowhook = 0; /* cannot call hooks inside a hook */ | 265 | L->allowhook = 0; /* cannot call hooks inside a hook */ |
262 | callstatus(L->func) |= CIST_HOOKED; | 266 | ci->callstatus |= CIST_HOOKED; |
263 | lua_unlock(L); | 267 | lua_unlock(L); |
264 | (*hook)(L, &ar); | 268 | (*hook)(L, &ar); |
265 | lua_lock(L); | 269 | lua_lock(L); |
266 | lua_assert(!L->allowhook); | 270 | lua_assert(!L->allowhook); |
267 | L->allowhook = 1; | 271 | L->allowhook = 1; |
268 | L->func->stkci.framesize = origframesize; | 272 | ci->top = restorestack(L, ci_top); |
269 | L->top = restorestack(L, top); | 273 | L->top = restorestack(L, top); |
270 | callstatus(L->func) &= ~CIST_HOOKED; | 274 | ci->callstatus &= ~CIST_HOOKED; |
271 | } | 275 | } |
272 | } | 276 | } |
273 | 277 | ||
274 | 278 | ||
275 | static void callhook (lua_State *L) { | 279 | static void callhook (lua_State *L, CallInfo *ci) { |
276 | int hook = LUA_HOOKCALL; | 280 | int hook = LUA_HOOKCALL; |
277 | StkId func = L->func; | 281 | ci->u.l.savedpc++; /* hooks assume 'pc' is already incremented */ |
278 | StkId previous = func - L->func->stkci.previous; | 282 | if (isLua(ci->previous) && |
279 | func->stkci.u.l.savedpc++; /* hooks assume 'pc' is already incremented */ | 283 | GET_OPCODE(*(ci->previous->u.l.savedpc - 1)) == OP_TAILCALL) { |
280 | if (isLua(previous) && | 284 | ci->callstatus |= CIST_TAIL; |
281 | GET_OPCODE(*(previous->stkci.u.l.savedpc - 1)) == OP_TAILCALL) { | ||
282 | callstatus(L->func) |= CIST_TAIL; | ||
283 | hook = LUA_HOOKTAILCALL; | 285 | hook = LUA_HOOKTAILCALL; |
284 | } | 286 | } |
285 | luaD_hook(L, hook, -1); | 287 | luaD_hook(L, hook, -1); |
286 | func = L->func; /* previous call can change stack */ | 288 | ci->u.l.savedpc--; /* correct 'pc' */ |
287 | func->stkci.u.l.savedpc--; /* correct 'pc' */ | ||
288 | } | 289 | } |
289 | 290 | ||
290 | 291 | ||
@@ -355,25 +356,28 @@ static int moveresults (lua_State *L, StkId firstResult, StkId res, | |||
355 | ** moves current number of results to proper place; returns 0 iff call | 356 | ** moves current number of results to proper place; returns 0 iff call |
356 | ** wanted multiple (variable number of) results. | 357 | ** wanted multiple (variable number of) results. |
357 | */ | 358 | */ |
358 | int luaD_poscall (lua_State *L, StkId firstResult, int nres) { | 359 | int luaD_poscall (lua_State *L, CallInfo *ci, StkId firstResult, int nres) { |
359 | StkId res = L->func; /* res == final position of 1st result */ | 360 | StkId res; |
360 | int wanted = res->stkci.nresults; | 361 | int wanted = ci->nresults; |
361 | if (L->hookmask & (LUA_MASKRET | LUA_MASKLINE)) { | 362 | if (L->hookmask & (LUA_MASKRET | LUA_MASKLINE)) { |
362 | if (L->hookmask & LUA_MASKRET) { | 363 | if (L->hookmask & LUA_MASKRET) { |
363 | ptrdiff_t fr = savestack(L, firstResult); /* hook may change stack */ | 364 | ptrdiff_t fr = savestack(L, firstResult); /* hook may change stack */ |
364 | luaD_hook(L, LUA_HOOKRET, -1); | 365 | luaD_hook(L, LUA_HOOKRET, -1); |
365 | firstResult = restorestack(L, fr); | 366 | firstResult = restorestack(L, fr); |
366 | res = L->func; | ||
367 | } | 367 | } |
368 | /* 'oldpc' for caller function */ | 368 | L->oldpc = ci->previous->u.l.savedpc; /* 'oldpc' for caller function */ |
369 | L->oldpc = (res - res->stkci.previous)->stkci.u.l.savedpc; | ||
370 | } | 369 | } |
371 | L->func = res - res->stkci.previous; | 370 | res = ci->func; /* res == final position of 1st result */ |
371 | L->ci = ci->previous; /* back to caller */ | ||
372 | /* move results to proper place */ | 372 | /* move results to proper place */ |
373 | return moveresults(L, firstResult, res, nres, wanted); | 373 | return moveresults(L, firstResult, res, nres, wanted); |
374 | } | 374 | } |
375 | 375 | ||
376 | 376 | ||
377 | |||
378 | #define next_ci(L) (L->ci = (L->ci->next ? L->ci->next : luaE_extendCI(L))) | ||
379 | |||
380 | |||
377 | /* | 381 | /* |
378 | ** Prepares a function call: checks the stack, creates a new CallInfo | 382 | ** Prepares a function call: checks the stack, creates a new CallInfo |
379 | ** entry, fills in the relevant information, calls hook if needed. | 383 | ** entry, fills in the relevant information, calls hook if needed. |
@@ -384,6 +388,7 @@ int luaD_poscall (lua_State *L, StkId firstResult, int nres) { | |||
384 | int luaD_precall (lua_State *L, StkId func, int nresults) { | 388 | int luaD_precall (lua_State *L, StkId func, int nresults) { |
385 | lua_CFunction f; | 389 | lua_CFunction f; |
386 | TValue *funcv = s2v(func); | 390 | TValue *funcv = s2v(func); |
391 | CallInfo *ci; | ||
387 | switch (ttype(funcv)) { | 392 | switch (ttype(funcv)) { |
388 | case LUA_TCCL: /* C closure */ | 393 | case LUA_TCCL: /* C closure */ |
389 | f = clCvalue(funcv)->f; | 394 | f = clCvalue(funcv)->f; |
@@ -393,19 +398,19 @@ int luaD_precall (lua_State *L, StkId func, int nresults) { | |||
393 | Cfunc: { | 398 | Cfunc: { |
394 | int n; /* number of returns */ | 399 | int n; /* number of returns */ |
395 | checkstackp(L, LUA_MINSTACK, func); /* ensure minimum stack size */ | 400 | checkstackp(L, LUA_MINSTACK, func); /* ensure minimum stack size */ |
396 | func->stkci.nresults = nresults; | 401 | ci = next_ci(L); /* now 'enter' new function */ |
397 | func->stkci.previous = func - L->func; | 402 | ci->nresults = nresults; |
398 | L->func = func; | 403 | ci->func = func; |
399 | setfunctop(func, L->top + LUA_MINSTACK); | 404 | ci->top = L->top + LUA_MINSTACK; |
400 | lua_assert(functop(func) <= L->stack_last); | 405 | lua_assert(ci->top <= L->stack_last); |
401 | callstatus(func) = 0; | 406 | ci->callstatus = 0; |
402 | if (L->hookmask & LUA_MASKCALL) | 407 | if (L->hookmask & LUA_MASKCALL) |
403 | luaD_hook(L, LUA_HOOKCALL, -1); | 408 | luaD_hook(L, LUA_HOOKCALL, -1); |
404 | lua_unlock(L); | 409 | lua_unlock(L); |
405 | n = (*f)(L); /* do the actual call */ | 410 | n = (*f)(L); /* do the actual call */ |
406 | lua_lock(L); | 411 | lua_lock(L); |
407 | api_checknelems(L, n); | 412 | api_checknelems(L, n); |
408 | luaD_poscall(L, L->top - n, n); | 413 | luaD_poscall(L, ci, L->top - n, n); |
409 | return 1; | 414 | return 1; |
410 | } | 415 | } |
411 | case LUA_TLCL: { /* Lua function: prepare its call */ | 416 | case LUA_TLCL: { /* Lua function: prepare its call */ |
@@ -417,16 +422,15 @@ int luaD_precall (lua_State *L, StkId func, int nresults) { | |||
417 | setnilvalue(s2v(L->top++)); /* complete missing arguments */ | 422 | setnilvalue(s2v(L->top++)); /* complete missing arguments */ |
418 | if (p->is_vararg) | 423 | if (p->is_vararg) |
419 | luaT_adjustvarargs(L, p, n); | 424 | luaT_adjustvarargs(L, p, n); |
420 | func->stkci.nresults = nresults; | 425 | ci = next_ci(L); /* now 'enter' new function */ |
421 | func->stkci.previous = func - L->func; | 426 | ci->nresults = nresults; |
422 | func->stkci.framesize = fsize + 1; /* size includes function itself */ | 427 | ci->func = func; |
423 | L->func = func; | 428 | L->top = ci->top = func + 1 + fsize; |
424 | L->top = func + 1 + fsize; | 429 | lua_assert(ci->top <= L->stack_last); |
425 | lua_assert(functop(func) <= L->stack_last); | 430 | ci->u.l.savedpc = p->code; /* starting point */ |
426 | func->stkci.u.l.savedpc = p->code; /* starting point */ | 431 | ci->callstatus = CIST_LUA; |
427 | callstatus(func) = 0; | ||
428 | if (L->hookmask & LUA_MASKCALL) | 432 | if (L->hookmask & LUA_MASKCALL) |
429 | callhook(L); | 433 | callhook(L, ci); |
430 | return 0; | 434 | return 0; |
431 | } | 435 | } |
432 | default: { /* not a function */ | 436 | default: { /* not a function */ |
@@ -483,25 +487,24 @@ void luaD_callnoyield (lua_State *L, StkId func, int nResults) { | |||
483 | ** continuation function. | 487 | ** continuation function. |
484 | */ | 488 | */ |
485 | static void finishCcall (lua_State *L, int status) { | 489 | static void finishCcall (lua_State *L, int status) { |
486 | StkId func = L->func; | 490 | CallInfo *ci = L->ci; |
487 | int n; | 491 | int n; |
488 | /* must have a continuation and must be able to call it */ | 492 | /* must have a continuation and must be able to call it */ |
489 | lua_assert(func->stkci.u.c.k != NULL && L->nny == 0); | 493 | lua_assert(ci->u.c.k != NULL && L->nny == 0); |
490 | /* error status can only happen in a protected call */ | 494 | /* error status can only happen in a protected call */ |
491 | lua_assert((callstatus(func) & CIST_YPCALL) || status == LUA_YIELD); | 495 | lua_assert((ci->callstatus & CIST_YPCALL) || status == LUA_YIELD); |
492 | if (callstatus(func) & CIST_YPCALL) { /* was inside a pcall? */ | 496 | if (ci->callstatus & CIST_YPCALL) { /* was inside a pcall? */ |
493 | callstatus(func) &= ~CIST_YPCALL; /* continuation is also inside it */ | 497 | ci->callstatus &= ~CIST_YPCALL; /* continuation is also inside it */ |
494 | L->errfunc = func->stkci.u.c.old_errfunc; /* with same error function */ | 498 | L->errfunc = ci->u.c.old_errfunc; /* with the same error function */ |
495 | } | 499 | } |
496 | /* finish 'lua_callk'/'lua_pcall'; CIST_YPCALL and 'errfunc' already | 500 | /* finish 'lua_callk'/'lua_pcall'; CIST_YPCALL and 'errfunc' already |
497 | handled */ | 501 | handled */ |
498 | adjustresults(L, func->stkci.nresults); | 502 | adjustresults(L, ci->nresults); |
499 | lua_unlock(L); | 503 | lua_unlock(L); |
500 | /* call continuation function */ | 504 | n = (*ci->u.c.k)(L, status, ci->u.c.ctx); /* call continuation function */ |
501 | n = (*func->stkci.u.c.k)(L, status, func->stkci.u.c.ctx); | ||
502 | lua_lock(L); | 505 | lua_lock(L); |
503 | api_checknelems(L, n); | 506 | api_checknelems(L, n); |
504 | luaD_poscall(L, L->top - n, n); /* finish 'luaD_precall' */ | 507 | luaD_poscall(L, ci, L->top - n, n); /* finish 'luaD_precall' */ |
505 | } | 508 | } |
506 | 509 | ||
507 | 510 | ||
@@ -516,8 +519,8 @@ static void finishCcall (lua_State *L, int status) { | |||
516 | static void unroll (lua_State *L, void *ud) { | 519 | static void unroll (lua_State *L, void *ud) { |
517 | if (ud != NULL) /* error status? */ | 520 | if (ud != NULL) /* error status? */ |
518 | finishCcall(L, *(int *)ud); /* finish 'lua_pcallk' callee */ | 521 | finishCcall(L, *(int *)ud); /* finish 'lua_pcallk' callee */ |
519 | while (L->func != L->stack) { /* something in the stack */ | 522 | while (L->ci != &L->base_ci) { /* something in the stack */ |
520 | if (!isLua(L->func)) /* C function? */ | 523 | if (!isLua(L->ci)) /* C function? */ |
521 | finishCcall(L, LUA_YIELD); /* complete its execution */ | 524 | finishCcall(L, LUA_YIELD); /* complete its execution */ |
522 | else { /* Lua function */ | 525 | else { /* Lua function */ |
523 | luaV_finishOp(L); /* finish interrupted instruction */ | 526 | luaV_finishOp(L); /* finish interrupted instruction */ |
@@ -531,13 +534,11 @@ static void unroll (lua_State *L, void *ud) { | |||
531 | ** Try to find a suspended protected call (a "recover point") for the | 534 | ** Try to find a suspended protected call (a "recover point") for the |
532 | ** given thread. | 535 | ** given thread. |
533 | */ | 536 | */ |
534 | static StkId findpcall (lua_State *L) { | 537 | static CallInfo *findpcall (lua_State *L) { |
535 | StkId func; | 538 | CallInfo *ci; |
536 | for (func = L->func; | 539 | for (ci = L->ci; ci != NULL; ci = ci->previous) { /* search for a pcall */ |
537 | func->stkci.previous != 0; | 540 | if (ci->callstatus & CIST_YPCALL) |
538 | func -= func->stkci.previous) { | 541 | return ci; |
539 | if (callstatus(func) & CIST_YPCALL) | ||
540 | return func; | ||
541 | } | 542 | } |
542 | return NULL; /* no pending pcall */ | 543 | return NULL; /* no pending pcall */ |
543 | } | 544 | } |
@@ -550,17 +551,17 @@ static StkId findpcall (lua_State *L) { | |||
550 | */ | 551 | */ |
551 | static int recover (lua_State *L, int status) { | 552 | static int recover (lua_State *L, int status) { |
552 | StkId oldtop; | 553 | StkId oldtop; |
553 | StkId recf = findpcall(L); | 554 | CallInfo *ci = findpcall(L); |
554 | if (recf == NULL) return 0; /* no recovery point */ | 555 | if (ci == NULL) return 0; /* no recovery point */ |
555 | /* "finish" luaD_pcall */ | 556 | /* "finish" luaD_pcall */ |
556 | oldtop = recf + recf->stkci.u2.funcidx; | 557 | oldtop = restorestack(L, ci->u2.funcidx); |
557 | luaF_close(L, oldtop); | 558 | luaF_close(L, oldtop); |
558 | seterrorobj(L, status, oldtop); | 559 | seterrorobj(L, status, oldtop); |
559 | L->func = recf; | 560 | L->ci = ci; |
560 | L->allowhook = getoah(callstatus(recf)); /* restore original 'allowhook' */ | 561 | L->allowhook = getoah(ci->callstatus); /* restore original 'allowhook' */ |
561 | L->nny = 0; /* should be zero to be yieldable */ | 562 | L->nny = 0; /* should be zero to be yieldable */ |
562 | luaD_shrinkstack(L); | 563 | luaD_shrinkstack(L); |
563 | L->errfunc = recf->stkci.u.c.old_errfunc; | 564 | L->errfunc = ci->u.c.old_errfunc; |
564 | return 1; /* continue running the coroutine */ | 565 | return 1; /* continue running the coroutine */ |
565 | } | 566 | } |
566 | 567 | ||
@@ -589,7 +590,7 @@ static int resume_error (lua_State *L, const char *msg, int narg) { | |||
589 | static void resume (lua_State *L, void *ud) { | 590 | static void resume (lua_State *L, void *ud) { |
590 | int n = *(cast(int*, ud)); /* number of arguments */ | 591 | int n = *(cast(int*, ud)); /* number of arguments */ |
591 | StkId firstArg = L->top - n; /* first argument */ | 592 | StkId firstArg = L->top - n; /* first argument */ |
592 | StkId func = L->func; | 593 | CallInfo *ci = L->ci; |
593 | if (L->status == LUA_OK) { /* starting a coroutine? */ | 594 | if (L->status == LUA_OK) { /* starting a coroutine? */ |
594 | if (!luaD_precall(L, firstArg - 1, LUA_MULTRET)) /* Lua function? */ | 595 | if (!luaD_precall(L, firstArg - 1, LUA_MULTRET)) /* Lua function? */ |
595 | luaV_execute(L); /* call it */ | 596 | luaV_execute(L); /* call it */ |
@@ -597,18 +598,17 @@ static void resume (lua_State *L, void *ud) { | |||
597 | else { /* resuming from previous yield */ | 598 | else { /* resuming from previous yield */ |
598 | lua_assert(L->status == LUA_YIELD); | 599 | lua_assert(L->status == LUA_YIELD); |
599 | L->status = LUA_OK; /* mark that it is running (again) */ | 600 | L->status = LUA_OK; /* mark that it is running (again) */ |
600 | if (isLua(func)) /* yielded inside a hook? */ | 601 | if (isLua(ci)) /* yielded inside a hook? */ |
601 | luaV_execute(L); /* just continue running Lua code */ | 602 | luaV_execute(L); /* just continue running Lua code */ |
602 | else { /* 'common' yield */ | 603 | else { /* 'common' yield */ |
603 | if (func->stkci.u.c.k != NULL) { /* does it have a continuation? */ | 604 | if (ci->u.c.k != NULL) { /* does it have a continuation function? */ |
604 | lua_unlock(L); | 605 | lua_unlock(L); |
605 | /* call continuation */ | 606 | n = (*ci->u.c.k)(L, LUA_YIELD, ci->u.c.ctx); /* call continuation */ |
606 | n = (*func->stkci.u.c.k)(L, LUA_YIELD, func->stkci.u.c.ctx); | ||
607 | lua_lock(L); | 607 | lua_lock(L); |
608 | api_checknelems(L, n); | 608 | api_checknelems(L, n); |
609 | firstArg = L->top - n; /* yield results come from continuation */ | 609 | firstArg = L->top - n; /* yield results come from continuation */ |
610 | } | 610 | } |
611 | luaD_poscall(L, firstArg, n); /* finish 'luaD_precall' */ | 611 | luaD_poscall(L, ci, firstArg, n); /* finish 'luaD_precall' */ |
612 | } | 612 | } |
613 | unroll(L, NULL); /* run continuation */ | 613 | unroll(L, NULL); /* run continuation */ |
614 | } | 614 | } |
@@ -621,7 +621,7 @@ LUA_API int lua_resume (lua_State *L, lua_State *from, int nargs, | |||
621 | unsigned short oldnny = L->nny; /* save "number of non-yieldable" calls */ | 621 | unsigned short oldnny = L->nny; /* save "number of non-yieldable" calls */ |
622 | lua_lock(L); | 622 | lua_lock(L); |
623 | if (L->status == LUA_OK) { /* may be starting a coroutine */ | 623 | if (L->status == LUA_OK) { /* may be starting a coroutine */ |
624 | if (L->func != L->stack) /* not in base level? */ | 624 | if (L->ci != &L->base_ci) /* not in base level? */ |
625 | return resume_error(L, "cannot resume non-suspended coroutine", nargs); | 625 | return resume_error(L, "cannot resume non-suspended coroutine", nargs); |
626 | } | 626 | } |
627 | else if (L->status != LUA_YIELD) | 627 | else if (L->status != LUA_YIELD) |
@@ -643,12 +643,12 @@ LUA_API int lua_resume (lua_State *L, lua_State *from, int nargs, | |||
643 | if (errorstatus(status)) { /* unrecoverable error? */ | 643 | if (errorstatus(status)) { /* unrecoverable error? */ |
644 | L->status = cast_byte(status); /* mark thread as 'dead' */ | 644 | L->status = cast_byte(status); /* mark thread as 'dead' */ |
645 | seterrorobj(L, status, L->top); /* push error message */ | 645 | seterrorobj(L, status, L->top); /* push error message */ |
646 | L->func->stkci.framesize = L->top - L->func; | 646 | L->ci->top = L->top; |
647 | } | 647 | } |
648 | else lua_assert(status == L->status); /* normal end or yield */ | 648 | else lua_assert(status == L->status); /* normal end or yield */ |
649 | } | 649 | } |
650 | *nresults = (status == LUA_YIELD) ? L->func->stkci.u2.nyield | 650 | *nresults = (status == LUA_YIELD) ? L->ci->u2.nyield |
651 | : L->top - (L->func + 1); | 651 | : L->top - (L->ci->func + 1); |
652 | L->nny = oldnny; /* restore 'nny' */ | 652 | L->nny = oldnny; /* restore 'nny' */ |
653 | L->nCcalls--; | 653 | L->nCcalls--; |
654 | lua_assert(L->nCcalls == ((from) ? from->nCcalls : 0)); | 654 | lua_assert(L->nCcalls == ((from) ? from->nCcalls : 0)); |
@@ -664,7 +664,7 @@ LUA_API int lua_isyieldable (lua_State *L) { | |||
664 | 664 | ||
665 | LUA_API int lua_yieldk (lua_State *L, int nresults, lua_KContext ctx, | 665 | LUA_API int lua_yieldk (lua_State *L, int nresults, lua_KContext ctx, |
666 | lua_KFunction k) { | 666 | lua_KFunction k) { |
667 | StkId func = L->func; | 667 | CallInfo *ci = L->ci; |
668 | luai_userstateyield(L, nresults); | 668 | luai_userstateyield(L, nresults); |
669 | lua_lock(L); | 669 | lua_lock(L); |
670 | api_checknelems(L, nresults); | 670 | api_checknelems(L, nresults); |
@@ -675,17 +675,17 @@ LUA_API int lua_yieldk (lua_State *L, int nresults, lua_KContext ctx, | |||
675 | luaG_runerror(L, "attempt to yield from outside a coroutine"); | 675 | luaG_runerror(L, "attempt to yield from outside a coroutine"); |
676 | } | 676 | } |
677 | L->status = LUA_YIELD; | 677 | L->status = LUA_YIELD; |
678 | if (isLua(func)) { /* inside a hook? */ | 678 | if (isLua(ci)) { /* inside a hook? */ |
679 | api_check(L, k == NULL, "hooks cannot continue after yielding"); | 679 | api_check(L, k == NULL, "hooks cannot continue after yielding"); |
680 | func->stkci.u2.nyield = 0; /* no results */ | 680 | ci->u2.nyield = 0; /* no results */ |
681 | } | 681 | } |
682 | else { | 682 | else { |
683 | if ((func->stkci.u.c.k = k) != NULL) /* is there a continuation? */ | 683 | if ((ci->u.c.k = k) != NULL) /* is there a continuation? */ |
684 | func->stkci.u.c.ctx = ctx; /* save context */ | 684 | ci->u.c.ctx = ctx; /* save context */ |
685 | func->stkci.u2.nyield = nresults; /* save number of results */ | 685 | ci->u2.nyield = nresults; /* save number of results */ |
686 | luaD_throw(L, LUA_YIELD); | 686 | luaD_throw(L, LUA_YIELD); |
687 | } | 687 | } |
688 | lua_assert(callstatus(func) & CIST_HOOKED); /* must be inside a hook */ | 688 | lua_assert(ci->callstatus & CIST_HOOKED); /* must be inside a hook */ |
689 | lua_unlock(L); | 689 | lua_unlock(L); |
690 | return 0; /* return to 'luaD_hook' */ | 690 | return 0; /* return to 'luaD_hook' */ |
691 | } | 691 | } |
@@ -694,7 +694,7 @@ LUA_API int lua_yieldk (lua_State *L, int nresults, lua_KContext ctx, | |||
694 | int luaD_pcall (lua_State *L, Pfunc func, void *u, | 694 | int luaD_pcall (lua_State *L, Pfunc func, void *u, |
695 | ptrdiff_t old_top, ptrdiff_t ef) { | 695 | ptrdiff_t old_top, ptrdiff_t ef) { |
696 | int status; | 696 | int status; |
697 | ptrdiff_t oldfunc = savestack(L, L->func); | 697 | CallInfo *old_ci = L->ci; |
698 | lu_byte old_allowhooks = L->allowhook; | 698 | lu_byte old_allowhooks = L->allowhook; |
699 | unsigned short old_nny = L->nny; | 699 | unsigned short old_nny = L->nny; |
700 | ptrdiff_t old_errfunc = L->errfunc; | 700 | ptrdiff_t old_errfunc = L->errfunc; |
@@ -704,7 +704,7 @@ int luaD_pcall (lua_State *L, Pfunc func, void *u, | |||
704 | StkId oldtop = restorestack(L, old_top); | 704 | StkId oldtop = restorestack(L, old_top); |
705 | luaF_close(L, oldtop); /* close possible pending closures */ | 705 | luaF_close(L, oldtop); /* close possible pending closures */ |
706 | seterrorobj(L, status, oldtop); | 706 | seterrorobj(L, status, oldtop); |
707 | L->func = restorestack(L, oldfunc); | 707 | L->ci = old_ci; |
708 | L->allowhook = old_allowhooks; | 708 | L->allowhook = old_allowhooks; |
709 | L->nny = old_nny; | 709 | L->nny = old_nny; |
710 | luaD_shrinkstack(L); | 710 | luaD_shrinkstack(L); |