* libguile/deprecated.h:
* libguile/goops.c:
* libguile/goops.h:
* libguile/deprecated.c (scm_slot_ref_using_class):
(scm_slot_set_using_class_x):
(scm_slot_bound_using_class_p):
(scm_slot_exists_using_class_p): Deprecate.
* module/oop/goops.scm (slot-ref-using-class, slot-set-using-class!)
(slot-bound-using-class?, slot-exists-using-class?): Deprecate.
Change to check that `class' is indeed the class of `obj', as
required, and then dispatch to slot-ref et al.
* module/oop/goops.scm (slot-ref, slot-set!, slot-bound?, slot-exists?):
Bypass slot-ref-using-class, slot-set-using-class!, and so on. Those
interfaces are public and have to check that the class is indeed a
class, they should check that the object is an instance of the class,
and so on, whereas if we get the class via class-of we know that the
invariant holds.
* libguile/goops.h: Remove unimplemented declarations of
scm_make_next_method, scm_sys_invalidate_method_cache_x, and
stklos_version.
(scm_sys_invalidate_class_x): Remove helper definition. This was
exported in the past but shouldn't have been.
* libguile/goops.c (scm_sys_make_vtable_vtable): Rename from
scm_sys_make_root_class, and don't do anything about flags.
(scm_sys_bless_applicable_struct_vtables_x, scm_class_p)
(scm_sys_invalidate_class_x): Remove; we do these in Scheme now.
(scm_init_goops_builtins): Define Scheme values for vtable flags.
* module/oop/goops.scm (vtable-flag-goops-metaclass)
(class-add-flags!, class-clear-flags!, class-has-flags?)
(class?, instance?): New definitions.
(<class>): Add GOOPS metaclass flags from Scheme.
(<applicable-struct-class>, <applicable-struct-with-setter-class>):
Add flags from Scheme.
(make, initialize): Add class flags as appropriate.
(class-redefinition): Clear the "valid" flag on the old class.
(check-slot-args): Use instance? instead of a CPL check.
* test-suite/tests/goops.test: Add tests for compute-cpl based on
comments from goops.scm.
* module/oop/goops.scm (compute-std-cpl): Remove comment, and add
docstring.
(compute-cpl): Improve comment.
* module/oop/goops/util.scm: Removed. Instead we fold these definitions
into goops.scm.
* module/oop/goops/save.scm: Remove useless import of util.scm.
* module/oop/goops.scm: Fold in util.scm. Since we always use
add-interesting-primitive!, import (language tree-il primitives) in
the header. Clean up some early comments, and use of eval-when.
* module/Makefile.am: Adapt.
* module/oop/goops.scm (make-class): Inline find-duplicate to its use
site.
* module/oop/goops/util.scm (improper->proper): Remove unused function.
(any, every): Don't re-export these from SRFI-1; users can get them
from SRFI-1 directly.
* libguile/goops.c: Move captured keywords and symbols up to the top.
(scm_i_inherit_applicable): Dispatch to Scheme.
(scm_sys_goops_early_init): Capture inherit-applicable!.
* module/oop/goops.scm (inherit-applicable!): Scheme implementation.
* libguile/goops.c (scm_sys_clear_fields_x): New function.
(scm_sys_allocate_instance): Remove. It was available to C but not to
Scheme and it's really internal.
* libguile/goops.h: Remove scm_sys_allocate_instance.
* module/oop/goops.scm (%allocate-instance): Implement in Scheme, using
allocate-struct and %clear-fields!.
(make, shallow-clone, deep-clone, allocate-instance): Adapt to
%allocate-instance not taking an initargs argument.
* module/oop/goops.scm (fold-<class>-slots): The first "reserved" slot
is actually for instance sizes, used by the "simple struct"
mechanism. Reuse this field for GOOPS's "nfields".
(make-standard-class, <class>, initialize): Adapt order of field
initializations.
* libguile/goops.h (SCM_CLASS_CLASS_LAYOUT, SCM_N_CLASS_SLOTS)
* libguile/goops.c (scm_sys_allocate_instance): Adapt.
* libguile/goops.c (scm_sys_make_root_class): Just make the
vtable-vtable, and leave initialization to Scheme.
* libguile/struct.c (scm_i_make_vtable_vtable): Change to take a full
list of fields, not just the extra fields.
(scm_init_struct): Adapt to scm_i_make_vtable_vtable change.
* module/oop/goops.scm (<class>): Compute layout for <class>, and
initialize <class> from here.
* libguile/goops.h:
* libguile/goops.c (scm_sys_initialize_object): Remove C interface.
This function was only really useful as part of a GOOPS initialize
method but was not exported from the goops module.
* module/oop/goops.scm (get-keyword, %initialize-object): Implement in
Scheme.
* module/oop/goops.scm (macro-fold-left): New helper.
(define-class-index): Define class-index-FOO for each slot FOO.
(fold-<class>-slots): Make the slots list have the marks of the
"visit" macro.
* module/oop/goops.scm (macro-fold-right, fold-<class>-slots, <class>):
Use a macro folder to define (and redefine) class slots. We'll use
this to compute static indices as well.
* libguile/goops.h (SCM_CLASS_CLASS_LAYOUT, SCM_INSTANCE_HASH)
(SCM_SET_HASHSET):
* libguile/goops.c (prep_hashsets, scm_sys_make_root_class,
scm_sys_init_layout_x):
* module/oop/goops.scm (build-<class>-slots): Remove hashsets from
classes. We haven't implemented hashed dispatch since Guile 1.8, and
it's not clear that the particular formulation of dispatch is a good
idea.
* libguile/goops.c (scm_sys_set_object_setter_x): Remove. Instead, we
use slot-set! of 'setter.
(scm_i_define_class_for_vtable): Move lower in the file, and fold in
scm_make_extended_class_from_symbol and make_class_from_symbol.
Properly handle applicable structs with setters.
(scm_class_applicable_struct_with_setter_class): New private capture.
(scm_sys_bless_applicable_struct_vtables_x): Rename to take two
arguments, and bless the second argument as an applicable struct with
setter vtable.
(scm_sys_goops_early_init): Capture setter classes.
* libguile/deprecated.c (SPEC_OF, CPL_OF): Access slots by name, not by
index.
(applicablep, more_specificp): Adapt to use CPL_OF.
(scm_find_method): Access "methods" slot by name.
* libguile/procs.c (scm_setter): Remove special case for generics; if
it's a setter, it will be a normal applicable struct.
* module/oop/goops.scm (<applicable-struct-with-setter-class>)
(<applicable-struct-with-setter>): New classes.
(<generic-with-setter>): Now an instance of the setter metaclass and a
child of the setter class, so that the "setter" slot ends up in the
right place.
(<accessor>, <extended-generic-with-setter>, <extended-accessor>): Be
instances of the setter metaclass.
(<method>, <accessor-method>): Move definitions farther down.
(make): Use slot-set! when initializing setters here.
(initialize): Likewise for <applicable-struct-with-setter>. Remove
specialization for <generic-with-setter>.
* libguile/goops.c (scm_sys_invalidate_method_cache_x): Remove C
interface to this internal method. Instead, internal callers are all
from Scheme, so we move the implementation to Scheme.
(scm_make): Dispatch to `make' in Scheme. This is an incompatible but
great change, as it fulfills the common user perception that scm_make
is the same as GOOPS's `make'.
(scm_sys_goops_early_init): Capture `make'.
(scm_no_applicable_method): Define in Scheme and capture in C.
* module/Makefile.am: Remove oop/goops/compile.scm and
oop/goops/dispatch.scm.
* module/oop/goops/compile.scm:
* module/oop/goops/dispatch.scm: Fold into goops.scm.
* module/oop/goops.scm: Fold in the generic compile and dispatch
modules. This eliminates a circularity that caused some eval-when
shenanigans, so remove the eval-whens as well. Reimplement the boot
version of `make' in Scheme, and make the <generic> `initialize'
method handle invalidation instead of the generic %allocate-instance.
(no-applicable-method): Define here. Import the utils module in the
normal define-module block.
* module/oop/goops.scm (build-<class>-slots): New helper, replacing
build_class_class_slots.
(build-slots-list, %compute-getters-n-setters, %compute-layout): New
private helpers, moved here from C.
(%prep-layout!): Reimplement in Scheme.
(make-standard-class): New private helper, replacing
scm_basic_make_class.
(<class>, <top>, <object>): Define in Scheme.
(<foreign-slot>, <protected-slot>, <hidden-slot>, <opaque-slot>,
<read-only-slot>, <self-slot>, <protected-opaque-slot>,
<protected-hidden-slot>, <protected-read-only-slot>, <scm-slot>,
<int-slot>, <float-slot>, <double-slot>, <procedure-class>,
<applicable-struct-class>, <method>, <accessor-method>, <applicable>,
<applicable-struct>, <generic>, <extended-generic>,
<generic-with-setter>, <accessor>, <extended-generic-with-setter>,
<extended-accessor>): Define in Scheme.
(<boolean>, <char>, <list>, <pair>, <null>, <string>, <symbol>,
<vector>, <foreign>, <hashtable>, <fluid>, <dynamic-state>, <frame>,
<vm-continuation>, <bytevector>, <uvec>, <array>, <bitvector>,
<number>, <complex>, <real>, <integer>, <fraction>, <keyword>,
<unknown>, <procedure>, <primitive-generic>, <port>, <input-port>,
<output-port>, <input-output-port>): Define in Scheme.
(compute-slots): Use build-slots-list helper.
* libguile/goops.h:
* libguile/goops.c (scm_basic_basic_make_class, scm_sys_compute_slots)
(scm_sys_prep_layout_x): Remove. These were available to C, but were
undocumented internals that were dangerous, confusing, and
unnecessary.
* libguile/goops.c: Add note about variable versus value references.
Remove internal C routines that were just used during boot, as they
have been moved to Scheme.
(scm_basic_make_class): Change to call out to make-standard-class in
Scheme.
(scm_sys_make_root_class, scm_sys_bless_applicable_struct_vtable_x)
(scm_sys_bless_pure_generic_vtable_x, scm_sys_init_layout_x): New
private helpers.
(scm_sys_goops_early_init): Change to capture values defined in
Scheme.
* libguile/goops.h:
* libguile/goops.c (scm_sys_fast_slot_ref, scm_sys_fast_slot_set_x):
Remove these unused, unsafe functions. They were publically available
only to C.
* module/oop/goops/active-slot.scm (compute-get-n-set): Update to use
struct-ref / struct-set! instead of %fast-slot-ref / %fast-slot-set!
from (oop goops internal).
* libguile/goops.c (scm_sys_goops_early_init)
(scm_init_goops_builtins): Factor out some initialization to a
separate helper. This will be the base for moving more things from C
to Scheme in the future.
* module/oop/goops.scm: Call %goops-early-init.
* libguile/goops.h:
* libguile/goops.c (scm_init_goops, scm_init_goops_builtins): Move
%init-goops-builtins to be an extension instead of a globally
accessible function.
* module/oop/goops.scm: Adapt.
* libguile/goops.c (build_class_class_slots, create_basic_classes):
Instead of creating <class> with uninitialized `direct-slots',
`slots', and `getters-n-setters' fields and initializing them later,
create <class> with a "boot" version of unspecialized slots and later
replace the fields with specialized slot classes. This allows
slot-ref to work during early boot, which is necessary to move
compute-cpl to Scheme.
(create_standard_classes): Finish initializing <class> here.
(map, filter_cpl, compute_cpl): Remove the boot-time compute-cpl in C
and its helpers.
(scm_basic_basic_make_class): Call compute-cpl in Scheme.
(fix_cpl): Remove; since we use the correct compute-cpl from the
beginning, there's no need to correct for the deficiencies of the C
implementation any more.
(build_slots_list): Adapt to build_class_class_slots change.
* module/oop/goops.scm (compute-std-cpl, compute-cpl): Move these up to
the top, so they can be called by the boot process.
(compute-clos-cpl, top-sort, std-tie-breaker, build-transitive-closure)
(build-constraints): Remove unused private code.
* libguile/goops.h:
* libguile/goops.c (more_specificp, scm_sys_method_more_specific_p):
* module/oop/goops.scm (%method-more-specific?): Rewrite in Scheme. We
remove the scm_sys_method_more_specific_p interface as it is a private
interface and it's not extensible.
* libguile/goops.c: Move %compute-applicable-methods to Scheme.
(scm_sys_goops_loaded): No need to initialize
var_compute_applicable_methods.
* libguile/goops.h (scm_sys_compute_applicable_methods): Remove. This
was internal so it shouldn't cause a problem.
* module/oop/goops.scm (%sort-applicable-methods):
(%compute-applicable-methods): New definitions.
Allocating an instance of a class with a #:class or #:each-subclass slot
allocation should not re-initialize the class-allocated slot. In Guile
1.8, this worked by effectively doing a slot-bound? within
%initialize-object. In Guile 2.0 we instead initialize the slot when it
is allocated -- in compute-get-n-set.
* module/oop/goops.scm (compute-getters-n-setters): Don't set an
init-thunk for class-allocated slots.
(compute-get-n-set): Initialize class-allocated slots here, if an
init-thunk or init-value are present.
* test-suite/tests/goops.test ("#:each-subclass"): Add test.
* libguile/goops.c (scm_sys_initialize_object): Refactor initialization
so that we don't ref uninitialized slots before initializing them.
This allows foreign slots, whose initial value is 0, to be initialized
via #:init-form.
* module/oop/goops.scm (@slot-ref, @slot-set!): Remove definitions.
Change callers to use struct-ref and struct-set!. slot-ref and
slot-set! were only marginally more efficient and were much more
dangerous. This change allows the standard accessors to work on
foreign slots; that was not the case before, as the 'u' fields of the
struct were read as if they were 'p' slots.
* module/language/tree-il/compile-glil.scm (lambda): Remove support for
compiling @slot-ref/@slot-set!. These were private to GOOPS.
* test-suite/tests/goops.test ("active-slot"): Update to not expect a
ref before initialization.
("foreign slots"): Add tests.