]> git.saurik.com Git - apple/javascriptcore.git/blame - wtf/Assertions.h
JavaScriptCore-903.5.tar.gz
[apple/javascriptcore.git] / wtf / Assertions.h
CommitLineData
b37bf2e1
A
1/*
2 * Copyright (C) 2003, 2006, 2007 Apple Inc. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 *
13 * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24 */
25
26#ifndef WTF_Assertions_h
27#define WTF_Assertions_h
28
29/*
30 no namespaces because this file has to be includable from C and Objective-C
31
32 Note, this file uses many GCC extensions, but it should be compatible with
33 C, Objective C, C++, and Objective C++.
34
35 For non-debug builds, everything is disabled by default.
36 Defining any of the symbols explicitly prevents this from having any effect.
37
38 MSVC7 note: variadic macro support was added in MSVC8, so for now we disable
39 those macros in MSVC7. For more info, see the MSDN document on variadic
40 macros here:
41
42 http://msdn2.microsoft.com/en-us/library/ms177415(VS.80).aspx
43*/
44
45#include "Platform.h"
46
ba379fdc
A
47#include <stdbool.h>
48
b37bf2e1 49#include <stddef.h>
14957cd0
A
50
51#if !COMPILER(MSVC)
b37bf2e1
A
52#include <inttypes.h>
53#endif
54
f9bf01c6
A
55#if OS(SYMBIAN)
56#include <e32def.h>
57#include <e32debug.h>
58#endif
59
14957cd0
A
60#if PLATFORM(BREWMP)
61#include <AEEError.h>
62#include <AEEdbg.h>
63#endif
64
b37bf2e1 65#ifdef NDEBUG
4e4e5a6f 66/* Disable ASSERT* macros in release mode. */
b37bf2e1
A
67#define ASSERTIONS_DISABLED_DEFAULT 1
68#else
69#define ASSERTIONS_DISABLED_DEFAULT 0
70#endif
71
4e4e5a6f 72#if COMPILER(MSVC7_OR_LOWER) || COMPILER(WINSCW)
f9bf01c6
A
73#define HAVE_VARIADIC_MACRO 0
74#else
75#define HAVE_VARIADIC_MACRO 1
76#endif
77
14957cd0
A
78#ifndef BACKTRACE_DISABLED
79#define BACKTRACE_DISABLED ASSERTIONS_DISABLED_DEFAULT
80#endif
81
b37bf2e1
A
82#ifndef ASSERT_DISABLED
83#define ASSERT_DISABLED ASSERTIONS_DISABLED_DEFAULT
84#endif
85
f9bf01c6
A
86#ifndef ASSERT_MSG_DISABLED
87#if HAVE(VARIADIC_MACRO)
88#define ASSERT_MSG_DISABLED ASSERTIONS_DISABLED_DEFAULT
89#else
90#define ASSERT_MSG_DISABLED 1
91#endif
92#endif
93
b37bf2e1
A
94#ifndef ASSERT_ARG_DISABLED
95#define ASSERT_ARG_DISABLED ASSERTIONS_DISABLED_DEFAULT
96#endif
97
98#ifndef FATAL_DISABLED
f9bf01c6 99#if HAVE(VARIADIC_MACRO)
b37bf2e1 100#define FATAL_DISABLED ASSERTIONS_DISABLED_DEFAULT
f9bf01c6
A
101#else
102#define FATAL_DISABLED 1
103#endif
b37bf2e1
A
104#endif
105
106#ifndef ERROR_DISABLED
f9bf01c6 107#if HAVE(VARIADIC_MACRO)
b37bf2e1 108#define ERROR_DISABLED ASSERTIONS_DISABLED_DEFAULT
f9bf01c6
A
109#else
110#define ERROR_DISABLED 1
111#endif
b37bf2e1
A
112#endif
113
114#ifndef LOG_DISABLED
f9bf01c6 115#if HAVE(VARIADIC_MACRO)
b37bf2e1 116#define LOG_DISABLED ASSERTIONS_DISABLED_DEFAULT
f9bf01c6
A
117#else
118#define LOG_DISABLED 1
119#endif
b37bf2e1
A
120#endif
121
122#if COMPILER(GCC)
123#define WTF_PRETTY_FUNCTION __PRETTY_FUNCTION__
124#else
125#define WTF_PRETTY_FUNCTION __FUNCTION__
126#endif
127
9dae56ea
A
128/* WTF logging functions can process %@ in the format string to log a NSObject* but the printf format attribute
129 emits a warning when %@ is used in the format string. Until <rdar://problem/5195437> is resolved we can't include
130 the attribute when being used from Objective-C code in case it decides to use %@. */
b37bf2e1
A
131#if COMPILER(GCC) && !defined(__OBJC__)
132#define WTF_ATTRIBUTE_PRINTF(formatStringArgument, extraArguments) __attribute__((__format__(printf, formatStringArgument, extraArguments)))
133#else
134#define WTF_ATTRIBUTE_PRINTF(formatStringArgument, extraArguments)
135#endif
136
ba379fdc
A
137/* This macro is needed to prevent the clang static analyzer from generating false-positive reports in ASSERT() macros. */
138#ifdef __clang__
139#define CLANG_ANALYZER_NORETURN __attribute__((analyzer_noreturn))
140#else
141#define CLANG_ANALYZER_NORETURN
142#endif
14957cd0
A
143/* For project uses WTF but has no config.h, we need to explicitly set the export defines here. */
144#ifndef WTF_EXPORT_PRIVATE
145#define WTF_EXPORT_PRIVATE
146#endif
ba379fdc 147
b37bf2e1
A
148/* These helper functions are always declared, but not necessarily always defined if the corresponding function is disabled. */
149
150#ifdef __cplusplus
151extern "C" {
152#endif
153
154typedef enum { WTFLogChannelOff, WTFLogChannelOn } WTFLogChannelState;
155
156typedef struct {
157 unsigned mask;
158 const char *defaultName;
159 WTFLogChannelState state;
160} WTFLogChannel;
161
14957cd0
A
162WTF_EXPORT_PRIVATE void WTFReportAssertionFailure(const char* file, int line, const char* function, const char* assertion) CLANG_ANALYZER_NORETURN;
163WTF_EXPORT_PRIVATE void WTFReportAssertionFailureWithMessage(const char* file, int line, const char* function, const char* assertion, const char* format, ...) CLANG_ANALYZER_NORETURN WTF_ATTRIBUTE_PRINTF(5, 6);
164WTF_EXPORT_PRIVATE void WTFReportArgumentAssertionFailure(const char* file, int line, const char* function, const char* argName, const char* assertion) CLANG_ANALYZER_NORETURN;
165WTF_EXPORT_PRIVATE void WTFReportBacktrace();
166WTF_EXPORT_PRIVATE void WTFReportFatalError(const char* file, int line, const char* function, const char* format, ...) CLANG_ANALYZER_NORETURN WTF_ATTRIBUTE_PRINTF(4, 5);
167WTF_EXPORT_PRIVATE void WTFReportError(const char* file, int line, const char* function, const char* format, ...) WTF_ATTRIBUTE_PRINTF(4, 5);
168WTF_EXPORT_PRIVATE void WTFLog(WTFLogChannel* channel, const char* format, ...) WTF_ATTRIBUTE_PRINTF(2, 3);
169WTF_EXPORT_PRIVATE void WTFLogVerbose(const char* file, int line, const char* function, WTFLogChannel* channel, const char* format, ...) WTF_ATTRIBUTE_PRINTF(5, 6);
b37bf2e1
A
170
171#ifdef __cplusplus
172}
173#endif
174
4e4e5a6f 175/* CRASH() - Raises a fatal error resulting in program termination and triggering either the debugger or the crash reporter.
b37bf2e1 176
4e4e5a6f
A
177 Use CRASH() in response to known, unrecoverable errors like out-of-memory.
178 Macro is enabled in both debug and release mode.
179 To test for unknown errors and verify assumptions, use ASSERT instead, to avoid impacting performance in release builds.
180
181 Signals are ignored by the crash reporter on OS X so we must do better.
182*/
b37bf2e1 183#ifndef CRASH
f9bf01c6
A
184#if OS(SYMBIAN)
185#define CRASH() do { \
186 __DEBUGGER(); \
187 User::Panic(_L("Webkit CRASH"),0); \
188 } while(false)
14957cd0
A
189#elif PLATFORM(BREWMP)
190#define CRASH() do { \
191 dbg_Message("WebKit CRASH", DBG_MSG_LEVEL_FATAL, __FILE__, __LINE__); \
192 *(int *)(uintptr_t)0xbbadbeef = 0; \
193 ((void(*)())0)(); /* More reliable, but doesn't say BBADBEEF */ \
194} while(false)
f9bf01c6 195#else
9dae56ea 196#define CRASH() do { \
14957cd0 197 WTFReportBacktrace(); \
9dae56ea
A
198 *(int *)(uintptr_t)0xbbadbeef = 0; \
199 ((void(*)())0)(); /* More reliable, but doesn't say BBADBEEF */ \
200} while(false)
b37bf2e1 201#endif
f9bf01c6 202#endif
b37bf2e1 203
14957cd0
A
204/* BACKTRACE
205
206 Print a backtrace to the same location as ASSERT messages.
207*/
208
209#if BACKTRACE_DISABLED
210
211#define BACKTRACE() ((void)0)
212
213#else
214
215#define BACKTRACE() do { \
216 WTFReportBacktrace(); \
217} while(false)
218
219#endif
220
4e4e5a6f
A
221/* ASSERT, ASSERT_NOT_REACHED, ASSERT_UNUSED
222
223 These macros are compiled out of release builds.
224 Expressions inside them are evaluated in debug builds only.
225*/
b37bf2e1 226
f9bf01c6 227#if OS(WINCE) && !PLATFORM(TORCHMOBILE)
9dae56ea
A
228/* FIXME: We include this here only to avoid a conflict with the ASSERT macro. */
229#include <windows.h>
230#undef min
231#undef max
232#undef ERROR
233#endif
234
f9bf01c6
A
235#if OS(WINDOWS) || OS(SYMBIAN)
236/* FIXME: Change to use something other than ASSERT to avoid this conflict with the underlying platform */
b37bf2e1
A
237#undef ASSERT
238#endif
239
4e4e5a6f
A
240#if PLATFORM(BREWMP)
241/* FIXME: We include this here only to avoid a conflict with the COMPILE_ASSERT macro. */
242#include <AEEClassIDs.h>
243
244/* FIXME: Change to use something other than COMPILE_ASSERT to avoid this conflict with the underlying platform */
245#undef COMPILE_ASSERT
246#endif
247
b37bf2e1
A
248#if ASSERT_DISABLED
249
250#define ASSERT(assertion) ((void)0)
b37bf2e1 251#define ASSERT_NOT_REACHED() ((void)0)
14957cd0
A
252
253#if COMPILER(INTEL) && !OS(WINDOWS) || COMPILER(RVCT)
254template<typename T>
255inline void assertUnused(T& x) { (void)x; }
256#define ASSERT_UNUSED(variable, assertion) (assertUnused(variable))
257#else
9dae56ea 258#define ASSERT_UNUSED(variable, assertion) ((void)variable)
14957cd0 259#endif
b37bf2e1
A
260
261#else
262
263#define ASSERT(assertion) do \
264 if (!(assertion)) { \
265 WTFReportAssertionFailure(__FILE__, __LINE__, WTF_PRETTY_FUNCTION, #assertion); \
266 CRASH(); \
267 } \
268while (0)
f9bf01c6
A
269
270#define ASSERT_NOT_REACHED() do { \
271 WTFReportAssertionFailure(__FILE__, __LINE__, WTF_PRETTY_FUNCTION, 0); \
272 CRASH(); \
273} while (0)
274
275#define ASSERT_UNUSED(variable, assertion) ASSERT(assertion)
276
277#endif
278
279/* ASSERT_WITH_MESSAGE */
280
4e4e5a6f 281#if COMPILER(MSVC7_OR_LOWER)
b37bf2e1 282#define ASSERT_WITH_MESSAGE(assertion) ((void)0)
f9bf01c6
A
283#elif COMPILER(WINSCW)
284#define ASSERT_WITH_MESSAGE(assertion, arg...) ((void)0)
285#elif ASSERT_MSG_DISABLED
286#define ASSERT_WITH_MESSAGE(assertion, ...) ((void)0)
b37bf2e1
A
287#else
288#define ASSERT_WITH_MESSAGE(assertion, ...) do \
289 if (!(assertion)) { \
290 WTFReportAssertionFailureWithMessage(__FILE__, __LINE__, WTF_PRETTY_FUNCTION, #assertion, __VA_ARGS__); \
291 CRASH(); \
292 } \
293while (0)
b37bf2e1 294#endif
14957cd0
A
295
296/* ASSERT_WITH_MESSAGE_UNUSED */
297
298#if COMPILER(MSVC7_OR_LOWER)
299#define ASSERT_WITH_MESSAGE_UNUSED(variable, assertion) ((void)0)
300#elif COMPILER(WINSCW)
301#define ASSERT_WITH_MESSAGE_UNUSED(variable, assertion, arg...) ((void)0)
302#elif ASSERT_MSG_DISABLED
303#if COMPILER(INTEL) && !OS(WINDOWS) || COMPILER(RVCT)
304template<typename T>
305inline void assertWithMessageUnused(T& x) { (void)x; }
306#define ASSERT_WITH_MESSAGE_UNUSED(variable, assertion, ...) (assertWithMessageUnused(variable))
307#else
308#define ASSERT_WITH_MESSAGE_UNUSED(variable, assertion, ...) ((void)variable)
309#endif
310#else
311#define ASSERT_WITH_MESSAGE_UNUSED(variable, assertion, ...) do \
312 if (!(assertion)) { \
313 WTFReportAssertionFailureWithMessage(__FILE__, __LINE__, WTF_PRETTY_FUNCTION, #assertion, __VA_ARGS__); \
314 CRASH(); \
315 } \
316while (0)
317#endif
f9bf01c6
A
318
319
b37bf2e1
A
320/* ASSERT_ARG */
321
322#if ASSERT_ARG_DISABLED
323
324#define ASSERT_ARG(argName, assertion) ((void)0)
325
326#else
327
328#define ASSERT_ARG(argName, assertion) do \
329 if (!(assertion)) { \
330 WTFReportArgumentAssertionFailure(__FILE__, __LINE__, WTF_PRETTY_FUNCTION, #argName, #assertion); \
331 CRASH(); \
332 } \
333while (0)
334
335#endif
336
337/* COMPILE_ASSERT */
338#ifndef COMPILE_ASSERT
ba379fdc 339#define COMPILE_ASSERT(exp, name) typedef int dummy##name [(exp) ? 1 : -1]
b37bf2e1
A
340#endif
341
342/* FATAL */
343
4e4e5a6f 344#if COMPILER(MSVC7_OR_LOWER)
b37bf2e1 345#define FATAL() ((void)0)
f9bf01c6
A
346#elif COMPILER(WINSCW)
347#define FATAL(arg...) ((void)0)
348#elif FATAL_DISABLED
349#define FATAL(...) ((void)0)
b37bf2e1
A
350#else
351#define FATAL(...) do { \
352 WTFReportFatalError(__FILE__, __LINE__, WTF_PRETTY_FUNCTION, __VA_ARGS__); \
353 CRASH(); \
354} while (0)
355#endif
356
357/* LOG_ERROR */
358
4e4e5a6f 359#if COMPILER(MSVC7_OR_LOWER)
b37bf2e1 360#define LOG_ERROR() ((void)0)
f9bf01c6
A
361#elif COMPILER(WINSCW)
362#define LOG_ERROR(arg...) ((void)0)
363#elif ERROR_DISABLED
364#define LOG_ERROR(...) ((void)0)
b37bf2e1
A
365#else
366#define LOG_ERROR(...) WTFReportError(__FILE__, __LINE__, WTF_PRETTY_FUNCTION, __VA_ARGS__)
367#endif
368
369/* LOG */
370
4e4e5a6f 371#if COMPILER(MSVC7_OR_LOWER)
b37bf2e1 372#define LOG() ((void)0)
f9bf01c6
A
373#elif COMPILER(WINSCW)
374#define LOG(arg...) ((void)0)
375#elif LOG_DISABLED
376#define LOG(channel, ...) ((void)0)
b37bf2e1
A
377#else
378#define LOG(channel, ...) WTFLog(&JOIN_LOG_CHANNEL_WITH_PREFIX(LOG_CHANNEL_PREFIX, channel), __VA_ARGS__)
379#define JOIN_LOG_CHANNEL_WITH_PREFIX(prefix, channel) JOIN_LOG_CHANNEL_WITH_PREFIX_LEVEL_2(prefix, channel)
380#define JOIN_LOG_CHANNEL_WITH_PREFIX_LEVEL_2(prefix, channel) prefix ## channel
381#endif
382
383/* LOG_VERBOSE */
384
4e4e5a6f 385#if COMPILER(MSVC7_OR_LOWER)
b37bf2e1 386#define LOG_VERBOSE(channel) ((void)0)
f9bf01c6
A
387#elif COMPILER(WINSCW)
388#define LOG_VERBOSE(channel, arg...) ((void)0)
389#elif LOG_DISABLED
390#define LOG_VERBOSE(channel, ...) ((void)0)
b37bf2e1
A
391#else
392#define LOG_VERBOSE(channel, ...) WTFLogVerbose(__FILE__, __LINE__, WTF_PRETTY_FUNCTION, &JOIN_LOG_CHANNEL_WITH_PREFIX(LOG_CHANNEL_PREFIX, channel), __VA_ARGS__)
393#endif
394
14957cd0
A
395#if ENABLE(GC_VALIDATION)
396#define ASSERT_GC_OBJECT_LOOKS_VALID(cell) do { \
397 if (!(cell))\
398 CRASH();\
399 if (cell->unvalidatedStructure()->unvalidatedStructure() != cell->unvalidatedStructure()->unvalidatedStructure()->unvalidatedStructure())\
400 CRASH();\
401} while (0)
402
403#define ASSERT_GC_OBJECT_INHERITS(object, classInfo) do {\
404 ASSERT_GC_OBJECT_LOOKS_VALID(object); \
405 if (!object->inherits(classInfo)) \
406 CRASH();\
407} while (0)
408
409#else
410#define ASSERT_GC_OBJECT_LOOKS_VALID(cell) do { (void)cell; } while (0)
411#define ASSERT_GC_OBJECT_INHERITS(object, classInfo) do { (void)object; (void)classInfo; } while (0)
412#endif
413
9dae56ea 414#endif /* WTF_Assertions_h */