cs: improve error reporting for FFI conversions
Match the error messages from BC.
This commit is contained in:
parent
585f9d8201
commit
ec064bee31
|
@ -329,14 +329,17 @@
|
|||
c-to-racket)]))
|
||||
|
||||
;; Apply all the conversion wrappers of `type` to the Scheme value `v`
|
||||
(define (s->c type v)
|
||||
(define (s->c who type v)
|
||||
(let* ([racket-to-c (ctype-scheme->c type)]
|
||||
[v (if racket-to-c
|
||||
(|#%app| racket-to-c v)
|
||||
(if (and (#%procedure? racket-to-c)
|
||||
(chez:procedure-arity-includes? racket-to-c 2))
|
||||
(racket-to-c who v)
|
||||
(|#%app| racket-to-c v))
|
||||
v)]
|
||||
[next (ctype-basetype type)])
|
||||
(if (ctype? next)
|
||||
(s->c next v)
|
||||
(s->c who next v)
|
||||
v)))
|
||||
|
||||
;; Apply all the conversion wrapper of `type` to the C value `v`
|
||||
|
@ -366,7 +369,7 @@
|
|||
;; foreign-thread regions. Also, the integer checks built into Chez
|
||||
;; Scheme are more permissive than Racket's.
|
||||
|
||||
(define-syntax-rule (checker who ?) (lambda (x) (if (? x) x (bad-ctype-value who x))))
|
||||
(define-syntax-rule (checker who ?) (lambda (for-whom x) (if (? x) x (bad-ctype-value for-whom who x))))
|
||||
(define-syntax integer-checker
|
||||
(syntax-rules (signed unsigned)
|
||||
[(_ who signed n int?) (checker who (lambda (x) (and (int? x) (<= (- (expt 2 (- n 1))) x (- (expt 2 (- n 1)) 1)))))]
|
||||
|
@ -391,10 +394,10 @@
|
|||
(checker who (lambda (x) (or (not x) (string? x)))))
|
||||
(define-ctype _void 'void 'void (checker who void))
|
||||
|
||||
(define (bad-ctype-value type-name v)
|
||||
(raise-arguments-error 'apply
|
||||
"bad value for conversion"
|
||||
"ctype" (make-unquoted-printing-string (symbol->string type-name))
|
||||
(define (bad-ctype-value who type-name v)
|
||||
(raise-arguments-error who
|
||||
"given value does not fit primitive C type"
|
||||
"C type" (make-unquoted-printing-string (symbol->string type-name))
|
||||
"value" v))
|
||||
|
||||
;; Unlike traditional Racket, copies when converting from C:
|
||||
|
@ -465,7 +468,7 @@
|
|||
(loop (fx+ i 4)))))
|
||||
|
||||
(define-ctype _short_bytes 'void* 'bytes
|
||||
(lambda (x) x)
|
||||
(lambda (form-whom x) x)
|
||||
(lambda (x) (let loop ([i 0])
|
||||
(if (fx= 0 (foreign-ref 'unsigned-16 x i))
|
||||
(let ([bstr (make-bytes i)])
|
||||
|
@ -474,37 +477,37 @@
|
|||
(loop (+ i 2))))))
|
||||
|
||||
(define-ctype _double* 'double 'double
|
||||
(lambda (x) (if (real? x)
|
||||
(exact->inexact x)
|
||||
(bad-ctype-value who x))))
|
||||
(lambda (for-whom x) (if (real? x)
|
||||
(exact->inexact x)
|
||||
(bad-ctype-value for-whom who x))))
|
||||
|
||||
(define-ctype _ufixnum 'fixnum 'fixnum (checker who fixnum?)) ; historically, no sign check
|
||||
(define-ctype _fixint 'integer-32 'fixint (checker who fixnum?))
|
||||
(define-ctype _ufixint 'unsigned-32 'ufixint (checker who fixnum?)) ; historically, no sign check
|
||||
|
||||
(define-ctype _symbol 'string 'string
|
||||
(lambda (x) (if (symbol? x)
|
||||
(symbol->string x)
|
||||
(bad-ctype-value who x)))
|
||||
(lambda (for-whom x) (if (symbol? x)
|
||||
(symbol->string x)
|
||||
(bad-ctype-value for-whom who x)))
|
||||
(lambda (s) (string->symbol s)))
|
||||
|
||||
(define-ctype _longdouble 'double 'double
|
||||
(lambda (x) (bad-ctype-value who x)))
|
||||
(lambda (for-whom x) (bad-ctype-value for-whom who x)))
|
||||
|
||||
(define-ctype _pointer 'void* 'pointer
|
||||
(lambda (v) (unwrap-cpointer who v)) ; resolved to an address later (with the GC disabled)
|
||||
(lambda (for-whom v) (unwrap-cpointer for-whom v)) ; resolved to an address later (with the GC disabled)
|
||||
(lambda (x) (memory->cpointer x)))
|
||||
|
||||
;; Treated specially by `ptr-ref`
|
||||
(define-ctype _fpointer 'void* 'fpointer
|
||||
(lambda (v) (unwrap-cpointer who v)) ; resolved to an address later (with the GC disabled)
|
||||
(lambda (for-whom v) (unwrap-cpointer for-whom v)) ; resolved to an address later (with the GC disabled)
|
||||
(lambda (x)
|
||||
(if (ffi-obj? x) ; check for `ptr-ref` special case on `ffi-obj`s
|
||||
x
|
||||
(memory->cpointer x))))
|
||||
|
||||
(define-ctype _gcpointer 'void* 'gcpointer
|
||||
(lambda (v) (unwrap-cpointer who v)) ; like `_pointer`: resolved later
|
||||
(lambda (for-whom v) (unwrap-cpointer for-whom v)) ; like `_pointer`: resolved later
|
||||
(lambda (x)
|
||||
;; `x` must have been converted to a bytevector or vector before
|
||||
;; the GC was re-enabled
|
||||
|
@ -512,7 +515,7 @@
|
|||
|
||||
;; One-byte stdbool is correct on all currently supported platforms, at least:
|
||||
(define-ctype _stdbool 'integer-8 'stdbool
|
||||
(lambda (x) (if x 1 0))
|
||||
(lambda (for-whom x) (if x 1 0))
|
||||
(lambda (v) (not (zero? v))))
|
||||
|
||||
(define make-cstruct-type
|
||||
|
@ -939,7 +942,8 @@
|
|||
[(p type v)
|
||||
(check who cpointer? p)
|
||||
(check who ctype? type)
|
||||
(foreign-set!* type
|
||||
(foreign-set!* who
|
||||
type
|
||||
p
|
||||
0
|
||||
v)]
|
||||
|
@ -947,7 +951,8 @@
|
|||
(check who cpointer? p)
|
||||
(check who ctype? type)
|
||||
(check who exact-integer? offset)
|
||||
(foreign-set!* type
|
||||
(foreign-set!* who
|
||||
type
|
||||
p
|
||||
(* (ctype-sizeof type) offset)
|
||||
v)]
|
||||
|
@ -956,7 +961,8 @@
|
|||
(check who ctype? type)
|
||||
(check who (lambda (p) (eq? p 'abs)) :contract "'abs" abs-tag)
|
||||
(check who exact-integer? offset)
|
||||
(foreign-set!* type
|
||||
(foreign-set!* who
|
||||
type
|
||||
p
|
||||
offset
|
||||
v)]))
|
||||
|
@ -1032,18 +1038,18 @@
|
|||
(define (word-aligned? offset)
|
||||
(zero? (fxand offset (fx- ptr-size-in-bytes 1))))
|
||||
|
||||
(define (foreign-set!* type orig-p offset orig-v)
|
||||
(define (foreign-set!* who type orig-p offset orig-v)
|
||||
(let ([p (unwrap-cpointer 'foreign-set!* orig-p)])
|
||||
(cond
|
||||
[(compound-ctype? type)
|
||||
;; Corresponds to a copy, since `v` is represented by a pointer
|
||||
(memcpy* p offset
|
||||
(s->c type orig-v) 0
|
||||
(s->c who type orig-v) 0
|
||||
(compound-ctype-size type)
|
||||
#f)]
|
||||
[else
|
||||
(let ([host-rep (ctype-host-rep type)]
|
||||
[v (s->c type orig-v)])
|
||||
[v (s->c who type orig-v)])
|
||||
(cond
|
||||
[(cpointer-nonatomic? p)
|
||||
(let ([offset (+ offset (ptr-offset* p))])
|
||||
|
@ -1674,8 +1680,9 @@
|
|||
(let* ([proc-p (unwrap-cpointer 'ffi-call to-wrap)]
|
||||
[proc (and (not (cpointer-needs-lock? proc-p))
|
||||
(gen-proc (cpointer-address proc-p)))]
|
||||
[name (cpointer->name proc-p)]
|
||||
[unwrap (lambda (arg in-type)
|
||||
(let ([c (s->c in-type arg)])
|
||||
(let ([c (s->c name in-type arg)])
|
||||
(if (cpointer? c)
|
||||
(unwrap-cpointer 'ffi-call c)
|
||||
c)))]
|
||||
|
@ -1736,19 +1743,15 @@
|
|||
(when lock (mutex-release lock))
|
||||
(c->s out-type r))))])
|
||||
arity-mask
|
||||
(cpointer->name proc-p)))))]
|
||||
name))))]
|
||||
[else
|
||||
(lambda (to-wrap)
|
||||
(let* ([proc-p (unwrap-cpointer 'ffi-call to-wrap)]
|
||||
#;
|
||||
[name (and (ffi-obj? proc-p) (let ([n (cpointer/ffi-obj-name proc-p)])
|
||||
(if (bytes? n)
|
||||
(utf8->string n)
|
||||
n)))])
|
||||
[name (cpointer->name proc-p)])
|
||||
(do-procedure-reduce-arity-mask
|
||||
(lambda orig-args
|
||||
(let* ([args (map (lambda (orig-arg in-type)
|
||||
(let ([arg (s->c in-type orig-arg)])
|
||||
(let ([arg (s->c name in-type orig-arg)])
|
||||
(if (and (cpointer? arg)
|
||||
(not (eq? 'scheme-object (ctype-host-rep in-type))))
|
||||
(let ([p (unwrap-cpointer 'ffi-call arg)])
|
||||
|
@ -1799,7 +1802,7 @@
|
|||
(go))))])
|
||||
(c->s out-type r)))
|
||||
(fxsll 1 (length in-types))
|
||||
(cpointer->name proc-p))))])]
|
||||
name)))])]
|
||||
[else ; callable
|
||||
(lambda (to-wrap)
|
||||
(gen-proc (lambda args ; if ret-id, includes an extra initial argument to receive the result
|
||||
|
@ -1811,6 +1814,7 @@
|
|||
(when (currently-blocking?)
|
||||
(#%printf "non-async in callback during blocking: ~s\n" to-wrap)))
|
||||
(s->c
|
||||
'callback
|
||||
out-type
|
||||
(apply to-wrap
|
||||
(let loop ([args (if ret-id (cdr args) args)] [in-types in-types])
|
||||
|
|
Loading…
Reference in New Issue
Block a user