napi/bindgen_runtime/js_values/
function.rs

1#![allow(deprecated)]
2
3use std::ptr;
4
5use super::{Either, FromNapiValue, ToNapiValue, TypeName, Unknown, ValidateNapiValue};
6
7#[cfg(feature = "napi4")]
8use crate::threadsafe_function::{ThreadsafeCallContext, ThreadsafeFunction};
9pub use crate::JsFunction;
10use crate::{
11  check_pending_exception, check_status, sys, Env, JsUndefined, NapiRaw, NapiValue, Result,
12  ValueType,
13};
14
15impl ValidateNapiValue for JsFunction {}
16
17pub trait JsValuesTupleIntoVec {
18  fn into_vec(self, env: sys::napi_env) -> Result<Vec<sys::napi_value>>;
19}
20
21impl<T> JsValuesTupleIntoVec for T
22where
23  T: ToNapiValue,
24{
25  #[allow(clippy::not_unsafe_ptr_arg_deref)]
26  fn into_vec(self, env: sys::napi_env) -> Result<Vec<sys::napi_value>> {
27    // allow call function with `()` and function's arguments should be empty array
28    if std::mem::size_of::<T>() == 0 {
29      Ok(vec![])
30    } else {
31      Ok(vec![unsafe {
32        <T as ToNapiValue>::to_napi_value(env, self)?
33      }])
34    }
35  }
36}
37pub trait TupleFromSliceValues {
38  #[allow(clippy::missing_safety_doc)]
39  unsafe fn from_slice_values(env: sys::napi_env, values: &[sys::napi_value]) -> Result<Self>
40  where
41    Self: Sized;
42}
43
44#[repr(C)]
45pub struct FnArgs<T> {
46  pub data: T,
47}
48
49impl<T> From<T> for FnArgs<T> {
50  fn from(value: T) -> Self {
51    FnArgs { data: value }
52  }
53}
54
55macro_rules! impl_tuple_conversion {
56  ($($ident:ident),*) => {
57    impl<$($ident: ToNapiValue),*> JsValuesTupleIntoVec for FnArgs<($($ident,)*)> {
58      #[allow(clippy::not_unsafe_ptr_arg_deref)]
59      fn into_vec(self, env: sys::napi_env) -> Result<Vec<sys::napi_value>> {
60        #[allow(non_snake_case)]
61        let ($($ident,)*) = self.data;
62        Ok(vec![$(unsafe { <$ident as ToNapiValue>::to_napi_value(env, $ident)? }),*])
63      }
64    }
65
66    impl<$($ident: FromNapiValue),*> TupleFromSliceValues for ($($ident,)*) {
67      unsafe fn from_slice_values(env: sys::napi_env, values: &[sys::napi_value]) -> $crate::Result<Self> {
68        #[allow(non_snake_case)]
69        let [$($ident),*] = values.try_into().map_err(|_| crate::Error::new(
70          crate::Status::InvalidArg,
71          "Invalid number of arguments",
72        ))?;
73        Ok(($(
74          unsafe { $ident::from_napi_value(env, $ident)?}
75        ,)*))
76      }
77    }
78  };
79}
80
81impl_tuple_conversion!(A);
82impl_tuple_conversion!(A, B);
83impl_tuple_conversion!(A, B, C);
84impl_tuple_conversion!(A, B, C, D);
85impl_tuple_conversion!(A, B, C, D, E);
86impl_tuple_conversion!(A, B, C, D, E, F);
87impl_tuple_conversion!(A, B, C, D, E, F, G);
88impl_tuple_conversion!(A, B, C, D, E, F, G, H);
89impl_tuple_conversion!(A, B, C, D, E, F, G, H, I);
90impl_tuple_conversion!(A, B, C, D, E, F, G, H, I, J);
91impl_tuple_conversion!(A, B, C, D, E, F, G, H, I, J, K);
92impl_tuple_conversion!(A, B, C, D, E, F, G, H, I, J, K, L);
93impl_tuple_conversion!(A, B, C, D, E, F, G, H, I, J, K, L, M);
94impl_tuple_conversion!(A, B, C, D, E, F, G, H, I, J, K, L, M, N);
95impl_tuple_conversion!(A, B, C, D, E, F, G, H, I, J, K, L, M, N, O);
96impl_tuple_conversion!(A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P);
97impl_tuple_conversion!(A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q);
98impl_tuple_conversion!(A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R);
99impl_tuple_conversion!(A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S);
100impl_tuple_conversion!(A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T);
101impl_tuple_conversion!(A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U);
102impl_tuple_conversion!(A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V);
103impl_tuple_conversion!(A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W);
104impl_tuple_conversion!(A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X);
105impl_tuple_conversion!(A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y);
106impl_tuple_conversion!(
107  A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z
108);
109
110/// A JavaScript function.
111/// It can only live in the scope of a function call.
112/// If you want to use it outside the scope of a function call, you can turn it into a reference.
113/// By calling the `create_ref` method.
114pub struct Function<'scope, Args: JsValuesTupleIntoVec = Unknown, Return = Unknown> {
115  pub(crate) env: sys::napi_env,
116  pub(crate) value: sys::napi_value,
117  pub(crate) _args: std::marker::PhantomData<Args>,
118  pub(crate) _return: std::marker::PhantomData<Return>,
119  _scope: std::marker::PhantomData<&'scope ()>,
120}
121
122impl<Args: JsValuesTupleIntoVec, Return> TypeName for Function<'_, Args, Return> {
123  fn type_name() -> &'static str {
124    "Function"
125  }
126
127  fn value_type() -> crate::ValueType {
128    ValueType::Function
129  }
130}
131
132impl<Args: JsValuesTupleIntoVec, Return> NapiRaw for Function<'_, Args, Return> {
133  unsafe fn raw(&self) -> sys::napi_value {
134    self.value
135  }
136}
137
138impl<Args: JsValuesTupleIntoVec, Return> FromNapiValue for Function<'_, Args, Return> {
139  unsafe fn from_napi_value(env: sys::napi_env, value: sys::napi_value) -> Result<Self> {
140    Ok(Function {
141      env,
142      value,
143      _args: std::marker::PhantomData,
144      _return: std::marker::PhantomData,
145      _scope: std::marker::PhantomData,
146    })
147  }
148}
149
150impl<Args: JsValuesTupleIntoVec, Return> ValidateNapiValue for Function<'_, Args, Return> {}
151
152impl<Args: JsValuesTupleIntoVec, Return> Function<'_, Args, Return> {
153  /// Get the name of the JavaScript function.
154  pub fn name(&self) -> Result<String> {
155    let mut name = ptr::null_mut();
156    check_status!(
157      unsafe {
158        sys::napi_get_named_property(self.env, self.value, c"name".as_ptr().cast(), &mut name)
159      },
160      "Get function name failed"
161    )?;
162    unsafe { String::from_napi_value(self.env, name) }
163  }
164
165  /// Create a reference to the JavaScript function.
166  pub fn create_ref(&self) -> Result<FunctionRef<Args, Return>> {
167    let mut reference = ptr::null_mut();
168    check_status!(
169      unsafe { sys::napi_create_reference(self.env, self.value, 1, &mut reference) },
170      "Create reference failed"
171    )?;
172    Ok(FunctionRef {
173      inner: reference,
174      env: self.env,
175      _args: std::marker::PhantomData,
176      _return: std::marker::PhantomData,
177    })
178  }
179
180  /// Create a new instance of the JavaScript Class.
181  pub fn new_instance(&self, args: Args) -> Result<Unknown> {
182    let mut raw_instance = ptr::null_mut();
183    let mut args = args.into_vec(self.env)?;
184    check_status!(
185      unsafe {
186        sys::napi_new_instance(
187          self.env,
188          self.value,
189          args.len(),
190          args.as_mut_ptr().cast(),
191          &mut raw_instance,
192        )
193      },
194      "Create new instance failed"
195    )?;
196    unsafe { Unknown::from_napi_value(self.env, raw_instance) }
197  }
198
199  #[cfg(feature = "napi4")]
200  /// Create a threadsafe function from the JavaScript function.
201  pub fn build_threadsafe_function<T: 'static>(
202    &self,
203  ) -> ThreadsafeFunctionBuilder<T, Args, Return> {
204    ThreadsafeFunctionBuilder {
205      env: self.env,
206      value: self.value,
207      _args: std::marker::PhantomData,
208      _return: std::marker::PhantomData,
209    }
210  }
211}
212
213impl<Args: JsValuesTupleIntoVec, Return: FromNapiValue> Function<'_, Args, Return> {
214  /// Call the JavaScript function.
215  /// `this` in the JavaScript function will be `undefined`.
216  /// If you want to specify `this`, you can use the `apply` method.
217  pub fn call(&self, args: Args) -> Result<Return> {
218    let mut raw_this = ptr::null_mut();
219    check_status!(
220      unsafe { sys::napi_get_undefined(self.env, &mut raw_this) },
221      "Get undefined value failed"
222    )?;
223    let args_ptr = args.into_vec(self.env)?;
224    let mut raw_return = ptr::null_mut();
225    check_pending_exception!(
226      self.env,
227      unsafe {
228        sys::napi_call_function(
229          self.env,
230          raw_this,
231          self.value,
232          args_ptr.len(),
233          args_ptr.as_ptr(),
234          &mut raw_return,
235        )
236      },
237      "Call Function failed"
238    )?;
239    unsafe { Return::from_napi_value(self.env, raw_return) }
240  }
241
242  /// Call the JavaScript function.
243  /// `this` in the JavaScript function will be the provided `this`.
244  pub fn apply<Context: ToNapiValue>(&self, this: Context, args: Args) -> Result<Return> {
245    let raw_this = unsafe { Context::to_napi_value(self.env, this) }?;
246    let args_ptr = args.into_vec(self.env)?;
247    let mut raw_return = ptr::null_mut();
248    check_status!(
249      unsafe {
250        sys::napi_call_function(
251          self.env,
252          raw_this,
253          self.value,
254          args_ptr.len(),
255          args_ptr.as_ptr(),
256          &mut raw_return,
257        )
258      },
259      "Call Function failed"
260    )?;
261    unsafe { Return::from_napi_value(self.env, raw_return) }
262  }
263
264  /// Call `Function.bind`
265  pub fn bind<T: ToNapiValue>(&self, this: T) -> Result<Function<'_, Args, Return>> {
266    let raw_this = unsafe { T::to_napi_value(self.env, this) }?;
267    let mut bind_function = ptr::null_mut();
268    check_status!(
269      unsafe {
270        sys::napi_get_named_property(self.env, self.value, c"bind".as_ptr(), &mut bind_function)
271      },
272      "Get bind function failed"
273    )?;
274    let mut bound_function = ptr::null_mut();
275    check_status!(
276      unsafe {
277        sys::napi_call_function(
278          self.env,
279          self.value,
280          bind_function,
281          1,
282          [raw_this].as_ptr(),
283          &mut bound_function,
284        )
285      },
286      "Bind function failed"
287    )?;
288    Ok(Function {
289      env: self.env,
290      value: bound_function,
291      _args: std::marker::PhantomData,
292      _return: std::marker::PhantomData,
293      _scope: std::marker::PhantomData,
294    })
295  }
296}
297
298#[cfg(feature = "napi4")]
299pub struct ThreadsafeFunctionBuilder<
300  'env,
301  T: 'static,
302  Args: 'static + JsValuesTupleIntoVec,
303  Return,
304  const CalleeHandled: bool = false,
305  const Weak: bool = false,
306  const MaxQueueSize: usize = 0,
307> {
308  pub(crate) env: sys::napi_env,
309  pub(crate) value: sys::napi_value,
310  _args: std::marker::PhantomData<(T, &'env Args)>,
311  _return: std::marker::PhantomData<Return>,
312}
313
314#[cfg(feature = "napi4")]
315impl<
316    'env,
317    T: 'static,
318    Args: 'static + JsValuesTupleIntoVec,
319    Return: FromNapiValue,
320    const CalleeHandled: bool,
321    const Weak: bool,
322    const MaxQueueSize: usize,
323  > ThreadsafeFunctionBuilder<'env, T, Args, Return, CalleeHandled, Weak, MaxQueueSize>
324{
325  pub fn weak<const NewWeak: bool>(
326    self,
327  ) -> ThreadsafeFunctionBuilder<'env, T, Args, Return, CalleeHandled, NewWeak, MaxQueueSize> {
328    ThreadsafeFunctionBuilder {
329      env: self.env,
330      value: self.value,
331      _args: std::marker::PhantomData,
332      _return: std::marker::PhantomData,
333    }
334  }
335
336  pub fn callee_handled<const NewCalleeHandled: bool>(
337    self,
338  ) -> ThreadsafeFunctionBuilder<'env, T, Args, Return, NewCalleeHandled, Weak, MaxQueueSize> {
339    ThreadsafeFunctionBuilder {
340      env: self.env,
341      value: self.value,
342      _args: std::marker::PhantomData,
343      _return: std::marker::PhantomData,
344    }
345  }
346
347  pub fn max_queue_size<const NewMaxQueueSize: usize>(
348    self,
349  ) -> ThreadsafeFunctionBuilder<'env, T, Args, Return, CalleeHandled, Weak, NewMaxQueueSize> {
350    ThreadsafeFunctionBuilder {
351      env: self.env,
352      value: self.value,
353      _args: std::marker::PhantomData,
354      _return: std::marker::PhantomData,
355    }
356  }
357
358  pub fn build_callback<CallJsBackArgs, Callback>(
359    &self,
360    call_js_back: Callback,
361  ) -> Result<ThreadsafeFunction<T, Return, CallJsBackArgs, CalleeHandled, Weak, MaxQueueSize>>
362  where
363    CallJsBackArgs: 'static + JsValuesTupleIntoVec,
364    Callback: 'static + FnMut(ThreadsafeCallContext<T>) -> Result<CallJsBackArgs>,
365  {
366    ThreadsafeFunction::<T, Return, Args, CalleeHandled, Weak, MaxQueueSize>::create(
367      self.env,
368      self.value,
369      call_js_back,
370    )
371  }
372}
373
374#[cfg(feature = "napi4")]
375impl<
376    T: 'static + JsValuesTupleIntoVec,
377    Return: FromNapiValue,
378    const CalleeHandled: bool,
379    const Weak: bool,
380    const MaxQueueSize: usize,
381  > ThreadsafeFunctionBuilder<'_, T, T, Return, CalleeHandled, Weak, MaxQueueSize>
382{
383  pub fn build(
384    &self,
385  ) -> Result<ThreadsafeFunction<T, Return, T, CalleeHandled, Weak, MaxQueueSize>> {
386    unsafe { ThreadsafeFunction::from_napi_value(self.env, self.value) }
387  }
388}
389
390/// A reference to a JavaScript function.
391/// It can be used to outlive the scope of the function.
392pub struct FunctionRef<Args: JsValuesTupleIntoVec, Return> {
393  pub(crate) inner: sys::napi_ref,
394  pub(crate) env: sys::napi_env,
395  _args: std::marker::PhantomData<Args>,
396  _return: std::marker::PhantomData<Return>,
397}
398
399unsafe impl<Args: JsValuesTupleIntoVec, Return> Sync for FunctionRef<Args, Return> {}
400
401impl<Args: JsValuesTupleIntoVec, Return> FunctionRef<Args, Return> {
402  pub fn borrow_back<'scope>(&self, env: &'scope Env) -> Result<Function<'scope, Args, Return>> {
403    let mut value = ptr::null_mut();
404    check_status!(
405      unsafe { sys::napi_get_reference_value(env.0, self.inner, &mut value) },
406      "Get reference value failed"
407    )?;
408    Ok(Function {
409      env: env.0,
410      value,
411      _args: std::marker::PhantomData,
412      _return: std::marker::PhantomData,
413      _scope: std::marker::PhantomData,
414    })
415  }
416}
417
418impl<Args: JsValuesTupleIntoVec, Return> Drop for FunctionRef<Args, Return> {
419  fn drop(&mut self) {
420    let status = unsafe { sys::napi_delete_reference(self.env, self.inner) };
421    debug_assert_eq!(status, sys::Status::napi_ok, "Drop FunctionRef failed");
422  }
423}
424
425impl<Args: JsValuesTupleIntoVec, Return> TypeName for FunctionRef<Args, Return> {
426  fn type_name() -> &'static str {
427    "Function"
428  }
429
430  fn value_type() -> crate::ValueType {
431    ValueType::Function
432  }
433}
434
435impl<Args: JsValuesTupleIntoVec, Return> FromNapiValue for FunctionRef<Args, Return> {
436  unsafe fn from_napi_value(env: sys::napi_env, value: sys::napi_value) -> Result<Self> {
437    let mut reference = ptr::null_mut();
438    check_status!(
439      unsafe { sys::napi_create_reference(env, value, 1, &mut reference) },
440      "Create reference failed"
441    )?;
442    Ok(FunctionRef {
443      inner: reference,
444      env,
445      _args: std::marker::PhantomData,
446      _return: std::marker::PhantomData,
447    })
448  }
449}
450
451impl<Args: JsValuesTupleIntoVec, Return: FromNapiValue> ValidateNapiValue
452  for FunctionRef<Args, Return>
453{
454}
455
456pub struct FunctionCallContext<'scope> {
457  pub(crate) args: &'scope [sys::napi_value],
458  pub(crate) this: sys::napi_value,
459  pub env: &'scope mut Env,
460}
461
462impl FunctionCallContext<'_> {
463  /// Get the number of arguments from the JavaScript function call.
464  pub fn length(&self) -> usize {
465    self.args.len()
466  }
467
468  pub fn get<ArgType: FromNapiValue>(&self, index: usize) -> Result<ArgType> {
469    if index >= self.length() {
470      Err(crate::Error::new(
471        crate::Status::GenericFailure,
472        "Arguments index out of range".to_owned(),
473      ))
474    } else {
475      unsafe { ArgType::from_napi_value(self.env.0, self.args[index]) }
476    }
477  }
478
479  pub fn try_get<ArgType: NapiValue + TypeName + FromNapiValue>(
480    &self,
481    index: usize,
482  ) -> Result<Either<ArgType, JsUndefined>> {
483    let len = self.length();
484    if index >= len {
485      Err(crate::Error::new(
486        crate::Status::GenericFailure,
487        "Arguments index out of range".to_owned(),
488      ))
489    } else if index < len {
490      unsafe { ArgType::from_raw(self.env.0, self.args[index]) }.map(Either::A)
491    } else {
492      self.env.get_undefined().map(Either::B)
493    }
494  }
495
496  /// Get the first argument from the JavaScript function call.
497  pub fn first_arg<T: FromNapiValue>(&self) -> Result<T> {
498    if self.args.is_empty() {
499      return Err(crate::Error::new(
500        crate::Status::InvalidArg,
501        "There is no arguments",
502      ));
503    }
504    unsafe { T::from_napi_value(self.env.0, self.args[0]) }
505  }
506
507  /// Get the arguments from the JavaScript function call.
508  /// The arguments will be converted to a tuple.
509  /// If the number of arguments is not equal to the number of tuple elements, an error will be returned.
510  /// example:
511  /// ```rust
512  /// let (num, string) = ctx.args::<(u32, String)>()?;
513  /// ````
514  pub fn args<Args: TupleFromSliceValues>(&self) -> Result<Args> {
515    unsafe { Args::from_slice_values(self.env.0, self.args) }
516  }
517
518  /// Get the arguments Vec from the JavaScript function call.
519  pub fn arguments<T: FromNapiValue>(&self) -> Result<Vec<T>> {
520    self
521      .args
522      .iter()
523      .map(|arg| unsafe { <T as FromNapiValue>::from_napi_value(self.env.0, *arg) })
524      .collect::<Result<Vec<T>>>()
525  }
526
527  /// Get the `this` from the JavaScript function call.
528  pub fn this<This: FromNapiValue>(&self) -> Result<This> {
529    unsafe { This::from_napi_value(self.env.0, self.this) }
530  }
531}
532
533macro_rules! impl_call_apply {
534  ($fn_call_name:ident, $fn_apply_name:ident, $($ident:ident),*) => {
535    #[allow(non_snake_case, clippy::too_many_arguments)]
536    pub fn $fn_call_name<$($ident: ToNapiValue),*, Return: FromNapiValue>(
537      &self,
538      $($ident: $ident),*
539    ) -> Result<Return> {
540      let raw_this = Env::from_raw(self.0.env)
541        .get_undefined()
542        .map(|u| unsafe { u.raw() })?;
543
544      let raw_args = vec![
545        $(
546          unsafe { $ident::to_napi_value(self.0.env, $ident) }?
547        ),*
548      ];
549
550      let mut return_value = ptr::null_mut();
551      check_pending_exception!(self.0.env, unsafe {
552        sys::napi_call_function(
553          self.0.env,
554          raw_this,
555          self.0.value,
556          raw_args.len(),
557          raw_args.as_ptr(),
558          &mut return_value,
559        )
560      })?;
561
562      unsafe { Return::from_napi_value(self.0.env, return_value) }
563    }
564
565    #[allow(non_snake_case, clippy::too_many_arguments)]
566    pub fn $fn_apply_name<$($ident: ToNapiValue),*, Context: ToNapiValue, Return: FromNapiValue>(
567      &self,
568      this: Context,
569      $($ident: $ident),*
570    ) -> Result<Return> {
571      let raw_this = unsafe { Context::to_napi_value(self.0.env, this) }?;
572
573      let raw_args = vec![
574        $(
575          unsafe { $ident::to_napi_value(self.0.env, $ident) }?
576        ),*
577      ];
578
579      let mut return_value = ptr::null_mut();
580      check_pending_exception!(self.0.env, unsafe {
581        sys::napi_call_function(
582          self.0.env,
583          raw_this,
584          self.0.value,
585          raw_args.len(),
586          raw_args.as_ptr(),
587          &mut return_value,
588        )
589      })?;
590
591      unsafe { Return::from_napi_value(self.0.env, return_value) }
592    }
593  };
594}
595
596impl JsFunction {
597  pub fn apply0<Return: FromNapiValue, Context: ToNapiValue>(
598    &self,
599    this: Context,
600  ) -> Result<Return> {
601    let raw_this = unsafe { Context::to_napi_value(self.0.env, this) }?;
602
603    let mut return_value = ptr::null_mut();
604    check_pending_exception!(self.0.env, unsafe {
605      sys::napi_call_function(
606        self.0.env,
607        raw_this,
608        self.0.value,
609        0,
610        ptr::null_mut(),
611        &mut return_value,
612      )
613    })?;
614
615    unsafe { Return::from_napi_value(self.0.env, return_value) }
616  }
617
618  pub fn call0<Return: FromNapiValue>(&self) -> Result<Return> {
619    let raw_this = Env::from_raw(self.0.env)
620      .get_undefined()
621      .map(|u| unsafe { u.raw() })?;
622
623    let mut return_value = ptr::null_mut();
624    check_pending_exception!(self.0.env, unsafe {
625      sys::napi_call_function(
626        self.0.env,
627        raw_this,
628        self.0.value,
629        0,
630        ptr::null_mut(),
631        &mut return_value,
632      )
633    })?;
634
635    unsafe { Return::from_napi_value(self.0.env, return_value) }
636  }
637
638  impl_call_apply!(call1, apply1, Arg1);
639  impl_call_apply!(call2, apply2, Arg1, Arg2);
640  impl_call_apply!(call3, apply3, Arg1, Arg2, Arg3);
641  impl_call_apply!(call4, apply4, Arg1, Arg2, Arg3, Arg4);
642  impl_call_apply!(call5, apply5, Arg1, Arg2, Arg3, Arg4, Arg5);
643  impl_call_apply!(call6, apply6, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6);
644  impl_call_apply!(call7, apply7, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7);
645  impl_call_apply!(call8, apply8, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8);
646  impl_call_apply!(call9, apply9, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8, Arg9);
647  impl_call_apply!(call10, apply10, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8, Arg9, Arg10);
648}