v8 10.2.154 (node 18.16.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;
23} // namespace internal
24
28class V8_EXPORT Primitive : public Value {};
29
34class V8_EXPORT Boolean : public Primitive {
35 public:
36 bool Value() const;
37 V8_INLINE static Boolean* Cast(v8::Data* data) {
38#ifdef V8_ENABLE_CHECKS
39 CheckCast(data);
40#endif
41 return static_cast<Boolean*>(data);
42 }
43
44 V8_INLINE static Local<Boolean> New(Isolate* isolate, bool value);
45
46 private:
47 static void CheckCast(v8::Data* that);
48};
49
58 public:
59 static Local<PrimitiveArray> New(Isolate* isolate, int length);
60 int Length() const;
61 void Set(Isolate* isolate, int index, Local<Primitive> item);
62 Local<Primitive> Get(Isolate* isolate, int index);
63
65#ifdef V8_ENABLE_CHECKS
66 CheckCast(data);
67#endif
68 return reinterpret_cast<PrimitiveArray*>(data);
69 }
70
71 private:
72 static void CheckCast(Data* obj);
73};
74
78class V8_EXPORT Name : public Primitive {
79 public:
88
89 V8_INLINE static Name* Cast(Data* data) {
90#ifdef V8_ENABLE_CHECKS
91 CheckCast(data);
92#endif
93 return static_cast<Name*>(data);
94 }
95
96 private:
97 static void CheckCast(Data* that);
98};
99
106enum class NewStringType {
110 kNormal,
111
118};
119
123class V8_EXPORT String : public Name {
124 public:
125 static constexpr int kMaxLength =
126 internal::kApiSystemPointerSize == 4 ? (1 << 28) - 16 : (1 << 29) - 24;
127
128 enum Encoding {
129 UNKNOWN_ENCODING = 0x1,
130 TWO_BYTE_ENCODING = 0x0,
131 ONE_BYTE_ENCODING = 0x8
132 };
136 int Length() const;
137
142 int Utf8Length(Isolate* isolate) const;
143
150 bool IsOneByte() const;
151
158
185 NO_OPTIONS = 0,
186 HINT_MANY_WRITES_EXPECTED = 1,
187 NO_NULL_TERMINATION = 2,
188 PRESERVE_ONE_BYTE_NULL = 4,
189 // Used by WriteUtf8 to replace orphan surrogate code units with the
190 // unicode replacement character. Needs to be set to guarantee valid UTF-8
191 // output.
192 REPLACE_INVALID_UTF8 = 8
193 };
194
195 // 16-bit character codes.
196 int Write(Isolate* isolate, uint16_t* buffer, int start = 0, int length = -1,
197 int options = NO_OPTIONS) const;
198 // One byte characters.
199 int WriteOneByte(Isolate* isolate, uint8_t* buffer, int start = 0,
200 int length = -1, int options = NO_OPTIONS) const;
201 // UTF-8 encoded characters.
202 int WriteUtf8(Isolate* isolate, char* buffer, int length = -1,
203 int* nchars_ref = nullptr, int options = NO_OPTIONS) const;
204
208 V8_INLINE static Local<String> Empty(Isolate* isolate);
209
213 bool IsExternal() const;
214
218 bool IsExternalTwoByte() const;
219
223 bool IsExternalOneByte() const;
224
226 public:
227 virtual ~ExternalStringResourceBase() = default;
228
234 virtual bool IsCacheable() const { return true; }
235
236 // Disallow copying and assigning.
239
240 protected:
242
249 virtual void Dispose() { delete this; }
250
262 virtual void Lock() const {}
263
267 virtual void Unlock() const {}
268
269 private:
270 friend class internal::ExternalString;
271 friend class v8::String;
272 friend class internal::ScopedExternalStringLock;
273 };
274
282 public:
287 ~ExternalStringResource() override = default;
288
293 virtual const uint16_t* data() const = 0;
294
298 virtual size_t length() const = 0;
305 const uint16_t* cached_data() const {
306 CheckCachedDataInvariants();
307 return cached_data_;
308 }
309
315
316 protected:
318
319 private:
320 void CheckCachedDataInvariants() const;
321
322 const uint16_t* cached_data_ = nullptr;
323 };
324
337 public:
342 ~ExternalOneByteStringResource() override = default;
343
348 virtual const char* data() const = 0;
349
351 virtual size_t length() const = 0;
352
358 const char* cached_data() const {
359 CheckCachedDataInvariants();
360 return cached_data_;
361 }
362
368
369 protected:
371
372 private:
373 void CheckCachedDataInvariants() const;
374
375 const char* cached_data_ = nullptr;
376 };
377
383 V8_INLINE ExternalStringResourceBase* GetExternalStringResourceBase(
384 Encoding* encoding_out) const;
385
390 V8_INLINE ExternalStringResource* GetExternalStringResource() const;
391
397
398 V8_INLINE static String* Cast(v8::Data* data) {
399#ifdef V8_ENABLE_CHECKS
400 CheckCast(data);
401#endif
402 return static_cast<String*>(data);
403 }
404
414 template <int N>
416 Isolate* isolate, const char (&literal)[N],
417 NewStringType type = NewStringType::kNormal) {
418 static_assert(N <= kMaxLength, "String is too long");
419 return NewFromUtf8Literal(isolate, literal, type, N - 1);
420 }
421
425 Isolate* isolate, const char* data,
426 NewStringType type = NewStringType::kNormal, int length = -1);
427
431 Isolate* isolate, const uint8_t* data,
432 NewStringType type = NewStringType::kNormal, int length = -1);
433
437 Isolate* isolate, const uint16_t* data,
438 NewStringType type = NewStringType::kNormal, int length = -1);
439
445 Local<String> right);
446
456 Isolate* isolate, ExternalStringResource* resource);
457
468
478 Isolate* isolate, ExternalOneByteStringResource* resource);
479
490
494 bool CanMakeExternal() const;
495
500
509 public:
512 char* operator*() { return str_; }
513 const char* operator*() const { return str_; }
514 int length() const { return length_; }
515
516 // Disallow copying and assigning.
517 Utf8Value(const Utf8Value&) = delete;
518 void operator=(const Utf8Value&) = delete;
519
520 private:
521 char* str_;
522 int length_;
523 };
524
532 public:
535 uint16_t* operator*() { return str_; }
536 const uint16_t* operator*() const { return str_; }
537 int length() const { return length_; }
538
539 // Disallow copying and assigning.
540 Value(const Value&) = delete;
541 void operator=(const Value&) = delete;
542
543 private:
544 uint16_t* str_;
545 int length_;
546 };
547
548 private:
549 void VerifyExternalStringResourceBase(ExternalStringResourceBase* v,
550 Encoding encoding) const;
551 void VerifyExternalStringResource(ExternalStringResource* val) const;
552 ExternalStringResource* GetExternalStringResourceSlow() const;
553 ExternalStringResourceBase* GetExternalStringResourceBaseSlow(
554 String::Encoding* encoding_out) const;
555
556 static Local<v8::String> NewFromUtf8Literal(Isolate* isolate,
557 const char* literal,
558 NewStringType type, int length);
559
560 static void CheckCast(v8::Data* that);
561};
562
563// Zero-length string specialization (templated string size includes
564// terminator).
565template <>
567 Isolate* isolate, const char (&literal)[1], NewStringType type) {
568 return String::Empty(isolate);
569}
570
575 public:
576 virtual ~ExternalResourceVisitor() = default;
577 virtual void VisitExternalString(Local<String> string) {}
578};
579
583class V8_EXPORT Symbol : public Name {
584 public:
589
594 static Local<Symbol> New(Isolate* isolate,
595 Local<String> description = Local<String>());
596
605 static Local<Symbol> For(Isolate* isolate, Local<String> description);
606
611 static Local<Symbol> ForApi(Isolate* isolate, Local<String> description);
612
613 // Well-known symbols
625
626 V8_INLINE static Symbol* Cast(Data* data) {
627#ifdef V8_ENABLE_CHECKS
628 CheckCast(data);
629#endif
630 return static_cast<Symbol*>(data);
631 }
632
633 private:
634 Symbol();
635 static void CheckCast(Data* that);
636};
637
641class V8_EXPORT Number : public Primitive {
642 public:
643 double Value() const;
644 static Local<Number> New(Isolate* isolate, double value);
645 V8_INLINE static Number* Cast(v8::Data* data) {
646#ifdef V8_ENABLE_CHECKS
647 CheckCast(data);
648#endif
649 return static_cast<Number*>(data);
650 }
651
652 private:
653 Number();
654 static void CheckCast(v8::Data* that);
655};
656
660class V8_EXPORT Integer : public Number {
661 public:
662 static Local<Integer> New(Isolate* isolate, int32_t value);
663 static Local<Integer> NewFromUnsigned(Isolate* isolate, uint32_t value);
664 int64_t Value() const;
666#ifdef V8_ENABLE_CHECKS
667 CheckCast(data);
668#endif
669 return static_cast<Integer*>(data);
670 }
671
672 private:
673 Integer();
674 static void CheckCast(v8::Data* that);
675};
676
680class V8_EXPORT Int32 : public Integer {
681 public:
682 int32_t Value() const;
683 V8_INLINE static Int32* Cast(v8::Data* data) {
684#ifdef V8_ENABLE_CHECKS
685 CheckCast(data);
686#endif
687 return static_cast<Int32*>(data);
688 }
689
690 private:
691 Int32();
692 static void CheckCast(v8::Data* that);
693};
694
698class V8_EXPORT Uint32 : public Integer {
699 public:
700 uint32_t Value() const;
701 V8_INLINE static Uint32* Cast(v8::Data* data) {
702#ifdef V8_ENABLE_CHECKS
703 CheckCast(data);
704#endif
705 return static_cast<Uint32*>(data);
706 }
707
708 private:
709 Uint32();
710 static void CheckCast(v8::Data* that);
711};
712
716class V8_EXPORT BigInt : public Primitive {
717 public:
718 static Local<BigInt> New(Isolate* isolate, int64_t value);
719 static Local<BigInt> NewFromUnsigned(Isolate* isolate, uint64_t value);
727 static MaybeLocal<BigInt> NewFromWords(Local<Context> context, int sign_bit,
728 int word_count, const uint64_t* words);
729
736 uint64_t Uint64Value(bool* lossless = nullptr) const;
737
743 int64_t Int64Value(bool* lossless = nullptr) const;
744
749 int WordCount() const;
750
759 void ToWordsArray(int* sign_bit, int* word_count, uint64_t* words) const;
760
761 V8_INLINE static BigInt* Cast(v8::Data* data) {
762#ifdef V8_ENABLE_CHECKS
763 CheckCast(data);
764#endif
765 return static_cast<BigInt*>(data);
766 }
767
768 private:
769 BigInt();
770 static void CheckCast(v8::Data* that);
771};
772
774 using S = internal::Address;
775 using I = internal::Internals;
776 I::CheckInitialized(isolate);
777 S* slot = I::GetRoot(isolate, I::kEmptyStringRootIndex);
778 return Local<String>(reinterpret_cast<String*>(slot));
779}
780
782 using A = internal::Address;
783 using I = internal::Internals;
784 A obj = *reinterpret_cast<const A*>(this);
785
787 if (I::IsExternalTwoByteString(I::GetInstanceType(obj))) {
788 internal::Isolate* isolate = I::GetIsolateForSandbox(obj);
789 A value =
790 I::ReadExternalPointerField(isolate, obj, I::kStringResourceOffset,
792 result = reinterpret_cast<String::ExternalStringResource*>(value);
793 } else {
794 result = GetExternalStringResourceSlow();
795 }
796#ifdef V8_ENABLE_CHECKS
797 VerifyExternalStringResource(result);
798#endif
799 return result;
800}
801
803 String::Encoding* encoding_out) const {
804 using A = internal::Address;
805 using I = internal::Internals;
806 A obj = *reinterpret_cast<const A*>(this);
807 int type = I::GetInstanceType(obj) & I::kStringRepresentationAndEncodingMask;
808 *encoding_out = static_cast<Encoding>(type & I::kStringEncodingMask);
810 if (type == I::kExternalOneByteRepresentationTag ||
811 type == I::kExternalTwoByteRepresentationTag) {
812 internal::Isolate* isolate = I::GetIsolateForSandbox(obj);
813 A value =
814 I::ReadExternalPointerField(isolate, obj, I::kStringResourceOffset,
816 resource = reinterpret_cast<ExternalStringResourceBase*>(value);
817 } else {
818 resource = GetExternalStringResourceBaseSlow(encoding_out);
819 }
820#ifdef V8_ENABLE_CHECKS
821 VerifyExternalStringResourceBase(resource, *encoding_out);
822#endif
823 return resource;
824}
825
826// --- Statics ---
827
829 using S = internal::Address;
830 using I = internal::Internals;
831 I::CheckInitialized(isolate);
832 S* slot = I::GetRoot(isolate, I::kUndefinedValueRootIndex);
833 return Local<Primitive>(reinterpret_cast<Primitive*>(slot));
834}
835
837 using S = internal::Address;
838 using I = internal::Internals;
839 I::CheckInitialized(isolate);
840 S* slot = I::GetRoot(isolate, I::kNullValueRootIndex);
841 return Local<Primitive>(reinterpret_cast<Primitive*>(slot));
842}
843
845 using S = internal::Address;
846 using I = internal::Internals;
847 I::CheckInitialized(isolate);
848 S* slot = I::GetRoot(isolate, I::kTrueValueRootIndex);
849 return Local<Boolean>(reinterpret_cast<Boolean*>(slot));
850}
851
853 using S = internal::Address;
854 using I = internal::Internals;
855 I::CheckInitialized(isolate);
856 S* slot = I::GetRoot(isolate, I::kFalseValueRootIndex);
857 return Local<Boolean>(reinterpret_cast<Boolean*>(slot));
858}
859
860Local<Boolean> Boolean::New(Isolate* isolate, bool value) {
861 return value ? True(isolate) : False(isolate);
862}
863
864} // namespace v8
865
866#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)
static V8_INLINE Name * Cast(Data *data)
int GetIdentityHash()
static V8_INLINE Number * Cast(v8::Data *data)
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 ~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
Utf8Value(const Utf8Value &)=delete
Utf8Value(Isolate *isolate, Local< v8::Value > obj)
const uint16_t * operator*() const
uint16_t * operator*()
void operator=(const Value &)=delete
Value(Isolate *isolate, Local< v8::Value > obj)
int length() const
Value(const Value &)=delete
bool ContainsOnlyOneByte() const
static V8_WARN_UNUSED_RESULT MaybeLocal< String > NewFromTwoByte(Isolate *isolate, const uint16_t *data, NewStringType type=NewStringType::kNormal, int length=-1)
bool CanMakeExternal() const
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 IsOneByte() const
bool MakeExternal(ExternalStringResource *resource)
static V8_INLINE String * Cast(v8::Data *data)
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
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 IsExternal() 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 > 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 > 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
uintptr_t Address
Definition v8-internal.h:29
@ kExternalStringResourceTag
V8_INLINE Local< Primitive > Null(Isolate *isolate)
V8_INLINE Local< Boolean > True(Isolate *isolate)
V8_INLINE Local< Boolean > False(Isolate *isolate)
int32_t(Local< Array > src, int32_t *dst, uint32_t max_length)
V8_INLINE Local< Primitive > Undefined(Isolate *isolate)
NewStringType
#define V8_EXPORT
Definition v8config.h:578
#define V8_INLINE
Definition v8config.h:425
#define V8_WARN_UNUSED_RESULT
Definition v8config.h:499