comparison src/vim9compile.c @ 23291:8e1427ac2bce v8.2.2191

patch 8.2.2191: Vim9: using wrong name with lambda in nested function Commit: https://github.com/vim/vim/commit/58a52f215a568b32c8a3aec0ccdb383f1a76dba0 Author: Bram Moolenaar <Bram@vim.org> Date: Tue Dec 22 18:56:55 2020 +0100 patch 8.2.2191: Vim9: using wrong name with lambda in nested function Problem: Vim9: using wrong name with lambda in nested function. Solution: Copy the lambda name earlier. (closes https://github.com/vim/vim/issues/7525)
author Bram Moolenaar <Bram@vim.org>
date Tue, 22 Dec 2020 19:00:06 +0100
parents ac701146c708
children 7951c5098e8e
comparison
equal deleted inserted replaced
23290:bbda7e5d2c51 23291:8e1427ac2bce
1426 return OK; 1426 return OK;
1427 } 1427 }
1428 1428
1429 /* 1429 /*
1430 * Generate an ISN_NEWFUNC instruction. 1430 * Generate an ISN_NEWFUNC instruction.
1431 * "lambda_name" and "func_name" must be in allocated memory and will be
1432 * consumed.
1431 */ 1433 */
1432 static int 1434 static int
1433 generate_NEWFUNC(cctx_T *cctx, char_u *lambda_name, char_u *func_name) 1435 generate_NEWFUNC(cctx_T *cctx, char_u *lambda_name, char_u *func_name)
1434 { 1436 {
1435 isn_T *isn; 1437 isn_T *isn;
1436 char_u *name; 1438
1437 1439 if (cctx->ctx_skip == SKIP_YES)
1438 RETURN_OK_IF_SKIP(cctx); 1440 {
1439 name = vim_strsave(lambda_name); 1441 vim_free(lambda_name);
1440 if (name == NULL) 1442 vim_free(func_name);
1441 return FAIL; 1443 return OK;
1444 }
1442 if ((isn = generate_instr(cctx, ISN_NEWFUNC)) == NULL) 1445 if ((isn = generate_instr(cctx, ISN_NEWFUNC)) == NULL)
1443 return FAIL; 1446 {
1444 isn->isn_arg.newfunc.nf_lambda = name; 1447 vim_free(lambda_name);
1448 vim_free(func_name);
1449 return FAIL;
1450 }
1451 isn->isn_arg.newfunc.nf_lambda = lambda_name;
1445 isn->isn_arg.newfunc.nf_global = func_name; 1452 isn->isn_arg.newfunc.nf_global = func_name;
1446 1453
1447 return OK; 1454 return OK;
1448 } 1455 }
1449 1456
4838 int is_global = *eap->arg == 'g' && eap->arg[1] == ':'; 4845 int is_global = *eap->arg == 'g' && eap->arg[1] == ':';
4839 char_u *name_start = eap->arg; 4846 char_u *name_start = eap->arg;
4840 char_u *name_end = to_name_end(eap->arg, TRUE); 4847 char_u *name_end = to_name_end(eap->arg, TRUE);
4841 char_u *lambda_name; 4848 char_u *lambda_name;
4842 ufunc_T *ufunc; 4849 ufunc_T *ufunc;
4843 int r; 4850 int r = FAIL;
4844 4851
4845 if (eap->forceit) 4852 if (eap->forceit)
4846 { 4853 {
4847 emsg(_(e_cannot_use_bang_with_nested_def)); 4854 emsg(_(e_cannot_use_bang_with_nested_def));
4848 return NULL; 4855 return NULL;
4881 eap->arg = name_end; 4888 eap->arg = name_end;
4882 eap->getline = exarg_getline; 4889 eap->getline = exarg_getline;
4883 eap->cookie = cctx; 4890 eap->cookie = cctx;
4884 eap->skip = cctx->ctx_skip == SKIP_YES; 4891 eap->skip = cctx->ctx_skip == SKIP_YES;
4885 eap->forceit = FALSE; 4892 eap->forceit = FALSE;
4886 lambda_name = get_lambda_name(); 4893 lambda_name = vim_strsave(get_lambda_name());
4894 if (lambda_name == NULL)
4895 return NULL;
4887 ufunc = define_function(eap, lambda_name); 4896 ufunc = define_function(eap, lambda_name);
4888 4897
4889 if (ufunc == NULL) 4898 if (ufunc == NULL)
4890 return eap->skip ? (char_u *)"" : NULL; 4899 {
4900 r = eap->skip ? OK : FAIL;
4901 goto theend;
4902 }
4891 if (ufunc->uf_def_status == UF_TO_BE_COMPILED 4903 if (ufunc->uf_def_status == UF_TO_BE_COMPILED
4892 && compile_def_function(ufunc, TRUE, cctx) == FAIL) 4904 && compile_def_function(ufunc, TRUE, cctx) == FAIL)
4893 { 4905 {
4894 func_ptr_unref(ufunc); 4906 func_ptr_unref(ufunc);
4895 return NULL; 4907 goto theend;
4896 } 4908 }
4897 4909
4898 if (is_global) 4910 if (is_global)
4899 { 4911 {
4900 char_u *func_name = vim_strnsave(name_start + 2, 4912 char_u *func_name = vim_strnsave(name_start + 2,
4901 name_end - name_start - 2); 4913 name_end - name_start - 2);
4902 4914
4903 if (func_name == NULL) 4915 if (func_name == NULL)
4904 r = FAIL; 4916 r = FAIL;
4905 else 4917 else
4918 {
4906 r = generate_NEWFUNC(cctx, lambda_name, func_name); 4919 r = generate_NEWFUNC(cctx, lambda_name, func_name);
4920 lambda_name = NULL;
4921 }
4907 } 4922 }
4908 else 4923 else
4909 { 4924 {
4910 // Define a local variable for the function reference. 4925 // Define a local variable for the function reference.
4911 lvar_T *lvar = reserve_local(cctx, name_start, name_end - name_start, 4926 lvar_T *lvar = reserve_local(cctx, name_start, name_end - name_start,
4912 TRUE, ufunc->uf_func_type); 4927 TRUE, ufunc->uf_func_type);
4913 int block_depth = cctx->ctx_ufunc->uf_block_depth; 4928 int block_depth = cctx->ctx_ufunc->uf_block_depth;
4914 4929
4915 if (lvar == NULL) 4930 if (lvar == NULL)
4916 return NULL; 4931 goto theend;
4917 if (generate_FUNCREF(cctx, ufunc) == FAIL) 4932 if (generate_FUNCREF(cctx, ufunc) == FAIL)
4918 return NULL; 4933 goto theend;
4919 r = generate_STORE(cctx, ISN_STORE, lvar->lv_idx, NULL); 4934 r = generate_STORE(cctx, ISN_STORE, lvar->lv_idx, NULL);
4920 4935
4921 // copy over the block scope IDs 4936 // copy over the block scope IDs
4922 if (block_depth > 0) 4937 if (block_depth > 0)
4923 { 4938 {
4928 sizeof(int) * block_depth); 4943 sizeof(int) * block_depth);
4929 ufunc->uf_block_depth = block_depth; 4944 ufunc->uf_block_depth = block_depth;
4930 } 4945 }
4931 } 4946 }
4932 } 4947 }
4933
4934 // TODO: warning for trailing text? 4948 // TODO: warning for trailing text?
4949 r = OK;
4950
4951 theend:
4952 vim_free(lambda_name);
4935 return r == FAIL ? NULL : (char_u *)""; 4953 return r == FAIL ? NULL : (char_u *)"";
4936 } 4954 }
4937 4955
4938 /* 4956 /*
4939 * Return the length of an assignment operator, or zero if there isn't one. 4957 * Return the length of an assignment operator, or zero if there isn't one.