To: vim_dev@googlegroups.com Subject: Patch 8.2.0729 Fcc: outbox From: Bram Moolenaar Mime-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ------------ Patch 8.2.0729 Problem: Vim9: When reloading a script variables are not cleared. Solution: When sourcing a script again clear all script-local variables. Files: src/dict.c, src/proto/dict.pro, src/scriptfile.c, src/testdir/test_vim9_script.vim *** ../vim-8.2.0728/src/dict.c 2020-04-23 13:37:59.494978699 +0200 --- src/dict.c 2020-05-10 15:13:11.945828250 +0200 *************** *** 105,132 **** void dict_free_contents(dict_T *d) { int todo; hashitem_T *hi; dictitem_T *di; // Lock the hashtab, we don't want it to resize while freeing items. ! hash_lock(&d->dv_hashtab); ! todo = (int)d->dv_hashtab.ht_used; ! for (hi = d->dv_hashtab.ht_array; todo > 0; ++hi) { if (!HASHITEM_EMPTY(hi)) { // Remove the item before deleting it, just in case there is // something recursive causing trouble. di = HI2DI(hi); ! hash_remove(&d->dv_hashtab, hi); dictitem_free(di); --todo; } } ! // The hashtab is still locked, it has to be re-initialized anyway ! hash_clear(&d->dv_hashtab); } static void --- 105,141 ---- void dict_free_contents(dict_T *d) { + hashtab_free_contents(&d->dv_hashtab); + } + + /* + * Clear hashtab "ht" and dict items it contains. + */ + void + hashtab_free_contents(hashtab_T *ht) + { int todo; hashitem_T *hi; dictitem_T *di; // Lock the hashtab, we don't want it to resize while freeing items. ! hash_lock(ht); ! todo = (int)ht->ht_used; ! for (hi = ht->ht_array; todo > 0; ++hi) { if (!HASHITEM_EMPTY(hi)) { // Remove the item before deleting it, just in case there is // something recursive causing trouble. di = HI2DI(hi); ! hash_remove(ht, hi); dictitem_free(di); --todo; } } ! // The hashtab is still locked, it has to be re-initialized anyway. ! hash_clear(ht); } static void *** ../vim-8.2.0728/src/proto/dict.pro 2020-01-11 16:05:19.594287610 +0100 --- src/proto/dict.pro 2020-05-10 15:13:10.565833347 +0200 *************** *** 5,10 **** --- 5,11 ---- int rettv_dict_alloc(typval_T *rettv); void rettv_dict_set(typval_T *rettv, dict_T *d); void dict_free_contents(dict_T *d); + void hashtab_free_contents(hashtab_T *ht); void dict_unref(dict_T *d); int dict_free_nonref(int copyID); void dict_free_items(int copyID); *** ../vim-8.2.0728/src/scriptfile.c 2020-05-09 22:50:04.751323784 +0200 --- src/scriptfile.c 2020-05-10 15:21:22.008583590 +0200 *************** *** 1295,1303 **** if (sid > 0) { hashtab_T *ht; - hashitem_T *hi; - dictitem_T *di; - int todo; int is_vim9 = si->sn_version == SCRIPT_VERSION_VIM9; // loading the same script again --- 1295,1300 ---- *************** *** 1306,1319 **** current_sctx.sc_sid = sid; ht = &SCRIPT_VARS(sid); ! todo = (int)ht->ht_used; ! for (hi = ht->ht_array; todo > 0; ++hi) ! if (!HASHITEM_EMPTY(hi)) ! { ! --todo; ! di = HI2DI(hi); ! di->di_flags |= DI_FLAGS_RELOAD; ! } // old imports are no longer valid free_imports(sid); --- 1303,1324 ---- current_sctx.sc_sid = sid; ht = &SCRIPT_VARS(sid); ! if (is_vim9) ! hashtab_free_contents(ht); ! else ! { ! int todo = (int)ht->ht_used; ! hashitem_T *hi; ! dictitem_T *di; ! ! for (hi = ht->ht_array; todo > 0; ++hi) ! if (!HASHITEM_EMPTY(hi)) ! { ! --todo; ! di = HI2DI(hi); ! di->di_flags |= DI_FLAGS_RELOAD; ! } ! } // old imports are no longer valid free_imports(sid); *** ../vim-8.2.0728/src/testdir/test_vim9_script.vim 2020-05-09 18:44:52.637841293 +0200 --- src/testdir/test_vim9_script.vim 2020-05-10 15:20:16.492657107 +0200 *************** *** 610,616 **** let import_star_lines =<< trim END vim9script import * from './Xexport.vim' - g:imported = exported END writefile(import_star_lines, 'Ximport.vim') assert_fails('source Ximport.vim', 'E1045:') --- 610,615 ---- *************** *** 807,812 **** --- 806,833 ---- delete('Xreloaded.vim') enddef + def Test_vim9script_reload_delvar() + # write the script with a script-local variable + let lines =<< trim END + vim9script + let var = 'string' + END + writefile(lines, 'XreloadVar.vim') + source XreloadVar.vim + + # now write the script using the same variable locally - works + lines =<< trim END + vim9script + def Func() + let var = 'string' + enddef + END + writefile(lines, 'XreloadVar.vim') + source XreloadVar.vim + + delete('XreloadVar.vim') + enddef + def Test_import_absolute() let import_lines = [ 'vim9script', *************** *** 862,869 **** unlet g:imported_rtp delete('Ximport_rtp.vim') ! delete('import/Xexport_rtp.vim') ! delete('import', 'd') enddef def Test_fixed_size_list() --- 883,889 ---- unlet g:imported_rtp delete('Ximport_rtp.vim') ! delete('import', 'rf') enddef def Test_fixed_size_list() *** ../vim-8.2.0728/src/version.c 2020-05-10 14:13:58.863609375 +0200 --- src/version.c 2020-05-10 15:22:57.348446330 +0200 *************** *** 748,749 **** --- 748,751 ---- { /* Add new patch number below this line */ + /**/ + 729, /**/ -- hundred-and-one symptoms of being an internet addict: 91. It's Saturday afternoon in the middle of May and you are on computer. /// 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 ///