diff options
author | Bram Moolenaar <Bram@vim.org> | 2021-03-17 18:42:08 +0100 |
---|---|---|
committer | Bram Moolenaar <Bram@vim.org> | 2021-03-17 18:42:08 +0100 |
commit | 8863bda25df821fc79bebf9dc73c79776ae5f675 (patch) | |
tree | 0c71db682e0c9ea275dfd06123586a94ccf82e23 | |
parent | 3e1916947d5b29f67af554ce3b874b03a84c9093 (diff) | |
download | vim-git-8863bda25df821fc79bebf9dc73c79776ae5f675.tar.gz |
patch 8.2.2617: Vim9: script variable in block not found by functionv8.2.2617
Problem: Vim9: script variable in a block scope not found by a nested
function.
Solution: Copy the block scope IDs before compiling the function.
-rw-r--r-- | src/testdir/test_vim9_disassemble.vim | 4 | ||||
-rw-r--r-- | src/testdir/test_vim9_func.vim | 20 | ||||
-rw-r--r-- | src/version.c | 2 | ||||
-rw-r--r-- | src/vim9compile.c | 28 |
4 files changed, 38 insertions, 16 deletions
diff --git a/src/testdir/test_vim9_disassemble.vim b/src/testdir/test_vim9_disassemble.vim index 9d05bbfd2..7470ac3ce 100644 --- a/src/testdir/test_vim9_disassemble.vim +++ b/src/testdir/test_vim9_disassemble.vim @@ -947,7 +947,7 @@ def NestedOuter() enddef enddef -def Test_nested_func() +def Test_disassemble_nested_func() var instr = execute('disassemble NestedOuter') assert_match('NestedOuter\_s*' .. 'def g:Inner()\_s*' .. @@ -965,7 +965,7 @@ def NestedDefList() def /Info/ enddef -def Test_nested_def_list() +def Test_disassemble_nested_def_list() var instr = execute('disassemble NestedDefList') assert_match('NestedDefList\_s*' .. 'def\_s*' .. diff --git a/src/testdir/test_vim9_func.vim b/src/testdir/test_vim9_func.vim index 6258b7d5d..73d8e37aa 100644 --- a/src/testdir/test_vim9_func.vim +++ b/src/testdir/test_vim9_func.vim @@ -393,7 +393,6 @@ def Test_nested_function() CheckDefFailure(lines, 'E1117:') # nested function inside conditional - # TODO: should it work when "thecount" is inside the "if"? lines =<< trim END vim9script var thecount = 0 @@ -411,6 +410,25 @@ def Test_nested_function() assert_equal(2, Test()) END CheckScriptSuccess(lines) + + # also works when "thecount" is inside the "if" block + lines =<< trim END + vim9script + if true + var thecount = 0 + def Test(): number + def TheFunc(): number + thecount += 1 + return thecount + enddef + return TheFunc() + enddef + endif + defcompile + assert_equal(1, Test()) + assert_equal(2, Test()) + END + CheckScriptSuccess(lines) enddef def Test_not_nested_function() diff --git a/src/version.c b/src/version.c index a92db82f3..3bb4eceb7 100644 --- a/src/version.c +++ b/src/version.c @@ -751,6 +751,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ /**/ + 2617, +/**/ 2616, /**/ 2615, diff --git a/src/vim9compile.c b/src/vim9compile.c index 3fef9bd6b..93ded0857 100644 --- a/src/vim9compile.c +++ b/src/vim9compile.c @@ -5183,6 +5183,21 @@ compile_nested_function(exarg_T *eap, cctx_T *cctx) r = eap->skip ? OK : FAIL; goto theend; } + + // copy over the block scope IDs before compiling + if (!is_global && cctx->ctx_ufunc->uf_block_depth > 0) + { + int block_depth = cctx->ctx_ufunc->uf_block_depth; + + ufunc->uf_block_ids = ALLOC_MULT(int, block_depth); + if (ufunc->uf_block_ids != NULL) + { + mch_memmove(ufunc->uf_block_ids, cctx->ctx_ufunc->uf_block_ids, + sizeof(int) * block_depth); + ufunc->uf_block_depth = block_depth; + } + } + if (func_needs_compiling(ufunc, PROFILING(ufunc)) && compile_def_function(ufunc, TRUE, PROFILING(ufunc), cctx) == FAIL) @@ -5209,25 +5224,12 @@ compile_nested_function(exarg_T *eap, cctx_T *cctx) // Define a local variable for the function reference. lvar_T *lvar = reserve_local(cctx, name_start, name_end - name_start, TRUE, ufunc->uf_func_type); - int block_depth = cctx->ctx_ufunc->uf_block_depth; if (lvar == NULL) goto theend; if (generate_FUNCREF(cctx, ufunc) == FAIL) goto theend; r = generate_STORE(cctx, ISN_STORE, lvar->lv_idx, NULL); - - // copy over the block scope IDs - if (block_depth > 0) - { - ufunc->uf_block_ids = ALLOC_MULT(int, block_depth); - if (ufunc->uf_block_ids != NULL) - { - mch_memmove(ufunc->uf_block_ids, cctx->ctx_ufunc->uf_block_ids, - sizeof(int) * block_depth); - ufunc->uf_block_depth = block_depth; - } - } } // TODO: warning for trailing text? |