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 { |