Index: runtime/vm/unit_test.h |
diff --git a/runtime/vm/unit_test.h b/runtime/vm/unit_test.h |
index b74d4479472ad331928968dd000a5d39889bd6e8..9c6682e812b92a62fcd54e0122028bb9d2275e14 100644 |
--- a/runtime/vm/unit_test.h |
+++ b/runtime/vm/unit_test.h |
@@ -323,6 +323,26 @@ class TestIsolateScope { |
}; |
+template<typename T> struct is_void { |
+ static const bool value = false; |
+}; |
+ |
+ |
+template<> struct is_void<void> { |
+ static const bool value = true; |
+}; |
+ |
+ |
+template<typename T> struct is_double { |
+ static const bool value = false; |
+}; |
+ |
+ |
+template<> struct is_double<double> { |
+ static const bool value = true; |
+}; |
+ |
+ |
class AssemblerTest { |
public: |
AssemblerTest(const char* name, Assembler* assembler) |
@@ -338,16 +358,87 @@ class AssemblerTest { |
const Code& code() const { return code_; } |
- uword entry() const { return entry_; } |
+ uword entry() const { return code_.EntryPoint(); } |
+ |
+ // Invoke is used to call assembler test functions using the ABI calling |
+ // convention. |
+ // ResultType is the return type of the assembler test function. |
+ // ArgNType is the type of the Nth argument. |
+#if defined(USING_SIMULATOR) |
+ |
+#if defined(ARCH_IS_64_BIT) |
+ // TODO(fschneider): Make Invoke<> more general and work on 32-bit platforms. |
+ // Since Simulator::Call always return a int64_t, bit_cast does not work |
+ // on 32-bit platforms when returning an int32_t. Since template functions |
+ // don't support partial specialization, we'd need to introduce a helper |
+ // class to support 32-bit return types. |
+ template<typename ResultType> ResultType Invoke() { |
+ const bool fp_return = is_double<ResultType>::value; |
+ const bool fp_args = false; |
+ return bit_cast<ResultType, int64_t>(Simulator::Current()->Call( |
+ bit_cast<intptr_t, uword>(entry()), 0, 0, 0, 0, fp_return, fp_args)); |
+ } |
+ template<typename ResultType, typename Arg1Type> |
+ ResultType Invoke(Arg1Type arg1) { |
+ const bool fp_return = is_double<ResultType>::value; |
+ const bool fp_args = is_double<Arg1Type>::value; |
+ // TODO(fschneider): Support double arguments for simulator calls. |
+ COMPILE_ASSERT(!fp_args); |
+ return bit_cast<ResultType, int64_t>(Simulator::Current()->Call( |
+ bit_cast<intptr_t, uword>(entry()), |
+ reinterpret_cast<intptr_t>(arg1), |
+ 0, 0, 0, fp_return, fp_args)); |
+ } |
+#endif // ARCH_IS_64_BIT |
+ |
+ template<typename ResultType, |
+ typename Arg1Type, |
+ typename Arg2Type, |
+ typename Arg3Type> |
+ ResultType Invoke(Arg1Type arg1, Arg2Type arg2, Arg3Type arg3) { |
+ // TODO(fschneider): Support double arguments for simulator calls. |
+ COMPILE_ASSERT(is_void<ResultType>::value); |
+ COMPILE_ASSERT(!is_double<Arg1Type>::value); |
+ COMPILE_ASSERT(!is_double<Arg2Type>::value); |
+ COMPILE_ASSERT(!is_double<Arg3Type>::value); |
+ const bool fp_args = false; |
+ const bool fp_return = false; |
+ Simulator::Current()->Call( |
+ bit_cast<intptr_t, uword>(entry()), |
+ reinterpret_cast<intptr_t>(arg1), |
+ reinterpret_cast<intptr_t>(arg2), |
+ reinterpret_cast<intptr_t>(arg3), |
+ 0, fp_return, fp_args); |
+ } |
+#else |
+ template<typename ResultType> ResultType Invoke() { |
+ typedef ResultType (*FunctionType) (); |
+ return reinterpret_cast<FunctionType>(entry())(); |
+ } |
+ |
+ template<typename ResultType, typename Arg1Type> |
+ ResultType Invoke(Arg1Type arg1) { |
+ typedef ResultType (*FunctionType) (Arg1Type); |
+ return reinterpret_cast<FunctionType>(entry())(arg1); |
+ } |
+ |
+ template<typename ResultType, |
+ typename Arg1Type, |
+ typename Arg2Type, |
+ typename Arg3Type> |
+ ResultType Invoke(Arg1Type arg1, Arg2Type arg2, Arg3Type arg3) { |
+ typedef ResultType (*FunctionType) (Arg1Type, Arg2Type, Arg3Type); |
+ return reinterpret_cast<FunctionType>(entry())(arg1, arg2, arg3); |
+ } |
+#endif // USING_SIMULATOR |
- // Assemble test and set code_ and entry_. |
+ // Assemble test and set code_. |
void Assemble(); |
private: |
const char* name_; |
Assembler* assembler_; |
Code& code_; |
- uword entry_; |
DISALLOW_COPY_AND_ASSIGN(AssemblerTest); |
}; |