1// Copyright 2012 the V8 project authors. All rights reserved. 2// Redistribution and use in source and binary forms, with or without 3// modification, are permitted provided that the following conditions are 4// met: 5// 6// * Redistributions of source code must retain the above copyright 7// notice, this list of conditions and the following disclaimer. 8// * Redistributions in binary form must reproduce the above 9// copyright notice, this list of conditions and the following 10// disclaimer in the documentation and/or other materials provided 11// with the distribution. 12// * Neither the name of Google Inc. nor the names of its 13// contributors may be used to endorse or promote products derived 14// from this software without specific prior written permission. 15// 16// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 17// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 18// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 19// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 20// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 21// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 22// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 26// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 28#ifndef V8_GLOBALS_H_ 29#define V8_GLOBALS_H_ 30 31// Define V8_INFINITY 32#define V8_INFINITY INFINITY 33 34// GCC specific stuff 35#ifdef __GNUC__ 36 37#define __GNUC_VERSION_FOR_INFTY__ (__GNUC__ * 10000 + __GNUC_MINOR__ * 100) 38 39// Unfortunately, the INFINITY macro cannot be used with the '-pedantic' 40// warning flag and certain versions of GCC due to a bug: 41// http://gcc.gnu.org/bugzilla/show_bug.cgi?id=11931 42// For now, we use the more involved template-based version from <limits>, but 43// only when compiling with GCC versions affected by the bug (2.96.x - 4.0.x) 44// __GNUC_PREREQ is not defined in GCC for Mac OS X, so we define our own macro 45#if __GNUC_VERSION_FOR_INFTY__ >= 29600 && __GNUC_VERSION_FOR_INFTY__ < 40100 46#include <limits> 47#undef V8_INFINITY 48#define V8_INFINITY std::numeric_limits<double>::infinity() 49#endif 50#undef __GNUC_VERSION_FOR_INFTY__ 51 52#endif // __GNUC__ 53 54#ifdef _MSC_VER 55#undef V8_INFINITY 56#define V8_INFINITY HUGE_VAL 57#endif 58 59 60#include "../include/v8stdint.h" 61 62namespace v8 { 63namespace internal { 64 65// Processor architecture detection. For more info on what's defined, see: 66// http://msdn.microsoft.com/en-us/library/b0084kay.aspx 67// http://www.agner.org/optimize/calling_conventions.pdf 68// or with gcc, run: "echo | gcc -E -dM -" 69#if defined(_M_X64) || defined(__x86_64__) 70#if defined(__native_client__) 71// For Native Client builds of V8, use V8_TARGET_ARCH_ARM, so that V8 72// generates ARM machine code, together with a portable ARM simulator 73// compiled for the host architecture in question. 74// 75// Since Native Client is ILP-32 on all architectures we use 76// V8_HOST_ARCH_IA32 on both 32- and 64-bit x86. 77#define V8_HOST_ARCH_IA32 1 78#define V8_HOST_ARCH_32_BIT 1 79#define V8_HOST_CAN_READ_UNALIGNED 1 80#else 81#define V8_HOST_ARCH_X64 1 82#define V8_HOST_ARCH_64_BIT 1 83#define V8_HOST_CAN_READ_UNALIGNED 1 84#endif // __native_client__ 85#elif defined(_M_IX86) || defined(__i386__) 86#define V8_HOST_ARCH_IA32 1 87#define V8_HOST_ARCH_32_BIT 1 88#define V8_HOST_CAN_READ_UNALIGNED 1 89#elif defined(__ARMEL__) 90#define V8_HOST_ARCH_ARM 1 91#define V8_HOST_ARCH_32_BIT 1 92#elif defined(__MIPSEL__) 93#define V8_HOST_ARCH_MIPS 1 94#define V8_HOST_ARCH_32_BIT 1 95#else 96#error Host architecture was not detected as supported by v8 97#endif 98 99#if defined(__ARM_ARCH_7A__) || \ 100 defined(__ARM_ARCH_7R__) || \ 101 defined(__ARM_ARCH_7__) 102# define CAN_USE_ARMV7_INSTRUCTIONS 1 103# ifndef CAN_USE_VFP3_INSTRUCTIONS 104# define CAN_USE_VFP3_INSTRUCTIONS 105# endif 106#endif 107 108 109// Target architecture detection. This may be set externally. If not, detect 110// in the same way as the host architecture, that is, target the native 111// environment as presented by the compiler. 112#if !V8_TARGET_ARCH_X64 && !V8_TARGET_ARCH_IA32 && \ 113 !V8_TARGET_ARCH_ARM && !V8_TARGET_ARCH_MIPS 114#if defined(_M_X64) || defined(__x86_64__) 115#define V8_TARGET_ARCH_X64 1 116#elif defined(_M_IX86) || defined(__i386__) 117#define V8_TARGET_ARCH_IA32 1 118#elif defined(__ARMEL__) 119#define V8_TARGET_ARCH_ARM 1 120#elif defined(__MIPSEL__) 121#define V8_TARGET_ARCH_MIPS 1 122#else 123#error Target architecture was not detected as supported by v8 124#endif 125#endif 126 127// Check for supported combinations of host and target architectures. 128#if V8_TARGET_ARCH_IA32 && !V8_HOST_ARCH_IA32 129#error Target architecture ia32 is only supported on ia32 host 130#endif 131#if V8_TARGET_ARCH_X64 && !V8_HOST_ARCH_X64 132#error Target architecture x64 is only supported on x64 host 133#endif 134#if (V8_TARGET_ARCH_ARM && !(V8_HOST_ARCH_IA32 || V8_HOST_ARCH_ARM)) 135#error Target architecture arm is only supported on arm and ia32 host 136#endif 137#if (V8_TARGET_ARCH_MIPS && !(V8_HOST_ARCH_IA32 || V8_HOST_ARCH_MIPS)) 138#error Target architecture mips is only supported on mips and ia32 host 139#endif 140 141// Determine whether we are running in a simulated environment. 142// Setting USE_SIMULATOR explicitly from the build script will force 143// the use of a simulated environment. 144#if !defined(USE_SIMULATOR) 145#if (V8_TARGET_ARCH_ARM && !V8_HOST_ARCH_ARM) 146#define USE_SIMULATOR 1 147#endif 148#if (V8_TARGET_ARCH_MIPS && !V8_HOST_ARCH_MIPS) 149#define USE_SIMULATOR 1 150#endif 151#endif 152 153// Determine architecture endiannes (we only support little-endian). 154#if V8_TARGET_ARCH_IA32 155#define V8_TARGET_LITTLE_ENDIAN 1 156#elif V8_TARGET_ARCH_X64 157#define V8_TARGET_LITTLE_ENDIAN 1 158#elif V8_TARGET_ARCH_ARM 159#define V8_TARGET_LITTLE_ENDIAN 1 160#elif V8_TARGET_ARCH_MIPS 161#define V8_TARGET_LITTLE_ENDIAN 1 162#else 163#error Unknown target architecture endiannes 164#endif 165 166// Support for alternative bool type. This is only enabled if the code is 167// compiled with USE_MYBOOL defined. This catches some nasty type bugs. 168// For instance, 'bool b = "false";' results in b == true! This is a hidden 169// source of bugs. 170// However, redefining the bool type does have some negative impact on some 171// platforms. It gives rise to compiler warnings (i.e. with 172// MSVC) in the API header files when mixing code that uses the standard 173// bool with code that uses the redefined version. 174// This does not actually belong in the platform code, but needs to be 175// defined here because the platform code uses bool, and platform.h is 176// include very early in the main include file. 177 178#ifdef USE_MYBOOL 179typedef unsigned int __my_bool__; 180#define bool __my_bool__ // use 'indirection' to avoid name clashes 181#endif 182 183typedef uint8_t byte; 184typedef byte* Address; 185 186// Define our own macros for writing 64-bit constants. This is less fragile 187// than defining __STDC_CONSTANT_MACROS before including <stdint.h>, and it 188// works on compilers that don't have it (like MSVC). 189#if V8_HOST_ARCH_64_BIT 190#if defined(_MSC_VER) 191#define V8_UINT64_C(x) (x ## UI64) 192#define V8_INT64_C(x) (x ## I64) 193#define V8_INTPTR_C(x) (x ## I64) 194#define V8_PTR_PREFIX "ll" 195#elif defined(__MINGW64__) 196#define V8_UINT64_C(x) (x ## ULL) 197#define V8_INT64_C(x) (x ## LL) 198#define V8_INTPTR_C(x) (x ## LL) 199#define V8_PTR_PREFIX "I64" 200#else 201#define V8_UINT64_C(x) (x ## UL) 202#define V8_INT64_C(x) (x ## L) 203#define V8_INTPTR_C(x) (x ## L) 204#define V8_PTR_PREFIX "l" 205#endif 206#else // V8_HOST_ARCH_64_BIT 207#define V8_INTPTR_C(x) (x) 208#define V8_PTR_PREFIX "" 209#endif // V8_HOST_ARCH_64_BIT 210 211// The following macro works on both 32 and 64-bit platforms. 212// Usage: instead of writing 0x1234567890123456 213// write V8_2PART_UINT64_C(0x12345678,90123456); 214#define V8_2PART_UINT64_C(a, b) (((static_cast<uint64_t>(a) << 32) + 0x##b##u)) 215 216#define V8PRIxPTR V8_PTR_PREFIX "x" 217#define V8PRIdPTR V8_PTR_PREFIX "d" 218#define V8PRIuPTR V8_PTR_PREFIX "u" 219 220// Fix for Mac OS X defining uintptr_t as "unsigned long": 221#if defined(__APPLE__) && defined(__MACH__) 222#undef V8PRIxPTR 223#define V8PRIxPTR "lx" 224#endif 225 226#if (defined(__APPLE__) && defined(__MACH__)) || \ 227 defined(__FreeBSD__) || defined(__OpenBSD__) 228#define USING_BSD_ABI 229#endif 230 231// ----------------------------------------------------------------------------- 232// Constants 233 234const int KB = 1024; 235const int MB = KB * KB; 236const int GB = KB * KB * KB; 237const int kMaxInt = 0x7FFFFFFF; 238const int kMinInt = -kMaxInt - 1; 239 240const uint32_t kMaxUInt32 = 0xFFFFFFFFu; 241 242const int kCharSize = sizeof(char); // NOLINT 243const int kShortSize = sizeof(short); // NOLINT 244const int kIntSize = sizeof(int); // NOLINT 245const int kDoubleSize = sizeof(double); // NOLINT 246const int kIntptrSize = sizeof(intptr_t); // NOLINT 247const int kPointerSize = sizeof(void*); // NOLINT 248const int kRegisterSize = kPointerSize; 249const int kPCOnStackSize = kRegisterSize; 250const int kFPOnStackSize = kRegisterSize; 251 252const int kDoubleSizeLog2 = 3; 253 254// Size of the state of a the random number generator. 255const int kRandomStateSize = 2 * kIntSize; 256 257#if V8_HOST_ARCH_64_BIT 258const int kPointerSizeLog2 = 3; 259const intptr_t kIntptrSignBit = V8_INT64_C(0x8000000000000000); 260const uintptr_t kUintptrAllBitsSet = V8_UINT64_C(0xFFFFFFFFFFFFFFFF); 261#else 262const int kPointerSizeLog2 = 2; 263const intptr_t kIntptrSignBit = 0x80000000; 264const uintptr_t kUintptrAllBitsSet = 0xFFFFFFFFu; 265#endif 266 267const int kBitsPerByte = 8; 268const int kBitsPerByteLog2 = 3; 269const int kBitsPerPointer = kPointerSize * kBitsPerByte; 270const int kBitsPerInt = kIntSize * kBitsPerByte; 271 272// IEEE 754 single precision floating point number bit layout. 273const uint32_t kBinary32SignMask = 0x80000000u; 274const uint32_t kBinary32ExponentMask = 0x7f800000u; 275const uint32_t kBinary32MantissaMask = 0x007fffffu; 276const int kBinary32ExponentBias = 127; 277const int kBinary32MaxExponent = 0xFE; 278const int kBinary32MinExponent = 0x01; 279const int kBinary32MantissaBits = 23; 280const int kBinary32ExponentShift = 23; 281 282// Quiet NaNs have bits 51 to 62 set, possibly the sign bit, and no 283// other bits set. 284const uint64_t kQuietNaNMask = static_cast<uint64_t>(0xfff) << 51; 285 286// Latin1/UTF-16 constants 287// Code-point values in Unicode 4.0 are 21 bits wide. 288// Code units in UTF-16 are 16 bits wide. 289typedef uint16_t uc16; 290typedef int32_t uc32; 291const int kOneByteSize = kCharSize; 292const int kUC16Size = sizeof(uc16); // NOLINT 293 294 295// The expression OFFSET_OF(type, field) computes the byte-offset 296// of the specified field relative to the containing type. This 297// corresponds to 'offsetof' (in stddef.h), except that it doesn't 298// use 0 or NULL, which causes a problem with the compiler warnings 299// we have enabled (which is also why 'offsetof' doesn't seem to work). 300// Here we simply use the non-zero value 4, which seems to work. 301#define OFFSET_OF(type, field) \ 302 (reinterpret_cast<intptr_t>(&(reinterpret_cast<type*>(4)->field)) - 4) 303 304 305// The expression ARRAY_SIZE(a) is a compile-time constant of type 306// size_t which represents the number of elements of the given 307// array. You should only use ARRAY_SIZE on statically allocated 308// arrays. 309#define ARRAY_SIZE(a) \ 310 ((sizeof(a) / sizeof(*(a))) / \ 311 static_cast<size_t>(!(sizeof(a) % sizeof(*(a))))) 312 313 314// The USE(x) template is used to silence C++ compiler warnings 315// issued for (yet) unused variables (typically parameters). 316template <typename T> 317inline void USE(T) { } 318 319 320// FUNCTION_ADDR(f) gets the address of a C function f. 321#define FUNCTION_ADDR(f) \ 322 (reinterpret_cast<v8::internal::Address>(reinterpret_cast<intptr_t>(f))) 323 324 325// FUNCTION_CAST<F>(addr) casts an address into a function 326// of type F. Used to invoke generated code from within C. 327template <typename F> 328F FUNCTION_CAST(Address addr) { 329 return reinterpret_cast<F>(reinterpret_cast<intptr_t>(addr)); 330} 331 332 333#if __cplusplus >= 201103L 334#define DISALLOW_BY_DELETE = delete 335#else 336#define DISALLOW_BY_DELETE 337#endif 338 339 340// A macro to disallow the evil copy constructor and operator= functions 341// This should be used in the private: declarations for a class 342#define DISALLOW_COPY_AND_ASSIGN(TypeName) \ 343 TypeName(const TypeName&) DISALLOW_BY_DELETE; \ 344 void operator=(const TypeName&) DISALLOW_BY_DELETE 345 346 347// A macro to disallow all the implicit constructors, namely the 348// default constructor, copy constructor and operator= functions. 349// 350// This should be used in the private: declarations for a class 351// that wants to prevent anyone from instantiating it. This is 352// especially useful for classes containing only static methods. 353#define DISALLOW_IMPLICIT_CONSTRUCTORS(TypeName) \ 354 TypeName() DISALLOW_BY_DELETE; \ 355 DISALLOW_COPY_AND_ASSIGN(TypeName) 356 357 358// Define used for helping GCC to make better inlining. Don't bother for debug 359// builds. On GCC 3.4.5 using __attribute__((always_inline)) causes compilation 360// errors in debug build. 361#if defined(__GNUC__) && !defined(DEBUG) 362#if (__GNUC__ >= 4) 363#define INLINE(header) inline header __attribute__((always_inline)) 364#define NO_INLINE(header) header __attribute__((noinline)) 365#else 366#define INLINE(header) inline __attribute__((always_inline)) header 367#define NO_INLINE(header) __attribute__((noinline)) header 368#endif 369#elif defined(_MSC_VER) && !defined(DEBUG) 370#define INLINE(header) __forceinline header 371#define NO_INLINE(header) header 372#else 373#define INLINE(header) inline header 374#define NO_INLINE(header) header 375#endif 376 377 378#if defined(__GNUC__) && __GNUC__ >= 4 379#define MUST_USE_RESULT __attribute__ ((warn_unused_result)) 380#else 381#define MUST_USE_RESULT 382#endif 383 384 385// Define DISABLE_ASAN macros. 386#if defined(__has_feature) 387#if __has_feature(address_sanitizer) 388#define DISABLE_ASAN __attribute__((no_address_safety_analysis)) 389#endif 390#endif 391 392 393#ifndef DISABLE_ASAN 394#define DISABLE_ASAN 395#endif 396 397 398// ----------------------------------------------------------------------------- 399// Forward declarations for frequently used classes 400// (sorted alphabetically) 401 402class FreeStoreAllocationPolicy; 403template <typename T, class P = FreeStoreAllocationPolicy> class List; 404 405// ----------------------------------------------------------------------------- 406// Declarations for use in both the preparser and the rest of V8. 407 408// The different language modes that V8 implements. ES5 defines two language 409// modes: an unrestricted mode respectively a strict mode which are indicated by 410// CLASSIC_MODE respectively STRICT_MODE in the enum. The harmony spec drafts 411// for the next ES standard specify a new third mode which is called 'extended 412// mode'. The extended mode is only available if the harmony flag is set. It is 413// based on the 'strict mode' and adds new functionality to it. This means that 414// most of the semantics of these two modes coincide. 415// 416// In the current draft the term 'base code' is used to refer to code that is 417// neither in strict nor extended mode. However, the more distinguishing term 418// 'classic mode' is used in V8 instead to avoid mix-ups. 419 420enum LanguageMode { 421 CLASSIC_MODE, 422 STRICT_MODE, 423 EXTENDED_MODE 424}; 425 426 427// A simple Maybe type, that can be passed by value. 428template<class T> 429struct Maybe { 430 Maybe() : has_value(false) {} 431 explicit Maybe(T t) : has_value(true), value(t) {} 432 Maybe(bool has, T t) : has_value(has), value(t) {} 433 434 bool has_value; 435 T value; 436}; 437 438 439// The Strict Mode (ECMA-262 5th edition, 4.2.2). 440// 441// This flag is used in the backend to represent the language mode. So far 442// there is no semantic difference between the strict and the extended mode in 443// the backend, so both modes are represented by the kStrictMode value. 444enum StrictModeFlag { 445 kNonStrictMode, 446 kStrictMode 447}; 448 449 450} } // namespace v8::internal 451 452#endif // V8_GLOBALS_H_ 453