;;; versions which break binary compatibility. But it certainly should
;;; be incremented for release versions which break binary
;;; compatibility.
-(def!constant +fasl-file-version+ 76)
+(def!constant +fasl-file-version+ 77)
;;; (description of versions before 0.9.0.1 deleted in 0.9.17)
;;; 56: (2005-05-22) Something between 0.9.0.1 and 0.9.0.14. My money is
;;; on 0.9.0.6 (MORE CASE CONSISTENCY).
;;; 73: (2007-04-13) Changed a hash function
;;; 74: (2007-06-05) UNWIND-TO-FRAME-AND-CALL
;;; 75: (2007-08-06) FD-STREAM layout changes
-;;; 76: (2007-05-10) MUTEX layout changes
+;;; 76: (2007-10-05) MUTEX layout changes
+;;; 77: (2007-11-08) Essentially obsolete fasl-file-version, fasls are now
+;;; considered compatible only when the version numbers of the compiling
+;;; SBCL instance is exactly the same as the one of the loading instance.
+;;; Further fasl-file-version bumps should only be done for real changes
+;;; in the fasl format, not for changes in function/macro signatures or
+;;; lisp data structures.
;;; the conventional file extension for our fasl files
(declaim (type simple-string *fasl-file-type*))
(invalid-fasl-expected condition)))))
(define-condition invalid-fasl-version (invalid-fasl)
- ((variant :reader invalid-fasl-variant :initarg :variant)
- (version :reader invalid-fasl-version :initarg :version))
+ ((version :reader invalid-fasl-version :initarg :version))
(:report
(lambda (condition stream)
- (format stream "~@<~S is in ~A fasl file format version ~W, ~
- but this version of SBCL uses format version ~W.~:@>"
+ (format stream "~@<~S is a fasl file compiled with SBCL ~W, and ~
+ can't be loaded into SBCL ~W.~:@>"
(invalid-fasl-stream condition)
- (invalid-fasl-variant condition)
(invalid-fasl-version condition)
(invalid-fasl-expected condition)))))
;;; or NIL if EOF was hit before anything was read. Signal an error if
;;; we encounter garbage.
(defun check-fasl-header (stream)
-
(let ((byte (read-byte stream nil)))
(when byte
-
;; Read and validate constant string prefix in fasl header.
(let* ((fhsss *fasl-header-string-start-string*)
(fhsss-length (length fhsss)))
:byte-nr count
:byte byte
:expected (char-code (schar fhsss count))))))
-
;; Read and validate version-specific compatibility stuff.
(flet ((string-from-stream ()
(let* ((length (read-unsigned-byte-32-arg))
result)))
;; Read and validate implementation and version.
(let* ((implementation (keywordicate (string-from-stream)))
- ;; FIXME: The logic above to read a keyword from the fasl file
- ;; could probably be shared with the read-a-keyword fop.
- (version (read-word-arg)))
- (flet ((check-version (variant
- possible-implementation
- needed-version)
- (when (string= possible-implementation implementation)
- (or (= version needed-version)
- (error 'invalid-fasl-version
- ;; :error :wrong-version
- :stream stream
- :variant variant
- :version version
- :expected needed-version)))))
- (or (check-version "native code"
- +backend-fasl-file-implementation+
- +fasl-file-version+)
- (error 'invalid-fasl-implementation
- :stream stream
- :implementation implementation
- :expected +backend-fasl-file-implementation+))))
+ (fasl-version (read-word-arg))
+ (sbcl-version (if (<= fasl-version 76)
+ "1.0.11.18"
+ (string-from-stream)))
+ (expected-version (sb!xc:lisp-implementation-version))
+ (expected-implementation +backend-fasl-file-implementation+))
+ (cond ((string/= expected-implementation implementation)
+ (error 'invalid-fasl-implementation
+ :stream stream
+ :implementation implementation
+ :expected expected-implementation))
+ ((string/= expected-version sbcl-version)
+ (restart-case
+ (error 'invalid-fasl-version
+ :stream stream
+ :version sbcl-version
+ :expected expected-version)
+ (continue ()
+ :report "Load the fasl file anyway")))))
;; Read and validate *FEATURES* which affect binary compatibility.
(let ((faff-in-this-file (string-from-stream)))
(unless (string= faff-in-this-file *features-affecting-fasl-format*)
:if-exists :supersede
:element-type 'sb!assem:assembly-unit))
(res (make-fasl-output :stream stream)))
-
;; Begin the header with the constant machine-readable (and
;; semi-human-readable) string which is used to identify fasl files.
(fasl-write-string *fasl-header-string-start-string* stream)
-
;; The constant string which begins the header is followed by
;; arbitrary human-readable text, terminated by a special
;; character code.
at ~A~% ~
on ~A~% ~
using ~A version ~A~%"
- where
+ where
(format-universal-time nil (get-universal-time))
(machine-instance)
(sb!xc:lisp-implementation-type)
(sb!xc:lisp-implementation-version))))
stream)
(dump-byte +fasl-header-string-stop-char-code+ res)
-
;; Finish the header by outputting fasl file implementation,
;; version, and key *FEATURES*.
(flet ((dump-counted-string (string)
(dump-byte (char-code (aref string i)) res))))
(dump-counted-string (symbol-name +backend-fasl-file-implementation+))
(dump-word +fasl-file-version+ res)
+ (dump-counted-string (sb!xc:lisp-implementation-version))
(dump-counted-string *features-affecting-fasl-format*))
-
res))
;;; Close the specified FASL-OUTPUT, aborting the write if ABORT-P.