** finish execution of an opcode interrupted by a yield */
| 853 | ** finish execution of an opcode interrupted by a yield |
| 854 | */ |
| 855 | void luaV_finishOp (lua_State *L) { |
| 856 | CallInfo *ci = L->ci; |
| 857 | StkId base = ci->func.p + 1; |
| 858 | Instruction inst = *(ci->u.l.savedpc - 1); /* interrupted instruction */ |
| 859 | OpCode op = GET_OPCODE(inst); |
| 860 | switch (op) { /* finish its execution */ |
| 861 | case OP_MMBIN: case OP_MMBINI: case OP_MMBINK: { |
| 862 | setobjs2s(L, base + GETARG_A(*(ci->u.l.savedpc - 2)), --L->top.p); |
| 863 | break; |
| 864 | } |
| 865 | case OP_UNM: case OP_BNOT: case OP_LEN: |
| 866 | case OP_GETTABUP: case OP_GETTABLE: case OP_GETI: |
| 867 | case OP_GETFIELD: case OP_SELF: { |
| 868 | setobjs2s(L, base + GETARG_A(inst), --L->top.p); |
| 869 | break; |
| 870 | } |
| 871 | case OP_LT: case OP_LE: |
| 872 | case OP_LTI: case OP_LEI: |
| 873 | case OP_GTI: case OP_GEI: |
| 874 | case OP_EQ: { /* note that 'OP_EQI'/'OP_EQK' cannot yield */ |
| 875 | int res = !l_isfalse(s2v(L->top.p - 1)); |
| 876 | L->top.p--; |
| 877 | lua_assert(GET_OPCODE(*ci->u.l.savedpc) == OP_JMP); |
| 878 | if (res != GETARG_k(inst)) /* condition failed? */ |
| 879 | ci->u.l.savedpc++; /* skip jump instruction */ |
| 880 | break; |
| 881 | } |
| 882 | case OP_CONCAT: { |
| 883 | StkId top = L->top.p - 1; /* top when 'luaT_tryconcatTM' was called */ |
| 884 | int a = GETARG_A(inst); /* first element to concatenate */ |
| 885 | int total = cast_int(top - 1 - (base + a)); /* yet to concatenate */ |
| 886 | setobjs2s(L, top - 2, top); /* put TM result in proper position */ |
| 887 | L->top.p = top - 1; /* top is one after last element (at top-2) */ |
| 888 | luaV_concat(L, total); /* concat them (may yield again) */ |
| 889 | break; |
| 890 | } |
| 891 | case OP_CLOSE: { /* yielded closing variables */ |
| 892 | ci->u.l.savedpc--; /* repeat instruction to close other vars. */ |
| 893 | break; |
| 894 | } |
| 895 | case OP_RETURN: { /* yielded closing variables */ |
| 896 | StkId ra = base + GETARG_A(inst); |
| 897 | /* adjust top to signal correct number of returns, in case the |
| 898 | return is "up to top" ('isIT') */ |
| 899 | L->top.p = ra + ci->u2.nres; |
| 900 | /* repeat instruction to close other vars. and complete the return */ |
| 901 | ci->u.l.savedpc--; |
| 902 | break; |
| 903 | } |
| 904 | default: { |
| 905 | /* only these other opcodes can yield */ |
| 906 | lua_assert(op == OP_TFORCALL || op == OP_CALL || |
| 907 | op == OP_TAILCALL || op == OP_SETTABUP || op == OP_SETTABLE || |
| 908 | op == OP_SETI || op == OP_SETFIELD); |
| 909 | break; |
| 910 | } |
| 911 | } |
| 912 | } |