私が把握しているバグとその一応の対処
もっと前のリビジョンからのバグかもしれないし、そうでないバグかもしれない。
r457で修正済み
* なお、xtal::debug::enable_debug_compileを呼び出しておかないと、デバッグ情報が積まれずに有効に動作しないので注意。
定義されていない変数の参照をチェックするcheck_implicit_lookupだが、いつからか、呼び出してもチェックされなくなってしまっている。
次のように変えるとチェックが有効になる。
// xtal_code.cpp // 10行目付近 void filelocal_check_implicit_lookup(const AnyPtr& a){ if(const CodePtr& code = ptr_cast<Code>(a)){ code->check_implicit_lookup(); } }
このようにすることで、次のような、定義されていない変数の参照が行われていないかどうかのチェックが行える。定義されていない変数の参照が行われていた場合、ランタイムエラーを発生させる。なお、定義されていない変数への代入はそもそもコンパイルエラーになる。
foo : 0; // filelocalへの変更が済んだら呼び出す check_implicit_lookup(); fun func(){ foo.p; bar.p; bar.p; hoge.p; } func();
同名の未定義変数参照につき1回しか報告してくれないようである。上の例で言うと、barとhogeの暗黙参照が報告されるが、barは片方の行数しか報告されない。
動的にfilelocalに追加する場合(他のファイルやC++などから追加する場合を指す)には使うことはできないが、それ以外の場合には有用であろう。typo対策を想定した、というのが公式の見解である。たぶん。
r458で追加修正
r456で修正済み
r438+VCで再現
内部でInt.timesを使っていて、かつそのブロック構文を1回でも抜けたファイバーが残っているとuninitializeで落ちるっぽい。
// 落ちる fib : fiber(){ for (;;){ 1.times{yield;} } } fib(); fib();
// 落ちない fib : fiber(){ for (;;){ 2.times{yield;} } } fib(); fib();
// 落ちない fib : fiber(){ for (;;){ 1.times{yield;} } } fib(); fib(); fib.halt;
// 落ちない fib : fiber(){ for (;;){ 1..1{yield;} } } fib(); fib();
// 落ちない fib : fiber(){ for (;;){ 1.times{yield;} } } fib(); fib(); fib = null;
r436で修正済み
VC2008とは関数のルックアップの順番が変わっているのが原因っぽい(コンパイルできたという話もあり?)。
エラーの場所は、xtal_base.hのVirtualmembersOverwriteChecker<T>で静的にオーバーライトをチェックしている部分と、xtal_utility.hのConvertible<T, U>, IsInherited<T, U>。
次のように変えるとコンパイルできる。
// xtal_base.h // 71行付近から template<class T> struct VirtualMembersOverwriteChecker{ typedef char (&yes)[2]; typedef char (&no)[1]; // 他のは省略 // 頭にcheck_ってつけただけ static no check_visit_members(void (RefCountingBase::*)(Visitor&)); template<class U> static yes check_visit_members(void (U::*)(Visitor&)); enum{ // 他のは省略 // こいつもcheck_ってつける visit_members_overwrite = sizeof(check_visit_members(&T::on_visit_members))!=sizeof(no), };
こっち(xtal_utility.h)の方は、もしかしたらxtalprojのtestプロジェクトでない限りいじらなくてもすむかも。未確認。
// xtal_utility.h // 245行付近から template<class T, class U> struct Convertible{ typedef char (&yes)[2]; typedef char (&no)[1]; static yes check_convertible(U); static no check_convertible(...); static T makeT(); enum{ value = sizeof(check_convertible(makeT()))==sizeof(yes) }; }; template<class T, class U> struct IsInherited{ typedef char (&yes)[2]; typedef char (&no)[1]; static yes check_is_inherited(const U*); static no check_is_inherited(...); static T* makeT(); enum{ // 完全型チェック CHECK = sizeof(T) + sizeof(U), value = sizeof(check_is_inherited(makeT()))==sizeof(yes) }; };
http://twitter.com/heppoko/status/12643769394
エラーが出た visit_members_overwrite = sizeof(visit_members(&T::on_visit_members))!=sizeof(no) を 1 にするとVS2010でビルドできる。 #xtal_lang
という話もある。確かにほんのちょっとオーバーヘッドが大きくなるかもだけどこれでも動く。
まあこの項の通りに変えておけば何も問題ないはず。
r438で修正済み
以下のようなコードでXtalが落ちる。
あくまでファイルローカル変数であり、関数内のローカル変数などでは大丈夫(たぶん)。
a : 0; b : 1; c : 2; d : 3;
原因は、xtal_vmachine.cppの1360行付近、XTAL_VM_CASE(InstSetFileLocalVariable)の内部でxarrayのサイズチェックをせずにset_atしてること。 とりあえずの対処としては、xtal_frame.hのclass Frameを直すと良い。
// xtal_frame.h // 78行付近 void set_member_direct(int_t i, const AnyPtr& value){ // これを追加 if (static_cast<int_t>(members_.size())<=i){ members_.resize(i+1); } members_.set_at(i, value); }
報告済み
解決(勘違いでした、というやつですね)
XTAL_PREBINDを忘れるとこうなる、っぽい
なので、コンストラクタや継承構造を記述しなくてもPREBINDだけは書く必要があるようだ。
r437で修正済み
ver : r432以降
Class::overwriteを呼び出すと、メモリアクセス例外で落ちる。
以下のようなコードをリロードすると、アクセス例外が出たりする。uninitializeで落ちたり、overwriteで落ちたりする。
class Foo{ reloaded(){ "reloaded".p; } } if (global::?Foo){ global::Foo.overwrite(Foo); } else { global::Foo : Foo; }
なお、r432-そのままでは、次のようなコードは1回リロードすると2回目以降はoverwriteが呼ばれない。
class global::Foo{ reloaded(){ "reloaded".p; } }
一応、xtal_class.cppの次の箇所を変更することで毎回overwriteが呼ばれるようにはなるが、僕の環境では割と高確率でメモリアクセス例外吐いた。
// xtal_class.cpp // 479行目あたり(r435) Class::overwrite_member // ... if(!dest->is_native() && !src->is_native()){ dest->overwrite(src); // FIX invalidate_cache_member(); return; }
正確な発生条件がわからず、わかりにくいメモリ破壊をしている気がするが、それも呼び出し方が悪いだけかもしれず……
"foobar".scan(xpeg::pred(|x| x=="o")){it.p;}
はうまく動くのに対し、
"foobar".each.scan(xpeg::pred(|x| x=="o")){it.p;}
ではうまく動かない。
実は上と同じ原因ではないか、とか思うけど未確認。
eosをちゃんとeatしていないようだ。