checks.h 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314
  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. #ifndef V8_CHECKS_H_
  28. #define V8_CHECKS_H_
  29. #include <string.h>
  30. #include "flags.h"
  31. extern "C" void V8_Fatal(const char* file, int line, const char* format, ...);
  32. void API_Fatal(const char* location, const char* format, ...);
  33. // The FATAL, UNREACHABLE and UNIMPLEMENTED macros are useful during
  34. // development, but they should not be relied on in the final product.
  35. #ifdef DEBUG
  36. #define FATAL(msg) \
  37. V8_Fatal(__FILE__, __LINE__, "%s", (msg))
  38. #define UNIMPLEMENTED() \
  39. V8_Fatal(__FILE__, __LINE__, "unimplemented code")
  40. #define UNREACHABLE() \
  41. V8_Fatal(__FILE__, __LINE__, "unreachable code")
  42. #else
  43. #define FATAL(msg) \
  44. V8_Fatal("", 0, "%s", (msg))
  45. #define UNIMPLEMENTED() \
  46. V8_Fatal("", 0, "unimplemented code")
  47. #define UNREACHABLE() ((void) 0)
  48. #endif
  49. // Used by the CHECK macro -- should not be called directly.
  50. static inline void CheckHelper(const char* file,
  51. int line,
  52. const char* source,
  53. bool condition) {
  54. if (!condition)
  55. V8_Fatal(file, line, "CHECK(%s) failed", source);
  56. }
  57. // The CHECK macro checks that the given condition is true; if not, it
  58. // prints a message to stderr and aborts.
  59. #define CHECK(condition) CheckHelper(__FILE__, __LINE__, #condition, condition)
  60. // Helper function used by the CHECK_EQ function when given int
  61. // arguments. Should not be called directly.
  62. static inline void CheckEqualsHelper(const char* file, int line,
  63. const char* expected_source, int expected,
  64. const char* value_source, int value) {
  65. if (expected != value) {
  66. V8_Fatal(file, line,
  67. "CHECK_EQ(%s, %s) failed\n# Expected: %i\n# Found: %i",
  68. expected_source, value_source, expected, value);
  69. }
  70. }
  71. // Helper function used by the CHECK_EQ function when given int64_t
  72. // arguments. Should not be called directly.
  73. static inline void CheckEqualsHelper(const char* file, int line,
  74. const char* expected_source,
  75. int64_t expected,
  76. const char* value_source,
  77. int64_t value) {
  78. if (expected != value) {
  79. // Print int64_t values in hex, as two int32s,
  80. // to avoid platform-dependencies.
  81. V8_Fatal(file, line,
  82. "CHECK_EQ(%s, %s) failed\n#"
  83. " Expected: 0x%08x%08x\n# Found: 0x%08x%08x",
  84. expected_source, value_source,
  85. static_cast<uint32_t>(expected >> 32),
  86. static_cast<uint32_t>(expected),
  87. static_cast<uint32_t>(value >> 32),
  88. static_cast<uint32_t>(value));
  89. }
  90. }
  91. // Helper function used by the CHECK_NE function when given int
  92. // arguments. Should not be called directly.
  93. static inline void CheckNonEqualsHelper(const char* file,
  94. int line,
  95. const char* unexpected_source,
  96. int unexpected,
  97. const char* value_source,
  98. int value) {
  99. if (unexpected == value) {
  100. V8_Fatal(file, line, "CHECK_NE(%s, %s) failed\n# Value: %i",
  101. unexpected_source, value_source, value);
  102. }
  103. }
  104. // Helper function used by the CHECK function when given string
  105. // arguments. Should not be called directly.
  106. static inline void CheckEqualsHelper(const char* file,
  107. int line,
  108. const char* expected_source,
  109. const char* expected,
  110. const char* value_source,
  111. const char* value) {
  112. if ((expected == NULL && value != NULL) ||
  113. (expected != NULL && value == NULL) ||
  114. (expected != NULL && value != NULL && strcmp(expected, value) != 0)) {
  115. V8_Fatal(file, line,
  116. "CHECK_EQ(%s, %s) failed\n# Expected: %s\n# Found: %s",
  117. expected_source, value_source, expected, value);
  118. }
  119. }
  120. static inline void CheckNonEqualsHelper(const char* file,
  121. int line,
  122. const char* expected_source,
  123. const char* expected,
  124. const char* value_source,
  125. const char* value) {
  126. if (expected == value ||
  127. (expected != NULL && value != NULL && strcmp(expected, value) == 0)) {
  128. V8_Fatal(file, line, "CHECK_NE(%s, %s) failed\n# Value: %s",
  129. expected_source, value_source, value);
  130. }
  131. }
  132. // Helper function used by the CHECK function when given pointer
  133. // arguments. Should not be called directly.
  134. static inline void CheckEqualsHelper(const char* file,
  135. int line,
  136. const char* expected_source,
  137. const void* expected,
  138. const char* value_source,
  139. const void* value) {
  140. if (expected != value) {
  141. V8_Fatal(file, line,
  142. "CHECK_EQ(%s, %s) failed\n# Expected: %p\n# Found: %p",
  143. expected_source, value_source,
  144. expected, value);
  145. }
  146. }
  147. static inline void CheckNonEqualsHelper(const char* file,
  148. int line,
  149. const char* expected_source,
  150. const void* expected,
  151. const char* value_source,
  152. const void* value) {
  153. if (expected == value) {
  154. V8_Fatal(file, line, "CHECK_NE(%s, %s) failed\n# Value: %p",
  155. expected_source, value_source, value);
  156. }
  157. }
  158. // Helper function used by the CHECK function when given floating
  159. // point arguments. Should not be called directly.
  160. static inline void CheckEqualsHelper(const char* file,
  161. int line,
  162. const char* expected_source,
  163. double expected,
  164. const char* value_source,
  165. double value) {
  166. // Force values to 64 bit memory to truncate 80 bit precision on IA32.
  167. volatile double* exp = new double[1];
  168. *exp = expected;
  169. volatile double* val = new double[1];
  170. *val = value;
  171. if (*exp != *val) {
  172. V8_Fatal(file, line,
  173. "CHECK_EQ(%s, %s) failed\n# Expected: %f\n# Found: %f",
  174. expected_source, value_source, *exp, *val);
  175. }
  176. delete[] exp;
  177. delete[] val;
  178. }
  179. static inline void CheckNonEqualsHelper(const char* file,
  180. int line,
  181. const char* expected_source,
  182. double expected,
  183. const char* value_source,
  184. double value) {
  185. // Force values to 64 bit memory to truncate 80 bit precision on IA32.
  186. volatile double* exp = new double[1];
  187. *exp = expected;
  188. volatile double* val = new double[1];
  189. *val = value;
  190. if (*exp == *val) {
  191. V8_Fatal(file, line,
  192. "CHECK_NE(%s, %s) failed\n# Value: %f",
  193. expected_source, value_source, *val);
  194. }
  195. delete[] exp;
  196. delete[] val;
  197. }
  198. namespace v8 {
  199. class Value;
  200. template <class T> class Handle;
  201. }
  202. void CheckNonEqualsHelper(const char* file,
  203. int line,
  204. const char* unexpected_source,
  205. v8::Handle<v8::Value> unexpected,
  206. const char* value_source,
  207. v8::Handle<v8::Value> value);
  208. void CheckEqualsHelper(const char* file,
  209. int line,
  210. const char* expected_source,
  211. v8::Handle<v8::Value> expected,
  212. const char* value_source,
  213. v8::Handle<v8::Value> value);
  214. #define CHECK_EQ(expected, value) CheckEqualsHelper(__FILE__, __LINE__, \
  215. #expected, expected, #value, value)
  216. #define CHECK_NE(unexpected, value) CheckNonEqualsHelper(__FILE__, __LINE__, \
  217. #unexpected, unexpected, #value, value)
  218. #define CHECK_GT(a, b) CHECK((a) > (b))
  219. #define CHECK_GE(a, b) CHECK((a) >= (b))
  220. // This is inspired by the static assertion facility in boost. This
  221. // is pretty magical. If it causes you trouble on a platform you may
  222. // find a fix in the boost code.
  223. template <bool> class StaticAssertion;
  224. template <> class StaticAssertion<true> { };
  225. // This macro joins two tokens. If one of the tokens is a macro the
  226. // helper call causes it to be resolved before joining.
  227. #define SEMI_STATIC_JOIN(a, b) SEMI_STATIC_JOIN_HELPER(a, b)
  228. #define SEMI_STATIC_JOIN_HELPER(a, b) a##b
  229. // Causes an error during compilation of the condition is not
  230. // statically known to be true. It is formulated as a typedef so that
  231. // it can be used wherever a typedef can be used. Beware that this
  232. // actually causes each use to introduce a new defined type with a
  233. // name depending on the source line.
  234. template <int> class StaticAssertionHelper { };
  235. #define STATIC_CHECK(test) \
  236. typedef \
  237. StaticAssertionHelper<sizeof(StaticAssertion<static_cast<bool>(test)>)> \
  238. SEMI_STATIC_JOIN(__StaticAssertTypedef__, __LINE__)
  239. // The ASSERT macro is equivalent to CHECK except that it only
  240. // generates code in debug builds.
  241. #ifdef DEBUG
  242. #define ASSERT_RESULT(expr) CHECK(expr)
  243. #define ASSERT(condition) CHECK(condition)
  244. #define ASSERT_EQ(v1, v2) CHECK_EQ(v1, v2)
  245. #define ASSERT_NE(v1, v2) CHECK_NE(v1, v2)
  246. #define ASSERT_GE(v1, v2) CHECK_GE(v1, v2)
  247. #define SLOW_ASSERT(condition) if (FLAG_enable_slow_asserts) CHECK(condition)
  248. #else
  249. #define ASSERT_RESULT(expr) (expr)
  250. #define ASSERT(condition) ((void) 0)
  251. #define ASSERT_EQ(v1, v2) ((void) 0)
  252. #define ASSERT_NE(v1, v2) ((void) 0)
  253. #define ASSERT_GE(v1, v2) ((void) 0)
  254. #define SLOW_ASSERT(condition) ((void) 0)
  255. #endif
  256. // Static asserts has no impact on runtime performance, so they can be
  257. // safely enabled in release mode. Moreover, the ((void) 0) expression
  258. // obeys different syntax rules than typedef's, e.g. it can't appear
  259. // inside class declaration, this leads to inconsistency between debug
  260. // and release compilation modes behaviour.
  261. #define STATIC_ASSERT(test) STATIC_CHECK(test)
  262. #define ASSERT_TAG_ALIGNED(address) \
  263. ASSERT((reinterpret_cast<intptr_t>(address) & kHeapObjectTagMask) == 0)
  264. #define ASSERT_SIZE_TAG_ALIGNED(size) ASSERT((size & kHeapObjectTagMask) == 0)
  265. #define ASSERT_NOT_NULL(p) ASSERT_NE(NULL, p)
  266. #endif // V8_CHECKS_H_