]> git.donarmstrong.com Git - lilypond.git/blob - lily/include/smobs.hh
New upstream version 2.19.65
[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   However, this is not sufficient when classes with their own
99   protectable elements are derived from the Complex base class.  This
100   is because initialization order is a tricky thing: once a base class
101   calls smobify_self () in its constructor, further allocations during
102   construction of base class and derived classes might lead to
103   mark_smob calls on the object under construction.  When those call a
104   virtual function like derived_mark, the virtual function
105   corresponding to the incompletely initialized object of derived
106   class type is likely to be called.
107
108   The order of initialization of an object consists in calling the
109   constructors of virtual base classes, then of non-virtual base
110   classes, then initializing all data members.
111
112   As a result, the constructor of a derived class comes too late for
113   initialization of data members that may be accessed in the
114   derived_mark kind of functions.
115
116   Such data members are consequently moved into Preinit_* classes
117   which come before the smobifying base class in derivation order and
118   construct the contained data members in a state suitable for
119   derived_mark calls.
120
121
122   CALLING INTERFACE
123
124   Common global functions for accessing C++ smob objects:
125
126   - unsmob<T> (SCM x) - unpack X and return a pointer to the C++ object,
127     or 0 if it has the wrong type.
128
129   IMPLEMENTATION
130
131   For implementating a class, the following public members can be
132   provided in the top class itself:
133
134   - SCM equal_p (SCM a, SCM b) - compare A and B. Returns a Scheme
135     boolean.  If the class does not define this function, equal? will
136     be equivalent to eq?.  The function will only be called when both
137     objects are of the respective type and not eq? to each other.
138
139   - mark_smob () function, that calls scm_gc_mark () on all Scheme
140     objects in the class.  If the class does not define this function,
141     it must not contain non-immediate Scheme values.
142
143   - a print_smob () function, that displays a representation for
144     debugging purposes.  If the class does not define this function,
145     the output will be #<Classname> when printing.
146
147   - a static const * const type_p_name_ string set to something like
148     "ly:grob?".  When provided, an accordingly named function for
149     checking for the given smob type will be available in Scheme.
150
151 */
152
153 // Initialization class.  Create a variable or static data member of
154 // this type at global scope (or creation will happen too late for
155 // Scheme initialization), initialising with a function to be called.
156 // Reference somewhere (like in the constructor of the containing
157 // class) to make sure the variable is actually instantiated.
158
159 class Scm_init {
160   static const Scm_init * list_;
161   void (*const fun_)(void);
162   Scm_init const * const next_;
163   Scm_init ();          // don't use default constructor, don't define
164   Scm_init (const Scm_init &);  // don't define copy constructor
165 public:
166   Scm_init (void (*fun) (void)) : fun_ (fun), next_ (list_)
167   { list_ = this; }
168   static void init ();
169 };
170
171 template <class Super>
172 class Smob_base
173 {
174   static scm_t_bits smob_tag_;
175   static Scm_init scm_init_;
176   static void init (void);
177   static string smob_name_;
178 protected:
179   static Super *unchecked_unsmob (SCM s)
180   {
181     return reinterpret_cast<Super *> (SCM_SMOB_DATA (s));
182   }
183   // reference scm_init_ in smob_tag which is sure to be called.  The
184   // constructor, in contrast, may not be called at all in classes
185   // like Smob1.
186   static scm_t_bits smob_tag () { (void) scm_init_; return smob_tag_; }
187   Smob_base () { }
188   static SCM register_ptr (Super *p);
189   static Super *unregister_ptr (SCM obj);
190 private:
191   // Those fallbacks are _only_ for internal use by Smob_base.  They
192   // are characterized by no knowledge about the implemented type
193   // apart from the type's name.  Overriding them as a template
194   // specialization is _not_ intended since a type-dependent
195   // implementation will in general need access to possibly private
196   // parts of the Super class.  So any class-dependent override should
197   // be done by redefining the respective function in the Super class
198   // (where it will mask the private template member) rather than
199   // specializing a different template function/pointer.
200   //
201   // Most default functions are do-nothings.  void init() will
202   // recognize their address when not overriden and will then refrain
203   // altogether from passing the the respective callbacks to GUILE.
204
205   SCM mark_smob (void) const;
206   static SCM mark_trampoline (SCM); // Used for calling mark_smob
207   static size_t free_smob (SCM obj);
208   static SCM equal_p (SCM, SCM);
209   int print_smob (SCM, scm_print_state *) const;
210   static int print_trampoline (SCM, SCM, scm_print_state *);
211   static void smob_proc_init (scm_t_bits) { };
212
213   // Define type_p_name_ in the Super class as a const char * const.
214   // Without such definition it defaults to 0, producing no predicate.
215
216   static const char * const type_p_name_; // = 0
217
218   // LY_DECLARE_SMOB_PROC is used in the Super class definition for
219   // making a smob callable like a function.  Its first argument is a
220   // function member pointer constant, to a function taking the
221   // correct number of SCM arguments and returning SCM.  The function
222   // itself has to be defined separately.
223
224 #define LY_DECLARE_SMOB_PROC(PMF, REQ, OPT, VAR)                        \
225   static void smob_proc_init (scm_t_bits smob_tag)                      \
226   {                                                                     \
227     scm_set_smob_apply (smob_tag,                                       \
228                         (scm_t_subr)smob_trampoline<PMF>,               \
229                         REQ, OPT, VAR);                                 \
230   }
231
232   // Well, function template argument packs are a C++11 feature.  So
233   // we just define a bunch of trampolines manually.  It turns out
234   // that GUILEĀ 1.8.8 cannot actually make callable structures with
235   // more than 3 arguments anyway.  That's surprising, to say the
236   // least, but in emergency situations one can always use a "rest"
237   // argument and take it apart manually.
238
239   template <SCM (Super::*pmf)(void)>
240   static SCM smob_trampoline (SCM self)
241   {
242     return (Super::unchecked_unsmob (self)->*pmf)();
243   }
244   template <SCM (Super::*pmf)(SCM)>
245   static SCM smob_trampoline (SCM self, SCM arg1)
246   {
247     return (Super::unchecked_unsmob (self)->*pmf)(arg1);
248   }
249   template <SCM (Super::*pmf)(SCM, SCM)>
250   static SCM smob_trampoline (SCM self, SCM arg1, SCM arg2)
251   {
252     return (Super::unchecked_unsmob (self)->*pmf)(arg1, arg2);
253   }
254   template <SCM (Super::*pmf)(SCM, SCM, SCM)>
255   static SCM smob_trampoline (SCM self, SCM arg1, SCM arg2, SCM arg3)
256   {
257     return (Super::unchecked_unsmob (self)->*pmf)(arg1, arg2, arg3);
258   }
259
260   static bool is_smob (SCM s)
261   {
262     return SCM_SMOB_PREDICATE (smob_tag (), s);
263   }
264   static SCM smob_p (SCM s)
265   {
266     return is_smob (s) ? SCM_BOOL_T : SCM_BOOL_F;
267   }
268
269   template <class T>
270   friend T *unsmob (SCM s);
271
272   template <class T>
273   friend T *ly_assert_smob (SCM s, int number, const char *fun);
274 };
275
276 template <class T>
277 inline T *unsmob (SCM s)
278 {
279   return T::is_smob (s) ? dynamic_cast<T *> (T::unchecked_unsmob (s)) : 0;
280 }
281
282 // Simple smobs
283 template <class Super>
284 class Simple_smob : public Smob_base<Super> {
285 public:
286   static size_t free_smob (SCM obj)
287   {
288     delete Smob_base<Super>::unregister_ptr (obj);
289     return 0;
290   }
291   SCM smobbed_copy () const
292   {
293     Super *p = new Super(*static_cast<const Super *> (this));
294     return Smob_base<Super>::register_ptr (p);
295   }
296 };
297
298 void protect_smob (SCM smob, SCM *prot_cons);
299 void unprotect_smob (SCM smob, SCM *prot_cons);
300
301 // The Smob_core class is not templated and contains material not
302 // depending on the Super class.
303
304 class Smob_core {
305 protected:
306   SCM self_scm_;
307   Smob_core () : self_scm_ (SCM_UNDEFINED) { };
308 public:
309   SCM self_scm () const { return self_scm_; }
310   Listener get_listener (SCM callback);
311 };
312
313 template <class Super>
314 class Smob : public Smob_core, public Smob_base<Super> {
315 private:
316   SCM protection_cons_;
317   Smob (const Smob<Super> &); // Do not define!  Not copyable!
318 protected:
319   Smob () : protection_cons_ (SCM_EOL) { };
320 public:
321   static size_t free_smob (SCM obj)
322   {
323     delete Smob_base<Super>::unregister_ptr (obj);
324     return 0;
325   }
326   SCM unprotected_smobify_self ()
327   {
328     SCM s = Smob_base<Super>::register_ptr (static_cast<Super *> (this));
329     self_scm_ = s;
330     return s;
331   }
332   void protect ()
333   {
334     protect_smob (self_scm_, &protection_cons_);
335   }
336   void smobify_self () {
337     protect_smob (unprotected_smobify_self (), &protection_cons_);
338   }
339   SCM unprotect ()
340   {
341     SCM s = self_scm_;
342     unprotect_smob (s, &protection_cons_);
343     return s;
344   }
345 };
346
347 extern bool parsed_objects_should_be_dead;
348 class parsed_dead
349 {
350   static vector<parsed_dead *> elements;
351   SCM data;
352   SCM readout_one ()
353   {
354     SCM res = data;
355     data = SCM_UNDEFINED;
356     return res;
357   }
358 public:
359   parsed_dead () : data (SCM_UNDEFINED)
360   {
361     elements.push_back (this);
362   }
363   void checkin (SCM arg) { data = arg; }
364   static SCM readout ();
365 };
366
367 // This does not appear to work with GUILEv2's garbage collector:
368 // Objects are found in the GC phase but printing them will crash at
369 // least some, so they are apparently not protected in spite of being
370 // included in the GC scans.  So it would appear that scanning smobs
371 // is not equivalent to marking them.  Ugh.
372 #if defined(DEBUG) && !GUILEV2
373 #define ASSERT_LIVE_IS_ALLOWED(arg)                                     \
374   do {                                                                  \
375     static parsed_dead pass_here;                                       \
376     if (parsed_objects_should_be_dead)                                  \
377       pass_here.checkin (arg);                                          \
378   } while (0)
379 #else
380 #define ASSERT_LIVE_IS_ALLOWED(arg) do { (void)(arg); }  \
381   while (0)
382 #endif
383
384 #include "smobs.tcc"
385 #endif /* SMOBS_HH */