diff options
author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2017-11-29 14:57:36 -0200 |
---|---|---|
committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2017-11-29 14:57:36 -0200 |
commit | 745eb4199333f153a28c75837b6a1addf614f4a9 (patch) | |
tree | 9eb2cfe63700db8e2102d980d603ee294111cb14 /lvm.c | |
parent | c766e4103db888063c4f928747afd6eb448e306f (diff) | |
download | lua-745eb4199333f153a28c75837b6a1addf614f4a9.tar.gz lua-745eb4199333f153a28c75837b6a1addf614f4a9.tar.bz2 lua-745eb4199333f153a28c75837b6a1addf614f4a9.zip |
new opcodes OP_RETURN0/OP_RETURN1
Diffstat (limited to 'lvm.c')
-rw-r--r-- | lvm.c | 69 |
1 files changed, 56 insertions, 13 deletions
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: lvm.c,v 2.320 2017/11/28 14:51:00 roberto Exp roberto $ | 2 | ** $Id: lvm.c,v 2.321 2017/11/29 13:02:17 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 | */ |
@@ -798,6 +798,11 @@ void luaV_finishOp (lua_State *L) { | |||
798 | */ | 798 | */ |
799 | #define Protect(exp) (savepc(L), (exp), updatetrap(ci)) | 799 | #define Protect(exp) (savepc(L), (exp), updatetrap(ci)) |
800 | 800 | ||
801 | /* | ||
802 | ** Protect code that will return. | ||
803 | */ | ||
804 | #define halfProtect(exp) (savepc(L), (exp)) | ||
805 | |||
801 | 806 | ||
802 | #define checkGC(L,c) \ | 807 | #define checkGC(L,c) \ |
803 | { luaC_condGC(L, L->top = (c), /* limit of live values */ \ | 808 | { luaC_condGC(L, L->top = (c), /* limit of live values */ \ |
@@ -824,11 +829,16 @@ void luaV_finishOp (lua_State *L) { | |||
824 | 829 | ||
825 | 830 | ||
826 | void luaV_execute (lua_State *L, CallInfo *ci) { | 831 | void luaV_execute (lua_State *L, CallInfo *ci) { |
827 | LClosure *cl = clLvalue(s2v(ci->func)); | 832 | LClosure *cl; |
828 | TValue *k = cl->p->k; | 833 | TValue *k; |
829 | StkId base = ci->func + 1; | 834 | StkId base; |
835 | const Instruction *pc; | ||
830 | int trap = ci->u.l.trap; | 836 | int trap = ci->u.l.trap; |
831 | const Instruction *pc = ci->u.l.savedpc; | 837 | tailcall: |
838 | cl = clLvalue(s2v(ci->func)); | ||
839 | k = cl->p->k; | ||
840 | base = ci->func + 1; | ||
841 | pc = ci->u.l.savedpc; | ||
832 | /* main loop of interpreter */ | 842 | /* main loop of interpreter */ |
833 | for (;;) { | 843 | for (;;) { |
834 | int cond; /* flag for conditional jumps */ | 844 | int cond; /* flag for conditional jumps */ |
@@ -1438,16 +1448,15 @@ void luaV_execute (lua_State *L, CallInfo *ci) { | |||
1438 | vra = s2v(ra); | 1448 | vra = s2v(ra); |
1439 | b++; /* there is now one extra argument */ | 1449 | b++; /* there is now one extra argument */ |
1440 | } | 1450 | } |
1441 | if (!ttisLclosure(vra)) /* C function? */ | 1451 | if (!ttisLclosure(vra)) { /* C function? */ |
1442 | Protect(luaD_call(L, ra, LUA_MULTRET)); /* call it */ | 1452 | Protect(luaD_call(L, ra, LUA_MULTRET)); /* call it */ |
1453 | /* next instruction will do the return */ | ||
1454 | } | ||
1443 | else { /* tail call */ | 1455 | else { /* tail call */ |
1444 | if (cl->p->sizep > 0) /* close upvalues from previous call */ | 1456 | if (cl->p->sizep > 0) /* close upvalues from previous call */ |
1445 | luaF_close(L, ci->func + 1); | 1457 | luaF_close(L, ci->func + 1); |
1446 | luaD_pretailcall(L, ci, ra, b); /* prepare call frame */ | 1458 | luaD_pretailcall(L, ci, ra, b); /* prepare call frame */ |
1447 | cl = clLvalue(s2v(ci->func)); | 1459 | goto tailcall; |
1448 | k = cl->p->k; | ||
1449 | updatebase(ci); | ||
1450 | pc = ci->u.l.savedpc; | ||
1451 | } | 1460 | } |
1452 | vmbreak; | 1461 | vmbreak; |
1453 | } | 1462 | } |
@@ -1455,9 +1464,43 @@ void luaV_execute (lua_State *L, CallInfo *ci) { | |||
1455 | int b = GETARG_B(i); | 1464 | int b = GETARG_B(i); |
1456 | if (cl->p->sizep > 0) | 1465 | if (cl->p->sizep > 0) |
1457 | luaF_close(L, base); | 1466 | luaF_close(L, base); |
1458 | savepc(L); | 1467 | halfProtect( |
1459 | luaD_poscall(L, ci, ra, (b != 0 ? b - 1 : cast_int(L->top - ra))); | 1468 | luaD_poscall(L, ci, ra, (b != 0 ? b - 1 : cast_int(L->top - ra))) |
1460 | return; /* external invocation: return */ | 1469 | ); |
1470 | return; | ||
1471 | } | ||
1472 | vmcase(OP_RETURN0) { | ||
1473 | if (cl->p->sizep > 0) | ||
1474 | luaF_close(L, base); | ||
1475 | if (L->hookmask) | ||
1476 | halfProtect(luaD_poscall(L, ci, ra, 0)); /* no hurry... */ | ||
1477 | else { | ||
1478 | int nres = ci->nresults; | ||
1479 | L->ci = ci->previous; /* back to caller */ | ||
1480 | L->top = base - 1; | ||
1481 | while (nres-- > 0) | ||
1482 | setnilvalue(s2v(L->top++)); /* all results are nil */ | ||
1483 | } | ||
1484 | return; | ||
1485 | } | ||
1486 | vmcase(OP_RETURN1) { | ||
1487 | if (cl->p->sizep > 0) | ||
1488 | luaF_close(L, base); | ||
1489 | if (L->hookmask) | ||
1490 | halfProtect(luaD_poscall(L, ci, ra, 1)); /* no hurry... */ | ||
1491 | else { | ||
1492 | int nres = ci->nresults; | ||
1493 | L->ci = ci->previous; /* back to caller */ | ||
1494 | if (nres == 0) | ||
1495 | L->top = base - 1; /* asked for no results */ | ||
1496 | else { | ||
1497 | setobjs2s(L, base - 1, ra); /* at least this result */ | ||
1498 | L->top = base; | ||
1499 | while (--nres > 0) /* complete missing results */ | ||
1500 | setnilvalue(s2v(L->top++)); | ||
1501 | } | ||
1502 | } | ||
1503 | return; | ||
1461 | } | 1504 | } |
1462 | vmcase(OP_FORLOOP) { | 1505 | vmcase(OP_FORLOOP) { |
1463 | if (ttisinteger(vra)) { /* integer loop? */ | 1506 | if (ttisinteger(vra)) { /* integer loop? */ |