Home | History | Annotate | Download | only in src
      1 // Copyright 2006-2008 the V8 project authors. All rights reserved.
      2 // 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 
     35 extern "C" void V8_Fatal(const char* file, int line, const char* format, ...);
     36 void 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.
     40 #ifdef DEBUG
     41 #define FATAL(msg)                              \
     42   V8_Fatal(__FILE__, __LINE__, "%s", (msg))
     43 #define UNIMPLEMENTED()                         \
     44   V8_Fatal(__FILE__, __LINE__, "unimplemented code")
     45 #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
     54 
     55 
     56 // Used by the CHECK macro -- should not be called directly.
     57 static 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.
     73 static 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 // Helper function used by the CHECK_EQ function when given int64_t
     84 // arguments.  Should not be called directly.
     85 static inline void CheckEqualsHelper(const char* file, int line,
     86                                      const char* expected_source,
     87                                      int64_t expected,
     88                                      const char* value_source,
     89                                      int64_t value) {
     90   if (expected != value) {
     91     // Print int64_t values in hex, as two int32s,
     92     // to avoid platform-dependencies.
     93     V8_Fatal(file, line,
     94              "CHECK_EQ(%s, %s) failed\n#"
     95              "   Expected: 0x%08x%08x\n#   Found: 0x%08x%08x",
     96              expected_source, value_source,
     97              static_cast<uint32_t>(expected >> 32),
     98              static_cast<uint32_t>(expected),
     99              static_cast<uint32_t>(value >> 32),
    100              static_cast<uint32_t>(value));
    101   }
    102 }
    103 
    104 
    105 // Helper function used by the CHECK_NE function when given int
    106 // arguments.  Should not be called directly.
    107 static inline void CheckNonEqualsHelper(const char* file,
    108                                         int line,
    109                                         const char* unexpected_source,
    110                                         int unexpected,
    111                                         const char* value_source,
    112                                         int value) {
    113   if (unexpected == value) {
    114     V8_Fatal(file, line, "CHECK_NE(%s, %s) failed\n#   Value: %i",
    115              unexpected_source, value_source, value);
    116   }
    117 }
    118 
    119 
    120 // Helper function used by the CHECK function when given string
    121 // arguments.  Should not be called directly.
    122 static inline void CheckEqualsHelper(const char* file,
    123                                      int line,
    124                                      const char* expected_source,
    125                                      const char* expected,
    126                                      const char* value_source,
    127                                      const char* value) {
    128   if ((expected == NULL && value != NULL) ||
    129       (expected != NULL && value == NULL) ||
    130       (expected != NULL && value != NULL && strcmp(expected, value) != 0)) {
    131     V8_Fatal(file, line,
    132              "CHECK_EQ(%s, %s) failed\n#   Expected: %s\n#   Found: %s",
    133              expected_source, value_source, expected, value);
    134   }
    135 }
    136 
    137 
    138 static inline void CheckNonEqualsHelper(const char* file,
    139                                         int line,
    140                                         const char* expected_source,
    141                                         const char* expected,
    142                                         const char* value_source,
    143                                         const char* value) {
    144   if (expected == value ||
    145       (expected != NULL && value != NULL && strcmp(expected, value) == 0)) {
    146     V8_Fatal(file, line, "CHECK_NE(%s, %s) failed\n#   Value: %s",
    147              expected_source, value_source, value);
    148   }
    149 }
    150 
    151 
    152 // Helper function used by the CHECK function when given pointer
    153 // arguments.  Should not be called directly.
    154 static inline void CheckEqualsHelper(const char* file,
    155                                      int line,
    156                                      const char* expected_source,
    157                                      void* expected,
    158                                      const char* value_source,
    159                                      void* value) {
    160   if (expected != value) {
    161     V8_Fatal(file, line,
    162              "CHECK_EQ(%s, %s) failed\n#   Expected: %p\n#   Found: %p",
    163              expected_source, value_source,
    164              expected, value);
    165   }
    166 }
    167 
    168 
    169 static inline void CheckNonEqualsHelper(const char* file,
    170                                         int line,
    171                                         const char* expected_source,
    172                                         void* expected,
    173                                         const char* value_source,
    174                                         void* value) {
    175   if (expected == value) {
    176     V8_Fatal(file, line, "CHECK_NE(%s, %s) failed\n#   Value: %p",
    177              expected_source, value_source, value);
    178   }
    179 }
    180 
    181 
    182 // Helper function used by the CHECK function when given floating
    183 // point arguments.  Should not be called directly.
    184 static inline void CheckEqualsHelper(const char* file,
    185                                      int line,
    186                                      const char* expected_source,
    187                                      double expected,
    188                                      const char* value_source,
    189                                      double value) {
    190   // Force values to 64 bit memory to truncate 80 bit precision on IA32.
    191   volatile double* exp = new double[1];
    192   *exp = expected;
    193   volatile double* val = new double[1];
    194   *val = value;
    195   if (*exp != *val) {
    196     V8_Fatal(file, line,
    197              "CHECK_EQ(%s, %s) failed\n#   Expected: %f\n#   Found: %f",
    198              expected_source, value_source, *exp, *val);
    199   }
    200   delete[] exp;
    201   delete[] val;
    202 }
    203 
    204 
    205 namespace v8 {
    206   class Value;
    207   template <class T> class Handle;
    208 }
    209 
    210 
    211 void CheckNonEqualsHelper(const char* file,
    212                           int line,
    213                           const char* unexpected_source,
    214                           v8::Handle<v8::Value> unexpected,
    215                           const char* value_source,
    216                           v8::Handle<v8::Value> value);
    217 
    218 
    219 void CheckEqualsHelper(const char* file,
    220                        int line,
    221                        const char* expected_source,
    222                        v8::Handle<v8::Value> expected,
    223                        const char* value_source,
    224                        v8::Handle<v8::Value> value);
    225 
    226 
    227 #define CHECK_EQ(expected, value) CheckEqualsHelper(__FILE__, __LINE__, \
    228   #expected, expected, #value, value)
    229 
    230 
    231 #define CHECK_NE(unexpected, value) CheckNonEqualsHelper(__FILE__, __LINE__, \
    232   #unexpected, unexpected, #value, value)
    233 
    234 
    235 #define CHECK_GT(a, b) CHECK((a) > (b))
    236 #define CHECK_GE(a, b) CHECK((a) >= (b))
    237 
    238 
    239 // This is inspired by the static assertion facility in boost.  This
    240 // is pretty magical.  If it causes you trouble on a platform you may
    241 // find a fix in the boost code.
    242 template <bool> class StaticAssertion;
    243 template <> class StaticAssertion<true> { };
    244 // This macro joins two tokens.  If one of the tokens is a macro the
    245 // helper call causes it to be resolved before joining.
    246 #define SEMI_STATIC_JOIN(a, b) SEMI_STATIC_JOIN_HELPER(a, b)
    247 #define SEMI_STATIC_JOIN_HELPER(a, b) a##b
    248 // Causes an error during compilation of the condition is not
    249 // statically known to be true.  It is formulated as a typedef so that
    250 // it can be used wherever a typedef can be used.  Beware that this
    251 // actually causes each use to introduce a new defined type with a
    252 // name depending on the source line.
    253 template <int> class StaticAssertionHelper { };
    254 #define STATIC_CHECK(test)                                                  \
    255   typedef                                                                   \
    256     StaticAssertionHelper<sizeof(StaticAssertion<static_cast<bool>(test)>)> \
    257     SEMI_STATIC_JOIN(__StaticAssertTypedef__, __LINE__)
    258 
    259 
    260 // The ASSERT macro is equivalent to CHECK except that it only
    261 // generates code in debug builds.  Ditto STATIC_ASSERT.
    262 #ifdef DEBUG
    263 #define ASSERT_RESULT(expr)  CHECK(expr)
    264 #define ASSERT(condition)    CHECK(condition)
    265 #define ASSERT_EQ(v1, v2)    CHECK_EQ(v1, v2)
    266 #define ASSERT_NE(v1, v2)   CHECK_NE(v1, v2)
    267 #define STATIC_ASSERT(test)  STATIC_CHECK(test)
    268 #define SLOW_ASSERT(condition) if (FLAG_enable_slow_asserts) CHECK(condition)
    269 #else
    270 #define ASSERT_RESULT(expr)     (expr)
    271 #define ASSERT(condition)      ((void) 0)
    272 #define ASSERT_EQ(v1, v2)      ((void) 0)
    273 #define ASSERT_NE(v1, v2)     ((void) 0)
    274 #define STATIC_ASSERT(test)    ((void) 0)
    275 #define SLOW_ASSERT(condition) ((void) 0)
    276 #endif
    277 
    278 
    279 #define ASSERT_TAG_ALIGNED(address) \
    280   ASSERT((reinterpret_cast<intptr_t>(address) & kHeapObjectTagMask) == 0)
    281 
    282 #define ASSERT_SIZE_TAG_ALIGNED(size) ASSERT((size & kHeapObjectTagMask) == 0)
    283 
    284 #define ASSERT_NOT_NULL(p)  ASSERT_NE(NULL, p)
    285 
    286 #endif  // V8_CHECKS_H_
    287