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-primitive.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_PRIMITIVE_H_
6
#define INCLUDE_V8_PRIMITIVE_H_
7
8
#include "v8-data.h"          // NOLINT(build/include_directory)
9
#include "v8-internal.h"      // NOLINT(build/include_directory)
10
#include "v8-local-handle.h"  // NOLINT(build/include_directory)
11
#include "v8-value.h"         // NOLINT(build/include_directory)
12
#include "v8config.h"         // NOLINT(build/include_directory)
13
14
namespace v8 {
15
16
class Context;
17
class Isolate;
18
class String;
19
20
namespace internal {
21
class ExternalString;
22
class ScopedExternalStringLock;
23
class StringForwardingTable;
24
}  // namespace internal
25
26
/**
27
 * The superclass of primitive values.  See ECMA-262 4.3.2.
28
 */
29
class V8_EXPORT Primitive : public Value {};
30
31
/**
32
 * A primitive boolean value (ECMA-262, 4.3.14).  Either the true
33
 * or false value.
34
 */
35
class V8_EXPORT Boolean : public Primitive {
36
 public:
37
  bool Value() const;
38
0
  V8_INLINE static Boolean* Cast(v8::Data* data) {
39
0
#ifdef V8_ENABLE_CHECKS
40
0
    CheckCast(data);
41
0
#endif
42
0
    return static_cast<Boolean*>(data);
43
0
  }
44
45
  V8_INLINE static Local<Boolean> New(Isolate* isolate, bool value);
46
47
 private:
48
  static void CheckCast(v8::Data* that);
49
};
50
51
/**
52
 * An array to hold Primitive values. This is used by the embedder to
53
 * pass host defined options to the ScriptOptions during compilation.
54
 *
55
 * This is passed back to the embedder as part of
56
 * HostImportModuleDynamicallyCallback for module loading.
57
 */
58
class V8_EXPORT PrimitiveArray : public Data {
59
 public:
60
  static Local<PrimitiveArray> New(Isolate* isolate, int length);
61
  int Length() const;
62
  void Set(Isolate* isolate, int index, Local<Primitive> item);
63
  Local<Primitive> Get(Isolate* isolate, int index);
64
65
0
  V8_INLINE static PrimitiveArray* Cast(Data* data) {
66
0
#ifdef V8_ENABLE_CHECKS
67
0
    CheckCast(data);
68
0
#endif
69
0
    return reinterpret_cast<PrimitiveArray*>(data);
70
0
  }
71
72
 private:
73
  static void CheckCast(Data* obj);
74
};
75
76
/**
77
 * A superclass for symbols and strings.
78
 */
79
class V8_EXPORT Name : public Primitive {
80
 public:
81
  /**
82
   * Returns the identity hash for this object. The current implementation
83
   * uses an inline property on the object to store the identity hash.
84
   *
85
   * The return value will never be 0. Also, it is not guaranteed to be
86
   * unique.
87
   */
88
  int GetIdentityHash();
89
90
0
  V8_INLINE static Name* Cast(Data* data) {
91
0
#ifdef V8_ENABLE_CHECKS
92
0
    CheckCast(data);
93
0
#endif
94
0
    return static_cast<Name*>(data);
95
0
  }
96
97
 private:
98
  static void CheckCast(Data* that);
99
};
100
101
/**
102
 * A flag describing different modes of string creation.
103
 *
104
 * Aside from performance implications there are no differences between the two
105
 * creation modes.
106
 */
107
enum class NewStringType {
108
  /**
109
   * Create a new string, always allocating new storage memory.
110
   */
111
  kNormal,
112
113
  /**
114
   * Acts as a hint that the string should be created in the
115
   * old generation heap space and be deduplicated if an identical string
116
   * already exists.
117
   */
118
  kInternalized
119
};
120
121
/**
122
 * A JavaScript string value (ECMA-262, 4.3.17).
123
 */
124
class V8_EXPORT String : public Name {
125
 public:
126
  static constexpr int kMaxLength =
127
      internal::kApiSystemPointerSize == 4 ? (1 << 28) - 16 : (1 << 29) - 24;
128
129
  enum Encoding {
130
    UNKNOWN_ENCODING = 0x1,
131
    TWO_BYTE_ENCODING = 0x0,
132
    ONE_BYTE_ENCODING = 0x8
133
  };
134
  /**
135
   * Returns the number of characters (UTF-16 code units) in this string.
136
   */
137
  int Length() const;
138
139
  /**
140
   * Returns the number of bytes in the UTF-8 encoded
141
   * representation of this string.
142
   */
143
  V8_DEPRECATED("Use Utf8LengthV2 instead.")
144
  int Utf8Length(Isolate* isolate) const;
145
146
  /**
147
   * Returns the number of bytes needed for the Utf8 encoding of this string.
148
   */
149
  size_t Utf8LengthV2(Isolate* isolate) const;
150
151
  /**
152
   * Returns whether this string is known to contain only one byte data,
153
   * i.e. ISO-8859-1 code points.
154
   * Does not read the string.
155
   * False negatives are possible.
156
   */
157
  bool IsOneByte() const;
158
159
  /**
160
   * Returns whether this string contain only one byte data,
161
   * i.e. ISO-8859-1 code points.
162
   * Will read the entire string in some cases.
163
   */
164
  bool ContainsOnlyOneByte() const;
165
166
  /**
167
   * Write the contents of the string to an external buffer.
168
   * If no arguments are given, expects the buffer to be large
169
   * enough to hold the entire string and NULL terminator. Copies
170
   * the contents of the string and the NULL terminator into the
171
   * buffer.
172
   *
173
   * WriteUtf8 will not write partial UTF-8 sequences, preferring to stop
174
   * before the end of the buffer.
175
   *
176
   * Copies up to length characters into the output buffer.
177
   * Only null-terminates if there is enough space in the buffer.
178
   *
179
   * \param buffer The buffer into which the string will be copied.
180
   * \param start The starting position within the string at which
181
   * copying begins.
182
   * \param length The number of characters to copy from the string.  For
183
   *    WriteUtf8 the number of bytes in the buffer.
184
   * \param nchars_ref The number of characters written, can be NULL.
185
   * \param options Various options that might affect performance of this or
186
   *    subsequent operations.
187
   * \return The number of characters copied to the buffer excluding the null
188
   *    terminator.  For WriteUtf8: The number of bytes copied to the buffer
189
   *    including the null terminator (if written).
190
   */
191
  enum WriteOptions {
192
    NO_OPTIONS = 0,
193
    HINT_MANY_WRITES_EXPECTED = 1,
194
    NO_NULL_TERMINATION = 2,
195
    PRESERVE_ONE_BYTE_NULL = 4,
196
    // Used by WriteUtf8 to replace orphan surrogate code units with the
197
    // unicode replacement character. Needs to be set to guarantee valid UTF-8
198
    // output.
199
    REPLACE_INVALID_UTF8 = 8
200
  };
201
202
  // 16-bit character codes.
203
  V8_DEPRECATED("Use WriteV2 instead.")
204
  int Write(Isolate* isolate, uint16_t* buffer, int start = 0, int length = -1,
205
            int options = NO_OPTIONS) const;
206
  // One byte characters.
207
  V8_DEPRECATED("Use WriteOneByteV2 instead.")
208
  int WriteOneByte(Isolate* isolate, uint8_t* buffer, int start = 0,
209
                   int length = -1, int options = NO_OPTIONS) const;
210
  // UTF-8 encoded characters.
211
  V8_DEPRECATED("Use WriteUtf8V2 instead.")
212
  int WriteUtf8(Isolate* isolate, char* buffer, int length = -1,
213
                int* nchars_ref = nullptr, int options = NO_OPTIONS) const;
214
215
  struct WriteFlags {
216
    enum {
217
      kNone = 0,
218
      // Indicates that the output string should be null-terminated. In that
219
      // case, the output buffer must include sufficient space for the
220
      // additional null character.
221
      kNullTerminate = 1,
222
      // Used by WriteUtf8 to replace orphan surrogate code units with the
223
      // unicode replacement character. Needs to be set to guarantee valid UTF-8
224
      // output.
225
      kReplaceInvalidUtf8 = 2
226
    };
227
  };
228
229
  /**
230
   * Write the contents of the string to an external buffer.
231
   *
232
   * Copies length characters into the output buffer starting at offset. The
233
   * output buffer must have sufficient space for all characters and the null
234
   * terminator if null termination is requested through the flags.
235
   *
236
   * \param offset The position within the string at which copying begins.
237
   * \param length The number of characters to copy from the string.
238
   * \param buffer The buffer into which the string will be copied.
239
   * \param flags Various flags that influence the behavior of this operation.
240
   */
241
  void WriteV2(Isolate* isolate, uint32_t offset, uint32_t length,
242
               uint16_t* buffer, int flags = WriteFlags::kNone) const;
243
  void WriteOneByteV2(Isolate* isolate, uint32_t offset, uint32_t length,
244
                      uint8_t* buffer, int flags = WriteFlags::kNone) const;
245
246
  /**
247
   * Encode the contents of the string as Utf8 into an external buffer.
248
   *
249
   * Encodes the characters of this string as Utf8 and writes them into the
250
   * output buffer until either all characters were encoded or the buffer is
251
   * full. Will not write partial UTF-8 sequences, preferring to stop before
252
   * the end of the buffer. If null termination is requested, the output buffer
253
   * will always be null terminated even if not all characters fit. In that
254
   * case, the capacity must be at least one. The required size of the output
255
   * buffer can be determined using Utf8Length().
256
   *
257
   * \param buffer The buffer into which the string will be written.
258
   * \param capacity The number of bytes available in the output buffer.
259
   * \param flags Various flags that influence the behavior of this operation.
260
   * \param processed_characters_return The number of processed characters from
261
   * the buffer.
262
   * \return The number of bytes copied to the buffer including the null
263
   * terminator (if written).
264
   */
265
  size_t WriteUtf8V2(Isolate* isolate, char* buffer, size_t capacity,
266
                     int flags = WriteFlags::kNone,
267
                     size_t* processed_characters_return = nullptr) const;
268
269
  /**
270
   * A zero length string.
271
   */
272
  V8_INLINE static Local<String> Empty(Isolate* isolate);
273
274
  /**
275
   * Returns true if the string is external.
276
   */
277
  bool IsExternal() const;
278
279
  /**
280
   * Returns true if the string is both external and two-byte.
281
   */
282
  bool IsExternalTwoByte() const;
283
284
  /**
285
   * Returns true if the string is both external and one-byte.
286
   */
287
  bool IsExternalOneByte() const;
288
289
  /**
290
   * Returns the internalized string. See `NewStringType::kInternalized` for
291
   * details on internalized strings.
292
   */
293
  Local<String> InternalizeString(Isolate* isolate);
294
295
  class V8_EXPORT ExternalStringResourceBase {
296
   public:
297
26.9k
    virtual ~ExternalStringResourceBase() = default;
298
299
    /**
300
     * If a string is cacheable, the value returned by
301
     * ExternalStringResource::data() may be cached, otherwise it is not
302
     * expected to be stable beyond the current top-level task.
303
     */
304
29.5k
    virtual bool IsCacheable() const { return true; }
305
306
    /**
307
     * Internally V8 will call this Unaccount method when the external string
308
     * resource should be unaccounted for. This method can be overridden in
309
     * subclasses to control how allocated external bytes are accounted.
310
     */
311
29.5k
    virtual void Unaccount(Isolate* isolate) {}
312
313
    /**
314
     * Returns an estimate of the memory occupied by this external string, to be
315
     * used by V8 when producing a heap snapshot. If this function returns
316
     * kDefaultMemoryEstimate, then V8 will estimate the external size based on
317
     * the string length. This function should return only memory that is
318
     * uniquely owned by this resource. If the resource has shared ownership of
319
     * a secondary allocation, it can report that memory by implementing
320
     * EstimateSharedMemoryUsage.
321
     */
322
0
    virtual size_t EstimateMemoryUsage() const {
323
0
      return kDefaultMemoryEstimate;
324
0
    }
325
    static constexpr size_t kDefaultMemoryEstimate = static_cast<size_t>(-1);
326
327
    class V8_EXPORT SharedMemoryUsageRecorder {
328
     public:
329
      /**
330
       * Record that a shared allocation at the given location has the given
331
       * size.
332
       */
333
      virtual void RecordSharedMemoryUsage(const void* location,
334
                                           size_t size) = 0;
335
    };
336
337
    /**
338
     * Estimates memory that this string resource may share with other string
339
     * resources, to be used by V8 when producing a heap snapshot.
340
     */
341
    virtual void EstimateSharedMemoryUsage(
342
0
        SharedMemoryUsageRecorder* recorder) const {}
343
344
    // Disallow copying and assigning.
345
    ExternalStringResourceBase(const ExternalStringResourceBase&) = delete;
346
    void operator=(const ExternalStringResourceBase&) = delete;
347
348
   protected:
349
53.4k
    ExternalStringResourceBase() = default;
350
351
    /**
352
     * Internally V8 will call this Dispose method when the external string
353
     * resource is no longer needed. The default implementation will use the
354
     * delete operator. This method can be overridden in subclasses to
355
     * control how allocated external string resources are disposed.
356
     */
357
26.9k
    virtual void Dispose() { delete this; }
358
359
    /**
360
     * For a non-cacheable string, the value returned by
361
     * |ExternalStringResource::data()| has to be stable between |Lock()| and
362
     * |Unlock()|, that is the string must behave as is |IsCacheable()| returned
363
     * true.
364
     *
365
     * These two functions must be thread-safe, and can be called from anywhere.
366
     * They also must handle lock depth, in the sense that each can be called
367
     * several times, from different threads, and unlocking should only happen
368
     * when the balance of Lock() and Unlock() calls is 0.
369
     */
370
8.12k
    virtual void Lock() const {}
371
372
    /**
373
     * Unlocks the string.
374
     */
375
8.12k
    virtual void Unlock() const {}
376
377
   private:
378
    friend class internal::ExternalString;
379
    friend class v8::String;
380
    friend class internal::StringForwardingTable;
381
    friend class internal::ScopedExternalStringLock;
382
  };
383
384
  /**
385
   * An ExternalStringResource is a wrapper around a two-byte string
386
   * buffer that resides outside V8's heap. Implement an
387
   * ExternalStringResource to manage the life cycle of the underlying
388
   * buffer.  Note that the string data must be immutable.
389
   */
390
  class V8_EXPORT ExternalStringResource : public ExternalStringResourceBase {
391
   public:
392
    /**
393
     * Override the destructor to manage the life cycle of the underlying
394
     * buffer.
395
     */
396
    ~ExternalStringResource() override = default;
397
398
    /**
399
     * The string data from the underlying buffer. If the resource is cacheable
400
     * then data() must return the same value for all invocations.
401
     */
402
    virtual const uint16_t* data() const = 0;
403
404
    /**
405
     * The length of the string. That is, the number of two-byte characters.
406
     */
407
    virtual size_t length() const = 0;
408
409
    /**
410
     * Returns the cached data from the underlying buffer. This method can be
411
     * called only for cacheable resources (i.e. IsCacheable() == true) and only
412
     * after UpdateDataCache() was called.
413
     */
414
0
    const uint16_t* cached_data() const {
415
0
      CheckCachedDataInvariants();
416
0
      return cached_data_;
417
0
    }
418
419
    /**
420
     * Update {cached_data_} with the data from the underlying buffer. This can
421
     * be called only for cacheable resources.
422
     */
423
    void UpdateDataCache();
424
425
   protected:
426
13.7k
    ExternalStringResource() = default;
427
428
   private:
429
    void CheckCachedDataInvariants() const;
430
431
    const uint16_t* cached_data_ = nullptr;
432
  };
433
434
  /**
435
   * An ExternalOneByteStringResource is a wrapper around an one-byte
436
   * string buffer that resides outside V8's heap. Implement an
437
   * ExternalOneByteStringResource to manage the life cycle of the
438
   * underlying buffer.  Note that the string data must be immutable
439
   * and that the data must be Latin-1 and not UTF-8, which would require
440
   * special treatment internally in the engine and do not allow efficient
441
   * indexing.  Use String::New or convert to 16 bit data for non-Latin1.
442
   */
443
444
  class V8_EXPORT ExternalOneByteStringResource
445
      : public ExternalStringResourceBase {
446
   public:
447
    /**
448
     * Override the destructor to manage the life cycle of the underlying
449
     * buffer.
450
     */
451
    ~ExternalOneByteStringResource() override = default;
452
453
    /**
454
     * The string data from the underlying buffer. If the resource is cacheable
455
     * then data() must return the same value for all invocations.
456
     */
457
    virtual const char* data() const = 0;
458
459
    /** The number of Latin-1 characters in the string.*/
460
    virtual size_t length() const = 0;
461
462
    /**
463
     * Returns the cached data from the underlying buffer. If the resource is
464
     * uncacheable or if UpdateDataCache() was not called before, it has
465
     * undefined behaviour.
466
     */
467
0
    const char* cached_data() const {
468
0
      CheckCachedDataInvariants();
469
0
      return cached_data_;
470
0
    }
471
472
    /**
473
     * Update {cached_data_} with the data from the underlying buffer. This can
474
     * be called only for cacheable resources.
475
     */
476
    void UpdateDataCache();
477
478
   protected:
479
39.6k
    ExternalOneByteStringResource() = default;
480
481
   private:
482
    void CheckCachedDataInvariants() const;
483
484
    const char* cached_data_ = nullptr;
485
  };
486
487
  /**
488
   * If the string is an external string, return the ExternalStringResourceBase
489
   * regardless of the encoding, otherwise return NULL.  The encoding of the
490
   * string is returned in encoding_out.
491
   */
492
  V8_INLINE ExternalStringResourceBase* GetExternalStringResourceBase(
493
      v8::Isolate* isolate, Encoding* encoding_out) const;
494
  V8_INLINE ExternalStringResourceBase* GetExternalStringResourceBase(
495
      Encoding* encoding_out) const;
496
497
  /**
498
   * Get the ExternalStringResource for an external string.  Returns
499
   * NULL if IsExternal() doesn't return true.
500
   */
501
  V8_INLINE ExternalStringResource* GetExternalStringResource() const;
502
503
  /**
504
   * Get the ExternalOneByteStringResource for an external one-byte string.
505
   * Returns NULL if IsExternalOneByte() doesn't return true.
506
   */
507
  const ExternalOneByteStringResource* GetExternalOneByteStringResource() const;
508
509
0
  V8_INLINE static String* Cast(v8::Data* data) {
510
#ifdef V8_ENABLE_CHECKS
511
    CheckCast(data);
512
#endif
513
0
    return static_cast<String*>(data);
514
0
  }
515
516
  /**
517
   * Allocates a new string from a UTF-8 literal. This is equivalent to calling
518
   * String::NewFromUtf(isolate, "...").ToLocalChecked(), but without the check
519
   * overhead.
520
   *
521
   * When called on a string literal containing '\0', the inferred length is the
522
   * length of the input array minus 1 (for the final '\0') and not the value
523
   * returned by strlen.
524
   **/
525
  template <int N>
526
  static V8_WARN_UNUSED_RESULT Local<String> NewFromUtf8Literal(
527
      Isolate* isolate, const char (&literal)[N],
528
17.2k
      NewStringType type = NewStringType::kNormal) {
529
17.2k
    static_assert(N <= kMaxLength, "String is too long");
530
17.2k
    return NewFromUtf8Literal(isolate, literal, type, N - 1);
531
17.2k
  }
v8::Local<v8::String> v8::String::NewFromUtf8Literal<6>(v8::Isolate*, char const (&) [6], v8::NewStringType)
Line
Count
Source
528
700
      NewStringType type = NewStringType::kNormal) {
529
700
    static_assert(N <= kMaxLength, "String is too long");
530
700
    return NewFromUtf8Literal(isolate, literal, type, N - 1);
531
700
  }
v8::Local<v8::String> v8::String::NewFromUtf8Literal<7>(v8::Isolate*, char const (&) [7], v8::NewStringType)
Line
Count
Source
528
1.40k
      NewStringType type = NewStringType::kNormal) {
529
1.40k
    static_assert(N <= kMaxLength, "String is too long");
530
1.40k
    return NewFromUtf8Literal(isolate, literal, type, N - 1);
531
1.40k
  }
v8::Local<v8::String> v8::String::NewFromUtf8Literal<11>(v8::Isolate*, char const (&) [11], v8::NewStringType)
Line
Count
Source
528
595
      NewStringType type = NewStringType::kNormal) {
529
595
    static_assert(N <= kMaxLength, "String is too long");
530
595
    return NewFromUtf8Literal(isolate, literal, type, N - 1);
531
595
  }
v8::Local<v8::String> v8::String::NewFromUtf8Literal<14>(v8::Isolate*, char const (&) [14], v8::NewStringType)
Line
Count
Source
528
350
      NewStringType type = NewStringType::kNormal) {
529
350
    static_assert(N <= kMaxLength, "String is too long");
530
350
    return NewFromUtf8Literal(isolate, literal, type, N - 1);
531
350
  }
v8::Local<v8::String> v8::String::NewFromUtf8Literal<13>(v8::Isolate*, char const (&) [13], v8::NewStringType)
Line
Count
Source
528
595
      NewStringType type = NewStringType::kNormal) {
529
595
    static_assert(N <= kMaxLength, "String is too long");
530
595
    return NewFromUtf8Literal(isolate, literal, type, N - 1);
531
595
  }
v8::Local<v8::String> v8::String::NewFromUtf8Literal<9>(v8::Isolate*, char const (&) [9], v8::NewStringType)
Line
Count
Source
528
595
      NewStringType type = NewStringType::kNormal) {
529
595
    static_assert(N <= kMaxLength, "String is too long");
530
595
    return NewFromUtf8Literal(isolate, literal, type, N - 1);
531
595
  }
v8::Local<v8::String> v8::String::NewFromUtf8Literal<8>(v8::Isolate*, char const (&) [8], v8::NewStringType)
Line
Count
Source
528
2.06k
      NewStringType type = NewStringType::kNormal) {
529
2.06k
    static_assert(N <= kMaxLength, "String is too long");
530
2.06k
    return NewFromUtf8Literal(isolate, literal, type, N - 1);
531
2.06k
  }
v8::Local<v8::String> v8::String::NewFromUtf8Literal<10>(v8::Isolate*, char const (&) [10], v8::NewStringType)
Line
Count
Source
528
525
      NewStringType type = NewStringType::kNormal) {
529
525
    static_assert(N <= kMaxLength, "String is too long");
530
525
    return NewFromUtf8Literal(isolate, literal, type, N - 1);
531
525
  }
v8::Local<v8::String> v8::String::NewFromUtf8Literal<5>(v8::Isolate*, char const (&) [5], v8::NewStringType)
Line
Count
Source
528
245
      NewStringType type = NewStringType::kNormal) {
529
245
    static_assert(N <= kMaxLength, "String is too long");
530
245
    return NewFromUtf8Literal(isolate, literal, type, N - 1);
531
245
  }
v8::Local<v8::String> v8::String::NewFromUtf8Literal<12>(v8::Isolate*, char const (&) [12], v8::NewStringType)
Line
Count
Source
528
560
      NewStringType type = NewStringType::kNormal) {
529
560
    static_assert(N <= kMaxLength, "String is too long");
530
560
    return NewFromUtf8Literal(isolate, literal, type, N - 1);
531
560
  }
v8::Local<v8::String> v8::String::NewFromUtf8Literal<4>(v8::Isolate*, char const (&) [4], v8::NewStringType)
Line
Count
Source
528
35
      NewStringType type = NewStringType::kNormal) {
529
35
    static_assert(N <= kMaxLength, "String is too long");
530
35
    return NewFromUtf8Literal(isolate, literal, type, N - 1);
531
35
  }
v8::Local<v8::String> v8::String::NewFromUtf8Literal<16>(v8::Isolate*, char const (&) [16], v8::NewStringType)
Line
Count
Source
528
560
      NewStringType type = NewStringType::kNormal) {
529
560
    static_assert(N <= kMaxLength, "String is too long");
530
560
    return NewFromUtf8Literal(isolate, literal, type, N - 1);
531
560
  }
v8::Local<v8::String> v8::String::NewFromUtf8Literal<22>(v8::Isolate*, char const (&) [22], v8::NewStringType)
Line
Count
Source
528
420
      NewStringType type = NewStringType::kNormal) {
529
420
    static_assert(N <= kMaxLength, "String is too long");
530
420
    return NewFromUtf8Literal(isolate, literal, type, N - 1);
531
420
  }
v8::Local<v8::String> v8::String::NewFromUtf8Literal<17>(v8::Isolate*, char const (&) [17], v8::NewStringType)
Line
Count
Source
528
630
      NewStringType type = NewStringType::kNormal) {
529
630
    static_assert(N <= kMaxLength, "String is too long");
530
630
    return NewFromUtf8Literal(isolate, literal, type, N - 1);
531
630
  }
v8::Local<v8::String> v8::String::NewFromUtf8Literal<23>(v8::Isolate*, char const (&) [23], v8::NewStringType)
Line
Count
Source
528
560
      NewStringType type = NewStringType::kNormal) {
529
560
    static_assert(N <= kMaxLength, "String is too long");
530
560
    return NewFromUtf8Literal(isolate, literal, type, N - 1);
531
560
  }
v8::Local<v8::String> v8::String::NewFromUtf8Literal<24>(v8::Isolate*, char const (&) [24], v8::NewStringType)
Line
Count
Source
528
490
      NewStringType type = NewStringType::kNormal) {
529
490
    static_assert(N <= kMaxLength, "String is too long");
530
490
    return NewFromUtf8Literal(isolate, literal, type, N - 1);
531
490
  }
v8::Local<v8::String> v8::String::NewFromUtf8Literal<41>(v8::Isolate*, char const (&) [41], v8::NewStringType)
Line
Count
Source
528
210
      NewStringType type = NewStringType::kNormal) {
529
210
    static_assert(N <= kMaxLength, "String is too long");
530
210
    return NewFromUtf8Literal(isolate, literal, type, N - 1);
531
210
  }
v8::Local<v8::String> v8::String::NewFromUtf8Literal<32>(v8::Isolate*, char const (&) [32], v8::NewStringType)
Line
Count
Source
528
490
      NewStringType type = NewStringType::kNormal) {
529
490
    static_assert(N <= kMaxLength, "String is too long");
530
490
    return NewFromUtf8Literal(isolate, literal, type, N - 1);
531
490
  }
v8::Local<v8::String> v8::String::NewFromUtf8Literal<28>(v8::Isolate*, char const (&) [28], v8::NewStringType)
Line
Count
Source
528
420
      NewStringType type = NewStringType::kNormal) {
529
420
    static_assert(N <= kMaxLength, "String is too long");
530
420
    return NewFromUtf8Literal(isolate, literal, type, N - 1);
531
420
  }
v8::Local<v8::String> v8::String::NewFromUtf8Literal<35>(v8::Isolate*, char const (&) [35], v8::NewStringType)
Line
Count
Source
528
105
      NewStringType type = NewStringType::kNormal) {
529
105
    static_assert(N <= kMaxLength, "String is too long");
530
105
    return NewFromUtf8Literal(isolate, literal, type, N - 1);
531
105
  }
v8::Local<v8::String> v8::String::NewFromUtf8Literal<29>(v8::Isolate*, char const (&) [29], v8::NewStringType)
Line
Count
Source
528
420
      NewStringType type = NewStringType::kNormal) {
529
420
    static_assert(N <= kMaxLength, "String is too long");
530
420
    return NewFromUtf8Literal(isolate, literal, type, N - 1);
531
420
  }
v8::Local<v8::String> v8::String::NewFromUtf8Literal<27>(v8::Isolate*, char const (&) [27], v8::NewStringType)
Line
Count
Source
528
210
      NewStringType type = NewStringType::kNormal) {
529
210
    static_assert(N <= kMaxLength, "String is too long");
530
210
    return NewFromUtf8Literal(isolate, literal, type, N - 1);
531
210
  }
v8::Local<v8::String> v8::String::NewFromUtf8Literal<20>(v8::Isolate*, char const (&) [20], v8::NewStringType)
Line
Count
Source
528
350
      NewStringType type = NewStringType::kNormal) {
529
350
    static_assert(N <= kMaxLength, "String is too long");
530
350
    return NewFromUtf8Literal(isolate, literal, type, N - 1);
531
350
  }
v8::Local<v8::String> v8::String::NewFromUtf8Literal<46>(v8::Isolate*, char const (&) [46], v8::NewStringType)
Line
Count
Source
528
140
      NewStringType type = NewStringType::kNormal) {
529
140
    static_assert(N <= kMaxLength, "String is too long");
530
140
    return NewFromUtf8Literal(isolate, literal, type, N - 1);
531
140
  }
v8::Local<v8::String> v8::String::NewFromUtf8Literal<18>(v8::Isolate*, char const (&) [18], v8::NewStringType)
Line
Count
Source
528
525
      NewStringType type = NewStringType::kNormal) {
529
525
    static_assert(N <= kMaxLength, "String is too long");
530
525
    return NewFromUtf8Literal(isolate, literal, type, N - 1);
531
525
  }
v8::Local<v8::String> v8::String::NewFromUtf8Literal<25>(v8::Isolate*, char const (&) [25], v8::NewStringType)
Line
Count
Source
528
245
      NewStringType type = NewStringType::kNormal) {
529
245
    static_assert(N <= kMaxLength, "String is too long");
530
245
    return NewFromUtf8Literal(isolate, literal, type, N - 1);
531
245
  }
v8::Local<v8::String> v8::String::NewFromUtf8Literal<19>(v8::Isolate*, char const (&) [19], v8::NewStringType)
Line
Count
Source
528
350
      NewStringType type = NewStringType::kNormal) {
529
350
    static_assert(N <= kMaxLength, "String is too long");
530
350
    return NewFromUtf8Literal(isolate, literal, type, N - 1);
531
350
  }
v8::Local<v8::String> v8::String::NewFromUtf8Literal<30>(v8::Isolate*, char const (&) [30], v8::NewStringType)
Line
Count
Source
528
210
      NewStringType type = NewStringType::kNormal) {
529
210
    static_assert(N <= kMaxLength, "String is too long");
530
210
    return NewFromUtf8Literal(isolate, literal, type, N - 1);
531
210
  }
v8::Local<v8::String> v8::String::NewFromUtf8Literal<26>(v8::Isolate*, char const (&) [26], v8::NewStringType)
Line
Count
Source
528
420
      NewStringType type = NewStringType::kNormal) {
529
420
    static_assert(N <= kMaxLength, "String is too long");
530
420
    return NewFromUtf8Literal(isolate, literal, type, N - 1);
531
420
  }
v8::Local<v8::String> v8::String::NewFromUtf8Literal<21>(v8::Isolate*, char const (&) [21], v8::NewStringType)
Line
Count
Source
528
210
      NewStringType type = NewStringType::kNormal) {
529
210
    static_assert(N <= kMaxLength, "String is too long");
530
210
    return NewFromUtf8Literal(isolate, literal, type, N - 1);
531
210
  }
v8::Local<v8::String> v8::String::NewFromUtf8Literal<15>(v8::Isolate*, char const (&) [15], v8::NewStringType)
Line
Count
Source
528
490
      NewStringType type = NewStringType::kNormal) {
529
490
    static_assert(N <= kMaxLength, "String is too long");
530
490
    return NewFromUtf8Literal(isolate, literal, type, N - 1);
531
490
  }
v8::Local<v8::String> v8::String::NewFromUtf8Literal<34>(v8::Isolate*, char const (&) [34], v8::NewStringType)
Line
Count
Source
528
245
      NewStringType type = NewStringType::kNormal) {
529
245
    static_assert(N <= kMaxLength, "String is too long");
530
245
    return NewFromUtf8Literal(isolate, literal, type, N - 1);
531
245
  }
v8::Local<v8::String> v8::String::NewFromUtf8Literal<39>(v8::Isolate*, char const (&) [39], v8::NewStringType)
Line
Count
Source
528
280
      NewStringType type = NewStringType::kNormal) {
529
280
    static_assert(N <= kMaxLength, "String is too long");
530
280
    return NewFromUtf8Literal(isolate, literal, type, N - 1);
531
280
  }
v8::Local<v8::String> v8::String::NewFromUtf8Literal<37>(v8::Isolate*, char const (&) [37], v8::NewStringType)
Line
Count
Source
528
245
      NewStringType type = NewStringType::kNormal) {
529
245
    static_assert(N <= kMaxLength, "String is too long");
530
245
    return NewFromUtf8Literal(isolate, literal, type, N - 1);
531
245
  }
v8::Local<v8::String> v8::String::NewFromUtf8Literal<33>(v8::Isolate*, char const (&) [33], v8::NewStringType)
Line
Count
Source
528
175
      NewStringType type = NewStringType::kNormal) {
529
175
    static_assert(N <= kMaxLength, "String is too long");
530
175
    return NewFromUtf8Literal(isolate, literal, type, N - 1);
531
175
  }
v8::Local<v8::String> v8::String::NewFromUtf8Literal<36>(v8::Isolate*, char const (&) [36], v8::NewStringType)
Line
Count
Source
528
35
      NewStringType type = NewStringType::kNormal) {
529
35
    static_assert(N <= kMaxLength, "String is too long");
530
35
    return NewFromUtf8Literal(isolate, literal, type, N - 1);
531
35
  }
v8::Local<v8::String> v8::String::NewFromUtf8Literal<40>(v8::Isolate*, char const (&) [40], v8::NewStringType)
Line
Count
Source
528
175
      NewStringType type = NewStringType::kNormal) {
529
175
    static_assert(N <= kMaxLength, "String is too long");
530
175
    return NewFromUtf8Literal(isolate, literal, type, N - 1);
531
175
  }
v8::Local<v8::String> v8::String::NewFromUtf8Literal<38>(v8::Isolate*, char const (&) [38], v8::NewStringType)
Line
Count
Source
528
245
      NewStringType type = NewStringType::kNormal) {
529
245
    static_assert(N <= kMaxLength, "String is too long");
530
245
    return NewFromUtf8Literal(isolate, literal, type, N - 1);
531
245
  }
v8::Local<v8::String> v8::String::NewFromUtf8Literal<42>(v8::Isolate*, char const (&) [42], v8::NewStringType)
Line
Count
Source
528
35
      NewStringType type = NewStringType::kNormal) {
529
35
    static_assert(N <= kMaxLength, "String is too long");
530
35
    return NewFromUtf8Literal(isolate, literal, type, N - 1);
531
35
  }
v8::Local<v8::String> v8::String::NewFromUtf8Literal<31>(v8::Isolate*, char const (&) [31], v8::NewStringType)
Line
Count
Source
528
140
      NewStringType type = NewStringType::kNormal) {
529
140
    static_assert(N <= kMaxLength, "String is too long");
530
140
    return NewFromUtf8Literal(isolate, literal, type, N - 1);
531
140
  }
v8::Local<v8::String> v8::String::NewFromUtf8Literal<44>(v8::Isolate*, char const (&) [44], v8::NewStringType)
Line
Count
Source
528
35
      NewStringType type = NewStringType::kNormal) {
529
35
    static_assert(N <= kMaxLength, "String is too long");
530
35
    return NewFromUtf8Literal(isolate, literal, type, N - 1);
531
35
  }
v8::Local<v8::String> v8::String::NewFromUtf8Literal<45>(v8::Isolate*, char const (&) [45], v8::NewStringType)
Line
Count
Source
528
105
      NewStringType type = NewStringType::kNormal) {
529
105
    static_assert(N <= kMaxLength, "String is too long");
530
105
    return NewFromUtf8Literal(isolate, literal, type, N - 1);
531
105
  }
v8::Local<v8::String> v8::String::NewFromUtf8Literal<57>(v8::Isolate*, char const (&) [57], v8::NewStringType)
Line
Count
Source
528
35
      NewStringType type = NewStringType::kNormal) {
529
35
    static_assert(N <= kMaxLength, "String is too long");
530
35
    return NewFromUtf8Literal(isolate, literal, type, N - 1);
531
35
  }
v8::Local<v8::String> v8::String::NewFromUtf8Literal<48>(v8::Isolate*, char const (&) [48], v8::NewStringType)
Line
Count
Source
528
70
      NewStringType type = NewStringType::kNormal) {
529
70
    static_assert(N <= kMaxLength, "String is too long");
530
70
    return NewFromUtf8Literal(isolate, literal, type, N - 1);
531
70
  }
v8::Local<v8::String> v8::String::NewFromUtf8Literal<49>(v8::Isolate*, char const (&) [49], v8::NewStringType)
Line
Count
Source
528
35
      NewStringType type = NewStringType::kNormal) {
529
35
    static_assert(N <= kMaxLength, "String is too long");
530
35
    return NewFromUtf8Literal(isolate, literal, type, N - 1);
531
35
  }
v8::Local<v8::String> v8::String::NewFromUtf8Literal<54>(v8::Isolate*, char const (&) [54], v8::NewStringType)
Line
Count
Source
528
35
      NewStringType type = NewStringType::kNormal) {
529
35
    static_assert(N <= kMaxLength, "String is too long");
530
35
    return NewFromUtf8Literal(isolate, literal, type, N - 1);
531
35
  }
v8::Local<v8::String> v8::String::NewFromUtf8Literal<50>(v8::Isolate*, char const (&) [50], v8::NewStringType)
Line
Count
Source
528
35
      NewStringType type = NewStringType::kNormal) {
529
35
    static_assert(N <= kMaxLength, "String is too long");
530
35
    return NewFromUtf8Literal(isolate, literal, type, N - 1);
531
35
  }
v8::Local<v8::String> v8::String::NewFromUtf8Literal<52>(v8::Isolate*, char const (&) [52], v8::NewStringType)
Line
Count
Source
528
35
      NewStringType type = NewStringType::kNormal) {
529
35
    static_assert(N <= kMaxLength, "String is too long");
530
35
    return NewFromUtf8Literal(isolate, literal, type, N - 1);
531
35
  }
v8::Local<v8::String> v8::String::NewFromUtf8Literal<47>(v8::Isolate*, char const (&) [47], v8::NewStringType)
Line
Count
Source
528
35
      NewStringType type = NewStringType::kNormal) {
529
35
    static_assert(N <= kMaxLength, "String is too long");
530
35
    return NewFromUtf8Literal(isolate, literal, type, N - 1);
531
35
  }
v8::Local<v8::String> v8::String::NewFromUtf8Literal<43>(v8::Isolate*, char const (&) [43], v8::NewStringType)
Line
Count
Source
528
105
      NewStringType type = NewStringType::kNormal) {
529
105
    static_assert(N <= kMaxLength, "String is too long");
530
105
    return NewFromUtf8Literal(isolate, literal, type, N - 1);
531
105
  }
532
533
  /** Allocates a new string from UTF-8 data. Only returns an empty value when
534
   * length > kMaxLength. **/
535
  static V8_WARN_UNUSED_RESULT MaybeLocal<String> NewFromUtf8(
536
      Isolate* isolate, const char* data,
537
      NewStringType type = NewStringType::kNormal, int length = -1);
538
539
  /** Allocates a new string from Latin-1 data.  Only returns an empty value
540
   * when length > kMaxLength. **/
541
  static V8_WARN_UNUSED_RESULT MaybeLocal<String> NewFromOneByte(
542
      Isolate* isolate, const uint8_t* data,
543
      NewStringType type = NewStringType::kNormal, int length = -1);
544
545
  /** Allocates a new string from UTF-16 data. Only returns an empty value when
546
   * length > kMaxLength. **/
547
  static V8_WARN_UNUSED_RESULT MaybeLocal<String> NewFromTwoByte(
548
      Isolate* isolate, const uint16_t* data,
549
      NewStringType type = NewStringType::kNormal, int length = -1);
550
551
  /**
552
   * Creates a new string by concatenating the left and the right strings
553
   * passed in as parameters.
554
   */
555
  static Local<String> Concat(Isolate* isolate, Local<String> left,
556
                              Local<String> right);
557
558
  /**
559
   * Creates a new external string using the data defined in the given
560
   * resource. When the external string is no longer live on V8's heap the
561
   * resource will be disposed by calling its Dispose method. The caller of
562
   * this function should not otherwise delete or modify the resource. Neither
563
   * should the underlying buffer be deallocated or modified except through the
564
   * destructor of the external string resource.
565
   */
566
  static V8_WARN_UNUSED_RESULT MaybeLocal<String> NewExternalTwoByte(
567
      Isolate* isolate, ExternalStringResource* resource);
568
569
  /**
570
   * Associate an external string resource with this string by transforming it
571
   * in place so that existing references to this string in the JavaScript heap
572
   * will use the external string resource. The external string resource's
573
   * character contents need to be equivalent to this string.
574
   * Returns true if the string has been changed to be an external string.
575
   * The string is not modified if the operation fails. See NewExternal for
576
   * information on the lifetime of the resource.
577
   */
578
  V8_DEPRECATE_SOON("Use the version with the isolate argument instead.")
579
  bool MakeExternal(ExternalStringResource* resource);
580
581
  /**
582
   * Associate an external string resource with this string by transforming it
583
   * in place so that existing references to this string in the JavaScript heap
584
   * will use the external string resource. The external string resource's
585
   * character contents need to be equivalent to this string.
586
   * Returns true if the string has been changed to be an external string.
587
   * The string is not modified if the operation fails. See NewExternal for
588
   * information on the lifetime of the resource.
589
   */
590
  bool MakeExternal(Isolate* isolate, ExternalStringResource* resource);
591
592
  /**
593
   * Creates a new external string using the one-byte data defined in the given
594
   * resource. When the external string is no longer live on V8's heap the
595
   * resource will be disposed by calling its Dispose method. The caller of
596
   * this function should not otherwise delete or modify the resource. Neither
597
   * should the underlying buffer be deallocated or modified except through the
598
   * destructor of the external string resource.
599
   */
600
  static V8_WARN_UNUSED_RESULT MaybeLocal<String> NewExternalOneByte(
601
      Isolate* isolate, ExternalOneByteStringResource* resource);
602
603
  /**
604
   * Associate an external string resource with this string by transforming it
605
   * in place so that existing references to this string in the JavaScript heap
606
   * will use the external string resource. The external string resource's
607
   * character contents need to be equivalent to this string.
608
   * Returns true if the string has been changed to be an external string.
609
   * The string is not modified if the operation fails. See NewExternal for
610
   * information on the lifetime of the resource.
611
   */
612
  V8_DEPRECATE_SOON("Use the version with the isolate argument instead.")
613
  bool MakeExternal(ExternalOneByteStringResource* resource);
614
615
  /**
616
   * Associate an external string resource with this string by transforming it
617
   * in place so that existing references to this string in the JavaScript heap
618
   * will use the external string resource. The external string resource's
619
   * character contents need to be equivalent to this string.
620
   * Returns true if the string has been changed to be an external string.
621
   * The string is not modified if the operation fails. See NewExternal for
622
   * information on the lifetime of the resource.
623
   */
624
  bool MakeExternal(Isolate* isolate, ExternalOneByteStringResource* resource);
625
626
  /**
627
   * Returns true if this string can be made external, given the encoding for
628
   * the external string resource.
629
   */
630
  bool CanMakeExternal(Encoding encoding) const;
631
632
  /**
633
   * Returns true if the strings values are equal. Same as JS ==/===.
634
   */
635
  bool StringEquals(Local<String> str) const;
636
637
  /**
638
   * Converts an object to a null-terminated UTF-8-encoded character array.
639
   * Useful if you want to print the object.  If conversion to a string fails
640
   * (e.g. due to an exception in the toString() method of the object) then the
641
   * length() method returns 0 and the * operator returns NULL.
642
   *
643
   * WARNING: This will unconditionally copy the contents of the JavaScript
644
   * string, and should be avoided in situations where performance is a concern.
645
   * Consider using WriteUtf8() instead.
646
   */
647
  class V8_EXPORT Utf8Value {
648
   public:
649
    Utf8Value(Isolate* isolate, Local<v8::Value> obj);
650
    ~Utf8Value();
651
0
    char* operator*() { return str_; }
652
0
    const char* operator*() const { return str_; }
653
0
    size_t length() const { return length_; }
654
655
    // Disallow copying and assigning.
656
    Utf8Value(const Utf8Value&) = delete;
657
    void operator=(const Utf8Value&) = delete;
658
659
   private:
660
    char* str_;
661
    size_t length_;
662
  };
663
664
  /**
665
   * Converts an object to a two-byte (UTF-16-encoded) string.
666
   *
667
   * If conversion to a string fails (eg. due to an exception in the toString()
668
   * method of the object) then the length() method returns 0 and the * operator
669
   * returns NULL.
670
   *
671
   * WARNING: This will unconditionally copy the contents of the JavaScript
672
   * string, and should be avoided in situations where performance is a concern.
673
   */
674
  class V8_EXPORT Value {
675
   public:
676
    V8_DEPRECATE_SOON(
677
        "Prefer using String::ValueView if you can, or string->Write to a "
678
        "buffer if you cannot.")
679
    Value(Isolate* isolate, Local<v8::Value> obj);
680
    ~Value();
681
0
    uint16_t* operator*() { return str_; }
682
0
    const uint16_t* operator*() const { return str_; }
683
0
    uint32_t length() const { return length_; }
684
685
    // Disallow copying and assigning.
686
    Value(const Value&) = delete;
687
    void operator=(const Value&) = delete;
688
689
   private:
690
    uint16_t* str_;
691
    uint32_t length_;
692
  };
693
694
  /**
695
   * Returns a view onto a string's contents.
696
   *
697
   * WARNING: This does not copy the string's contents, and will therefore be
698
   * invalidated if the GC can move the string while the ValueView is alive. It
699
   * is therefore required that no GC or allocation can happen while there is an
700
   * active ValueView. This requirement may be relaxed in the future.
701
   *
702
   * V8 strings are either encoded as one-byte or two-bytes per character.
703
   */
704
  class V8_EXPORT ValueView {
705
   public:
706
    ValueView(Isolate* isolate, Local<v8::String> str);
707
    ~ValueView();
708
3.60k
    const uint8_t* data8() const {
709
#if V8_ENABLE_CHECKS
710
      CheckOneByte(true);
711
#endif
712
3.60k
      return data8_;
713
3.60k
    }
714
0
    const uint16_t* data16() const {
715
#if V8_ENABLE_CHECKS
716
      CheckOneByte(false);
717
#endif
718
0
      return data16_;
719
0
    }
720
3.60k
    uint32_t length() const { return length_; }
721
3.60k
    bool is_one_byte() const { return is_one_byte_; }
722
723
    // Disallow copying and assigning.
724
    ValueView(const ValueView&) = delete;
725
    void operator=(const ValueView&) = delete;
726
727
   private:
728
    void CheckOneByte(bool is_one_byte) const;
729
730
    Local<v8::String> flat_str_;
731
    union {
732
      const uint8_t* data8_;
733
      const uint16_t* data16_;
734
    };
735
    uint32_t length_;
736
    bool is_one_byte_;
737
    // Avoid exposing the internal DisallowGarbageCollection scope.
738
    alignas(internal::Internals::
739
                kDisallowGarbageCollectionAlign) char no_gc_debug_scope_
740
        [internal::Internals::kDisallowGarbageCollectionSize];
741
  };
742
743
 private:
744
  void VerifyExternalStringResourceBase(ExternalStringResourceBase* v,
745
                                        Encoding encoding) const;
746
  void VerifyExternalStringResource(ExternalStringResource* val) const;
747
  ExternalStringResource* GetExternalStringResourceSlow() const;
748
  ExternalStringResourceBase* GetExternalStringResourceBaseSlow(
749
      String::Encoding* encoding_out) const;
750
751
  static Local<v8::String> NewFromUtf8Literal(Isolate* isolate,
752
                                              const char* literal,
753
                                              NewStringType type, int length);
754
755
  static void CheckCast(v8::Data* that);
756
};
757
758
// Zero-length string specialization (templated string size includes
759
// terminator).
760
template <>
761
inline V8_WARN_UNUSED_RESULT Local<String> String::NewFromUtf8Literal(
762
0
    Isolate* isolate, const char (&literal)[1], NewStringType type) {
763
0
  return String::Empty(isolate);
764
0
}
765
766
/**
767
 * Interface for iterating through all external resources in the heap.
768
 */
769
class V8_EXPORT ExternalResourceVisitor {
770
 public:
771
  virtual ~ExternalResourceVisitor() = default;
772
0
  virtual void VisitExternalString(Local<String> string) {}
773
};
774
775
/**
776
 * A JavaScript symbol (ECMA-262 edition 6)
777
 */
778
class V8_EXPORT Symbol : public Name {
779
 public:
780
  /**
781
   * Returns the description string of the symbol, or undefined if none.
782
   */
783
  Local<Value> Description(Isolate* isolate) const;
784
785
  /**
786
   * Create a symbol. If description is not empty, it will be used as the
787
   * description.
788
   */
789
  static Local<Symbol> New(Isolate* isolate,
790
                           Local<String> description = Local<String>());
791
792
  /**
793
   * Access global symbol registry.
794
   * Note that symbols created this way are never collected, so
795
   * they should only be used for statically fixed properties.
796
   * Also, there is only one global name space for the descriptions used as
797
   * keys.
798
   * To minimize the potential for clashes, use qualified names as keys.
799
   */
800
  static Local<Symbol> For(Isolate* isolate, Local<String> description);
801
802
  /**
803
   * Retrieve a global symbol. Similar to |For|, but using a separate
804
   * registry that is not accessible by (and cannot clash with) JavaScript code.
805
   */
806
  static Local<Symbol> ForApi(Isolate* isolate, Local<String> description);
807
808
  // Well-known symbols
809
  static Local<Symbol> GetAsyncIterator(Isolate* isolate);
810
  static Local<Symbol> GetHasInstance(Isolate* isolate);
811
  static Local<Symbol> GetIsConcatSpreadable(Isolate* isolate);
812
  static Local<Symbol> GetIterator(Isolate* isolate);
813
  static Local<Symbol> GetMatch(Isolate* isolate);
814
  static Local<Symbol> GetReplace(Isolate* isolate);
815
  static Local<Symbol> GetSearch(Isolate* isolate);
816
  static Local<Symbol> GetSplit(Isolate* isolate);
817
  static Local<Symbol> GetToPrimitive(Isolate* isolate);
818
  static Local<Symbol> GetToStringTag(Isolate* isolate);
819
  static Local<Symbol> GetUnscopables(Isolate* isolate);
820
  static Local<Symbol> GetDispose(Isolate* isolate);
821
  static Local<Symbol> GetAsyncDispose(Isolate* isolate);
822
823
0
  V8_INLINE static Symbol* Cast(Data* data) {
824
#ifdef V8_ENABLE_CHECKS
825
    CheckCast(data);
826
#endif
827
0
    return static_cast<Symbol*>(data);
828
0
  }
829
830
 private:
831
  Symbol();
832
  static void CheckCast(Data* that);
833
};
834
835
/**
836
 * A JavaScript numeric value (either Number or BigInt).
837
 * https://tc39.es/ecma262/#sec-numeric-types
838
 */
839
class V8_EXPORT Numeric : public Primitive {
840
 private:
841
  Numeric();
842
  static void CheckCast(v8::Data* that);
843
};
844
845
/**
846
 * A JavaScript number value (ECMA-262, 4.3.20)
847
 */
848
class V8_EXPORT Number : public Numeric {
849
 public:
850
  double Value() const;
851
  static Local<Number> New(Isolate* isolate, double value);
852
  template <typename Int>
853
    requires(std::is_integral<Int>::value && !std::is_same<Int, bool>::value &&
854
             std::is_signed_v<Int> && sizeof(Int) <= sizeof(int32_t))
855
0
  V8_INLINE static Local<Number> New(Isolate* isolate, Int value) {
856
0
    return NewFromInt32(isolate, value);
857
0
  }
858
  template <typename UInt>
859
    requires(std::is_integral<UInt>::value &&
860
             !std::is_same<UInt, bool>::value && std::is_unsigned_v<UInt> &&
861
             sizeof(UInt) <= sizeof(uint32_t))
862
0
  V8_INLINE static Local<Number> New(Isolate* isolate, UInt value) {
863
0
    return NewFromUint32(isolate, value);
864
0
  }
865
0
  V8_INLINE static Number* Cast(v8::Data* data) {
866
0
#ifdef V8_ENABLE_CHECKS
867
0
    CheckCast(data);
868
0
#endif
869
0
    return static_cast<Number*>(data);
870
0
  }
871
872
 private:
873
  Number();
874
  static Local<Number> NewFromInt32(Isolate* isolate, int32_t value);
875
  static Local<Number> NewFromUint32(Isolate* isolate, uint32_t value);
876
  static void CheckCast(v8::Data* that);
877
};
878
879
/**
880
 * A JavaScript value representing a signed integer.
881
 */
882
class V8_EXPORT Integer : public Number {
883
 public:
884
  static Local<Integer> New(Isolate* isolate, int32_t value);
885
  static Local<Integer> NewFromUnsigned(Isolate* isolate, uint32_t value);
886
  int64_t Value() const;
887
0
  V8_INLINE static Integer* Cast(v8::Data* data) {
888
0
#ifdef V8_ENABLE_CHECKS
889
0
    CheckCast(data);
890
0
#endif
891
0
    return static_cast<Integer*>(data);
892
0
  }
893
894
 private:
895
  Integer();
896
  static void CheckCast(v8::Data* that);
897
};
898
899
/**
900
 * A JavaScript value representing a 32-bit signed integer.
901
 */
902
class V8_EXPORT Int32 : public Integer {
903
 public:
904
  int32_t Value() const;
905
0
  V8_INLINE static Int32* Cast(v8::Data* data) {
906
0
#ifdef V8_ENABLE_CHECKS
907
0
    CheckCast(data);
908
0
#endif
909
0
    return static_cast<Int32*>(data);
910
0
  }
911
912
 private:
913
  Int32();
914
  static void CheckCast(v8::Data* that);
915
};
916
917
/**
918
 * A JavaScript value representing a 32-bit unsigned integer.
919
 */
920
class V8_EXPORT Uint32 : public Integer {
921
 public:
922
  uint32_t Value() const;
923
0
  V8_INLINE static Uint32* Cast(v8::Data* data) {
924
0
#ifdef V8_ENABLE_CHECKS
925
0
    CheckCast(data);
926
0
#endif
927
0
    return static_cast<Uint32*>(data);
928
0
  }
929
930
 private:
931
  Uint32();
932
  static void CheckCast(v8::Data* that);
933
};
934
935
/**
936
 * A JavaScript BigInt value (https://tc39.github.io/proposal-bigint)
937
 */
938
class V8_EXPORT BigInt : public Numeric {
939
 public:
940
  static Local<BigInt> New(Isolate* isolate, int64_t value);
941
  static Local<BigInt> NewFromUnsigned(Isolate* isolate, uint64_t value);
942
  /**
943
   * Creates a new BigInt object using a specified sign bit and a
944
   * specified list of digits/words.
945
   * The resulting number is calculated as:
946
   *
947
   * (-1)^sign_bit * (words[0] * (2^64)^0 + words[1] * (2^64)^1 + ...)
948
   */
949
  static MaybeLocal<BigInt> NewFromWords(Local<Context> context, int sign_bit,
950
                                         int word_count, const uint64_t* words);
951
952
  /**
953
   * Returns the value of this BigInt as an unsigned 64-bit integer.
954
   * If `lossless` is provided, it will reflect whether the return value was
955
   * truncated or wrapped around. In particular, it is set to `false` if this
956
   * BigInt is negative.
957
   */
958
  uint64_t Uint64Value(bool* lossless = nullptr) const;
959
960
  /**
961
   * Returns the value of this BigInt as a signed 64-bit integer.
962
   * If `lossless` is provided, it will reflect whether this BigInt was
963
   * truncated or not.
964
   */
965
  int64_t Int64Value(bool* lossless = nullptr) const;
966
967
  /**
968
   * Returns the number of 64-bit words needed to store the result of
969
   * ToWordsArray().
970
   */
971
  int WordCount() const;
972
973
  /**
974
   * Writes the contents of this BigInt to a specified memory location.
975
   * `sign_bit` must be provided and will be set to 1 if this BigInt is
976
   * negative.
977
   * `*word_count` has to be initialized to the length of the `words` array.
978
   * Upon return, it will be set to the actual number of words that would
979
   * be needed to store this BigInt (i.e. the return value of `WordCount()`).
980
   */
981
  void ToWordsArray(int* sign_bit, int* word_count, uint64_t* words) const;
982
983
0
  V8_INLINE static BigInt* Cast(v8::Data* data) {
984
0
#ifdef V8_ENABLE_CHECKS
985
0
    CheckCast(data);
986
0
#endif
987
0
    return static_cast<BigInt*>(data);
988
0
  }
989
990
 private:
991
  BigInt();
992
  static void CheckCast(v8::Data* that);
993
};
994
995
0
Local<String> String::Empty(Isolate* isolate) {
996
0
  using S = internal::Address;
997
0
  using I = internal::Internals;
998
0
  I::CheckInitialized(isolate);
999
0
  S* slot = I::GetRootSlot(isolate, I::kEmptyStringRootIndex);
1000
0
  return Local<String>::FromSlot(slot);
1001
0
}
1002
1003
0
String::ExternalStringResource* String::GetExternalStringResource() const {
1004
0
  using A = internal::Address;
1005
0
  using I = internal::Internals;
1006
0
  A obj = internal::ValueHelper::ValueAsAddress(this);
1007
1008
0
  ExternalStringResource* result;
1009
0
  if (I::IsExternalTwoByteString(I::GetInstanceType(obj))) {
1010
0
    Isolate* isolate = I::GetCurrentIsolateForSandbox();
1011
0
    A value = I::ReadExternalPointerField<internal::kExternalStringResourceTag>(
1012
0
        isolate, obj, I::kStringResourceOffset);
1013
0
    result = reinterpret_cast<String::ExternalStringResource*>(value);
1014
0
  } else {
1015
0
    result = GetExternalStringResourceSlow();
1016
0
  }
1017
#ifdef V8_ENABLE_CHECKS
1018
  VerifyExternalStringResource(result);
1019
#endif
1020
0
  return result;
1021
0
}
1022
1023
String::ExternalStringResourceBase* String::GetExternalStringResourceBase(
1024
0
    v8::Isolate* isolate, String::Encoding* encoding_out) const {
1025
0
  using A = internal::Address;
1026
0
  using I = internal::Internals;
1027
0
  A obj = internal::ValueHelper::ValueAsAddress(this);
1028
0
  int type = I::GetInstanceType(obj) & I::kStringRepresentationAndEncodingMask;
1029
0
  *encoding_out = static_cast<Encoding>(type & I::kStringEncodingMask);
1030
0
  ExternalStringResourceBase* resource;
1031
0
  if (type == I::kExternalOneByteRepresentationTag ||
1032
0
      type == I::kExternalTwoByteRepresentationTag) {
1033
0
    A value = I::ReadExternalPointerField<internal::kExternalStringResourceTag>(
1034
0
        isolate, obj, I::kStringResourceOffset);
1035
0
    resource = reinterpret_cast<ExternalStringResourceBase*>(value);
1036
0
  } else {
1037
0
    resource = GetExternalStringResourceBaseSlow(encoding_out);
1038
0
  }
1039
0
#ifdef V8_ENABLE_CHECKS
1040
0
  VerifyExternalStringResourceBase(resource, *encoding_out);
1041
0
#endif
1042
0
  return resource;
1043
0
}
1044
1045
String::ExternalStringResourceBase* String::GetExternalStringResourceBase(
1046
0
    String::Encoding* encoding_out) const {
1047
0
  using A = internal::Address;
1048
0
  using I = internal::Internals;
1049
0
  A obj = internal::ValueHelper::ValueAsAddress(this);
1050
0
  int type = I::GetInstanceType(obj) & I::kStringRepresentationAndEncodingMask;
1051
0
  *encoding_out = static_cast<Encoding>(type & I::kStringEncodingMask);
1052
0
  ExternalStringResourceBase* resource;
1053
0
  if (type == I::kExternalOneByteRepresentationTag ||
1054
0
      type == I::kExternalTwoByteRepresentationTag) {
1055
0
    Isolate* isolate = I::GetCurrentIsolateForSandbox();
1056
0
    A value = I::ReadExternalPointerField<internal::kExternalStringResourceTag>(
1057
0
        isolate, obj, I::kStringResourceOffset);
1058
0
    resource = reinterpret_cast<ExternalStringResourceBase*>(value);
1059
0
  } else {
1060
0
    resource = GetExternalStringResourceBaseSlow(encoding_out);
1061
0
  }
1062
0
#ifdef V8_ENABLE_CHECKS
1063
0
  VerifyExternalStringResourceBase(resource, *encoding_out);
1064
0
#endif
1065
0
  return resource;
1066
0
}
1067
1068
// --- Statics ---
1069
1070
1.61k
V8_INLINE Local<Primitive> Undefined(Isolate* isolate) {
1071
1.61k
  using S = internal::Address;
1072
1.61k
  using I = internal::Internals;
1073
1.61k
  I::CheckInitialized(isolate);
1074
1.61k
  S* slot = I::GetRootSlot(isolate, I::kUndefinedValueRootIndex);
1075
1.61k
  return Local<Primitive>::FromSlot(slot);
1076
1.61k
}
1077
1078
631
V8_INLINE Local<Primitive> Null(Isolate* isolate) {
1079
631
  using S = internal::Address;
1080
631
  using I = internal::Internals;
1081
631
  I::CheckInitialized(isolate);
1082
631
  S* slot = I::GetRootSlot(isolate, I::kNullValueRootIndex);
1083
631
  return Local<Primitive>::FromSlot(slot);
1084
631
}
1085
1086
4.48k
V8_INLINE Local<Boolean> True(Isolate* isolate) {
1087
4.48k
  using S = internal::Address;
1088
4.48k
  using I = internal::Internals;
1089
4.48k
  I::CheckInitialized(isolate);
1090
4.48k
  S* slot = I::GetRootSlot(isolate, I::kTrueValueRootIndex);
1091
4.48k
  return Local<Boolean>::FromSlot(slot);
1092
4.48k
}
1093
1094
4.34k
V8_INLINE Local<Boolean> False(Isolate* isolate) {
1095
4.34k
  using S = internal::Address;
1096
4.34k
  using I = internal::Internals;
1097
4.34k
  I::CheckInitialized(isolate);
1098
4.34k
  S* slot = I::GetRootSlot(isolate, I::kFalseValueRootIndex);
1099
4.34k
  return Local<Boolean>::FromSlot(slot);
1100
4.34k
}
1101
1102
8.29k
Local<Boolean> Boolean::New(Isolate* isolate, bool value) {
1103
8.29k
  return value ? True(isolate) : False(isolate);
1104
8.29k
}
1105
1106
}  // namespace v8
1107
1108
#endif  // INCLUDE_V8_PRIMITIVE_H_