The new non-libltdl foreign library loading algorithm from 3.0.6
fails to cover common cases regarding how libtool names and installs
DLL files. Notably, it fails to recognize when libtool has added the
major version number into the filename itself, such as libfoo-1.dll
Also, it does not search in binary directories and the PATH for DLL
files, where libtool is likely to install DLLs.
This adds the option to search for dlls with major version numbers
in the filename, and modifies the search strategy for DLL-using
OSs to check bindir and PATH.
For MSYS, libraries are installed with the 'msys-' prefix. So this
modifies load-foreign-library to handle that prefix as well.
It changes the #:rename-on-cygwin? option to #:host-type-rename? to
better reflect that is works on both Cygwin and MSYS.
Partially based on a patch by Hannes Müller.
* NEWS: updated
* doc/ref/api-foreign.texi: document updates to load-foreign-library
and system-dll-path
* module/system/foreign-library.scm (is-integer-string?): new utility function
(dll-name-match?): new utility function
(find-best-dll-from-matches): new utility function
(dll-exists-with-version): new function that implements new dll search logic
(file-exists-with-extension): add flag argument to allow new dll search
(file-exists-in-path-with-extension): add flag argument to all new dll search
(system-dll-path): new parameter
(lib->msys): new helper function
(load-foreign-library): add new optarg flag #:allow-dll-version-suffix?
Pass new flag to library search functions.
Implement new search strategy for #:search-system-paths? on DLL systems'
replace #:rename-on-cygwin? with #:host-type-rename?
Use that option to rename both MSYS and Cygwin libraries.
(guile-system-extensions-path): prefer bindir to libdir on DLL systems
* test-suite/tests/foreign.test ("dll-name-match?"): new test category
("find-best-dll-from-matches"): new test category
("lib->msys"): new unit tests
Fixes <https://bugs.gnu.org/30600>.
* module/system/repl/command.scm (define-meta-command): Flush all
remaining input after handling a read error.
* module/system/repl/common.scm (flush-all-input): New public procedure.
* module/system/repl/repl.scm: Remove local flush-all-input definition.
The builtin primitive procedure `error` takes an optional message and
a list of arguments to include into the error message.
These args are formatted with `~S` and appended to the error message, so
that an example call of
`(error "Wrong argument: " 42)`
results in the output
"Wrong argument: 42"
If format strings occur in the message itself, however, they are
escaped. Thus a call like
`(error "Wrong argument: ~a" 42)`
is rendered as
"Wrong argument: ~a 42"
Some callers did not take this behavior into account, leading to
confusing error messages.
Changing the behavior of `error` to be
both backwards-compatible and accept also format strings inside messages
is not straightforward, because it would have to handle escaped `~`
characters as well. Therefore, fix `error` call sites using format
strings to use `format` before calling out to `error`.
The following files are affected:
* module/ice-9/format.scm (format)
* module/ice-9/r6rs-libraries.scm (resolve-r6rs-interface)
* module/oop/goops.scm (make)
* module/srfi/srfi-37.scm (Comment at the beginning of file)
* module/system/base/compile.scm (call-once)
* module/system/repl/command.scm (break, tracepoint)
* module/system/repl/common.scm (repl-default-options)
* module/system/vm/traps.scm (arg-check, trap-at-source-location)
There are a couple of further call sites that were left unchanged,
either because they are using their own `error` procedure:
* module/ice-9/read.scm
* module/ice-9/command-line.scm
or are not referenced from other modules:
* module/system/base/lalr.upstream.scm:
* module/sxml/upstream/assert.scm:
* module/sxml/sxml-match.ss:
Signed-off-by: Ludovic Courtès <ludo@gnu.org>
Fixes a regression introduced in
4a0c2433d9: the strategy wouldn’t work
when writing to, say, a bytevector output port.
* module/system/vm/linker.scm (link-elf)[write-padding]: Reintroduce
loop for when PORT is not a file port. Remove first argument.
Since ‘*lcm-page-size*’ is 64 KiB, this saves disk space for small ‘.go’
files.
* module/system/vm/linker.scm (link-elf)[write-padding]: Rewrite in
terms of ‘seek’.
* module/system/foreign.scm (read-fields, write-fields): Don't return
the final offset, as the offset after the final field is not necessarily
the end of the struct, because of padding.
* module/system/foreign.scm (bytevector-complex-single-native-ref)
(bytevector-complex-single-native-set!)
(bytevector-complex-double-native-ref)
(bytevector-complex-double-native-set!): Be more static in our
definitions.
(compile-time-eval):
(switch/compile-time-keys): New helpers.
(align): Make available at compile-time.
(read-field, read-fields, write-field, write-fields): New helpers. More
efficient than the alist.
(write-c-struct, read-c-struct): Rework in terms of new helpers.
(parse-c-struct): Just use sizeof to get the size.
* libguile/foreign.h:
* libguile/foreign.c: Always define complex-float and complex-double.
Fall back to alignof float / 2*sizeof float if no complex numbers. (But
with C99 surely it exists everywhere.)
* module/system/foreign.scm (*writers*, *readers*): Always include
complex-float and complex-double readers and writers.
* test-suite/tests/foreign.test: Always run the complex tests.
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.
This satisfies a longstanding complaint that Guile backtraces were being
truncated too much by default (72 columns), often hindering debugging.
* module/system/repl/debug.scm (default-frame-width): New variable.
(print-frames): Change default #:width value depending on whether PORT
is a tty.
* 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/primitives.scm (*interesting-primitive-names*):
(*primitive-accessors*): Add string->utf8, utf8->string, and
string-utf8-length.
(primitive-module): New public function, moved here from (language
tree-il compile-bytecode).
* module/language/tree-il/compile-bytecode.scm: Use primitive-module
from (language tree-il primitives).
* module/language/tree-il/peval.scm (peval): A bugfix: load primitives
from their proper module. Allows bytevector primitives to fold.
* module/language/cps/guile-vm/reify-primitives.scm:
* module/language/cps/effects-analysis.scm:
* module/language/cps/types.scm
* module/language/tree-il/primitives.scm:
* module/language/tree-il/cps-primitives.scm:
* module/language/tree-il/effects.scm (make-effects-analyzer):
Add string->utf8, utf8->string, and string-utf8-length.
* module/language/tree-il/compile-cps.scm (string->utf8)
(string-utf8-length, utf8->string): New custom lowerers, including type
checks and an unboxed result for string-utf8-length.
* module/system/vm/assembler.scm:
* libguile/intrinsics.h:
* libguile/intrinsics.c: Because string-utf8-length returns an unboxed
value, we need an intrinsic for it; go ahead and add an intrinsic for
string->utf8 and utf8->string too, as we will likely be able to use
these in the future.
Recognize `raise-exception` in the same way we recognize `throw`, though
it is a bit less optimized and the boot story is not as complicated.
* doc/ref/vm.texi (Non-Local Control Flow Instructions):
* libguile/jit.c (compile_unreachable):
(compile_unreachable_slow):
* libguile/vm-engine.c (VM_NAME):
* module/language/cps/compile-bytecode.scm (compile-function):
* module/system/vm/assembler.scm (emit-unreachable): Add new
"unreachable" instruction, inserted after a call to non-continuable
`raise-exception`.
* module/language/tree-il/compile-cps.scm (raise-exception):
* module/language/tree-il/primitives.scm
(*interesting-primitive-names*): Recognize raise-exception, and if it is
called with just one argument, prune that branch of the control-flow
graph.
* module/language/cps/utils.scm (compute-var-representations): $code
makes a 'code. bv-contents makes a 'bv-contents.
* module/language/cps/slot-allocation.scm:
* module/language/cps/hoot/tailify.scm:
* module/system/vm/assembler.scm: Adapt.
* module/system/base/target.scm (target-runtime): New export.
* module/language/cps/optimize.scm (make-cps-lowerer): Load a
backend-specific lowering module dynamically.
* module/language/cps/guile-vm.scm: New module for lowering to Guile's
VM.
* module/language/cps/guile-vm/loop-instrumentation.scm:
* module/language/cps/guile-vm/lower-primcalls.scm:
* module/language/cps/guile-vm/reify-primitives.scm: Move here, from
parent dir.
* am/bootstrap.am: Update for new file list.
* module/language/tree-il/analyze.scm (<module-info>): New record type.
(unused-module-analysis): New variable.
(make-unused-module-analysis): New analysis.
(make-analyzer): Add it.
* module/system/base/message.scm (%warning-types): Add 'unused-module'.
* test-suite/tests/tree-il.test (%opts-w-unused-module): New variable.
("warnings")["unused-module"]: New test prefix.
* NEWS: Update.
This reduces the amount of memory that needs to be allocated while
writing the ELF file to disk.
Note: We're abusing #:page-aligned? in 'link-elf' to choose whether to
return a bytevector or a procedure.
* module/system/vm/linker.scm (process-reloc): Subtract SECTION-OFFSET
when writing to BV.
(write-linker-object): Pass BV directly to the linker object writer.
(link-elf): When PAGE-ALIGNED? is false, call 'bytevector-slice' from
here. When it is true, return a procedure that takes a port and writes
to it, without having to allocate a bytevector for the whole ELF
container.
* module/language/bytecode/spec.scm (bytecode->value): Handle X being a
procedure instead of a bytevector.
(bytecode) <#:printer>: Likewise.
* test-suite/tests/linker.test (link-elf-with-one-main-section): Pass
#:page-aligned? #f.
This reduces the amount of memory used during linking and reduces the
number of copies to be done between bytevectors.
* module/system/vm/linker.scm (<linker-object>): Remove 'bv' field and
add 'size' and 'writer'.
(make-linker-object): Adjust accordingly.
(string-table-size): New procedure.
(link-string-table!): Remove.
(string-table-writer): New procedure.
(allocate-segment): Adjust 'make-linker-object' call.
(find-shstrndx): Call the 'linker-object-writer' of O.
(add-elf-objects): Adjust 'make-linker-object' call. Remove
'make-bytevector' allocations and move serialization to lazy 'writer'
procedures. Define 'segments' and 'add-header-segment!'. Return the
latter as the first value.
* module/system/vm/assembler.scm (make-object): Remove 'bv' parameter
and add 'size' and 'writer'.
(link-data): Remove 'make-bytevector' call and move serialization to
a lazy 'writer' procedure.
(link-text-object): Likewise.
(link-frame-maps): Likewise.
(link-dynamic-section): Likewise.
(link-shstrtab): Likewise.
(link-symtab): Likewise.
(link-arities): Likewise, and remove 'bytevector-append'.
(link-docstrs): Likewise.
(link-procprops): Likewise.
(link-debug): Likewise, and define 'copy-writer'.
* test-suite/tests/linker.test (link-elf-with-one-main-section): Adjust
accordingly.
* module/system/vm/assembler.scm (process-relocs): Remove 'buf'
parameter and turn into a pure function.
(patch-relocs!): New procedure. Perform the side effects previously
done in 'process-relocs'.
(link-text-object): Adjust accordingly.
Workaround for <https://bugs.gnu.org/57948>.
* module/system/vm/frame.scm (frame-call-representation): Treat a
binding as "unspecified" if its slot exceeds 'frame-num-locals'.
Locations are stored in tree-il records in "source vector" form, but
`location-string' was rendering these as <unknown-location>.
* module/system/base/message.scm (location-string): Support locations
passed as a file/line/column vector.
The code coverage function `coverage-data->lcov` has a documented
`modules` argument, however that was missing from the source. I have
added it so when supplied it only converts the coverage data for the
supplied modules. If not supplied it defaults the old behavour of
including all the modules currently loaded.
* module/system/vm/coverage.scm (coverage-data->lcov): Add #:modules
parameter and honor it.
Signed-off-by: Ludovic Courtès <ludo@gnu.org>
NetBSD and pkgsrc have been using an empty vendor string since the
mid-'90s, such as x86_64--netbsd. pkgsrc has been carrying around a
workaround just the guile build for a long time. (Before that,
NetBSD omitted the vendor altogether, so if x86_64 existed then it
might have been `x86_64-netbsd', but that caused more problems.)
This change makes Guile accept an empty vendor string so workarounds
are no longer necessary.
* module/system/base/target.scm (validate-target): Allow empty vendor
string in GNU target triplets.
* test-suite/tests/cross-compilation.test ("cross-compilation"): Add
tests for "x86_64--netbsd".
Co-authored-by: Ludovic Courtès <ludo@gnu.org>
Avoiding systematic conversion from source vectors to property alists
saves 20% on the final heap size of a process doing:
(compile-file FILE #:optimization-level 1)
where FILE is large.
* module/language/tree-il.scm (tree-il-src/ensure-alist): New procedure
with setter. Export as 'tree-il-src'.
* module/ice-9/psyntax.scm (build-void, build-call)
(build-conditional, build-lexical-reference, build-lexical-assignment)
(build-global-reference, build-global-assignment)
(build-global-definition, build-simple-lambda, build-case-lambda)
(build-lambda-case, build-primcall, build-primref)
(build-data, build-sequence, build-let, build-named-let)
(build-letrec, expand-body): Remove (sourcev->alist src) calls.
* module/ice-9/psyntax-pp.scm: Regenerate.
* module/language/tree-il/analyze.scm (shadowed-toplevel-analysis): Use
'tree-il-src' instead of accessing the 'src' slot directly.
* module/system/vm/assembler.scm (link-debug): Adjust so PC can be
followed by a vector or an alist.
* configure.ac:
* Makefile.am (SUBDIRS): Replace bootstrap/ with stage0, stage1, and
stage2.
* am/bootstrap.am: Include all files and all rules.
* meta/build-env.in (GUILE_AUTO_COMPILE): Always turn off
auto-compilation. Take a GUILE_BOOTSTRAP_STAGE argument, which can be
stage0, stage1, stage2, or unset. Adapt the load-compiled path
accordingly.
* meta/uninstalled-env.in: Include .go files from stage2.
* module/Makefile.am: Rework to use boostrap.am.
* module/system/base/optimize.scm (available-optimizations): Punt the
inlinable-exports machinery to -O2.
* stage0/Makefile.am:
* stage1/Makefile.am:
* stage2/Makefile.am: New files.
496f69dba2 introduced C99 complex types in
libguile/foreign.h and (system foreign). Since these types are provided
conditionally in foreign.h based on autoconf tests they need to be used
conditionally in (system foreign) based on their presence.