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