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
--- 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,