Beginnings of <slot> slot definition class
[bpt/guile.git] / libguile / goops.c
CommitLineData
e2fafeb9 1/* Copyright (C) 1998,1999,2000,2001,2002,2003,2004,2008,2009,2010,2011,2012,2013,2014,2015
366ecaec 2 * Free Software Foundation, Inc.
6d77c894 3 *
73be1d9e 4 * This library is free software; you can redistribute it and/or
53befeb7
NJ
5 * modify it under the terms of the GNU Lesser General Public License
6 * as published by the Free Software Foundation; either version 3 of
7 * the License, or (at your option) any later version.
6d77c894 8 *
53befeb7
NJ
9 * This library is distributed in the hope that it will be useful, but
10 * WITHOUT ANY WARRANTY; without even the implied warranty of
73be1d9e
MV
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
6d77c894 13 *
73be1d9e
MV
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
53befeb7
NJ
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
17 * 02110-1301 USA
73be1d9e 18 */
80662eda
MD
19\f
20
21/* This software is a derivative work of other copyrighted softwares; the
22 * copyright notices of these softwares are placed in the file COPYRIGHTS
23 *
24 * This file is based upon stklos.c from the STk distribution by
25 * Erick Gallesio <eg@unice.fr>.
26 */
27
dbb605f5
LC
28#ifdef HAVE_CONFIG_H
29# include <config.h>
30#endif
31
80662eda 32#include "libguile/_scm.h"
4e047c3e 33#include "libguile/async.h"
539d5410 34#include "libguile/chars.h"
80662eda
MD
35#include "libguile/dynwind.h"
36#include "libguile/eval.h"
9fdf9fd3 37#include "libguile/gsubr.h"
80662eda
MD
38#include "libguile/hashtab.h"
39#include "libguile/keywords.h"
40#include "libguile/macros.h"
41#include "libguile/modules.h"
80662eda
MD
42#include "libguile/ports.h"
43#include "libguile/procprop.h"
efcebb5b 44#include "libguile/programs.h"
80662eda
MD
45#include "libguile/smob.h"
46#include "libguile/strings.h"
47#include "libguile/strports.h"
48#include "libguile/vectors.h"
80662eda 49
ca83b028 50#include "libguile/validate.h"
80662eda
MD
51#include "libguile/goops.h"
52
efcebb5b
AW
53/* Port classes */
54#define SCM_IN_PCLASS_INDEX 0
55#define SCM_OUT_PCLASS_INDEX SCM_I_MAX_PORT_TYPE_COUNT
56#define SCM_INOUT_PCLASS_INDEX (2 * SCM_I_MAX_PORT_TYPE_COUNT)
57
51fd1cd6
AW
58/* Objects have identity, so references to classes and instances are by
59 value, not by reference. Redefinition of a class or modification of
60 an instance causes in-place update; you can think of GOOPS as
61 building in its own indirection, and for that reason referring to
62 GOOPS values by variable reference is unnecessary.
bef95911 63
51fd1cd6
AW
64 References to ordinary procedures is by reference (by variable),
65 though, as in the rest of Guile. */
66
f37bece4
AW
67SCM_KEYWORD (k_name, "name");
68SCM_KEYWORD (k_setter, "setter");
2025a027 69SCM_SYMBOL (sym_redefined, "redefined");
f37bece4
AW
70SCM_GLOBAL_SYMBOL (scm_sym_args, "args");
71
f6088819
AW
72static int goops_loaded_p = 0;
73
51fd1cd6 74static SCM var_make_standard_class = SCM_BOOL_F;
bef95911 75static SCM var_change_class = SCM_BOOL_F;
e0590e7c 76static SCM var_make = SCM_BOOL_F;
f37bece4 77static SCM var_inherit_applicable = SCM_BOOL_F;
70dd6000
AW
78static SCM var_class_name = SCM_BOOL_F;
79static SCM var_class_direct_supers = SCM_BOOL_F;
80static SCM var_class_direct_slots = SCM_BOOL_F;
81static SCM var_class_direct_subclasses = SCM_BOOL_F;
82static SCM var_class_direct_methods = SCM_BOOL_F;
83static SCM var_class_precedence_list = SCM_BOOL_F;
84static SCM var_class_slots = SCM_BOOL_F;
bef95911 85
48c981c9
AW
86static SCM var_generic_function_methods = SCM_BOOL_F;
87static SCM var_method_generic_function = SCM_BOOL_F;
88static SCM var_method_specializers = SCM_BOOL_F;
89static SCM var_method_procedure = SCM_BOOL_F;
90
ade4cf4c
AW
91static SCM var_slot_ref = SCM_BOOL_F;
92static SCM var_slot_set_x = SCM_BOOL_F;
93static SCM var_slot_bound_p = SCM_BOOL_F;
94static SCM var_slot_exists_p = SCM_BOOL_F;
95
539d5410 96/* These variables are filled in by the object system when loaded. */
57898597
AW
97static SCM class_boolean, class_char, class_pair;
98static SCM class_procedure, class_string, class_symbol;
99static SCM class_primitive_generic;
100static SCM class_vector, class_null;
101static SCM class_integer, class_real, class_complex, class_fraction;
102static SCM class_unknown;
103static SCM class_top, class_object, class_class;
104static SCM class_applicable;
105static SCM class_applicable_struct, class_applicable_struct_with_setter;
106static SCM class_generic, class_generic_with_setter;
107static SCM class_accessor;
108static SCM class_extended_generic, class_extended_generic_with_setter;
109static SCM class_extended_accessor;
110static SCM class_method;
111static SCM class_accessor_method;
112static SCM class_procedure_class;
113static SCM class_applicable_struct_class;
114static SCM class_applicable_struct_with_setter_class;
115static SCM class_number, class_list;
116static SCM class_keyword;
117static SCM class_port, class_input_output_port;
118static SCM class_input_port, class_output_port;
119static SCM class_foreign_slot;
120static SCM class_self, class_protected;
121static SCM class_hidden, class_opaque, class_read_only;
122static SCM class_protected_hidden, class_protected_opaque, class_protected_read_only;
123static SCM class_scm;
124static SCM class_int, class_float, class_double;
80662eda 125
e2c2a699 126static SCM class_foreign;
9ea31741
AW
127static SCM class_hashtable;
128static SCM class_fluid;
129static SCM class_dynamic_state;
6f3b0cc2 130static SCM class_frame;
6f3b0cc2 131static SCM class_vm_cont;
f826a886
AW
132static SCM class_bytevector;
133static SCM class_uvec;
b2637c98 134static SCM class_array;
ff1feca9 135static SCM class_bitvector;
9ea31741 136
f3c6a02c
AW
137static SCM vtable_class_map = SCM_BOOL_F;
138
63385df2
LC
139/* Port classes. Allocate 3 times the maximum number of port types so that
140 input ports, output ports, and in/out ports can be stored at different
141 offsets. See `SCM_IN_PCLASS_INDEX' et al. */
57898597 142SCM scm_i_port_class[3 * SCM_I_MAX_PORT_TYPE_COUNT];
63385df2
LC
143
144/* SMOB classes. */
57898597 145SCM scm_i_smob_class[SCM_I_MAX_SMOB_TYPE_COUNT];
539d5410 146
c2aa5d9b
AW
147SCM scm_module_goops;
148
761338f6 149static SCM scm_sys_make_vtable_vtable (SCM layout);
51fd1cd6 150static SCM scm_sys_init_layout_x (SCM class, SCM layout);
567a6d1e 151static SCM scm_sys_clear_fields_x (SCM obj, SCM unbound);
82ab5090 152static SCM scm_sys_goops_early_init (void);
398d8ee1 153static SCM scm_sys_goops_loaded (void);
80662eda 154
f3c6a02c 155
60061fe0
AW
156\f
157
761338f6 158SCM_DEFINE (scm_sys_make_vtable_vtable, "%make-vtable-vtable", 1, 0, 0,
c2aa5d9b
AW
159 (SCM layout),
160 "")
761338f6 161#define FUNC_NAME s_scm_sys_make_vtable_vtable
c2aa5d9b 162{
761338f6 163 return scm_i_make_vtable_vtable (layout);
c2aa5d9b
AW
164}
165#undef FUNC_NAME
166
60061fe0
AW
167SCM
168scm_make_standard_class (SCM meta, SCM name, SCM dsupers, SCM dslots)
169{
170 return scm_call_4 (scm_variable_ref (var_make_standard_class),
171 meta, name, dsupers, dslots);
172}
173
174SCM_DEFINE (scm_sys_init_layout_x, "%init-layout!", 2, 0, 0,
175 (SCM class, SCM layout),
176 "")
177#define FUNC_NAME s_scm_sys_init_layout_x
178{
179 SCM_VALIDATE_INSTANCE (1, class);
180 SCM_ASSERT (!scm_is_symbol (SCM_VTABLE_LAYOUT (class)), class, 1, FUNC_NAME);
181 SCM_VALIDATE_STRING (2, layout);
182
183 SCM_SET_VTABLE_LAYOUT (class, scm_make_struct_layout (layout));
184 scm_i_struct_inherit_vtable_magic (SCM_CLASS_OF (class), class);
185 SCM_SET_CLASS_FLAGS (class, SCM_CLASSF_GOOPS_OR_VALID);
186
187 return SCM_UNSPECIFIED;
188}
189#undef FUNC_NAME
190
191
192\f
193
539d5410
MV
194/* This function is used for efficient type dispatch. */
195SCM_DEFINE (scm_class_of, "class-of", 1, 0, 0,
196 (SCM x),
197 "Return the class of @var{x}.")
198#define FUNC_NAME s_scm_class_of
199{
200 switch (SCM_ITAG3 (x))
201 {
202 case scm_tc3_int_1:
203 case scm_tc3_int_2:
57898597 204 return class_integer;
539d5410
MV
205
206 case scm_tc3_imm24:
207 if (SCM_CHARP (x))
57898597 208 return class_char;
539d5410 209 else if (scm_is_bool (x))
57898597 210 return class_boolean;
539d5410 211 else if (scm_is_null (x))
57898597 212 return class_null;
539d5410 213 else
57898597 214 return class_unknown;
539d5410
MV
215
216 case scm_tc3_cons:
217 switch (SCM_TYP7 (x))
218 {
219 case scm_tcs_cons_nimcar:
57898597 220 return class_pair;
539d5410 221 case scm_tc7_symbol:
57898597 222 return class_symbol;
539d5410
MV
223 case scm_tc7_vector:
224 case scm_tc7_wvect:
57898597 225 return class_vector;
5b46a8c2 226 case scm_tc7_pointer:
e2c2a699 227 return class_foreign;
c99de5aa 228 case scm_tc7_hashtable:
9ea31741
AW
229 return class_hashtable;
230 case scm_tc7_fluid:
231 return class_fluid;
232 case scm_tc7_dynamic_state:
233 return class_dynamic_state;
6f3b0cc2
AW
234 case scm_tc7_frame:
235 return class_frame;
e2fafeb9 236 case scm_tc7_keyword:
57898597 237 return class_keyword;
6f3b0cc2
AW
238 case scm_tc7_vm_cont:
239 return class_vm_cont;
f826a886
AW
240 case scm_tc7_bytevector:
241 if (SCM_BYTEVECTOR_ELEMENT_TYPE (x) == SCM_ARRAY_ELEMENT_TYPE_VU8)
242 return class_bytevector;
243 else
244 return class_uvec;
b2637c98
AW
245 case scm_tc7_array:
246 return class_array;
ff1feca9
AW
247 case scm_tc7_bitvector:
248 return class_bitvector;
539d5410 249 case scm_tc7_string:
57898597 250 return class_string;
539d5410
MV
251 case scm_tc7_number:
252 switch SCM_TYP16 (x) {
253 case scm_tc16_big:
57898597 254 return class_integer;
539d5410 255 case scm_tc16_real:
57898597 256 return class_real;
539d5410 257 case scm_tc16_complex:
57898597 258 return class_complex;
539d5410 259 case scm_tc16_fraction:
57898597 260 return class_fraction;
539d5410 261 }
e0755cd1 262 case scm_tc7_program:
b2b33168
AW
263 if (SCM_PROGRAM_IS_PRIMITIVE_GENERIC (x)
264 && SCM_UNPACK (*SCM_SUBR_GENERIC (x)))
57898597 265 return class_primitive_generic;
fd12a19a 266 else
57898597 267 return class_procedure;
539d5410
MV
268
269 case scm_tc7_smob:
270 {
271 scm_t_bits type = SCM_TYP16 (x);
272 if (type != scm_tc16_port_with_ps)
57898597 273 return scm_i_smob_class[SCM_TC2SMOBNUM (type)];
539d5410
MV
274 x = SCM_PORT_WITH_PS_PORT (x);
275 /* fall through to ports */
276 }
277 case scm_tc7_port:
57898597
AW
278 return scm_i_port_class[(SCM_WRTNG & SCM_CELL_WORD_0 (x)
279 ? (SCM_RDNG & SCM_CELL_WORD_0 (x)
280 ? SCM_INOUT_PCLASS_INDEX | SCM_PTOBNUM (x)
281 : SCM_OUT_PCLASS_INDEX | SCM_PTOBNUM (x))
282 : SCM_IN_PCLASS_INDEX | SCM_PTOBNUM (x))];
539d5410
MV
283 case scm_tcs_struct:
284 if (SCM_OBJ_CLASS_FLAGS (x) & SCM_CLASSF_GOOPS_VALID)
2025a027 285 /* A GOOPS object with a valid class. */
539d5410
MV
286 return SCM_CLASS_OF (x);
287 else if (SCM_OBJ_CLASS_FLAGS (x) & SCM_CLASSF_GOOPS)
2025a027 288 /* A GOOPS object whose class might have been redefined. */
539d5410 289 {
2025a027
AW
290 SCM class = SCM_CLASS_OF (x);
291 SCM new_class = scm_slot_ref (class, sym_redefined);
292 if (!scm_is_false (new_class))
293 scm_change_object_class (x, class, new_class);
294 /* Re-load class from instance. */
539d5410
MV
295 return SCM_CLASS_OF (x);
296 }
297 else
f3c6a02c 298 return scm_i_define_class_for_vtable (SCM_CLASS_OF (x));
539d5410
MV
299 default:
300 if (scm_is_pair (x))
57898597 301 return class_pair;
539d5410 302 else
57898597 303 return class_unknown;
539d5410
MV
304 }
305
306 case scm_tc3_struct:
307 case scm_tc3_tc7_1:
308 case scm_tc3_tc7_2:
314b8716 309 /* case scm_tc3_unused: */
539d5410
MV
310 /* Never reached */
311 break;
312 }
57898597 313 return class_unknown;
539d5410
MV
314}
315#undef FUNC_NAME
316
80662eda 317
c2aa5d9b 318\f
80662eda 319
398d8ee1
KN
320SCM_DEFINE (scm_instance_p, "instance?", 1, 0, 0,
321 (SCM obj),
6bcefd15 322 "Return @code{#t} if @var{obj} is an instance.")
398d8ee1 323#define FUNC_NAME s_scm_instance_p
80662eda 324{
7888309b 325 return scm_from_bool (SCM_INSTANCEP (obj));
80662eda 326}
398d8ee1 327#undef FUNC_NAME
80662eda 328
57898597
AW
329int
330scm_is_generic (SCM x)
331{
332 return SCM_INSTANCEP (x) && SCM_SUBCLASSP (SCM_CLASS_OF (x), class_generic);
333}
334
335int
336scm_is_method (SCM x)
337{
338 return SCM_INSTANCEP (x) && SCM_SUBCLASSP (SCM_CLASS_OF (x), class_method);
339}
80662eda 340
c2aa5d9b
AW
341
342\f
51fd1cd6 343
70dd6000
AW
344SCM
345scm_class_name (SCM obj)
80662eda 346{
70dd6000 347 return scm_call_1 (scm_variable_ref (var_class_name), obj);
80662eda
MD
348}
349
70dd6000
AW
350SCM
351scm_class_direct_supers (SCM obj)
80662eda 352{
70dd6000 353 return scm_call_1 (scm_variable_ref (var_class_direct_supers), obj);
80662eda
MD
354}
355
70dd6000
AW
356SCM
357scm_class_direct_slots (SCM obj)
80662eda 358{
70dd6000 359 return scm_call_1 (scm_variable_ref (var_class_direct_slots), obj);
80662eda
MD
360}
361
70dd6000
AW
362SCM
363scm_class_direct_subclasses (SCM obj)
80662eda 364{
70dd6000 365 return scm_call_1 (scm_variable_ref (var_class_direct_subclasses), obj);
80662eda
MD
366}
367
70dd6000
AW
368SCM
369scm_class_direct_methods (SCM obj)
80662eda 370{
70dd6000 371 return scm_call_1 (scm_variable_ref (var_class_direct_methods), obj);
80662eda
MD
372}
373
70dd6000
AW
374SCM
375scm_class_precedence_list (SCM obj)
80662eda 376{
70dd6000 377 return scm_call_1 (scm_variable_ref (var_class_precedence_list), obj);
80662eda
MD
378}
379
70dd6000
AW
380SCM
381scm_class_slots (SCM obj)
80662eda 382{
70dd6000 383 return scm_call_1 (scm_variable_ref (var_class_slots), obj);
80662eda
MD
384}
385
c2aa5d9b
AW
386
387\f
388
398d8ee1 389SCM_DEFINE (scm_generic_function_name, "generic-function-name", 1, 0, 0,
70dd6000 390 (SCM obj),
6bcefd15 391 "Return the name of the generic function @var{obj}.")
398d8ee1 392#define FUNC_NAME s_scm_generic_function_name
80662eda 393{
398d8ee1 394 SCM_VALIDATE_GENERIC (1, obj);
80662eda
MD
395 return scm_procedure_property (obj, scm_sym_name);
396}
398d8ee1 397#undef FUNC_NAME
80662eda 398
48c981c9
AW
399SCM
400scm_generic_function_methods (SCM obj)
80662eda 401{
48c981c9 402 return scm_call_1 (scm_variable_ref (var_generic_function_methods), obj);
80662eda
MD
403}
404
48c981c9
AW
405SCM
406scm_method_generic_function (SCM obj)
80662eda 407{
48c981c9 408 return scm_call_1 (scm_variable_ref (var_method_generic_function), obj);
80662eda
MD
409}
410
48c981c9
AW
411SCM
412scm_method_specializers (SCM obj)
80662eda 413{
48c981c9 414 return scm_call_1 (scm_variable_ref (var_method_specializers), obj);
80662eda
MD
415}
416
48c981c9
AW
417SCM
418scm_method_procedure (SCM obj)
80662eda 419{
48c981c9 420 return scm_call_1 (scm_variable_ref (var_method_procedure), obj);
80662eda
MD
421}
422
c2aa5d9b
AW
423
424\f
80662eda 425
ade4cf4c
AW
426SCM
427scm_slot_ref (SCM obj, SCM slot_name)
80662eda 428{
ade4cf4c 429 return scm_call_2 (scm_variable_ref (var_slot_ref), obj, slot_name);
80662eda
MD
430}
431
ade4cf4c
AW
432SCM
433scm_slot_set_x (SCM obj, SCM slot_name, SCM value)
80662eda 434{
ade4cf4c 435 return scm_call_3 (scm_variable_ref (var_slot_set_x), obj, slot_name, value);
80662eda
MD
436}
437
ade4cf4c
AW
438SCM
439scm_slot_bound_p (SCM obj, SCM slot_name)
80662eda 440{
ade4cf4c 441 return scm_call_2 (scm_variable_ref (var_slot_bound_p), obj, slot_name);
80662eda
MD
442}
443
ade4cf4c
AW
444SCM
445scm_slot_exists_p (SCM obj, SCM slot_name)
80662eda 446{
ade4cf4c 447 return scm_call_2 (scm_variable_ref (var_slot_exists_p), obj, slot_name);
80662eda
MD
448}
449
c2aa5d9b
AW
450
451\f
452
567a6d1e
AW
453SCM_DEFINE (scm_sys_clear_fields_x, "%clear-fields!", 2, 0, 0,
454 (SCM obj, SCM unbound),
07452c83
AW
455 "")
456#define FUNC_NAME s_scm_sys_clear_fields_x
80662eda 457{
e25f3727 458 scm_t_signed_bits n, i;
07452c83 459 SCM vtable, layout;
80662eda 460
07452c83
AW
461 SCM_VALIDATE_STRUCT (1, obj);
462 vtable = SCM_STRUCT_VTABLE (obj);
80662eda 463
07452c83
AW
464 n = SCM_STRUCT_DATA_REF (vtable, scm_vtable_index_size);
465 layout = SCM_VTABLE_LAYOUT (vtable);
80662eda 466
07452c83 467 /* Set all SCM-holding slots to the GOOPS unbound value. */
b6cf4d02 468 for (i = 0; i < n; i++)
07452c83 469 if (scm_i_symbol_ref (layout, i*2) == 'p')
567a6d1e 470 SCM_STRUCT_SLOT_SET (obj, i, unbound);
6d77c894 471
07452c83 472 return SCM_UNSPECIFIED;
80662eda 473}
398d8ee1 474#undef FUNC_NAME
80662eda 475
c2aa5d9b
AW
476
477\f
80662eda 478
398d8ee1
KN
479SCM_DEFINE (scm_sys_modify_instance, "%modify-instance", 2, 0, 0,
480 (SCM old, SCM new),
c2aa5d9b 481 "Used by change-class to modify objects in place.")
398d8ee1 482#define FUNC_NAME s_scm_sys_modify_instance
80662eda 483{
398d8ee1
KN
484 SCM_VALIDATE_INSTANCE (1, old);
485 SCM_VALIDATE_INSTANCE (2, new);
80662eda 486
6d77c894 487 /* Exchange the data contained in old and new. We exchange rather than
80662eda
MD
488 * scratch the old value with new to be correct with GC.
489 * See "Class redefinition protocol above".
490 */
9de87eea 491 SCM_CRITICAL_SECTION_START;
80662eda 492 {
32b12f40
KR
493 scm_t_bits word0, word1;
494 word0 = SCM_CELL_WORD_0 (old);
495 word1 = SCM_CELL_WORD_1 (old);
496 SCM_SET_CELL_WORD_0 (old, SCM_CELL_WORD_0 (new));
497 SCM_SET_CELL_WORD_1 (old, SCM_CELL_WORD_1 (new));
498 SCM_SET_CELL_WORD_0 (new, word0);
499 SCM_SET_CELL_WORD_1 (new, word1);
80662eda 500 }
9de87eea 501 SCM_CRITICAL_SECTION_END;
80662eda
MD
502 return SCM_UNSPECIFIED;
503}
398d8ee1 504#undef FUNC_NAME
80662eda 505
398d8ee1
KN
506SCM_DEFINE (scm_sys_modify_class, "%modify-class", 2, 0, 0,
507 (SCM old, SCM new),
508 "")
509#define FUNC_NAME s_scm_sys_modify_class
80662eda 510{
398d8ee1
KN
511 SCM_VALIDATE_CLASS (1, old);
512 SCM_VALIDATE_CLASS (2, new);
80662eda 513
9de87eea 514 SCM_CRITICAL_SECTION_START;
80662eda 515 {
32b12f40
KR
516 scm_t_bits word0, word1;
517 word0 = SCM_CELL_WORD_0 (old);
518 word1 = SCM_CELL_WORD_1 (old);
519 SCM_SET_CELL_WORD_0 (old, SCM_CELL_WORD_0 (new));
520 SCM_SET_CELL_WORD_1 (old, SCM_CELL_WORD_1 (new));
b6cf4d02 521 SCM_STRUCT_DATA (old)[scm_vtable_index_self] = SCM_UNPACK (old);
32b12f40
KR
522 SCM_SET_CELL_WORD_0 (new, word0);
523 SCM_SET_CELL_WORD_1 (new, word1);
b6cf4d02 524 SCM_STRUCT_DATA (new)[scm_vtable_index_self] = SCM_UNPACK (new);
80662eda 525 }
9de87eea 526 SCM_CRITICAL_SECTION_END;
80662eda
MD
527 return SCM_UNSPECIFIED;
528}
398d8ee1 529#undef FUNC_NAME
80662eda 530
80662eda
MD
531/* When instances change class, they finally get a new body, but
532 * before that, they go through purgatory in hell. Odd as it may
533 * seem, this data structure saves us from eternal suffering in
534 * infinite recursions.
535 */
536
92c2555f 537static scm_t_bits **hell;
c014a02e
ML
538static long n_hell = 1; /* one place for the evil one himself */
539static long hell_size = 4;
2132f0d2 540static SCM hell_mutex;
80662eda 541
c014a02e 542static long
80662eda
MD
543burnin (SCM o)
544{
c014a02e 545 long i;
80662eda 546 for (i = 1; i < n_hell; ++i)
6b80d352 547 if (SCM_STRUCT_DATA (o) == hell[i])
80662eda
MD
548 return i;
549 return 0;
550}
551
552static void
553go_to_hell (void *o)
554{
b5df9cda 555 SCM obj = *(SCM*)o;
2132f0d2 556 scm_lock_mutex (hell_mutex);
51ef99f7 557 if (n_hell >= hell_size)
80662eda 558 {
51ef99f7 559 hell_size *= 2;
408bcd99 560 hell = scm_realloc (hell, hell_size * sizeof(*hell));
80662eda 561 }
6b80d352 562 hell[n_hell++] = SCM_STRUCT_DATA (obj);
2132f0d2 563 scm_unlock_mutex (hell_mutex);
80662eda
MD
564}
565
566static void
567go_to_heaven (void *o)
568{
b5df9cda 569 SCM obj = *(SCM*)o;
2132f0d2 570 scm_lock_mutex (hell_mutex);
b5df9cda 571 hell[burnin (obj)] = hell[--n_hell];
2132f0d2 572 scm_unlock_mutex (hell_mutex);
80662eda
MD
573}
574
6b80d352 575
80662eda 576static SCM
b5df9cda 577purgatory (SCM obj, SCM new_class)
80662eda 578{
b5df9cda 579 return scm_call_2 (SCM_VARIABLE_REF (var_change_class), obj, new_class);
80662eda
MD
580}
581
38d8927c
MD
582/* This function calls the generic function change-class for all
583 * instances which aren't currently undergoing class change.
584 */
585
80662eda 586void
e81d98ec 587scm_change_object_class (SCM obj, SCM old_class SCM_UNUSED, SCM new_class)
80662eda
MD
588{
589 if (!burnin (obj))
b5df9cda
AW
590 {
591 scm_dynwind_begin (SCM_F_DYNWIND_REWINDABLE);
592 scm_dynwind_rewind_handler (go_to_hell, &obj, SCM_F_WIND_EXPLICITLY);
593 scm_dynwind_unwind_handler (go_to_heaven, &obj, SCM_F_WIND_EXPLICITLY);
594 purgatory (obj, new_class);
595 scm_dynwind_end ();
596 }
80662eda
MD
597}
598
c2aa5d9b
AW
599
600\f
601
602/* Primitive generics: primitives that can dispatch to generics if their
603 arguments fail to apply. */
80662eda 604
398d8ee1
KN
605SCM_DEFINE (scm_generic_capability_p, "generic-capability?", 1, 0, 0,
606 (SCM proc),
607 "")
608#define FUNC_NAME s_scm_generic_capability_p
80662eda 609{
7888309b 610 SCM_ASSERT (scm_is_true (scm_procedure_p (proc)),
398d8ee1 611 proc, SCM_ARG1, FUNC_NAME);
9fdf9fd3 612 return (SCM_PRIMITIVE_GENERIC_P (proc) ? SCM_BOOL_T : SCM_BOOL_F);
80662eda 613}
398d8ee1 614#undef FUNC_NAME
80662eda 615
398d8ee1
KN
616SCM_DEFINE (scm_enable_primitive_generic_x, "enable-primitive-generic!", 0, 0, 1,
617 (SCM subrs),
618 "")
619#define FUNC_NAME s_scm_enable_primitive_generic_x
80662eda 620{
6b80d352 621 SCM_VALIDATE_REST_ARGUMENT (subrs);
d2e53ed6 622 while (!scm_is_null (subrs))
80662eda
MD
623 {
624 SCM subr = SCM_CAR (subrs);
9fdf9fd3 625 SCM_ASSERT (SCM_PRIMITIVE_GENERIC_P (subr), subr, SCM_ARGn, FUNC_NAME);
52fd9639 626 SCM_SET_SUBR_GENERIC (subr,
57898597 627 scm_make (scm_list_3 (class_generic,
52fd9639
AW
628 k_name,
629 SCM_SUBR_NAME (subr))));
80662eda
MD
630 subrs = SCM_CDR (subrs);
631 }
632 return SCM_UNSPECIFIED;
633}
398d8ee1 634#undef FUNC_NAME
80662eda 635
9f63ce02
AW
636SCM_DEFINE (scm_set_primitive_generic_x, "set-primitive-generic!", 2, 0, 0,
637 (SCM subr, SCM generic),
638 "")
639#define FUNC_NAME s_scm_set_primitive_generic_x
640{
9fdf9fd3 641 SCM_ASSERT (SCM_PRIMITIVE_GENERIC_P (subr), subr, SCM_ARG1, FUNC_NAME);
2b7692bc 642 SCM_ASSERT (SCM_GENERICP (generic), generic, SCM_ARG2, FUNC_NAME);
52fd9639 643 SCM_SET_SUBR_GENERIC (subr, generic);
9f63ce02
AW
644 return SCM_UNSPECIFIED;
645}
646#undef FUNC_NAME
647
398d8ee1
KN
648SCM_DEFINE (scm_primitive_generic_generic, "primitive-generic-generic", 1, 0, 0,
649 (SCM subr),
650 "")
651#define FUNC_NAME s_scm_primitive_generic_generic
80662eda 652{
9fdf9fd3 653 if (SCM_PRIMITIVE_GENERIC_P (subr))
80662eda 654 {
b2b33168 655 if (!SCM_UNPACK (*SCM_SUBR_GENERIC (subr)))
a48d60b1
MD
656 scm_enable_primitive_generic_x (scm_list_1 (subr));
657 return *SCM_SUBR_GENERIC (subr);
80662eda 658 }
db4b4ca6 659 SCM_WRONG_TYPE_ARG (SCM_ARG1, subr);
80662eda 660}
398d8ee1 661#undef FUNC_NAME
80662eda 662
fa075d40
AW
663SCM
664scm_wta_dispatch_0 (SCM gf, const char *subr)
665{
666 if (!SCM_UNPACK (gf))
667 scm_error_num_args_subr (subr);
668
669 return scm_call_0 (gf);
670}
671
672SCM
673scm_wta_dispatch_1 (SCM gf, SCM a1, int pos, const char *subr)
674{
675 if (!SCM_UNPACK (gf))
676 scm_wrong_type_arg (subr, pos, a1);
677
678 return scm_call_1 (gf, a1);
679}
680
681SCM
682scm_wta_dispatch_2 (SCM gf, SCM a1, SCM a2, int pos, const char *subr)
683{
684 if (!SCM_UNPACK (gf))
685 scm_wrong_type_arg (subr, pos, (pos == SCM_ARG1) ? a1 : a2);
686
687 return scm_call_2 (gf, a1, a2);
688}
689
690SCM
691scm_wta_dispatch_n (SCM gf, SCM args, int pos, const char *subr)
692{
693 if (!SCM_UNPACK (gf))
694 scm_wrong_type_arg (subr, pos, scm_list_ref (args, scm_from_int (pos)));
695
696 return scm_apply_0 (gf, args);
697}
698
c2aa5d9b
AW
699
700\f
80662eda 701
cb3ea03d
AW
702SCM
703scm_make (SCM args)
80662eda 704{
e0590e7c 705 return scm_apply_0 (scm_variable_ref (var_make), args);
80662eda
MD
706}
707
80662eda 708
c2aa5d9b
AW
709\f
710
711/* SMOB, struct, and port classes. */
80662eda
MD
712
713static SCM
2e0b6934 714make_class_name (const char *prefix, const char *type_name, const char *suffix)
80662eda 715{
2e0b6934
AW
716 if (!type_name)
717 type_name = "";
718 return scm_string_to_symbol (scm_string_append
719 (scm_list_3 (scm_from_utf8_string (prefix),
720 scm_from_utf8_string (type_name),
721 scm_from_utf8_string (suffix))));
80662eda
MD
722}
723
724SCM
da0e6c2b 725scm_make_extended_class (char const *type_name, int applicablep)
80662eda 726{
2e0b6934
AW
727 SCM name, meta, supers;
728
729 name = make_class_name ("<", type_name, ">");
730 meta = class_class;
731
732 if (applicablep)
733 supers = scm_list_1 (class_applicable);
734 else
735 supers = scm_list_1 (class_top);
736
737 return scm_make_standard_class (meta, name, supers, SCM_EOL);
74b6d6e4
MD
738}
739
740void
741scm_i_inherit_applicable (SCM c)
742{
f37bece4 743 scm_call_1 (scm_variable_ref (var_inherit_applicable), c);
80662eda
MD
744}
745
746static void
747create_smob_classes (void)
748{
c014a02e 749 long i;
80662eda 750
c891a40e 751 for (i = 0; i < SCM_I_MAX_SMOB_TYPE_COUNT; ++i)
57898597 752 scm_i_smob_class[i] = SCM_BOOL_F;
80662eda 753
80662eda 754 for (i = 0; i < scm_numsmob; ++i)
57898597
AW
755 if (scm_is_false (scm_i_smob_class[i]))
756 scm_i_smob_class[i] = scm_make_extended_class (SCM_SMOBNAME (i),
757 scm_smobs[i].apply != 0);
80662eda
MD
758}
759
760void
c014a02e 761scm_make_port_classes (long ptobnum, char *type_name)
80662eda 762{
2e0b6934
AW
763 SCM name, meta, super, supers;
764
765 meta = class_class;
766
767 name = make_class_name ("<", type_name, "-port>");
768 supers = scm_list_1 (class_port);
769 super = scm_make_standard_class (meta, name, supers, SCM_EOL);
770
771 name = make_class_name ("<", type_name, "-input-port>");
772 supers = scm_list_2 (super, class_input_port);
57898597 773 scm_i_port_class[SCM_IN_PCLASS_INDEX + ptobnum]
2e0b6934
AW
774 = scm_make_standard_class (meta, name, supers, SCM_EOL);
775
776 name = make_class_name ("<", type_name, "-output-port>");
777 supers = scm_list_2 (super, class_output_port);
57898597 778 scm_i_port_class[SCM_OUT_PCLASS_INDEX + ptobnum]
2e0b6934
AW
779 = scm_make_standard_class (meta, name, supers, SCM_EOL);
780
781 name = make_class_name ("<", type_name, "-input-output-port>");
782 supers = scm_list_2 (super, class_input_output_port);
57898597 783 scm_i_port_class[SCM_INOUT_PCLASS_INDEX + ptobnum]
2e0b6934 784 = scm_make_standard_class (meta, name, supers, SCM_EOL);
80662eda
MD
785}
786
787static void
788create_port_classes (void)
789{
c014a02e 790 long i;
80662eda 791
62bd5d66 792 for (i = scm_c_num_port_types () - 1; i >= 0; i--)
80662eda
MD
793 scm_make_port_classes (i, SCM_PTOBNAME (i));
794}
795
6c7dd9eb
AW
796SCM
797scm_i_define_class_for_vtable (SCM vtable)
798{
799 SCM class;
800
801 scm_i_pthread_mutex_lock (&scm_i_misc_mutex);
802 if (scm_is_false (vtable_class_map))
803 vtable_class_map = scm_c_make_weak_table (0, SCM_WEAK_TABLE_KIND_KEY);
804 scm_i_pthread_mutex_unlock (&scm_i_misc_mutex);
805
806 if (scm_is_false (scm_struct_vtable_p (vtable)))
807 abort ();
808
809 class = scm_weak_table_refq (vtable_class_map, vtable, SCM_BOOL_F);
810
811 if (scm_is_false (class))
812 {
57898597 813 if (SCM_UNPACK (class_class))
6c7dd9eb
AW
814 {
815 SCM name, meta, supers;
816
817 name = SCM_VTABLE_NAME (vtable);
818 if (scm_is_symbol (name))
819 name = scm_string_to_symbol
820 (scm_string_append
821 (scm_list_3 (scm_from_latin1_string ("<"),
822 scm_symbol_to_string (name),
823 scm_from_latin1_string (">"))));
824 else
825 name = scm_from_latin1_symbol ("<>");
826
827 if (SCM_STRUCT_VTABLE_FLAG_IS_SET (vtable, SCM_VTABLE_FLAG_SETTER))
828 {
57898597
AW
829 meta = class_applicable_struct_with_setter_class;
830 supers = scm_list_1 (class_applicable_struct_with_setter);
6c7dd9eb
AW
831 }
832 else if (SCM_STRUCT_VTABLE_FLAG_IS_SET (vtable,
833 SCM_VTABLE_FLAG_APPLICABLE))
834 {
57898597
AW
835 meta = class_applicable_struct_class;
836 supers = scm_list_1 (class_applicable_struct);
6c7dd9eb
AW
837 }
838 else
839 {
57898597
AW
840 meta = class_class;
841 supers = scm_list_1 (class_top);
6c7dd9eb
AW
842 }
843
844 return scm_make_standard_class (meta, name, supers, SCM_EOL);
845 }
846 else
847 /* `create_struct_classes' will fill this in later. */
848 class = SCM_BOOL_F;
849
850 /* Don't worry about races. This only happens when creating a
851 vtable, which happens by definition in one thread. */
852 scm_weak_table_putq_x (vtable_class_map, vtable, class);
853 }
854
855 return class;
856}
857
80662eda 858static SCM
74b6d6e4
MD
859make_struct_class (void *closure SCM_UNUSED,
860 SCM vtable, SCM data, SCM prev SCM_UNUSED)
80662eda 861{
f3c6a02c
AW
862 if (scm_is_false (data))
863 scm_i_define_class_for_vtable (vtable);
80662eda
MD
864 return SCM_UNSPECIFIED;
865}
866
867static void
868create_struct_classes (void)
869{
ea742d29 870 /* FIXME: take the vtable_class_map while initializing goops? */
f3c6a02c
AW
871 scm_internal_hash_fold (make_struct_class, 0, SCM_BOOL_F,
872 vtable_class_map);
80662eda
MD
873}
874
c2aa5d9b
AW
875
876\f
80662eda
MD
877
878void
879scm_load_goops ()
880{
881 if (!goops_loaded_p)
abd28220 882 scm_c_resolve_module ("oop goops");
80662eda
MD
883}
884
80662eda
MD
885SCM
886scm_ensure_accessor (SCM name)
887{
3f48638c
AW
888 SCM var, gf;
889
890 var = scm_module_variable (scm_current_module (), name);
891 if (SCM_VARIABLEP (var) && !SCM_UNBNDP (SCM_VARIABLE_REF (var)))
892 gf = SCM_VARIABLE_REF (var);
893 else
894 gf = SCM_BOOL_F;
895
57898597 896 if (!SCM_IS_A_P (gf, class_accessor))
80662eda 897 {
57898597
AW
898 gf = scm_make (scm_list_3 (class_generic, k_name, name));
899 gf = scm_make (scm_list_5 (class_accessor,
1afff620 900 k_name, name, k_setter, gf));
80662eda 901 }
3f48638c 902
80662eda
MD
903 return gf;
904}
905
80662eda 906
c2aa5d9b 907\f
51fd1cd6 908
82ab5090
AW
909SCM_DEFINE (scm_sys_goops_early_init, "%goops-early-init", 0, 0, 0,
910 (),
911 "")
912#define FUNC_NAME s_scm_sys_goops_early_init
913{
51fd1cd6 914 var_make_standard_class = scm_c_lookup ("make-standard-class");
e0590e7c 915 var_make = scm_c_lookup ("make");
f37bece4 916 var_inherit_applicable = scm_c_lookup ("inherit-applicable!");
51fd1cd6 917
2025a027
AW
918 /* For SCM_SUBCLASSP. */
919 var_class_precedence_list = scm_c_lookup ("class-precedence-list");
920
ade4cf4c
AW
921 var_slot_ref = scm_c_lookup ("slot-ref");
922 var_slot_set_x = scm_c_lookup ("slot-set!");
923 var_slot_bound_p = scm_c_lookup ("slot-bound?");
924 var_slot_exists_p = scm_c_lookup ("slot-exists?");
925
57898597
AW
926 class_class = scm_variable_ref (scm_c_lookup ("<class>"));
927 class_top = scm_variable_ref (scm_c_lookup ("<top>"));
928 class_object = scm_variable_ref (scm_c_lookup ("<object>"));
929
930 class_foreign_slot = scm_variable_ref (scm_c_lookup ("<foreign-slot>"));
931 class_protected = scm_variable_ref (scm_c_lookup ("<protected-slot>"));
932 class_hidden = scm_variable_ref (scm_c_lookup ("<hidden-slot>"));
933 class_opaque = scm_variable_ref (scm_c_lookup ("<opaque-slot>"));
934 class_read_only = scm_variable_ref (scm_c_lookup ("<read-only-slot>"));
935 class_self = scm_variable_ref (scm_c_lookup ("<self-slot>"));
936 class_protected_opaque = scm_variable_ref (scm_c_lookup ("<protected-opaque-slot>"));
937 class_protected_hidden = scm_variable_ref (scm_c_lookup ("<protected-hidden-slot>"));
938 class_protected_read_only = scm_variable_ref (scm_c_lookup ("<protected-read-only-slot>"));
939 class_scm = scm_variable_ref (scm_c_lookup ("<scm-slot>"));
940 class_int = scm_variable_ref (scm_c_lookup ("<int-slot>"));
941 class_float = scm_variable_ref (scm_c_lookup ("<float-slot>"));
942 class_double = scm_variable_ref (scm_c_lookup ("<double-slot>"));
943
944 /* Applicables */
945 class_procedure_class = scm_variable_ref (scm_c_lookup ("<procedure-class>"));
946 class_applicable_struct_class = scm_variable_ref (scm_c_lookup ("<applicable-struct-class>"));
947 class_applicable_struct_with_setter_class =
6c7dd9eb 948 scm_variable_ref (scm_c_lookup ("<applicable-struct-with-setter-class>"));
51fd1cd6 949
57898597
AW
950 class_method = scm_variable_ref (scm_c_lookup ("<method>"));
951 class_accessor_method = scm_variable_ref (scm_c_lookup ("<accessor-method>"));
952 class_applicable = scm_variable_ref (scm_c_lookup ("<applicable>"));
953 class_applicable_struct = scm_variable_ref (scm_c_lookup ("<applicable-struct>"));
954 class_applicable_struct_with_setter = scm_variable_ref (scm_c_lookup ("<applicable-struct-with-setter>"));
955 class_generic = scm_variable_ref (scm_c_lookup ("<generic>"));
956 class_extended_generic = scm_variable_ref (scm_c_lookup ("<extended-generic>"));
957 class_generic_with_setter = scm_variable_ref (scm_c_lookup ("<generic-with-setter>"));
958 class_accessor = scm_variable_ref (scm_c_lookup ("<accessor>"));
959 class_extended_generic_with_setter = scm_variable_ref (scm_c_lookup ("<extended-generic-with-setter>"));
960 class_extended_accessor = scm_variable_ref (scm_c_lookup ("<extended-accessor>"));
51fd1cd6
AW
961
962 /* Primitive types classes */
57898597
AW
963 class_boolean = scm_variable_ref (scm_c_lookup ("<boolean>"));
964 class_char = scm_variable_ref (scm_c_lookup ("<char>"));
965 class_list = scm_variable_ref (scm_c_lookup ("<list>"));
966 class_pair = scm_variable_ref (scm_c_lookup ("<pair>"));
967 class_null = scm_variable_ref (scm_c_lookup ("<null>"));
968 class_string = scm_variable_ref (scm_c_lookup ("<string>"));
969 class_symbol = scm_variable_ref (scm_c_lookup ("<symbol>"));
970 class_vector = scm_variable_ref (scm_c_lookup ("<vector>"));
51fd1cd6
AW
971 class_foreign = scm_variable_ref (scm_c_lookup ("<foreign>"));
972 class_hashtable = scm_variable_ref (scm_c_lookup ("<hashtable>"));
973 class_fluid = scm_variable_ref (scm_c_lookup ("<fluid>"));
974 class_dynamic_state = scm_variable_ref (scm_c_lookup ("<dynamic-state>"));
975 class_frame = scm_variable_ref (scm_c_lookup ("<frame>"));
976 class_vm_cont = scm_variable_ref (scm_c_lookup ("<vm-continuation>"));
977 class_bytevector = scm_variable_ref (scm_c_lookup ("<bytevector>"));
978 class_uvec = scm_variable_ref (scm_c_lookup ("<uvec>"));
979 class_array = scm_variable_ref (scm_c_lookup ("<array>"));
980 class_bitvector = scm_variable_ref (scm_c_lookup ("<bitvector>"));
57898597
AW
981 class_number = scm_variable_ref (scm_c_lookup ("<number>"));
982 class_complex = scm_variable_ref (scm_c_lookup ("<complex>"));
983 class_real = scm_variable_ref (scm_c_lookup ("<real>"));
984 class_integer = scm_variable_ref (scm_c_lookup ("<integer>"));
985 class_fraction = scm_variable_ref (scm_c_lookup ("<fraction>"));
986 class_keyword = scm_variable_ref (scm_c_lookup ("<keyword>"));
987 class_unknown = scm_variable_ref (scm_c_lookup ("<unknown>"));
988 class_procedure = scm_variable_ref (scm_c_lookup ("<procedure>"));
989 class_primitive_generic = scm_variable_ref (scm_c_lookup ("<primitive-generic>"));
990 class_port = scm_variable_ref (scm_c_lookup ("<port>"));
991 class_input_port = scm_variable_ref (scm_c_lookup ("<input-port>"));
992 class_output_port = scm_variable_ref (scm_c_lookup ("<output-port>"));
993 class_input_output_port = scm_variable_ref (scm_c_lookup ("<input-output-port>"));
51fd1cd6 994
82ab5090
AW
995 create_smob_classes ();
996 create_struct_classes ();
997 create_port_classes ();
998
82ab5090
AW
999 return SCM_UNSPECIFIED;
1000}
1001#undef FUNC_NAME
1002
398d8ee1
KN
1003SCM_DEFINE (scm_sys_goops_loaded, "%goops-loaded", 0, 0, 0,
1004 (),
6bcefd15
MG
1005 "Announce that GOOPS is loaded and perform initialization\n"
1006 "on the C level which depends on the loaded GOOPS modules.")
398d8ee1 1007#define FUNC_NAME s_scm_sys_goops_loaded
80662eda
MD
1008{
1009 goops_loaded_p = 1;
48c981c9
AW
1010 var_class_name = scm_c_lookup ("class-name");
1011 var_class_direct_supers = scm_c_lookup ("class-direct-supers");
1012 var_class_direct_slots = scm_c_lookup ("class-direct-slots");
1013 var_class_direct_subclasses = scm_c_lookup ("class-direct-subclasses");
1014 var_class_direct_methods = scm_c_lookup ("class-direct-methods");
48c981c9
AW
1015 var_class_slots = scm_c_lookup ("class-slots");
1016
1017 var_generic_function_methods = scm_c_lookup ("generic-function-methods");
1018 var_method_generic_function = scm_c_lookup ("method-generic-function");
1019 var_method_specializers = scm_c_lookup ("method-specializers");
1020 var_method_procedure = scm_c_lookup ("method-procedure");
1021
5a6165db 1022 var_change_class = scm_c_lookup ("change-class");
623559f3
AW
1023
1024#if (SCM_ENABLE_DEPRECATED == 1)
1025 scm_init_deprecated_goops ();
1026#endif
1027
80662eda
MD
1028 return SCM_UNSPECIFIED;
1029}
398d8ee1 1030#undef FUNC_NAME
80662eda 1031
6ab19396
AW
1032static void
1033scm_init_goops_builtins (void *unused)
80662eda 1034{
abd28220 1035 scm_module_goops = scm_current_module ();
80662eda 1036
bb764c0e 1037 hell = scm_calloc (hell_size * sizeof (*hell));
f39448c5 1038 hell_mutex = scm_make_mutex ();
80662eda 1039
82ab5090 1040#include "libguile/goops.x"
761338f6
AW
1041
1042 scm_c_define ("vtable-flag-vtable",
1043 scm_from_int (SCM_VTABLE_FLAG_VTABLE));
1044 scm_c_define ("vtable-flag-applicable-vtable",
1045 scm_from_int (SCM_VTABLE_FLAG_APPLICABLE_VTABLE));
1046 scm_c_define ("vtable-flag-setter-vtable",
1047 scm_from_int (SCM_VTABLE_FLAG_SETTER_VTABLE));
1048 scm_c_define ("vtable-flag-validated",
1049 scm_from_int (SCM_VTABLE_FLAG_VALIDATED));
1050 scm_c_define ("vtable-flag-goops-class",
1051 scm_from_int (SCM_VTABLE_FLAG_GOOPS_CLASS));
1052 scm_c_define ("vtable-flag-goops-valid",
1053 scm_from_int (SCM_VTABLE_FLAG_GOOPS_VALID));
80662eda
MD
1054}
1055
1056void
abd28220 1057scm_init_goops ()
80662eda 1058{
6ab19396
AW
1059 scm_c_register_extension ("libguile-" SCM_EFFECTIVE_VERSION,
1060 "scm_init_goops_builtins", scm_init_goops_builtins,
1061 NULL);
80662eda 1062}
23437298
DH
1063
1064/*
1065 Local Variables:
1066 c-file-style: "gnu"
1067 End:
1068*/