rquickjs_core/value/function/
ffi.rs1use crate::{
2 class::{JsCell, JsClass, Readable, Trace, Tracer},
3 qjs,
4 value::function::Params,
5 Ctx, Function, JsLifetime, Object, Result, Value,
6};
7
8use alloc::boxed::Box;
9
10use super::Constructor;
11
12pub unsafe extern "C" fn defer_call_job(
13 ctx: *mut qjs::JSContext,
14 argc: qjs::c_int,
15 argv: *mut qjs::JSValue,
16) -> qjs::JSValue {
17 let func = *argv.offset((argc - 1) as _);
18 let this = *argv.offset((argc - 2) as _);
19 let argc = argc - 2;
20 qjs::JS_Call(ctx, func, this, argc, argv)
21}
22
23pub trait RustFunc<'js> {
25 fn call<'a>(&self, params: Params<'a, 'js>) -> Result<Value<'js>>;
27}
28
29impl<'js, F> RustFunc<'js> for F
30where
31 for<'a> F: Fn(Params<'a, 'js>) -> Result<Value<'js>>,
32{
33 fn call<'a>(&self, params: Params<'a, 'js>) -> Result<Value<'js>> {
34 (self)(params)
35 }
36}
37
38pub struct RustFunction<'js>(pub Box<dyn RustFunc<'js> + 'js>);
41
42unsafe impl<'js> JsLifetime<'js> for RustFunction<'js> {
43 type Changed<'to> = RustFunction<'to>;
44}
45
46impl<'js> Trace<'js> for RustFunction<'js> {
47 fn trace<'a>(&self, _tracer: Tracer<'a, 'js>) {}
48}
49
50impl<'js> JsClass<'js> for RustFunction<'js> {
51 const NAME: &'static str = "RustFunction";
52
53 type Mutable = Readable;
54
55 const CALLABLE: bool = true;
56
57 fn prototype(ctx: &Ctx<'js>) -> Result<Option<Object<'js>>> {
58 Ok(Some(Function::prototype(ctx.clone())))
59 }
60
61 fn constructor(_ctx: &Ctx<'js>) -> Result<Option<Constructor<'js>>> {
62 Ok(None)
63 }
64
65 fn call<'a>(this: &JsCell<'js, Self>, params: Params<'a, 'js>) -> Result<Value<'js>> {
66 this.borrow().0.call(params)
67 }
68}