1 行でブラウザ判別を行うスクリプト (IE 用の日本語紹介記事、Firefox、Safari 用の日本語紹介記事) が注目を集めています。それによると Firefox の判別は次の 15 文字で行えるそうです。
//Firefox detector 2/3 by DoctorDan
FF=/a/[-1]=='a'
いったいなぜこれで Firefox が判別できるのか、少し探ってみました。
実際に探っていく前にひとつ注意しなければいけないことがあります。それは、上記のコードが Firefox を判別するものではないということです。このコードには Web ブラウザ固有のオブジェクトモデルに関する情報が含まれておらず、正確には Firefox 等で使われている JavaScript エンジン「SpiderMonkey」を判別するためのものであるというべきでしょう。
上記コードを見るに、SpiderMonkey では正規表現オブジェクトのインデックス -1 が source プロパティに対応するようです。しかしそうなる原因を探るにはどうすればよいのでしょうか。とりあえず -1 プロパティを取得するという JavaScript コードに対して、SpiderMonkey が生成する中間コードを見てみることにします。中間コードは、単体の SpiderMonkey に付属する JavaScript shell で使える dis 関数で確認できます。なお、都合によりここで使用する SpiderMonkey 及び参照する SpiderMonkey のソースコードは、Firefox 3.0 系列に含まれるものと同等のバージョン (SpiderMonkey 1.8) のものとします。
$ js js> dis(function () /a/[-1]); flags: LAMBDA EXPR_CLOSURE INTERPRETED main: 00000: regexp null 00003: int8 -1 00005: getelem 00006: return 00007: stop Source notes: 0: 5 [ 5] pcbase offset 5
これを見ると、数値的プロパティの取得には getelem 命令が使われることがわかります。そこで、SpiderMoneky のソースコードから、getelem 命令を処理している部分を見ると次のようになっています (一部改変)。
/* jsinterp.c */
セコメントをする