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 *)"";