]> git.donarmstrong.com Git - lilypond.git/blob - lily/include/smobs.hh
Issue 4997/1: Add Preinit class for early initialization
[lilypond.git] / lily / include / smobs.hh
1 /*
2   This file is part of LilyPond, the GNU music typesetter.
3
4   Copyright (C) 1999--2015 Han-Wen Nienhuys <hanwen@xs4all.nl>
5
6   LilyPond is free software: you can redistribute it and/or modify
7   it under the terms of the GNU General Public License as published by
8   the Free Software Foundation, either version 3 of the License, or
9   (at your option) any later version.
10
11   LilyPond is distributed in the hope that it will be useful,
12   but WITHOUT ANY WARRANTY; without even the implied warranty of
13   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14   GNU General Public License for more details.
15
16   You should have received a copy of the GNU General Public License
17   along with LilyPond.  If not, see <http://www.gnu.org/licenses/>.
18 */
19
20 #ifndef SMOBS_HH
21 #define SMOBS_HH
22
23 #include "lily-guile.hh"
24 #include "lily-proto.hh"
25 #include "warn.hh"
26 #include <string>
27
28 /*
29   Smobs are GUILEs mechanism of exporting C(++) objects to the Scheme
30   world.  They are documented in the GUILE manual.
31
32
33   In LilyPond, C++ objects can be placed under the control of GUILE's
34   type system and garbage collection mechanism by inheriting from one
35   of several Smob base classes.
36
37   There are two types of smob objects.
38
39   1. Simple smobs are intended for simple objects like numbers:
40   immutable objects that can be copied without change of meaning.
41
42   To obtain an SCM version of a simple smob, use the member function
43   SCM smobbed_copy ().
44
45   Simple smobs are created by deriving from Simple_smob<Classname>.
46
47   A simple smob is only optionally under the reign of the GUILE
48   garbage collector: its usual life time is that of a normal C++
49   object.  While a smobbed_copy () is fully under control of the
50   garbage collector and will have its mark_smob function called during
51   garbage collection, an automatic variable of this type will not have
52   mark_smob called, but rather have its memory image in the call stack
53   scanned for contained non-immediate SCM values.  Anything requiring
54   more complex mark_smob behavior is not suitable for a simple smob.
55
56   When you create a smobbed_copy, the _copy_ is fully managed by the
57   GUILE memory system.  As a corollary, multiple smobbed_copy calls
58   yield multiple GUILE objects generally not eq? to each other.
59
60   2. Complex smobs are objects that have an identity. These objects
61   carry this identity in the form of a self_scm () method, which is a
62   SCM pointer to the object itself.  Complex smobs are always under
63   control of the GUILE memory system.
64
65   The constructor for a complex smob should have 3 steps:
66
67   * initialize all SCM members to an immediate value (like SCM_EOL)
68
69   * call smobify_self ()
70
71   * initialize SCM members
72
73   For example,
74
75   Complex_smob::Complex_smob : public Smob<Complex_smob> () {
76   scm_member_ = SCM_EOL;
77   smobify_self ();
78   scm_member_ = <..what you want to store..>
79   }
80
81   after construction, the self_scm () field of a complex smob is
82   protected from Garbage Collection.  This protection should be
83   removed once the object is put into another (reachable) Scheme data
84   structure, i.e.
85
86   Complex_smob *p = new Complex_smob;
87   list = scm_cons (p->self_scm (), list);
88   p->unprotect ();
89
90   Since unprotect returns the SCM object itself, this particular case
91   can be written as
92
93   Complex_smob *p = new Complex_smob;
94   list = scm_cons (p->unprotect (), list);
95
96   Complex smobs are created by deriving from Smob<Classname>.
97
98   CALLING INTERFACE
99
100   Common global functions for accessing C++ smob objects:
101
102   - unsmob<T> (SCM x) - unpack X and return a pointer to the C++ object,
103     or 0 if it has the wrong type.
104
105   IMPLEMENTATION
106
107   For implementating a class, the following public members can be
108   provided in the top class itself:
109
110   - SCM equal_p (SCM a, SCM b) - compare A and B. Returns a Scheme
111     boolean.  If the class does not define this function, equal? will
112     be equivalent to eq?.  The function will only be called when both
113     objects are of the respective type and not eq? to each other.
114
115   - mark_smob () function, that calls scm_gc_mark () on all Scheme
116     objects in the class.  If the class does not define this function,
117     it must not contain non-immediate Scheme values.
118
119   - a print_smob () function, that displays a representation for
120     debugging purposes.  If the class does not define this function,
121     the output will be #<Classname> when printing.
122
123   - a static const * const type_p_name_ string set to something like
124     "ly:grob?".  When provided, an accordingly named function for
125     checking for the given smob type will be available in Scheme.
126
127 */
128
129 // Initialization class.  Create a variable or static data member of
130 // this type at global scope (or creation will happen too late for
131 // Scheme initialization), initialising with a function to be called.
132 // Reference somewhere (like in the constructor of the containing
133 // class) to make sure the variable is actually instantiated.
134
135 class Scm_init {
136   static const Scm_init * list_;
137   void (*const fun_)(void);
138   Scm_init const * const next_;
139   Scm_init ();          // don't use default constructor, don't define
140   Scm_init (const Scm_init &);  // don't define copy constructor
141 public:
142   Scm_init (void (*fun) (void)) : fun_ (fun), next_ (list_)
143   { list_ = this; }
144   static void init ();
145 };
146
147 template <class Super>
148 class Smob_base
149 {
150   static scm_t_bits smob_tag_;
151   static Scm_init scm_init_;
152   static void init (void);
153   static string smob_name_;
154 protected:
155   static Super *unchecked_unsmob (SCM s)
156   {
157     return reinterpret_cast<Super *> (SCM_SMOB_DATA (s));
158   }
159   // reference scm_init_ in smob_tag which is sure to be called.  The
160   // constructor, in contrast, may not be called at all in classes
161   // like Smob1.
162   static scm_t_bits smob_tag () { (void) scm_init_; return smob_tag_; }
163   Smob_base () { }
164   static SCM register_ptr (Super *p);
165   static Super *unregister_ptr (SCM obj);
166 private:
167   // Those fallbacks are _only_ for internal use by Smob_base.  They
168   // are characterized by no knowledge about the implemented type
169   // apart from the type's name.  Overriding them as a template
170   // specialization is _not_ intended since a type-dependent
171   // implementation will in general need access to possibly private
172   // parts of the Super class.  So any class-dependent override should
173   // be done by redefining the respective function in the Super class
174   // (where it will mask the private template member) rather than
175   // specializing a different template function/pointer.
176   //
177   // Most default functions are do-nothings.  void init() will
178   // recognize their address when not overriden and will then refrain
179   // altogether from passing the the respective callbacks to GUILE.
180
181   SCM mark_smob (void) const;
182   static SCM mark_trampoline (SCM); // Used for calling mark_smob
183   static size_t free_smob (SCM obj);
184   static SCM equal_p (SCM, SCM);
185   int print_smob (SCM, scm_print_state *) const;
186   static int print_trampoline (SCM, SCM, scm_print_state *);
187   static void smob_proc_init (scm_t_bits) { };
188
189   // Define type_p_name_ in the Super class as a const char * const.
190   // Without such definition it defaults to 0, producing no predicate.
191
192   static const char * const type_p_name_; // = 0
193
194   // LY_DECLARE_SMOB_PROC is used in the Super class definition for
195   // making a smob callable like a function.  Its first argument is a
196   // function member pointer constant, to a function taking the
197   // correct number of SCM arguments and returning SCM.  The function
198   // itself has to be defined separately.
199
200 #define LY_DECLARE_SMOB_PROC(PMF, REQ, OPT, VAR)                        \
201   static void smob_proc_init (scm_t_bits smob_tag)                      \
202   {                                                                     \
203     scm_set_smob_apply (smob_tag,                                       \
204                         (scm_t_subr)smob_trampoline<PMF>,               \
205                         REQ, OPT, VAR);                                 \
206   }
207
208   // Well, function template argument packs are a C++11 feature.  So
209   // we just define a bunch of trampolines manually.  It turns out
210   // that GUILEĀ 1.8.8 cannot actually make callable structures with
211   // more than 3 arguments anyway.  That's surprising, to say the
212   // least, but in emergency situations one can always use a "rest"
213   // argument and take it apart manually.
214
215   template <SCM (Super::*pmf)(void)>
216   static SCM smob_trampoline (SCM self)
217   {
218     return (Super::unchecked_unsmob (self)->*pmf)();
219   }
220   template <SCM (Super::*pmf)(SCM)>
221   static SCM smob_trampoline (SCM self, SCM arg1)
222   {
223     return (Super::unchecked_unsmob (self)->*pmf)(arg1);
224   }
225   template <SCM (Super::*pmf)(SCM, SCM)>
226   static SCM smob_trampoline (SCM self, SCM arg1, SCM arg2)
227   {
228     return (Super::unchecked_unsmob (self)->*pmf)(arg1, arg2);
229   }
230   template <SCM (Super::*pmf)(SCM, SCM, SCM)>
231   static SCM smob_trampoline (SCM self, SCM arg1, SCM arg2, SCM arg3)
232   {
233     return (Super::unchecked_unsmob (self)->*pmf)(arg1, arg2, arg3);
234   }
235
236   static bool is_smob (SCM s)
237   {
238     return SCM_SMOB_PREDICATE (smob_tag (), s);
239   }
240   static SCM smob_p (SCM s)
241   {
242     return is_smob (s) ? SCM_BOOL_T : SCM_BOOL_F;
243   }
244
245   template <class T>
246   friend T *unsmob (SCM s);
247
248   template <class T>
249   friend T *ly_assert_smob (SCM s, int number, const char *fun);
250 };
251
252 template <class T>
253 inline T *unsmob (SCM s)
254 {
255   return T::is_smob (s) ? dynamic_cast<T *> (T::unchecked_unsmob (s)) : 0;
256 }
257
258 // Simple smobs
259 template <class Super>
260 class Simple_smob : public Smob_base<Super> {
261 public:
262   static size_t free_smob (SCM obj)
263   {
264     delete Smob_base<Super>::unregister_ptr (obj);
265     return 0;
266   }
267   SCM smobbed_copy () const
268   {
269     Super *p = new Super(*static_cast<const Super *> (this));
270     return Smob_base<Super>::register_ptr (p);
271   }
272 };
273
274 void protect_smob (SCM smob, SCM *prot_cons);
275 void unprotect_smob (SCM smob, SCM *prot_cons);
276
277 // The Smob_core class is not templated and contains material not
278 // depending on the Super class.
279
280 class Smob_core {
281 protected:
282   SCM self_scm_;
283   Smob_core () : self_scm_ (SCM_UNDEFINED) { };
284 public:
285   SCM self_scm () const { return self_scm_; }
286   Listener get_listener (SCM callback);
287 };
288
289 template <class Super>
290 class Smob : public Smob_core, public Smob_base<Super> {
291 private:
292   SCM protection_cons_;
293   Smob (const Smob<Super> &); // Do not define!  Not copyable!
294 protected:
295   Smob () : protection_cons_ (SCM_EOL) { };
296 public:
297   static size_t free_smob (SCM obj)
298   {
299     delete Smob_base<Super>::unregister_ptr (obj);
300     return 0;
301   }
302   SCM unprotected_smobify_self ()
303   {
304     SCM s = Smob_base<Super>::register_ptr (static_cast<Super *> (this));
305     self_scm_ = s;
306     return s;
307   }
308   void protect ()
309   {
310     protect_smob (self_scm_, &protection_cons_);
311   }
312   void smobify_self () {
313     protect_smob (unprotected_smobify_self (), &protection_cons_);
314   }
315   SCM unprotect ()
316   {
317     SCM s = self_scm_;
318     unprotect_smob (s, &protection_cons_);
319     return s;
320   }
321 };
322
323 // This is a tricky thing: once a base class calls smobify_self () in
324 // its constructor, further allocations during construction of base
325 // class and derived classes might lead to mark_smob calls on the
326 // object under construction.  When those call a virtual function like
327 // derived_mark, the virtual function corresponding to the
328 // incompletely initialized object is likely to be called.
329 //
330 // The order of initialization of an object consists in calling the
331 // constructors of virtual base classes, then of non-virtual base
332 // classes, then initializing all data members.
333 //
334 // As a result, the derived constructor comes too late for
335 // initialization.  That's where the Preinit template class comes in.
336 // Derive from it _before_ deriving from the smobifying base class
337 // providing derived_mark, and it will call its Base class' pre_init
338 // function (which must not rely on the instantiation being complete).
339
340 template <class Base>
341 class Preinit {
342 protected:
343   Preinit ()
344   {
345     (static_cast <Base *> (this)) -> pre_init ();
346   }
347 };
348
349 extern bool parsed_objects_should_be_dead;
350 class parsed_dead
351 {
352   static vector<parsed_dead *> elements;
353   SCM data;
354   SCM readout_one ()
355   {
356     SCM res = data;
357     data = SCM_UNDEFINED;
358     return res;
359   }
360 public:
361   parsed_dead () : data (SCM_UNDEFINED)
362   {
363     elements.push_back (this);
364   }
365   void checkin (SCM arg) { data = arg; }
366   static SCM readout ();
367 };
368
369 // This does not appear to work with GUILEv2's garbage collector:
370 // Objects are found in the GC phase but printing them will crash at
371 // least some, so they are apparently not protected in spite of being
372 // included in the GC scans.  So it would appear that scanning smobs
373 // is not equivalent to marking them.  Ugh.
374 #if defined(DEBUG) && !GUILEV2
375 #define ASSERT_LIVE_IS_ALLOWED(arg)                                     \
376   do {                                                                  \
377     static parsed_dead pass_here;                                       \
378     if (parsed_objects_should_be_dead)                                  \
379       pass_here.checkin (arg);                                          \
380   } while (0)
381 #else
382 #define ASSERT_LIVE_IS_ALLOWED(arg) do { (void)(arg); }  \
383   while (0)
384 #endif
385
386 #include "smobs.tcc"
387 #endif /* SMOBS_HH */