R6RS Macros and R6RS librariesを今度こそ移植する の6

最後は東の横綱exceptionsが残るのみとなった。

キャッシュディレクトリの自動生成

(define (ca-serialize fn l)
  (unless (file-exists? (nmosh-cache-dir))
    (create-directory (nmosh-cache-dir)))
  (ca-writeobj fn (compile-w/o-halt l)))

現在のmoshは起動時に生成しているが、書き込み時に毎回チェックするようにタイミングを変更した。インタプリタの実行中に削除されるケースも考えられるため。

キャッシュの無効化

今の所2つのケースでキャッシュが無効化される可能性が有る。

  • 元のファイルよりキャッシュが古い
  • すでにロードされるライブラリの中に、互換性の無いものを含んでいる
(define (ca-load fn recompile? name)
  (define (reload)
    (PCK 'CACHE: 'RECOMPILE!!!)
    (set! nm:parachute #f)
    (ca-load fn #t name))
  (let ((cfn (ca-filename->cachename fn)))
    (cond
      ((file-exists? cfn)
       (cond ((and (not recompile?) (file-newer? cfn fn))
              (PCK (list 'CACHE: 'loading.. cfn))
              ; try loading
              (if (eq? 'nm:failure
                       (call/cc (lambda (k) ; FIXME: i assume a call/cc is much faster than an I/O
                                  (set! nm:parachute k)
                                  (eval-compiled! (ca-readobj cfn)))))
                (reload)
                (set! nm:parachute #f))
              (PCK 'CACHE: 'done))

後者のケースのために、継続をつかって大域脱出を行っている。この継続の評価は、シリアライズされるライブラリに挿入される、ライブラリエントリポイントで必要に応じて行われる。これらはmosh-utils5.scmではなくexpander.scmに書かれている :

    (define (expand-file-to-cache filename target name)
      (define (fappend a b)
        (define (itr cur rest)
          (if (pair? rest)
            (itr (cons (car rest) cur) (cdr rest))
            cur))
        (itr b (reverse a)))

      (define KODE `((nm:register-source ,filename (quote ,name) (quote ,(nm:dump-library-table name)))))
      (with-toplevel-parameters
        (lambda ()
          (ca-serialize target
                        (cons 'begin
                              (fappend KODE (expand-toplevel-sequence (normalize (read-file filename)))))))))

展開されるコードをbeginでつつみ、register-source手続きの呼び出しを加えている。この呼び出し中に、ライブラリがコンパイルされた際のロードされていたライブラリのバージョン全てを含めている。
すでにロードしたライブラリのバージョンチェック(今回追加した)と、ライブラリをロードしたあと必要なライブラリをロードするためのテスト(これは本来備わっている)を両方持つのはムダなので、起動の高速化のためには修正されるべきだろう。

テスト

通らないテスト :

  • mosh
    • concurrent
    • shell
  • R6RS
    • exceptions - symbol-valueの無限ループ
    • syntax-case 22/102
    • base 3/2053

SRFI-27は末尾に不正な文字列が追加されていたので削除した。