Coverage Report

Created: 2025-12-30 08:42

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