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#define V8_HOST_ARCH_X64 1
71#define V8_HOST_ARCH_64_BIT 1
72#define V8_HOST_CAN_READ_UNALIGNED 1
73#elif defined(_M_IX86) || defined(__i386__)
74#define V8_HOST_ARCH_IA32 1
75#define V8_HOST_ARCH_32_BIT 1
76#define V8_HOST_CAN_READ_UNALIGNED 1
77#elif defined(__ARMEL__)
78#define V8_HOST_ARCH_ARM 1
79#define V8_HOST_ARCH_32_BIT 1
80// Some CPU-OS combinations allow unaligned access on ARM. We assume
81// that unaligned accesses are not allowed unless the build system
82// defines the CAN_USE_UNALIGNED_ACCESSES macro to be non-zero.
83#if CAN_USE_UNALIGNED_ACCESSES
84#define V8_HOST_CAN_READ_UNALIGNED 1
85#endif
86#elif defined(__MIPSEL__)
87#define V8_HOST_ARCH_MIPS 1
88#define V8_HOST_ARCH_32_BIT 1
89#else
90#error Host architecture was not detected as supported by v8
91#endif
92
93// Target architecture detection. This may be set externally. If not, detect
94// in the same way as the host architecture, that is, target the native
95// environment as presented by the compiler.
96#if !defined(V8_TARGET_ARCH_X64) && !defined(V8_TARGET_ARCH_IA32) && \
97    !defined(V8_TARGET_ARCH_ARM) && !defined(V8_TARGET_ARCH_MIPS)
98#if defined(_M_X64) || defined(__x86_64__)
99#define V8_TARGET_ARCH_X64 1
100#elif defined(_M_IX86) || defined(__i386__)
101#define V8_TARGET_ARCH_IA32 1
102#elif defined(__ARMEL__)
103#define V8_TARGET_ARCH_ARM 1
104#elif defined(__MIPSEL__)
105#define V8_TARGET_ARCH_MIPS 1
106#else
107#error Target architecture was not detected as supported by v8
108#endif
109#endif
110
111// Check for supported combinations of host and target architectures.
112#if defined(V8_TARGET_ARCH_IA32) && !defined(V8_HOST_ARCH_IA32)
113#error Target architecture ia32 is only supported on ia32 host
114#endif
115#if defined(V8_TARGET_ARCH_X64) && !defined(V8_HOST_ARCH_X64)
116#error Target architecture x64 is only supported on x64 host
117#endif
118#if (defined(V8_TARGET_ARCH_ARM) && \
119    !(defined(V8_HOST_ARCH_IA32) || defined(V8_HOST_ARCH_ARM)))
120#error Target architecture arm is only supported on arm and ia32 host
121#endif
122#if (defined(V8_TARGET_ARCH_MIPS) && \
123    !(defined(V8_HOST_ARCH_IA32) || defined(V8_HOST_ARCH_MIPS)))
124#error Target architecture mips is only supported on mips and ia32 host
125#endif
126
127// Determine whether we are running in a simulated environment.
128// Setting USE_SIMULATOR explicitly from the build script will force
129// the use of a simulated environment.
130#if !defined(USE_SIMULATOR)
131#if (defined(V8_TARGET_ARCH_ARM) && !defined(V8_HOST_ARCH_ARM))
132#define USE_SIMULATOR 1
133#endif
134#if (defined(V8_TARGET_ARCH_MIPS) && !defined(V8_HOST_ARCH_MIPS))
135#define USE_SIMULATOR 1
136#endif
137#endif
138
139// Define unaligned read for the target architectures supporting it.
140#if defined(V8_TARGET_ARCH_X64) || defined(V8_TARGET_ARCH_IA32)
141#define V8_TARGET_CAN_READ_UNALIGNED 1
142#elif V8_TARGET_ARCH_ARM
143// Some CPU-OS combinations allow unaligned access on ARM. We assume
144// that unaligned accesses are not allowed unless the build system
145// defines the CAN_USE_UNALIGNED_ACCESSES macro to be non-zero.
146#if CAN_USE_UNALIGNED_ACCESSES
147#define V8_TARGET_CAN_READ_UNALIGNED 1
148#endif
149#elif V8_TARGET_ARCH_MIPS
150#else
151#error Target architecture is not supported by v8
152#endif
153
154// Support for alternative bool type. This is only enabled if the code is
155// compiled with USE_MYBOOL defined. This catches some nasty type bugs.
156// For instance, 'bool b = "false";' results in b == true! This is a hidden
157// source of bugs.
158// However, redefining the bool type does have some negative impact on some
159// platforms. It gives rise to compiler warnings (i.e. with
160// MSVC) in the API header files when mixing code that uses the standard
161// bool with code that uses the redefined version.
162// This does not actually belong in the platform code, but needs to be
163// defined here because the platform code uses bool, and platform.h is
164// include very early in the main include file.
165
166#ifdef USE_MYBOOL
167typedef unsigned int __my_bool__;
168#define bool __my_bool__  // use 'indirection' to avoid name clashes
169#endif
170
171typedef uint8_t byte;
172typedef byte* Address;
173
174// Define our own macros for writing 64-bit constants.  This is less fragile
175// than defining __STDC_CONSTANT_MACROS before including <stdint.h>, and it
176// works on compilers that don't have it (like MSVC).
177#if V8_HOST_ARCH_64_BIT
178#if defined(_MSC_VER)
179#define V8_UINT64_C(x)  (x ## UI64)
180#define V8_INT64_C(x)   (x ## I64)
181#define V8_INTPTR_C(x)  (x ## I64)
182#define V8_PTR_PREFIX "ll"
183#elif defined(__MINGW64__)
184#define V8_UINT64_C(x)  (x ## ULL)
185#define V8_INT64_C(x)   (x ## LL)
186#define V8_INTPTR_C(x)  (x ## LL)
187#define V8_PTR_PREFIX "I64"
188#else
189#define V8_UINT64_C(x)  (x ## UL)
190#define V8_INT64_C(x)   (x ## L)
191#define V8_INTPTR_C(x)  (x ## L)
192#define V8_PTR_PREFIX "l"
193#endif
194#else  // V8_HOST_ARCH_64_BIT
195#define V8_INTPTR_C(x)  (x)
196#define V8_PTR_PREFIX ""
197#endif  // V8_HOST_ARCH_64_BIT
198
199// The following macro works on both 32 and 64-bit platforms.
200// Usage: instead of writing 0x1234567890123456
201//      write V8_2PART_UINT64_C(0x12345678,90123456);
202#define V8_2PART_UINT64_C(a, b) (((static_cast<uint64_t>(a) << 32) + 0x##b##u))
203
204#define V8PRIxPTR V8_PTR_PREFIX "x"
205#define V8PRIdPTR V8_PTR_PREFIX "d"
206
207// Fix for Mac OS X defining uintptr_t as "unsigned long":
208#if defined(__APPLE__) && defined(__MACH__)
209#undef V8PRIxPTR
210#define V8PRIxPTR "lx"
211#endif
212
213#if (defined(__APPLE__) && defined(__MACH__)) || \
214    defined(__FreeBSD__) || defined(__OpenBSD__)
215#define USING_BSD_ABI
216#endif
217
218// -----------------------------------------------------------------------------
219// Constants
220
221const int KB = 1024;
222const int MB = KB * KB;
223const int GB = KB * KB * KB;
224const int kMaxInt = 0x7FFFFFFF;
225const int kMinInt = -kMaxInt - 1;
226
227const uint32_t kMaxUInt32 = 0xFFFFFFFFu;
228
229const int kCharSize     = sizeof(char);      // NOLINT
230const int kShortSize    = sizeof(short);     // NOLINT
231const int kIntSize      = sizeof(int);       // NOLINT
232const int kDoubleSize   = sizeof(double);    // NOLINT
233const int kIntptrSize   = sizeof(intptr_t);  // NOLINT
234const int kPointerSize  = sizeof(void*);     // NOLINT
235
236const int kDoubleSizeLog2 = 3;
237
238// Size of the state of a the random number generator.
239const int kRandomStateSize = 2 * kIntSize;
240
241#if V8_HOST_ARCH_64_BIT
242const int kPointerSizeLog2 = 3;
243const intptr_t kIntptrSignBit = V8_INT64_C(0x8000000000000000);
244const uintptr_t kUintptrAllBitsSet = V8_UINT64_C(0xFFFFFFFFFFFFFFFF);
245#else
246const int kPointerSizeLog2 = 2;
247const intptr_t kIntptrSignBit = 0x80000000;
248const uintptr_t kUintptrAllBitsSet = 0xFFFFFFFFu;
249#endif
250
251const int kBitsPerByte = 8;
252const int kBitsPerByteLog2 = 3;
253const int kBitsPerPointer = kPointerSize * kBitsPerByte;
254const int kBitsPerInt = kIntSize * kBitsPerByte;
255
256// IEEE 754 single precision floating point number bit layout.
257const uint32_t kBinary32SignMask = 0x80000000u;
258const uint32_t kBinary32ExponentMask = 0x7f800000u;
259const uint32_t kBinary32MantissaMask = 0x007fffffu;
260const int kBinary32ExponentBias = 127;
261const int kBinary32MaxExponent  = 0xFE;
262const int kBinary32MinExponent  = 0x01;
263const int kBinary32MantissaBits = 23;
264const int kBinary32ExponentShift = 23;
265
266// Quiet NaNs have bits 51 to 62 set, possibly the sign bit, and no
267// other bits set.
268const uint64_t kQuietNaNMask = static_cast<uint64_t>(0xfff) << 51;
269
270// ASCII/UTF-16 constants
271// Code-point values in Unicode 4.0 are 21 bits wide.
272// Code units in UTF-16 are 16 bits wide.
273typedef uint16_t uc16;
274typedef int32_t uc32;
275const int kASCIISize    = kCharSize;
276const int kUC16Size     = sizeof(uc16);      // NOLINT
277const uc32 kMaxAsciiCharCode = 0x7f;
278const uint32_t kMaxAsciiCharCodeU = 0x7fu;
279
280
281// The expression OFFSET_OF(type, field) computes the byte-offset
282// of the specified field relative to the containing type. This
283// corresponds to 'offsetof' (in stddef.h), except that it doesn't
284// use 0 or NULL, which causes a problem with the compiler warnings
285// we have enabled (which is also why 'offsetof' doesn't seem to work).
286// Here we simply use the non-zero value 4, which seems to work.
287#define OFFSET_OF(type, field)                                          \
288  (reinterpret_cast<intptr_t>(&(reinterpret_cast<type*>(4)->field)) - 4)
289
290
291// The expression ARRAY_SIZE(a) is a compile-time constant of type
292// size_t which represents the number of elements of the given
293// array. You should only use ARRAY_SIZE on statically allocated
294// arrays.
295#define ARRAY_SIZE(a)                                   \
296  ((sizeof(a) / sizeof(*(a))) /                         \
297  static_cast<size_t>(!(sizeof(a) % sizeof(*(a)))))
298
299
300// The USE(x) template is used to silence C++ compiler warnings
301// issued for (yet) unused variables (typically parameters).
302template <typename T>
303inline void USE(T) { }
304
305
306// FUNCTION_ADDR(f) gets the address of a C function f.
307#define FUNCTION_ADDR(f)                                        \
308  (reinterpret_cast<v8::internal::Address>(reinterpret_cast<intptr_t>(f)))
309
310
311// FUNCTION_CAST<F>(addr) casts an address into a function
312// of type F. Used to invoke generated code from within C.
313template <typename F>
314F FUNCTION_CAST(Address addr) {
315  return reinterpret_cast<F>(reinterpret_cast<intptr_t>(addr));
316}
317
318
319// A macro to disallow the evil copy constructor and operator= functions
320// This should be used in the private: declarations for a class
321#define DISALLOW_COPY_AND_ASSIGN(TypeName)      \
322  TypeName(const TypeName&);                    \
323  void operator=(const TypeName&)
324
325
326// A macro to disallow all the implicit constructors, namely the
327// default constructor, copy constructor and operator= functions.
328//
329// This should be used in the private: declarations for a class
330// that wants to prevent anyone from instantiating it. This is
331// especially useful for classes containing only static methods.
332#define DISALLOW_IMPLICIT_CONSTRUCTORS(TypeName) \
333  TypeName();                                    \
334  DISALLOW_COPY_AND_ASSIGN(TypeName)
335
336
337// Define used for helping GCC to make better inlining. Don't bother for debug
338// builds. On GCC 3.4.5 using __attribute__((always_inline)) causes compilation
339// errors in debug build.
340#if defined(__GNUC__) && !defined(DEBUG)
341#if (__GNUC__ >= 4)
342#define INLINE(header) inline header  __attribute__((always_inline))
343#define NO_INLINE(header) header __attribute__((noinline))
344#else
345#define INLINE(header) inline __attribute__((always_inline)) header
346#define NO_INLINE(header) __attribute__((noinline)) header
347#endif
348#else
349#define INLINE(header) inline header
350#define NO_INLINE(header) header
351#endif
352
353
354#if defined(__GNUC__) && __GNUC__ >= 4
355#define MUST_USE_RESULT __attribute__ ((warn_unused_result))
356#else
357#define MUST_USE_RESULT
358#endif
359
360// -----------------------------------------------------------------------------
361// Forward declarations for frequently used classes
362// (sorted alphabetically)
363
364class FreeStoreAllocationPolicy;
365template <typename T, class P = FreeStoreAllocationPolicy> class List;
366
367// -----------------------------------------------------------------------------
368// Declarations for use in both the preparser and the rest of V8.
369
370// The different language modes that V8 implements. ES5 defines two language
371// modes: an unrestricted mode respectively a strict mode which are indicated by
372// CLASSIC_MODE respectively STRICT_MODE in the enum. The harmony spec drafts
373// for the next ES standard specify a new third mode which is called 'extended
374// mode'. The extended mode is only available if the harmony flag is set. It is
375// based on the 'strict mode' and adds new functionality to it. This means that
376// most of the semantics of these two modes coincide.
377//
378// In the current draft the term 'base code' is used to refer to code that is
379// neither in strict nor extended mode. However, the more distinguishing term
380// 'classic mode' is used in V8 instead to avoid mix-ups.
381
382enum LanguageMode {
383  CLASSIC_MODE,
384  STRICT_MODE,
385  EXTENDED_MODE
386};
387
388
389// The Strict Mode (ECMA-262 5th edition, 4.2.2).
390//
391// This flag is used in the backend to represent the language mode. So far
392// there is no semantic difference between the strict and the extended mode in
393// the backend, so both modes are represented by the kStrictMode value.
394enum StrictModeFlag {
395  kNonStrictMode,
396  kStrictMode
397};
398
399
400} }  // namespace v8::internal
401
402#endif  // V8_GLOBALS_H_
403