Add missing fender to define-cstruct
prevents internal error from libffi for (define-cstruct _S ())
This commit is contained in:
parent
0e02b7e368
commit
0b1f96ab3d
|
@ -946,7 +946,7 @@ string carries its size information.}
|
||||||
|
|
||||||
@section{C Struct Types}
|
@section{C Struct Types}
|
||||||
|
|
||||||
@defproc[(make-cstruct-type [types (listof ctype?)]
|
@defproc[(make-cstruct-type [types (non-empty-listof ctype?)]
|
||||||
[abi (or/c #f 'default 'stdcall 'sysv) #f]
|
[abi (or/c #f 'default 'stdcall 'sysv) #f]
|
||||||
[alignment (or/c #f 1 2 4 8 16) #f])
|
[alignment (or/c #f 1 2 4 8 16) #f])
|
||||||
ctype?]{
|
ctype?]{
|
||||||
|
@ -980,7 +980,7 @@ below for a more efficient approach.}
|
||||||
|
|
||||||
@defform/subs[(define-cstruct id/sup ([field-id type-expr] ...) property ...)
|
@defform/subs[(define-cstruct id/sup ([field-id type-expr] ...) property ...)
|
||||||
[(id/sup _id
|
[(id/sup _id
|
||||||
(_id super-id))
|
(_id _super-id))
|
||||||
(property (code:line #:alignment alignment-expr)
|
(property (code:line #:alignment alignment-expr)
|
||||||
(code:line #:property prop-expr val-expr)
|
(code:line #:property prop-expr val-expr)
|
||||||
#:no-equal)]]{
|
#:no-equal)]]{
|
||||||
|
@ -991,7 +991,8 @@ marshaling them to Racket values. The syntax is similar to
|
||||||
@racket[define-struct], providing accessor functions for raw struct
|
@racket[define-struct], providing accessor functions for raw struct
|
||||||
values (which are pointer objects); the @racket[_id]
|
values (which are pointer objects); the @racket[_id]
|
||||||
must start with @litchar{_}, and at most one @racket[#:alignment]
|
must start with @litchar{_}, and at most one @racket[#:alignment]
|
||||||
can be supplied.
|
can be supplied. If no @racket[_super-id] is provided, then at least one
|
||||||
|
field must be specified.
|
||||||
|
|
||||||
The resulting bindings are as follows:
|
The resulting bindings are as follows:
|
||||||
|
|
||||||
|
|
|
@ -1315,10 +1315,11 @@
|
||||||
|
|
||||||
;; Simple structs: call this with a list of types, and get a type that marshals
|
;; Simple structs: call this with a list of types, and get a type that marshals
|
||||||
;; C structs to/from Scheme lists.
|
;; C structs to/from Scheme lists.
|
||||||
(define* (_list-struct #:alignment [alignment #f] . types)
|
(define* (_list-struct #:alignment [alignment #f] type . types)
|
||||||
(let ([stype (make-cstruct-type types #f alignment)]
|
(let ([stype (make-cstruct-type types #f alignment)]
|
||||||
[offsets (compute-offsets types alignment)]
|
[offsets (compute-offsets types alignment)]
|
||||||
[len (length types)])
|
[len (add1 (length types))]
|
||||||
|
[types (cons type types)])
|
||||||
(make-ctype stype
|
(make-ctype stype
|
||||||
(lambda (vals)
|
(lambda (vals)
|
||||||
(unless (list? vals)
|
(unless (list? vals)
|
||||||
|
@ -1588,6 +1589,8 @@
|
||||||
stx xs))
|
stx xs))
|
||||||
(syntax-case stx ()
|
(syntax-case stx ()
|
||||||
[(_ type ([slot slot-type] ...) . more)
|
[(_ type ([slot slot-type] ...) . more)
|
||||||
|
(or (stx-pair? #'type)
|
||||||
|
(stx-pair? #'(slot ...)))
|
||||||
(let-values ([(_TYPE _SUPER)
|
(let-values ([(_TYPE _SUPER)
|
||||||
(syntax-case #'type ()
|
(syntax-case #'type ()
|
||||||
[(t s) (values #'t #'s)]
|
[(t s) (values #'t #'s)]
|
||||||
|
@ -1629,13 +1632,13 @@
|
||||||
#'x)]
|
#'x)]
|
||||||
[else (err "bad syntax")]))])
|
[else (err "bad syntax")]))])
|
||||||
(unless (identifier? _TYPE)
|
(unless (identifier? _TYPE)
|
||||||
(err "bad type, expecting a _name identifier or (_name super-ctype)"
|
(err "expecting a `_name' identifier or `(_name _super-name)'"
|
||||||
_TYPE))
|
_TYPE))
|
||||||
(unless (regexp-match? #rx"^_." (symbol->string (syntax-e _TYPE)))
|
(unless (regexp-match? #rx"^_." (symbol->string (syntax-e _TYPE)))
|
||||||
(err "cstruct name must begin with a `_'" _TYPE))
|
(err "cstruct name must begin with a `_'" _TYPE))
|
||||||
(for ([s (in-list (syntax->list #'(slot ...)))])
|
(for ([s (in-list (syntax->list #'(slot ...)))])
|
||||||
(unless (identifier? s)
|
(unless (identifier? s)
|
||||||
(err "bad field name, expecting an identifier identifier" s)))
|
(err "bad field name, expecting an identifier" s)))
|
||||||
(if _SUPER
|
(if _SUPER
|
||||||
(make-syntax _TYPE #t
|
(make-syntax _TYPE #t
|
||||||
#`(#,(datum->syntax _TYPE 'super _TYPE) slot ...)
|
#`(#,(datum->syntax _TYPE 'super _TYPE) slot ...)
|
||||||
|
@ -1646,13 +1649,16 @@
|
||||||
no-equal?)
|
no-equal?)
|
||||||
(make-syntax _TYPE #f #'(slot ...) #`(slot-type ...)
|
(make-syntax _TYPE #f #'(slot ...) #`(slot-type ...)
|
||||||
alignment properties property-bindings no-equal?)))]
|
alignment properties property-bindings no-equal?)))]
|
||||||
|
[(_ type () . more)
|
||||||
|
(identifier? #'type)
|
||||||
|
(err "must have either a supertype or at least one field")]
|
||||||
;; specific errors for bad slot specs, leave the rest for a generic error
|
;; specific errors for bad slot specs, leave the rest for a generic error
|
||||||
[(_ type (bad ...) . more)
|
[(_ type (bad ...) . more)
|
||||||
(err "bad slot specification, expecting [name ctype]"
|
(err "bad field specification, expecting `[name ctype]'"
|
||||||
(ormap (lambda (s) (syntax-case s () [[n ct] #t] [_ s]))
|
(ormap (lambda (s) (syntax-case s () [[n ct] #t] [_ s]))
|
||||||
(syntax->list #'(bad ...))))]
|
(syntax->list #'(bad ...))))]
|
||||||
[(_ type bad . more)
|
[(_ type bad . more)
|
||||||
(err "bad slot specification, expecting a sequence of [name ctype]"
|
(err "bad field specification, expecting a sequence of `[name ctype]'"
|
||||||
#'bad)]))
|
#'bad)]))
|
||||||
|
|
||||||
;; Add `prop:equal+hash' to use pointer equality
|
;; Add `prop:equal+hash' to use pointer equality
|
||||||
|
|
|
@ -1281,7 +1281,7 @@ static Scheme_Object *foreign_make_cstruct_type(int argc, Scheme_Object *argv[])
|
||||||
int i, nargs, with_alignment;
|
int i, nargs, with_alignment;
|
||||||
ffi_abi abi;
|
ffi_abi abi;
|
||||||
nargs = scheme_proper_list_length(argv[0]);
|
nargs = scheme_proper_list_length(argv[0]);
|
||||||
if (nargs < 0) scheme_wrong_contract(MYNAME, "list?", 0, argc, argv);
|
if (nargs <= 0) scheme_wrong_contract(MYNAME, "(non-empty-listof ctype?)", 0, argc, argv);
|
||||||
abi = GET_ABI(MYNAME,1);
|
abi = GET_ABI(MYNAME,1);
|
||||||
if (argc > 2) {
|
if (argc > 2) {
|
||||||
if (!SCHEME_FALSEP(argv[2])) {
|
if (!SCHEME_FALSEP(argv[2])) {
|
||||||
|
@ -1301,7 +1301,7 @@ static Scheme_Object *foreign_make_cstruct_type(int argc, Scheme_Object *argv[])
|
||||||
elements[nargs] = NULL;
|
elements[nargs] = NULL;
|
||||||
for (i=0, p=argv[0]; i<nargs; i++, p=SCHEME_CDR(p)) {
|
for (i=0, p=argv[0]; i<nargs; i++, p=SCHEME_CDR(p)) {
|
||||||
if (NULL == (base = get_ctype_base(SCHEME_CAR(p))))
|
if (NULL == (base = get_ctype_base(SCHEME_CAR(p))))
|
||||||
scheme_wrong_contract(MYNAME, "(listof ctype?)", 0, argc, argv);
|
scheme_wrong_contract(MYNAME, "(non-empty-listof ctype?)", 0, argc, argv);
|
||||||
if (CTYPE_PRIMLABEL(base) == FOREIGN_void)
|
if (CTYPE_PRIMLABEL(base) == FOREIGN_void)
|
||||||
wrong_void(MYNAME, SCHEME_CAR(p), 1, 0, argc, argv);
|
wrong_void(MYNAME, SCHEME_CAR(p), 1, 0, argc, argv);
|
||||||
elements[i] = CTYPE_PRIMTYPE(base);
|
elements[i] = CTYPE_PRIMTYPE(base);
|
||||||
|
|
|
@ -1107,7 +1107,7 @@ static void wrong_void(const char *who, Scheme_Object *list_element, int specifi
|
||||||
int i, nargs, with_alignment;
|
int i, nargs, with_alignment;
|
||||||
ffi_abi abi;
|
ffi_abi abi;
|
||||||
nargs = scheme_proper_list_length(argv[0]);
|
nargs = scheme_proper_list_length(argv[0]);
|
||||||
if (nargs < 0) scheme_wrong_contract(MYNAME, "list?", 0, argc, argv);
|
if (nargs <= 0) scheme_wrong_contract(MYNAME, "(non-empty-listof ctype?)", 0, argc, argv);
|
||||||
abi = GET_ABI(MYNAME,1);
|
abi = GET_ABI(MYNAME,1);
|
||||||
if (argc > 2) {
|
if (argc > 2) {
|
||||||
if (!SCHEME_FALSEP(argv[2])) {
|
if (!SCHEME_FALSEP(argv[2])) {
|
||||||
|
@ -1127,7 +1127,7 @@ static void wrong_void(const char *who, Scheme_Object *list_element, int specifi
|
||||||
elements[nargs] = NULL;
|
elements[nargs] = NULL;
|
||||||
for (i=0, p=argv[0]; i<nargs; i++, p=SCHEME_CDR(p)) {
|
for (i=0, p=argv[0]; i<nargs; i++, p=SCHEME_CDR(p)) {
|
||||||
if (NULL == (base = get_ctype_base(SCHEME_CAR(p))))
|
if (NULL == (base = get_ctype_base(SCHEME_CAR(p))))
|
||||||
scheme_wrong_contract(MYNAME, "(listof ctype?)", 0, argc, argv);
|
scheme_wrong_contract(MYNAME, "(non-empty-listof ctype?)", 0, argc, argv);
|
||||||
if (CTYPE_PRIMLABEL(base) == FOREIGN_void)
|
if (CTYPE_PRIMLABEL(base) == FOREIGN_void)
|
||||||
wrong_void(MYNAME, SCHEME_CAR(p), 1, 0, argc, argv);
|
wrong_void(MYNAME, SCHEME_CAR(p), 1, 0, argc, argv);
|
||||||
elements[i] = CTYPE_PRIMTYPE(base);
|
elements[i] = CTYPE_PRIMTYPE(base);
|
||||||
|
|
Loading…
Reference in New Issue
Block a user