blob: e254dfe627d0190d9fb96f59f87b75a4ba3629ec [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 Rogerse63db272014-07-15 15:36:11 -070021#include "ScopedLocalRef.h"
Ian Rogers53b8b092014-03-13 23:45:53 -070022
Mathieu Chartiere401d142015-04-22 13:56:20 -070023#include "art_method-inl.h"
Andreas Gampe542451c2016-07-26 09:02:02 -070024#include "base/enums.h"
Ian Rogers53b8b092014-03-13 23:45:53 -070025#include "common_compiler_test.h"
Andreas Gampe13b27842016-11-07 16:48:23 -080026#include "jni_internal.h"
Mathieu Chartier0795f232016-09-27 18:43:30 -070027#include "scoped_thread_state_change-inl.h"
Ian Rogers53b8b092014-03-13 23:45:53 -070028
29namespace art {
30
31// TODO: Convert to CommonRuntimeTest. Currently MakeExecutable is used.
32class ReflectionTest : public CommonCompilerTest {
33 protected:
34 virtual void SetUp() {
35 CommonCompilerTest::SetUp();
36
37 vm_ = Runtime::Current()->GetJavaVM();
38
39 // Turn on -verbose:jni for the JNI tests.
40 // gLogVerbosity.jni = true;
41
Mathieu Chartier2cebb242015-04-21 16:50:40 -070042 vm_->AttachCurrentThread(&env_, nullptr);
Ian Rogers53b8b092014-03-13 23:45:53 -070043
44 ScopedLocalRef<jclass> aioobe(env_,
45 env_->FindClass("java/lang/ArrayIndexOutOfBoundsException"));
Mathieu Chartier2cebb242015-04-21 16:50:40 -070046 CHECK(aioobe.get() != nullptr);
Ian Rogers53b8b092014-03-13 23:45:53 -070047 aioobe_ = reinterpret_cast<jclass>(env_->NewGlobalRef(aioobe.get()));
48
49 ScopedLocalRef<jclass> ase(env_, env_->FindClass("java/lang/ArrayStoreException"));
Mathieu Chartier2cebb242015-04-21 16:50:40 -070050 CHECK(ase.get() != nullptr);
Ian Rogers53b8b092014-03-13 23:45:53 -070051 ase_ = reinterpret_cast<jclass>(env_->NewGlobalRef(ase.get()));
52
53 ScopedLocalRef<jclass> sioobe(env_,
54 env_->FindClass("java/lang/StringIndexOutOfBoundsException"));
Mathieu Chartier2cebb242015-04-21 16:50:40 -070055 CHECK(sioobe.get() != nullptr);
Ian Rogers53b8b092014-03-13 23:45:53 -070056 sioobe_ = reinterpret_cast<jclass>(env_->NewGlobalRef(sioobe.get()));
57 }
58
59 void CleanUpJniEnv() {
Mathieu Chartier2cebb242015-04-21 16:50:40 -070060 if (aioobe_ != nullptr) {
Ian Rogers53b8b092014-03-13 23:45:53 -070061 env_->DeleteGlobalRef(aioobe_);
Mathieu Chartier2cebb242015-04-21 16:50:40 -070062 aioobe_ = nullptr;
Ian Rogers53b8b092014-03-13 23:45:53 -070063 }
Mathieu Chartier2cebb242015-04-21 16:50:40 -070064 if (ase_ != nullptr) {
Ian Rogers53b8b092014-03-13 23:45:53 -070065 env_->DeleteGlobalRef(ase_);
Mathieu Chartier2cebb242015-04-21 16:50:40 -070066 ase_ = nullptr;
Ian Rogers53b8b092014-03-13 23:45:53 -070067 }
Mathieu Chartier2cebb242015-04-21 16:50:40 -070068 if (sioobe_ != nullptr) {
Ian Rogers53b8b092014-03-13 23:45:53 -070069 env_->DeleteGlobalRef(sioobe_);
Mathieu Chartier2cebb242015-04-21 16:50:40 -070070 sioobe_ = nullptr;
Ian Rogers53b8b092014-03-13 23:45:53 -070071 }
72 }
73
74 virtual void TearDown() {
75 CleanUpJniEnv();
76 CommonCompilerTest::TearDown();
77 }
78
79 jclass GetPrimitiveClass(char descriptor) {
80 ScopedObjectAccess soa(env_);
81 mirror::Class* c = class_linker_->FindPrimitiveClass(descriptor);
82 CHECK(c != nullptr);
83 return soa.AddLocalReference<jclass>(c);
84 }
85
Mathieu Chartiere401d142015-04-22 13:56:20 -070086 void ReflectionTestMakeExecutable(ArtMethod** method,
Mathieu Chartier28bd2e42016-10-04 13:54:57 -070087 ObjPtr<mirror::Object>* receiver,
88 bool is_static,
89 const char* method_name,
Ian Rogers53b8b092014-03-13 23:45:53 -070090 const char* method_signature)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -070091 REQUIRES_SHARED(Locks::mutator_lock_) {
Ian Rogers53b8b092014-03-13 23:45:53 -070092 const char* class_name = is_static ? "StaticLeafMethods" : "NonStaticLeafMethods";
93 jobject jclass_loader(LoadDex(class_name));
94 Thread* self = Thread::Current();
Mathieu Chartier28bd2e42016-10-04 13:54:57 -070095 StackHandleScope<3> hs(self);
Mathieu Chartiereb8167a2014-05-07 15:43:14 -070096 Handle<mirror::ClassLoader> class_loader(
97 hs.NewHandle(
Mathieu Chartier0795f232016-09-27 18:43:30 -070098 ScopedObjectAccessUnchecked(self).Decode<mirror::ClassLoader>(jclass_loader)));
99 if (!is_static) {
Ian Rogers53b8b092014-03-13 23:45:53 -0700100 MakeExecutable(nullptr, "java.lang.Class");
101 MakeExecutable(nullptr, "java.lang.Object");
Ian Rogers53b8b092014-03-13 23:45:53 -0700102 }
Mathieu Chartier0795f232016-09-27 18:43:30 -0700103 MakeExecutable(class_loader.Get(), class_name);
Ian Rogers53b8b092014-03-13 23:45:53 -0700104
Mathieu Chartier28bd2e42016-10-04 13:54:57 -0700105 ObjPtr<mirror::Class> c = class_linker_->FindClass(self,
106 DotToDescriptor(class_name).c_str(),
107 class_loader);
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700108 CHECK(c != nullptr);
Ian Rogers53b8b092014-03-13 23:45:53 -0700109
Andreas Gampe542451c2016-07-26 09:02:02 -0700110 *method = is_static ? c->FindDirectMethod(method_name, method_signature, kRuntimePointerSize)
111 : c->FindVirtualMethod(method_name, method_signature, kRuntimePointerSize);
Ian Rogers53b8b092014-03-13 23:45:53 -0700112 CHECK(method != nullptr);
113
Sebastien Hertz4e99b3d2014-06-24 14:35:40 +0200114 if (is_static) {
115 *receiver = nullptr;
116 } else {
117 // Ensure class is initialized before allocating object
Mathieu Chartier28bd2e42016-10-04 13:54:57 -0700118 {
119 StackHandleScope<1> hs2(self);
120 HandleWrapperObjPtr<mirror::Class> h_class(hs2.NewHandleWrapper(&c));
121 bool initialized = class_linker_->EnsureInitialized(self, h_class, true, true);
122 CHECK(initialized);
123 }
Sebastien Hertz4e99b3d2014-06-24 14:35:40 +0200124 *receiver = c->AllocObject(self);
125 }
Ian Rogers53b8b092014-03-13 23:45:53 -0700126
127 // Start runtime.
Mathieu Chartier28bd2e42016-10-04 13:54:57 -0700128 HandleWrapperObjPtr<mirror::Object> h(hs.NewHandleWrapper(receiver));
Ian Rogers53b8b092014-03-13 23:45:53 -0700129 bool started = runtime_->Start();
130 CHECK(started);
131 self->TransitionFromSuspendedToRunnable();
132 }
133
134 void InvokeNopMethod(bool is_static) {
135 ScopedObjectAccess soa(env_);
Mathieu Chartiere401d142015-04-22 13:56:20 -0700136 ArtMethod* method;
Mathieu Chartier28bd2e42016-10-04 13:54:57 -0700137 ObjPtr<mirror::Object> receiver;
Ian Rogers53b8b092014-03-13 23:45:53 -0700138 ReflectionTestMakeExecutable(&method, &receiver, is_static, "nop", "()V");
Jeff Hao39b6c242015-05-19 20:30:23 -0700139 ScopedLocalRef<jobject> receiver_ref(soa.Env(), soa.AddLocalReference<jobject>(receiver));
Andreas Gampe13b27842016-11-07 16:48:23 -0800140 InvokeWithJValues(soa, receiver_ref.get(), jni::EncodeArtMethod(method), nullptr);
Ian Rogers53b8b092014-03-13 23:45:53 -0700141 }
142
143 void InvokeIdentityByteMethod(bool is_static) {
144 ScopedObjectAccess soa(env_);
Mathieu Chartiere401d142015-04-22 13:56:20 -0700145 ArtMethod* method;
Mathieu Chartier28bd2e42016-10-04 13:54:57 -0700146 ObjPtr<mirror::Object> receiver;
Ian Rogers53b8b092014-03-13 23:45:53 -0700147 ReflectionTestMakeExecutable(&method, &receiver, is_static, "identity", "(B)B");
Jeff Hao39b6c242015-05-19 20:30:23 -0700148 ScopedLocalRef<jobject> receiver_ref(soa.Env(), soa.AddLocalReference<jobject>(receiver));
Ian Rogers53b8b092014-03-13 23:45:53 -0700149 jvalue args[1];
150
151 args[0].b = 0;
Andreas Gampe13b27842016-11-07 16:48:23 -0800152 JValue result = InvokeWithJValues(soa, receiver_ref.get(), jni::EncodeArtMethod(method), args);
Ian Rogers53b8b092014-03-13 23:45:53 -0700153 EXPECT_EQ(0, result.GetB());
154
155 args[0].b = -1;
Andreas Gampe13b27842016-11-07 16:48:23 -0800156 result = InvokeWithJValues(soa, receiver_ref.get(), jni::EncodeArtMethod(method), args);
Ian Rogers53b8b092014-03-13 23:45:53 -0700157 EXPECT_EQ(-1, result.GetB());
158
159 args[0].b = SCHAR_MAX;
Andreas Gampe13b27842016-11-07 16:48:23 -0800160 result = InvokeWithJValues(soa, receiver_ref.get(), jni::EncodeArtMethod(method), args);
Ian Rogers53b8b092014-03-13 23:45:53 -0700161 EXPECT_EQ(SCHAR_MAX, result.GetB());
162
Andreas Gampe58554b72015-10-20 21:08:52 -0700163 static_assert(SCHAR_MIN == -128, "SCHAR_MIN unexpected");
164 args[0].b = SCHAR_MIN;
Andreas Gampe13b27842016-11-07 16:48:23 -0800165 result = InvokeWithJValues(soa, receiver_ref.get(), jni::EncodeArtMethod(method), args);
Ian Rogers53b8b092014-03-13 23:45:53 -0700166 EXPECT_EQ(SCHAR_MIN, result.GetB());
167 }
168
169 void InvokeIdentityIntMethod(bool is_static) {
170 ScopedObjectAccess soa(env_);
Mathieu Chartiere401d142015-04-22 13:56:20 -0700171 ArtMethod* method;
Mathieu Chartier28bd2e42016-10-04 13:54:57 -0700172 ObjPtr<mirror::Object> receiver;
Ian Rogers53b8b092014-03-13 23:45:53 -0700173 ReflectionTestMakeExecutable(&method, &receiver, is_static, "identity", "(I)I");
Jeff Hao39b6c242015-05-19 20:30:23 -0700174 ScopedLocalRef<jobject> receiver_ref(soa.Env(), soa.AddLocalReference<jobject>(receiver));
Ian Rogers53b8b092014-03-13 23:45:53 -0700175 jvalue args[1];
176
177 args[0].i = 0;
Andreas Gampe13b27842016-11-07 16:48:23 -0800178 JValue result = InvokeWithJValues(soa, receiver_ref.get(), jni::EncodeArtMethod(method), args);
Ian Rogers53b8b092014-03-13 23:45:53 -0700179 EXPECT_EQ(0, result.GetI());
180
181 args[0].i = -1;
Andreas Gampe13b27842016-11-07 16:48:23 -0800182 result = InvokeWithJValues(soa, receiver_ref.get(), jni::EncodeArtMethod(method), args);
Ian Rogers53b8b092014-03-13 23:45:53 -0700183 EXPECT_EQ(-1, result.GetI());
184
185 args[0].i = INT_MAX;
Andreas Gampe13b27842016-11-07 16:48:23 -0800186 result = InvokeWithJValues(soa, receiver_ref.get(), jni::EncodeArtMethod(method), args);
Ian Rogers53b8b092014-03-13 23:45:53 -0700187 EXPECT_EQ(INT_MAX, result.GetI());
188
189 args[0].i = INT_MIN;
Andreas Gampe13b27842016-11-07 16:48:23 -0800190 result = InvokeWithJValues(soa, receiver_ref.get(), jni::EncodeArtMethod(method), args);
Ian Rogers53b8b092014-03-13 23:45:53 -0700191 EXPECT_EQ(INT_MIN, result.GetI());
192 }
193
194 void InvokeIdentityDoubleMethod(bool is_static) {
195 ScopedObjectAccess soa(env_);
Mathieu Chartiere401d142015-04-22 13:56:20 -0700196 ArtMethod* method;
Mathieu Chartier28bd2e42016-10-04 13:54:57 -0700197 ObjPtr<mirror::Object> receiver;
Ian Rogers53b8b092014-03-13 23:45:53 -0700198 ReflectionTestMakeExecutable(&method, &receiver, is_static, "identity", "(D)D");
Jeff Hao39b6c242015-05-19 20:30:23 -0700199 ScopedLocalRef<jobject> receiver_ref(soa.Env(), soa.AddLocalReference<jobject>(receiver));
Ian Rogers53b8b092014-03-13 23:45:53 -0700200 jvalue args[1];
201
202 args[0].d = 0.0;
Andreas Gampe13b27842016-11-07 16:48:23 -0800203 JValue result = InvokeWithJValues(soa, receiver_ref.get(), jni::EncodeArtMethod(method), args);
Ian Rogers647b1a82014-10-10 11:02:11 -0700204 EXPECT_DOUBLE_EQ(0.0, result.GetD());
Ian Rogers53b8b092014-03-13 23:45:53 -0700205
206 args[0].d = -1.0;
Andreas Gampe13b27842016-11-07 16:48:23 -0800207 result = InvokeWithJValues(soa, receiver_ref.get(), jni::EncodeArtMethod(method), args);
Ian Rogers647b1a82014-10-10 11:02:11 -0700208 EXPECT_DOUBLE_EQ(-1.0, result.GetD());
Ian Rogers53b8b092014-03-13 23:45:53 -0700209
210 args[0].d = DBL_MAX;
Andreas Gampe13b27842016-11-07 16:48:23 -0800211 result = InvokeWithJValues(soa, receiver_ref.get(), jni::EncodeArtMethod(method), args);
Ian Rogers647b1a82014-10-10 11:02:11 -0700212 EXPECT_DOUBLE_EQ(DBL_MAX, result.GetD());
Ian Rogers53b8b092014-03-13 23:45:53 -0700213
214 args[0].d = DBL_MIN;
Andreas Gampe13b27842016-11-07 16:48:23 -0800215 result = InvokeWithJValues(soa, receiver_ref.get(), jni::EncodeArtMethod(method), args);
Ian Rogers647b1a82014-10-10 11:02:11 -0700216 EXPECT_DOUBLE_EQ(DBL_MIN, result.GetD());
Ian Rogers53b8b092014-03-13 23:45:53 -0700217 }
218
219 void InvokeSumIntIntMethod(bool is_static) {
220 ScopedObjectAccess soa(env_);
Mathieu Chartiere401d142015-04-22 13:56:20 -0700221 ArtMethod* method;
Mathieu Chartier28bd2e42016-10-04 13:54:57 -0700222 ObjPtr<mirror::Object> receiver;
Ian Rogers53b8b092014-03-13 23:45:53 -0700223 ReflectionTestMakeExecutable(&method, &receiver, is_static, "sum", "(II)I");
Jeff Hao39b6c242015-05-19 20:30:23 -0700224 ScopedLocalRef<jobject> receiver_ref(soa.Env(), soa.AddLocalReference<jobject>(receiver));
Ian Rogers53b8b092014-03-13 23:45:53 -0700225 jvalue args[2];
226
227 args[0].i = 1;
228 args[1].i = 2;
Andreas Gampe13b27842016-11-07 16:48:23 -0800229 JValue result = InvokeWithJValues(soa, receiver_ref.get(), jni::EncodeArtMethod(method), args);
Ian Rogers53b8b092014-03-13 23:45:53 -0700230 EXPECT_EQ(3, result.GetI());
231
232 args[0].i = -2;
233 args[1].i = 5;
Andreas Gampe13b27842016-11-07 16:48:23 -0800234 result = InvokeWithJValues(soa, receiver_ref.get(), jni::EncodeArtMethod(method), args);
Ian Rogers53b8b092014-03-13 23:45:53 -0700235 EXPECT_EQ(3, result.GetI());
236
237 args[0].i = INT_MAX;
238 args[1].i = INT_MIN;
Andreas Gampe13b27842016-11-07 16:48:23 -0800239 result = InvokeWithJValues(soa, receiver_ref.get(), jni::EncodeArtMethod(method), args);
Ian Rogers53b8b092014-03-13 23:45:53 -0700240 EXPECT_EQ(-1, result.GetI());
241
242 args[0].i = INT_MAX;
243 args[1].i = INT_MAX;
Andreas Gampe13b27842016-11-07 16:48:23 -0800244 result = InvokeWithJValues(soa, receiver_ref.get(), jni::EncodeArtMethod(method), args);
Ian Rogers53b8b092014-03-13 23:45:53 -0700245 EXPECT_EQ(-2, result.GetI());
246 }
247
248 void InvokeSumIntIntIntMethod(bool is_static) {
249 ScopedObjectAccess soa(env_);
Mathieu Chartiere401d142015-04-22 13:56:20 -0700250 ArtMethod* method;
Mathieu Chartier28bd2e42016-10-04 13:54:57 -0700251 ObjPtr<mirror::Object> receiver;
Ian Rogers53b8b092014-03-13 23:45:53 -0700252 ReflectionTestMakeExecutable(&method, &receiver, is_static, "sum", "(III)I");
Jeff Hao39b6c242015-05-19 20:30:23 -0700253 ScopedLocalRef<jobject> receiver_ref(soa.Env(), soa.AddLocalReference<jobject>(receiver));
Ian Rogers53b8b092014-03-13 23:45:53 -0700254 jvalue args[3];
255
256 args[0].i = 0;
257 args[1].i = 0;
258 args[2].i = 0;
Andreas Gampe13b27842016-11-07 16:48:23 -0800259 JValue result = InvokeWithJValues(soa, receiver_ref.get(), jni::EncodeArtMethod(method), args);
Ian Rogers53b8b092014-03-13 23:45:53 -0700260 EXPECT_EQ(0, result.GetI());
261
262 args[0].i = 1;
263 args[1].i = 2;
264 args[2].i = 3;
Andreas Gampe13b27842016-11-07 16:48:23 -0800265 result = InvokeWithJValues(soa, receiver_ref.get(), jni::EncodeArtMethod(method), args);
Ian Rogers53b8b092014-03-13 23:45:53 -0700266 EXPECT_EQ(6, result.GetI());
267
268 args[0].i = -1;
269 args[1].i = 2;
270 args[2].i = -3;
Andreas Gampe13b27842016-11-07 16:48:23 -0800271 result = InvokeWithJValues(soa, receiver_ref.get(), jni::EncodeArtMethod(method), args);
Ian Rogers53b8b092014-03-13 23:45:53 -0700272 EXPECT_EQ(-2, result.GetI());
273
274 args[0].i = INT_MAX;
275 args[1].i = INT_MIN;
276 args[2].i = INT_MAX;
Andreas Gampe13b27842016-11-07 16:48:23 -0800277 result = InvokeWithJValues(soa, receiver_ref.get(), jni::EncodeArtMethod(method), args);
Ian Rogers53b8b092014-03-13 23:45:53 -0700278 EXPECT_EQ(2147483646, result.GetI());
279
280 args[0].i = INT_MAX;
281 args[1].i = INT_MAX;
282 args[2].i = INT_MAX;
Andreas Gampe13b27842016-11-07 16:48:23 -0800283 result = InvokeWithJValues(soa, receiver_ref.get(), jni::EncodeArtMethod(method), args);
Ian Rogers53b8b092014-03-13 23:45:53 -0700284 EXPECT_EQ(2147483645, result.GetI());
285 }
286
287 void InvokeSumIntIntIntIntMethod(bool is_static) {
288 ScopedObjectAccess soa(env_);
Mathieu Chartiere401d142015-04-22 13:56:20 -0700289 ArtMethod* method;
Mathieu Chartier28bd2e42016-10-04 13:54:57 -0700290 ObjPtr<mirror::Object> receiver;
Ian Rogers53b8b092014-03-13 23:45:53 -0700291 ReflectionTestMakeExecutable(&method, &receiver, is_static, "sum", "(IIII)I");
Jeff Hao39b6c242015-05-19 20:30:23 -0700292 ScopedLocalRef<jobject> receiver_ref(soa.Env(), soa.AddLocalReference<jobject>(receiver));
Ian Rogers53b8b092014-03-13 23:45:53 -0700293 jvalue args[4];
294
295 args[0].i = 0;
296 args[1].i = 0;
297 args[2].i = 0;
298 args[3].i = 0;
Andreas Gampe13b27842016-11-07 16:48:23 -0800299 JValue result = InvokeWithJValues(soa, receiver_ref.get(), jni::EncodeArtMethod(method), args);
Ian Rogers53b8b092014-03-13 23:45:53 -0700300 EXPECT_EQ(0, result.GetI());
301
302 args[0].i = 1;
303 args[1].i = 2;
304 args[2].i = 3;
305 args[3].i = 4;
Andreas Gampe13b27842016-11-07 16:48:23 -0800306 result = InvokeWithJValues(soa, receiver_ref.get(), jni::EncodeArtMethod(method), args);
Ian Rogers53b8b092014-03-13 23:45:53 -0700307 EXPECT_EQ(10, result.GetI());
308
309 args[0].i = -1;
310 args[1].i = 2;
311 args[2].i = -3;
312 args[3].i = 4;
Andreas Gampe13b27842016-11-07 16:48:23 -0800313 result = InvokeWithJValues(soa, receiver_ref.get(), jni::EncodeArtMethod(method), args);
Ian Rogers53b8b092014-03-13 23:45:53 -0700314 EXPECT_EQ(2, result.GetI());
315
316 args[0].i = INT_MAX;
317 args[1].i = INT_MIN;
318 args[2].i = INT_MAX;
319 args[3].i = INT_MIN;
Andreas Gampe13b27842016-11-07 16:48:23 -0800320 result = InvokeWithJValues(soa, receiver_ref.get(), jni::EncodeArtMethod(method), args);
Ian Rogers53b8b092014-03-13 23:45:53 -0700321 EXPECT_EQ(-2, result.GetI());
322
323 args[0].i = INT_MAX;
324 args[1].i = INT_MAX;
325 args[2].i = INT_MAX;
326 args[3].i = INT_MAX;
Andreas Gampe13b27842016-11-07 16:48:23 -0800327 result = InvokeWithJValues(soa, receiver_ref.get(), jni::EncodeArtMethod(method), args);
Ian Rogers53b8b092014-03-13 23:45:53 -0700328 EXPECT_EQ(-4, result.GetI());
329 }
330
331 void InvokeSumIntIntIntIntIntMethod(bool is_static) {
332 ScopedObjectAccess soa(env_);
Mathieu Chartiere401d142015-04-22 13:56:20 -0700333 ArtMethod* method;
Mathieu Chartier28bd2e42016-10-04 13:54:57 -0700334 ObjPtr<mirror::Object> receiver;
Ian Rogers53b8b092014-03-13 23:45:53 -0700335 ReflectionTestMakeExecutable(&method, &receiver, is_static, "sum", "(IIIII)I");
Jeff Hao39b6c242015-05-19 20:30:23 -0700336 ScopedLocalRef<jobject> receiver_ref(soa.Env(), soa.AddLocalReference<jobject>(receiver));
Ian Rogers53b8b092014-03-13 23:45:53 -0700337 jvalue args[5];
338
339 args[0].i = 0;
340 args[1].i = 0;
341 args[2].i = 0;
342 args[3].i = 0;
343 args[4].i = 0;
Andreas Gampe13b27842016-11-07 16:48:23 -0800344 JValue result = InvokeWithJValues(soa, receiver_ref.get(), jni::EncodeArtMethod(method), args);
Ian Rogers53b8b092014-03-13 23:45:53 -0700345 EXPECT_EQ(0, result.GetI());
346
347 args[0].i = 1;
348 args[1].i = 2;
349 args[2].i = 3;
350 args[3].i = 4;
351 args[4].i = 5;
Andreas Gampe13b27842016-11-07 16:48:23 -0800352 result = InvokeWithJValues(soa, receiver_ref.get(), jni::EncodeArtMethod(method), args);
Ian Rogers53b8b092014-03-13 23:45:53 -0700353 EXPECT_EQ(15, result.GetI());
354
355 args[0].i = -1;
356 args[1].i = 2;
357 args[2].i = -3;
358 args[3].i = 4;
359 args[4].i = -5;
Andreas Gampe13b27842016-11-07 16:48:23 -0800360 result = InvokeWithJValues(soa, receiver_ref.get(), jni::EncodeArtMethod(method), args);
Ian Rogers53b8b092014-03-13 23:45:53 -0700361 EXPECT_EQ(-3, result.GetI());
362
363 args[0].i = INT_MAX;
364 args[1].i = INT_MIN;
365 args[2].i = INT_MAX;
366 args[3].i = INT_MIN;
367 args[4].i = INT_MAX;
Andreas Gampe13b27842016-11-07 16:48:23 -0800368 result = InvokeWithJValues(soa, receiver_ref.get(), jni::EncodeArtMethod(method), args);
Ian Rogers53b8b092014-03-13 23:45:53 -0700369 EXPECT_EQ(2147483645, result.GetI());
370
371 args[0].i = INT_MAX;
372 args[1].i = INT_MAX;
373 args[2].i = INT_MAX;
374 args[3].i = INT_MAX;
375 args[4].i = INT_MAX;
Andreas Gampe13b27842016-11-07 16:48:23 -0800376 result = InvokeWithJValues(soa, receiver_ref.get(), jni::EncodeArtMethod(method), args);
Ian Rogers53b8b092014-03-13 23:45:53 -0700377 EXPECT_EQ(2147483643, result.GetI());
378 }
379
380 void InvokeSumDoubleDoubleMethod(bool is_static) {
381 ScopedObjectAccess soa(env_);
Mathieu Chartiere401d142015-04-22 13:56:20 -0700382 ArtMethod* method;
Mathieu Chartier28bd2e42016-10-04 13:54:57 -0700383 ObjPtr<mirror::Object> receiver;
Ian Rogers53b8b092014-03-13 23:45:53 -0700384 ReflectionTestMakeExecutable(&method, &receiver, is_static, "sum", "(DD)D");
Jeff Hao39b6c242015-05-19 20:30:23 -0700385 ScopedLocalRef<jobject> receiver_ref(soa.Env(), soa.AddLocalReference<jobject>(receiver));
Ian Rogers53b8b092014-03-13 23:45:53 -0700386 jvalue args[2];
387
388 args[0].d = 0.0;
389 args[1].d = 0.0;
Andreas Gampe13b27842016-11-07 16:48:23 -0800390 JValue result = InvokeWithJValues(soa, receiver_ref.get(), jni::EncodeArtMethod(method), args);
Ian Rogers647b1a82014-10-10 11:02:11 -0700391 EXPECT_DOUBLE_EQ(0.0, result.GetD());
Ian Rogers53b8b092014-03-13 23:45:53 -0700392
393 args[0].d = 1.0;
394 args[1].d = 2.0;
Andreas Gampe13b27842016-11-07 16:48:23 -0800395 result = InvokeWithJValues(soa, receiver_ref.get(), jni::EncodeArtMethod(method), args);
Ian Rogers647b1a82014-10-10 11:02:11 -0700396 EXPECT_DOUBLE_EQ(3.0, result.GetD());
Ian Rogers53b8b092014-03-13 23:45:53 -0700397
398 args[0].d = 1.0;
399 args[1].d = -2.0;
Andreas Gampe13b27842016-11-07 16:48:23 -0800400 result = InvokeWithJValues(soa, receiver_ref.get(), jni::EncodeArtMethod(method), args);
Ian Rogers647b1a82014-10-10 11:02:11 -0700401 EXPECT_DOUBLE_EQ(-1.0, result.GetD());
Ian Rogers53b8b092014-03-13 23:45:53 -0700402
403 args[0].d = DBL_MAX;
404 args[1].d = DBL_MIN;
Andreas Gampe13b27842016-11-07 16:48:23 -0800405 result = InvokeWithJValues(soa, receiver_ref.get(), jni::EncodeArtMethod(method), args);
Ian Rogers647b1a82014-10-10 11:02:11 -0700406 EXPECT_DOUBLE_EQ(1.7976931348623157e308, result.GetD());
Ian Rogers53b8b092014-03-13 23:45:53 -0700407
408 args[0].d = DBL_MAX;
409 args[1].d = DBL_MAX;
Andreas Gampe13b27842016-11-07 16:48:23 -0800410 result = InvokeWithJValues(soa, receiver_ref.get(), jni::EncodeArtMethod(method), args);
Ian Rogers647b1a82014-10-10 11:02:11 -0700411 EXPECT_DOUBLE_EQ(INFINITY, result.GetD());
Ian Rogers53b8b092014-03-13 23:45:53 -0700412 }
413
414 void InvokeSumDoubleDoubleDoubleMethod(bool is_static) {
415 ScopedObjectAccess soa(env_);
Mathieu Chartiere401d142015-04-22 13:56:20 -0700416 ArtMethod* method;
Mathieu Chartier28bd2e42016-10-04 13:54:57 -0700417 ObjPtr<mirror::Object> receiver;
Ian Rogers53b8b092014-03-13 23:45:53 -0700418 ReflectionTestMakeExecutable(&method, &receiver, is_static, "sum", "(DDD)D");
Jeff Hao39b6c242015-05-19 20:30:23 -0700419 ScopedLocalRef<jobject> receiver_ref(soa.Env(), soa.AddLocalReference<jobject>(receiver));
Ian Rogers53b8b092014-03-13 23:45:53 -0700420 jvalue args[3];
421
422 args[0].d = 0.0;
423 args[1].d = 0.0;
424 args[2].d = 0.0;
Andreas Gampe13b27842016-11-07 16:48:23 -0800425 JValue result = InvokeWithJValues(soa, receiver_ref.get(), jni::EncodeArtMethod(method), args);
Ian Rogers647b1a82014-10-10 11:02:11 -0700426 EXPECT_DOUBLE_EQ(0.0, result.GetD());
Ian Rogers53b8b092014-03-13 23:45:53 -0700427
428 args[0].d = 1.0;
429 args[1].d = 2.0;
430 args[2].d = 3.0;
Andreas Gampe13b27842016-11-07 16:48:23 -0800431 result = InvokeWithJValues(soa, receiver_ref.get(), jni::EncodeArtMethod(method), args);
Ian Rogers647b1a82014-10-10 11:02:11 -0700432 EXPECT_DOUBLE_EQ(6.0, result.GetD());
Ian Rogers53b8b092014-03-13 23:45:53 -0700433
434 args[0].d = 1.0;
435 args[1].d = -2.0;
436 args[2].d = 3.0;
Andreas Gampe13b27842016-11-07 16:48:23 -0800437 result = InvokeWithJValues(soa, receiver_ref.get(), jni::EncodeArtMethod(method), args);
Ian Rogers647b1a82014-10-10 11:02:11 -0700438 EXPECT_DOUBLE_EQ(2.0, result.GetD());
Ian Rogers53b8b092014-03-13 23:45:53 -0700439 }
440
441 void InvokeSumDoubleDoubleDoubleDoubleMethod(bool is_static) {
442 ScopedObjectAccess soa(env_);
Mathieu Chartiere401d142015-04-22 13:56:20 -0700443 ArtMethod* method;
Mathieu Chartier28bd2e42016-10-04 13:54:57 -0700444 ObjPtr<mirror::Object> receiver;
Ian Rogers53b8b092014-03-13 23:45:53 -0700445 ReflectionTestMakeExecutable(&method, &receiver, is_static, "sum", "(DDDD)D");
Jeff Hao39b6c242015-05-19 20:30:23 -0700446 ScopedLocalRef<jobject> receiver_ref(soa.Env(), soa.AddLocalReference<jobject>(receiver));
Ian Rogers53b8b092014-03-13 23:45:53 -0700447 jvalue args[4];
448
449 args[0].d = 0.0;
450 args[1].d = 0.0;
451 args[2].d = 0.0;
452 args[3].d = 0.0;
Andreas Gampe13b27842016-11-07 16:48:23 -0800453 JValue result = InvokeWithJValues(soa, receiver_ref.get(), jni::EncodeArtMethod(method), args);
Ian Rogers647b1a82014-10-10 11:02:11 -0700454 EXPECT_DOUBLE_EQ(0.0, result.GetD());
Ian Rogers53b8b092014-03-13 23:45:53 -0700455
456 args[0].d = 1.0;
457 args[1].d = 2.0;
458 args[2].d = 3.0;
459 args[3].d = 4.0;
Andreas Gampe13b27842016-11-07 16:48:23 -0800460 result = InvokeWithJValues(soa, receiver_ref.get(), jni::EncodeArtMethod(method), args);
Ian Rogers647b1a82014-10-10 11:02:11 -0700461 EXPECT_DOUBLE_EQ(10.0, result.GetD());
Ian Rogers53b8b092014-03-13 23:45:53 -0700462
463 args[0].d = 1.0;
464 args[1].d = -2.0;
465 args[2].d = 3.0;
466 args[3].d = -4.0;
Andreas Gampe13b27842016-11-07 16:48:23 -0800467 result = InvokeWithJValues(soa, receiver_ref.get(), jni::EncodeArtMethod(method), args);
Ian Rogers647b1a82014-10-10 11:02:11 -0700468 EXPECT_DOUBLE_EQ(-2.0, result.GetD());
Ian Rogers53b8b092014-03-13 23:45:53 -0700469 }
470
471 void InvokeSumDoubleDoubleDoubleDoubleDoubleMethod(bool is_static) {
472 ScopedObjectAccess soa(env_);
Mathieu Chartiere401d142015-04-22 13:56:20 -0700473 ArtMethod* method;
Mathieu Chartier28bd2e42016-10-04 13:54:57 -0700474 ObjPtr<mirror::Object> receiver;
Ian Rogers53b8b092014-03-13 23:45:53 -0700475 ReflectionTestMakeExecutable(&method, &receiver, is_static, "sum", "(DDDDD)D");
Jeff Hao39b6c242015-05-19 20:30:23 -0700476 ScopedLocalRef<jobject> receiver_ref(soa.Env(), soa.AddLocalReference<jobject>(receiver));
Ian Rogers53b8b092014-03-13 23:45:53 -0700477 jvalue args[5];
478
479 args[0].d = 0.0;
480 args[1].d = 0.0;
481 args[2].d = 0.0;
482 args[3].d = 0.0;
483 args[4].d = 0.0;
Andreas Gampe13b27842016-11-07 16:48:23 -0800484 JValue result = InvokeWithJValues(soa, receiver_ref.get(), jni::EncodeArtMethod(method), args);
Ian Rogers647b1a82014-10-10 11:02:11 -0700485 EXPECT_DOUBLE_EQ(0.0, result.GetD());
Ian Rogers53b8b092014-03-13 23:45:53 -0700486
487 args[0].d = 1.0;
488 args[1].d = 2.0;
489 args[2].d = 3.0;
490 args[3].d = 4.0;
491 args[4].d = 5.0;
Andreas Gampe13b27842016-11-07 16:48:23 -0800492 result = InvokeWithJValues(soa, receiver_ref.get(), jni::EncodeArtMethod(method), args);
Ian Rogers647b1a82014-10-10 11:02:11 -0700493 EXPECT_DOUBLE_EQ(15.0, result.GetD());
Ian Rogers53b8b092014-03-13 23:45:53 -0700494
495 args[0].d = 1.0;
496 args[1].d = -2.0;
497 args[2].d = 3.0;
498 args[3].d = -4.0;
499 args[4].d = 5.0;
Andreas Gampe13b27842016-11-07 16:48:23 -0800500 result = InvokeWithJValues(soa, receiver_ref.get(), jni::EncodeArtMethod(method), args);
Ian Rogers647b1a82014-10-10 11:02:11 -0700501 EXPECT_DOUBLE_EQ(3.0, result.GetD());
Ian Rogers53b8b092014-03-13 23:45:53 -0700502 }
503
504 JavaVMExt* vm_;
505 JNIEnv* env_;
506 jclass aioobe_;
507 jclass ase_;
508 jclass sioobe_;
509};
510
511TEST_F(ReflectionTest, StaticMainMethod) {
Roland Levillain0d5a2812015-11-13 10:07:31 +0000512 TEST_DISABLED_FOR_READ_BARRIER_WITH_OPTIMIZING_FOR_UNSUPPORTED_INSTRUCTION_SETS();
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
Andreas Gampe542451c2016-07-26 09:02:02 -0700523 ArtMethod* method = klass->FindDirectMethod("main",
524 "([Ljava/lang/String;)V",
525 kRuntimePointerSize);
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700526 ASSERT_TRUE(method != nullptr);
Ian Rogers53b8b092014-03-13 23:45:53 -0700527
528 // Start runtime.
529 bool started = runtime_->Start();
530 CHECK(started);
531 soa.Self()->TransitionFromSuspendedToRunnable();
532
533 jvalue args[1];
534 args[0].l = nullptr;
Andreas Gampe13b27842016-11-07 16:48:23 -0800535 InvokeWithJValues(soa, nullptr, jni::EncodeArtMethod(method), args);
Ian Rogers53b8b092014-03-13 23:45:53 -0700536}
537
538TEST_F(ReflectionTest, StaticNopMethod) {
Ian Rogers53b8b092014-03-13 23:45:53 -0700539 InvokeNopMethod(true);
540}
541
542TEST_F(ReflectionTest, NonStaticNopMethod) {
Ian Rogers53b8b092014-03-13 23:45:53 -0700543 InvokeNopMethod(false);
544}
545
546TEST_F(ReflectionTest, StaticIdentityByteMethod) {
Ian Rogers53b8b092014-03-13 23:45:53 -0700547 InvokeIdentityByteMethod(true);
548}
549
550TEST_F(ReflectionTest, NonStaticIdentityByteMethod) {
Ian Rogers53b8b092014-03-13 23:45:53 -0700551 InvokeIdentityByteMethod(false);
552}
553
554TEST_F(ReflectionTest, StaticIdentityIntMethod) {
Ian Rogers53b8b092014-03-13 23:45:53 -0700555 InvokeIdentityIntMethod(true);
556}
557
558TEST_F(ReflectionTest, NonStaticIdentityIntMethod) {
Ian Rogers53b8b092014-03-13 23:45:53 -0700559 InvokeIdentityIntMethod(false);
560}
561
562TEST_F(ReflectionTest, StaticIdentityDoubleMethod) {
Ian Rogers53b8b092014-03-13 23:45:53 -0700563 InvokeIdentityDoubleMethod(true);
564}
565
566TEST_F(ReflectionTest, NonStaticIdentityDoubleMethod) {
Ian Rogers53b8b092014-03-13 23:45:53 -0700567 InvokeIdentityDoubleMethod(false);
568}
569
570TEST_F(ReflectionTest, StaticSumIntIntMethod) {
Ian Rogers53b8b092014-03-13 23:45:53 -0700571 InvokeSumIntIntMethod(true);
572}
573
574TEST_F(ReflectionTest, NonStaticSumIntIntMethod) {
Ian Rogers53b8b092014-03-13 23:45:53 -0700575 InvokeSumIntIntMethod(false);
576}
577
578TEST_F(ReflectionTest, StaticSumIntIntIntMethod) {
Ian Rogers53b8b092014-03-13 23:45:53 -0700579 InvokeSumIntIntIntMethod(true);
580}
581
582TEST_F(ReflectionTest, NonStaticSumIntIntIntMethod) {
Ian Rogers53b8b092014-03-13 23:45:53 -0700583 InvokeSumIntIntIntMethod(false);
584}
585
586TEST_F(ReflectionTest, StaticSumIntIntIntIntMethod) {
Ian Rogers53b8b092014-03-13 23:45:53 -0700587 InvokeSumIntIntIntIntMethod(true);
588}
589
590TEST_F(ReflectionTest, NonStaticSumIntIntIntIntMethod) {
Ian Rogers53b8b092014-03-13 23:45:53 -0700591 InvokeSumIntIntIntIntMethod(false);
592}
593
594TEST_F(ReflectionTest, StaticSumIntIntIntIntIntMethod) {
Ian Rogers53b8b092014-03-13 23:45:53 -0700595 InvokeSumIntIntIntIntIntMethod(true);
596}
597
598TEST_F(ReflectionTest, NonStaticSumIntIntIntIntIntMethod) {
Ian Rogers53b8b092014-03-13 23:45:53 -0700599 InvokeSumIntIntIntIntIntMethod(false);
600}
601
602TEST_F(ReflectionTest, StaticSumDoubleDoubleMethod) {
Ian Rogers53b8b092014-03-13 23:45:53 -0700603 InvokeSumDoubleDoubleMethod(true);
604}
605
606TEST_F(ReflectionTest, NonStaticSumDoubleDoubleMethod) {
Ian Rogers53b8b092014-03-13 23:45:53 -0700607 InvokeSumDoubleDoubleMethod(false);
608}
609
610TEST_F(ReflectionTest, StaticSumDoubleDoubleDoubleMethod) {
Ian Rogers53b8b092014-03-13 23:45:53 -0700611 InvokeSumDoubleDoubleDoubleMethod(true);
612}
613
614TEST_F(ReflectionTest, NonStaticSumDoubleDoubleDoubleMethod) {
Ian Rogers53b8b092014-03-13 23:45:53 -0700615 InvokeSumDoubleDoubleDoubleMethod(false);
616}
617
618TEST_F(ReflectionTest, StaticSumDoubleDoubleDoubleDoubleMethod) {
Ian Rogers53b8b092014-03-13 23:45:53 -0700619 InvokeSumDoubleDoubleDoubleDoubleMethod(true);
620}
621
622TEST_F(ReflectionTest, NonStaticSumDoubleDoubleDoubleDoubleMethod) {
Ian Rogers53b8b092014-03-13 23:45:53 -0700623 InvokeSumDoubleDoubleDoubleDoubleMethod(false);
624}
625
626TEST_F(ReflectionTest, StaticSumDoubleDoubleDoubleDoubleDoubleMethod) {
Ian Rogers53b8b092014-03-13 23:45:53 -0700627 InvokeSumDoubleDoubleDoubleDoubleDoubleMethod(true);
628}
629
630TEST_F(ReflectionTest, NonStaticSumDoubleDoubleDoubleDoubleDoubleMethod) {
Ian Rogers53b8b092014-03-13 23:45:53 -0700631 InvokeSumDoubleDoubleDoubleDoubleDoubleMethod(false);
632}
633
634} // namespace art