Mercurial > vim
comparison src/vim9execute.c @ 24220:a7a9176bb542 v8.2.2651
patch 8.2.2651: Vim9: restoring command modifiers happens after jump
Commit: https://github.com/vim/vim/commit/a91a71322dc2e6a1640e73b6da1f1a2f94f39a54
Author: Bram Moolenaar <Bram@vim.org>
Date: Thu Mar 25 21:12:15 2021 +0100
patch 8.2.2651: Vim9: restoring command modifiers happens after jump
Problem: Vim9: restoring command modifiers happens after jump.
Solution: Move the restore instruction to before the jump. (closes https://github.com/vim/vim/issues/8006)
Also handle for and while.
author | Bram Moolenaar <Bram@vim.org> |
---|---|
date | Thu, 25 Mar 2021 21:15:04 +0100 |
parents | 40e27d96e395 |
children | f49f80a0905d |
comparison
equal
deleted
inserted
replaced
24219:529521098193 | 24220:a7a9176bb542 |
---|---|
791 } | 791 } |
792 if (did_emsg > did_emsg_before) | 792 if (did_emsg > did_emsg_before) |
793 // Error other than from calling the function itself. | 793 // Error other than from calling the function itself. |
794 return FAIL; | 794 return FAIL; |
795 return OK; | 795 return OK; |
796 } | |
797 | |
798 /* | |
799 * If command modifiers were applied restore them. | |
800 */ | |
801 static void | |
802 may_restore_cmdmod(funclocal_T *funclocal) | |
803 { | |
804 if (funclocal->floc_restore_cmdmod) | |
805 { | |
806 cmdmod.cmod_filter_regmatch.regprog = NULL; | |
807 undo_cmdmod(&cmdmod); | |
808 cmdmod = funclocal->floc_save_cmdmod; | |
809 funclocal->floc_restore_cmdmod = FALSE; | |
810 } | |
796 } | 811 } |
797 | 812 |
798 /* | 813 /* |
799 * Return TRUE if an error was given or CTRL-C was pressed. | 814 * Return TRUE if an error was given or CTRL-C was pressed. |
800 */ | 815 */ |
2717 // push the next item from the list | 2732 // push the next item from the list |
2718 if (GA_GROW(&ectx.ec_stack, 1) == FAIL) | 2733 if (GA_GROW(&ectx.ec_stack, 1) == FAIL) |
2719 goto failed; | 2734 goto failed; |
2720 ++idxtv->vval.v_number; | 2735 ++idxtv->vval.v_number; |
2721 if (list == NULL || idxtv->vval.v_number >= list->lv_len) | 2736 if (list == NULL || idxtv->vval.v_number >= list->lv_len) |
2737 { | |
2722 // past the end of the list, jump to "endfor" | 2738 // past the end of the list, jump to "endfor" |
2723 ectx.ec_iidx = iptr->isn_arg.forloop.for_end; | 2739 ectx.ec_iidx = iptr->isn_arg.forloop.for_end; |
2740 may_restore_cmdmod(&funclocal); | |
2741 } | |
2724 else if (list->lv_first == &range_list_item) | 2742 else if (list->lv_first == &range_list_item) |
2725 { | 2743 { |
2726 // non-materialized range() list | 2744 // non-materialized range() list |
2727 tv = STACK_TV_BOT(0); | 2745 tv = STACK_TV_BOT(0); |
2728 tv->v_type = VAR_NUMBER; | 2746 tv->v_type = VAR_NUMBER; |
2753 ++ectx.ec_trystack.ga_len; | 2771 ++ectx.ec_trystack.ga_len; |
2754 ++trylevel; | 2772 ++trylevel; |
2755 CLEAR_POINTER(trycmd); | 2773 CLEAR_POINTER(trycmd); |
2756 trycmd->tcd_frame_idx = ectx.ec_frame_idx; | 2774 trycmd->tcd_frame_idx = ectx.ec_frame_idx; |
2757 trycmd->tcd_stack_len = ectx.ec_stack.ga_len; | 2775 trycmd->tcd_stack_len = ectx.ec_stack.ga_len; |
2758 trycmd->tcd_catch_idx = iptr->isn_arg.try.try_ref->try_catch; | 2776 trycmd->tcd_catch_idx = |
2759 trycmd->tcd_finally_idx = iptr->isn_arg.try.try_ref->try_finally; | 2777 iptr->isn_arg.try.try_ref->try_catch; |
2760 trycmd->tcd_endtry_idx = iptr->isn_arg.try.try_ref->try_endtry; | 2778 trycmd->tcd_finally_idx = |
2779 iptr->isn_arg.try.try_ref->try_finally; | |
2780 trycmd->tcd_endtry_idx = | |
2781 iptr->isn_arg.try.try_ref->try_endtry; | |
2761 } | 2782 } |
2762 break; | 2783 break; |
2763 | 2784 |
2764 case ISN_PUSHEXC: | 2785 case ISN_PUSHEXC: |
2765 if (current_exception == NULL) | 2786 if (current_exception == NULL) |
2780 | 2801 |
2781 case ISN_CATCH: | 2802 case ISN_CATCH: |
2782 { | 2803 { |
2783 garray_T *trystack = &ectx.ec_trystack; | 2804 garray_T *trystack = &ectx.ec_trystack; |
2784 | 2805 |
2785 if (funclocal.floc_restore_cmdmod) | 2806 may_restore_cmdmod(&funclocal); |
2786 { | |
2787 cmdmod.cmod_filter_regmatch.regprog = NULL; | |
2788 undo_cmdmod(&cmdmod); | |
2789 cmdmod = funclocal.floc_save_cmdmod; | |
2790 funclocal.floc_restore_cmdmod = FALSE; | |
2791 } | |
2792 if (trystack->ga_len > 0) | 2807 if (trystack->ga_len > 0) |
2793 { | 2808 { |
2794 trycmd_T *trycmd = ((trycmd_T *)trystack->ga_data) | 2809 trycmd_T *trycmd = ((trycmd_T *)trystack->ga_data) |
2795 + trystack->ga_len - 1; | 2810 + trystack->ga_len - 1; |
2796 trycmd->tcd_caught = TRUE; | 2811 trycmd->tcd_caught = TRUE; |