mirror of
https://git.savannah.gnu.org/git/guile.git
synced 2025-05-01 04:10:18 +02:00
Optimize %initialize-object
* module/oop/goops.scm (%initialize-object): Optimize by inlining the slot initialization, and by avoiding multiple checks for initargs validity.
This commit is contained in:
parent
2a3ef7c44b
commit
79c2ca26ae
1 changed files with 24 additions and 5 deletions
|
@ -2736,30 +2736,49 @@ function."
|
||||||
(define (%initialize-object obj initargs)
|
(define (%initialize-object obj initargs)
|
||||||
"Initialize the object @var{obj} with the given arguments
|
"Initialize the object @var{obj} with the given arguments
|
||||||
var{initargs}."
|
var{initargs}."
|
||||||
|
(define (valid-initargs? initargs)
|
||||||
|
(match initargs
|
||||||
|
(() #t)
|
||||||
|
(((? keyword?) _ . initargs) (valid-initargs? initargs))
|
||||||
|
(_ #f)))
|
||||||
(unless (instance? obj)
|
(unless (instance? obj)
|
||||||
(scm-error 'wrong-type-arg #f "Not an object: ~S"
|
(scm-error 'wrong-type-arg #f "Not an object: ~S"
|
||||||
(list obj) #f))
|
(list obj) #f))
|
||||||
(unless (even? (length initargs))
|
(unless (valid-initargs? initargs)
|
||||||
(scm-error 'wrong-type-arg #f "Initargs has odd length: ~S"
|
(scm-error 'wrong-type-arg #f "Invalid initargs: ~S"
|
||||||
(list initargs) #f))
|
(list initargs) #f))
|
||||||
(let ((class (class-of obj)))
|
(let ((class (class-of obj)))
|
||||||
(define (get-initarg kw)
|
(define (get-initarg kw)
|
||||||
(if kw
|
(if kw
|
||||||
(get-keyword kw initargs *unbound*)
|
;; Inlined get-keyword to avoid checking initargs for validity
|
||||||
|
;; each time.
|
||||||
|
(let lp ((initargs initargs))
|
||||||
|
(match initargs
|
||||||
|
((kw* val . initargs)
|
||||||
|
(if (eq? kw* kw)
|
||||||
|
val
|
||||||
|
(lp initargs)))
|
||||||
|
(_ *unbound*)))
|
||||||
*unbound*))
|
*unbound*))
|
||||||
(let lp ((slots (struct-ref class class-index-slots)))
|
(let lp ((slots (struct-ref class class-index-slots)))
|
||||||
(match slots
|
(match slots
|
||||||
(() obj)
|
(() obj)
|
||||||
((slot . slots)
|
((slot . slots)
|
||||||
|
(define (initialize-slot! value)
|
||||||
|
(cond
|
||||||
|
((%slot-definition-slot-set! slot)
|
||||||
|
=> (lambda (slot-set!) (slot-set! obj value)))
|
||||||
|
(else
|
||||||
|
(struct-set! obj (%slot-definition-index slot) value))))
|
||||||
(let ((initarg (get-initarg (%slot-definition-init-keyword slot))))
|
(let ((initarg (get-initarg (%slot-definition-init-keyword slot))))
|
||||||
(cond
|
(cond
|
||||||
((not (unbound? initarg))
|
((not (unbound? initarg))
|
||||||
(slot-set! obj (%slot-definition-name slot) initarg))
|
(initialize-slot! initarg))
|
||||||
((%slot-definition-init-thunk slot)
|
((%slot-definition-init-thunk slot)
|
||||||
=> (lambda (init-thunk)
|
=> (lambda (init-thunk)
|
||||||
(unless (memq (slot-definition-allocation slot)
|
(unless (memq (slot-definition-allocation slot)
|
||||||
'(#:class #:each-subclass))
|
'(#:class #:each-subclass))
|
||||||
(slot-set! obj (%slot-definition-name slot) (init-thunk)))))))
|
(initialize-slot! (init-thunk)))))))
|
||||||
(lp slots))))))
|
(lp slots))))))
|
||||||
|
|
||||||
(define-method (initialize (object <object>) initargs)
|
(define-method (initialize (object <object>) initargs)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue