From ee35bce9fe991b2ee3dfa7e33539d74b29bcf91f Mon Sep 17 00:00:00 2001 From: David Kastrup Date: Wed, 6 May 2015 11:55:18 +0200 Subject: [PATCH] Issue 4373: Start up GUILE type system before anything else This permits using our datatypes in the general Scheme initialization phase without crashing or order dependencies. --- lily/guile-init.cc | 12 ++++++++++++ lily/include/smobs.hh | 13 ++++++++----- lily/include/smobs.tcc | 2 +- lily/smobs.cc | 10 ++++++++++ 4 files changed, 31 insertions(+), 6 deletions(-) diff --git a/lily/guile-init.cc b/lily/guile-init.cc index 67ed72822a..86a998e9ab 100644 --- a/lily/guile-init.cc +++ b/lily/guile-init.cc @@ -21,11 +21,21 @@ #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 *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)) (); diff --git a/lily/include/smobs.hh b/lily/include/smobs.hh index 3ee2ef80ab..2787750ec5 100644 --- a/lily/include/smobs.hh +++ b/lily/include/smobs.hh @@ -134,12 +134,15 @@ // 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 diff --git a/lily/include/smobs.tcc b/lily/include/smobs.tcc index b4dacacaa3..913785315a 100644 --- a/lily/include/smobs.tcc +++ b/lily/include/smobs.tcc @@ -110,7 +110,7 @@ template scm_t_bits Smob_base::smob_tag_ = 0; template -Scm_init Smob_base::scm_init_ = init; +Scm_init Smob_base::scm_init_ (init); template string Smob_base::smob_name_; diff --git a/lily/smobs.cc b/lily/smobs.cc index 8b3c8a9014..d36c9be7dc 100644 --- a/lily/smobs.cc +++ b/lily/smobs.cc @@ -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_ (); +} -- 2.39.2