Coverage Report

Created: 2025-10-31 09:06

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