llvm-project
8f51da36 - [orc-rt] Add Error / Exception interop. (#172247)

Commit
43 days ago
[orc-rt] Add Error / Exception interop. (#172247) The ORC runtime needs to work in diverse codebases, both with and without C++ exceptions enabled (e.g. most LLVM projects compile with exceptions turned off, but regular C++ codebases will typically have them turned on). This introduces a tension in the ORC runtime: If a C++ exception is thrown (e.g. by a client-supplied callback) it can't be ignored, but orc_rt::Error values will assert if not handled prior to destruction. That makes the following pattern fundamentally unsafe in the ORC runtime: ``` if (auto Err = orc_rt_operation(...)) { log("failure, bailing out"); // <- may throw if exceptions enabled // Exception unwinds stack before Error is handled, triggers Error-not-checked // assertion here. return Err; } ``` We can resolve this tension by preventing any exceptions from unwinding through ORC runtime stack frames. We can do this while preserving exception *values* by catching all exceptions (using `catch (...)`) and capturing their values as a std::exception_ptr into an Error. This patch adds APIs to simplify conversion between C++ exceptions and Errors. These APIs are available only when enabled when the ORC runtime is configured with ORC_RT_ENABLE_EXCEPTIONS=On (the default). - `ExceptionError` wraps a std::exception_ptr. - `runCapturingExceptions` takes a T() callback and converts any exceptions thrown by the body into Errors. If T is Expected or Error already then runCapturingExceptions returns the same type. If T is void then runCapturingExceptions returns an Error (returning Error::success() if no exception is thrown). If T is any other type then runCapturingExceptions returns an Expected<T>. - A new Error::throwOnFailure method is added that converts failing values into thrown exceptions according to the following rules: 1. If the Error is of type ExceptionError then std::rethrow_exception is called on the contained std::exception_ptr to rethrow the original exception value. 2. If the Error is of any other type then std::unique_ptr<T> is thrown where T is the dynamic type of the Error. These rules allow exceptions to be propagated through the ORC runtime as Errors, and for ORC runtime errors to be converted to exceptions by clients.
Author
Parents
Loading