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