portability of *.elc (Re: APEL 問題、再燃?)
Shuhei KOBAYASHI
shuhei @ aqua.ocn.ne.jp
1999年 11月 9日 (火) 11:59:29 JST
こばやしです. さっきのと関連するのでこれも.
>>>>> In <htxzowur09p.fsf @ mulelab3.etl.go.jp>,
>>>>> tomo @ etl.go.jp (守岡 知彦 / MORIOKA Tomohiko) wrote:
> ただ、現実問題として、*.elc の互換性問題に関しては真摯に取り組むべき
> だと思っています。
これを徹底的に進めてもいいですか? ;-)
(1) APEL 上の application の *.elc の互換性に関する原則.
APEL の制限によって APEL を利用する application の *.elc の互換性
を制限してはいけない.
(2) APEL 自体の *.elc の互換性(の放棄;-))に関する原則.
APEL の中でも VERSION_SPECIFIC_LISPDIR に install されるものにつ
いては, static-* や *-maybe による compile 時の判定は既定の方針と
して認める.
(1) は割と妥当に見えますね;-) (2) は既に合意されていると思います.
ただし, (2) については要請として,
* XEmacs w/ Mule と w/o Mule では *.elc を共有できなければいけない.
(XEmacs package の都合; 21.1 系と 21.2 系での共有も問題になる?)
* 異なる OS 間で *.elc を共有できなければいけない.
(NFS で site-lisp や home を共有する場合など)
というものがあります. 純粋に emacs の version に依るものだけを compile
時に判定するようにしなければなりません. (XEmacs 21.1/21.2 の事は未確認)
具体的には以下のような場合には compile 時の判定をしてはいけません.
;;; From modified poe.el:
(static-when (featurep 'xemacs)
;; must be load-time check to share .elc between w/ MULE and w/o MULE.
(when (featurep 'mule)
(provide 'file-coding)))
;;; From pces.el:
(eval-and-compile
;; must be load-time check to share .elc between different systems.
(unless (fboundp 'open-network-stream)
(require 'tcp)))
NTEmacs や Meadow などと Unix 系 OS とで *.elc を共有するのが現実的
ならば, convert-standard-filename なども compile 時に判定を行なって
はいけない事になります.
一方, (1) からは
* version によって定義の異なるものは compile 時に展開してはいけない.
という制限が導き出されます.
例えば, enable-invisible などは現在は macro ですが, これは関数にする
べきです. (ところでなぜ enable- に対応するのが disable- ではないの?)
as-binary-* も version によって異なる定義に展開される macro なので,
application の *.elc の互換性を高めようとしたら用いるべきではありませ
ん. call-process-as-binary, start-process-as-binary などの関数を用意し,
それらによって置き換えられるべきです.
;;; From modified pces.el:
;; pces-* sub-module may provide better version of these functions.
(defun-maybe start-process-as-binary (name buffer program &rest args)
"Like `start-process', q.v., but don't code conversion."
(as-binary-process
(apply (function start-process)
name buffer program args)))
本質的に *.elc が非互換である場合に限り compile 時に展開しても良いので
はないかという話がありましたが, それでは *.elc の本質的な非互換性がどの
程度のものであるかを検討してみます.
各 Emacsen の bytecode.c や bytecomp.el を比較した結果です.
まず,
(a) 非 ASCII 文字の内部表現が各 Emacsen で異なる.
というのがありますが, これはどうしようもないので, 以下では非 ASCII
文字を含まない場合を仮定します.
(b) v19 で bytecode interpreter に多くの opcode が追加された.
これは FSF Emacs では compile 時に byte-compile-compatibility を non-
nil に設定する事で回避できます. (XEmacs の compiler にこの機能はない)
(c) Emacs 19.29/XEmacs 19.14 で dynamic docstring/function loading が
導入された.
これは byte-compile-dynamic と byte-compile-dynamic-docstrings を nil
に設定する事で回避できます. なお, XEmacs-mule は dynamic function load
に未対応だそうです.
(d) Emacs 19.29 で keyboard の modifier bit が変更された.
Elisp manual によると, これらを含む場合には 19.28 以前と 19.29 以後で
*.elc の互換性はなくなるようです. (詳細は未確認)
(e) XEmacs 20 で eq, memq, equal, assq の bytecode が変更された.
新たな bytecode が割り当てられたのですが, 従来の bytecode も old_eq
などの形で残されています. byte-compile-emacs19-compatibility を t に
設定する事で v19 互換の *.elc を生成することもできます.
(f) v20 で save-current-buffer という special-form が builtin になり,
v18 の Bread_char という bytecode を置き換える形で bytecode が割
り当てられた.
XEmacs ではこれも byte-compile-emacs19-compatibility を t に設定する
と回避できます. XEmacs と同様の変更を compiler に加えると FSF 版でも
これは回避できるようになります.
まとめると, 非 ASCII 文字を含まない場合 (a) に問題になるのは (d) と,
(b) の XEmacs で compile した *.elc を v18 で load する場合, (f) の
v18 で compile した *.elc を v20 で load する場合だけです.
つまり, APEL の API では version に依存する定義を defmacro/defsubst
として提供する余地はほとんど残されていない事になります.
また, こうなると, 例えば FLIM や SEMI の場合に *.elc の互換性を阻害
している主要な原因は (a) の code-name だという事になります:-p
実際, 上に述べたように APEL の macro を関数に置き換えると, 19.34 で
compile した FLIM と SEMI(から code-name を除いたもの)を用いて 20.4
で Gnus を動かす事ができました.
--
Shuhei KOBAYASHI
More information about the APEL-ja
mailing list