blob: 77c43bc0c2dd77b99a8aca200b3e886105554b12 [file] [log] [blame]
ager@chromium.org9258b6b2008-09-11 09:11:10 +00001// Copyright 2006-2008 the V8 project authors. All rights reserved.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002// 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_CHECKS_H_
29#define V8_CHECKS_H_
30
31#include <string.h>
32
33#include "flags.h"
34
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000035extern "C" void V8_Fatal(const char* file, int line, const char* format, ...);
36void API_Fatal(const char* location, const char* format, ...);
37
38// The FATAL, UNREACHABLE and UNIMPLEMENTED macros are useful during
39// development, but they should not be relied on in the final product.
ager@chromium.org236ad962008-09-25 09:45:57 +000040#ifdef DEBUG
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000041#define FATAL(msg) \
42 V8_Fatal(__FILE__, __LINE__, "%s", (msg))
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000043#define UNIMPLEMENTED() \
44 V8_Fatal(__FILE__, __LINE__, "unimplemented code")
ager@chromium.org236ad962008-09-25 09:45:57 +000045#define UNREACHABLE() \
46 V8_Fatal(__FILE__, __LINE__, "unreachable code")
47#else
48#define FATAL(msg) \
49 V8_Fatal("", 0, "%s", (msg))
50#define UNIMPLEMENTED() \
51 V8_Fatal("", 0, "unimplemented code")
52#define UNREACHABLE() ((void) 0)
53#endif
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000054
55
56// Used by the CHECK macro -- should not be called directly.
57static inline void CheckHelper(const char* file,
58 int line,
59 const char* source,
60 bool condition) {
61 if (!condition)
62 V8_Fatal(file, line, "CHECK(%s) failed", source);
63}
64
65
66// The CHECK macro checks that the given condition is true; if not, it
67// prints a message to stderr and aborts.
68#define CHECK(condition) CheckHelper(__FILE__, __LINE__, #condition, condition)
69
70
71// Helper function used by the CHECK_EQ function when given int
72// arguments. Should not be called directly.
73static inline void CheckEqualsHelper(const char* file, int line,
74 const char* expected_source, int expected,
75 const char* value_source, int value) {
76 if (expected != value) {
77 V8_Fatal(file, line,
78 "CHECK_EQ(%s, %s) failed\n# Expected: %i\n# Found: %i",
79 expected_source, value_source, expected, value);
80 }
81}
82
83
84// Helper function used by the CHECK_NE function when given int
85// arguments. Should not be called directly.
86static inline void CheckNonEqualsHelper(const char* file,
87 int line,
88 const char* unexpected_source,
89 int unexpected,
90 const char* value_source,
91 int value) {
92 if (unexpected == value) {
93 V8_Fatal(file, line, "CHECK_NE(%s, %s) failed\n# Value: %i",
94 unexpected_source, value_source, value);
95 }
96}
97
98
99// Helper function used by the CHECK function when given string
100// arguments. Should not be called directly.
101static inline void CheckEqualsHelper(const char* file,
102 int line,
103 const char* expected_source,
104 const char* expected,
105 const char* value_source,
106 const char* value) {
107 if (strcmp(expected, value) != 0) {
108 V8_Fatal(file, line,
109 "CHECK_EQ(%s, %s) failed\n# Expected: %s\n# Found: %s",
110 expected_source, value_source, expected, value);
111 }
112}
113
114
115static inline void CheckNonEqualsHelper(const char* file,
116 int line,
117 const char* expected_source,
118 const char* expected,
119 const char* value_source,
120 const char* value) {
121 if (expected == value ||
122 (expected != NULL && value != NULL && strcmp(expected, value) == 0)) {
123 V8_Fatal(file, line, "CHECK_NE(%s, %s) failed\n# Value: %s",
124 expected_source, value_source, value);
125 }
126}
127
128
129// Helper function used by the CHECK function when given pointer
130// arguments. Should not be called directly.
131static inline void CheckEqualsHelper(const char* file,
132 int line,
133 const char* expected_source,
134 void* expected,
135 const char* value_source,
136 void* value) {
137 if (expected != value) {
138 V8_Fatal(file, line,
139 "CHECK_EQ(%s, %s) failed\n# Expected: %i\n# Found: %i",
140 expected_source, value_source,
141 reinterpret_cast<int>(expected), reinterpret_cast<int>(value));
142 }
143}
144
145
146static inline void CheckNonEqualsHelper(const char* file,
147 int line,
148 const char* expected_source,
149 void* expected,
150 const char* value_source,
151 void* value) {
152 if (expected == value) {
153 V8_Fatal(file, line, "CHECK_NE(%s, %s) failed\n# Value: %i",
154 expected_source, value_source, reinterpret_cast<int>(value));
155 }
156}
157
158
159// Helper function used by the CHECK function when given floating
160// point arguments. Should not be called directly.
161static inline void CheckEqualsHelper(const char* file,
162 int line,
163 const char* expected_source,
164 double expected,
165 const char* value_source,
166 double value) {
kasperl@chromium.org41044eb2008-10-06 08:24:46 +0000167 // Force values to 64 bit memory to truncate 80 bit precision on IA32.
168 volatile double* exp = new double[1];
169 *exp = expected;
170 volatile double* val = new double[1];
171 *val = value;
172 if (*exp != *val) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000173 V8_Fatal(file, line,
174 "CHECK_EQ(%s, %s) failed\n# Expected: %f\n# Found: %f",
kasperl@chromium.org41044eb2008-10-06 08:24:46 +0000175 expected_source, value_source, *exp, *val);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000176 }
kasperl@chromium.org41044eb2008-10-06 08:24:46 +0000177 delete[] exp;
178 delete[] val;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000179}
180
181
182namespace v8 {
183 class Value;
184 template <class T> class Handle;
185}
186
187
188void CheckNonEqualsHelper(const char* file,
189 int line,
190 const char* unexpected_source,
191 v8::Handle<v8::Value> unexpected,
192 const char* value_source,
193 v8::Handle<v8::Value> value);
194
195
196void CheckEqualsHelper(const char* file,
197 int line,
198 const char* expected_source,
199 v8::Handle<v8::Value> expected,
200 const char* value_source,
201 v8::Handle<v8::Value> value);
202
203
204#define CHECK_EQ(expected, value) CheckEqualsHelper(__FILE__, __LINE__, \
205 #expected, expected, #value, value)
206
207
208#define CHECK_NE(unexpected, value) CheckNonEqualsHelper(__FILE__, __LINE__, \
209 #unexpected, unexpected, #value, value)
210
211
212#define CHECK_GT(a, b) CHECK((a) > (b))
213#define CHECK_GE(a, b) CHECK((a) >= (b))
214
215
216// This is inspired by the static assertion facility in boost. This
217// is pretty magical. If it causes you trouble on a platform you may
218// find a fix in the boost code.
219template <bool> class StaticAssertion;
220template <> class StaticAssertion<true> { };
221// This macro joins two tokens. If one of the tokens is a macro the
222// helper call causes it to be resolved before joining.
223#define SEMI_STATIC_JOIN(a, b) SEMI_STATIC_JOIN_HELPER(a, b)
224#define SEMI_STATIC_JOIN_HELPER(a, b) a##b
225// Causes an error during compilation of the condition is not
226// statically known to be true. It is formulated as a typedef so that
227// it can be used wherever a typedef can be used. Beware that this
228// actually causes each use to introduce a new defined type with a
229// name depending on the source line.
230template <int> class StaticAssertionHelper { };
231#define STATIC_CHECK(test) \
232 typedef \
233 StaticAssertionHelper<sizeof(StaticAssertion<static_cast<bool>(test)>)> \
234 SEMI_STATIC_JOIN(__StaticAssertTypedef__, __LINE__)
235
236
237// The ASSERT macro is equivalent to CHECK except that it only
238// generates code in debug builds. Ditto STATIC_ASSERT.
239#ifdef DEBUG
ager@chromium.orga74f0da2008-12-03 16:05:52 +0000240#define ASSERT_RESULT(expr) CHECK(expr)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000241#define ASSERT(condition) CHECK(condition)
242#define ASSERT_EQ(v1, v2) CHECK_EQ(v1, v2)
243#define ASSERT_NE(v1, v2) CHECK_NE(v1, v2)
244#define STATIC_ASSERT(test) STATIC_CHECK(test)
245#define SLOW_ASSERT(condition) if (FLAG_enable_slow_asserts) CHECK(condition)
246#else
ager@chromium.orga74f0da2008-12-03 16:05:52 +0000247#define ASSERT_RESULT(expr) (expr)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000248#define ASSERT(condition) ((void) 0)
249#define ASSERT_EQ(v1, v2) ((void) 0)
250#define ASSERT_NE(v1, v2) ((void) 0)
251#define STATIC_ASSERT(test) ((void) 0)
252#define SLOW_ASSERT(condition) ((void) 0)
253#endif
254
255
256#define ASSERT_TAG_ALIGNED(address) \
257 ASSERT((reinterpret_cast<int>(address) & kHeapObjectTagMask) == 0)
258
259#define ASSERT_SIZE_TAG_ALIGNED(size) ASSERT((size & kHeapObjectTagMask) == 0)
260
ager@chromium.orga74f0da2008-12-03 16:05:52 +0000261#define ASSERT_NOT_NULL(p) ASSERT_NE(NULL, p)
262
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000263#endif // V8_CHECKS_H_