1
Fork 0
mirror of https://git.savannah.gnu.org/git/guile.git synced 2025-05-20 19:50:24 +02:00

Split `load-in-vicinity' into small procedures.

* module/ice-9/boot-9.scm (load-in-vicinity)[compiled-extension]: New
  variable.
  [compiled-file-name]: Rename to...
  [fallback-file-name]: ... this; update caller.  Use COMPILED-EXTENSION.
  [more-recent?, compile, warn-about-exception]: New procedures.
  [fresh-compiled-file-name]: Use them.
This commit is contained in:
Ludovic Courtès 2012-11-26 22:41:23 +01:00
parent 6356e0dc2f
commit 9fbca4b32e

View file

@ -3569,6 +3569,10 @@ module '(ice-9 q) '(make-q q-length))}."
duplicate-case-datum bad-case-datum))) duplicate-case-datum bad-case-datum)))
(define* (load-in-vicinity dir path #:optional reader) (define* (load-in-vicinity dir path #:optional reader)
"Load source file PATH in vicinity of directory DIR. Use a pre-compiled
version of PATH when available, and auto-compile one when none is available,
reading PATH with READER."
(define (canonical->suffix canon) (define (canonical->suffix canon)
(cond (cond
((string-prefix? "/" canon) canon) ((string-prefix? "/" canon) canon)
@ -3578,6 +3582,49 @@ module '(ice-9 q) '(make-q q-length))}."
(string-append "/" (substring canon 0 1) (substring canon 2))) (string-append "/" (substring canon 0 1) (substring canon 2)))
(else canon))) (else canon)))
(define compiled-extension
;; File name extension of compiled files.
(cond ((or (null? %load-compiled-extensions)
(string-null? (car %load-compiled-extensions)))
(warn "invalid %load-compiled-extensions"
%load-compiled-extensions)
".go")
(else (car %load-compiled-extensions))))
(define (more-recent? stat1 stat2)
;; Return #t when STAT1 has an mtime greater than that of STAT2.
(or (> (stat:mtime stat1) (stat:mtime stat2))
(and (= (stat:mtime stat1) (stat:mtime stat2))
(>= (stat:mtimensec stat1)
(stat:mtimensec stat2)))))
(define (fallback-file-name canon-path)
;; Return the in-cache compiled file name for source file CANON-PATH.
;; FIXME: would probably be better just to append SHA1(canon-path)
;; to the %compile-fallback-path, to avoid deep directory stats.
(and %compile-fallback-path
(string-append %compile-fallback-path
(canonical->suffix canon-path)
compiled-extension)))
(define (compile file)
;; Compile source FILE, lazily loading the compiler.
((module-ref (resolve-interface '(system base compile))
'compile-file)
file
#:opts %auto-compilation-options
#:env (current-module)))
(define (warn-about-exception key args)
(for-each (lambda (s)
(if (not (string-null? s))
(format (current-warning-port) ";;; ~a\n" s)))
(string-split
(call-with-output-string
(lambda (port) (print-exception port #f key args)))
#\newline)))
;; Returns the .go file corresponding to `name'. Does not search load ;; Returns the .go file corresponding to `name'. Does not search load
;; paths, only the fallback path. If the .go file is missing or out of ;; paths, only the fallback path. If the .go file is missing or out of
;; date, and auto-compilation is enabled, will try auto-compilation, just ;; date, and auto-compilation is enabled, will try auto-compilation, just
@ -3587,32 +3634,16 @@ module '(ice-9 q) '(make-q q-length))}."
;; NB: Unless we need to compile the file, this function should not cause ;; NB: Unless we need to compile the file, this function should not cause
;; (system base compile) to be loaded up. For that reason compiled-file-name ;; (system base compile) to be loaded up. For that reason compiled-file-name
;; partially duplicates functionality from (system base compile). ;; partially duplicates functionality from (system base compile).
;;
(define (compiled-file-name canon-path)
;; FIXME: would probably be better just to append SHA1(canon-path)
;; to the %compile-fallback-path, to avoid deep directory stats.
(and %compile-fallback-path
(string-append
%compile-fallback-path
(canonical->suffix canon-path)
(cond ((or (null? %load-compiled-extensions)
(string-null? (car %load-compiled-extensions)))
(warn "invalid %load-compiled-extensions"
%load-compiled-extensions)
".go")
(else (car %load-compiled-extensions))))))
(define (fresh-compiled-file-name name go-path) (define (fresh-compiled-file-name name go-path)
;; Return GO-PATH after making sure that it contains a freshly compiled
;; version of source file NAME; return #f on failure.
(catch #t (catch #t
(lambda () (lambda ()
(let* ((scmstat (stat name)) (let* ((scmstat (stat name))
(gostat (and (not %fresh-auto-compile) (gostat (and (not %fresh-auto-compile)
(stat go-path #f)))) (stat go-path #f))))
(if (and gostat (if (and gostat (more-recent? gostat scmstat))
(or (> (stat:mtime gostat) (stat:mtime scmstat))
(and (= (stat:mtime gostat) (stat:mtime scmstat))
(>= (stat:mtimensec gostat)
(stat:mtimensec scmstat)))))
go-path go-path
(begin (begin
(if gostat (if gostat
@ -3623,26 +3654,14 @@ module '(ice-9 q) '(make-q q-length))}."
(%load-should-auto-compile (%load-should-auto-compile
(%warn-auto-compilation-enabled) (%warn-auto-compilation-enabled)
(format (current-warning-port) ";;; compiling ~a\n" name) (format (current-warning-port) ";;; compiling ~a\n" name)
(let ((cfn (let ((cfn (compile name)))
((module-ref
(resolve-interface '(system base compile))
'compile-file)
name
#:opts %auto-compilation-options
#:env (current-module))))
(format (current-warning-port) ";;; compiled ~a\n" cfn) (format (current-warning-port) ";;; compiled ~a\n" cfn)
cfn)) cfn))
(else #f)))))) (else #f))))))
(lambda (k . args) (lambda (k . args)
(format (current-warning-port) (format (current-warning-port)
";;; WARNING: compilation of ~a failed:\n" name) ";;; WARNING: compilation of ~a failed:\n" name)
(for-each (lambda (s) (warn-about-exception k args)
(if (not (string-null? s))
(format (current-warning-port) ";;; ~a\n" s)))
(string-split
(call-with-output-string
(lambda (port) (print-exception port #f k args)))
#\newline))
#f))) #f)))
(define (absolute-path? path) (define (absolute-path? path)
@ -3651,7 +3670,7 @@ module '(ice-9 q) '(make-q q-length))}."
(define (load-absolute abs-path) (define (load-absolute abs-path)
(let ((cfn (let ((canon (false-if-exception (canonicalize-path abs-path)))) (let ((cfn (let ((canon (false-if-exception (canonicalize-path abs-path))))
(and canon (and canon
(let ((go-path (compiled-file-name canon))) (let ((go-path (fallback-file-name canon)))
(and go-path (and go-path
(fresh-compiled-file-name abs-path go-path))))))) (fresh-compiled-file-name abs-path go-path)))))))
(if cfn (if cfn
@ -3667,7 +3686,7 @@ module '(ice-9 q) '(make-q q-length))}."
(with-fluids ((current-reader reader) (with-fluids ((current-reader reader)
(%file-port-name-canonicalization 'relative)) (%file-port-name-canonicalization 'relative))
(cond (cond
((or (absolute-path? path)) ((absolute-path? path)
(load-absolute path)) (load-absolute path))
((absolute-path? dir) ((absolute-path? dir)
(load-absolute (in-vicinity dir path))) (load-absolute (in-vicinity dir path)))