diff options
| -rw-r--r-- | ldo.c | 69 | ||||
| -rw-r--r-- | ldo.h | 5 | ||||
| -rw-r--r-- | lvm.c | 25 |
3 files changed, 48 insertions, 51 deletions
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: ldo.c,v 2.199 2018/03/07 16:26:01 roberto Exp roberto $ | 2 | ** $Id: ldo.c,v 2.200 2018/03/16 15:33:34 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 | */ |
| @@ -319,14 +319,15 @@ void luaD_hookcall (lua_State *L, CallInfo *ci) { | |||
| 319 | } | 319 | } |
| 320 | 320 | ||
| 321 | 321 | ||
| 322 | static void rethook (lua_State *L, CallInfo *ci, StkId firstres, int nres) { | 322 | static StkId rethook (lua_State *L, CallInfo *ci, StkId firstres, int nres) { |
| 323 | ptrdiff_t oldtop = savestack(L, L->top); /* hook may change top */ | ||
| 323 | int delta = 0; | 324 | int delta = 0; |
| 324 | if (isLuacode(ci)) { | 325 | if (isLuacode(ci)) { |
| 325 | Proto *p = clLvalue(s2v(ci->func))->p; | 326 | Proto *p = clLvalue(s2v(ci->func))->p; |
| 326 | if (p->is_vararg) | 327 | if (p->is_vararg) |
| 327 | delta = ci->u.l.nextraargs + p->numparams + 1; | 328 | delta = ci->u.l.nextraargs + p->numparams + 1; |
| 328 | if (L->top < ci->top) | 329 | if (L->top < ci->top) |
| 329 | L->top = ci->top; /* correct top */ | 330 | L->top = ci->top; /* correct top to run hook */ |
| 330 | } | 331 | } |
| 331 | if (L->hookmask & LUA_MASKRET) { /* is return hook on? */ | 332 | if (L->hookmask & LUA_MASKRET) { /* is return hook on? */ |
| 332 | int ftransfer; | 333 | int ftransfer; |
| @@ -337,6 +338,7 @@ static void rethook (lua_State *L, CallInfo *ci, StkId firstres, int nres) { | |||
| 337 | } | 338 | } |
| 338 | if (isLua(ci->previous)) | 339 | if (isLua(ci->previous)) |
| 339 | L->oldpc = ci->previous->u.l.savedpc; /* update 'oldpc' */ | 340 | L->oldpc = ci->previous->u.l.savedpc; /* update 'oldpc' */ |
| 341 | return restorestack(L, oldtop); | ||
| 340 | } | 342 | } |
| 341 | 343 | ||
| 342 | 344 | ||
| @@ -363,40 +365,33 @@ void luaD_tryfuncTM (lua_State *L, StkId func) { | |||
| 363 | ** expressions, multiple results for tail calls/single parameters) | 365 | ** expressions, multiple results for tail calls/single parameters) |
| 364 | ** separated. | 366 | ** separated. |
| 365 | */ | 367 | */ |
| 366 | static void moveresults (lua_State *L, StkId firstResult, StkId res, | 368 | static void moveresults (lua_State *L, StkId res, int nres, int wanted) { |
| 367 | int nres, int wanted) { | ||
| 368 | switch (wanted) { /* handle typical cases separately */ | 369 | switch (wanted) { /* handle typical cases separately */ |
| 369 | case 0: break; /* nothing to move */ | 370 | case 0: /* no values needed */ |
| 370 | case 1: { /* one result needed */ | 371 | L->top = res; |
| 372 | break; | ||
| 373 | case 1: /* one value needed */ | ||
| 371 | if (nres == 0) /* no results? */ | 374 | if (nres == 0) /* no results? */ |
| 372 | setnilvalue(s2v(res)); /* adjust with nil */ | 375 | setnilvalue(s2v(res)); /* adjust with nil */ |
| 373 | else | 376 | else |
| 374 | setobjs2s(L, res, firstResult); /* move it to proper place */ | 377 | setobjs2s(L, res, L->top - nres); /* move it to proper place */ |
| 378 | L->top = res + 1; | ||
| 375 | break; | 379 | break; |
| 376 | } | 380 | case LUA_MULTRET: |
| 377 | case LUA_MULTRET: { | 381 | wanted = nres; /* we want all results */ |
| 382 | /* FALLTHROUGH */ | ||
| 383 | default: { /* multiple results */ | ||
| 384 | StkId firstresult = L->top - nres; /* index of first result */ | ||
| 378 | int i; | 385 | int i; |
| 379 | for (i = 0; i < nres; i++) /* move all results to correct place */ | 386 | /* move all results to correct place */ |
| 380 | setobjs2s(L, res + i, firstResult + i); | 387 | for (i = 0; i < nres && i < wanted; i++) |
| 381 | wanted = nres; /* it wanted what it had */ | 388 | setobjs2s(L, res + i, firstresult + i); |
| 382 | break; | 389 | for (; i < wanted; i++) /* complete wanted number of results */ |
| 383 | } | 390 | setnilvalue(s2v(res + i)); |
| 384 | default: { | 391 | L->top = res + wanted; /* top points after the last result */ |
| 385 | int i; | ||
| 386 | if (wanted <= nres) { /* enough results? */ | ||
| 387 | for (i = 0; i < wanted; i++) /* move wanted results to correct place */ | ||
| 388 | setobjs2s(L, res + i, firstResult + i); | ||
| 389 | } | ||
| 390 | else { /* not enough results; use all of them plus nils */ | ||
| 391 | for (i = 0; i < nres; i++) /* move all results to correct place */ | ||
| 392 | setobjs2s(L, res + i, firstResult + i); | ||
| 393 | for (; i < wanted; i++) /* complete wanted number of results */ | ||
| 394 | setnilvalue(s2v(res + i)); | ||
| 395 | } | ||
| 396 | break; | 392 | break; |
| 397 | } | 393 | } |
| 398 | } | 394 | } |
| 399 | L->top = res + wanted; /* top points after the last result */ | ||
| 400 | } | 395 | } |
| 401 | 396 | ||
| 402 | 397 | ||
| @@ -404,15 +399,12 @@ static void moveresults (lua_State *L, StkId firstResult, StkId res, | |||
| 404 | ** Finishes a function call: calls hook if necessary, removes CallInfo, | 399 | ** Finishes a function call: calls hook if necessary, removes CallInfo, |
| 405 | ** moves current number of results to proper place. | 400 | ** moves current number of results to proper place. |
| 406 | */ | 401 | */ |
| 407 | void luaD_poscall (lua_State *L, CallInfo *ci, StkId firstResult, int nres) { | 402 | void luaD_poscall (lua_State *L, CallInfo *ci, int nres) { |
| 408 | if (L->hookmask) { | 403 | if (L->hookmask) |
| 409 | ptrdiff_t fr = savestack(L, firstResult); /* hook may change stack */ | 404 | L->top = rethook(L, ci, L->top - nres, nres); |
| 410 | rethook(L, ci, firstResult, nres); | ||
| 411 | firstResult = restorestack(L, fr); | ||
| 412 | } | ||
| 413 | L->ci = ci->previous; /* back to caller */ | 405 | L->ci = ci->previous; /* back to caller */ |
| 414 | /* move results to proper place */ | 406 | /* move results to proper place */ |
| 415 | moveresults(L, firstResult, ci->func, nres, ci->nresults); | 407 | moveresults(L, ci->func, nres, ci->nresults); |
| 416 | } | 408 | } |
| 417 | 409 | ||
| 418 | 410 | ||
| @@ -477,7 +469,7 @@ void luaD_call (lua_State *L, StkId func, int nresults) { | |||
| 477 | n = (*f)(L); /* do the actual call */ | 469 | n = (*f)(L); /* do the actual call */ |
| 478 | lua_lock(L); | 470 | lua_lock(L); |
| 479 | api_checknelems(L, n); | 471 | api_checknelems(L, n); |
| 480 | luaD_poscall(L, ci, L->top - n, n); | 472 | luaD_poscall(L, ci, n); |
| 481 | break; | 473 | break; |
| 482 | } | 474 | } |
| 483 | case LUA_TLCL: { /* Lua function */ | 475 | case LUA_TLCL: { /* Lua function */ |
| @@ -540,7 +532,7 @@ static void finishCcall (lua_State *L, int status) { | |||
| 540 | n = (*ci->u.c.k)(L, status, ci->u.c.ctx); /* call continuation function */ | 532 | n = (*ci->u.c.k)(L, status, ci->u.c.ctx); /* call continuation function */ |
| 541 | lua_lock(L); | 533 | lua_lock(L); |
| 542 | api_checknelems(L, n); | 534 | api_checknelems(L, n); |
| 543 | luaD_poscall(L, ci, L->top - n, n); /* finish 'luaD_call' */ | 535 | luaD_poscall(L, ci, n); /* finish 'luaD_call' */ |
| 544 | } | 536 | } |
| 545 | 537 | ||
| 546 | 538 | ||
| @@ -642,9 +634,8 @@ static void resume (lua_State *L, void *ud) { | |||
| 642 | n = (*ci->u.c.k)(L, LUA_YIELD, ci->u.c.ctx); /* call continuation */ | 634 | n = (*ci->u.c.k)(L, LUA_YIELD, ci->u.c.ctx); /* call continuation */ |
| 643 | lua_lock(L); | 635 | lua_lock(L); |
| 644 | api_checknelems(L, n); | 636 | api_checknelems(L, n); |
| 645 | firstArg = L->top - n; /* yield results come from continuation */ | ||
| 646 | } | 637 | } |
| 647 | luaD_poscall(L, ci, firstArg, n); /* finish 'luaD_call' */ | 638 | luaD_poscall(L, ci, n); /* finish 'luaD_call' */ |
| 648 | } | 639 | } |
| 649 | unroll(L, NULL); /* run continuation */ | 640 | unroll(L, NULL); /* run continuation */ |
| 650 | } | 641 | } |
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: ldo.h,v 2.42 2018/02/15 15:34:29 roberto Exp roberto $ | 2 | ** $Id: ldo.h,v 2.43 2018/02/17 19:29: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 | */ |
| @@ -61,8 +61,7 @@ LUAI_FUNC void luaD_callnoyield (lua_State *L, StkId func, int nResults); | |||
| 61 | LUAI_FUNC void luaD_tryfuncTM (lua_State *L, StkId func); | 61 | LUAI_FUNC void luaD_tryfuncTM (lua_State *L, StkId func); |
| 62 | LUAI_FUNC int luaD_pcall (lua_State *L, Pfunc func, void *u, | 62 | LUAI_FUNC int luaD_pcall (lua_State *L, Pfunc func, void *u, |
| 63 | ptrdiff_t oldtop, ptrdiff_t ef); | 63 | ptrdiff_t oldtop, ptrdiff_t ef); |
| 64 | LUAI_FUNC void luaD_poscall (lua_State *L, CallInfo *ci, StkId firstResult, | 64 | LUAI_FUNC void luaD_poscall (lua_State *L, CallInfo *ci, int nres); |
| 65 | int nres); | ||
| 66 | LUAI_FUNC int luaD_reallocstack (lua_State *L, int newsize, int raiseerror); | 65 | LUAI_FUNC int luaD_reallocstack (lua_State *L, int newsize, int raiseerror); |
| 67 | LUAI_FUNC int luaD_growstack (lua_State *L, int n, int raiseerror); | 66 | LUAI_FUNC int luaD_growstack (lua_State *L, int n, int raiseerror); |
| 68 | LUAI_FUNC void luaD_shrinkstack (lua_State *L); | 67 | LUAI_FUNC void luaD_shrinkstack (lua_State *L); |
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: lvm.c,v 2.353 2018/04/04 14:23:41 roberto Exp roberto $ | 2 | ** $Id: lvm.c,v 2.354 2018/05/02 18:17:59 roberto Exp roberto $ |
| 3 | ** Lua virtual machine | 3 | ** Lua virtual machine |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| @@ -1591,7 +1591,7 @@ void luaV_execute (lua_State *L, CallInfo *ci) { | |||
| 1591 | ra = RA(i); | 1591 | ra = RA(i); |
| 1592 | } | 1592 | } |
| 1593 | ci->func -= delta; | 1593 | ci->func -= delta; |
| 1594 | luaD_poscall(L, ci, ra, cast_int(L->top - ra)); | 1594 | luaD_poscall(L, ci, cast_int(L->top - ra)); |
| 1595 | return; | 1595 | return; |
| 1596 | } | 1596 | } |
| 1597 | else { /* Lua tail call */ | 1597 | else { /* Lua tail call */ |
| @@ -1602,20 +1602,25 @@ void luaV_execute (lua_State *L, CallInfo *ci) { | |||
| 1602 | vmbreak; | 1602 | vmbreak; |
| 1603 | } | 1603 | } |
| 1604 | vmcase(OP_RETURN) { | 1604 | vmcase(OP_RETURN) { |
| 1605 | int b = GETARG_B(i); | 1605 | int n = GETARG_B(i) - 1; /* number of results */ |
| 1606 | int n = (b != 0 ? b - 1 : cast_int(L->top - ra)); | 1606 | if (n < 0) /* not fixed? */ |
| 1607 | n = cast_int(L->top - ra); /* get what is available */ | ||
| 1608 | else | ||
| 1609 | L->top = ra + n; /* set call for 'luaD_poscall' */ | ||
| 1607 | if (TESTARG_k(i)) { | 1610 | if (TESTARG_k(i)) { |
| 1608 | int nparams1 = GETARG_C(i); | 1611 | int nparams1 = GETARG_C(i); |
| 1609 | if (nparams1) /* vararg function? */ | 1612 | if (nparams1) /* vararg function? */ |
| 1610 | ci->func -= ci->u.l.nextraargs + nparams1; | 1613 | ci->func -= ci->u.l.nextraargs + nparams1; |
| 1611 | luaF_close(L, base); /* there may be open upvalues */ | 1614 | luaF_close(L, base); /* there may be open upvalues */ |
| 1612 | } | 1615 | } |
| 1613 | halfProtect(luaD_poscall(L, ci, ra, n)); | 1616 | halfProtect(luaD_poscall(L, ci, n)); |
| 1614 | return; | 1617 | return; |
| 1615 | } | 1618 | } |
| 1616 | vmcase(OP_RETURN0) { | 1619 | vmcase(OP_RETURN0) { |
| 1617 | if (L->hookmask) | 1620 | if (L->hookmask) { |
| 1618 | halfProtect(luaD_poscall(L, ci, ra, 0)); /* no hurry... */ | 1621 | L->top = ra; |
| 1622 | halfProtect(luaD_poscall(L, ci, 0)); /* no hurry... */ | ||
| 1623 | } | ||
| 1619 | else { | 1624 | else { |
| 1620 | int nres = ci->nresults; | 1625 | int nres = ci->nresults; |
| 1621 | L->ci = ci->previous; /* back to caller */ | 1626 | L->ci = ci->previous; /* back to caller */ |
| @@ -1626,8 +1631,10 @@ void luaV_execute (lua_State *L, CallInfo *ci) { | |||
| 1626 | return; | 1631 | return; |
| 1627 | } | 1632 | } |
| 1628 | vmcase(OP_RETURN1) { | 1633 | vmcase(OP_RETURN1) { |
| 1629 | if (L->hookmask) | 1634 | if (L->hookmask) { |
| 1630 | halfProtect(luaD_poscall(L, ci, ra, 1)); /* no hurry... */ | 1635 | L->top = ra + 1; |
| 1636 | halfProtect(luaD_poscall(L, ci, 1)); /* no hurry... */ | ||
| 1637 | } | ||
| 1631 | else { | 1638 | else { |
| 1632 | int nres = ci->nresults; | 1639 | int nres = ci->nresults; |
| 1633 | L->ci = ci->previous; /* back to caller */ | 1640 | L->ci = ci->previous; /* back to caller */ |
