Extend `define-cstruct' to support #:property specs, which causes
the constructor and C->Racket coercsions to wrap the pointer in
a structure instance with the specified properties. Of course,
the wrapper structure has a `prop:cpointer' property so that the
wrapper can be used transparently as a C pointer.
Add missing tests and documentation for the id`->list', `list->'id,
id`->list*', and `list*->'id bindings created by `define-cstruct'.
The FFI's weak table of callback procedures (to map Racket procedures
to FFI callback objects) suffered from the classic key-in-value
problem.
Closes PR 12228, probably
Merge to 5.2
Macros and other tools that need syntax privilege used
`(current-code-inspector)' at the module top-level to try to
capture the right code inspector at load time. It's more
consistent to instead use the enclosing module's declaration-time
inspector, and `var-ref->mod-decl-insp' provides that. The
new function works only on references to anonymous variables,
which limits access to the inspector.
The real function name is longer, of course.
- the `lam' structure from `compiler/zo-struct' changed to include a
`toplevel-map' field
This change helps solve a finalization problem in `racket/draw',
which in turn sigificantly reduces the peak memory use of `raco setup'
during the doc-building phase (because some documents load `racket/draw'
to render images, and multiple copies of `racket/draw' were retained
before finalization was fixed).
The change is an extreme way to solve a specific finalization
problem, but it's a kind of space-safety improvement; space safety
almost never matters, but when it does, then working around a lack of
space safety is practically impossible. In this case, it's not clear
how to otherwise solve the `racket/draw' finalization problem.
The improvement doesn't change the representation of closures, but it
requires special cooperation with the GC. All closures in a module
continue to share the same array of globals (plus syntax objects);
that is, instead of completely flat closures, Racket uses a two-level
environment where top-/module-level variables are grouped
together. The code half of a closure now records which
top-/module-level variables the body code actually uses, and the mark
phase of GC consults this information to retain only parts of the
top-/module-level environment frame that are actually used by some
closure (or all of the frame if it is accessible through some other
route). In other words, the GC supports a kind of "dependent
reference" to an array that is indexed by positions into the array
--- except that the code is more in the "Racket" directory instead of
the "GC" directory, since it's so specific to the closure
representation.