Add missing fender to define-cstruct

prevents internal error from libffi for
(define-cstruct _S ())
This commit is contained in:
Tobias Hammer 2013-08-27 17:15:46 +02:00 committed by Matthew Flatt
parent 0e02b7e368
commit 0b1f96ab3d
4 changed files with 20 additions and 13 deletions

View File

@ -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:

View File

@ -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

View File

@ -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);

View File

@ -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);