Skip to main content

v8/
template.rs

1use crate::ConstructorBehavior;
2use crate::Context;
3use crate::Function;
4use crate::FunctionBuilder;
5use crate::FunctionCallback;
6use crate::IndexedDefinerCallback;
7use crate::IndexedDeleterCallback;
8use crate::IndexedGetterCallback;
9use crate::IndexedQueryCallback;
10use crate::IndexedSetterCallback;
11use crate::Local;
12use crate::NamedDefinerCallback;
13use crate::NamedDeleterCallback;
14use crate::NamedGetterCallback;
15use crate::NamedGetterCallbackForAccessor;
16use crate::NamedQueryCallback;
17use crate::NamedSetterCallback;
18use crate::NamedSetterCallbackForAccessor;
19use crate::Object;
20use crate::PropertyAttribute;
21use crate::PropertyEnumeratorCallback;
22use crate::PropertyHandlerFlags;
23use crate::SideEffectType;
24use crate::Signature;
25use crate::String;
26use crate::Value;
27use crate::data::Data;
28use crate::data::FunctionTemplate;
29use crate::data::Name;
30use crate::data::ObjectTemplate;
31use crate::data::Template;
32use crate::fast_api::CFunction;
33use crate::isolate::RealIsolate;
34use crate::scope::PinScope;
35use crate::support::MapFnTo;
36use crate::support::int;
37use std::convert::TryFrom;
38use std::ptr::null;
39
40unsafe extern "C" {
41  fn v8__Template__Set(
42    this: *const Template,
43    key: *const Name,
44    value: *const Data,
45    attr: PropertyAttribute,
46  );
47  fn v8__Template__SetIntrinsicDataProperty(
48    this: *const Template,
49    key: *const Name,
50    intrinsic: Intrinsic,
51    attr: PropertyAttribute,
52  );
53
54  fn v8__Signature__New(
55    isolate: *mut RealIsolate,
56    templ: *const FunctionTemplate,
57  ) -> *const Signature;
58  fn v8__FunctionTemplate__New(
59    isolate: *mut RealIsolate,
60    callback: FunctionCallback,
61    data_or_null: *const Value,
62    signature_or_null: *const Signature,
63    length: i32,
64    constructor_behavior: ConstructorBehavior,
65    side_effect_type: SideEffectType,
66    c_functions: *const CFunction,
67    c_functions_len: usize,
68  ) -> *const FunctionTemplate;
69  fn v8__FunctionTemplate__GetFunction(
70    this: *const FunctionTemplate,
71    context: *const Context,
72  ) -> *const Function;
73  fn v8__FunctionTemplate__PrototypeTemplate(
74    this: *const FunctionTemplate,
75  ) -> *const ObjectTemplate;
76  fn v8__FunctionTemplate__InstanceTemplate(
77    this: *const FunctionTemplate,
78  ) -> *const ObjectTemplate;
79  fn v8__FunctionTemplate__SetClassName(
80    this: *const FunctionTemplate,
81    name: *const String,
82  );
83  fn v8__FunctionTemplate__Inherit(
84    this: *const FunctionTemplate,
85    parent: *const FunctionTemplate,
86  );
87  fn v8__FunctionTemplate__ReadOnlyPrototype(this: *const FunctionTemplate);
88  fn v8__FunctionTemplate__RemovePrototype(this: *const FunctionTemplate);
89
90  fn v8__ObjectTemplate__New(
91    isolate: *mut RealIsolate,
92    templ: *const FunctionTemplate,
93  ) -> *const ObjectTemplate;
94  fn v8__ObjectTemplate__NewInstance(
95    this: *const ObjectTemplate,
96    context: *const Context,
97  ) -> *const Object;
98  fn v8__ObjectTemplate__InternalFieldCount(this: *const ObjectTemplate)
99  -> int;
100  fn v8__ObjectTemplate__SetInternalFieldCount(
101    this: *const ObjectTemplate,
102    value: int,
103  );
104
105  fn v8__ObjectTemplate__SetNativeDataProperty(
106    this: *const ObjectTemplate,
107    key: *const Name,
108    getter: AccessorNameGetterCallback,
109    setter: Option<AccessorNameSetterCallback>,
110    data_or_null: *const Value,
111    attr: PropertyAttribute,
112  );
113  fn v8__ObjectTemplate__SetAccessorProperty(
114    this: *const ObjectTemplate,
115    key: *const Name,
116    getter: *const FunctionTemplate,
117    setter: *const FunctionTemplate,
118    attr: PropertyAttribute,
119  );
120
121  fn v8__ObjectTemplate__SetNamedPropertyHandler(
122    this: *const ObjectTemplate,
123    getter: Option<NamedPropertyGetterCallback>,
124    setter: Option<NamedPropertySetterCallback>,
125    query: Option<NamedPropertyQueryCallback>,
126    deleter: Option<NamedPropertyDeleterCallback>,
127    enumerator: Option<NamedPropertyEnumeratorCallback>,
128    definer: Option<NamedPropertyDefinerCallback>,
129    descriptor: Option<NamedPropertyDescriptorCallback>,
130    data_or_null: *const Value,
131    flags: PropertyHandlerFlags,
132  );
133
134  fn v8__ObjectTemplate__SetIndexedPropertyHandler(
135    this: *const ObjectTemplate,
136    getter: Option<IndexedPropertyGetterCallback>,
137    setter: Option<IndexedPropertySetterCallback>,
138    query: Option<IndexedPropertyQueryCallback>,
139    deleter: Option<IndexedPropertyDeleterCallback>,
140    enumerator: Option<IndexedPropertyEnumeratorCallback>,
141    definer: Option<IndexedPropertyDefinerCallback>,
142    descriptor: Option<IndexedPropertyDescriptorCallback>,
143    data_or_null: *const Value,
144  );
145
146  fn v8__ObjectTemplate__SetImmutableProto(this: *const ObjectTemplate);
147}
148
149/// Interceptor callbacks use this value to indicate whether the request was
150/// intercepted or not.
151#[repr(u8)]
152pub enum Intercepted {
153  No,
154  Yes,
155}
156
157pub type AccessorNameGetterCallback = NamedGetterCallbackForAccessor;
158
159/// Note: [ReturnValue] is ignored for accessors.
160pub type AccessorNameSetterCallback = NamedSetterCallbackForAccessor;
161
162/// Interceptor for get requests on an object.
163///
164/// Use [ReturnValue] to set the return value of the intercepted get request. If
165/// the property does not exist the callback should not set the result and must
166/// not produce side effects.
167///
168/// See also [ObjectTemplate::set_handler].
169pub type NamedPropertyGetterCallback = NamedGetterCallback;
170
171/// Interceptor for set requests on an object.
172///
173/// Use [ReturnValue] to indicate whether the request was intercepted or not. If
174/// the setter successfully intercepts the request, i.e., if the request should
175/// not be further executed, call [ReturnValue::set]. If the setter did not
176/// intercept the request, i.e., if the request should be handled as if no
177/// interceptor is present, do not not call set() and do not produce side
178/// effects.
179///
180/// See also [ObjectTemplate::set_named_property_handler].
181pub type NamedPropertySetterCallback = NamedSetterCallback;
182
183/// Intercepts all requests that query the attributes of the property, e.g.,
184/// getOwnPropertyDescriptor(), propertyIsEnumerable(), and defineProperty().
185///
186/// Use [ReturnValue::set] to set the property attributes. The value is an
187/// integer encoding a [PropertyAttribute]. If the property does not exist the
188/// callback should not set the result and must not produce side effects.
189///
190/// Note: Some functions query the property attributes internally, even though
191/// they do not return the attributes. For example, hasOwnProperty() can trigger
192/// this interceptor depending on the state of the object.
193///
194/// See also [ObjectTemplate::set_named_property_handler].
195pub type NamedPropertyQueryCallback = NamedQueryCallback;
196
197/// Interceptor for delete requests on an object.
198///
199/// Use [ReturnValue] to indicate whether the request was intercepted or not. If
200/// the deleter successfully intercepts the request, i.e., if the request should
201/// not be further executed, call [ReturnValue::set] with a boolean value. The
202/// value is used as the return value of delete. If the deleter does not
203/// intercept the request then it should not set the result and must not produce
204/// side effects.
205///
206/// Note: If you need to mimic the behavior of delete, i.e., throw in strict
207/// mode instead of returning false, use
208/// [PropertyCallbackArguments::should_throw_on_error] to determine if you are
209/// in strict mode.
210///
211/// See also [ObjectTemplate::set_named_property_handler].
212pub type NamedPropertyDeleterCallback = NamedDeleterCallback;
213
214/// Returns an array containing the names of the properties the named property getter intercepts.
215///
216/// Note: The values in the array must be of type v8::Name.
217///
218/// See also [ObjectTemplate::set_named_property_handler].
219pub type NamedPropertyEnumeratorCallback = PropertyEnumeratorCallback;
220
221/// Interceptor for defineProperty requests on an object.
222///
223/// Use [ReturnValue] to indicate whether the request was intercepted or not. If
224/// the definer successfully intercepts the request, i.e., if the request should
225/// not be further executed, call [ReturnValue::set]. If the definer did not
226/// intercept the request, i.e., if the request should be handled as if no
227/// interceptor is present, do not not call set() and do not produce side
228/// effects.
229///
230/// See also [ObjectTemplate::set_named_property_handler].
231pub type NamedPropertyDefinerCallback = NamedDefinerCallback;
232
233/// Interceptor for getOwnPropertyDescriptor requests on an object.
234///
235/// Use [ReturnValue::set] to set the return value of the intercepted request.
236/// The return value must be an object that can be converted to a
237/// [PropertyDescriptor], e.g., a [Value] returned from
238/// `Object.getOwnPropertyDescriptor()`.
239///
240/// Note: If GetOwnPropertyDescriptor is intercepted, it will always return
241/// true, i.e., indicate that the property was found.
242///
243/// See also [ObjectTemplate::set_named_property_handler].
244pub type NamedPropertyDescriptorCallback = NamedGetterCallback;
245
246/// See [GenericNamedPropertyGetterCallback].
247pub type IndexedPropertyGetterCallback = IndexedGetterCallback;
248
249/// See [GenericNamedPropertySetterCallback].
250pub type IndexedPropertySetterCallback = IndexedSetterCallback;
251
252/// See [GenericNamedPropertyQueryCallback].
253pub type IndexedPropertyQueryCallback = IndexedQueryCallback;
254
255/// See [GenericNamedPropertyDeleterCallback].
256pub type IndexedPropertyDeleterCallback = IndexedDeleterCallback;
257
258/// See [GenericNamedPropertyEnumeratorCallback].
259pub type IndexedPropertyEnumeratorCallback = PropertyEnumeratorCallback;
260
261/// See [GenericNamedPropertyDefinerCallback].
262pub type IndexedPropertyDefinerCallback = IndexedDefinerCallback;
263
264/// See [GenericNamedPropertyDescriptorCallback].
265pub type IndexedPropertyDescriptorCallback = IndexedGetterCallback;
266
267pub struct AccessorConfiguration<'s> {
268  pub(crate) getter: AccessorNameGetterCallback,
269  pub(crate) setter: Option<AccessorNameSetterCallback>,
270  pub(crate) data: Option<Local<'s, Value>>,
271  pub(crate) property_attribute: PropertyAttribute,
272}
273
274impl<'s> AccessorConfiguration<'s> {
275  pub fn new(getter: impl MapFnTo<AccessorNameGetterCallback>) -> Self {
276    Self {
277      getter: getter.map_fn_to(),
278      setter: None,
279      data: None,
280      property_attribute: PropertyAttribute::NONE,
281    }
282  }
283
284  pub fn setter(
285    mut self,
286    setter: impl MapFnTo<AccessorNameSetterCallback>,
287  ) -> Self {
288    self.setter = Some(setter.map_fn_to());
289    self
290  }
291
292  pub fn property_attribute(
293    mut self,
294    property_attribute: PropertyAttribute,
295  ) -> Self {
296    self.property_attribute = property_attribute;
297    self
298  }
299
300  /// Set the associated data. The default is no associated data.
301  pub fn data(mut self, data: Local<'s, Value>) -> Self {
302    self.data = Some(data);
303    self
304  }
305}
306
307#[derive(Default)]
308pub struct NamedPropertyHandlerConfiguration<'s> {
309  pub(crate) getter: Option<NamedPropertyGetterCallback>,
310  pub(crate) setter: Option<NamedPropertySetterCallback>,
311  pub(crate) query: Option<NamedPropertyQueryCallback>,
312  pub(crate) deleter: Option<NamedPropertyDeleterCallback>,
313  pub(crate) enumerator: Option<NamedPropertyEnumeratorCallback>,
314  pub(crate) definer: Option<NamedPropertyDefinerCallback>,
315  pub(crate) descriptor: Option<NamedPropertyDescriptorCallback>,
316  pub(crate) data: Option<Local<'s, Value>>,
317  pub(crate) flags: PropertyHandlerFlags,
318}
319
320impl<'s> NamedPropertyHandlerConfiguration<'s> {
321  pub fn new() -> Self {
322    Self {
323      getter: None,
324      setter: None,
325      query: None,
326      deleter: None,
327      enumerator: None,
328      definer: None,
329      descriptor: None,
330      data: None,
331      flags: PropertyHandlerFlags::NONE,
332    }
333  }
334
335  pub fn is_some(&self) -> bool {
336    self.getter.is_some()
337      || self.setter.is_some()
338      || self.query.is_some()
339      || self.deleter.is_some()
340      || self.enumerator.is_some()
341      || self.definer.is_some()
342      || self.descriptor.is_some()
343      || !self.flags.is_none()
344  }
345
346  pub fn getter(
347    mut self,
348    getter: impl MapFnTo<NamedPropertyGetterCallback>,
349  ) -> Self {
350    self.getter = Some(getter.map_fn_to());
351    self
352  }
353
354  pub fn getter_raw(mut self, getter: NamedPropertyGetterCallback) -> Self {
355    self.getter = Some(getter);
356    self
357  }
358
359  pub fn setter(
360    mut self,
361    setter: impl MapFnTo<NamedPropertySetterCallback>,
362  ) -> Self {
363    self.setter = Some(setter.map_fn_to());
364    self
365  }
366
367  pub fn setter_raw(mut self, setter: NamedPropertySetterCallback) -> Self {
368    self.setter = Some(setter);
369    self
370  }
371
372  pub fn query(
373    mut self,
374    query: impl MapFnTo<NamedPropertyQueryCallback>,
375  ) -> Self {
376    self.query = Some(query.map_fn_to());
377    self
378  }
379
380  pub fn query_raw(mut self, query: NamedPropertyQueryCallback) -> Self {
381    self.query = Some(query);
382    self
383  }
384
385  pub fn deleter(
386    mut self,
387    deleter: impl MapFnTo<NamedPropertyDeleterCallback>,
388  ) -> Self {
389    self.deleter = Some(deleter.map_fn_to());
390    self
391  }
392
393  pub fn deleter_raw(mut self, deleter: NamedPropertyDeleterCallback) -> Self {
394    self.deleter = Some(deleter);
395    self
396  }
397
398  pub fn enumerator(
399    mut self,
400    enumerator: impl MapFnTo<NamedPropertyEnumeratorCallback>,
401  ) -> Self {
402    self.enumerator = Some(enumerator.map_fn_to());
403    self
404  }
405
406  pub fn enumerator_raw(
407    mut self,
408    enumerator: NamedPropertyEnumeratorCallback,
409  ) -> Self {
410    self.enumerator = Some(enumerator);
411    self
412  }
413
414  pub fn definer(
415    mut self,
416    definer: impl MapFnTo<NamedPropertyDefinerCallback>,
417  ) -> Self {
418    self.definer = Some(definer.map_fn_to());
419    self
420  }
421
422  pub fn definer_raw(mut self, definer: NamedPropertyDefinerCallback) -> Self {
423    self.definer = Some(definer);
424    self
425  }
426
427  pub fn descriptor(
428    mut self,
429    descriptor: impl MapFnTo<NamedPropertyDescriptorCallback>,
430  ) -> Self {
431    self.descriptor = Some(descriptor.map_fn_to());
432    self
433  }
434
435  pub fn descriptor_raw(
436    mut self,
437    descriptor: NamedPropertyDescriptorCallback,
438  ) -> Self {
439    self.descriptor = Some(descriptor);
440    self
441  }
442
443  /// Set the associated data. The default is no associated data.
444  pub fn data(mut self, data: Local<'s, Value>) -> Self {
445    self.data = Some(data);
446    self
447  }
448
449  /// Set the property handler flags. The default is PropertyHandlerFlags::NONE.
450  pub fn flags(mut self, flags: PropertyHandlerFlags) -> Self {
451    self.flags = flags;
452    self
453  }
454}
455
456#[derive(Default)]
457pub struct IndexedPropertyHandlerConfiguration<'s> {
458  pub(crate) getter: Option<IndexedPropertyGetterCallback>,
459  pub(crate) setter: Option<IndexedPropertySetterCallback>,
460  pub(crate) query: Option<IndexedPropertyQueryCallback>,
461  pub(crate) deleter: Option<IndexedPropertyDeleterCallback>,
462  pub(crate) enumerator: Option<IndexedPropertyEnumeratorCallback>,
463  pub(crate) definer: Option<IndexedPropertyDefinerCallback>,
464  pub(crate) descriptor: Option<IndexedPropertyDescriptorCallback>,
465  pub(crate) data: Option<Local<'s, Value>>,
466  pub(crate) flags: PropertyHandlerFlags,
467}
468
469impl<'s> IndexedPropertyHandlerConfiguration<'s> {
470  pub fn new() -> Self {
471    Self {
472      getter: None,
473      setter: None,
474      query: None,
475      deleter: None,
476      enumerator: None,
477      definer: None,
478      descriptor: None,
479      data: None,
480      flags: PropertyHandlerFlags::NONE,
481    }
482  }
483
484  pub fn is_some(&self) -> bool {
485    self.getter.is_some()
486      || self.setter.is_some()
487      || self.query.is_some()
488      || self.deleter.is_some()
489      || self.enumerator.is_some()
490      || self.definer.is_some()
491      || self.descriptor.is_some()
492      || !self.flags.is_none()
493  }
494
495  pub fn getter(
496    mut self,
497    getter: impl MapFnTo<IndexedPropertyGetterCallback>,
498  ) -> Self {
499    self.getter = Some(getter.map_fn_to());
500    self
501  }
502
503  pub fn getter_raw(mut self, getter: IndexedPropertyGetterCallback) -> Self {
504    self.getter = Some(getter);
505    self
506  }
507
508  pub fn setter(
509    mut self,
510    setter: impl MapFnTo<IndexedPropertySetterCallback>,
511  ) -> Self {
512    self.setter = Some(setter.map_fn_to());
513    self
514  }
515
516  pub fn setter_raw(mut self, setter: IndexedPropertySetterCallback) -> Self {
517    self.setter = Some(setter);
518    self
519  }
520
521  pub fn query(
522    mut self,
523    query: impl MapFnTo<IndexedPropertyQueryCallback>,
524  ) -> Self {
525    self.query = Some(query.map_fn_to());
526    self
527  }
528
529  pub fn query_raw(mut self, query: IndexedPropertyQueryCallback) -> Self {
530    self.query = Some(query);
531    self
532  }
533
534  pub fn deleter(
535    mut self,
536    deleter: impl MapFnTo<IndexedPropertyDeleterCallback>,
537  ) -> Self {
538    self.deleter = Some(deleter.map_fn_to());
539    self
540  }
541
542  pub fn deleter_raw(
543    mut self,
544    deleter: IndexedPropertyDeleterCallback,
545  ) -> Self {
546    self.deleter = Some(deleter);
547    self
548  }
549
550  pub fn enumerator(
551    mut self,
552    enumerator: impl MapFnTo<IndexedPropertyEnumeratorCallback>,
553  ) -> Self {
554    self.enumerator = Some(enumerator.map_fn_to());
555    self
556  }
557
558  pub fn enumerator_raw(
559    mut self,
560    enumerator: IndexedPropertyEnumeratorCallback,
561  ) -> Self {
562    self.enumerator = Some(enumerator);
563    self
564  }
565
566  pub fn definer(
567    mut self,
568    definer: impl MapFnTo<IndexedPropertyDefinerCallback>,
569  ) -> Self {
570    self.definer = Some(definer.map_fn_to());
571    self
572  }
573
574  pub fn definer_raw(
575    mut self,
576    definer: IndexedPropertyDefinerCallback,
577  ) -> Self {
578    self.definer = Some(definer);
579    self
580  }
581
582  pub fn descriptor(
583    mut self,
584    descriptor: impl MapFnTo<IndexedPropertyDescriptorCallback>,
585  ) -> Self {
586    self.descriptor = Some(descriptor.map_fn_to());
587    self
588  }
589
590  pub fn descriptor_raw(
591    mut self,
592    descriptor: IndexedPropertyDescriptorCallback,
593  ) -> Self {
594    self.descriptor = Some(descriptor);
595    self
596  }
597
598  /// Set the associated data. The default is no associated data.
599  pub fn data(mut self, data: Local<'s, Value>) -> Self {
600    self.data = Some(data);
601    self
602  }
603
604  /// Set the property handler flags. The default is PropertyHandlerFlags::NONE.
605  pub fn flags(mut self, flags: PropertyHandlerFlags) -> Self {
606    self.flags = flags;
607    self
608  }
609}
610
611#[derive(Debug, Clone, Copy)]
612#[repr(C)]
613pub enum Intrinsic {
614  ArrayProtoEntries,
615  ArrayProtoForEach,
616  ArrayProtoKeys,
617  ArrayProtoValues,
618  ArrayPrototype,
619  AsyncIteratorPrototype,
620  ErrorPrototype,
621  IteratorPrototype,
622  MapIteratorPrototype,
623  ObjProtoValueOf,
624  SetIteratorPrototype,
625}
626
627impl Template {
628  /// Adds a property to each instance created by this template.
629  #[inline(always)]
630  pub fn set(&self, key: Local<Name>, value: Local<Data>) {
631    self.set_with_attr(key, value, PropertyAttribute::NONE);
632  }
633
634  /// Adds a property to each instance created by this template with
635  /// the specified property attributes.
636  #[inline(always)]
637  pub fn set_with_attr(
638    &self,
639    key: Local<Name>,
640    value: Local<Data>,
641    attr: PropertyAttribute,
642  ) {
643    unsafe { v8__Template__Set(self, &*key, &*value, attr) }
644  }
645
646  /// During template instantiation, sets the value with the
647  /// intrinsic property from the correct context.
648  #[inline(always)]
649  pub fn set_intrinsic_data_property(
650    &self,
651    key: Local<Name>,
652    intrinsic: Intrinsic,
653    attr: PropertyAttribute,
654  ) {
655    unsafe {
656      v8__Template__SetIntrinsicDataProperty(self, &*key, intrinsic, attr);
657    }
658  }
659}
660
661impl<'s> FunctionBuilder<'s, FunctionTemplate> {
662  /// Set the function call signature. The default is no signature.
663  #[inline(always)]
664  pub fn signature(mut self, signature: Local<'s, Signature>) -> Self {
665    self.signature = Some(signature);
666    self
667  }
668
669  /// Creates the function template.
670  #[inline(always)]
671  pub fn build<'i>(
672    self,
673    scope: &PinScope<'s, 'i, ()>,
674  ) -> Local<'s, FunctionTemplate> {
675    unsafe {
676      scope.cast_local(|sd| {
677        v8__FunctionTemplate__New(
678          sd.get_isolate_ptr(),
679          self.callback,
680          self.data.map_or_else(null, |p| &*p),
681          self.signature.map_or_else(null, |p| &*p),
682          self.length,
683          self.constructor_behavior,
684          self.side_effect_type,
685          null(),
686          0,
687        )
688      })
689    }
690    .unwrap()
691  }
692
693  /// It's not required to provide `CFunctionInfo` for the overloads - if they
694  /// are omitted, then they will be automatically created. In some cases it is
695  /// useful to pass them explicitly - eg. when you are snapshotting you'd provide
696  /// the overloads and `CFunctionInfo` that would be placed in the external
697  /// references array.
698  pub fn build_fast<'i>(
699    self,
700    scope: &PinScope<'s, 'i>,
701    overloads: &[CFunction],
702  ) -> Local<'s, FunctionTemplate> {
703    unsafe {
704      scope.cast_local(|sd| {
705        v8__FunctionTemplate__New(
706          sd.get_isolate_ptr(),
707          self.callback,
708          self.data.map_or_else(null, |p| &*p),
709          self.signature.map_or_else(null, |p| &*p),
710          self.length,
711          ConstructorBehavior::Throw,
712          self.side_effect_type,
713          overloads.as_ptr(),
714          overloads.len(),
715        )
716      })
717    }
718    .unwrap()
719  }
720}
721
722/// A Signature specifies which receiver is valid for a function.
723///
724/// A receiver matches a given signature if the receiver (or any of its
725/// hidden prototypes) was created from the signature's FunctionTemplate, or
726/// from a FunctionTemplate that inherits directly or indirectly from the
727/// signature's FunctionTemplate.
728impl Signature {
729  #[inline(always)]
730  pub fn new<'s>(
731    scope: &PinScope<'s, '_, ()>,
732    templ: Local<FunctionTemplate>,
733  ) -> Local<'s, Self> {
734    unsafe {
735      scope.cast_local(|sd| v8__Signature__New(sd.get_isolate_ptr(), &*templ))
736    }
737    .unwrap()
738  }
739}
740
741impl FunctionTemplate {
742  /// Create a FunctionBuilder to configure a FunctionTemplate.
743  /// This is the same as FunctionBuilder::<FunctionTemplate>::new().
744  #[inline(always)]
745  pub fn builder<'s>(
746    callback: impl MapFnTo<FunctionCallback>,
747  ) -> FunctionBuilder<'s, Self> {
748    FunctionBuilder::new(callback)
749  }
750
751  #[inline(always)]
752  pub fn builder_raw<'s>(
753    callback: FunctionCallback,
754  ) -> FunctionBuilder<'s, Self> {
755    FunctionBuilder::new_raw(callback)
756  }
757
758  /// Creates a function template.
759  #[inline(always)]
760  pub fn new<'s>(
761    scope: &PinScope<'s, '_, ()>,
762    callback: impl MapFnTo<FunctionCallback>,
763  ) -> Local<'s, FunctionTemplate> {
764    Self::builder(callback).build(scope)
765  }
766
767  #[inline(always)]
768  pub fn new_raw<'s>(
769    scope: &PinScope<'s, '_, ()>,
770    callback: FunctionCallback,
771  ) -> Local<'s, FunctionTemplate> {
772    Self::builder_raw(callback).build(scope)
773  }
774
775  /// Returns the unique function instance in the current execution context.
776  #[inline(always)]
777  pub fn get_function<'s>(
778    &self,
779    scope: &PinScope<'s, '_>,
780  ) -> Option<Local<'s, Function>> {
781    unsafe {
782      scope.cast_local(|sd| {
783        v8__FunctionTemplate__GetFunction(self, sd.get_current_context())
784      })
785    }
786  }
787
788  /// Set the class name of the FunctionTemplate. This is used for
789  /// printing objects created with the function created from the
790  /// FunctionTemplate as its constructor.
791  #[inline(always)]
792  pub fn set_class_name(&self, name: Local<String>) {
793    unsafe { v8__FunctionTemplate__SetClassName(self, &*name) };
794  }
795
796  /// Returns the ObjectTemplate that is used by this
797  /// FunctionTemplate as a PrototypeTemplate
798  #[inline(always)]
799  pub fn prototype_template<'s>(
800    &self,
801    scope: &PinScope<'s, '_, ()>,
802  ) -> Local<'s, ObjectTemplate> {
803    unsafe {
804      scope.cast_local(|_sd| v8__FunctionTemplate__PrototypeTemplate(self))
805    }
806    .unwrap()
807  }
808
809  /// Returns the object template that is used for instances created when this function
810  /// template is called as a constructor.
811  #[inline(always)]
812  pub fn instance_template<'s>(
813    &self,
814    scope: &PinScope<'s, '_, ()>,
815  ) -> Local<'s, ObjectTemplate> {
816    unsafe {
817      scope.cast_local(|_sd| v8__FunctionTemplate__InstanceTemplate(self))
818    }
819    .unwrap()
820  }
821
822  /// Causes the function template to inherit from a parent function template.
823  /// This means the function's prototype.__proto__ is set to the parent function's prototype.
824  #[inline(always)]
825  pub fn inherit(&self, parent: Local<FunctionTemplate>) {
826    unsafe { v8__FunctionTemplate__Inherit(self, &*parent) };
827  }
828
829  /// Sets the ReadOnly flag in the attributes of the 'prototype' property
830  /// of functions created from this FunctionTemplate to true.
831  #[inline(always)]
832  pub fn read_only_prototype(&self) {
833    unsafe { v8__FunctionTemplate__ReadOnlyPrototype(self) };
834  }
835
836  /// Removes the prototype property from functions created from this FunctionTemplate.
837  #[inline(always)]
838  pub fn remove_prototype(&self) {
839    unsafe { v8__FunctionTemplate__RemovePrototype(self) };
840  }
841}
842
843impl ObjectTemplate {
844  /// Creates an object template.
845  #[inline(always)]
846  pub fn new<'s>(scope: &PinScope<'s, '_, ()>) -> Local<'s, ObjectTemplate> {
847    unsafe {
848      scope.cast_local(|sd| {
849        v8__ObjectTemplate__New(sd.get_isolate_ptr(), std::ptr::null())
850      })
851    }
852    .unwrap()
853  }
854
855  /// Creates an object template from a function template.
856  #[inline(always)]
857  pub fn new_from_template<'s>(
858    scope: &PinScope<'s, '_, ()>,
859    templ: Local<FunctionTemplate>,
860  ) -> Local<'s, ObjectTemplate> {
861    unsafe {
862      scope
863        .cast_local(|sd| v8__ObjectTemplate__New(sd.get_isolate_ptr(), &*templ))
864    }
865    .unwrap()
866  }
867
868  /// Creates a new instance of this object template.
869  #[inline(always)]
870  pub fn new_instance<'s>(
871    &self,
872    scope: &PinScope<'s, '_>,
873  ) -> Option<Local<'s, Object>> {
874    unsafe {
875      scope.cast_local(|sd| {
876        v8__ObjectTemplate__NewInstance(self, sd.get_current_context())
877      })
878    }
879  }
880
881  /// Gets the number of internal fields for objects generated from
882  /// this template.
883  #[inline(always)]
884  pub fn internal_field_count(&self) -> usize {
885    let count = unsafe { v8__ObjectTemplate__InternalFieldCount(self) };
886    usize::try_from(count).expect("bad internal field count") // Can't happen.
887  }
888
889  /// Sets the number of internal fields for objects generated from
890  /// this template.
891  #[inline(always)]
892  pub fn set_internal_field_count(&self, value: usize) -> bool {
893    // The C++ API takes an i32 but trying to set a value < 0
894    // results in unpredictable behavior, hence we disallow it.
895    match int::try_from(value) {
896      Err(_) => false,
897      Ok(value) => {
898        unsafe { v8__ObjectTemplate__SetInternalFieldCount(self, value) };
899        true
900      }
901    }
902  }
903
904  #[inline(always)]
905  pub fn set_accessor(
906    &self,
907    key: Local<Name>,
908    getter: impl MapFnTo<AccessorNameGetterCallback>,
909  ) {
910    self
911      .set_accessor_with_configuration(key, AccessorConfiguration::new(getter));
912  }
913
914  #[inline(always)]
915  pub fn set_accessor_with_setter(
916    &self,
917    key: Local<Name>,
918    getter: impl MapFnTo<AccessorNameGetterCallback>,
919    setter: impl MapFnTo<AccessorNameSetterCallback>,
920  ) {
921    self.set_accessor_with_configuration(
922      key,
923      AccessorConfiguration::new(getter).setter(setter),
924    );
925  }
926
927  #[inline(always)]
928  pub fn set_accessor_with_configuration(
929    &self,
930    key: Local<Name>,
931    configuration: AccessorConfiguration,
932  ) {
933    unsafe {
934      v8__ObjectTemplate__SetNativeDataProperty(
935        self,
936        &*key,
937        configuration.getter,
938        configuration.setter,
939        configuration.data.map_or_else(null, |p| &*p),
940        configuration.property_attribute,
941      );
942    }
943  }
944
945  //Re uses the AccessorNameGetterCallback to avoid implementation conflicts since the declaration for
946  //GenericNamedPropertyGetterCallback and  AccessorNameGetterCallback are the same
947  pub fn set_named_property_handler(
948    &self,
949    configuration: NamedPropertyHandlerConfiguration,
950  ) {
951    assert!(configuration.is_some());
952    unsafe {
953      v8__ObjectTemplate__SetNamedPropertyHandler(
954        self,
955        configuration.getter,
956        configuration.setter,
957        configuration.query,
958        configuration.deleter,
959        configuration.enumerator,
960        configuration.definer,
961        configuration.descriptor,
962        configuration.data.map_or_else(null, |p| &*p),
963        configuration.flags,
964      );
965    }
966  }
967
968  pub fn set_indexed_property_handler(
969    &self,
970    configuration: IndexedPropertyHandlerConfiguration,
971  ) {
972    assert!(configuration.is_some());
973    unsafe {
974      v8__ObjectTemplate__SetIndexedPropertyHandler(
975        self,
976        configuration.getter,
977        configuration.setter,
978        configuration.query,
979        configuration.deleter,
980        configuration.enumerator,
981        configuration.definer,
982        configuration.descriptor,
983        configuration.data.map_or_else(null, |p| &*p),
984      );
985    }
986  }
987
988  /// Sets an [accessor property](https://tc39.es/ecma262/#sec-property-attributes)
989  /// on the object template.
990  ///
991  /// # Panics
992  ///
993  /// Panics if both `getter` and `setter` are `None`.
994  #[inline(always)]
995  pub fn set_accessor_property(
996    &self,
997    key: Local<Name>,
998    getter: Option<Local<FunctionTemplate>>,
999    setter: Option<Local<FunctionTemplate>>,
1000    attr: PropertyAttribute,
1001  ) {
1002    assert!(getter.is_some() || setter.is_some());
1003
1004    unsafe {
1005      let getter = getter.map_or_else(std::ptr::null, |v| &*v);
1006      let setter = setter.map_or_else(std::ptr::null, |v| &*v);
1007      v8__ObjectTemplate__SetAccessorProperty(
1008        self, &*key, getter, setter, attr,
1009      );
1010    }
1011  }
1012
1013  /// Makes the ObjectTemplate for an immutable prototype exotic object,
1014  /// with an immutable proto.
1015  #[inline(always)]
1016  pub fn set_immutable_proto(&self) {
1017    unsafe { v8__ObjectTemplate__SetImmutableProto(self) };
1018  }
1019}