cs & ffi/unsafe: change base type of (_bytes o <n>)
to _pointer
A base type of `_gcpointer` works ok for traditional Racket as a kind of "maybe it's GCable, so treat it that way just in case". That approach doesn't work for Racket CS, where `_gpointer` has to mean "definitely GCable memory". Although the difference is unfortunate, making Racket CS base `(_bytes o <n>)` on `_pointer` is consistent with the way plain `_bytes` is like `_pointer` in Racket CS and like `_gcpointer` in traditional Racket.
This commit is contained in:
parent
e0b51e2709
commit
01ed8e4662
|
@ -57,8 +57,18 @@ offset is always in bytes.}
|
|||
@defproc[(cpointer-gcable? [cptr cpointer?]) boolean?]{
|
||||
|
||||
Returns @racket[#t] if @racket[cptr] is treated as a reference to
|
||||
memory that is managed by the garbage collector, @racket[#f]
|
||||
otherwise.}
|
||||
memory that is (assumed to be) managed by the garbage collector,
|
||||
@racket[#f] otherwise.
|
||||
|
||||
For a pointer based on @racket[_gcpointer] as a result type,
|
||||
@racket[cpointer-gcable?] will return @racket[#t]. In the @3m[] and
|
||||
@CGC[] variants of Racket, @racket[cpointer-gcable?] will return
|
||||
@racket[#f] for a pointer based on @racket[_pointer] as a result type.
|
||||
The @CS[] variant is mostly the sane, except that if a pointer is
|
||||
extracted using the @racket[_pointer] type from memory allocated as
|
||||
@racket['nonatomic], @racket[cpointer-gcable?] will report @racket[#t]
|
||||
for the extracted pointer.}
|
||||
|
||||
|
||||
@; ----------------------------------------------------------------------
|
||||
|
||||
|
@ -466,12 +476,12 @@ use by such finalizers.}
|
|||
@defproc[(make-sized-byte-string [cptr cpointer?] [length exact-nonnegative-integer?])
|
||||
bytes?]{
|
||||
|
||||
Returns a byte string made of the given pointer and the given length.
|
||||
No copying is performed. Beware that future implementations of Racket
|
||||
may not support this function (in case of a byte string representation
|
||||
that combines a size and byte-string content without an indirection).
|
||||
Returns a byte string made of the given pointer and the given length
|
||||
in the @3m[] and @CGC[] variants of Racket; no copying is performed.
|
||||
In the @CS[] variant, the @racket[exn:fail:unsupported] exception is
|
||||
raised.
|
||||
|
||||
Beware also that the representation of a Racket byte string normally
|
||||
Beware that the representation of a Racket byte string normally
|
||||
requires a nul terminator at the end of the byte string (after
|
||||
@racket[length] bytes), but some functions work with a byte-string
|
||||
representation that has no such terminator---notably
|
||||
|
|
|
@ -418,11 +418,13 @@ See @secref["foreign:tagged-pointers"] for creating pointer types that
|
|||
use these tags for safety. A @racket[#f] value is converted to
|
||||
@cpp{NULL} and vice versa.
|
||||
|
||||
The address referenced by a @racket[_pointer] value must not refer to
|
||||
As a result type, the address referenced by a @racket[_pointer] value must not refer to
|
||||
memory managed by the garbage collector (unless the address
|
||||
corresponds to a value that supports interior pointers and that is
|
||||
otherwise referenced to preserve the value from garbage collection).
|
||||
The reference is not traced or updated by the garbage collector.
|
||||
As an argument type, @racket[_pointer] works for a reference to either
|
||||
GC-managed memory or not.
|
||||
|
||||
The @racket[equal?] predicate equates C pointers (including pointers
|
||||
for @racket[_gcpointer] and possibly containing an offset) when they
|
||||
|
@ -433,11 +435,13 @@ case the equality rules of the relevant structure types apply.}
|
|||
|
||||
@defthing[_gcpointer ctype?]{
|
||||
|
||||
Like @racket[_pointer], but for a C pointer value that can refer to memory
|
||||
managed by the garbage collector.
|
||||
The same as @racket[_pointer] as an argument type, but as a result
|
||||
type, @racket[_gcpointer] corresponds to a C pointer value that refers
|
||||
to memory managed by the garbage collector.
|
||||
|
||||
Although a @racket[_gcpointer] can reference to memory that is not
|
||||
managed by the garbage collector, beware of using an address that
|
||||
In the @3m[] and @CGC[] variants of Racket, a @racket[_gcpointer] result
|
||||
pointer can reference to memory that is not
|
||||
managed by the garbage collector, but beware of using an address that
|
||||
might eventually become managed by the garbage collector. For example,
|
||||
if a reference is created by @racket[malloc] with @racket['raw] and
|
||||
released by @racket[free], then the @racket[free] may allow the memory
|
||||
|
@ -445,9 +449,8 @@ formerly occupied by the reference to be used later by the garbage
|
|||
collector.
|
||||
|
||||
The @racket[cpointer-gcable?] function returns @racket[#t] for a
|
||||
cpointer generated via the @racket[_gcpointer] type, while it
|
||||
generates @racket[#f] for a cpointer generated via the
|
||||
@racket[_cpointer] type.}
|
||||
cpointer generated via the @racket[_gcpointer] result type. See
|
||||
@racket[cpointer-gcable?] for more information.}
|
||||
|
||||
|
||||
@deftogether[(
|
||||
|
@ -1141,10 +1144,13 @@ type; a byte string is passed as @racket[_bytes] without any copying.
|
|||
Beware that a Racket byte string is not necessarily nul terminated;
|
||||
see also @racket[_bytes/nul-terminated].
|
||||
|
||||
In the @3m[] and @CGC[] variants of Racket, a C non-NULL @cpp{char*}
|
||||
is converted to a Racket byte string without copying. In the @CS[]
|
||||
variant, conversion requires copying to represent a C @cpp{char*}
|
||||
result as a Racket byte string. In both cases, the C result must have
|
||||
In the @3m[] and @CGC[] variants of Racket, a C non-NULL result value
|
||||
is converted to a Racket byte string without copying; the pointer is
|
||||
treated as potentially managed by the garbage collector (see
|
||||
@racket[_gcpointer] for caveats). In the @CS[] variant of Racket,
|
||||
conversion requires copying to represent a C @cpp{char*}
|
||||
result as a Racket byte string, and the original pointer is @emph{not}
|
||||
treated as managed by the garbage collector. In both cases, the C result must have
|
||||
a nul terminator to determine the Racket byte string's length.
|
||||
|
||||
A @racket[(_bytes o len-expr)] form is a @tech{custom function type}.
|
||||
|
@ -1182,6 +1188,7 @@ results.
|
|||
|
||||
@history[#:added "6.12.0.2"]}
|
||||
|
||||
|
||||
@; ------------------------------------------------------------
|
||||
|
||||
@section{C Struct Types}
|
||||
|
|
|
@ -1114,6 +1114,13 @@
|
|||
pre: (x => (vector->cblock x t))
|
||||
post: (x => (cblock->vector x t n)))]))
|
||||
|
||||
;; Reflect the difference between 'racket and 'chez-scheme
|
||||
;; VMs for `_bytes` in `_bytes*`:
|
||||
(define _pointer/maybe-gcable
|
||||
(if (eq? 'racket (system-type 'vm))
|
||||
_gcpointer
|
||||
_pointer))
|
||||
|
||||
;; _bytes or (_bytes o n) is for a memory block represented as a Scheme byte
|
||||
;; string. _bytes is just like a byte-string, and (_bytes o n) is for
|
||||
;; pre-malloc of the string. There is no need for other modes: i or io would
|
||||
|
@ -1123,7 +1130,7 @@
|
|||
(provide (rename-out [_bytes* _bytes]))
|
||||
(define-fun-syntax _bytes*
|
||||
(syntax-id-rules (o)
|
||||
[(_ o n) (type: _gcpointer
|
||||
[(_ o n) (type: _pointer/maybe-gcable
|
||||
pre: (make-bytes-argument n)
|
||||
;; post is needed when this is used as a function output type
|
||||
post: (x => (receive-bytes-result x n)))]
|
||||
|
|
|
@ -268,9 +268,8 @@
|
|||
(define (to-utf-16 s)
|
||||
(let ([v (malloc _gcpointer)])
|
||||
(ptr-set! v _string/utf-16 s)
|
||||
(let ([p (ptr-ref v _gcpointer)])
|
||||
(let ([len (* 2 (+ 1 (utf-16-length s)))])
|
||||
(ptr-ref v (_bytes o len))))))
|
||||
(let ([len (* 2 (+ 1 (utf-16-length s)))])
|
||||
(ptr-ref v (_bytes o len)))))
|
||||
|
||||
(define (utf-16-length s)
|
||||
(for/fold ([len 0]) ([c (in-string s)])
|
||||
|
|
Loading…
Reference in New Issue
Block a user