v8 14.1.146 (node 25.0.0)
V8 is Google's open source JavaScript engine
Loading...
Searching...
No Matches
v8-primitive.h
Go to the documentation of this file.
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
14namespace v8 {
15
16class Context;
17class Isolate;
18class String;
19
20namespace internal {
21class ExternalString;
22class ScopedExternalStringLock;
23class StringForwardingTable;
24} // namespace internal
25
26/**
27 * The superclass of primitive values. See ECMA-262 4.3.2.
28 */
29class 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 */
35class V8_EXPORT Boolean : public Primitive {
36 public:
37 bool Value() const;
38 V8_INLINE static Boolean* Cast(v8::Data* data) {
39#ifdef V8_ENABLE_CHECKS
40 CheckCast(data);
41#endif
42 return static_cast<Boolean*>(data);
43 }
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 */
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
66#ifdef V8_ENABLE_CHECKS
67 CheckCast(data);
68#endif
69 return reinterpret_cast<PrimitiveArray*>(data);
70 }
71
72 private:
73 static void CheckCast(Data* obj);
74};
75
76/**
77 * A superclass for symbols and strings.
78 */
79class 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 */
89
90 V8_INLINE static Name* Cast(Data* data) {
91#ifdef V8_ENABLE_CHECKS
92 CheckCast(data);
93#endif
94 return static_cast<Name*>(data);
95 }
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 */
107enum 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 */
119};
120
121/**
122 * A JavaScript string value (ECMA-262, 4.3.17).
123 */
124class 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 {
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 */
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 */
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.
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.
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.
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 */
294
296 public:
297 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 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 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 virtual size_t EstimateMemoryUsage() const {
323 return kDefaultMemoryEstimate;
324 }
325 static constexpr size_t kDefaultMemoryEstimate = static_cast<size_t>(-1);
326
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 */
342 SharedMemoryUsageRecorder* recorder) const {}
343
344 // Disallow copying and assigning.
346 void operator=(const ExternalStringResourceBase&) = delete;
347
348 protected:
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 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 virtual void Lock() const {}
371
372 /**
373 * Unlocks the string.
374 */
375 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 */
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 const uint16_t* cached_data() const {
415 CheckCachedDataInvariants();
416 return cached_data_;
417 }
418
419 /**
420 * Update {cached_data_} with the data from the underlying buffer. This can
421 * be called only for cacheable resources.
422 */
424
425 protected:
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
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 const char* cached_data() const {
468 CheckCachedDataInvariants();
469 return cached_data_;
470 }
471
472 /**
473 * Update {cached_data_} with the data from the underlying buffer. This can
474 * be called only for cacheable resources.
475 */
477
478 protected:
480
481 private:
482 void CheckCachedDataInvariants() const;
483
484 const char* cached_data_ = nullptr;
485 };
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 */
493 v8::Isolate* isolate, Encoding* encoding_out) const;
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 */
502
503 /**
504 * Get the ExternalOneByteStringResource for an external one-byte string.
505 * Returns NULL if IsExternalOneByte() doesn't return true.
506 */
508
509 V8_INLINE static String* Cast(v8::Data* data) {
510#ifdef V8_ENABLE_CHECKS
511 CheckCast(data);
512#endif
513 return static_cast<String*>(data);
514 }
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>
527 Isolate* isolate, const char (&literal)[N],
529 static_assert(N <= kMaxLength, "String is too long");
530 return NewFromUtf8Literal(isolate, literal, type, N - 1);
531 }
532
533 /** Allocates a new string from UTF-8 data. Only returns an empty value when
534 * length > kMaxLength. **/
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. **/
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. **/
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 */
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.")
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 */
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.")
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 */
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 */
648 public:
649 Utf8Value(Isolate* isolate, Local<v8::Value> obj);
651 char* operator*() { return str_; }
652 const char* operator*() const { return str_; }
653 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 */
675 public:
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);
681 uint16_t* operator*() { return str_; }
682 const uint16_t* operator*() const { return str_; }
683 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 */
705 public:
706 ValueView(Isolate* isolate, Local<v8::String> str);
708 const uint8_t* data8() const {
709#if V8_ENABLE_CHECKS
710 CheckOneByte(true);
711#endif
712 return data8_;
713 }
714 const uint16_t* data16() const {
715#if V8_ENABLE_CHECKS
716 CheckOneByte(false);
717#endif
718 return data16_;
719 }
720 uint32_t length() const { return length_; }
721 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_
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).
760template <>
762 Isolate* isolate, const char (&literal)[1], NewStringType type) {
763 return String::Empty(isolate);
764}
765
766/**
767 * Interface for iterating through all external resources in the heap.
768 */
770 public:
771 virtual ~ExternalResourceVisitor() = default;
772 virtual void VisitExternalString(Local<String> string) {}
773};
774
775/**
776 * A JavaScript symbol (ECMA-262 edition 6)
777 */
778class 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
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);
820 static Local<Symbol> GetDispose(Isolate* isolate);
822
823 V8_INLINE static Symbol* Cast(Data* data) {
824#ifdef V8_ENABLE_CHECKS
825 CheckCast(data);
826#endif
827 return static_cast<Symbol*>(data);
828 }
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 */
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 */
848class 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))
856 return NewFromInt32(isolate, value);
857 }
858 template <typename UInt>
860 !std::is_same<UInt, bool>::value && std::is_unsigned_v<UInt> &&
861 sizeof(UInt) <= sizeof(uint32_t))
863 return NewFromUint32(isolate, value);
864 }
866#ifdef V8_ENABLE_CHECKS
868#endif
869 return static_cast<Number*>(data);
870 }
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 */
882class 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 V8_INLINE static Integer* Cast(v8::Data* data) {
888#ifdef V8_ENABLE_CHECKS
889 CheckCast(data);
890#endif
891 return static_cast<Integer*>(data);
892 }
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 */
902class V8_EXPORT Int32 : public Integer {
903 public:
904 int32_t Value() const;
905 V8_INLINE static Int32* Cast(v8::Data* data) {
906#ifdef V8_ENABLE_CHECKS
907 CheckCast(data);
908#endif
909 return static_cast<Int32*>(data);
910 }
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 */
920class V8_EXPORT Uint32 : public Integer {
921 public:
922 uint32_t Value() const;
923 V8_INLINE static Uint32* Cast(v8::Data* data) {
924#ifdef V8_ENABLE_CHECKS
925 CheckCast(data);
926#endif
927 return static_cast<Uint32*>(data);
928 }
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 */
938class 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 V8_INLINE static BigInt* Cast(v8::Data* data) {
984#ifdef V8_ENABLE_CHECKS
985 CheckCast(data);
986#endif
987 return static_cast<BigInt*>(data);
988 }
989
990 private:
991 BigInt();
992 static void CheckCast(v8::Data* that);
993};
994
996 using S = internal::Address;
997 using I = internal::Internals;
998 I::CheckInitialized(isolate);
999 S* slot = I::GetRootSlot(isolate, I::kEmptyStringRootIndex);
1000 return Local<String>::FromSlot(slot);
1001}
1002
1004 using A = internal::Address;
1005 using I = internal::Internals;
1006 A obj = internal::ValueHelper::ValueAsAddress(this);
1007
1008 ExternalStringResource* result;
1011 A value = I::ReadExternalPointerField<internal::kExternalStringResourceTag>(
1012 isolate, obj, I::kStringResourceOffset);
1013 result = reinterpret_cast<String::ExternalStringResource*>(value);
1014 } else {
1015 result = GetExternalStringResourceSlow();
1016 }
1017#ifdef V8_ENABLE_CHECKS
1018 VerifyExternalStringResource(result);
1019#endif
1020 return result;
1021}
1022
1024 v8::Isolate* isolate, String::Encoding* encoding_out) const {
1025 using A = internal::Address;
1026 using I = internal::Internals;
1027 A obj = internal::ValueHelper::ValueAsAddress(this);
1029 *encoding_out = static_cast<Encoding>(type & I::kStringEncodingMask);
1033 A value = I::ReadExternalPointerField<internal::kExternalStringResourceTag>(
1034 isolate, obj, I::kStringResourceOffset);
1035 resource = reinterpret_cast<ExternalStringResourceBase*>(value);
1036 } else {
1037 resource = GetExternalStringResourceBaseSlow(encoding_out);
1038 }
1039#ifdef V8_ENABLE_CHECKS
1040 VerifyExternalStringResourceBase(resource, *encoding_out);
1041#endif
1042 return resource;
1043}
1044
1046 String::Encoding* encoding_out) const {
1047 using A = internal::Address;
1048 using I = internal::Internals;
1049 A obj = internal::ValueHelper::ValueAsAddress(this);
1051 *encoding_out = static_cast<Encoding>(type & I::kStringEncodingMask);
1056 A value = I::ReadExternalPointerField<internal::kExternalStringResourceTag>(
1057 isolate, obj, I::kStringResourceOffset);
1058 resource = reinterpret_cast<ExternalStringResourceBase*>(value);
1059 } else {
1060 resource = GetExternalStringResourceBaseSlow(encoding_out);
1061 }
1062#ifdef V8_ENABLE_CHECKS
1063 VerifyExternalStringResourceBase(resource, *encoding_out);
1064#endif
1065 return resource;
1066}
1067
1068// --- Statics ---
1069
1071 using S = internal::Address;
1072 using I = internal::Internals;
1073 I::CheckInitialized(isolate);
1075 return Local<Primitive>::FromSlot(slot);
1076}
1077
1079 using S = internal::Address;
1080 using I = internal::Internals;
1081 I::CheckInitialized(isolate);
1082 S* slot = I::GetRootSlot(isolate, I::kNullValueRootIndex);
1083 return Local<Primitive>::FromSlot(slot);
1084}
1085
1087 using S = internal::Address;
1088 using I = internal::Internals;
1089 I::CheckInitialized(isolate);
1090 S* slot = I::GetRootSlot(isolate, I::kTrueValueRootIndex);
1091 return Local<Boolean>::FromSlot(slot);
1092}
1093
1095 using S = internal::Address;
1096 using I = internal::Internals;
1097 I::CheckInitialized(isolate);
1098 S* slot = I::GetRootSlot(isolate, I::kFalseValueRootIndex);
1099 return Local<Boolean>::FromSlot(slot);
1100}
1101
1102Local<Boolean> Boolean::New(Isolate* isolate, bool value) {
1103 return value ? True(isolate) : False(isolate);
1104}
1105
1106} // namespace v8
1107
1108#endif // INCLUDE_V8_PRIMITIVE_H_
static MaybeLocal< BigInt > NewFromWords(Local< Context > context, int sign_bit, int word_count, const uint64_t *words)
static Local< BigInt > New(Isolate *isolate, int64_t value)
void ToWordsArray(int *sign_bit, int *word_count, uint64_t *words) const
uint64_t Uint64Value(bool *lossless=nullptr) const
static V8_INLINE BigInt * Cast(v8::Data *data)
int WordCount() const
static Local< BigInt > NewFromUnsigned(Isolate *isolate, uint64_t value)
int64_t Int64Value(bool *lossless=nullptr) const
bool Value() const
static V8_INLINE Boolean * Cast(v8::Data *data)
static V8_INLINE Local< Boolean > New(Isolate *isolate, bool value)
virtual void VisitExternalString(Local< String > string)
virtual ~ExternalResourceVisitor()=default
int32_t Value() const
static V8_INLINE Int32 * Cast(v8::Data *data)
int64_t Value() const
static Local< Integer > New(Isolate *isolate, int32_t value)
static V8_INLINE Integer * Cast(v8::Data *data)
static Local< Integer > NewFromUnsigned(Isolate *isolate, uint32_t value)
friend class Local
friend Local< Primitive > Null(Isolate *isolate)
friend Local< Boolean > False(Isolate *isolate)
friend Local< Primitive > Undefined(Isolate *isolate)
friend class MaybeLocal
friend Local< Boolean > True(Isolate *isolate)
static V8_INLINE Name * Cast(Data *data)
int GetIdentityHash()
double Value() const
static Local< Number > New(Isolate *isolate, double value)
void Set(Isolate *isolate, int index, Local< Primitive > item)
int Length() const
Local< Primitive > Get(Isolate *isolate, int index)
static Local< PrimitiveArray > New(Isolate *isolate, int length)
static V8_INLINE PrimitiveArray * Cast(Data *data)
~ExternalOneByteStringResource() override=default
virtual const char * data() const =0
virtual void RecordSharedMemoryUsage(const void *location, size_t size)=0
virtual void Unaccount(Isolate *isolate)
static constexpr size_t kDefaultMemoryEstimate
virtual size_t EstimateMemoryUsage() const
virtual void EstimateSharedMemoryUsage(SharedMemoryUsageRecorder *recorder) const
virtual ~ExternalStringResourceBase()=default
void operator=(const ExternalStringResourceBase &)=delete
ExternalStringResourceBase(const ExternalStringResourceBase &)=delete
~ExternalStringResource() override=default
const uint16_t * cached_data() const
virtual const uint16_t * data() const =0
virtual size_t length() const =0
void operator=(const Utf8Value &)=delete
const char * operator*() const
size_t length() const
Utf8Value(const Utf8Value &)=delete
Utf8Value(Isolate *isolate, Local< v8::Value > obj)
const uint16_t * operator*() const
uint32_t length() const
uint16_t * operator*()
void operator=(const Value &)=delete
Value(const Value &)=delete
Local< v8::Value > obj
ValueView(const ValueView &)=delete
ValueView(Isolate *isolate, Local< v8::String > str)
const uint16_t * data16_
uint32_t length() const
const uint16_t * data16() const
bool is_one_byte() const
const uint8_t * data8_
const uint8_t * data8() const
void operator=(const ValueView &)=delete
bool ContainsOnlyOneByte() const
Local< String > InternalizeString(Isolate *isolate)
V8_WARN_UNUSED_RESULT Local< String > NewFromUtf8Literal(Isolate *isolate, const char(&literal)[1], NewStringType type)
size_t Utf8LengthV2(Isolate *isolate) const
static V8_WARN_UNUSED_RESULT MaybeLocal< String > NewFromTwoByte(Isolate *isolate, const uint16_t *data, NewStringType type=NewStringType::kNormal, int length=-1)
bool MakeExternal(Isolate *isolate, ExternalStringResource *resource)
@ HINT_MANY_WRITES_EXPECTED
@ PRESERVE_ONE_BYTE_NULL
V8_INLINE ExternalStringResource * GetExternalStringResource() const
bool IsExternalTwoByte() const
static V8_WARN_UNUSED_RESULT Local< String > NewFromUtf8Literal(Isolate *isolate, const char(&literal)[N], NewStringType type=NewStringType::kNormal)
int Length() const
bool MakeExternal(Isolate *isolate, ExternalOneByteStringResource *resource)
static constexpr int kMaxLength
bool IsOneByte() const
bool MakeExternal(ExternalStringResource *resource)
static V8_INLINE String * Cast(v8::Data *data)
void WriteV2(Isolate *isolate, uint32_t offset, uint32_t length, uint16_t *buffer, int flags=WriteFlags::kNone) const
static V8_INLINE Local< String > Empty(Isolate *isolate)
const ExternalOneByteStringResource * GetExternalOneByteStringResource() const
V8_INLINE ExternalStringResourceBase * GetExternalStringResourceBase(Encoding *encoding_out) const
int WriteUtf8(Isolate *isolate, char *buffer, int length=-1, int *nchars_ref=nullptr, int options=NO_OPTIONS) const
size_t WriteUtf8V2(Isolate *isolate, char *buffer, size_t capacity, int flags=WriteFlags::kNone, size_t *processed_characters_return=nullptr) const
int WriteOneByte(Isolate *isolate, uint8_t *buffer, int start=0, int length=-1, int options=NO_OPTIONS) const
bool MakeExternal(ExternalOneByteStringResource *resource)
bool StringEquals(Local< String > str) const
static V8_WARN_UNUSED_RESULT MaybeLocal< String > NewExternalTwoByte(Isolate *isolate, ExternalStringResource *resource)
static V8_WARN_UNUSED_RESULT MaybeLocal< String > NewFromUtf8(Isolate *isolate, const char *data, NewStringType type=NewStringType::kNormal, int length=-1)
static Local< String > Concat(Isolate *isolate, Local< String > left, Local< String > right)
bool IsExternalOneByte() const
int Utf8Length(Isolate *isolate) const
static V8_WARN_UNUSED_RESULT MaybeLocal< String > NewExternalOneByte(Isolate *isolate, ExternalOneByteStringResource *resource)
bool CanMakeExternal(Encoding encoding) const
bool IsExternal() const
V8_INLINE ExternalStringResourceBase * GetExternalStringResourceBase(v8::Isolate *isolate, Encoding *encoding_out) const
void WriteOneByteV2(Isolate *isolate, uint32_t offset, uint32_t length, uint8_t *buffer, int flags=WriteFlags::kNone) const
int Write(Isolate *isolate, uint16_t *buffer, int start=0, int length=-1, int options=NO_OPTIONS) const
static V8_WARN_UNUSED_RESULT MaybeLocal< String > NewFromOneByte(Isolate *isolate, const uint8_t *data, NewStringType type=NewStringType::kNormal, int length=-1)
static Local< Symbol > New(Isolate *isolate, Local< String > description=Local< String >())
static Local< Symbol > GetAsyncDispose(Isolate *isolate)
static Local< Symbol > GetIterator(Isolate *isolate)
static V8_INLINE Symbol * Cast(Data *data)
static Local< Symbol > GetToPrimitive(Isolate *isolate)
static Local< Symbol > GetHasInstance(Isolate *isolate)
static Local< Symbol > GetIsConcatSpreadable(Isolate *isolate)
static Local< Symbol > GetToStringTag(Isolate *isolate)
static Local< Symbol > ForApi(Isolate *isolate, Local< String > description)
static Local< Symbol > GetDispose(Isolate *isolate)
static Local< Symbol > GetReplace(Isolate *isolate)
Local< Value > Description(Isolate *isolate) const
static Local< Symbol > For(Isolate *isolate, Local< String > description)
static Local< Symbol > GetAsyncIterator(Isolate *isolate)
static Local< Symbol > GetMatch(Isolate *isolate)
static Local< Symbol > GetSplit(Isolate *isolate)
static Local< Symbol > GetUnscopables(Isolate *isolate)
static Local< Symbol > GetSearch(Isolate *isolate)
static V8_INLINE Uint32 * Cast(v8::Data *data)
uint32_t Value() const
static const int kTrueValueRootIndex
static const int kFalseValueRootIndex
static const int kNullValueRootIndex
static const int kEmptyStringRootIndex
static const int kStringRepresentationAndEncodingMask
static const int kDisallowGarbageCollectionSize
static const int kExternalTwoByteRepresentationTag
static const int kUndefinedValueRootIndex
static V8_INLINE void CheckInitialized(v8::Isolate *isolate)
static V8_INLINE Address * GetRootSlot(v8::Isolate *isolate, int index)
static const int kExternalOneByteRepresentationTag
static V8_INLINE int GetInstanceType(Address obj)
static V8_INLINE v8::Isolate * GetCurrentIsolateForSandbox()
static V8_INLINE bool IsExternalTwoByteString(int instance_type)
static const int kStringEncodingMask
static const int kStringResourceOffset
const int kApiSystemPointerSize
Definition v8-internal.h:65
@ kExternalStringResourceTag
uintptr_t Address
Definition v8-internal.h:52
NewStringType
#define V8_EXPORT
Definition v8config.h:860
#define V8_INLINE
Definition v8config.h:513
#define V8_DEPRECATE_SOON(message)
Definition v8config.h:627
#define V8_DEPRECATED(message)
Definition v8config.h:619
#define V8_WARN_UNUSED_RESULT
Definition v8config.h:684