X-Git-Url: https://git.saurik.com/apple/javascriptcore.git/blobdiff_plain/9dae56ea45a0f5f8136a5c93d6f3a7f99399ca73..14957cd040308e3eeec43d26bae5d76da13fcd85:/wtf/Assertions.h diff --git a/wtf/Assertions.h b/wtf/Assertions.h index c17e501..f6187bb 100644 --- a/wtf/Assertions.h +++ b/wtf/Assertions.h @@ -44,36 +44,79 @@ #include "Platform.h" -#if COMPILER(MSVC) +#include + #include -#else + +#if !COMPILER(MSVC) #include #endif +#if OS(SYMBIAN) +#include +#include +#endif + +#if PLATFORM(BREWMP) +#include +#include +#endif + #ifdef NDEBUG +/* Disable ASSERT* macros in release mode. */ #define ASSERTIONS_DISABLED_DEFAULT 1 #else #define ASSERTIONS_DISABLED_DEFAULT 0 #endif +#if COMPILER(MSVC7_OR_LOWER) || COMPILER(WINSCW) +#define HAVE_VARIADIC_MACRO 0 +#else +#define HAVE_VARIADIC_MACRO 1 +#endif + +#ifndef BACKTRACE_DISABLED +#define BACKTRACE_DISABLED ASSERTIONS_DISABLED_DEFAULT +#endif + #ifndef ASSERT_DISABLED #define ASSERT_DISABLED ASSERTIONS_DISABLED_DEFAULT #endif +#ifndef ASSERT_MSG_DISABLED +#if HAVE(VARIADIC_MACRO) +#define ASSERT_MSG_DISABLED ASSERTIONS_DISABLED_DEFAULT +#else +#define ASSERT_MSG_DISABLED 1 +#endif +#endif + #ifndef ASSERT_ARG_DISABLED #define ASSERT_ARG_DISABLED ASSERTIONS_DISABLED_DEFAULT #endif #ifndef FATAL_DISABLED +#if HAVE(VARIADIC_MACRO) #define FATAL_DISABLED ASSERTIONS_DISABLED_DEFAULT +#else +#define FATAL_DISABLED 1 +#endif #endif #ifndef ERROR_DISABLED +#if HAVE(VARIADIC_MACRO) #define ERROR_DISABLED ASSERTIONS_DISABLED_DEFAULT +#else +#define ERROR_DISABLED 1 +#endif #endif #ifndef LOG_DISABLED +#if HAVE(VARIADIC_MACRO) #define LOG_DISABLED ASSERTIONS_DISABLED_DEFAULT +#else +#define LOG_DISABLED 1 +#endif #endif #if COMPILER(GCC) @@ -91,6 +134,17 @@ #define WTF_ATTRIBUTE_PRINTF(formatStringArgument, extraArguments) #endif +/* This macro is needed to prevent the clang static analyzer from generating false-positive reports in ASSERT() macros. */ +#ifdef __clang__ +#define CLANG_ANALYZER_NORETURN __attribute__((analyzer_noreturn)) +#else +#define CLANG_ANALYZER_NORETURN +#endif +/* For project uses WTF but has no config.h, we need to explicitly set the export defines here. */ +#ifndef WTF_EXPORT_PRIVATE +#define WTF_EXPORT_PRIVATE +#endif + /* These helper functions are always declared, but not necessarily always defined if the corresponding function is disabled. */ #ifdef __cplusplus @@ -105,30 +159,72 @@ typedef struct { WTFLogChannelState state; } WTFLogChannel; -void WTFReportAssertionFailure(const char* file, int line, const char* function, const char* assertion); -void WTFReportAssertionFailureWithMessage(const char* file, int line, const char* function, const char* assertion, const char* format, ...) WTF_ATTRIBUTE_PRINTF(5, 6); -void WTFReportArgumentAssertionFailure(const char* file, int line, const char* function, const char* argName, const char* assertion); -void WTFReportFatalError(const char* file, int line, const char* function, const char* format, ...) WTF_ATTRIBUTE_PRINTF(4, 5); -void WTFReportError(const char* file, int line, const char* function, const char* format, ...) WTF_ATTRIBUTE_PRINTF(4, 5); -void WTFLog(WTFLogChannel* channel, const char* format, ...) WTF_ATTRIBUTE_PRINTF(2, 3); -void WTFLogVerbose(const char* file, int line, const char* function, WTFLogChannel* channel, const char* format, ...) WTF_ATTRIBUTE_PRINTF(5, 6); +WTF_EXPORT_PRIVATE void WTFReportAssertionFailure(const char* file, int line, const char* function, const char* assertion) CLANG_ANALYZER_NORETURN; +WTF_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); +WTF_EXPORT_PRIVATE void WTFReportArgumentAssertionFailure(const char* file, int line, const char* function, const char* argName, const char* assertion) CLANG_ANALYZER_NORETURN; +WTF_EXPORT_PRIVATE void WTFReportBacktrace(); +WTF_EXPORT_PRIVATE void WTFReportFatalError(const char* file, int line, const char* function, const char* format, ...) CLANG_ANALYZER_NORETURN WTF_ATTRIBUTE_PRINTF(4, 5); +WTF_EXPORT_PRIVATE void WTFReportError(const char* file, int line, const char* function, const char* format, ...) WTF_ATTRIBUTE_PRINTF(4, 5); +WTF_EXPORT_PRIVATE void WTFLog(WTFLogChannel* channel, const char* format, ...) WTF_ATTRIBUTE_PRINTF(2, 3); +WTF_EXPORT_PRIVATE void WTFLogVerbose(const char* file, int line, const char* function, WTFLogChannel* channel, const char* format, ...) WTF_ATTRIBUTE_PRINTF(5, 6); #ifdef __cplusplus } #endif -/* CRASH -- gets us into the debugger or the crash reporter -- signals are ignored by the crash reporter so we must do better */ +/* CRASH() - Raises a fatal error resulting in program termination and triggering either the debugger or the crash reporter. + + Use CRASH() in response to known, unrecoverable errors like out-of-memory. + Macro is enabled in both debug and release mode. + To test for unknown errors and verify assumptions, use ASSERT instead, to avoid impacting performance in release builds. + Signals are ignored by the crash reporter on OS X so we must do better. +*/ #ifndef CRASH +#if OS(SYMBIAN) +#define CRASH() do { \ + __DEBUGGER(); \ + User::Panic(_L("Webkit CRASH"),0); \ + } while(false) +#elif PLATFORM(BREWMP) +#define CRASH() do { \ + dbg_Message("WebKit CRASH", DBG_MSG_LEVEL_FATAL, __FILE__, __LINE__); \ + *(int *)(uintptr_t)0xbbadbeef = 0; \ + ((void(*)())0)(); /* More reliable, but doesn't say BBADBEEF */ \ +} while(false) +#else #define CRASH() do { \ + WTFReportBacktrace(); \ *(int *)(uintptr_t)0xbbadbeef = 0; \ ((void(*)())0)(); /* More reliable, but doesn't say BBADBEEF */ \ } while(false) +#endif +#endif + +/* BACKTRACE + + Print a backtrace to the same location as ASSERT messages. +*/ + +#if BACKTRACE_DISABLED + +#define BACKTRACE() ((void)0) + +#else + +#define BACKTRACE() do { \ + WTFReportBacktrace(); \ +} while(false) + #endif -/* ASSERT, ASSERT_WITH_MESSAGE, ASSERT_NOT_REACHED */ +/* ASSERT, ASSERT_NOT_REACHED, ASSERT_UNUSED -#if PLATFORM(WIN_CE) + These macros are compiled out of release builds. + Expressions inside them are evaluated in debug builds only. +*/ + +#if OS(WINCE) && !PLATFORM(TORCHMOBILE) /* FIXME: We include this here only to avoid a conflict with the ASSERT macro. */ #include #undef min @@ -136,17 +232,31 @@ void WTFLogVerbose(const char* file, int line, const char* function, WTFLogChann #undef ERROR #endif -#if PLATFORM(WIN_OS) -/* FIXME: Change to use something other than ASSERT to avoid this conflict with win32. */ +#if OS(WINDOWS) || OS(SYMBIAN) +/* FIXME: Change to use something other than ASSERT to avoid this conflict with the underlying platform */ #undef ASSERT #endif +#if PLATFORM(BREWMP) +/* FIXME: We include this here only to avoid a conflict with the COMPILE_ASSERT macro. */ +#include + +/* FIXME: Change to use something other than COMPILE_ASSERT to avoid this conflict with the underlying platform */ +#undef COMPILE_ASSERT +#endif + #if ASSERT_DISABLED #define ASSERT(assertion) ((void)0) -#define ASSERT_WITH_MESSAGE(assertion, ...) ((void)0) #define ASSERT_NOT_REACHED() ((void)0) + +#if COMPILER(INTEL) && !OS(WINDOWS) || COMPILER(RVCT) +template +inline void assertUnused(T& x) { (void)x; } +#define ASSERT_UNUSED(variable, assertion) (assertUnused(variable)) +#else #define ASSERT_UNUSED(variable, assertion) ((void)variable) +#endif #else @@ -156,8 +266,24 @@ void WTFLogVerbose(const char* file, int line, const char* function, WTFLogChann CRASH(); \ } \ while (0) -#if COMPILER(MSVC7) + +#define ASSERT_NOT_REACHED() do { \ + WTFReportAssertionFailure(__FILE__, __LINE__, WTF_PRETTY_FUNCTION, 0); \ + CRASH(); \ +} while (0) + +#define ASSERT_UNUSED(variable, assertion) ASSERT(assertion) + +#endif + +/* ASSERT_WITH_MESSAGE */ + +#if COMPILER(MSVC7_OR_LOWER) #define ASSERT_WITH_MESSAGE(assertion) ((void)0) +#elif COMPILER(WINSCW) +#define ASSERT_WITH_MESSAGE(assertion, arg...) ((void)0) +#elif ASSERT_MSG_DISABLED +#define ASSERT_WITH_MESSAGE(assertion, ...) ((void)0) #else #define ASSERT_WITH_MESSAGE(assertion, ...) do \ if (!(assertion)) { \ @@ -165,16 +291,32 @@ while (0) CRASH(); \ } \ while (0) -#endif /* COMPILER(MSVC7) */ -#define ASSERT_NOT_REACHED() do { \ - WTFReportAssertionFailure(__FILE__, __LINE__, WTF_PRETTY_FUNCTION, 0); \ - CRASH(); \ -} while (0) - -#define ASSERT_UNUSED(variable, assertion) ASSERT(assertion) - #endif +/* ASSERT_WITH_MESSAGE_UNUSED */ + +#if COMPILER(MSVC7_OR_LOWER) +#define ASSERT_WITH_MESSAGE_UNUSED(variable, assertion) ((void)0) +#elif COMPILER(WINSCW) +#define ASSERT_WITH_MESSAGE_UNUSED(variable, assertion, arg...) ((void)0) +#elif ASSERT_MSG_DISABLED +#if COMPILER(INTEL) && !OS(WINDOWS) || COMPILER(RVCT) +template +inline void assertWithMessageUnused(T& x) { (void)x; } +#define ASSERT_WITH_MESSAGE_UNUSED(variable, assertion, ...) (assertWithMessageUnused(variable)) +#else +#define ASSERT_WITH_MESSAGE_UNUSED(variable, assertion, ...) ((void)variable) +#endif +#else +#define ASSERT_WITH_MESSAGE_UNUSED(variable, assertion, ...) do \ + if (!(assertion)) { \ + WTFReportAssertionFailureWithMessage(__FILE__, __LINE__, WTF_PRETTY_FUNCTION, #assertion, __VA_ARGS__); \ + CRASH(); \ + } \ +while (0) +#endif + + /* ASSERT_ARG */ #if ASSERT_ARG_DISABLED @@ -194,15 +336,17 @@ while (0) /* COMPILE_ASSERT */ #ifndef COMPILE_ASSERT -#define COMPILE_ASSERT(exp, name) typedef int dummy##name [(exp) ? 1 : -1]; +#define COMPILE_ASSERT(exp, name) typedef int dummy##name [(exp) ? 1 : -1] #endif /* FATAL */ -#if FATAL_DISABLED -#define FATAL(...) ((void)0) -#elif COMPILER(MSVC7) +#if COMPILER(MSVC7_OR_LOWER) #define FATAL() ((void)0) +#elif COMPILER(WINSCW) +#define FATAL(arg...) ((void)0) +#elif FATAL_DISABLED +#define FATAL(...) ((void)0) #else #define FATAL(...) do { \ WTFReportFatalError(__FILE__, __LINE__, WTF_PRETTY_FUNCTION, __VA_ARGS__); \ @@ -212,20 +356,24 @@ while (0) /* LOG_ERROR */ -#if ERROR_DISABLED -#define LOG_ERROR(...) ((void)0) -#elif COMPILER(MSVC7) +#if COMPILER(MSVC7_OR_LOWER) #define LOG_ERROR() ((void)0) +#elif COMPILER(WINSCW) +#define LOG_ERROR(arg...) ((void)0) +#elif ERROR_DISABLED +#define LOG_ERROR(...) ((void)0) #else #define LOG_ERROR(...) WTFReportError(__FILE__, __LINE__, WTF_PRETTY_FUNCTION, __VA_ARGS__) #endif /* LOG */ -#if LOG_DISABLED -#define LOG(channel, ...) ((void)0) -#elif COMPILER(MSVC7) +#if COMPILER(MSVC7_OR_LOWER) #define LOG() ((void)0) +#elif COMPILER(WINSCW) +#define LOG(arg...) ((void)0) +#elif LOG_DISABLED +#define LOG(channel, ...) ((void)0) #else #define LOG(channel, ...) WTFLog(&JOIN_LOG_CHANNEL_WITH_PREFIX(LOG_CHANNEL_PREFIX, channel), __VA_ARGS__) #define JOIN_LOG_CHANNEL_WITH_PREFIX(prefix, channel) JOIN_LOG_CHANNEL_WITH_PREFIX_LEVEL_2(prefix, channel) @@ -234,12 +382,33 @@ while (0) /* LOG_VERBOSE */ -#if LOG_DISABLED -#define LOG_VERBOSE(channel, ...) ((void)0) -#elif COMPILER(MSVC7) +#if COMPILER(MSVC7_OR_LOWER) #define LOG_VERBOSE(channel) ((void)0) +#elif COMPILER(WINSCW) +#define LOG_VERBOSE(channel, arg...) ((void)0) +#elif LOG_DISABLED +#define LOG_VERBOSE(channel, ...) ((void)0) #else #define LOG_VERBOSE(channel, ...) WTFLogVerbose(__FILE__, __LINE__, WTF_PRETTY_FUNCTION, &JOIN_LOG_CHANNEL_WITH_PREFIX(LOG_CHANNEL_PREFIX, channel), __VA_ARGS__) #endif +#if ENABLE(GC_VALIDATION) +#define ASSERT_GC_OBJECT_LOOKS_VALID(cell) do { \ + if (!(cell))\ + CRASH();\ + if (cell->unvalidatedStructure()->unvalidatedStructure() != cell->unvalidatedStructure()->unvalidatedStructure()->unvalidatedStructure())\ + CRASH();\ +} while (0) + +#define ASSERT_GC_OBJECT_INHERITS(object, classInfo) do {\ + ASSERT_GC_OBJECT_LOOKS_VALID(object); \ + if (!object->inherits(classInfo)) \ + CRASH();\ +} while (0) + +#else +#define ASSERT_GC_OBJECT_LOOKS_VALID(cell) do { (void)cell; } while (0) +#define ASSERT_GC_OBJECT_INHERITS(object, classInfo) do { (void)object; (void)classInfo; } while (0) +#endif + #endif /* WTF_Assertions_h */