既知のバグ

私が把握しているバグとその一応の対処

もっと前のリビジョンからのバグかもしれないし、そうでないバグかもしれない。

check_implicit_lookupを呼び出してもチェックされない

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対策を想定した、というのが公式の見解である。たぶん。

uninitialize時にファイバーが残っていると落ちる

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;

VC++2010でコンパイルできない

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

という話もある。確かにほんのちょっとオーバーヘッドが大きくなるかもだけどこれでも動く。

まあこの項の通りに変えておけば何も問題ないはず。

ファイルローカルに4つ以上定義するとエラー

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);
}

ポインタをSmartPtrに暗黙変換すると落ちる

報告済み 解決(勘違いでした、というやつですね)

XTAL_PREBINDを忘れるとこうなる、っぽい

なので、コンストラクタや継承構造を記述しなくてもPREBINDだけは書く必要があるようだ。

Class::overwrite がおかしい

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;
				}

正確な発生条件がわからず、わかりにくいメモリ破壊をしている気がするが、それも呼び出し方が悪いだけかもしれず……

ライブラリ関連のミス

Xtalで実装されている部分

  • fun xpeg::select で、return Eelement(…) になっている。
    • 正しくは return Element(…)

Iterator::scanが動作しない

"foobar".scan(xpeg::pred(|x| x=="o")){it.p;}

はうまく動くのに対し、

"foobar".each.scan(xpeg::pred(|x| x=="o")){it.p;}

ではうまく動かない。

ArrayIter::scanが動作しない

実は上と同じ原因ではないか、とか思うけど未確認。

Executor::matchにeosを食わせると確実にtrueを返す

eosをちゃんとeatしていないようだ。

バインド関連

bug.txt · 最終更新: 2012/04/22 21:37 by sukai
www.chimeric.de Valid CSS Driven by DokuWiki do yourself a favour and use a real browser - get firefox!! Recent changes RSS feed Valid XHTML 1.0