Entities were meant to be a form of applicable struct. Unfortunately,
the implementation is intertwingled with generics. Removing them, for
now, will make it possible to cleanly re-add applicable struct support.
* libguile/struct.h (SCM_STRUCTF_ENTITY): Remove.
(SCM_STRUCTF_GOOPS_HACK): New flag; sigh.
* libguile/struct.c (scm_make_struct): We make "entity" structs if the
GOOPS_HACK flag is set. This will be fixed when we rework flags and
remove hidden words.
* libguile/goops.c (scm_class_of): Structs are not applicable, for now
at least.
(scm_sys_inherit_magic_x, scm_basic_basic_make_class)
(scm_sys_allocate_instance, scm_sys_set_object_setter_x):
(make_struct_class): Adapt for no more entities (and thus no entity
flag).
(create_standard_classes): For some reason, generic functions were
getting the LIGHT flag set, after the ENTITY flag was removed; so for
now explicitly clear that flag.
* libguile/goops.h (SCM_GENERIC_SETTER, SCM_SET_GENERIC_SETTER): New
macros.
* libguile/objects.h:
* libguile/objects.c: Remove code for entities.
* libguile/debug.c: (scm_procedure_source): Only work with generics.
* libguile/eval.c (scm_trampoline_0, scm_trampoline_1)
(scm_trampoline_2): Only handle generics.
* libguile/eval.i.c (CEVAL): #ifdef out the pieces about entities.
* libguile/procprop.c (scm_i_procedure_arity): Remove support for
entities.
* libguile/procs.c (scm_procedure_p, scm_procedure, scm_setter): Remove
entity support.
* libguile/goops.h (SCM_GENERIC_METHOD_CACHE)
(SCM_SET_GENERIC_METHOD_CACHE): Two new macros; the same as
SCM_[SET_]ENTITY_PROCEDURE, but more reflecting the reality of the
generic hack.
* libguile/eval.i.c:
* libguile/goops.c:
* libguile/objects.c:
* libguile/vm-i-system.c: Use the new macros when it is appropriate to
do so.
* Renumbers the IFLAG constants.
* Adds several macros related to boolean type tests, null tests, and
boolean-truth testing (including lisp-style boolean-truth tests).
* Adds compile-time checks to verify the necessary IFLAG numbering
properties needed for the checks to work properly.
* Changes some existing code to use the new optimized macros, without
changing the semantics of the code at all (except that scm_is_bool
is changed from a function to a macro).
I added the following macros, whose names explicitly state how %nil
should be handled. See the comments in the patch for more information
about these.
scm_is_false_assume_not_lisp_nil scm_is_true_assume_not_lisp_nil
scm_is_false_and_not_lisp_nil scm_is_true_or_lisp_nil
scm_is_false_or_lisp_nil scm_is_true_and_not_lisp_nil
scm_is_lisp_false scm_is_lisp_true
scm_is_null_assume_not_lisp_nil
scm_is_null_and_not_lisp_nil
scm_is_null_or_lisp_nil
scm_is_bool_and_not_lisp_nil
scm_is_bool_or_lisp_nil
The following already-existing macros are defined as aliases, such
that their semantics is unchanged (although scm_is_bool used to be a
function and is now a macro).
scm_is_null --> scm_is_null_and_not_lisp_nil
scm_is_false --> scm_is_false_and_not_lisp_nil
scm_is_true --> scm_is_true_or_lisp_nil
scm_is_bool --> scm_is_bool_and_not_lisp_nil
(I still believe that these should be changed to versions that handle
%nil properly, but await approval on that point, so these patches do
not make those changes)
Also, if the preprocessor macro SCM_ENABLE_ELISP is not true (this
macro already existed and was used in lang.h), all overheads
associated with %nil handling are eliminated from the above macros.
* libguile/tags.h (SCM_BOOL_F, SCM_BOOL_T, SCM_UNSPECIFIED)
(SCM_UNDEFINED, SCM_UNBOUND, SCM_ELISP_NIL): Renumber, so that a
number of important distinctions (false versus true, end-of-list, etc)
can be made by masking a single bit. Also define a number of
build-time tests to assert that this condition holds.
* libguile/boolean.h (scm_is_false_and_not_nil, scm_is_true_or_nil)
(scm_is_false_assume_not_nil, scm_is_true_assume_not_nil):
(scm_is_false_or_nil, scm_is_true_and_not_nil)
(scm_is_bool_or_nil, scm_is_bool_and_not_nil): New exciting macros to
test certain boolean/end-of-list properties.
(scm_is_false, scm_is_true): Use a restrictive definition, where only
SCM_BOOL_F is false. Should probably change in the future.
(scm_is_bool): Incompatible change: changed to be a macro. Was a
function before. Probably should allow nil as a boolean, but that will
be for a later patch.
(scm_is_lisp_false, scm_is_lisp_true): New macros, implementing the
standard Lisp boolean predicates, where '() is actually false.
* libguile/eval.i.c (CEVAL): Fix a number of false-or-nil and similar
tests to use the new macros.
* libguile/lang.h (SCM_NULL_OR_NIL_P): Use scm_is_null_or_nil.
* libguile/pairs.c: Add a compile-time check that null and nil differ by
only one bit.
* libguile/pairs.h (scm_is_null_and_not_nil, scm_is_null_assume_not_nil)
(scm_is_null_or_nil): New exciting macros!
(scm_is_null): Just be scm_is_null_and_not_nil, for now.
* libguile/print.c: Adapt to the reordering, and print suitably nasty
things for the not-to-be-used values.
This fixes a bug introduced in e20d7001c3
and reported by Neil.
* libguile/eval.i.c (CEVAL)[DEVAL]: Don't duplicate ARG1 in
`debug.info->a.args' for gsubr stack frames.
(scm_apply): Likewise.
* test-suite/tests/eval.test ("stacks")["arguments of a gsubr stack
frame"]: New test.
The symbol's characters are only accessed in case they are needed
for an error message. This can be avoided by passing the symbol
all the way to a error message function.
* libguile/__scm.h (SCM_WTA_DISPATCH_1_SUBR): new macro
* libguile/error.c (scm_i_wrong_type_arg_symbol): new error function
* libguile/error.h: declaration of scm_i_wrong_type_arg_symbol
* libguile/eval.c (call_dsubr_1): use new macro SCM_WTA_DISPATCH_1_SUBR
to avoid having to unpack the symbol's chars
* libguile/eval.i.c: use new macro SCM_WTA_DISPATCH_1_SUBR
* libguile/tags.h (scm_tc7_program):
* libguile/programs.h: Programs now have their own tc7 code. Fix up the
macros appropriately.
* libguile/programs.c: Remove smobby bits, leaving marking, printing,
and application for other parts of Guile.
* libguile/debug.c (scm_procedure_source):
* libguile/eval.c (scm_trampoline_0, scm_trampoline_1)
(scm_trampoline_2): Add cases for tc7_program.
* libguile/eval.i.c (CEVAL, SCM_APPLY):
* libguile/evalext.c (scm_self_evaluating_p):
* libguile/gc-card.c (scm_i_sweep_card, scm_i_tag_name):
* libguile/gc-mark.c (1):
* libguile/print.c (iprin1):
* libguile/procs.c (scm_procedure_p, scm_thunk_p)
* libguile/vm-i-system.c (make-closure): Adapt to new procedure
representation.
* libguile/procprop.c (scm_i_procedure_arity): Do the right thing for
programs.
* test-suite/tests/procprop.test ("procedure-arity"): Arity test now
succeeds.
* libguile/goops.c (scm_class_of): Programs now belong to the class
<procedure>, not a smob class.
* libguile/vm.h (struct vm, struct vm_cont):
* libguile/vm-engine.c (vm_engine):
* libguile/frames.h (SCM_FRAME_BYTE_CAST, struct vm_frame):
* libguile/frames.c (scm_c_make_vm_frame): Fix usages of scm_byte_t,
changing them to scm_t_uint8.
* libguile/eval.i.c (CEVAL): Update calls to `scm_i_gsubr_apply ()' with
a fixed number of arguments. Use `scm_i_gsubr_apply_list ()' for
calls with a list of arguments of unknown length.
(SCM_APPLY): Use `scm_i_gsubr_apply_list ()' instead of
`scm_i_gsubr_apply ()'.
* libguile/gsubr.c (gsubr_apply_raw): New.
(scm_i_gsubr_apply): Change to take a C vararg list instead of a
Scheme list. Use `gsubr_apply_raw ()'.
(scm_i_gsubr_apply_list): Use `gsubr_apply_raw ()'.
* libguile/gsubr.h (scm_i_gsubr_apply): Update prototype.
(scm_i_gsubr_apply_list): New declaration.
The idea is to introduce `gsubrs' whose arity is encoded in their type
(more precisely in the sizeof (void *) - 8 MSBs). This removes the
indirection introduced by cclos and simplifies the code.
* libguile/__scm.h (CCLO): Remove.
* libguile/debug.c (scm_procedure_source, scm_procedure_environment):
Remove references to `scm_tc7_cclo'.
* libguile/eval.c (scm_trampoline_0, scm_trampoline_1,
scm_trampoline_2): Replace `scm_tc7_cclo' with `scm_tc7_gsubr'.
* libguile/eval.i.c (CEVAL): Likewise. No longer make PROC the first
argument. Directly invoke `scm_gsubr_apply ()' instead of jump to the
`evap(N+1)' label or call to `SCM_APPLY ()'.
* libguile/evalext.c (scm_self_evaluating_p): Remove reference to
`scm_tc7_cclo'.
* libguile/gc-card.c (scm_i_sweep_card, scm_i_tag_name): Likewise.
* libguile/gc-mark.c (scm_gc_mark_dependencies): Likewise.
* libguile/goops.c (scm_class_of): Likewise.
* libguile/print.c (iprin1): Likewise.
* libguile/gsubr.c (create_gsubr): Use `unsigned int's for REQ, OPT and
RST. Use `scm_tc7_gsubr' instead of `scm_makcclo ()' in the default
case.
(scm_gsubr_apply): Remove calls to `SCM_GSUBR_PROC ()'.
(scm_f_gsubr_apply): Remove.
* libguile/gsubr.h (SCM_GSUBR_TYPE): New definition.
(SCM_GSUBR_MAX): Changed to 33.
(SCM_SET_GSUBR_TYPE, SCM_GSUBR_PROC, SCM_SET_GSUBR_PROC,
scm_f_gsubr_apply): Remove.
* libguile/procprop.c (scm_i_procedure_arity): Remove reference to
`scm_tc7_cclo'; add proper handling of `scm_tc7_gsubr'.
* libguile/procs.c (scm_makcclo, scm_make_cclo): Remove.
(scm_procedure_p): Remove reference to `scm_tc7_cclo'.
(scm_thunk_p): Likewise, plus add proper `scm_tc7_gsubr' handling.
* libguile/procs.h (SCM_CCLO_LENGTH, SCM_MAKE_CCLO_TAG,
SCM_SET_CCLO_LENGTH, SCM_CCLO_BASE, SCM_SET_CCLO_BASE, SCM_CCLO_REF,
SCM_CCLO_SET, SCM_CCLO_SUBR, SCM_SET_CCLO_SUBR, scm_makcclo,
scm_make_cclo): Remove.
* libguile/stacks.c (read_frames): Remove reference to `scm_f_gsubr_apply'.
* libguile/tags.h (scm_tc7_cclo): Remove.
(scm_tc7_gsubr): New.
(scm_tcs_subrs): Add `scm_tc7_gsubr'.
* libguile/gsubr.c (scm_gsubr_apply): Make SELF the first argument
instead of the first element of ARGS.
* libguile/gsubr.h: Update.
* libguile/eval.i.c (CEVAL): Update.
* libguile/eval.i.c (type_dispatch, apply_vm_cmethod)
(apply_memoized_cmethod): Tweak the nastiness a bit more so as to deal
with the '(no-method) empty entries. I would like to stop the search if
the cdr isn't a pair, but currently with the inlined memoized bits, the
cdr is a pair. The fix would be to make the memoizer return a procedure
and not the already-inlined bits -- slightly slower but the vm will be
faster anyway.
* libguile/objects.c (scm_mcache_lookup_cmethod): Same fixes here.
* oop/goops/dispatch.scm (cache-hashval, cache-try-hash!): Allow non-list
cmethod tails.
* ice-9/boot-9.scm (make-modules-in): Change to make sure that we are
making modules in modules; that is, that a global binding of `compile'
doesn't prevent a module from importing a submodule named `compile'.
(resolve-module): Clean up a bit, and serialize the logic.
* libguile/objects.c (scm_mcache_lookup_cmethod, scm_apply_generic):
* libguile/eval.i.c (CEVAL): Now that cmethod entries can have a program
as their tail instead of a memoized proc, we have to change the halting
condition on the method cache search, in both places: the one that's
inlined into eval.i.c and the one in objects.c. If the cmethod isn't a
pair, apply it.
* libguile/goops.c (make): In the `make' procedure that's used before
GOOPS is booted, bind #:formals, #:body, and #:compile-env on methods.
* oop/goops/compile.scm (compute-entry-with-cmethod): There was a
terrible trick here that involved putting a dummy pair in the cache,
then modifying it in place with the result of memoization. The note
claimed that this was to cut recursion short, or something. I can't see
how it could recurse, given that `methods' is changing each time. Also,
the pair trick doesn't work with byte-compiled methods. So, remove it.
(compile-method): Dispatch to the appropriate method compiler, based on
whether the method was defined with the interpreter or with the
compiler.
(make-next-method): New function, generically computes a `next-method'
procedure, though the caller has to supply the arguments.
(compile-method/vm): Exciting method byte compiler!
(make-make-next-method/memoizer, compile-method/memoizer): Add the
/memoizer suffix, and move all this code to the bottom of the file.
* libguile/eval.h:
* libguile/eval.c (scm_make_promise): Rename from `scm_makprom', and
export as the scheme procedure, `make-promise'.
* libguile/eval.i.c (CEVAL): s/makprom/make_promise/.