File indexing completed on 2025-02-22 10:42:33
0001
0002
0003
0004
0005 #ifndef INCLUDE_V8_PRIMITIVE_H_
0006 #define INCLUDE_V8_PRIMITIVE_H_
0007
0008 #include "v8-data.h" // NOLINT(build/include_directory)
0009 #include "v8-internal.h" // NOLINT(build/include_directory)
0010 #include "v8-local-handle.h" // NOLINT(build/include_directory)
0011 #include "v8-value.h" // NOLINT(build/include_directory)
0012 #include "v8config.h" // NOLINT(build/include_directory)
0013
0014 namespace v8 {
0015
0016 class Context;
0017 class Isolate;
0018 class String;
0019
0020 namespace internal {
0021 class ExternalString;
0022 class ScopedExternalStringLock;
0023 class StringForwardingTable;
0024 }
0025
0026
0027
0028
0029 class V8_EXPORT Primitive : public Value {};
0030
0031
0032
0033
0034
0035 class V8_EXPORT Boolean : public Primitive {
0036 public:
0037 bool Value() const;
0038 V8_INLINE static Boolean* Cast(v8::Data* data) {
0039 #ifdef V8_ENABLE_CHECKS
0040 CheckCast(data);
0041 #endif
0042 return static_cast<Boolean*>(data);
0043 }
0044
0045 V8_INLINE static Local<Boolean> New(Isolate* isolate, bool value);
0046
0047 private:
0048 static void CheckCast(v8::Data* that);
0049 };
0050
0051
0052
0053
0054
0055
0056
0057
0058 class V8_EXPORT PrimitiveArray : public Data {
0059 public:
0060 static Local<PrimitiveArray> New(Isolate* isolate, int length);
0061 int Length() const;
0062 void Set(Isolate* isolate, int index, Local<Primitive> item);
0063 Local<Primitive> Get(Isolate* isolate, int index);
0064
0065 V8_INLINE static PrimitiveArray* Cast(Data* data) {
0066 #ifdef V8_ENABLE_CHECKS
0067 CheckCast(data);
0068 #endif
0069 return reinterpret_cast<PrimitiveArray*>(data);
0070 }
0071
0072 private:
0073 static void CheckCast(Data* obj);
0074 };
0075
0076
0077
0078
0079 class V8_EXPORT Name : public Primitive {
0080 public:
0081
0082
0083
0084
0085
0086
0087
0088 int GetIdentityHash();
0089
0090 V8_INLINE static Name* Cast(Data* data) {
0091 #ifdef V8_ENABLE_CHECKS
0092 CheckCast(data);
0093 #endif
0094 return static_cast<Name*>(data);
0095 }
0096
0097 private:
0098 static void CheckCast(Data* that);
0099 };
0100
0101
0102
0103
0104
0105
0106
0107 enum class NewStringType {
0108
0109
0110
0111 kNormal,
0112
0113
0114
0115
0116
0117
0118 kInternalized
0119 };
0120
0121
0122
0123
0124 class V8_EXPORT String : public Name {
0125 public:
0126 static constexpr int kMaxLength =
0127 internal::kApiSystemPointerSize == 4 ? (1 << 28) - 16 : (1 << 29) - 24;
0128
0129 enum Encoding {
0130 UNKNOWN_ENCODING = 0x1,
0131 TWO_BYTE_ENCODING = 0x0,
0132 ONE_BYTE_ENCODING = 0x8
0133 };
0134
0135
0136
0137 int Length() const;
0138
0139
0140
0141
0142
0143 int Utf8Length(Isolate* isolate) const;
0144
0145
0146
0147
0148
0149
0150
0151 bool IsOneByte() const;
0152
0153
0154
0155
0156
0157
0158 bool ContainsOnlyOneByte() const;
0159
0160
0161
0162
0163
0164
0165
0166
0167
0168
0169
0170
0171
0172
0173
0174
0175
0176
0177
0178
0179
0180
0181
0182
0183
0184
0185 enum WriteOptions {
0186 NO_OPTIONS = 0,
0187 HINT_MANY_WRITES_EXPECTED = 1,
0188 NO_NULL_TERMINATION = 2,
0189 PRESERVE_ONE_BYTE_NULL = 4,
0190
0191
0192
0193 REPLACE_INVALID_UTF8 = 8
0194 };
0195
0196
0197 int Write(Isolate* isolate, uint16_t* buffer, int start = 0, int length = -1,
0198 int options = NO_OPTIONS) const;
0199
0200 int WriteOneByte(Isolate* isolate, uint8_t* buffer, int start = 0,
0201 int length = -1, int options = NO_OPTIONS) const;
0202
0203 int WriteUtf8(Isolate* isolate, char* buffer, int length = -1,
0204 int* nchars_ref = nullptr, int options = NO_OPTIONS) const;
0205
0206
0207
0208
0209 V8_INLINE static Local<String> Empty(Isolate* isolate);
0210
0211
0212
0213
0214 bool IsExternal() const;
0215
0216
0217
0218
0219 bool IsExternalTwoByte() const;
0220
0221
0222
0223
0224 bool IsExternalOneByte() const;
0225
0226 class V8_EXPORT ExternalStringResourceBase {
0227 public:
0228 virtual ~ExternalStringResourceBase() = default;
0229
0230
0231
0232
0233
0234
0235 virtual bool IsCacheable() const { return true; }
0236
0237
0238 ExternalStringResourceBase(const ExternalStringResourceBase&) = delete;
0239 void operator=(const ExternalStringResourceBase&) = delete;
0240
0241 protected:
0242 ExternalStringResourceBase() = default;
0243
0244
0245
0246
0247
0248
0249
0250 virtual void Dispose() { delete this; }
0251
0252
0253
0254
0255
0256
0257
0258
0259
0260
0261
0262
0263 virtual void Lock() const {}
0264
0265
0266
0267
0268 virtual void Unlock() const {}
0269
0270 private:
0271 friend class internal::ExternalString;
0272 friend class v8::String;
0273 friend class internal::StringForwardingTable;
0274 friend class internal::ScopedExternalStringLock;
0275 };
0276
0277
0278
0279
0280
0281
0282
0283 class V8_EXPORT ExternalStringResource : public ExternalStringResourceBase {
0284 public:
0285
0286
0287
0288
0289 ~ExternalStringResource() override = default;
0290
0291
0292
0293
0294
0295 virtual const uint16_t* data() const = 0;
0296
0297
0298
0299
0300 virtual size_t length() const = 0;
0301
0302
0303
0304
0305
0306
0307 const uint16_t* cached_data() const {
0308 CheckCachedDataInvariants();
0309 return cached_data_;
0310 }
0311
0312
0313
0314
0315
0316 void UpdateDataCache();
0317
0318 protected:
0319 ExternalStringResource() = default;
0320
0321 private:
0322 void CheckCachedDataInvariants() const;
0323
0324 const uint16_t* cached_data_ = nullptr;
0325 };
0326
0327
0328
0329
0330
0331
0332
0333
0334
0335
0336
0337 class V8_EXPORT ExternalOneByteStringResource
0338 : public ExternalStringResourceBase {
0339 public:
0340
0341
0342
0343
0344 ~ExternalOneByteStringResource() override = default;
0345
0346
0347
0348
0349
0350 virtual const char* data() const = 0;
0351
0352
0353 virtual size_t length() const = 0;
0354
0355
0356
0357
0358
0359
0360 const char* cached_data() const {
0361 CheckCachedDataInvariants();
0362 return cached_data_;
0363 }
0364
0365
0366
0367
0368
0369 void UpdateDataCache();
0370
0371 protected:
0372 ExternalOneByteStringResource() = default;
0373
0374 private:
0375 void CheckCachedDataInvariants() const;
0376
0377 const char* cached_data_ = nullptr;
0378 };
0379
0380
0381
0382
0383
0384
0385 V8_INLINE ExternalStringResourceBase* GetExternalStringResourceBase(
0386 Encoding* encoding_out) const;
0387
0388
0389
0390
0391
0392 V8_INLINE ExternalStringResource* GetExternalStringResource() const;
0393
0394
0395
0396
0397
0398 const ExternalOneByteStringResource* GetExternalOneByteStringResource() const;
0399
0400 V8_INLINE static String* Cast(v8::Data* data) {
0401 #ifdef V8_ENABLE_CHECKS
0402 CheckCast(data);
0403 #endif
0404 return static_cast<String*>(data);
0405 }
0406
0407
0408
0409
0410
0411
0412
0413
0414
0415
0416 template <int N>
0417 static V8_WARN_UNUSED_RESULT Local<String> NewFromUtf8Literal(
0418 Isolate* isolate, const char (&literal)[N],
0419 NewStringType type = NewStringType::kNormal) {
0420 static_assert(N <= kMaxLength, "String is too long");
0421 return NewFromUtf8Literal(isolate, literal, type, N - 1);
0422 }
0423
0424
0425
0426 static V8_WARN_UNUSED_RESULT MaybeLocal<String> NewFromUtf8(
0427 Isolate* isolate, const char* data,
0428 NewStringType type = NewStringType::kNormal, int length = -1);
0429
0430
0431
0432 static V8_WARN_UNUSED_RESULT MaybeLocal<String> NewFromOneByte(
0433 Isolate* isolate, const uint8_t* data,
0434 NewStringType type = NewStringType::kNormal, int length = -1);
0435
0436
0437
0438 static V8_WARN_UNUSED_RESULT MaybeLocal<String> NewFromTwoByte(
0439 Isolate* isolate, const uint16_t* data,
0440 NewStringType type = NewStringType::kNormal, int length = -1);
0441
0442
0443
0444
0445
0446 static Local<String> Concat(Isolate* isolate, Local<String> left,
0447 Local<String> right);
0448
0449
0450
0451
0452
0453
0454
0455
0456
0457 static V8_WARN_UNUSED_RESULT MaybeLocal<String> NewExternalTwoByte(
0458 Isolate* isolate, ExternalStringResource* resource);
0459
0460
0461
0462
0463
0464
0465
0466
0467
0468
0469 bool MakeExternal(ExternalStringResource* resource);
0470
0471
0472
0473
0474
0475
0476
0477
0478
0479 static V8_WARN_UNUSED_RESULT MaybeLocal<String> NewExternalOneByte(
0480 Isolate* isolate, ExternalOneByteStringResource* resource);
0481
0482
0483
0484
0485
0486
0487
0488
0489
0490
0491 bool MakeExternal(ExternalOneByteStringResource* resource);
0492
0493
0494
0495
0496
0497 bool CanMakeExternal(Encoding encoding) const;
0498
0499
0500
0501
0502 bool StringEquals(Local<String> str) const;
0503
0504
0505
0506
0507
0508
0509
0510
0511 class V8_EXPORT Utf8Value {
0512 public:
0513 Utf8Value(Isolate* isolate, Local<v8::Value> obj);
0514 ~Utf8Value();
0515 char* operator*() { return str_; }
0516 const char* operator*() const { return str_; }
0517 int length() const { return length_; }
0518
0519
0520 Utf8Value(const Utf8Value&) = delete;
0521 void operator=(const Utf8Value&) = delete;
0522
0523 private:
0524 char* str_;
0525 int length_;
0526 };
0527
0528
0529
0530
0531
0532
0533
0534 class V8_EXPORT Value {
0535 public:
0536 Value(Isolate* isolate, Local<v8::Value> obj);
0537 ~Value();
0538 uint16_t* operator*() { return str_; }
0539 const uint16_t* operator*() const { return str_; }
0540 int length() const { return length_; }
0541
0542
0543 Value(const Value&) = delete;
0544 void operator=(const Value&) = delete;
0545
0546 private:
0547 uint16_t* str_;
0548 int length_;
0549 };
0550
0551 private:
0552 void VerifyExternalStringResourceBase(ExternalStringResourceBase* v,
0553 Encoding encoding) const;
0554 void VerifyExternalStringResource(ExternalStringResource* val) const;
0555 ExternalStringResource* GetExternalStringResourceSlow() const;
0556 ExternalStringResourceBase* GetExternalStringResourceBaseSlow(
0557 String::Encoding* encoding_out) const;
0558
0559 static Local<v8::String> NewFromUtf8Literal(Isolate* isolate,
0560 const char* literal,
0561 NewStringType type, int length);
0562
0563 static void CheckCast(v8::Data* that);
0564 };
0565
0566
0567
0568 template <>
0569 inline V8_WARN_UNUSED_RESULT Local<String> String::NewFromUtf8Literal(
0570 Isolate* isolate, const char (&literal)[1], NewStringType type) {
0571 return String::Empty(isolate);
0572 }
0573
0574
0575
0576
0577 class V8_EXPORT ExternalResourceVisitor {
0578 public:
0579 virtual ~ExternalResourceVisitor() = default;
0580 virtual void VisitExternalString(Local<String> string) {}
0581 };
0582
0583
0584
0585
0586 class V8_EXPORT Symbol : public Name {
0587 public:
0588
0589
0590
0591 Local<Value> Description(Isolate* isolate) const;
0592
0593
0594
0595
0596
0597 static Local<Symbol> New(Isolate* isolate,
0598 Local<String> description = Local<String>());
0599
0600
0601
0602
0603
0604
0605
0606
0607
0608 static Local<Symbol> For(Isolate* isolate, Local<String> description);
0609
0610
0611
0612
0613
0614 static Local<Symbol> ForApi(Isolate* isolate, Local<String> description);
0615
0616
0617 static Local<Symbol> GetAsyncIterator(Isolate* isolate);
0618 static Local<Symbol> GetHasInstance(Isolate* isolate);
0619 static Local<Symbol> GetIsConcatSpreadable(Isolate* isolate);
0620 static Local<Symbol> GetIterator(Isolate* isolate);
0621 static Local<Symbol> GetMatch(Isolate* isolate);
0622 static Local<Symbol> GetReplace(Isolate* isolate);
0623 static Local<Symbol> GetSearch(Isolate* isolate);
0624 static Local<Symbol> GetSplit(Isolate* isolate);
0625 static Local<Symbol> GetToPrimitive(Isolate* isolate);
0626 static Local<Symbol> GetToStringTag(Isolate* isolate);
0627 static Local<Symbol> GetUnscopables(Isolate* isolate);
0628
0629 V8_INLINE static Symbol* Cast(Data* data) {
0630 #ifdef V8_ENABLE_CHECKS
0631 CheckCast(data);
0632 #endif
0633 return static_cast<Symbol*>(data);
0634 }
0635
0636 private:
0637 Symbol();
0638 static void CheckCast(Data* that);
0639 };
0640
0641
0642
0643
0644
0645 class V8_EXPORT Numeric : public Primitive {
0646 private:
0647 Numeric();
0648 static void CheckCast(v8::Data* that);
0649 };
0650
0651
0652
0653
0654 class V8_EXPORT Number : public Numeric {
0655 public:
0656 double Value() const;
0657 static Local<Number> New(Isolate* isolate, double value);
0658 V8_INLINE static Number* Cast(v8::Data* data) {
0659 #ifdef V8_ENABLE_CHECKS
0660 CheckCast(data);
0661 #endif
0662 return static_cast<Number*>(data);
0663 }
0664
0665 private:
0666 Number();
0667 static void CheckCast(v8::Data* that);
0668 };
0669
0670
0671
0672
0673 class V8_EXPORT Integer : public Number {
0674 public:
0675 static Local<Integer> New(Isolate* isolate, int32_t value);
0676 static Local<Integer> NewFromUnsigned(Isolate* isolate, uint32_t value);
0677 int64_t Value() const;
0678 V8_INLINE static Integer* Cast(v8::Data* data) {
0679 #ifdef V8_ENABLE_CHECKS
0680 CheckCast(data);
0681 #endif
0682 return static_cast<Integer*>(data);
0683 }
0684
0685 private:
0686 Integer();
0687 static void CheckCast(v8::Data* that);
0688 };
0689
0690
0691
0692
0693 class V8_EXPORT Int32 : public Integer {
0694 public:
0695 int32_t Value() const;
0696 V8_INLINE static Int32* Cast(v8::Data* data) {
0697 #ifdef V8_ENABLE_CHECKS
0698 CheckCast(data);
0699 #endif
0700 return static_cast<Int32*>(data);
0701 }
0702
0703 private:
0704 Int32();
0705 static void CheckCast(v8::Data* that);
0706 };
0707
0708
0709
0710
0711 class V8_EXPORT Uint32 : public Integer {
0712 public:
0713 uint32_t Value() const;
0714 V8_INLINE static Uint32* Cast(v8::Data* data) {
0715 #ifdef V8_ENABLE_CHECKS
0716 CheckCast(data);
0717 #endif
0718 return static_cast<Uint32*>(data);
0719 }
0720
0721 private:
0722 Uint32();
0723 static void CheckCast(v8::Data* that);
0724 };
0725
0726
0727
0728
0729 class V8_EXPORT BigInt : public Numeric {
0730 public:
0731 static Local<BigInt> New(Isolate* isolate, int64_t value);
0732 static Local<BigInt> NewFromUnsigned(Isolate* isolate, uint64_t value);
0733
0734
0735
0736
0737
0738
0739
0740 static MaybeLocal<BigInt> NewFromWords(Local<Context> context, int sign_bit,
0741 int word_count, const uint64_t* words);
0742
0743
0744
0745
0746
0747
0748
0749 uint64_t Uint64Value(bool* lossless = nullptr) const;
0750
0751
0752
0753
0754
0755
0756 int64_t Int64Value(bool* lossless = nullptr) const;
0757
0758
0759
0760
0761
0762 int WordCount() const;
0763
0764
0765
0766
0767
0768
0769
0770
0771
0772 void ToWordsArray(int* sign_bit, int* word_count, uint64_t* words) const;
0773
0774 V8_INLINE static BigInt* Cast(v8::Data* data) {
0775 #ifdef V8_ENABLE_CHECKS
0776 CheckCast(data);
0777 #endif
0778 return static_cast<BigInt*>(data);
0779 }
0780
0781 private:
0782 BigInt();
0783 static void CheckCast(v8::Data* that);
0784 };
0785
0786 Local<String> String::Empty(Isolate* isolate) {
0787 using S = internal::Address;
0788 using I = internal::Internals;
0789 I::CheckInitialized(isolate);
0790 S* slot = I::GetRootSlot(isolate, I::kEmptyStringRootIndex);
0791 return Local<String>::FromSlot(slot);
0792 }
0793
0794 String::ExternalStringResource* String::GetExternalStringResource() const {
0795 using A = internal::Address;
0796 using I = internal::Internals;
0797 A obj = internal::ValueHelper::ValueAsAddress(this);
0798
0799 ExternalStringResource* result;
0800 if (I::IsExternalTwoByteString(I::GetInstanceType(obj))) {
0801 Isolate* isolate = I::GetIsolateForSandbox(obj);
0802 A value = I::ReadExternalPointerField<internal::kExternalStringResourceTag>(
0803 isolate, obj, I::kStringResourceOffset);
0804 result = reinterpret_cast<String::ExternalStringResource*>(value);
0805 } else {
0806 result = GetExternalStringResourceSlow();
0807 }
0808 #ifdef V8_ENABLE_CHECKS
0809 VerifyExternalStringResource(result);
0810 #endif
0811 return result;
0812 }
0813
0814 String::ExternalStringResourceBase* String::GetExternalStringResourceBase(
0815 String::Encoding* encoding_out) const {
0816 using A = internal::Address;
0817 using I = internal::Internals;
0818 A obj = internal::ValueHelper::ValueAsAddress(this);
0819 int type = I::GetInstanceType(obj) & I::kStringRepresentationAndEncodingMask;
0820 *encoding_out = static_cast<Encoding>(type & I::kStringEncodingMask);
0821 ExternalStringResourceBase* resource;
0822 if (type == I::kExternalOneByteRepresentationTag ||
0823 type == I::kExternalTwoByteRepresentationTag) {
0824 Isolate* isolate = I::GetIsolateForSandbox(obj);
0825 A value = I::ReadExternalPointerField<internal::kExternalStringResourceTag>(
0826 isolate, obj, I::kStringResourceOffset);
0827 resource = reinterpret_cast<ExternalStringResourceBase*>(value);
0828 } else {
0829 resource = GetExternalStringResourceBaseSlow(encoding_out);
0830 }
0831 #ifdef V8_ENABLE_CHECKS
0832 VerifyExternalStringResourceBase(resource, *encoding_out);
0833 #endif
0834 return resource;
0835 }
0836
0837
0838
0839 V8_INLINE Local<Primitive> Undefined(Isolate* isolate) {
0840 using S = internal::Address;
0841 using I = internal::Internals;
0842 I::CheckInitialized(isolate);
0843 S* slot = I::GetRootSlot(isolate, I::kUndefinedValueRootIndex);
0844 return Local<Primitive>::FromSlot(slot);
0845 }
0846
0847 V8_INLINE Local<Primitive> Null(Isolate* isolate) {
0848 using S = internal::Address;
0849 using I = internal::Internals;
0850 I::CheckInitialized(isolate);
0851 S* slot = I::GetRootSlot(isolate, I::kNullValueRootIndex);
0852 return Local<Primitive>::FromSlot(slot);
0853 }
0854
0855 V8_INLINE Local<Boolean> True(Isolate* isolate) {
0856 using S = internal::Address;
0857 using I = internal::Internals;
0858 I::CheckInitialized(isolate);
0859 S* slot = I::GetRootSlot(isolate, I::kTrueValueRootIndex);
0860 return Local<Boolean>::FromSlot(slot);
0861 }
0862
0863 V8_INLINE Local<Boolean> False(Isolate* isolate) {
0864 using S = internal::Address;
0865 using I = internal::Internals;
0866 I::CheckInitialized(isolate);
0867 S* slot = I::GetRootSlot(isolate, I::kFalseValueRootIndex);
0868 return Local<Boolean>::FromSlot(slot);
0869 }
0870
0871 Local<Boolean> Boolean::New(Isolate* isolate, bool value) {
0872 return value ? True(isolate) : False(isolate);
0873 }
0874
0875 }
0876
0877 #endif