| 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 |