1use std::convert::TryFrom;
2use std::marker::PhantomData;
3use std::ptr::NonNull;
4use std::ptr::null;
5
6use crate::Array;
7use crate::Boolean;
8use crate::CallbackScope;
9use crate::Context;
10use crate::Function;
11use crate::Integer;
12use crate::Isolate;
13use crate::Local;
14use crate::Name;
15use crate::Object;
16use crate::PropertyDescriptor;
17use crate::SealedLocal;
18use crate::Signature;
19use crate::String;
20use crate::UniqueRef;
21use crate::Value;
22use crate::isolate::RealIsolate;
23use crate::scope::PinScope;
24use crate::scope::callback_scope;
25use crate::script_compiler::CachedData;
26use crate::support::MapFnFrom;
27use crate::support::MapFnTo;
28use crate::support::ToCFn;
29use crate::support::UnitType;
30use crate::support::{Opaque, int};
31use crate::template::Intercepted;
32use crate::{ScriptOrigin, undefined};
33
34unsafe extern "C" {
35 fn v8__Function__New(
36 context: *const Context,
37 callback: FunctionCallback,
38 data_or_null: *const Value,
39 length: i32,
40 constructor_behavior: ConstructorBehavior,
41 side_effect_type: SideEffectType,
42 ) -> *const Function;
43 fn v8__Function__Call(
44 this: *const Function,
45 context: *const Context,
46 recv: *const Value,
47 argc: int,
48 argv: *const *const Value,
49 ) -> *const Value;
50 fn v8__Function__NewInstance(
51 this: *const Function,
52 context: *const Context,
53 argc: int,
54 argv: *const *const Value,
55 ) -> *const Object;
56 fn v8__Function__GetName(this: *const Function) -> *const String;
57 fn v8__Function__SetName(this: *const Function, name: *const String);
58 fn v8__Function__GetScriptColumnNumber(this: *const Function) -> int;
59 fn v8__Function__GetScriptLineNumber(this: *const Function) -> int;
60 fn v8__Function__ScriptId(this: *const Function) -> int;
61 fn v8__Function__GetScriptOrigin(
62 this: *const Function,
63 ) -> *const ScriptOrigin<'static>;
64
65 fn v8__Function__CreateCodeCache(
66 script: *const Function,
67 ) -> *mut CachedData<'static>;
68
69 static v8__FunctionCallbackInfo__kArgsLength: int;
70
71 fn v8__FunctionCallbackInfo__Data(
72 this: *const FunctionCallbackInfo,
73 ) -> *const Value;
74
75 fn v8__PropertyCallbackInfo__GetIsolate(
76 this: *const RawPropertyCallbackInfo,
77 ) -> *mut RealIsolate;
78 fn v8__PropertyCallbackInfo__Data(
79 this: *const RawPropertyCallbackInfo,
80 ) -> *const Value;
81 fn v8__PropertyCallbackInfo__This(
82 this: *const RawPropertyCallbackInfo,
83 ) -> *const Object;
84 fn v8__PropertyCallbackInfo__Holder(
85 this: *const RawPropertyCallbackInfo,
86 ) -> *const Object;
87 fn v8__PropertyCallbackInfo__GetReturnValue(
88 this: *const RawPropertyCallbackInfo,
89 ) -> usize;
90 fn v8__PropertyCallbackInfo__ShouldThrowOnError(
91 this: *const RawPropertyCallbackInfo,
92 ) -> bool;
93
94 fn v8__ReturnValue__Value__Set(
95 this: *mut RawReturnValue,
96 value: *const Value,
97 );
98 fn v8__ReturnValue__Value__Set__Bool(this: *mut RawReturnValue, value: bool);
99 fn v8__ReturnValue__Value__Set__Int32(this: *mut RawReturnValue, value: i32);
100 fn v8__ReturnValue__Value__Set__Uint32(this: *mut RawReturnValue, value: u32);
101 fn v8__ReturnValue__Value__Set__Double(this: *mut RawReturnValue, value: f64);
102 fn v8__ReturnValue__Value__SetNull(this: *mut RawReturnValue);
103 fn v8__ReturnValue__Value__SetUndefined(this: *mut RawReturnValue);
104 fn v8__ReturnValue__Value__SetEmptyString(this: *mut RawReturnValue);
105 fn v8__ReturnValue__Value__Get(this: *const RawReturnValue) -> *const Value;
106}
107
108#[repr(C)]
116pub enum ConstructorBehavior {
117 Throw,
118 Allow,
119}
120
121#[repr(C)]
130pub enum SideEffectType {
131 HasSideEffect,
132 HasNoSideEffect,
133 HasSideEffectToReceiver,
134}
135
136#[repr(C)]
137#[derive(Debug)]
138struct RawReturnValue(usize);
139
140#[derive(Debug)]
144pub struct ReturnValue<'cb, T = Value>(RawReturnValue, PhantomData<&'cb T>);
145
146impl<'cb, T> ReturnValue<'cb, T> {
147 #[inline(always)]
148 pub fn from_property_callback_info(
149 info: &'cb PropertyCallbackInfo<T>,
150 ) -> Self {
151 Self(
152 unsafe {
153 RawReturnValue(v8__PropertyCallbackInfo__GetReturnValue(&info.0))
154 },
155 PhantomData,
156 )
157 }
158}
159
160impl<'cb> ReturnValue<'cb, Value> {
161 #[inline(always)]
162 pub fn from_function_callback_info(info: &'cb FunctionCallbackInfo) -> Self {
163 let nn = info.get_return_value_non_null();
164 Self(RawReturnValue(nn.as_ptr() as _), PhantomData)
165 }
166}
167
168impl ReturnValue<'_, ()> {
169 #[inline(always)]
170 pub fn set_bool(&mut self, value: bool) {
171 unsafe { v8__ReturnValue__Value__Set__Bool(&mut self.0, value) }
172 }
173}
174
175impl<T> ReturnValue<'_, T>
176where
177 for<'s> Local<'s, T>: Into<Local<'s, Value>>,
178{
179 #[inline(always)]
180 pub fn set(&mut self, value: Local<T>) {
181 unsafe { v8__ReturnValue__Value__Set(&mut self.0, &*value.into()) }
182 }
183
184 #[inline(always)]
185 pub fn set_bool(&mut self, value: bool) {
186 unsafe { v8__ReturnValue__Value__Set__Bool(&mut self.0, value) }
187 }
188
189 #[inline(always)]
190 pub fn set_int32(&mut self, value: i32) {
191 unsafe { v8__ReturnValue__Value__Set__Int32(&mut self.0, value) }
192 }
193
194 #[inline(always)]
195 pub fn set_uint32(&mut self, value: u32) {
196 unsafe { v8__ReturnValue__Value__Set__Uint32(&mut self.0, value) }
197 }
198
199 #[inline(always)]
200 pub fn set_double(&mut self, value: f64) {
201 unsafe { v8__ReturnValue__Value__Set__Double(&mut self.0, value) }
202 }
203
204 #[inline(always)]
205 pub fn set_null(&mut self) {
206 unsafe { v8__ReturnValue__Value__SetNull(&mut self.0) }
207 }
208
209 #[inline(always)]
210 pub fn set_undefined(&mut self) {
211 unsafe { v8__ReturnValue__Value__SetUndefined(&mut self.0) }
212 }
213
214 #[inline(always)]
215 pub fn set_empty_string(&mut self) {
216 unsafe { v8__ReturnValue__Value__SetEmptyString(&mut self.0) }
217 }
218
219 #[inline(always)]
223 pub fn get<'s>(&self, scope: &PinScope<'s, '_>) -> Local<'s, Value> {
224 unsafe { scope.cast_local(|_| v8__ReturnValue__Value__Get(&self.0)) }
225 .unwrap()
226 }
227}
228
229#[repr(C)]
234#[derive(Debug)]
235pub struct FunctionCallbackInfo {
236 implicit_args: *mut *const Opaque,
239 values: *mut *const Opaque,
240 length: int,
241}
242
243#[allow(dead_code, non_upper_case_globals)]
246impl FunctionCallbackInfo {
247 const kHolderIndex: i32 = 0;
248 const kIsolateIndex: i32 = 1;
249 const kContextIndex: i32 = 2;
250 const kReturnValueIndex: i32 = 3;
251 const kTargetIndex: i32 = 4;
252 const kNewTargetIndex: i32 = 5;
253 const kArgsLength: i32 = 6;
254}
255
256impl FunctionCallbackInfo {
257 #[inline(always)]
258 pub(crate) fn get_isolate_ptr(&self) -> *mut RealIsolate {
259 let arg_nn =
260 self.get_implicit_arg_non_null::<*mut RealIsolate>(Self::kIsolateIndex);
261 *unsafe { arg_nn.as_ref() }
262 }
263
264 #[inline(always)]
265 pub(crate) fn get_return_value_non_null(&self) -> NonNull<Value> {
266 self.get_implicit_arg_non_null::<Value>(Self::kReturnValueIndex)
267 }
268
269 #[inline(always)]
270 pub(crate) fn new_target(&self) -> Local<'_, Value> {
271 unsafe { self.get_implicit_arg_local(Self::kNewTargetIndex) }
272 }
273
274 #[inline(always)]
275 pub(crate) fn this(&self) -> Local<'_, Object> {
276 unsafe { self.get_arg_local(-1) }
277 }
278
279 #[inline]
280 pub fn is_construct_call(&self) -> bool {
281 !self.new_target().is_undefined()
283 }
284
285 #[inline(always)]
286 pub(crate) fn data(&self) -> Local<'_, Value> {
287 unsafe {
288 let ptr = v8__FunctionCallbackInfo__Data(self);
289 let nn = NonNull::new_unchecked(ptr as *mut Value);
290 Local::from_non_null(nn)
291 }
292 }
293
294 #[inline(always)]
295 pub(crate) fn length(&self) -> i32 {
296 self.length
297 }
298
299 #[inline(always)]
300 pub(crate) fn get(&self, index: int) -> Local<'_, Value> {
301 if index >= 0 && index < self.length {
302 unsafe { self.get_arg_local(index) }
303 } else {
304 let isolate = unsafe {
305 crate::isolate::Isolate::from_raw_ptr(self.get_isolate_ptr())
306 };
307 undefined(&isolate).into()
308 }
309 }
310
311 #[inline(always)]
312 fn get_implicit_arg_non_null<T>(&self, index: i32) -> NonNull<T> {
313 debug_assert_eq!(
317 unsafe { v8__FunctionCallbackInfo__kArgsLength },
318 Self::kArgsLength
319 );
320 assert!(index >= 0);
322 assert!(index < Self::kArgsLength);
323 let ptr = unsafe { self.implicit_args.offset(index as isize) as *mut T };
325 debug_assert!(!ptr.is_null());
326 unsafe { NonNull::new_unchecked(ptr) }
327 }
328
329 #[inline(always)]
332 unsafe fn get_implicit_arg_local<T>(&self, index: i32) -> Local<'_, T> {
333 let nn = self.get_implicit_arg_non_null::<T>(index);
334 unsafe { Local::from_non_null(nn) }
335 }
336
337 #[inline(always)]
340 unsafe fn get_arg_local<T>(&self, index: i32) -> Local<'_, T> {
341 let ptr = unsafe { self.values.offset(index as _) } as *mut T;
342 debug_assert!(!ptr.is_null());
343 let nn = unsafe { NonNull::new_unchecked(ptr) };
344 unsafe { Local::from_non_null(nn) }
345 }
346}
347
348#[repr(C)]
349#[derive(Debug)]
350struct RawPropertyCallbackInfo(Opaque);
351
352#[repr(C)]
355#[derive(Debug)]
356pub struct PropertyCallbackInfo<T>(RawPropertyCallbackInfo, PhantomData<T>);
357
358impl<T> PropertyCallbackInfo<T> {
359 #[inline(always)]
360 pub(crate) fn get_isolate_ptr(&self) -> *mut RealIsolate {
361 unsafe { v8__PropertyCallbackInfo__GetIsolate(&self.0) }
362 }
363}
364
365#[derive(Debug)]
366pub struct FunctionCallbackArguments<'s>(&'s FunctionCallbackInfo);
367
368impl<'s> FunctionCallbackArguments<'s> {
369 #[inline(always)]
370 pub fn from_function_callback_info(info: &'s FunctionCallbackInfo) -> Self {
371 Self(info)
372 }
373
374 #[inline(always)]
379 pub unsafe fn get_isolate(&mut self) -> &mut Isolate {
380 unsafe { &mut *(self.0.get_isolate_ptr() as *mut crate::isolate::Isolate) }
381 }
382
383 #[inline(always)]
385 pub fn new_target(&self) -> Local<'s, Value> {
386 self.0.new_target()
387 }
388
389 #[inline]
392 pub fn is_construct_call(&self) -> bool {
393 self.0.is_construct_call()
394 }
395
396 #[inline(always)]
398 pub fn this(&self) -> Local<'s, Object> {
399 self.0.this()
400 }
401
402 #[inline(always)]
404 pub fn data(&self) -> Local<'s, Value> {
405 self.0.data()
406 }
407
408 #[inline(always)]
410 pub fn length(&self) -> int {
411 self.0.length()
412 }
413
414 #[inline(always)]
417 pub fn get(&self, i: int) -> Local<'s, Value> {
418 self.0.get(i)
419 }
420}
421
422#[derive(Debug)]
423pub struct PropertyCallbackArguments<'s>(&'s RawPropertyCallbackInfo);
424
425impl<'s> PropertyCallbackArguments<'s> {
426 #[inline(always)]
427 pub(crate) fn from_property_callback_info<T>(
428 info: &'s PropertyCallbackInfo<T>,
429 ) -> Self {
430 Self(&info.0)
431 }
432
433 #[inline(always)]
439 pub fn holder(&self) -> Local<'s, Object> {
440 unsafe {
441 Local::from_raw(v8__PropertyCallbackInfo__Holder(self.0))
442 .unwrap_unchecked()
443 }
444 }
445
446 #[inline(always)]
486 pub fn this(&self) -> Local<'s, Object> {
487 unsafe {
488 Local::from_raw(v8__PropertyCallbackInfo__This(self.0)).unwrap_unchecked()
489 }
490 }
491
492 #[inline(always)]
496 pub fn data(&self) -> Local<'s, Value> {
497 unsafe {
498 Local::from_raw(v8__PropertyCallbackInfo__Data(self.0)).unwrap_unchecked()
499 }
500 }
501
502 #[inline(always)]
508 pub fn should_throw_on_error(&self) -> bool {
509 unsafe { v8__PropertyCallbackInfo__ShouldThrowOnError(self.0) }
510 }
511}
512
513pub type FunctionCallback = unsafe extern "C" fn(*const FunctionCallbackInfo);
514
515impl<F> MapFnFrom<F> for FunctionCallback
516where
517 F: UnitType
518 + for<'s, 'i> Fn(
519 &mut PinScope<'s, 'i>,
520 FunctionCallbackArguments<'s>,
521 ReturnValue<'s, Value>,
522 ),
523{
524 fn mapping() -> Self {
525 let f = |info: *const FunctionCallbackInfo| {
526 let info = unsafe { &*info };
527 let scope = std::pin::pin!(unsafe { CallbackScope::new(info) });
528 let mut scope = scope.init();
529 let args = FunctionCallbackArguments::from_function_callback_info(info);
530 let rv = ReturnValue::from_function_callback_info(info);
531 (F::get())(&mut scope, args, rv);
532 };
533 f.to_c_fn()
534 }
535}
536
537pub(crate) type NamedGetterCallbackForAccessor =
538 unsafe extern "C" fn(SealedLocal<Name>, *const PropertyCallbackInfo<Value>);
539
540impl<F> MapFnFrom<F> for NamedGetterCallbackForAccessor
541where
542 F: UnitType
543 + for<'s, 'i> Fn(
544 &mut PinScope<'s, 'i>,
545 Local<'s, Name>,
546 PropertyCallbackArguments<'s>,
547 ReturnValue<Value>,
548 ),
549{
550 fn mapping() -> Self {
551 let f = |key: SealedLocal<Name>,
552 info: *const PropertyCallbackInfo<Value>| {
553 let info = unsafe { &*info };
554 callback_scope!(unsafe scope, info);
555 let key = unsafe { scope.unseal(key) };
556 let args = PropertyCallbackArguments::from_property_callback_info(info);
557 let rv = ReturnValue::from_property_callback_info(info);
558 (F::get())(scope, key, args, rv);
559 };
560 f.to_c_fn()
561 }
562}
563
564pub(crate) type NamedGetterCallback = unsafe extern "C" fn(
565 SealedLocal<Name>,
566 *const PropertyCallbackInfo<Value>,
567) -> Intercepted;
568
569impl<F> MapFnFrom<F> for NamedGetterCallback
570where
571 F: UnitType
572 + for<'s, 'i> Fn(
573 &mut PinScope<'s, 'i>,
574 Local<'s, Name>,
575 PropertyCallbackArguments<'s>,
576 ReturnValue<Value>,
577 ) -> Intercepted,
578{
579 fn mapping() -> Self {
580 let f = |key: SealedLocal<Name>,
581 info: *const PropertyCallbackInfo<Value>| {
582 let info = unsafe { &*info };
583 callback_scope!(unsafe scope, info);
584 let key = unsafe { scope.unseal(key) };
585 let args = PropertyCallbackArguments::from_property_callback_info(info);
586 let rv = ReturnValue::from_property_callback_info(info);
587 (F::get())(scope, key, args, rv)
588 };
589 f.to_c_fn()
590 }
591}
592
593pub(crate) type NamedQueryCallback = unsafe extern "C" fn(
594 SealedLocal<Name>,
595 *const PropertyCallbackInfo<Integer>,
596) -> Intercepted;
597
598impl<F> MapFnFrom<F> for NamedQueryCallback
599where
600 F: UnitType
601 + for<'s, 'i> Fn(
602 &mut PinScope<'s, 'i>,
603 Local<'s, Name>,
604 PropertyCallbackArguments<'s>,
605 ReturnValue<Integer>,
606 ) -> Intercepted,
607{
608 fn mapping() -> Self {
609 let f = |key: SealedLocal<Name>,
610 info: *const PropertyCallbackInfo<Integer>| {
611 let info = unsafe { &*info };
612 callback_scope!(unsafe scope, info);
613 let key = unsafe { scope.unseal(key) };
614 let args = PropertyCallbackArguments::from_property_callback_info(info);
615 let rv = ReturnValue::from_property_callback_info(info);
616 (F::get())(scope, key, args, rv)
617 };
618 f.to_c_fn()
619 }
620}
621
622pub(crate) type NamedSetterCallbackForAccessor = unsafe extern "C" fn(
623 SealedLocal<Name>,
624 SealedLocal<Value>,
625 *const PropertyCallbackInfo<()>,
626);
627
628impl<F> MapFnFrom<F> for NamedSetterCallbackForAccessor
629where
630 F: UnitType
631 + for<'s, 'i> Fn(
632 &mut PinScope<'s, 'i>,
633 Local<'s, Name>,
634 Local<'s, Value>,
635 PropertyCallbackArguments<'s>,
636 ReturnValue<()>,
637 ),
638{
639 fn mapping() -> Self {
640 let f = |key: SealedLocal<Name>,
641 value: SealedLocal<Value>,
642 info: *const PropertyCallbackInfo<()>| {
643 let info = unsafe { &*info };
644 callback_scope!(unsafe scope, info);
645 let key = unsafe { scope.unseal(key) };
646 let value = unsafe { scope.unseal(value) };
647 let args = PropertyCallbackArguments::from_property_callback_info(info);
648 let rv = ReturnValue::from_property_callback_info(info);
649 (F::get())(scope, key, value, args, rv);
650 };
651 f.to_c_fn()
652 }
653}
654
655pub(crate) type NamedSetterCallback = unsafe extern "C" fn(
656 SealedLocal<Name>,
657 SealedLocal<Value>,
658 *const PropertyCallbackInfo<()>,
659) -> Intercepted;
660
661impl<F> MapFnFrom<F> for NamedSetterCallback
662where
663 F: UnitType
664 + for<'s, 'i> Fn(
665 &mut PinScope<'s, 'i>,
666 Local<'s, Name>,
667 Local<'s, Value>,
668 PropertyCallbackArguments<'s>,
669 ReturnValue<()>,
670 ) -> Intercepted,
671{
672 fn mapping() -> Self {
673 let f = |key: SealedLocal<Name>,
674 value: SealedLocal<Value>,
675 info: *const PropertyCallbackInfo<()>| {
676 let info = unsafe { &*info };
677 callback_scope!(unsafe scope, info);
678 let key = unsafe { scope.unseal(key) };
679 let value = unsafe { scope.unseal(value) };
680 let args = PropertyCallbackArguments::from_property_callback_info(info);
681 let rv = ReturnValue::from_property_callback_info(info);
682 (F::get())(scope, key, value, args, rv)
683 };
684 f.to_c_fn()
685 }
686}
687
688pub(crate) type PropertyEnumeratorCallback =
690 unsafe extern "C" fn(*const PropertyCallbackInfo<Array>);
691
692impl<F> MapFnFrom<F> for PropertyEnumeratorCallback
693where
694 F: UnitType
695 + for<'s, 'i> Fn(
696 &mut PinScope<'s, 'i>,
697 PropertyCallbackArguments<'s>,
698 ReturnValue<Array>,
699 ),
700{
701 fn mapping() -> Self {
702 let f = |info: *const PropertyCallbackInfo<Array>| {
703 let info = unsafe { &*info };
704 callback_scope!(unsafe scope, info);
705 let args = PropertyCallbackArguments::from_property_callback_info(info);
706 let rv = ReturnValue::from_property_callback_info(info);
707 (F::get())(scope, args, rv);
708 };
709 f.to_c_fn()
710 }
711}
712
713pub(crate) type NamedDefinerCallback = unsafe extern "C" fn(
714 SealedLocal<Name>,
715 *const PropertyDescriptor,
716 *const PropertyCallbackInfo<()>,
717) -> Intercepted;
718
719impl<F> MapFnFrom<F> for NamedDefinerCallback
720where
721 F: UnitType
722 + for<'s, 'i> Fn(
723 &mut PinScope<'s, 'i>,
724 Local<'s, Name>,
725 &PropertyDescriptor,
726 PropertyCallbackArguments<'s>,
727 ReturnValue<()>,
728 ) -> Intercepted,
729{
730 fn mapping() -> Self {
731 let f = |key: SealedLocal<Name>,
732 desc: *const PropertyDescriptor,
733 info: *const PropertyCallbackInfo<()>| {
734 let info = unsafe { &*info };
735 callback_scope!(unsafe scope, info);
736 let key = unsafe { scope.unseal(key) };
737 let args = PropertyCallbackArguments::from_property_callback_info(info);
738 let desc = unsafe { &*desc };
739 let rv = ReturnValue::from_property_callback_info(info);
740 (F::get())(scope, key, desc, args, rv)
741 };
742 f.to_c_fn()
743 }
744}
745
746pub(crate) type NamedDeleterCallback = unsafe extern "C" fn(
747 SealedLocal<Name>,
748 *const PropertyCallbackInfo<Boolean>,
749) -> Intercepted;
750
751impl<F> MapFnFrom<F> for NamedDeleterCallback
752where
753 F: UnitType
754 + for<'s, 'i> Fn(
755 &mut PinScope<'s, 'i>,
756 Local<'s, Name>,
757 PropertyCallbackArguments<'s>,
758 ReturnValue<Boolean>,
759 ) -> Intercepted,
760{
761 fn mapping() -> Self {
762 let f = |key: SealedLocal<Name>,
763 info: *const PropertyCallbackInfo<Boolean>| {
764 let info = unsafe { &*info };
765 callback_scope!(unsafe scope, info);
766 let key = unsafe { scope.unseal(key) };
767 let args = PropertyCallbackArguments::from_property_callback_info(info);
768 let rv = ReturnValue::from_property_callback_info(info);
769 (F::get())(scope, key, args, rv)
770 };
771 f.to_c_fn()
772 }
773}
774
775pub(crate) type IndexedGetterCallback =
776 unsafe extern "C" fn(u32, *const PropertyCallbackInfo<Value>) -> Intercepted;
777
778impl<F> MapFnFrom<F> for IndexedGetterCallback
779where
780 F: UnitType
781 + for<'s, 'i> Fn(
782 &mut PinScope<'s, 'i>,
783 u32,
784 PropertyCallbackArguments<'s>,
785 ReturnValue<Value>,
786 ) -> Intercepted,
787{
788 fn mapping() -> Self {
789 let f = |index: u32, info: *const PropertyCallbackInfo<Value>| {
790 let info = unsafe { &*info };
791 callback_scope!(unsafe scope, info);
792 let args = PropertyCallbackArguments::from_property_callback_info(info);
793 let rv = ReturnValue::from_property_callback_info(info);
794 (F::get())(scope, index, args, rv)
795 };
796 f.to_c_fn()
797 }
798}
799
800pub(crate) type IndexedQueryCallback = unsafe extern "C" fn(
801 u32,
802 *const PropertyCallbackInfo<Integer>,
803) -> Intercepted;
804
805impl<F> MapFnFrom<F> for IndexedQueryCallback
806where
807 F: UnitType
808 + for<'s, 'i> Fn(
809 &mut PinScope<'s, 'i>,
810 u32,
811 PropertyCallbackArguments<'s>,
812 ReturnValue<Integer>,
813 ) -> Intercepted,
814{
815 fn mapping() -> Self {
816 let f = |key: u32, info: *const PropertyCallbackInfo<Integer>| {
817 let info = unsafe { &*info };
818 callback_scope!(unsafe scope, info);
819 let args = PropertyCallbackArguments::from_property_callback_info(info);
820 let rv = ReturnValue::from_property_callback_info(info);
821 (F::get())(scope, key, args, rv)
822 };
823 f.to_c_fn()
824 }
825}
826
827pub(crate) type IndexedSetterCallback = unsafe extern "C" fn(
828 u32,
829 SealedLocal<Value>,
830 *const PropertyCallbackInfo<()>,
831) -> Intercepted;
832
833impl<F> MapFnFrom<F> for IndexedSetterCallback
834where
835 F: UnitType
836 + for<'s, 'i> Fn(
837 &mut PinScope<'s, 'i>,
838 u32,
839 Local<'s, Value>,
840 PropertyCallbackArguments<'s>,
841 ReturnValue<()>,
842 ) -> Intercepted,
843{
844 fn mapping() -> Self {
845 let f = |index: u32,
846 value: SealedLocal<Value>,
847 info: *const PropertyCallbackInfo<()>| {
848 let info = unsafe { &*info };
849 callback_scope!(unsafe scope, info);
850 let value = unsafe { scope.unseal(value) };
851 let args = PropertyCallbackArguments::from_property_callback_info(info);
852 let rv = ReturnValue::from_property_callback_info(info);
853 (F::get())(scope, index, value, args, rv)
854 };
855 f.to_c_fn()
856 }
857}
858
859pub(crate) type IndexedDefinerCallback = unsafe extern "C" fn(
860 u32,
861 *const PropertyDescriptor,
862 *const PropertyCallbackInfo<()>,
863) -> Intercepted;
864
865impl<F> MapFnFrom<F> for IndexedDefinerCallback
866where
867 F: UnitType
868 + for<'s, 'i> Fn(
869 &mut PinScope<'s, 'i>,
870 u32,
871 &PropertyDescriptor,
872 PropertyCallbackArguments<'s>,
873 ReturnValue<()>,
874 ) -> Intercepted,
875{
876 fn mapping() -> Self {
877 let f = |index: u32,
878 desc: *const PropertyDescriptor,
879 info: *const PropertyCallbackInfo<()>| {
880 let info = unsafe { &*info };
881 callback_scope!(unsafe scope, info);
882 let args = PropertyCallbackArguments::from_property_callback_info(info);
883 let rv = ReturnValue::from_property_callback_info(info);
884 let desc = unsafe { &*desc };
885 (F::get())(scope, index, desc, args, rv)
886 };
887 f.to_c_fn()
888 }
889}
890
891pub(crate) type IndexedDeleterCallback = unsafe extern "C" fn(
892 u32,
893 *const PropertyCallbackInfo<Boolean>,
894) -> Intercepted;
895
896impl<F> MapFnFrom<F> for IndexedDeleterCallback
897where
898 F: UnitType
899 + for<'s, 'i> Fn(
900 &mut PinScope<'s, 'i>,
901 u32,
902 PropertyCallbackArguments<'s>,
903 ReturnValue<Boolean>,
904 ) -> Intercepted,
905{
906 fn mapping() -> Self {
907 let f = |index: u32, info: *const PropertyCallbackInfo<Boolean>| {
908 let info = unsafe { &*info };
909 callback_scope!(unsafe scope, info);
910 let args = PropertyCallbackArguments::from_property_callback_info(info);
911 let rv = ReturnValue::from_property_callback_info(info);
912 (F::get())(scope, index, args, rv)
913 };
914 f.to_c_fn()
915 }
916}
917
918pub struct FunctionBuilder<'s, T> {
920 pub(crate) callback: FunctionCallback,
921 pub(crate) data: Option<Local<'s, Value>>,
922 pub(crate) signature: Option<Local<'s, Signature>>,
923 pub(crate) length: i32,
924 pub(crate) constructor_behavior: ConstructorBehavior,
925 pub(crate) side_effect_type: SideEffectType,
926 phantom: PhantomData<T>,
927}
928
929impl<'s, T> FunctionBuilder<'s, T> {
930 #[inline(always)]
932 pub fn new(callback: impl MapFnTo<FunctionCallback>) -> Self {
933 Self::new_raw(callback.map_fn_to())
934 }
935
936 #[inline(always)]
937 pub fn new_raw(callback: FunctionCallback) -> Self {
938 Self {
939 callback,
940 data: None,
941 signature: None,
942 length: 0,
943 constructor_behavior: ConstructorBehavior::Allow,
944 side_effect_type: SideEffectType::HasSideEffect,
945 phantom: PhantomData,
946 }
947 }
948
949 #[inline(always)]
951 pub fn data(mut self, data: Local<'s, Value>) -> Self {
952 self.data = Some(data);
953 self
954 }
955
956 #[inline(always)]
958 pub fn length(mut self, length: i32) -> Self {
959 self.length = length;
960 self
961 }
962
963 #[inline(always)]
965 pub fn constructor_behavior(
966 mut self,
967 constructor_behavior: ConstructorBehavior,
968 ) -> Self {
969 self.constructor_behavior = constructor_behavior;
970 self
971 }
972
973 #[inline(always)]
975 pub fn side_effect_type(mut self, side_effect_type: SideEffectType) -> Self {
976 self.side_effect_type = side_effect_type;
977 self
978 }
979}
980
981impl<'s> FunctionBuilder<'s, Function> {
982 #[inline(always)]
984 pub fn build<'i>(
985 self,
986 scope: &PinScope<'s, 'i>,
987 ) -> Option<Local<'s, Function>> {
988 unsafe {
989 scope.cast_local(|sd| {
990 v8__Function__New(
991 sd.get_current_context(),
992 self.callback,
993 self.data.map_or_else(null, |p| &*p),
994 self.length,
995 self.constructor_behavior,
996 self.side_effect_type,
997 )
998 })
999 }
1000 }
1001}
1002
1003impl Function {
1004 #[inline(always)]
1007 pub fn builder<'s>(
1008 callback: impl MapFnTo<FunctionCallback>,
1009 ) -> FunctionBuilder<'s, Self> {
1010 FunctionBuilder::new(callback)
1011 }
1012
1013 #[inline(always)]
1014 pub fn builder_raw<'s>(
1015 callback: FunctionCallback,
1016 ) -> FunctionBuilder<'s, Self> {
1017 FunctionBuilder::new_raw(callback)
1018 }
1019
1020 #[inline(always)]
1023 pub fn new<'s>(
1024 scope: &mut PinScope<'s, '_>,
1025 callback: impl MapFnTo<FunctionCallback>,
1026 ) -> Option<Local<'s, Function>> {
1027 Self::builder(callback).build(scope)
1028 }
1029
1030 #[inline(always)]
1031 pub fn new_raw<'s>(
1032 scope: &mut PinScope<'s, '_>,
1033 callback: FunctionCallback,
1034 ) -> Option<Local<'s, Function>> {
1035 Self::builder_raw(callback).build(scope)
1036 }
1037
1038 #[inline]
1040 pub fn call<'s>(
1041 &self,
1042 scope: &PinScope<'s, '_>,
1043 recv: Local<Value>,
1044 args: &[Local<Value>],
1045 ) -> Option<Local<'s, Value>> {
1046 let args = Local::slice_into_raw(args);
1047 let argc = int::try_from(args.len()).unwrap();
1048 let argv = args.as_ptr();
1049 unsafe {
1050 scope.cast_local(|sd| {
1051 v8__Function__Call(self, sd.get_current_context(), &*recv, argc, argv)
1052 })
1053 }
1054 }
1055
1056 #[inline]
1058 pub fn call_with_context<'s>(
1059 &self,
1060 scope: &PinScope<'s, '_, ()>,
1061 context: Local<Context>,
1062 recv: Local<Value>,
1063 args: &[Local<Value>],
1064 ) -> Option<Local<'s, Value>> {
1065 let args = Local::slice_into_raw(args);
1066 let argc = int::try_from(args.len()).unwrap();
1067 let argv = args.as_ptr();
1068 unsafe {
1069 let ret = v8__Function__Call(
1070 self,
1071 context.as_non_null().as_ptr(),
1072 &*recv,
1073 argc,
1074 argv,
1075 );
1076 if ret.is_null() {
1077 None
1078 } else {
1079 scope.cast_local(|_| ret)
1080 }
1081 }
1082 }
1083
1084 #[inline(always)]
1085 pub fn new_instance<'s>(
1086 &self,
1087 scope: &PinScope<'s, '_>,
1088 args: &[Local<Value>],
1089 ) -> Option<Local<'s, Object>> {
1090 let args = Local::slice_into_raw(args);
1091 let argc = int::try_from(args.len()).unwrap();
1092 let argv = args.as_ptr();
1093 unsafe {
1094 scope.cast_local(|sd| {
1095 v8__Function__NewInstance(self, sd.get_current_context(), argc, argv)
1096 })
1097 }
1098 }
1099
1100 #[inline(always)]
1101 pub fn get_name<'s>(&self, scope: &PinScope<'s, '_>) -> Local<'s, String> {
1102 unsafe { scope.cast_local(|_| v8__Function__GetName(self)).unwrap() }
1103 }
1104
1105 #[inline(always)]
1106 pub fn set_name(&self, name: Local<String>) {
1107 unsafe { v8__Function__SetName(self, &*name) }
1108 }
1109
1110 #[inline(always)]
1112 pub fn get_script_column_number(&self) -> Option<u32> {
1113 let ret = unsafe { v8__Function__GetScriptColumnNumber(self) };
1114 (ret >= 0).then_some(ret as u32)
1115 }
1116
1117 #[inline(always)]
1119 pub fn get_script_line_number(&self) -> Option<u32> {
1120 let ret = unsafe { v8__Function__GetScriptLineNumber(self) };
1121 (ret >= 0).then_some(ret as u32)
1122 }
1123
1124 #[inline(always)]
1125 pub fn get_script_origin(&self) -> &ScriptOrigin<'_> {
1126 unsafe {
1127 let ptr = v8__Function__GetScriptOrigin(self);
1128 &*ptr
1129 }
1130 }
1131
1132 #[inline(always)]
1134 pub fn script_id(&self) -> i32 {
1135 unsafe { v8__Function__ScriptId(self) }
1136 }
1137
1138 #[inline(always)]
1142 pub fn create_code_cache(&self) -> Option<UniqueRef<CachedData<'static>>> {
1143 let code_cache =
1144 unsafe { UniqueRef::try_from_raw(v8__Function__CreateCodeCache(self)) };
1145 if let Some(code_cache) = &code_cache {
1146 debug_assert_eq!(
1147 code_cache.buffer_policy(),
1148 crate::script_compiler::BufferPolicy::BufferOwned
1149 );
1150 }
1151 code_cache
1152 }
1153}