Index: runtime/vm/unit_test.h |
diff --git a/runtime/vm/unit_test.h b/runtime/vm/unit_test.h |
index 01ba00926e5dbba4eb3a75a2e2a04ec5ed2c76e5..5a22372c96c0e8e3e9c3b57267cbbfd084de7227 100644 |
--- a/runtime/vm/unit_test.h |
+++ b/runtime/vm/unit_test.h |
@@ -321,6 +321,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) |
@@ -337,6 +357,64 @@ class AssemblerTest { |
const Code& code() const { return code_; } |
uword entry() const { return entry_; } |
+#if defined(USING_SIMULATOR) |
zra
2015/08/11 19:48:17
Please add comments here about how to use Invoke()
Florian Schneider
2015/08/12 07:30:53
If you happen to write a test that requires a new
zra
2015/08/17 16:35:43
Template errors from the compiler are hard to read
|
+ template<typename ResultType> ResultType Invoke() { |
+ const bool fp_return = is_double<ResultType>::value; |
+ COMPILE_ASSERT(!fp_return); |
+ const bool fp_args = false; |
+ return static_cast<ResultType>(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; |
+ COMPILE_ASSERT(!fp_return); |
+ const bool fp_args = false; |
+ COMPILE_ASSERT(!is_double<Arg1Type>::value); |
+ return static_cast<ResultType>(Simulator::Current()->Call( |
+ bit_cast<intptr_t, uword>(entry()), |
+ reinterpret_cast<intptr_t>(arg1), |
+ 0, 0, 0, fp_return, fp_args)); |
+ } |
+ template<typename ResultType, |
+ typename Arg1Type, |
+ typename Arg2Type, |
+ typename Arg3Type> |
+ ResultType Invoke(Arg1Type arg1, Arg2Type arg2, Arg3Type arg3) { |
+ COMPILE_ASSERT(is_void<ResultType>::value); |
+ const bool fp_return = false; |
+ COMPILE_ASSERT(!is_double<Arg1Type>::value); |
+ COMPILE_ASSERT(!is_double<Arg2Type>::value); |
+ COMPILE_ASSERT(!is_double<Arg3Type>::value); |
+ const bool fp_args = false; |
+ return static_cast<ResultType>(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 |
// Assemble test and set code_ and entry_. |
void Assemble(); |