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 */ 58class 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 V8_INLINE static PrimitiveArray* Cast(Data* data) { 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 */ 88 int GetIdentityHash(); 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 */ 118 kInternalized 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 { 130 UNKNOWN_ENCODING = 0x1, 131 TWO_BYTE_ENCODING = 0x0, 132 ONE_BYTE_ENCODING = 0x8 133 }; 134 /** 135 * Returns the number of characters (UTF-16 code units) in this string. 136 */ 137 int Length() const; 138 139 /** 140 * Returns the number of bytes in the UTF-8 encoded 141 * representation of this string. 142 */ 143 int Utf8Length(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 /** 161 * Write the contents of the string to an external buffer. 162 * If no arguments are given, expects the buffer to be large 163 * enough to hold the entire string and NULL terminator. Copies 164 * the contents of the string and the NULL terminator into the 165 * buffer. 166 * 167 * WriteUtf8 will not write partial UTF-8 sequences, preferring to stop 168 * before the end of the buffer. 169 * 170 * Copies up to length characters into the output buffer. 171 * Only null-terminates if there is enough space in the buffer. 172 * 173 * \param buffer The buffer into which the string will be copied. 174 * \param start The starting position within the string at which 175 * copying begins. 176 * \param length The number of characters to copy from the string. For 177 * WriteUtf8 the number of bytes in the buffer. 178 * \param nchars_ref The number of characters written, can be NULL. 179 * \param options Various options that might affect performance of this or 180 * subsequent operations. 181 * \return The number of characters copied to the buffer excluding the null 182 * terminator. For WriteUtf8: The number of bytes copied to the buffer 183 * including the null terminator (if written). 184 */ 185 enum WriteOptions { 186 NO_OPTIONS = 0, 187 HINT_MANY_WRITES_EXPECTED = 1, 188 NO_NULL_TERMINATION = 2, 189 PRESERVE_ONE_BYTE_NULL = 4, 190 // Used by WriteUtf8 to replace orphan surrogate code units with the 191 // unicode replacement character. Needs to be set to guarantee valid UTF-8 192 // output. 193 REPLACE_INVALID_UTF8 = 8 194 }; 195 196 // 16-bit character codes. 197 int Write(Isolate* isolate, uint16_t* buffer, int start = 0, int length = -1, 198 int options = NO_OPTIONS) const; 199 // One byte characters. 200 int WriteOneByte(Isolate* isolate, uint8_t* buffer, int start = 0, 201 int length = -1, int options = NO_OPTIONS) const; 202 // UTF-8 encoded characters. 203 int WriteUtf8(Isolate* isolate, char* buffer, int length = -1, 204 int* nchars_ref = nullptr, int options = NO_OPTIONS) const; 205 206 /** 207 * A zero length string. 208 */ 209 V8_INLINE static Local<String> Empty(Isolate* isolate); 210 211 /** 212 * Returns true if the string is external. 213 */ 214 bool IsExternal() const; 215 216 /** 217 * Returns true if the string is both external and two-byte. 218 */ 219 bool IsExternalTwoByte() const; 220 221 /** 222 * Returns true if the string is both external and one-byte. 223 */ 224 bool IsExternalOneByte() const; 225 226 class V8_EXPORT ExternalStringResourceBase { 227 public: 228 virtual ~ExternalStringResourceBase() = default; 229 230 /** 231 * If a string is cacheable, the value returned by 232 * ExternalStringResource::data() may be cached, otherwise it is not 233 * expected to be stable beyond the current top-level task. 234 */ 235 virtual bool IsCacheable() const { return true; } 236 237 // Disallow copying and assigning. 238 ExternalStringResourceBase(const ExternalStringResourceBase&) = delete; 239 void operator=(const ExternalStringResourceBase&) = delete; 240 241 protected: 242 ExternalStringResourceBase() = default; 243 244 /** 245 * Internally V8 will call this Dispose method when the external string 246 * resource is no longer needed. The default implementation will use the 247 * delete operator. This method can be overridden in subclasses to 248 * control how allocated external string resources are disposed. 249 */ 250 virtual void Dispose() { delete this; } 251 252 /** 253 * For a non-cacheable string, the value returned by 254 * |ExternalStringResource::data()| has to be stable between |Lock()| and 255 * |Unlock()|, that is the string must behave as is |IsCacheable()| returned 256 * true. 257 * 258 * These two functions must be thread-safe, and can be called from anywhere. 259 * They also must handle lock depth, in the sense that each can be called 260 * several times, from different threads, and unlocking should only happen 261 * when the balance of Lock() and Unlock() calls is 0. 262 */ 263 virtual void Lock() const {} 264 265 /** 266 * Unlocks the string. 267 */ 268 virtual void Unlock() const {} 269 270 private: 271 friend class internal::ExternalString; 272 friend class v8::String; 273 friend class internal::StringForwardingTable; 274 friend class internal::ScopedExternalStringLock; 275 }; 276 277 /** 278 * An ExternalStringResource is a wrapper around a two-byte string 279 * buffer that resides outside V8's heap. Implement an 280 * ExternalStringResource to manage the life cycle of the underlying 281 * buffer. Note that the string data must be immutable. 282 */ 283 class V8_EXPORT ExternalStringResource : public ExternalStringResourceBase { 284 public: 285 /** 286 * Override the destructor to manage the life cycle of the underlying 287 * buffer. 288 */ 289 ~ExternalStringResource() override = default; 290 291 /** 292 * The string data from the underlying buffer. If the resource is cacheable 293 * then data() must return the same value for all invocations. 294 */ 295 virtual const uint16_t* data() const = 0; 296 297 /** 298 * The length of the string. That is, the number of two-byte characters. 299 */ 300 virtual size_t length() const = 0; 301 302 /** 303 * Returns the cached data from the underlying buffer. This method can be 304 * called only for cacheable resources (i.e. IsCacheable() == true) and only 305 * after UpdateDataCache() was called. 306 */ 307 const uint16_t* cached_data() const { 308 CheckCachedDataInvariants(); 309 return cached_data_; 310 } 311 312 /** 313 * Update {cached_data_} with the data from the underlying buffer. This can 314 * be called only for cacheable resources. 315 */ 316 void UpdateDataCache(); 317 318 protected: 319 ExternalStringResource() = default; 320 321 private: 322 void CheckCachedDataInvariants() const; 323 324 const uint16_t* cached_data_ = nullptr; 325 }; 326 327 /** 328 * An ExternalOneByteStringResource is a wrapper around an one-byte 329 * string buffer that resides outside V8's heap. Implement an 330 * ExternalOneByteStringResource to manage the life cycle of the 331 * underlying buffer. Note that the string data must be immutable 332 * and that the data must be Latin-1 and not UTF-8, which would require 333 * special treatment internally in the engine and do not allow efficient 334 * indexing. Use String::New or convert to 16 bit data for non-Latin1. 335 */ 336 337 class V8_EXPORT ExternalOneByteStringResource 338 : public ExternalStringResourceBase { 339 public: 340 /** 341 * Override the destructor to manage the life cycle of the underlying 342 * buffer. 343 */ 344 ~ExternalOneByteStringResource() 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 char* data() const = 0; 351 352 /** The number of Latin-1 characters in the string.*/ 353 virtual size_t length() const = 0; 354 355 /** 356 * Returns the cached data from the underlying buffer. If the resource is 357 * uncacheable or if UpdateDataCache() was not called before, it has 358 * undefined behaviour. 359 */ 360 const char* cached_data() const { 361 CheckCachedDataInvariants(); 362 return cached_data_; 363 } 364 365 /** 366 * Update {cached_data_} with the data from the underlying buffer. This can 367 * be called only for cacheable resources. 368 */ 369 void UpdateDataCache(); 370 371 protected: 372 ExternalOneByteStringResource() = default; 373 374 private: 375 void CheckCachedDataInvariants() const; 376 377 const char* cached_data_ = nullptr; 378 }; 379 380 /** 381 * If the string is an external string, return the ExternalStringResourceBase 382 * regardless of the encoding, otherwise return NULL. The encoding of the 383 * string is returned in encoding_out. 384 */ 385 V8_INLINE ExternalStringResourceBase* GetExternalStringResourceBase( 386 Encoding* encoding_out) const; 387 388 /** 389 * Get the ExternalStringResource for an external string. Returns 390 * NULL if IsExternal() doesn't return true. 391 */ 392 V8_INLINE ExternalStringResource* GetExternalStringResource() const; 393 394 /** 395 * Get the ExternalOneByteStringResource for an external one-byte string. 396 * Returns NULL if IsExternalOneByte() doesn't return true. 397 */ 398 const ExternalOneByteStringResource* GetExternalOneByteStringResource() const; 399 400 V8_INLINE static String* Cast(v8::Data* data) { 401#ifdef V8_ENABLE_CHECKS 402 CheckCast(data); 403#endif 404 return static_cast<String*>(data); 405 } 406 407 /** 408 * Allocates a new string from a UTF-8 literal. This is equivalent to calling 409 * String::NewFromUtf(isolate, "...").ToLocalChecked(), but without the check 410 * overhead. 411 * 412 * When called on a string literal containing '\0', the inferred length is the 413 * length of the input array minus 1 (for the final '\0') and not the value 414 * returned by strlen. 415 **/ 416 template <int N> 417 static V8_WARN_UNUSED_RESULT Local<String> NewFromUtf8Literal( 418 Isolate* isolate, const char (&literal)[N], 419 NewStringType type = NewStringType::kNormal) { 420 static_assert(N <= kMaxLength, "String is too long"); 421 return NewFromUtf8Literal(isolate, literal, type, N - 1); 422 } 423 424 /** Allocates a new string from UTF-8 data. Only returns an empty value when 425 * length > kMaxLength. **/ 426 static V8_WARN_UNUSED_RESULT MaybeLocal<String> NewFromUtf8( 427 Isolate* isolate, const char* data, 428 NewStringType type = NewStringType::kNormal, int length = -1); 429 430 /** Allocates a new string from Latin-1 data. Only returns an empty value 431 * when length > kMaxLength. **/ 432 static V8_WARN_UNUSED_RESULT MaybeLocal<String> NewFromOneByte( 433 Isolate* isolate, const uint8_t* data, 434 NewStringType type = NewStringType::kNormal, int length = -1); 435 436 /** Allocates a new string from UTF-16 data. Only returns an empty value when 437 * length > kMaxLength. **/ 438 static V8_WARN_UNUSED_RESULT MaybeLocal<String> NewFromTwoByte( 439 Isolate* isolate, const uint16_t* data, 440 NewStringType type = NewStringType::kNormal, int length = -1); 441 442 /** 443 * Creates a new string by concatenating the left and the right strings 444 * passed in as parameters. 445 */ 446 static Local<String> Concat(Isolate* isolate, Local<String> left, 447 Local<String> right); 448 449 /** 450 * Creates a new external string using the data defined in the given 451 * resource. When the external string is no longer live on V8's heap the 452 * resource will be disposed by calling its Dispose method. The caller of 453 * this function should not otherwise delete or modify the resource. Neither 454 * should the underlying buffer be deallocated or modified except through the 455 * destructor of the external string resource. 456 */ 457 static V8_WARN_UNUSED_RESULT MaybeLocal<String> NewExternalTwoByte( 458 Isolate* isolate, ExternalStringResource* resource); 459 460 /** 461 * Associate an external string resource with this string by transforming it 462 * in place so that existing references to this string in the JavaScript heap 463 * will use the external string resource. The external string resource's 464 * character contents need to be equivalent to this string. 465 * Returns true if the string has been changed to be an external string. 466 * The string is not modified if the operation fails. See NewExternal for 467 * information on the lifetime of the resource. 468 */ 469 bool MakeExternal(ExternalStringResource* resource); 470 471 /** 472 * Creates a new external string using the one-byte data defined in the given 473 * resource. When the external string is no longer live on V8's heap the 474 * resource will be disposed by calling its Dispose method. The caller of 475 * this function should not otherwise delete or modify the resource. Neither 476 * should the underlying buffer be deallocated or modified except through the 477 * destructor of the external string resource. 478 */ 479 static V8_WARN_UNUSED_RESULT MaybeLocal<String> NewExternalOneByte( 480 Isolate* isolate, ExternalOneByteStringResource* resource); 481 482 /** 483 * Associate an external string resource with this string by transforming it 484 * in place so that existing references to this string in the JavaScript heap 485 * will use the external string resource. The external string resource's 486 * character contents need to be equivalent to this string. 487 * Returns true if the string has been changed to be an external string. 488 * The string is not modified if the operation fails. See NewExternal for 489 * information on the lifetime of the resource. 490 */ 491 bool MakeExternal(ExternalOneByteStringResource* resource); 492 493 /** 494 * Returns true if this string can be made external. 495 */ 496 V8_DEPRECATED("Use the version that takes an encoding as argument.") 497 bool CanMakeExternal() const; 498 499 /** 500 * Returns true if this string can be made external, given the encoding for 501 * the external string resource. 502 */ 503 bool CanMakeExternal(Encoding encoding) const; 504 505 /** 506 * Returns true if the strings values are equal. Same as JS ==/===. 507 */ 508 bool StringEquals(Local<String> str) const; 509 510 /** 511 * Converts an object to a UTF-8-encoded character array. Useful if 512 * you want to print the object. If conversion to a string fails 513 * (e.g. due to an exception in the toString() method of the object) 514 * then the length() method returns 0 and the * operator returns 515 * NULL. 516 */ 517 class V8_EXPORT Utf8Value { 518 public: 519 Utf8Value(Isolate* isolate, Local<v8::Value> obj); 520 ~Utf8Value(); 521 char* operator*() { return str_; } 522 const char* operator*() const { return str_; } 523 int length() const { return length_; } 524 525 // Disallow copying and assigning. 526 Utf8Value(const Utf8Value&) = delete; 527 void operator=(const Utf8Value&) = delete; 528 529 private: 530 char* str_; 531 int length_; 532 }; 533 534 /** 535 * Converts an object to a two-byte (UTF-16-encoded) string. 536 * If conversion to a string fails (eg. due to an exception in the toString() 537 * method of the object) then the length() method returns 0 and the * operator 538 * returns NULL. 539 */ 540 class V8_EXPORT Value { 541 public: 542 Value(Isolate* isolate, Local<v8::Value> obj); 543 ~Value(); 544 uint16_t* operator*() { return str_; } 545 const uint16_t* operator*() const { return str_; } 546 int length() const { return length_; } 547 548 // Disallow copying and assigning. 549 Value(const Value&) = delete; 550 void operator=(const Value&) = delete; 551 552 private: 553 uint16_t* str_; 554 int length_; 555 }; 556 557 private: 558 void VerifyExternalStringResourceBase(ExternalStringResourceBase* v, 559 Encoding encoding) const; 560 void VerifyExternalStringResource(ExternalStringResource* val) const; 561 ExternalStringResource* GetExternalStringResourceSlow() const; 562 ExternalStringResourceBase* GetExternalStringResourceBaseSlow( 563 String::Encoding* encoding_out) const; 564 565 static Local<v8::String> NewFromUtf8Literal(Isolate* isolate, 566 const char* literal, 567 NewStringType type, int length); 568 569 static void CheckCast(v8::Data* that); 570}; 571 572// Zero-length string specialization (templated string size includes 573// terminator). 574template <> 575inline V8_WARN_UNUSED_RESULT Local<String> String::NewFromUtf8Literal( 576 Isolate* isolate, const char (&literal)[1], NewStringType type) { 577 return String::Empty(isolate); 578} 579 580/** 581 * Interface for iterating through all external resources in the heap. 582 */ 583class V8_EXPORT ExternalResourceVisitor { 584 public: 585 virtual ~ExternalResourceVisitor() = default; 586 virtual void VisitExternalString(Local<String> string) {} 587}; 588 589/** 590 * A JavaScript symbol (ECMA-262 edition 6) 591 */ 592class V8_EXPORT Symbol : public Name { 593 public: 594 /** 595 * Returns the description string of the symbol, or undefined if none. 596 */ 597 Local<Value> Description(Isolate* isolate) const; 598 599 /** 600 * Create a symbol. If description is not empty, it will be used as the 601 * description. 602 */ 603 static Local<Symbol> New(Isolate* isolate, 604 Local<String> description = Local<String>()); 605 606 /** 607 * Access global symbol registry. 608 * Note that symbols created this way are never collected, so 609 * they should only be used for statically fixed properties. 610 * Also, there is only one global name space for the descriptions used as 611 * keys. 612 * To minimize the potential for clashes, use qualified names as keys. 613 */ 614 static Local<Symbol> For(Isolate* isolate, Local<String> description); 615 616 /** 617 * Retrieve a global symbol. Similar to |For|, but using a separate 618 * registry that is not accessible by (and cannot clash with) JavaScript code. 619 */ 620 static Local<Symbol> ForApi(Isolate* isolate, Local<String> description); 621 622 // Well-known symbols 623 static Local<Symbol> GetAsyncIterator(Isolate* isolate); 624 static Local<Symbol> GetHasInstance(Isolate* isolate); 625 static Local<Symbol> GetIsConcatSpreadable(Isolate* isolate); 626 static Local<Symbol> GetIterator(Isolate* isolate); 627 static Local<Symbol> GetMatch(Isolate* isolate); 628 static Local<Symbol> GetReplace(Isolate* isolate); 629 static Local<Symbol> GetSearch(Isolate* isolate); 630 static Local<Symbol> GetSplit(Isolate* isolate); 631 static Local<Symbol> GetToPrimitive(Isolate* isolate); 632 static Local<Symbol> GetToStringTag(Isolate* isolate); 633 static Local<Symbol> GetUnscopables(Isolate* isolate); 634 635 V8_INLINE static Symbol* Cast(Data* data) { 636#ifdef V8_ENABLE_CHECKS 637 CheckCast(data); 638#endif 639 return static_cast<Symbol*>(data); 640 } 641 642 private: 643 Symbol(); 644 static void CheckCast(Data* that); 645}; 646 647/** 648 * A JavaScript number value (ECMA-262, 4.3.20) 649 */ 650class V8_EXPORT Number : public Primitive { 651 public: 652 double Value() const; 653 static Local<Number> New(Isolate* isolate, double value); 654 V8_INLINE static Number* Cast(v8::Data* data) { 655#ifdef V8_ENABLE_CHECKS 656 CheckCast(data); 657#endif 658 return static_cast<Number*>(data); 659 } 660 661 private: 662 Number(); 663 static void CheckCast(v8::Data* that); 664}; 665 666/** 667 * A JavaScript value representing a signed integer. 668 */ 669class V8_EXPORT Integer : public Number { 670 public: 671 static Local<Integer> New(Isolate* isolate, int32_t value); 672 static Local<Integer> NewFromUnsigned(Isolate* isolate, uint32_t value); 673 int64_t Value() const; 674 V8_INLINE static Integer* Cast(v8::Data* data) { 675#ifdef V8_ENABLE_CHECKS 676 CheckCast(data); 677#endif 678 return static_cast<Integer*>(data); 679 } 680 681 private: 682 Integer(); 683 static void CheckCast(v8::Data* that); 684}; 685 686/** 687 * A JavaScript value representing a 32-bit signed integer. 688 */ 689class V8_EXPORT Int32 : public Integer { 690 public: 691 int32_t Value() const; 692 V8_INLINE static Int32* Cast(v8::Data* data) { 693#ifdef V8_ENABLE_CHECKS 694 CheckCast(data); 695#endif 696 return static_cast<Int32*>(data); 697 } 698 699 private: 700 Int32(); 701 static void CheckCast(v8::Data* that); 702}; 703 704/** 705 * A JavaScript value representing a 32-bit unsigned integer. 706 */ 707class V8_EXPORT Uint32 : public Integer { 708 public: 709 uint32_t Value() const; 710 V8_INLINE static Uint32* Cast(v8::Data* data) { 711#ifdef V8_ENABLE_CHECKS 712 CheckCast(data); 713#endif 714 return static_cast<Uint32*>(data); 715 } 716 717 private: 718 Uint32(); 719 static void CheckCast(v8::Data* that); 720}; 721 722/** 723 * A JavaScript BigInt value (https://tc39.github.io/proposal-bigint) 724 */ 725class V8_EXPORT BigInt : public Primitive { 726 public: 727 static Local<BigInt> New(Isolate* isolate, int64_t value); 728 static Local<BigInt> NewFromUnsigned(Isolate* isolate, uint64_t value); 729 /** 730 * Creates a new BigInt object using a specified sign bit and a 731 * specified list of digits/words. 732 * The resulting number is calculated as: 733 * 734 * (-1)^sign_bit * (words[0] * (2^64)^0 + words[1] * (2^64)^1 + ...) 735 */ 736 static MaybeLocal<BigInt> NewFromWords(Local<Context> context, int sign_bit, 737 int word_count, const uint64_t* words); 738 739 /** 740 * Returns the value of this BigInt as an unsigned 64-bit integer. 741 * If `lossless` is provided, it will reflect whether the return value was 742 * truncated or wrapped around. In particular, it is set to `false` if this 743 * BigInt is negative. 744 */ 745 uint64_t Uint64Value(bool* lossless = nullptr) const; 746 747 /** 748 * Returns the value of this BigInt as a signed 64-bit integer. 749 * If `lossless` is provided, it will reflect whether this BigInt was 750 * truncated or not. 751 */ 752 int64_t Int64Value(bool* lossless = nullptr) const; 753 754 /** 755 * Returns the number of 64-bit words needed to store the result of 756 * ToWordsArray(). 757 */ 758 int WordCount() const; 759 760 /** 761 * Writes the contents of this BigInt to a specified memory location. 762 * `sign_bit` must be provided and will be set to 1 if this BigInt is 763 * negative. 764 * `*word_count` has to be initialized to the length of the `words` array. 765 * Upon return, it will be set to the actual number of words that would 766 * be needed to store this BigInt (i.e. the return value of `WordCount()`). 767 */ 768 void ToWordsArray(int* sign_bit, int* word_count, uint64_t* words) const; 769 770 V8_INLINE static BigInt* Cast(v8::Data* data) { 771#ifdef V8_ENABLE_CHECKS 772 CheckCast(data); 773#endif 774 return static_cast<BigInt*>(data); 775 } 776 777 private: 778 BigInt(); 779 static void CheckCast(v8::Data* that); 780}; 781 782Local<String> String::Empty(Isolate* isolate) { 783 using S = internal::Address; 784 using I = internal::Internals; 785 I::CheckInitialized(isolate); 786 S* slot = I::GetRootSlot(isolate, I::kEmptyStringRootIndex); 787 return Local<String>::FromSlot(slot); 788} 789 790String::ExternalStringResource* String::GetExternalStringResource() const { 791 using A = internal::Address; 792 using I = internal::Internals; 793 A obj = internal::ValueHelper::ValueAsAddress(this); 794 795 ExternalStringResource* result; 796 if (I::IsExternalTwoByteString(I::GetInstanceType(obj))) { 797 Isolate* isolate = I::GetIsolateForSandbox(obj); 798 A value = I::ReadExternalPointerField<internal::kExternalStringResourceTag>( 799 isolate, obj, I::kStringResourceOffset); 800 result = reinterpret_cast<String::ExternalStringResource*>(value); 801 } else { 802 result = GetExternalStringResourceSlow(); 803 } 804#ifdef V8_ENABLE_CHECKS 805 VerifyExternalStringResource(result); 806#endif 807 return result; 808} 809 810String::ExternalStringResourceBase* String::GetExternalStringResourceBase( 811 String::Encoding* encoding_out) const { 812 using A = internal::Address; 813 using I = internal::Internals; 814 A obj = internal::ValueHelper::ValueAsAddress(this); 815 int type = I::GetInstanceType(obj) & I::kStringRepresentationAndEncodingMask; 816 *encoding_out = static_cast<Encoding>(type & I::kStringEncodingMask); 817 ExternalStringResourceBase* resource; 818 if (type == I::kExternalOneByteRepresentationTag || 819 type == I::kExternalTwoByteRepresentationTag) { 820 Isolate* isolate = I::GetIsolateForSandbox(obj); 821 A value = I::ReadExternalPointerField<internal::kExternalStringResourceTag>( 822 isolate, obj, I::kStringResourceOffset); 823 resource = reinterpret_cast<ExternalStringResourceBase*>(value); 824 } else { 825 resource = GetExternalStringResourceBaseSlow(encoding_out); 826 } 827#ifdef V8_ENABLE_CHECKS 828 VerifyExternalStringResourceBase(resource, *encoding_out); 829#endif 830 return resource; 831} 832 833// --- Statics --- 834 835V8_INLINE Local<Primitive> Undefined(Isolate* isolate) { 836 using S = internal::Address; 837 using I = internal::Internals; 838 I::CheckInitialized(isolate); 839 S* slot = I::GetRootSlot(isolate, I::kUndefinedValueRootIndex); 840 return Local<Primitive>::FromSlot(slot); 841} 842 843V8_INLINE Local<Primitive> Null(Isolate* isolate) { 844 using S = internal::Address; 845 using I = internal::Internals; 846 I::CheckInitialized(isolate); 847 S* slot = I::GetRootSlot(isolate, I::kNullValueRootIndex); 848 return Local<Primitive>::FromSlot(slot); 849} 850 851V8_INLINE Local<Boolean> True(Isolate* isolate) { 852 using S = internal::Address; 853 using I = internal::Internals; 854 I::CheckInitialized(isolate); 855 S* slot = I::GetRootSlot(isolate, I::kTrueValueRootIndex); 856 return Local<Boolean>::FromSlot(slot); 857} 858 859V8_INLINE Local<Boolean> False(Isolate* isolate) { 860 using S = internal::Address; 861 using I = internal::Internals; 862 I::CheckInitialized(isolate); 863 S* slot = I::GetRootSlot(isolate, I::kFalseValueRootIndex); 864 return Local<Boolean>::FromSlot(slot); 865} 866 867Local<Boolean> Boolean::New(Isolate* isolate, bool value) { 868 return value ? True(isolate) : False(isolate); 869} 870 871} // namespace v8 872 873#endif // INCLUDE_V8_PRIMITIVE_H_ 874