Coverage Report

Created: 2025-12-30 08:42

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