Exception Personality Function

I figured that there might be others out there who are trying to figure out how to write a personality function, so I've attached the one I have written as an example. The code is straight ANSI C.

I used the GCC version as a reference, but I re-wrote most of it, and made the syntax more like the LLVM style. I also drew from a number of other personality functions for other languages that I found out on the web. One thing I did was to cut down on the complexity by making the code LLVM-specific - for example, I only included decoding functions for those encodings that are actually emitted by LLVM.

The personality function uses type descriptors from my language (Tart) rather than C++ std::type_info objects, and tests the exception type using my language's own isSubclass() method. This can serve as an example for how to use exceptions for languages that are different from C++.

To invoke the personality function and have it catch an exception, the IR that you generate should look like the following:

try:
  ;; Throw some exception
  invoke { } @"throwSomething"() to label %endTry unwind label %catch

catch:
  ;; Catch and decode the exception
  %eh_ptr = call i8* @llvm.eh.exception()
  %eh_action = call i32 (i8*, i8*, ...)* @llvm.eh.selector.i32(
    i8* %eh_ptr,
    i8* bitcast (i32 (i32, i32, i64, i8*, i8*)* @__tart_eh_personality to i8*),
    %tart.reflect.Type* @tart.core.InvalidArgumentException.type,
    %tart.reflect.Type* @tart.core.Throwable.type)

  ;; subtract offset of UnwindExceptInfo member within class Throwable
  %0 = bitcast i8* %eh_ptr to [0 x i8]*
  %eh_throwable = getelementptr [0 x i8]* %0, i32 0,
    i32 sub (i32 0, i32 ptrtoint (%2* getelementptr (
       %tart.core.Throwable* null, i32 0, i32 2) to i32))

  ;; Branch based on action from personality func.
  switch i32 %eh_action, label %catch-InvalidArgumentException [
    i32 0, label %catch-InvalidArgumentException
    i32 1, label %catch-Throwable
  ]

catch-InvalidArgumentException:
  ;; Cast to caught type
  %bitcast = bitcast i8* %eh_throwable to %tart.core.InvalidArgumentException*
  br label %endTry

catch-Throwable: ; preds = %catch
  ;; Cast to caught type
  %bitcast9 = bitcast i8* %eh_throwable to %tart.core.Throwable*
  br label %endTry

-- Talin

tart_eh_personality.c (8.26 KB)