* libguile/root.h:
* libguile/root.c: Remove these files.
* libguile/deprecated.h:
* libguile/deprecated.c (scm_internal_cwdr, scm_call_with_dynamic_root)
(scm_dynamic_root, scm_apply_with_dynamic_root): Deprecate.
Remove all root.h usage, which was vestigial.
* module/ice-9/serialize.scm: Use (current-thread) instead
of (dynamic-root).
* libguile/hashtab.c (scm_hash_count): New function. Count the number
of elements in a hash table.
* doc/ref/api-compound.texi (Hash Tables): Update examples and
reference.
* test-suite/tests/hash.test (hash-count): New test.
* libguile/weak-table.h:
* libguile/weak-table.c (scm_weak_table_putq_x)
(scm_weak_table_remq_x, scm_weak_table_clear_x)
(scm_weak_table_for_each): Declare these as returning void instead of
SCM.
* libguile/hashtab.c (scm_hashq_set_x, scm_hashq_remove_x)
(scm_hashv_set_x, scm_hashv_remove_x)
(scm_hash_set_x, scm_hash_remove_x)
(scm_hashx_set_x, scm_hashx_remove_x):
(scm_hash_for_each): For weak tables, have the set! functions return
the values, as they used to do. Have remove! functions return #f,
indicating the lack of a handle. Shim around for-each to return
unspecified, even though that wasn't yet a problem.
* test-suite/tests/weaks.test: Add a test.
* libguile/hashtab.c (scm_i_hashtable_print): Use `SCM_UNPACK', not
`SCM2PTR'.
* test-suite/tests/hash.test: Adjust tests that rely on the output of
the printer to just check for the suffix of the hash table's external
representation.
* libguile/ports.c (scm_putc, scm_puts):
* libguile/ports.h (scm_putc_unlocked, scm_puts_unlocked): Separate into
_unlocked and locked variants. Change all callers to use the
_unlocked versions.
* libguile/tags.h (SCM_UNPACK_POINTER, SCM_PACK_POINTER): New macros.
The old SCM2PTR and PTR2SCM were defined in such a way that
round-tripping through a pointer could lose precision, even in the
case in which you weren't interested in actually dereferencing the
pointer, it was simply that you needed to plumb a SCM through APIs
that take pointers. These new macros are more like SCM_PACK and
SCM_UNPACK, but for pointer types. The bit representation of the
pointer should be the same as the scm_t_bits representation.
* libguile/gc.h (PTR2SCM, SCM2PTR): Remove support for (old) UNICOS
pointers. We are going to try tagging the SCM object itself in the
future, and I don't think that keeping this support is worth its
cost. It probably doesn't work anyway.
* libguile/backtrace.c:
* libguile/bytevectors.c:
* libguile/continuations.c:
* libguile/fluids.c:
* libguile/foreign.c:
* libguile/gc.h:
* libguile/guardians.c:
* libguile/hashtab.c:
* libguile/load.c:
* libguile/numbers.c:
* libguile/ports.c:
* libguile/smob.c:
* libguile/strings.c:
* libguile/symbols.c:
* libguile/vm.c:
* libguile/weak-set.c:
* libguile/weak-table.c:
* libguile/weak-vector.c: Update many sites to use the new macros.
* libguile/hashtab.c:
* libguile/hashtab.h: Reimplement the weak hash table implementation in
terms of weak tables. All is well except for the horrific hack for
hashx tables.
* libguile/weak-table.h:
* libguile/weak-table.c (scm_make_weak_key_hash_table)
(scm_make_weak_value_hash_table, scm_make_doubly_weak_hash_table)
(scm_weak_key_hash_table_p, scm_weak_value_hash_table_p)
(scm_doubly_weak_hash_table_p): Move these definitions here.
* test-suite/tests/weaks.test: Add tests.
* libguile/hashtab.c (scm_hash_fn_set_x): Fix updates to weak-value hash
tables to not deadlock inside the alloc lock.
* libguile/hashtab.c (scm_internal_hash_fold): Don't try to unlink
deleted weak pairs. Our previous code was buggy (`prev' should have
only been updated in the case of a successful traversal), but more
than that, we're not in the alloc lock.
Thanks very much to Michael Wells for the report, and the debugging!
* libguile/hashtab.c (set_weak_cdr):
* libguile/vectors.c (scm_c_vector_set_x):
* libguile/weaks.c (scm_weak_car_pair, scm_weak_cdr_pair):
(scm_doubly_weak_pair): Use SCM2PTR for the target of
SCM_I_REGISTER_DISAPPEARING_LINK calls.
* libguile/hashtab.c (scm_hashq_get_handle, scm_hashq_create_handle_x)
(scm_hashv_get_handle, scm_hashv_create_handle_x)
(scm_hash_get_handle, scm_hash_create_handle_x)
(scm_hashx_get_handle, scm_hashx_create_handle_x): Don't allow these
functions to be called on weak hash tables, as we have no idea when
the GC will null out fields of the handle, and set-cdr! won't register
disappearing links, and set-car! would never work of course.
* libguile/hashtab.c (set_weak_cdr, scm_hash_fn_set_x): If we have a
weak-value hash table with a previous non-immediate value for a given
key, and we are setting an immediate as the new value, we were not
unregistering the disappearing link. Fixed.
* configure.ac: Add a check for GC_set_start_callback.
* libguile/gc.c (scm_i_gc): If we don't have GC_set_start_callback, run
the before-gc hook manually here.
(scm_init_gc): Otherwise set it as a start callback.
* libguile/hashtab.c (weak_gc_callback, weak_gc_hook)
(weak_gc_finalizer, scm_c_register_weak_gc_callback): Fix to work
either way, with or without GC_set_start_callback.
* libguile/hashtab.c (weak_gc_callback)
(scm_c_register_weak_gc_callback): Change implementation to use the
before-gc C hook instead of the after-gc finalizers.
* libguile/hashtab.c (scm_c_register_weak_gc_callback): New private
helper, arranges for a C function to be called with a SCM as an
argument, as long as the argument is reachable by GC.
(scm_make_weak_key_hash_table)
(scm_make_weak_value_hash_table)
(scm_make_doubly_weak_hash_table): Register a weak GC callback to
vacuum_weak_hash_table.
* libguile/hashtab.c (vacuum_weak_hash_table): New helper, goes through
the entirety of a weak hash table, vacuuming dead entries.
(scm_hash_fn_create_handle_x): If when adding to a weak hash table, we
would trigger a rehash, vacuum the table first. The weak_bucket_assoc
would have only caught dead entries within one bucket.
Without this patch, the following code leaks:
(let lp ()
(call-with-output-string
(lambda (port)
(display "foo" port)))
(lp))
* libguile/hashtab.c: Fix remaining vector hash table support.
* module/ice-9/session.scm (apropos-fold): Use a hash table instead of a
vector for the completions.
* libguile/hashtab.c (struct t_assoc_args, do_weak_bucket_assoc):
Remove.
(struct t_fixup_args): New type.
(do_weak_bucket_fixup): New function.
(weak_bucket_assoc): Use it. Keep strong references to BUCKET's
entries in STRONG_REFS. Call ASSOC once the alloc lock has been
released. This fixes bug #29616.
* test-suite/tests/weaks.test ("assoc can do anything"): New test.
* libguile/hashtab.c (scm_fixup_weak_alist): Keep the value of PREV
unchanged after a nullified pair is deleted; this fixes a bug whereby
if several successive nullified pairs were encountered, not all of them
would be removed, and the assertion in `weak_bucket_assoc' would be
hit. In addition, remove the `scm_is_pair (pair)' test.
* libguile/hashtab.c (scm_hash_fn_set_x): Register a disappearing link
to VAL when TABLE is weak-value.
* test-suite/tests/weaks.test ("weak-hash")["weak-key dies", "weak-value
dies", "doubly-weak dies"]: Use `hash-set!' and `hash-ref', not
`hashq-set!' and `hashq-ref', otherwise these tests would always
succeed because (eq? "this" "this") => #f.
["lives"]: Use `hash-ref' and `hash-set!' too for consistency.
* libguile/hashtab.c: Re-arrange functions to avoid the need for
pre-declaring character arrays with no length. Fixes compilation on
Compaq C V6.3-025. Thanks to Jay Krell for the report.
If you're wondering what I'm doing, I'm trying to eventually reimplement
smobs in terms of structs, so that applicable smobs can just follow the
applicable struct dispatch path. But to do that I have to get structs
initialized before things that use smobs, which means transforming a
bunch of smobby things to tc7 things. But this transformation is good
for performance anyway, and we currently have a glut of unused tc7s,
so here we go...
* libguile/tags.h (scm_tc7_fluid, scm_tc7_dynamic_state): Fluids (and
dynamic states) now have tc7s.
* libguile/fluids.h: Remove scm_fluids_prehistory, and add internal
scm_i_fluid_print. Update a comment.
* libguile/fluids.c: Update for tc7 representation. Also remove the next
pointers while we're at it, as they aren't used in the new BDW GC.
* libguile/eq.c (scm_equal_p): Remove the hashtable case. Hashtables
could never be equal? before, I don't see why to add stubs doing the
same thing now.
* libguile/print.c (iprin1):
* libguile/gc.c (scm_i_tag_name):
* libguile/evalext.c (scm_self_evaluating_p): Add fluid and
dynamic_state cases.
* libguile/goops.h: Remove scm_class_hashtable; it will be static.
* libguile/goops.c: Make <hashtable> static, and add <fluid> and
<dynamic-state> classes.
* libguile/hashtab.h:
* libguile/hashtab.c: Remove scm_i_hashtable_equal_p.
* libguile/init.c (scm_i_init_guile): Remove call to fluids_prehistory.
* libguile/tags.h (scm_tc7_hashtable): Allocate a tc7 for hashtables.
* libguile/hashtab.h: Adjust macros accordingly.
(scm_i_hashtable_print, scm_i_hashtable_equal_p): New internal
functions.
(scm_hashtab_prehistory): Remove, no more need for this.
* libguile/hashtab.c (scm_hash_fn_remove_x): Fix a longstanding bug.
(make_hash_table): Adapt to the new hash table representation.
* libguile/eq.c (scm_equal_p)
* libguile/evalext.c (scm_self_evaluating_p)
* libguile/print.c (iprin1)
* libguile/gc.c (scm_i_tag_name): Add some tc7_hashtab cases.
* libguile/init.c: Remove unused environments init functions. Remove
call to hashtab_prehistory.
* libguile/goops.h (scm_class_hashtable)
* libguile/goops.c (scm_class_of, create_standard_classes): Have to
make a class for hash tables manually, because they aren't smobs any
more.
* libguile/hashtab.h (scm_t_hash_fold_fn, scm_t_hash_handle_fn): New
types.
(scm_internal_hash_fold, scm_internal_hash_for_each_handle): Use them.
* libguile/hashtab.c (scm_internal_hash_fold): Take an
`scm_t_hash_fold_fn'. Update callers.
(scm_internal_hash_for_each_handle): Take an `scm_t_hash_handle_fn'.
Update callers.
This is a followup to d587c9e8b2 ("Use
proper types for hash/assoc functions in `hashtab.h'.").
* libguile/hashtab.c (scm_i_rehash, scm_hash_fn_create_handle_x,
scm_hash_fn_ref, scm_hash_fn_set_x, scm_hash_fn_remove_x): Use
`scm_t_hash_fn' and `scm_t_assoc_fn' as appropriate.
Partly fixes bug #23681 ("Function declarators with empty parentheses
should not be used").
* libguile/goops.c (scm_wrap_component): Cast `scm_sloppy_assq'.
* libguile/hashtab.c (scm_hash_fn_get_handle): Update to take functions
of type `scm_t_hash_fn' and `scm_t_assoc_fn'. Update callers.
(scm_ihashx): Change to match `scm_t_hash_fn'.
(scm_sloppy_assx): Change to match `scm_t_assoc_fn'.
* libguile/hashtab.h (scm_t_hash_fn, scm_t_assoc_fn): New types.
(scm_t_hashtable)[hash_fn]: Change to `scm_t_hash_fn'.
(scm_i_rehash, scm_hash_fn_get_handle, scm_hash_fn_create_handle_x,
scm_hash_fn_ref, scm_hash_fn_set_x, scm_hash_fn_remove_x): Change to
take `scm_t_hash_fn' and `scm_t_assoc_fn' parameters.
* libguile/srcprop.h (scm_whash_get_handle, scm_whash_create_handle,
scm_whash_lookup): Implement in terms of `scm_hashq_*' instead of
`scm_hash_fn_*'.
* libguile/struct.c (scm_struct_ihashq): Change to match
`scm_t_hash_fn'.
(scm_struct_create_handle): Cast `scm_sloppy_assq'.
* libguile/struct.h (scm_struct_ihashq): Update, make internal.