#:g1: LispWorks 7.1 購入への道(3) — バグ報告2件

Posted 2018-01-14 09:15:07 GMT

LispWorks 7.1を試用していて2件程バグっぽい挙動に遭遇していました。
折角試用させて貰ったので、何かバグ的なものは報告しておきたいところなので期間最終日に報告。

7.1は関数のボディで点対リストを受けつける

具体的な再現コードにすると

(defun foo (x) x . a)
→ foo

(compile nil (lambda (x) x . a)) → #<Function 15 406003A054> NIL NIL

というのが通ってしまいます。
LW 7.0では、 In a call to length of (x . a), tail a is not a LIST.

というエラーになりますが、LispWorks以外の大抵の処理系も同様のエラーとします。
7.1では、点対リストを許容するようになったのかとも思えますが、

(compile nil (lambda (x) . a))
→ Cannot take CDR of A.

こういうのは通らないので一貫性がない様子。

UTF-8のエンコーディング設定で起動時にエラーになる

もう一点、LispWorks 7.0を利用していてバグじゃないかと思いつつも適当なワークアラウンドで回避できていたのですっかり忘れていたことがありました。
具体的には、UTF-8の設定時に起動でコケるというちょっと嫌な感じのもの。

どうやらバイナリのファイル(スプラッシュ画像)をUTF-8で開こうとしてエラーになるらしいので、ファイルのエンコーディング判定関数で画像ファイルは迂回するようにしていましたが、これが7.1でも発生する様子。

;;; 回避コード
(defun utf-8-file-encoding (pathname ef-spec buffer length)
  (declare (ignore buffer length))
  (if (assoc (pathname-type pathname) graphics-ports::*file-types-to-image-types*
             :test #'equalp)
      '(:latin-1)
      (system:merge-ef-specs ef-spec '(:utf-8 :use-replacement t))))

(setq system:*file-encoding-detection-algorithm* '(utf-8-file-encoding))

報告を作成するためにちょっと追い掛けてみましたが、capi-gtk-library::put-image-data-in-fileでエラーになるらしいので、この関数のトレース結果を添付しました。

報告してみた

最終日に報告してみたところ、UTF-8の方はバグだったらしく二日後にプライベートパッチが届きました。
なんとパッチが出るとは想定していなかった。試用期間は終了しているのでパッチが試せないという……。

パッチの名前が、put-image-data-in-file.64ufaslなので、やはり報告した、capi-gtk-library::put-image-data-in-fileが問題のようです。

もったいないので、とりあえず駄目元で7.0で読み込ませてみましたが、faslに互換性がないと警告がでるものの、無視して続行可能なので試したら、7.0でも機能するようです。

ちょっと深追いして、パッチ適用前後のcapi-gtk-library::put-image-data-in-fileを比較してみると、修正前のものは、バイナリの一時ファイルを作成するのにsys:make-temp-fileというテキストの一時ファイルを作成する関数を呼んでいたため、エンコーディングの問題が発生していたようです。
修正では、sys:make-temp-fileの下請けであるsys::open-temp-fileを使ってファイルを(unsigned-byte 8)で開くようにした様子。

大抵のユーザーはlatin-1で使っていたから遭遇しなかった問題なのか、なんなのか。
とりあえず、バイナリファイルの開き方が悪かったということで、エンコーディング周りがバグってるわけではない様子なので良かったです。

ちなみに7.0で強制的に読み込ませるのには、

(handler-bind ((fasl-error #'continue))
  (scm:require-private-patch "put-image-data-in-file" :capi-gtk))

としています。

7.0用のパッチが貰えるなら、貰った方が良いのかもしれない。

試しにdisassembleの内容からコードを推測しつつ自作しててみましたが、下記と等価なようです。
(コンパイルオプションを設定すればdisassembleの結果が同じになる)

(in-package :cg-lib)

(declaim (optimize (safety 3) (speed 1) (float 1) (sys:interruptible 0) (compilation-speed 1) (debug 2) (hcl:fixnum-safety 3)))

(defun put-image-data-in-file (image-data) (destructuring-bind (file-type . data) image-data (let ((out (sys::open-temp-file :file-type file-type :element-type '(unsigned-byte 8) :external-format :latin-1))) (write-sequence data out) (close out) (namestring out))))

このコードを

(let ((source-debugging-on-p (source-debugging-on-p)))
  (toggle-source-debugging nil)
  (compile-file "put-image-data-in-file.lisp" :debug-info nil)
  (toggle-source-debugging source-debugging-on-p))

のような感じでコンパイルすれば、大体提供されているパッチファイルと同じになるようです。

LispWorks 7.0のパッチが入手できない場合は、最悪これでも良いかもしれません。

もう一つのボディが点対リストを許容する件については、一週間後位に回答があり、次期バージョンで善処したいということでした。

むすび

試用期間のバグ報告は、パッチが期間内に試せるように早めに報告しよう。


HTML generated by 3bmd in LispWorks 7.0.0

comments powered by Disqus