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