blob: 7b36c7368e6ae44df53d52f0c74ff5c51e24a2fa [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"
David Sehrb2ec9f52018-02-21 13:20:31 -080025#include "dex/descriptors_names.h"
Andreas Gampec15a2f42017-04-21 12:09:39 -070026#include "java_vm_ext.h"
Andreas Gampe13b27842016-11-07 16:48:23 -080027#include "jni_internal.h"
Andreas Gampe373a9b52017-10-18 09:01:57 -070028#include "nativehelper/scoped_local_ref.h"
Mathieu Chartier0795f232016-09-27 18:43:30 -070029#include "scoped_thread_state_change-inl.h"
Ian Rogers53b8b092014-03-13 23:45:53 -070030
31namespace art {
32
33// TODO: Convert to CommonRuntimeTest. Currently MakeExecutable is used.
34class ReflectionTest : public CommonCompilerTest {
35 protected:
36 virtual void SetUp() {
37 CommonCompilerTest::SetUp();
38
39 vm_ = Runtime::Current()->GetJavaVM();
40
41 // Turn on -verbose:jni for the JNI tests.
42 // gLogVerbosity.jni = true;
43
Mathieu Chartier2cebb242015-04-21 16:50:40 -070044 vm_->AttachCurrentThread(&env_, nullptr);
Ian Rogers53b8b092014-03-13 23:45:53 -070045
46 ScopedLocalRef<jclass> aioobe(env_,
47 env_->FindClass("java/lang/ArrayIndexOutOfBoundsException"));
Mathieu Chartier2cebb242015-04-21 16:50:40 -070048 CHECK(aioobe.get() != nullptr);
Ian Rogers53b8b092014-03-13 23:45:53 -070049 aioobe_ = reinterpret_cast<jclass>(env_->NewGlobalRef(aioobe.get()));
50
51 ScopedLocalRef<jclass> ase(env_, env_->FindClass("java/lang/ArrayStoreException"));
Mathieu Chartier2cebb242015-04-21 16:50:40 -070052 CHECK(ase.get() != nullptr);
Ian Rogers53b8b092014-03-13 23:45:53 -070053 ase_ = reinterpret_cast<jclass>(env_->NewGlobalRef(ase.get()));
54
55 ScopedLocalRef<jclass> sioobe(env_,
56 env_->FindClass("java/lang/StringIndexOutOfBoundsException"));
Mathieu Chartier2cebb242015-04-21 16:50:40 -070057 CHECK(sioobe.get() != nullptr);
Ian Rogers53b8b092014-03-13 23:45:53 -070058 sioobe_ = reinterpret_cast<jclass>(env_->NewGlobalRef(sioobe.get()));
59 }
60
61 void CleanUpJniEnv() {
Mathieu Chartier2cebb242015-04-21 16:50:40 -070062 if (aioobe_ != nullptr) {
Ian Rogers53b8b092014-03-13 23:45:53 -070063 env_->DeleteGlobalRef(aioobe_);
Mathieu Chartier2cebb242015-04-21 16:50:40 -070064 aioobe_ = nullptr;
Ian Rogers53b8b092014-03-13 23:45:53 -070065 }
Mathieu Chartier2cebb242015-04-21 16:50:40 -070066 if (ase_ != nullptr) {
Ian Rogers53b8b092014-03-13 23:45:53 -070067 env_->DeleteGlobalRef(ase_);
Mathieu Chartier2cebb242015-04-21 16:50:40 -070068 ase_ = nullptr;
Ian Rogers53b8b092014-03-13 23:45:53 -070069 }
Mathieu Chartier2cebb242015-04-21 16:50:40 -070070 if (sioobe_ != nullptr) {
Ian Rogers53b8b092014-03-13 23:45:53 -070071 env_->DeleteGlobalRef(sioobe_);
Mathieu Chartier2cebb242015-04-21 16:50:40 -070072 sioobe_ = nullptr;
Ian Rogers53b8b092014-03-13 23:45:53 -070073 }
74 }
75
76 virtual void TearDown() {
77 CleanUpJniEnv();
78 CommonCompilerTest::TearDown();
79 }
80
81 jclass GetPrimitiveClass(char descriptor) {
82 ScopedObjectAccess soa(env_);
83 mirror::Class* c = class_linker_->FindPrimitiveClass(descriptor);
84 CHECK(c != nullptr);
85 return soa.AddLocalReference<jclass>(c);
86 }
87
Mathieu Chartiere401d142015-04-22 13:56:20 -070088 void ReflectionTestMakeExecutable(ArtMethod** method,
Mathieu Chartier28bd2e42016-10-04 13:54:57 -070089 ObjPtr<mirror::Object>* receiver,
90 bool is_static,
91 const char* method_name,
Ian Rogers53b8b092014-03-13 23:45:53 -070092 const char* method_signature)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -070093 REQUIRES_SHARED(Locks::mutator_lock_) {
Ian Rogers53b8b092014-03-13 23:45:53 -070094 const char* class_name = is_static ? "StaticLeafMethods" : "NonStaticLeafMethods";
95 jobject jclass_loader(LoadDex(class_name));
96 Thread* self = Thread::Current();
Mathieu Chartier28bd2e42016-10-04 13:54:57 -070097 StackHandleScope<3> hs(self);
Mathieu Chartiereb8167a2014-05-07 15:43:14 -070098 Handle<mirror::ClassLoader> class_loader(
99 hs.NewHandle(
Mathieu Chartier0795f232016-09-27 18:43:30 -0700100 ScopedObjectAccessUnchecked(self).Decode<mirror::ClassLoader>(jclass_loader)));
101 if (!is_static) {
Ian Rogers53b8b092014-03-13 23:45:53 -0700102 MakeExecutable(nullptr, "java.lang.Class");
103 MakeExecutable(nullptr, "java.lang.Object");
Ian Rogers53b8b092014-03-13 23:45:53 -0700104 }
Mathieu Chartier0795f232016-09-27 18:43:30 -0700105 MakeExecutable(class_loader.Get(), class_name);
Ian Rogers53b8b092014-03-13 23:45:53 -0700106
Mathieu Chartier28bd2e42016-10-04 13:54:57 -0700107 ObjPtr<mirror::Class> c = class_linker_->FindClass(self,
108 DotToDescriptor(class_name).c_str(),
109 class_loader);
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700110 CHECK(c != nullptr);
Ian Rogers53b8b092014-03-13 23:45:53 -0700111
Vladimir Markoba118822017-06-12 15:41:56 +0100112 *method = c->FindClassMethod(method_name, method_signature, kRuntimePointerSize);
113 CHECK(*method != nullptr);
114 CHECK_EQ(is_static, (*method)->IsStatic());
Ian Rogers53b8b092014-03-13 23:45:53 -0700115
Sebastien Hertz4e99b3d2014-06-24 14:35:40 +0200116 if (is_static) {
117 *receiver = nullptr;
118 } else {
119 // Ensure class is initialized before allocating object
Mathieu Chartier28bd2e42016-10-04 13:54:57 -0700120 {
121 StackHandleScope<1> hs2(self);
122 HandleWrapperObjPtr<mirror::Class> h_class(hs2.NewHandleWrapper(&c));
123 bool initialized = class_linker_->EnsureInitialized(self, h_class, true, true);
124 CHECK(initialized);
125 }
Sebastien Hertz4e99b3d2014-06-24 14:35:40 +0200126 *receiver = c->AllocObject(self);
127 }
Ian Rogers53b8b092014-03-13 23:45:53 -0700128
129 // Start runtime.
Mathieu Chartier28bd2e42016-10-04 13:54:57 -0700130 HandleWrapperObjPtr<mirror::Object> h(hs.NewHandleWrapper(receiver));
Ian Rogers53b8b092014-03-13 23:45:53 -0700131 bool started = runtime_->Start();
132 CHECK(started);
133 self->TransitionFromSuspendedToRunnable();
134 }
135
136 void InvokeNopMethod(bool is_static) {
137 ScopedObjectAccess soa(env_);
Mathieu Chartiere401d142015-04-22 13:56:20 -0700138 ArtMethod* method;
Mathieu Chartier28bd2e42016-10-04 13:54:57 -0700139 ObjPtr<mirror::Object> receiver;
Ian Rogers53b8b092014-03-13 23:45:53 -0700140 ReflectionTestMakeExecutable(&method, &receiver, is_static, "nop", "()V");
Jeff Hao39b6c242015-05-19 20:30:23 -0700141 ScopedLocalRef<jobject> receiver_ref(soa.Env(), soa.AddLocalReference<jobject>(receiver));
Andreas Gampe13b27842016-11-07 16:48:23 -0800142 InvokeWithJValues(soa, receiver_ref.get(), jni::EncodeArtMethod(method), nullptr);
Ian Rogers53b8b092014-03-13 23:45:53 -0700143 }
144
145 void InvokeIdentityByteMethod(bool is_static) {
146 ScopedObjectAccess soa(env_);
Mathieu Chartiere401d142015-04-22 13:56:20 -0700147 ArtMethod* method;
Mathieu Chartier28bd2e42016-10-04 13:54:57 -0700148 ObjPtr<mirror::Object> receiver;
Ian Rogers53b8b092014-03-13 23:45:53 -0700149 ReflectionTestMakeExecutable(&method, &receiver, is_static, "identity", "(B)B");
Jeff Hao39b6c242015-05-19 20:30:23 -0700150 ScopedLocalRef<jobject> receiver_ref(soa.Env(), soa.AddLocalReference<jobject>(receiver));
Ian Rogers53b8b092014-03-13 23:45:53 -0700151 jvalue args[1];
152
153 args[0].b = 0;
Andreas Gampe13b27842016-11-07 16:48:23 -0800154 JValue result = InvokeWithJValues(soa, receiver_ref.get(), jni::EncodeArtMethod(method), args);
Ian Rogers53b8b092014-03-13 23:45:53 -0700155 EXPECT_EQ(0, result.GetB());
156
157 args[0].b = -1;
Andreas Gampe13b27842016-11-07 16:48:23 -0800158 result = InvokeWithJValues(soa, receiver_ref.get(), jni::EncodeArtMethod(method), args);
Ian Rogers53b8b092014-03-13 23:45:53 -0700159 EXPECT_EQ(-1, result.GetB());
160
161 args[0].b = SCHAR_MAX;
Andreas Gampe13b27842016-11-07 16:48:23 -0800162 result = InvokeWithJValues(soa, receiver_ref.get(), jni::EncodeArtMethod(method), args);
Ian Rogers53b8b092014-03-13 23:45:53 -0700163 EXPECT_EQ(SCHAR_MAX, result.GetB());
164
Andreas Gampe58554b72015-10-20 21:08:52 -0700165 static_assert(SCHAR_MIN == -128, "SCHAR_MIN unexpected");
166 args[0].b = SCHAR_MIN;
Andreas Gampe13b27842016-11-07 16:48:23 -0800167 result = InvokeWithJValues(soa, receiver_ref.get(), jni::EncodeArtMethod(method), args);
Ian Rogers53b8b092014-03-13 23:45:53 -0700168 EXPECT_EQ(SCHAR_MIN, result.GetB());
169 }
170
171 void InvokeIdentityIntMethod(bool is_static) {
172 ScopedObjectAccess soa(env_);
Mathieu Chartiere401d142015-04-22 13:56:20 -0700173 ArtMethod* method;
Mathieu Chartier28bd2e42016-10-04 13:54:57 -0700174 ObjPtr<mirror::Object> receiver;
Ian Rogers53b8b092014-03-13 23:45:53 -0700175 ReflectionTestMakeExecutable(&method, &receiver, is_static, "identity", "(I)I");
Jeff Hao39b6c242015-05-19 20:30:23 -0700176 ScopedLocalRef<jobject> receiver_ref(soa.Env(), soa.AddLocalReference<jobject>(receiver));
Ian Rogers53b8b092014-03-13 23:45:53 -0700177 jvalue args[1];
178
179 args[0].i = 0;
Andreas Gampe13b27842016-11-07 16:48:23 -0800180 JValue result = InvokeWithJValues(soa, receiver_ref.get(), jni::EncodeArtMethod(method), args);
Ian Rogers53b8b092014-03-13 23:45:53 -0700181 EXPECT_EQ(0, result.GetI());
182
183 args[0].i = -1;
Andreas Gampe13b27842016-11-07 16:48:23 -0800184 result = InvokeWithJValues(soa, receiver_ref.get(), jni::EncodeArtMethod(method), args);
Ian Rogers53b8b092014-03-13 23:45:53 -0700185 EXPECT_EQ(-1, result.GetI());
186
187 args[0].i = INT_MAX;
Andreas Gampe13b27842016-11-07 16:48:23 -0800188 result = InvokeWithJValues(soa, receiver_ref.get(), jni::EncodeArtMethod(method), args);
Ian Rogers53b8b092014-03-13 23:45:53 -0700189 EXPECT_EQ(INT_MAX, result.GetI());
190
191 args[0].i = INT_MIN;
Andreas Gampe13b27842016-11-07 16:48:23 -0800192 result = InvokeWithJValues(soa, receiver_ref.get(), jni::EncodeArtMethod(method), args);
Ian Rogers53b8b092014-03-13 23:45:53 -0700193 EXPECT_EQ(INT_MIN, result.GetI());
194 }
195
196 void InvokeIdentityDoubleMethod(bool is_static) {
197 ScopedObjectAccess soa(env_);
Mathieu Chartiere401d142015-04-22 13:56:20 -0700198 ArtMethod* method;
Mathieu Chartier28bd2e42016-10-04 13:54:57 -0700199 ObjPtr<mirror::Object> receiver;
Ian Rogers53b8b092014-03-13 23:45:53 -0700200 ReflectionTestMakeExecutable(&method, &receiver, is_static, "identity", "(D)D");
Jeff Hao39b6c242015-05-19 20:30:23 -0700201 ScopedLocalRef<jobject> receiver_ref(soa.Env(), soa.AddLocalReference<jobject>(receiver));
Ian Rogers53b8b092014-03-13 23:45:53 -0700202 jvalue args[1];
203
204 args[0].d = 0.0;
Andreas Gampe13b27842016-11-07 16:48:23 -0800205 JValue result = InvokeWithJValues(soa, receiver_ref.get(), jni::EncodeArtMethod(method), args);
Ian Rogers647b1a82014-10-10 11:02:11 -0700206 EXPECT_DOUBLE_EQ(0.0, result.GetD());
Ian Rogers53b8b092014-03-13 23:45:53 -0700207
208 args[0].d = -1.0;
Andreas Gampe13b27842016-11-07 16:48:23 -0800209 result = InvokeWithJValues(soa, receiver_ref.get(), jni::EncodeArtMethod(method), args);
Ian Rogers647b1a82014-10-10 11:02:11 -0700210 EXPECT_DOUBLE_EQ(-1.0, result.GetD());
Ian Rogers53b8b092014-03-13 23:45:53 -0700211
212 args[0].d = DBL_MAX;
Andreas Gampe13b27842016-11-07 16:48:23 -0800213 result = InvokeWithJValues(soa, receiver_ref.get(), jni::EncodeArtMethod(method), args);
Ian Rogers647b1a82014-10-10 11:02:11 -0700214 EXPECT_DOUBLE_EQ(DBL_MAX, result.GetD());
Ian Rogers53b8b092014-03-13 23:45:53 -0700215
216 args[0].d = DBL_MIN;
Andreas Gampe13b27842016-11-07 16:48:23 -0800217 result = InvokeWithJValues(soa, receiver_ref.get(), jni::EncodeArtMethod(method), args);
Ian Rogers647b1a82014-10-10 11:02:11 -0700218 EXPECT_DOUBLE_EQ(DBL_MIN, result.GetD());
Ian Rogers53b8b092014-03-13 23:45:53 -0700219 }
220
221 void InvokeSumIntIntMethod(bool is_static) {
222 ScopedObjectAccess soa(env_);
Mathieu Chartiere401d142015-04-22 13:56:20 -0700223 ArtMethod* method;
Mathieu Chartier28bd2e42016-10-04 13:54:57 -0700224 ObjPtr<mirror::Object> receiver;
Ian Rogers53b8b092014-03-13 23:45:53 -0700225 ReflectionTestMakeExecutable(&method, &receiver, is_static, "sum", "(II)I");
Jeff Hao39b6c242015-05-19 20:30:23 -0700226 ScopedLocalRef<jobject> receiver_ref(soa.Env(), soa.AddLocalReference<jobject>(receiver));
Ian Rogers53b8b092014-03-13 23:45:53 -0700227 jvalue args[2];
228
229 args[0].i = 1;
230 args[1].i = 2;
Andreas Gampe13b27842016-11-07 16:48:23 -0800231 JValue result = InvokeWithJValues(soa, receiver_ref.get(), jni::EncodeArtMethod(method), args);
Ian Rogers53b8b092014-03-13 23:45:53 -0700232 EXPECT_EQ(3, result.GetI());
233
234 args[0].i = -2;
235 args[1].i = 5;
Andreas Gampe13b27842016-11-07 16:48:23 -0800236 result = InvokeWithJValues(soa, receiver_ref.get(), jni::EncodeArtMethod(method), args);
Ian Rogers53b8b092014-03-13 23:45:53 -0700237 EXPECT_EQ(3, result.GetI());
238
239 args[0].i = INT_MAX;
240 args[1].i = INT_MIN;
Andreas Gampe13b27842016-11-07 16:48:23 -0800241 result = InvokeWithJValues(soa, receiver_ref.get(), jni::EncodeArtMethod(method), args);
Ian Rogers53b8b092014-03-13 23:45:53 -0700242 EXPECT_EQ(-1, result.GetI());
243
244 args[0].i = INT_MAX;
245 args[1].i = INT_MAX;
Andreas Gampe13b27842016-11-07 16:48:23 -0800246 result = InvokeWithJValues(soa, receiver_ref.get(), jni::EncodeArtMethod(method), args);
Ian Rogers53b8b092014-03-13 23:45:53 -0700247 EXPECT_EQ(-2, result.GetI());
248 }
249
250 void InvokeSumIntIntIntMethod(bool is_static) {
251 ScopedObjectAccess soa(env_);
Mathieu Chartiere401d142015-04-22 13:56:20 -0700252 ArtMethod* method;
Mathieu Chartier28bd2e42016-10-04 13:54:57 -0700253 ObjPtr<mirror::Object> receiver;
Ian Rogers53b8b092014-03-13 23:45:53 -0700254 ReflectionTestMakeExecutable(&method, &receiver, is_static, "sum", "(III)I");
Jeff Hao39b6c242015-05-19 20:30:23 -0700255 ScopedLocalRef<jobject> receiver_ref(soa.Env(), soa.AddLocalReference<jobject>(receiver));
Ian Rogers53b8b092014-03-13 23:45:53 -0700256 jvalue args[3];
257
258 args[0].i = 0;
259 args[1].i = 0;
260 args[2].i = 0;
Andreas Gampe13b27842016-11-07 16:48:23 -0800261 JValue result = InvokeWithJValues(soa, receiver_ref.get(), jni::EncodeArtMethod(method), args);
Ian Rogers53b8b092014-03-13 23:45:53 -0700262 EXPECT_EQ(0, result.GetI());
263
264 args[0].i = 1;
265 args[1].i = 2;
266 args[2].i = 3;
Andreas Gampe13b27842016-11-07 16:48:23 -0800267 result = InvokeWithJValues(soa, receiver_ref.get(), jni::EncodeArtMethod(method), args);
Ian Rogers53b8b092014-03-13 23:45:53 -0700268 EXPECT_EQ(6, result.GetI());
269
270 args[0].i = -1;
271 args[1].i = 2;
272 args[2].i = -3;
Andreas Gampe13b27842016-11-07 16:48:23 -0800273 result = InvokeWithJValues(soa, receiver_ref.get(), jni::EncodeArtMethod(method), args);
Ian Rogers53b8b092014-03-13 23:45:53 -0700274 EXPECT_EQ(-2, result.GetI());
275
276 args[0].i = INT_MAX;
277 args[1].i = INT_MIN;
278 args[2].i = INT_MAX;
Andreas Gampe13b27842016-11-07 16:48:23 -0800279 result = InvokeWithJValues(soa, receiver_ref.get(), jni::EncodeArtMethod(method), args);
Ian Rogers53b8b092014-03-13 23:45:53 -0700280 EXPECT_EQ(2147483646, result.GetI());
281
282 args[0].i = INT_MAX;
283 args[1].i = INT_MAX;
284 args[2].i = INT_MAX;
Andreas Gampe13b27842016-11-07 16:48:23 -0800285 result = InvokeWithJValues(soa, receiver_ref.get(), jni::EncodeArtMethod(method), args);
Ian Rogers53b8b092014-03-13 23:45:53 -0700286 EXPECT_EQ(2147483645, result.GetI());
287 }
288
289 void InvokeSumIntIntIntIntMethod(bool is_static) {
290 ScopedObjectAccess soa(env_);
Mathieu Chartiere401d142015-04-22 13:56:20 -0700291 ArtMethod* method;
Mathieu Chartier28bd2e42016-10-04 13:54:57 -0700292 ObjPtr<mirror::Object> receiver;
Ian Rogers53b8b092014-03-13 23:45:53 -0700293 ReflectionTestMakeExecutable(&method, &receiver, is_static, "sum", "(IIII)I");
Jeff Hao39b6c242015-05-19 20:30:23 -0700294 ScopedLocalRef<jobject> receiver_ref(soa.Env(), soa.AddLocalReference<jobject>(receiver));
Ian Rogers53b8b092014-03-13 23:45:53 -0700295 jvalue args[4];
296
297 args[0].i = 0;
298 args[1].i = 0;
299 args[2].i = 0;
300 args[3].i = 0;
Andreas Gampe13b27842016-11-07 16:48:23 -0800301 JValue result = InvokeWithJValues(soa, receiver_ref.get(), jni::EncodeArtMethod(method), args);
Ian Rogers53b8b092014-03-13 23:45:53 -0700302 EXPECT_EQ(0, result.GetI());
303
304 args[0].i = 1;
305 args[1].i = 2;
306 args[2].i = 3;
307 args[3].i = 4;
Andreas Gampe13b27842016-11-07 16:48:23 -0800308 result = InvokeWithJValues(soa, receiver_ref.get(), jni::EncodeArtMethod(method), args);
Ian Rogers53b8b092014-03-13 23:45:53 -0700309 EXPECT_EQ(10, result.GetI());
310
311 args[0].i = -1;
312 args[1].i = 2;
313 args[2].i = -3;
314 args[3].i = 4;
Andreas Gampe13b27842016-11-07 16:48:23 -0800315 result = InvokeWithJValues(soa, receiver_ref.get(), jni::EncodeArtMethod(method), args);
Ian Rogers53b8b092014-03-13 23:45:53 -0700316 EXPECT_EQ(2, result.GetI());
317
318 args[0].i = INT_MAX;
319 args[1].i = INT_MIN;
320 args[2].i = INT_MAX;
321 args[3].i = INT_MIN;
Andreas Gampe13b27842016-11-07 16:48:23 -0800322 result = InvokeWithJValues(soa, receiver_ref.get(), jni::EncodeArtMethod(method), args);
Ian Rogers53b8b092014-03-13 23:45:53 -0700323 EXPECT_EQ(-2, result.GetI());
324
325 args[0].i = INT_MAX;
326 args[1].i = INT_MAX;
327 args[2].i = INT_MAX;
328 args[3].i = INT_MAX;
Andreas Gampe13b27842016-11-07 16:48:23 -0800329 result = InvokeWithJValues(soa, receiver_ref.get(), jni::EncodeArtMethod(method), args);
Ian Rogers53b8b092014-03-13 23:45:53 -0700330 EXPECT_EQ(-4, result.GetI());
331 }
332
333 void InvokeSumIntIntIntIntIntMethod(bool is_static) {
334 ScopedObjectAccess soa(env_);
Mathieu Chartiere401d142015-04-22 13:56:20 -0700335 ArtMethod* method;
Mathieu Chartier28bd2e42016-10-04 13:54:57 -0700336 ObjPtr<mirror::Object> receiver;
Ian Rogers53b8b092014-03-13 23:45:53 -0700337 ReflectionTestMakeExecutable(&method, &receiver, is_static, "sum", "(IIIII)I");
Jeff Hao39b6c242015-05-19 20:30:23 -0700338 ScopedLocalRef<jobject> receiver_ref(soa.Env(), soa.AddLocalReference<jobject>(receiver));
Ian Rogers53b8b092014-03-13 23:45:53 -0700339 jvalue args[5];
340
341 args[0].i = 0;
342 args[1].i = 0;
343 args[2].i = 0;
344 args[3].i = 0;
345 args[4].i = 0;
Andreas Gampe13b27842016-11-07 16:48:23 -0800346 JValue result = InvokeWithJValues(soa, receiver_ref.get(), jni::EncodeArtMethod(method), args);
Ian Rogers53b8b092014-03-13 23:45:53 -0700347 EXPECT_EQ(0, result.GetI());
348
349 args[0].i = 1;
350 args[1].i = 2;
351 args[2].i = 3;
352 args[3].i = 4;
353 args[4].i = 5;
Andreas Gampe13b27842016-11-07 16:48:23 -0800354 result = InvokeWithJValues(soa, receiver_ref.get(), jni::EncodeArtMethod(method), args);
Ian Rogers53b8b092014-03-13 23:45:53 -0700355 EXPECT_EQ(15, result.GetI());
356
357 args[0].i = -1;
358 args[1].i = 2;
359 args[2].i = -3;
360 args[3].i = 4;
361 args[4].i = -5;
Andreas Gampe13b27842016-11-07 16:48:23 -0800362 result = InvokeWithJValues(soa, receiver_ref.get(), jni::EncodeArtMethod(method), args);
Ian Rogers53b8b092014-03-13 23:45:53 -0700363 EXPECT_EQ(-3, result.GetI());
364
365 args[0].i = INT_MAX;
366 args[1].i = INT_MIN;
367 args[2].i = INT_MAX;
368 args[3].i = INT_MIN;
369 args[4].i = INT_MAX;
Andreas Gampe13b27842016-11-07 16:48:23 -0800370 result = InvokeWithJValues(soa, receiver_ref.get(), jni::EncodeArtMethod(method), args);
Ian Rogers53b8b092014-03-13 23:45:53 -0700371 EXPECT_EQ(2147483645, result.GetI());
372
373 args[0].i = INT_MAX;
374 args[1].i = INT_MAX;
375 args[2].i = INT_MAX;
376 args[3].i = INT_MAX;
377 args[4].i = INT_MAX;
Andreas Gampe13b27842016-11-07 16:48:23 -0800378 result = InvokeWithJValues(soa, receiver_ref.get(), jni::EncodeArtMethod(method), args);
Ian Rogers53b8b092014-03-13 23:45:53 -0700379 EXPECT_EQ(2147483643, result.GetI());
380 }
381
382 void InvokeSumDoubleDoubleMethod(bool is_static) {
383 ScopedObjectAccess soa(env_);
Mathieu Chartiere401d142015-04-22 13:56:20 -0700384 ArtMethod* method;
Mathieu Chartier28bd2e42016-10-04 13:54:57 -0700385 ObjPtr<mirror::Object> receiver;
Ian Rogers53b8b092014-03-13 23:45:53 -0700386 ReflectionTestMakeExecutable(&method, &receiver, is_static, "sum", "(DD)D");
Jeff Hao39b6c242015-05-19 20:30:23 -0700387 ScopedLocalRef<jobject> receiver_ref(soa.Env(), soa.AddLocalReference<jobject>(receiver));
Ian Rogers53b8b092014-03-13 23:45:53 -0700388 jvalue args[2];
389
390 args[0].d = 0.0;
391 args[1].d = 0.0;
Andreas Gampe13b27842016-11-07 16:48:23 -0800392 JValue result = InvokeWithJValues(soa, receiver_ref.get(), jni::EncodeArtMethod(method), args);
Ian Rogers647b1a82014-10-10 11:02:11 -0700393 EXPECT_DOUBLE_EQ(0.0, result.GetD());
Ian Rogers53b8b092014-03-13 23:45:53 -0700394
395 args[0].d = 1.0;
396 args[1].d = 2.0;
Andreas Gampe13b27842016-11-07 16:48:23 -0800397 result = InvokeWithJValues(soa, receiver_ref.get(), jni::EncodeArtMethod(method), args);
Ian Rogers647b1a82014-10-10 11:02:11 -0700398 EXPECT_DOUBLE_EQ(3.0, result.GetD());
Ian Rogers53b8b092014-03-13 23:45:53 -0700399
400 args[0].d = 1.0;
401 args[1].d = -2.0;
Andreas Gampe13b27842016-11-07 16:48:23 -0800402 result = InvokeWithJValues(soa, receiver_ref.get(), jni::EncodeArtMethod(method), args);
Ian Rogers647b1a82014-10-10 11:02:11 -0700403 EXPECT_DOUBLE_EQ(-1.0, result.GetD());
Ian Rogers53b8b092014-03-13 23:45:53 -0700404
405 args[0].d = DBL_MAX;
406 args[1].d = DBL_MIN;
Andreas Gampe13b27842016-11-07 16:48:23 -0800407 result = InvokeWithJValues(soa, receiver_ref.get(), jni::EncodeArtMethod(method), args);
Ian Rogers647b1a82014-10-10 11:02:11 -0700408 EXPECT_DOUBLE_EQ(1.7976931348623157e308, result.GetD());
Ian Rogers53b8b092014-03-13 23:45:53 -0700409
410 args[0].d = DBL_MAX;
411 args[1].d = DBL_MAX;
Andreas Gampe13b27842016-11-07 16:48:23 -0800412 result = InvokeWithJValues(soa, receiver_ref.get(), jni::EncodeArtMethod(method), args);
Ian Rogers647b1a82014-10-10 11:02:11 -0700413 EXPECT_DOUBLE_EQ(INFINITY, result.GetD());
Ian Rogers53b8b092014-03-13 23:45:53 -0700414 }
415
416 void InvokeSumDoubleDoubleDoubleMethod(bool is_static) {
417 ScopedObjectAccess soa(env_);
Mathieu Chartiere401d142015-04-22 13:56:20 -0700418 ArtMethod* method;
Mathieu Chartier28bd2e42016-10-04 13:54:57 -0700419 ObjPtr<mirror::Object> receiver;
Ian Rogers53b8b092014-03-13 23:45:53 -0700420 ReflectionTestMakeExecutable(&method, &receiver, is_static, "sum", "(DDD)D");
Jeff Hao39b6c242015-05-19 20:30:23 -0700421 ScopedLocalRef<jobject> receiver_ref(soa.Env(), soa.AddLocalReference<jobject>(receiver));
Ian Rogers53b8b092014-03-13 23:45:53 -0700422 jvalue args[3];
423
424 args[0].d = 0.0;
425 args[1].d = 0.0;
426 args[2].d = 0.0;
Andreas Gampe13b27842016-11-07 16:48:23 -0800427 JValue result = InvokeWithJValues(soa, receiver_ref.get(), jni::EncodeArtMethod(method), args);
Ian Rogers647b1a82014-10-10 11:02:11 -0700428 EXPECT_DOUBLE_EQ(0.0, result.GetD());
Ian Rogers53b8b092014-03-13 23:45:53 -0700429
430 args[0].d = 1.0;
431 args[1].d = 2.0;
432 args[2].d = 3.0;
Andreas Gampe13b27842016-11-07 16:48:23 -0800433 result = InvokeWithJValues(soa, receiver_ref.get(), jni::EncodeArtMethod(method), args);
Ian Rogers647b1a82014-10-10 11:02:11 -0700434 EXPECT_DOUBLE_EQ(6.0, result.GetD());
Ian Rogers53b8b092014-03-13 23:45:53 -0700435
436 args[0].d = 1.0;
437 args[1].d = -2.0;
438 args[2].d = 3.0;
Andreas Gampe13b27842016-11-07 16:48:23 -0800439 result = InvokeWithJValues(soa, receiver_ref.get(), jni::EncodeArtMethod(method), args);
Ian Rogers647b1a82014-10-10 11:02:11 -0700440 EXPECT_DOUBLE_EQ(2.0, result.GetD());
Ian Rogers53b8b092014-03-13 23:45:53 -0700441 }
442
443 void InvokeSumDoubleDoubleDoubleDoubleMethod(bool is_static) {
444 ScopedObjectAccess soa(env_);
Mathieu Chartiere401d142015-04-22 13:56:20 -0700445 ArtMethod* method;
Mathieu Chartier28bd2e42016-10-04 13:54:57 -0700446 ObjPtr<mirror::Object> receiver;
Ian Rogers53b8b092014-03-13 23:45:53 -0700447 ReflectionTestMakeExecutable(&method, &receiver, is_static, "sum", "(DDDD)D");
Jeff Hao39b6c242015-05-19 20:30:23 -0700448 ScopedLocalRef<jobject> receiver_ref(soa.Env(), soa.AddLocalReference<jobject>(receiver));
Ian Rogers53b8b092014-03-13 23:45:53 -0700449 jvalue args[4];
450
451 args[0].d = 0.0;
452 args[1].d = 0.0;
453 args[2].d = 0.0;
454 args[3].d = 0.0;
Andreas Gampe13b27842016-11-07 16:48:23 -0800455 JValue result = InvokeWithJValues(soa, receiver_ref.get(), jni::EncodeArtMethod(method), args);
Ian Rogers647b1a82014-10-10 11:02:11 -0700456 EXPECT_DOUBLE_EQ(0.0, result.GetD());
Ian Rogers53b8b092014-03-13 23:45:53 -0700457
458 args[0].d = 1.0;
459 args[1].d = 2.0;
460 args[2].d = 3.0;
461 args[3].d = 4.0;
Andreas Gampe13b27842016-11-07 16:48:23 -0800462 result = InvokeWithJValues(soa, receiver_ref.get(), jni::EncodeArtMethod(method), args);
Ian Rogers647b1a82014-10-10 11:02:11 -0700463 EXPECT_DOUBLE_EQ(10.0, result.GetD());
Ian Rogers53b8b092014-03-13 23:45:53 -0700464
465 args[0].d = 1.0;
466 args[1].d = -2.0;
467 args[2].d = 3.0;
468 args[3].d = -4.0;
Andreas Gampe13b27842016-11-07 16:48:23 -0800469 result = InvokeWithJValues(soa, receiver_ref.get(), jni::EncodeArtMethod(method), args);
Ian Rogers647b1a82014-10-10 11:02:11 -0700470 EXPECT_DOUBLE_EQ(-2.0, result.GetD());
Ian Rogers53b8b092014-03-13 23:45:53 -0700471 }
472
473 void InvokeSumDoubleDoubleDoubleDoubleDoubleMethod(bool is_static) {
474 ScopedObjectAccess soa(env_);
Mathieu Chartiere401d142015-04-22 13:56:20 -0700475 ArtMethod* method;
Mathieu Chartier28bd2e42016-10-04 13:54:57 -0700476 ObjPtr<mirror::Object> receiver;
Ian Rogers53b8b092014-03-13 23:45:53 -0700477 ReflectionTestMakeExecutable(&method, &receiver, is_static, "sum", "(DDDDD)D");
Jeff Hao39b6c242015-05-19 20:30:23 -0700478 ScopedLocalRef<jobject> receiver_ref(soa.Env(), soa.AddLocalReference<jobject>(receiver));
Ian Rogers53b8b092014-03-13 23:45:53 -0700479 jvalue args[5];
480
481 args[0].d = 0.0;
482 args[1].d = 0.0;
483 args[2].d = 0.0;
484 args[3].d = 0.0;
485 args[4].d = 0.0;
Andreas Gampe13b27842016-11-07 16:48:23 -0800486 JValue result = InvokeWithJValues(soa, receiver_ref.get(), jni::EncodeArtMethod(method), args);
Ian Rogers647b1a82014-10-10 11:02:11 -0700487 EXPECT_DOUBLE_EQ(0.0, result.GetD());
Ian Rogers53b8b092014-03-13 23:45:53 -0700488
489 args[0].d = 1.0;
490 args[1].d = 2.0;
491 args[2].d = 3.0;
492 args[3].d = 4.0;
493 args[4].d = 5.0;
Andreas Gampe13b27842016-11-07 16:48:23 -0800494 result = InvokeWithJValues(soa, receiver_ref.get(), jni::EncodeArtMethod(method), args);
Ian Rogers647b1a82014-10-10 11:02:11 -0700495 EXPECT_DOUBLE_EQ(15.0, result.GetD());
Ian Rogers53b8b092014-03-13 23:45:53 -0700496
497 args[0].d = 1.0;
498 args[1].d = -2.0;
499 args[2].d = 3.0;
500 args[3].d = -4.0;
501 args[4].d = 5.0;
Andreas Gampe13b27842016-11-07 16:48:23 -0800502 result = InvokeWithJValues(soa, receiver_ref.get(), jni::EncodeArtMethod(method), args);
Ian Rogers647b1a82014-10-10 11:02:11 -0700503 EXPECT_DOUBLE_EQ(3.0, result.GetD());
Ian Rogers53b8b092014-03-13 23:45:53 -0700504 }
505
506 JavaVMExt* vm_;
507 JNIEnv* env_;
508 jclass aioobe_;
509 jclass ase_;
510 jclass sioobe_;
511};
512
513TEST_F(ReflectionTest, StaticMainMethod) {
Ian Rogers53b8b092014-03-13 23:45:53 -0700514 ScopedObjectAccess soa(Thread::Current());
515 jobject jclass_loader = LoadDex("Main");
Mathieu Chartiereb8167a2014-05-07 15:43:14 -0700516 StackHandleScope<1> hs(soa.Self());
517 Handle<mirror::ClassLoader> class_loader(
Mathieu Chartier0795f232016-09-27 18:43:30 -0700518 hs.NewHandle(soa.Decode<mirror::ClassLoader>(jclass_loader)));
Ian Rogers53b8b092014-03-13 23:45:53 -0700519 CompileDirectMethod(class_loader, "Main", "main", "([Ljava/lang/String;)V");
520
521 mirror::Class* klass = class_linker_->FindClass(soa.Self(), "LMain;", class_loader);
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700522 ASSERT_TRUE(klass != nullptr);
Ian Rogers53b8b092014-03-13 23:45:53 -0700523
Vladimir Markoba118822017-06-12 15:41:56 +0100524 ArtMethod* method = klass->FindClassMethod("main",
525 "([Ljava/lang/String;)V",
526 kRuntimePointerSize);
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700527 ASSERT_TRUE(method != nullptr);
Vladimir Markoba118822017-06-12 15:41:56 +0100528 ASSERT_TRUE(method->IsStatic());
Ian Rogers53b8b092014-03-13 23:45:53 -0700529
530 // Start runtime.
531 bool started = runtime_->Start();
532 CHECK(started);
533 soa.Self()->TransitionFromSuspendedToRunnable();
534
535 jvalue args[1];
536 args[0].l = nullptr;
Andreas Gampe13b27842016-11-07 16:48:23 -0800537 InvokeWithJValues(soa, nullptr, jni::EncodeArtMethod(method), args);
Ian Rogers53b8b092014-03-13 23:45:53 -0700538}
539
540TEST_F(ReflectionTest, StaticNopMethod) {
Ian Rogers53b8b092014-03-13 23:45:53 -0700541 InvokeNopMethod(true);
542}
543
544TEST_F(ReflectionTest, NonStaticNopMethod) {
Ian Rogers53b8b092014-03-13 23:45:53 -0700545 InvokeNopMethod(false);
546}
547
548TEST_F(ReflectionTest, StaticIdentityByteMethod) {
Ian Rogers53b8b092014-03-13 23:45:53 -0700549 InvokeIdentityByteMethod(true);
550}
551
552TEST_F(ReflectionTest, NonStaticIdentityByteMethod) {
Ian Rogers53b8b092014-03-13 23:45:53 -0700553 InvokeIdentityByteMethod(false);
554}
555
556TEST_F(ReflectionTest, StaticIdentityIntMethod) {
Ian Rogers53b8b092014-03-13 23:45:53 -0700557 InvokeIdentityIntMethod(true);
558}
559
560TEST_F(ReflectionTest, NonStaticIdentityIntMethod) {
Ian Rogers53b8b092014-03-13 23:45:53 -0700561 InvokeIdentityIntMethod(false);
562}
563
564TEST_F(ReflectionTest, StaticIdentityDoubleMethod) {
Ian Rogers53b8b092014-03-13 23:45:53 -0700565 InvokeIdentityDoubleMethod(true);
566}
567
568TEST_F(ReflectionTest, NonStaticIdentityDoubleMethod) {
Ian Rogers53b8b092014-03-13 23:45:53 -0700569 InvokeIdentityDoubleMethod(false);
570}
571
572TEST_F(ReflectionTest, StaticSumIntIntMethod) {
Ian Rogers53b8b092014-03-13 23:45:53 -0700573 InvokeSumIntIntMethod(true);
574}
575
576TEST_F(ReflectionTest, NonStaticSumIntIntMethod) {
Ian Rogers53b8b092014-03-13 23:45:53 -0700577 InvokeSumIntIntMethod(false);
578}
579
580TEST_F(ReflectionTest, StaticSumIntIntIntMethod) {
Ian Rogers53b8b092014-03-13 23:45:53 -0700581 InvokeSumIntIntIntMethod(true);
582}
583
584TEST_F(ReflectionTest, NonStaticSumIntIntIntMethod) {
Ian Rogers53b8b092014-03-13 23:45:53 -0700585 InvokeSumIntIntIntMethod(false);
586}
587
588TEST_F(ReflectionTest, StaticSumIntIntIntIntMethod) {
Ian Rogers53b8b092014-03-13 23:45:53 -0700589 InvokeSumIntIntIntIntMethod(true);
590}
591
592TEST_F(ReflectionTest, NonStaticSumIntIntIntIntMethod) {
Ian Rogers53b8b092014-03-13 23:45:53 -0700593 InvokeSumIntIntIntIntMethod(false);
594}
595
596TEST_F(ReflectionTest, StaticSumIntIntIntIntIntMethod) {
Ian Rogers53b8b092014-03-13 23:45:53 -0700597 InvokeSumIntIntIntIntIntMethod(true);
598}
599
600TEST_F(ReflectionTest, NonStaticSumIntIntIntIntIntMethod) {
Ian Rogers53b8b092014-03-13 23:45:53 -0700601 InvokeSumIntIntIntIntIntMethod(false);
602}
603
604TEST_F(ReflectionTest, StaticSumDoubleDoubleMethod) {
Ian Rogers53b8b092014-03-13 23:45:53 -0700605 InvokeSumDoubleDoubleMethod(true);
606}
607
608TEST_F(ReflectionTest, NonStaticSumDoubleDoubleMethod) {
Ian Rogers53b8b092014-03-13 23:45:53 -0700609 InvokeSumDoubleDoubleMethod(false);
610}
611
612TEST_F(ReflectionTest, StaticSumDoubleDoubleDoubleMethod) {
Ian Rogers53b8b092014-03-13 23:45:53 -0700613 InvokeSumDoubleDoubleDoubleMethod(true);
614}
615
616TEST_F(ReflectionTest, NonStaticSumDoubleDoubleDoubleMethod) {
Ian Rogers53b8b092014-03-13 23:45:53 -0700617 InvokeSumDoubleDoubleDoubleMethod(false);
618}
619
620TEST_F(ReflectionTest, StaticSumDoubleDoubleDoubleDoubleMethod) {
Ian Rogers53b8b092014-03-13 23:45:53 -0700621 InvokeSumDoubleDoubleDoubleDoubleMethod(true);
622}
623
624TEST_F(ReflectionTest, NonStaticSumDoubleDoubleDoubleDoubleMethod) {
Ian Rogers53b8b092014-03-13 23:45:53 -0700625 InvokeSumDoubleDoubleDoubleDoubleMethod(false);
626}
627
628TEST_F(ReflectionTest, StaticSumDoubleDoubleDoubleDoubleDoubleMethod) {
Ian Rogers53b8b092014-03-13 23:45:53 -0700629 InvokeSumDoubleDoubleDoubleDoubleDoubleMethod(true);
630}
631
632TEST_F(ReflectionTest, NonStaticSumDoubleDoubleDoubleDoubleDoubleMethod) {
Ian Rogers53b8b092014-03-13 23:45:53 -0700633 InvokeSumDoubleDoubleDoubleDoubleDoubleMethod(false);
634}
635
636} // namespace art