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::ScriptOrigin;
18use crate::SealedLocal;
19use crate::Signature;
20use crate::String;
21use crate::UniqueRef;
22use crate::Value;
23use crate::isolate::RealIsolate;
24use crate::scope::PinScope;
25use crate::scope::callback_scope;
26use crate::script_compiler::CachedData;
27use crate::support::MapFnFrom;
28use crate::support::MapFnTo;
29use crate::support::ToCFn;
30use crate::support::UnitType;
31use crate::support::{Opaque, int};
32use crate::template::Intercepted;
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 fn v8__FunctionCallbackInfo__GetIsolate(
70 this: *const FunctionCallbackInfo,
71 ) -> *mut RealIsolate;
72 fn v8__FunctionCallbackInfo__Data(
73 this: *const FunctionCallbackInfo,
74 ) -> *const Value;
75 fn v8__FunctionCallbackInfo__This(
76 this: *const FunctionCallbackInfo,
77 ) -> *const Object;
78 fn v8__FunctionCallbackInfo__NewTarget(
79 this: *const FunctionCallbackInfo,
80 ) -> *const Value;
81 fn v8__FunctionCallbackInfo__IsConstructCall(
82 this: *const FunctionCallbackInfo,
83 ) -> bool;
84 fn v8__FunctionCallbackInfo__Get(
85 this: *const FunctionCallbackInfo,
86 index: int,
87 ) -> *const Value;
88 fn v8__FunctionCallbackInfo__Length(this: *const FunctionCallbackInfo)
89 -> int;
90 fn v8__FunctionCallbackInfo__GetReturnValue(
91 this: *const FunctionCallbackInfo,
92 ) -> usize;
93
94 fn v8__PropertyCallbackInfo__GetIsolate(
95 this: *const RawPropertyCallbackInfo,
96 ) -> *mut RealIsolate;
97 fn v8__PropertyCallbackInfo__Data(
98 this: *const RawPropertyCallbackInfo,
99 ) -> *const Value;
100 fn v8__PropertyCallbackInfo__This(
101 this: *const RawPropertyCallbackInfo,
102 ) -> *const Object;
103 fn v8__PropertyCallbackInfo__Holder(
104 this: *const RawPropertyCallbackInfo,
105 ) -> *const Object;
106 fn v8__PropertyCallbackInfo__GetReturnValue(
107 this: *const RawPropertyCallbackInfo,
108 ) -> usize;
109 fn v8__PropertyCallbackInfo__ShouldThrowOnError(
110 this: *const RawPropertyCallbackInfo,
111 ) -> bool;
112
113 fn v8__ReturnValue__Value__Set(
114 this: *mut RawReturnValue,
115 value: *const Value,
116 );
117 fn v8__ReturnValue__Value__Set__Bool(this: *mut RawReturnValue, value: bool);
118 fn v8__ReturnValue__Value__Set__Int32(this: *mut RawReturnValue, value: i32);
119 fn v8__ReturnValue__Value__Set__Uint32(this: *mut RawReturnValue, value: u32);
120 fn v8__ReturnValue__Value__Set__Double(this: *mut RawReturnValue, value: f64);
121 fn v8__ReturnValue__Value__SetNull(this: *mut RawReturnValue);
122 fn v8__ReturnValue__Value__SetUndefined(this: *mut RawReturnValue);
123 fn v8__ReturnValue__Value__SetEmptyString(this: *mut RawReturnValue);
124 fn v8__ReturnValue__Value__Get(this: *const RawReturnValue) -> *const Value;
125}
126
127#[repr(C)]
135pub enum ConstructorBehavior {
136 Throw,
137 Allow,
138}
139
140#[repr(C)]
149pub enum SideEffectType {
150 HasSideEffect,
151 HasNoSideEffect,
152 HasSideEffectToReceiver,
153}
154
155#[repr(C)]
156#[derive(Debug)]
157struct RawReturnValue(usize);
158
159#[derive(Debug)]
163pub struct ReturnValue<'cb, T = Value>(RawReturnValue, PhantomData<&'cb T>);
164
165impl<'cb, T> ReturnValue<'cb, T> {
166 #[inline(always)]
167 pub fn from_property_callback_info(
168 info: &'cb PropertyCallbackInfo<T>,
169 ) -> Self {
170 Self(
171 unsafe {
172 RawReturnValue(v8__PropertyCallbackInfo__GetReturnValue(&info.0))
173 },
174 PhantomData,
175 )
176 }
177}
178
179impl<'cb> ReturnValue<'cb, Value> {
180 #[inline(always)]
181 pub fn from_function_callback_info(info: &'cb FunctionCallbackInfo) -> Self {
182 Self(
183 unsafe { RawReturnValue(v8__FunctionCallbackInfo__GetReturnValue(info)) },
184 PhantomData,
185 )
186 }
187}
188
189impl ReturnValue<'_, ()> {
190 #[inline(always)]
191 pub fn set_bool(&mut self, value: bool) {
192 unsafe { v8__ReturnValue__Value__Set__Bool(&mut self.0, value) }
193 }
194}
195
196impl<T> ReturnValue<'_, T>
197where
198 for<'s> Local<'s, T>: Into<Local<'s, Value>>,
199{
200 #[inline(always)]
201 pub fn set(&mut self, value: Local<T>) {
202 unsafe { v8__ReturnValue__Value__Set(&mut self.0, &*value.into()) }
203 }
204
205 #[inline(always)]
206 pub fn set_bool(&mut self, value: bool) {
207 unsafe { v8__ReturnValue__Value__Set__Bool(&mut self.0, value) }
208 }
209
210 #[inline(always)]
211 pub fn set_int32(&mut self, value: i32) {
212 unsafe { v8__ReturnValue__Value__Set__Int32(&mut self.0, value) }
213 }
214
215 #[inline(always)]
216 pub fn set_uint32(&mut self, value: u32) {
217 unsafe { v8__ReturnValue__Value__Set__Uint32(&mut self.0, value) }
218 }
219
220 #[inline(always)]
221 pub fn set_double(&mut self, value: f64) {
222 unsafe { v8__ReturnValue__Value__Set__Double(&mut self.0, value) }
223 }
224
225 #[inline(always)]
226 pub fn set_null(&mut self) {
227 unsafe { v8__ReturnValue__Value__SetNull(&mut self.0) }
228 }
229
230 #[inline(always)]
231 pub fn set_undefined(&mut self) {
232 unsafe { v8__ReturnValue__Value__SetUndefined(&mut self.0) }
233 }
234
235 #[inline(always)]
236 pub fn set_empty_string(&mut self) {
237 unsafe { v8__ReturnValue__Value__SetEmptyString(&mut self.0) }
238 }
239
240 #[inline(always)]
244 pub fn get<'s>(&self, scope: &PinScope<'s, '_>) -> Local<'s, Value> {
245 unsafe { scope.cast_local(|_| v8__ReturnValue__Value__Get(&self.0)) }
246 .unwrap()
247 }
248}
249
250#[repr(C)]
255#[derive(Debug)]
256pub struct FunctionCallbackInfo(*mut Opaque);
257
258impl FunctionCallbackInfo {
259 #[inline(always)]
260 pub(crate) fn get_isolate_ptr(&self) -> *mut RealIsolate {
261 unsafe { v8__FunctionCallbackInfo__GetIsolate(self) }
262 }
263
264 #[inline(always)]
265 pub(crate) fn new_target(&self) -> Local<'_, Value> {
266 unsafe {
267 let ptr = v8__FunctionCallbackInfo__NewTarget(self);
268 let nn = NonNull::new_unchecked(ptr as *mut _);
269 Local::from_non_null(nn)
270 }
271 }
272
273 #[inline(always)]
274 pub(crate) fn this(&self) -> Local<'_, Object> {
275 unsafe {
276 let ptr = v8__FunctionCallbackInfo__This(self);
277 let nn = NonNull::new_unchecked(ptr as *mut _);
278 Local::from_non_null(nn)
279 }
280 }
281
282 #[inline]
283 pub fn is_construct_call(&self) -> bool {
284 unsafe { v8__FunctionCallbackInfo__IsConstructCall(self) }
285 }
286
287 #[inline(always)]
288 pub(crate) fn data(&self) -> Local<'_, Value> {
289 unsafe {
290 let ptr = v8__FunctionCallbackInfo__Data(self);
291 let nn = NonNull::new_unchecked(ptr as *mut Value);
292 Local::from_non_null(nn)
293 }
294 }
295
296 #[inline(always)]
297 pub(crate) fn length(&self) -> int {
298 unsafe { v8__FunctionCallbackInfo__Length(self) }
299 }
300
301 #[inline(always)]
302 pub(crate) fn get(&self, index: int) -> Local<'_, Value> {
303 unsafe {
304 let ptr = v8__FunctionCallbackInfo__Get(self, index);
305 let nn = NonNull::new_unchecked(ptr as *mut Value);
306 Local::from_non_null(nn)
307 }
308 }
309}
310
311#[repr(C)]
312#[derive(Debug)]
313struct RawPropertyCallbackInfo(*mut Opaque);
314
315#[repr(C)]
318#[derive(Debug)]
319pub struct PropertyCallbackInfo<T>(RawPropertyCallbackInfo, PhantomData<T>);
320
321impl<T> PropertyCallbackInfo<T> {
322 #[inline(always)]
323 pub(crate) fn get_isolate_ptr(&self) -> *mut RealIsolate {
324 unsafe { v8__PropertyCallbackInfo__GetIsolate(&self.0) }
325 }
326}
327
328#[derive(Debug)]
329pub struct FunctionCallbackArguments<'s>(&'s FunctionCallbackInfo);
330
331impl<'s> FunctionCallbackArguments<'s> {
332 #[inline(always)]
333 pub fn from_function_callback_info(info: &'s FunctionCallbackInfo) -> Self {
334 Self(info)
335 }
336
337 #[inline(always)]
342 pub unsafe fn get_isolate(&mut self) -> &mut Isolate {
343 unsafe { &mut *(self.0.get_isolate_ptr() as *mut crate::isolate::Isolate) }
344 }
345
346 #[inline(always)]
348 pub fn new_target(&self) -> Local<'s, Value> {
349 self.0.new_target()
350 }
351
352 #[inline]
355 pub fn is_construct_call(&self) -> bool {
356 self.0.is_construct_call()
357 }
358
359 #[inline(always)]
361 pub fn this(&self) -> Local<'s, Object> {
362 self.0.this()
363 }
364
365 #[inline(always)]
367 pub fn data(&self) -> Local<'s, Value> {
368 self.0.data()
369 }
370
371 #[inline(always)]
373 pub fn length(&self) -> int {
374 self.0.length()
375 }
376
377 #[inline(always)]
380 pub fn get(&self, i: int) -> Local<'s, Value> {
381 self.0.get(i)
382 }
383}
384
385#[derive(Debug)]
386pub struct PropertyCallbackArguments<'s>(&'s RawPropertyCallbackInfo);
387
388impl<'s> PropertyCallbackArguments<'s> {
389 #[inline(always)]
390 pub(crate) fn from_property_callback_info<T>(
391 info: &'s PropertyCallbackInfo<T>,
392 ) -> Self {
393 Self(&info.0)
394 }
395
396 #[inline(always)]
402 pub fn holder(&self) -> Local<'s, Object> {
403 unsafe {
404 Local::from_raw(v8__PropertyCallbackInfo__Holder(self.0))
405 .unwrap_unchecked()
406 }
407 }
408
409 #[inline(always)]
449 pub fn this(&self) -> Local<'s, Object> {
450 unsafe {
451 Local::from_raw(v8__PropertyCallbackInfo__This(self.0)).unwrap_unchecked()
452 }
453 }
454
455 #[inline(always)]
459 pub fn data(&self) -> Local<'s, Value> {
460 unsafe {
461 Local::from_raw(v8__PropertyCallbackInfo__Data(self.0)).unwrap_unchecked()
462 }
463 }
464
465 #[inline(always)]
471 pub fn should_throw_on_error(&self) -> bool {
472 unsafe { v8__PropertyCallbackInfo__ShouldThrowOnError(self.0) }
473 }
474}
475
476pub type FunctionCallback = unsafe extern "C" fn(*const FunctionCallbackInfo);
477
478impl<F> MapFnFrom<F> for FunctionCallback
479where
480 F: UnitType
481 + for<'s, 'i> Fn(
482 &mut PinScope<'s, 'i>,
483 FunctionCallbackArguments<'s>,
484 ReturnValue<'s, Value>,
485 ),
486{
487 fn mapping() -> Self {
488 let f = |info: *const FunctionCallbackInfo| {
489 let info = unsafe { &*info };
490 let scope = std::pin::pin!(unsafe { CallbackScope::new(info) });
491 let mut scope = scope.init();
492 let args = FunctionCallbackArguments::from_function_callback_info(info);
493 let rv = ReturnValue::from_function_callback_info(info);
494 (F::get())(&mut scope, args, rv);
495 };
496 f.to_c_fn()
497 }
498}
499
500pub(crate) type NamedGetterCallbackForAccessor =
501 unsafe extern "C" fn(SealedLocal<Name>, *const PropertyCallbackInfo<Value>);
502
503impl<F> MapFnFrom<F> for NamedGetterCallbackForAccessor
504where
505 F: UnitType
506 + for<'s, 'i> Fn(
507 &mut PinScope<'s, 'i>,
508 Local<'s, Name>,
509 PropertyCallbackArguments<'s>,
510 ReturnValue<Value>,
511 ),
512{
513 fn mapping() -> Self {
514 let f = |key: SealedLocal<Name>,
515 info: *const PropertyCallbackInfo<Value>| {
516 let info = unsafe { &*info };
517 callback_scope!(unsafe scope, info);
518 let key = unsafe { scope.unseal(key) };
519 let args = PropertyCallbackArguments::from_property_callback_info(info);
520 let rv = ReturnValue::from_property_callback_info(info);
521 (F::get())(scope, key, args, rv);
522 };
523 f.to_c_fn()
524 }
525}
526
527pub(crate) type NamedGetterCallback = unsafe extern "C" fn(
528 SealedLocal<Name>,
529 *const PropertyCallbackInfo<Value>,
530) -> Intercepted;
531
532impl<F> MapFnFrom<F> for NamedGetterCallback
533where
534 F: UnitType
535 + for<'s, 'i> Fn(
536 &mut PinScope<'s, 'i>,
537 Local<'s, Name>,
538 PropertyCallbackArguments<'s>,
539 ReturnValue<Value>,
540 ) -> Intercepted,
541{
542 fn mapping() -> Self {
543 let f = |key: SealedLocal<Name>,
544 info: *const PropertyCallbackInfo<Value>| {
545 let info = unsafe { &*info };
546 callback_scope!(unsafe scope, info);
547 let key = unsafe { scope.unseal(key) };
548 let args = PropertyCallbackArguments::from_property_callback_info(info);
549 let rv = ReturnValue::from_property_callback_info(info);
550 (F::get())(scope, key, args, rv)
551 };
552 f.to_c_fn()
553 }
554}
555
556pub(crate) type NamedQueryCallback = unsafe extern "C" fn(
557 SealedLocal<Name>,
558 *const PropertyCallbackInfo<Integer>,
559) -> Intercepted;
560
561impl<F> MapFnFrom<F> for NamedQueryCallback
562where
563 F: UnitType
564 + for<'s, 'i> Fn(
565 &mut PinScope<'s, 'i>,
566 Local<'s, Name>,
567 PropertyCallbackArguments<'s>,
568 ReturnValue<Integer>,
569 ) -> Intercepted,
570{
571 fn mapping() -> Self {
572 let f = |key: SealedLocal<Name>,
573 info: *const PropertyCallbackInfo<Integer>| {
574 let info = unsafe { &*info };
575 callback_scope!(unsafe scope, info);
576 let key = unsafe { scope.unseal(key) };
577 let args = PropertyCallbackArguments::from_property_callback_info(info);
578 let rv = ReturnValue::from_property_callback_info(info);
579 (F::get())(scope, key, args, rv)
580 };
581 f.to_c_fn()
582 }
583}
584
585pub(crate) type NamedSetterCallbackForAccessor = unsafe extern "C" fn(
586 SealedLocal<Name>,
587 SealedLocal<Value>,
588 *const PropertyCallbackInfo<()>,
589);
590
591impl<F> MapFnFrom<F> for NamedSetterCallbackForAccessor
592where
593 F: UnitType
594 + for<'s, 'i> Fn(
595 &mut PinScope<'s, 'i>,
596 Local<'s, Name>,
597 Local<'s, Value>,
598 PropertyCallbackArguments<'s>,
599 ReturnValue<()>,
600 ),
601{
602 fn mapping() -> Self {
603 let f = |key: SealedLocal<Name>,
604 value: SealedLocal<Value>,
605 info: *const PropertyCallbackInfo<()>| {
606 let info = unsafe { &*info };
607 callback_scope!(unsafe scope, info);
608 let key = unsafe { scope.unseal(key) };
609 let value = unsafe { scope.unseal(value) };
610 let args = PropertyCallbackArguments::from_property_callback_info(info);
611 let rv = ReturnValue::from_property_callback_info(info);
612 (F::get())(scope, key, value, args, rv);
613 };
614 f.to_c_fn()
615 }
616}
617
618pub(crate) type NamedSetterCallback = unsafe extern "C" fn(
619 SealedLocal<Name>,
620 SealedLocal<Value>,
621 *const PropertyCallbackInfo<()>,
622) -> Intercepted;
623
624impl<F> MapFnFrom<F> for NamedSetterCallback
625where
626 F: UnitType
627 + for<'s, 'i> Fn(
628 &mut PinScope<'s, 'i>,
629 Local<'s, Name>,
630 Local<'s, Value>,
631 PropertyCallbackArguments<'s>,
632 ReturnValue<()>,
633 ) -> Intercepted,
634{
635 fn mapping() -> Self {
636 let f = |key: SealedLocal<Name>,
637 value: SealedLocal<Value>,
638 info: *const PropertyCallbackInfo<()>| {
639 let info = unsafe { &*info };
640 callback_scope!(unsafe scope, info);
641 let key = unsafe { scope.unseal(key) };
642 let value = unsafe { scope.unseal(value) };
643 let args = PropertyCallbackArguments::from_property_callback_info(info);
644 let rv = ReturnValue::from_property_callback_info(info);
645 (F::get())(scope, key, value, args, rv)
646 };
647 f.to_c_fn()
648 }
649}
650
651pub(crate) type PropertyEnumeratorCallback =
653 unsafe extern "C" fn(*const PropertyCallbackInfo<Array>);
654
655impl<F> MapFnFrom<F> for PropertyEnumeratorCallback
656where
657 F: UnitType
658 + for<'s, 'i> Fn(
659 &mut PinScope<'s, 'i>,
660 PropertyCallbackArguments<'s>,
661 ReturnValue<Array>,
662 ),
663{
664 fn mapping() -> Self {
665 let f = |info: *const PropertyCallbackInfo<Array>| {
666 let info = unsafe { &*info };
667 callback_scope!(unsafe scope, info);
668 let args = PropertyCallbackArguments::from_property_callback_info(info);
669 let rv = ReturnValue::from_property_callback_info(info);
670 (F::get())(scope, args, rv);
671 };
672 f.to_c_fn()
673 }
674}
675
676pub(crate) type NamedDefinerCallback = unsafe extern "C" fn(
677 SealedLocal<Name>,
678 *const PropertyDescriptor,
679 *const PropertyCallbackInfo<()>,
680) -> Intercepted;
681
682impl<F> MapFnFrom<F> for NamedDefinerCallback
683where
684 F: UnitType
685 + for<'s, 'i> Fn(
686 &mut PinScope<'s, 'i>,
687 Local<'s, Name>,
688 &PropertyDescriptor,
689 PropertyCallbackArguments<'s>,
690 ReturnValue<()>,
691 ) -> Intercepted,
692{
693 fn mapping() -> Self {
694 let f = |key: SealedLocal<Name>,
695 desc: *const PropertyDescriptor,
696 info: *const PropertyCallbackInfo<()>| {
697 let info = unsafe { &*info };
698 callback_scope!(unsafe scope, info);
699 let key = unsafe { scope.unseal(key) };
700 let args = PropertyCallbackArguments::from_property_callback_info(info);
701 let desc = unsafe { &*desc };
702 let rv = ReturnValue::from_property_callback_info(info);
703 (F::get())(scope, key, desc, args, rv)
704 };
705 f.to_c_fn()
706 }
707}
708
709pub(crate) type NamedDeleterCallback = unsafe extern "C" fn(
710 SealedLocal<Name>,
711 *const PropertyCallbackInfo<Boolean>,
712) -> Intercepted;
713
714impl<F> MapFnFrom<F> for NamedDeleterCallback
715where
716 F: UnitType
717 + for<'s, 'i> Fn(
718 &mut PinScope<'s, 'i>,
719 Local<'s, Name>,
720 PropertyCallbackArguments<'s>,
721 ReturnValue<Boolean>,
722 ) -> Intercepted,
723{
724 fn mapping() -> Self {
725 let f = |key: SealedLocal<Name>,
726 info: *const PropertyCallbackInfo<Boolean>| {
727 let info = unsafe { &*info };
728 callback_scope!(unsafe scope, info);
729 let key = unsafe { scope.unseal(key) };
730 let args = PropertyCallbackArguments::from_property_callback_info(info);
731 let rv = ReturnValue::from_property_callback_info(info);
732 (F::get())(scope, key, args, rv)
733 };
734 f.to_c_fn()
735 }
736}
737
738pub(crate) type IndexedGetterCallback =
739 unsafe extern "C" fn(u32, *const PropertyCallbackInfo<Value>) -> Intercepted;
740
741impl<F> MapFnFrom<F> for IndexedGetterCallback
742where
743 F: UnitType
744 + for<'s, 'i> Fn(
745 &mut PinScope<'s, 'i>,
746 u32,
747 PropertyCallbackArguments<'s>,
748 ReturnValue<Value>,
749 ) -> Intercepted,
750{
751 fn mapping() -> Self {
752 let f = |index: u32, info: *const PropertyCallbackInfo<Value>| {
753 let info = unsafe { &*info };
754 callback_scope!(unsafe scope, info);
755 let args = PropertyCallbackArguments::from_property_callback_info(info);
756 let rv = ReturnValue::from_property_callback_info(info);
757 (F::get())(scope, index, args, rv)
758 };
759 f.to_c_fn()
760 }
761}
762
763pub(crate) type IndexedQueryCallback = unsafe extern "C" fn(
764 u32,
765 *const PropertyCallbackInfo<Integer>,
766) -> Intercepted;
767
768impl<F> MapFnFrom<F> for IndexedQueryCallback
769where
770 F: UnitType
771 + for<'s, 'i> Fn(
772 &mut PinScope<'s, 'i>,
773 u32,
774 PropertyCallbackArguments<'s>,
775 ReturnValue<Integer>,
776 ) -> Intercepted,
777{
778 fn mapping() -> Self {
779 let f = |key: u32, info: *const PropertyCallbackInfo<Integer>| {
780 let info = unsafe { &*info };
781 callback_scope!(unsafe scope, info);
782 let args = PropertyCallbackArguments::from_property_callback_info(info);
783 let rv = ReturnValue::from_property_callback_info(info);
784 (F::get())(scope, key, args, rv)
785 };
786 f.to_c_fn()
787 }
788}
789
790pub(crate) type IndexedSetterCallback = unsafe extern "C" fn(
791 u32,
792 SealedLocal<Value>,
793 *const PropertyCallbackInfo<()>,
794) -> Intercepted;
795
796impl<F> MapFnFrom<F> for IndexedSetterCallback
797where
798 F: UnitType
799 + for<'s, 'i> Fn(
800 &mut PinScope<'s, 'i>,
801 u32,
802 Local<'s, Value>,
803 PropertyCallbackArguments<'s>,
804 ReturnValue<()>,
805 ) -> Intercepted,
806{
807 fn mapping() -> Self {
808 let f = |index: u32,
809 value: SealedLocal<Value>,
810 info: *const PropertyCallbackInfo<()>| {
811 let info = unsafe { &*info };
812 callback_scope!(unsafe scope, info);
813 let value = unsafe { scope.unseal(value) };
814 let args = PropertyCallbackArguments::from_property_callback_info(info);
815 let rv = ReturnValue::from_property_callback_info(info);
816 (F::get())(scope, index, value, args, rv)
817 };
818 f.to_c_fn()
819 }
820}
821
822pub(crate) type IndexedDefinerCallback = unsafe extern "C" fn(
823 u32,
824 *const PropertyDescriptor,
825 *const PropertyCallbackInfo<()>,
826) -> Intercepted;
827
828impl<F> MapFnFrom<F> for IndexedDefinerCallback
829where
830 F: UnitType
831 + for<'s, 'i> Fn(
832 &mut PinScope<'s, 'i>,
833 u32,
834 &PropertyDescriptor,
835 PropertyCallbackArguments<'s>,
836 ReturnValue<()>,
837 ) -> Intercepted,
838{
839 fn mapping() -> Self {
840 let f = |index: u32,
841 desc: *const PropertyDescriptor,
842 info: *const PropertyCallbackInfo<()>| {
843 let info = unsafe { &*info };
844 callback_scope!(unsafe scope, info);
845 let args = PropertyCallbackArguments::from_property_callback_info(info);
846 let rv = ReturnValue::from_property_callback_info(info);
847 let desc = unsafe { &*desc };
848 (F::get())(scope, index, desc, args, rv)
849 };
850 f.to_c_fn()
851 }
852}
853
854pub(crate) type IndexedDeleterCallback = unsafe extern "C" fn(
855 u32,
856 *const PropertyCallbackInfo<Boolean>,
857) -> Intercepted;
858
859impl<F> MapFnFrom<F> for IndexedDeleterCallback
860where
861 F: UnitType
862 + for<'s, 'i> Fn(
863 &mut PinScope<'s, 'i>,
864 u32,
865 PropertyCallbackArguments<'s>,
866 ReturnValue<Boolean>,
867 ) -> Intercepted,
868{
869 fn mapping() -> Self {
870 let f = |index: u32, info: *const PropertyCallbackInfo<Boolean>| {
871 let info = unsafe { &*info };
872 callback_scope!(unsafe scope, info);
873 let args = PropertyCallbackArguments::from_property_callback_info(info);
874 let rv = ReturnValue::from_property_callback_info(info);
875 (F::get())(scope, index, args, rv)
876 };
877 f.to_c_fn()
878 }
879}
880
881pub struct FunctionBuilder<'s, T> {
883 pub(crate) callback: FunctionCallback,
884 pub(crate) data: Option<Local<'s, Value>>,
885 pub(crate) signature: Option<Local<'s, Signature>>,
886 pub(crate) length: i32,
887 pub(crate) constructor_behavior: ConstructorBehavior,
888 pub(crate) side_effect_type: SideEffectType,
889 phantom: PhantomData<T>,
890}
891
892impl<'s, T> FunctionBuilder<'s, T> {
893 #[inline(always)]
895 pub fn new(callback: impl MapFnTo<FunctionCallback>) -> Self {
896 Self::new_raw(callback.map_fn_to())
897 }
898
899 #[inline(always)]
900 pub fn new_raw(callback: FunctionCallback) -> Self {
901 Self {
902 callback,
903 data: None,
904 signature: None,
905 length: 0,
906 constructor_behavior: ConstructorBehavior::Allow,
907 side_effect_type: SideEffectType::HasSideEffect,
908 phantom: PhantomData,
909 }
910 }
911
912 #[inline(always)]
914 pub fn data(mut self, data: Local<'s, Value>) -> Self {
915 self.data = Some(data);
916 self
917 }
918
919 #[inline(always)]
921 pub fn length(mut self, length: i32) -> Self {
922 self.length = length;
923 self
924 }
925
926 #[inline(always)]
928 pub fn constructor_behavior(
929 mut self,
930 constructor_behavior: ConstructorBehavior,
931 ) -> Self {
932 self.constructor_behavior = constructor_behavior;
933 self
934 }
935
936 #[inline(always)]
938 pub fn side_effect_type(mut self, side_effect_type: SideEffectType) -> Self {
939 self.side_effect_type = side_effect_type;
940 self
941 }
942}
943
944impl<'s> FunctionBuilder<'s, Function> {
945 #[inline(always)]
947 pub fn build<'i>(
948 self,
949 scope: &PinScope<'s, 'i>,
950 ) -> Option<Local<'s, Function>> {
951 unsafe {
952 scope.cast_local(|sd| {
953 v8__Function__New(
954 sd.get_current_context(),
955 self.callback,
956 self.data.map_or_else(null, |p| &*p),
957 self.length,
958 self.constructor_behavior,
959 self.side_effect_type,
960 )
961 })
962 }
963 }
964}
965
966impl Function {
967 #[inline(always)]
970 pub fn builder<'s>(
971 callback: impl MapFnTo<FunctionCallback>,
972 ) -> FunctionBuilder<'s, Self> {
973 FunctionBuilder::new(callback)
974 }
975
976 #[inline(always)]
977 pub fn builder_raw<'s>(
978 callback: FunctionCallback,
979 ) -> FunctionBuilder<'s, Self> {
980 FunctionBuilder::new_raw(callback)
981 }
982
983 #[inline(always)]
986 pub fn new<'s>(
987 scope: &mut PinScope<'s, '_>,
988 callback: impl MapFnTo<FunctionCallback>,
989 ) -> Option<Local<'s, Function>> {
990 Self::builder(callback).build(scope)
991 }
992
993 #[inline(always)]
994 pub fn new_raw<'s>(
995 scope: &mut PinScope<'s, '_>,
996 callback: FunctionCallback,
997 ) -> Option<Local<'s, Function>> {
998 Self::builder_raw(callback).build(scope)
999 }
1000
1001 #[inline]
1003 pub fn call<'s>(
1004 &self,
1005 scope: &PinScope<'s, '_>,
1006 recv: Local<Value>,
1007 args: &[Local<Value>],
1008 ) -> Option<Local<'s, Value>> {
1009 let args = Local::slice_into_raw(args);
1010 let argc = int::try_from(args.len()).unwrap();
1011 let argv = args.as_ptr();
1012 unsafe {
1013 scope.cast_local(|sd| {
1014 v8__Function__Call(self, sd.get_current_context(), &*recv, argc, argv)
1015 })
1016 }
1017 }
1018
1019 #[inline]
1021 pub fn call_with_context<'s>(
1022 &self,
1023 scope: &PinScope<'s, '_, ()>,
1024 context: Local<Context>,
1025 recv: Local<Value>,
1026 args: &[Local<Value>],
1027 ) -> Option<Local<'s, Value>> {
1028 let args = Local::slice_into_raw(args);
1029 let argc = int::try_from(args.len()).unwrap();
1030 let argv = args.as_ptr();
1031 unsafe {
1032 let ret = v8__Function__Call(
1033 self,
1034 context.as_non_null().as_ptr(),
1035 &*recv,
1036 argc,
1037 argv,
1038 );
1039 if ret.is_null() {
1040 None
1041 } else {
1042 scope.cast_local(|_| ret)
1043 }
1044 }
1045 }
1046
1047 #[inline(always)]
1048 pub fn new_instance<'s>(
1049 &self,
1050 scope: &PinScope<'s, '_>,
1051 args: &[Local<Value>],
1052 ) -> Option<Local<'s, Object>> {
1053 let args = Local::slice_into_raw(args);
1054 let argc = int::try_from(args.len()).unwrap();
1055 let argv = args.as_ptr();
1056 unsafe {
1057 scope.cast_local(|sd| {
1058 v8__Function__NewInstance(self, sd.get_current_context(), argc, argv)
1059 })
1060 }
1061 }
1062
1063 #[inline(always)]
1064 pub fn get_name<'s>(&self, scope: &PinScope<'s, '_>) -> Local<'s, String> {
1065 unsafe { scope.cast_local(|_| v8__Function__GetName(self)).unwrap() }
1066 }
1067
1068 #[inline(always)]
1069 pub fn set_name(&self, name: Local<String>) {
1070 unsafe { v8__Function__SetName(self, &*name) }
1071 }
1072
1073 #[inline(always)]
1075 pub fn get_script_column_number(&self) -> Option<u32> {
1076 let ret = unsafe { v8__Function__GetScriptColumnNumber(self) };
1077 (ret >= 0).then_some(ret as u32)
1078 }
1079
1080 #[inline(always)]
1082 pub fn get_script_line_number(&self) -> Option<u32> {
1083 let ret = unsafe { v8__Function__GetScriptLineNumber(self) };
1084 (ret >= 0).then_some(ret as u32)
1085 }
1086
1087 #[inline(always)]
1088 pub fn get_script_origin(&self) -> &ScriptOrigin<'_> {
1089 unsafe {
1090 let ptr = v8__Function__GetScriptOrigin(self);
1091 &*ptr
1092 }
1093 }
1094
1095 #[inline(always)]
1097 pub fn script_id(&self) -> i32 {
1098 unsafe { v8__Function__ScriptId(self) }
1099 }
1100
1101 #[inline(always)]
1105 pub fn create_code_cache(&self) -> Option<UniqueRef<CachedData<'static>>> {
1106 let code_cache =
1107 unsafe { UniqueRef::try_from_raw(v8__Function__CreateCodeCache(self)) };
1108 if let Some(code_cache) = &code_cache {
1109 debug_assert_eq!(
1110 code_cache.buffer_policy(),
1111 crate::script_compiler::BufferPolicy::BufferOwned
1112 );
1113 }
1114 code_cache
1115 }
1116}