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