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()
と怒られた。でも、どこが悪いのかさっぱりなので、コードを読もう。
対象
- http://hg.mozilla.org/tamarin-central/file/2cee46be9ce0(2cee46be9ce0)
あと、上記の例外を投げているのは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; }