blob: fa2f1e5793093dc3ce796a012abf6d253fd83b26 [file] [log] [blame]
Ian Rogers53b8b092014-03-13 23:45:53 -07001/*
2 * Copyright (C) 2011 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#include "reflection.h"
18
Brian Carlstrom8edba0b2014-03-14 16:11:43 -070019#include <float.h>
Ian Rogers88e46a32014-03-14 14:37:59 -070020#include <limits.h>
Ian Rogers53b8b092014-03-13 23:45:53 -070021
Mathieu Chartiere401d142015-04-22 13:56:20 -070022#include "art_method-inl.h"
Andreas Gampe542451c2016-07-26 09:02:02 -070023#include "base/enums.h"
Ian Rogers53b8b092014-03-13 23:45:53 -070024#include "common_compiler_test.h"
Andreas Gampec15a2f42017-04-21 12:09:39 -070025#include "java_vm_ext.h"
Andreas Gampe13b27842016-11-07 16:48:23 -080026#include "jni_internal.h"
Steven Morelande431e272017-07-18 16:53:49 -070027#include "nativehelper/ScopedLocalRef.h"
Mathieu Chartier0795f232016-09-27 18:43:30 -070028#include "scoped_thread_state_change-inl.h"
Ian Rogers53b8b092014-03-13 23:45:53 -070029
30namespace art {
31
32// TODO: Convert to CommonRuntimeTest. Currently MakeExecutable is used.
33class ReflectionTest : public CommonCompilerTest {
34 protected:
35 virtual void SetUp() {
36 CommonCompilerTest::SetUp();
37
38 vm_ = Runtime::Current()->GetJavaVM();
39
40 // Turn on -verbose:jni for the JNI tests.
41 // gLogVerbosity.jni = true;
42
Mathieu Chartier2cebb242015-04-21 16:50:40 -070043 vm_->AttachCurrentThread(&env_, nullptr);
Ian Rogers53b8b092014-03-13 23:45:53 -070044
45 ScopedLocalRef<jclass> aioobe(env_,
46 env_->FindClass("java/lang/ArrayIndexOutOfBoundsException"));
Mathieu Chartier2cebb242015-04-21 16:50:40 -070047 CHECK(aioobe.get() != nullptr);
Ian Rogers53b8b092014-03-13 23:45:53 -070048 aioobe_ = reinterpret_cast<jclass>(env_->NewGlobalRef(aioobe.get()));
49
50 ScopedLocalRef<jclass> ase(env_, env_->FindClass("java/lang/ArrayStoreException"));
Mathieu Chartier2cebb242015-04-21 16:50:40 -070051 CHECK(ase.get() != nullptr);
Ian Rogers53b8b092014-03-13 23:45:53 -070052 ase_ = reinterpret_cast<jclass>(env_->NewGlobalRef(ase.get()));
53
54 ScopedLocalRef<jclass> sioobe(env_,
55 env_->FindClass("java/lang/StringIndexOutOfBoundsException"));
Mathieu Chartier2cebb242015-04-21 16:50:40 -070056 CHECK(sioobe.get() != nullptr);
Ian Rogers53b8b092014-03-13 23:45:53 -070057 sioobe_ = reinterpret_cast<jclass>(env_->NewGlobalRef(sioobe.get()));
58 }
59
60 void CleanUpJniEnv() {
Mathieu Chartier2cebb242015-04-21 16:50:40 -070061 if (aioobe_ != nullptr) {
Ian Rogers53b8b092014-03-13 23:45:53 -070062 env_->DeleteGlobalRef(aioobe_);
Mathieu Chartier2cebb242015-04-21 16:50:40 -070063 aioobe_ = nullptr;
Ian Rogers53b8b092014-03-13 23:45:53 -070064 }
Mathieu Chartier2cebb242015-04-21 16:50:40 -070065 if (ase_ != nullptr) {
Ian Rogers53b8b092014-03-13 23:45:53 -070066 env_->DeleteGlobalRef(ase_);
Mathieu Chartier2cebb242015-04-21 16:50:40 -070067 ase_ = nullptr;
Ian Rogers53b8b092014-03-13 23:45:53 -070068 }
Mathieu Chartier2cebb242015-04-21 16:50:40 -070069 if (sioobe_ != nullptr) {
Ian Rogers53b8b092014-03-13 23:45:53 -070070 env_->DeleteGlobalRef(sioobe_);
Mathieu Chartier2cebb242015-04-21 16:50:40 -070071 sioobe_ = nullptr;
Ian Rogers53b8b092014-03-13 23:45:53 -070072 }
73 }
74
75 virtual void TearDown() {
76 CleanUpJniEnv();
77 CommonCompilerTest::TearDown();
78 }
79
80 jclass GetPrimitiveClass(char descriptor) {
81 ScopedObjectAccess soa(env_);
82 mirror::Class* c = class_linker_->FindPrimitiveClass(descriptor);
83 CHECK(c != nullptr);
84 return soa.AddLocalReference<jclass>(c);
85 }
86
Mathieu Chartiere401d142015-04-22 13:56:20 -070087 void ReflectionTestMakeExecutable(ArtMethod** method,
Mathieu Chartier28bd2e42016-10-04 13:54:57 -070088 ObjPtr<mirror::Object>* receiver,
89 bool is_static,
90 const char* method_name,
Ian Rogers53b8b092014-03-13 23:45:53 -070091 const char* method_signature)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -070092 REQUIRES_SHARED(Locks::mutator_lock_) {
Ian Rogers53b8b092014-03-13 23:45:53 -070093 const char* class_name = is_static ? "StaticLeafMethods" : "NonStaticLeafMethods";
94 jobject jclass_loader(LoadDex(class_name));
95 Thread* self = Thread::Current();
Mathieu Chartier28bd2e42016-10-04 13:54:57 -070096 StackHandleScope<3> hs(self);
Mathieu Chartiereb8167a2014-05-07 15:43:14 -070097 Handle<mirror::ClassLoader> class_loader(
98 hs.NewHandle(
Mathieu Chartier0795f232016-09-27 18:43:30 -070099 ScopedObjectAccessUnchecked(self).Decode<mirror::ClassLoader>(jclass_loader)));
100 if (!is_static) {
Ian Rogers53b8b092014-03-13 23:45:53 -0700101 MakeExecutable(nullptr, "java.lang.Class");
102 MakeExecutable(nullptr, "java.lang.Object");
Ian Rogers53b8b092014-03-13 23:45:53 -0700103 }
Mathieu Chartier0795f232016-09-27 18:43:30 -0700104 MakeExecutable(class_loader.Get(), class_name);
Ian Rogers53b8b092014-03-13 23:45:53 -0700105
Mathieu Chartier28bd2e42016-10-04 13:54:57 -0700106 ObjPtr<mirror::Class> c = class_linker_->FindClass(self,
107 DotToDescriptor(class_name).c_str(),
108 class_loader);
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700109 CHECK(c != nullptr);
Ian Rogers53b8b092014-03-13 23:45:53 -0700110
Vladimir Markoba118822017-06-12 15:41:56 +0100111 *method = c->FindClassMethod(method_name, method_signature, kRuntimePointerSize);
112 CHECK(*method != nullptr);
113 CHECK_EQ(is_static, (*method)->IsStatic());
Ian Rogers53b8b092014-03-13 23:45:53 -0700114
Sebastien Hertz4e99b3d2014-06-24 14:35:40 +0200115 if (is_static) {
116 *receiver = nullptr;
117 } else {
118 // Ensure class is initialized before allocating object
Mathieu Chartier28bd2e42016-10-04 13:54:57 -0700119 {
120 StackHandleScope<1> hs2(self);
121 HandleWrapperObjPtr<mirror::Class> h_class(hs2.NewHandleWrapper(&c));
122 bool initialized = class_linker_->EnsureInitialized(self, h_class, true, true);
123 CHECK(initialized);
124 }
Sebastien Hertz4e99b3d2014-06-24 14:35:40 +0200125 *receiver = c->AllocObject(self);
126 }
Ian Rogers53b8b092014-03-13 23:45:53 -0700127
128 // Start runtime.
Mathieu Chartier28bd2e42016-10-04 13:54:57 -0700129 HandleWrapperObjPtr<mirror::Object> h(hs.NewHandleWrapper(receiver));
Ian Rogers53b8b092014-03-13 23:45:53 -0700130 bool started = runtime_->Start();
131 CHECK(started);
132 self->TransitionFromSuspendedToRunnable();
133 }
134
135 void InvokeNopMethod(bool is_static) {
136 ScopedObjectAccess soa(env_);
Mathieu Chartiere401d142015-04-22 13:56:20 -0700137 ArtMethod* method;
Mathieu Chartier28bd2e42016-10-04 13:54:57 -0700138 ObjPtr<mirror::Object> receiver;
Ian Rogers53b8b092014-03-13 23:45:53 -0700139 ReflectionTestMakeExecutable(&method, &receiver, is_static, "nop", "()V");
Jeff Hao39b6c242015-05-19 20:30:23 -0700140 ScopedLocalRef<jobject> receiver_ref(soa.Env(), soa.AddLocalReference<jobject>(receiver));
Andreas Gampe13b27842016-11-07 16:48:23 -0800141 InvokeWithJValues(soa, receiver_ref.get(), jni::EncodeArtMethod(method), nullptr);
Ian Rogers53b8b092014-03-13 23:45:53 -0700142 }
143
144 void InvokeIdentityByteMethod(bool is_static) {
145 ScopedObjectAccess soa(env_);
Mathieu Chartiere401d142015-04-22 13:56:20 -0700146 ArtMethod* method;
Mathieu Chartier28bd2e42016-10-04 13:54:57 -0700147 ObjPtr<mirror::Object> receiver;
Ian Rogers53b8b092014-03-13 23:45:53 -0700148 ReflectionTestMakeExecutable(&method, &receiver, is_static, "identity", "(B)B");
Jeff Hao39b6c242015-05-19 20:30:23 -0700149 ScopedLocalRef<jobject> receiver_ref(soa.Env(), soa.AddLocalReference<jobject>(receiver));
Ian Rogers53b8b092014-03-13 23:45:53 -0700150 jvalue args[1];
151
152 args[0].b = 0;
Andreas Gampe13b27842016-11-07 16:48:23 -0800153 JValue result = InvokeWithJValues(soa, receiver_ref.get(), jni::EncodeArtMethod(method), args);
Ian Rogers53b8b092014-03-13 23:45:53 -0700154 EXPECT_EQ(0, result.GetB());
155
156 args[0].b = -1;
Andreas Gampe13b27842016-11-07 16:48:23 -0800157 result = InvokeWithJValues(soa, receiver_ref.get(), jni::EncodeArtMethod(method), args);
Ian Rogers53b8b092014-03-13 23:45:53 -0700158 EXPECT_EQ(-1, result.GetB());
159
160 args[0].b = SCHAR_MAX;
Andreas Gampe13b27842016-11-07 16:48:23 -0800161 result = InvokeWithJValues(soa, receiver_ref.get(), jni::EncodeArtMethod(method), args);
Ian Rogers53b8b092014-03-13 23:45:53 -0700162 EXPECT_EQ(SCHAR_MAX, result.GetB());
163
Andreas Gampe58554b72015-10-20 21:08:52 -0700164 static_assert(SCHAR_MIN == -128, "SCHAR_MIN unexpected");
165 args[0].b = SCHAR_MIN;
Andreas Gampe13b27842016-11-07 16:48:23 -0800166 result = InvokeWithJValues(soa, receiver_ref.get(), jni::EncodeArtMethod(method), args);
Ian Rogers53b8b092014-03-13 23:45:53 -0700167 EXPECT_EQ(SCHAR_MIN, result.GetB());
168 }
169
170 void InvokeIdentityIntMethod(bool is_static) {
171 ScopedObjectAccess soa(env_);
Mathieu Chartiere401d142015-04-22 13:56:20 -0700172 ArtMethod* method;
Mathieu Chartier28bd2e42016-10-04 13:54:57 -0700173 ObjPtr<mirror::Object> receiver;
Ian Rogers53b8b092014-03-13 23:45:53 -0700174 ReflectionTestMakeExecutable(&method, &receiver, is_static, "identity", "(I)I");
Jeff Hao39b6c242015-05-19 20:30:23 -0700175 ScopedLocalRef<jobject> receiver_ref(soa.Env(), soa.AddLocalReference<jobject>(receiver));
Ian Rogers53b8b092014-03-13 23:45:53 -0700176 jvalue args[1];
177
178 args[0].i = 0;
Andreas Gampe13b27842016-11-07 16:48:23 -0800179 JValue result = InvokeWithJValues(soa, receiver_ref.get(), jni::EncodeArtMethod(method), args);
Ian Rogers53b8b092014-03-13 23:45:53 -0700180 EXPECT_EQ(0, result.GetI());
181
182 args[0].i = -1;
Andreas Gampe13b27842016-11-07 16:48:23 -0800183 result = InvokeWithJValues(soa, receiver_ref.get(), jni::EncodeArtMethod(method), args);
Ian Rogers53b8b092014-03-13 23:45:53 -0700184 EXPECT_EQ(-1, result.GetI());
185
186 args[0].i = INT_MAX;
Andreas Gampe13b27842016-11-07 16:48:23 -0800187 result = InvokeWithJValues(soa, receiver_ref.get(), jni::EncodeArtMethod(method), args);
Ian Rogers53b8b092014-03-13 23:45:53 -0700188 EXPECT_EQ(INT_MAX, result.GetI());
189
190 args[0].i = INT_MIN;
Andreas Gampe13b27842016-11-07 16:48:23 -0800191 result = InvokeWithJValues(soa, receiver_ref.get(), jni::EncodeArtMethod(method), args);
Ian Rogers53b8b092014-03-13 23:45:53 -0700192 EXPECT_EQ(INT_MIN, result.GetI());
193 }
194
195 void InvokeIdentityDoubleMethod(bool is_static) {
196 ScopedObjectAccess soa(env_);
Mathieu Chartiere401d142015-04-22 13:56:20 -0700197 ArtMethod* method;
Mathieu Chartier28bd2e42016-10-04 13:54:57 -0700198 ObjPtr<mirror::Object> receiver;
Ian Rogers53b8b092014-03-13 23:45:53 -0700199 ReflectionTestMakeExecutable(&method, &receiver, is_static, "identity", "(D)D");
Jeff Hao39b6c242015-05-19 20:30:23 -0700200 ScopedLocalRef<jobject> receiver_ref(soa.Env(), soa.AddLocalReference<jobject>(receiver));
Ian Rogers53b8b092014-03-13 23:45:53 -0700201 jvalue args[1];
202
203 args[0].d = 0.0;
Andreas Gampe13b27842016-11-07 16:48:23 -0800204 JValue result = InvokeWithJValues(soa, receiver_ref.get(), jni::EncodeArtMethod(method), args);
Ian Rogers647b1a82014-10-10 11:02:11 -0700205 EXPECT_DOUBLE_EQ(0.0, result.GetD());
Ian Rogers53b8b092014-03-13 23:45:53 -0700206
207 args[0].d = -1.0;
Andreas Gampe13b27842016-11-07 16:48:23 -0800208 result = InvokeWithJValues(soa, receiver_ref.get(), jni::EncodeArtMethod(method), args);
Ian Rogers647b1a82014-10-10 11:02:11 -0700209 EXPECT_DOUBLE_EQ(-1.0, result.GetD());
Ian Rogers53b8b092014-03-13 23:45:53 -0700210
211 args[0].d = DBL_MAX;
Andreas Gampe13b27842016-11-07 16:48:23 -0800212 result = InvokeWithJValues(soa, receiver_ref.get(), jni::EncodeArtMethod(method), args);
Ian Rogers647b1a82014-10-10 11:02:11 -0700213 EXPECT_DOUBLE_EQ(DBL_MAX, result.GetD());
Ian Rogers53b8b092014-03-13 23:45:53 -0700214
215 args[0].d = DBL_MIN;
Andreas Gampe13b27842016-11-07 16:48:23 -0800216 result = InvokeWithJValues(soa, receiver_ref.get(), jni::EncodeArtMethod(method), args);
Ian Rogers647b1a82014-10-10 11:02:11 -0700217 EXPECT_DOUBLE_EQ(DBL_MIN, result.GetD());
Ian Rogers53b8b092014-03-13 23:45:53 -0700218 }
219
220 void InvokeSumIntIntMethod(bool is_static) {
221 ScopedObjectAccess soa(env_);
Mathieu Chartiere401d142015-04-22 13:56:20 -0700222 ArtMethod* method;
Mathieu Chartier28bd2e42016-10-04 13:54:57 -0700223 ObjPtr<mirror::Object> receiver;
Ian Rogers53b8b092014-03-13 23:45:53 -0700224 ReflectionTestMakeExecutable(&method, &receiver, is_static, "sum", "(II)I");
Jeff Hao39b6c242015-05-19 20:30:23 -0700225 ScopedLocalRef<jobject> receiver_ref(soa.Env(), soa.AddLocalReference<jobject>(receiver));
Ian Rogers53b8b092014-03-13 23:45:53 -0700226 jvalue args[2];
227
228 args[0].i = 1;
229 args[1].i = 2;
Andreas Gampe13b27842016-11-07 16:48:23 -0800230 JValue result = InvokeWithJValues(soa, receiver_ref.get(), jni::EncodeArtMethod(method), args);
Ian Rogers53b8b092014-03-13 23:45:53 -0700231 EXPECT_EQ(3, result.GetI());
232
233 args[0].i = -2;
234 args[1].i = 5;
Andreas Gampe13b27842016-11-07 16:48:23 -0800235 result = InvokeWithJValues(soa, receiver_ref.get(), jni::EncodeArtMethod(method), args);
Ian Rogers53b8b092014-03-13 23:45:53 -0700236 EXPECT_EQ(3, result.GetI());
237
238 args[0].i = INT_MAX;
239 args[1].i = INT_MIN;
Andreas Gampe13b27842016-11-07 16:48:23 -0800240 result = InvokeWithJValues(soa, receiver_ref.get(), jni::EncodeArtMethod(method), args);
Ian Rogers53b8b092014-03-13 23:45:53 -0700241 EXPECT_EQ(-1, result.GetI());
242
243 args[0].i = INT_MAX;
244 args[1].i = INT_MAX;
Andreas Gampe13b27842016-11-07 16:48:23 -0800245 result = InvokeWithJValues(soa, receiver_ref.get(), jni::EncodeArtMethod(method), args);
Ian Rogers53b8b092014-03-13 23:45:53 -0700246 EXPECT_EQ(-2, result.GetI());
247 }
248
249 void InvokeSumIntIntIntMethod(bool is_static) {
250 ScopedObjectAccess soa(env_);
Mathieu Chartiere401d142015-04-22 13:56:20 -0700251 ArtMethod* method;
Mathieu Chartier28bd2e42016-10-04 13:54:57 -0700252 ObjPtr<mirror::Object> receiver;
Ian Rogers53b8b092014-03-13 23:45:53 -0700253 ReflectionTestMakeExecutable(&method, &receiver, is_static, "sum", "(III)I");
Jeff Hao39b6c242015-05-19 20:30:23 -0700254 ScopedLocalRef<jobject> receiver_ref(soa.Env(), soa.AddLocalReference<jobject>(receiver));
Ian Rogers53b8b092014-03-13 23:45:53 -0700255 jvalue args[3];
256
257 args[0].i = 0;
258 args[1].i = 0;
259 args[2].i = 0;
Andreas Gampe13b27842016-11-07 16:48:23 -0800260 JValue result = InvokeWithJValues(soa, receiver_ref.get(), jni::EncodeArtMethod(method), args);
Ian Rogers53b8b092014-03-13 23:45:53 -0700261 EXPECT_EQ(0, result.GetI());
262
263 args[0].i = 1;
264 args[1].i = 2;
265 args[2].i = 3;
Andreas Gampe13b27842016-11-07 16:48:23 -0800266 result = InvokeWithJValues(soa, receiver_ref.get(), jni::EncodeArtMethod(method), args);
Ian Rogers53b8b092014-03-13 23:45:53 -0700267 EXPECT_EQ(6, result.GetI());
268
269 args[0].i = -1;
270 args[1].i = 2;
271 args[2].i = -3;
Andreas Gampe13b27842016-11-07 16:48:23 -0800272 result = InvokeWithJValues(soa, receiver_ref.get(), jni::EncodeArtMethod(method), args);
Ian Rogers53b8b092014-03-13 23:45:53 -0700273 EXPECT_EQ(-2, result.GetI());
274
275 args[0].i = INT_MAX;
276 args[1].i = INT_MIN;
277 args[2].i = INT_MAX;
Andreas Gampe13b27842016-11-07 16:48:23 -0800278 result = InvokeWithJValues(soa, receiver_ref.get(), jni::EncodeArtMethod(method), args);
Ian Rogers53b8b092014-03-13 23:45:53 -0700279 EXPECT_EQ(2147483646, result.GetI());
280
281 args[0].i = INT_MAX;
282 args[1].i = INT_MAX;
283 args[2].i = INT_MAX;
Andreas Gampe13b27842016-11-07 16:48:23 -0800284 result = InvokeWithJValues(soa, receiver_ref.get(), jni::EncodeArtMethod(method), args);
Ian Rogers53b8b092014-03-13 23:45:53 -0700285 EXPECT_EQ(2147483645, result.GetI());
286 }
287
288 void InvokeSumIntIntIntIntMethod(bool is_static) {
289 ScopedObjectAccess soa(env_);
Mathieu Chartiere401d142015-04-22 13:56:20 -0700290 ArtMethod* method;
Mathieu Chartier28bd2e42016-10-04 13:54:57 -0700291 ObjPtr<mirror::Object> receiver;
Ian Rogers53b8b092014-03-13 23:45:53 -0700292 ReflectionTestMakeExecutable(&method, &receiver, is_static, "sum", "(IIII)I");
Jeff Hao39b6c242015-05-19 20:30:23 -0700293 ScopedLocalRef<jobject> receiver_ref(soa.Env(), soa.AddLocalReference<jobject>(receiver));
Ian Rogers53b8b092014-03-13 23:45:53 -0700294 jvalue args[4];
295
296 args[0].i = 0;
297 args[1].i = 0;
298 args[2].i = 0;
299 args[3].i = 0;
Andreas Gampe13b27842016-11-07 16:48:23 -0800300 JValue result = InvokeWithJValues(soa, receiver_ref.get(), jni::EncodeArtMethod(method), args);
Ian Rogers53b8b092014-03-13 23:45:53 -0700301 EXPECT_EQ(0, result.GetI());
302
303 args[0].i = 1;
304 args[1].i = 2;
305 args[2].i = 3;
306 args[3].i = 4;
Andreas Gampe13b27842016-11-07 16:48:23 -0800307 result = InvokeWithJValues(soa, receiver_ref.get(), jni::EncodeArtMethod(method), args);
Ian Rogers53b8b092014-03-13 23:45:53 -0700308 EXPECT_EQ(10, result.GetI());
309
310 args[0].i = -1;
311 args[1].i = 2;
312 args[2].i = -3;
313 args[3].i = 4;
Andreas Gampe13b27842016-11-07 16:48:23 -0800314 result = InvokeWithJValues(soa, receiver_ref.get(), jni::EncodeArtMethod(method), args);
Ian Rogers53b8b092014-03-13 23:45:53 -0700315 EXPECT_EQ(2, result.GetI());
316
317 args[0].i = INT_MAX;
318 args[1].i = INT_MIN;
319 args[2].i = INT_MAX;
320 args[3].i = INT_MIN;
Andreas Gampe13b27842016-11-07 16:48:23 -0800321 result = InvokeWithJValues(soa, receiver_ref.get(), jni::EncodeArtMethod(method), args);
Ian Rogers53b8b092014-03-13 23:45:53 -0700322 EXPECT_EQ(-2, result.GetI());
323
324 args[0].i = INT_MAX;
325 args[1].i = INT_MAX;
326 args[2].i = INT_MAX;
327 args[3].i = INT_MAX;
Andreas Gampe13b27842016-11-07 16:48:23 -0800328 result = InvokeWithJValues(soa, receiver_ref.get(), jni::EncodeArtMethod(method), args);
Ian Rogers53b8b092014-03-13 23:45:53 -0700329 EXPECT_EQ(-4, result.GetI());
330 }
331
332 void InvokeSumIntIntIntIntIntMethod(bool is_static) {
333 ScopedObjectAccess soa(env_);
Mathieu Chartiere401d142015-04-22 13:56:20 -0700334 ArtMethod* method;
Mathieu Chartier28bd2e42016-10-04 13:54:57 -0700335 ObjPtr<mirror::Object> receiver;
Ian Rogers53b8b092014-03-13 23:45:53 -0700336 ReflectionTestMakeExecutable(&method, &receiver, is_static, "sum", "(IIIII)I");
Jeff Hao39b6c242015-05-19 20:30:23 -0700337 ScopedLocalRef<jobject> receiver_ref(soa.Env(), soa.AddLocalReference<jobject>(receiver));
Ian Rogers53b8b092014-03-13 23:45:53 -0700338 jvalue args[5];
339
340 args[0].i = 0;
341 args[1].i = 0;
342 args[2].i = 0;
343 args[3].i = 0;
344 args[4].i = 0;
Andreas Gampe13b27842016-11-07 16:48:23 -0800345 JValue result = InvokeWithJValues(soa, receiver_ref.get(), jni::EncodeArtMethod(method), args);
Ian Rogers53b8b092014-03-13 23:45:53 -0700346 EXPECT_EQ(0, result.GetI());
347
348 args[0].i = 1;
349 args[1].i = 2;
350 args[2].i = 3;
351 args[3].i = 4;
352 args[4].i = 5;
Andreas Gampe13b27842016-11-07 16:48:23 -0800353 result = InvokeWithJValues(soa, receiver_ref.get(), jni::EncodeArtMethod(method), args);
Ian Rogers53b8b092014-03-13 23:45:53 -0700354 EXPECT_EQ(15, result.GetI());
355
356 args[0].i = -1;
357 args[1].i = 2;
358 args[2].i = -3;
359 args[3].i = 4;
360 args[4].i = -5;
Andreas Gampe13b27842016-11-07 16:48:23 -0800361 result = InvokeWithJValues(soa, receiver_ref.get(), jni::EncodeArtMethod(method), args);
Ian Rogers53b8b092014-03-13 23:45:53 -0700362 EXPECT_EQ(-3, result.GetI());
363
364 args[0].i = INT_MAX;
365 args[1].i = INT_MIN;
366 args[2].i = INT_MAX;
367 args[3].i = INT_MIN;
368 args[4].i = INT_MAX;
Andreas Gampe13b27842016-11-07 16:48:23 -0800369 result = InvokeWithJValues(soa, receiver_ref.get(), jni::EncodeArtMethod(method), args);
Ian Rogers53b8b092014-03-13 23:45:53 -0700370 EXPECT_EQ(2147483645, result.GetI());
371
372 args[0].i = INT_MAX;
373 args[1].i = INT_MAX;
374 args[2].i = INT_MAX;
375 args[3].i = INT_MAX;
376 args[4].i = INT_MAX;
Andreas Gampe13b27842016-11-07 16:48:23 -0800377 result = InvokeWithJValues(soa, receiver_ref.get(), jni::EncodeArtMethod(method), args);
Ian Rogers53b8b092014-03-13 23:45:53 -0700378 EXPECT_EQ(2147483643, result.GetI());
379 }
380
381 void InvokeSumDoubleDoubleMethod(bool is_static) {
382 ScopedObjectAccess soa(env_);
Mathieu Chartiere401d142015-04-22 13:56:20 -0700383 ArtMethod* method;
Mathieu Chartier28bd2e42016-10-04 13:54:57 -0700384 ObjPtr<mirror::Object> receiver;
Ian Rogers53b8b092014-03-13 23:45:53 -0700385 ReflectionTestMakeExecutable(&method, &receiver, is_static, "sum", "(DD)D");
Jeff Hao39b6c242015-05-19 20:30:23 -0700386 ScopedLocalRef<jobject> receiver_ref(soa.Env(), soa.AddLocalReference<jobject>(receiver));
Ian Rogers53b8b092014-03-13 23:45:53 -0700387 jvalue args[2];
388
389 args[0].d = 0.0;
390 args[1].d = 0.0;
Andreas Gampe13b27842016-11-07 16:48:23 -0800391 JValue result = InvokeWithJValues(soa, receiver_ref.get(), jni::EncodeArtMethod(method), args);
Ian Rogers647b1a82014-10-10 11:02:11 -0700392 EXPECT_DOUBLE_EQ(0.0, result.GetD());
Ian Rogers53b8b092014-03-13 23:45:53 -0700393
394 args[0].d = 1.0;
395 args[1].d = 2.0;
Andreas Gampe13b27842016-11-07 16:48:23 -0800396 result = InvokeWithJValues(soa, receiver_ref.get(), jni::EncodeArtMethod(method), args);
Ian Rogers647b1a82014-10-10 11:02:11 -0700397 EXPECT_DOUBLE_EQ(3.0, result.GetD());
Ian Rogers53b8b092014-03-13 23:45:53 -0700398
399 args[0].d = 1.0;
400 args[1].d = -2.0;
Andreas Gampe13b27842016-11-07 16:48:23 -0800401 result = InvokeWithJValues(soa, receiver_ref.get(), jni::EncodeArtMethod(method), args);
Ian Rogers647b1a82014-10-10 11:02:11 -0700402 EXPECT_DOUBLE_EQ(-1.0, result.GetD());
Ian Rogers53b8b092014-03-13 23:45:53 -0700403
404 args[0].d = DBL_MAX;
405 args[1].d = DBL_MIN;
Andreas Gampe13b27842016-11-07 16:48:23 -0800406 result = InvokeWithJValues(soa, receiver_ref.get(), jni::EncodeArtMethod(method), args);
Ian Rogers647b1a82014-10-10 11:02:11 -0700407 EXPECT_DOUBLE_EQ(1.7976931348623157e308, result.GetD());
Ian Rogers53b8b092014-03-13 23:45:53 -0700408
409 args[0].d = DBL_MAX;
410 args[1].d = DBL_MAX;
Andreas Gampe13b27842016-11-07 16:48:23 -0800411 result = InvokeWithJValues(soa, receiver_ref.get(), jni::EncodeArtMethod(method), args);
Ian Rogers647b1a82014-10-10 11:02:11 -0700412 EXPECT_DOUBLE_EQ(INFINITY, result.GetD());
Ian Rogers53b8b092014-03-13 23:45:53 -0700413 }
414
415 void InvokeSumDoubleDoubleDoubleMethod(bool is_static) {
416 ScopedObjectAccess soa(env_);
Mathieu Chartiere401d142015-04-22 13:56:20 -0700417 ArtMethod* method;
Mathieu Chartier28bd2e42016-10-04 13:54:57 -0700418 ObjPtr<mirror::Object> receiver;
Ian Rogers53b8b092014-03-13 23:45:53 -0700419 ReflectionTestMakeExecutable(&method, &receiver, is_static, "sum", "(DDD)D");
Jeff Hao39b6c242015-05-19 20:30:23 -0700420 ScopedLocalRef<jobject> receiver_ref(soa.Env(), soa.AddLocalReference<jobject>(receiver));
Ian Rogers53b8b092014-03-13 23:45:53 -0700421 jvalue args[3];
422
423 args[0].d = 0.0;
424 args[1].d = 0.0;
425 args[2].d = 0.0;
Andreas Gampe13b27842016-11-07 16:48:23 -0800426 JValue result = InvokeWithJValues(soa, receiver_ref.get(), jni::EncodeArtMethod(method), args);
Ian Rogers647b1a82014-10-10 11:02:11 -0700427 EXPECT_DOUBLE_EQ(0.0, result.GetD());
Ian Rogers53b8b092014-03-13 23:45:53 -0700428
429 args[0].d = 1.0;
430 args[1].d = 2.0;
431 args[2].d = 3.0;
Andreas Gampe13b27842016-11-07 16:48:23 -0800432 result = InvokeWithJValues(soa, receiver_ref.get(), jni::EncodeArtMethod(method), args);
Ian Rogers647b1a82014-10-10 11:02:11 -0700433 EXPECT_DOUBLE_EQ(6.0, result.GetD());
Ian Rogers53b8b092014-03-13 23:45:53 -0700434
435 args[0].d = 1.0;
436 args[1].d = -2.0;
437 args[2].d = 3.0;
Andreas Gampe13b27842016-11-07 16:48:23 -0800438 result = InvokeWithJValues(soa, receiver_ref.get(), jni::EncodeArtMethod(method), args);
Ian Rogers647b1a82014-10-10 11:02:11 -0700439 EXPECT_DOUBLE_EQ(2.0, result.GetD());
Ian Rogers53b8b092014-03-13 23:45:53 -0700440 }
441
442 void InvokeSumDoubleDoubleDoubleDoubleMethod(bool is_static) {
443 ScopedObjectAccess soa(env_);
Mathieu Chartiere401d142015-04-22 13:56:20 -0700444 ArtMethod* method;
Mathieu Chartier28bd2e42016-10-04 13:54:57 -0700445 ObjPtr<mirror::Object> receiver;
Ian Rogers53b8b092014-03-13 23:45:53 -0700446 ReflectionTestMakeExecutable(&method, &receiver, is_static, "sum", "(DDDD)D");
Jeff Hao39b6c242015-05-19 20:30:23 -0700447 ScopedLocalRef<jobject> receiver_ref(soa.Env(), soa.AddLocalReference<jobject>(receiver));
Ian Rogers53b8b092014-03-13 23:45:53 -0700448 jvalue args[4];
449
450 args[0].d = 0.0;
451 args[1].d = 0.0;
452 args[2].d = 0.0;
453 args[3].d = 0.0;
Andreas Gampe13b27842016-11-07 16:48:23 -0800454 JValue result = InvokeWithJValues(soa, receiver_ref.get(), jni::EncodeArtMethod(method), args);
Ian Rogers647b1a82014-10-10 11:02:11 -0700455 EXPECT_DOUBLE_EQ(0.0, result.GetD());
Ian Rogers53b8b092014-03-13 23:45:53 -0700456
457 args[0].d = 1.0;
458 args[1].d = 2.0;
459 args[2].d = 3.0;
460 args[3].d = 4.0;
Andreas Gampe13b27842016-11-07 16:48:23 -0800461 result = InvokeWithJValues(soa, receiver_ref.get(), jni::EncodeArtMethod(method), args);
Ian Rogers647b1a82014-10-10 11:02:11 -0700462 EXPECT_DOUBLE_EQ(10.0, result.GetD());
Ian Rogers53b8b092014-03-13 23:45:53 -0700463
464 args[0].d = 1.0;
465 args[1].d = -2.0;
466 args[2].d = 3.0;
467 args[3].d = -4.0;
Andreas Gampe13b27842016-11-07 16:48:23 -0800468 result = InvokeWithJValues(soa, receiver_ref.get(), jni::EncodeArtMethod(method), args);
Ian Rogers647b1a82014-10-10 11:02:11 -0700469 EXPECT_DOUBLE_EQ(-2.0, result.GetD());
Ian Rogers53b8b092014-03-13 23:45:53 -0700470 }
471
472 void InvokeSumDoubleDoubleDoubleDoubleDoubleMethod(bool is_static) {
473 ScopedObjectAccess soa(env_);
Mathieu Chartiere401d142015-04-22 13:56:20 -0700474 ArtMethod* method;
Mathieu Chartier28bd2e42016-10-04 13:54:57 -0700475 ObjPtr<mirror::Object> receiver;
Ian Rogers53b8b092014-03-13 23:45:53 -0700476 ReflectionTestMakeExecutable(&method, &receiver, is_static, "sum", "(DDDDD)D");
Jeff Hao39b6c242015-05-19 20:30:23 -0700477 ScopedLocalRef<jobject> receiver_ref(soa.Env(), soa.AddLocalReference<jobject>(receiver));
Ian Rogers53b8b092014-03-13 23:45:53 -0700478 jvalue args[5];
479
480 args[0].d = 0.0;
481 args[1].d = 0.0;
482 args[2].d = 0.0;
483 args[3].d = 0.0;
484 args[4].d = 0.0;
Andreas Gampe13b27842016-11-07 16:48:23 -0800485 JValue result = InvokeWithJValues(soa, receiver_ref.get(), jni::EncodeArtMethod(method), args);
Ian Rogers647b1a82014-10-10 11:02:11 -0700486 EXPECT_DOUBLE_EQ(0.0, result.GetD());
Ian Rogers53b8b092014-03-13 23:45:53 -0700487
488 args[0].d = 1.0;
489 args[1].d = 2.0;
490 args[2].d = 3.0;
491 args[3].d = 4.0;
492 args[4].d = 5.0;
Andreas Gampe13b27842016-11-07 16:48:23 -0800493 result = InvokeWithJValues(soa, receiver_ref.get(), jni::EncodeArtMethod(method), args);
Ian Rogers647b1a82014-10-10 11:02:11 -0700494 EXPECT_DOUBLE_EQ(15.0, result.GetD());
Ian Rogers53b8b092014-03-13 23:45:53 -0700495
496 args[0].d = 1.0;
497 args[1].d = -2.0;
498 args[2].d = 3.0;
499 args[3].d = -4.0;
500 args[4].d = 5.0;
Andreas Gampe13b27842016-11-07 16:48:23 -0800501 result = InvokeWithJValues(soa, receiver_ref.get(), jni::EncodeArtMethod(method), args);
Ian Rogers647b1a82014-10-10 11:02:11 -0700502 EXPECT_DOUBLE_EQ(3.0, result.GetD());
Ian Rogers53b8b092014-03-13 23:45:53 -0700503 }
504
505 JavaVMExt* vm_;
506 JNIEnv* env_;
507 jclass aioobe_;
508 jclass ase_;
509 jclass sioobe_;
510};
511
512TEST_F(ReflectionTest, StaticMainMethod) {
Ian Rogers53b8b092014-03-13 23:45:53 -0700513 ScopedObjectAccess soa(Thread::Current());
514 jobject jclass_loader = LoadDex("Main");
Mathieu Chartiereb8167a2014-05-07 15:43:14 -0700515 StackHandleScope<1> hs(soa.Self());
516 Handle<mirror::ClassLoader> class_loader(
Mathieu Chartier0795f232016-09-27 18:43:30 -0700517 hs.NewHandle(soa.Decode<mirror::ClassLoader>(jclass_loader)));
Ian Rogers53b8b092014-03-13 23:45:53 -0700518 CompileDirectMethod(class_loader, "Main", "main", "([Ljava/lang/String;)V");
519
520 mirror::Class* klass = class_linker_->FindClass(soa.Self(), "LMain;", class_loader);
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700521 ASSERT_TRUE(klass != nullptr);
Ian Rogers53b8b092014-03-13 23:45:53 -0700522
Vladimir Markoba118822017-06-12 15:41:56 +0100523 ArtMethod* method = klass->FindClassMethod("main",
524 "([Ljava/lang/String;)V",
525 kRuntimePointerSize);
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700526 ASSERT_TRUE(method != nullptr);
Vladimir Markoba118822017-06-12 15:41:56 +0100527 ASSERT_TRUE(method->IsStatic());
Ian Rogers53b8b092014-03-13 23:45:53 -0700528
529 // Start runtime.
530 bool started = runtime_->Start();
531 CHECK(started);
532 soa.Self()->TransitionFromSuspendedToRunnable();
533
534 jvalue args[1];
535 args[0].l = nullptr;
Andreas Gampe13b27842016-11-07 16:48:23 -0800536 InvokeWithJValues(soa, nullptr, jni::EncodeArtMethod(method), args);
Ian Rogers53b8b092014-03-13 23:45:53 -0700537}
538
539TEST_F(ReflectionTest, StaticNopMethod) {
Ian Rogers53b8b092014-03-13 23:45:53 -0700540 InvokeNopMethod(true);
541}
542
543TEST_F(ReflectionTest, NonStaticNopMethod) {
Ian Rogers53b8b092014-03-13 23:45:53 -0700544 InvokeNopMethod(false);
545}
546
547TEST_F(ReflectionTest, StaticIdentityByteMethod) {
Ian Rogers53b8b092014-03-13 23:45:53 -0700548 InvokeIdentityByteMethod(true);
549}
550
551TEST_F(ReflectionTest, NonStaticIdentityByteMethod) {
Ian Rogers53b8b092014-03-13 23:45:53 -0700552 InvokeIdentityByteMethod(false);
553}
554
555TEST_F(ReflectionTest, StaticIdentityIntMethod) {
Ian Rogers53b8b092014-03-13 23:45:53 -0700556 InvokeIdentityIntMethod(true);
557}
558
559TEST_F(ReflectionTest, NonStaticIdentityIntMethod) {
Ian Rogers53b8b092014-03-13 23:45:53 -0700560 InvokeIdentityIntMethod(false);
561}
562
563TEST_F(ReflectionTest, StaticIdentityDoubleMethod) {
Ian Rogers53b8b092014-03-13 23:45:53 -0700564 InvokeIdentityDoubleMethod(true);
565}
566
567TEST_F(ReflectionTest, NonStaticIdentityDoubleMethod) {
Ian Rogers53b8b092014-03-13 23:45:53 -0700568 InvokeIdentityDoubleMethod(false);
569}
570
571TEST_F(ReflectionTest, StaticSumIntIntMethod) {
Ian Rogers53b8b092014-03-13 23:45:53 -0700572 InvokeSumIntIntMethod(true);
573}
574
575TEST_F(ReflectionTest, NonStaticSumIntIntMethod) {
Ian Rogers53b8b092014-03-13 23:45:53 -0700576 InvokeSumIntIntMethod(false);
577}
578
579TEST_F(ReflectionTest, StaticSumIntIntIntMethod) {
Ian Rogers53b8b092014-03-13 23:45:53 -0700580 InvokeSumIntIntIntMethod(true);
581}
582
583TEST_F(ReflectionTest, NonStaticSumIntIntIntMethod) {
Ian Rogers53b8b092014-03-13 23:45:53 -0700584 InvokeSumIntIntIntMethod(false);
585}
586
587TEST_F(ReflectionTest, StaticSumIntIntIntIntMethod) {
Ian Rogers53b8b092014-03-13 23:45:53 -0700588 InvokeSumIntIntIntIntMethod(true);
589}
590
591TEST_F(ReflectionTest, NonStaticSumIntIntIntIntMethod) {
Ian Rogers53b8b092014-03-13 23:45:53 -0700592 InvokeSumIntIntIntIntMethod(false);
593}
594
595TEST_F(ReflectionTest, StaticSumIntIntIntIntIntMethod) {
Ian Rogers53b8b092014-03-13 23:45:53 -0700596 InvokeSumIntIntIntIntIntMethod(true);
597}
598
599TEST_F(ReflectionTest, NonStaticSumIntIntIntIntIntMethod) {
Ian Rogers53b8b092014-03-13 23:45:53 -0700600 InvokeSumIntIntIntIntIntMethod(false);
601}
602
603TEST_F(ReflectionTest, StaticSumDoubleDoubleMethod) {
Ian Rogers53b8b092014-03-13 23:45:53 -0700604 InvokeSumDoubleDoubleMethod(true);
605}
606
607TEST_F(ReflectionTest, NonStaticSumDoubleDoubleMethod) {
Ian Rogers53b8b092014-03-13 23:45:53 -0700608 InvokeSumDoubleDoubleMethod(false);
609}
610
611TEST_F(ReflectionTest, StaticSumDoubleDoubleDoubleMethod) {
Ian Rogers53b8b092014-03-13 23:45:53 -0700612 InvokeSumDoubleDoubleDoubleMethod(true);
613}
614
615TEST_F(ReflectionTest, NonStaticSumDoubleDoubleDoubleMethod) {
Ian Rogers53b8b092014-03-13 23:45:53 -0700616 InvokeSumDoubleDoubleDoubleMethod(false);
617}
618
619TEST_F(ReflectionTest, StaticSumDoubleDoubleDoubleDoubleMethod) {
Ian Rogers53b8b092014-03-13 23:45:53 -0700620 InvokeSumDoubleDoubleDoubleDoubleMethod(true);
621}
622
623TEST_F(ReflectionTest, NonStaticSumDoubleDoubleDoubleDoubleMethod) {
Ian Rogers53b8b092014-03-13 23:45:53 -0700624 InvokeSumDoubleDoubleDoubleDoubleMethod(false);
625}
626
627TEST_F(ReflectionTest, StaticSumDoubleDoubleDoubleDoubleDoubleMethod) {
Ian Rogers53b8b092014-03-13 23:45:53 -0700628 InvokeSumDoubleDoubleDoubleDoubleDoubleMethod(true);
629}
630
631TEST_F(ReflectionTest, NonStaticSumDoubleDoubleDoubleDoubleDoubleMethod) {
Ian Rogers53b8b092014-03-13 23:45:53 -0700632 InvokeSumDoubleDoubleDoubleDoubleDoubleMethod(false);
633}
634
635} // namespace art