rquickjs_core/value/function/
ffi.rsuse crate::{
class::{JsCell, JsClass, Readable, Trace, Tracer},
qjs,
value::function::Params,
Ctx, Function, JsLifetime, Object, Result, Value,
};
use super::Constructor;
pub unsafe extern "C" fn defer_call_job(
ctx: *mut qjs::JSContext,
argc: qjs::c_int,
argv: *mut qjs::JSValue,
) -> qjs::JSValue {
let func = *argv.offset((argc - 1) as _);
let this = *argv.offset((argc - 2) as _);
let argc = argc - 2;
qjs::JS_Call(ctx, func, this, argc, argv)
}
pub trait RustFunc<'js> {
fn call<'a>(&self, params: Params<'a, 'js>) -> Result<Value<'js>>;
}
impl<'js, F> RustFunc<'js> for F
where
for<'a> F: Fn(Params<'a, 'js>) -> Result<Value<'js>>,
{
fn call<'a>(&self, params: Params<'a, 'js>) -> Result<Value<'js>> {
(self)(params)
}
}
pub struct RustFunction<'js>(pub Box<dyn RustFunc<'js> + 'js>);
unsafe impl<'js> JsLifetime<'js> for RustFunction<'js> {
type Changed<'to> = RustFunction<'to>;
}
impl<'js> Trace<'js> for RustFunction<'js> {
fn trace<'a>(&self, _tracer: Tracer<'a, 'js>) {}
}
impl<'js> JsClass<'js> for RustFunction<'js> {
const NAME: &'static str = "RustFunction";
type Mutable = Readable;
const CALLABLE: bool = true;
fn prototype(ctx: &Ctx<'js>) -> Result<Option<Object<'js>>> {
Ok(Some(Function::prototype(ctx.clone())))
}
fn constructor(_ctx: &Ctx<'js>) -> Result<Option<Constructor<'js>>> {
Ok(None)
}
fn call<'a>(this: &JsCell<'js, Self>, params: Params<'a, 'js>) -> Result<Value<'js>> {
this.borrow().0.call(params)
}
}