1 // Copyright 2021 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #ifndef INCLUDE_V8_TEMPLATE_H_
6 #define INCLUDE_V8_TEMPLATE_H_
7 
8 #include "v8-data.h"               // NOLINT(build/include_directory)
9 #include "v8-function-callback.h"  // NOLINT(build/include_directory)
10 #include "v8-local-handle.h"       // NOLINT(build/include_directory)
11 #include "v8-memory-span.h"        // NOLINT(build/include_directory)
12 #include "v8-object.h"             // NOLINT(build/include_directory)
13 #include "v8config.h"              // NOLINT(build/include_directory)
14 
15 namespace v8 {
16 
17 class AccessorSignature;
18 class CFunction;
19 class FunctionTemplate;
20 class ObjectTemplate;
21 class Signature;
22 
23 // --- Templates ---
24 
25 #define V8_INTRINSICS_LIST(F)                                 \
26   F(ArrayProto_entries, array_entries_iterator)               \
27   F(ArrayProto_forEach, array_for_each_iterator)              \
28   F(ArrayProto_keys, array_keys_iterator)                     \
29   F(ArrayProto_values, array_values_iterator)                 \
30   F(ArrayPrototype, initial_array_prototype)                  \
31   F(AsyncIteratorPrototype, initial_async_iterator_prototype) \
32   F(ErrorPrototype, initial_error_prototype)                  \
33   F(IteratorPrototype, initial_iterator_prototype)            \
34   F(ObjProto_valueOf, object_value_of_function)
35 
36 enum Intrinsic {
37 #define V8_DECL_INTRINSIC(name, iname) k##name,
38   V8_INTRINSICS_LIST(V8_DECL_INTRINSIC)
39 #undef V8_DECL_INTRINSIC
40 };
41 
42 /**
43  * The superclass of object and function templates.
44  */
45 class V8_EXPORT Template : public Data {
46  public:
47   /**
48    * Adds a property to each instance created by this template.
49    *
50    * The property must be defined either as a primitive value, or a template.
51    */
52   void Set(Local<Name> name, Local<Data> value,
53            PropertyAttribute attributes = None);
54   void SetPrivate(Local<Private> name, Local<Data> value,
55                   PropertyAttribute attributes = None);
56   V8_INLINE void Set(Isolate* isolate, const char* name, Local<Data> value,
57                      PropertyAttribute attributes = None);
58 
59   void SetAccessorProperty(
60       Local<Name> name,
61       Local<FunctionTemplate> getter = Local<FunctionTemplate>(),
62       Local<FunctionTemplate> setter = Local<FunctionTemplate>(),
63       PropertyAttribute attribute = None, AccessControl settings = DEFAULT);
64 
65   /**
66    * Whenever the property with the given name is accessed on objects
67    * created from this Template the getter and setter callbacks
68    * are called instead of getting and setting the property directly
69    * on the JavaScript object.
70    *
71    * \param name The name of the property for which an accessor is added.
72    * \param getter The callback to invoke when getting the property.
73    * \param setter The callback to invoke when setting the property.
74    * \param data A piece of data that will be passed to the getter and setter
75    *   callbacks whenever they are invoked.
76    * \param settings Access control settings for the accessor. This is a bit
77    *   field consisting of one of more of
78    *   DEFAULT = 0, ALL_CAN_READ = 1, or ALL_CAN_WRITE = 2.
79    *   The default is to not allow cross-context access.
80    *   ALL_CAN_READ means that all cross-context reads are allowed.
81    *   ALL_CAN_WRITE means that all cross-context writes are allowed.
82    *   The combination ALL_CAN_READ | ALL_CAN_WRITE can be used to allow all
83    *   cross-context access.
84    * \param attribute The attributes of the property for which an accessor
85    *   is added.
86    * \param signature The signature describes valid receivers for the accessor
87    *   and is used to perform implicit instance checks against them. If the
88    *   receiver is incompatible (i.e. is not an instance of the constructor as
89    *   defined by FunctionTemplate::HasInstance()), an implicit TypeError is
90    *   thrown and no callback is invoked.
91    */
92   void SetNativeDataProperty(
93       Local<String> name, AccessorGetterCallback getter,
94       AccessorSetterCallback setter = nullptr,
95       Local<Value> data = Local<Value>(), PropertyAttribute attribute = None,
96       Local<AccessorSignature> signature = Local<AccessorSignature>(),
97       AccessControl settings = DEFAULT,
98       SideEffectType getter_side_effect_type = SideEffectType::kHasSideEffect,
99       SideEffectType setter_side_effect_type = SideEffectType::kHasSideEffect);
100   void SetNativeDataProperty(
101       Local<Name> name, AccessorNameGetterCallback getter,
102       AccessorNameSetterCallback setter = nullptr,
103       Local<Value> data = Local<Value>(), PropertyAttribute attribute = None,
104       Local<AccessorSignature> signature = Local<AccessorSignature>(),
105       AccessControl settings = DEFAULT,
106       SideEffectType getter_side_effect_type = SideEffectType::kHasSideEffect,
107       SideEffectType setter_side_effect_type = SideEffectType::kHasSideEffect);
108 
109   /**
110    * Like SetNativeDataProperty, but V8 will replace the native data property
111    * with a real data property on first access.
112    */
113   void SetLazyDataProperty(
114       Local<Name> name, AccessorNameGetterCallback getter,
115       Local<Value> data = Local<Value>(), PropertyAttribute attribute = None,
116       SideEffectType getter_side_effect_type = SideEffectType::kHasSideEffect,
117       SideEffectType setter_side_effect_type = SideEffectType::kHasSideEffect);
118 
119   /**
120    * During template instantiation, sets the value with the intrinsic property
121    * from the correct context.
122    */
123   void SetIntrinsicDataProperty(Local<Name> name, Intrinsic intrinsic,
124                                 PropertyAttribute attribute = None);
125 
126  private:
127   Template();
128 
129   friend class ObjectTemplate;
130   friend class FunctionTemplate;
131 };
132 
133 // TODO(dcarney): Replace GenericNamedPropertyFooCallback with just
134 // NamedPropertyFooCallback.
135 
136 /**
137  * Interceptor for get requests on an object.
138  *
139  * Use `info.GetReturnValue().Set()` to set the return value of the
140  * intercepted get request.
141  *
142  * \param property The name of the property for which the request was
143  * intercepted.
144  * \param info Information about the intercepted request, such as
145  * isolate, receiver, return value, or whether running in `'use strict`' mode.
146  * See `PropertyCallbackInfo`.
147  *
148  * \code
149  *  void GetterCallback(
150  *    Local<Name> name,
151  *    const v8::PropertyCallbackInfo<v8::Value>& info) {
152  *      info.GetReturnValue().Set(v8_num(42));
153  *  }
154  *
155  *  v8::Local<v8::FunctionTemplate> templ =
156  *      v8::FunctionTemplate::New(isolate);
157  *  templ->InstanceTemplate()->SetHandler(
158  *      v8::NamedPropertyHandlerConfiguration(GetterCallback));
159  *  LocalContext env;
160  *  env->Global()
161  *      ->Set(env.local(), v8_str("obj"), templ->GetFunction(env.local())
162  *                                             .ToLocalChecked()
163  *                                             ->NewInstance(env.local())
164  *                                             .ToLocalChecked())
165  *      .FromJust();
166  *  v8::Local<v8::Value> result = CompileRun("obj.a = 17; obj.a");
167  *  CHECK(v8_num(42)->Equals(env.local(), result).FromJust());
168  * \endcode
169  *
170  * See also `ObjectTemplate::SetHandler`.
171  */
172 using GenericNamedPropertyGetterCallback =
173     void (*)(Local<Name> property, const PropertyCallbackInfo<Value>& info);
174 
175 /**
176  * Interceptor for set requests on an object.
177  *
178  * Use `info.GetReturnValue()` to indicate whether the request was intercepted
179  * or not. If the setter successfully intercepts the request, i.e., if the
180  * request should not be further executed, call
181  * `info.GetReturnValue().Set(value)`. If the setter
182  * did not intercept the request, i.e., if the request should be handled as
183  * if no interceptor is present, do not not call `Set()`.
184  *
185  * \param property The name of the property for which the request was
186  * intercepted.
187  * \param value The value which the property will have if the request
188  * is not intercepted.
189  * \param info Information about the intercepted request, such as
190  * isolate, receiver, return value, or whether running in `'use strict'` mode.
191  * See `PropertyCallbackInfo`.
192  *
193  * See also
194  * `ObjectTemplate::SetHandler.`
195  */
196 using GenericNamedPropertySetterCallback =
197     void (*)(Local<Name> property, Local<Value> value,
198              const PropertyCallbackInfo<Value>& info);
199 
200 /**
201  * Intercepts all requests that query the attributes of the
202  * property, e.g., getOwnPropertyDescriptor(), propertyIsEnumerable(), and
203  * defineProperty().
204  *
205  * Use `info.GetReturnValue().Set(value)` to set the property attributes. The
206  * value is an integer encoding a `v8::PropertyAttribute`.
207  *
208  * \param property The name of the property for which the request was
209  * intercepted.
210  * \param info Information about the intercepted request, such as
211  * isolate, receiver, return value, or whether running in `'use strict'` mode.
212  * See `PropertyCallbackInfo`.
213  *
214  * \note Some functions query the property attributes internally, even though
215  * they do not return the attributes. For example, `hasOwnProperty()` can
216  * trigger this interceptor depending on the state of the object.
217  *
218  * See also
219  * `ObjectTemplate::SetHandler.`
220  */
221 using GenericNamedPropertyQueryCallback =
222     void (*)(Local<Name> property, const PropertyCallbackInfo<Integer>& info);
223 
224 /**
225  * Interceptor for delete requests on an object.
226  *
227  * Use `info.GetReturnValue()` to indicate whether the request was intercepted
228  * or not. If the deleter successfully intercepts the request, i.e., if the
229  * request should not be further executed, call
230  * `info.GetReturnValue().Set(value)` with a boolean `value`. The `value` is
231  * used as the return value of `delete`.
232  *
233  * \param property The name of the property for which the request was
234  * intercepted.
235  * \param info Information about the intercepted request, such as
236  * isolate, receiver, return value, or whether running in `'use strict'` mode.
237  * See `PropertyCallbackInfo`.
238  *
239  * \note If you need to mimic the behavior of `delete`, i.e., throw in strict
240  * mode instead of returning false, use `info.ShouldThrowOnError()` to determine
241  * if you are in strict mode.
242  *
243  * See also `ObjectTemplate::SetHandler.`
244  */
245 using GenericNamedPropertyDeleterCallback =
246     void (*)(Local<Name> property, const PropertyCallbackInfo<Boolean>& info);
247 
248 /**
249  * Returns an array containing the names of the properties the named
250  * property getter intercepts.
251  *
252  * Note: The values in the array must be of type v8::Name.
253  */
254 using GenericNamedPropertyEnumeratorCallback =
255     void (*)(const PropertyCallbackInfo<Array>& info);
256 
257 /**
258  * Interceptor for defineProperty requests on an object.
259  *
260  * Use `info.GetReturnValue()` to indicate whether the request was intercepted
261  * or not. If the definer successfully intercepts the request, i.e., if the
262  * request should not be further executed, call
263  * `info.GetReturnValue().Set(value)`. If the definer
264  * did not intercept the request, i.e., if the request should be handled as
265  * if no interceptor is present, do not not call `Set()`.
266  *
267  * \param property The name of the property for which the request was
268  * intercepted.
269  * \param desc The property descriptor which is used to define the
270  * property if the request is not intercepted.
271  * \param info Information about the intercepted request, such as
272  * isolate, receiver, return value, or whether running in `'use strict'` mode.
273  * See `PropertyCallbackInfo`.
274  *
275  * See also `ObjectTemplate::SetHandler`.
276  */
277 using GenericNamedPropertyDefinerCallback =
278     void (*)(Local<Name> property, const PropertyDescriptor& desc,
279              const PropertyCallbackInfo<Value>& info);
280 
281 /**
282  * Interceptor for getOwnPropertyDescriptor requests on an object.
283  *
284  * Use `info.GetReturnValue().Set()` to set the return value of the
285  * intercepted request. The return value must be an object that
286  * can be converted to a PropertyDescriptor, e.g., a `v8::value` returned from
287  * `v8::Object::getOwnPropertyDescriptor`.
288  *
289  * \param property The name of the property for which the request was
290  * intercepted.
291  * \info Information about the intercepted request, such as
292  * isolate, receiver, return value, or whether running in `'use strict'` mode.
293  * See `PropertyCallbackInfo`.
294  *
295  * \note If GetOwnPropertyDescriptor is intercepted, it will
296  * always return true, i.e., indicate that the property was found.
297  *
298  * See also `ObjectTemplate::SetHandler`.
299  */
300 using GenericNamedPropertyDescriptorCallback =
301     void (*)(Local<Name> property, const PropertyCallbackInfo<Value>& info);
302 
303 /**
304  * See `v8::GenericNamedPropertyGetterCallback`.
305  */
306 using IndexedPropertyGetterCallback =
307     void (*)(uint32_t index, const PropertyCallbackInfo<Value>& info);
308 
309 /**
310  * See `v8::GenericNamedPropertySetterCallback`.
311  */
312 using IndexedPropertySetterCallback =
313     void (*)(uint32_t index, Local<Value> value,
314              const PropertyCallbackInfo<Value>& info);
315 
316 /**
317  * See `v8::GenericNamedPropertyQueryCallback`.
318  */
319 using IndexedPropertyQueryCallback =
320     void (*)(uint32_t index, const PropertyCallbackInfo<Integer>& info);
321 
322 /**
323  * See `v8::GenericNamedPropertyDeleterCallback`.
324  */
325 using IndexedPropertyDeleterCallback =
326     void (*)(uint32_t index, const PropertyCallbackInfo<Boolean>& info);
327 
328 /**
329  * Returns an array containing the indices of the properties the indexed
330  * property getter intercepts.
331  *
332  * Note: The values in the array must be uint32_t.
333  */
334 using IndexedPropertyEnumeratorCallback =
335     void (*)(const PropertyCallbackInfo<Array>& info);
336 
337 /**
338  * See `v8::GenericNamedPropertyDefinerCallback`.
339  */
340 using IndexedPropertyDefinerCallback =
341     void (*)(uint32_t index, const PropertyDescriptor& desc,
342              const PropertyCallbackInfo<Value>& info);
343 
344 /**
345  * See `v8::GenericNamedPropertyDescriptorCallback`.
346  */
347 using IndexedPropertyDescriptorCallback =
348     void (*)(uint32_t index, const PropertyCallbackInfo<Value>& info);
349 
350 /**
351  * Returns true if the given context should be allowed to access the given
352  * object.
353  */
354 using AccessCheckCallback = bool (*)(Local<Context> accessing_context,
355                                      Local<Object> accessed_object,
356                                      Local<Value> data);
357 
358 enum class ConstructorBehavior { kThrow, kAllow };
359 
360 /**
361  * A FunctionTemplate is used to create functions at runtime. There
362  * can only be one function created from a FunctionTemplate in a
363  * context.  The lifetime of the created function is equal to the
364  * lifetime of the context.  So in case the embedder needs to create
365  * temporary functions that can be collected using Scripts is
366  * preferred.
367  *
368  * Any modification of a FunctionTemplate after first instantiation will trigger
369  * a crash.
370  *
371  * A FunctionTemplate can have properties, these properties are added to the
372  * function object when it is created.
373  *
374  * A FunctionTemplate has a corresponding instance template which is
375  * used to create object instances when the function is used as a
376  * constructor. Properties added to the instance template are added to
377  * each object instance.
378  *
379  * A FunctionTemplate can have a prototype template. The prototype template
380  * is used to create the prototype object of the function.
381  *
382  * The following example shows how to use a FunctionTemplate:
383  *
384  * \code
385  *    v8::Local<v8::FunctionTemplate> t = v8::FunctionTemplate::New(isolate);
386  *    t->Set(isolate, "func_property", v8::Number::New(isolate, 1));
387  *
388  *    v8::Local<v8::Template> proto_t = t->PrototypeTemplate();
389  *    proto_t->Set(isolate,
390  *                 "proto_method",
391  *                 v8::FunctionTemplate::New(isolate, InvokeCallback));
392  *    proto_t->Set(isolate, "proto_const", v8::Number::New(isolate, 2));
393  *
394  *    v8::Local<v8::ObjectTemplate> instance_t = t->InstanceTemplate();
395  *    instance_t->SetAccessor(
396           String::NewFromUtf8Literal(isolate, "instance_accessor"),
397  *        InstanceAccessorCallback);
398  *    instance_t->SetHandler(
399  *        NamedPropertyHandlerConfiguration(PropertyHandlerCallback));
400  *    instance_t->Set(String::NewFromUtf8Literal(isolate, "instance_property"),
401  *                    Number::New(isolate, 3));
402  *
403  *    v8::Local<v8::Function> function = t->GetFunction();
404  *    v8::Local<v8::Object> instance = function->NewInstance();
405  * \endcode
406  *
407  * Let's use "function" as the JS variable name of the function object
408  * and "instance" for the instance object created above.  The function
409  * and the instance will have the following properties:
410  *
411  * \code
412  *   func_property in function == true;
413  *   function.func_property == 1;
414  *
415  *   function.prototype.proto_method() invokes 'InvokeCallback'
416  *   function.prototype.proto_const == 2;
417  *
418  *   instance instanceof function == true;
419  *   instance.instance_accessor calls 'InstanceAccessorCallback'
420  *   instance.instance_property == 3;
421  * \endcode
422  *
423  * A FunctionTemplate can inherit from another one by calling the
424  * FunctionTemplate::Inherit method.  The following graph illustrates
425  * the semantics of inheritance:
426  *
427  * \code
428  *   FunctionTemplate Parent  -> Parent() . prototype -> { }
429  *     ^                                                  ^
430  *     | Inherit(Parent)                                  | .__proto__
431  *     |                                                  |
432  *   FunctionTemplate Child   -> Child()  . prototype -> { }
433  * \endcode
434  *
435  * A FunctionTemplate 'Child' inherits from 'Parent', the prototype
436  * object of the Child() function has __proto__ pointing to the
437  * Parent() function's prototype object. An instance of the Child
438  * function has all properties on Parent's instance templates.
439  *
440  * Let Parent be the FunctionTemplate initialized in the previous
441  * section and create a Child FunctionTemplate by:
442  *
443  * \code
444  *   Local<FunctionTemplate> parent = t;
445  *   Local<FunctionTemplate> child = FunctionTemplate::New();
446  *   child->Inherit(parent);
447  *
448  *   Local<Function> child_function = child->GetFunction();
449  *   Local<Object> child_instance = child_function->NewInstance();
450  * \endcode
451  *
452  * The Child function and Child instance will have the following
453  * properties:
454  *
455  * \code
456  *   child_func.prototype.__proto__ == function.prototype;
457  *   child_instance.instance_accessor calls 'InstanceAccessorCallback'
458  *   child_instance.instance_property == 3;
459  * \endcode
460  *
461  * The additional 'c_function' parameter refers to a fast API call, which
462  * must not trigger GC or JavaScript execution, or call into V8 in other
463  * ways. For more information how to define them, see
464  * include/v8-fast-api-calls.h. Please note that this feature is still
465  * experimental.
466  */
467 class V8_EXPORT FunctionTemplate : public Template {
468  public:
469   /** Creates a function template.*/
470   static Local<FunctionTemplate> New(
471       Isolate* isolate, FunctionCallback callback = nullptr,
472       Local<Value> data = Local<Value>(),
473       Local<Signature> signature = Local<Signature>(), int length = 0,
474       ConstructorBehavior behavior = ConstructorBehavior::kAllow,
475       SideEffectType side_effect_type = SideEffectType::kHasSideEffect,
476       const CFunction* c_function = nullptr, uint16_t instance_type = 0,
477       uint16_t allowed_receiver_instance_type_range_start = 0,
478       uint16_t allowed_receiver_instance_type_range_end = 0);
479 
480   /** Creates a function template for multiple overloaded fast API calls.*/
481   static Local<FunctionTemplate> NewWithCFunctionOverloads(
482       Isolate* isolate, FunctionCallback callback = nullptr,
483       Local<Value> data = Local<Value>(),
484       Local<Signature> signature = Local<Signature>(), int length = 0,
485       ConstructorBehavior behavior = ConstructorBehavior::kAllow,
486       SideEffectType side_effect_type = SideEffectType::kHasSideEffect,
487       const MemorySpan<const CFunction>& c_function_overloads = {});
488 
489   /**
490    * Creates a function template backed/cached by a private property.
491    */
492   static Local<FunctionTemplate> NewWithCache(
493       Isolate* isolate, FunctionCallback callback,
494       Local<Private> cache_property, Local<Value> data = Local<Value>(),
495       Local<Signature> signature = Local<Signature>(), int length = 0,
496       SideEffectType side_effect_type = SideEffectType::kHasSideEffect);
497 
498   /** Returns the unique function instance in the current execution context.*/
499   V8_WARN_UNUSED_RESULT MaybeLocal<Function> GetFunction(
500       Local<Context> context);
501 
502   /**
503    * Similar to Context::NewRemoteContext, this creates an instance that
504    * isn't backed by an actual object.
505    *
506    * The InstanceTemplate of this FunctionTemplate must have access checks with
507    * handlers installed.
508    */
509   V8_WARN_UNUSED_RESULT MaybeLocal<Object> NewRemoteInstance();
510 
511   /**
512    * Set the call-handler callback for a FunctionTemplate.  This
513    * callback is called whenever the function created from this
514    * FunctionTemplate is called. The 'c_function' represents a fast
515    * API call, see the comment above the class declaration.
516    */
517   void SetCallHandler(
518       FunctionCallback callback, Local<Value> data = Local<Value>(),
519       SideEffectType side_effect_type = SideEffectType::kHasSideEffect,
520       const MemorySpan<const CFunction>& c_function_overloads = {});
521 
522   /** Set the predefined length property for the FunctionTemplate. */
523   void SetLength(int length);
524 
525   /** Get the InstanceTemplate. */
526   Local<ObjectTemplate> InstanceTemplate();
527 
528   /**
529    * Causes the function template to inherit from a parent function template.
530    * This means the function's prototype.__proto__ is set to the parent
531    * function's prototype.
532    **/
533   void Inherit(Local<FunctionTemplate> parent);
534 
535   /**
536    * A PrototypeTemplate is the template used to create the prototype object
537    * of the function created by this template.
538    */
539   Local<ObjectTemplate> PrototypeTemplate();
540 
541   /**
542    * A PrototypeProviderTemplate is another function template whose prototype
543    * property is used for this template. This is mutually exclusive with setting
544    * a prototype template indirectly by calling PrototypeTemplate() or using
545    * Inherit().
546    **/
547   void SetPrototypeProviderTemplate(Local<FunctionTemplate> prototype_provider);
548 
549   /**
550    * Set the class name of the FunctionTemplate.  This is used for
551    * printing objects created with the function created from the
552    * FunctionTemplate as its constructor.
553    */
554   void SetClassName(Local<String> name);
555 
556   /**
557    * When set to true, no access check will be performed on the receiver of a
558    * function call.  Currently defaults to true, but this is subject to change.
559    */
560   void SetAcceptAnyReceiver(bool value);
561 
562   /**
563    * Sets the ReadOnly flag in the attributes of the 'prototype' property
564    * of functions created from this FunctionTemplate to true.
565    */
566   void ReadOnlyPrototype();
567 
568   /**
569    * Removes the prototype property from functions created from this
570    * FunctionTemplate.
571    */
572   void RemovePrototype();
573 
574   /**
575    * Returns true if the given object is an instance of this function
576    * template.
577    */
578   bool HasInstance(Local<Value> object);
579 
580   /**
581    * Returns true if the given value is an API object that was constructed by an
582    * instance of this function template (without checking for inheriting
583    * function templates).
584    *
585    * This is an experimental feature and may still change significantly.
586    */
587   bool IsLeafTemplateForApiObject(v8::Local<v8::Value> value) const;
588 
589   V8_INLINE static FunctionTemplate* Cast(Data* data);
590 
591  private:
592   FunctionTemplate();
593 
594   static void CheckCast(Data* that);
595   friend class Context;
596   friend class ObjectTemplate;
597 };
598 
599 /**
600  * Configuration flags for v8::NamedPropertyHandlerConfiguration or
601  * v8::IndexedPropertyHandlerConfiguration.
602  */
603 enum class PropertyHandlerFlags {
604   /**
605    * None.
606    */
607   kNone = 0,
608 
609   /**
610    * See ALL_CAN_READ above.
611    */
612   kAllCanRead = 1,
613 
614   /** Will not call into interceptor for properties on the receiver or prototype
615    * chain, i.e., only call into interceptor for properties that do not exist.
616    * Currently only valid for named interceptors.
617    */
618   kNonMasking = 1 << 1,
619 
620   /**
621    * Will not call into interceptor for symbol lookup.  Only meaningful for
622    * named interceptors.
623    */
624   kOnlyInterceptStrings = 1 << 2,
625 
626   /**
627    * The getter, query, enumerator callbacks do not produce side effects.
628    */
629   kHasNoSideEffect = 1 << 3,
630 };
631 
632 struct NamedPropertyHandlerConfiguration {
633   NamedPropertyHandlerConfiguration(
634       GenericNamedPropertyGetterCallback getter,
635       GenericNamedPropertySetterCallback setter,
636       GenericNamedPropertyQueryCallback query,
637       GenericNamedPropertyDeleterCallback deleter,
638       GenericNamedPropertyEnumeratorCallback enumerator,
639       GenericNamedPropertyDefinerCallback definer,
640       GenericNamedPropertyDescriptorCallback descriptor,
641       Local<Value> data = Local<Value>(),
642       PropertyHandlerFlags flags = PropertyHandlerFlags::kNone)
getterNamedPropertyHandlerConfiguration643       : getter(getter),
644         setter(setter),
645         query(query),
646         deleter(deleter),
647         enumerator(enumerator),
648         definer(definer),
649         descriptor(descriptor),
650         data(data),
651         flags(flags) {}
652 
653   NamedPropertyHandlerConfiguration(
654       /** Note: getter is required */
655       GenericNamedPropertyGetterCallback getter = nullptr,
656       GenericNamedPropertySetterCallback setter = nullptr,
657       GenericNamedPropertyQueryCallback query = nullptr,
658       GenericNamedPropertyDeleterCallback deleter = nullptr,
659       GenericNamedPropertyEnumeratorCallback enumerator = nullptr,
660       Local<Value> data = Local<Value>(),
661       PropertyHandlerFlags flags = PropertyHandlerFlags::kNone)
getterNamedPropertyHandlerConfiguration662       : getter(getter),
663         setter(setter),
664         query(query),
665         deleter(deleter),
666         enumerator(enumerator),
667         definer(nullptr),
668         descriptor(nullptr),
669         data(data),
670         flags(flags) {}
671 
672   NamedPropertyHandlerConfiguration(
673       GenericNamedPropertyGetterCallback getter,
674       GenericNamedPropertySetterCallback setter,
675       GenericNamedPropertyDescriptorCallback descriptor,
676       GenericNamedPropertyDeleterCallback deleter,
677       GenericNamedPropertyEnumeratorCallback enumerator,
678       GenericNamedPropertyDefinerCallback definer,
679       Local<Value> data = Local<Value>(),
680       PropertyHandlerFlags flags = PropertyHandlerFlags::kNone)
getterNamedPropertyHandlerConfiguration681       : getter(getter),
682         setter(setter),
683         query(nullptr),
684         deleter(deleter),
685         enumerator(enumerator),
686         definer(definer),
687         descriptor(descriptor),
688         data(data),
689         flags(flags) {}
690 
691   GenericNamedPropertyGetterCallback getter;
692   GenericNamedPropertySetterCallback setter;
693   GenericNamedPropertyQueryCallback query;
694   GenericNamedPropertyDeleterCallback deleter;
695   GenericNamedPropertyEnumeratorCallback enumerator;
696   GenericNamedPropertyDefinerCallback definer;
697   GenericNamedPropertyDescriptorCallback descriptor;
698   Local<Value> data;
699   PropertyHandlerFlags flags;
700 };
701 
702 struct IndexedPropertyHandlerConfiguration {
703   IndexedPropertyHandlerConfiguration(
704       IndexedPropertyGetterCallback getter,
705       IndexedPropertySetterCallback setter, IndexedPropertyQueryCallback query,
706       IndexedPropertyDeleterCallback deleter,
707       IndexedPropertyEnumeratorCallback enumerator,
708       IndexedPropertyDefinerCallback definer,
709       IndexedPropertyDescriptorCallback descriptor,
710       Local<Value> data = Local<Value>(),
711       PropertyHandlerFlags flags = PropertyHandlerFlags::kNone)
getterIndexedPropertyHandlerConfiguration712       : getter(getter),
713         setter(setter),
714         query(query),
715         deleter(deleter),
716         enumerator(enumerator),
717         definer(definer),
718         descriptor(descriptor),
719         data(data),
720         flags(flags) {}
721 
722   IndexedPropertyHandlerConfiguration(
723       /** Note: getter is required */
724       IndexedPropertyGetterCallback getter = nullptr,
725       IndexedPropertySetterCallback setter = nullptr,
726       IndexedPropertyQueryCallback query = nullptr,
727       IndexedPropertyDeleterCallback deleter = nullptr,
728       IndexedPropertyEnumeratorCallback enumerator = nullptr,
729       Local<Value> data = Local<Value>(),
730       PropertyHandlerFlags flags = PropertyHandlerFlags::kNone)
getterIndexedPropertyHandlerConfiguration731       : getter(getter),
732         setter(setter),
733         query(query),
734         deleter(deleter),
735         enumerator(enumerator),
736         definer(nullptr),
737         descriptor(nullptr),
738         data(data),
739         flags(flags) {}
740 
741   IndexedPropertyHandlerConfiguration(
742       IndexedPropertyGetterCallback getter,
743       IndexedPropertySetterCallback setter,
744       IndexedPropertyDescriptorCallback descriptor,
745       IndexedPropertyDeleterCallback deleter,
746       IndexedPropertyEnumeratorCallback enumerator,
747       IndexedPropertyDefinerCallback definer,
748       Local<Value> data = Local<Value>(),
749       PropertyHandlerFlags flags = PropertyHandlerFlags::kNone)
getterIndexedPropertyHandlerConfiguration750       : getter(getter),
751         setter(setter),
752         query(nullptr),
753         deleter(deleter),
754         enumerator(enumerator),
755         definer(definer),
756         descriptor(descriptor),
757         data(data),
758         flags(flags) {}
759 
760   IndexedPropertyGetterCallback getter;
761   IndexedPropertySetterCallback setter;
762   IndexedPropertyQueryCallback query;
763   IndexedPropertyDeleterCallback deleter;
764   IndexedPropertyEnumeratorCallback enumerator;
765   IndexedPropertyDefinerCallback definer;
766   IndexedPropertyDescriptorCallback descriptor;
767   Local<Value> data;
768   PropertyHandlerFlags flags;
769 };
770 
771 /**
772  * An ObjectTemplate is used to create objects at runtime.
773  *
774  * Properties added to an ObjectTemplate are added to each object
775  * created from the ObjectTemplate.
776  */
777 class V8_EXPORT ObjectTemplate : public Template {
778  public:
779   /** Creates an ObjectTemplate. */
780   static Local<ObjectTemplate> New(
781       Isolate* isolate,
782       Local<FunctionTemplate> constructor = Local<FunctionTemplate>());
783 
784   /** Creates a new instance of this template.*/
785   V8_WARN_UNUSED_RESULT MaybeLocal<Object> NewInstance(Local<Context> context);
786 
787   /**
788    * Sets an accessor on the object template.
789    *
790    * Whenever the property with the given name is accessed on objects
791    * created from this ObjectTemplate the getter and setter callbacks
792    * are called instead of getting and setting the property directly
793    * on the JavaScript object.
794    *
795    * \param name The name of the property for which an accessor is added.
796    * \param getter The callback to invoke when getting the property.
797    * \param setter The callback to invoke when setting the property.
798    * \param data A piece of data that will be passed to the getter and setter
799    *   callbacks whenever they are invoked.
800    * \param settings Access control settings for the accessor. This is a bit
801    *   field consisting of one of more of
802    *   DEFAULT = 0, ALL_CAN_READ = 1, or ALL_CAN_WRITE = 2.
803    *   The default is to not allow cross-context access.
804    *   ALL_CAN_READ means that all cross-context reads are allowed.
805    *   ALL_CAN_WRITE means that all cross-context writes are allowed.
806    *   The combination ALL_CAN_READ | ALL_CAN_WRITE can be used to allow all
807    *   cross-context access.
808    * \param attribute The attributes of the property for which an accessor
809    *   is added.
810    * \param signature The signature describes valid receivers for the accessor
811    *   and is used to perform implicit instance checks against them. If the
812    *   receiver is incompatible (i.e. is not an instance of the constructor as
813    *   defined by FunctionTemplate::HasInstance()), an implicit TypeError is
814    *   thrown and no callback is invoked.
815    */
816   void SetAccessor(
817       Local<String> name, AccessorGetterCallback getter,
818       AccessorSetterCallback setter = nullptr,
819       Local<Value> data = Local<Value>(), AccessControl settings = DEFAULT,
820       PropertyAttribute attribute = None,
821       Local<AccessorSignature> signature = Local<AccessorSignature>(),
822       SideEffectType getter_side_effect_type = SideEffectType::kHasSideEffect,
823       SideEffectType setter_side_effect_type = SideEffectType::kHasSideEffect);
824   void SetAccessor(
825       Local<Name> name, AccessorNameGetterCallback getter,
826       AccessorNameSetterCallback setter = nullptr,
827       Local<Value> data = Local<Value>(), AccessControl settings = DEFAULT,
828       PropertyAttribute attribute = None,
829       Local<AccessorSignature> signature = Local<AccessorSignature>(),
830       SideEffectType getter_side_effect_type = SideEffectType::kHasSideEffect,
831       SideEffectType setter_side_effect_type = SideEffectType::kHasSideEffect);
832 
833   /**
834    * Sets a named property handler on the object template.
835    *
836    * Whenever a property whose name is a string or a symbol is accessed on
837    * objects created from this object template, the provided callback is
838    * invoked instead of accessing the property directly on the JavaScript
839    * object.
840    *
841    * @param configuration The NamedPropertyHandlerConfiguration that defines the
842    * callbacks to invoke when accessing a property.
843    */
844   void SetHandler(const NamedPropertyHandlerConfiguration& configuration);
845 
846   /**
847    * Sets an indexed property handler on the object template.
848    *
849    * Whenever an indexed property is accessed on objects created from
850    * this object template, the provided callback is invoked instead of
851    * accessing the property directly on the JavaScript object.
852    *
853    * \param getter The callback to invoke when getting a property.
854    * \param setter The callback to invoke when setting a property.
855    * \param query The callback to invoke to check if an object has a property.
856    * \param deleter The callback to invoke when deleting a property.
857    * \param enumerator The callback to invoke to enumerate all the indexed
858    *   properties of an object.
859    * \param data A piece of data that will be passed to the callbacks
860    *   whenever they are invoked.
861    */
862   // TODO(dcarney): deprecate
863   void SetIndexedPropertyHandler(
864       IndexedPropertyGetterCallback getter,
865       IndexedPropertySetterCallback setter = nullptr,
866       IndexedPropertyQueryCallback query = nullptr,
867       IndexedPropertyDeleterCallback deleter = nullptr,
868       IndexedPropertyEnumeratorCallback enumerator = nullptr,
869       Local<Value> data = Local<Value>()) {
870     SetHandler(IndexedPropertyHandlerConfiguration(getter, setter, query,
871                                                    deleter, enumerator, data));
872   }
873 
874   /**
875    * Sets an indexed property handler on the object template.
876    *
877    * Whenever an indexed property is accessed on objects created from
878    * this object template, the provided callback is invoked instead of
879    * accessing the property directly on the JavaScript object.
880    *
881    * @param configuration The IndexedPropertyHandlerConfiguration that defines
882    * the callbacks to invoke when accessing a property.
883    */
884   void SetHandler(const IndexedPropertyHandlerConfiguration& configuration);
885 
886   /**
887    * Sets the callback to be used when calling instances created from
888    * this template as a function.  If no callback is set, instances
889    * behave like normal JavaScript objects that cannot be called as a
890    * function.
891    */
892   void SetCallAsFunctionHandler(FunctionCallback callback,
893                                 Local<Value> data = Local<Value>());
894 
895   /**
896    * Mark object instances of the template as undetectable.
897    *
898    * In many ways, undetectable objects behave as though they are not
899    * there.  They behave like 'undefined' in conditionals and when
900    * printed.  However, properties can be accessed and called as on
901    * normal objects.
902    */
903   void MarkAsUndetectable();
904 
905   /**
906    * Sets access check callback on the object template and enables access
907    * checks.
908    *
909    * When accessing properties on instances of this object template,
910    * the access check callback will be called to determine whether or
911    * not to allow cross-context access to the properties.
912    */
913   void SetAccessCheckCallback(AccessCheckCallback callback,
914                               Local<Value> data = Local<Value>());
915 
916   /**
917    * Like SetAccessCheckCallback but invokes an interceptor on failed access
918    * checks instead of looking up all-can-read properties. You can only use
919    * either this method or SetAccessCheckCallback, but not both at the same
920    * time.
921    */
922   void SetAccessCheckCallbackAndHandler(
923       AccessCheckCallback callback,
924       const NamedPropertyHandlerConfiguration& named_handler,
925       const IndexedPropertyHandlerConfiguration& indexed_handler,
926       Local<Value> data = Local<Value>());
927 
928   /**
929    * Gets the number of internal fields for objects generated from
930    * this template.
931    */
932   int InternalFieldCount() const;
933 
934   /**
935    * Sets the number of internal fields for objects generated from
936    * this template.
937    */
938   void SetInternalFieldCount(int value);
939 
940   /**
941    * Returns true if the object will be an immutable prototype exotic object.
942    */
943   bool IsImmutableProto() const;
944 
945   /**
946    * Makes the ObjectTemplate for an immutable prototype exotic object, with an
947    * immutable __proto__.
948    */
949   void SetImmutableProto();
950 
951   /**
952    * Support for TC39 "dynamic code brand checks" proposal.
953    *
954    * This API allows to mark (& query) objects as "code like", which causes
955    * them to be treated like Strings in the context of eval and function
956    * constructor.
957    *
958    * Reference: https://github.com/tc39/proposal-dynamic-code-brand-checks
959    */
960   void SetCodeLike();
961   bool IsCodeLike() const;
962 
963   V8_INLINE static ObjectTemplate* Cast(Data* data);
964 
965  private:
966   ObjectTemplate();
967   static Local<ObjectTemplate> New(internal::Isolate* isolate,
968                                    Local<FunctionTemplate> constructor);
969   static void CheckCast(Data* that);
970   friend class FunctionTemplate;
971 };
972 
973 /**
974  * A Signature specifies which receiver is valid for a function.
975  *
976  * A receiver matches a given signature if the receiver (or any of its
977  * hidden prototypes) was created from the signature's FunctionTemplate, or
978  * from a FunctionTemplate that inherits directly or indirectly from the
979  * signature's FunctionTemplate.
980  */
981 class V8_EXPORT Signature : public Data {
982  public:
983   static Local<Signature> New(
984       Isolate* isolate,
985       Local<FunctionTemplate> receiver = Local<FunctionTemplate>());
986 
987   V8_INLINE static Signature* Cast(Data* data);
988 
989  private:
990   Signature();
991 
992   static void CheckCast(Data* that);
993 };
994 
995 /**
996  * An AccessorSignature specifies which receivers are valid parameters
997  * to an accessor callback.
998  */
999 class V8_EXPORT AccessorSignature : public Data {
1000  public:
1001   static Local<AccessorSignature> New(
1002       Isolate* isolate,
1003       Local<FunctionTemplate> receiver = Local<FunctionTemplate>());
1004 
1005   V8_INLINE static AccessorSignature* Cast(Data* data);
1006 
1007  private:
1008   AccessorSignature();
1009 
1010   static void CheckCast(Data* that);
1011 };
1012 
1013 // --- Implementation ---
1014 
Set(Isolate * isolate,const char * name,Local<Data> value,PropertyAttribute attributes)1015 void Template::Set(Isolate* isolate, const char* name, Local<Data> value,
1016                    PropertyAttribute attributes) {
1017   Set(String::NewFromUtf8(isolate, name, NewStringType::kInternalized)
1018           .ToLocalChecked(),
1019       value, attributes);
1020 }
1021 
Cast(Data * data)1022 FunctionTemplate* FunctionTemplate::Cast(Data* data) {
1023 #ifdef V8_ENABLE_CHECKS
1024   CheckCast(data);
1025 #endif
1026   return reinterpret_cast<FunctionTemplate*>(data);
1027 }
1028 
Cast(Data * data)1029 ObjectTemplate* ObjectTemplate::Cast(Data* data) {
1030 #ifdef V8_ENABLE_CHECKS
1031   CheckCast(data);
1032 #endif
1033   return reinterpret_cast<ObjectTemplate*>(data);
1034 }
1035 
Cast(Data * data)1036 Signature* Signature::Cast(Data* data) {
1037 #ifdef V8_ENABLE_CHECKS
1038   CheckCast(data);
1039 #endif
1040   return reinterpret_cast<Signature*>(data);
1041 }
1042 
Cast(Data * data)1043 AccessorSignature* AccessorSignature::Cast(Data* data) {
1044 #ifdef V8_ENABLE_CHECKS
1045   CheckCast(data);
1046 #endif
1047   return reinterpret_cast<AccessorSignature*>(data);
1048 }
1049 
1050 }  // namespace v8
1051 
1052 #endif  // INCLUDE_V8_TEMPLATE_H_
1053