# HG changeset patch # User Bram Moolenaar # Date 1672925404 -3600 # Node ID d19377e0a0b4a7970361df1426446ac363772f47 # Parent 874f82a0817ca7c377d44f9d3843f558249e96e5 patch 9.0.1149: class members may be garbage collected Commit: https://github.com/vim/vim/commit/cf760d50dceb46bd583321c210b88b92360eb959 Author: Bram Moolenaar 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. diff --git a/src/eval.c b/src/eval.c --- 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: { diff --git a/src/structs.h b/src/structs.h --- 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; diff --git a/src/testdir/test_vim9_class.vim b/src/testdir/test_vim9_class.vim --- 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 diff --git a/src/version.c b/src/version.c --- a/src/version.c +++ b/src/version.c @@ -696,6 +696,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ /**/ + 1149, +/**/ 1148, /**/ 1147,