近&況

Recent Posts
Edit

LLVMで例外を実装するには

2017-04-06

LLVMを使った自作言語に例外を入れることを考えてた。結論からいうとCrystalのソースを真似するのでよさそう。

_Unwind_RaiseException等の仕様はここ。http://itanium-cxx-abi.github.io/cxx-abi/abi-eh.html

「Itanium C++ ABI」という名前ではあるけれど、Level I, II, IIIのうちのLevel I部分(_Unwind_RaiseException等)はC++に限らない言語独立なAPIになっている。__cxa_throwはLevel IIで、C++用のもの(であるけれど、場合によってはこれが使えることもあるかも)。

1. http://releases.llvm.org/4.0.0/docs/ExceptionHandling.html

LLVMの公式ドキュメントに例外についての文書があるんだけど、これ読んでも何をしたらいいのか良く分からんのだよな。 特に例外を投げる方法が書いてない。

2. http://sile.hatenablog.jp/entry/20100206/1265454978

過去のLLVM(2.6)では「unwind命令」というのがあり、例外を投げることができたっぽい?

3. Crystal

Crystalのソースを見るとlibunwindというライブラリを使っているらしいことがわかる。

4. clang

clangでthrowがどうコンパイルされるか見てみると、@__cxa_throwという外部関数の呼び出しになった。

declare void @__cxa_throw(i8*, i8*, i8*)

5. g++ http://d.hatena.ne.jp/fixme/20100124/1264301168

__cxa_throwで検索すると、g++における実装が見つかる。_Unwind_RaiseExceptionという関数を呼び出している。

6. http://stackoverflow.com/a/17695760/1662841

でですね、StackOverflowによると、_Unwind_RaiseExceptionはlibunwindの関数であるらしい。

Short answer is that _Unwind_RaiseException is not a C++-specific function. It comes from the libunwind library, and allows to throw any type of exception.

ということでまとめると以下のような構図になっている。

参考文献

真面目にやるならこのへん読むのがよさそう

おまけ1

github libunwindで検索するといくつか見つけるけど、中を見る限り別のものっぽい

おまけ2

http://www.snsystems.com/ja/technology/tech-blog/2015/06/11/abi-bugs-are-a-nightmare/

ItaniumってインテルのCPUの名前じゃなかったっけ?という疑問に対する解答があった

IA-64 ABI または Itanium ABI として知られる、現在使用されている C++ コンパイラのほとんどに採用されている C++ ABI は、当初 Itanium 64 ビット プロセッサ用に開発されたものでした。しかし、この ABI は、GNU-C++、ARMcc、Clang/LLVM や PS3、PSVita および PS4 などの PlayStation 用コンパイラなど、広く使用されている多くのコンパイラによって利用されてきました。Microsoft Visual C++ コンパイラを除き、C++ ABI は、コンパイラ ベンダーの事実上の業界標準になりました。