Mercurial > vim
changeset 31633:d19377e0a0b4 v9.0.1149
patch 9.0.1149: class members may be garbage collected
Commit: https://github.com/vim/vim/commit/cf760d50dceb46bd583321c210b88b92360eb959
Author: Bram Moolenaar <Bram@vim.org>
Date: Thu Jan 5 13:16:04 2023 +0000
patch 9.0.1149: class members may be garbage collected
Problem: Class members may be garbage collected.
Solution: Mark class members as being in use.
author | Bram Moolenaar <Bram@vim.org> |
---|---|
date | Thu, 05 Jan 2023 14:30:04 +0100 |
parents | 874f82a0817c |
children | 40a31588b97c |
files | src/eval.c src/structs.h src/testdir/test_vim9_class.vim src/version.c |
diffstat | 4 files changed, 46 insertions(+), 3 deletions(-) [+] |
line wrap: on
line diff
--- a/src/eval.c +++ b/src/eval.c @@ -5674,9 +5674,32 @@ set_ref_in_item( } case VAR_CLASS: - // TODO: Mark methods in class_obj_methods ? - // Mark initializer expressions? - break; + { + class_T *cl = tv->vval.v_class; + if (cl != NULL && cl->class_copyID != copyID) + { + cl->class_copyID = copyID; + for (int i = 0; !abort + && i < cl->class_class_member_count; ++i) + abort = abort || set_ref_in_item( + &cl->class_members_tv[i], + copyID, ht_stack, list_stack); + + + for (int i = 0; !abort + && i < cl->class_class_function_count; ++i) + abort = abort || set_ref_in_func(NULL, + cl->class_class_functions[i], copyID); + + for (int i = 0; !abort + && i < cl->class_obj_method_count; ++i) + abort = abort || set_ref_in_func(NULL, + cl->class_obj_methods[i], copyID); + + // Mark initializer expressions? + } + break; + } case VAR_OBJECT: {
--- a/src/structs.h +++ b/src/structs.h @@ -1487,6 +1487,7 @@ struct class_S { char_u *class_name; // allocated int class_refcount; + int class_copyID; // used by garbage collection // class members: "static varname" int class_class_member_count;
--- a/src/testdir/test_vim9_class.vim +++ b/src/testdir/test_vim9_class.vim @@ -493,6 +493,23 @@ def Test_class_member() v9.CheckScriptFailure(lines, 'E1341: Variable already declared in the class: count') enddef +func Test_class_garbagecollect() + let lines =<< trim END + vim9script + + class Point + this.p = [2, 3] + static pl = ['a', 'b'] + static pd = {a: 'a', b: 'b'} + endclass + + echo Point.pl Point.pd + call test_garbagecollect_now() + echo Point.pl Point.pd + END + call v9.CheckScriptSuccess(lines) +endfunc + def Test_class_function() var lines =<< trim END vim9script