1a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Copyright 2006-2008 the V8 project authors. All rights reserved.
2a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Redistribution and use in source and binary forms, with or without
3a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// modification, are permitted provided that the following conditions are
4a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// met:
5a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//
6a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//     * Redistributions of source code must retain the above copyright
7a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//       notice, this list of conditions and the following disclaimer.
8a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//     * Redistributions in binary form must reproduce the above
9a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//       copyright notice, this list of conditions and the following
10a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//       disclaimer in the documentation and/or other materials provided
11a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//       with the distribution.
12a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//     * Neither the name of Google Inc. nor the names of its
13a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//       contributors may be used to endorse or promote products derived
14a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//       from this software without specific prior written permission.
15a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//
16a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
28a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#ifndef V8_CHECKS_H_
29a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#define V8_CHECKS_H_
30a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
31a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#include <string.h>
32a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
33b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch#include "../include/v8stdint.h"
34a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockextern "C" void V8_Fatal(const char* file, int line, const char* format, ...);
35a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
36a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// The FATAL, UNREACHABLE and UNIMPLEMENTED macros are useful during
37a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// development, but they should not be relied on in the final product.
38a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#ifdef DEBUG
39a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#define FATAL(msg)                              \
40a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  V8_Fatal(__FILE__, __LINE__, "%s", (msg))
41a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#define UNIMPLEMENTED()                         \
42a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  V8_Fatal(__FILE__, __LINE__, "unimplemented code")
43a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#define UNREACHABLE()                           \
44a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  V8_Fatal(__FILE__, __LINE__, "unreachable code")
45a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#else
46a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#define FATAL(msg)                              \
47a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  V8_Fatal("", 0, "%s", (msg))
48a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#define UNIMPLEMENTED()                         \
49a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  V8_Fatal("", 0, "unimplemented code")
50a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#define UNREACHABLE() ((void) 0)
51a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#endif
52a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
53a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
54a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Used by the CHECK macro -- should not be called directly.
55a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic inline void CheckHelper(const char* file,
56a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                               int line,
57a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                               const char* source,
58a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                               bool condition) {
59a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (!condition)
60a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    V8_Fatal(file, line, "CHECK(%s) failed", source);
61a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
62a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
63a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
64a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// The CHECK macro checks that the given condition is true; if not, it
65a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// prints a message to stderr and aborts.
66a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#define CHECK(condition) CheckHelper(__FILE__, __LINE__, #condition, condition)
67a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
68a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
69a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Helper function used by the CHECK_EQ function when given int
70a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// arguments.  Should not be called directly.
71a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic inline void CheckEqualsHelper(const char* file, int line,
72a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                                     const char* expected_source, int expected,
73a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                                     const char* value_source, int value) {
74a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (expected != value) {
75a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    V8_Fatal(file, line,
76a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block             "CHECK_EQ(%s, %s) failed\n#   Expected: %i\n#   Found: %i",
77a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block             expected_source, value_source, expected, value);
78a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
79a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
80a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
816ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
823ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block// Helper function used by the CHECK_EQ function when given int64_t
833ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block// arguments.  Should not be called directly.
843ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Blockstatic inline void CheckEqualsHelper(const char* file, int line,
853ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block                                     const char* expected_source,
863ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block                                     int64_t expected,
873ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block                                     const char* value_source,
883ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block                                     int64_t value) {
893ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  if (expected != value) {
903ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block    // Print int64_t values in hex, as two int32s,
913ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block    // to avoid platform-dependencies.
923ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block    V8_Fatal(file, line,
933ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block             "CHECK_EQ(%s, %s) failed\n#"
943ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block             "   Expected: 0x%08x%08x\n#   Found: 0x%08x%08x",
953ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block             expected_source, value_source,
963ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block             static_cast<uint32_t>(expected >> 32),
973ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block             static_cast<uint32_t>(expected),
983ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block             static_cast<uint32_t>(value >> 32),
993ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block             static_cast<uint32_t>(value));
1003ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  }
1013ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block}
1023ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block
103a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
104a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Helper function used by the CHECK_NE function when given int
105a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// arguments.  Should not be called directly.
106a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic inline void CheckNonEqualsHelper(const char* file,
107a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                                        int line,
108a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                                        const char* unexpected_source,
109a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                                        int unexpected,
110a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                                        const char* value_source,
111a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                                        int value) {
112a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (unexpected == value) {
113a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    V8_Fatal(file, line, "CHECK_NE(%s, %s) failed\n#   Value: %i",
114a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block             unexpected_source, value_source, value);
115a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
116a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
117a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
118a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
119a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Helper function used by the CHECK function when given string
120a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// arguments.  Should not be called directly.
121a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic inline void CheckEqualsHelper(const char* file,
122a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                                     int line,
123a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                                     const char* expected_source,
124a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                                     const char* expected,
125a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                                     const char* value_source,
126a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                                     const char* value) {
127402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu  if ((expected == NULL && value != NULL) ||
128402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu      (expected != NULL && value == NULL) ||
129402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu      (expected != NULL && value != NULL && strcmp(expected, value) != 0)) {
130a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    V8_Fatal(file, line,
131a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block             "CHECK_EQ(%s, %s) failed\n#   Expected: %s\n#   Found: %s",
132a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block             expected_source, value_source, expected, value);
133a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
134a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
135a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
136a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
137a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic inline void CheckNonEqualsHelper(const char* file,
138a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                                        int line,
139a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                                        const char* expected_source,
140a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                                        const char* expected,
141a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                                        const char* value_source,
142a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                                        const char* value) {
143a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (expected == value ||
144a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      (expected != NULL && value != NULL && strcmp(expected, value) == 0)) {
145a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    V8_Fatal(file, line, "CHECK_NE(%s, %s) failed\n#   Value: %s",
146a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block             expected_source, value_source, value);
147a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
148a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
149a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
150a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
151a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Helper function used by the CHECK function when given pointer
152a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// arguments.  Should not be called directly.
153a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic inline void CheckEqualsHelper(const char* file,
154a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                                     int line,
155a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                                     const char* expected_source,
1569dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen                                     const void* expected,
157a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                                     const char* value_source,
1589dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen                                     const void* value) {
159a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (expected != value) {
160a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    V8_Fatal(file, line,
161a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block             "CHECK_EQ(%s, %s) failed\n#   Expected: %p\n#   Found: %p",
162a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block             expected_source, value_source,
163a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block             expected, value);
164a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
165a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
166a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
167a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
168a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic inline void CheckNonEqualsHelper(const char* file,
169a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                                        int line,
170a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                                        const char* expected_source,
1719dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen                                        const void* expected,
172a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                                        const char* value_source,
1739dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen                                        const void* value) {
174a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (expected == value) {
175a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    V8_Fatal(file, line, "CHECK_NE(%s, %s) failed\n#   Value: %p",
176a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block             expected_source, value_source, value);
177a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
178a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
179a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
180a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
181a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Helper function used by the CHECK function when given floating
182a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// point arguments.  Should not be called directly.
183a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic inline void CheckEqualsHelper(const char* file,
184a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                                     int line,
185a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                                     const char* expected_source,
186a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                                     double expected,
187a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                                     const char* value_source,
188a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                                     double value) {
189a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Force values to 64 bit memory to truncate 80 bit precision on IA32.
190a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  volatile double* exp = new double[1];
191a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  *exp = expected;
192a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  volatile double* val = new double[1];
193a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  *val = value;
194a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (*exp != *val) {
195a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    V8_Fatal(file, line,
196a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block             "CHECK_EQ(%s, %s) failed\n#   Expected: %f\n#   Found: %f",
197a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block             expected_source, value_source, *exp, *val);
198a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
199a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  delete[] exp;
200a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  delete[] val;
201a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
202a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
203a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2046ded16be15dd865a9b21ea304d5273c8be299c87Steve Blockstatic inline void CheckNonEqualsHelper(const char* file,
2056ded16be15dd865a9b21ea304d5273c8be299c87Steve Block                                     int line,
2066ded16be15dd865a9b21ea304d5273c8be299c87Steve Block                                     const char* expected_source,
2076ded16be15dd865a9b21ea304d5273c8be299c87Steve Block                                     double expected,
2086ded16be15dd865a9b21ea304d5273c8be299c87Steve Block                                     const char* value_source,
2096ded16be15dd865a9b21ea304d5273c8be299c87Steve Block                                     double value) {
2106ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  // Force values to 64 bit memory to truncate 80 bit precision on IA32.
2116ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  volatile double* exp = new double[1];
2126ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  *exp = expected;
2136ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  volatile double* val = new double[1];
2146ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  *val = value;
2156ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  if (*exp == *val) {
2166ded16be15dd865a9b21ea304d5273c8be299c87Steve Block    V8_Fatal(file, line,
2176ded16be15dd865a9b21ea304d5273c8be299c87Steve Block             "CHECK_NE(%s, %s) failed\n#   Value: %f",
2186ded16be15dd865a9b21ea304d5273c8be299c87Steve Block             expected_source, value_source, *val);
2196ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  }
2206ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  delete[] exp;
2216ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  delete[] val;
2226ded16be15dd865a9b21ea304d5273c8be299c87Steve Block}
2236ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
2246ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
225a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#define CHECK_EQ(expected, value) CheckEqualsHelper(__FILE__, __LINE__, \
226a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  #expected, expected, #value, value)
227a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
228a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
229a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#define CHECK_NE(unexpected, value) CheckNonEqualsHelper(__FILE__, __LINE__, \
230a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  #unexpected, unexpected, #value, value)
231a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
232a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
233a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#define CHECK_GT(a, b) CHECK((a) > (b))
234a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#define CHECK_GE(a, b) CHECK((a) >= (b))
235b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch#define CHECK_LT(a, b) CHECK((a) < (b))
236b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch#define CHECK_LE(a, b) CHECK((a) <= (b))
237a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
238a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
239a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// This is inspired by the static assertion facility in boost.  This
240a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// is pretty magical.  If it causes you trouble on a platform you may
241a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// find a fix in the boost code.
242a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blocktemplate <bool> class StaticAssertion;
243a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blocktemplate <> class StaticAssertion<true> { };
244a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// This macro joins two tokens.  If one of the tokens is a macro the
245a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// helper call causes it to be resolved before joining.
246a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#define SEMI_STATIC_JOIN(a, b) SEMI_STATIC_JOIN_HELPER(a, b)
247a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#define SEMI_STATIC_JOIN_HELPER(a, b) a##b
248a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Causes an error during compilation of the condition is not
249a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// statically known to be true.  It is formulated as a typedef so that
250a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// it can be used wherever a typedef can be used.  Beware that this
251a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// actually causes each use to introduce a new defined type with a
252a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// name depending on the source line.
253a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blocktemplate <int> class StaticAssertionHelper { };
254a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#define STATIC_CHECK(test)                                                  \
255a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  typedef                                                                   \
256a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    StaticAssertionHelper<sizeof(StaticAssertion<static_cast<bool>(test)>)> \
257a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    SEMI_STATIC_JOIN(__StaticAssertTypedef__, __LINE__)
258a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
259a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2603e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhunamespace v8 { namespace internal {
2613e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu
2623e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhubool EnableSlowAsserts();
2633e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu
2643e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu} }  // namespace v8::internal
2653e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu
266a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// The ASSERT macro is equivalent to CHECK except that it only
267756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick// generates code in debug builds.
268a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#ifdef DEBUG
269a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#define ASSERT_RESULT(expr)  CHECK(expr)
270a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#define ASSERT(condition)    CHECK(condition)
271a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#define ASSERT_EQ(v1, v2)    CHECK_EQ(v1, v2)
2727f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch#define ASSERT_NE(v1, v2)    CHECK_NE(v1, v2)
2737f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch#define ASSERT_GE(v1, v2)    CHECK_GE(v1, v2)
2748b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch#define ASSERT_LT(v1, v2)    CHECK_LT(v1, v2)
2758b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch#define ASSERT_LE(v1, v2)    CHECK_LE(v1, v2)
2763e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu#define SLOW_ASSERT(condition) if (EnableSlowAsserts()) CHECK(condition)
277a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#else
278a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#define ASSERT_RESULT(expr)     (expr)
279a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#define ASSERT(condition)      ((void) 0)
280a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#define ASSERT_EQ(v1, v2)      ((void) 0)
2817f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch#define ASSERT_NE(v1, v2)      ((void) 0)
2827f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch#define ASSERT_GE(v1, v2)      ((void) 0)
2838b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch#define ASSERT_LT(v1, v2)      ((void) 0)
2848b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch#define ASSERT_LE(v1, v2)      ((void) 0)
285a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#define SLOW_ASSERT(condition) ((void) 0)
286a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#endif
287756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick// Static asserts has no impact on runtime performance, so they can be
288756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick// safely enabled in release mode. Moreover, the ((void) 0) expression
289756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick// obeys different syntax rules than typedef's, e.g. it can't appear
290756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick// inside class declaration, this leads to inconsistency between debug
291b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch// and release compilation modes behavior.
292756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick#define STATIC_ASSERT(test)  STATIC_CHECK(test)
293a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
294a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#define ASSERT_NOT_NULL(p)  ASSERT_NE(NULL, p)
295a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
296a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#endif  // V8_CHECKS_H_
297