(optional (map name->slot optional))
(rest (and rest (name->slot rest))))
(map (lambda (slot)
- (let* ((name (slot/name slot))
- (dv (default-value-expr structure name)))
+ (let ((name (slot/name slot))
+ (dv (default-value-expr structure slot)))
(cond ((or (memq slot required)
(eq? slot rest))
name)
`(IF (DEFAULT-OBJECT? ,name) ,dv ,name))
(else dv))))
(structure/slots structure)))))))))))
-
+\f
(define (make-constructor structure name lambda-list generate-body)
(let* ((context (structure/context structure))
(tag-expression (close (structure/tag-expression structure) context)))
`(DEFINE (,name ,@lambda-list)
,(generate-body tag-expression)))))
-(define (default-value-expr structure name)
- (let ((context (structure/context structure)))
- `(,(absolute (if (structure/record-type? structure)
- 'RECORD-TYPE-DEFAULT-VALUE
- 'DEFINE-STRUCTURE/DEFAULT-VALUE)
- context)
- ,(close (structure/type-descriptor structure) context)
- ',name)))
+(define (default-value-expr structure slot)
+ (let ((expression (slot/default slot)))
+ ;; Scheme spends a remarkable amount of time fetching and calling
+ ;; the default value procedures. This hack eliminates that time
+ ;; for many uses of DEFINE-STRUCTURE.
+ (if (not (pair? (strip-syntactic-closures expression)))
+ expression
+ (let ((record? (structure/record-type? structure))
+ (context (structure/context structure)))
+ `(,(absolute (if record?
+ 'RECORD-TYPE-DEFAULT-VALUE-BY-INDEX
+ 'DEFINE-STRUCTURE/DEFAULT-VALUE-BY-INDEX)
+ context)
+ ,(close (structure/type-descriptor structure) context)
+ ,(- (slot/index slot)
+ (if record?
+ 0
+ (+ (structure/offset structure)
+ (if (structure/tagged? structure) 1 0)))))))))
\f
(define (copier-definitions structure)
(let ((copier-name (structure/copier structure)))
(vector-set! v i (car values))))))
(define (record-type-default-value record-type field-name)
+ (record-type-default-value-by-index
+ record-type
+ (record-type-field-index record-type field-name #t)))
+
+(define (record-type-default-value-by-index record-type field-name-index)
((vector-ref (%record-type-default-inits record-type)
- (fix:- (record-type-field-index record-type field-name #t) 1))))
+ (fix:- field-name-index 1))))
(define set-record-type-unparser-method!
(named-lambda (set-record-type-unparser-method!/booting record-type method)
(structure-type/field-name-index type field-name)))
(define-integrable (structure-type/default-init type field-name)
- (vector-ref (structure-type/default-inits type)
- (structure-type/field-name-index type field-name)))
+ (structure-type/default-init-by-index
+ type
+ (structure-type/field-name-index type field-name)))
+
+(define-integrable (structure-type/default-init-by-index type field-name-index)
+ (vector-ref (structure-type/default-inits type) field-name-index))
(define (structure-type/field-name-index type field-name)
(let ((names (structure-type/field-names type)))
(define (define-structure/default-value type field-name)
((structure-type/default-init type field-name)))
+(define (define-structure/default-value-by-index type field-name-index)
+ ((structure-type/default-init-by-index type field-name-index)))
+\f
(define (define-structure/keyword-constructor type)
(let ((names (structure-type/field-names type))
(indexes (structure-type/field-indexes type))
%record?
copy-record
define-structure/default-value
+ define-structure/default-value-by-index
define-structure/keyword-constructor
define-structure/list-accessor
define-structure/list-modifier
record-predicate
record-type-default-inits
record-type-default-value
+ record-type-default-value-by-index
record-type-descriptor
record-type-dispatch-tag
record-type-extension