* libguile/vm-engine.c (vm_engine): Cache the address of local 0 instead
of the FP. This makes locals access a bit cheaper, but we still have
to negate the index. The right fix is to index relative to the SP
instead. That's a more involved change, so we punt until later.
Adapt VM stack to grow downward. This will make native compilation look
more like the VM code, as we will be able to use native CALL
instructions, taking proper advantage of the return address buffer.
* libguile/continuations.c (scm_i_continuation_to_frame): Record offsets
from stack top.
* libguile/control.c (scm_i_prompt_pop_abort_args_x): Adapt for reversed
order of arguments, and instead of relying on the abort to push on the
number of arguments, make the caller save the stack depth, which
allows us to compute the number of arguments ourselves.
(reify_partial_continuation, scm_c_abort): Adapt to reversed stack
order.
* libguile/dynstack.c (scm_dynstack_wind_prompt): Since we wind the
stack in a downward direction, subtract the reloc instead of adding
it.
* libguile/dynstack.h (SCM_F_DYNSTACK_PROMPT_ESCAPE_ONLY): Remove flag;
instead rely on prompt-establishing code to save the stack depth.
* libguile/eval.c (eval): Remove extraneous "volatile" declarations for
variables that are not re-set between the setjmp and any longjmp.
Adapt to save stack depth before instating the prompt.
* libguile/foreign.c (scm_i_foreign_call): Adapt to receive arguments in
reverse order.
* libguile/frames.c (frame_stack_top, scm_i_frame_stack_top): Adapt to
compute stack top instead of stack bottom.
(scm_c_frame_closure): Adapt to stack growth change.
(scm_frame_num_locals, scm_frame_local_ref, scm_frame_set_x): Use
union data type to access stack.
(RELOC): Reformat.
(scm_c_frame_previous): Adapt to stack growth change.
* libguile/frames.h: Adapt stack diagram to indicate that the stack
grows up.
(union scm_vm_stack_element): New data type used to access items on
the stack.
(SCM_FRAME_PREVIOUS_SP)
(SCM_FRAME_RETURN_ADDRESS, SCM_FRAME_SET_RETURN_ADDRESS)
(SCM_FRAME_DYNAMIC_LINK, SCM_FRAME_SET_DYNAMIC_LINK)
(SCM_FRAME_LOCAL, SCM_FRAME_NUM_LOCALS): Adapt to stack representation
change.
(SCM_FRAME_SLOT): New helper.
(SCM_VM_FRAME_FP, SCM_VM_FRAME_SP): Adapt to stack growth change.
* libguile/stacks.c (scm_make_stack): Record offsets from top of stack.
* libguile/throw.c (catch): Adapt to scm_i_prompt_pop_abort_args_x
change.
* libguile/vm-engine.c (ALLOC_FRAME, RESET_FRAME):
(FRAME_LOCALS_COUNT_FROM): Adapt to stack growth change.
(LOCAL_ADDRESS): Use SCM_FRAME_SLOT to get the address as the proper
data type.
(RETURN_ONE_VALUE, RETURN_VALUE_LIST): Adapt to stack growth change.
(apply): Shuffling up the SMOB apply args can cause the stack to
expand, so use ALLOC_FRAME instead of RESET_FRAME.
(vm_engine): Adapt for stack growth change.
* libguile/vm.c (vm_increase_sp, vm_push_sp, vm_restore_sp): Adapt to
stack representation change.
(scm_i_vm_cont_to_frame): Adapt to take offsets from the top.
(scm_i_vm_capture_stack): Adapt to capture from the top.
(vm_return_to_continuation_inner): Adapt for data type changes.
(vm_return_to_continuation): Likewise, and instead of looping, just
splat the saved arguments on with memcpy.
(vm_dispatch_hook): Adapt to receive arguments in the reverse order.
Adapt callers.
(vm_abort): There is never a tail argument. Adapt to stack
representation change.
(vm_reinstate_partial_continuation)
(vm_reinstate_partial_continuation_inner): Adapt to stack growth
change.
(allocate_stack, free_stack): Adapt to data type change.
(expand_stack): Don't try to mremap(), as you can't grow a mapping
from the bottom. Without knowing that there's a free mapping space
right below the old stack, which there usually isn't on Linux, we have
to copy. We can't use MAP_GROWSDOWN because Linux is buggy.
(make_vm): Adapt to stack representation changes.
(return_unused_stack_to_os): Round down instead of up, as the stack
grows down.
(scm_i_vm_mark_stack): Adapt to walk up the stack.
(scm_i_vm_free_stack): Adapt to scm_vm changes.
(vm_expand_stack_inner, reset_stack_limit, vm_expand_stack): Adapt to
the stack growing down.
(scm_call_n): Adapt to the stack growing down. Don't allow argv to
point into the stack.
* libguile/vm.h (struct scm_vm, struct scm_vm_cont): Adapt to hold the
stack top and bottom.
* libguile/strings.c (scm_from_utf8_stringn): Use 'u8_mbtoucr' and check
for a decoding error by its 'nbytes' return value. Previously we used
'u8_mbtouc' and improperly assumed that a U+FFFD character indicated a
decoding error.
* libguile/symbols.c (utf8_string_equals_wide_string): Likewise.
* test-suite/tests/bytevectors.test (exception:decoding-error): New
variable.
("2.9 Operations on Strings"): Add tests.
* libguile/vm-engine.c (RETURN_ONE_VALUE, RETURN_VALUE_LIST): These
helpers, used in subr-call and the like, might not actually have
enough space to push the return values. Use ALLOC_FRAME instead of
RESET_FRAME, for that reason.
* libguile/libguile-2.2-gdb.scm (vm-frame-function-name): Don't default
to the address, as we will have better identifying info via the file
name.
(vm-frame-source): New helper.
(compile-time-cond): For some reason "else" matching wasn't working;
punt and use expressions.
(snarfy-frame-decorator): Rename from decorator, and adapt to new
version of Guile frame filter patch.
(vm-frame-filter): Adapt to frame filter changes, and fill in source
info.
* libguile/arrays.c (scm_i_print_array): Print the dimension whenever
the array is a true scm_tc7_array.
* test-suite/tests/arrays.test: Check that non-vector 1D arrays print as
expected.
* libguile/libguile-2.2-gdb.scm (make-scm-pretty-printer-worker):
(%scm-pretty-printer): Refactor to avoid printing all struct / array
fields by hinting these as arrays. The resulting print is not as
faithful to the original data, but that's probably OK.
These features depend on a patch to GDB that has not been merged yet.
If GDB doesn't support the annotator/filter interface, the code have no
effect.
* libguile/libguile-2.2-gdb.scm (compile-time-cond): New helper.
(snarfy-frame-annotator): Simple annotator that gives subr names for
snarfed gsubrs.
(vm-frame-filter): New filter that interleaves Scheme frames with C
frames on the stack when the user asks for a backtrace.
* libguile/libguile-2.2-gdb.scm: Update to work with Guile 2.2 stacks.
Represent the VM stack as a SRFI-41 stream, which will work better
with the frame filter interface. Add support for getting the vm
frame's function name, if possible.
* libguile/goops.h (SCM_VTABLE_FLAG_GOOPS_STATIC): Reserve the fourth
GOOPS flag to indicate that a class has static slot allocation.
* libguile/goops.c (scm_init_goops_builtins): Define
vtable-flag-goops-static for goops.scm.
* module/oop/goops.scm (class-has-statically-allocated-slots?): New
helper.
(build-slots-list): Instead of the ad-hoc checks for <class> or
<slot>, use the new helper.
(initialize): Accept #:static-slot-allocation? keyword.
* module/system/foreign-object.scm (make-foreign-object-type): Declare
foreign object classes as having static slot allocation.
* test-suite/tests/goops.test ("static slot allocation"): Add tests.
* libguile/goops.h (SCM_VTABLE_FLAG_GOOPS_SLOT): Allocate another vtable
flag to indicate that instances of this vtable are slots.
* libguile/goops.c (scm_init_goops_builtins): Export
vtable-flag-goops-slot to Scheme.
* module/oop/goops.scm (<slot>, slot?, make-standard-class, initialize):
Arrange for <slot> classes to have the vtable-flag-goops.slot.
(build-slots-list): Ensure that <slot> slots are statically laid out.
* module/oop/goops.scm (fold-class-slots): Change format to use proper
slot specifications.
(fold-slot-slots): Flesh out with all needed slots.
(<class>): Update cons-layout to deal with new fold-class-slots form.
Don't create slots; we do that later.
(is-a?, get-keyword, *unbound, unbound?, %allocate-instance): Move
definitions up.
(<slot>, slot?): New definitions.
(slot-definition-name, slot-definition-allocation)
(slot-definition-init-keyword, slot-definition-init-form)
(slot-definition-init-value, slot-definition-init-thunk)
(slot-definition-options, slot-definition-getter)
(slot-definition-setter, slot-definition-accessor)
(slot-definition-slot-ref, slot-definition-slot-set!)
(slot-definition-index, slot-definition-size): New definitions as
accessors on <slot> objects.
(class-slot-definition): Adapt to class-slots change.
(direct-slot-definition-class, make-slot): New definitions.
(make): Define a boot version that can allocate <slot> instances.
(compute-direct-slot-definition)
(compute-direct-slot-definition-initargs)
(effective-slot-definition-class, compute-effective-slot-definition):
New definitions.
(build-slots-list): Adapt to slots being <slot> objects.
(compute-get-n-set): New boot definition.
(allocate-slots): New definition. Replaces
compute-getters-n-setters.
(%compute-layout, %prep-layout): Adapt to changes.
(make-standard-class): Make <slot> objects for direct-slots, and
handle the allocate-slots protocol.
(<foreign-slot>): Inherit from <slot>.
(get-slot-value-using-name, set-slot-value-using-name!)
(test-slot-existence): Adapt to using slot definition objects.
(make-class): Allow slot specs or <slot> objects as the `slots'
argument.
(write): New method on <slot>.
(class-slot-ref, class-slot-set!): Reimplement.
(compute-slot-accessors, compute-getter-method)
(compute-setter-method): Adapt to changes.
(compute-getters-n-setters): Remove. Yay!
(compute-get-n-set): Adapt to use effective slot definitions instead
of the getters-n-setters for #:class / #:each-subclass allocation.
(%initialize-object): Adapt.
(initialize): New method for <slot>. Adapt method for <class>.
* module/oop/goops/active-slot.scm (compute-get-n-set):
* module/oop/goops/composite-slot.scm (compute-propagated-get-n-set):
Use slot-definition-options to access options of slot.
* test-suite/tests/goops.test ("bad init-thunk"): Fix to be a "pass-if"
instead of an "expect-fail".
* libguile/goops.c (SCM_GOOPS_UNBOUND, SCM_GOOPS_UNBOUNDP): Remove
internal macros.
(scm_make_unbound, scm_unbound_p): Remove internal functions.
(scm_sys_clear_fields_x): Add "unbound" parameter, for the init
value.
* module/oop/goops.scm (*unbound*): Define in Scheme as a simple
heap-allocated value.
(unbound?): New definition.
(%allocate-instance): Pass *unbound* to %clear-fields!.
(make-class, slot-definition-init-value)
(slot-definition-init-form, make-closure-variable): Use *unbound*
instead of (make-unbound), which is now gone.
* module/oop/goops/active-slot.scm (compute-get-n-set): Use *unbound*
instead of make-unbound. This module uses the GOOPS internals module;
perhaps we should export make-unbound or something...
* module/oop/goops/save.scm (make-unbound): Export our own make-unbound
definition, for use by residualized save code.
* module/language/ecmascript/base.scm (<undefined>, *undefined*): Use a
unique object kind and instance for the undefined value.
* libguile/vm.c (scm_i_vm_mark_stack): Fill the stack with
SCM_UNSPECIFIED instead of SCM_UNBOUND.
* 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.
* 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.
* libguile/goops.c (scm_class_of): Access "redefined" slot by name in
the case where we need to change the class of an instance.
(scm_sys_goops_early_init): Move up capture of class-precedence-list
so SCM_SUBCLASSP can use it.
* libguile/goops.h (SCM_CLASS_CLASS_LAYOUT, scm_si_redefined)
(scm_si_direct_supers, scm_si_direct_slots, scm_si_direct_subclasses)
(scm_si_direct_methods, scm_si_cpl scm_si_slots)
(scm_si_getters_n_setters, SCM_N_CLASS_SLOTS, SCM_OBJ_CLASS_REDEF):
Remove. Now C code has no special knowledge about the layout of
GOOPS classes.
(SCM_SUBCLASSP): Use scm_class_precedence_list to get CPL.
(SCM_INST, SCM_ACCESSORS_OF): Remove unused macros that were
undocumented and nonsensical.
* 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.
* libguile/goops.h (scm_c_extend_primitive_generic): Remove public
interface. This was introduced in 2003 with the "extended" generics
but never documented, unused as far as I can tell, and is better
accessed from Scheme.
* libguile/goops.c: Remove support for scm_c_extend_primitive_generic.
Simplify capture of change-class.
* libguile/goops.c: Remove unused #includes.
(make_class_name): New helper, replaces unsafe use of sprintf.
(scm_make_extended_class): Rewrite to call scm_make_standard_class
directly.
(scm_make_port_classes): Rewrite to use scm_make_standard_class, and
no need to patch the CPL any more.
* 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>.