Bug 712129 - Add more assertion macro flavors to mfbt, and make the JS engine use mfbt's implementations where appropriate. r=cjones
--- a/js/public/Utility.h
+++ b/js/public/Utility.h
@@ -35,16 +35,18 @@
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#ifndef js_utility_h__
#define js_utility_h__
+#include "mozilla/Assertions.h"
+
#include <stdlib.h>
#include <string.h>
#include "jstypes.h"
#ifdef __cplusplus
/* The public JS engine namespace. */
@@ -66,37 +68,29 @@ using namespace mozilla;
JS_BEGIN_EXTERN_C
/*
* Pattern used to overwrite freed memory. If you are accessing an object with
* this pattern, you probably have a dangling pointer.
*/
#define JS_FREE_PATTERN 0xDA
-/* JS_ASSERT */
+#define JS_ASSERT(expr) MOZ_ASSERT(expr)
+#define JS_ASSERT_IF(cond, expr) MOZ_ASSERT_IF((cond), (expr))
+#define JS_NOT_REACHED(reason) MOZ_NOT_REACHED(reason)
+#define JS_ALWAYS_TRUE(expr) MOZ_ALWAYS_TRUE(expr)
+#define JS_ALWAYS_FALSE(expr) MOZ_ALWAYS_FALSE(expr)
+
#ifdef DEBUG
-# define JS_ASSERT(expr) \
- ((expr) ? (void)0 : JS_Assert(#expr, __FILE__, __LINE__))
-# define JS_ASSERT_IF(cond, expr) \
- ((!(cond) || (expr)) ? (void)0 : JS_Assert(#expr, __FILE__, __LINE__))
-# define JS_NOT_REACHED(reason) \
- JS_Assert(reason, __FILE__, __LINE__)
-# define JS_ALWAYS_TRUE(expr) JS_ASSERT(expr)
-# define JS_ALWAYS_FALSE(expr) JS_ASSERT(!(expr))
# ifdef JS_THREADSAFE
# define JS_THREADSAFE_ASSERT(expr) JS_ASSERT(expr)
# else
# define JS_THREADSAFE_ASSERT(expr) ((void) 0)
# endif
#else
-# define JS_ASSERT(expr) ((void) 0)
-# define JS_ASSERT_IF(cond,expr) ((void) 0)
-# define JS_NOT_REACHED(reason)
-# define JS_ALWAYS_TRUE(expr) ((void) (expr))
-# define JS_ALWAYS_FALSE(expr) ((void) (expr))
# define JS_THREADSAFE_ASSERT(expr) ((void) 0)
#endif
/*
* JS_STATIC_ASSERT
*
* A compile-time assert. "cond" must be a constant expression. The macro can
* be used only in places where an "extern" declaration is allowed.
--- a/mfbt/Assertions.h
+++ b/mfbt/Assertions.h
@@ -65,19 +65,77 @@ extern MFBT_API(void)
JS_Assert(const char* s, const char* file, int ln);
#ifdef __cplusplus
} /* extern "C" */
#endif
/*
* MOZ_ASSERT() is a "strong" assertion of state, like libc's
- * assert(). If a MOZ_ASSERT() fails in a debug build, the process in
- * which it fails will stop running in a loud and dramatic way.
+ * assert().
+ *
+ * MOZ_ASSERT(twoToThePowerOf(5) == 32);
+ *
+ * If a MOZ_ASSERT() fails in a debug build, the process in which it fails will
+ * stop running in a loud and dramatic way. It has no effect in an optimized
+ * build. This macro is designed to catch bugs during debugging, not "in the
+ * field".
*/
#ifdef DEBUG
# define MOZ_ASSERT(expr_) \
((expr_) ? ((void)0) : JS_Assert(#expr_, __FILE__, __LINE__))
#else
# define MOZ_ASSERT(expr_) ((void)0)
#endif /* DEBUG */
+/*
+ * MOZ_ASSERT_IF(cond1, cond2) is equivalent to MOZ_ASSERT(cond2) if cond1 is
+ * true.
+ *
+ * MOZ_ASSERT_IF(isPrime(num), num == 2 || isOdd(num));
+ *
+ * As with MOZ_ASSERT, MOZ_ASSERT_IF has effect only in debug builds. It is
+ * designed to catch bugs during debugging, not "in the field".
+ */
+#ifdef DEBUG
+# define MOZ_ASSERT_IF(cond, expr) ((cond) ? MOZ_ASSERT(expr) : ((void)0))
+#else
+# define MOZ_ASSERT_IF(cond, expr) ((void)0)
+#endif
+
+/*
+ * MOZ_NOT_REACHED(reason) indicates that the given point can't be reached
+ * during execution: simply reaching that point in execution is a bug. It takes
+ * as an argument an error message indicating the reason why that point should
+ * not have been reachable.
+ *
+ * // ...in a language parser...
+ * void handle(BooleanLiteralNode node)
+ * {
+ * if (node.isTrue())
+ * handleTrueLiteral();
+ * else if (node.isFalse())
+ * handleFalseLiteral();
+ * else
+ * MOZ_NOT_REACHED("boolean literal that's not true or false?");
+ * }
+ */
+#ifdef DEBUG
+# define MOZ_NOT_REACHED(reason) JS_Assert(reason, __FILE__, __LINE__)
+#else
+# define MOZ_NOT_REACHED(reason) ((void)0)
+#endif
+
+/*
+ * MOZ_ALWAYS_TRUE(expr) and MOZ_ALWAYS_FALSE(expr) always evaluate the provided
+ * expression, in debug builds and in release builds both. Then, in debug
+ * builds only, the value of the expression is asserted either true or false
+ * using MOZ_ASSERT.
+ */
+#ifdef DEBUG
+# define MOZ_ALWAYS_TRUE(expr) MOZ_ASSERT((expr))
+# define MOZ_ALWAYS_FALSE(expr) MOZ_ASSERT(!(expr))
+#else
+# define MOZ_ALWAYS_TRUE(expr) ((void)(expr))
+# define MOZ_ALWAYS_FALSE(expr) ((void)(expr))
+#endif
+
#endif /* mozilla_Assertions_h_ */