Reimplement %allocate-instance in Scheme
[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
f6088819
AW
58#define SCM_GOOPS_UNBOUND SCM_UNBOUND
59#define SCM_GOOPS_UNBOUNDP(x) (scm_is_eq (x, SCM_GOOPS_UNBOUND))
60
51fd1cd6
AW
61/* Objects have identity, so references to classes and instances are by
62 value, not by reference. Redefinition of a class or modification of
63 an instance causes in-place update; you can think of GOOPS as
64 building in its own indirection, and for that reason referring to
65 GOOPS values by variable reference is unnecessary.
bef95911 66
51fd1cd6
AW
67 References to ordinary procedures is by reference (by variable),
68 though, as in the rest of Guile. */
69
f6088819
AW
70static int goops_loaded_p = 0;
71
51fd1cd6 72static SCM var_make_standard_class = SCM_BOOL_F;
bef95911 73static SCM var_change_class = SCM_BOOL_F;
e0590e7c 74static SCM var_make = SCM_BOOL_F;
70dd6000
AW
75static SCM var_class_name = SCM_BOOL_F;
76static SCM var_class_direct_supers = SCM_BOOL_F;
77static SCM var_class_direct_slots = SCM_BOOL_F;
78static SCM var_class_direct_subclasses = SCM_BOOL_F;
79static SCM var_class_direct_methods = SCM_BOOL_F;
80static SCM var_class_precedence_list = SCM_BOOL_F;
81static SCM var_class_slots = SCM_BOOL_F;
bef95911 82
48c981c9
AW
83static SCM var_generic_function_methods = SCM_BOOL_F;
84static SCM var_method_generic_function = SCM_BOOL_F;
85static SCM var_method_specializers = SCM_BOOL_F;
86static SCM var_method_procedure = SCM_BOOL_F;
87
ade4cf4c
AW
88static SCM var_slot_ref_using_class = SCM_BOOL_F;
89static SCM var_slot_set_using_class_x = SCM_BOOL_F;
90static SCM var_slot_bound_using_class_p = SCM_BOOL_F;
91static SCM var_slot_exists_using_class_p = SCM_BOOL_F;
92
93static SCM var_slot_ref = SCM_BOOL_F;
94static SCM var_slot_set_x = SCM_BOOL_F;
95static SCM var_slot_bound_p = SCM_BOOL_F;
96static SCM var_slot_exists_p = SCM_BOOL_F;
97
539d5410 98/* These variables are filled in by the object system when loaded. */
57898597
AW
99static SCM class_boolean, class_char, class_pair;
100static SCM class_procedure, class_string, class_symbol;
101static SCM class_primitive_generic;
102static SCM class_vector, class_null;
103static SCM class_integer, class_real, class_complex, class_fraction;
104static SCM class_unknown;
105static SCM class_top, class_object, class_class;
106static SCM class_applicable;
107static SCM class_applicable_struct, class_applicable_struct_with_setter;
108static SCM class_generic, class_generic_with_setter;
109static SCM class_accessor;
110static SCM class_extended_generic, class_extended_generic_with_setter;
111static SCM class_extended_accessor;
112static SCM class_method;
113static SCM class_accessor_method;
114static SCM class_procedure_class;
115static SCM class_applicable_struct_class;
116static SCM class_applicable_struct_with_setter_class;
117static SCM class_number, class_list;
118static SCM class_keyword;
119static SCM class_port, class_input_output_port;
120static SCM class_input_port, class_output_port;
121static SCM class_foreign_slot;
122static SCM class_self, class_protected;
123static SCM class_hidden, class_opaque, class_read_only;
124static SCM class_protected_hidden, class_protected_opaque, class_protected_read_only;
125static SCM class_scm;
126static SCM class_int, class_float, class_double;
80662eda 127
e2c2a699 128static SCM class_foreign;
9ea31741
AW
129static SCM class_hashtable;
130static SCM class_fluid;
131static SCM class_dynamic_state;
6f3b0cc2 132static SCM class_frame;
6f3b0cc2 133static SCM class_vm_cont;
f826a886
AW
134static SCM class_bytevector;
135static SCM class_uvec;
b2637c98 136static SCM class_array;
ff1feca9 137static SCM class_bitvector;
9ea31741 138
f3c6a02c
AW
139static SCM vtable_class_map = SCM_BOOL_F;
140
63385df2
LC
141/* Port classes. Allocate 3 times the maximum number of port types so that
142 input ports, output ports, and in/out ports can be stored at different
143 offsets. See `SCM_IN_PCLASS_INDEX' et al. */
57898597 144SCM scm_i_port_class[3 * SCM_I_MAX_PORT_TYPE_COUNT];
63385df2
LC
145
146/* SMOB classes. */
57898597 147SCM scm_i_smob_class[SCM_I_MAX_SMOB_TYPE_COUNT];
539d5410 148
80662eda
MD
149static SCM scm_make_unbound (void);
150static SCM scm_unbound_p (SCM obj);
70dd6000 151static SCM scm_class_p (SCM obj);
6c7dd9eb
AW
152static SCM scm_sys_bless_applicable_struct_vtables_x (SCM applicable,
153 SCM setter);
4702cbeb 154static SCM scm_sys_make_root_class (SCM layout);
51fd1cd6 155static SCM scm_sys_init_layout_x (SCM class, SCM layout);
07452c83 156static SCM scm_sys_clear_fields_x (SCM obj);
82ab5090 157static SCM scm_sys_goops_early_init (void);
398d8ee1 158static SCM scm_sys_goops_loaded (void);
80662eda 159
f3c6a02c 160
539d5410
MV
161/* This function is used for efficient type dispatch. */
162SCM_DEFINE (scm_class_of, "class-of", 1, 0, 0,
163 (SCM x),
164 "Return the class of @var{x}.")
165#define FUNC_NAME s_scm_class_of
166{
167 switch (SCM_ITAG3 (x))
168 {
169 case scm_tc3_int_1:
170 case scm_tc3_int_2:
57898597 171 return class_integer;
539d5410
MV
172
173 case scm_tc3_imm24:
174 if (SCM_CHARP (x))
57898597 175 return class_char;
539d5410 176 else if (scm_is_bool (x))
57898597 177 return class_boolean;
539d5410 178 else if (scm_is_null (x))
57898597 179 return class_null;
539d5410 180 else
57898597 181 return class_unknown;
539d5410
MV
182
183 case scm_tc3_cons:
184 switch (SCM_TYP7 (x))
185 {
186 case scm_tcs_cons_nimcar:
57898597 187 return class_pair;
539d5410 188 case scm_tc7_symbol:
57898597 189 return class_symbol;
539d5410
MV
190 case scm_tc7_vector:
191 case scm_tc7_wvect:
57898597 192 return class_vector;
5b46a8c2 193 case scm_tc7_pointer:
e2c2a699 194 return class_foreign;
c99de5aa 195 case scm_tc7_hashtable:
9ea31741
AW
196 return class_hashtable;
197 case scm_tc7_fluid:
198 return class_fluid;
199 case scm_tc7_dynamic_state:
200 return class_dynamic_state;
6f3b0cc2
AW
201 case scm_tc7_frame:
202 return class_frame;
e2fafeb9 203 case scm_tc7_keyword:
57898597 204 return class_keyword;
6f3b0cc2
AW
205 case scm_tc7_vm_cont:
206 return class_vm_cont;
f826a886
AW
207 case scm_tc7_bytevector:
208 if (SCM_BYTEVECTOR_ELEMENT_TYPE (x) == SCM_ARRAY_ELEMENT_TYPE_VU8)
209 return class_bytevector;
210 else
211 return class_uvec;
b2637c98
AW
212 case scm_tc7_array:
213 return class_array;
ff1feca9
AW
214 case scm_tc7_bitvector:
215 return class_bitvector;
539d5410 216 case scm_tc7_string:
57898597 217 return class_string;
539d5410
MV
218 case scm_tc7_number:
219 switch SCM_TYP16 (x) {
220 case scm_tc16_big:
57898597 221 return class_integer;
539d5410 222 case scm_tc16_real:
57898597 223 return class_real;
539d5410 224 case scm_tc16_complex:
57898597 225 return class_complex;
539d5410 226 case scm_tc16_fraction:
57898597 227 return class_fraction;
539d5410 228 }
e0755cd1 229 case scm_tc7_program:
b2b33168
AW
230 if (SCM_PROGRAM_IS_PRIMITIVE_GENERIC (x)
231 && SCM_UNPACK (*SCM_SUBR_GENERIC (x)))
57898597 232 return class_primitive_generic;
fd12a19a 233 else
57898597 234 return class_procedure;
539d5410
MV
235
236 case scm_tc7_smob:
237 {
238 scm_t_bits type = SCM_TYP16 (x);
239 if (type != scm_tc16_port_with_ps)
57898597 240 return scm_i_smob_class[SCM_TC2SMOBNUM (type)];
539d5410
MV
241 x = SCM_PORT_WITH_PS_PORT (x);
242 /* fall through to ports */
243 }
244 case scm_tc7_port:
57898597
AW
245 return scm_i_port_class[(SCM_WRTNG & SCM_CELL_WORD_0 (x)
246 ? (SCM_RDNG & SCM_CELL_WORD_0 (x)
247 ? SCM_INOUT_PCLASS_INDEX | SCM_PTOBNUM (x)
248 : SCM_OUT_PCLASS_INDEX | SCM_PTOBNUM (x))
249 : SCM_IN_PCLASS_INDEX | SCM_PTOBNUM (x))];
539d5410
MV
250 case scm_tcs_struct:
251 if (SCM_OBJ_CLASS_FLAGS (x) & SCM_CLASSF_GOOPS_VALID)
252 return SCM_CLASS_OF (x);
253 else if (SCM_OBJ_CLASS_FLAGS (x) & SCM_CLASSF_GOOPS)
254 {
255 /* Goops object */
256 if (! scm_is_false (SCM_OBJ_CLASS_REDEF (x)))
257 scm_change_object_class (x,
258 SCM_CLASS_OF (x), /* old */
259 SCM_OBJ_CLASS_REDEF (x)); /* new */
260 return SCM_CLASS_OF (x);
261 }
262 else
f3c6a02c 263 return scm_i_define_class_for_vtable (SCM_CLASS_OF (x));
539d5410
MV
264 default:
265 if (scm_is_pair (x))
57898597 266 return class_pair;
539d5410 267 else
57898597 268 return class_unknown;
539d5410
MV
269 }
270
271 case scm_tc3_struct:
272 case scm_tc3_tc7_1:
273 case scm_tc3_tc7_2:
314b8716 274 /* case scm_tc3_unused: */
539d5410
MV
275 /* Never reached */
276 break;
277 }
57898597 278 return class_unknown;
539d5410
MV
279}
280#undef FUNC_NAME
281
51fd1cd6
AW
282SCM_DEFINE (scm_sys_init_layout_x, "%init-layout!", 2, 0, 0,
283 (SCM class, SCM layout),
398d8ee1 284 "")
51fd1cd6 285#define FUNC_NAME s_scm_sys_init_layout_x
80662eda 286{
398d8ee1 287 SCM_VALIDATE_INSTANCE (1, class);
51fd1cd6
AW
288 SCM_ASSERT (!scm_is_symbol (SCM_VTABLE_LAYOUT (class)), class, 1, FUNC_NAME);
289 SCM_VALIDATE_STRING (2, layout);
290
291 SCM_SET_VTABLE_LAYOUT (class, scm_make_struct_layout (layout));
80662eda
MD
292 return SCM_UNSPECIFIED;
293}
398d8ee1 294#undef FUNC_NAME
80662eda 295
398d8ee1
KN
296SCM_DEFINE (scm_sys_inherit_magic_x, "%inherit-magic!", 2, 0, 0,
297 (SCM class, SCM dsupers),
298 "")
299#define FUNC_NAME s_scm_sys_inherit_magic_x
80662eda 300{
398d8ee1 301 SCM_VALIDATE_INSTANCE (1, class);
51f66c91
AW
302 scm_i_struct_inherit_vtable_magic (SCM_CLASS_OF (class), class);
303 SCM_SET_CLASS_FLAGS (class, SCM_CLASSF_GOOPS_OR_VALID);
80662eda 304
80662eda
MD
305 return SCM_UNSPECIFIED;
306}
398d8ee1 307#undef FUNC_NAME
80662eda 308
80662eda
MD
309/******************************************************************************/
310
80662eda 311SCM
28b818d3 312scm_make_standard_class (SCM meta, SCM name, SCM dsupers, SCM dslots)
80662eda 313{
51fd1cd6 314 return scm_call_4 (scm_variable_ref (var_make_standard_class),
28b818d3 315 meta, name, dsupers, dslots);
80662eda
MD
316}
317
318/******************************************************************************/
319
4702cbeb
AW
320SCM_DEFINE (scm_sys_make_root_class, "%make-root-class", 1, 0, 0,
321 (SCM layout),
51fd1cd6
AW
322 "")
323#define FUNC_NAME s_scm_sys_make_root_class
80662eda 324{
4702cbeb
AW
325 SCM z;
326
327 z = scm_i_make_vtable_vtable (layout);
328 SCM_SET_CLASS_FLAGS (z, (SCM_CLASSF_GOOPS_OR_VALID | SCM_CLASSF_METACLASS));
80662eda 329
51fd1cd6 330 return z;
80662eda 331}
51fd1cd6 332#undef FUNC_NAME
80662eda
MD
333
334/******************************************************************************/
335
398d8ee1
KN
336SCM_DEFINE (scm_instance_p, "instance?", 1, 0, 0,
337 (SCM obj),
6bcefd15 338 "Return @code{#t} if @var{obj} is an instance.")
398d8ee1 339#define FUNC_NAME s_scm_instance_p
80662eda 340{
7888309b 341 return scm_from_bool (SCM_INSTANCEP (obj));
80662eda 342}
398d8ee1 343#undef FUNC_NAME
80662eda 344
70dd6000
AW
345SCM_DEFINE (scm_class_p, "class?", 1, 0, 0,
346 (SCM obj),
347 "Return @code{#t} if @var{obj} is a class.")
348#define FUNC_NAME s_scm_class_p
349{
350 return scm_from_bool (SCM_CLASSP (obj));
351}
352#undef FUNC_NAME
353
57898597
AW
354int
355scm_is_generic (SCM x)
356{
357 return SCM_INSTANCEP (x) && SCM_SUBCLASSP (SCM_CLASS_OF (x), class_generic);
358}
359
360int
361scm_is_method (SCM x)
362{
363 return SCM_INSTANCEP (x) && SCM_SUBCLASSP (SCM_CLASS_OF (x), class_method);
364}
80662eda
MD
365
366/******************************************************************************
6d77c894 367 *
80662eda
MD
368 * Meta object accessors
369 *
370 ******************************************************************************/
51fd1cd6 371
70dd6000
AW
372SCM
373scm_class_name (SCM obj)
80662eda 374{
70dd6000 375 return scm_call_1 (scm_variable_ref (var_class_name), obj);
80662eda
MD
376}
377
70dd6000
AW
378SCM
379scm_class_direct_supers (SCM obj)
80662eda 380{
70dd6000 381 return scm_call_1 (scm_variable_ref (var_class_direct_supers), obj);
80662eda
MD
382}
383
70dd6000
AW
384SCM
385scm_class_direct_slots (SCM obj)
80662eda 386{
70dd6000 387 return scm_call_1 (scm_variable_ref (var_class_direct_slots), obj);
80662eda
MD
388}
389
70dd6000
AW
390SCM
391scm_class_direct_subclasses (SCM obj)
80662eda 392{
70dd6000 393 return scm_call_1 (scm_variable_ref (var_class_direct_subclasses), obj);
80662eda
MD
394}
395
70dd6000
AW
396SCM
397scm_class_direct_methods (SCM obj)
80662eda 398{
70dd6000 399 return scm_call_1 (scm_variable_ref (var_class_direct_methods), obj);
80662eda
MD
400}
401
70dd6000
AW
402SCM
403scm_class_precedence_list (SCM obj)
80662eda 404{
70dd6000 405 return scm_call_1 (scm_variable_ref (var_class_precedence_list), obj);
80662eda
MD
406}
407
70dd6000
AW
408SCM
409scm_class_slots (SCM obj)
80662eda 410{
70dd6000 411 return scm_call_1 (scm_variable_ref (var_class_slots), obj);
80662eda
MD
412}
413
398d8ee1 414SCM_DEFINE (scm_generic_function_name, "generic-function-name", 1, 0, 0,
70dd6000 415 (SCM obj),
6bcefd15 416 "Return the name of the generic function @var{obj}.")
398d8ee1 417#define FUNC_NAME s_scm_generic_function_name
80662eda 418{
398d8ee1 419 SCM_VALIDATE_GENERIC (1, obj);
80662eda
MD
420 return scm_procedure_property (obj, scm_sym_name);
421}
398d8ee1 422#undef FUNC_NAME
80662eda 423
48c981c9
AW
424SCM
425scm_generic_function_methods (SCM obj)
80662eda 426{
48c981c9 427 return scm_call_1 (scm_variable_ref (var_generic_function_methods), obj);
80662eda
MD
428}
429
48c981c9
AW
430SCM
431scm_method_generic_function (SCM obj)
80662eda 432{
48c981c9 433 return scm_call_1 (scm_variable_ref (var_method_generic_function), obj);
80662eda
MD
434}
435
48c981c9
AW
436SCM
437scm_method_specializers (SCM obj)
80662eda 438{
48c981c9 439 return scm_call_1 (scm_variable_ref (var_method_specializers), obj);
80662eda
MD
440}
441
48c981c9
AW
442SCM
443scm_method_procedure (SCM obj)
80662eda 444{
48c981c9 445 return scm_call_1 (scm_variable_ref (var_method_procedure), obj);
80662eda
MD
446}
447
80662eda
MD
448/******************************************************************************
449 *
450 * S l o t a c c e s s
451 *
452 ******************************************************************************/
453
398d8ee1
KN
454SCM_DEFINE (scm_make_unbound, "make-unbound", 0, 0, 0,
455 (),
6bcefd15 456 "Return the unbound value.")
398d8ee1 457#define FUNC_NAME s_scm_make_unbound
80662eda
MD
458{
459 return SCM_GOOPS_UNBOUND;
460}
398d8ee1 461#undef FUNC_NAME
80662eda 462
398d8ee1
KN
463SCM_DEFINE (scm_unbound_p, "unbound?", 1, 0, 0,
464 (SCM obj),
6bcefd15 465 "Return @code{#t} if @var{obj} is unbound.")
398d8ee1 466#define FUNC_NAME s_scm_unbound_p
80662eda
MD
467{
468 return SCM_GOOPS_UNBOUNDP (obj) ? SCM_BOOL_T : SCM_BOOL_F;
469}
398d8ee1 470#undef FUNC_NAME
80662eda 471
80662eda 472
4d0949ea 473\f
80662eda 474
ade4cf4c
AW
475SCM
476scm_slot_ref_using_class (SCM class, SCM obj, SCM slot_name)
80662eda 477{
ade4cf4c
AW
478 return scm_call_3 (scm_variable_ref (var_slot_ref_using_class),
479 class, obj, slot_name);
80662eda 480}
80662eda 481
ade4cf4c
AW
482SCM
483scm_slot_set_using_class_x (SCM class, SCM obj, SCM slot_name, SCM value)
80662eda 484{
ade4cf4c
AW
485 return scm_call_4 (scm_variable_ref (var_slot_set_using_class_x),
486 class, obj, slot_name, value);
80662eda 487}
23437298 488
ade4cf4c
AW
489SCM
490scm_slot_bound_using_class_p (SCM class, SCM obj, SCM slot_name)
80662eda 491{
ade4cf4c
AW
492 return scm_call_3 (scm_variable_ref (var_slot_bound_using_class_p),
493 class, obj, slot_name);
80662eda
MD
494}
495
ade4cf4c
AW
496SCM
497scm_slot_exists_using_class_p (SCM class, SCM obj, SCM slot_name)
398d8ee1 498{
ade4cf4c
AW
499 return scm_call_3 (scm_variable_ref (var_slot_exists_using_class_p),
500 class, obj, slot_name);
80662eda 501}
80662eda 502
ade4cf4c
AW
503SCM
504scm_slot_ref (SCM obj, SCM slot_name)
80662eda 505{
ade4cf4c 506 return scm_call_2 (scm_variable_ref (var_slot_ref), obj, slot_name);
80662eda
MD
507}
508
ade4cf4c
AW
509SCM
510scm_slot_set_x (SCM obj, SCM slot_name, SCM value)
80662eda 511{
ade4cf4c 512 return scm_call_3 (scm_variable_ref (var_slot_set_x), obj, slot_name, value);
80662eda
MD
513}
514
ade4cf4c
AW
515SCM
516scm_slot_bound_p (SCM obj, SCM slot_name)
80662eda 517{
ade4cf4c 518 return scm_call_2 (scm_variable_ref (var_slot_bound_p), obj, slot_name);
80662eda
MD
519}
520
ade4cf4c
AW
521SCM
522scm_slot_exists_p (SCM obj, SCM slot_name)
80662eda 523{
ade4cf4c 524 return scm_call_2 (scm_variable_ref (var_slot_exists_p), obj, slot_name);
80662eda
MD
525}
526
07452c83
AW
527SCM_DEFINE (scm_sys_clear_fields_x, "%clear-fields!", 1, 0, 0,
528 (SCM obj),
529 "")
530#define FUNC_NAME s_scm_sys_clear_fields_x
80662eda 531{
e25f3727 532 scm_t_signed_bits n, i;
07452c83 533 SCM vtable, layout;
80662eda 534
07452c83
AW
535 SCM_VALIDATE_STRUCT (1, obj);
536 vtable = SCM_STRUCT_VTABLE (obj);
80662eda 537
07452c83
AW
538 n = SCM_STRUCT_DATA_REF (vtable, scm_vtable_index_size);
539 layout = SCM_VTABLE_LAYOUT (vtable);
80662eda 540
07452c83 541 /* Set all SCM-holding slots to the GOOPS unbound value. */
b6cf4d02 542 for (i = 0; i < n; i++)
07452c83
AW
543 if (scm_i_symbol_ref (layout, i*2) == 'p')
544 SCM_STRUCT_SLOT_SET (obj, i, SCM_GOOPS_UNBOUND);
6d77c894 545
07452c83 546 return SCM_UNSPECIFIED;
80662eda 547}
398d8ee1 548#undef FUNC_NAME
80662eda 549
80662eda
MD
550/******************************************************************************
551 *
552 * %modify-instance (used by change-class to modify in place)
6d77c894 553 *
80662eda
MD
554 ******************************************************************************/
555
398d8ee1
KN
556SCM_DEFINE (scm_sys_modify_instance, "%modify-instance", 2, 0, 0,
557 (SCM old, SCM new),
558 "")
559#define FUNC_NAME s_scm_sys_modify_instance
80662eda 560{
398d8ee1
KN
561 SCM_VALIDATE_INSTANCE (1, old);
562 SCM_VALIDATE_INSTANCE (2, new);
80662eda 563
6d77c894 564 /* Exchange the data contained in old and new. We exchange rather than
80662eda
MD
565 * scratch the old value with new to be correct with GC.
566 * See "Class redefinition protocol above".
567 */
9de87eea 568 SCM_CRITICAL_SECTION_START;
80662eda 569 {
32b12f40
KR
570 scm_t_bits word0, word1;
571 word0 = SCM_CELL_WORD_0 (old);
572 word1 = SCM_CELL_WORD_1 (old);
573 SCM_SET_CELL_WORD_0 (old, SCM_CELL_WORD_0 (new));
574 SCM_SET_CELL_WORD_1 (old, SCM_CELL_WORD_1 (new));
575 SCM_SET_CELL_WORD_0 (new, word0);
576 SCM_SET_CELL_WORD_1 (new, word1);
80662eda 577 }
9de87eea 578 SCM_CRITICAL_SECTION_END;
80662eda
MD
579 return SCM_UNSPECIFIED;
580}
398d8ee1 581#undef FUNC_NAME
80662eda 582
398d8ee1
KN
583SCM_DEFINE (scm_sys_modify_class, "%modify-class", 2, 0, 0,
584 (SCM old, SCM new),
585 "")
586#define FUNC_NAME s_scm_sys_modify_class
80662eda 587{
398d8ee1
KN
588 SCM_VALIDATE_CLASS (1, old);
589 SCM_VALIDATE_CLASS (2, new);
80662eda 590
9de87eea 591 SCM_CRITICAL_SECTION_START;
80662eda 592 {
32b12f40
KR
593 scm_t_bits word0, word1;
594 word0 = SCM_CELL_WORD_0 (old);
595 word1 = SCM_CELL_WORD_1 (old);
596 SCM_SET_CELL_WORD_0 (old, SCM_CELL_WORD_0 (new));
597 SCM_SET_CELL_WORD_1 (old, SCM_CELL_WORD_1 (new));
b6cf4d02 598 SCM_STRUCT_DATA (old)[scm_vtable_index_self] = SCM_UNPACK (old);
32b12f40
KR
599 SCM_SET_CELL_WORD_0 (new, word0);
600 SCM_SET_CELL_WORD_1 (new, word1);
b6cf4d02 601 SCM_STRUCT_DATA (new)[scm_vtable_index_self] = SCM_UNPACK (new);
80662eda 602 }
9de87eea 603 SCM_CRITICAL_SECTION_END;
80662eda
MD
604 return SCM_UNSPECIFIED;
605}
398d8ee1 606#undef FUNC_NAME
80662eda 607
398d8ee1
KN
608SCM_DEFINE (scm_sys_invalidate_class, "%invalidate-class", 1, 0, 0,
609 (SCM class),
610 "")
611#define FUNC_NAME s_scm_sys_invalidate_class
80662eda 612{
398d8ee1 613 SCM_VALIDATE_CLASS (1, class);
80662eda
MD
614 SCM_CLEAR_CLASS_FLAGS (class, SCM_CLASSF_GOOPS_VALID);
615 return SCM_UNSPECIFIED;
616}
398d8ee1 617#undef FUNC_NAME
80662eda
MD
618
619/* When instances change class, they finally get a new body, but
620 * before that, they go through purgatory in hell. Odd as it may
621 * seem, this data structure saves us from eternal suffering in
622 * infinite recursions.
623 */
624
92c2555f 625static scm_t_bits **hell;
c014a02e
ML
626static long n_hell = 1; /* one place for the evil one himself */
627static long hell_size = 4;
2132f0d2 628static SCM hell_mutex;
80662eda 629
c014a02e 630static long
80662eda
MD
631burnin (SCM o)
632{
c014a02e 633 long i;
80662eda 634 for (i = 1; i < n_hell; ++i)
6b80d352 635 if (SCM_STRUCT_DATA (o) == hell[i])
80662eda
MD
636 return i;
637 return 0;
638}
639
640static void
641go_to_hell (void *o)
642{
b5df9cda 643 SCM obj = *(SCM*)o;
2132f0d2 644 scm_lock_mutex (hell_mutex);
51ef99f7 645 if (n_hell >= hell_size)
80662eda 646 {
51ef99f7 647 hell_size *= 2;
408bcd99 648 hell = scm_realloc (hell, hell_size * sizeof(*hell));
80662eda 649 }
6b80d352 650 hell[n_hell++] = SCM_STRUCT_DATA (obj);
2132f0d2 651 scm_unlock_mutex (hell_mutex);
80662eda
MD
652}
653
654static void
655go_to_heaven (void *o)
656{
b5df9cda 657 SCM obj = *(SCM*)o;
2132f0d2 658 scm_lock_mutex (hell_mutex);
b5df9cda 659 hell[burnin (obj)] = hell[--n_hell];
2132f0d2 660 scm_unlock_mutex (hell_mutex);
80662eda
MD
661}
662
6b80d352 663
80662eda 664static SCM
b5df9cda 665purgatory (SCM obj, SCM new_class)
80662eda 666{
b5df9cda 667 return scm_call_2 (SCM_VARIABLE_REF (var_change_class), obj, new_class);
80662eda
MD
668}
669
38d8927c
MD
670/* This function calls the generic function change-class for all
671 * instances which aren't currently undergoing class change.
672 */
673
80662eda 674void
e81d98ec 675scm_change_object_class (SCM obj, SCM old_class SCM_UNUSED, SCM new_class)
80662eda
MD
676{
677 if (!burnin (obj))
b5df9cda
AW
678 {
679 scm_dynwind_begin (SCM_F_DYNWIND_REWINDABLE);
680 scm_dynwind_rewind_handler (go_to_hell, &obj, SCM_F_WIND_EXPLICITLY);
681 scm_dynwind_unwind_handler (go_to_heaven, &obj, SCM_F_WIND_EXPLICITLY);
682 purgatory (obj, new_class);
683 scm_dynwind_end ();
684 }
80662eda
MD
685}
686
687/******************************************************************************
688 *
6d77c894
TTN
689 * GGGG FFFFF
690 * G F
691 * G GG FFF
692 * G G F
80662eda
MD
693 * GGG E N E R I C F U N C T I O N S
694 *
695 * This implementation provides
696 * - generic functions (with class specializers)
697 * - multi-methods
6d77c894 698 * - next-method
80662eda
MD
699 * - a hard-coded MOP for standard gf, which can be overloaded for non-std gf
700 *
701 ******************************************************************************/
702
703SCM_KEYWORD (k_name, "name");
63c1872f 704SCM_GLOBAL_SYMBOL (scm_sym_args, "args");
80662eda 705
398d8ee1
KN
706SCM_DEFINE (scm_generic_capability_p, "generic-capability?", 1, 0, 0,
707 (SCM proc),
708 "")
709#define FUNC_NAME s_scm_generic_capability_p
80662eda 710{
7888309b 711 SCM_ASSERT (scm_is_true (scm_procedure_p (proc)),
398d8ee1 712 proc, SCM_ARG1, FUNC_NAME);
9fdf9fd3 713 return (SCM_PRIMITIVE_GENERIC_P (proc) ? SCM_BOOL_T : SCM_BOOL_F);
80662eda 714}
398d8ee1 715#undef FUNC_NAME
80662eda 716
398d8ee1
KN
717SCM_DEFINE (scm_enable_primitive_generic_x, "enable-primitive-generic!", 0, 0, 1,
718 (SCM subrs),
719 "")
720#define FUNC_NAME s_scm_enable_primitive_generic_x
80662eda 721{
6b80d352 722 SCM_VALIDATE_REST_ARGUMENT (subrs);
d2e53ed6 723 while (!scm_is_null (subrs))
80662eda
MD
724 {
725 SCM subr = SCM_CAR (subrs);
9fdf9fd3 726 SCM_ASSERT (SCM_PRIMITIVE_GENERIC_P (subr), subr, SCM_ARGn, FUNC_NAME);
52fd9639 727 SCM_SET_SUBR_GENERIC (subr,
57898597 728 scm_make (scm_list_3 (class_generic,
52fd9639
AW
729 k_name,
730 SCM_SUBR_NAME (subr))));
80662eda
MD
731 subrs = SCM_CDR (subrs);
732 }
733 return SCM_UNSPECIFIED;
734}
398d8ee1 735#undef FUNC_NAME
80662eda 736
9f63ce02
AW
737SCM_DEFINE (scm_set_primitive_generic_x, "set-primitive-generic!", 2, 0, 0,
738 (SCM subr, SCM generic),
739 "")
740#define FUNC_NAME s_scm_set_primitive_generic_x
741{
9fdf9fd3 742 SCM_ASSERT (SCM_PRIMITIVE_GENERIC_P (subr), subr, SCM_ARG1, FUNC_NAME);
2b7692bc 743 SCM_ASSERT (SCM_GENERICP (generic), generic, SCM_ARG2, FUNC_NAME);
52fd9639 744 SCM_SET_SUBR_GENERIC (subr, generic);
9f63ce02
AW
745 return SCM_UNSPECIFIED;
746}
747#undef FUNC_NAME
748
398d8ee1
KN
749SCM_DEFINE (scm_primitive_generic_generic, "primitive-generic-generic", 1, 0, 0,
750 (SCM subr),
751 "")
752#define FUNC_NAME s_scm_primitive_generic_generic
80662eda 753{
9fdf9fd3 754 if (SCM_PRIMITIVE_GENERIC_P (subr))
80662eda 755 {
b2b33168 756 if (!SCM_UNPACK (*SCM_SUBR_GENERIC (subr)))
a48d60b1
MD
757 scm_enable_primitive_generic_x (scm_list_1 (subr));
758 return *SCM_SUBR_GENERIC (subr);
80662eda 759 }
db4b4ca6 760 SCM_WRONG_TYPE_ARG (SCM_ARG1, subr);
80662eda 761}
398d8ee1 762#undef FUNC_NAME
80662eda 763
fa075d40
AW
764/* Dirk:FIXME:: In all of these scm_wta_dispatch_* routines it is
765 * assumed that 'gf' is zero if uninitialized. It would be cleaner if
766 * some valid SCM value like SCM_BOOL_F or SCM_UNDEFINED were chosen.
767 */
768
769SCM
770scm_wta_dispatch_0 (SCM gf, const char *subr)
771{
772 if (!SCM_UNPACK (gf))
773 scm_error_num_args_subr (subr);
774
775 return scm_call_0 (gf);
776}
777
778SCM
779scm_wta_dispatch_1 (SCM gf, SCM a1, int pos, const char *subr)
780{
781 if (!SCM_UNPACK (gf))
782 scm_wrong_type_arg (subr, pos, a1);
783
784 return scm_call_1 (gf, a1);
785}
786
787SCM
788scm_wta_dispatch_2 (SCM gf, SCM a1, SCM a2, int pos, const char *subr)
789{
790 if (!SCM_UNPACK (gf))
791 scm_wrong_type_arg (subr, pos, (pos == SCM_ARG1) ? a1 : a2);
792
793 return scm_call_2 (gf, a1, a2);
794}
795
796SCM
797scm_wta_dispatch_n (SCM gf, SCM args, int pos, const char *subr)
798{
799 if (!SCM_UNPACK (gf))
800 scm_wrong_type_arg (subr, pos, scm_list_ref (args, scm_from_int (pos)));
801
802 return scm_apply_0 (gf, args);
803}
804
80662eda 805/******************************************************************************
6d77c894 806 *
80662eda 807 * Protocol for calling a generic fumction
6d77c894 808 * This protocol is roughly equivalent to (parameter are a little bit different
80662eda
MD
809 * for efficiency reasons):
810 *
811 * + apply-generic (gf args)
812 * + compute-applicable-methods (gf args ...)
813 * + sort-applicable-methods (methods args)
814 * + apply-methods (gf methods args)
6d77c894
TTN
815 *
816 * apply-methods calls make-next-method to build the "continuation" of a a
80662eda
MD
817 * method. Applying a next-method will call apply-next-method which in
818 * turn will call apply again to call effectively the following method.
819 *
820 ******************************************************************************/
821
398d8ee1
KN
822SCM_DEFINE (scm_make, "make", 0, 0, 1,
823 (SCM args),
27c37006 824 "Make a new object. @var{args} must contain the class and\n"
6bcefd15 825 "all necessary initialization information.")
398d8ee1 826#define FUNC_NAME s_scm_make
80662eda 827{
e0590e7c 828 return scm_apply_0 (scm_variable_ref (var_make), args);
80662eda 829}
398d8ee1 830#undef FUNC_NAME
80662eda 831
80662eda 832
80662eda
MD
833/**********************************************************************
834 *
835 * Smob classes
836 *
837 **********************************************************************/
838
839static SCM
2e0b6934 840make_class_name (const char *prefix, const char *type_name, const char *suffix)
80662eda 841{
2e0b6934
AW
842 if (!type_name)
843 type_name = "";
844 return scm_string_to_symbol (scm_string_append
845 (scm_list_3 (scm_from_utf8_string (prefix),
846 scm_from_utf8_string (type_name),
847 scm_from_utf8_string (suffix))));
80662eda
MD
848}
849
850SCM
da0e6c2b 851scm_make_extended_class (char const *type_name, int applicablep)
80662eda 852{
2e0b6934
AW
853 SCM name, meta, supers;
854
855 name = make_class_name ("<", type_name, ">");
856 meta = class_class;
857
858 if (applicablep)
859 supers = scm_list_1 (class_applicable);
860 else
861 supers = scm_list_1 (class_top);
862
863 return scm_make_standard_class (meta, name, supers, SCM_EOL);
74b6d6e4
MD
864}
865
866void
867scm_i_inherit_applicable (SCM c)
868{
57898597 869 if (!SCM_SUBCLASSP (c, class_applicable))
74b6d6e4
MD
870 {
871 SCM dsupers = SCM_SLOT (c, scm_si_direct_supers);
872 SCM cpl = SCM_SLOT (c, scm_si_cpl);
57898597
AW
873 /* patch class_applicable into direct-supers */
874 SCM top = scm_c_memq (class_top, dsupers);
7888309b 875 if (scm_is_false (top))
74b6d6e4 876 dsupers = scm_append (scm_list_2 (dsupers,
57898597 877 scm_list_1 (class_applicable)));
74b6d6e4
MD
878 else
879 {
57898597
AW
880 SCM_SETCAR (top, class_applicable);
881 SCM_SETCDR (top, scm_cons (class_top, SCM_CDR (top)));
74b6d6e4
MD
882 }
883 SCM_SET_SLOT (c, scm_si_direct_supers, dsupers);
57898597
AW
884 /* patch class_applicable into cpl */
885 top = scm_c_memq (class_top, cpl);
7888309b 886 if (scm_is_false (top))
74b6d6e4
MD
887 abort ();
888 else
889 {
57898597
AW
890 SCM_SETCAR (top, class_applicable);
891 SCM_SETCDR (top, scm_cons (class_top, SCM_CDR (top)));
74b6d6e4 892 }
57898597
AW
893 /* add class to direct-subclasses of class_applicable */
894 SCM_SET_SLOT (class_applicable,
74b6d6e4 895 scm_si_direct_subclasses,
57898597 896 scm_cons (c, SCM_SLOT (class_applicable,
74b6d6e4
MD
897 scm_si_direct_subclasses)));
898 }
80662eda
MD
899}
900
901static void
902create_smob_classes (void)
903{
c014a02e 904 long i;
80662eda 905
c891a40e 906 for (i = 0; i < SCM_I_MAX_SMOB_TYPE_COUNT; ++i)
57898597 907 scm_i_smob_class[i] = SCM_BOOL_F;
80662eda 908
80662eda 909 for (i = 0; i < scm_numsmob; ++i)
57898597
AW
910 if (scm_is_false (scm_i_smob_class[i]))
911 scm_i_smob_class[i] = scm_make_extended_class (SCM_SMOBNAME (i),
912 scm_smobs[i].apply != 0);
80662eda
MD
913}
914
915void
c014a02e 916scm_make_port_classes (long ptobnum, char *type_name)
80662eda 917{
2e0b6934
AW
918 SCM name, meta, super, supers;
919
920 meta = class_class;
921
922 name = make_class_name ("<", type_name, "-port>");
923 supers = scm_list_1 (class_port);
924 super = scm_make_standard_class (meta, name, supers, SCM_EOL);
925
926 name = make_class_name ("<", type_name, "-input-port>");
927 supers = scm_list_2 (super, class_input_port);
57898597 928 scm_i_port_class[SCM_IN_PCLASS_INDEX + ptobnum]
2e0b6934
AW
929 = scm_make_standard_class (meta, name, supers, SCM_EOL);
930
931 name = make_class_name ("<", type_name, "-output-port>");
932 supers = scm_list_2 (super, class_output_port);
57898597 933 scm_i_port_class[SCM_OUT_PCLASS_INDEX + ptobnum]
2e0b6934
AW
934 = scm_make_standard_class (meta, name, supers, SCM_EOL);
935
936 name = make_class_name ("<", type_name, "-input-output-port>");
937 supers = scm_list_2 (super, class_input_output_port);
57898597 938 scm_i_port_class[SCM_INOUT_PCLASS_INDEX + ptobnum]
2e0b6934 939 = scm_make_standard_class (meta, name, supers, SCM_EOL);
80662eda
MD
940}
941
942static void
943create_port_classes (void)
944{
c014a02e 945 long i;
80662eda 946
62bd5d66 947 for (i = scm_c_num_port_types () - 1; i >= 0; i--)
80662eda
MD
948 scm_make_port_classes (i, SCM_PTOBNAME (i));
949}
950
6c7dd9eb
AW
951SCM
952scm_i_define_class_for_vtable (SCM vtable)
953{
954 SCM class;
955
956 scm_i_pthread_mutex_lock (&scm_i_misc_mutex);
957 if (scm_is_false (vtable_class_map))
958 vtable_class_map = scm_c_make_weak_table (0, SCM_WEAK_TABLE_KIND_KEY);
959 scm_i_pthread_mutex_unlock (&scm_i_misc_mutex);
960
961 if (scm_is_false (scm_struct_vtable_p (vtable)))
962 abort ();
963
964 class = scm_weak_table_refq (vtable_class_map, vtable, SCM_BOOL_F);
965
966 if (scm_is_false (class))
967 {
57898597 968 if (SCM_UNPACK (class_class))
6c7dd9eb
AW
969 {
970 SCM name, meta, supers;
971
972 name = SCM_VTABLE_NAME (vtable);
973 if (scm_is_symbol (name))
974 name = scm_string_to_symbol
975 (scm_string_append
976 (scm_list_3 (scm_from_latin1_string ("<"),
977 scm_symbol_to_string (name),
978 scm_from_latin1_string (">"))));
979 else
980 name = scm_from_latin1_symbol ("<>");
981
982 if (SCM_STRUCT_VTABLE_FLAG_IS_SET (vtable, SCM_VTABLE_FLAG_SETTER))
983 {
57898597
AW
984 meta = class_applicable_struct_with_setter_class;
985 supers = scm_list_1 (class_applicable_struct_with_setter);
6c7dd9eb
AW
986 }
987 else if (SCM_STRUCT_VTABLE_FLAG_IS_SET (vtable,
988 SCM_VTABLE_FLAG_APPLICABLE))
989 {
57898597
AW
990 meta = class_applicable_struct_class;
991 supers = scm_list_1 (class_applicable_struct);
6c7dd9eb
AW
992 }
993 else
994 {
57898597
AW
995 meta = class_class;
996 supers = scm_list_1 (class_top);
6c7dd9eb
AW
997 }
998
999 return scm_make_standard_class (meta, name, supers, SCM_EOL);
1000 }
1001 else
1002 /* `create_struct_classes' will fill this in later. */
1003 class = SCM_BOOL_F;
1004
1005 /* Don't worry about races. This only happens when creating a
1006 vtable, which happens by definition in one thread. */
1007 scm_weak_table_putq_x (vtable_class_map, vtable, class);
1008 }
1009
1010 return class;
1011}
1012
80662eda 1013static SCM
74b6d6e4
MD
1014make_struct_class (void *closure SCM_UNUSED,
1015 SCM vtable, SCM data, SCM prev SCM_UNUSED)
80662eda 1016{
f3c6a02c
AW
1017 if (scm_is_false (data))
1018 scm_i_define_class_for_vtable (vtable);
80662eda
MD
1019 return SCM_UNSPECIFIED;
1020}
1021
1022static void
1023create_struct_classes (void)
1024{
ea742d29 1025 /* FIXME: take the vtable_class_map while initializing goops? */
f3c6a02c
AW
1026 scm_internal_hash_fold (make_struct_class, 0, SCM_BOOL_F,
1027 vtable_class_map);
80662eda
MD
1028}
1029
1030/**********************************************************************
1031 *
1032 * C interface
1033 *
1034 **********************************************************************/
1035
1036void
1037scm_load_goops ()
1038{
1039 if (!goops_loaded_p)
abd28220 1040 scm_c_resolve_module ("oop goops");
80662eda
MD
1041}
1042
e11208ca 1043
e0590e7c
AW
1044SCM_KEYWORD (k_setter, "setter");
1045
80662eda
MD
1046SCM
1047scm_ensure_accessor (SCM name)
1048{
3f48638c
AW
1049 SCM var, gf;
1050
1051 var = scm_module_variable (scm_current_module (), name);
1052 if (SCM_VARIABLEP (var) && !SCM_UNBNDP (SCM_VARIABLE_REF (var)))
1053 gf = SCM_VARIABLE_REF (var);
1054 else
1055 gf = SCM_BOOL_F;
1056
57898597 1057 if (!SCM_IS_A_P (gf, class_accessor))
80662eda 1058 {
57898597
AW
1059 gf = scm_make (scm_list_3 (class_generic, k_name, name));
1060 gf = scm_make (scm_list_5 (class_accessor,
1afff620 1061 k_name, name, k_setter, gf));
80662eda 1062 }
3f48638c 1063
80662eda
MD
1064 return gf;
1065}
1066
80662eda
MD
1067/*
1068 * Initialization
1069 */
1070
6c7dd9eb
AW
1071SCM_DEFINE (scm_sys_bless_applicable_struct_vtables_x, "%bless-applicable-struct-vtables!", 2, 0, 0,
1072 (SCM applicable, SCM setter),
51fd1cd6 1073 "")
6c7dd9eb 1074#define FUNC_NAME s_scm_sys_bless_applicable_struct_vtables_x
51fd1cd6 1075{
6c7dd9eb
AW
1076 SCM_VALIDATE_CLASS (1, applicable);
1077 SCM_VALIDATE_CLASS (2, setter);
1078 SCM_SET_VTABLE_FLAGS (applicable, SCM_VTABLE_FLAG_APPLICABLE_VTABLE);
1079 SCM_SET_VTABLE_FLAGS (setter, SCM_VTABLE_FLAG_SETTER_VTABLE);
51fd1cd6
AW
1080 return SCM_UNSPECIFIED;
1081}
1082#undef FUNC_NAME
1083
82ab5090
AW
1084SCM_DEFINE (scm_sys_goops_early_init, "%goops-early-init", 0, 0, 0,
1085 (),
1086 "")
1087#define FUNC_NAME s_scm_sys_goops_early_init
1088{
51fd1cd6 1089 var_make_standard_class = scm_c_lookup ("make-standard-class");
e0590e7c 1090 var_make = scm_c_lookup ("make");
51fd1cd6 1091
ade4cf4c
AW
1092 var_slot_ref_using_class = scm_c_lookup ("slot-ref-using-class");
1093 var_slot_set_using_class_x = scm_c_lookup ("slot-set-using-class!");
1094 var_slot_bound_using_class_p = scm_c_lookup ("slot-bound-using-class?");
1095 var_slot_exists_using_class_p = scm_c_lookup ("slot-exists-using-class?");
1096
1097 var_slot_ref = scm_c_lookup ("slot-ref");
1098 var_slot_set_x = scm_c_lookup ("slot-set!");
1099 var_slot_bound_p = scm_c_lookup ("slot-bound?");
1100 var_slot_exists_p = scm_c_lookup ("slot-exists?");
1101
57898597
AW
1102 class_class = scm_variable_ref (scm_c_lookup ("<class>"));
1103 class_top = scm_variable_ref (scm_c_lookup ("<top>"));
1104 class_object = scm_variable_ref (scm_c_lookup ("<object>"));
1105
1106 class_foreign_slot = scm_variable_ref (scm_c_lookup ("<foreign-slot>"));
1107 class_protected = scm_variable_ref (scm_c_lookup ("<protected-slot>"));
1108 class_hidden = scm_variable_ref (scm_c_lookup ("<hidden-slot>"));
1109 class_opaque = scm_variable_ref (scm_c_lookup ("<opaque-slot>"));
1110 class_read_only = scm_variable_ref (scm_c_lookup ("<read-only-slot>"));
1111 class_self = scm_variable_ref (scm_c_lookup ("<self-slot>"));
1112 class_protected_opaque = scm_variable_ref (scm_c_lookup ("<protected-opaque-slot>"));
1113 class_protected_hidden = scm_variable_ref (scm_c_lookup ("<protected-hidden-slot>"));
1114 class_protected_read_only = scm_variable_ref (scm_c_lookup ("<protected-read-only-slot>"));
1115 class_scm = scm_variable_ref (scm_c_lookup ("<scm-slot>"));
1116 class_int = scm_variable_ref (scm_c_lookup ("<int-slot>"));
1117 class_float = scm_variable_ref (scm_c_lookup ("<float-slot>"));
1118 class_double = scm_variable_ref (scm_c_lookup ("<double-slot>"));
1119
1120 /* Applicables */
1121 class_procedure_class = scm_variable_ref (scm_c_lookup ("<procedure-class>"));
1122 class_applicable_struct_class = scm_variable_ref (scm_c_lookup ("<applicable-struct-class>"));
1123 class_applicable_struct_with_setter_class =
6c7dd9eb 1124 scm_variable_ref (scm_c_lookup ("<applicable-struct-with-setter-class>"));
51fd1cd6 1125
57898597
AW
1126 class_method = scm_variable_ref (scm_c_lookup ("<method>"));
1127 class_accessor_method = scm_variable_ref (scm_c_lookup ("<accessor-method>"));
1128 class_applicable = scm_variable_ref (scm_c_lookup ("<applicable>"));
1129 class_applicable_struct = scm_variable_ref (scm_c_lookup ("<applicable-struct>"));
1130 class_applicable_struct_with_setter = scm_variable_ref (scm_c_lookup ("<applicable-struct-with-setter>"));
1131 class_generic = scm_variable_ref (scm_c_lookup ("<generic>"));
1132 class_extended_generic = scm_variable_ref (scm_c_lookup ("<extended-generic>"));
1133 class_generic_with_setter = scm_variable_ref (scm_c_lookup ("<generic-with-setter>"));
1134 class_accessor = scm_variable_ref (scm_c_lookup ("<accessor>"));
1135 class_extended_generic_with_setter = scm_variable_ref (scm_c_lookup ("<extended-generic-with-setter>"));
1136 class_extended_accessor = scm_variable_ref (scm_c_lookup ("<extended-accessor>"));
51fd1cd6
AW
1137
1138 /* Primitive types classes */
57898597
AW
1139 class_boolean = scm_variable_ref (scm_c_lookup ("<boolean>"));
1140 class_char = scm_variable_ref (scm_c_lookup ("<char>"));
1141 class_list = scm_variable_ref (scm_c_lookup ("<list>"));
1142 class_pair = scm_variable_ref (scm_c_lookup ("<pair>"));
1143 class_null = scm_variable_ref (scm_c_lookup ("<null>"));
1144 class_string = scm_variable_ref (scm_c_lookup ("<string>"));
1145 class_symbol = scm_variable_ref (scm_c_lookup ("<symbol>"));
1146 class_vector = scm_variable_ref (scm_c_lookup ("<vector>"));
51fd1cd6
AW
1147 class_foreign = scm_variable_ref (scm_c_lookup ("<foreign>"));
1148 class_hashtable = scm_variable_ref (scm_c_lookup ("<hashtable>"));
1149 class_fluid = scm_variable_ref (scm_c_lookup ("<fluid>"));
1150 class_dynamic_state = scm_variable_ref (scm_c_lookup ("<dynamic-state>"));
1151 class_frame = scm_variable_ref (scm_c_lookup ("<frame>"));
1152 class_vm_cont = scm_variable_ref (scm_c_lookup ("<vm-continuation>"));
1153 class_bytevector = scm_variable_ref (scm_c_lookup ("<bytevector>"));
1154 class_uvec = scm_variable_ref (scm_c_lookup ("<uvec>"));
1155 class_array = scm_variable_ref (scm_c_lookup ("<array>"));
1156 class_bitvector = scm_variable_ref (scm_c_lookup ("<bitvector>"));
57898597
AW
1157 class_number = scm_variable_ref (scm_c_lookup ("<number>"));
1158 class_complex = scm_variable_ref (scm_c_lookup ("<complex>"));
1159 class_real = scm_variable_ref (scm_c_lookup ("<real>"));
1160 class_integer = scm_variable_ref (scm_c_lookup ("<integer>"));
1161 class_fraction = scm_variable_ref (scm_c_lookup ("<fraction>"));
1162 class_keyword = scm_variable_ref (scm_c_lookup ("<keyword>"));
1163 class_unknown = scm_variable_ref (scm_c_lookup ("<unknown>"));
1164 class_procedure = scm_variable_ref (scm_c_lookup ("<procedure>"));
1165 class_primitive_generic = scm_variable_ref (scm_c_lookup ("<primitive-generic>"));
1166 class_port = scm_variable_ref (scm_c_lookup ("<port>"));
1167 class_input_port = scm_variable_ref (scm_c_lookup ("<input-port>"));
1168 class_output_port = scm_variable_ref (scm_c_lookup ("<output-port>"));
1169 class_input_output_port = scm_variable_ref (scm_c_lookup ("<input-output-port>"));
51fd1cd6 1170
82ab5090
AW
1171 create_smob_classes ();
1172 create_struct_classes ();
1173 create_port_classes ();
1174
82ab5090
AW
1175 return SCM_UNSPECIFIED;
1176}
1177#undef FUNC_NAME
1178
398d8ee1
KN
1179SCM_DEFINE (scm_sys_goops_loaded, "%goops-loaded", 0, 0, 0,
1180 (),
6bcefd15
MG
1181 "Announce that GOOPS is loaded and perform initialization\n"
1182 "on the C level which depends on the loaded GOOPS modules.")
398d8ee1 1183#define FUNC_NAME s_scm_sys_goops_loaded
80662eda
MD
1184{
1185 goops_loaded_p = 1;
48c981c9
AW
1186 var_class_name = scm_c_lookup ("class-name");
1187 var_class_direct_supers = scm_c_lookup ("class-direct-supers");
1188 var_class_direct_slots = scm_c_lookup ("class-direct-slots");
1189 var_class_direct_subclasses = scm_c_lookup ("class-direct-subclasses");
1190 var_class_direct_methods = scm_c_lookup ("class-direct-methods");
1191 var_class_precedence_list = scm_c_lookup ("class-precedence-list");
1192 var_class_slots = scm_c_lookup ("class-slots");
1193
1194 var_generic_function_methods = scm_c_lookup ("generic-function-methods");
1195 var_method_generic_function = scm_c_lookup ("method-generic-function");
1196 var_method_specializers = scm_c_lookup ("method-specializers");
1197 var_method_procedure = scm_c_lookup ("method-procedure");
1198
5a6165db 1199 var_change_class = scm_c_lookup ("change-class");
623559f3
AW
1200
1201#if (SCM_ENABLE_DEPRECATED == 1)
1202 scm_init_deprecated_goops ();
1203#endif
1204
80662eda
MD
1205 return SCM_UNSPECIFIED;
1206}
398d8ee1 1207#undef FUNC_NAME
80662eda
MD
1208
1209SCM scm_module_goops;
1210
6ab19396
AW
1211static void
1212scm_init_goops_builtins (void *unused)
80662eda 1213{
abd28220 1214 scm_module_goops = scm_current_module ();
80662eda 1215
bb764c0e 1216 hell = scm_calloc (hell_size * sizeof (*hell));
f39448c5 1217 hell_mutex = scm_make_mutex ();
80662eda 1218
82ab5090 1219#include "libguile/goops.x"
80662eda
MD
1220}
1221
1222void
abd28220 1223scm_init_goops ()
80662eda 1224{
6ab19396
AW
1225 scm_c_register_extension ("libguile-" SCM_EFFECTIVE_VERSION,
1226 "scm_init_goops_builtins", scm_init_goops_builtins,
1227 NULL);
80662eda 1228}
23437298
DH
1229
1230/*
1231 Local Variables:
1232 c-file-style: "gnu"
1233 End:
1234*/