Tamarin 始動2006年11月09日 21時55分

Adobe および Mozilla Foundation、オープンソース Flash Player スクリプトエンジンを発表」――というわけでやってきました tamarin……じゃなくて TamarinSpider monkey といい猿が好きなんですね。CVS に取り込まれ、Flash9_DotReleases_Branch が切られ (しかしこのブランチは何のため?)、Bugzilla の Core プロダクトには Tamarin コンポーネントが追加され、MDC-ja では Tamarin のビルド方法が翻訳されるなどまったく仕事の早いことでお疲れ様です。

詳しくは見ていませんが、基幹部分は結構現在の ECMAScript 4 草案に沿っているようですね。ECMAScript による ECMAScript コンパイラを提供するという部分では、構文木を XML で表現し、それを E4X で操作しているみたいですが、これって .NET Framework でいう CodeDOM? SpiderMonkey は C で書かれていて Tamarin は主に C++ でスムーズに統合できるのかとか、この成果は Flash にもフィードバックされるのかとか、いろいろと疑問はありますが、何はともあれこれは期待できそうです。

Tamarin 自体は Adobe と Mozilla が共同で開発を続け、Flash にも反映されるようですね。SpiderMonkey は Tamarin の GC を実装し、Tamarin 用のバイトコードを吐くようになる?

このブログで Safari がクラッシュ?2006年11月20日 20時07分

Safari 1.3.2 でこのブログを見るとクラッシュするという報告がありました。手元に Safari がないので確認できませんが、古の NN 4 ではあるまいし HTML や CSS が原因で落ちるとは考えづらく、おそらく JavaScript 絡みだろうと思います。なのでいったんスクリプトを外してみました。

しかし、このままでは原因がわかりませんので、それを絞るべくいくつかパターンを用意しました。Safari をお使いの方はよろしければ各パターンについて (面倒なら 1 だけでも) Safari がクラッシュするかどうかを検証していただけないでしょうか。なお、報告に際しては、Safari のバージョンと確実にクラッシュするのか時々クラッシュするのか、またはまったくクラッシュしないのかを添えてもらえると助かります。

  1. 従来どおり (スクリプトあり)
  2. ユーティリティースクリプトを外した状態
  3. 自作スクリプトライブラリを外した状態
  4. アクセス解析スクリプトを外した状態
  5. スクリプトをすべて外した状態
  6. スクリプトあり (改訂版)

Safari でのクラッシュを修正2006年11月21日 20時13分

Safari でこのブログを見るとクラッシュすることがあった問題ですが、私の書いたスクリプトに原因がありました。

var Klass = function () {
  if (this.constructor != arguments.callee)
    return new arguments.callee();

  /* Initialize object... */
};

これは「クラスの機能と関数の機能を併用」を基にしたもので、Klass() のように関数として呼び出されたときも、new Klass() と呼び出されたときと同じく Klass オブジェクトを返すための処理なのですが、これが期待通り働くためには Klass.prototype.constructor == Klass が成り立っていないといけません。しかし、Safari には関数式により作られた関数オブジェクト f に関して、f.prototype.constructor が設定されない (f.prototype.hasOwnProperty("constructor") == false となる) というバグがあるため、条件式が常に真と判断され、結果無限再帰に陥りクラッシュしてしまうようです。

修正案として真っ先に考えられるのは Klass.prototype.constructor = Klass と明示的に constructor プロパティを設定することですが、これを書いている途中でそれよりも条件式を !(this instanceof arguments.callee) にしたほうがいいと思い当たりました。でないと以下のような場合に不具合がおきます。

function Super(x) {
  if (!(this instanceof arguments.callee))
    return new arguments.callee(x);
  this.x = x;
  return this; // SpiderMonkey での警告を避ける
}

function Sub(x) {
  Super.apply(this, arguments);
}
Sub.prototype = new Super();
Sub.prototype.constructor = Sub;

print(new Sub(42).x); // 42
// if (this.constructor != arguments.callee) だと
// new Sub(42).x === undefined となる

しかし Safari がクラッシュするというのならアクセス解析に残っていた Safari の記録は何なのだろうと思って見直したら、どうもアクセス解析にあるのは Safari 2 (WebKit のビルド番号 400 番代) だけみたいです。原因となったバグ自体は Safari 2 でも直っていないのでエラーは出ているはずですが、クラッシュはしないように修正されたのでしょうか。

それにしても Safari を使っている人には 2 か月近くこのブログはブラクラと化していたわけで申し訳ないことです。おまけにこのバグは Safari の JavaScript の不備にも載せてあったもので、自分で引っかかるとはまったく情けない限りです。