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