]> git.donarmstrong.com Git - lilypond.git/commitdiff
Issue 4373: Start up GUILE type system before anything else
authorDavid Kastrup <dak@gnu.org>
Wed, 6 May 2015 09:55:18 +0000 (11:55 +0200)
committerDavid Kastrup <dak@gnu.org>
Wed, 6 May 2015 19:34:08 +0000 (21:34 +0200)
This permits using our datatypes in the general Scheme initialization
phase without crashing or order dependencies.

lily/guile-init.cc
lily/include/smobs.hh
lily/include/smobs.tcc
lily/smobs.cc

index 67ed72822ace306853e6b9ac6dd33a3867c1dc9a..86a998e9ab5c71ab23fda0465067c33650ebf8b8 100644 (file)
 #include "lily-guile.hh"
 #include "main.hh"
 #include "warn.hh"
+#include "smobs.hh"
 
 /*
   INIT
 */
 
+// Why a pointer here?  Because it has zero initialization at load
+// time which is guaranteed to come before the static initializations
+// of all constructors for static expressions of the classes created
+// by ADD_SCM_INIT_FUNC.  The vector data type does not have load-time
+// initialization and might clear out already set callbacks at the
+// time it is initialized since there is no implied order among
+// non-trivial constructors for static data in separate compilation
+// units.  So we need a trivial type like a pointer instead.
+
 typedef void (*Void_fptr) ();
 vector<Void_fptr> *scm_init_funcs_;
 
@@ -40,6 +50,8 @@ void add_scm_init_func (void (*f) ())
 void
 ly_init_ly_module (void *)
 {
+  // Start up type system first.
+  Scm_init::init ();
   for (vsize i = scm_init_funcs_->size (); i--;)
     (scm_init_funcs_->at (i)) ();
 
index 3ee2ef80abce09b44b2acadf1081173eb6579ce6..2787750ec5b4b58e7393ba2ddbc9fd1df7e61307 100644 (file)
 // class) to make sure the variable is actually instantiated.
 
 class Scm_init {
+  static const Scm_init * list_;
+  void (*const fun_)(void);
+  Scm_init const * const next_;
+  Scm_init ();          // don't use default constructor, don't define
+  Scm_init (const Scm_init &);  // don't define copy constructor
 public:
-  Scm_init () { }
-  Scm_init (void (*fun) (void))
-  {
-    add_scm_init_func (fun);
-  }
+  Scm_init (void (*fun) (void)) : fun_ (fun), next_ (list_)
+  { list_ = this; }
+  static void init ();
 };
 
 template <class Super>
index b4dacacaa325ec8759bf321e368b4c8e138cc0ff..913785315ae9bb46f9d72f1ea6f44233ac5e277e 100644 (file)
@@ -110,7 +110,7 @@ template <class Super>
 scm_t_bits Smob_base<Super>::smob_tag_ = 0;
 
 template <class Super>
-Scm_init Smob_base<Super>::scm_init_ = init;
+Scm_init Smob_base<Super>::scm_init_ (init);
 
 template <class Super>
 string Smob_base<Super>::smob_name_;
index 8b3c8a90141e63a61991dd86579d40ab987dcf59..d36c9be7dc6f6ec560839c6c0b1c8c64c5941739 100644 (file)
@@ -85,3 +85,13 @@ unprotect_smob (SCM smob, SCM *prot_cons)
   *prot_cons = SCM_EOL;
 #endif
 }
+
+
+Scm_init const *Scm_init::list_ = 0;
+
+void
+Scm_init::init ()
+{
+  for (Scm_init const *p = list_; p; p = p->next_)
+    p->fun_ ();
+}