1// Copyright 2012 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 V8_GLOBALS_H_ 6#define V8_GLOBALS_H_ 7 8#include "include/v8stdint.h" 9 10#include "src/base/build_config.h" 11#include "src/base/logging.h" 12#include "src/base/macros.h" 13 14// Unfortunately, the INFINITY macro cannot be used with the '-pedantic' 15// warning flag and certain versions of GCC due to a bug: 16// http://gcc.gnu.org/bugzilla/show_bug.cgi?id=11931 17// For now, we use the more involved template-based version from <limits>, but 18// only when compiling with GCC versions affected by the bug (2.96.x - 4.0.x) 19#if V8_CC_GNU && V8_GNUC_PREREQ(2, 96, 0) && !V8_GNUC_PREREQ(4, 1, 0) 20# include <limits> // NOLINT 21# define V8_INFINITY std::numeric_limits<double>::infinity() 22#elif V8_LIBC_MSVCRT 23# define V8_INFINITY HUGE_VAL 24#else 25# define V8_INFINITY INFINITY 26#endif 27 28#if V8_TARGET_ARCH_IA32 || V8_TARGET_ARCH_X64 || V8_TARGET_ARCH_ARM || \ 29 V8_TARGET_ARCH_ARM64 30#define V8_TURBOFAN_BACKEND 1 31#else 32#define V8_TURBOFAN_BACKEND 0 33#endif 34#if V8_TURBOFAN_BACKEND && !(V8_OS_WIN && V8_TARGET_ARCH_X64) 35#define V8_TURBOFAN_TARGET 1 36#else 37#define V8_TURBOFAN_TARGET 0 38#endif 39 40namespace v8 { 41 42namespace base { 43class Mutex; 44class RecursiveMutex; 45class VirtualMemory; 46} 47 48namespace internal { 49 50// Determine whether we are running in a simulated environment. 51// Setting USE_SIMULATOR explicitly from the build script will force 52// the use of a simulated environment. 53#if !defined(USE_SIMULATOR) 54#if (V8_TARGET_ARCH_ARM64 && !V8_HOST_ARCH_ARM64) 55#define USE_SIMULATOR 1 56#endif 57#if (V8_TARGET_ARCH_ARM && !V8_HOST_ARCH_ARM) 58#define USE_SIMULATOR 1 59#endif 60#if (V8_TARGET_ARCH_MIPS && !V8_HOST_ARCH_MIPS) 61#define USE_SIMULATOR 1 62#endif 63#if (V8_TARGET_ARCH_MIPS64 && !V8_HOST_ARCH_MIPS64) 64#define USE_SIMULATOR 1 65#endif 66#endif 67 68// Determine whether the architecture uses an out-of-line constant pool. 69#define V8_OOL_CONSTANT_POOL 0 70 71#ifdef V8_TARGET_ARCH_ARM 72// Set stack limit lower for ARM than for other architectures because 73// stack allocating MacroAssembler takes 120K bytes. 74// See issue crbug.com/405338 75#define V8_DEFAULT_STACK_SIZE_KB 864 76#else 77// Slightly less than 1MB, since Windows' default stack size for 78// the main execution thread is 1MB for both 32 and 64-bit. 79#define V8_DEFAULT_STACK_SIZE_KB 984 80#endif 81 82 83// Support for alternative bool type. This is only enabled if the code is 84// compiled with USE_MYBOOL defined. This catches some nasty type bugs. 85// For instance, 'bool b = "false";' results in b == true! This is a hidden 86// source of bugs. 87// However, redefining the bool type does have some negative impact on some 88// platforms. It gives rise to compiler warnings (i.e. with 89// MSVC) in the API header files when mixing code that uses the standard 90// bool with code that uses the redefined version. 91// This does not actually belong in the platform code, but needs to be 92// defined here because the platform code uses bool, and platform.h is 93// include very early in the main include file. 94 95#ifdef USE_MYBOOL 96typedef unsigned int __my_bool__; 97#define bool __my_bool__ // use 'indirection' to avoid name clashes 98#endif 99 100typedef uint8_t byte; 101typedef byte* Address; 102 103// ----------------------------------------------------------------------------- 104// Constants 105 106const int KB = 1024; 107const int MB = KB * KB; 108const int GB = KB * KB * KB; 109const int kMaxInt = 0x7FFFFFFF; 110const int kMinInt = -kMaxInt - 1; 111const int kMaxInt8 = (1 << 7) - 1; 112const int kMinInt8 = -(1 << 7); 113const int kMaxUInt8 = (1 << 8) - 1; 114const int kMinUInt8 = 0; 115const int kMaxInt16 = (1 << 15) - 1; 116const int kMinInt16 = -(1 << 15); 117const int kMaxUInt16 = (1 << 16) - 1; 118const int kMinUInt16 = 0; 119 120const uint32_t kMaxUInt32 = 0xFFFFFFFFu; 121 122const int kCharSize = sizeof(char); // NOLINT 123const int kShortSize = sizeof(short); // NOLINT 124const int kIntSize = sizeof(int); // NOLINT 125const int kInt32Size = sizeof(int32_t); // NOLINT 126const int kInt64Size = sizeof(int64_t); // NOLINT 127const int kDoubleSize = sizeof(double); // NOLINT 128const int kIntptrSize = sizeof(intptr_t); // NOLINT 129const int kPointerSize = sizeof(void*); // NOLINT 130#if V8_TARGET_ARCH_X64 && V8_TARGET_ARCH_32_BIT 131const int kRegisterSize = kPointerSize + kPointerSize; 132#else 133const int kRegisterSize = kPointerSize; 134#endif 135const int kPCOnStackSize = kRegisterSize; 136const int kFPOnStackSize = kRegisterSize; 137 138const int kDoubleSizeLog2 = 3; 139 140#if V8_HOST_ARCH_64_BIT 141const int kPointerSizeLog2 = 3; 142const intptr_t kIntptrSignBit = V8_INT64_C(0x8000000000000000); 143const uintptr_t kUintptrAllBitsSet = V8_UINT64_C(0xFFFFFFFFFFFFFFFF); 144const bool kRequiresCodeRange = true; 145const size_t kMaximalCodeRangeSize = 512 * MB; 146#else 147const int kPointerSizeLog2 = 2; 148const intptr_t kIntptrSignBit = 0x80000000; 149const uintptr_t kUintptrAllBitsSet = 0xFFFFFFFFu; 150#if V8_TARGET_ARCH_X64 && V8_TARGET_ARCH_32_BIT 151// x32 port also requires code range. 152const bool kRequiresCodeRange = true; 153const size_t kMaximalCodeRangeSize = 256 * MB; 154#else 155const bool kRequiresCodeRange = false; 156const size_t kMaximalCodeRangeSize = 0 * MB; 157#endif 158#endif 159 160STATIC_ASSERT(kPointerSize == (1 << kPointerSizeLog2)); 161 162const int kBitsPerByte = 8; 163const int kBitsPerByteLog2 = 3; 164const int kBitsPerPointer = kPointerSize * kBitsPerByte; 165const int kBitsPerInt = kIntSize * kBitsPerByte; 166 167// IEEE 754 single precision floating point number bit layout. 168const uint32_t kBinary32SignMask = 0x80000000u; 169const uint32_t kBinary32ExponentMask = 0x7f800000u; 170const uint32_t kBinary32MantissaMask = 0x007fffffu; 171const int kBinary32ExponentBias = 127; 172const int kBinary32MaxExponent = 0xFE; 173const int kBinary32MinExponent = 0x01; 174const int kBinary32MantissaBits = 23; 175const int kBinary32ExponentShift = 23; 176 177// Quiet NaNs have bits 51 to 62 set, possibly the sign bit, and no 178// other bits set. 179const uint64_t kQuietNaNMask = static_cast<uint64_t>(0xfff) << 51; 180 181// Latin1/UTF-16 constants 182// Code-point values in Unicode 4.0 are 21 bits wide. 183// Code units in UTF-16 are 16 bits wide. 184typedef uint16_t uc16; 185typedef int32_t uc32; 186const int kOneByteSize = kCharSize; 187const int kUC16Size = sizeof(uc16); // NOLINT 188 189 190// Round up n to be a multiple of sz, where sz is a power of 2. 191#define ROUND_UP(n, sz) (((n) + ((sz) - 1)) & ~((sz) - 1)) 192 193 194// FUNCTION_ADDR(f) gets the address of a C function f. 195#define FUNCTION_ADDR(f) \ 196 (reinterpret_cast<v8::internal::Address>(reinterpret_cast<intptr_t>(f))) 197 198 199// FUNCTION_CAST<F>(addr) casts an address into a function 200// of type F. Used to invoke generated code from within C. 201template <typename F> 202F FUNCTION_CAST(Address addr) { 203 return reinterpret_cast<F>(reinterpret_cast<intptr_t>(addr)); 204} 205 206 207// ----------------------------------------------------------------------------- 208// Forward declarations for frequently used classes 209// (sorted alphabetically) 210 211class FreeStoreAllocationPolicy; 212template <typename T, class P = FreeStoreAllocationPolicy> class List; 213 214// ----------------------------------------------------------------------------- 215// Declarations for use in both the preparser and the rest of V8. 216 217// The Strict Mode (ECMA-262 5th edition, 4.2.2). 218 219enum StrictMode { SLOPPY, STRICT }; 220 221 222// Mask for the sign bit in a smi. 223const intptr_t kSmiSignMask = kIntptrSignBit; 224 225const int kObjectAlignmentBits = kPointerSizeLog2; 226const intptr_t kObjectAlignment = 1 << kObjectAlignmentBits; 227const intptr_t kObjectAlignmentMask = kObjectAlignment - 1; 228 229// Desired alignment for pointers. 230const intptr_t kPointerAlignment = (1 << kPointerSizeLog2); 231const intptr_t kPointerAlignmentMask = kPointerAlignment - 1; 232 233// Desired alignment for double values. 234const intptr_t kDoubleAlignment = 8; 235const intptr_t kDoubleAlignmentMask = kDoubleAlignment - 1; 236 237// Desired alignment for generated code is 32 bytes (to improve cache line 238// utilization). 239const int kCodeAlignmentBits = 5; 240const intptr_t kCodeAlignment = 1 << kCodeAlignmentBits; 241const intptr_t kCodeAlignmentMask = kCodeAlignment - 1; 242 243// The owner field of a page is tagged with the page header tag. We need that 244// to find out if a slot is part of a large object. If we mask out the lower 245// 0xfffff bits (1M pages), go to the owner offset, and see that this field 246// is tagged with the page header tag, we can just look up the owner. 247// Otherwise, we know that we are somewhere (not within the first 1M) in a 248// large object. 249const int kPageHeaderTag = 3; 250const int kPageHeaderTagSize = 2; 251const intptr_t kPageHeaderTagMask = (1 << kPageHeaderTagSize) - 1; 252 253 254// Zap-value: The value used for zapping dead objects. 255// Should be a recognizable hex value tagged as a failure. 256#ifdef V8_HOST_ARCH_64_BIT 257const Address kZapValue = 258 reinterpret_cast<Address>(V8_UINT64_C(0xdeadbeedbeadbeef)); 259const Address kHandleZapValue = 260 reinterpret_cast<Address>(V8_UINT64_C(0x1baddead0baddeaf)); 261const Address kGlobalHandleZapValue = 262 reinterpret_cast<Address>(V8_UINT64_C(0x1baffed00baffedf)); 263const Address kFromSpaceZapValue = 264 reinterpret_cast<Address>(V8_UINT64_C(0x1beefdad0beefdaf)); 265const uint64_t kDebugZapValue = V8_UINT64_C(0xbadbaddbbadbaddb); 266const uint64_t kSlotsZapValue = V8_UINT64_C(0xbeefdeadbeefdeef); 267const uint64_t kFreeListZapValue = 0xfeed1eaffeed1eaf; 268#else 269const Address kZapValue = reinterpret_cast<Address>(0xdeadbeef); 270const Address kHandleZapValue = reinterpret_cast<Address>(0xbaddeaf); 271const Address kGlobalHandleZapValue = reinterpret_cast<Address>(0xbaffedf); 272const Address kFromSpaceZapValue = reinterpret_cast<Address>(0xbeefdaf); 273const uint32_t kSlotsZapValue = 0xbeefdeef; 274const uint32_t kDebugZapValue = 0xbadbaddb; 275const uint32_t kFreeListZapValue = 0xfeed1eaf; 276#endif 277 278const int kCodeZapValue = 0xbadc0de; 279 280// On Intel architecture, cache line size is 64 bytes. 281// On ARM it may be less (32 bytes), but as far this constant is 282// used for aligning data, it doesn't hurt to align on a greater value. 283#define PROCESSOR_CACHE_LINE_SIZE 64 284 285// Constants relevant to double precision floating point numbers. 286// If looking only at the top 32 bits, the QNaN mask is bits 19 to 30. 287const uint32_t kQuietNaNHighBitsMask = 0xfff << (51 - 32); 288 289 290// ----------------------------------------------------------------------------- 291// Forward declarations for frequently used classes 292 293class AccessorInfo; 294class Allocation; 295class Arguments; 296class Assembler; 297class Code; 298class CodeGenerator; 299class CodeStub; 300class Context; 301class Debug; 302class Debugger; 303class DebugInfo; 304class Descriptor; 305class DescriptorArray; 306class TransitionArray; 307class ExternalReference; 308class FixedArray; 309class FunctionTemplateInfo; 310class MemoryChunk; 311class SeededNumberDictionary; 312class UnseededNumberDictionary; 313class NameDictionary; 314template <typename T> class MaybeHandle; 315template <typename T> class Handle; 316class Heap; 317class HeapObject; 318class IC; 319class InterceptorInfo; 320class Isolate; 321class JSReceiver; 322class JSArray; 323class JSFunction; 324class JSObject; 325class LargeObjectSpace; 326class LookupResult; 327class MacroAssembler; 328class Map; 329class MapSpace; 330class MarkCompactCollector; 331class NewSpace; 332class Object; 333class OldSpace; 334class Foreign; 335class Scope; 336class ScopeInfo; 337class Script; 338class Smi; 339template <typename Config, class Allocator = FreeStoreAllocationPolicy> 340 class SplayTree; 341class String; 342class Name; 343class Struct; 344class Variable; 345class RelocInfo; 346class Deserializer; 347class MessageLocation; 348 349typedef bool (*WeakSlotCallback)(Object** pointer); 350 351typedef bool (*WeakSlotCallbackWithHeap)(Heap* heap, Object** pointer); 352 353// ----------------------------------------------------------------------------- 354// Miscellaneous 355 356// NOTE: SpaceIterator depends on AllocationSpace enumeration values being 357// consecutive. 358enum AllocationSpace { 359 NEW_SPACE, // Semispaces collected with copying collector. 360 OLD_POINTER_SPACE, // May contain pointers to new space. 361 OLD_DATA_SPACE, // Must not have pointers to new space. 362 CODE_SPACE, // No pointers to new space, marked executable. 363 MAP_SPACE, // Only and all map objects. 364 CELL_SPACE, // Only and all cell objects. 365 PROPERTY_CELL_SPACE, // Only and all global property cell objects. 366 LO_SPACE, // Promoted large objects. 367 INVALID_SPACE, // Only used in AllocationResult to signal success. 368 369 FIRST_SPACE = NEW_SPACE, 370 LAST_SPACE = LO_SPACE, 371 FIRST_PAGED_SPACE = OLD_POINTER_SPACE, 372 LAST_PAGED_SPACE = PROPERTY_CELL_SPACE 373}; 374const int kSpaceTagSize = 3; 375const int kSpaceTagMask = (1 << kSpaceTagSize) - 1; 376 377 378// A flag that indicates whether objects should be pretenured when 379// allocated (allocated directly into the old generation) or not 380// (allocated in the young generation if the object size and type 381// allows). 382enum PretenureFlag { NOT_TENURED, TENURED }; 383 384enum MinimumCapacity { 385 USE_DEFAULT_MINIMUM_CAPACITY, 386 USE_CUSTOM_MINIMUM_CAPACITY 387}; 388 389enum GarbageCollector { SCAVENGER, MARK_COMPACTOR }; 390 391enum Executability { NOT_EXECUTABLE, EXECUTABLE }; 392 393enum VisitMode { 394 VISIT_ALL, 395 VISIT_ALL_IN_SCAVENGE, 396 VISIT_ALL_IN_SWEEP_NEWSPACE, 397 VISIT_ONLY_STRONG 398}; 399 400// Flag indicating whether code is built into the VM (one of the natives files). 401enum NativesFlag { NOT_NATIVES_CODE, NATIVES_CODE }; 402 403 404// A CodeDesc describes a buffer holding instructions and relocation 405// information. The instructions start at the beginning of the buffer 406// and grow forward, the relocation information starts at the end of 407// the buffer and grows backward. 408// 409// |<--------------- buffer_size ---------------->| 410// |<-- instr_size -->| |<-- reloc_size -->| 411// +==================+========+==================+ 412// | instructions | free | reloc info | 413// +==================+========+==================+ 414// ^ 415// | 416// buffer 417 418struct CodeDesc { 419 byte* buffer; 420 int buffer_size; 421 int instr_size; 422 int reloc_size; 423 Assembler* origin; 424}; 425 426 427// Callback function used for iterating objects in heap spaces, 428// for example, scanning heap objects. 429typedef int (*HeapObjectCallback)(HeapObject* obj); 430 431 432// Callback function used for checking constraints when copying/relocating 433// objects. Returns true if an object can be copied/relocated from its 434// old_addr to a new_addr. 435typedef bool (*ConstraintCallback)(Address new_addr, Address old_addr); 436 437 438// Callback function on inline caches, used for iterating over inline caches 439// in compiled code. 440typedef void (*InlineCacheCallback)(Code* code, Address ic); 441 442 443// State for inline cache call sites. Aliased as IC::State. 444enum InlineCacheState { 445 // Has never been executed. 446 UNINITIALIZED, 447 // Has been executed but monomorhic state has been delayed. 448 PREMONOMORPHIC, 449 // Has been executed and only one receiver type has been seen. 450 MONOMORPHIC, 451 // Check failed due to prototype (or map deprecation). 452 PROTOTYPE_FAILURE, 453 // Multiple receiver types have been seen. 454 POLYMORPHIC, 455 // Many receiver types have been seen. 456 MEGAMORPHIC, 457 // A generic handler is installed and no extra typefeedback is recorded. 458 GENERIC, 459 // Special state for debug break or step in prepare stubs. 460 DEBUG_STUB, 461 // Type-vector-based ICs have a default state, with the full calculation 462 // of IC state only determined by a look at the IC and the typevector 463 // together. 464 DEFAULT 465}; 466 467 468enum CallFunctionFlags { 469 NO_CALL_FUNCTION_FLAGS, 470 CALL_AS_METHOD, 471 // Always wrap the receiver and call to the JSFunction. Only use this flag 472 // both the receiver type and the target method are statically known. 473 WRAP_AND_CALL 474}; 475 476 477enum CallConstructorFlags { 478 NO_CALL_CONSTRUCTOR_FLAGS, 479 // The call target is cached in the instruction stream. 480 RECORD_CONSTRUCTOR_TARGET 481}; 482 483 484enum CacheHolderFlag { 485 kCacheOnPrototype, 486 kCacheOnPrototypeReceiverIsDictionary, 487 kCacheOnPrototypeReceiverIsPrimitive, 488 kCacheOnReceiver 489}; 490 491 492// The Store Buffer (GC). 493typedef enum { 494 kStoreBufferFullEvent, 495 kStoreBufferStartScanningPagesEvent, 496 kStoreBufferScanningPageEvent 497} StoreBufferEvent; 498 499 500typedef void (*StoreBufferCallback)(Heap* heap, 501 MemoryChunk* page, 502 StoreBufferEvent event); 503 504 505// Union used for fast testing of specific double values. 506union DoubleRepresentation { 507 double value; 508 int64_t bits; 509 DoubleRepresentation(double x) { value = x; } 510 bool operator==(const DoubleRepresentation& other) const { 511 return bits == other.bits; 512 } 513}; 514 515 516// Union used for customized checking of the IEEE double types 517// inlined within v8 runtime, rather than going to the underlying 518// platform headers and libraries 519union IeeeDoubleLittleEndianArchType { 520 double d; 521 struct { 522 unsigned int man_low :32; 523 unsigned int man_high :20; 524 unsigned int exp :11; 525 unsigned int sign :1; 526 } bits; 527}; 528 529 530union IeeeDoubleBigEndianArchType { 531 double d; 532 struct { 533 unsigned int sign :1; 534 unsigned int exp :11; 535 unsigned int man_high :20; 536 unsigned int man_low :32; 537 } bits; 538}; 539 540 541// AccessorCallback 542struct AccessorDescriptor { 543 Object* (*getter)(Isolate* isolate, Object* object, void* data); 544 Object* (*setter)( 545 Isolate* isolate, JSObject* object, Object* value, void* data); 546 void* data; 547}; 548 549 550// Logging and profiling. A StateTag represents a possible state of 551// the VM. The logger maintains a stack of these. Creating a VMState 552// object enters a state by pushing on the stack, and destroying a 553// VMState object leaves a state by popping the current state from the 554// stack. 555 556enum StateTag { 557 JS, 558 GC, 559 COMPILER, 560 OTHER, 561 EXTERNAL, 562 IDLE 563}; 564 565 566// ----------------------------------------------------------------------------- 567// Macros 568 569// Testers for test. 570 571#define HAS_SMI_TAG(value) \ 572 ((reinterpret_cast<intptr_t>(value) & kSmiTagMask) == kSmiTag) 573 574#define HAS_FAILURE_TAG(value) \ 575 ((reinterpret_cast<intptr_t>(value) & kFailureTagMask) == kFailureTag) 576 577// OBJECT_POINTER_ALIGN returns the value aligned as a HeapObject pointer 578#define OBJECT_POINTER_ALIGN(value) \ 579 (((value) + kObjectAlignmentMask) & ~kObjectAlignmentMask) 580 581// POINTER_SIZE_ALIGN returns the value aligned as a pointer. 582#define POINTER_SIZE_ALIGN(value) \ 583 (((value) + kPointerAlignmentMask) & ~kPointerAlignmentMask) 584 585// CODE_POINTER_ALIGN returns the value aligned as a generated code segment. 586#define CODE_POINTER_ALIGN(value) \ 587 (((value) + kCodeAlignmentMask) & ~kCodeAlignmentMask) 588 589// Support for tracking C++ memory allocation. Insert TRACK_MEMORY("Fisk") 590// inside a C++ class and new and delete will be overloaded so logging is 591// performed. 592// This file (globals.h) is included before log.h, so we use direct calls to 593// the Logger rather than the LOG macro. 594#ifdef DEBUG 595#define TRACK_MEMORY(name) \ 596 void* operator new(size_t size) { \ 597 void* result = ::operator new(size); \ 598 Logger::NewEventStatic(name, result, size); \ 599 return result; \ 600 } \ 601 void operator delete(void* object) { \ 602 Logger::DeleteEventStatic(name, object); \ 603 ::operator delete(object); \ 604 } 605#else 606#define TRACK_MEMORY(name) 607#endif 608 609 610// CPU feature flags. 611enum CpuFeature { 612 // x86 613 SSE4_1, 614 SSE3, 615 SAHF, 616 // ARM 617 VFP3, 618 ARMv7, 619 SUDIV, 620 MLS, 621 UNALIGNED_ACCESSES, 622 MOVW_MOVT_IMMEDIATE_LOADS, 623 VFP32DREGS, 624 NEON, 625 // MIPS, MIPS64 626 FPU, 627 FP64FPU, 628 MIPSr1, 629 MIPSr2, 630 MIPSr6, 631 // ARM64 632 ALWAYS_ALIGN_CSP, 633 NUMBER_OF_CPU_FEATURES 634}; 635 636 637// Used to specify if a macro instruction must perform a smi check on tagged 638// values. 639enum SmiCheckType { 640 DONT_DO_SMI_CHECK, 641 DO_SMI_CHECK 642}; 643 644 645enum ScopeType { 646 EVAL_SCOPE, // The top-level scope for an eval source. 647 FUNCTION_SCOPE, // The top-level scope for a function. 648 MODULE_SCOPE, // The scope introduced by a module literal 649 GLOBAL_SCOPE, // The top-level scope for a program or a top-level eval. 650 CATCH_SCOPE, // The scope introduced by catch. 651 BLOCK_SCOPE, // The scope introduced by a new block. 652 WITH_SCOPE // The scope introduced by with. 653}; 654 655 656const uint32_t kHoleNanUpper32 = 0x7FFFFFFF; 657const uint32_t kHoleNanLower32 = 0xFFFFFFFF; 658const uint32_t kNaNOrInfinityLowerBoundUpper32 = 0x7FF00000; 659 660const uint64_t kHoleNanInt64 = 661 (static_cast<uint64_t>(kHoleNanUpper32) << 32) | kHoleNanLower32; 662const uint64_t kLastNonNaNInt64 = 663 (static_cast<uint64_t>(kNaNOrInfinityLowerBoundUpper32) << 32); 664 665 666// The order of this enum has to be kept in sync with the predicates below. 667enum VariableMode { 668 // User declared variables: 669 VAR, // declared via 'var', and 'function' declarations 670 671 CONST_LEGACY, // declared via legacy 'const' declarations 672 673 LET, // declared via 'let' declarations (first lexical) 674 675 CONST, // declared via 'const' declarations 676 677 MODULE, // declared via 'module' declaration (last lexical) 678 679 // Variables introduced by the compiler: 680 INTERNAL, // like VAR, but not user-visible (may or may not 681 // be in a context) 682 683 TEMPORARY, // temporary variables (not user-visible), stack-allocated 684 // unless the scope as a whole has forced context allocation 685 686 DYNAMIC, // always require dynamic lookup (we don't know 687 // the declaration) 688 689 DYNAMIC_GLOBAL, // requires dynamic lookup, but we know that the 690 // variable is global unless it has been shadowed 691 // by an eval-introduced variable 692 693 DYNAMIC_LOCAL // requires dynamic lookup, but we know that the 694 // variable is local and where it is unless it 695 // has been shadowed by an eval-introduced 696 // variable 697}; 698 699 700inline bool IsDynamicVariableMode(VariableMode mode) { 701 return mode >= DYNAMIC && mode <= DYNAMIC_LOCAL; 702} 703 704 705inline bool IsDeclaredVariableMode(VariableMode mode) { 706 return mode >= VAR && mode <= MODULE; 707} 708 709 710inline bool IsLexicalVariableMode(VariableMode mode) { 711 return mode >= LET && mode <= MODULE; 712} 713 714 715inline bool IsImmutableVariableMode(VariableMode mode) { 716 return (mode >= CONST && mode <= MODULE) || mode == CONST_LEGACY; 717} 718 719 720// ES6 Draft Rev3 10.2 specifies declarative environment records with mutable 721// and immutable bindings that can be in two states: initialized and 722// uninitialized. In ES5 only immutable bindings have these two states. When 723// accessing a binding, it needs to be checked for initialization. However in 724// the following cases the binding is initialized immediately after creation 725// so the initialization check can always be skipped: 726// 1. Var declared local variables. 727// var foo; 728// 2. A local variable introduced by a function declaration. 729// function foo() {} 730// 3. Parameters 731// function x(foo) {} 732// 4. Catch bound variables. 733// try {} catch (foo) {} 734// 6. Function variables of named function expressions. 735// var x = function foo() {} 736// 7. Implicit binding of 'this'. 737// 8. Implicit binding of 'arguments' in functions. 738// 739// ES5 specified object environment records which are introduced by ES elements 740// such as Program and WithStatement that associate identifier bindings with the 741// properties of some object. In the specification only mutable bindings exist 742// (which may be non-writable) and have no distinct initialization step. However 743// V8 allows const declarations in global code with distinct creation and 744// initialization steps which are represented by non-writable properties in the 745// global object. As a result also these bindings need to be checked for 746// initialization. 747// 748// The following enum specifies a flag that indicates if the binding needs a 749// distinct initialization step (kNeedsInitialization) or if the binding is 750// immediately initialized upon creation (kCreatedInitialized). 751enum InitializationFlag { 752 kNeedsInitialization, 753 kCreatedInitialized 754}; 755 756 757enum MaybeAssignedFlag { kNotAssigned, kMaybeAssigned }; 758 759 760enum ClearExceptionFlag { 761 KEEP_EXCEPTION, 762 CLEAR_EXCEPTION 763}; 764 765 766enum MinusZeroMode { 767 TREAT_MINUS_ZERO_AS_ZERO, 768 FAIL_ON_MINUS_ZERO 769}; 770 771 772enum Signedness { kSigned, kUnsigned }; 773 774 775enum FunctionKind { 776 kNormalFunction = 0, 777 kArrowFunction = 1, 778 kGeneratorFunction = 2, 779 kConciseMethod = 4, 780 kConciseGeneratorMethod = kGeneratorFunction | kConciseMethod 781}; 782 783 784inline bool IsValidFunctionKind(FunctionKind kind) { 785 return kind == FunctionKind::kNormalFunction || 786 kind == FunctionKind::kArrowFunction || 787 kind == FunctionKind::kGeneratorFunction || 788 kind == FunctionKind::kConciseMethod || 789 kind == FunctionKind::kConciseGeneratorMethod; 790} 791 792 793inline bool IsArrowFunction(FunctionKind kind) { 794 DCHECK(IsValidFunctionKind(kind)); 795 return kind & FunctionKind::kArrowFunction; 796} 797 798 799inline bool IsGeneratorFunction(FunctionKind kind) { 800 DCHECK(IsValidFunctionKind(kind)); 801 return kind & FunctionKind::kGeneratorFunction; 802} 803 804 805inline bool IsConciseMethod(FunctionKind kind) { 806 DCHECK(IsValidFunctionKind(kind)); 807 return kind & FunctionKind::kConciseMethod; 808} 809} } // namespace v8::internal 810 811namespace i = v8::internal; 812 813#endif // V8_GLOBALS_H_ 814