* module/language/tree-il.scm (tree-il-src): Always a vector now;
tree-il-srcv is gone. An incompatible change but we are in the
compiler.
(location): For parse-tree-il, make vector locations instead of alists.
* module/language/tree-il/analyze.scm:
* module/language/tree-il/compile-bytecode.scm:
* module/language/tree-il/compile-cps.scm:
* module/language/tree-il/debug.scm:
* module/language/tree-il/letrectify.scm:
* module/language/tree-il/peval.scm:
* module/system/vm/assembler.scm: Update all uses to expect vectors
instead of alists and to use tree-il-src instead of tree-il-srcv.
* module/language/elisp/compile-tree-il.scm (location): Create vectors,
not alists.
* test-suite/tests/compiler.test ("psyntax"): Update syntax-source
expectation.
This will allow for weak tables to be implemented partly in Scheme.
* module/ice-9/object-properties.scm: New file.
* am/bootstrap.am (SOURCES): Add new file.
* module/ice-9/boot-9.scm:
* module/ice-9/deprecated.scm (make-object-property*): Deprecate
make-object-property in default env and add a shim.
* module/ice-9/buffered-input.scm (ice-9):
* module/language/elisp/boot.el (plist-function):
* module/scripts/frisk.scm (scripts):
* module/web/http.scm (web): Adapt users to import the new module.
* module/ice-9/boot-9.scm(symbol-property, set-symbol-property!)
(symbol-property-remove!): Remove.
* module/ice-9/boot-9.scm (make-record-type): Name must be symbol.
(record-constructor): Alias record-type-constructor.
(make-module): Require size to be zero. Should fix this with keyword
args :/
(try-load-module): Inline definition of try-module-autoload. Remove
try-module-autoload binding.
(make-soft-port): Add deprecation warning, so we can remove it
eventually.
* module/ice-9/save-stack.scm: Remove deprecation comment.
* module/ice-9/top-repl.scm:
* module/ice-9/threads.scm: Export instead of replace bindings.
* module/language/bytecode.scm: Remove instruction-arity et al.
* module/language/tree-il/analyze.scm: Remove deprecated
unbound-variable-analysis and macro-use-before-definition-analysis.
* module/rnrs.scm: Fix syntax-case export now that module and value
namespaces are separate.
* module/system/base/language.scm (invalidate-compilation-cache!):
Remove.
* module/system/base/language.scm (*current-language*): Remove.
* module/ice-9/atomic.scm: Don't add-interesting-primitive! here.
* module/language/tree-il/primitives.scm
(*interesting-primitive-names*): Instead, import atomics here and
register the primitives as usual. This will let atomics be used earlier
in the boot graph.
* libguile/scm.h (scm_tc7_thread): Give threads their own tc7.
* libguile/threads.h (struct scm_thread): Add a tag, so that struct
thread can be a SCM directly. Add a struct gc_mutator* member.
(scm_thread_handle): New inline function.
(SCM_I_IS_THREAD, SCM_I_THREAD_DATA, SCM_VALIDATE_THREAD): Update to use
tc7 instead of SMOB tags.
* libguile/continuations.c (scm_i_with_continuation_barrier)
* libguile/finalizers.c (queue_finalizer_async)
* libguile/jit.c (compile_current_thread)
* libguile/threads.c (block_self, guilify_self_2)
(lock_mutex, unlock_mutex, timed_wait scm_current_thread)
(scm_all_threads)
* libguile/vm-engine.c (current-thread): Use scm_thread_handle instead
of thread->handle.
* libguile/evalext.c (scm_self_evaluating_p):
* libguile/goops.c (class_thread, scm_class_of, scm_sys_goops_early_init)
* libguile/print.c (iprin1)
* module/language/cps/compile-bytecode.scm (compile-function)
* module/oop/goops.scm (<thread>)
* module/system/base/types.scm (cell->object)
* module/system/base/types/internal.scm (heap-tags)
* module/system/vm/assembler.scm: (emit-thread?): Adapt to
scm_tc7_thread.
* libguile/gc-internal.h: Move init functions that take "struct
gc_stack_addr" here, so that internal Whippet uses don't cause Whippet
to be added to public headers.
* libguile/gc.c (scm_storage_prehistory): Take struct gc_stack_addr as
arg, and pass to gc_init. Return a mutator pointer.
* libguile/init.c (scm_i_init_guile): Pass mutator and stack base to GC
and thread init routines.
* libguile/threads.c (scm_trace_dynstack, scm_trace_thread)
(scm_trace_thread_mutator_roots): New infra for marking threads in terms
of Whippet API.
* libguile/threads.c (guilify_self_1): Since we don't use a separate GC
kind for threads any more, and thread marking is keyed off
gc_mutator_set_roots, we can avoid some of the gnarly synchronization.
(on_thread_exit): Arrange to gc_finish_for_thread.
(scm_i_init_thread_for_guile): Use gc_init_for_thread.
(init_main_thread, with_guile, scm_i_with_guile): Use Whippet API.
(scm_threads_prehistory): Take main-thread mutator and the stack base as
arguments.
* libguile/vm.c (scm_trace_vm): Rework in terms of Whippet API.
* libguile/whippet-embedder.h (gc_trace_mutator_roots): Arrange to trace
the current mutator's SCM thread object.
* libguile/trace.h: New file, to declare implementations of trace
routines.
* libguile/Makefile.am (noinst_HEADERS): Add trace.h.
* module/language/tree-il/fix-letrec.scm (compute-sccs): Instead of
depending on all previous complex bindings, we can just depend on the
most recent one. Decreases the graph size.
We were using list sets, which when you end up with thousands of
bindings in an SCC reaches the point where we are off the quadratic end
of the curve. Fix to use intsets and intmaps instead.
* module/language/tree-il/fix-letrec.scm (compute-ids): New function.
(compute-referenced-and-assigned): Rename from analyze-lexicals, and
compute intsets.
(make-compute-free-variables): Rename from free-variables, return a
procedure instead of a hash table, and use intsets. Use a global cache
to avoid quadratic behavior with regard to binding depth.
(compute-complex): Compute a global set of "complex" variables, as an
intset.
(compute-sccs): Use intsets and intmaps to compute the free-variable and
ordering edges.
(fix-scc, fix-term): Refactorings.
(reorder-bindings): Avoid a linear search.
(fix-letrec): Refactor.
* module/language/cps/specialize-numbers.scm (sigbits-ref): New helper.
(invert-graph*): New helper.
(compute-significant-bits): When visiting a term changes computed
needed-bits for one of its definitions, we need to revisit the variables
that contributed to its result (the uses), because they might need more
bits as well. Previously we were doing this by enqueueing predecessors
to the term, which worked if the uses were defined in predecessors, or
if all defining terms were already in the worklist, which is the case
without loops. But with loops, when revisiting a term, you could see
that it causes sigbits to change, enqueue its predecessors, but then the
predecessors don't change anything and the fixpoint stops before
reaching the definitions of the variables we need. So instead we
compute the use-def graph and enqueue defs directly.
* module/language/cps/specialize-numbers.scm (next-power-of-two): Use
integer-length. No change.
(compute-significant-bits): Fix the fixpoint computation, which was
failing to complete in some cases with loops.
* module/language/cps/specialize-numbers.scm (specialize-operations):
Accept any operand to logand/immediate, provided the result is a u64 in
the right range.
* module/language/cps/types.scm
(ulogand, ulogand/immediate, ulogsub, ulogior, ulogxor): Where we have
u64 inputs, there's no need to `restrict!`; the range will come from the
definition.
* module/language/tree-il/peval.scm (peval)
(inlinable-kwargs-bug-fixup): Before 3.0.10, the inlinable exports pass
was incorrectly serializing functions with keyword arguments. This was
fixed in 2c645571b3, but that meant that
3.0.10 compiling against 3.0.9 binaries could raise an exception at
compile-time; whoops. Add a workaround so that 3.0.9 binaries still
work.
Fixes https://issues.guix.gnu.org/72936.
* module/language/cps/intset.scm (make-intset-folder): intset-fold-right
on a transient intset would dispatch to left fold after making the
persistent set. Sadness!
As suggested in
<https://lists.gnu.org/archive/html/guile-devel/2023-06/msg00008.html>.
* module/language/wisp.scm (wisp-uuid): Remove.
(repr-quote, repr-unquote, repr-quasiquote, repr-unquote-splicing)
(repr-syntax, repr-unsyntax, repr-quasisyntax, repr-unsyntax-splicing):
Turn into uninterned symbols.
(line-continues?, chunk-ends-with-period,
line-code-replace-inline-colons): Adjust comparisons accordingly.
(wisp-replace-paren-quotation-repr)[pred]: New procedure.
Use it to compare against the various ‘repr-’ values.
(wisp-make-improper)[dot?]: New procedure.
Use it to compare against ‘repr-dot’.
* module/language/tree-il/optimize.scm (make-optimizer): If the keyword
argument #:dump-optimized-tree-il? is present, print the Tree-IL that
will be handed to the next compiler. Also re-enable #:verify-tree-il?.
* module/language/cps/effects-analysis.scm (compute-clobber-map):
Previously a whole-object read would not be clobbered by a specific
field write. This crops up for the &read introduced at the site of
`cons` for the synthetic car and cdr definitions. This error was there
before but didn't cause bugs before 3.0.10 because cons got eagerly
lowered to separate allocation and initialization instructions.
* module/language/tree-il/inlinable-exports.scm (inlinable-exp): Call
assq-ref in the right order. Embarrassing!
* module/language/tree-il/peval.scm (peval): Print the symbols so that
we can diagnose later failures.
* module/language/tree-il/peval.scm (peval): Handle all lambda inlining
the same, and extend with support for multiple clauses and keyword
arguments.
* test-suite/tests/peval.test ("case-lambda"): Enable kwarg inlining.
Can help reduce case-lambda* / lambda* at Tree-IL optimization-time.
* module/language/tree-il/demux-lambda.scm: New file.
* am/bootstrap.am (SOURCES): Add new file.
* module/language/tree-il/optimize.scm (make-optimizer):
* module/system/base/optimize.scm (available-optimizations): Enable
demux-lambda at level 2.
* module/language/tree-il/primitives.scm (*primitive-constructors*):
(append): Recognize append and reduce it to only the two-operand form.
* module/language/tree-il/peval.scm (peval): Add optimizations to
append.
* module/language/tree-il/peval.scm (peval): When visiting (values) in
anything other than an effect or values context,
residualize (values (values)), which will cause a run-time error.
* test-suite/tests/peval.test ("values"): Add test.
Allowing variables to hold an unbound value and requiring a check on
each load is suboptimal; the fixing letrec boolean check is better. So
other runtimes (hoot) might preclude unbound variables by construction.
Allow them to do so.
* module/language/cps/guile-vm.scm (target-has-unbound-boxes?): New
definition.
* module/language/tree-il/compile-cps.scm (target-has-unbound-boxes?):
(%box-ref): Only residualize an unbound check if the target has unbound
boxes.
* module/language/tree-il/peval.scm (peval): Introduce raise-type-error
for dynwind unwinder thunk check.
* module/language/tree-il/compile-cps.scm (raise-type-error):
* module/language/tree-il/compile-bytecode.scm (canonicalize): Handle
raise-type-error, as it can be in Tree-IL now.
This keeps things higher level, and is a step towards structured
exceptions in guile.
* module/language/cps/guile-vm/reify-primitives.scm (reify-primitives):
Turn raise-type-error, raise-range-error, and raise-arity-error into
variants of "throw". Lower raise-exception to a non-tail primcall.
* module/language/tree-il/compile-cps.scm: Instead of residualizing
"throw/value+data" throws, exceptions introduced by CPS lowering are
more structured: raise-type-error, raise-range-error, and
raise-arity-error. Also, lower raise-exception to an ordinary `$throw`
instead of eagerly producing the non-tail call to a $prim.
* module/language/cps/specialize-numbers.scm (logand/immediate): Define
a sigbits handler.
(specialize-operations): Require logand/immediate operand to be u64 to
lower to ulogand/immediate. Shouldn't be necessary but even if only u64
bits are used, negative fixnums will have the sign bit set, which trips
up further unboxed uses which error if the operand to `scm->u64` is
negative.
* module/language/cps/type-fold.scm (rem): Emit logand/immediate.
Also rework so that the symbol hash uses the low bits instead of high
bits. We can do this because, for the guile-vm target, now we compute
the full target hash.
* module/language/cps/guile-vm.scm (jenkins-lookup3-hashword2):
(target-symbol-hash, target-symbol-hash-bits): New exported functions..
* module/language/cps/switch.scm (optimize-branch-chain): Change to use
target-symbol-hash and target-symbol-hash-bits from the current
target-runtime.
* libguile/jit.c (compile_ulogand_immediate, compile_ulogand_immediate_slow)
* libguile/vm-engine.c (ulogand_immediate): New JIT and interpreter
support for ulogand/immediate.
* module/language/cps/guile-vm/lower-primcalls.scm (string-ref):
(vtable-vtable?):
(vtable-field-boxed?): Emit ulogand/immediate.
* module/language/cps/guile-vm/reify-primitives.scm (reify-primitives):
Remove logand/immediate. Only emit ulogand/immediate if the immediate
is a u8. Refactor mul/immediate.
* module/language/cps/specialize-numbers.scm (specialize-operations):
Produce ulogand/immediate if the result is a u64.
* module/language/cps/effects-analysis.scm:
* module/language/cps/types.scm (logand/immediate): Add effect and type
inference for logand/immediate, ulogand/immediate,
* module/language/cps/utils.scm (primcall-raw-representations):
ulogand/immediate makes a u64.
* module/language/tree-il/compile-cps.scm (convert): Generate
logand/immediate if possible.
* module/language/cps/compile-bytecode.scm (compile-function):
* module/system/vm/assembler.scm (system): Add ulogand/immediate
emitter.
* libguile/loader.h (SCM_OBJCODE_MINOR_VERSION): Bump.
* module/language/tree-il/peval.scm (peval): If a primcall is
effect-free, don't require that its args are too: just revisit args as a
sequence in effect context.
* module/language/tree-il/effects.scm (effect-free-primcall?): New
exported function.
* module/language/tree-il/peval.scm (peval): fix-letrec can residualize
useless primcalls, when a let or letrec-bound var is unused. Fix to
elide these.
* module/language/tree-il/effects.scm (add-primcall-effect-analyzer!):
New facility.
* module/language/tree-il/effects.scm (make-effects-analyzer): If a
primcall's args cause no effects, call out to a user-provided
effect-free? primitive for a primcall. If true, the primcall will be
marked as depending on all effects but causing none; this will allow it
to be elided by letrectify or peval.