]> git.donarmstrong.com Git - lilypond.git/commitdiff
Issue 4360: Reorganize smob initialization to make it more reliable
authorDavid Kastrup <dak@gnu.org>
Thu, 30 Apr 2015 18:48:09 +0000 (20:48 +0200)
committerDavid Kastrup <dak@gnu.org>
Sat, 2 May 2015 08:56:34 +0000 (10:56 +0200)
This change is a nuisance in that it requires an explicit call to
ADD_SMOB_INIT for each Scheme-related class.

However, this setup guarantees that at the point Scheme execution
commences, all predicates of the likes of "ly:grob?" will be present.
It also guarantees that if a particular type should seem required during
_other_ initializations that happen to depend on the type and get
executed earlier, it will be provided early.

42 files changed:
lily/book.cc
lily/box.cc
lily/context-def.cc
lily/context-mod.cc
lily/context-property.cc
lily/context.cc
lily/dispatcher.cc
lily/duration.cc
lily/font-metric.cc
lily/grob-array.cc
lily/grob.cc
lily/include/smobs.hh
lily/include/smobs.tcc
lily/input-smob.cc
lily/lily-lexer.cc
lily/lily-parser.cc
lily/listener.cc
lily/moment.cc
lily/music-function.cc
lily/music-iterator.cc
lily/music-output.cc
lily/output-def.cc
lily/page-marker.cc
lily/paper-book.cc
lily/paper-outputter.cc
lily/pitch.cc
lily/prob.cc
lily/scale.cc
lily/scheme-listener.cc
lily/scm-hash.cc
lily/score.cc
lily/simple-closure.cc
lily/simple-spacer.cc
lily/skyline-pair.cc
lily/skyline.cc
lily/source-file.cc
lily/spring.cc
lily/stencil.cc
lily/translator-dispatch-list.cc
lily/translator-group.cc
lily/translator.cc
lily/undead.cc

index 8e63d889e09ab80cc51f7f3aba265364afd3e331..e76963eaf30fb140d2bdf68a6104b6ebcb62f1c2 100644 (file)
@@ -33,6 +33,7 @@ using namespace std;
 #include "paper-score.hh"
 #include "page-marker.hh"
 
+ADD_SMOB_INIT (Book);
 
 Book::Book ()
 {
index 629b8010fae6b2ab9b429399e463952d5ed2aa04..050824a25ac74fa6d162b9ce8ff668b5f5ffede9 100644 (file)
@@ -19,6 +19,8 @@
 
 #include "box.hh"
 
+ADD_SMOB_INIT (Box);
+
 void
 Box::translate (Offset o)
 {
index 10f31ae83079c71cfa6062abbb2c9b2a82fffda1..b2aaedf44abed31aaf41b715f9e90e009e150a23 100644 (file)
@@ -29,6 +29,8 @@
 #include "translator.hh"
 #include "warn.hh"
 
+ADD_SMOB_INIT (Context_def);
+
 Context_def::Context_def ()
 {
   context_aliases_ = SCM_EOL;
index fd2a25d2fe5fc64fec88a7eea3ec34deedc85962..b9c43fe76a7f013e3bf16c21d5444920d2d6d222 100644 (file)
@@ -19,6 +19,8 @@
 
 #include "context-mod.hh"
 
+ADD_SMOB_INIT (Context_mod);
+
 Context_mod::Context_mod ()
 {
   mods_ = SCM_EOL;
index 59bcf9afc6764fdf1cf1cd81a97c98bcc2ec53d6..7a605352fd704fecb0028d336b5b650b46511282 100644 (file)
@@ -94,6 +94,8 @@ private:
     cooked_ (alist), cooked_from_ (alist), nested_ (0) { }
 };
 
+ADD_SMOB_INIT (Grob_properties);
+
 const char Grob_properties::type_p_name_[] = "ly:grob-properties?";
 
 SCM
index 9dad38f269c623a9264966ebee9d1cd381ad0357..1d8efed630e77b5d088a89f5e2f28c629ba3cf86 100644 (file)
@@ -31,6 +31,8 @@
 #include "translator-group.hh"
 #include "warn.hh"
 
+ADD_SMOB_INIT (Context);
+
 bool
 Context::is_removable () const
 {
index efb3ca506c0d2bcf2d533daeaee75f25acdd5a75..b76e76c35c828c1914416f1fdc0468f1f3ca3789 100644 (file)
@@ -22,6 +22,8 @@
 #include "international.hh"
 #include "warn.hh"
 
+ADD_SMOB_INIT (Dispatcher);
+
 const char Dispatcher::type_p_name_[] = "ly:dispatcher?";
 
 Dispatcher::~Dispatcher ()
index 4768f015b501c6510f52b373fb4625d94f168889..78ae045a886316d18d7cb03fd9b48deee8435d58 100644 (file)
@@ -20,6 +20,8 @@
 
 #include "duration.hh"
 
+ADD_SMOB_INIT (Duration);
+
 #include "misc.hh"
 #include "lily-proto.hh"
 
index f18b2d7256ae2717928937c3bbe76cc41799d121..be071fe912dcfa9e5cf4c23d6dc1d55a85334939 100644 (file)
@@ -29,6 +29,7 @@ using namespace std;
 #include "stencil.hh"
 #include "warn.hh"
 
+ADD_SMOB_INIT (Font_metric);
 
 Real
 Font_metric::design_size () const
index 2747e0d77fb052e66339263500d21cd9996a90a4..f267ce5a440729fe97f8d959236b746bfbb517f2 100644 (file)
@@ -21,6 +21,7 @@
 #include "item.hh"
 #include "spanner.hh"
 
+ADD_SMOB_INIT (Grob_array);
 
 Item *
 Grob_array::item (vsize i)
index 435a6faff3a92447ad67c637678a89129f5a09dd..8cfb14d53974a23d9e3278b52f7b12e47b67e1ca 100644 (file)
@@ -39,6 +39,7 @@
 #include "unpure-pure-container.hh"
 #include "warn.hh"
 
+ADD_SMOB_INIT (Grob);
 
 Grob *
 Grob::clone () const
index 3ee2ef80abce09b44b2acadf1081173eb6579ce6..eeb385e1a26d6ae390714f0bb574c584d81da42a 100644 (file)
 
 */
 
-// Initialization class.  Create a variable or static data member of
-// this type at global scope (or creation will happen too late for
-// Scheme initialization), initialising with a function to be called.
-// Reference somewhere (like in the constructor of the containing
-// class) to make sure the variable is actually instantiated.
-
-class Scm_init {
-public:
-  Scm_init () { }
-  Scm_init (void (*fun) (void))
-  {
-    add_scm_init_func (fun);
-  }
-};
-
 template <class Super>
 class Smob_base
 {
   static scm_t_bits smob_tag_;
-  static Scm_init scm_init_;
-  static void init (void);
+  static scm_t_bits init_id (void);
   static string smob_name_;
   static Super *unchecked_unsmob (SCM s)
   {
     return reinterpret_cast<Super *> (SCM_SMOB_DATA (s));
   }
 protected:
-  // reference scm_init_ in smob_tag which is sure to be called.  The
-  // constructor, in contrast, may not be called at all in classes
-  // like Smob1.
-  static scm_t_bits smob_tag () { (void) scm_init_; return smob_tag_; }
+  // This is an initialization with side effect.  It is called once,
+  // the first time smob_tag is actually getting called.  This
+  // allocates and initializes the type before it is first used for
+  // anything.
+  static scm_t_bits smob_tag ()
+  {
+    static scm_t_bits tag = init_id ();
+    return tag;
+  }
   Smob_base () { }
   static SCM register_ptr (Super *p);
   static Super *unregister_ptr (SCM obj);
@@ -217,6 +206,17 @@ private:
   static const int smob_proc_signature_ = -1;
 
 public:
+  static void init (void)
+  {
+    // This is stupid, but without forcing initialization at the
+    // Scheme startup hook stage, stuff like ly:undead? will not be
+    // defined when the first Scheme files are loaded.
+    //
+    // So we provide an explicit initialization routine that can be
+    // used with ADD_SCM_INIT_FUNC
+    (void) smob_tag ();
+  }
+#define ADD_SMOB_INIT(type) ADD_SCM_INIT_FUNC (Smob_init_ ## type, Smob_base<type>::init)
   static bool is_smob (SCM s)
   {
     return SCM_SMOB_PREDICATE (smob_tag (), s);
index b4dacacaa325ec8759bf321e368b4c8e138cc0ff..097047e32b05ff2f30763602c57edbee63304b6c 100644 (file)
@@ -106,17 +106,11 @@ Smob_base<Super>::unregister_ptr (SCM obj)
   return p;
 }
 
-template <class Super>
-scm_t_bits Smob_base<Super>::smob_tag_ = 0;
-
-template <class Super>
-Scm_init Smob_base<Super>::scm_init_ = init;
-
 template <class Super>
 string Smob_base<Super>::smob_name_;
 
 template <class Super>
-void Smob_base<Super>::init ()
+scm_t_bits Smob_base<Super>::init_id ()
 {
   smob_name_ = typeid (Super).name ();
   // Primitive demangling, suitable for GCC, should be harmless
@@ -124,8 +118,7 @@ void Smob_base<Super>::init ()
   // unsuitable for Texinfo documentation.  If that proves to be an
   // issue, we need some smarter strategy.
   smob_name_ = smob_name_.substr (smob_name_.find_first_not_of ("0123456789"));
-  assert(!smob_tag_);
-  smob_tag_ = scm_make_smob_type (smob_name_.c_str (), 0);
+  scm_t_bits smob_tag = scm_make_smob_type (smob_name_.c_str (), 0);
   // The following have trivial private default definitions not
   // referring to any aspect of the Super class apart from its name.
   // They should be overridden (or rather masked) at Super level: that
@@ -134,7 +127,7 @@ void Smob_base<Super>::init ()
   // doing it like the rest.
 
   if (&Super::free_smob != &Smob_base<Super>::free_smob)
-    scm_set_smob_free (smob_tag_, Super::free_smob);
+    scm_set_smob_free (smob_tag, Super::free_smob);
   // Old GCC versions get their type lattice for pointers-to-members
   // tangled up to a degree where we need to typecast _both_ covariant
   // types in order to be able to compare them.  The other comparisons
@@ -142,10 +135,10 @@ void Smob_base<Super>::init ()
   // pointers which work without those contortions.
   if (static_cast<SCM (Super::*)()>(&Super::mark_smob) !=
       static_cast<SCM (Super::*)()>(&Smob_base<Super>::mark_smob))
-    scm_set_smob_mark (smob_tag_, Super::mark_trampoline);
-  scm_set_smob_print (smob_tag_, Super::print_trampoline);
+    scm_set_smob_mark (smob_tag, Super::mark_trampoline);
+  scm_set_smob_print (smob_tag, Super::print_trampoline);
   if (&Super::equal_p != &Smob_base<Super>::equal_p)
-    scm_set_smob_equalp (smob_tag_, Super::equal_p);
+    scm_set_smob_equalp (smob_tag, Super::equal_p);
   if (Super::type_p_name_ != 0)
     {
       SCM subr = scm_c_define_gsubr (Super::type_p_name_, 1, 0, 0,
@@ -158,10 +151,11 @@ void Smob_base<Super>::init ()
     }
   ly_add_type_predicate ((void *) is_smob, smob_name_.c_str ());
   if (Super::smob_proc_signature_ >= 0)
-    scm_set_smob_apply (smob_tag_,
+    scm_set_smob_apply (smob_tag,
                         (scm_t_subr)Super::smob_proc,
                         Super::smob_proc_signature_ >> 8,
                         (Super::smob_proc_signature_ >> 4)&0xf,
                         Super::smob_proc_signature_ & 0xf);
+  return smob_tag;
 }
 #endif
index 0a33bd6a596243159596b864c38378e4cbc709f2..f6a3b7a77372098e6093137a26e212a3ca13730c 100644 (file)
@@ -21,6 +21,8 @@
 #include "source-file.hh"
 #include "std-string.hh"
 
+ADD_SMOB_INIT (Input);
+
 
 /* Dummy input location for use if real one is missing.  */
 Input dummy_input_global;
index 3bb7921b2b89d9d5356ec8e4c80edb0f8d177f20..7785ede29600765bf181c2a14b2f8a743ac5cb02 100644 (file)
@@ -36,6 +36,8 @@ using namespace std;
 #include "program-option.hh"
 #include "lily-parser.hh"
 
+ADD_SMOB_INIT (Lily_lexer);
+
 static Keyword_ent the_key_tab[]
 =
 {
index 2d006f8d788894fe0c8b4407a16279d18c78a757..4bba3e445bd6f9e4f5fad3ef3ae4109d2fff7943 100644 (file)
@@ -37,6 +37,7 @@
 #include "warn.hh"
 #include "program-option.hh"
 
+ADD_SMOB_INIT (Lily_parser);
 
 Lily_parser::Lily_parser (Sources *sources)
 {
index 50f1969ecb418c4735715fc8c77bf9f08963b080..4194c836184d388afb609b010f5b97ee086f4a96 100644 (file)
@@ -20,6 +20,8 @@
 #include "listener.hh"
 #include "warn.hh"
 
+ADD_SMOB_INIT (Listener);
+
 Listener::Listener ()
 {
   target_ = 0;
index 9f3e8ed383837e3fb7059eebff437cac5423588a..cd82c8a597899a1650332389b20e7484fe170f9b 100644 (file)
@@ -21,6 +21,8 @@
 
 #include "warn.hh"
 
+ADD_SMOB_INIT (Moment);
+
 Moment::Moment ()
 {
 }
index 35341e3c6d6fae828265b3d11f10f3e7c277daf7..a20af4d0a2a104264127956f1a827d2983330d48 100644 (file)
@@ -19,6 +19,8 @@
 
 #include "music-function.hh"
 
+ADD_SMOB_INIT (Music_function);
+
 const char Music_function::type_p_name_[] = "ly:music-function?";
 
 /* Print a textual represenation of the smob to a given port.  */
index 8eb238c295bc6d95e47187e6995358e9ac4ab01d..ed778323b9ed1bad88beb219b91ad76120c2465a 100644 (file)
@@ -30,6 +30,7 @@ using namespace std;
 #include "music-wrapper-iterator.hh"
 #include "simple-music-iterator.hh"
 
+ADD_SMOB_INIT (Music_iterator);
 
 Music_iterator::Music_iterator ()
 {
index 0907bf38f4d6f1707ee7087d53ed8eb822f618b2..8e03177bf45e764e9033f341a9771b5856296dd5 100644 (file)
@@ -19,6 +19,7 @@
 
 #include "music-output.hh"
 
+ADD_SMOB_INIT (Music_output);
 
 Music_output::Music_output ()
 {
index af407fb70ac08465f87757fde59b59b2936db0de..525ccd975e0a9bcc6950cc0d9cf1220e0b2c985c 100644 (file)
@@ -34,6 +34,8 @@
 
 #include "string-convert.hh"
 
+ADD_SMOB_INIT (Output_def);
+
 Output_def::Output_def ()
 {
   scope_ = SCM_EOL;
index 1e393862e6b861b1a859602aee3b5a80e54ac927..88eb975304ca9e980feff387ef447d87365ab5c2 100644 (file)
@@ -19,6 +19,8 @@
 
 #include "page-marker.hh"
 
+ADD_SMOB_INIT (Page_marker);
+
 Page_marker::Page_marker ()
 {
   symbol_ = SCM_EOL;
index 7dce3a9507e7d48badcd24bca281f1f5578359ec..00917966e5a0c121966204e81a5e07092a7d6695 100644 (file)
@@ -31,6 +31,7 @@
 #include "program-option.hh"
 #include "page-marker.hh"
 
+ADD_SMOB_INIT (Paper_book);
 
 Paper_book::Paper_book ()
 {
index 269e1e294c1ceeb18a5edc69205deb06788d4cff..e8f1d821aa49201c35a6fc5f5fb78027a7dcb082 100644 (file)
@@ -38,6 +38,7 @@ using namespace std;
 #include "string-convert.hh"
 #include "warn.hh"
 
+ADD_SMOB_INIT (Paper_outputter);
 
 Paper_outputter::Paper_outputter (SCM port, const string &format)
 {
index 0fd75129476a7a1d889d751c504e290f22c30843..4c5cb79e37620dfd4f347adc36c98b8f4888ebcb 100644 (file)
@@ -26,6 +26,8 @@
 
 #include <cmath>
 
+ADD_SMOB_INIT (Pitch);
+
 Pitch::Pitch (int o, int n, Rational a)
 {
   notename_ = n;
index 37dad6246b34a00b2e0d3019ef0322849168ce85..57f6b2f4d551a1e21aca2f5775596fdb8aefe426 100644 (file)
@@ -23,6 +23,7 @@
 #include "input.hh"
 #include "profile.hh"
 
+ADD_SMOB_INIT (Prob);
 
 const char Prob::type_p_name_[] = "ly:prob?";
 
index a5afd41daee5f86fd466e4ac0af98c52fa641e95..57406f0af0982b11a6114b5c7b5d5a3270a40a09 100644 (file)
@@ -21,6 +21,7 @@
 
 #include "scale.hh"
 
+ADD_SMOB_INIT (Scale);
 
 /*
   todo: put string <-> pitch here too.
index 9df6960bdf0e2af166ba7e764b28874caf20045b..8a9e175f5c4648b5b853dc327e35d327b584e036 100644 (file)
@@ -19,6 +19,8 @@
 
 #include "scheme-listener.hh"
 
+ADD_SMOB_INIT (Scheme_listener);
+
 IMPLEMENT_LISTENER (Scheme_listener, call)
 void
 Scheme_listener::call (SCM ev)
index 5eb048f6d177694dda7bb88873b5286bc6fdbd57..c5a8959548d611b4e861996b9e8ddf123aa82b97 100644 (file)
@@ -23,6 +23,8 @@
 #include <algorithm>
 using namespace std;
 
+ADD_SMOB_INIT (Scheme_hash_table);
+
 
 /*
   Return: number of objects.
index 5ce7e3ba95efedf2fcd143453468601db3cd1a52..9210766c7760b286f596e822b17149e5798b1851 100644 (file)
@@ -19,6 +19,8 @@
 
 #include "score.hh"
 
+ADD_SMOB_INIT (Score);
+
 #include <cstdio>
 
 using namespace std;
index b62649f06d52b28c88bfd40081ac917d771f8dce..0ef57ded6ebaa3426f5db557a0b0d62f398ea0f8 100644 (file)
@@ -22,6 +22,8 @@
 
 #include "grob.hh"
 
+ADD_SMOB_INIT (Simple_closure);
+
 SCM
 evaluate_args (SCM delayed_argument, SCM args, bool pure, int start, int end)
 {
index ada16593aa7e6b1441360413f714cc58d2a1afc5..ce587c5fdd644080b336783f6c151a9498a488cd 100644 (file)
@@ -32,6 +32,8 @@
 #include "spring.hh"
 #include "warn.hh"
 
+ADD_SMOB_INIT (Simple_spacer);
+
 /*
   A simple spacing constraint solver. The approach:
 
index 92ae97a342e0961571b066c0ad4b30775ea050b0..005b9b77cf88699a250fd2a3b0427d8e9439d3be 100644 (file)
@@ -22,6 +22,8 @@
 
 #include "international.hh"
 
+ADD_SMOB_INIT (Skyline_pair);
+
 Skyline_pair::Skyline_pair ()
   : skylines_ (Skyline (DOWN), Skyline (UP))
 {
index 42a028fe0a59271d4626c939f69091e35b65f8a6..ef284e7131265144809fb3b2134ef11dc26d8ac7 100644 (file)
@@ -65,6 +65,8 @@
    Alert to these considerations, we now accept buildings of zero-width.
 */
 
+ADD_SMOB_INIT (Skyline);
+
 static void
 print_buildings (list<Building> const &b)
 {
index 1118b9d286ee29a823c6ce0b2a7d6041a9ed19aa..67690289b97d7dc42bdef0f8c27dd2e916415cc9 100644 (file)
@@ -42,6 +42,8 @@ using namespace std;
 #include "misc.hh"
 #include "warn.hh"
 
+ADD_SMOB_INIT (Source_file);
+
 void
 Source_file::load_stdin ()
 {
index d1640e72b9790fb2d96991a743cfebef63f62f81..3d3dfff5fb155609bfa09dacb6da4dd8a0cbc94a 100644 (file)
@@ -36,6 +36,8 @@
 
 #include "spring.hh"
 
+ADD_SMOB_INIT (Spring);
+
 Spring::Spring ()
 {
   distance_ = 1.0;
index 980618ceaa5d965fdb8900372d77d60ff0350747..b1622808295ca0922bfe54be0e3964cfe6fda86d 100644 (file)
@@ -25,6 +25,7 @@
 #include "string-convert.hh"
 #include "warn.hh"
 
+ADD_SMOB_INIT (Stencil);
 
 Stencil::Stencil ()
 {
index ed968c571a5d504484cd99b1951af5b3b14b7c38..02de105da9b0ff246c6150e9c00d6a79dd274113 100644 (file)
@@ -20,6 +20,7 @@
 #include "translator-dispatch-list.hh"
 #include "engraver.hh"
 
+ADD_SMOB_INIT (Engraver_dispatch_list);
 
 void
 Engraver_dispatch_list::apply (Grob_info gi)
index 2e6039a9af93a2c5c10b93535d0009a882d1f795..f8818462c6b6ff21c29740ce48d7fa266664ed5e 100644 (file)
@@ -35,6 +35,8 @@
 #include "scm-hash.hh"
 #include "warn.hh"
 
+ADD_SMOB_INIT (Translator_group);
+
 void
 translator_each (SCM list, Translator_method method)
 {
index d6874ef78ca35d90a0e4a088405183961f17870c..a1053c57250f4bc697b91b44a62c1db9e48decd9 100644 (file)
@@ -28,6 +28,8 @@
 
 #include "translator.icc"
 
+ADD_SMOB_INIT (Translator);
+
 Translator::~Translator ()
 {
 }
index d6e3d550d1b47a9ca9a410024252c28c7b0e3dd2..9adc5e6fd072f65c27b62baa61e5d1f6a995f029 100644 (file)
@@ -32,6 +32,8 @@ public:
   Undead (SCM object = SCM_UNDEFINED) : object_ (object) { };
 };
 
+ADD_SMOB_INIT (Undead);
+
 SCM
 Undead::mark_smob ()
 {