Skip to content

Rethrow Haskell exceptions #95

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 6 commits into from

Conversation

roberth
Copy link
Collaborator

@roberth roberth commented Aug 10, 2019

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

  • Removes instances Eq CppException, Ord CppException because those can
    not be implemented for the CppHaskellException SomeException
    constructor.
  • Currently requires some boilerplate to actually throw a Haskell
    exception, but at least it can be done.

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

 - Removes instances Eq CppException, Ord CppException because those can
   not be implemented for the  CppHaskellException SomeException
   constructor.
 - Currently requires significant boilerplate to actually throw a Haskell
   exception, but at least it can be done.
@roberth roberth force-pushed the passthrough-exceptions branch from 71981bb to 18cdcb0 Compare August 10, 2019 21:17
@bitonic
Copy link
Collaborator

bitonic commented Aug 13, 2019

@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
Copy link
Collaborator

bitonic commented Aug 13, 2019

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

@roberth
Copy link
Collaborator Author

roberth commented Aug 13, 2019

@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
Copy link
Collaborator

bitonic commented Aug 13, 2019

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

  • Use my branch fpco/passthrough-exceptions which contains some cosmetic changes
  • Explain in a comment when this feature is useful, explaining why this wrapper cannot be written now
  • Get rid of the code automatically freeing the stable pointer from C++. I think the entire wrapper class should go. The reason why I think the wrapper class is a bad idea is that the responsibility for allocating and freeing should be in the same place. In this case Haskell should direct the allocation of the stable pointers.
  • I don't think that C++11 is required by anything but #pragma once. If that's the case, let's get rid of #pragma once and the C++11 requirement.

@roberth
Copy link
Collaborator Author

roberth commented Aug 13, 2019

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
Copy link
Collaborator

bitonic commented Aug 13, 2019

@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 roberth force-pushed the passthrough-exceptions branch from e05e396 to 70d1825 Compare August 27, 2019 14:40
@roberth
Copy link
Collaborator Author

roberth commented Aug 27, 2019

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
Copy link
Collaborator

bitonic commented Nov 25, 2019

Like with #83 (comment) , 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 🙏 .

@bitonic bitonic closed this Nov 25, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants