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