yhara.jp

Recent Posts

LLVMと例外

Tech

LLVMはC++のコンパイルのために例外をサポートするいくつかの機構を持っています。これはCrystalなど例外を持つ言語で利用されているほか、Rustのように例外を持たない言語でも、関数脱出時の確実な後処理(RustでいうDrop)を実現するために利用されているケースがあります。

https://llvm.org/docs/ExceptionHandling.html

各言語での実装

関連するLLVM命令

  • invoke命令
    • invoke 関数 to label %A unwind label %B の形をとる
    • 関数を実行し、例外が発生したらラベルBに飛ぶ。そうでなければラベルAに飛ぶ
    • invokeを呼ぶ関数はpersonality functionの指定が必要
  • 関数定義時のpersonality functionの指定
    • 例:define void @foo() personality i32 (i32, i32, i64, %"unwind::libunwind::_Unwind_Exception"*, %"unwind::libunwind::_Unwind_Context"*)* @rust_eh_personality {
    • rust_eh_personalityは declare i32 @rust_eh_personality(i32, i32 noundef, i64, %"unwind::libunwind::_Unwind_Exception"*, %"unwind::libunwind::_Unwind_Context"*) のように宣言されている
  • landingpad命令
    • invoke ~ unwind %BのラベルBの冒頭で使われる命令。発生した例外の情報を取り出すために使われる?
    • landingpad ~ catch: 例外をキャッチした際の処理を指定。
    • landingpad ~ cleanup: cleanup処理を指定。resume命令で終わること。
  • resume命令
    • unwind処理を再開する。
  • catchswitch命令
    • ある関数が複数のcatchをもつ場合に使う?

用語解説

personality functionの仕様

例外の発生方法

libunwindの_Unwind_RaiseException()を呼ぶ。

More posts

Posts

(more...)

Articles

(more...)

Category

Ads

About

About the author