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