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 40 namespace v8 { 41 42 namespace base { 43 class Mutex; 44 class RecursiveMutex; 45 class VirtualMemory; 46 } 47 48 namespace 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 96 typedef unsigned int __my_bool__; 97 #define bool __my_bool__ // use 'indirection' to avoid name clashes 98 #endif 99 100 typedef uint8_t byte; 101 typedef byte* Address; 102 103 // ----------------------------------------------------------------------------- 104 // Constants 105 106 const int KB = 1024; 107 const int MB = KB * KB; 108 const int GB = KB * KB * KB; 109 const int kMaxInt = 0x7FFFFFFF; 110 const int kMinInt = -kMaxInt - 1; 111 const int kMaxInt8 = (1 << 7) - 1; 112 const int kMinInt8 = -(1 << 7); 113 const int kMaxUInt8 = (1 << 8) - 1; 114 const int kMinUInt8 = 0; 115 const int kMaxInt16 = (1 << 15) - 1; 116 const int kMinInt16 = -(1 << 15); 117 const int kMaxUInt16 = (1 << 16) - 1; 118 const int kMinUInt16 = 0; 119 120 const uint32_t kMaxUInt32 = 0xFFFFFFFFu; 121 122 const int kCharSize = sizeof(char); // NOLINT 123 const int kShortSize = sizeof(short); // NOLINT 124 const int kIntSize = sizeof(int); // NOLINT 125 const int kInt32Size = sizeof(int32_t); // NOLINT 126 const int kInt64Size = sizeof(int64_t); // NOLINT 127 const int kDoubleSize = sizeof(double); // NOLINT 128 const int kIntptrSize = sizeof(intptr_t); // NOLINT 129 const int kPointerSize = sizeof(void*); // NOLINT 130 #if V8_TARGET_ARCH_X64 && V8_TARGET_ARCH_32_BIT 131 const int kRegisterSize = kPointerSize + kPointerSize; 132 #else 133 const int kRegisterSize = kPointerSize; 134 #endif 135 const int kPCOnStackSize = kRegisterSize; 136 const int kFPOnStackSize = kRegisterSize; 137 138 const int kDoubleSizeLog2 = 3; 139 140 #if V8_HOST_ARCH_64_BIT 141 const int kPointerSizeLog2 = 3; 142 const intptr_t kIntptrSignBit = V8_INT64_C(0x8000000000000000); 143 const uintptr_t kUintptrAllBitsSet = V8_UINT64_C(0xFFFFFFFFFFFFFFFF); 144 const bool kRequiresCodeRange = true; 145 const size_t kMaximalCodeRangeSize = 512 * MB; 146 #else 147 const int kPointerSizeLog2 = 2; 148 const intptr_t kIntptrSignBit = 0x80000000; 149 const uintptr_t kUintptrAllBitsSet = 0xFFFFFFFFu; 150 #if V8_TARGET_ARCH_X64 && V8_TARGET_ARCH_32_BIT 151 // x32 port also requires code range. 152 const bool kRequiresCodeRange = true; 153 const size_t kMaximalCodeRangeSize = 256 * MB; 154 #else 155 const bool kRequiresCodeRange = false; 156 const size_t kMaximalCodeRangeSize = 0 * MB; 157 #endif 158 #endif 159 160 STATIC_ASSERT(kPointerSize == (1 << kPointerSizeLog2)); 161 162 const int kBitsPerByte = 8; 163 const int kBitsPerByteLog2 = 3; 164 const int kBitsPerPointer = kPointerSize * kBitsPerByte; 165 const int kBitsPerInt = kIntSize * kBitsPerByte; 166 167 // IEEE 754 single precision floating point number bit layout. 168 const uint32_t kBinary32SignMask = 0x80000000u; 169 const uint32_t kBinary32ExponentMask = 0x7f800000u; 170 const uint32_t kBinary32MantissaMask = 0x007fffffu; 171 const int kBinary32ExponentBias = 127; 172 const int kBinary32MaxExponent = 0xFE; 173 const int kBinary32MinExponent = 0x01; 174 const int kBinary32MantissaBits = 23; 175 const int kBinary32ExponentShift = 23; 176 177 // Quiet NaNs have bits 51 to 62 set, possibly the sign bit, and no 178 // other bits set. 179 const 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. 184 typedef uint16_t uc16; 185 typedef int32_t uc32; 186 const int kOneByteSize = kCharSize; 187 const 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. 201 template <typename F> 202 F 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 211 class FreeStoreAllocationPolicy; 212 template <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 219 enum StrictMode { SLOPPY, STRICT }; 220 221 222 // Mask for the sign bit in a smi. 223 const intptr_t kSmiSignMask = kIntptrSignBit; 224 225 const int kObjectAlignmentBits = kPointerSizeLog2; 226 const intptr_t kObjectAlignment = 1 << kObjectAlignmentBits; 227 const intptr_t kObjectAlignmentMask = kObjectAlignment - 1; 228 229 // Desired alignment for pointers. 230 const intptr_t kPointerAlignment = (1 << kPointerSizeLog2); 231 const intptr_t kPointerAlignmentMask = kPointerAlignment - 1; 232 233 // Desired alignment for double values. 234 const intptr_t kDoubleAlignment = 8; 235 const intptr_t kDoubleAlignmentMask = kDoubleAlignment - 1; 236 237 // Desired alignment for generated code is 32 bytes (to improve cache line 238 // utilization). 239 const int kCodeAlignmentBits = 5; 240 const intptr_t kCodeAlignment = 1 << kCodeAlignmentBits; 241 const 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. 249 const int kPageHeaderTag = 3; 250 const int kPageHeaderTagSize = 2; 251 const 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 257 const Address kZapValue = 258 reinterpret_cast<Address>(V8_UINT64_C(0xdeadbeedbeadbeef)); 259 const Address kHandleZapValue = 260 reinterpret_cast<Address>(V8_UINT64_C(0x1baddead0baddeaf)); 261 const Address kGlobalHandleZapValue = 262 reinterpret_cast<Address>(V8_UINT64_C(0x1baffed00baffedf)); 263 const Address kFromSpaceZapValue = 264 reinterpret_cast<Address>(V8_UINT64_C(0x1beefdad0beefdaf)); 265 const uint64_t kDebugZapValue = V8_UINT64_C(0xbadbaddbbadbaddb); 266 const uint64_t kSlotsZapValue = V8_UINT64_C(0xbeefdeadbeefdeef); 267 const uint64_t kFreeListZapValue = 0xfeed1eaffeed1eaf; 268 #else 269 const Address kZapValue = reinterpret_cast<Address>(0xdeadbeef); 270 const Address kHandleZapValue = reinterpret_cast<Address>(0xbaddeaf); 271 const Address kGlobalHandleZapValue = reinterpret_cast<Address>(0xbaffedf); 272 const Address kFromSpaceZapValue = reinterpret_cast<Address>(0xbeefdaf); 273 const uint32_t kSlotsZapValue = 0xbeefdeef; 274 const uint32_t kDebugZapValue = 0xbadbaddb; 275 const uint32_t kFreeListZapValue = 0xfeed1eaf; 276 #endif 277 278 const 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. 287 const uint32_t kQuietNaNHighBitsMask = 0xfff << (51 - 32); 288 289 290 // ----------------------------------------------------------------------------- 291 // Forward declarations for frequently used classes 292 293 class AccessorInfo; 294 class Allocation; 295 class Arguments; 296 class Assembler; 297 class Code; 298 class CodeGenerator; 299 class CodeStub; 300 class Context; 301 class Debug; 302 class Debugger; 303 class DebugInfo; 304 class Descriptor; 305 class DescriptorArray; 306 class TransitionArray; 307 class ExternalReference; 308 class FixedArray; 309 class FunctionTemplateInfo; 310 class MemoryChunk; 311 class SeededNumberDictionary; 312 class UnseededNumberDictionary; 313 class NameDictionary; 314 template <typename T> class MaybeHandle; 315 template <typename T> class Handle; 316 class Heap; 317 class HeapObject; 318 class IC; 319 class InterceptorInfo; 320 class Isolate; 321 class JSReceiver; 322 class JSArray; 323 class JSFunction; 324 class JSObject; 325 class LargeObjectSpace; 326 class LookupResult; 327 class MacroAssembler; 328 class Map; 329 class MapSpace; 330 class MarkCompactCollector; 331 class NewSpace; 332 class Object; 333 class OldSpace; 334 class Foreign; 335 class Scope; 336 class ScopeInfo; 337 class Script; 338 class Smi; 339 template <typename Config, class Allocator = FreeStoreAllocationPolicy> 340 class SplayTree; 341 class String; 342 class Name; 343 class Struct; 344 class Variable; 345 class RelocInfo; 346 class Deserializer; 347 class MessageLocation; 348 349 typedef bool (*WeakSlotCallback)(Object** pointer); 350 351 typedef bool (*WeakSlotCallbackWithHeap)(Heap* heap, Object** pointer); 352 353 // ----------------------------------------------------------------------------- 354 // Miscellaneous 355 356 // NOTE: SpaceIterator depends on AllocationSpace enumeration values being 357 // consecutive. 358 enum 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 }; 374 const int kSpaceTagSize = 3; 375 const 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). 382 enum PretenureFlag { NOT_TENURED, TENURED }; 383 384 enum MinimumCapacity { 385 USE_DEFAULT_MINIMUM_CAPACITY, 386 USE_CUSTOM_MINIMUM_CAPACITY 387 }; 388 389 enum GarbageCollector { SCAVENGER, MARK_COMPACTOR }; 390 391 enum Executability { NOT_EXECUTABLE, EXECUTABLE }; 392 393 enum 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). 401 enum 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 418 struct 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. 429 typedef 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. 435 typedef 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. 440 typedef void (*InlineCacheCallback)(Code* code, Address ic); 441 442 443 // State for inline cache call sites. Aliased as IC::State. 444 enum 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 468 enum 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 477 enum CallConstructorFlags { 478 NO_CALL_CONSTRUCTOR_FLAGS, 479 // The call target is cached in the instruction stream. 480 RECORD_CONSTRUCTOR_TARGET 481 }; 482 483 484 enum CacheHolderFlag { 485 kCacheOnPrototype, 486 kCacheOnPrototypeReceiverIsDictionary, 487 kCacheOnPrototypeReceiverIsPrimitive, 488 kCacheOnReceiver 489 }; 490 491 492 // The Store Buffer (GC). 493 typedef enum { 494 kStoreBufferFullEvent, 495 kStoreBufferStartScanningPagesEvent, 496 kStoreBufferScanningPageEvent 497 } StoreBufferEvent; 498 499 500 typedef void (*StoreBufferCallback)(Heap* heap, 501 MemoryChunk* page, 502 StoreBufferEvent event); 503 504 505 // Union used for fast testing of specific double values. 506 union 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 519 union 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 530 union 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 542 struct 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 556 enum 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. 611 enum 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. 639 enum SmiCheckType { 640 DONT_DO_SMI_CHECK, 641 DO_SMI_CHECK 642 }; 643 644 645 enum 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 656 const uint32_t kHoleNanUpper32 = 0x7FFFFFFF; 657 const uint32_t kHoleNanLower32 = 0xFFFFFFFF; 658 const uint32_t kNaNOrInfinityLowerBoundUpper32 = 0x7FF00000; 659 660 const uint64_t kHoleNanInt64 = 661 (static_cast<uint64_t>(kHoleNanUpper32) << 32) | kHoleNanLower32; 662 const 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. 667 enum 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 700 inline bool IsDynamicVariableMode(VariableMode mode) { 701 return mode >= DYNAMIC && mode <= DYNAMIC_LOCAL; 702 } 703 704 705 inline bool IsDeclaredVariableMode(VariableMode mode) { 706 return mode >= VAR && mode <= MODULE; 707 } 708 709 710 inline bool IsLexicalVariableMode(VariableMode mode) { 711 return mode >= LET && mode <= MODULE; 712 } 713 714 715 inline 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). 751 enum InitializationFlag { 752 kNeedsInitialization, 753 kCreatedInitialized 754 }; 755 756 757 enum MaybeAssignedFlag { kNotAssigned, kMaybeAssigned }; 758 759 760 enum ClearExceptionFlag { 761 KEEP_EXCEPTION, 762 CLEAR_EXCEPTION 763 }; 764 765 766 enum MinusZeroMode { 767 TREAT_MINUS_ZERO_AS_ZERO, 768 FAIL_ON_MINUS_ZERO 769 }; 770 771 772 enum Signedness { kSigned, kUnsigned }; 773 774 775 enum FunctionKind { 776 kNormalFunction = 0, 777 kArrowFunction = 1, 778 kGeneratorFunction = 2, 779 kConciseMethod = 4, 780 kConciseGeneratorMethod = kGeneratorFunction | kConciseMethod 781 }; 782 783 784 inline 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 793 inline bool IsArrowFunction(FunctionKind kind) { 794 DCHECK(IsValidFunctionKind(kind)); 795 return kind & FunctionKind::kArrowFunction; 796 } 797 798 799 inline bool IsGeneratorFunction(FunctionKind kind) { 800 DCHECK(IsValidFunctionKind(kind)); 801 return kind & FunctionKind::kGeneratorFunction; 802 } 803 804 805 inline bool IsConciseMethod(FunctionKind kind) { 806 DCHECK(IsValidFunctionKind(kind)); 807 return kind & FunctionKind::kConciseMethod; 808 } 809 } } // namespace v8::internal 810 811 namespace i = v8::internal; 812 813 #endif // V8_GLOBALS_H_ 814