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