fpco / inline-c

284 stars 50 forks source link

Rethrow Haskell exceptions #95

Closed roberth closed 4 years ago

roberth commented 5 years ago

This adds the ability to throw any Haskell exception from C++ code.

Functions to make the throwing easier/automatic can be built on top of this.

bitonic commented 5 years ago

@roberth thanks for the contribution!

However, it's not entirely clear to me what this is for. From the PR title I'd have expected it to be some code related to the handling of Haskell exceptions thrown in Haskell code being called by C++, but it seems to be about being able to explicitly throwing Haskell exceptions from C++.

Can you clarify the kind of situations where this is useful?

bitonic commented 5 years ago

BTW, I've pushed a cleaned-up version of your branch to fpco/passthrough-exceptions.

roberth commented 5 years ago

@bitonic Indeed it doesn't implement the "throwing" side of the feature. It currently needs a custom wrapper to achieve this.

We're having some trouble building C++ projects on darwin like #64 so we can't really implement a generic solution for the wrappers / funPtr until that's solved.

The reason we built this is because we need to propagate a specific exception that we throw to all throwBlocks. Specifically, these are build exceptions (Haskell) during Nix evaluation (C++) in hercules-ci-agent (Haskell).

bitonic commented 5 years ago

I see. From a first review, these are the things to do to get it merged:

roberth commented 5 years ago

I don't think the Haskell code can know when to free the stable pointer. If the exception is caught in C++, Haskell will never see it again, causing a leak.

I'll document how to use it. Ideally, the library user doesn't have to deal with this because inline-c-cpp will do it automatically in funPtr.

bitonic commented 5 years ago

@roberth can't the Haskell code just unconditionally free the stable pointer once the C++ code has finished executing? In any case, if it must be from C++, explain why in a comment.

roberth commented 5 years ago

can't the Haskell code just unconditionally free the stable pointer once the C++ code has finished executing?

This is for passing Haskell functions to C++ code that we don't control (technically passing a manually written wrapper to the C++ code, but that doesn't change anything). So in general, we don't know when the Haskell exception can be freed by the C++ code. It may even sit around for a long time in a std::promise for example.

(This is now reflected in the inline doc on the HaskellException class)

bitonic commented 4 years ago

Like with https://github.com/fpco/inline-c/pull/83#issuecomment-558351762 , I got busy and I completely forgot about these two not-obvious PRs. I've now merged this and released it as inline-c-cpp-0.4.0.0. So sorry about the delay :pray: .