@@ -7518,10 +7518,17 @@ compile_try(char_u *arg, cctx_T *cctx)
75187518
75197519 if (cctx -> ctx_skip != SKIP_YES )
75207520 {
7521- // "catch" is set when the first ":catch" is found.
7522- // "finally" is set when ":finally" or ":endtry" is found
7521+ isn_T * isn ;
7522+
7523+ // "try_catch" is set when the first ":catch" is found or when no catch
7524+ // is found and ":finally" is found.
7525+ // "try_finally" is set when ":finally" is found
7526+ // "try_endtry" is set when ":endtry" is found
75237527 try_scope -> se_u .se_try .ts_try_label = instr -> ga_len ;
7524- if (generate_instr (cctx , ISN_TRY ) == NULL )
7528+ if ((isn = generate_instr (cctx , ISN_TRY )) == NULL )
7529+ return NULL ;
7530+ isn -> isn_arg .try .try_ref = ALLOC_CLEAR_ONE (tryref_T );
7531+ if (isn -> isn_arg .try .try_ref == NULL )
75257532 return NULL ;
75267533 }
75277534
@@ -7577,8 +7584,8 @@ compile_catch(char_u *arg, cctx_T *cctx UNUSED)
75777584
75787585 // End :try or :catch scope: set value in ISN_TRY instruction
75797586 isn = ((isn_T * )instr -> ga_data ) + scope -> se_u .se_try .ts_try_label ;
7580- if (isn -> isn_arg .try .try_catch == 0 )
7581- isn -> isn_arg .try .try_catch = instr -> ga_len ;
7587+ if (isn -> isn_arg .try .try_ref -> try_catch == 0 )
7588+ isn -> isn_arg .try .try_ref -> try_catch = instr -> ga_len ;
75827589 if (scope -> se_u .se_try .ts_catch_label != 0 )
75837590 {
75847591 // Previous catch without match jumps here
@@ -7670,7 +7677,7 @@ compile_finally(char_u *arg, cctx_T *cctx)
76707677
76717678 // End :catch or :finally scope: set value in ISN_TRY instruction
76727679 isn = ((isn_T * )instr -> ga_data ) + scope -> se_u .se_try .ts_try_label ;
7673- if (isn -> isn_arg .try .try_finally != 0 )
7680+ if (isn -> isn_arg .try .try_ref -> try_finally != 0 )
76747681 {
76757682 emsg (_ (e_finally_dup ));
76767683 return NULL ;
@@ -7688,14 +7695,19 @@ compile_finally(char_u *arg, cctx_T *cctx)
76887695 compile_fill_jump_to_end (& scope -> se_u .se_try .ts_end_label ,
76897696 this_instr , cctx );
76907697
7691- isn -> isn_arg .try .try_finally = this_instr ;
7698+ // If there is no :catch then an exception jumps to :finally.
7699+ if (isn -> isn_arg .try .try_ref -> try_catch == 0 )
7700+ isn -> isn_arg .try .try_ref -> try_catch = this_instr ;
7701+ isn -> isn_arg .try .try_ref -> try_finally = this_instr ;
76927702 if (scope -> se_u .se_try .ts_catch_label != 0 )
76937703 {
76947704 // Previous catch without match jumps here
76957705 isn = ((isn_T * )instr -> ga_data ) + scope -> se_u .se_try .ts_catch_label ;
76967706 isn -> isn_arg .jump .jump_where = this_instr ;
76977707 scope -> se_u .se_try .ts_catch_label = 0 ;
76987708 }
7709+ if (generate_instr (cctx , ISN_FINALLY ) == NULL )
7710+ return NULL ;
76997711
77007712 // TODO: set index in ts_finally_label jumps
77017713
@@ -7731,8 +7743,8 @@ compile_endtry(char_u *arg, cctx_T *cctx)
77317743 try_isn = ((isn_T * )instr -> ga_data ) + scope -> se_u .se_try .ts_try_label ;
77327744 if (cctx -> ctx_skip != SKIP_YES )
77337745 {
7734- if (try_isn -> isn_arg .try .try_catch == 0
7735- && try_isn -> isn_arg .try .try_finally == 0 )
7746+ if (try_isn -> isn_arg .try .try_ref -> try_catch == 0
7747+ && try_isn -> isn_arg .try .try_ref -> try_finally == 0 )
77367748 {
77377749 emsg (_ (e_missing_catch_or_finally ));
77387750 return NULL ;
@@ -7751,12 +7763,6 @@ compile_endtry(char_u *arg, cctx_T *cctx)
77517763 compile_fill_jump_to_end (& scope -> se_u .se_try .ts_end_label ,
77527764 instr -> ga_len , cctx );
77537765
7754- // End :catch or :finally scope: set value in ISN_TRY instruction
7755- if (try_isn -> isn_arg .try .try_catch == 0 )
7756- try_isn -> isn_arg .try .try_catch = instr -> ga_len ;
7757- if (try_isn -> isn_arg .try .try_finally == 0 )
7758- try_isn -> isn_arg .try .try_finally = instr -> ga_len ;
7759-
77607766 if (scope -> se_u .se_try .ts_catch_label != 0 )
77617767 {
77627768 // Last catch without match jumps here
@@ -7770,11 +7776,9 @@ compile_endtry(char_u *arg, cctx_T *cctx)
77707776
77717777 if (cctx -> ctx_skip != SKIP_YES )
77727778 {
7773- if (try_isn -> isn_arg .try .try_finally == 0 )
7774- // No :finally encountered, use the try_finaly field to point to
7775- // ENDTRY, so that TRYCONT can jump there.
7776- try_isn -> isn_arg .try .try_finally = instr -> ga_len ;
7777-
7779+ // End :catch or :finally scope: set instruction index in ISN_TRY
7780+ // instruction
7781+ try_isn -> isn_arg .try .try_ref -> try_endtry = instr -> ga_len ;
77787782 if (cctx -> ctx_skip != SKIP_YES
77797783 && generate_instr (cctx , ISN_ENDTRY ) == NULL )
77807784 return NULL ;
@@ -8867,6 +8871,10 @@ delete_instr(isn_T *isn)
88678871 vim_free (isn -> isn_arg .script .scriptref );
88688872 break ;
88698873
8874+ case ISN_TRY :
8875+ vim_free (isn -> isn_arg .try .try_ref );
8876+ break ;
8877+
88708878 case ISN_2BOOL :
88718879 case ISN_2STRING :
88728880 case ISN_2STRING_ANY :
@@ -8899,6 +8907,7 @@ delete_instr(isn_T *isn)
88998907 case ISN_ENDTRY :
89008908 case ISN_EXECCONCAT :
89018909 case ISN_EXECUTE :
8910+ case ISN_FINALLY :
89028911 case ISN_FOR :
89038912 case ISN_GETITEM :
89048913 case ISN_JUMP :
@@ -8943,7 +8952,6 @@ delete_instr(isn_T *isn)
89438952 case ISN_STRINDEX :
89448953 case ISN_STRSLICE :
89458954 case ISN_THROW :
8946- case ISN_TRY :
89478955 case ISN_TRYCONT :
89488956 case ISN_UNLETINDEX :
89498957 case ISN_UNLETRANGE :
0 commit comments