X-Git-Url: http://repo.macrolet.net/gitweb/?a=blobdiff_plain;ds=sidebyside;f=src%2Fcode%2Ftarget-defstruct.lisp;h=0e5742f9f7884f05932f051300a86e4adf9b4650;hb=18dc0069cd514c976042766ab9a785c970fe1603;hp=f179459a85bd96ef77485f38bf886efa4146adca;hpb=c55397520c6238fb878bb80ed6687da1700b66ca;p=sbcl.git diff --git a/src/code/target-defstruct.lisp b/src/code/target-defstruct.lisp index f179459..0e5742f 100644 --- a/src/code/target-defstruct.lisp +++ b/src/code/target-defstruct.lisp @@ -31,103 +31,68 @@ (defun %instance-set (instance index new-value) (setf (%instance-ref instance index) new-value)) -#!-hppa -(progn - (defun %raw-instance-ref/word (instance index) - (declare (type index index)) - (%raw-instance-ref/word instance index)) - (defun %raw-instance-set/word (instance index new-value) - (declare (type index index) - (type sb!vm:word new-value)) - (%raw-instance-set/word instance index new-value)) - - (defun %raw-instance-ref/single (instance index) - (declare (type index index)) - (%raw-instance-ref/single instance index)) - (defun %raw-instance-set/single (instance index new-value) - (declare (type index index) - (type single-float new-value)) - (%raw-instance-set/single instance index new-value)) - - (defun %raw-instance-ref/double (instance index) - (declare (type index index)) - (%raw-instance-ref/double instance index)) - (defun %raw-instance-set/double (instance index new-value) - (declare (type index index) - (type double-float new-value)) - (%raw-instance-set/double instance index new-value)) - - (defun %raw-instance-ref/complex-single (instance index) - (declare (type index index)) - (%raw-instance-ref/complex-single instance index)) - (defun %raw-instance-set/complex-single (instance index new-value) - (declare (type index index) - (type (complex single-float) new-value)) - (%raw-instance-set/complex-single instance index new-value)) - - (defun %raw-instance-ref/complex-double (instance index) - (declare (type index index)) - (%raw-instance-ref/complex-double instance index)) - (defun %raw-instance-set/complex-double (instance index new-value) - (declare (type index index) - (type (complex double-float) new-value)) - (%raw-instance-set/complex-double instance index new-value)) -) ; #!-HPPA - -#!+hppa -(progn -(defun %raw-ref-single (vec index) +;;; Normally IR2 converted, definition needed for interpreted structure +;;; constructors only. +#!+sb-eval +(defun %make-structure-instance (dd slot-specs &rest slot-values) + (let ((instance (%make-instance (dd-instance-length dd)))) + (setf (%instance-layout instance) (dd-layout-or-lose dd)) + (mapc (lambda (spec value) + (destructuring-bind (raw-type . index) (cdr spec) + (macrolet ((make-case () + `(ecase raw-type + ((t) + (setf (%instance-ref instance index) value)) + ,@(mapcar + (lambda (rsd) + `(,(raw-slot-data-raw-type rsd) + (setf (,(raw-slot-data-accessor-name rsd) + instance index) + value))) + *raw-slot-data-list*)))) + (make-case)))) + slot-specs slot-values) + instance)) + +(defun %raw-instance-ref/word (instance index) (declare (type index index)) - (%raw-ref-single vec index)) + (%raw-instance-ref/word instance index)) +(defun %raw-instance-set/word (instance index new-value) + (declare (type index index) + (type sb!vm:word new-value)) + (%raw-instance-set/word instance index new-value)) -(defun %raw-ref-double (vec index) +(defun %raw-instance-ref/single (instance index) (declare (type index index)) - (%raw-ref-double vec index)) + (%raw-instance-ref/single instance index)) +(defun %raw-instance-set/single (instance index new-value) + (declare (type index index) + (type single-float new-value)) + (%raw-instance-set/single instance index new-value)) -#!+long-float -(defun %raw-ref-long (vec index) +(defun %raw-instance-ref/double (instance index) (declare (type index index)) - (%raw-ref-long vec index)) + (%raw-instance-ref/double instance index)) +(defun %raw-instance-set/double (instance index new-value) + (declare (type index index) + (type double-float new-value)) + (%raw-instance-set/double instance index new-value)) -(defun %raw-set-single (vec index val) +(defun %raw-instance-ref/complex-single (instance index) (declare (type index index)) - (%raw-set-single vec index val)) + (%raw-instance-ref/complex-single instance index)) +(defun %raw-instance-set/complex-single (instance index new-value) + (declare (type index index) + (type (complex single-float) new-value)) + (%raw-instance-set/complex-single instance index new-value)) -(defun %raw-set-double (vec index val) +(defun %raw-instance-ref/complex-double (instance index) (declare (type index index)) - (%raw-set-double vec index val)) - -#!+long-float -(defun %raw-set-long (vec index val) - (declare (type index index)) - (%raw-set-long vec index val)) - -(defun %raw-ref-complex-single (vec index) - (declare (type index index)) - (%raw-ref-complex-single vec index)) - -(defun %raw-ref-complex-double (vec index) - (declare (type index index)) - (%raw-ref-complex-double vec index)) - -#!+long-float -(defun %raw-ref-complex-long (vec index) - (declare (type index index)) - (%raw-ref-complex-long vec index)) - -(defun %raw-set-complex-single (vec index val) - (declare (type index index)) - (%raw-set-complex-single vec index val)) - -(defun %raw-set-complex-double (vec index val) - (declare (type index index)) - (%raw-set-complex-double vec index val)) - -#!+long-float -(defun %raw-set-complex-long (vec index val) - (declare (type index index)) - (%raw-set-complex-long vec index val)) -) ; #!+HPPA + (%raw-instance-ref/complex-double instance index)) +(defun %raw-instance-set/complex-double (instance index new-value) + (declare (type index index) + (type (complex double-float) new-value)) + (%raw-instance-set/complex-double instance index new-value)) (defun %instance-layout (instance) (%instance-layout instance)) @@ -138,7 +103,11 @@ (defun %make-funcallable-instance (len) (%make-funcallable-instance len)) -(defun funcallable-instance-p (x) (funcallable-instance-p x)) +(defun funcallable-instance-p (x) + (funcallable-instance-p x)) + +(deftype funcallable-instance () + `(satisfies funcallable-instance-p)) (defun %funcallable-instance-info (fin i) (%funcallable-instance-info fin i)) @@ -151,19 +120,6 @@ (defun (setf funcallable-instance-fun) (new-value fin) (setf (%funcallable-instance-function fin) new-value)) - -;;; service function for structure constructors -(defun %make-instance-with-layout (layout) - ;; Make sure the object ends at a two-word boundary. Note that this does - ;; not affect the amount of memory used, since the allocator would add the - ;; same padding anyway. However, raw slots are indexed from the length of - ;; the object as indicated in the header, so the pad word needs to be - ;; included in that length to guarantee proper alignment of raw double float - ;; slots, necessary for (at least) the SPARC backend. - (let* ((length (layout-length layout)) - (result (%make-instance (+ length (mod (1+ length) 2))))) - (setf (%instance-layout result) layout) - result)) ;;;; target-only parts of the DEFSTRUCT top level code @@ -183,6 +139,36 @@ (/show0 "leaving PROTECT-CL") (values)) +(defun make-defstruct-predicate (dd layout) + (ecase (dd-type dd) + ;; structures with LAYOUTs + ((structure funcallable-structure) + (/show0 "with-LAYOUT case") + #'(lambda (object) + (locally ; <- to keep SAFETY 0 from affecting arg count checking + (declare (optimize (speed 3) (safety 0))) + (/noshow0 "in with-LAYOUT structure predicate closure,") + (/noshow0 " OBJECT,LAYOUT=..") + (/nohexstr object) + (/nohexstr layout) + (typep-to-layout object layout)))) + ;; structures with no LAYOUT (i.e. :TYPE VECTOR or :TYPE LIST) + ;; + ;; FIXME: should handle the :NAMED T case in these cases + (vector + (/show0 ":TYPE VECTOR case") + #'vectorp) + (list + (/show0 ":TYPE LIST case") + #'listp))) + +(defun make-defstruct-copier (dd layout) + (ecase (dd-type dd) + (structure + #'(lambda (instance) + (%check-structure-type-from-layout instance layout) + (copy-structure instance))))) + ;;; the part of %DEFSTRUCT which makes sense only on the target SBCL ;;; ;;; (The "static" in the name is because it needs to be done not only @@ -232,34 +218,14 @@ ;; (And funcallable instances don't need copiers anyway.) (aver (eql (dd-type dd) 'structure)) (setf (symbol-function (dd-copier-name dd)) - ;; FIXME: should use a closure which checks arg type before copying - #'copy-structure)) + (make-defstruct-copier dd layout))) ;; Set FDEFINITION for predicate. (when (dd-predicate-name dd) (/show0 "doing FDEFINITION for predicate") (protect-cl (dd-predicate-name dd)) (setf (symbol-function (dd-predicate-name dd)) - (ecase (dd-type dd) - ;; structures with LAYOUTs - ((structure funcallable-structure) - (/show0 "with-LAYOUT case") - (lambda (object) - (locally ; <- to keep SAFETY 0 from affecting arg count checking - (declare (optimize (speed 3) (safety 0))) - (/noshow0 "in with-LAYOUT structure predicate closure, OBJECT,LAYOUT=..") - (/nohexstr object) - (/nohexstr layout) - (typep-to-layout object layout)))) - ;; structures with no LAYOUT (i.e. :TYPE VECTOR or :TYPE LIST) - ;; - ;; FIXME: should handle the :NAMED T case in these cases - (vector - (/show0 ":TYPE VECTOR case") - #'vectorp) - (list - (/show0 ":TYPE LIST case") - #'listp)))) + (make-defstruct-predicate dd layout))) (when (dd-doc dd) (setf (fdocumentation (dd-name dd) 'structure) @@ -395,16 +361,16 @@ #!+sb-doc "Return a copy of STRUCTURE with the same (EQL) slot values." (declare (type structure-object structure)) - (let* ((len (%instance-length structure)) - (res (%make-instance len)) - (layout (%instance-layout structure)) + (let* ((layout (%instance-layout structure)) + (res (%make-instance (%instance-length structure))) + (len (layout-length layout)) (nuntagged (layout-n-untagged-slots layout))) (declare (type index len)) (when (layout-invalid layout) (error "attempt to copy an obsolete structure:~% ~S" structure)) - ;; Copy ordinary slots. + ;; Copy ordinary slots and layout. (dotimes (i (- len nuntagged)) (declare (type index i)) (setf (%instance-ref res i) @@ -428,20 +394,14 @@ ;; all this with %RAW-INSTANCE-REF/WORD and bitwise comparisons, but ;; that'll fail in some cases. For example -0.0 and 0.0 are EQUALP ;; but have different bit patterns. -- JES, 2007-08-21 - (loop with i = -1 - for dsd in (dd-slots (layout-info layout)) + (loop for dsd in (dd-slots (layout-info layout)) for raw-type = (dsd-raw-type dsd) - for rsd = (when raw-type + for rsd = (unless (eql raw-type t) (find raw-type *raw-slot-data-list* :key 'raw-slot-data-raw-type)) - for accessor = (when rsd - (raw-slot-data-accessor-name rsd)) - always (or (not accessor) - (progn - (incf i) - (equalp (funcall accessor x i) - (funcall accessor y i)))))) + always (or (not rsd) + (funcall (raw-slot-data-comparer rsd) (dsd-index dsd) x y)))) ;;; default PRINT-OBJECT method @@ -555,28 +515,25 @@ (/nohexstr obj) (/nohexstr layout) (when (layout-invalid layout) - (error "An obsolete structure accessor function was called.")) + (error "An obsolete structure typecheck function was called.")) (/noshow0 "back from testing LAYOUT-INVALID LAYOUT") (and (%instancep obj) (let ((obj-layout (%instance-layout obj))) - (cond ((eq obj-layout layout) - ;; (In this case OBJ-LAYOUT can't be invalid, because - ;; we determined LAYOUT is valid in the test above.) - (/noshow0 "EQ case") - t) - ((layout-invalid obj-layout) - (/noshow0 "LAYOUT-INVALID case") - (error 'layout-invalid - :expected-type (layout-classoid obj-layout) - :datum obj)) - (t - (let ((depthoid (layout-depthoid layout))) - (/noshow0 "DEPTHOID case, DEPTHOID,LAYOUT-INHERITS=..") - (/nohexstr depthoid) - (/nohexstr layout-inherits) - (and (> (layout-depthoid obj-layout) depthoid) - (eq (svref (layout-inherits obj-layout) depthoid) - layout)))))))) + (when (eq obj-layout layout) + ;; (In this case OBJ-LAYOUT can't be invalid, because + ;; we determined LAYOUT is valid in the test above.) + (/noshow0 "EQ case") + (return-from typep-to-layout t)) + (when (layout-invalid obj-layout) + (/noshow0 "LAYOUT-INVALID case") + (setf obj-layout (update-object-layout-or-invalid obj layout))) + (let ((depthoid (layout-depthoid layout))) + (/noshow0 "DEPTHOID case, DEPTHOID,LAYOUT-INHERITS=..") + (/nohexstr depthoid) + (/nohexstr layout-inherits) + (and (> (layout-depthoid obj-layout) depthoid) + (eq (svref (layout-inherits obj-layout) depthoid) + layout)))))) ;;;; checking structure types