OLD | NEW |
1 // Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file |
2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
4 | 4 |
5 #ifndef RUNTIME_VM_UNIT_TEST_H_ | 5 #ifndef RUNTIME_VM_UNIT_TEST_H_ |
6 #define RUNTIME_VM_UNIT_TEST_H_ | 6 #define RUNTIME_VM_UNIT_TEST_H_ |
7 | 7 |
8 #include "include/dart_native_api.h" | 8 #include "include/dart_native_api.h" |
9 | 9 |
10 #include "platform/globals.h" | 10 #include "platform/globals.h" |
(...skipping 16 matching lines...) Expand all Loading... |
27 static const dart::TestCase kRegister##name(Dart_Test##name, #name); \ | 27 static const dart::TestCase kRegister##name(Dart_Test##name, #name); \ |
28 void Dart_Test##name() | 28 void Dart_Test##name() |
29 | 29 |
30 // The VM_TEST_CASE macro is used for tests that need an isolate and zone | 30 // The VM_TEST_CASE macro is used for tests that need an isolate and zone |
31 // in order to test its functionality. This macro is used for tests that | 31 // in order to test its functionality. This macro is used for tests that |
32 // are implemented using the VM code directly and do not use the Dart API | 32 // are implemented using the VM code directly and do not use the Dart API |
33 // for calling into the VM. The safepoint execution state of threads using | 33 // for calling into the VM. The safepoint execution state of threads using |
34 // this macro is transitioned from kThreadInNative to kThreadInVM. | 34 // this macro is transitioned from kThreadInNative to kThreadInVM. |
35 #define VM_TEST_CASE(name) \ | 35 #define VM_TEST_CASE(name) \ |
36 static void Dart_TestHelper##name(Thread* thread); \ | 36 static void Dart_TestHelper##name(Thread* thread); \ |
37 UNIT_TEST_CASE(name) \ | 37 UNIT_TEST_CASE(name) { \ |
38 { \ | |
39 TestIsolateScope __test_isolate__; \ | 38 TestIsolateScope __test_isolate__; \ |
40 Thread* __thread__ = Thread::Current(); \ | 39 Thread* __thread__ = Thread::Current(); \ |
41 ASSERT(__thread__->isolate() == __test_isolate__.isolate()); \ | 40 ASSERT(__thread__->isolate() == __test_isolate__.isolate()); \ |
42 TransitionNativeToVM transition(__thread__); \ | 41 TransitionNativeToVM transition(__thread__); \ |
43 StackZone __zone__(__thread__); \ | 42 StackZone __zone__(__thread__); \ |
44 HandleScope __hs__(__thread__); \ | 43 HandleScope __hs__(__thread__); \ |
45 Dart_TestHelper##name(__thread__); \ | 44 Dart_TestHelper##name(__thread__); \ |
46 } \ | 45 } \ |
47 static void Dart_TestHelper##name(Thread* thread) | 46 static void Dart_TestHelper##name(Thread* thread) |
48 | 47 |
49 // The TEST_CASE macro is used for tests that need an isolate and zone | 48 // The TEST_CASE macro is used for tests that need an isolate and zone |
50 // in order to test its functionality. This macro is used for tests that | 49 // in order to test its functionality. This macro is used for tests that |
51 // are implemented using the Dart API for calling into the VM. The safepoint | 50 // are implemented using the Dart API for calling into the VM. The safepoint |
52 // execution state of threads using this macro remains kThreadNative. | 51 // execution state of threads using this macro remains kThreadNative. |
53 #define TEST_CASE(name) \ | 52 #define TEST_CASE(name) \ |
54 static void Dart_TestHelper##name(Thread* thread); \ | 53 static void Dart_TestHelper##name(Thread* thread); \ |
55 UNIT_TEST_CASE(name) \ | 54 UNIT_TEST_CASE(name) { \ |
56 { \ | |
57 TestIsolateScope __test_isolate__; \ | 55 TestIsolateScope __test_isolate__; \ |
58 Thread* __thread__ = Thread::Current(); \ | 56 Thread* __thread__ = Thread::Current(); \ |
59 ASSERT(__thread__->isolate() == __test_isolate__.isolate()); \ | 57 ASSERT(__thread__->isolate() == __test_isolate__.isolate()); \ |
60 StackZone __zone__(__thread__); \ | 58 StackZone __zone__(__thread__); \ |
61 HandleScope __hs__(__thread__); \ | 59 HandleScope __hs__(__thread__); \ |
62 Dart_TestHelper##name(__thread__); \ | 60 Dart_TestHelper##name(__thread__); \ |
63 } \ | 61 } \ |
64 static void Dart_TestHelper##name(Thread* thread) | 62 static void Dart_TestHelper##name(Thread* thread) |
65 | 63 |
66 // The ASSEMBLER_TEST_GENERATE macro is used to generate a unit test | 64 // The ASSEMBLER_TEST_GENERATE macro is used to generate a unit test |
67 // for the assembler. | 65 // for the assembler. |
68 #define ASSEMBLER_TEST_GENERATE(name, assembler) \ | 66 #define ASSEMBLER_TEST_GENERATE(name, assembler) \ |
69 void AssemblerTestGenerate##name(Assembler* assembler) | 67 void AssemblerTestGenerate##name(Assembler* assembler) |
70 | 68 |
71 // The ASSEMBLER_TEST_EXTERN macro is used to declare a unit test | 69 // The ASSEMBLER_TEST_EXTERN macro is used to declare a unit test |
72 // for the assembler. | 70 // for the assembler. |
73 #define ASSEMBLER_TEST_EXTERN(name) \ | 71 #define ASSEMBLER_TEST_EXTERN(name) \ |
74 extern void AssemblerTestGenerate##name(Assembler* assembler); | 72 extern void AssemblerTestGenerate##name(Assembler* assembler); |
75 | 73 |
76 // The ASSEMBLER_TEST_RUN macro is used to execute the assembler unit | 74 // The ASSEMBLER_TEST_RUN macro is used to execute the assembler unit |
77 // test generated using the ASSEMBLER_TEST_GENERATE macro. | 75 // test generated using the ASSEMBLER_TEST_GENERATE macro. |
78 // C++ callee-saved registers are not preserved. Arguments may be passed in. | 76 // C++ callee-saved registers are not preserved. Arguments may be passed in. |
79 #define ASSEMBLER_TEST_RUN(name, test) \ | 77 #define ASSEMBLER_TEST_RUN(name, test) \ |
80 static void AssemblerTestRun##name(AssemblerTest* test); \ | 78 static void AssemblerTestRun##name(AssemblerTest* test); \ |
81 VM_TEST_CASE(name) { \ | 79 VM_TEST_CASE(name) { \ |
82 Assembler __assembler__; \ | 80 Assembler __assembler__; \ |
83 AssemblerTest test(""#name, &__assembler__); \ | 81 AssemblerTest test("" #name, &__assembler__); \ |
84 AssemblerTestGenerate##name(test.assembler()); \ | 82 AssemblerTestGenerate##name(test.assembler()); \ |
85 test.Assemble(); \ | 83 test.Assemble(); \ |
86 AssemblerTestRun##name(&test); \ | 84 AssemblerTestRun##name(&test); \ |
87 } \ | 85 } \ |
88 static void AssemblerTestRun##name(AssemblerTest* test) | 86 static void AssemblerTestRun##name(AssemblerTest* test) |
89 | 87 |
90 // Populate node list with AST nodes. | 88 // Populate node list with AST nodes. |
91 #define CODEGEN_TEST_GENERATE(name, test) \ | 89 #define CODEGEN_TEST_GENERATE(name, test) \ |
92 static void CodeGenTestGenerate##name(CodeGenTest* test) | 90 static void CodeGenTestGenerate##name(CodeGenTest* test) |
93 | 91 |
94 // Populate node list with AST nodes, possibly using the provided function | 92 // Populate node list with AST nodes, possibly using the provided function |
95 // object built by a previous CODEGEN_TEST_GENERATE. | 93 // object built by a previous CODEGEN_TEST_GENERATE. |
96 #define CODEGEN_TEST2_GENERATE(name, function, test) \ | 94 #define CODEGEN_TEST2_GENERATE(name, function, test) \ |
97 static void CodeGenTestGenerate##name(const Function& function, \ | 95 static void CodeGenTestGenerate##name(const Function& function, \ |
98 CodeGenTest* test) | 96 CodeGenTest* test) |
99 | 97 |
100 | 98 |
101 // Pass the name of test and the expected results as RawObject. | 99 // Pass the name of test and the expected results as RawObject. |
102 #define CODEGEN_TEST_RUN(name, expected) \ | 100 #define CODEGEN_TEST_RUN(name, expected) \ |
103 static void CodeGenTestRun##name(const Function& function); \ | 101 static void CodeGenTestRun##name(const Function& function); \ |
104 VM_TEST_CASE(name) { \ | 102 VM_TEST_CASE(name) { \ |
105 CodeGenTest __test__(""#name); \ | 103 CodeGenTest __test__("" #name); \ |
106 CodeGenTestGenerate##name(&__test__); \ | 104 CodeGenTestGenerate##name(&__test__); \ |
107 __test__.Compile(); \ | 105 __test__.Compile(); \ |
108 CodeGenTestRun##name(__test__.function()); \ | 106 CodeGenTestRun##name(__test__.function()); \ |
109 } \ | 107 } \ |
110 static void CodeGenTestRun##name(const Function& function) { \ | 108 static void CodeGenTestRun##name(const Function& function) { \ |
111 Object& result = Object::Handle(); \ | 109 Object& result = Object::Handle(); \ |
112 result = DartEntry::InvokeFunction(function, Object::empty_array()); \ | 110 result = DartEntry::InvokeFunction(function, Object::empty_array()); \ |
113 EXPECT(!result.IsError()); \ | 111 EXPECT(!result.IsError()); \ |
114 Instance& actual = Instance::Handle(); \ | 112 Instance& actual = Instance::Handle(); \ |
115 actual ^= result.raw(); \ | 113 actual ^= result.raw(); \ |
116 EXPECT(actual.CanonicalizeEquals(Instance::Handle(expected))); \ | 114 EXPECT(actual.CanonicalizeEquals(Instance::Handle(expected))); \ |
117 } | 115 } |
118 | 116 |
119 | 117 |
120 // Pass the name of test, and use the generated function to call it | 118 // Pass the name of test, and use the generated function to call it |
121 // and evaluate its result. | 119 // and evaluate its result. |
122 #define CODEGEN_TEST_RAW_RUN(name, function) \ | 120 #define CODEGEN_TEST_RAW_RUN(name, function) \ |
123 static void CodeGenTestRun##name(const Function& function); \ | 121 static void CodeGenTestRun##name(const Function& function); \ |
124 VM_TEST_CASE(name) { \ | 122 VM_TEST_CASE(name) { \ |
125 CodeGenTest __test__(""#name); \ | 123 CodeGenTest __test__("" #name); \ |
126 CodeGenTestGenerate##name(&__test__); \ | 124 CodeGenTestGenerate##name(&__test__); \ |
127 __test__.Compile(); \ | 125 __test__.Compile(); \ |
128 CodeGenTestRun##name(__test__.function()); \ | 126 CodeGenTestRun##name(__test__.function()); \ |
129 } \ | 127 } \ |
130 static void CodeGenTestRun##name(const Function& function) | 128 static void CodeGenTestRun##name(const Function& function) |
131 | 129 |
132 | 130 |
133 // Generate code for two sequences of AST nodes and execute the first one. | 131 // Generate code for two sequences of AST nodes and execute the first one. |
134 // The first one may reference the Function object generated by the second one. | 132 // The first one may reference the Function object generated by the second one. |
135 #define CODEGEN_TEST2_RUN(name1, name2, expected) \ | 133 #define CODEGEN_TEST2_RUN(name1, name2, expected) \ |
136 static void CodeGenTestRun##name1(const Function& function); \ | 134 static void CodeGenTestRun##name1(const Function& function); \ |
137 VM_TEST_CASE(name1) { \ | 135 VM_TEST_CASE(name1) { \ |
138 /* Generate code for name2 */ \ | 136 /* Generate code for name2 */ \ |
139 CodeGenTest __test2__(""#name2); \ | 137 CodeGenTest __test2__("" #name2); \ |
140 CodeGenTestGenerate##name2(&__test2__); \ | 138 CodeGenTestGenerate##name2(&__test2__); \ |
141 __test2__.Compile(); \ | 139 __test2__.Compile(); \ |
142 /* Generate code for name1, providing function2 */ \ | 140 /* Generate code for name1, providing function2 */ \ |
143 CodeGenTest __test1__(""#name1); \ | 141 CodeGenTest __test1__("" #name1); \ |
144 CodeGenTestGenerate##name1(__test2__.function(), &__test1__); \ | 142 CodeGenTestGenerate##name1(__test2__.function(), &__test1__); \ |
145 __test1__.Compile(); \ | 143 __test1__.Compile(); \ |
146 CodeGenTestRun##name1(__test1__.function()); \ | 144 CodeGenTestRun##name1(__test1__.function()); \ |
147 } \ | 145 } \ |
148 static void CodeGenTestRun##name1(const Function& function) { \ | 146 static void CodeGenTestRun##name1(const Function& function) { \ |
149 Object& result = Object::Handle(); \ | 147 Object& result = Object::Handle(); \ |
150 result = DartEntry::InvokeFunction(function, Object::empty_array()); \ | 148 result = DartEntry::InvokeFunction(function, Object::empty_array()); \ |
151 EXPECT(!result.IsError()); \ | 149 EXPECT(!result.IsError()); \ |
152 Instance& actual = Instance::Handle(); \ | 150 Instance& actual = Instance::Handle(); \ |
153 actual ^= result.raw(); \ | 151 actual ^= result.raw(); \ |
154 EXPECT(actual.CanonicalizeEquals(Instance::Handle(expected))); \ | 152 EXPECT(actual.CanonicalizeEquals(Instance::Handle(expected))); \ |
155 } | 153 } |
156 | 154 |
157 | 155 |
158 #if defined(TARGET_ARCH_ARM) || \ | 156 #if defined(TARGET_ARCH_ARM) || defined(TARGET_ARCH_MIPS) || \ |
159 defined(TARGET_ARCH_MIPS) || \ | |
160 defined(TARGET_ARCH_ARM64) | 157 defined(TARGET_ARCH_ARM64) |
161 #if defined(HOST_ARCH_ARM) || \ | 158 #if defined(HOST_ARCH_ARM) || defined(HOST_ARCH_MIPS) || \ |
162 defined(HOST_ARCH_MIPS) || \ | |
163 defined(HOST_ARCH_ARM64) | 159 defined(HOST_ARCH_ARM64) |
164 // Running on actual ARM or MIPS hardware, execute code natively. | 160 // Running on actual ARM or MIPS hardware, execute code natively. |
165 #define EXECUTE_TEST_CODE_INT32(name, entry) reinterpret_cast<name>(entry)() | 161 #define EXECUTE_TEST_CODE_INT32(name, entry) reinterpret_cast<name>(entry)() |
166 #define EXECUTE_TEST_CODE_INT64(name, entry) reinterpret_cast<name>(entry)() | 162 #define EXECUTE_TEST_CODE_INT64(name, entry) reinterpret_cast<name>(entry)() |
167 #define EXECUTE_TEST_CODE_INT64_LL(name, entry, long_arg0, long_arg1) \ | 163 #define EXECUTE_TEST_CODE_INT64_LL(name, entry, long_arg0, long_arg1) \ |
168 reinterpret_cast<name>(entry)(long_arg0, long_arg1) | 164 reinterpret_cast<name>(entry)(long_arg0, long_arg1) |
169 #define EXECUTE_TEST_CODE_FLOAT(name, entry) reinterpret_cast<name>(entry)() | 165 #define EXECUTE_TEST_CODE_FLOAT(name, entry) reinterpret_cast<name>(entry)() |
170 #define EXECUTE_TEST_CODE_DOUBLE(name, entry) reinterpret_cast<name>(entry)() | 166 #define EXECUTE_TEST_CODE_DOUBLE(name, entry) reinterpret_cast<name>(entry)() |
171 #define EXECUTE_TEST_CODE_INT32_F(name, entry, float_arg) \ | 167 #define EXECUTE_TEST_CODE_INT32_F(name, entry, float_arg) \ |
172 reinterpret_cast<name>(entry)(float_arg) | 168 reinterpret_cast<name>(entry)(float_arg) |
173 #define EXECUTE_TEST_CODE_INT32_D(name, entry, double_arg) \ | 169 #define EXECUTE_TEST_CODE_INT32_D(name, entry, double_arg) \ |
174 reinterpret_cast<name>(entry)(double_arg) | 170 reinterpret_cast<name>(entry)(double_arg) |
175 #define EXECUTE_TEST_CODE_INTPTR_INTPTR(name, entry, pointer_arg) \ | 171 #define EXECUTE_TEST_CODE_INTPTR_INTPTR(name, entry, pointer_arg) \ |
176 reinterpret_cast<name>(entry)(pointer_arg) | 172 reinterpret_cast<name>(entry)(pointer_arg) |
177 #define EXECUTE_TEST_CODE_INT32_INTPTR(name, entry, pointer_arg) \ | 173 #define EXECUTE_TEST_CODE_INT32_INTPTR(name, entry, pointer_arg) \ |
178 reinterpret_cast<name>(entry)(pointer_arg) | 174 reinterpret_cast<name>(entry)(pointer_arg) |
179 #else | 175 #else |
180 // Not running on ARM or MIPS hardware, call simulator to execute code. | 176 // Not running on ARM or MIPS hardware, call simulator to execute code. |
181 #if defined(ARCH_IS_64_BIT) | 177 #if defined(ARCH_IS_64_BIT) |
182 #define EXECUTE_TEST_CODE_INT64(name, entry) \ | 178 #define EXECUTE_TEST_CODE_INT64(name, entry) \ |
183 static_cast<int64_t>(Simulator::Current()->Call( \ | 179 static_cast<int64_t>( \ |
184 bit_cast<int64_t, uword>(entry), 0, 0, 0, 0)) | 180 Simulator::Current()->Call(bit_cast<int64_t, uword>(entry), 0, 0, 0, 0)) |
185 #define EXECUTE_TEST_CODE_DOUBLE(name, entry) \ | 181 #define EXECUTE_TEST_CODE_DOUBLE(name, entry) \ |
186 bit_cast<double, int64_t>(Simulator::Current()->Call( \ | 182 bit_cast<double, int64_t>(Simulator::Current()->Call( \ |
187 bit_cast<int64_t, uword>(entry), 0, 0, 0, 0, true)) | 183 bit_cast<int64_t, uword>(entry), 0, 0, 0, 0, true)) |
188 #define EXECUTE_TEST_CODE_INTPTR_INTPTR(name, entry, pointer_arg) \ | 184 #define EXECUTE_TEST_CODE_INTPTR_INTPTR(name, entry, pointer_arg) \ |
189 static_cast<intptr_t>(Simulator::Current()->Call( \ | 185 static_cast<intptr_t>(Simulator::Current()->Call( \ |
190 bit_cast<int64_t, uword>(entry), \ | 186 bit_cast<int64_t, uword>(entry), \ |
191 bit_cast<int64_t, intptr_t>(pointer_arg), \ | 187 bit_cast<int64_t, intptr_t>(pointer_arg), 0, 0, 0)) |
192 0, 0, 0)) | |
193 #define EXECUTE_TEST_CODE_INT32_INTPTR(name, entry, pointer_arg) \ | 188 #define EXECUTE_TEST_CODE_INT32_INTPTR(name, entry, pointer_arg) \ |
194 static_cast<int32_t>(Simulator::Current()->Call( \ | 189 static_cast<int32_t>(Simulator::Current()->Call( \ |
195 bit_cast<int64_t, uword>(entry), \ | 190 bit_cast<int64_t, uword>(entry), \ |
196 bit_cast<int64_t, intptr_t>(pointer_arg), \ | 191 bit_cast<int64_t, intptr_t>(pointer_arg), 0, 0, 0)) |
197 0, 0, 0)) | |
198 #else | 192 #else |
199 #define EXECUTE_TEST_CODE_INT32(name, entry) \ | 193 #define EXECUTE_TEST_CODE_INT32(name, entry) \ |
200 static_cast<int32_t>(Simulator::Current()->Call( \ | 194 static_cast<int32_t>( \ |
201 bit_cast<int32_t, uword>(entry), 0, 0, 0, 0)) | 195 Simulator::Current()->Call(bit_cast<int32_t, uword>(entry), 0, 0, 0, 0)) |
202 #define EXECUTE_TEST_CODE_DOUBLE(name, entry) \ | 196 #define EXECUTE_TEST_CODE_DOUBLE(name, entry) \ |
203 bit_cast<double, int64_t>(Simulator::Current()->Call( \ | 197 bit_cast<double, int64_t>(Simulator::Current()->Call( \ |
204 bit_cast<int32_t, uword>(entry), 0, 0, 0, 0, true)) | 198 bit_cast<int32_t, uword>(entry), 0, 0, 0, 0, true)) |
205 #define EXECUTE_TEST_CODE_INTPTR_INTPTR(name, entry, pointer_arg) \ | 199 #define EXECUTE_TEST_CODE_INTPTR_INTPTR(name, entry, pointer_arg) \ |
206 static_cast<intptr_t>(Simulator::Current()->Call( \ | 200 static_cast<intptr_t>(Simulator::Current()->Call( \ |
207 bit_cast<int32_t, uword>(entry), \ | 201 bit_cast<int32_t, uword>(entry), \ |
208 bit_cast<int32_t, intptr_t>(pointer_arg), \ | 202 bit_cast<int32_t, intptr_t>(pointer_arg), 0, 0, 0)) |
209 0, 0, 0)) | |
210 #define EXECUTE_TEST_CODE_INT32_INTPTR(name, entry, pointer_arg) \ | 203 #define EXECUTE_TEST_CODE_INT32_INTPTR(name, entry, pointer_arg) \ |
211 static_cast<int32_t>(Simulator::Current()->Call( \ | 204 static_cast<int32_t>(Simulator::Current()->Call( \ |
212 bit_cast<int32_t, uword>(entry), \ | 205 bit_cast<int32_t, uword>(entry), \ |
213 bit_cast<int32_t, intptr_t>(pointer_arg), \ | 206 bit_cast<int32_t, intptr_t>(pointer_arg), 0, 0, 0)) |
214 0, 0, 0)) | |
215 #endif // defined(ARCH_IS_64_BIT) | 207 #endif // defined(ARCH_IS_64_BIT) |
216 #define EXECUTE_TEST_CODE_INT64_LL(name, entry, long_arg0, long_arg1) \ | 208 #define EXECUTE_TEST_CODE_INT64_LL(name, entry, long_arg0, long_arg1) \ |
217 static_cast<int64_t>(Simulator::Current()->Call( \ | 209 static_cast<int64_t>(Simulator::Current()->Call( \ |
218 bit_cast<int32_t, uword>(entry), \ | 210 bit_cast<int32_t, uword>(entry), Utils::Low32Bits(long_arg0), \ |
219 Utils::Low32Bits(long_arg0), \ | 211 Utils::High32Bits(long_arg0), Utils::Low32Bits(long_arg1), \ |
220 Utils::High32Bits(long_arg0), \ | |
221 Utils::Low32Bits(long_arg1), \ | |
222 Utils::High32Bits(long_arg1))) | 212 Utils::High32Bits(long_arg1))) |
223 #define EXECUTE_TEST_CODE_FLOAT(name, entry) \ | 213 #define EXECUTE_TEST_CODE_FLOAT(name, entry) \ |
224 bit_cast<float, int32_t>(Simulator::Current()->Call( \ | 214 bit_cast<float, int32_t>(Simulator::Current()->Call( \ |
225 bit_cast<int32_t, uword>(entry), 0, 0, 0, 0, true)) | 215 bit_cast<int32_t, uword>(entry), 0, 0, 0, 0, true)) |
226 #define EXECUTE_TEST_CODE_INT32_F(name, entry, float_arg) \ | 216 #define EXECUTE_TEST_CODE_INT32_F(name, entry, float_arg) \ |
227 static_cast<int32_t>(Simulator::Current()->Call( \ | 217 static_cast<int32_t>(Simulator::Current()->Call( \ |
228 bit_cast<int32_t, uword>(entry), \ | 218 bit_cast<int32_t, uword>(entry), bit_cast<int32_t, float>(float_arg), 0, \ |
229 bit_cast<int32_t, float>(float_arg), \ | 219 0, 0, false, true)) |
230 0, 0, 0, false, true)) | |
231 #define EXECUTE_TEST_CODE_INT32_D(name, entry, double_arg) \ | 220 #define EXECUTE_TEST_CODE_INT32_D(name, entry, double_arg) \ |
232 static_cast<int32_t>(Simulator::Current()->Call( \ | 221 static_cast<int32_t>(Simulator::Current()->Call( \ |
233 bit_cast<int32_t, uword>(entry), \ | 222 bit_cast<int32_t, uword>(entry), \ |
234 Utils::Low32Bits(bit_cast<int64_t, double>(double_arg)), \ | 223 Utils::Low32Bits(bit_cast<int64_t, double>(double_arg)), \ |
235 Utils::High32Bits(bit_cast<int64_t, double>(double_arg)), \ | 224 Utils::High32Bits(bit_cast<int64_t, double>(double_arg)), 0, 0, false, \ |
236 0, 0, false, true)) | 225 true)) |
237 #endif // defined(HOST_ARCH_ARM) || defined(HOST_ARCH_MIPS) | 226 #endif // defined(HOST_ARCH_ARM) || defined(HOST_ARCH_MIPS) |
238 #endif // defined(TARGET_ARCH_{ARM, ARM64, MIPS}) | 227 #endif // defined(TARGET_ARCH_{ARM, ARM64, MIPS}) |
239 | 228 |
240 | 229 |
241 inline Dart_Handle NewString(const char* str) { | 230 inline Dart_Handle NewString(const char* str) { |
242 return Dart_NewStringFromCString(str); | 231 return Dart_NewStringFromCString(str); |
243 } | 232 } |
244 | 233 |
245 | 234 |
246 namespace dart { | 235 namespace dart { |
(...skipping 11 matching lines...) Expand all Loading... |
258 | 247 |
259 // isolate_snapshot_buffer points to a snapshot for an isolate if we link in a | 248 // isolate_snapshot_buffer points to a snapshot for an isolate if we link in a |
260 // snapshot otherwise it is initialized to NULL. | 249 // snapshot otherwise it is initialized to NULL. |
261 extern const uint8_t* isolate_snapshot_buffer; | 250 extern const uint8_t* isolate_snapshot_buffer; |
262 } | 251 } |
263 | 252 |
264 | 253 |
265 class TestCaseBase { | 254 class TestCaseBase { |
266 public: | 255 public: |
267 explicit TestCaseBase(const char* name); | 256 explicit TestCaseBase(const char* name); |
268 virtual ~TestCaseBase() { } | 257 virtual ~TestCaseBase() {} |
269 | 258 |
270 const char* name() const { return name_; } | 259 const char* name() const { return name_; } |
271 | 260 |
272 virtual void Run() = 0; | 261 virtual void Run() = 0; |
273 void RunTest(); | 262 void RunTest(); |
274 | 263 |
275 static void RunAll(); | 264 static void RunAll(); |
276 | 265 |
277 private: | 266 private: |
278 static TestCaseBase* first_; | 267 static TestCaseBase* first_; |
279 static TestCaseBase* tail_; | 268 static TestCaseBase* tail_; |
280 | 269 |
281 TestCaseBase* next_; | 270 TestCaseBase* next_; |
282 const char* name_; | 271 const char* name_; |
283 | 272 |
284 DISALLOW_COPY_AND_ASSIGN(TestCaseBase); | 273 DISALLOW_COPY_AND_ASSIGN(TestCaseBase); |
285 }; | 274 }; |
286 | 275 |
287 #define USER_TEST_URI "test-lib" | 276 #define USER_TEST_URI "test-lib" |
288 #define CORELIB_TEST_URI "dart:test-lib" | 277 #define CORELIB_TEST_URI "dart:test-lib" |
289 | 278 |
290 class TestCase : TestCaseBase { | 279 class TestCase : TestCaseBase { |
291 public: | 280 public: |
292 typedef void (RunEntry)(); | 281 typedef void(RunEntry)(); |
293 | 282 |
294 TestCase(RunEntry* run, const char* name) : TestCaseBase(name), run_(run) { } | 283 TestCase(RunEntry* run, const char* name) : TestCaseBase(name), run_(run) {} |
295 | 284 |
296 static Dart_Handle LoadTestScript(const char* script, | 285 static Dart_Handle LoadTestScript(const char* script, |
297 Dart_NativeEntryResolver resolver, | 286 Dart_NativeEntryResolver resolver, |
298 const char* lib_uri = USER_TEST_URI, | 287 const char* lib_uri = USER_TEST_URI, |
299 bool finalize = true); | 288 bool finalize = true); |
300 static Dart_Handle LoadCoreTestScript(const char* script, | 289 static Dart_Handle LoadCoreTestScript(const char* script, |
301 Dart_NativeEntryResolver resolver); | 290 Dart_NativeEntryResolver resolver); |
302 static Dart_Handle lib(); | 291 static Dart_Handle lib(); |
303 static const char* url() { return USER_TEST_URI; } | 292 static const char* url() { return USER_TEST_URI; } |
304 static Dart_Isolate CreateTestIsolateFromSnapshot( | 293 static Dart_Isolate CreateTestIsolateFromSnapshot(uint8_t* buffer, |
305 uint8_t* buffer, const char* name = NULL) { | 294 const char* name = NULL) { |
306 return CreateIsolate(buffer, name); | 295 return CreateIsolate(buffer, name); |
307 } | 296 } |
308 static Dart_Isolate CreateTestIsolate(const char* name = NULL) { | 297 static Dart_Isolate CreateTestIsolate(const char* name = NULL) { |
309 return CreateIsolate(bin::isolate_snapshot_buffer, name); | 298 return CreateIsolate(bin::isolate_snapshot_buffer, name); |
310 } | 299 } |
311 static Dart_Handle library_handler(Dart_LibraryTag tag, | 300 static Dart_Handle library_handler(Dart_LibraryTag tag, |
312 Dart_Handle library, | 301 Dart_Handle library, |
313 Dart_Handle url); | 302 Dart_Handle url); |
314 static char* BigintToHexValue(Dart_CObject* bigint); | 303 static char* BigintToHexValue(Dart_CObject* bigint); |
315 | 304 |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
349 } | 338 } |
350 Isolate* isolate() const { return isolate_; } | 339 Isolate* isolate() const { return isolate_; } |
351 | 340 |
352 private: | 341 private: |
353 Isolate* isolate_; | 342 Isolate* isolate_; |
354 | 343 |
355 DISALLOW_COPY_AND_ASSIGN(TestIsolateScope); | 344 DISALLOW_COPY_AND_ASSIGN(TestIsolateScope); |
356 }; | 345 }; |
357 | 346 |
358 | 347 |
359 template<typename T> struct is_void { | 348 template <typename T> |
| 349 struct is_void { |
360 static const bool value = false; | 350 static const bool value = false; |
361 }; | 351 }; |
362 | 352 |
363 | 353 |
364 template<> struct is_void<void> { | 354 template <> |
| 355 struct is_void<void> { |
365 static const bool value = true; | 356 static const bool value = true; |
366 }; | 357 }; |
367 | 358 |
368 | 359 |
369 template<typename T> struct is_double { | 360 template <typename T> |
| 361 struct is_double { |
370 static const bool value = false; | 362 static const bool value = false; |
371 }; | 363 }; |
372 | 364 |
373 | 365 |
374 template<> struct is_double<double> { | 366 template <> |
| 367 struct is_double<double> { |
375 static const bool value = true; | 368 static const bool value = true; |
376 }; | 369 }; |
377 | 370 |
378 | 371 |
379 class AssemblerTest { | 372 class AssemblerTest { |
380 public: | 373 public: |
381 AssemblerTest(const char* name, Assembler* assembler) | 374 AssemblerTest(const char* name, Assembler* assembler) |
382 : name_(name), | 375 : name_(name), assembler_(assembler), code_(Code::ZoneHandle()) { |
383 assembler_(assembler), | |
384 code_(Code::ZoneHandle()) { | |
385 ASSERT(name != NULL); | 376 ASSERT(name != NULL); |
386 ASSERT(assembler != NULL); | 377 ASSERT(assembler != NULL); |
387 } | 378 } |
388 ~AssemblerTest() { } | 379 ~AssemblerTest() {} |
389 | 380 |
390 Assembler* assembler() const { return assembler_; } | 381 Assembler* assembler() const { return assembler_; } |
391 | 382 |
392 const Code& code() const { return code_; } | 383 const Code& code() const { return code_; } |
393 | 384 |
394 uword payload_start() const { return code_.PayloadStart(); } | 385 uword payload_start() const { return code_.PayloadStart(); } |
395 uword entry() const { return code_.UncheckedEntryPoint(); } | 386 uword entry() const { return code_.UncheckedEntryPoint(); } |
396 | 387 |
397 // Invoke/InvokeWithCodeAndThread is used to call assembler test functions | 388 // Invoke/InvokeWithCodeAndThread is used to call assembler test functions |
398 // using the ABI calling convention. | 389 // using the ABI calling convention. |
399 // ResultType is the return type of the assembler test function. | 390 // ResultType is the return type of the assembler test function. |
400 // ArgNType is the type of the Nth argument. | 391 // ArgNType is the type of the Nth argument. |
401 #if defined(USING_SIMULATOR) && !defined(TARGET_ARCH_DBC) | 392 #if defined(USING_SIMULATOR) && !defined(TARGET_ARCH_DBC) |
402 | 393 |
403 #if defined(ARCH_IS_64_BIT) | 394 #if defined(ARCH_IS_64_BIT) |
404 // TODO(fschneider): Make InvokeWithCodeAndThread<> more general and work on | 395 // TODO(fschneider): Make InvokeWithCodeAndThread<> more general and work on |
405 // 32-bit. | 396 // 32-bit. |
406 // Since Simulator::Call always return a int64_t, bit_cast does not work | 397 // Since Simulator::Call always return a int64_t, bit_cast does not work |
407 // on 32-bit platforms when returning an int32_t. Since template functions | 398 // on 32-bit platforms when returning an int32_t. Since template functions |
408 // don't support partial specialization, we'd need to introduce a helper | 399 // don't support partial specialization, we'd need to introduce a helper |
409 // class to support 32-bit return types. | 400 // class to support 32-bit return types. |
410 template<typename ResultType> ResultType InvokeWithCodeAndThread() { | 401 template <typename ResultType> |
| 402 ResultType InvokeWithCodeAndThread() { |
411 const bool fp_return = is_double<ResultType>::value; | 403 const bool fp_return = is_double<ResultType>::value; |
412 const bool fp_args = false; | 404 const bool fp_args = false; |
413 Thread* thread = Thread::Current(); | 405 Thread* thread = Thread::Current(); |
414 ASSERT(thread != NULL); | 406 ASSERT(thread != NULL); |
415 return bit_cast<ResultType, int64_t>(Simulator::Current()->Call( | 407 return bit_cast<ResultType, int64_t>(Simulator::Current()->Call( |
416 bit_cast<intptr_t, uword>(entry()), | 408 bit_cast<intptr_t, uword>(entry()), reinterpret_cast<intptr_t>(&code_), |
417 reinterpret_cast<intptr_t>(&code_), | 409 reinterpret_cast<intptr_t>(thread), 0, 0, fp_return, fp_args)); |
418 reinterpret_cast<intptr_t>(thread), | |
419 0, 0, fp_return, fp_args)); | |
420 } | 410 } |
421 template<typename ResultType, typename Arg1Type> | 411 template <typename ResultType, typename Arg1Type> |
422 ResultType InvokeWithCodeAndThread(Arg1Type arg1) { | 412 ResultType InvokeWithCodeAndThread(Arg1Type arg1) { |
423 const bool fp_return = is_double<ResultType>::value; | 413 const bool fp_return = is_double<ResultType>::value; |
424 const bool fp_args = is_double<Arg1Type>::value; | 414 const bool fp_args = is_double<Arg1Type>::value; |
425 // TODO(fschneider): Support double arguments for simulator calls. | 415 // TODO(fschneider): Support double arguments for simulator calls. |
426 COMPILE_ASSERT(!fp_args); | 416 COMPILE_ASSERT(!fp_args); |
427 Thread* thread = Thread::Current(); | 417 Thread* thread = Thread::Current(); |
428 ASSERT(thread != NULL); | 418 ASSERT(thread != NULL); |
429 return bit_cast<ResultType, int64_t>(Simulator::Current()->Call( | 419 return bit_cast<ResultType, int64_t>(Simulator::Current()->Call( |
430 bit_cast<intptr_t, uword>(entry()), | 420 bit_cast<intptr_t, uword>(entry()), reinterpret_cast<intptr_t>(&code_), |
431 reinterpret_cast<intptr_t>(&code_), | 421 reinterpret_cast<intptr_t>(thread), reinterpret_cast<intptr_t>(arg1), 0, |
432 reinterpret_cast<intptr_t>(thread), | 422 fp_return, fp_args)); |
433 reinterpret_cast<intptr_t>(arg1), | |
434 0, fp_return, fp_args)); | |
435 } | 423 } |
436 #endif // ARCH_IS_64_BIT | 424 #endif // ARCH_IS_64_BIT |
437 | 425 |
438 template<typename ResultType, | 426 template <typename ResultType, |
439 typename Arg1Type, | 427 typename Arg1Type, |
440 typename Arg2Type, | 428 typename Arg2Type, |
441 typename Arg3Type> | 429 typename Arg3Type> |
442 ResultType Invoke(Arg1Type arg1, Arg2Type arg2, Arg3Type arg3) { | 430 ResultType Invoke(Arg1Type arg1, Arg2Type arg2, Arg3Type arg3) { |
443 // TODO(fschneider): Support double arguments for simulator calls. | 431 // TODO(fschneider): Support double arguments for simulator calls. |
444 COMPILE_ASSERT(is_void<ResultType>::value); | 432 COMPILE_ASSERT(is_void<ResultType>::value); |
445 COMPILE_ASSERT(!is_double<Arg1Type>::value); | 433 COMPILE_ASSERT(!is_double<Arg1Type>::value); |
446 COMPILE_ASSERT(!is_double<Arg2Type>::value); | 434 COMPILE_ASSERT(!is_double<Arg2Type>::value); |
447 COMPILE_ASSERT(!is_double<Arg3Type>::value); | 435 COMPILE_ASSERT(!is_double<Arg3Type>::value); |
448 const bool fp_args = false; | 436 const bool fp_args = false; |
449 const bool fp_return = false; | 437 const bool fp_return = false; |
450 Simulator::Current()->Call( | 438 Simulator::Current()->Call( |
451 bit_cast<intptr_t, uword>(entry()), | 439 bit_cast<intptr_t, uword>(entry()), reinterpret_cast<intptr_t>(arg1), |
452 reinterpret_cast<intptr_t>(arg1), | 440 reinterpret_cast<intptr_t>(arg2), reinterpret_cast<intptr_t>(arg3), 0, |
453 reinterpret_cast<intptr_t>(arg2), | 441 fp_return, fp_args); |
454 reinterpret_cast<intptr_t>(arg3), | |
455 0, fp_return, fp_args); | |
456 } | 442 } |
457 #elif defined(USING_SIMULATOR) && defined(TARGET_ARCH_DBC) | 443 #elif defined(USING_SIMULATOR) && defined(TARGET_ARCH_DBC) |
458 template<typename ResultType, | 444 template <typename ResultType, |
459 typename Arg1Type, | 445 typename Arg1Type, |
460 typename Arg2Type, | 446 typename Arg2Type, |
461 typename Arg3Type> | 447 typename Arg3Type> |
462 ResultType Invoke(Arg1Type arg1, Arg2Type arg2, Arg3Type arg3) { | 448 ResultType Invoke(Arg1Type arg1, Arg2Type arg2, Arg3Type arg3) { |
463 // TODO(fschneider): Support double arguments for simulator calls. | 449 // TODO(fschneider): Support double arguments for simulator calls. |
464 COMPILE_ASSERT(is_void<ResultType>::value); | 450 COMPILE_ASSERT(is_void<ResultType>::value); |
465 COMPILE_ASSERT(!is_double<Arg1Type>::value); | 451 COMPILE_ASSERT(!is_double<Arg1Type>::value); |
466 COMPILE_ASSERT(!is_double<Arg2Type>::value); | 452 COMPILE_ASSERT(!is_double<Arg2Type>::value); |
467 COMPILE_ASSERT(!is_double<Arg3Type>::value); | 453 COMPILE_ASSERT(!is_double<Arg3Type>::value); |
468 const Object& arg1obj = Object::Handle(reinterpret_cast<RawObject*>(arg1)); | 454 const Object& arg1obj = Object::Handle(reinterpret_cast<RawObject*>(arg1)); |
469 const Object& arg2obj = Object::Handle(reinterpret_cast<RawObject*>(arg2)); | 455 const Object& arg2obj = Object::Handle(reinterpret_cast<RawObject*>(arg2)); |
470 const Array& argdesc = Array::Handle(ArgumentsDescriptor::New(2)); | 456 const Array& argdesc = Array::Handle(ArgumentsDescriptor::New(2)); |
471 const Array& arguments = Array::Handle(Array::New(2)); | 457 const Array& arguments = Array::Handle(Array::New(2)); |
472 arguments.SetAt(0, arg1obj); | 458 arguments.SetAt(0, arg1obj); |
473 arguments.SetAt(1, arg2obj); | 459 arguments.SetAt(1, arg2obj); |
474 Simulator::Current()->Call( | 460 Simulator::Current()->Call(code(), argdesc, arguments, |
475 code(), | 461 reinterpret_cast<Thread*>(arg3)); |
476 argdesc, | |
477 arguments, | |
478 reinterpret_cast<Thread*>(arg3)); | |
479 } | 462 } |
480 #else | 463 #else |
481 template<typename ResultType> ResultType InvokeWithCodeAndThread() { | 464 template <typename ResultType> |
| 465 ResultType InvokeWithCodeAndThread() { |
482 Thread* thread = Thread::Current(); | 466 Thread* thread = Thread::Current(); |
483 ASSERT(thread != NULL); | 467 ASSERT(thread != NULL); |
484 typedef ResultType (*FunctionType) (const Code&, Thread*); | 468 typedef ResultType (*FunctionType)(const Code&, Thread*); |
485 return reinterpret_cast<FunctionType>(entry())(code_, thread); | 469 return reinterpret_cast<FunctionType>(entry())(code_, thread); |
486 } | 470 } |
487 | 471 |
488 template<typename ResultType, typename Arg1Type> | 472 template <typename ResultType, typename Arg1Type> |
489 ResultType InvokeWithCodeAndThread(Arg1Type arg1) { | 473 ResultType InvokeWithCodeAndThread(Arg1Type arg1) { |
490 Thread* thread = Thread::Current(); | 474 Thread* thread = Thread::Current(); |
491 ASSERT(thread != NULL); | 475 ASSERT(thread != NULL); |
492 typedef ResultType (*FunctionType) (const Code&, Thread*, Arg1Type); | 476 typedef ResultType (*FunctionType)(const Code&, Thread*, Arg1Type); |
493 return reinterpret_cast<FunctionType>(entry())(code_, thread, arg1); | 477 return reinterpret_cast<FunctionType>(entry())(code_, thread, arg1); |
494 } | 478 } |
495 | 479 |
496 template<typename ResultType, | 480 template <typename ResultType, |
497 typename Arg1Type, | 481 typename Arg1Type, |
498 typename Arg2Type, | 482 typename Arg2Type, |
499 typename Arg3Type> | 483 typename Arg3Type> |
500 ResultType Invoke(Arg1Type arg1, Arg2Type arg2, Arg3Type arg3) { | 484 ResultType Invoke(Arg1Type arg1, Arg2Type arg2, Arg3Type arg3) { |
501 typedef ResultType (*FunctionType) (Arg1Type, Arg2Type, Arg3Type); | 485 typedef ResultType (*FunctionType)(Arg1Type, Arg2Type, Arg3Type); |
502 return reinterpret_cast<FunctionType>(entry())(arg1, arg2, arg3); | 486 return reinterpret_cast<FunctionType>(entry())(arg1, arg2, arg3); |
503 } | 487 } |
504 #endif // defined(USING_SIMULATOR) && !defined(TARGET_ARCH_DBC) | 488 #endif // defined(USING_SIMULATOR) && !defined(TARGET_ARCH_DBC) |
505 | 489 |
506 // Assemble test and set code_. | 490 // Assemble test and set code_. |
507 void Assemble(); | 491 void Assemble(); |
508 | 492 |
509 private: | 493 private: |
510 const char* name_; | 494 const char* name_; |
511 Assembler* assembler_; | 495 Assembler* assembler_; |
512 Code& code_; | 496 Code& code_; |
513 | 497 |
514 DISALLOW_COPY_AND_ASSIGN(AssemblerTest); | 498 DISALLOW_COPY_AND_ASSIGN(AssemblerTest); |
515 }; | 499 }; |
516 | 500 |
517 | 501 |
518 class CodeGenTest { | 502 class CodeGenTest { |
519 public: | 503 public: |
520 explicit CodeGenTest(const char* name); | 504 explicit CodeGenTest(const char* name); |
521 ~CodeGenTest() { } | 505 ~CodeGenTest() {} |
522 | 506 |
523 // Accessors. | 507 // Accessors. |
524 const Function& function() const { return function_; } | 508 const Function& function() const { return function_; } |
525 | 509 |
526 SequenceNode* node_sequence() const { return node_sequence_; } | 510 SequenceNode* node_sequence() const { return node_sequence_; } |
527 | 511 |
528 void set_default_parameter_values(ZoneGrowableArray<const Instance*>* value) { | 512 void set_default_parameter_values(ZoneGrowableArray<const Instance*>* value) { |
529 default_parameter_values_ = value; | 513 default_parameter_values_ = value; |
530 } | 514 } |
531 | 515 |
532 // Compile test and set code in function. | 516 // Compile test and set code in function. |
533 void Compile(); | 517 void Compile(); |
(...skipping 15 matching lines...) Expand all Loading... |
549 | 533 |
550 // Test the Compiler::CompileFunction functionality by checking the return | 534 // Test the Compiler::CompileFunction functionality by checking the return |
551 // value to see if no parse errors were reported. | 535 // value to see if no parse errors were reported. |
552 static bool TestCompileFunction(const Function& function); | 536 static bool TestCompileFunction(const Function& function); |
553 }; | 537 }; |
554 | 538 |
555 #define EXPECT_VALID(handle) \ | 539 #define EXPECT_VALID(handle) \ |
556 do { \ | 540 do { \ |
557 Dart_Handle tmp_handle = (handle); \ | 541 Dart_Handle tmp_handle = (handle); \ |
558 if (Dart_IsError(tmp_handle)) { \ | 542 if (Dart_IsError(tmp_handle)) { \ |
559 dart::Expect(__FILE__, __LINE__).Fail( \ | 543 dart::Expect(__FILE__, __LINE__) \ |
560 "expected '%s' to be a valid handle but found an error handle:\n" \ | 544 .Fail( \ |
561 " '%s'\n", \ | 545 "expected '%s' to be a valid handle but found an error " \ |
562 #handle, Dart_GetError(tmp_handle)); \ | 546 "handle:\n" \ |
| 547 " '%s'\n", \ |
| 548 #handle, Dart_GetError(tmp_handle)); \ |
563 } \ | 549 } \ |
564 } while (0) | 550 } while (0) |
565 | 551 |
566 #define EXPECT_ERROR(handle, substring) \ | 552 #define EXPECT_ERROR(handle, substring) \ |
567 do { \ | 553 do { \ |
568 Dart_Handle tmp_handle = (handle); \ | 554 Dart_Handle tmp_handle = (handle); \ |
569 if (Dart_IsError(tmp_handle)) { \ | 555 if (Dart_IsError(tmp_handle)) { \ |
570 dart::Expect(__FILE__, __LINE__).IsSubstring((substring), \ | 556 dart::Expect(__FILE__, __LINE__) \ |
571 Dart_GetError(tmp_handle)); \ | 557 .IsSubstring((substring), Dart_GetError(tmp_handle)); \ |
572 } else { \ | 558 } else { \ |
573 dart::Expect(__FILE__, __LINE__).Fail( \ | 559 dart::Expect(__FILE__, __LINE__) \ |
574 "expected '%s' to be an error handle but found a valid handle.\n", \ | 560 .Fail( \ |
575 #handle); \ | 561 "expected '%s' to be an error handle but found a valid " \ |
| 562 "handle.\n", \ |
| 563 #handle); \ |
576 } \ | 564 } \ |
577 } while (0) | 565 } while (0) |
578 | 566 |
579 #define EXPECT_TRUE(handle) \ | 567 #define EXPECT_TRUE(handle) \ |
580 do { \ | 568 do { \ |
581 Dart_Handle tmp_handle = (handle); \ | 569 Dart_Handle tmp_handle = (handle); \ |
582 if (Dart_IsBoolean(tmp_handle)) { \ | 570 if (Dart_IsBoolean(tmp_handle)) { \ |
583 bool value; \ | 571 bool value; \ |
584 Dart_BooleanValue(tmp_handle, &value); \ | 572 Dart_BooleanValue(tmp_handle, &value); \ |
585 if (!value) { \ | 573 if (!value) { \ |
586 dart::Expect(__FILE__, __LINE__).Fail("expected True, but was '%s'\n", \ | 574 dart::Expect(__FILE__, __LINE__) \ |
587 #handle); \ | 575 .Fail("expected True, but was '%s'\n", #handle); \ |
588 } \ | 576 } \ |
589 } else { \ | 577 } else { \ |
590 dart::Expect(__FILE__, __LINE__).Fail("expected True, but was '%s'\n", \ | 578 dart::Expect(__FILE__, __LINE__) \ |
591 #handle); \ | 579 .Fail("expected True, but was '%s'\n", #handle); \ |
592 } \ | 580 } \ |
593 } while (0) | 581 } while (0) |
594 | 582 |
595 | 583 |
596 // Elide a substring which starts with some prefix and ends with a ". | 584 // Elide a substring which starts with some prefix and ends with a ". |
597 // | 585 // |
598 // This is used to remove non-deterministic or fragile substrings from | 586 // This is used to remove non-deterministic or fragile substrings from |
599 // JSON output. | 587 // JSON output. |
600 // | 588 // |
601 // For example: | 589 // For example: |
602 // | 590 // |
603 // prefix = "classes" | 591 // prefix = "classes" |
604 // in = "\"id\":\"classes/46\"" | 592 // in = "\"id\":\"classes/46\"" |
605 // | 593 // |
606 // Yields: | 594 // Yields: |
607 // | 595 // |
608 // out = "\"id\":\"\"" | 596 // out = "\"id\":\"\"" |
609 // | 597 // |
610 void ElideJSONSubstring(const char* prefix, const char* in, char* out); | 598 void ElideJSONSubstring(const char* prefix, const char* in, char* out); |
611 | 599 |
612 | 600 |
613 template<typename T> | 601 template <typename T> |
614 class SetFlagScope : public ValueObject { | 602 class SetFlagScope : public ValueObject { |
615 public: | 603 public: |
616 SetFlagScope(T* flag, T value) | 604 SetFlagScope(T* flag, T value) : flag_(flag), original_value_(*flag) { |
617 : flag_(flag), | |
618 original_value_(*flag) { | |
619 *flag_ = value; | 605 *flag_ = value; |
620 } | 606 } |
621 | 607 |
622 ~SetFlagScope() { | 608 ~SetFlagScope() { *flag_ = original_value_; } |
623 *flag_ = original_value_; | |
624 } | |
625 | 609 |
626 private: | 610 private: |
627 T* flag_; | 611 T* flag_; |
628 T original_value_; | 612 T original_value_; |
629 }; | 613 }; |
630 | 614 |
631 } // namespace dart | 615 } // namespace dart |
632 | 616 |
633 #endif // RUNTIME_VM_UNIT_TEST_H_ | 617 #endif // RUNTIME_VM_UNIT_TEST_H_ |
OLD | NEW |