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