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
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.
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.
33 #include "../include/v8stdint.h"
34 extern "C" void V8_Fatal(const char* file, int line, const char* format, ...);
36 // The FATAL, UNREACHABLE and UNIMPLEMENTED macros are useful during
37 // development, but they should not be relied on in the final product.
40 V8_Fatal(__FILE__, __LINE__, "%s", (msg))
41 #define UNIMPLEMENTED() \
42 V8_Fatal(__FILE__, __LINE__, "unimplemented code")
43 #define UNREACHABLE() \
44 V8_Fatal(__FILE__, __LINE__, "unreachable code")
47 V8_Fatal("", 0, "%s", (msg))
48 #define UNIMPLEMENTED() \
49 V8_Fatal("", 0, "unimplemented code")
50 #define UNREACHABLE() ((void) 0)
54 // The CHECK macro checks that the given condition is true; if not, it
55 // prints a message to stderr and aborts.
56 #define CHECK(condition) do { \
58 V8_Fatal(__FILE__, __LINE__, "CHECK(%s) failed", #condition); \
63 // Helper function used by the CHECK_EQ function when given int
64 // arguments. Should not be called directly.
65 inline void CheckEqualsHelper(const char* file, int line,
66 const char* expected_source, int expected,
67 const char* value_source, int value) {
68 if (expected != value) {
70 "CHECK_EQ(%s, %s) failed\n# Expected: %i\n# Found: %i",
71 expected_source, value_source, expected, value);
76 // Helper function used by the CHECK_EQ function when given int64_t
77 // arguments. Should not be called directly.
78 inline void CheckEqualsHelper(const char* file, int line,
79 const char* expected_source,
81 const char* value_source,
83 if (expected != value) {
84 // Print int64_t values in hex, as two int32s,
85 // to avoid platform-dependencies.
87 "CHECK_EQ(%s, %s) failed\n#"
88 " Expected: 0x%08x%08x\n# Found: 0x%08x%08x",
89 expected_source, value_source,
90 static_cast<uint32_t>(expected >> 32),
91 static_cast<uint32_t>(expected),
92 static_cast<uint32_t>(value >> 32),
93 static_cast<uint32_t>(value));
98 // Helper function used by the CHECK_NE function when given int
99 // arguments. Should not be called directly.
100 inline void CheckNonEqualsHelper(const char* file,
102 const char* unexpected_source,
104 const char* value_source,
106 if (unexpected == value) {
107 V8_Fatal(file, line, "CHECK_NE(%s, %s) failed\n# Value: %i",
108 unexpected_source, value_source, value);
113 // Helper function used by the CHECK function when given string
114 // arguments. Should not be called directly.
115 inline void CheckEqualsHelper(const char* file,
117 const char* expected_source,
118 const char* expected,
119 const char* value_source,
121 if ((expected == NULL && value != NULL) ||
122 (expected != NULL && value == NULL) ||
123 (expected != NULL && value != NULL && strcmp(expected, value) != 0)) {
125 "CHECK_EQ(%s, %s) failed\n# Expected: %s\n# Found: %s",
126 expected_source, value_source, expected, value);
131 inline void CheckNonEqualsHelper(const char* file,
133 const char* expected_source,
134 const char* expected,
135 const char* value_source,
137 if (expected == value ||
138 (expected != NULL && value != NULL && strcmp(expected, value) == 0)) {
139 V8_Fatal(file, line, "CHECK_NE(%s, %s) failed\n# Value: %s",
140 expected_source, value_source, value);
145 // Helper function used by the CHECK function when given pointer
146 // arguments. Should not be called directly.
147 inline void CheckEqualsHelper(const char* file,
149 const char* expected_source,
150 const void* expected,
151 const char* value_source,
153 if (expected != value) {
155 "CHECK_EQ(%s, %s) failed\n# Expected: %p\n# Found: %p",
156 expected_source, value_source,
162 inline void CheckNonEqualsHelper(const char* file,
164 const char* expected_source,
165 const void* expected,
166 const char* value_source,
168 if (expected == value) {
169 V8_Fatal(file, line, "CHECK_NE(%s, %s) failed\n# Value: %p",
170 expected_source, value_source, value);
175 // Helper function used by the CHECK function when given floating
176 // point arguments. Should not be called directly.
177 inline void CheckEqualsHelper(const char* file,
179 const char* expected_source,
181 const char* value_source,
183 // Force values to 64 bit memory to truncate 80 bit precision on IA32.
184 volatile double* exp = new double[1];
186 volatile double* val = new double[1];
190 "CHECK_EQ(%s, %s) failed\n# Expected: %f\n# Found: %f",
191 expected_source, value_source, *exp, *val);
198 inline void CheckNonEqualsHelper(const char* file,
200 const char* expected_source,
202 const char* value_source,
204 // Force values to 64 bit memory to truncate 80 bit precision on IA32.
205 volatile double* exp = new double[1];
207 volatile double* val = new double[1];
211 "CHECK_NE(%s, %s) failed\n# Value: %f",
212 expected_source, value_source, *val);
219 #define CHECK_EQ(expected, value) CheckEqualsHelper(__FILE__, __LINE__, \
220 #expected, expected, #value, value)
223 #define CHECK_NE(unexpected, value) CheckNonEqualsHelper(__FILE__, __LINE__, \
224 #unexpected, unexpected, #value, value)
227 #define CHECK_GT(a, b) CHECK((a) > (b))
228 #define CHECK_GE(a, b) CHECK((a) >= (b))
229 #define CHECK_LT(a, b) CHECK((a) < (b))
230 #define CHECK_LE(a, b) CHECK((a) <= (b))
233 // This is inspired by the static assertion facility in boost. This
234 // is pretty magical. If it causes you trouble on a platform you may
235 // find a fix in the boost code.
236 template <bool> class StaticAssertion;
237 template <> class StaticAssertion<true> { };
238 // This macro joins two tokens. If one of the tokens is a macro the
239 // helper call causes it to be resolved before joining.
240 #define SEMI_STATIC_JOIN(a, b) SEMI_STATIC_JOIN_HELPER(a, b)
241 #define SEMI_STATIC_JOIN_HELPER(a, b) a##b
242 // Causes an error during compilation of the condition is not
243 // statically known to be true. It is formulated as a typedef so that
244 // it can be used wherever a typedef can be used. Beware that this
245 // actually causes each use to introduce a new defined type with a
246 // name depending on the source line.
247 template <int> class StaticAssertionHelper { };
248 #define STATIC_CHECK(test) \
250 StaticAssertionHelper<sizeof(StaticAssertion<static_cast<bool>((test))>)> \
251 SEMI_STATIC_JOIN(__StaticAssertTypedef__, __LINE__)
254 extern bool FLAG_enable_slow_asserts;
257 // The ASSERT macro is equivalent to CHECK except that it only
258 // generates code in debug builds.
260 #define ASSERT_RESULT(expr) CHECK(expr)
261 #define ASSERT(condition) CHECK(condition)
262 #define ASSERT_EQ(v1, v2) CHECK_EQ(v1, v2)
263 #define ASSERT_NE(v1, v2) CHECK_NE(v1, v2)
264 #define ASSERT_GE(v1, v2) CHECK_GE(v1, v2)
265 #define ASSERT_LT(v1, v2) CHECK_LT(v1, v2)
266 #define ASSERT_LE(v1, v2) CHECK_LE(v1, v2)
267 #define SLOW_ASSERT(condition) CHECK(!FLAG_enable_slow_asserts || (condition))
269 #define ASSERT_RESULT(expr) (expr)
270 #define ASSERT(condition) ((void) 0)
271 #define ASSERT_EQ(v1, v2) ((void) 0)
272 #define ASSERT_NE(v1, v2) ((void) 0)
273 #define ASSERT_GE(v1, v2) ((void) 0)
274 #define ASSERT_LT(v1, v2) ((void) 0)
275 #define ASSERT_LE(v1, v2) ((void) 0)
276 #define SLOW_ASSERT(condition) ((void) 0)
278 // Static asserts has no impact on runtime performance, so they can be
279 // safely enabled in release mode. Moreover, the ((void) 0) expression
280 // obeys different syntax rules than typedef's, e.g. it can't appear
281 // inside class declaration, this leads to inconsistency between debug
282 // and release compilation modes behavior.
283 #define STATIC_ASSERT(test) STATIC_CHECK(test)
285 #define ASSERT_NOT_NULL(p) ASSERT_NE(NULL, p)
287 #endif // V8_CHECKS_H_