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