aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ldo.c69
-rw-r--r--ldo.h5
-rw-r--r--lvm.c25
3 files changed, 48 insertions, 51 deletions
diff --git a/ldo.c b/ldo.c
index 41b41756..169eb714 100644
--- a/ldo.c
+++ b/ldo.c
@@ -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
322static void rethook (lua_State *L, CallInfo *ci, StkId firstres, int nres) { 322static 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*/
366static void moveresults (lua_State *L, StkId firstResult, StkId res, 368static 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*/
407void luaD_poscall (lua_State *L, CallInfo *ci, StkId firstResult, int nres) { 402void 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 }
diff --git a/ldo.h b/ldo.h
index 1fdc75be..a3ac6f50 100644
--- a/ldo.h
+++ b/ldo.h
@@ -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);
61LUAI_FUNC void luaD_tryfuncTM (lua_State *L, StkId func); 61LUAI_FUNC void luaD_tryfuncTM (lua_State *L, StkId func);
62LUAI_FUNC int luaD_pcall (lua_State *L, Pfunc func, void *u, 62LUAI_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);
64LUAI_FUNC void luaD_poscall (lua_State *L, CallInfo *ci, StkId firstResult, 64LUAI_FUNC void luaD_poscall (lua_State *L, CallInfo *ci, int nres);
65 int nres);
66LUAI_FUNC int luaD_reallocstack (lua_State *L, int newsize, int raiseerror); 65LUAI_FUNC int luaD_reallocstack (lua_State *L, int newsize, int raiseerror);
67LUAI_FUNC int luaD_growstack (lua_State *L, int n, int raiseerror); 66LUAI_FUNC int luaD_growstack (lua_State *L, int n, int raiseerror);
68LUAI_FUNC void luaD_shrinkstack (lua_State *L); 67LUAI_FUNC void luaD_shrinkstack (lua_State *L);
diff --git a/lvm.c b/lvm.c
index 347a8269..4406afb6 100644
--- a/lvm.c
+++ b/lvm.c
@@ -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 */