cs: fix checking for a non-atomic argument to a foreign call
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 commit is contained in:
parent
c35a843e71
commit
f35a92744d
|
@ -1125,6 +1125,11 @@ allocated using @racket[(malloc type-expr)] if
|
||||||
@racket[maybe-malloc-mode] is not specified or if it is @racket[#f],
|
@racket[maybe-malloc-mode] is not specified or if it is @racket[#f],
|
||||||
@racket[(malloc type-expr '@#,racket[maybe-malloc-mode])] otherwise.
|
@racket[(malloc type-expr '@#,racket[maybe-malloc-mode])] otherwise.
|
||||||
|
|
||||||
|
Note that in the @CS[] implementation of Racket, a @racket[(_ptr i
|
||||||
|
__ctype)] argument will trigger an error if @racket[__ctype] indicates
|
||||||
|
values that are managed by the garbage collector, since pointers to
|
||||||
|
non-atomic memory cannot be passed to foreign functions.
|
||||||
|
|
||||||
@history[#:changed "7.7.0.6" @elem{The modes @racket[i], @racket[o],
|
@history[#:changed "7.7.0.6" @elem{The modes @racket[i], @racket[o],
|
||||||
and @racket[io] match as symbols
|
and @racket[io] match as symbols
|
||||||
instead of free identifiers.}
|
instead of free identifiers.}
|
||||||
|
@ -1195,6 +1200,11 @@ return two values, the vector and the boolean.
|
||||||
-> (values vec res))
|
-> (values vec res))
|
||||||
]
|
]
|
||||||
|
|
||||||
|
Note that in the @CS[] implementation of Racket, a @racket[(_list i
|
||||||
|
__ctype)] argument will trigger an error if @racket[__ctype] indicates
|
||||||
|
values that are managed by the garbage collector, since pointers to
|
||||||
|
non-atomic memory cannot be passed to foreign functions.
|
||||||
|
|
||||||
@history[#:changed "7.7.0.2" @elem{Added @racket[maybe-mode].}]
|
@history[#:changed "7.7.0.2" @elem{Added @racket[maybe-mode].}]
|
||||||
#:changed "7.7.0.6" @elem{The modes @racket[i], @racket[o],
|
#:changed "7.7.0.6" @elem{The modes @racket[i], @racket[o],
|
||||||
and @racket[io] match as symbols
|
and @racket[io] match as symbols
|
||||||
|
|
|
@ -360,6 +360,13 @@
|
||||||
(with-keeper b)
|
(with-keeper b)
|
||||||
(set-box! b #f)))
|
(set-box! b #f)))
|
||||||
;; ---
|
;; ---
|
||||||
|
;; test error reported when trying to pass non-atomic on CS
|
||||||
|
(when (eq? 'chez-scheme (system-type 'vm))
|
||||||
|
(err/rt-test ((ffi 'grab7th (_fun (_list i _string) -> _int ))
|
||||||
|
(list "hello"))
|
||||||
|
exn:fail?
|
||||||
|
"non-atomic"))
|
||||||
|
;; ---
|
||||||
;; test exposing internal mzscheme functionality
|
;; test exposing internal mzscheme functionality
|
||||||
(when (eq? 'racket (system-type 'vm))
|
(when (eq? 'racket (system-type 'vm))
|
||||||
(test '(1 2)
|
(test '(1 2)
|
||||||
|
|
|
@ -1717,7 +1717,7 @@
|
||||||
[unwrap (lambda (arg in-type)
|
[unwrap (lambda (arg in-type)
|
||||||
(let ([c (s->c name in-type arg)])
|
(let ([c (s->c name in-type arg)])
|
||||||
(if (cpointer? c)
|
(if (cpointer? c)
|
||||||
(unwrap-cpointer 'ffi-call c)
|
(unwrap-cpointer-for-foreign-call c arg proc-p)
|
||||||
c)))]
|
c)))]
|
||||||
[unpack (lambda (arg in-type)
|
[unpack (lambda (arg in-type)
|
||||||
(case (array-rep-to-pointer-rep (ctype-host-rep in-type))
|
(case (array-rep-to-pointer-rep (ctype-host-rep in-type))
|
||||||
|
@ -1787,11 +1787,7 @@
|
||||||
(let ([arg (s->c name in-type orig-arg)])
|
(let ([arg (s->c name in-type orig-arg)])
|
||||||
(if (and (cpointer? arg)
|
(if (and (cpointer? arg)
|
||||||
(not (eq? 'scheme-object (ctype-host-rep in-type))))
|
(not (eq? 'scheme-object (ctype-host-rep in-type))))
|
||||||
(let ([p (unwrap-cpointer 'ffi-call arg)])
|
(unwrap-cpointer-for-foreign-call arg orig-arg proc-p)
|
||||||
(when (and (cpointer-nonatomic? p)
|
|
||||||
(not (cpointer/cell? p)))
|
|
||||||
(disallow-nonatomic-pointer 'argument orig-arg proc-p))
|
|
||||||
p)
|
|
||||||
arg)))
|
arg)))
|
||||||
orig-args in-types)]
|
orig-args in-types)]
|
||||||
[r (let ([ret-ptr (and ret-id
|
[r (let ([ret-ptr (and ret-id
|
||||||
|
@ -1905,11 +1901,15 @@
|
||||||
(loop (cdr types) (cons id reps) (append id-decls decls)))
|
(loop (cdr types) (cons id reps) (append id-decls decls)))
|
||||||
(loop (cdr types) (cons (ctype-host-rep type) reps) decls)))])))
|
(loop (cdr types) (cons (ctype-host-rep type) reps) decls)))])))
|
||||||
|
|
||||||
(define (disallow-nonatomic-pointer what arg proc-p)
|
(define (unwrap-cpointer-for-foreign-call arg orig-arg proc-p)
|
||||||
(raise-arguments-error 'foreign-call "cannot pass non-atomic pointer to a function"
|
(let ([p (unwrap-cpointer 'ffi-call arg)])
|
||||||
"pointer" arg
|
(when (and (cpointer-nonatomic? p)
|
||||||
"function" (or (cpointer->name proc-p)
|
(not (cpointer/cell? p)))
|
||||||
'unknown)))
|
(raise-arguments-error 'foreign-call "cannot pass non-atomic pointer to a function"
|
||||||
|
"pointer" arg
|
||||||
|
"function" (or (cpointer->name proc-p)
|
||||||
|
'unknown)))
|
||||||
|
p))
|
||||||
|
|
||||||
;; Rely on the fact that a virtual register defaults to 0 to detect a
|
;; Rely on the fact that a virtual register defaults to 0 to detect a
|
||||||
;; thread that we didn't start. For a thread that we did start, a
|
;; thread that we didn't start. For a thread that we did start, a
|
||||||
|
|
Loading…
Reference in New Issue
Block a user