Index: runtime/vm/unit_test.h |
diff --git a/runtime/vm/unit_test.h b/runtime/vm/unit_test.h |
index 01ba00926e5dbba4eb3a75a2e2a04ec5ed2c76e5..cb2feb2110393556eae03adb12d3bfd6ecee0a77 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,59 @@ class AssemblerTest { |
const Code& code() const { return code_; } |
uword entry() const { return entry_; } |
+#if defined(USING_SIMULATOR) |
srdjan
2015/08/10 16:23:51
I am not sure I found this more readable and maint
zra
2015/08/10 16:43:32
This makes writing the assembler tests a bit easie
Florian Schneider
2015/08/11 07:58:28
Yes, I just added the variants necessary.
The comp
Florian Schneider
2015/08/11 07:58:28
There may be even more elegant ways to solve this
|
+ template<typename ResultType> ResultType Invoke() { |
+ const bool fp_return = is_double<ResultType>::value; |
+ const bool fp_args = false; |
+ return static_cast<ResultType>(Simulator::Current()->Call( |
+ bit_cast<int64_t, uword>(entry()), 0, 0, 0, 0, fp_return, fp_args)); |
+ } |
zra
2015/08/10 16:43:32
Missing newline
|
+ template<typename ResultType, typename Arg1Type> |
+ ResultType Invoke(Arg1Type arg1) { |
+ const bool fp_return = is_double<ResultType>::value; |
+ COMPILE_ASSERT(!is_double<Arg1Type>::value); |
+ const bool fp_args = false; |
+ return static_cast<ResultType>(Simulator::Current()->Call( |
+ bit_cast<int64_t, uword>(entry()), reinterpret_cast<int64_t>(arg1), |
+ 0, 0, 0, fp_return, fp_args)); |
+ } |
zra
2015/08/10 16:43:32
Missing newline
Florian Schneider
2015/08/11 07:58:28
Not between template functions
|
+ template<typename ResultType, |
+ typename Arg1Type, |
+ typename Arg2Type, |
+ typename Arg3Type> |
+ ResultType Invoke(Arg1Type arg1, Arg2Type arg2, Arg3Type arg3) { |
zra
2015/08/10 16:43:32
The first two Invokes appear to be used for assemb
Florian Schneider
2015/08/11 07:58:28
This one is used ony for one test right now (Store
|
+ COMPILE_ASSERT(is_void<ResultType>::value); |
+ const bool fp_return = false; |
+ COMPILE_ASSERT(!is_double<Arg1Type>::value); |
+ const bool fp_args = false; |
+ return static_cast<ResultType>(Simulator::Current()->Call( |
+ bit_cast<int64_t, uword>(entry()), |
+ reinterpret_cast<int64_t>(arg1), |
+ reinterpret_cast<int64_t>(arg2), |
+ reinterpret_cast<int64_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); |
zra
2015/08/10 16:43:31
Is there some reason not to have the same asserts
Florian Schneider
2015/08/11 07:58:28
No, regular invocation just works with all types.
zra
2015/08/11 19:48:17
I think it would be good to have consistent behavi
Florian Schneider
2015/08/12 07:30:53
Why add assertions that don't guard against anythi
zra
2015/08/17 16:35:43
The assertions guard against doing something in ar
|
+ 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); |
zra
2015/08/10 16:43:32
Same question.
|
+ return reinterpret_cast<FunctionType>(entry())(arg1, arg2, arg3); |
+ } |
+#endif |
// Assemble test and set code_ and entry_. |
void Assemble(); |