Initial commit of OpenSPARC T2 architecture model.
[OpenSPARC-T2-SAM] / sam-t2 / devtools / v8plus / html / swig / Chicken.html
CommitLineData
920dae64
AT
1<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
2<!-- Hand-written HTML -->
3<html>
4<head>
5<title>SWIG and Chicken</title>
6<link rel="stylesheet" type="text/css" href="style.css">
7</head>
8
9<body bgcolor="#ffffff">
10
11<H1><a name="Chicken"></a>17 SWIG and Chicken</H1>
12<!-- INDEX -->
13<div class="sectiontoc">
14<ul>
15<li><a href="#Chicken_nn2">Preliminaries</a>
16<ul>
17<li><a href="#Chicken_nn3">Running SWIG in C mode</a>
18<li><a href="#Chicken_nn4">Running SWIG in C++ mode</a>
19</ul>
20<li><a href="#Chicken_nn5">Code Generation</a>
21<ul>
22<li><a href="#Chicken_nn6">Naming Conventions</a>
23<li><a href="#Chicken_nn7">Modules</a>
24<li><a href="#Chicken_nn8">Constants and Variables</a>
25<li><a href="#Chicken_nn9">Functions</a>
26<li><a href="#Chicken_nn10">Exceptions</a>
27</ul>
28<li><a href="#Chicken_nn11">TinyCLOS</a>
29<li><a href="#Chicken_nn12">Linkage</a>
30<ul>
31<li><a href="#Chicken_nn13">Static binary or shared library linked at compile time</a>
32<li><a href="#Chicken_nn14">Building chicken extension libraries</a>
33<li><a href="#Chicken_nn15">Linking multiple SWIG modules with TinyCLOS</a>
34</ul>
35<li><a href="#Chicken_nn16">Typemaps</a>
36<li><a href="#Chicken_nn17">Pointers</a>
37<ul>
38<li><a href="#collection">Garbage collection</a>
39</ul>
40<li><a href="#Chicken_nn18">Unsupported features and known problems</a>
41</ul>
42</div>
43<!-- INDEX -->
44
45
46
47 <p>
48 This chapter describes SWIG's support of CHICKEN. CHICKEN is a
49 Scheme-to-C compiler supporting most of the language features as
50 defined in the <i>Revised^5 Report on Scheme</i>. Its main
51 attributes are that it
52 </p>
53
54 <ol>
55 <li>generates portable C code</li>
56 <li>includes a customizable interpreter</li>
57 <li>links to C libraries with a simple Foreign Function Interface</li>
58 <li>supports full tail-recursion and first-class continuations</li>
59 </ol>
60
61 <p>
62 When confronted with a large C library, CHICKEN users can use
63 SWIG to generate CHICKEN wrappers for the C library. However,
64 the real advantages of using SWIG with CHICKEN are its
65 <strong>support for C++</strong> -- object-oriented code is
66 difficult to wrap by hand in CHICKEN -- and its <strong>typed
67 pointer representation</strong>, essential for C and C++
68 libraries involving structures or classes.
69
70 </p>
71
72<H2><a name="Chicken_nn2"></a>17.1 Preliminaries</H2>
73
74
75 <p>
76 CHICKEN support was introduced to SWIG in version 1.3.18. SWIG
77 relies on some recent additions to CHICKEN, which are only
78 present in releases of CHICKEN with version number
79 <strong>greater than or equal to 1.89</strong>.
80 To use a chicken version between 1.40 and 1.89, see the <a href="#collection">Garbage collection</a>
81 section below.
82 </p>
83
84 <p>
85 You may want to look at any of the examples in Examples/chicken/
86 or Examples/GIFPlot/Chicken for the basic steps to run SWIG
87 CHICKEN.
88 </p>
89
90<H3><a name="Chicken_nn3"></a>17.1.1 Running SWIG in C mode</H3>
91
92
93 <p>
94 To run SWIG CHICKEN in C mode, use
95 the -chicken option.
96 </p>
97
98 <div class="shell">
99 <pre>% swig -chicken example.i</pre>
100 </div>
101
102 <p>
103 To allow the wrapper to take advantage of future CHICKEN code
104 generation improvements, part of the wrapper is direct CHICKEN
105 function calls (<tt>example_wrap.c</tt>) and part is CHICKEN
106 Scheme (<tt>example.scm</tt>). The basic Scheme code must
107 be compiled to C using your system's CHICKEN compiler or
108 both files can be compiled directly using the much simpler <tt>csc</tt>.
109 </p>
110
111 <div class="shell">
112<pre>
113% chicken example.scm -output-file oexample.c
114</pre>
115 </div>
116
117 <p>
118 So for the C mode of SWIG CHICKEN, <tt>example_wrap.c</tt> and
119 <tt>oexample.c</tt> are the files that must be compiled to
120 object files and linked into your project.
121 </p>
122
123<H3><a name="Chicken_nn4"></a>17.1.2 Running SWIG in C++ mode</H3>
124
125
126 <p>
127 To run SWIG CHICKEN in C++ mode, use
128 the -chicken -c++ option.
129 </p>
130
131 <div class="shell">
132 <pre>% swig -chicken -c++ example.i</pre>
133 </div>
134
135 <p>
136 This will generate <tt>example_wrap.cxx</tt> and
137 <tt>example.scm</tt>. The basic Scheme code must be
138 compiled to C using your system's CHICKEN compiler or
139 both files can be compiled directly using the much simpler <tt>csc</tt>.
140 </p>
141
142 <div class="shell">
143 <pre>% chicken example.scm -output-file oexample.c</pre>
144 </div>
145
146 <p>
147 So for the C++ mode of SWIG CHICKEN, <tt>example_wrap.cxx</tt>
148 and <tt>oexample.c</tt> are the files that must be compiled to
149 object files and linked into your project.
150 </p>
151
152<H2><a name="Chicken_nn5"></a>17.2 Code Generation</H2>
153
154
155<H3><a name="Chicken_nn6"></a>17.2.1 Naming Conventions</H3>
156
157
158 <p>
159 Given a C variable, function or constant declaration named
160 <tt>Foo_Bar</tt>, the declaration will be available
161 in CHICKEN as an identifier ending with
162 <tt>Foo-Bar</tt>. That is, an underscore is converted
163 to a dash.
164 </p>
165
166 <p>
167 You may control what the CHICKEN identifier will be by using the
168 <tt>%rename</tt> SWIG directive in the SWIG interface file.
169 </p>
170
171<H3><a name="Chicken_nn7"></a>17.2.2 Modules</H3>
172
173
174 <p>
175 The name of the module must be declared one of two ways:
176 <ul>
177 <li>Placing <tt>%module example</tt> in the SWIG interface
178 file.</li>
179 <li>Using <tt>-module example</tt> on the SWIG command
180 line.</li>
181 </ul>
182
183 <p>
184 The generated example.scm file then exports <code>(declare (unit modulename))</code>.
185 If you do not want SWIG to export the <code>(declare (unit modulename))</code>, pass
186 the -nounit option to SWIG.
187
188 <p>
189 CHICKEN will be able to access the module using the <code>(declare
190 (uses <i>modulename</i>))</code> CHICKEN Scheme form.
191 </p>
192
193<H3><a name="Chicken_nn8"></a>17.2.3 Constants and Variables</H3>
194
195
196 <p>
197 Constants may be created using any of the four constructs in
198 the interface file:
199 </p>
200 <ol>
201 <li><code>#define MYCONSTANT1 ...</code></li>
202 <li><code>%constant int MYCONSTANT2 = ...</code></li>
203 <li><code>const int MYCONSTANT3 = ...</code></li>
204 <li><code>enum { MYCONSTANT4 = ... };</code></li>
205 </ol>
206
207 <p>
208 In all cases, the constants may be accessed from within CHICKEN
209 using the form <tt>(MYCONSTANT1)</tt>; that is, the constants
210 may be accessed using the read-only parameter form.
211 </p>
212
213 <p>
214 Variables are accessed using the full parameter form.
215 For example, to set the C variable "int my_variable;", use the
216 Scheme form <tt>(my-variable 2345)</tt>. To get the C variable,
217 use <tt>(my-variable)</tt>.
218 </p>
219
220<H3><a name="Chicken_nn9"></a>17.2.4 Functions</H3>
221
222
223 <p>
224 C functions declared in the SWIG interface file will have
225 corresponding CHICKEN Scheme procedures. For example, the C
226 function "int sqrt(double x);" will be available using the
227 Scheme form <tt>(sqrt 2345.0)</tt>. A <code>void</code> return
228 value will give C_SCHEME_UNDEFINED as a result.
229 </p>
230 <p>
231 A function may return more than one value by using the
232 <code>OUTPUT</code> specifier (see Lib/chicken/typemaps.i).
233 They will be returned as multiple values using <code>(values)</code> if there is more than one
234 result (that is, a non-void return value and at least one argout
235 parameter, or a void return value and at least two argout
236 parameters). The return values can then be accessed with <code>(call-with-values)</code>.
237 </p>
238
239<H3><a name="Chicken_nn10"></a>17.2.5 Exceptions</H3>
240
241
242 <p>The SWIG chicken module has support for exceptions thrown from
243 C or C++ code to be caught in scheme.
244 See <a href="Customization.html#exception">Exception handling with %exception</a>
245 for more information about declaring exceptions in the interface file.
246 </p>
247
248 <p>Chicken supports both the <code>SWIG_exception(int code, const char *msg)</code> interface
249 as well as a <code>SWIG_ThrowException(C_word val)</code> function for throwing exceptions from
250 inside the %exception blocks. <code>SWIG_exception</code> will throw a list consisting of the code
251 (as an integer) and the message. Both of these will throw an exception using <code>(abort)</code>,
252 which can be handled by <code>(handle-exceptions)</code>. See
253 <a href="http://www.call-with-current-continuation.org/manual/Exceptions.html#Exceptions">Chicken manual on Exceptions</a>
254 and <a href="http://srfi.schemers.org/srfi-12/srfi-12.html">SFRI-12</a>. Since the exception values are thrown
255 directly, if <code>(condition-case)</code> is used to catch an exception the exception will come through in the <code>val ()</code> case.
256 </p>
257
258 <p>The following simple module</p>
259
260<div class="code"><pre>
261%module exception_test
262
263%inline %{
264 void test_throw(int i) throws (int) {
265 if (i == 1) throw 15;
266 }
267%}
268</pre></div>
269
270 <p>could be run with</p>
271
272<div class="targetlang"><pre>
273(handle-exceptions exvar
274 (if (= exvar 15)
275 (print "Correct!")
276 (print "Threw something else " exvar))
277 (test-throw 1))
278</pre></div>
279
280
281<H2><a name="Chicken_nn11"></a>17.3 TinyCLOS</H2>
282
283
284 <p>
285 The author of TinyCLOS, Gregor Kiczales, describes TinyCLOS as:
286 "Tiny CLOS is a Scheme implementation of a `kernelized' CLOS, with a
287 metaobject protocol. The implementation is even simpler than
288 the simple CLOS found in `The Art of the Metaobject Protocol,'
289 weighing in at around 850 lines of code, including (some)
290 comments and documentation."
291 </p>
292
293 <p>
294 Almost all good Scheme books describe how to use metaobjects and
295 generic procedures to implement an object-oriented Scheme
296 system. Please consult a Scheme book if you are unfamiliar
297 with the concept.
298 </p>
299
300 <p>
301
302 CHICKEN has a modified version of TinyCLOS, which SWIG CHICKEN
303 uses if the -proxy argument is given. If -proxy is passed, then
304 the generated example.scm file will contain TinyCLOS class definitions.
305 A class named Foo is declared as &lt;Foo&gt;, and each member variable
306 is allocated a slot. Member functions are exported as generic functions.
307
308 <p>
309
310 Primitive symbols and functions (the interface that would be presented if
311 -proxy was not passed) are hidden and no longer accessable. If the -unhideprimitive
312 command line argument is passed to SWIG, then the primitive symbols will be
313 available, but each will be prefixed by the string "primitive:"
314
315 <p>
316
317 The exported symbol names can be controlled with the -closprefix and -useclassprefix arguments.
318 If -useclassprefix is passed to SWIG, every member function will be generated with the class name
319 as a prefix. If the -closprefix mymod: argument is passed to SWIG, then the exported functions will
320 be prefixed by the string "mymod:". If -useclassprefix is passed, -closprefix is ignored.
321
322 </p>
323
324<H2><a name="Chicken_nn12"></a>17.4 Linkage</H2>
325
326
327 <p>
328 Please refer to <em>CHICKEN - A practical and portable Scheme
329 system - User's manual</em> for detailed help on how to link
330 object files to create a CHICKEN Scheme program. Briefly, to
331 link object files, be sure to add <tt>`chicken-config
332 -extra-libs -libs`</tt> or <tt>`chicken-config -shared
333 -extra-libs -libs`</tt>to your linker options. Use the
334 <tt>-shared</tt> option if you want to create a dynamically
335 loadable module. You might also want to use the much simpler
336 <tt>csc</tt> or <tt>csc.bat</tt>.
337 </p>
338
339 <p>Each scheme file that is generated
340 by SWIG contains <code>(declare (uses <i>modname</i>))</code>. This means that to load the
341 module from scheme code, the code must include <code>(declare (uses <i>modname</i>))</code>.
342 </p>
343
344
345<H3><a name="Chicken_nn13"></a>17.4.1 Static binary or shared library linked at compile time</H3>
346
347
348 <p>We can easily use csc to build a static binary.</p>
349
350<div class="shell">
351<pre>
352$ swig -chicken example.i
353$ csc -v example.scm example_impl.c example_wrap.c test_script.scm -o example
354$ ./example
355</pre>
356</div>
357
358<p>Similar to the above, any number of <tt>module.scm</tt> files could be compiled
359into a shared library, and then that shared library linked when compiling the
360main application.</p>
361
362<div class="shell">
363<pre>
364$ swig -chicken example.i
365$ csc -sv example.scm example_wrap.c example_impl.c -o example.so
366</pre>
367</div>
368
369<p>The <tt>exmaple.so</tt> file can then linked with <tt>test_script.scm</tt> when it
370is compiled, in which case <tt>test_script.scm</tt> must have <code>(declare (uses example))</code>.
371Multiple SWIG modules could have been linked into <tt>example.so</tt> and each
372one accessed with a <code>(declare (uses ... ))</code>.
373</p>
374
375<div class="shell">
376<pre>
377$ csc -v test_script.scm -lexample
378</pre>
379</div>
380
381<p>An alternative is that the test_script.scm can have the code <code>(load-library 'example "example.so")</code>,
382in which case the test script does not need to be linked with example.so. The test_script.scm file can then
383be run with <tt>csi</tt>.
384</p>
385
386<H3><a name="Chicken_nn14"></a>17.4.2 Building chicken extension libraries</H3>
387
388
389<p>Building a shared library like in the above section only works if the library
390is linked at compile time with a script containing <code>(declare (uses ...))</code> or is
391loaded explicitly with <code>(load-library 'example "example.so")</code>. It is
392not the format that CHICKEN expects for extension libraries and eggs. The problem is the
393<code>(declare (unit <i>modname</i>))</code> inside the <tt>modname.scm</tt> file. There are
394two possible solutions to this.</p>
395
396<p>First, SWIG accepts a <tt>-nounit</tt> argument, in which case the <code>(declare (unit <i>modname</i>))</code>
397is not generated. Then, the <tt>modname.scm</tt> and <tt>modname_wrap.c</tt> files <b>must</b> be compiled into
398their own shared library.</p>
399
400<div class="shell">
401<pre>
402$ csc -sv modname.scm modname_wrap.c modname_impl.c -o modname.so
403</pre>
404</div>
405
406<p>This library can then be loaded by scheme code with the <code>(require 'modname)</code> function.
407See <a href="http://www.call-with-current-continuation.org/manual/Loading-extension-libraries.html">
408Loading-extension-libraries</a> in the eval unit inside the CHICKEN manual for more information.</p>
409
410<p>Another alternative is to run SWIG normally and create a scheme file that contains <code>(declare (uses <i>modname</i>))</code>
411and then compile that file into the shared library as well. For example, inside the <tt>mod_load.scm</tt> file,</p>
412
413<div class="targetlang">
414<pre>
415(declare (uses mod1))
416(declare (uses mod2))
417</pre>
418</div>
419
420<p>Which would then be compiled with</p>
421
422<div class="shell">
423<pre>
424$ swig -chicken mod1.i
425$ swig -chicken mod2.i
426$ csc -sv mod_load.scm mod1.scm mod2.scm mod1_wrap.c mod2_wrap.c mod1_impl.c mod2_impl.c -o mod.so
427</pre>
428</div>
429
430<p>Then the extension library can be loaded with <code>(require 'mod)</code>. As we can see here,
431<tt>mod_load.scm</tt> contains the code that gets exectued when the module is loaded. All this code
432does is load both mod1 and mod2. As we can see, this technique is more useful when you want to
433combine a few SWIG modules into one chicken extension library, especially if modules are related by
434<code>%import</code></p>
435
436<p>In either method, the files that are compiled into the shared library could also be
437packaged into an egg. The <tt>mod1_wrap.c</tt> and <tt>mod2_wrap.c</tt> files that are created by SWIG
438are stand alone and do not need SWIG to be installed to be compiled. Thus the egg could be
439distributed and used by anyone, even if SWIG is not installed.</p>
440
441<p>See the <tt>Examples/chicken/egg</tt> directory in the SWIG source for an example that builds
442two eggs, one using the first method and one using the second method.</p>
443
444<H3><a name="Chicken_nn15"></a>17.4.3 Linking multiple SWIG modules with TinyCLOS</H3>
445
446
447<p>Linking together multiple modules that share type information using the <code>%import</code>
448directive while also using <tt>-proxy</tt> is more complicated. For example, if <tt>mod2.i</tt> imports <tt>mod1.i</tt>, then the
449<tt>mod2.scm</tt> file contains references to symbols declared in <tt>mod1.scm</tt>,
450and thus a <code>(declare (uses <i>mod1</i>))</code> or <code>(require '<i>mod1</i>)</code> must be exported
451to the top of <tt>mod2.scm</tt>. By default, when SWIG encounters an <code>%import "modname.i"</code> directive,
452it exports <code>(declare (uses <i>modname</i>))</code> into the scm file. This works fine unless mod1 was compiled with
453the <tt>-nounit</tt> argument or was compiled into an extension library with other modules under a different name.</p>
454
455<p>One option is to override the automatic generation of <code>(declare (uses mod1))</code>
456by passing the <tt>-noclosuses</tt> option to SWIG when compiling <tt>mod2.i</tt>.
457SWIG then provides the <code>%insert(closprefix) %{ %}</code> directive. Any scheme code inside that directive is inserted into the
458generated .scm file, and if <tt>mod1</tt> was compiled with <tt>-nounit</tt>, the directive should contain <code>(require 'mod1)</code>.
459This option allows for mixed loading as well, where some modules are imported with <code>(declare (uses <i>modname</i>))</code>
460(which means they were compiled without -nounit) and some are imported with <code>(require 'modname)</code>.</p>
461
462<p>The other option is to use the second idea in the above section. Compile all the modules normally, without any
463<code>%insert(closprefix)</code>, <tt>-nounit</tt>, or <tt>-noclosuses</tt>. Then the modules will import each other correctly
464with <code>(declare (uses ...))</code>.
465To create an extension library or an egg, just create a <tt>module_load.scm</tt> file that <code>(declare (uses ...))</code>
466all the modules.</p>
467
468<H2><a name="Chicken_nn16"></a>17.5 Typemaps</H2>
469
470
471 <p>
472 The Chicken module handles all types via typemaps. This information is
473 read from <code>Lib/chicken/typemaps.i</code> and
474 <code>Lib/chicken/chicken.swg</code>.
475 </p>
476
477<H2><a name="Chicken_nn17"></a>17.6 Pointers</H2>
478
479
480 <p>
481 For pointer types, SWIG uses CHICKEN tagged pointers.
482
483 A tagged pointer is an ordinary CHICKEN pointer with an
484 extra slot for a void *. With SWIG
485 CHICKEN, this void * is a pointer to a type-info
486 structure. So each pointer used as input or output from
487 the SWIG-generated CHICKEN wrappers will have type
488 information attached to it. This will let the wrappers
489 correctly determine which method should be called
490 according to the object type hierarchy exposed in the SWIG
491 interface files.
492 </p>
493 <p>
494 To construct a Scheme object from a C pointer, the wrapper code
495 calls the function
496 <code>SWIG_NewPointerObj(void *ptr, swig_type_info *type, int owner)</code>,
497 The function that calls <code>SWIG_NewPointerObj</code> must have a variable declared
498 <code>C_word *known_space = C_alloc(C_SIZEOF_SWIG_POINTER);</code>
499 It is ok to call <code>SWIG_NewPointerObj</code> more than once,
500 just make sure known_space has enough space for all the created pointers.
501 </p>
502 <p>
503 To get the pointer represented by a CHICKEN tagged pointer, the
504 wrapper code calls the function
505 <code>SWIG_ConvertPtr(C_word s, void **result, swig_type_info *type, int flags)</code>,
506 passing a pointer to a struct representing the expected pointer
507 type. flags is either zero or SWIG_POINTER_DISOWN (see below).
508 </p>
509
510<H3><a name="collection"></a>17.6.1 Garbage collection</H3>
511
512
513 <p>If the owner flag passed to <code>SWIG_NewPointerObj</code> is 1, <code>NewPointerObj</code> will add a
514 finalizer to the type which will call the destructor or delete method of
515 that type. The destructor and delete functions are no longer exported for
516 use in scheme code, instead SWIG and chicken manage pointers.
517 In situations where SWIG knows that a function is returning a type that should
518 be garbage collected, SWIG will automaticly set the owner flag to 1. For other functions,
519 the <code>%newobject</code> directive must be specified for functions whose return values
520 should be garbage collected. See
521 <a href="Customization.html#ownership">Object ownership and %newobject</a> for more information.
522 </p>
523
524 <p>In situations where a C or C++ function will assume ownership of a pointer, and thus
525 chicken should no longer garbage collect it, SWIG provides the <code>DISOWN</code> input typemap.
526 After applying this typemap (see the <a href="Typemaps.html">Typemaps chapter</a> for more information on how to apply typemaps),
527 any pointer that gets passed in will no longer be garbage collected.
528 An object is disowned by passing the <code>SWIG_POINTER_DISOWN</code> flag to <code>SWIG_ConvertPtr</code>.
529 <b>Warning:</b> Since the lifetime of the object is now controlled by the underlying code, the object might
530 get deleted while the scheme code still holds a pointer to it. Further use of this pointer
531 can lead to a crash.
532 </p>
533
534 <p>Adding a finalizer function from C code was added to chicken in the 1.89 release, so garbage collection
535 does not work for chicken versions below 1.89. If you would like the SWIG generated code to work with
536 chicken 1.40 to 1.89, pass the <code>-nocollection</code> argument to SWIG. This will not export code
537 inside the _wrap.c file to register finalizers, and will then export destructor functions which
538 must be called manually.
539 </p>
540
541<H2><a name="Chicken_nn18"></a>17.7 Unsupported features and known problems</H2>
542
543
544 <ul>
545 <li>No director support.</li>
546 <li>No support for c++ standard types like std::vector.</li>
547 <li>The TinyCLOS wrappers for overloaded functions will not work correctly when using
548 <a href="SWIGPlus.html#SWIGPlus_default_args">%feature(compactdefaultargs)</a>.</li>
549 </ul>
550
551 <p>TinyCLOS has a limitation such that generic methods do not properly work on methods
552 with different number of specializers: TinyCLOS assumes that every method added to a generic function
553 will have the same number of specializers. SWIG generates functions with different lengths of specializers
554 when C/C++ functions are overloaded. For example, the code</p>
555
556<div class="code">
557<pre>
558class Foo {};
559int foo(int a, Foo *b);
560int foo(int a);
561</pre></div>
562
563<p>will produce scheme code</p>
564
565<div class="targetlang">
566<pre>
567(define-method (foo (arg0 &lt;top&gt;) (arg1 &lt;Foo&gt;)) (<i>call primitive function</i>))
568(define-method (foo (arg0 &lt;top&gt;)) (<i>call primitive function</i>))
569</pre></div>
570
571<p>Using unpatched TinyCLOS, the second <code>(define-method)</code> will replace the first one,
572so calling <code>(foo 3 f)</code> will produce an error.</p>
573
574<p>There are two solutions to this: the
575file <tt>Lib/chicken/tinyclos-multi-generic.patch</tt> in the SWIG source contains a patch against
576tinyclos.scm inside the chicken source to add support into TinyCLOS for multi-argument generics.
577This requires chicken to be rebuilt and custom install of chicken. An alternative is the <tt>Lib/chicken/multi-generic.scm</tt>
578file in the SWIG source. This file can be loaded after TinyCLOS is loaded, and it will override some functions
579inside TinyCLOS to correctly support multi-argument generics. This solution will work on any install of chicken.
580Please see the comments at the top of both files for more information.</p>
581
582 </body>
583</html>