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