Mercurial > vim
comparison src/vim9compile.c @ 28173:b0c885507de4 v8.2.4612
patch 8.2.4612: Vim9: cannot use a recursive call in a nested function
Commit: https://github.com/vim/vim/commit/a915fa010330ee7212e06d3511acd363d04d2d28
Author: Bram Moolenaar <Bram@vim.org>
Date: Wed Mar 23 11:29:15 2022 +0000
patch 8.2.4612: Vim9: cannot use a recursive call in a nested function
Problem: Vim9: cannot use a recursive call in a nested function. (Sergey
Vlasov)
Solution: Define the funcref before compiling the function. (closes #9989)
author | Bram Moolenaar <Bram@vim.org> |
---|---|
date | Wed, 23 Mar 2022 12:30:04 +0100 |
parents | 088d8dc22045 |
children | 662d2d5db9a6 |
comparison
equal
deleted
inserted
replaced
28172:f5cd730da5b6 | 28173:b0c885507de4 |
---|---|
816 char_u *func_name; | 816 char_u *func_name; |
817 char_u *lambda_name; | 817 char_u *lambda_name; |
818 ufunc_T *ufunc; | 818 ufunc_T *ufunc; |
819 int r = FAIL; | 819 int r = FAIL; |
820 compiletype_T compile_type; | 820 compiletype_T compile_type; |
821 isn_T *funcref_isn = NULL; | |
821 | 822 |
822 if (eap->forceit) | 823 if (eap->forceit) |
823 { | 824 { |
824 emsg(_(e_cannot_use_bang_with_nested_def)); | 825 emsg(_(e_cannot_use_bang_with_nested_def)); |
825 return NULL; | 826 return NULL; |
909 { | 910 { |
910 mch_memmove(ufunc->uf_block_ids, cctx->ctx_ufunc->uf_block_ids, | 911 mch_memmove(ufunc->uf_block_ids, cctx->ctx_ufunc->uf_block_ids, |
911 sizeof(int) * block_depth); | 912 sizeof(int) * block_depth); |
912 ufunc->uf_block_depth = block_depth; | 913 ufunc->uf_block_depth = block_depth; |
913 } | 914 } |
915 } | |
916 | |
917 // Define the funcref before compiling, so that it is found by any | |
918 // recursive call. | |
919 if (is_global) | |
920 { | |
921 r = generate_NEWFUNC(cctx, lambda_name, func_name); | |
922 func_name = NULL; | |
923 lambda_name = NULL; | |
924 } | |
925 else | |
926 { | |
927 // Define a local variable for the function reference. | |
928 lvar_T *lvar = reserve_local(cctx, func_name, name_end - name_start, | |
929 TRUE, ufunc->uf_func_type); | |
930 | |
931 if (lvar == NULL) | |
932 goto theend; | |
933 if (generate_FUNCREF(cctx, ufunc, &funcref_isn) == FAIL) | |
934 goto theend; | |
935 r = generate_STORE(cctx, ISN_STORE, lvar->lv_idx, NULL); | |
914 } | 936 } |
915 | 937 |
916 compile_type = get_compile_type(ufunc); | 938 compile_type = get_compile_type(ufunc); |
917 #ifdef FEAT_PROFILE | 939 #ifdef FEAT_PROFILE |
918 // If the outer function is profiled, also compile the nested function for | 940 // If the outer function is profiled, also compile the nested function for |
932 // may be called without profiling. Compile it here in the right context. | 954 // may be called without profiling. Compile it here in the right context. |
933 if (compile_type == CT_PROFILE && func_needs_compiling(ufunc, CT_NONE)) | 955 if (compile_type == CT_PROFILE && func_needs_compiling(ufunc, CT_NONE)) |
934 compile_def_function(ufunc, FALSE, CT_NONE, cctx); | 956 compile_def_function(ufunc, FALSE, CT_NONE, cctx); |
935 #endif | 957 #endif |
936 | 958 |
937 if (is_global) | 959 // If a FUNCREF instruction was generated, set the index after compiling. |
938 { | 960 if (funcref_isn != NULL && ufunc->uf_def_status == UF_COMPILED) |
939 r = generate_NEWFUNC(cctx, lambda_name, func_name); | 961 funcref_isn->isn_arg.funcref.fr_dfunc_idx = ufunc->uf_dfunc_idx; |
940 func_name = NULL; | |
941 lambda_name = NULL; | |
942 } | |
943 else | |
944 { | |
945 // Define a local variable for the function reference. | |
946 lvar_T *lvar = reserve_local(cctx, func_name, name_end - name_start, | |
947 TRUE, ufunc->uf_func_type); | |
948 | |
949 if (lvar == NULL) | |
950 goto theend; | |
951 if (generate_FUNCREF(cctx, ufunc) == FAIL) | |
952 goto theend; | |
953 r = generate_STORE(cctx, ISN_STORE, lvar->lv_idx, NULL); | |
954 } | |
955 | 962 |
956 theend: | 963 theend: |
957 vim_free(lambda_name); | 964 vim_free(lambda_name); |
958 vim_free(func_name); | 965 vim_free(func_name); |
959 return r == FAIL ? NULL : (char_u *)""; | 966 return r == FAIL ? NULL : (char_u *)""; |