//! Support for long-lived closures in `wasm-bindgen`
//!
//! This module defines the `Closure` type which is used to pass "owned
//! closures" from Rust to JS. Some more details can be found on the `Closure`
//! type itself.

use std::fmt;
#[cfg(feature = "nightly")]
use std::marker::Unsize;
use std::mem::{self, ManuallyDrop};
use std::prelude::v1::*;

use crate::convert::*;
use crate::describe::*;
use crate::throw_str;
use crate::JsValue;
use crate::UnwrapThrowExt;

/// A handle to both a closure in Rust as well as JS closure which will invoke
/// the Rust closure.
///
/// A `Closure` is the primary way that a `'static` lifetime closure is
/// transferred from Rust to JS. `Closure` currently requires that the closures
/// it's created with have the `'static` lifetime in Rust for soundness reasons.
///
/// This type is a "handle" in the sense that whenever it is dropped it will
/// invalidate the JS closure that it refers to. Any usage of the closure in JS
/// after the `Closure` has been dropped will raise an exception. It's then up
/// to you to arrange for `Closure` to be properly deallocate at an appropriate
/// location in your program.
///
/// The type parameter on `Closure` is the type of closure that this represents.
/// Currently this can only be the `Fn` and `FnMut` traits with up to 7
/// arguments (and an optional return value). The arguments/return value of the
/// trait must be numbers like `u32` for now, although this restriction may be
/// lifted in the future!
///
/// # Examples
///
/// Here are a number of examples of using `Closure`.
///
/// ## Using the `setInterval` API
///
/// Sample usage of `Closure` to invoke the `setInterval` API.
///
/// ```rust,no_run
/// use wasm_bindgen::prelude::*;
///
/// #[wasm_bindgen]
/// extern "C" {
///     fn setInterval(closure: &Closure<FnMut()>, time: u32) -> i32;
///     fn clearInterval(id: i32);
///
///     #[wasm_bindgen(js_namespace = console)]
///     fn log(s: &str);
/// }
///
/// #[wasm_bindgen]
/// pub struct IntervalHandle {
///     interval_id: i32,
///     _closure: Closure<FnMut()>,
/// }
///
/// impl Drop for IntervalHandle {
///     fn drop(&mut self) {
///         clearInterval(self.interval_id);
///     }
/// }
///
/// #[wasm_bindgen]
/// pub fn run() -> IntervalHandle {
///     // First up we use `Closure::wrap` to wrap up a Rust closure and create
///     // a JS closure.
///     let cb = Closure::wrap(Box::new(|| {
///         log("interval elapsed!");
///     }) as Box<FnMut()>);
///
///     // Next we pass this via reference to the `setInterval` function, and
///     // `setInterval` gets a handle to the corresponding JS closure.
///     let interval_id = setInterval(&cb, 1_000);
///
///     // If we were to drop `cb` here it would cause an exception to be raised
///     // whenever the interval elapses. Instead we *return* our handle back to JS
///     // so JS can decide when to cancel the interval and deallocate the closure.
///     IntervalHandle {
///         interval_id,
///         _closure: cb,
///     }
/// }
/// ```
///
/// ## Casting a `Closure` to a `js_sys::Function`
///
/// This is the same `setInterval` example as above, except it is using
/// `web_sys` (which uses `js_sys::Function` for callbacks) instead of manually
/// writing bindings to `setInterval` and other Web APIs.
///
/// ```rust,ignore
/// use wasm_bindgen::JsCast;
///
/// #[wasm_bindgen]
/// pub struct IntervalHandle {
///     interval_id: i32,
///     _closure: Closure<FnMut()>,
/// }
///
/// impl Drop for IntervalHandle {
///     fn drop(&mut self) {
///         let window = web_sys::window().unwrap();
///         window.clear_interval_with_handle(self.interval_id);
///     }
/// }
///
/// #[wasm_bindgen]
/// pub fn run() -> Result<IntervalHandle, JsValue> {
///     let cb = Closure::wrap(Box::new(|| {
///         web_sys::console::log_1(&"inverval elapsed!".into());
///     }) as Box<FnMut()>);
///
///     let window = web_sys::window().unwrap();
///     let interval_id = window.set_interval_with_callback_and_timeout_and_arguments_0(
///         // Note this method call, which uses `as_ref()` to get a `JsValue`
///         // from our `Closure` which is then converted to a `&Function`
///         // using the `JsCast::unchecked_ref` function.
///         cb.as_ref().unchecked_ref(),
///         1_000,
///     )?;
///
///     // Same as above.
///     Ok(IntervalHandle {
///         interval_id,
///         _closure: cb,
///     })
/// }
/// ```
///
/// ## Using `FnOnce` and `Closure::once` with `requestAnimationFrame`
///
/// Because `requestAnimationFrame` only calls its callback once, we can use
/// `FnOnce` and `Closure::once` with it.
///
/// ```rust,no_run
/// use wasm_bindgen::prelude::*;
///
/// #[wasm_bindgen]
/// extern "C" {
///     fn requestAnimationFrame(closure: &Closure<FnMut()>) -> u32;
///     fn cancelAnimationFrame(id: u32);
///
///     #[wasm_bindgen(js_namespace = console)]
///     fn log(s: &str);
/// }
///
/// #[wasm_bindgen]
/// pub struct AnimationFrameHandle {
///     animation_id: u32,
///     _closure: Closure<FnMut()>,
/// }
///
/// impl Drop for AnimationFrameHandle {
///     fn drop(&mut self) {
///         cancelAnimationFrame(self.animation_id);
///     }
/// }
///
/// // A type that will log a message when it is dropped.
/// struct LogOnDrop(&'static str);
/// impl Drop for LogOnDrop {
///     fn drop(&mut self) {
///         log(self.0);
///     }
/// }
///
/// #[wasm_bindgen]
/// pub fn run() -> AnimationFrameHandle {
///     // We are using `Closure::once` which takes a `FnOnce`, so the function
///     // can drop and/or move things that it closes over.
///     let fired = LogOnDrop("animation frame fired or canceled");
///     let cb = Closure::once(move || drop(fired));
///
///     // Schedule the animation frame!
///     let animation_id = requestAnimationFrame(&cb);
///
///     // Again, return a handle to JS, so that the closure is not dropped
///     // immediately and JS can decide whether to cancel the animation frame.
///     AnimationFrameHandle {
///         animation_id,
///         _closure: cb,
///     }
/// }
/// ```
///
/// ## Converting `FnOnce`s directly into JavaScript Functions with `Closure::once_into_js`
///
/// If we don't want to allow a `FnOnce` to be eagerly dropped (maybe because we
/// just want it to drop after it is called and don't care about cancellation)
/// then we can use the `Closure::once_into_js` function.
///
/// This is the same `requestAnimationFrame` example as above, but without
/// supporting early cancellation.
///
/// ```
/// use wasm_bindgen::prelude::*;
///
/// #[wasm_bindgen]
/// extern "C" {
///     // We modify the binding to take an untyped `JsValue` since that is what
///     // is returned by `Closure::once_into_js`.
///     //
///     // If we were using the `web_sys` binding for `requestAnimationFrame`,
///     // then the call sites would cast the `JsValue` into a `&js_sys::Function`
///     // using `f.unchecked_ref::<js_sys::Function>()`. See the `web_sys`
///     // example above for details.
///     fn requestAnimationFrame(callback: JsValue);
///
///     #[wasm_bindgen(js_namespace = console)]
///     fn log(s: &str);
/// }
///
/// // A type that will log a message when it is dropped.
/// struct LogOnDrop(&'static str);
/// impl Drop for LogOnDrop {
///     fn drop(&mut self) {
///         log(self.0);
///     }
/// }
///
/// #[wasm_bindgen]
/// pub fn run() {
///     // We are using `Closure::once_into_js` which takes a `FnOnce` and
///     // converts it into a JavaScript function, which is returned as a
///     // `JsValue`.
///     let fired = LogOnDrop("animation frame fired");
///     let cb = Closure::once_into_js(move || drop(fired));
///
///     // Schedule the animation frame!
///     requestAnimationFrame(cb);
///
///     // No need to worry about whether or not we drop a `Closure`
///     // here or return some sort of handle to JS!
/// }
/// ```
pub struct Closure<T: ?Sized> {
    js: ManuallyDrop<JsValue>,
    data: ManuallyDrop<Box<T>>,
}

union FatPtr<T: ?Sized> {
    ptr: *mut T,
    fields: (usize, usize),
}

impl<T> Closure<T>
where
    T: ?Sized + WasmClosure,
{
    /// A more ergonomic version of `Closure::wrap` that does the boxing and
    /// cast to trait object for you.
    ///
    /// *This method requires the `nightly` feature of the `wasm-bindgen` crate
    /// to be enabled, meaning this is a nightly-only API. Users on stable
    /// should use `Closure::wrap`.*
    #[cfg(feature = "nightly")]
    pub fn new<F>(t: F) -> Closure<T>
    where
        F: Unsize<T> + 'static,
    {
        Closure::wrap(Box::new(t) as Box<T>)
    }

    /// Creates a new instance of `Closure` from the provided boxed Rust
    /// function.
    ///
    /// Note that the closure provided here, `Box<T>`, has a few requirements
    /// associated with it:
    ///
    /// * It must implement `Fn` or `FnMut` (for `FnOnce` functions see
    ///   `Closure::once` and `Closure::once_into_js`).
    ///
    /// * It must be `'static`, aka no stack references (use the `move`
    ///   keyword).
    ///
    /// * It can have at most 7 arguments.
    ///
    /// * Its arguments and return values are all types that can be shared with
    ///   JS (i.e. have `#[wasm_bindgen]` annotations or are simple numbers,
    ///   etc.)
    pub fn wrap(mut data: Box<T>) -> Closure<T> {
        assert_eq!(mem::size_of::<*const T>(), mem::size_of::<FatPtr<T>>());
        let (a, b) = unsafe {
            FatPtr {
                ptr: &mut *data as *mut T,
            }
            .fields
        };

        // Here we need to create a `JsValue` with the data and `T::invoke()`
        // function pointer. To do that we... take a few unconventional turns.
        // In essence what happens here is this:
        //
        // 1. First up, below we call a function, `breaks_if_inlined`. This
        //    function, as the name implies, does not work if it's inlined.
        //    More on that in a moment.
        // 2. This function internally calls a special import recognized by the
        //    `wasm-bindgen` CLI tool, `__wbindgen_describe_closure`. This
        //    imported symbol is similar to `__wbindgen_describe` in that it's
        //    not intended to show up in the final binary but it's an
        //    intermediate state for a `wasm-bindgen` binary.
        // 3. The `__wbindgen_describe_closure` import is namely passed a
        //    descriptor function, monomorphized for each invocation.
        //
        // Most of this doesn't actually make sense to happen at runtime! The
        // real magic happens when `wasm-bindgen` comes along and updates our
        // generated code. When `wasm-bindgen` runs it performs a few tasks:
        //
        // * First, it finds all functions that call
        //   `__wbindgen_describe_closure`. These are all `breaks_if_inlined`
        //   defined below as the symbol isn't called anywhere else.
        // * Next, `wasm-bindgen` executes the `breaks_if_inlined`
        //   monomorphized functions, passing it dummy arguments. This will
        //   execute the function just enough to invoke the special import,
        //   namely telling us about the function pointer that is the describe
        //   shim.
        // * This knowledge is then used to actually find the descriptor in the
        //   function table which is then executed to figure out the signature
        //   of the closure.
        // * Finally, and probably most heinously, the call to
        //   `breaks_if_inlined` is rewritten to call an otherwise globally
        //   imported function. This globally imported function will generate
        //   the `JsValue` for this closure specialized for the signature in
        //   question.
        //
        // Later on `wasm-gc` will clean up all the dead code and ensure that
        // we don't actually call `__wbindgen_describe_closure` at runtime. This
        // means we will end up not actually calling `breaks_if_inlined` in the
        // final binary, all calls to that function should be pruned.
        //
        // See crates/cli-support/src/js/closures.rs for a more information
        // about what's going on here.

        extern "C" fn describe<T: WasmClosure + ?Sized>() {
            inform(CLOSURE);
            T::describe()
        }

        #[inline(never)]
        unsafe fn breaks_if_inlined<T: WasmClosure + ?Sized>(a: usize, b: usize) -> u32 {
            super::__wbindgen_describe_closure(a as u32, b as u32, describe::<T> as u32)
        }

        let idx = unsafe { breaks_if_inlined::<T>(a, b) };

        Closure {
            js: ManuallyDrop::new(JsValue::_new(idx)),
            data: ManuallyDrop::new(data),
        }
    }

    /// Leaks this `Closure` to ensure it remains valid for the duration of the
    /// entire program.
    ///
    /// > **Note**: this function will leak memory. It should be used sparingly
    /// > to ensure the memory leak doesn't affect the program too much.
    ///
    /// When a `Closure` is dropped it will invalidate the associated JS
    /// closure, but this isn't always desired. Some callbacks are alive for
    /// the entire duration of the program, so this can be used to conveniently
    /// leak this instance of `Closure` while performing as much internal
    /// cleanup as it can.
    pub fn forget(self) {
        unsafe {
            super::__wbindgen_cb_forget(self.js.idx);
            mem::forget(self);
        }
    }
}

// NB: we use a specific `T` for this `Closure<T>` impl block to avoid every
// call site having to provide an explicit, turbo-fished type like
// `Closure::<FnOnce()>::once(...)`.
impl Closure<dyn FnOnce()> {
    /// Create a `Closure` from a function that can only be called once.
    ///
    /// Since we have no way of enforcing that JS cannot attempt to call this
    /// `FnOne(A...) -> R` more than once, this produces a `Closure<FnMut(A...)
    /// -> R>` that will dynamically throw a JavaScript error if called more
    /// than once.
    ///
    /// # Example
    ///
    /// ```rust,no_run
    /// use wasm_bindgen::prelude::*;
    ///
    /// // Create an non-`Copy`, owned `String`.
    /// let mut s = String::from("Hello");
    ///
    /// // Close over `s`. Since `f` returns `s`, it is `FnOnce` and can only be
    /// // called once. If it was called a second time, it wouldn't have any `s`
    /// // to work with anymore!
    /// let f = move || {
    ///     s += ", World!";
    ///     s
    /// };
    ///
    /// // Create a `Closure` from `f`. Note that the `Closure`'s type parameter
    /// // is `FnMut`, even though `f` is `FnOnce`.
    /// let closure: Closure<FnMut() -> String> = Closure::once(f);
    /// ```
    pub fn once<F, A, R>(fn_once: F) -> Closure<F::FnMut>
    where
        F: 'static + WasmClosureFnOnce<A, R>,
    {
        Closure::wrap(fn_once.into_fn_mut())
    }

    /// Convert a `FnOnce(A...) -> R` into a JavaScript `Function` object.
    ///
    /// If the JavaScript function is invoked more than once, it will throw an
    /// exception.
    ///
    /// Unlike `Closure::once`, this does *not* return a `Closure` that can be
    /// dropped before the function is invoked to deallocate the closure. The
    /// only way the `FnOnce` is deallocated is by calling the JavaScript
    /// function. If the JavaScript function is never called then the `FnOnce`
    /// and everything it closes over will leak.
    ///
    /// ```rust,ignore
    /// use js_sys;
    /// use wasm_bindgen::{prelude::*, JsCast};
    ///
    /// let f = Closure::once_into_js(move || {
    ///     // ...
    /// });
    ///
    /// assert!(f.is_instance_of::<js_sys::Function>());
    /// ```
    pub fn once_into_js<F, A, R>(fn_once: F) -> JsValue
    where
        F: 'static + WasmClosureFnOnce<A, R>,
    {
        fn_once.into_js_function()
    }
}

/// A trait for converting an `FnOnce(A...) -> R` into a `FnMut(A...) -> R` that
/// will throw if ever called more than once.
#[doc(hidden)]
pub trait WasmClosureFnOnce<A, R>: 'static {
    type FnMut: ?Sized + 'static + WasmClosure;

    fn into_fn_mut(self) -> Box<Self::FnMut>;

    fn into_js_function(self) -> JsValue;
}

impl<T: ?Sized> AsRef<JsValue> for Closure<T> {
    fn as_ref(&self) -> &JsValue {
        &self.js
    }
}

impl<T> WasmDescribe for Closure<T>
where
    T: WasmClosure + ?Sized,
{
    fn describe() {
        inform(ANYREF);
    }
}

// `Closure` can only be passed by reference to imports.
impl<'a, T> IntoWasmAbi for &'a Closure<T>
where
    T: WasmClosure + ?Sized,
{
    type Abi = u32;

    fn into_abi(self) -> u32 {
        (&*self.js).into_abi()
    }
}

fn _check() {
    fn _assert<T: IntoWasmAbi>() {}
    _assert::<&Closure<dyn Fn()>>();
    _assert::<&Closure<dyn Fn(String)>>();
    _assert::<&Closure<dyn Fn() -> String>>();
    _assert::<&Closure<dyn FnMut()>>();
    _assert::<&Closure<dyn FnMut(String)>>();
    _assert::<&Closure<dyn FnMut() -> String>>();
}

impl<T> fmt::Debug for Closure<T>
where
    T: ?Sized,
{
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "Closure {{ ... }}")
    }
}

impl<T> Drop for Closure<T>
where
    T: ?Sized,
{
    fn drop(&mut self) {
        unsafe {
            // this will implicitly drop our strong reference in addition to
            // invalidating all future invocations of the closure
            if super::__wbindgen_cb_drop(self.js.idx) != 0 {
                ManuallyDrop::drop(&mut self.data);
            }
        }
    }
}

/// An internal trait for the `Closure` type.
///
/// This trait is not stable and it's not recommended to use this in bounds or
/// implement yourself.
#[doc(hidden)]
pub unsafe trait WasmClosure {
    fn describe();
}

// The memory safety here in these implementations below is a bit tricky. We
// want to be able to drop the `Closure` object from within the invocation of a
// `Closure` for cases like promises. That means that while it's running we
// might drop the `Closure`, but that shouldn't invalidate the environment yet.
//
// Instead what we do is to wrap closures in `Rc` variables. The main `Closure`
// has a strong reference count which keeps the trait object alive. Each
// invocation of a closure then *also* clones this and gets a new reference
// count. When the closure returns it will release the reference count.
//
// This means that if the main `Closure` is dropped while it's being invoked
// then destruction is deferred until execution returns. Otherwise it'll
// deallocate data immediately.

macro_rules! doit {
    ($(
        ($($var:ident)*)
    )*) => ($(
        unsafe impl<$($var,)* R> WasmClosure for dyn Fn($($var),*) -> R + 'static
            where $($var: FromWasmAbi + 'static,)*
                  R: ReturnWasmAbi + 'static,
        {
            fn describe() {
                #[allow(non_snake_case)]
                unsafe extern "C" fn invoke<$($var: FromWasmAbi,)* R: ReturnWasmAbi>(
                    a: usize,
                    b: usize,
                    $($var: <$var as FromWasmAbi>::Abi),*
                ) -> <R as ReturnWasmAbi>::Abi {
                    if a == 0 {
                        throw_str("closure invoked recursively or destroyed already");
                    }
                    // Make sure all stack variables are converted before we
                    // convert `ret` as it may throw (for `Result`, for
                    // example)
                    let ret = {
                        let f: *const dyn Fn($($var),*) -> R =
                            FatPtr { fields: (a, b) }.ptr;
                        $(
                            let $var = <$var as FromWasmAbi>::from_abi($var);
                        )*
                        (*f)($($var),*)
                    };
                    ret.return_abi()
                }

                inform(invoke::<$($var,)* R> as u32);

                unsafe extern fn destroy<$($var: FromWasmAbi,)* R: ReturnWasmAbi>(
                    a: usize,
                    b: usize,
                ) {
                    // This can be called by the JS glue in erroneous situations
                    // such as when the closure has already been destroyed. If
                    // that's the case let's not make things worse by
                    // segfaulting and/or asserting, so just ignore null
                    // pointers.
                    if a == 0 {
                        return;
                    }
                    drop(Box::from_raw(FatPtr::<dyn Fn($($var,)*) -> R> {
                        fields: (a, b)
                    }.ptr));
                }
                inform(destroy::<$($var,)* R> as u32);

                <&Self>::describe();
            }
        }

        unsafe impl<$($var,)* R> WasmClosure for dyn FnMut($($var),*) -> R + 'static
            where $($var: FromWasmAbi + 'static,)*
                  R: ReturnWasmAbi + 'static,
        {
            fn describe() {
                #[allow(non_snake_case)]
                unsafe extern "C" fn invoke<$($var: FromWasmAbi,)* R: ReturnWasmAbi>(
                    a: usize,
                    b: usize,
                    $($var: <$var as FromWasmAbi>::Abi),*
                ) -> <R as ReturnWasmAbi>::Abi {
                    if a == 0 {
                        throw_str("closure invoked recursively or destroyed already");
                    }
                    // Make sure all stack variables are converted before we
                    // convert `ret` as it may throw (for `Result`, for
                    // example)
                    let ret = {
                        let f: *const dyn FnMut($($var),*) -> R =
                            FatPtr { fields: (a, b) }.ptr;
                        let f = f as *mut dyn FnMut($($var),*) -> R;
                        $(
                            let $var = <$var as FromWasmAbi>::from_abi($var);
                        )*
                        (*f)($($var),*)
                    };
                    ret.return_abi()
                }

                inform(invoke::<$($var,)* R> as u32);

                unsafe extern fn destroy<$($var: FromWasmAbi,)* R: ReturnWasmAbi>(
                    a: usize,
                    b: usize,
                ) {
                    // See `Fn()` above for why we simply return
                    if a == 0 {
                        return;
                    }
                    drop(Box::from_raw(FatPtr::<dyn FnMut($($var,)*) -> R> {
                        fields: (a, b)
                    }.ptr));
                }
                inform(destroy::<$($var,)* R> as u32);

                <&mut Self>::describe();
            }
        }

        #[allow(non_snake_case, unused_parens)]
        impl<T, $($var,)* R> WasmClosureFnOnce<($($var),*), R> for T
            where T: 'static + FnOnce($($var),*) -> R,
                  $($var: FromWasmAbi + 'static,)*
                  R: ReturnWasmAbi + 'static
        {
            type FnMut = dyn FnMut($($var),*) -> R;

            fn into_fn_mut(self) -> Box<Self::FnMut> {
                let mut me = Some(self);
                Box::new(move |$($var),*| {
                    let me = me.take().expect_throw("FnOnce called more than once");
                    me($($var),*)
                })
            }

            fn into_js_function(self) -> JsValue {
                use std::rc::Rc;
                use crate::__rt::WasmRefCell;

                let mut me = Some(self);

                let rc1 = Rc::new(WasmRefCell::new(None));
                let rc2 = rc1.clone();

                let closure = Closure::wrap(Box::new(move |$($var),*| {
                    // Invoke ourself and get the result.
                    let me = me.take().expect_throw("FnOnce called more than once");
                    let result = me($($var),*);

                    // And then drop the `Rc` holding this function's `Closure`
                    // alive.
                    debug_assert_eq!(Rc::strong_count(&rc2), 1);
                    let option_closure = rc2.borrow_mut().take();
                    debug_assert!(option_closure.is_some());
                    drop(option_closure);

                    result
                }) as Box<dyn FnMut($($var),*) -> R>);

                let js_val = closure.as_ref().clone();

                *rc1.borrow_mut() = Some(closure);
                debug_assert_eq!(Rc::strong_count(&rc1), 2);
                drop(rc1);

                js_val
            }
        }
    )*)
}

doit! {
    ()
    (A)
    (A B)
    (A B C)
    (A B C D)
    (A B C D E)
    (A B C D E F)
    (A B C D E F G)
    (A B C D E F G H)
}

// Copy the above impls down here for where there's only one argument and it's a
// reference. We could add more impls for more kinds of references, but it
// becomes a combinatorial explosion quickly. Let's see how far we can get with
// just this one! Maybe someone else can figure out voodoo so we don't have to
// duplicate.

unsafe impl<A, R> WasmClosure for dyn Fn(&A) -> R
    where A: RefFromWasmAbi,
          R: ReturnWasmAbi + 'static,
{
    fn describe() {
        #[allow(non_snake_case)]
        unsafe extern "C" fn invoke<A: RefFromWasmAbi, R: ReturnWasmAbi>(
            a: usize,
            b: usize,
            arg: <A as RefFromWasmAbi>::Abi,
        ) -> <R as ReturnWasmAbi>::Abi {
            if a == 0 {
                throw_str("closure invoked recursively or destroyed already");
            }
            // Make sure all stack variables are converted before we
            // convert `ret` as it may throw (for `Result`, for
            // example)
            let ret = {
                let f: *const dyn Fn(&A) -> R =
                    FatPtr { fields: (a, b) }.ptr;
                let arg = <A as RefFromWasmAbi>::ref_from_abi(arg);
                (*f)(&*arg)
            };
            ret.return_abi()
        }

        inform(invoke::<A, R> as u32);

        unsafe extern fn destroy<A: RefFromWasmAbi, R: ReturnWasmAbi>(
            a: usize,
            b: usize,
        ) {
            // See `Fn()` above for why we simply return
            if a == 0 {
                return;
            }
            drop(Box::from_raw(FatPtr::<dyn Fn(&A) -> R> {
                fields: (a, b)
            }.ptr));
        }
        inform(destroy::<A, R> as u32);

        <&Self>::describe();
    }
}

unsafe impl<A, R> WasmClosure for dyn FnMut(&A) -> R
    where A: RefFromWasmAbi,
          R: ReturnWasmAbi + 'static,
{
    fn describe() {
        #[allow(non_snake_case)]
        unsafe extern "C" fn invoke<A: RefFromWasmAbi, R: ReturnWasmAbi>(
            a: usize,
            b: usize,
            arg: <A as RefFromWasmAbi>::Abi,
        ) -> <R as ReturnWasmAbi>::Abi {
            if a == 0 {
                throw_str("closure invoked recursively or destroyed already");
            }
            // Make sure all stack variables are converted before we
            // convert `ret` as it may throw (for `Result`, for
            // example)
            let ret = {
                let f: *const dyn FnMut(&A) -> R =
                    FatPtr { fields: (a, b) }.ptr;
                let f = f as *mut dyn FnMut(&A) -> R;
                let arg = <A as RefFromWasmAbi>::ref_from_abi(arg);
                (*f)(&*arg)
            };
            ret.return_abi()
        }

        inform(invoke::<A, R> as u32);

        unsafe extern fn destroy<A: RefFromWasmAbi, R: ReturnWasmAbi>(
            a: usize,
            b: usize,
        ) {
            // See `Fn()` above for why we simply return
            if a == 0 {
                return;
            }
            drop(Box::from_raw(FatPtr::<dyn FnMut(&A) -> R> {
                fields: (a, b)
            }.ptr));
        }
        inform(destroy::<A, R> as u32);

        <&mut Self>::describe();
    }
}

#[allow(non_snake_case)]
impl<T, A, R> WasmClosureFnOnce<(&A,), R> for T
    where T: 'static + FnOnce(&A) -> R,
          A: RefFromWasmAbi + 'static,
          R: ReturnWasmAbi + 'static
{
    type FnMut = dyn FnMut(&A) -> R;

    fn into_fn_mut(self) -> Box<Self::FnMut> {
        let mut me = Some(self);
        Box::new(move |arg| {
            let me = me.take().expect_throw("FnOnce called more than once");
            me(arg)
        })
    }

    fn into_js_function(self) -> JsValue {
        use std::rc::Rc;
        use crate::__rt::WasmRefCell;

        let mut me = Some(self);

        let rc1 = Rc::new(WasmRefCell::new(None));
        let rc2 = rc1.clone();

        let closure = Closure::wrap(Box::new(move |arg: &A| {
            // Invoke ourself and get the result.
            let me = me.take().expect_throw("FnOnce called more than once");
            let result = me(arg);

            // And then drop the `Rc` holding this function's `Closure`
            // alive.
            debug_assert_eq!(Rc::strong_count(&rc2), 1);
            let option_closure = rc2.borrow_mut().take();
            debug_assert!(option_closure.is_some());
            drop(option_closure);

            result
        }) as Box<dyn FnMut(&A) -> R>);

        let js_val = closure.as_ref().clone();

        *rc1.borrow_mut() = Some(closure);
        debug_assert_eq!(Rc::strong_count(&rc1), 2);
        drop(rc1);

        js_val
    }
}
