** finish execution of an opcode interrupted by an yield */
| 700 | ** finish execution of an opcode interrupted by an yield |
| 701 | */ |
| 702 | void luaV_finishOp(lua_State *L) { |
| 703 | CallInfo *ci = L->ci; |
| 704 | StkId base = ci->u.l.base; |
| 705 | Instruction inst = *(ci->u.l.savedpc - 1); /* interrupted instruction */ |
| 706 | OpCode op = GET_OPCODE(inst); |
| 707 | switch (op) { /* finish its execution */ |
| 708 | case OP_ADD: case OP_SUB: case OP_MUL: case OP_DIV: case OP_IDIV: |
| 709 | case OP_BAND: case OP_BOR: case OP_BXOR: case OP_SHL: case OP_SHR: |
| 710 | case OP_MOD: case OP_POW: |
| 711 | case OP_UNM: case OP_BNOT: case OP_LEN: |
| 712 | case OP_GETTABUP: case OP_GETTABLE: case OP_SELF: { |
| 713 | setobjs2s(L, base + GETARG_A(inst), --L->top); |
| 714 | break; |
| 715 | } |
| 716 | case OP_LE: case OP_LT: case OP_EQ: { |
| 717 | int res = !l_isfalse(L->top - 1); |
| 718 | L->top--; |
| 719 | if (ci->callstatus & CIST_LEQ) { /* "<=" using "<" instead? */ |
| 720 | lua_assert(op == OP_LE); |
| 721 | ci->callstatus ^= CIST_LEQ; /* clear mark */ |
| 722 | res = !res; /* negate result */ |
| 723 | } |
| 724 | lua_assert(GET_OPCODE(*ci->u.l.savedpc) == OP_JMP); |
| 725 | if (res != GETARG_A(inst)) /* condition failed? */ |
| 726 | ci->u.l.savedpc++; /* skip jump instruction */ |
| 727 | break; |
| 728 | } |
| 729 | case OP_CONCAT: { |
| 730 | StkId top = L->top - 1; /* top when 'luaT_trybinTM' was called */ |
| 731 | int b = GETARG_B(inst); /* first element to concatenate */ |
| 732 | int total = cast_int(top - 1 - (base + b)); /* yet to concatenate */ |
| 733 | setobj2s(L, top - 2, top); /* put TM result in proper position */ |
| 734 | if (total > 1) { /* are there elements to concat? */ |
| 735 | L->top = top - 1; /* top is one after last element (at top-2) */ |
| 736 | luaV_concat(L, total); /* concat them (may yield again) */ |
| 737 | } |
| 738 | /* move final result to final position */ |
| 739 | setobj2s(L, ci->u.l.base + GETARG_A(inst), L->top - 1); |
| 740 | L->top = ci->top; /* restore top */ |
| 741 | break; |
| 742 | } |
| 743 | case OP_TFORCALL: { |
| 744 | lua_assert(GET_OPCODE(*ci->u.l.savedpc) == OP_TFORLOOP); |
| 745 | L->top = ci->top; /* correct top */ |
| 746 | break; |
| 747 | } |
| 748 | case OP_CALL: { |
| 749 | if (GETARG_C(inst) - 1 >= 0) /* nresults >= 0? */ |
| 750 | L->top = ci->top; /* adjust results */ |
| 751 | break; |
| 752 | } |
| 753 | case OP_TAILCALL: case OP_SETTABUP: case OP_SETTABLE: |
| 754 | break; |
| 755 | default: lua_assert(0); |
| 756 | } |
| 757 | } |
| 758 | |
| 759 |