diff options
| author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2018-02-15 13:34:29 -0200 |
|---|---|---|
| committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2018-02-15 13:34:29 -0200 |
| commit | 0682fe816929da2e5abe8e191ad9c8509e6bfc12 (patch) | |
| tree | bac8b079fde63e7f2e436e51ed6fd571dfd6f195 /lvm.c | |
| parent | b1379936cf35787d3ef3aab82d1607a3e1562eef (diff) | |
| download | lua-0682fe816929da2e5abe8e191ad9c8509e6bfc12.tar.gz lua-0682fe816929da2e5abe8e191ad9c8509e6bfc12.tar.bz2 lua-0682fe816929da2e5abe8e191ad9c8509e6bfc12.zip | |
some simplifications/optimizations in returns from Lua functions
Diffstat (limited to 'lvm.c')
| -rw-r--r-- | lvm.c | 60 |
1 files changed, 26 insertions, 34 deletions
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: lvm.c,v 2.338 2018/02/07 15:18:04 roberto Exp roberto $ | 2 | ** $Id: lvm.c,v 2.339 2018/02/09 15:16:06 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 | */ |
| @@ -1493,23 +1493,35 @@ void luaV_execute (lua_State *L, CallInfo *ci) { | |||
| 1493 | } | 1493 | } |
| 1494 | vmcase(OP_TAILCALL) { | 1494 | vmcase(OP_TAILCALL) { |
| 1495 | int b = GETARG_B(i); /* number of arguments + 1 (function) */ | 1495 | int b = GETARG_B(i); /* number of arguments + 1 (function) */ |
| 1496 | int delta = 0; /* virtual 'func' - real 'func' (vararg functions) */ | ||
| 1496 | if (b != 0) | 1497 | if (b != 0) |
| 1497 | L->top = ra + b; | 1498 | L->top = ra + b; |
| 1498 | else /* previous instruction set top */ | 1499 | else /* previous instruction set top */ |
| 1499 | b = cast_int(L->top - ra); | 1500 | b = cast_int(L->top - ra); |
| 1500 | lua_assert(GETARG_C(i) - 1 == LUA_MULTRET); | 1501 | savepc(ci); |
| 1502 | if (TESTARG_k(i)) { | ||
| 1503 | int nparams1 = GETARG_C(i); | ||
| 1504 | if (nparams1) /* vararg function? */ | ||
| 1505 | delta = ci->u.l.nextraargs + nparams1; | ||
| 1506 | luaF_close(L, base); /* close upvalues from current call */ | ||
| 1507 | } | ||
| 1501 | if (!ttisfunction(vra)) { /* not a function? */ | 1508 | if (!ttisfunction(vra)) { /* not a function? */ |
| 1502 | ProtectNT(luaD_tryfuncTM(L, ra)); /* try '__call' metamethod */ | 1509 | luaD_tryfuncTM(L, ra); /* try '__call' metamethod */ |
| 1503 | b++; /* there is now one extra argument */ | 1510 | b++; /* there is now one extra argument */ |
| 1504 | } | 1511 | } |
| 1505 | if (TESTARG_k(i)) | ||
| 1506 | luaF_close(L, base); /* close upvalues from current call */ | ||
| 1507 | if (!ttisLclosure(vra)) { /* C function? */ | 1512 | if (!ttisLclosure(vra)) { /* C function? */ |
| 1508 | ProtectNT(luaD_call(L, ra, LUA_MULTRET)); /* call it */ | 1513 | luaD_call(L, ra, LUA_MULTRET); /* call it */ |
| 1514 | updatetrap(ci); | ||
| 1515 | if (trap) { /* stack may have been relocated */ | ||
| 1516 | updatebase(ci); | ||
| 1517 | ra = RA(i); | ||
| 1518 | } | ||
| 1519 | ci->func -= delta; | ||
| 1520 | luaD_poscall(L, ci, ra, cast_int(L->top - ra)); | ||
| 1521 | return; | ||
| 1509 | } | 1522 | } |
| 1510 | else { /* Lua tail call */ | 1523 | else { /* Lua tail call */ |
| 1511 | if (cl->p->is_vararg) | 1524 | ci->func -= delta; |
| 1512 | ci->func -= cl->p->numparams + ci->u.l.nextraargs + 1; | ||
| 1513 | luaD_pretailcall(L, ci, ra, b); /* prepare call frame */ | 1525 | luaD_pretailcall(L, ci, ra, b); /* prepare call frame */ |
| 1514 | goto tailcall; | 1526 | goto tailcall; |
| 1515 | } | 1527 | } |
| @@ -1518,34 +1530,16 @@ void luaV_execute (lua_State *L, CallInfo *ci) { | |||
| 1518 | vmcase(OP_RETURN) { | 1530 | vmcase(OP_RETURN) { |
| 1519 | int b = GETARG_B(i); | 1531 | int b = GETARG_B(i); |
| 1520 | int n = (b != 0 ? b - 1 : cast_int(L->top - ra)); | 1532 | int n = (b != 0 ? b - 1 : cast_int(L->top - ra)); |
| 1521 | if (TESTARG_k(i)) | 1533 | if (TESTARG_k(i)) { |
| 1522 | luaF_close(L, base); | 1534 | int nparams1 = GETARG_C(i); |
| 1523 | halfProtect(luaD_poscall(L, ci, ra, n)); | 1535 | if (nparams1) /* vararg function? */ |
| 1524 | return; | 1536 | ci->func -= ci->u.l.nextraargs + nparams1; |
| 1525 | } | 1537 | luaF_close(L, base); /* there may be open upvalues */ |
| 1526 | vmcase(OP_RETVARARG) { | ||
| 1527 | int b = GETARG_B(i); | ||
| 1528 | int nparams = GETARG_C(i); | ||
| 1529 | int nres = (b != 0 ? b - 1 : cast_int(L->top - ra)); | ||
| 1530 | int delta = ci->u.l.nextraargs + nparams + 2; | ||
| 1531 | if (TESTARG_k(i)) | ||
| 1532 | luaF_close(L, base); | ||
| 1533 | savepc(L); | ||
| 1534 | /* code similar to 'luaD_poscall', but with a delta */ | ||
| 1535 | if (L->hookmask) { | ||
| 1536 | luaD_rethook(L, ci); | ||
| 1537 | if (ci->u.l.trap) { | ||
| 1538 | updatebase(ci); | ||
| 1539 | ra = RA(i); | ||
| 1540 | } | ||
| 1541 | } | 1538 | } |
| 1542 | L->ci = ci->previous; /* back to caller */ | 1539 | halfProtect(luaD_poscall(L, ci, ra, n)); |
| 1543 | luaD_moveresults(L, ra, base - delta, nres, ci->nresults); | ||
| 1544 | return; | 1540 | return; |
| 1545 | } | 1541 | } |
| 1546 | vmcase(OP_RETURN0) { | 1542 | vmcase(OP_RETURN0) { |
| 1547 | if (TESTARG_k(i)) | ||
| 1548 | luaF_close(L, base); | ||
| 1549 | if (L->hookmask) | 1543 | if (L->hookmask) |
| 1550 | halfProtect(luaD_poscall(L, ci, ra, 0)); /* no hurry... */ | 1544 | halfProtect(luaD_poscall(L, ci, ra, 0)); /* no hurry... */ |
| 1551 | else { | 1545 | else { |
| @@ -1558,8 +1552,6 @@ void luaV_execute (lua_State *L, CallInfo *ci) { | |||
| 1558 | return; | 1552 | return; |
| 1559 | } | 1553 | } |
| 1560 | vmcase(OP_RETURN1) { | 1554 | vmcase(OP_RETURN1) { |
| 1561 | if (TESTARG_k(i)) | ||
| 1562 | luaF_close(L, base); | ||
| 1563 | if (L->hookmask) | 1555 | if (L->hookmask) |
| 1564 | halfProtect(luaD_poscall(L, ci, ra, 1)); /* no hurry... */ | 1556 | halfProtect(luaD_poscall(L, ci, ra, 1)); /* no hurry... */ |
| 1565 | else { | 1557 | else { |
