Bug 712129 - Add more assertion macro flavors to mfbt, and make the JS engine use mfbt's implementations where appropriate. r=cjones
authorJeff Walden <jwalden@mit.edu>
Mon, 19 Dec 2011 15:54:12 -0500
changeset 83238 0d7567cf0a67a44906ab85ba9f2acc6ead70ba63
parent 83237 cffea4a903accb901b02517270378f6d76403382
child 83239 8d4a9617fcd105c8e06d80abfd4b0c3de47ff486
push id4319
push userjwalden@mit.edu
push dateThu, 22 Dec 2011 02:57:27 +0000
treeherdermozilla-inbound@8d4a9617fcd1 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerscjones
bugs712129
milestone12.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 712129 - Add more assertion macro flavors to mfbt, and make the JS engine use mfbt's implementations where appropriate. r=cjones
js/public/Utility.h
mfbt/Assertions.h
--- 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_ */