X-Git-Url: http://repo.macrolet.net/gitweb/?a=blobdiff_plain;f=src%2Fcode%2Ftarget-defstruct.lisp;h=2f462ef9f89baa3c00f5b87d3e4bd493900fe6d2;hb=617d4fa1db5a4a11564e7c59bfb684c7eb25633d;hp=5fb9ac18d968e385b0518c668c3526bc1ac71fc6;hpb=4898ef32c639b1c7f4ee13a5ba566ce6debd03e6;p=sbcl.git diff --git a/src/code/target-defstruct.lisp b/src/code/target-defstruct.lisp index 5fb9ac1..2f462ef 100644 --- a/src/code/target-defstruct.lisp +++ b/src/code/target-defstruct.lisp @@ -31,6 +31,15 @@ (defun %instance-set (instance index new-value) (setf (%instance-ref instance index) new-value)) +(defun %instance-compare-and-swap (instance index old new) + #!+(or x86 x86-64) + (%instance-compare-and-swap instance index old new) + #!-(or x86 x86-64) + (let ((n-old (%instance-ref instance index))) + (when (eq old n-old) + (%instance-set instance index new)) + n-old)) + #!-hppa (progn (defun %raw-instance-ref/word (instance index) @@ -71,8 +80,11 @@ (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))) + (%raw-instance-set/complex-double instance index new-value)) +) ; #!-HPPA +#!+hppa +(progn (defun %raw-ref-single (vec index) (declare (type index index)) (%raw-ref-single vec index)) @@ -124,6 +136,7 @@ (defun %raw-set-complex-long (vec index val) (declare (type index index)) (%raw-set-complex-long vec index val)) +) ; #!+HPPA (defun %instance-layout (instance) (%instance-layout instance)) @@ -131,8 +144,8 @@ (defun %set-instance-layout (instance new-value) (%set-instance-layout instance new-value)) -(defun %make-funcallable-instance (len layout) - (%make-funcallable-instance len layout)) +(defun %make-funcallable-instance (len) + (%make-funcallable-instance len)) (defun funcallable-instance-p (x) (funcallable-instance-p x)) @@ -143,38 +156,10 @@ (%set-funcallable-instance-info fin i new-value)) (defun funcallable-instance-fun (fin) - (%funcallable-instance-lexenv fin)) - -;;; The heart of the magic of funcallable instances ("FINs"). The -;;; function for a FIN must be a magical INSTANCE-LAMBDA form. When -;;; called (as with any other function), we grab the code pointer, and -;;; call it, leaving the original function object in LEXENV (in case -;;; it was a closure). If it is actually a FIN, then we need to do an -;;; extra indirection with funcallable-instance-lexenv to get at any -;;; closure environment. This extra indirection is set up when -;;; accessing the closure environment of an INSTANCE-LAMBDA. Note that -;;; the original FIN pointer is lost, so if the called function wants -;;; to get at the original object to do some slot accesses, it must -;;; close over the FIN object. -;;; -;;; If we set the FIN function to be a FIN, we directly copy across -;;; both the code pointer and the lexenv, since that code pointer (for -;;; an instance-lambda) is expecting that lexenv to be accessed. This -;;; effectively pre-flattens what would otherwise be a chain of -;;; indirections. (That used to happen when PCL dispatch functions -;;; were byte-compiled; now that the byte compiler is gone, I can't -;;; think of another example offhand. -- WHN 2001-10-06) -;;; -;;; The only loss is that if someone accesses the -;;; FUNCALLABLE-INSTANCE-FUN, then won't get a FIN back. This probably -;;; doesn't matter, since PCL only sets the FIN function. + (%funcallable-instance-function fin)) + (defun (setf funcallable-instance-fun) (new-value fin) - (setf (%funcallable-instance-fun fin) - (%closure-fun new-value)) - (setf (%funcallable-instance-lexenv fin) - (if (funcallable-instance-p new-value) - (%funcallable-instance-lexenv new-value) - new-value))) + (setf (%funcallable-instance-function fin) new-value)) ;;; service function for structure constructors (defun %make-instance-with-layout (layout) @@ -444,81 +429,85 @@ ;;; default PRINT-OBJECT method +(defun %print-structure-sans-layout-info (name stream) + ;; KLUDGE: during PCL build debugging, we can sometimes + ;; attempt to print out a PCL object (with null LAYOUT-INFO). + (pprint-logical-block (stream nil :prefix "#<" :suffix ">") + (prin1 name stream) + (write-char #\space stream) + (write-string "(no LAYOUT-INFO)" stream))) + +(defun %print-structure-sans-slots (name stream) + ;; the structure type doesn't count as a component for *PRINT-LEVEL* + ;; processing. We can likewise elide the logical block processing, + ;; since all we have to print is the type name. -- CSR, 2004-10-05 + (write-string "#S(" stream) + (prin1 name stream) + (write-char #\) stream)) + (defun %default-structure-pretty-print (structure stream) (let* ((layout (%instance-layout structure)) (name (classoid-name (layout-classoid layout))) (dd (layout-info layout))) - ;; KLUDGE: during the build process with SB-SHOW, we can sometimes - ;; attempt to print out a PCL object (with null LAYOUT-INFO). - #!+sb-show - (when (null dd) - (pprint-logical-block (stream nil :prefix "#<" :suffix ">") - (prin1 name stream) - (write-char #\space stream) - (write-string "(no LAYOUT-INFO)")) - (return-from %default-structure-pretty-print nil)) - ;; the structure type doesn't count as a component for - ;; *PRINT-LEVEL* processing. We can likewise elide the logical - ;; block processing, since all we have to print is the type name. - ;; -- CSR, 2004-10-05 - (when (and dd (null (dd-slots dd))) - (write-string "#S(" stream) - (prin1 name stream) - (write-char #\) stream) - (return-from %default-structure-pretty-print nil)) - (pprint-logical-block (stream nil :prefix "#S(" :suffix ")") - (prin1 name stream) - (let ((remaining-slots (dd-slots dd))) - (when remaining-slots - (write-char #\space stream) - ;; CMU CL had (PPRINT-INDENT :BLOCK 2 STREAM) here, - ;; but I can't see why. -- WHN 20000205 - (pprint-newline :linear stream) - (loop - (pprint-pop) - (let ((slot (pop remaining-slots))) - (write-char #\: stream) - (output-symbol-name (symbol-name (dsd-name slot)) stream) - (write-char #\space stream) - (pprint-newline :miser stream) - (output-object (funcall (fdefinition (dsd-accessor-name slot)) - structure) - stream) - (when (null remaining-slots) - (return)) - (write-char #\space stream) - (pprint-newline :linear stream)))))))) + (cond ((not dd) + (%print-structure-sans-layout-info name stream)) + ((not (dd-slots dd)) + (%print-structure-sans-slots name stream)) + (t + (pprint-logical-block (stream nil :prefix "#S(" :suffix ")") + (prin1 name stream) + (let ((remaining-slots (dd-slots dd))) + (when remaining-slots + (write-char #\space stream) + ;; CMU CL had (PPRINT-INDENT :BLOCK 2 STREAM) here, + ;; but I can't see why. -- WHN 20000205 + (pprint-newline :linear stream) + (loop + (pprint-pop) + (let ((slot (pop remaining-slots))) + (write-char #\: stream) + (output-symbol-name (symbol-name (dsd-name slot)) stream) + (write-char #\space stream) + (pprint-newline :miser stream) + (output-object (funcall (fdefinition (dsd-accessor-name slot)) + structure) + stream) + (when (null remaining-slots) + (return)) + (write-char #\space stream) + (pprint-newline :linear stream)))))))))) + (defun %default-structure-ugly-print (structure stream) (let* ((layout (%instance-layout structure)) (name (classoid-name (layout-classoid layout))) (dd (layout-info layout))) - (when (and dd (null (dd-slots dd))) - (write-string "#S(" stream) - (prin1 name stream) - (write-char #\) stream) - (return-from %default-structure-ugly-print nil)) - (descend-into (stream) - (write-string "#S(" stream) - (prin1 name stream) - (do ((index 0 (1+ index)) - (remaining-slots (dd-slots dd) (cdr remaining-slots))) - ((or (null remaining-slots) - (and (not *print-readably*) - *print-length* - (>= index *print-length*))) - (if (null remaining-slots) - (write-string ")" stream) - (write-string " ...)" stream))) - (declare (type index index)) - (write-char #\space stream) - (write-char #\: stream) - (let ((slot (first remaining-slots))) - (output-symbol-name (symbol-name (dsd-name slot)) stream) - (write-char #\space stream) - (output-object - (funcall (fdefinition (dsd-accessor-name slot)) - structure) - stream)))))) + (cond ((not dd) + (%print-structure-sans-layout-info name stream)) + ((not (dd-slots dd)) + (%print-structure-sans-slots name stream)) + (t + (descend-into (stream) + (write-string "#S(" stream) + (prin1 name stream) + (do ((index 0 (1+ index)) + (remaining-slots (dd-slots dd) (cdr remaining-slots))) + ((or (null remaining-slots) + (and (not *print-readably*) + *print-length* + (>= index *print-length*))) + (if (null remaining-slots) + (write-string ")" stream) + (write-string " ...)" stream))) + (declare (type index index)) + (write-string " :" stream) + (let ((slot (first remaining-slots))) + (output-symbol-name (symbol-name (dsd-name slot)) stream) + (write-char #\space stream) + (output-object + (funcall (fdefinition (dsd-accessor-name slot)) + structure) + stream)))))))) + (defun default-structure-print (structure stream depth) (declare (ignore depth)) (cond ((funcallable-instance-p structure) @@ -527,6 +516,7 @@ (%default-structure-pretty-print structure stream)) (t (%default-structure-ugly-print structure stream)))) + (def!method print-object ((x structure-object) stream) (default-structure-print x stream *current-level-in-print*)) @@ -551,9 +541,7 @@ (when (layout-invalid layout) (error "An obsolete structure accessor function was called.")) (/noshow0 "back from testing LAYOUT-INVALID LAYOUT") - ;; FIXME: CMU CL used (%INSTANCEP OBJ) here. Check that - ;; (TYPEP OBJ 'INSTANCE) is optimized to equally efficient code. - (and (typep obj 'instance) + (and (%instancep obj) (let ((obj-layout (%instance-layout obj))) (cond ((eq obj-layout layout) ;; (In this case OBJ-LAYOUT can't be invalid, because @@ -627,5 +615,6 @@ :datum x :expected-type (classoid-name (layout-classoid layout)))) (values)) + (/show0 "target-defstruct.lisp end of file")