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