]> git.donarmstrong.com Git - lilypond.git/commitdiff
Issue 4997/4: Use Preinit in Spanner
authorDavid Kastrup <dak@gnu.org>
Sat, 4 Jun 2016 15:41:23 +0000 (17:41 +0200)
committerDavid Kastrup <dak@gnu.org>
Fri, 18 Nov 2016 20:49:58 +0000 (21:49 +0100)
lily/include/spanner.hh
lily/spanner.cc

index 79032dfb305c2d52dc2eef5f3d057e52565240c7..bc41ec6e639155fdc08ce05a9ed443551e0182c5 100644 (file)
@@ -39,7 +39,7 @@
     is absolutely necessary for beams, since they have to adjust the
     length of stems of notes they encompass.
 */
-class Spanner : public Grob
+class Spanner : public Preinit<Spanner>, public Grob
 {
   Drul_array<Item *> spanned_drul_;
   vsize break_index_;
@@ -66,6 +66,7 @@ public:
   void set_bound (Direction d, Grob *);
   Item *get_bound (Direction d) const;
 
+  void pre_init ();
   Spanner (SCM);
   Spanner (Spanner const &);
   bool is_broken () const;
index 3f3d17fb270ffb70d1b76d126e998733a50fda7a..1b6798086a3244558555a7cd1fa98059e15e834d 100644 (file)
@@ -224,19 +224,27 @@ Spanner::set_bound (Direction d, Grob *s)
     Pointer_group_interface::add_grob (i, ly_symbol2scm ("bounded-by-me"), this);
 }
 
+void
+Spanner::pre_init ()
+{
+  break_index_ = (vsize)-1;
+  // This is stupid, but derived_mark may be run before broken_into_
+  // has run its constructor and has a recognizable array size.
+  // So we use break_index_ == -1 as a sentinel.
+  spanned_drul_.set (0, 0);
+  pure_property_cache_ = SCM_UNDEFINED;
+}
+
 Spanner::Spanner (SCM s)
   : Grob (s)
 {
   break_index_ = 0;
-  spanned_drul_.set (0, 0);
-  pure_property_cache_ = SCM_UNDEFINED;
 }
 
 Spanner::Spanner (Spanner const &s)
   : Grob (s)
 {
-  spanned_drul_.set (0, 0);
-  pure_property_cache_ = SCM_UNDEFINED;
+  break_index_ = 0;
 }
 
 /*
@@ -341,8 +349,11 @@ Spanner::derived_mark () const
       scm_gc_mark (spanned_drul_[d]->self_scm ());
   ;
 
-  for (vsize i = broken_intos_.size (); i--;)
-    scm_gc_mark (broken_intos_[i]->self_scm ());
+  // If break_index_ is -1, broken_intos_ might not yet have run its
+  // constructor and any access might break things.
+  if (break_index_ != (vsize)-1)
+    for (vsize i = broken_intos_.size (); i--;)
+      scm_gc_mark (broken_intos_[i]->self_scm ());
 }
 
 /*