Hatena::ブログ(Diary)

みずぴー日記 Twitter

2008-12-23(火)

ABCのSlotがさっぱりなので、コードを読もう

| ABCのSlotがさっぱりなので、コードを読もうを含むブックマーク

ABCのSlotがさっぱりなので、Tamarinのコードを読もう。

目的

(define foo (new Foo))

というコードのfooにslotを割り当てたら、

TypeError: Error #1034: Type Coercion failed: cannot convert Foo@11177c9 to class Foo.
        at global$init()

と怒られた。でも、どこが悪いのかさっぱりなので、コードを読もう。

対象

読むソースコードは、Tamarinの最新版。

あと、上記の例外を投げているのはToplevel::coerceなので、そこを中心に。

ドキュメント生成

まずはDoxygenを使って、メソッド一覧とかを作ってやる。

http://howdyworld.org/junk/tamarin/namespaceavmplus.html

ホントは、EAを使ってクラス図を生成するつもりだったけど、うまくいかなかった。foo()->bar()のパースに失敗するような気がする。

XCodeデバッグ

ブレイクポイントとかが使えると便利なので、XCodeのプロジェクトを開いてやる。

プロジェクトのファイルはplatform/mac/shell/shell.xcodeprojに置いてある。

実行するABCコマンドラインで指定するにはXcodeでコマンドライン引数を指定する: シン石丸の電脳芸事ニッキを参考にする。

Toplevel.cpp

エラーになるのは、Toplevel.cppの761行目付近。

if (actual->containsInterface(expected))
{
  return atom;
}
else
{
  // failed
#ifdef AVMPLUS_VERBOSE
  //core->console << "checktype failed " << expected << " <- " << atom << "\n";
#endif
  throwTypeError(kCheckTypeFailedError, core->atomToErrorString(atom), core->toErrorString(expected));
  return atom;//unreachable
}

Traits::containsInterfaceは次のようになっている。

inline bool containsInterface(Traitsp t) { 
  return this == t || this->getTraitsBindings()->containsInterface(t); 
}

で、本体のTratsBinding::containsInterfaceはこんな感じ。

bool TraitsBindings::containsInterface(Traitsp t) const
{
        for (TraitsBindingsp self = this; self; self = self->base)
        {
                if (self->owner == t || self->findInterfaceAddr(t)->t != NULL)
                        return true;
                }
        return false;
}
トラックバック - http://d.hatena.ne.jp/mzp/20081223/traits
リンク元