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