Skip to content

Instantly share code, notes, and snippets.

@harpocrates
Last active May 15, 2018 15:39
Show Gist options
  • Select an option

  • Save harpocrates/be95a19dbd8adf14170429e2608963a6 to your computer and use it in GitHub Desktop.

Select an option

Save harpocrates/be95a19dbd8adf14170429e2608963a6 to your computer and use it in GitHub Desktop.
An idea...
#![feature(fn_traits)]
#![feature(unboxed_closures)]
/// Wrapper around Haskell function. Note this _cannot_ be copied/cloned
#[repr(C)]
pub struct HaskellFn1<A,B>(extern "C" fn(A) -> B);
/// Closure behaviour
impl<A,B> FnOnce<A> for HaskellFn1<A,B> {
type Output = B;
extern "rust-call" fn call_once(self, args: A) -> B {
let HaskellFn1(func) = self;
func(args)
}
}
impl<A,B> FnMut<A> for HaskellFn1<A,B> {
extern "rust-call" fn call_mut(&mut self, args: A) -> B {
let HaskellFn1(func) = self;
func(args)
}
}
impl<A,B> Fn<A> for HaskellFn1<A,B> {
extern "rust-call" fn call(&self, args: A) -> B {
let HaskellFn1(func) = self;
func(args)
}
}
/// Deallocation
impl <A,B> Drop for HaskellFn1<A,B> {
fn drop(&mut self) {
extern "C" {
#[no_mangle]
fn freeHaskellFunctionPtr(f: extern fn(*const u8) -> *const u8);
}
let HaskellFn1(func) = self;
unsafe {
freeHaskellFunctionPtr(::std::mem::transmute(*func));
}
}
}
/// Marshalling
pub trait MarshalInto<T> { fn marshal(self) -> T; }
impl<A,B> MarshalInto<HaskellFn1<A,B>> for (extern "C" fn(A) -> B) {
fn marshal(self) -> HaskellFn1<A,B> {
HaskellFn1(self)
}
}
fn main() { }
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment