Mercurial > vim
comparison src/vim9compile.c @ 23440:b0587f7ec422 v8.2.2263
patch 8.2.2263: Vim9: compilation error with try-catch in skipped block
Commit: https://github.com/vim/vim/commit/69f7050cebb0f069d6e39571961b9bbe8531c69a
Author: Bram Moolenaar <Bram@vim.org>
Date: Fri Jan 1 16:10:46 2021 +0100
patch 8.2.2263: Vim9: compilation error with try-catch in skipped block
Problem: Vim9: compilation error with try-catch in skipped block.
Solution: Do not bail out when generate_instr() returns NULL. (closes https://github.com/vim/vim/issues/7584)
author | Bram Moolenaar <Bram@vim.org> |
---|---|
date | Fri, 01 Jan 2021 16:15:04 +0100 |
parents | ab163feb30cb |
children | b1dbbc81a011 |
comparison
equal
deleted
inserted
replaced
23439:ce571f96b8a7 | 23440:b0587f7ec422 |
---|---|
6914 // scope that holds the jumps that go to catch/finally/endtry | 6914 // scope that holds the jumps that go to catch/finally/endtry |
6915 try_scope = new_scope(cctx, TRY_SCOPE); | 6915 try_scope = new_scope(cctx, TRY_SCOPE); |
6916 if (try_scope == NULL) | 6916 if (try_scope == NULL) |
6917 return NULL; | 6917 return NULL; |
6918 | 6918 |
6919 // "catch" is set when the first ":catch" is found. | 6919 if (cctx->ctx_skip != SKIP_YES) |
6920 // "finally" is set when ":finally" or ":endtry" is found | 6920 { |
6921 try_scope->se_u.se_try.ts_try_label = instr->ga_len; | 6921 // "catch" is set when the first ":catch" is found. |
6922 if (generate_instr(cctx, ISN_TRY) == NULL) | 6922 // "finally" is set when ":finally" or ":endtry" is found |
6923 return NULL; | 6923 try_scope->se_u.se_try.ts_try_label = instr->ga_len; |
6924 if (generate_instr(cctx, ISN_TRY) == NULL) | |
6925 return NULL; | |
6926 } | |
6924 | 6927 |
6925 // scope for the try block itself | 6928 // scope for the try block itself |
6926 scope = new_scope(cctx, BLOCK_SCOPE); | 6929 scope = new_scope(cctx, BLOCK_SCOPE); |
6927 if (scope == NULL) | 6930 if (scope == NULL) |
6928 return NULL; | 6931 return NULL; |
6957 { | 6960 { |
6958 emsg(_(e_catch_unreachable_after_catch_all)); | 6961 emsg(_(e_catch_unreachable_after_catch_all)); |
6959 return NULL; | 6962 return NULL; |
6960 } | 6963 } |
6961 | 6964 |
6962 // Jump from end of previous block to :finally or :endtry | 6965 if (cctx->ctx_skip != SKIP_YES) |
6963 if (compile_jump_to_end(&scope->se_u.se_try.ts_end_label, | 6966 { |
6967 // Jump from end of previous block to :finally or :endtry | |
6968 if (compile_jump_to_end(&scope->se_u.se_try.ts_end_label, | |
6964 JUMP_ALWAYS, cctx) == FAIL) | 6969 JUMP_ALWAYS, cctx) == FAIL) |
6965 return NULL; | 6970 return NULL; |
6966 | 6971 |
6967 // End :try or :catch scope: set value in ISN_TRY instruction | 6972 // End :try or :catch scope: set value in ISN_TRY instruction |
6968 isn = ((isn_T *)instr->ga_data) + scope->se_u.se_try.ts_try_label; | 6973 isn = ((isn_T *)instr->ga_data) + scope->se_u.se_try.ts_try_label; |
6969 if (isn->isn_arg.try.try_catch == 0) | 6974 if (isn->isn_arg.try.try_catch == 0) |
6970 isn->isn_arg.try.try_catch = instr->ga_len; | 6975 isn->isn_arg.try.try_catch = instr->ga_len; |
6971 if (scope->se_u.se_try.ts_catch_label != 0) | 6976 if (scope->se_u.se_try.ts_catch_label != 0) |
6972 { | 6977 { |
6973 // Previous catch without match jumps here | 6978 // Previous catch without match jumps here |
6974 isn = ((isn_T *)instr->ga_data) + scope->se_u.se_try.ts_catch_label; | 6979 isn = ((isn_T *)instr->ga_data) + scope->se_u.se_try.ts_catch_label; |
6975 isn->isn_arg.jump.jump_where = instr->ga_len; | 6980 isn->isn_arg.jump.jump_where = instr->ga_len; |
6981 } | |
6976 } | 6982 } |
6977 | 6983 |
6978 p = skipwhite(arg); | 6984 p = skipwhite(arg); |
6979 if (ends_excmd2(arg, p)) | 6985 if (ends_excmd2(arg, p)) |
6980 { | 6986 { |
7017 scope->se_u.se_try.ts_catch_label = instr->ga_len; | 7023 scope->se_u.se_try.ts_catch_label = instr->ga_len; |
7018 if (generate_JUMP(cctx, JUMP_IF_FALSE, 0) == FAIL) | 7024 if (generate_JUMP(cctx, JUMP_IF_FALSE, 0) == FAIL) |
7019 return NULL; | 7025 return NULL; |
7020 } | 7026 } |
7021 | 7027 |
7022 if (generate_instr(cctx, ISN_CATCH) == NULL) | 7028 if (cctx->ctx_skip != SKIP_YES && generate_instr(cctx, ISN_CATCH) == NULL) |
7023 return NULL; | 7029 return NULL; |
7024 | 7030 |
7025 if (new_scope(cctx, BLOCK_SCOPE) == NULL) | 7031 if (new_scope(cctx, BLOCK_SCOPE) == NULL) |
7026 return NULL; | 7032 return NULL; |
7027 return p; | 7033 return p; |
7095 else | 7101 else |
7096 emsg(_(e_endif)); | 7102 emsg(_(e_endif)); |
7097 return NULL; | 7103 return NULL; |
7098 } | 7104 } |
7099 | 7105 |
7100 isn = ((isn_T *)instr->ga_data) + scope->se_u.se_try.ts_try_label; | 7106 if (cctx->ctx_skip != SKIP_YES) |
7101 if (isn->isn_arg.try.try_catch == 0 && isn->isn_arg.try.try_finally == 0) | 7107 { |
7102 { | 7108 isn = ((isn_T *)instr->ga_data) + scope->se_u.se_try.ts_try_label; |
7103 emsg(_(e_missing_catch_or_finally)); | 7109 if (isn->isn_arg.try.try_catch == 0 |
7104 return NULL; | 7110 && isn->isn_arg.try.try_finally == 0) |
7105 } | 7111 { |
7106 | 7112 emsg(_(e_missing_catch_or_finally)); |
7107 // Fill in the "end" label in jumps at the end of the blocks, if not done | 7113 return NULL; |
7108 // by ":finally". | 7114 } |
7109 compile_fill_jump_to_end(&scope->se_u.se_try.ts_end_label, cctx); | 7115 |
7110 | 7116 // Fill in the "end" label in jumps at the end of the blocks, if not |
7111 // End :catch or :finally scope: set value in ISN_TRY instruction | 7117 // done by ":finally". |
7112 if (isn->isn_arg.try.try_catch == 0) | 7118 compile_fill_jump_to_end(&scope->se_u.se_try.ts_end_label, cctx); |
7113 isn->isn_arg.try.try_catch = instr->ga_len; | 7119 |
7114 if (isn->isn_arg.try.try_finally == 0) | 7120 // End :catch or :finally scope: set value in ISN_TRY instruction |
7115 isn->isn_arg.try.try_finally = instr->ga_len; | 7121 if (isn->isn_arg.try.try_catch == 0) |
7116 | 7122 isn->isn_arg.try.try_catch = instr->ga_len; |
7117 if (scope->se_u.se_try.ts_catch_label != 0) | 7123 if (isn->isn_arg.try.try_finally == 0) |
7118 { | 7124 isn->isn_arg.try.try_finally = instr->ga_len; |
7119 // Last catch without match jumps here | 7125 |
7120 isn = ((isn_T *)instr->ga_data) + scope->se_u.se_try.ts_catch_label; | 7126 if (scope->se_u.se_try.ts_catch_label != 0) |
7121 isn->isn_arg.jump.jump_where = instr->ga_len; | 7127 { |
7128 // Last catch without match jumps here | |
7129 isn = ((isn_T *)instr->ga_data) + scope->se_u.se_try.ts_catch_label; | |
7130 isn->isn_arg.jump.jump_where = instr->ga_len; | |
7131 } | |
7122 } | 7132 } |
7123 | 7133 |
7124 compile_endblock(cctx); | 7134 compile_endblock(cctx); |
7125 | 7135 |
7126 if (generate_instr(cctx, ISN_ENDTRY) == NULL) | 7136 if (cctx->ctx_skip != SKIP_YES && generate_instr(cctx, ISN_ENDTRY) == NULL) |
7127 return NULL; | 7137 return NULL; |
7128 return arg; | 7138 return arg; |
7129 } | 7139 } |
7130 | 7140 |
7131 /* | 7141 /* |