@@ -1497,6 +1497,9 @@ copy_object(typval_T *from, typval_T *to)
14971497 static void
14981498object_clear (object_T * obj )
14991499{
1500+ // Avoid a recursive call, it can happen if "obj" has a circular reference.
1501+ obj -> obj_refcount = INT_MAX ;
1502+
15001503 class_T * cl = obj -> obj_class ;
15011504
15021505 // the member values are just after the object structure
@@ -1619,6 +1622,8 @@ object_created(object_T *obj)
16191622 first_object = obj ;
16201623}
16211624
1625+ static object_T * next_nonref_obj = NULL ;
1626+
16221627/*
16231628 * Call this function when an object has been cleared and is about to be freed.
16241629 * It is removed from the list headed by "first_object".
@@ -1632,6 +1637,10 @@ object_cleared(object_T *obj)
16321637 obj -> obj_prev_used -> obj_next_used = obj -> obj_next_used ;
16331638 else if (first_object == obj )
16341639 first_object = obj -> obj_next_used ;
1640+
1641+ // update the next object to check if needed
1642+ if (obj == next_nonref_obj )
1643+ next_nonref_obj = obj -> obj_next_used ;
16351644}
16361645
16371646/*
@@ -1641,11 +1650,10 @@ object_cleared(object_T *obj)
16411650object_free_nonref (int copyID )
16421651{
16431652 int did_free = FALSE;
1644- object_T * next_obj ;
16451653
1646- for (object_T * obj = first_object ; obj != NULL ; obj = next_obj )
1654+ for (object_T * obj = first_object ; obj != NULL ; obj = next_nonref_obj )
16471655 {
1648- next_obj = obj -> obj_next_used ;
1656+ next_nonref_obj = obj -> obj_next_used ;
16491657 if ((obj -> obj_copyID & COPYID_MASK ) != (copyID & COPYID_MASK ))
16501658 {
16511659 // Free the object and items it contains.
@@ -1654,6 +1662,7 @@ object_free_nonref(int copyID)
16541662 }
16551663 }
16561664
1665+ next_nonref_obj = NULL ;
16571666 return did_free ;
16581667}
16591668
0 commit comments