libguile-smobs.texi 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705
  1. @c -*-texinfo-*-
  2. @c This is part of the GNU Guile Reference Manual.
  3. @c Copyright (C) 1996, 1997, 2000, 2001, 2002, 2003, 2004, 2005, 2010, 2011, 2013
  4. @c Free Software Foundation, Inc.
  5. @c See the file guile.texi for copying conditions.
  6. @node Defining New Types (Smobs)
  7. @section Defining New Types (Smobs)
  8. @dfn{Smobs} are Guile's mechanism for adding new primitive types to
  9. the system. The term ``smob'' was coined by Aubrey Jaffer, who says
  10. it comes from ``small object'', referring to the fact that they are
  11. quite limited in size: they can hold just one pointer to a larger
  12. memory block plus 16 extra bits.
  13. To define a new smob type, the programmer provides Guile with some
  14. essential information about the type --- how to print it, how to
  15. garbage collect it, and so on --- and Guile allocates a fresh type tag
  16. for it. The programmer can then use @code{scm_c_define_gsubr} to make
  17. a set of C functions visible to Scheme code that create and operate on
  18. these objects.
  19. (You can find a complete version of the example code used in this
  20. section in the Guile distribution, in @file{doc/example-smob}. That
  21. directory includes a makefile and a suitable @code{main} function, so
  22. you can build a complete interactive Guile shell, extended with the
  23. datatypes described here.)
  24. @menu
  25. * Describing a New Type::
  26. * Creating Smob Instances::
  27. * Type checking::
  28. * Garbage Collecting Smobs::
  29. * Garbage Collecting Simple Smobs::
  30. * Remembering During Operations::
  31. * Double Smobs::
  32. * The Complete Example::
  33. @end menu
  34. @node Describing a New Type
  35. @subsection Describing a New Type
  36. To define a new type, the programmer must write four functions to
  37. manage instances of the type:
  38. @table @code
  39. @item mark
  40. Guile will apply this function to each instance of the new type it
  41. encounters during garbage collection. This function is responsible for
  42. telling the collector about any other @code{SCM} values that the object
  43. has stored. The default smob mark function does nothing.
  44. @xref{Garbage Collecting Smobs}, for more details.
  45. @item free
  46. Guile will apply this function to each instance of the new type that is
  47. to be deallocated. The function should release all resources held by
  48. the object. This is analogous to the Java finalization method-- it is
  49. invoked at an unspecified time (when garbage collection occurs) after
  50. the object is dead. The default free function frees the smob data (if
  51. the size of the struct passed to @code{scm_make_smob_type} is non-zero)
  52. using @code{scm_gc_free}. @xref{Garbage Collecting Smobs}, for more
  53. details.
  54. This function operates while the heap is in an inconsistent state and
  55. must therefore be careful. @xref{Smobs}, for details about what this
  56. function is allowed to do.
  57. @item print
  58. Guile will apply this function to each instance of the new type to print
  59. the value, as for @code{display} or @code{write}. The default print
  60. function prints @code{#<NAME ADDRESS>} where @code{NAME} is the first
  61. argument passed to @code{scm_make_smob_type}.
  62. @item equalp
  63. If Scheme code asks the @code{equal?} function to compare two instances
  64. of the same smob type, Guile calls this function. It should return
  65. @code{SCM_BOOL_T} if @var{a} and @var{b} should be considered
  66. @code{equal?}, or @code{SCM_BOOL_F} otherwise. If @code{equalp} is
  67. @code{NULL}, @code{equal?} will assume that two instances of this type are
  68. never @code{equal?} unless they are @code{eq?}.
  69. @end table
  70. To actually register the new smob type, call @code{scm_make_smob_type}.
  71. It returns a value of type @code{scm_t_bits} which identifies the new
  72. smob type.
  73. The four special functions described above are registered by calling
  74. one of @code{scm_set_smob_mark}, @code{scm_set_smob_free},
  75. @code{scm_set_smob_print}, or @code{scm_set_smob_equalp}, as
  76. appropriate. Each function is intended to be used at most once per
  77. type, and the call should be placed immediately following the call to
  78. @code{scm_make_smob_type}.
  79. There can only be at most 256 different smob types in the system.
  80. Instead of registering a huge number of smob types (for example, one
  81. for each relevant C struct in your application), it is sometimes
  82. better to register just one and implement a second layer of type
  83. dispatching on top of it. This second layer might use the 16 extra
  84. bits to extend its type, for example.
  85. Here is how one might declare and register a new type representing
  86. eight-bit gray-scale images:
  87. @example
  88. #include <libguile.h>
  89. struct image @{
  90. int width, height;
  91. char *pixels;
  92. /* The name of this image */
  93. SCM name;
  94. /* A function to call when this image is
  95. modified, e.g., to update the screen,
  96. or SCM_BOOL_F if no action necessary */
  97. SCM update_func;
  98. @};
  99. static scm_t_bits image_tag;
  100. void
  101. init_image_type (void)
  102. @{
  103. image_tag = scm_make_smob_type ("image", sizeof (struct image));
  104. scm_set_smob_mark (image_tag, mark_image);
  105. scm_set_smob_free (image_tag, free_image);
  106. scm_set_smob_print (image_tag, print_image);
  107. @}
  108. @end example
  109. @node Creating Smob Instances
  110. @subsection Creating Smob Instances
  111. Normally, smobs can have one @emph{immediate} word of data. This word
  112. stores either a pointer to an additional memory block that holds the
  113. real data, or it might hold the data itself when it fits. The word is
  114. large enough for a @code{SCM} value, a pointer to @code{void}, or an
  115. integer that fits into a @code{size_t} or @code{ssize_t}.
  116. You can also create smobs that have two or three immediate words, and
  117. when these words suffice to store all data, it is more efficient to use
  118. these super-sized smobs instead of using a normal smob plus a memory
  119. block. @xref{Double Smobs}, for their discussion.
  120. Guile provides functions for managing memory which are often helpful
  121. when implementing smobs. @xref{Memory Blocks}.
  122. To retrieve the immediate word of a smob, you use the macro
  123. @code{SCM_SMOB_DATA}. It can be set with @code{SCM_SET_SMOB_DATA}.
  124. The 16 extra bits can be accessed with @code{SCM_SMOB_FLAGS} and
  125. @code{SCM_SET_SMOB_FLAGS}.
  126. The two macros @code{SCM_SMOB_DATA} and @code{SCM_SET_SMOB_DATA} treat
  127. the immediate word as if it were of type @code{scm_t_bits}, which is
  128. an unsigned integer type large enough to hold a pointer to
  129. @code{void}. Thus you can use these macros to store arbitrary
  130. pointers in the smob word.
  131. When you want to store a @code{SCM} value directly in the immediate
  132. word of a smob, you should use the macros @code{SCM_SMOB_OBJECT} and
  133. @code{SCM_SET_SMOB_OBJECT} to access it.
  134. Creating a smob instance can be tricky when it consists of multiple
  135. steps that allocate resources and might fail. It is recommended that
  136. you go about creating a smob in the following way:
  137. @itemize
  138. @item
  139. Allocate the memory block for holding the data with
  140. @code{scm_gc_malloc}.
  141. @item
  142. Initialize it to a valid state without calling any functions that might
  143. cause a non-local exits. For example, initialize pointers to NULL.
  144. Also, do not store @code{SCM} values in it that must be protected.
  145. Initialize these fields with @code{SCM_BOOL_F}.
  146. A valid state is one that can be safely acted upon by the @emph{mark}
  147. and @emph{free} functions of your smob type.
  148. @item
  149. Create the smob using @code{scm_new_smob}, passing it the initialized
  150. memory block. (This step will always succeed.)
  151. @item
  152. Complete the initialization of the memory block by, for example,
  153. allocating additional resources and making it point to them.
  154. @end itemize
  155. This procedure ensures that the smob is in a valid state as soon as it
  156. exists, that all resources that are allocated for the smob are
  157. properly associated with it so that they can be properly freed, and
  158. that no @code{SCM} values that need to be protected are stored in it
  159. while the smob does not yet completely exist and thus can not protect
  160. them.
  161. Continuing the example from above, if the global variable
  162. @code{image_tag} contains a tag returned by @code{scm_make_smob_type},
  163. here is how we could construct a smob whose immediate word contains a
  164. pointer to a freshly allocated @code{struct image}:
  165. @example
  166. SCM
  167. make_image (SCM name, SCM s_width, SCM s_height)
  168. @{
  169. SCM smob;
  170. struct image *image;
  171. int width = scm_to_int (s_width);
  172. int height = scm_to_int (s_height);
  173. /* Step 1: Allocate the memory block.
  174. */
  175. image = (struct image *)
  176. scm_gc_malloc (sizeof (struct image), "image");
  177. /* Step 2: Initialize it with straight code.
  178. */
  179. image->width = width;
  180. image->height = height;
  181. image->pixels = NULL;
  182. image->name = SCM_BOOL_F;
  183. image->update_func = SCM_BOOL_F;
  184. /* Step 3: Create the smob.
  185. */
  186. smob = scm_new_smob (image_tag, image);
  187. /* Step 4: Finish the initialization.
  188. */
  189. image->name = name;
  190. image->pixels =
  191. scm_gc_malloc (width * height, "image pixels");
  192. return smob;
  193. @}
  194. @end example
  195. Let us look at what might happen when @code{make_image} is called.
  196. The conversions of @var{s_width} and @var{s_height} to @code{int}s might
  197. fail and signal an error, thus causing a non-local exit. This is not a
  198. problem since no resources have been allocated yet that would have to be
  199. freed.
  200. The allocation of @var{image} in step 1 might fail, but this is likewise
  201. no problem.
  202. Step 2 can not exit non-locally. At the end of it, the @var{image}
  203. struct is in a valid state for the @code{mark_image} and
  204. @code{free_image} functions (see below).
  205. Step 3 can not exit non-locally either. This is guaranteed by Guile.
  206. After it, @var{smob} contains a valid smob that is properly initialized
  207. and protected, and in turn can properly protect the Scheme values in its
  208. @var{image} struct.
  209. But before the smob is completely created, @code{scm_new_smob} might
  210. cause the garbage collector to run. During this garbage collection, the
  211. @code{SCM} values in the @var{image} struct would be invisible to Guile.
  212. It only gets to know about them via the @code{mark_image} function, but
  213. that function can not yet do its job since the smob has not been created
  214. yet. Thus, it is important to not store @code{SCM} values in the
  215. @var{image} struct until after the smob has been created.
  216. Step 4, finally, might fail and cause a non-local exit. In that case,
  217. the complete creation of the smob has not been successful, but it does
  218. nevertheless exist in a valid state. It will eventually be freed by
  219. the garbage collector, and all the resources that have been allocated
  220. for it will be correctly freed by @code{free_image}.
  221. @node Type checking
  222. @subsection Type checking
  223. Functions that operate on smobs should check that the passed
  224. @code{SCM} value indeed is a suitable smob before accessing its data.
  225. They can do this with @code{scm_assert_smob_type}.
  226. For example, here is a simple function that operates on an image smob,
  227. and checks the type of its argument.
  228. @example
  229. SCM
  230. clear_image (SCM image_smob)
  231. @{
  232. int area;
  233. struct image *image;
  234. scm_assert_smob_type (image_tag, image_smob);
  235. image = (struct image *) SCM_SMOB_DATA (image_smob);
  236. area = image->width * image->height;
  237. memset (image->pixels, 0, area);
  238. /* Invoke the image's update function.
  239. */
  240. if (scm_is_true (image->update_func))
  241. scm_call_0 (image->update_func);
  242. scm_remember_upto_here_1 (image_smob);
  243. return SCM_UNSPECIFIED;
  244. @}
  245. @end example
  246. See @ref{Remembering During Operations} for an explanation of the call
  247. to @code{scm_remember_upto_here_1}.
  248. @node Garbage Collecting Smobs
  249. @subsection Garbage Collecting Smobs
  250. Once a smob has been released to the tender mercies of the Scheme
  251. system, it must be prepared to survive garbage collection. Guile calls
  252. the @emph{mark} and @emph{free} functions of the smob to manage this.
  253. As described in more detail elsewhere (@pxref{Conservative GC}), every
  254. object in the Scheme system has a @dfn{mark bit}, which the garbage
  255. collector uses to tell live objects from dead ones. When collection
  256. starts, every object's mark bit is clear. The collector traces pointers
  257. through the heap, starting from objects known to be live, and sets the
  258. mark bit on each object it encounters. When it can find no more
  259. unmarked objects, the collector walks all objects, live and dead, frees
  260. those whose mark bits are still clear, and clears the mark bit on the
  261. others.
  262. The two main portions of the collection are called the @dfn{mark phase},
  263. during which the collector marks live objects, and the @dfn{sweep
  264. phase}, during which the collector frees all unmarked objects.
  265. The mark bit of a smob lives in a special memory region. When the
  266. collector encounters a smob, it sets the smob's mark bit, and uses the
  267. smob's type tag to find the appropriate @emph{mark} function for that
  268. smob. It then calls this @emph{mark} function, passing it the smob as
  269. its only argument.
  270. The @emph{mark} function is responsible for marking any other Scheme
  271. objects the smob refers to. If it does not do so, the objects' mark
  272. bits will still be clear when the collector begins to sweep, and the
  273. collector will free them. If this occurs, it will probably break, or at
  274. least confuse, any code operating on the smob; the smob's @code{SCM}
  275. values will have become dangling references.
  276. To mark an arbitrary Scheme object, the @emph{mark} function calls
  277. @code{scm_gc_mark}.
  278. Thus, here is how we might write @code{mark_image}:
  279. @example
  280. @group
  281. SCM
  282. mark_image (SCM image_smob)
  283. @{
  284. /* Mark the image's name and update function. */
  285. struct image *image = (struct image *) SCM_SMOB_DATA (image_smob);
  286. scm_gc_mark (image->name);
  287. scm_gc_mark (image->update_func);
  288. return SCM_BOOL_F;
  289. @}
  290. @end group
  291. @end example
  292. Note that, even though the image's @code{update_func} could be an
  293. arbitrarily complex structure (representing a procedure and any values
  294. enclosed in its environment), @code{scm_gc_mark} will recurse as
  295. necessary to mark all its components. Because @code{scm_gc_mark} sets
  296. an object's mark bit before it recurses, it is not confused by
  297. circular structures.
  298. As an optimization, the collector will mark whatever value is returned
  299. by the @emph{mark} function; this helps limit depth of recursion during
  300. the mark phase. Thus, the code above should really be written as:
  301. @example
  302. @group
  303. SCM
  304. mark_image (SCM image_smob)
  305. @{
  306. /* Mark the image's name and update function. */
  307. struct image *image = (struct image *) SCM_SMOB_DATA (image_smob);
  308. scm_gc_mark (image->name);
  309. return image->update_func;
  310. @}
  311. @end group
  312. @end example
  313. Finally, when the collector encounters an unmarked smob during the sweep
  314. phase, it uses the smob's tag to find the appropriate @emph{free}
  315. function for the smob. It then calls that function, passing it the smob
  316. as its only argument.
  317. The @emph{free} function must release any resources used by the smob.
  318. However, it must not free objects managed by the collector; the
  319. collector will take care of them. For historical reasons, the return
  320. type of the @emph{free} function should be @code{size_t}, an unsigned
  321. integral type; the @emph{free} function should always return zero.
  322. Here is how we might write the @code{free_image} function for the image
  323. smob type:
  324. @example
  325. size_t
  326. free_image (SCM image_smob)
  327. @{
  328. struct image *image = (struct image *) SCM_SMOB_DATA (image_smob);
  329. scm_gc_free (image->pixels,
  330. image->width * image->height,
  331. "image pixels");
  332. scm_gc_free (image, sizeof (struct image), "image");
  333. return 0;
  334. @}
  335. @end example
  336. During the sweep phase, the garbage collector will clear the mark bits
  337. on all live objects. The code which implements a smob need not do this
  338. itself.
  339. There is no way for smob code to be notified when collection is
  340. complete.
  341. It is usually a good idea to minimize the amount of processing done
  342. during garbage collection; keep the @emph{mark} and @emph{free}
  343. functions very simple. Since collections occur at unpredictable times,
  344. it is easy for any unusual activity to interfere with normal code.
  345. @node Garbage Collecting Simple Smobs
  346. @subsection Garbage Collecting Simple Smobs
  347. It is often useful to define very simple smob types --- smobs which have
  348. no data to mark, other than the cell itself, or smobs whose immediate
  349. data word is simply an ordinary Scheme object, to be marked recursively.
  350. Guile provides some functions to handle these common cases; you can use
  351. this function as your smob type's @emph{mark} function, if your smob's
  352. structure is simple enough.
  353. If the smob refers to no other Scheme objects, then no action is
  354. necessary; the garbage collector has already marked the smob cell
  355. itself. In that case, you can use zero as your mark function.
  356. If the smob refers to exactly one other Scheme object via its first
  357. immediate word, you can use @code{scm_markcdr} as its mark function.
  358. Its definition is simply:
  359. @smallexample
  360. SCM
  361. scm_markcdr (SCM obj)
  362. @{
  363. return SCM_SMOB_OBJECT (obj);
  364. @}
  365. @end smallexample
  366. @node Remembering During Operations
  367. @subsection Remembering During Operations
  368. @cindex remembering
  369. It's important that a smob is visible to the garbage collector
  370. whenever its contents are being accessed. Otherwise it could be freed
  371. while code is still using it.
  372. For example, consider a procedure to convert image data to a list of
  373. pixel values.
  374. @example
  375. SCM
  376. image_to_list (SCM image_smob)
  377. @{
  378. struct image *image;
  379. SCM lst;
  380. int i;
  381. scm_assert_smob_type (image_tag, image_smob);
  382. image = (struct image *) SCM_SMOB_DATA (image_smob);
  383. lst = SCM_EOL;
  384. for (i = image->width * image->height - 1; i >= 0; i--)
  385. lst = scm_cons (scm_from_char (image->pixels[i]), lst);
  386. scm_remember_upto_here_1 (image_smob);
  387. return lst;
  388. @}
  389. @end example
  390. In the loop, only the @code{image} pointer is used and the C compiler
  391. has no reason to keep the @code{image_smob} value anywhere. If
  392. @code{scm_cons} results in a garbage collection, @code{image_smob} might
  393. not be on the stack or anywhere else and could be freed, leaving the
  394. loop accessing freed data. The use of @code{scm_remember_upto_here_1}
  395. prevents this, by creating a reference to @code{image_smob} after all
  396. data accesses.
  397. There's no need to do the same for @code{lst}, since that's the return
  398. value and the compiler will certainly keep it in a register or
  399. somewhere throughout the routine.
  400. The @code{clear_image} example previously shown (@pxref{Type checking})
  401. also used @code{scm_remember_upto_here_1} for this reason.
  402. It's only in quite rare circumstances that a missing
  403. @code{scm_remember_upto_here_1} will bite, but when it happens the
  404. consequences are serious. Fortunately the rule is simple: whenever
  405. calling a Guile library function or doing something that might, ensure
  406. that the @code{SCM} of a smob is referenced past all accesses to its
  407. insides. Do this by adding an @code{scm_remember_upto_here_1} if
  408. there are no other references.
  409. In a multi-threaded program, the rule is the same. As far as a given
  410. thread is concerned, a garbage collection still only occurs within a
  411. Guile library function, not at an arbitrary time. (Guile waits for all
  412. threads to reach one of its library functions, and holds them there
  413. while the collector runs.)
  414. @node Double Smobs
  415. @subsection Double Smobs
  416. Smobs are called smob because they are small: they normally have only
  417. room for one @code{void*} or @code{SCM} value plus 16 bits. The
  418. reason for this is that smobs are directly implemented by using the
  419. low-level, two-word cells of Guile that are also used to implement
  420. pairs, for example. (@pxref{Data Representation} for the
  421. details.) One word of the two-word cells is used for
  422. @code{SCM_SMOB_DATA} (or @code{SCM_SMOB_OBJECT}), the other contains
  423. the 16-bit type tag and the 16 extra bits.
  424. In addition to the fundamental two-word cells, Guile also has
  425. four-word cells, which are appropriately called @dfn{double cells}.
  426. You can use them for @dfn{double smobs} and get two more immediate
  427. words of type @code{scm_t_bits}.
  428. A double smob is created with @code{scm_new_double_smob}. Its immediate
  429. words can be retrieved as @code{scm_t_bits} with @code{SCM_SMOB_DATA_2}
  430. and @code{SCM_SMOB_DATA_3} in addition to @code{SCM_SMOB_DATA}.
  431. Unsurprisingly, the words can be set to @code{scm_t_bits} values with
  432. @code{SCM_SET_SMOB_DATA_2} and @code{SCM_SET_SMOB_DATA_3}.
  433. Of course there are also @code{SCM_SMOB_OBJECT_2},
  434. @code{SCM_SMOB_OBJECT_3}, @code{SCM_SET_SMOB_OBJECT_2}, and
  435. @code{SCM_SET_SMOB_OBJECT_3}.
  436. @node The Complete Example
  437. @subsection The Complete Example
  438. Here is the complete text of the implementation of the image datatype,
  439. as presented in the sections above. We also provide a definition for
  440. the smob's @emph{print} function, and make some objects and functions
  441. static, to clarify exactly what the surrounding code is using.
  442. As mentioned above, you can find this code in the Guile distribution, in
  443. @file{doc/example-smob}. That directory includes a makefile and a
  444. suitable @code{main} function, so you can build a complete interactive
  445. Guile shell, extended with the datatypes described here.)
  446. @example
  447. /* file "image-type.c" */
  448. #include <stdlib.h>
  449. #include <libguile.h>
  450. static scm_t_bits image_tag;
  451. struct image @{
  452. int width, height;
  453. char *pixels;
  454. /* The name of this image */
  455. SCM name;
  456. /* A function to call when this image is
  457. modified, e.g., to update the screen,
  458. or SCM_BOOL_F if no action necessary */
  459. SCM update_func;
  460. @};
  461. static SCM
  462. make_image (SCM name, SCM s_width, SCM s_height)
  463. @{
  464. SCM smob;
  465. struct image *image;
  466. int width = scm_to_int (s_width);
  467. int height = scm_to_int (s_height);
  468. /* Step 1: Allocate the memory block.
  469. */
  470. image = (struct image *)
  471. scm_gc_malloc (sizeof (struct image), "image");
  472. /* Step 2: Initialize it with straight code.
  473. */
  474. image->width = width;
  475. image->height = height;
  476. image->pixels = NULL;
  477. image->name = SCM_BOOL_F;
  478. image->update_func = SCM_BOOL_F;
  479. /* Step 3: Create the smob.
  480. */
  481. smob = scm_new_smob (image_tag, image);
  482. /* Step 4: Finish the initialization.
  483. */
  484. image->name = name;
  485. image->pixels =
  486. scm_gc_malloc (width * height, "image pixels");
  487. return smob;
  488. @}
  489. SCM
  490. clear_image (SCM image_smob)
  491. @{
  492. int area;
  493. struct image *image;
  494. scm_assert_smob_type (image_tag, image_smob);
  495. image = (struct image *) SCM_SMOB_DATA (image_smob);
  496. area = image->width * image->height;
  497. memset (image->pixels, 0, area);
  498. /* Invoke the image's update function.
  499. */
  500. if (scm_is_true (image->update_func))
  501. scm_call_0 (image->update_func);
  502. scm_remember_upto_here_1 (image_smob);
  503. return SCM_UNSPECIFIED;
  504. @}
  505. static SCM
  506. mark_image (SCM image_smob)
  507. @{
  508. /* Mark the image's name and update function. */
  509. struct image *image = (struct image *) SCM_SMOB_DATA (image_smob);
  510. scm_gc_mark (image->name);
  511. return image->update_func;
  512. @}
  513. static size_t
  514. free_image (SCM image_smob)
  515. @{
  516. struct image *image = (struct image *) SCM_SMOB_DATA (image_smob);
  517. scm_gc_free (image->pixels,
  518. image->width * image->height,
  519. "image pixels");
  520. scm_gc_free (image, sizeof (struct image), "image");
  521. return 0;
  522. @}
  523. static int
  524. print_image (SCM image_smob, SCM port, scm_print_state *pstate)
  525. @{
  526. struct image *image = (struct image *) SCM_SMOB_DATA (image_smob);
  527. scm_puts ("#<image ", port);
  528. scm_display (image->name, port);
  529. scm_puts (">", port);
  530. /* non-zero means success */
  531. return 1;
  532. @}
  533. void
  534. init_image_type (void)
  535. @{
  536. image_tag = scm_make_smob_type ("image", sizeof (struct image));
  537. scm_set_smob_mark (image_tag, mark_image);
  538. scm_set_smob_free (image_tag, free_image);
  539. scm_set_smob_print (image_tag, print_image);
  540. scm_c_define_gsubr ("clear-image", 1, 0, 0, clear_image);
  541. scm_c_define_gsubr ("make-image", 3, 0, 0, make_image);
  542. @}
  543. @end example
  544. Here is a sample build and interaction with the code from the
  545. @file{example-smob} directory, on the author's machine:
  546. @example
  547. zwingli:example-smob$ make CC=gcc
  548. gcc `pkg-config --cflags guile-@value{EFFECTIVE-VERSION}` -c image-type.c -o image-type.o
  549. gcc `pkg-config --cflags guile-@value{EFFECTIVE-VERSION}` -c myguile.c -o myguile.o
  550. gcc image-type.o myguile.o `pkg-config --libs guile-@value{EFFECTIVE-VERSION}` -o myguile
  551. zwingli:example-smob$ ./myguile
  552. guile> make-image
  553. #<primitive-procedure make-image>
  554. guile> (define i (make-image "Whistler's Mother" 100 100))
  555. guile> i
  556. #<image Whistler's Mother>
  557. guile> (clear-image i)
  558. guile> (clear-image 4)
  559. ERROR: In procedure clear-image in expression (clear-image 4):
  560. ERROR: Wrong type (expecting image): 4
  561. ABORT: (wrong-type-arg)
  562. Type "(backtrace)" to get more information.
  563. guile>
  564. @end example