2 This file is part of LilyPond, the GNU music typesetter.
4 Copyright (C) 1999--2015 Han-Wen Nienhuys <hanwen@xs4all.nl>
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.
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.
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/>.
23 #include "lily-guile.hh"
24 #include "lily-proto.hh"
29 Smobs are GUILEs mechanism of exporting C(++) objects to the Scheme
30 world. They are documented in the GUILE manual.
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.
37 There are two types of smob objects.
39 1. Simple smobs are intended for simple objects like numbers:
40 immutable objects that can be copied without change of meaning.
42 To obtain an SCM version of a simple smob, use the member function
45 Simple smobs are created by deriving from Simple_smob<Classname>.
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.
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.
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.
65 The constructor for a complex smob should have 3 steps:
67 * initialize all SCM members to an immediate value (like SCM_EOL)
69 * call smobify_self ()
71 * initialize SCM members
75 Complex_smob::Complex_smob : public Smob<Complex_smob> () {
76 scm_member_ = SCM_EOL;
78 scm_member_ = <..what you want to store..>
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
86 Complex_smob *p = new Complex_smob;
87 list = scm_cons (p->self_scm (), list);
90 Since unprotect returns the SCM object itself, this particular case
93 Complex_smob *p = new Complex_smob;
94 list = scm_cons (p->unprotect (), list);
96 Complex smobs are created by deriving from Smob<Classname>.
100 Common public methods to C++ smob objects:
102 - unsmob (SCM x) - unpacks X and returns pointer to the C++ object,
103 or 0 if it has the wrong type. This can be used as a boolean
104 condition at C++ level.
105 - smob_p (SCM x) returns #t or #f at Scheme level.
109 For implementating a class, the following public members can be
110 provided in the top class itself:
112 - SCM equal_p (SCM a, SCM b) - compare A and B. Returns a Scheme
113 boolean. If the class does not define this function, equal? will
114 be equivalent to eq?. The function will only be called when both
115 objects are of the respective type and not eq? to each other.
117 - mark_smob () function, that calls scm_gc_mark () on all Scheme
118 objects in the class. If the class does not define this function,
119 it must not contain non-immediate Scheme values.
121 - a print_smob () function, that displays a representation for
122 debugging purposes. If the class does not define this function,
123 the output will be #<Classname> when printing.
125 - a static const type_p_name_[] string set to something like
126 "ly:grob?". When provided, an accordingly named function for
127 checking for the given smob type will be available in Scheme.
131 // Initialization class. Create a variable or static data member of
132 // this type at global scope (or creation will happen too late for
133 // Scheme initialization), initialising with a function to be called.
134 // Reference somewhere (like in the constructor of the containing
135 // class) to make sure the variable is actually instantiated.
138 static const Scm_init * list_;
139 void (*const fun_)(void);
140 Scm_init const * const next_;
141 Scm_init (); // don't use default constructor, don't define
142 Scm_init (const Scm_init &); // don't define copy constructor
144 Scm_init (void (*fun) (void)) : fun_ (fun), next_ (list_)
149 template <class Super>
152 static scm_t_bits smob_tag_;
153 static Scm_init scm_init_;
154 static void init (void);
155 static string smob_name_;
156 static Super *unchecked_unsmob (SCM s)
158 return reinterpret_cast<Super *> (SCM_SMOB_DATA (s));
161 // reference scm_init_ in smob_tag which is sure to be called. The
162 // constructor, in contrast, may not be called at all in classes
164 static scm_t_bits smob_tag () { (void) scm_init_; return smob_tag_; }
166 static SCM register_ptr (Super *p);
167 static Super *unregister_ptr (SCM obj);
169 // Those fallbacks are _only_ for internal use by Smob_base. They
170 // are characterized by no knowledge about the implemented type
171 // apart from the type's name. Overriding them as a template
172 // specialization is _not_ intended since a type-dependent
173 // implementation will in general need access to possibly private
174 // parts of the Super class. So any class-dependent override should
175 // be done by redefining the respective function in the Super class
176 // (where it will mask the private template member) rather than
177 // specializing a different template function/pointer.
179 // Most default functions are do-nothings. void init() will
180 // recognize their address when not overriden and will then refrain
181 // altogether from passing the the respective callbacks to GUILE.
182 SCM mark_smob (void);
183 static SCM mark_trampoline (SCM); // Used for calling mark_smob
184 static size_t free_smob (SCM obj);
185 static SCM equal_p (SCM, SCM);
186 int print_smob (SCM, scm_print_state *);
187 static int print_trampoline (SCM, SCM, scm_print_state *);
189 // type_p_name_ can be overriden in the Super class with a static
190 // const char [] string. This requires both a declaration in the
191 // class as well as a single instantiation outside. Using a
192 // template specialization for supplying a different string name
193 // right in Smob_base<Super> itself seems tempting, but the C++
194 // rules would then require a specialization declaration at the
195 // class definition site as well as a specialization instantiation
196 // in a single compilation unit. That requires just as much source
197 // code maintenance while being harder to understand and quite
198 // trickier in its failure symptoms when things go wrong. So we
199 // just use a static zero as "not here" indication.
200 static const int type_p_name_ = 0;
202 // LY_DECLARE_SMOB_PROC is used in the Super class definition for
203 // making a smob callable like a function. Declaration has to be
204 // public. It may be either be completed with a semicolon in which
205 // case a definition of the member function smob_proc has to be done
206 // outside of the class body, or the semicolon is left off and an
207 // inline function body is added immediately below. It would be
208 // nice if this were a non-static member function but it would seem
209 // tricky to do the required trampolining for unsmobbing the first
210 // argument of the callback and using it as a this pointer.
211 #define LY_DECLARE_SMOB_PROC(REQ, OPT, VAR, ARGLIST) \
212 static const int smob_proc_signature_ = ((REQ)<<8)|((OPT)<<4)|(VAR); \
213 static SCM smob_proc ARGLIST
215 // a separate LY_DEFINE_SMOB_PROC seems sort of pointless as it
216 // would just result in SCM CLASS::smob_proc ARGLIST
218 // The default case without function functionality is recognized by
219 // smob_proc_signature being -1.
220 static const int smob_proc = 0;
221 static const int smob_proc_signature_ = -1;
224 static bool is_smob (SCM s)
226 return SCM_SMOB_PREDICATE (smob_tag (), s);
228 static SCM smob_p (SCM s)
230 return is_smob (s) ? SCM_BOOL_T : SCM_BOOL_F;
232 static Super *unsmob (SCM s)
234 return is_smob (s) ? Super::unchecked_unsmob (s) : 0;
238 // derived_unsmob includes a dynamic_cast:
241 inline T *derived_unsmob (SCM arg)
243 return dynamic_cast<T *> (T::unsmob (arg));
247 template <class Super>
248 class Simple_smob : public Smob_base<Super> {
250 static size_t free_smob (SCM obj)
252 delete Smob_base<Super>::unregister_ptr (obj);
255 SCM smobbed_copy () const
257 Super *p = new Super(*static_cast<const Super *> (this));
258 return Smob_base<Super>::register_ptr (p);
262 void protect_smob (SCM smob, SCM *prot_cons);
263 void unprotect_smob (SCM smob, SCM *prot_cons);
265 // The Smob_core class is not templated and contains material not
266 // depending on the Super class.
271 Smob_core () : self_scm_ (SCM_UNDEFINED) { };
273 SCM self_scm () const { return self_scm_; }
274 Listener get_listener (SCM callback);
277 template <class Super>
278 class Smob : public Smob_core, public Smob_base<Super> {
280 SCM protection_cons_;
281 Smob (const Smob<Super> &); // Do not define! Not copyable!
283 Smob () : protection_cons_ (SCM_EOL) { };
285 static size_t free_smob (SCM obj)
287 delete Smob_base<Super>::unregister_ptr (obj);
290 SCM unprotected_smobify_self ()
292 SCM s = Smob_base<Super>::register_ptr (static_cast<Super *> (this));
298 protect_smob (self_scm_, &protection_cons_);
300 void smobify_self () {
301 protect_smob (unprotected_smobify_self (), &protection_cons_);
306 unprotect_smob (s, &protection_cons_);
311 extern bool parsed_objects_should_be_dead;
314 static vector<parsed_dead *> elements;
319 data = SCM_UNDEFINED;
323 parsed_dead () : data (SCM_UNDEFINED)
325 elements.push_back (this);
327 void checkin (SCM arg) { data = arg; }
328 static SCM readout ();
331 // This does not appear to work with GUILEv2's garbage collector:
332 // Objects are found in the GC phase but printing them will crash at
333 // least some, so they are apparently not protected in spite of being
334 // included in the GC scans. So it would appear that scanning smobs
335 // is not equivalent to marking them. Ugh.
336 #if defined(DEBUG) && !GUILEV2
337 #define ASSERT_LIVE_IS_ALLOWED(arg) \
339 static parsed_dead pass_here; \
340 if (parsed_objects_should_be_dead) \
341 pass_here.checkin (arg); \
344 #define ASSERT_LIVE_IS_ALLOWED(arg) do { (void)(arg); } \
349 #endif /* SMOBS_HH */