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