Mercurial > vim
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. |