To: vim_dev@googlegroups.com Subject: Patch 8.2.2617 Fcc: outbox From: Bram Moolenaar Mime-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ------------ Patch 8.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. Files: src/vim9compile.c, src/testdir/test_vim9_func.vim, src/testdir/test_vim9_disassemble.vim *** ../vim-8.2.2616/src/vim9compile.c 2021-03-14 13:21:31.789065156 +0100 --- src/vim9compile.c 2021-03-17 18:34:40.876008167 +0100 *************** *** 5183,5188 **** --- 5183,5203 ---- 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,5233 **** // 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? --- 5224,5235 ---- *** ../vim-8.2.2616/src/testdir/test_vim9_func.vim 2021-03-11 20:03:59.574114833 +0100 --- src/testdir/test_vim9_func.vim 2021-03-17 18:37:15.679602626 +0100 *************** *** 393,399 **** CheckDefFailure(lines, 'E1117:') # nested function inside conditional - # TODO: should it work when "thecount" is inside the "if"? lines =<< trim END vim9script var thecount = 0 --- 393,398 ---- *************** *** 401,406 **** --- 400,424 ---- 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) + + # 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() *** ../vim-8.2.2616/src/testdir/test_vim9_disassemble.vim 2021-02-21 21:32:38.305201161 +0100 --- src/testdir/test_vim9_disassemble.vim 2021-03-17 18:09:26.576251736 +0100 *************** *** 947,953 **** enddef enddef ! def Test_nested_func() var instr = execute('disassemble NestedOuter') assert_match('NestedOuter\_s*' .. 'def g:Inner()\_s*' .. --- 947,953 ---- enddef enddef ! def Test_disassemble_nested_func() var instr = execute('disassemble NestedOuter') assert_match('NestedOuter\_s*' .. 'def g:Inner()\_s*' .. *************** *** 965,971 **** def /Info/ enddef ! def Test_nested_def_list() var instr = execute('disassemble NestedDefList') assert_match('NestedDefList\_s*' .. 'def\_s*' .. --- 965,971 ---- def /Info/ enddef ! def Test_disassemble_nested_def_list() var instr = execute('disassemble NestedDefList') assert_match('NestedDefList\_s*' .. 'def\_s*' .. *** ../vim-8.2.2616/src/version.c 2021-03-17 17:45:55.353935904 +0100 --- src/version.c 2021-03-17 18:40:39.543082376 +0100 *************** *** 752,753 **** --- 752,755 ---- { /* Add new patch number below this line */ + /**/ + 2617, /**/ -- For society, it's probably a good thing that engineers value function over appearance. For example, you wouldn't want engineers to build nuclear power plants that only _look_ like they would keep all the radiation inside. (Scott Adams - The Dilbert principle) /// Bram Moolenaar -- Bram@Moolenaar.net -- http://www.Moolenaar.net \\\ /// sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\ \\\ an exciting new programming language -- http://www.Zimbu.org /// \\\ help me help AIDS victims -- http://ICCF-Holland.org ///