* module/oop/goops/dispatch.scm: Add a dispatch protocol in Scheme. The
idea is that instead of using a hardcoded C protocol, we compile
dispatch procedures at runtime. To avoid too much thrashing at bootup,
there is a simple JIT mechanism -- dispatch will be data-driven,
through the cache, for the first 5 invocations, then a dispatch
procedure will be compiled from the cache.
My initial timings indicate that interpreted dispatch takes about
100us, and that compiled dispatch takes about 60us. Compilation itself
takes about 16000us (16 ms). The compiled procedure dispatch times
will improve soon, hopefully.
* libguile/eq.c (scm_eqv_p): Not a generic any more. Since eqv? is used
by e.g. `case', which should be able to compile into dispatch tables,
it really doesn't make sense to dispatch out to a generic.
(scm_equal_p): So it was always the case that (equal? 'foo "foo") =>
#f. But (equal? 'foo 'bar) could actually be extended by a generic.
This was a bug, if you follow the other logic of the code. Changed so
that generic functions can only extend the domain of equal? when
operating on goops objects.
* oop/goops.scm: No more eqv? generic.
* test-suite/tests/goops.test: Remove eqv? tests.
* libguile/goops.h (scm_si_dispatch_procedure)
(scm_si_effective_methods): Rename the new generics slots to
"effective-methods" and "dispatch-procedure".
(scm_si_generic_setter): Rename this one from "%setter" to "setter",
and it's not a cache -- it's a pointer to the setter, which is also a
generic. I didn't realize that before. It's better this way (like it
always was.)
(SCM_SET_GENERIC_DISPATCH_PROCEDURE)
(SCM_CLEAR_GENERIC_EFFECTIVE_METHODS): New helper macros.
* libguile/goops.c (clear_method_cache): Clear the new dispatch
procedure and the effective methods as well.
(create_standard_classes): Rename slots, and fix the setter slots.
* module/oop/goops/dispatch.scm (memoize-method!): If we don't have a
no-applicable-method, just call no-applicable-method directly.
* test-suite/tests/goops.test ("no-applicable-method"): Add some tests.
* libguile/goops.c (scm_sys_invalidate_method_cache_x, scm_make)
(create_standard_classes): Remove code-table slot from methods. The
generic cache completely does its job, afaict.
* libguile/goops.h (scm_si_formals, scm_si_body, scm_si_make_procedure):
Renumber slots.
* module/oop/goops.scm (initialize on <method>): No more code-table
slot.
* module/oop/goops/compile.scm: Always "compile" a method, instead of
looking for a hit in an always-empty cache.
* libguile/goops.c (clear_method_cache)
(scm_sys_invalidate_method_cache_x, scm_make)
(create_standard_classes): Remove the used-by method from generics, as
it is not used at all.
* libguile/goops.h: Renumber generic slots.
* module/oop/goops/dispatch.scm (memoize-method!): No more used-by slot.
* libguile/goops.c (create_standard_classes):
* libguile/goops.h *scm_si_applicable_methods, scm_si_effective_method)
(scm_si_applicable_setter_methods, scm_si_effective_setter_method):
Add space for the new form of the generic cache and effective method.
I tried to split this one, and I know it's a bit disruptive, but this
stuff really is one big cobweb. So instead we'll pretend like these are
separate commits, by separating the changelog.
Applicable struct runtime support.
* libguile/debug.c (scm_procedure_source):
* libguile/eval.c (scm_trampoline_0, scm_trampoline_1)
(scm_trampoline_2):
* libguile/eval.i.c (CEVAL):
* libguile/goops.c (scm_class_of):
* libguile/procprop.c (scm_i_procedure_arity):
* libguile/procs.c (scm_procedure_p, scm_procedure, scm_setter): Allow
for applicable structs. Whee!
* libguile/deprecated.h (scm_vtable_index_vtable): Define as a synonym
for scm_vtable_index_self.
(scm_vtable_index_printer): Alias scm_vtable_index_instance_printer.
(scm_struct_i_free): Alias scm_vtable_index_instance_finalize.
(scm_struct_i_flags): Alias scm_vtable_index_flags.
(SCM_STRUCTF_FLAGS): Be a -1 mask, we have a whole word now.
(SCM_SET_VTABLE_DESTRUCTOR): Implement by hand.
Hidden slots.
* libguile/struct.c (scm_make_struct_layout): Add support for "hidden"
fields, writable fields that are not visible to make-struct. This
allows us to add fields to vtables and not break existing make-struct
invocations.
(scm_struct_ref, scm_struct_set_x): Always get struct length from the
vtable. Support hidden fields.
* libguile/goops.c (scm_class_hidden, scm_class_protected_hidden): New
slot classes, to correspond to the new vtable slots.
(scm_sys_prep_layout_x): Turn hidden slots into 'h'.
(build_class_class_slots): Reorder the class slots to account for
vtable fields coming out of negative-land, for name as a vtable slot,
and for hidden fields.
(create_standard_classes): Define <hidden-slot> and
<protected-hidden-slot>.
Clean up struct.h.
* libguile/struct.h: Lay things out cleaner. There are no more hidden
(negative) words. Names are nicer. The exposition is nicer. But the
basics are the same. The incompatibilities are that <vtable> has more
slots now, and that scm_alloc_struct's signature has changed. The
former is ameliorated by the "hidden" slots mentioned before, and the
latter, well, it was always a very internal thing...
(scm_t_struct_finalize): New type, a finalizer function to be run when
instances of a vtable are collected.
(scm_t_struct_free): Removed, structs' data is managed by the GC now,
and not freed by vtable functions.
* libguile/struct.c: (scm_vtable_p): Now we keep flags on
vtable-vtables, so this check is cheaper.
(scm_alloc_struct): No hidden words. Yippee.
(struct_finalizer_trampoline): Entersify.
(scm_make_struct): No need to babysit extra words, though now we have
to babysit flags. Propagate the vtable, applicable, and setter flags
appropriately.
(scm_make_vtable_vtable): Update for new simplicity.
(scm_print_struct): A better printer.
(scm_init_struct): Define <applicable-struct-vtable>, a magical vtable
like CL's funcallable-standard-class. Also define
<applicable-struct-with-setter-vtable>.
Remove foreign object implementation.
* libguile/goops.h:
* libguile/goops.c (scm_make_foreign_object, scm_make_class)
(scm_add_slot, scm_wrap_object, scm_wrap_component): Remove, these
were undocumented and unworking.
Clean up goops.h, a little.
* libguile/goops.h:
* libguile/goops.c: Also clean up.
* module/oop/goops/dispatch.scm (hashset-index): Adapt for new hashset
index.
* acinclude.m4, configure.ac, examples/compat/acinclude.m4: Properly
quote the first argument for `AC_DEFINE' and `AC_DEFINE_UNQUOTED'.
* .x-sc_m4_quote_check: New file.
* configure.ac: Check for `intptr_t' and `uintptr_t'. Substitute
`SCM_I_GSC_T_INTPTR' and `SCM_I_GSC_T_UINPTR'.
* libguile/__scm.h (SCM_T_UINTPTR_MAX, SCM_T_INTPTR_MIN,
SCM_T_INTPTR_MAX): New macros.
* libguile/_scm.h (SIZEOF_SCM_T_BITS): New macro.
* libguile/gen-scmconfig.c (main): Produce typedefs for `scm_t_intptr'
and `scm_t_uintptr'.
* libguile/gen-scmconfig.h.in (SCM_I_GSC_T_INTPTR, SCM_I_GSC_T_UINPTR):
New macros.
* libguile/tags.h: Don't check for `HAVE_INTTYPES_H' and
`HAVE_STDINT_H'; don't include <inttypes.h> nor <stdint.h>.
(scm_t_signed_bits, scm_t_bits): Define unconditionally as aliases for
`scm_t_intptr' and `scm_t_uintptr', respectively.
(SCM_T_SIGNED_BITS_MAX, SCM_T_SIGNED_BITS_MIN, SCM_T_BITS_MAX):
Likewise.
(SIZEOF_SCM_T_BITS): Remove.
* configure.ac: For `--without-threads' and `--with-threads=null', set
`SCM_I_GSC_HAVE_THREAD_STORAGE_CLASS=0'. This fixes compilation of
`gen-scmconfig.c' in these cases.
* libguile/i18n.c (scm_make_locale): Simplify global locale handling,
using duplocale(3) for all kinds of locales.
(scm_init_i18n): Comment on why we don't just use `LC_GLOBAL_LOCALE'
for `global_locale_smob'.
* m4/gnulib-cache.m4: Add `duplocale'.
* doc/ref/api-evaluation.texi (Character Encoding of Source Files):
Don't suggest `latin1' as a good encoding name since Emacs cannot deal
with it.
* libguile/read.c (scm_file_encoding): Fix "Emacs" spelling.
* test-suite/tests/socket.test (%tmpdir, %curdir): New variables.
Chdir to %TMPDIR. Switch back to %CURDIR at the end.
(temp-file-path): Return a base file name, not an absolute path.
This obviates the need for the previous commit,
53da7372be.
* GUILE-VERSION (VERSION, PACKAGE): Remove. The latter was conflicting
with Automake's definition, which is "guile", not "GNU Guile".
* Makefile.am (distdir): Remove.
* configure.ac: Hardcode the package name passed to `AC_INIT'.
(pkgdatadir, pkgincludedir, pkglibdir, pkglibexecdir): Remove.
This fixes a regression introduced in
4f02b98d0e ("Use Gnulib's
`version-etc-fsf' for `--version' and `--help' output."), which led
$(pkgdatadir) & co. to contain the string "GNU Guile" instead of
"guile".
* configure.ac (pkgdatadir, pkgincludedir, pkglibdir, pkglibexecdir):
New variables.
The intent is to allow compilation with `-Wundef', which in turn should
make it easier to catch erroneous uses of nonexistent macros.
* libguile/__scm.h: Don't assume `BUILDING_LIBGUILE' is defined.
* libguile/conv-uinteger.i.c (SCM_TO_TYPE_PROTO): Remove unneeded CPP
conditional on `TYPE_MIN == 0'.
* libguile/fports.c: Check for the definition of `HAVE_CHSIZE' and
`HAVE_FTRUNCATE', not for their value.
* libguile/ports.c: Likewise.
* libguile/numbers.c (guile_ieee_init): Likewise with `HAVE_DINFINITY'
and `HAVE_DQNAN'.
* test-suite/standalone/test-conversion.c (ieee_init): Likewise.
* libguile/strings.c: Likewise with `SCM_STRING_LENGTH_HISTOGRAM'.
* libguile/strings.h: Likewise.
* libguile/tags.h: Likewise with `HAVE_INTTYPES_H' and `HAVE_STDINT_H'.
* libguile/threads.c: Likewise with `HAVE_PTHREAD_GET_STACKADDR_NP'.
* libguile/vm-engine.c (VM_NAME): Likewise with `VM_CHECK_IP'.
* libguile/gen-scmconfig.c (main): Use "#ifdef HAVE_", not "#if HAVE_".
* libguile/socket.c (scm_setsockopt): Likewise.
* libguile/guardians.c (guardian_apply): Remove `#if ENABLE_DEPRECATED'
section since it was never compiled in, not even in 1.8.
(scm_init_guardians): Likewise.
* libguile/vm-i-system.c (br-if-nargs-gt): Fix variable declaration
placement.
(bind-kwargs): Patch mostly by Ludovic: it seems that in the mode in
which we have rest args, the keywords can appear anywhere. Bummer.
Change to allow for this.
* module/ice-9/optargs.scm (parse-lambda-case): Same, add a
permissive-keys clause that handles the case in which there's a rest
argument.
lists in method cache matching.
* libguile/goops.c (scm_mcache_lookup_cmethod): Don't apply SCM_CAR to
non-pairs when walking argument lists in method cache matching.
Don't check for CLASSP or symbol in the car slot, since the end of
the specifier list is a non-pair. Update comments to reflect new
structure of method cache entry.
* module/oops/goops/dispatch.scm: Update comments here too.