Clean up tangled and partly repeated code, and normalize ELF use for
boot files and embedded modules. Also, repair Unix-style Mac OS
builds.
With these changes, `raco exe` should always produce a well-formed
ELF, Mach-O, or PE excutable. The mode that just appends to the end of
the executable should happen only platforms that don't use one of
those three --- which are very rare and unlikely supported, anyway.
Closes#3831
- avoid blocking once we are committed to an error
- consume eof exactly when there is an error or eof is the only thing in the stream
Also to improve the testing of these two, the new test suite support
lets us carefully control what's coming out of the port, including
situations where there are eof objects with data that comes afterwards
(so we can test if an eof is consumed or not)
Converting between strings and paths interferes with cross
compilation. This hasn't caused more problems only because cross
compilation has tended to run on Unix platforms, where the generated
paths are acceptable to Windows. But using strings goes wrong when
manipulating a Windows-based build for further cross-build actions on
Unix, and it can go wrong if paths contain bytes that cannot be
encoded in strings.
The `ffi/unsafe/string-list` library is not needed now that `(_list i
_string)` and similar work. This way, existing code that uses `(_list
i _string)`, `(_vector i _string)`, etc., does not needed to be
modified to work with CS.
We don't usually remove libraries, of course, but this one has only
existed for a few days, and it was made to work around a problem that
has been solved in a better way.
Related to #3825
A reference bytevector holds a mixture of addresses within GCable
objects and foreign addresses, where "address" corresponds to the
payload of a bytevector or flvector object. The GC knows to apply a
suitable offset to the reference, so that object counts as reachable
from a reference bytevector, and the reference bytevector is updated
if the object is relocated during a collection.
With this change, the restriction in Racket CS against passing
non-atomic memory to a foreign function can be lifted. For example,
`(_list i _string)` can be useful as the type of a foreign-call
argument.
Making reference bytevectors a subtype of bytevectors is not an
obvious choice, given that writing to a reference bytevector with
byte-level operations can easily corrupt it. But this choice makes
various things simpler and easier.
I'm not sure this is a good idea, but it doesn't apear to be a
particularly bad idea. Exporting symbols just makes the executable
size slightly larger.
Closes#3617
Passing an array of strings or byte strings to a foreign function can
be especially tedious on Racket CS, due to the prohibition against
passing an array of GCable pointers to a foreign function.
Closes#3825
In CS, a pointer to non-atomic memory cannot usefully be passed to a
foreign function. The general foreign-call path checked for that kind
of argument and raised an exception, but the check was missing from
the common-case fast path, so a meaningless argument would be quietly
passed to the foreign function.
Related to #3825
This speeds up `(factorial 1000000)` (using factorial from math/number-theory)
by about 3x, and the conversion of the result to a string by about 2x.
Benchmark:
#lang racket
(require math/number-theory)
(define n (time (factorial 1000000)))
(define s (time (number->string n)))
(string-length s)
Current Racket CS:
cpu time: 19135 real time: 19137 gc time: 372
cpu time: 33416 real time: 33418 gc time: 463
Current Racket BC (GMP is really fast):
cpu time: 1465 real time: 1465 gc time: 51
cpu time: 3661 real time: 3659 gc time: 3
This PR:
cpu time: 6173 real time: 6172 gc time: 168
cpu time: 17846 real time: 17847 gc time: 377
Cutoff between Karatsuba and Toom3 estimated by mflatt.
Cutoff between Toom3 & Toom4 guessed.
The argument type `(_ptr i _string/utf-16)` is not used on CS, because
a pointer to non-atomic memory cannot usefully be passed to a foreign
function from Racket CS.
Closes#3820
When a struct is called as a procedure and the struct is
impersonators, make a method-style `prop:procedure` receive the
impersonated structure as its argument. This change makes a
method-style `prop:procedure` more consistent with a field-index
`prop:procedure. The old behavior, meanwhile, seems to create an
unsoundness in Typed Racket.
Closes#2574