Upstream version 7.36.149.0
[platform/framework/web/crosswalk.git] / src / v8 / src / checks.h
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_CHECKS_H_
6 #define V8_CHECKS_H_
7
8 #include <string.h>
9
10 #include "../include/v8stdint.h"
11
12 extern "C" void V8_Fatal(const char* file, int line, const char* format, ...);
13
14
15 // The FATAL, UNREACHABLE and UNIMPLEMENTED macros are useful during
16 // development, but they should not be relied on in the final product.
17 #ifdef DEBUG
18 #define FATAL(msg)                              \
19   V8_Fatal(__FILE__, __LINE__, "%s", (msg))
20 #define UNIMPLEMENTED()                         \
21   V8_Fatal(__FILE__, __LINE__, "unimplemented code")
22 #define UNREACHABLE()                           \
23   V8_Fatal(__FILE__, __LINE__, "unreachable code")
24 #else
25 #define FATAL(msg)                              \
26   V8_Fatal("", 0, "%s", (msg))
27 #define UNIMPLEMENTED()                         \
28   V8_Fatal("", 0, "unimplemented code")
29 #define UNREACHABLE() ((void) 0)
30 #endif
31
32 // Simulator specific helpers.
33 #if defined(USE_SIMULATOR) && defined(V8_TARGET_ARCH_ARM64)
34   // TODO(all): If possible automatically prepend an indicator like
35   // UNIMPLEMENTED or LOCATION.
36   #define ASM_UNIMPLEMENTED(message)                                         \
37   __ Debug(message, __LINE__, NO_PARAM)
38   #define ASM_UNIMPLEMENTED_BREAK(message)                                   \
39   __ Debug(message, __LINE__,                                                \
40            FLAG_ignore_asm_unimplemented_break ? NO_PARAM : BREAK)
41   #define ASM_LOCATION(message)                                              \
42   __ Debug("LOCATION: " message, __LINE__, NO_PARAM)
43 #else
44   #define ASM_UNIMPLEMENTED(message)
45   #define ASM_UNIMPLEMENTED_BREAK(message)
46   #define ASM_LOCATION(message)
47 #endif
48
49
50 // The CHECK macro checks that the given condition is true; if not, it
51 // prints a message to stderr and aborts.
52 #define CHECK(condition) do {                                       \
53     if (!(condition)) {                                             \
54       V8_Fatal(__FILE__, __LINE__, "CHECK(%s) failed", #condition); \
55     }                                                               \
56   } while (0)
57
58
59 // Helper function used by the CHECK_EQ function when given int
60 // arguments.  Should not be called directly.
61 inline void CheckEqualsHelper(const char* file, int line,
62                               const char* expected_source, int expected,
63                               const char* value_source, int value) {
64   if (expected != value) {
65     V8_Fatal(file, line,
66              "CHECK_EQ(%s, %s) failed\n#   Expected: %i\n#   Found: %i",
67              expected_source, value_source, expected, value);
68   }
69 }
70
71
72 // Helper function used by the CHECK_EQ function when given int64_t
73 // arguments.  Should not be called directly.
74 inline void CheckEqualsHelper(const char* file, int line,
75                               const char* expected_source,
76                               int64_t expected,
77                               const char* value_source,
78                               int64_t value) {
79   if (expected != value) {
80     // Print int64_t values in hex, as two int32s,
81     // to avoid platform-dependencies.
82     V8_Fatal(file, line,
83              "CHECK_EQ(%s, %s) failed\n#"
84              "   Expected: 0x%08x%08x\n#   Found: 0x%08x%08x",
85              expected_source, value_source,
86              static_cast<uint32_t>(expected >> 32),
87              static_cast<uint32_t>(expected),
88              static_cast<uint32_t>(value >> 32),
89              static_cast<uint32_t>(value));
90   }
91 }
92
93
94 // Helper function used by the CHECK_NE function when given int
95 // arguments.  Should not be called directly.
96 inline void CheckNonEqualsHelper(const char* file,
97                                  int line,
98                                  const char* unexpected_source,
99                                  int unexpected,
100                                  const char* value_source,
101                                  int value) {
102   if (unexpected == value) {
103     V8_Fatal(file, line, "CHECK_NE(%s, %s) failed\n#   Value: %i",
104              unexpected_source, value_source, value);
105   }
106 }
107
108
109 // Helper function used by the CHECK function when given string
110 // arguments.  Should not be called directly.
111 inline void CheckEqualsHelper(const char* file,
112                               int line,
113                               const char* expected_source,
114                               const char* expected,
115                               const char* value_source,
116                               const char* value) {
117   if ((expected == NULL && value != NULL) ||
118       (expected != NULL && value == NULL) ||
119       (expected != NULL && value != NULL && strcmp(expected, value) != 0)) {
120     V8_Fatal(file, line,
121              "CHECK_EQ(%s, %s) failed\n#   Expected: %s\n#   Found: %s",
122              expected_source, value_source, expected, value);
123   }
124 }
125
126
127 inline void CheckNonEqualsHelper(const char* file,
128                                  int line,
129                                  const char* expected_source,
130                                  const char* expected,
131                                  const char* value_source,
132                                  const char* value) {
133   if (expected == value ||
134       (expected != NULL && value != NULL && strcmp(expected, value) == 0)) {
135     V8_Fatal(file, line, "CHECK_NE(%s, %s) failed\n#   Value: %s",
136              expected_source, value_source, value);
137   }
138 }
139
140
141 // Helper function used by the CHECK function when given pointer
142 // arguments.  Should not be called directly.
143 inline void CheckEqualsHelper(const char* file,
144                               int line,
145                               const char* expected_source,
146                               const void* expected,
147                               const char* value_source,
148                               const void* value) {
149   if (expected != value) {
150     V8_Fatal(file, line,
151              "CHECK_EQ(%s, %s) failed\n#   Expected: %p\n#   Found: %p",
152              expected_source, value_source,
153              expected, value);
154   }
155 }
156
157
158 inline void CheckNonEqualsHelper(const char* file,
159                                  int line,
160                                  const char* expected_source,
161                                  const void* expected,
162                                  const char* value_source,
163                                  const void* value) {
164   if (expected == value) {
165     V8_Fatal(file, line, "CHECK_NE(%s, %s) failed\n#   Value: %p",
166              expected_source, value_source, value);
167   }
168 }
169
170
171 // Helper function used by the CHECK function when given floating
172 // point arguments.  Should not be called directly.
173 inline void CheckEqualsHelper(const char* file,
174                               int line,
175                               const char* expected_source,
176                               double expected,
177                               const char* value_source,
178                               double value) {
179   // Force values to 64 bit memory to truncate 80 bit precision on IA32.
180   volatile double* exp = new double[1];
181   *exp = expected;
182   volatile double* val = new double[1];
183   *val = value;
184   if (*exp != *val) {
185     V8_Fatal(file, line,
186              "CHECK_EQ(%s, %s) failed\n#   Expected: %f\n#   Found: %f",
187              expected_source, value_source, *exp, *val);
188   }
189   delete[] exp;
190   delete[] val;
191 }
192
193
194 inline void CheckNonEqualsHelper(const char* file,
195                               int line,
196                               const char* expected_source,
197                               int64_t expected,
198                               const char* value_source,
199                               int64_t value) {
200   if (expected == value) {
201     V8_Fatal(file, line,
202              "CHECK_EQ(%s, %s) failed\n#   Expected: %f\n#   Found: %f",
203              expected_source, value_source, expected, value);
204   }
205 }
206
207
208 inline void CheckNonEqualsHelper(const char* file,
209                                  int line,
210                                  const char* expected_source,
211                                  double expected,
212                                  const char* value_source,
213                                  double value) {
214   // Force values to 64 bit memory to truncate 80 bit precision on IA32.
215   volatile double* exp = new double[1];
216   *exp = expected;
217   volatile double* val = new double[1];
218   *val = value;
219   if (*exp == *val) {
220     V8_Fatal(file, line,
221              "CHECK_NE(%s, %s) failed\n#   Value: %f",
222              expected_source, value_source, *val);
223   }
224   delete[] exp;
225   delete[] val;
226 }
227
228
229 #define CHECK_EQ(expected, value) CheckEqualsHelper(__FILE__, __LINE__, \
230   #expected, expected, #value, value)
231
232
233 #define CHECK_NE(unexpected, value) CheckNonEqualsHelper(__FILE__, __LINE__, \
234   #unexpected, unexpected, #value, value)
235
236
237 #define CHECK_GT(a, b) CHECK((a) > (b))
238 #define CHECK_GE(a, b) CHECK((a) >= (b))
239 #define CHECK_LT(a, b) CHECK((a) < (b))
240 #define CHECK_LE(a, b) CHECK((a) <= (b))
241
242
243 // Use C++11 static_assert if possible, which gives error
244 // messages that are easier to understand on first sight.
245 #if V8_HAS_CXX11_STATIC_ASSERT
246 #define STATIC_CHECK(test) static_assert(test, #test)
247 #else
248 // This is inspired by the static assertion facility in boost.  This
249 // is pretty magical.  If it causes you trouble on a platform you may
250 // find a fix in the boost code.
251 template <bool> class StaticAssertion;
252 template <> class StaticAssertion<true> { };
253 // This macro joins two tokens.  If one of the tokens is a macro the
254 // helper call causes it to be resolved before joining.
255 #define SEMI_STATIC_JOIN(a, b) SEMI_STATIC_JOIN_HELPER(a, b)
256 #define SEMI_STATIC_JOIN_HELPER(a, b) a##b
257 // Causes an error during compilation of the condition is not
258 // statically known to be true.  It is formulated as a typedef so that
259 // it can be used wherever a typedef can be used.  Beware that this
260 // actually causes each use to introduce a new defined type with a
261 // name depending on the source line.
262 template <int> class StaticAssertionHelper { };
263 #define STATIC_CHECK(test)                                                    \
264   typedef                                                                     \
265     StaticAssertionHelper<sizeof(StaticAssertion<static_cast<bool>((test))>)> \
266     SEMI_STATIC_JOIN(__StaticAssertTypedef__, __LINE__) V8_UNUSED
267 #endif
268
269
270 #ifdef DEBUG
271 #ifndef OPTIMIZED_DEBUG
272 #define ENABLE_SLOW_ASSERTS    1
273 #endif
274 #endif
275
276 namespace v8 {
277 namespace internal {
278 #ifdef ENABLE_SLOW_ASSERTS
279 #define SLOW_ASSERT(condition) \
280   CHECK(!v8::internal::FLAG_enable_slow_asserts || (condition))
281 extern bool FLAG_enable_slow_asserts;
282 #else
283 #define SLOW_ASSERT(condition) ((void) 0)
284 const bool FLAG_enable_slow_asserts = false;
285 #endif
286
287 // Exposed for making debugging easier (to see where your function is being
288 // called, just add a call to DumpBacktrace).
289 void DumpBacktrace();
290
291 } }  // namespace v8::internal
292
293
294 // The ASSERT macro is equivalent to CHECK except that it only
295 // generates code in debug builds.
296 #ifdef DEBUG
297 #define ASSERT_RESULT(expr)    CHECK(expr)
298 #define ASSERT(condition)      CHECK(condition)
299 #define ASSERT_EQ(v1, v2)      CHECK_EQ(v1, v2)
300 #define ASSERT_NE(v1, v2)      CHECK_NE(v1, v2)
301 #define ASSERT_GE(v1, v2)      CHECK_GE(v1, v2)
302 #define ASSERT_LT(v1, v2)      CHECK_LT(v1, v2)
303 #define ASSERT_LE(v1, v2)      CHECK_LE(v1, v2)
304 #else
305 #define ASSERT_RESULT(expr)    (expr)
306 #define ASSERT(condition)      ((void) 0)
307 #define ASSERT_EQ(v1, v2)      ((void) 0)
308 #define ASSERT_NE(v1, v2)      ((void) 0)
309 #define ASSERT_GE(v1, v2)      ((void) 0)
310 #define ASSERT_LT(v1, v2)      ((void) 0)
311 #define ASSERT_LE(v1, v2)      ((void) 0)
312 #endif
313 // Static asserts has no impact on runtime performance, so they can be
314 // safely enabled in release mode. Moreover, the ((void) 0) expression
315 // obeys different syntax rules than typedef's, e.g. it can't appear
316 // inside class declaration, this leads to inconsistency between debug
317 // and release compilation modes behavior.
318 #define STATIC_ASSERT(test)  STATIC_CHECK(test)
319
320 #define ASSERT_NOT_NULL(p)  ASSERT_NE(NULL, p)
321
322 // "Extra checks" are lightweight checks that are enabled in some release
323 // builds.
324 #ifdef ENABLE_EXTRA_CHECKS
325 #define EXTRA_CHECK(condition) CHECK(condition)
326 #else
327 #define EXTRA_CHECK(condition) ((void) 0)
328 #endif
329
330 #endif  // V8_CHECKS_H_