1b67f96038c787a6bd6a835e6c436c82e1b245486machenbach@chromium.org// Copyright 2014 the V8 project authors. All rights reserved.
23484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org// Use of this source code is governed by a BSD-style license that can be
33484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org// found in the LICENSE file.
4b67f96038c787a6bd6a835e6c436c82e1b245486machenbach@chromium.org
5b67f96038c787a6bd6a835e6c436c82e1b245486machenbach@chromium.org#ifndef V8_BASE_MACROS_H_
6b67f96038c787a6bd6a835e6c436c82e1b245486machenbach@chromium.org#define V8_BASE_MACROS_H_
7b67f96038c787a6bd6a835e6c436c82e1b245486machenbach@chromium.org
8e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org#include <cstring>
9e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org
10196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "include/v8stdint.h"
11248dd43badb99ffce44eae2d767cda3cefaad521machenbach@chromium.org#include "src/base/build_config.h"
12ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org#include "src/base/compiler-specific.h"
135de0074a922429f5e0ec2cf140c2d2989bf88140yangguo@chromium.org#include "src/base/logging.h"
14b67f96038c787a6bd6a835e6c436c82e1b245486machenbach@chromium.org
15b67f96038c787a6bd6a835e6c436c82e1b245486machenbach@chromium.org
16b67f96038c787a6bd6a835e6c436c82e1b245486machenbach@chromium.org// The expression OFFSET_OF(type, field) computes the byte-offset
17b67f96038c787a6bd6a835e6c436c82e1b245486machenbach@chromium.org// of the specified field relative to the containing type. This
18b67f96038c787a6bd6a835e6c436c82e1b245486machenbach@chromium.org// corresponds to 'offsetof' (in stddef.h), except that it doesn't
19b67f96038c787a6bd6a835e6c436c82e1b245486machenbach@chromium.org// use 0 or NULL, which causes a problem with the compiler warnings
20b67f96038c787a6bd6a835e6c436c82e1b245486machenbach@chromium.org// we have enabled (which is also why 'offsetof' doesn't seem to work).
21b67f96038c787a6bd6a835e6c436c82e1b245486machenbach@chromium.org// Here we simply use the non-zero value 4, which seems to work.
22b67f96038c787a6bd6a835e6c436c82e1b245486machenbach@chromium.org#define OFFSET_OF(type, field)                                          \
23b67f96038c787a6bd6a835e6c436c82e1b245486machenbach@chromium.org  (reinterpret_cast<intptr_t>(&(reinterpret_cast<type*>(4)->field)) - 4)
24b67f96038c787a6bd6a835e6c436c82e1b245486machenbach@chromium.org
25b67f96038c787a6bd6a835e6c436c82e1b245486machenbach@chromium.org
26fa7f914e3bacba481b13da5cf2bc4c935567ebc4machenbach@chromium.org// ARRAYSIZE_UNSAFE performs essentially the same calculation as arraysize,
27fa7f914e3bacba481b13da5cf2bc4c935567ebc4machenbach@chromium.org// but can be used on anonymous types or types defined inside
28fa7f914e3bacba481b13da5cf2bc4c935567ebc4machenbach@chromium.org// functions.  It's less safe than arraysize as it accepts some
29fa7f914e3bacba481b13da5cf2bc4c935567ebc4machenbach@chromium.org// (although not all) pointers.  Therefore, you should use arraysize
30fa7f914e3bacba481b13da5cf2bc4c935567ebc4machenbach@chromium.org// whenever possible.
31fa7f914e3bacba481b13da5cf2bc4c935567ebc4machenbach@chromium.org//
32fa7f914e3bacba481b13da5cf2bc4c935567ebc4machenbach@chromium.org// The expression ARRAYSIZE_UNSAFE(a) is a compile-time constant of type
33fa7f914e3bacba481b13da5cf2bc4c935567ebc4machenbach@chromium.org// size_t.
34fa7f914e3bacba481b13da5cf2bc4c935567ebc4machenbach@chromium.org//
35fa7f914e3bacba481b13da5cf2bc4c935567ebc4machenbach@chromium.org// ARRAYSIZE_UNSAFE catches a few type errors.  If you see a compiler error
36fa7f914e3bacba481b13da5cf2bc4c935567ebc4machenbach@chromium.org//
37fa7f914e3bacba481b13da5cf2bc4c935567ebc4machenbach@chromium.org//   "warning: division by zero in ..."
38fa7f914e3bacba481b13da5cf2bc4c935567ebc4machenbach@chromium.org//
39fa7f914e3bacba481b13da5cf2bc4c935567ebc4machenbach@chromium.org// when using ARRAYSIZE_UNSAFE, you are (wrongfully) giving it a pointer.
40fa7f914e3bacba481b13da5cf2bc4c935567ebc4machenbach@chromium.org// You should only use ARRAYSIZE_UNSAFE on statically allocated arrays.
41fa7f914e3bacba481b13da5cf2bc4c935567ebc4machenbach@chromium.org//
42fa7f914e3bacba481b13da5cf2bc4c935567ebc4machenbach@chromium.org// The following comments are on the implementation details, and can
43fa7f914e3bacba481b13da5cf2bc4c935567ebc4machenbach@chromium.org// be ignored by the users.
44fa7f914e3bacba481b13da5cf2bc4c935567ebc4machenbach@chromium.org//
45fa7f914e3bacba481b13da5cf2bc4c935567ebc4machenbach@chromium.org// ARRAYSIZE_UNSAFE(arr) works by inspecting sizeof(arr) (the # of bytes in
46fa7f914e3bacba481b13da5cf2bc4c935567ebc4machenbach@chromium.org// the array) and sizeof(*(arr)) (the # of bytes in one array
47fa7f914e3bacba481b13da5cf2bc4c935567ebc4machenbach@chromium.org// element).  If the former is divisible by the latter, perhaps arr is
48fa7f914e3bacba481b13da5cf2bc4c935567ebc4machenbach@chromium.org// indeed an array, in which case the division result is the # of
49fa7f914e3bacba481b13da5cf2bc4c935567ebc4machenbach@chromium.org// elements in the array.  Otherwise, arr cannot possibly be an array,
50fa7f914e3bacba481b13da5cf2bc4c935567ebc4machenbach@chromium.org// and we generate a compiler error to prevent the code from
51fa7f914e3bacba481b13da5cf2bc4c935567ebc4machenbach@chromium.org// compiling.
52fa7f914e3bacba481b13da5cf2bc4c935567ebc4machenbach@chromium.org//
53fa7f914e3bacba481b13da5cf2bc4c935567ebc4machenbach@chromium.org// Since the size of bool is implementation-defined, we need to cast
54fa7f914e3bacba481b13da5cf2bc4c935567ebc4machenbach@chromium.org// !(sizeof(a) & sizeof(*(a))) to size_t in order to ensure the final
55fa7f914e3bacba481b13da5cf2bc4c935567ebc4machenbach@chromium.org// result has type size_t.
56fa7f914e3bacba481b13da5cf2bc4c935567ebc4machenbach@chromium.org//
57fa7f914e3bacba481b13da5cf2bc4c935567ebc4machenbach@chromium.org// This macro is not perfect as it wrongfully accepts certain
58fa7f914e3bacba481b13da5cf2bc4c935567ebc4machenbach@chromium.org// pointers, namely where the pointer size is divisible by the pointee
59fa7f914e3bacba481b13da5cf2bc4c935567ebc4machenbach@chromium.org// size.  Since all our code has to go through a 32-bit compiler,
60fa7f914e3bacba481b13da5cf2bc4c935567ebc4machenbach@chromium.org// where a pointer is 4 bytes, this means all pointers to a type whose
61fa7f914e3bacba481b13da5cf2bc4c935567ebc4machenbach@chromium.org// size is 3 or greater than 4 will be (righteously) rejected.
62fa7f914e3bacba481b13da5cf2bc4c935567ebc4machenbach@chromium.org#define ARRAYSIZE_UNSAFE(a)     \
63fa7f914e3bacba481b13da5cf2bc4c935567ebc4machenbach@chromium.org  ((sizeof(a) / sizeof(*(a))) / \
64fa7f914e3bacba481b13da5cf2bc4c935567ebc4machenbach@chromium.org   static_cast<size_t>(!(sizeof(a) % sizeof(*(a)))))  // NOLINT
65fa7f914e3bacba481b13da5cf2bc4c935567ebc4machenbach@chromium.org
66fa7f914e3bacba481b13da5cf2bc4c935567ebc4machenbach@chromium.org
67fa7f914e3bacba481b13da5cf2bc4c935567ebc4machenbach@chromium.org#if V8_OS_NACL
68fa7f914e3bacba481b13da5cf2bc4c935567ebc4machenbach@chromium.org
69fa7f914e3bacba481b13da5cf2bc4c935567ebc4machenbach@chromium.org// TODO(bmeurer): For some reason, the NaCl toolchain cannot handle the correct
70fa7f914e3bacba481b13da5cf2bc4c935567ebc4machenbach@chromium.org// definition of arraysize() below, so we have to use the unsafe version for
71fa7f914e3bacba481b13da5cf2bc4c935567ebc4machenbach@chromium.org// now.
72fa7f914e3bacba481b13da5cf2bc4c935567ebc4machenbach@chromium.org#define arraysize ARRAYSIZE_UNSAFE
73fa7f914e3bacba481b13da5cf2bc4c935567ebc4machenbach@chromium.org
74fa7f914e3bacba481b13da5cf2bc4c935567ebc4machenbach@chromium.org#else  // V8_OS_NACL
75fa7f914e3bacba481b13da5cf2bc4c935567ebc4machenbach@chromium.org
76fa7f914e3bacba481b13da5cf2bc4c935567ebc4machenbach@chromium.org// The arraysize(arr) macro returns the # of elements in an array arr.
77fa7f914e3bacba481b13da5cf2bc4c935567ebc4machenbach@chromium.org// The expression is a compile-time constant, and therefore can be
78fa7f914e3bacba481b13da5cf2bc4c935567ebc4machenbach@chromium.org// used in defining new arrays, for example.  If you use arraysize on
79fa7f914e3bacba481b13da5cf2bc4c935567ebc4machenbach@chromium.org// a pointer by mistake, you will get a compile-time error.
80fa7f914e3bacba481b13da5cf2bc4c935567ebc4machenbach@chromium.org//
81fa7f914e3bacba481b13da5cf2bc4c935567ebc4machenbach@chromium.org// One caveat is that arraysize() doesn't accept any array of an
82fa7f914e3bacba481b13da5cf2bc4c935567ebc4machenbach@chromium.org// anonymous type or a type defined inside a function.  In these rare
83fa7f914e3bacba481b13da5cf2bc4c935567ebc4machenbach@chromium.org// cases, you have to use the unsafe ARRAYSIZE_UNSAFE() macro below.  This is
84fa7f914e3bacba481b13da5cf2bc4c935567ebc4machenbach@chromium.org// due to a limitation in C++'s template system.  The limitation might
85fa7f914e3bacba481b13da5cf2bc4c935567ebc4machenbach@chromium.org// eventually be removed, but it hasn't happened yet.
86fa7f914e3bacba481b13da5cf2bc4c935567ebc4machenbach@chromium.org#define arraysize(array) (sizeof(ArraySizeHelper(array)))
87fa7f914e3bacba481b13da5cf2bc4c935567ebc4machenbach@chromium.org
88fa7f914e3bacba481b13da5cf2bc4c935567ebc4machenbach@chromium.org
89fa7f914e3bacba481b13da5cf2bc4c935567ebc4machenbach@chromium.org// This template function declaration is used in defining arraysize.
90fa7f914e3bacba481b13da5cf2bc4c935567ebc4machenbach@chromium.org// Note that the function doesn't need an implementation, as we only
91fa7f914e3bacba481b13da5cf2bc4c935567ebc4machenbach@chromium.org// use its type.
92fa7f914e3bacba481b13da5cf2bc4c935567ebc4machenbach@chromium.orgtemplate <typename T, size_t N>
93fa7f914e3bacba481b13da5cf2bc4c935567ebc4machenbach@chromium.orgchar (&ArraySizeHelper(T (&array)[N]))[N];
94fa7f914e3bacba481b13da5cf2bc4c935567ebc4machenbach@chromium.org
95fa7f914e3bacba481b13da5cf2bc4c935567ebc4machenbach@chromium.org
96fa7f914e3bacba481b13da5cf2bc4c935567ebc4machenbach@chromium.org#if !V8_CC_MSVC
97fa7f914e3bacba481b13da5cf2bc4c935567ebc4machenbach@chromium.org// That gcc wants both of these prototypes seems mysterious. VC, for
98fa7f914e3bacba481b13da5cf2bc4c935567ebc4machenbach@chromium.org// its part, can't decide which to use (another mystery). Matching of
99fa7f914e3bacba481b13da5cf2bc4c935567ebc4machenbach@chromium.org// template overloads: the final frontier.
100fa7f914e3bacba481b13da5cf2bc4c935567ebc4machenbach@chromium.orgtemplate <typename T, size_t N>
101fa7f914e3bacba481b13da5cf2bc4c935567ebc4machenbach@chromium.orgchar (&ArraySizeHelper(const T (&array)[N]))[N];
102fa7f914e3bacba481b13da5cf2bc4c935567ebc4machenbach@chromium.org#endif
103fa7f914e3bacba481b13da5cf2bc4c935567ebc4machenbach@chromium.org
104fa7f914e3bacba481b13da5cf2bc4c935567ebc4machenbach@chromium.org#endif  // V8_OS_NACL
105b67f96038c787a6bd6a835e6c436c82e1b245486machenbach@chromium.org
106b67f96038c787a6bd6a835e6c436c82e1b245486machenbach@chromium.org
107e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org// The COMPILE_ASSERT macro can be used to verify that a compile time
108e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org// expression is true. For example, you could use it to verify the
109e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org// size of a static array:
110e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org//
111e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org//   COMPILE_ASSERT(ARRAYSIZE_UNSAFE(content_type_names) == CONTENT_NUM_TYPES,
112e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org//                  content_type_names_incorrect_size);
113e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org//
114e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org// or to make sure a struct is smaller than a certain size:
115e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org//
116e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org//   COMPILE_ASSERT(sizeof(foo) < 128, foo_too_large);
117e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org//
118e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org// The second argument to the macro is the name of the variable. If
119e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org// the expression is false, most compilers will issue a warning/error
120e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org// containing the name of the variable.
121e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org#if V8_HAS_CXX11_STATIC_ASSERT
122e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org
123e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org// Under C++11, just use static_assert.
124e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org#define COMPILE_ASSERT(expr, msg) static_assert(expr, #msg)
125e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org
126e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org#else
127e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org
128e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.orgtemplate <bool>
129e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.orgstruct CompileAssert {};
130e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org
131e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org#define COMPILE_ASSERT(expr, msg)                \
132e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org  typedef CompileAssert<static_cast<bool>(expr)> \
133e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org      msg[static_cast<bool>(expr) ? 1 : -1] ALLOW_UNUSED
134e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org
135e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org// Implementation details of COMPILE_ASSERT:
136e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org//
137e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org// - COMPILE_ASSERT works by defining an array type that has -1
138e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org//   elements (and thus is invalid) when the expression is false.
139e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org//
140e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org// - The simpler definition
141e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org//
142e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org//     #define COMPILE_ASSERT(expr, msg) typedef char msg[(expr) ? 1 : -1]
143e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org//
144e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org//   does not work, as gcc supports variable-length arrays whose sizes
145e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org//   are determined at run-time (this is gcc's extension and not part
146e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org//   of the C++ standard).  As a result, gcc fails to reject the
147e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org//   following code with the simple definition:
148e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org//
149e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org//     int foo;
150e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org//     COMPILE_ASSERT(foo, msg); // not supposed to compile as foo is
151e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org//                               // not a compile-time constant.
152e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org//
153e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org// - By using the type CompileAssert<(bool(expr))>, we ensures that
154e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org//   expr is a compile-time constant.  (Template arguments must be
155e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org//   determined at compile-time.)
156e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org//
157e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org// - The outer parentheses in CompileAssert<(bool(expr))> are necessary
158e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org//   to work around a bug in gcc 3.4.4 and 4.0.1.  If we had written
159e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org//
160e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org//     CompileAssert<bool(expr)>
161e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org//
162e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org//   instead, these compilers will refuse to compile
163e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org//
164e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org//     COMPILE_ASSERT(5 > 0, some_message);
165e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org//
166e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org//   (They seem to think the ">" in "5 > 0" marks the end of the
167e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org//   template argument list.)
168e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org//
169e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org// - The array size is (bool(expr) ? 1 : -1), instead of simply
170e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org//
171e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org//     ((expr) ? 1 : -1).
172e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org//
173e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org//   This is to avoid running into a bug in MS VC 7.1, which
174e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org//   causes ((0.0) ? 1 : -1) to incorrectly evaluate to 1.
175e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org
176e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org#endif
177e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org
178e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org
179e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org// bit_cast<Dest,Source> is a template function that implements the
180e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org// equivalent of "*reinterpret_cast<Dest*>(&source)".  We need this in
181e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org// very low-level functions like the protobuf library and fast math
182e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org// support.
183e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org//
184e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org//   float f = 3.14159265358979;
185e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org//   int i = bit_cast<int32>(f);
186e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org//   // i = 0x40490fdb
187e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org//
188e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org// The classical address-casting method is:
189e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org//
190e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org//   // WRONG
191e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org//   float f = 3.14159265358979;            // WRONG
192e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org//   int i = * reinterpret_cast<int*>(&f);  // WRONG
193e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org//
194e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org// The address-casting method actually produces undefined behavior
195e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org// according to ISO C++ specification section 3.10 -15 -.  Roughly, this
196e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org// section says: if an object in memory has one type, and a program
197e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org// accesses it with a different type, then the result is undefined
198e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org// behavior for most values of "different type".
199e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org//
200e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org// This is true for any cast syntax, either *(int*)&f or
201e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org// *reinterpret_cast<int*>(&f).  And it is particularly true for
202e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org// conversions between integral lvalues and floating-point lvalues.
203e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org//
204e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org// The purpose of 3.10 -15- is to allow optimizing compilers to assume
205e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org// that expressions with different types refer to different memory.  gcc
206e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org// 4.0.1 has an optimizer that takes advantage of this.  So a
207e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org// non-conforming program quietly produces wildly incorrect output.
208e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org//
209e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org// The problem is not the use of reinterpret_cast.  The problem is type
210e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org// punning: holding an object in memory of one type and reading its bits
211e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org// back using a different type.
212e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org//
213e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org// The C++ standard is more subtle and complex than this, but that
214e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org// is the basic idea.
215e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org//
216e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org// Anyways ...
217e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org//
218e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org// bit_cast<> calls memcpy() which is blessed by the standard,
219e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org// especially by the example in section 3.9 .  Also, of course,
220e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org// bit_cast<> wraps up the nasty logic in one place.
221e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org//
222e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org// Fortunately memcpy() is very fast.  In optimized mode, with a
223e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org// constant size, gcc 2.95.3, gcc 4.0.1, and msvc 7.1 produce inline
224e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org// code with the minimal amount of data movement.  On a 32-bit system,
225e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org// memcpy(d,s,4) compiles to one load and one store, and memcpy(d,s,8)
226e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org// compiles to two loads and two stores.
227e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org//
228e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org// I tested this code with gcc 2.95.3, gcc 4.0.1, icc 8.1, and msvc 7.1.
229e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org//
230e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org// WARNING: if Dest or Source is a non-POD type, the result of the memcpy
231e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org// is likely to surprise you.
232e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.orgtemplate <class Dest, class Source>
23306b2696801712948b665372a38f96b1f10be6997machenbach@chromium.orgV8_INLINE Dest bit_cast(Source const& source) {
234e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org  COMPILE_ASSERT(sizeof(Dest) == sizeof(Source), VerifySizesAreEqual);
235e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org
236e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org  Dest dest;
237e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org  memcpy(&dest, &source, sizeof(dest));
238e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org  return dest;
239e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org}
240e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org
241e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org
242b67f96038c787a6bd6a835e6c436c82e1b245486machenbach@chromium.org// A macro to disallow the evil copy constructor and operator= functions
243b67f96038c787a6bd6a835e6c436c82e1b245486machenbach@chromium.org// This should be used in the private: declarations for a class
244b67f96038c787a6bd6a835e6c436c82e1b245486machenbach@chromium.org#define DISALLOW_COPY_AND_ASSIGN(TypeName)  \
245b67f96038c787a6bd6a835e6c436c82e1b245486machenbach@chromium.org  TypeName(const TypeName&) V8_DELETE;      \
246b67f96038c787a6bd6a835e6c436c82e1b245486machenbach@chromium.org  void operator=(const TypeName&) V8_DELETE
247b67f96038c787a6bd6a835e6c436c82e1b245486machenbach@chromium.org
248b67f96038c787a6bd6a835e6c436c82e1b245486machenbach@chromium.org
249b67f96038c787a6bd6a835e6c436c82e1b245486machenbach@chromium.org// A macro to disallow all the implicit constructors, namely the
250b67f96038c787a6bd6a835e6c436c82e1b245486machenbach@chromium.org// default constructor, copy constructor and operator= functions.
251b67f96038c787a6bd6a835e6c436c82e1b245486machenbach@chromium.org//
252b67f96038c787a6bd6a835e6c436c82e1b245486machenbach@chromium.org// This should be used in the private: declarations for a class
253b67f96038c787a6bd6a835e6c436c82e1b245486machenbach@chromium.org// that wants to prevent anyone from instantiating it. This is
254b67f96038c787a6bd6a835e6c436c82e1b245486machenbach@chromium.org// especially useful for classes containing only static methods.
255b67f96038c787a6bd6a835e6c436c82e1b245486machenbach@chromium.org#define DISALLOW_IMPLICIT_CONSTRUCTORS(TypeName)  \
256b67f96038c787a6bd6a835e6c436c82e1b245486machenbach@chromium.org  TypeName() V8_DELETE;                           \
257b67f96038c787a6bd6a835e6c436c82e1b245486machenbach@chromium.org  DISALLOW_COPY_AND_ASSIGN(TypeName)
258b67f96038c787a6bd6a835e6c436c82e1b245486machenbach@chromium.org
259b67f96038c787a6bd6a835e6c436c82e1b245486machenbach@chromium.org
260b67f96038c787a6bd6a835e6c436c82e1b245486machenbach@chromium.org// Newly written code should use V8_INLINE and V8_NOINLINE directly.
261b67f96038c787a6bd6a835e6c436c82e1b245486machenbach@chromium.org#define INLINE(declarator)    V8_INLINE declarator
262b67f96038c787a6bd6a835e6c436c82e1b245486machenbach@chromium.org#define NO_INLINE(declarator) V8_NOINLINE declarator
263b67f96038c787a6bd6a835e6c436c82e1b245486machenbach@chromium.org
264b67f96038c787a6bd6a835e6c436c82e1b245486machenbach@chromium.org
265ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org// Newly written code should use WARN_UNUSED_RESULT.
266ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org#define MUST_USE_RESULT WARN_UNUSED_RESULT
267b67f96038c787a6bd6a835e6c436c82e1b245486machenbach@chromium.org
268b67f96038c787a6bd6a835e6c436c82e1b245486machenbach@chromium.org
2696a4d394882dba70a85567fb90ffd4f428a9eb170machenbach@chromium.org// Define V8_USE_ADDRESS_SANITIZER macros.
270b67f96038c787a6bd6a835e6c436c82e1b245486machenbach@chromium.org#if defined(__has_feature)
271b67f96038c787a6bd6a835e6c436c82e1b245486machenbach@chromium.org#if __has_feature(address_sanitizer)
2726a4d394882dba70a85567fb90ffd4f428a9eb170machenbach@chromium.org#define V8_USE_ADDRESS_SANITIZER 1
273b67f96038c787a6bd6a835e6c436c82e1b245486machenbach@chromium.org#endif
274b67f96038c787a6bd6a835e6c436c82e1b245486machenbach@chromium.org#endif
275b67f96038c787a6bd6a835e6c436c82e1b245486machenbach@chromium.org
2766a4d394882dba70a85567fb90ffd4f428a9eb170machenbach@chromium.org// Define DISABLE_ASAN macros.
2776a4d394882dba70a85567fb90ffd4f428a9eb170machenbach@chromium.org#ifdef V8_USE_ADDRESS_SANITIZER
2786a4d394882dba70a85567fb90ffd4f428a9eb170machenbach@chromium.org#define DISABLE_ASAN __attribute__((no_sanitize_address))
2796a4d394882dba70a85567fb90ffd4f428a9eb170machenbach@chromium.org#else
280b67f96038c787a6bd6a835e6c436c82e1b245486machenbach@chromium.org#define DISABLE_ASAN
281b67f96038c787a6bd6a835e6c436c82e1b245486machenbach@chromium.org#endif
282b67f96038c787a6bd6a835e6c436c82e1b245486machenbach@chromium.org
283b67f96038c787a6bd6a835e6c436c82e1b245486machenbach@chromium.org
284b67f96038c787a6bd6a835e6c436c82e1b245486machenbach@chromium.org#if V8_CC_GNU
285b67f96038c787a6bd6a835e6c436c82e1b245486machenbach@chromium.org#define V8_IMMEDIATE_CRASH() __builtin_trap()
286b67f96038c787a6bd6a835e6c436c82e1b245486machenbach@chromium.org#else
287b67f96038c787a6bd6a835e6c436c82e1b245486machenbach@chromium.org#define V8_IMMEDIATE_CRASH() ((void(*)())0)()
288b67f96038c787a6bd6a835e6c436c82e1b245486machenbach@chromium.org#endif
289b67f96038c787a6bd6a835e6c436c82e1b245486machenbach@chromium.org
290e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org
291e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org// Use C++11 static_assert if possible, which gives error
292e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org// messages that are easier to understand on first sight.
293e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org#if V8_HAS_CXX11_STATIC_ASSERT
294e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org#define STATIC_ASSERT(test) static_assert(test, #test)
295e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org#else
296e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org// This is inspired by the static assertion facility in boost.  This
297e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org// is pretty magical.  If it causes you trouble on a platform you may
298e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org// find a fix in the boost code.
299e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.orgtemplate <bool> class StaticAssertion;
300e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.orgtemplate <> class StaticAssertion<true> { };
301e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org// This macro joins two tokens.  If one of the tokens is a macro the
302e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org// helper call causes it to be resolved before joining.
303e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org#define SEMI_STATIC_JOIN(a, b) SEMI_STATIC_JOIN_HELPER(a, b)
304e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org#define SEMI_STATIC_JOIN_HELPER(a, b) a##b
305e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org// Causes an error during compilation of the condition is not
306e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org// statically known to be true.  It is formulated as a typedef so that
307e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org// it can be used wherever a typedef can be used.  Beware that this
308e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org// actually causes each use to introduce a new defined type with a
309e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org// name depending on the source line.
310e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.orgtemplate <int> class StaticAssertionHelper { };
311e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org#define STATIC_ASSERT(test)                                                    \
312e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org  typedef                                                                     \
313e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org    StaticAssertionHelper<sizeof(StaticAssertion<static_cast<bool>((test))>)> \
314ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org    SEMI_STATIC_JOIN(__StaticAssertTypedef__, __LINE__) ALLOW_UNUSED
315e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org
316e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org#endif
317e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org
318e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org
319e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org// The USE(x) template is used to silence C++ compiler warnings
320e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org// issued for (yet) unused variables (typically parameters).
321e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.orgtemplate <typename T>
322e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.orginline void USE(T) { }
323e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org
3243ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.org
3253ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.org#define IS_POWER_OF_TWO(x) ((x) != 0 && (((x) & ((x) - 1)) == 0))
3263ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.org
327248dd43badb99ffce44eae2d767cda3cefaad521machenbach@chromium.org
328248dd43badb99ffce44eae2d767cda3cefaad521machenbach@chromium.org// Define our own macros for writing 64-bit constants.  This is less fragile
329248dd43badb99ffce44eae2d767cda3cefaad521machenbach@chromium.org// than defining __STDC_CONSTANT_MACROS before including <stdint.h>, and it
330248dd43badb99ffce44eae2d767cda3cefaad521machenbach@chromium.org// works on compilers that don't have it (like MSVC).
331248dd43badb99ffce44eae2d767cda3cefaad521machenbach@chromium.org#if V8_CC_MSVC
332248dd43badb99ffce44eae2d767cda3cefaad521machenbach@chromium.org# define V8_UINT64_C(x)   (x ## UI64)
333248dd43badb99ffce44eae2d767cda3cefaad521machenbach@chromium.org# define V8_INT64_C(x)    (x ## I64)
334248dd43badb99ffce44eae2d767cda3cefaad521machenbach@chromium.org# if V8_HOST_ARCH_64_BIT
335248dd43badb99ffce44eae2d767cda3cefaad521machenbach@chromium.org#  define V8_INTPTR_C(x)  (x ## I64)
336248dd43badb99ffce44eae2d767cda3cefaad521machenbach@chromium.org#  define V8_PTR_PREFIX   "ll"
337248dd43badb99ffce44eae2d767cda3cefaad521machenbach@chromium.org# else
338248dd43badb99ffce44eae2d767cda3cefaad521machenbach@chromium.org#  define V8_INTPTR_C(x)  (x)
339248dd43badb99ffce44eae2d767cda3cefaad521machenbach@chromium.org#  define V8_PTR_PREFIX   ""
340248dd43badb99ffce44eae2d767cda3cefaad521machenbach@chromium.org# endif  // V8_HOST_ARCH_64_BIT
341248dd43badb99ffce44eae2d767cda3cefaad521machenbach@chromium.org#elif V8_CC_MINGW64
342248dd43badb99ffce44eae2d767cda3cefaad521machenbach@chromium.org# define V8_UINT64_C(x)   (x ## ULL)
343248dd43badb99ffce44eae2d767cda3cefaad521machenbach@chromium.org# define V8_INT64_C(x)    (x ## LL)
344248dd43badb99ffce44eae2d767cda3cefaad521machenbach@chromium.org# define V8_INTPTR_C(x)   (x ## LL)
345248dd43badb99ffce44eae2d767cda3cefaad521machenbach@chromium.org# define V8_PTR_PREFIX    "I64"
346248dd43badb99ffce44eae2d767cda3cefaad521machenbach@chromium.org#elif V8_HOST_ARCH_64_BIT
347248dd43badb99ffce44eae2d767cda3cefaad521machenbach@chromium.org# if V8_OS_MACOSX
348248dd43badb99ffce44eae2d767cda3cefaad521machenbach@chromium.org#  define V8_UINT64_C(x)   (x ## ULL)
349248dd43badb99ffce44eae2d767cda3cefaad521machenbach@chromium.org#  define V8_INT64_C(x)    (x ## LL)
350248dd43badb99ffce44eae2d767cda3cefaad521machenbach@chromium.org# else
351248dd43badb99ffce44eae2d767cda3cefaad521machenbach@chromium.org#  define V8_UINT64_C(x)   (x ## UL)
352248dd43badb99ffce44eae2d767cda3cefaad521machenbach@chromium.org#  define V8_INT64_C(x)    (x ## L)
353248dd43badb99ffce44eae2d767cda3cefaad521machenbach@chromium.org# endif
354248dd43badb99ffce44eae2d767cda3cefaad521machenbach@chromium.org# define V8_INTPTR_C(x)   (x ## L)
355248dd43badb99ffce44eae2d767cda3cefaad521machenbach@chromium.org# define V8_PTR_PREFIX    "l"
356248dd43badb99ffce44eae2d767cda3cefaad521machenbach@chromium.org#else
357248dd43badb99ffce44eae2d767cda3cefaad521machenbach@chromium.org# define V8_UINT64_C(x)   (x ## ULL)
358248dd43badb99ffce44eae2d767cda3cefaad521machenbach@chromium.org# define V8_INT64_C(x)    (x ## LL)
359248dd43badb99ffce44eae2d767cda3cefaad521machenbach@chromium.org# define V8_INTPTR_C(x)   (x)
360248dd43badb99ffce44eae2d767cda3cefaad521machenbach@chromium.org# define V8_PTR_PREFIX    ""
361248dd43badb99ffce44eae2d767cda3cefaad521machenbach@chromium.org#endif
362248dd43badb99ffce44eae2d767cda3cefaad521machenbach@chromium.org
363248dd43badb99ffce44eae2d767cda3cefaad521machenbach@chromium.org#define V8PRIxPTR V8_PTR_PREFIX "x"
364248dd43badb99ffce44eae2d767cda3cefaad521machenbach@chromium.org#define V8PRIdPTR V8_PTR_PREFIX "d"
365248dd43badb99ffce44eae2d767cda3cefaad521machenbach@chromium.org#define V8PRIuPTR V8_PTR_PREFIX "u"
366248dd43badb99ffce44eae2d767cda3cefaad521machenbach@chromium.org
367248dd43badb99ffce44eae2d767cda3cefaad521machenbach@chromium.org// Fix for Mac OS X defining uintptr_t as "unsigned long":
368248dd43badb99ffce44eae2d767cda3cefaad521machenbach@chromium.org#if V8_OS_MACOSX
369248dd43badb99ffce44eae2d767cda3cefaad521machenbach@chromium.org#undef V8PRIxPTR
370248dd43badb99ffce44eae2d767cda3cefaad521machenbach@chromium.org#define V8PRIxPTR "lx"
371248dd43badb99ffce44eae2d767cda3cefaad521machenbach@chromium.org#endif
372248dd43badb99ffce44eae2d767cda3cefaad521machenbach@chromium.org
3733ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.org// The following macro works on both 32 and 64-bit platforms.
3743ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.org// Usage: instead of writing 0x1234567890123456
3753ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.org//      write V8_2PART_UINT64_C(0x12345678,90123456);
3763ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.org#define V8_2PART_UINT64_C(a, b) (((static_cast<uint64_t>(a) << 32) + 0x##b##u))
3773ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.org
3785de0074a922429f5e0ec2cf140c2d2989bf88140yangguo@chromium.org
3795de0074a922429f5e0ec2cf140c2d2989bf88140yangguo@chromium.org// Compute the 0-relative offset of some absolute value x of type T.
3805de0074a922429f5e0ec2cf140c2d2989bf88140yangguo@chromium.org// This allows conversion of Addresses and integral types into
3815de0074a922429f5e0ec2cf140c2d2989bf88140yangguo@chromium.org// 0-relative int offsets.
3825de0074a922429f5e0ec2cf140c2d2989bf88140yangguo@chromium.orgtemplate <typename T>
3835de0074a922429f5e0ec2cf140c2d2989bf88140yangguo@chromium.orginline intptr_t OffsetFrom(T x) {
3845de0074a922429f5e0ec2cf140c2d2989bf88140yangguo@chromium.org  return x - static_cast<T>(0);
3855de0074a922429f5e0ec2cf140c2d2989bf88140yangguo@chromium.org}
3865de0074a922429f5e0ec2cf140c2d2989bf88140yangguo@chromium.org
3875de0074a922429f5e0ec2cf140c2d2989bf88140yangguo@chromium.org
3885de0074a922429f5e0ec2cf140c2d2989bf88140yangguo@chromium.org// Compute the absolute value of type T for some 0-relative offset x.
3895de0074a922429f5e0ec2cf140c2d2989bf88140yangguo@chromium.org// This allows conversion of 0-relative int offsets into Addresses and
3905de0074a922429f5e0ec2cf140c2d2989bf88140yangguo@chromium.org// integral types.
3915de0074a922429f5e0ec2cf140c2d2989bf88140yangguo@chromium.orgtemplate <typename T>
3925de0074a922429f5e0ec2cf140c2d2989bf88140yangguo@chromium.orginline T AddressFrom(intptr_t x) {
3935de0074a922429f5e0ec2cf140c2d2989bf88140yangguo@chromium.org  return static_cast<T>(static_cast<T>(0) + x);
3945de0074a922429f5e0ec2cf140c2d2989bf88140yangguo@chromium.org}
3955de0074a922429f5e0ec2cf140c2d2989bf88140yangguo@chromium.org
3965de0074a922429f5e0ec2cf140c2d2989bf88140yangguo@chromium.org
3975de0074a922429f5e0ec2cf140c2d2989bf88140yangguo@chromium.org// Return the largest multiple of m which is <= x.
3985de0074a922429f5e0ec2cf140c2d2989bf88140yangguo@chromium.orgtemplate <typename T>
3995de0074a922429f5e0ec2cf140c2d2989bf88140yangguo@chromium.orginline T RoundDown(T x, intptr_t m) {
40021d700eedcdd6570eff22ece724b63a5eefe78cbmachenbach@chromium.org  DCHECK(IS_POWER_OF_TWO(m));
4015de0074a922429f5e0ec2cf140c2d2989bf88140yangguo@chromium.org  return AddressFrom<T>(OffsetFrom(x) & -m);
4025de0074a922429f5e0ec2cf140c2d2989bf88140yangguo@chromium.org}
4035de0074a922429f5e0ec2cf140c2d2989bf88140yangguo@chromium.org
4045de0074a922429f5e0ec2cf140c2d2989bf88140yangguo@chromium.org
4055de0074a922429f5e0ec2cf140c2d2989bf88140yangguo@chromium.org// Return the smallest multiple of m which is >= x.
4065de0074a922429f5e0ec2cf140c2d2989bf88140yangguo@chromium.orgtemplate <typename T>
4075de0074a922429f5e0ec2cf140c2d2989bf88140yangguo@chromium.orginline T RoundUp(T x, intptr_t m) {
4085de0074a922429f5e0ec2cf140c2d2989bf88140yangguo@chromium.org  return RoundDown<T>(static_cast<T>(x + m - 1), m);
4095de0074a922429f5e0ec2cf140c2d2989bf88140yangguo@chromium.org}
4105de0074a922429f5e0ec2cf140c2d2989bf88140yangguo@chromium.org
411b67f96038c787a6bd6a835e6c436c82e1b245486machenbach@chromium.org#endif   // V8_BASE_MACROS_H_
412