mirror of
git://git.code.sf.net/p/sbcl/sbcl
synced 2026-09-10 07:26:40 -04:00
Preserve COMPILE-FILE's argument & *D-P-D* through to fasls.
This consists of (a) splitting one slot into two, albeit in 3 different structures; and (b) having the old source namestring accessors obey a new variable. * FILE-INFO's old UNTRUENAME is now PATHNAME-1 and PATHNAME-2. The first is the original argument (with the type filled in), and the second is *D-P-D* if merging contributes anything to PATHNAME-1. * DEBUG-SOURCE and SOURCE-LOCATION now have corresponding NAMESTRING-1 and NAMESTRING-2 slots, with equivalent purpose except when we're supposed to be storing *SOURCE-NAMESTRING*. * The new variable SB-EXT:*SOURCE-FILE-DEFAULTING* influences what namestring introspection functions return. If it's NIL, they return NAMESTRING-1. If it's :DEFAULT, they return the (equivalent of) merging NAMESTRING-1 with NAMESTRING-2. N.B., this removes the recently added SB-C::*MERGE-PATHNAMES*, since now it's not a question what information to store at compile time, but whether to return merged or unmerged results at inquiry time.
This commit is contained in:
parent
d7d3f820b4
commit
ed585f7386
|
|
@ -63,9 +63,8 @@ echo //doing warm init - load and dump phase
|
|||
(progn ${devel})
|
||||
(sb-fasl::!warm-load "make-target-2-load.lisp")
|
||||
(setf (extern-alien "gc_coalesce_string_literals" char) 2)
|
||||
;;; Use the historical (bad) convention for *compile-file-pathname*
|
||||
(setf sb-c::*merge-pathnames* t)
|
||||
;;; and for storing pathname namestrings in fasls too.
|
||||
;;; Use the historical (bad) convention for storing pathname
|
||||
;;; namestrings in fasls.
|
||||
(setq sb-c::*name-context-file-path-selector* 'truename)
|
||||
(let ((sb-ext:*invoke-debugger-hook* (prog1 sb-ext:*invoke-debugger-hook* (sb-ext:enable-debugger))))
|
||||
(sb-ext:save-lisp-and-die "output/sbcl.core"))
|
||||
|
|
|
|||
|
|
@ -940,6 +940,7 @@ like *STACK-TOP-HINT* and unsupported stuff like *TRACED-FUN-LIST*."
|
|||
"PRINT-SYMBOL-WITH-PREFIX"
|
||||
"*PRINT-VECTOR-LENGTH*"
|
||||
"DECIMAL-WITH-GROUPED-DIGITS-WIDTH"
|
||||
"*SOURCE-FILE-DEFAULTING*"
|
||||
;;"OBJECT-SIZE"
|
||||
|
||||
;; stepping interface
|
||||
|
|
|
|||
|
|
@ -384,12 +384,42 @@
|
|||
(:copier nil))
|
||||
;; When the DEBUG-SOURCE describes a file, the file's namestring.
|
||||
;; Otherwise, NIL.
|
||||
(namestring nil :type (or null string))
|
||||
(namestring-1 nil :type (or null string))
|
||||
;; When NAMESTRING-1 is relative, the namestring of the pathname
|
||||
;; relative to which NAMESTRING-1 named a file at COMPILE-FILE
|
||||
;; time.
|
||||
(namestring-2 nil :type (or null string))
|
||||
;; the universal time that the source was written, or NIL if
|
||||
;; unavailable
|
||||
(created nil :type (or unsigned-byte null))
|
||||
;; Additional information from (WITH-COMPILATION-UNIT (:SOURCE-PLIST ...))
|
||||
(plist *source-plist* :read-only t))
|
||||
|
||||
(declaim (type (or (member nil :default) pathname)))
|
||||
(defvar *source-file-defaulting* :default
|
||||
"Influences how introspection routines return namestrings for source
|
||||
files originally compiled using relative pathname designators. One of
|
||||
NIL (return the relative namestring), :DEFAULT (return the namestring
|
||||
of the defaulted pathname at compile-time).")
|
||||
|
||||
(defun maybe-reconstitute-namestring (namestring-1 namestring-2
|
||||
&optional (mode *source-file-defaulting*))
|
||||
(cond ((null mode)
|
||||
namestring-1)
|
||||
((eql :default mode)
|
||||
;; If NAMESTRING-2 is NIL, there's a chance
|
||||
;; NAMESTRING-1's syntax will be ambiguous in the dynamic
|
||||
;; environment where someone is calling this. (This is
|
||||
;; probably why we used to only dump absolute names.) Nothing
|
||||
;; much we can do about that, though.
|
||||
(concatenate 'string (or namestring-2 "") namestring-1))))
|
||||
|
||||
;; This used to be an accessor, but now it obeys
|
||||
;; *SOURCE-FILE-DEFAULTING*.
|
||||
(defun debug-source-namestring (debug-source)
|
||||
(maybe-reconstitute-namestring
|
||||
(debug-source-namestring-1 debug-source)
|
||||
(debug-source-namestring-2 debug-source)))
|
||||
|
||||
;;;; DEBUG-INFO structures
|
||||
|
||||
|
|
@ -446,11 +476,13 @@
|
|||
(truename nil :type (or pathname null (eql :lisp)))
|
||||
;; the external format that we'll call OPEN with, if NAME is a file.
|
||||
(external-format nil :read-only t)
|
||||
;; the defaulted, but not necessarily absolute file name (i.e. prior
|
||||
;; to TRUENAME call.) Null if not a file. This is used to set
|
||||
;; *COMPILE-FILE-PATHNAME*, and if absolute (a harmful constraint to be sure),
|
||||
;; is dumped in the debug-info.
|
||||
(pathname nil :type (or pathname null) :read-only t)
|
||||
;; the defaulted, but not necessarily absolute file name. Null if not a file.
|
||||
(pathname-1 nil :type (or pathname null) :read-only t)
|
||||
;; the *DEFAULT-PATHNAME-DEFAULTS* used to open the file in
|
||||
;; COMPILE-FILE, or NIL if merging that with PATHNAME doesn't make a
|
||||
;; difference. Gets stored in the fasl so that users can optionally
|
||||
;; reconstruct the compile-time pathname later.
|
||||
(pathname-2 nil :type (or pathname null) :read-only t)
|
||||
;; the file's write date (if relevant)
|
||||
(write-date nil :type (or unsigned-byte null) :read-only t)
|
||||
;; parallel vectors containing the forms read out of the file and
|
||||
|
|
|
|||
|
|
@ -11,22 +11,37 @@
|
|||
|
||||
(in-package "SB-C")
|
||||
|
||||
;;; Some uses of source locations want absolute filenames that were
|
||||
;;; (implicitly) involved at compile- or load-time, some want relative
|
||||
;;; filenames, and some want absolute filenames derived from runtime
|
||||
;;; state. In order to keep the DEFINITION-SOURCE-LOCATION structure
|
||||
;;; small, we separate out the filename pieces to its own record.
|
||||
(def!struct (definition-source-location-filenames
|
||||
(:constructor %make-definition-source-location-filenames
|
||||
(namestring-1 namestring-2)))
|
||||
;; Namestring (often not always relative) of the source file that the
|
||||
;; definition was compiled from. This is null if the definition was
|
||||
;; not compiled from a file.
|
||||
(namestring-1 nil :type (or string null) :read-only t)
|
||||
;; Either null or the namestring relative to which NAMESTRING-1 named
|
||||
;; a file at compile-file-time.
|
||||
(namestring-2 nil :type (or string null) :read-only t))
|
||||
(!set-load-form-method definition-source-location-filenames (:xc :target))
|
||||
|
||||
;;; A DEFINITION-SOURCE-LOCATION contains two packed fixnums in the INDICES slot,
|
||||
;;; and unless there is a non-nil plist, does not store the plist.
|
||||
;;; Packed representation is: header + layout, namestring, indices, (padding)
|
||||
(def!struct (definition-source-location
|
||||
(:constructor %make-basic-definition-source-location
|
||||
(namestring indices))
|
||||
(filenames indices))
|
||||
(:copier nil))
|
||||
;; Namestring of the source file that the definition was compiled from.
|
||||
;; This is null if the definition was not compiled from a file.
|
||||
(namestring nil :type (or string null) :read-only t)
|
||||
(filenames nil :type (or null definition-source-location-filenames) :read-only t)
|
||||
(indices 0 :type integer :read-only t))
|
||||
(!set-load-form-method definition-source-location (:xc :target))
|
||||
(def!struct (definition-source-location+plist
|
||||
(:include definition-source-location)
|
||||
(:constructor %make-full-definition-source-location
|
||||
(namestring indices plist))
|
||||
(filenames indices plist))
|
||||
(:copier nil))
|
||||
(plist nil :read-only t))
|
||||
|
||||
|
|
@ -48,7 +63,15 @@
|
|||
'definition-source-location+plist)
|
||||
(definition-source-location+plist-plist source-loc)))
|
||||
|
||||
(defun %make-definition-source-location (namestring tlf-num subform-num)
|
||||
;; This used to be an accessor, but now it obeys
|
||||
;; *SOURCE-NAMESTRING-DEFAULTING*.
|
||||
(defun definition-source-location-namestring (source-loc)
|
||||
(let* ((filenames (definition-source-location-filenames source-loc))
|
||||
(namestring-1 (definition-source-location-filenames-namestring-1 filenames))
|
||||
(namestring-2 (definition-source-location-filenames-namestring-2 filenames)))
|
||||
(maybe-reconstitute-namestring namestring-1 namestring-2)))
|
||||
|
||||
(defun %make-definition-source-location (namestring-1 namestring-2 tlf-num subform-num)
|
||||
(declare (type (or null (integer -1 *)) tlf-num)
|
||||
(type (or null unsigned-byte) subform-num))
|
||||
(let* ((plist *source-plist*)
|
||||
|
|
@ -65,44 +88,58 @@
|
|||
0)))
|
||||
(source-info (and (boundp '*source-info*) *source-info*))
|
||||
(last (and source-info
|
||||
(source-info-last-defn-source-loc source-info))))
|
||||
(source-info-last-defn-source-loc source-info)))
|
||||
(last-filenames (if last (definition-source-location-filenames last)))
|
||||
(filenames (if (and last
|
||||
(equal (definition-source-location-filenames-namestring-1
|
||||
last-filenames)
|
||||
namestring-1)
|
||||
(equal (definition-source-location-filenames-namestring-2
|
||||
last-filenames)
|
||||
namestring-2))
|
||||
last-filenames
|
||||
(%make-definition-source-location-filenames
|
||||
namestring-1 namestring-2))))
|
||||
(if (and last
|
||||
(eql (definition-source-location-indices last) indices)
|
||||
(string= (definition-source-location-namestring last) namestring)
|
||||
(eql last-filenames filenames)
|
||||
(equal (definition-source-location-plist last) plist))
|
||||
last
|
||||
(let ((new (if plist
|
||||
(%make-full-definition-source-location namestring indices plist)
|
||||
(%make-basic-definition-source-location namestring indices))))
|
||||
(%make-full-definition-source-location filenames indices plist)
|
||||
(%make-basic-definition-source-location filenames indices))))
|
||||
(when source-info
|
||||
(setf (source-info-last-defn-source-loc source-info) new))
|
||||
new))))
|
||||
|
||||
(defun make-definition-source-location ()
|
||||
(let* ((source-info (and (boundp '*source-info*) *source-info*))
|
||||
(namestring
|
||||
(or *source-namestring*
|
||||
(when source-info
|
||||
(make-file-info-namestring
|
||||
cl:*compile-file-pathname*
|
||||
(get-toplevelish-file-info source-info)))))
|
||||
(let ((source-info (and (boundp '*source-info*) *source-info*))
|
||||
tlf-number
|
||||
form-number)
|
||||
(acond ((boundp '*current-path*)
|
||||
(setf tlf-number (source-path-tlf-number *current-path*)
|
||||
form-number (source-path-form-number *current-path*)))
|
||||
((and source-info (source-info-file-info source-info))
|
||||
(setf tlf-number (1- (fill-pointer (file-info-forms it))))))
|
||||
(%make-definition-source-location namestring tlf-number form-number)))
|
||||
(multiple-value-bind (namestring-1 namestring-2)
|
||||
(or *source-namestring*
|
||||
(when source-info
|
||||
(make-file-info-namestrings
|
||||
cl:*compile-file-pathname*
|
||||
(get-toplevelish-file-info source-info))))
|
||||
(acond ((boundp '*current-path*)
|
||||
(setf tlf-number (source-path-tlf-number *current-path*)
|
||||
form-number (source-path-form-number *current-path*)))
|
||||
((and source-info (source-info-file-info source-info))
|
||||
(setf tlf-number (1- (fill-pointer (file-info-forms it))))))
|
||||
(%make-definition-source-location namestring-1 namestring-2 tlf-number form-number))))
|
||||
|
||||
(defun make-file-info-namestring (name file-info)
|
||||
(let* ((pathname (file-info-pathname file-info))
|
||||
(dir (and pathname (pathname-directory pathname))))
|
||||
(if (and dir (eq (first dir) :absolute))
|
||||
(namestring pathname)
|
||||
(if name
|
||||
(namestring name)
|
||||
nil))))
|
||||
(defun make-file-info-namestrings (name file-info)
|
||||
(let* ((pathname-1 (file-info-pathname-1 file-info))
|
||||
(dir (and pathname-1 (pathname-directory pathname-1)))
|
||||
(pathname-2 (file-info-pathname-2 file-info)))
|
||||
(cond ((and dir (eq (first dir) :absolute))
|
||||
(values (namestring pathname-1) nil))
|
||||
((and pathname-1 pathname-2)
|
||||
(values (namestring pathname-1) (namestring pathname-2)))
|
||||
(t (if name
|
||||
(namestring name)
|
||||
nil)))))
|
||||
|
||||
(in-package "SB-IMPL")
|
||||
|
||||
|
|
|
|||
|
|
@ -346,23 +346,25 @@
|
|||
(defun debug-source-for-info (info &key function)
|
||||
(declare (type source-info info))
|
||||
(let ((file-info (get-toplevelish-file-info info)))
|
||||
(multiple-value-call
|
||||
(if function 'sb-di::make-core-debug-source 'make-debug-source)
|
||||
:namestring (or *source-namestring*
|
||||
(make-file-info-namestring
|
||||
(let ((pathname
|
||||
(case *name-context-file-path-selector*
|
||||
(pathname (file-info-pathname file-info))
|
||||
(truename (file-info-truename file-info)))))
|
||||
(if (pathnamep pathname) pathname))
|
||||
file-info))
|
||||
:created (file-info-write-date file-info)
|
||||
(if function
|
||||
(values :form (let ((direct-file-info (source-info-file-info info)))
|
||||
(when (eq :lisp (file-info-truename direct-file-info))
|
||||
(elt (file-info-forms direct-file-info) 0)))
|
||||
:function function)
|
||||
(values)))))
|
||||
(multiple-value-bind (namestring-1 namestring-2)
|
||||
(make-file-info-namestrings
|
||||
(let ((pathname
|
||||
(case *name-context-file-path-selector*
|
||||
(pathname (file-info-pathname-1 file-info))
|
||||
(truename (file-info-truename file-info)))))
|
||||
(if (pathnamep pathname) pathname))
|
||||
file-info)
|
||||
(multiple-value-call
|
||||
(if function 'sb-di::make-core-debug-source 'make-debug-source)
|
||||
:namestring-1 (or *source-namestring* namestring-1)
|
||||
:namestring-2 (unless *source-namestring* namestring-2)
|
||||
:created (file-info-write-date file-info)
|
||||
(if function
|
||||
(values :form (let ((direct-file-info (source-info-file-info info)))
|
||||
(when (eq :lisp (file-info-truename direct-file-info))
|
||||
(elt (file-info-forms direct-file-info) 0)))
|
||||
:function function)
|
||||
(values))))))
|
||||
|
||||
(defun smallest-element-type (integer negative)
|
||||
(let ((bits (max (+ (integer-length integer)
|
||||
|
|
|
|||
|
|
@ -836,25 +836,23 @@ necessary, since type inference may take arbitrarily long to converge.")
|
|||
(terpri)
|
||||
(values))
|
||||
|
||||
;;; Leave this as NIL if you want modern, rational, correct, behavior,
|
||||
;;; or switch it to T for legacy (CLHS-specified) bullshit a la
|
||||
;;; "During a call to compile-file, *compile-file-pathname* is bound to the pathname
|
||||
;;; denoted by the first argument to compile-file, merged against the defaults"
|
||||
;;; The normal build sets it to T in make-target-2, despite that I think most people would
|
||||
;;; prefer the nonstandard behavior. The standard behavior makes stored pathnames all wrong
|
||||
;;; when files are physically moved. (Same problem as SBCL_HOME embedded into C pretty much)
|
||||
(defglobal *merge-pathnames* t)
|
||||
|
||||
;;; Given a pathname, return a SOURCE-INFO structure.
|
||||
(defun make-file-source-info (file external-format &optional form-tracking-p)
|
||||
(defun make-file-source-info (pathname external-format &optional form-tracking-p)
|
||||
(make-source-info
|
||||
:file-info (make-file-info :pathname ; becomes *C-F-PATHNAME*
|
||||
(if *merge-pathnames* (merge-pathnames file) file)
|
||||
:external-format external-format
|
||||
:subforms
|
||||
(if form-tracking-p
|
||||
(make-array 100 :fill-pointer 0 :adjustable t))
|
||||
:write-date (file-write-date file))))
|
||||
:file-info (make-file-info
|
||||
:pathname-1 pathname
|
||||
;; FIXME: this shouldn't have to be initialized here,
|
||||
;; but delaying it till GET-SOURCE-STREAM somehow
|
||||
;; prevents it from showing up in DEBUG-SOURCEs later.
|
||||
:pathname-2 (unless (equal (merge-pathnames pathname) pathname)
|
||||
*default-pathname-defaults*)
|
||||
:external-format external-format
|
||||
:subforms (if form-tracking-p
|
||||
(make-array 100 :fill-pointer 0 :adjustable t))
|
||||
;; FIXME: this shouldn't have to be initialized here,
|
||||
;; but delaying it till GET-SOURCE-STREAM somehow
|
||||
;; prevents it from showing up in DEBUG-SOURCEs later.
|
||||
:write-date (file-write-date pathname))))
|
||||
|
||||
;; LOAD-AS-SOURCE uses this.
|
||||
(defun make-file-stream-source-info (file-stream)
|
||||
|
|
@ -862,7 +860,7 @@ necessary, since type inference may take arbitrarily long to converge.")
|
|||
:file-info (make-file-info :truename (truename file-stream)
|
||||
;; This T-L-P has been around since at least 2011.
|
||||
;; It's unclear why an LPN isn't good enough.
|
||||
:pathname (translate-logical-pathname file-stream)
|
||||
:pathname-1 (translate-logical-pathname file-stream)
|
||||
:external-format (stream-external-format file-stream)
|
||||
:write-date (file-write-date file-stream))))
|
||||
|
||||
|
|
@ -903,7 +901,7 @@ necessary, since type inference may take arbitrarily long to converge.")
|
|||
(declare (type source-info info))
|
||||
(or (source-info-stream info)
|
||||
(let* ((file-info (source-info-file-info info))
|
||||
(pathname (file-info-pathname file-info))
|
||||
(pathname (file-info-pathname-1 file-info))
|
||||
(external-format (file-info-external-format file-info)))
|
||||
(let ((stream
|
||||
(open pathname
|
||||
|
|
@ -912,12 +910,17 @@ necessary, since type inference may take arbitrarily long to converge.")
|
|||
;; SBCL stream classes aren't available in the host
|
||||
#-sb-xc-host :class
|
||||
#-sb-xc-host 'form-tracking-stream)))
|
||||
;; If you don't want merged pathnames embedded in your build artifacts,
|
||||
;; then you surely don't want them in *COMPILE-FILE-PATHNAME* either.
|
||||
;; [And can't we just bind this to PATHNAME is all cases? If anything,
|
||||
;; it seems to me that asking the stream for its name is expressly backwards]
|
||||
(setf *compile-file-pathname* (if *merge-pathnames* (pathname stream) pathname)
|
||||
;; OPEN is required to merge PATHNAME, and the FILE-STREAM
|
||||
;; is required to return that merge from #'PATHNAME. So we
|
||||
;; can get the merged pathname we used to open the file from
|
||||
;; the stream itself.
|
||||
(setf *compile-file-pathname* (pathname stream)
|
||||
*compile-file-truename* (truename stream)
|
||||
;; FIXME: it ought to be possible to defer setting the
|
||||
;; PATHNAME-2 and WRITE-DATE slots to here (i.e.,
|
||||
;; delaying some work/computation till we know we've
|
||||
;; got an open file), but doing so somehow leaves the
|
||||
;; corresponding slots NIL in DEBUG-SOURCEs later.
|
||||
(file-info-truename file-info) *compile-file-truename*)
|
||||
(when (file-info-subforms file-info)
|
||||
(setf (form-tracking-stream-observer stream)
|
||||
|
|
@ -1835,6 +1838,9 @@ necessary, since type inference may take arbitrarily long to converge.")
|
|||
(values t t t)))))
|
||||
|
||||
;;; Return a pathname for the named file. The file must exist.
|
||||
;; FIXME: is this anything other than a merge-pathnames wrapped in a
|
||||
;; minor time-of-check/time-of-use bug? OPEN will surely tell us if
|
||||
;; the file doesn't exist.
|
||||
(defun verify-source-file (pathname-designator)
|
||||
(let* ((pathname (pathname pathname-designator))
|
||||
(default-host (make-pathname :host (pathname-host pathname))))
|
||||
|
|
|
|||
|
|
@ -2828,7 +2828,8 @@ bootstrapping.
|
|||
(debug-source (sb-c::debug-info-source debug-info))
|
||||
(debug-fun (debug-info-debug-function function debug-info)))
|
||||
(sb-c::%make-definition-source-location
|
||||
(sb-c::debug-source-namestring debug-source)
|
||||
(sb-c::debug-source-namestring-1 debug-source)
|
||||
(sb-c::debug-source-namestring-2 debug-source)
|
||||
(sb-c::compiled-debug-info-tlf-number debug-info)
|
||||
(sb-c::compiled-debug-fun-form-number debug-fun))))
|
||||
(debug-info-debug-function (function debug-info)
|
||||
|
|
|
|||
|
|
@ -1069,9 +1069,12 @@
|
|||
(let* ((source
|
||||
(sb-c::compiled-debug-info-source
|
||||
(truly-the sb-c::compiled-debug-info
|
||||
(translate (%code-debug-info code) spaces))))
|
||||
(translate (%code-debug-info code) spaces))))
|
||||
;; FIXME: we used to have just one namestring in
|
||||
;; the debug-source, now we've got two, and this
|
||||
;; ignores one of them.
|
||||
(namestring
|
||||
(debug-source-namestring
|
||||
(sb-c::debug-source-namestring-1
|
||||
(truly-the sb-c::debug-source (translate source spaces)))))
|
||||
(setq namestring (if (eq namestring (core-nil-object core))
|
||||
"sbcl.core"
|
||||
|
|
|
|||
Loading…
Reference in a new issue