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