blob: 0f584444e567ef9de9c0209ae939e4dc538e6dfd [file] [log] [blame]
Elliott Hughes2faa5f12012-01-30 14:42:07 -08001/*
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 */
Elliott Hughes0c9cd562011-08-12 10:59:29 -070016
Carl Shapiro9b9ba282011-08-14 15:30:39 -070017#include "jni_internal.h"
Elliott Hughes0c9cd562011-08-12 10:59:29 -070018
Elliott Hughesf66330a2012-12-12 17:27:00 -080019#include <cfloat>
Ian Rogers0cfe1fb2011-08-26 03:29:44 -070020#include <cmath>
21
Carl Shapiro9b9ba282011-08-14 15:30:39 -070022#include "common_test.h"
Jeff Hao5d917302013-02-27 17:57:33 -080023#include "invoke_arg_array_builder.h"
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080024#include "mirror/abstract_method-inl.h"
Ian Rogers4f6ad8a2013-03-18 15:27:28 -070025#include "mirror/class-inl.h"
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080026#include "mirror/object_array-inl.h"
Ian Rogers04d7aa92013-03-16 14:29:17 -070027#include "mirror/object-inl.h"
Elliott Hughes726079d2011-10-07 18:43:44 -070028#include "ScopedLocalRef.h"
Ian Rogers1f539342012-10-03 21:09:42 -070029#include "sirt_ref.h"
Elliott Hughes0c9cd562011-08-12 10:59:29 -070030
31namespace art {
32
Brian Carlstromf734cf52011-08-17 16:28:14 -070033class JniInternalTest : public CommonTest {
Elliott Hughesc7ac37f2011-08-12 12:21:58 -070034 protected:
35 virtual void SetUp() {
Brian Carlstromf734cf52011-08-17 16:28:14 -070036 CommonTest::SetUp();
Elliott Hughes5174fe62011-08-23 15:12:35 -070037
Elliott Hughesa2501992011-08-26 19:39:54 -070038 vm_ = Runtime::Current()->GetJavaVM();
39
Elliott Hughes5174fe62011-08-23 15:12:35 -070040 // Turn on -verbose:jni for the JNI tests.
Elliott Hughes4dd9b4d2011-12-12 18:29:24 -080041 gLogVerbosity.jni = true;
Elliott Hughes5174fe62011-08-23 15:12:35 -070042
Brian Carlstrom4d571432012-05-16 00:21:41 -070043 vm_->AttachCurrentThread(&env_, NULL);
Elliott Hughesb465ab02011-08-24 11:21:21 -070044
Elliott Hughes726079d2011-10-07 18:43:44 -070045 ScopedLocalRef<jclass> aioobe(env_, env_->FindClass("java/lang/ArrayIndexOutOfBoundsException"));
46 CHECK(aioobe.get() != NULL);
47 aioobe_ = reinterpret_cast<jclass>(env_->NewGlobalRef(aioobe.get()));
Elliott Hughesb465ab02011-08-24 11:21:21 -070048
Elliott Hughesb264f082012-04-06 17:10:10 -070049 ScopedLocalRef<jclass> ase(env_, env_->FindClass("java/lang/ArrayStoreException"));
50 CHECK(ase.get() != NULL);
51 ase_ = reinterpret_cast<jclass>(env_->NewGlobalRef(ase.get()));
52
Elliott Hughes726079d2011-10-07 18:43:44 -070053 ScopedLocalRef<jclass> sioobe(env_, env_->FindClass("java/lang/StringIndexOutOfBoundsException"));
54 CHECK(sioobe.get() != NULL);
55 sioobe_ = reinterpret_cast<jclass>(env_->NewGlobalRef(sioobe.get()));
56 }
57
Brian Carlstrom4d571432012-05-16 00:21:41 -070058 void CleanUpJniEnv() {
59 if (aioobe_ != NULL) {
60 env_->DeleteGlobalRef(aioobe_);
61 aioobe_ = NULL;
62 }
63 if (ase_ != NULL) {
64 env_->DeleteGlobalRef(ase_);
65 ase_ = NULL;
66 }
67 if (sioobe_ != NULL) {
68 env_->DeleteGlobalRef(sioobe_);
69 sioobe_ = NULL;
70 }
71 }
72
Elliott Hughes726079d2011-10-07 18:43:44 -070073 virtual void TearDown() {
Brian Carlstrom4d571432012-05-16 00:21:41 -070074 CleanUpJniEnv();
Elliott Hughes726079d2011-10-07 18:43:44 -070075 CommonTest::TearDown();
Elliott Hughesc7ac37f2011-08-12 12:21:58 -070076 }
Elliott Hughesb465ab02011-08-24 11:21:21 -070077
Jeff Hao5d917302013-02-27 17:57:33 -080078 void DoCompile(mirror::AbstractMethod*& method,
79 mirror::Object*& receiver,
80 bool is_static, const char* method_name,
81 const char* method_signature)
Ian Rogersb726dcb2012-09-05 08:57:23 -070082 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Elliott Hughes77405792012-03-15 15:22:12 -070083 const char* class_name = is_static ? "StaticLeafMethods" : "NonStaticLeafMethods";
Ian Rogers00f7d0e2012-07-19 15:28:27 -070084 jobject jclass_loader(LoadDex(class_name));
Ian Rogers1f539342012-10-03 21:09:42 -070085 Thread* self = Thread::Current();
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080086 SirtRef<mirror::ClassLoader>
Ian Rogers1f539342012-10-03 21:09:42 -070087 class_loader(self,
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080088 ScopedObjectAccessUnchecked(self).Decode<mirror::ClassLoader*>(jclass_loader));
Elliott Hughes77405792012-03-15 15:22:12 -070089 if (is_static) {
90 CompileDirectMethod(class_loader.get(), class_name, method_name, method_signature);
91 } else {
92 CompileVirtualMethod(NULL, "java.lang.Class", "isFinalizable", "()Z");
93 CompileDirectMethod(NULL, "java.lang.Object", "<init>", "()V");
94 CompileVirtualMethod(class_loader.get(), class_name, method_name, method_signature);
95 }
96
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080097 mirror::Class* c = class_linker_->FindClass(DotToDescriptor(class_name).c_str(), class_loader.get());
Elliott Hughes77405792012-03-15 15:22:12 -070098 CHECK(c != NULL);
99
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700100 method = is_static ? c->FindDirectMethod(method_name, method_signature)
101 : c->FindVirtualMethod(method_name, method_signature);
Elliott Hughes77405792012-03-15 15:22:12 -0700102 CHECK(method != NULL);
103
Ian Rogers50b35e22012-10-04 10:09:15 -0700104 receiver = (is_static ? NULL : c->AllocObject(self));
Sebastien Hertzb95851f2013-03-29 10:36:40 +0100105
106 // Start runtime.
107 bool started = runtime_->Start();
108 CHECK(started);
109 self->TransitionFromSuspendedToRunnable();
Elliott Hughes77405792012-03-15 15:22:12 -0700110 }
111
Ian Rogersb726dcb2012-09-05 08:57:23 -0700112 void InvokeNopMethod(bool is_static) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800113 mirror::AbstractMethod* method;
114 mirror::Object* receiver;
Jeff Hao5d917302013-02-27 17:57:33 -0800115 DoCompile(method, receiver, is_static, "nop", "()V");
116
117 ArgArray arg_array(NULL, 0);
118 JValue result;
Jeff Hao5d917302013-02-27 17:57:33 -0800119
120 if (!is_static) {
121 arg_array.Append(reinterpret_cast<uint32_t>(receiver));
122 }
Sebastien Hertzb95851f2013-03-29 10:36:40 +0100123
124 method->Invoke(Thread::Current(), arg_array.GetArray(), arg_array.GetNumBytes(), &result, 'V');
Elliott Hughes77405792012-03-15 15:22:12 -0700125 }
126
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700127 void InvokeIdentityByteMethod(bool is_static)
Ian Rogersb726dcb2012-09-05 08:57:23 -0700128 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800129 mirror::AbstractMethod* method;
130 mirror::Object* receiver;
Jeff Hao5d917302013-02-27 17:57:33 -0800131 DoCompile(method, receiver, is_static, "identity", "(I)I");
Elliott Hughes77405792012-03-15 15:22:12 -0700132
Jeff Hao5d917302013-02-27 17:57:33 -0800133 ArgArray arg_array(NULL, 0);
134 uint32_t* args = arg_array.GetArray();
Elliott Hughes77405792012-03-15 15:22:12 -0700135 JValue result;
136
Jeff Hao5d917302013-02-27 17:57:33 -0800137 if (!is_static) {
138 arg_array.Append(reinterpret_cast<uint32_t>(receiver));
139 args++;
140 }
141
142 arg_array.Append(0);
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700143 result.SetB(-1);
Sebastien Hertzb95851f2013-03-29 10:36:40 +0100144 method->Invoke(Thread::Current(), arg_array.GetArray(), arg_array.GetNumBytes(), &result, 'B');
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700145 EXPECT_EQ(0, result.GetB());
Elliott Hughes77405792012-03-15 15:22:12 -0700146
Jeff Hao5d917302013-02-27 17:57:33 -0800147 args[0] = -1;
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700148 result.SetB(0);
Sebastien Hertzb95851f2013-03-29 10:36:40 +0100149 method->Invoke(Thread::Current(), arg_array.GetArray(), arg_array.GetNumBytes(), &result, 'B');
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700150 EXPECT_EQ(-1, result.GetB());
Elliott Hughes77405792012-03-15 15:22:12 -0700151
Jeff Hao5d917302013-02-27 17:57:33 -0800152 args[0] = SCHAR_MAX;
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700153 result.SetB(0);
Sebastien Hertzb95851f2013-03-29 10:36:40 +0100154 method->Invoke(Thread::Current(), arg_array.GetArray(), arg_array.GetNumBytes(), &result, 'B');
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700155 EXPECT_EQ(SCHAR_MAX, result.GetB());
Elliott Hughes77405792012-03-15 15:22:12 -0700156
Jeff Hao5d917302013-02-27 17:57:33 -0800157 args[0] = (SCHAR_MIN << 24) >> 24;
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700158 result.SetB(0);
Sebastien Hertzb95851f2013-03-29 10:36:40 +0100159 method->Invoke(Thread::Current(), arg_array.GetArray(), arg_array.GetNumBytes(), &result, 'B');
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700160 EXPECT_EQ(SCHAR_MIN, result.GetB());
Elliott Hughes77405792012-03-15 15:22:12 -0700161 }
162
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700163 void InvokeIdentityIntMethod(bool is_static)
Ian Rogersb726dcb2012-09-05 08:57:23 -0700164 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800165 mirror::AbstractMethod* method;
166 mirror::Object* receiver;
Jeff Hao5d917302013-02-27 17:57:33 -0800167 DoCompile(method, receiver, is_static, "identity", "(I)I");
Elliott Hughes77405792012-03-15 15:22:12 -0700168
Jeff Hao5d917302013-02-27 17:57:33 -0800169 ArgArray arg_array(NULL, 0);
170 uint32_t* args = arg_array.GetArray();
Elliott Hughes77405792012-03-15 15:22:12 -0700171 JValue result;
172
Jeff Hao5d917302013-02-27 17:57:33 -0800173 if (!is_static) {
174 arg_array.Append(reinterpret_cast<uint32_t>(receiver));
175 args++;
176 }
177
178 arg_array.Append(0);
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700179 result.SetI(-1);
Sebastien Hertzb95851f2013-03-29 10:36:40 +0100180 method->Invoke(Thread::Current(), arg_array.GetArray(), arg_array.GetNumBytes(), &result, 'I');
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700181 EXPECT_EQ(0, result.GetI());
Elliott Hughes77405792012-03-15 15:22:12 -0700182
Jeff Hao5d917302013-02-27 17:57:33 -0800183 args[0] = -1;
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700184 result.SetI(0);
Sebastien Hertzb95851f2013-03-29 10:36:40 +0100185 method->Invoke(Thread::Current(), arg_array.GetArray(), arg_array.GetNumBytes(), &result, 'I');
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700186 EXPECT_EQ(-1, result.GetI());
Elliott Hughes77405792012-03-15 15:22:12 -0700187
Jeff Hao5d917302013-02-27 17:57:33 -0800188 args[0] = INT_MAX;
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700189 result.SetI(0);
Sebastien Hertzb95851f2013-03-29 10:36:40 +0100190 method->Invoke(Thread::Current(), arg_array.GetArray(), arg_array.GetNumBytes(), &result, 'I');
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700191 EXPECT_EQ(INT_MAX, result.GetI());
Elliott Hughes77405792012-03-15 15:22:12 -0700192
Jeff Hao5d917302013-02-27 17:57:33 -0800193 args[0] = INT_MIN;
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700194 result.SetI(0);
Sebastien Hertzb95851f2013-03-29 10:36:40 +0100195 method->Invoke(Thread::Current(), arg_array.GetArray(), arg_array.GetNumBytes(), &result, 'I');
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700196 EXPECT_EQ(INT_MIN, result.GetI());
Elliott Hughes77405792012-03-15 15:22:12 -0700197 }
198
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700199 void InvokeIdentityDoubleMethod(bool is_static)
Ian Rogersb726dcb2012-09-05 08:57:23 -0700200 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800201 mirror::AbstractMethod* method;
202 mirror::Object* receiver;
Jeff Hao5d917302013-02-27 17:57:33 -0800203 DoCompile(method, receiver, is_static, "identity", "(D)D");
Elliott Hughes77405792012-03-15 15:22:12 -0700204
Jeff Hao5d917302013-02-27 17:57:33 -0800205 ArgArray arg_array(NULL, 0);
206 uint32_t* args = arg_array.GetArray();
207 JValue value;
Elliott Hughes77405792012-03-15 15:22:12 -0700208 JValue result;
209
Jeff Hao5d917302013-02-27 17:57:33 -0800210 if (!is_static) {
211 arg_array.Append(reinterpret_cast<uint32_t>(receiver));
212 args++;
213 }
214
215 value.SetD(0.0);
216 arg_array.AppendWide(value.GetJ());
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700217 result.SetD(-1.0);
Sebastien Hertzb95851f2013-03-29 10:36:40 +0100218 method->Invoke(Thread::Current(), arg_array.GetArray(), arg_array.GetNumBytes(), &result, 'D');
Jeff Hao6474d192013-03-26 14:08:09 -0700219 EXPECT_EQ(0.0, result.GetD());
Elliott Hughes77405792012-03-15 15:22:12 -0700220
Jeff Hao5d917302013-02-27 17:57:33 -0800221 value.SetD(-1.0);
222 args[0] = value.GetJ();
223 args[1] = value.GetJ() >> 32;
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700224 result.SetD(0.0);
Sebastien Hertzb95851f2013-03-29 10:36:40 +0100225 method->Invoke(Thread::Current(), arg_array.GetArray(), arg_array.GetNumBytes(), &result, 'D');
Jeff Hao6474d192013-03-26 14:08:09 -0700226 EXPECT_EQ(-1.0, result.GetD());
Elliott Hughes77405792012-03-15 15:22:12 -0700227
Jeff Hao5d917302013-02-27 17:57:33 -0800228 value.SetD(DBL_MAX);
229 args[0] = value.GetJ();
230 args[1] = value.GetJ() >> 32;
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700231 result.SetD(0.0);
Sebastien Hertzb95851f2013-03-29 10:36:40 +0100232 method->Invoke(Thread::Current(), arg_array.GetArray(), arg_array.GetNumBytes(), &result, 'D');
Jeff Hao6474d192013-03-26 14:08:09 -0700233 EXPECT_EQ(DBL_MAX, result.GetD());
Elliott Hughes77405792012-03-15 15:22:12 -0700234
Jeff Hao5d917302013-02-27 17:57:33 -0800235 value.SetD(DBL_MIN);
236 args[0] = value.GetJ();
237 args[1] = value.GetJ() >> 32;
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700238 result.SetD(0.0);
Sebastien Hertzb95851f2013-03-29 10:36:40 +0100239 method->Invoke(Thread::Current(), arg_array.GetArray(), arg_array.GetNumBytes(), &result, 'D');
Jeff Hao6474d192013-03-26 14:08:09 -0700240 EXPECT_EQ(DBL_MIN, result.GetD());
Elliott Hughes77405792012-03-15 15:22:12 -0700241 }
242
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700243 void InvokeSumIntIntMethod(bool is_static)
Ian Rogersb726dcb2012-09-05 08:57:23 -0700244 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800245 mirror::AbstractMethod* method;
246 mirror::Object* receiver;
Jeff Hao5d917302013-02-27 17:57:33 -0800247 DoCompile(method, receiver, is_static, "sum", "(II)I");
Elliott Hughes77405792012-03-15 15:22:12 -0700248
Jeff Hao5d917302013-02-27 17:57:33 -0800249 ArgArray arg_array(NULL, 0);
250 uint32_t* args = arg_array.GetArray();
Elliott Hughes77405792012-03-15 15:22:12 -0700251 JValue result;
Jeff Hao5d917302013-02-27 17:57:33 -0800252
253 if (!is_static) {
254 arg_array.Append(reinterpret_cast<uint32_t>(receiver));
255 args++;
256 }
257
258 arg_array.Append(0);
259 arg_array.Append(0);
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700260 result.SetI(-1);
Sebastien Hertzb95851f2013-03-29 10:36:40 +0100261 method->Invoke(Thread::Current(), arg_array.GetArray(), arg_array.GetNumBytes(), &result, 'I');
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700262 EXPECT_EQ(0, result.GetI());
Elliott Hughes77405792012-03-15 15:22:12 -0700263
Jeff Hao5d917302013-02-27 17:57:33 -0800264 args[0] = 1;
265 args[1] = 2;
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700266 result.SetI(0);
Sebastien Hertzb95851f2013-03-29 10:36:40 +0100267 method->Invoke(Thread::Current(), arg_array.GetArray(), arg_array.GetNumBytes(), &result, 'I');
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700268 EXPECT_EQ(3, result.GetI());
Elliott Hughes77405792012-03-15 15:22:12 -0700269
Jeff Hao5d917302013-02-27 17:57:33 -0800270 args[0] = -2;
271 args[1] = 5;
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700272 result.SetI(0);
Sebastien Hertzb95851f2013-03-29 10:36:40 +0100273 method->Invoke(Thread::Current(), arg_array.GetArray(), arg_array.GetNumBytes(), &result, 'I');
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700274 EXPECT_EQ(3, result.GetI());
Elliott Hughes77405792012-03-15 15:22:12 -0700275
Jeff Hao5d917302013-02-27 17:57:33 -0800276 args[0] = INT_MAX;
277 args[1] = INT_MIN;
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700278 result.SetI(1234);
Sebastien Hertzb95851f2013-03-29 10:36:40 +0100279 method->Invoke(Thread::Current(), arg_array.GetArray(), arg_array.GetNumBytes(), &result, 'I');
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700280 EXPECT_EQ(-1, result.GetI());
Elliott Hughes77405792012-03-15 15:22:12 -0700281
Jeff Hao5d917302013-02-27 17:57:33 -0800282 args[0] = INT_MAX;
283 args[1] = INT_MAX;
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700284 result.SetI(INT_MIN);
Sebastien Hertzb95851f2013-03-29 10:36:40 +0100285 method->Invoke(Thread::Current(), arg_array.GetArray(), arg_array.GetNumBytes(), &result, 'I');
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700286 EXPECT_EQ(-2, result.GetI());
Elliott Hughes77405792012-03-15 15:22:12 -0700287 }
288
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700289 void InvokeSumIntIntIntMethod(bool is_static)
Ian Rogersb726dcb2012-09-05 08:57:23 -0700290 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800291 mirror::AbstractMethod* method;
292 mirror::Object* receiver;
Jeff Hao5d917302013-02-27 17:57:33 -0800293 DoCompile(method, receiver, is_static, "sum", "(III)I");
Elliott Hughes77405792012-03-15 15:22:12 -0700294
Jeff Hao5d917302013-02-27 17:57:33 -0800295 ArgArray arg_array(NULL, 0);
296 uint32_t* args = arg_array.GetArray();
Elliott Hughes77405792012-03-15 15:22:12 -0700297 JValue result;
Jeff Hao5d917302013-02-27 17:57:33 -0800298
299 if (!is_static) {
300 arg_array.Append(reinterpret_cast<uint32_t>(receiver));
301 args++;
302 }
303
304 arg_array.Append(0);
305 arg_array.Append(0);
306 arg_array.Append(0);
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700307 result.SetI(-1);
Sebastien Hertzb95851f2013-03-29 10:36:40 +0100308 method->Invoke(Thread::Current(), arg_array.GetArray(), arg_array.GetNumBytes(), &result, 'I');
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700309 EXPECT_EQ(0, result.GetI());
Elliott Hughes77405792012-03-15 15:22:12 -0700310
Jeff Hao5d917302013-02-27 17:57:33 -0800311 args[0] = 1;
312 args[1] = 2;
313 args[2] = 3;
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700314 result.SetI(0);
Sebastien Hertzb95851f2013-03-29 10:36:40 +0100315 method->Invoke(Thread::Current(), arg_array.GetArray(), arg_array.GetNumBytes(), &result, 'I');
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700316 EXPECT_EQ(6, result.GetI());
Elliott Hughes77405792012-03-15 15:22:12 -0700317
Jeff Hao5d917302013-02-27 17:57:33 -0800318 args[0] = -1;
319 args[1] = 2;
320 args[2] = -3;
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700321 result.SetI(0);
Sebastien Hertzb95851f2013-03-29 10:36:40 +0100322 method->Invoke(Thread::Current(), arg_array.GetArray(), arg_array.GetNumBytes(), &result, 'I');
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700323 EXPECT_EQ(-2, result.GetI());
Elliott Hughes77405792012-03-15 15:22:12 -0700324
Jeff Hao5d917302013-02-27 17:57:33 -0800325 args[0] = INT_MAX;
326 args[1] = INT_MIN;
327 args[2] = INT_MAX;
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700328 result.SetI(1234);
Sebastien Hertzb95851f2013-03-29 10:36:40 +0100329 method->Invoke(Thread::Current(), arg_array.GetArray(), arg_array.GetNumBytes(), &result, 'I');
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700330 EXPECT_EQ(2147483646, result.GetI());
Elliott Hughes77405792012-03-15 15:22:12 -0700331
Jeff Hao5d917302013-02-27 17:57:33 -0800332 args[0] = INT_MAX;
333 args[1] = INT_MAX;
334 args[2] = INT_MAX;
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700335 result.SetI(INT_MIN);
Sebastien Hertzb95851f2013-03-29 10:36:40 +0100336 method->Invoke(Thread::Current(), arg_array.GetArray(), arg_array.GetNumBytes(), &result, 'I');
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700337 EXPECT_EQ(2147483645, result.GetI());
Elliott Hughes77405792012-03-15 15:22:12 -0700338 }
339
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700340 void InvokeSumIntIntIntIntMethod(bool is_static)
Ian Rogersb726dcb2012-09-05 08:57:23 -0700341 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800342 mirror::AbstractMethod* method;
343 mirror::Object* receiver;
Jeff Hao5d917302013-02-27 17:57:33 -0800344 DoCompile(method, receiver, is_static, "sum", "(IIII)I");
Elliott Hughes77405792012-03-15 15:22:12 -0700345
Jeff Hao5d917302013-02-27 17:57:33 -0800346 ArgArray arg_array(NULL, 0);
347 uint32_t* args = arg_array.GetArray();
Elliott Hughes77405792012-03-15 15:22:12 -0700348 JValue result;
Jeff Hao5d917302013-02-27 17:57:33 -0800349
350 if (!is_static) {
351 arg_array.Append(reinterpret_cast<uint32_t>(receiver));
352 args++;
353 }
354
355 arg_array.Append(0);
356 arg_array.Append(0);
357 arg_array.Append(0);
358 arg_array.Append(0);
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700359 result.SetI(-1);
Sebastien Hertzb95851f2013-03-29 10:36:40 +0100360 method->Invoke(Thread::Current(), arg_array.GetArray(), arg_array.GetNumBytes(), &result, 'I');
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700361 EXPECT_EQ(0, result.GetI());
Elliott Hughes77405792012-03-15 15:22:12 -0700362
Jeff Hao5d917302013-02-27 17:57:33 -0800363 args[0] = 1;
364 args[1] = 2;
365 args[2] = 3;
366 args[3] = 4;
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700367 result.SetI(0);
Sebastien Hertzb95851f2013-03-29 10:36:40 +0100368 method->Invoke(Thread::Current(), arg_array.GetArray(), arg_array.GetNumBytes(), &result, 'I');
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700369 EXPECT_EQ(10, result.GetI());
Elliott Hughes77405792012-03-15 15:22:12 -0700370
Jeff Hao5d917302013-02-27 17:57:33 -0800371 args[0] = -1;
372 args[1] = 2;
373 args[2] = -3;
374 args[3] = 4;
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700375 result.SetI(0);
Sebastien Hertzb95851f2013-03-29 10:36:40 +0100376 method->Invoke(Thread::Current(), arg_array.GetArray(), arg_array.GetNumBytes(), &result, 'I');
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700377 EXPECT_EQ(2, result.GetI());
Elliott Hughes77405792012-03-15 15:22:12 -0700378
Jeff Hao5d917302013-02-27 17:57:33 -0800379 args[0] = INT_MAX;
380 args[1] = INT_MIN;
381 args[2] = INT_MAX;
382 args[3] = INT_MIN;
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700383 result.SetI(1234);
Sebastien Hertzb95851f2013-03-29 10:36:40 +0100384 method->Invoke(Thread::Current(), arg_array.GetArray(), arg_array.GetNumBytes(), &result, 'I');
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700385 EXPECT_EQ(-2, result.GetI());
Elliott Hughes77405792012-03-15 15:22:12 -0700386
Jeff Hao5d917302013-02-27 17:57:33 -0800387 args[0] = INT_MAX;
388 args[1] = INT_MAX;
389 args[2] = INT_MAX;
390 args[3] = INT_MAX;
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700391 result.SetI(INT_MIN);
Sebastien Hertzb95851f2013-03-29 10:36:40 +0100392 method->Invoke(Thread::Current(), arg_array.GetArray(), arg_array.GetNumBytes(), &result, 'I');
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700393 EXPECT_EQ(-4, result.GetI());
Elliott Hughes77405792012-03-15 15:22:12 -0700394 }
395
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700396 void InvokeSumIntIntIntIntIntMethod(bool is_static)
Ian Rogersb726dcb2012-09-05 08:57:23 -0700397 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800398 mirror::AbstractMethod* method;
399 mirror::Object* receiver;
Jeff Hao5d917302013-02-27 17:57:33 -0800400 DoCompile(method, receiver, is_static, "sum", "(IIIII)I");
Elliott Hughes77405792012-03-15 15:22:12 -0700401
Jeff Hao5d917302013-02-27 17:57:33 -0800402 ArgArray arg_array(NULL, 0);
403 uint32_t* args = arg_array.GetArray();
Elliott Hughes77405792012-03-15 15:22:12 -0700404 JValue result;
Jeff Hao5d917302013-02-27 17:57:33 -0800405
406 if (!is_static) {
407 arg_array.Append(reinterpret_cast<uint32_t>(receiver));
408 args++;
409 }
410
411 arg_array.Append(0);
412 arg_array.Append(0);
413 arg_array.Append(0);
414 arg_array.Append(0);
415 arg_array.Append(0);
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700416 result.SetI(-1.0);
Sebastien Hertzb95851f2013-03-29 10:36:40 +0100417 method->Invoke(Thread::Current(), arg_array.GetArray(), arg_array.GetNumBytes(), &result, 'I');
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700418 EXPECT_EQ(0, result.GetI());
Elliott Hughes77405792012-03-15 15:22:12 -0700419
Jeff Hao5d917302013-02-27 17:57:33 -0800420 args[0] = 1;
421 args[1] = 2;
422 args[2] = 3;
423 args[3] = 4;
424 args[4] = 5;
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700425 result.SetI(0);
Sebastien Hertzb95851f2013-03-29 10:36:40 +0100426 method->Invoke(Thread::Current(), arg_array.GetArray(), arg_array.GetNumBytes(), &result, 'I');
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700427 EXPECT_EQ(15, result.GetI());
Elliott Hughes77405792012-03-15 15:22:12 -0700428
Jeff Hao5d917302013-02-27 17:57:33 -0800429 args[0] = -1;
430 args[1] = 2;
431 args[2] = -3;
432 args[3] = 4;
433 args[4] = -5;
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700434 result.SetI(0);
Sebastien Hertzb95851f2013-03-29 10:36:40 +0100435 method->Invoke(Thread::Current(), arg_array.GetArray(), arg_array.GetNumBytes(), &result, 'I');
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700436 EXPECT_EQ(-3, result.GetI());
Elliott Hughes77405792012-03-15 15:22:12 -0700437
Jeff Hao5d917302013-02-27 17:57:33 -0800438 args[0] = INT_MAX;
439 args[1] = INT_MIN;
440 args[2] = INT_MAX;
441 args[3] = INT_MIN;
442 args[4] = INT_MAX;
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700443 result.SetI(1234);
Sebastien Hertzb95851f2013-03-29 10:36:40 +0100444 method->Invoke(Thread::Current(), arg_array.GetArray(), arg_array.GetNumBytes(), &result, 'I');
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700445 EXPECT_EQ(2147483645, result.GetI());
Elliott Hughes77405792012-03-15 15:22:12 -0700446
Jeff Hao5d917302013-02-27 17:57:33 -0800447 args[0] = INT_MAX;
448 args[1] = INT_MAX;
449 args[2] = INT_MAX;
450 args[3] = INT_MAX;
451 args[4] = INT_MAX;
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700452 result.SetI(INT_MIN);
Sebastien Hertzb95851f2013-03-29 10:36:40 +0100453 method->Invoke(Thread::Current(), arg_array.GetArray(), arg_array.GetNumBytes(), &result, 'I');
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700454 EXPECT_EQ(2147483643, result.GetI());
Elliott Hughes77405792012-03-15 15:22:12 -0700455 }
456
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700457 void InvokeSumDoubleDoubleMethod(bool is_static)
Ian Rogersb726dcb2012-09-05 08:57:23 -0700458 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800459 mirror::AbstractMethod* method;
460 mirror::Object* receiver;
Jeff Hao5d917302013-02-27 17:57:33 -0800461 DoCompile(method, receiver, is_static, "sum", "(DD)D");
Elliott Hughes77405792012-03-15 15:22:12 -0700462
Jeff Hao5d917302013-02-27 17:57:33 -0800463 ArgArray arg_array(NULL, 0);
464 uint32_t* args = arg_array.GetArray();
465 JValue value;
466 JValue value2;
Elliott Hughes77405792012-03-15 15:22:12 -0700467 JValue result;
468
Jeff Hao5d917302013-02-27 17:57:33 -0800469 if (!is_static) {
470 arg_array.Append(reinterpret_cast<uint32_t>(receiver));
471 args++;
472 }
473
474 value.SetD(0.0);
475 value2.SetD(0.0);
476 arg_array.AppendWide(value.GetJ());
477 arg_array.AppendWide(value2.GetJ());
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700478 result.SetD(-1.0);
Sebastien Hertzb95851f2013-03-29 10:36:40 +0100479 method->Invoke(Thread::Current(), arg_array.GetArray(), arg_array.GetNumBytes(), &result, 'D');
Jeff Hao6474d192013-03-26 14:08:09 -0700480 EXPECT_EQ(0.0, result.GetD());
Elliott Hughes77405792012-03-15 15:22:12 -0700481
Jeff Hao5d917302013-02-27 17:57:33 -0800482 value.SetD(1.0);
483 value2.SetD(2.0);
484 args[0] = value.GetJ();
485 args[1] = value.GetJ() >> 32;
486 args[2] = value2.GetJ();
487 args[3] = value2.GetJ() >> 32;
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700488 result.SetD(0.0);
Sebastien Hertzb95851f2013-03-29 10:36:40 +0100489 method->Invoke(Thread::Current(), arg_array.GetArray(), arg_array.GetNumBytes(), &result, 'D');
Jeff Hao6474d192013-03-26 14:08:09 -0700490 EXPECT_EQ(3.0, result.GetD());
Elliott Hughes77405792012-03-15 15:22:12 -0700491
Jeff Hao5d917302013-02-27 17:57:33 -0800492 value.SetD(1.0);
493 value2.SetD(-2.0);
494 args[0] = value.GetJ();
495 args[1] = value.GetJ() >> 32;
496 args[2] = value2.GetJ();
497 args[3] = value2.GetJ() >> 32;
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700498 result.SetD(0.0);
Sebastien Hertzb95851f2013-03-29 10:36:40 +0100499 method->Invoke(Thread::Current(), arg_array.GetArray(), arg_array.GetNumBytes(), &result, 'D');
Jeff Hao6474d192013-03-26 14:08:09 -0700500 EXPECT_EQ(-1.0, result.GetD());
Elliott Hughes77405792012-03-15 15:22:12 -0700501
Jeff Hao5d917302013-02-27 17:57:33 -0800502 value.SetD(DBL_MAX);
503 value2.SetD(DBL_MIN);
504 args[0] = value.GetJ();
505 args[1] = value.GetJ() >> 32;
506 args[2] = value2.GetJ();
507 args[3] = value2.GetJ() >> 32;
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700508 result.SetD(0.0);
Sebastien Hertzb95851f2013-03-29 10:36:40 +0100509 method->Invoke(Thread::Current(), arg_array.GetArray(), arg_array.GetNumBytes(), &result, 'D');
Jeff Hao6474d192013-03-26 14:08:09 -0700510 EXPECT_EQ(1.7976931348623157e308, result.GetD());
Elliott Hughes77405792012-03-15 15:22:12 -0700511
Jeff Hao5d917302013-02-27 17:57:33 -0800512 value.SetD(DBL_MAX);
513 value2.SetD(DBL_MAX);
514 args[0] = value.GetJ();
515 args[1] = value.GetJ() >> 32;
516 args[2] = value2.GetJ();
517 args[3] = value2.GetJ() >> 32;
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700518 result.SetD(0.0);
Sebastien Hertzb95851f2013-03-29 10:36:40 +0100519 method->Invoke(Thread::Current(), arg_array.GetArray(), arg_array.GetNumBytes(), &result, 'D');
Jeff Hao6474d192013-03-26 14:08:09 -0700520 EXPECT_EQ(INFINITY, result.GetD());
Elliott Hughes77405792012-03-15 15:22:12 -0700521 }
522
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700523 void InvokeSumDoubleDoubleDoubleMethod(bool is_static)
Ian Rogersb726dcb2012-09-05 08:57:23 -0700524 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800525 mirror::AbstractMethod* method;
526 mirror::Object* receiver;
Jeff Hao5d917302013-02-27 17:57:33 -0800527 DoCompile(method, receiver, is_static, "sum", "(DDD)D");
Elliott Hughes77405792012-03-15 15:22:12 -0700528
Jeff Hao5d917302013-02-27 17:57:33 -0800529 ArgArray arg_array(NULL, 0);
530 uint32_t* args = arg_array.GetArray();
531 JValue value;
532 JValue value2;
533 JValue value3;
Elliott Hughes77405792012-03-15 15:22:12 -0700534 JValue result;
535
Jeff Hao5d917302013-02-27 17:57:33 -0800536 if (!is_static) {
537 arg_array.Append(reinterpret_cast<uint32_t>(receiver));
538 args++;
539 }
540
541 value.SetD(0.0);
542 value2.SetD(0.0);
543 value3.SetD(0.0);
544 arg_array.AppendWide(value.GetJ());
545 arg_array.AppendWide(value2.GetJ());
546 arg_array.AppendWide(value3.GetJ());
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700547 result.SetD(-1.0);
Sebastien Hertzb95851f2013-03-29 10:36:40 +0100548 method->Invoke(Thread::Current(), arg_array.GetArray(), arg_array.GetNumBytes(), &result, 'D');
Jeff Hao6474d192013-03-26 14:08:09 -0700549 EXPECT_EQ(0.0, result.GetD());
Elliott Hughes77405792012-03-15 15:22:12 -0700550
Jeff Hao5d917302013-02-27 17:57:33 -0800551 value.SetD(1.0);
552 value2.SetD(2.0);
553 value3.SetD(3.0);
554 args[0] = value.GetJ();
555 args[1] = value.GetJ() >> 32;
556 args[2] = value2.GetJ();
557 args[3] = value2.GetJ() >> 32;
558 args[4] = value3.GetJ();
559 args[5] = value3.GetJ() >> 32;
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700560 result.SetD(0.0);
Sebastien Hertzb95851f2013-03-29 10:36:40 +0100561 method->Invoke(Thread::Current(), arg_array.GetArray(), arg_array.GetNumBytes(), &result, 'D');
Jeff Hao6474d192013-03-26 14:08:09 -0700562 EXPECT_EQ(6.0, result.GetD());
Elliott Hughes77405792012-03-15 15:22:12 -0700563
Jeff Hao5d917302013-02-27 17:57:33 -0800564 value.SetD(1.0);
565 value2.SetD(-2.0);
566 value3.SetD(3.0);
567 args[0] = value.GetJ();
568 args[1] = value.GetJ() >> 32;
569 args[2] = value2.GetJ();
570 args[3] = value2.GetJ() >> 32;
571 args[4] = value3.GetJ();
572 args[5] = value3.GetJ() >> 32;
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700573 result.SetD(0.0);
Sebastien Hertzb95851f2013-03-29 10:36:40 +0100574 method->Invoke(Thread::Current(), arg_array.GetArray(), arg_array.GetNumBytes(), &result, 'D');
Jeff Hao6474d192013-03-26 14:08:09 -0700575 EXPECT_EQ(2.0, result.GetD());
Elliott Hughes77405792012-03-15 15:22:12 -0700576 }
577
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700578 void InvokeSumDoubleDoubleDoubleDoubleMethod(bool is_static)
Ian Rogersb726dcb2012-09-05 08:57:23 -0700579 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800580 mirror::AbstractMethod* method;
581 mirror::Object* receiver;
Jeff Hao5d917302013-02-27 17:57:33 -0800582 DoCompile(method, receiver, is_static, "sum", "(DDDD)D");
Elliott Hughes77405792012-03-15 15:22:12 -0700583
Jeff Hao5d917302013-02-27 17:57:33 -0800584 ArgArray arg_array(NULL, 0);
585 uint32_t* args = arg_array.GetArray();
586 JValue value;
587 JValue value2;
588 JValue value3;
589 JValue value4;
Elliott Hughes77405792012-03-15 15:22:12 -0700590 JValue result;
591
Jeff Hao5d917302013-02-27 17:57:33 -0800592 if (!is_static) {
593 arg_array.Append(reinterpret_cast<uint32_t>(receiver));
594 args++;
595 }
596
597 value.SetD(0.0);
598 value2.SetD(0.0);
599 value3.SetD(0.0);
600 value4.SetD(0.0);
601 arg_array.AppendWide(value.GetJ());
602 arg_array.AppendWide(value2.GetJ());
603 arg_array.AppendWide(value3.GetJ());
604 arg_array.AppendWide(value4.GetJ());
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700605 result.SetD(-1.0);
Sebastien Hertzb95851f2013-03-29 10:36:40 +0100606 method->Invoke(Thread::Current(), arg_array.GetArray(), arg_array.GetNumBytes(), &result, 'D');
Jeff Hao6474d192013-03-26 14:08:09 -0700607 EXPECT_EQ(0.0, result.GetD());
Elliott Hughes77405792012-03-15 15:22:12 -0700608
Jeff Hao5d917302013-02-27 17:57:33 -0800609 value.SetD(1.0);
610 value2.SetD(2.0);
611 value3.SetD(3.0);
612 value4.SetD(4.0);
613 args[0] = value.GetJ();
614 args[1] = value.GetJ() >> 32;
615 args[2] = value2.GetJ();
616 args[3] = value2.GetJ() >> 32;
617 args[4] = value3.GetJ();
618 args[5] = value3.GetJ() >> 32;
619 args[6] = value4.GetJ();
620 args[7] = value4.GetJ() >> 32;
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700621 result.SetD(0.0);
Sebastien Hertzb95851f2013-03-29 10:36:40 +0100622 method->Invoke(Thread::Current(), arg_array.GetArray(), arg_array.GetNumBytes(), &result, 'D');
Jeff Hao6474d192013-03-26 14:08:09 -0700623 EXPECT_EQ(10.0, result.GetD());
Elliott Hughes77405792012-03-15 15:22:12 -0700624
Jeff Hao5d917302013-02-27 17:57:33 -0800625 value.SetD(1.0);
626 value2.SetD(-2.0);
627 value3.SetD(3.0);
628 value4.SetD(-4.0);
629 args[0] = value.GetJ();
630 args[1] = value.GetJ() >> 32;
631 args[2] = value2.GetJ();
632 args[3] = value2.GetJ() >> 32;
633 args[4] = value3.GetJ();
634 args[5] = value3.GetJ() >> 32;
635 args[6] = value4.GetJ();
636 args[7] = value4.GetJ() >> 32;
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700637 result.SetD(0.0);
Sebastien Hertzb95851f2013-03-29 10:36:40 +0100638 method->Invoke(Thread::Current(), arg_array.GetArray(), arg_array.GetNumBytes(), &result, 'D');
Jeff Hao6474d192013-03-26 14:08:09 -0700639 EXPECT_EQ(-2.0, result.GetD());
Elliott Hughes77405792012-03-15 15:22:12 -0700640 }
641
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700642 void InvokeSumDoubleDoubleDoubleDoubleDoubleMethod(bool is_static)
Ian Rogersb726dcb2012-09-05 08:57:23 -0700643 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800644 mirror::AbstractMethod* method;
645 mirror::Object* receiver;
Jeff Hao5d917302013-02-27 17:57:33 -0800646 DoCompile(method, receiver, is_static, "sum", "(DDDDD)D");
Elliott Hughes77405792012-03-15 15:22:12 -0700647
Jeff Hao5d917302013-02-27 17:57:33 -0800648 ArgArray arg_array(NULL, 0);
649 uint32_t* args = arg_array.GetArray();
650 JValue value;
651 JValue value2;
652 JValue value3;
653 JValue value4;
654 JValue value5;
Elliott Hughes77405792012-03-15 15:22:12 -0700655 JValue result;
656
Jeff Hao5d917302013-02-27 17:57:33 -0800657 if (!is_static) {
658 arg_array.Append(reinterpret_cast<uint32_t>(receiver));
659 args++;
660 }
661
662 value.SetD(0.0);
663 value2.SetD(0.0);
664 value3.SetD(0.0);
665 value4.SetD(0.0);
666 value5.SetD(0.0);
667 arg_array.AppendWide(value.GetJ());
668 arg_array.AppendWide(value2.GetJ());
669 arg_array.AppendWide(value3.GetJ());
670 arg_array.AppendWide(value4.GetJ());
671 arg_array.AppendWide(value5.GetJ());
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700672 result.SetD(-1.0);
Sebastien Hertzb95851f2013-03-29 10:36:40 +0100673 method->Invoke(Thread::Current(), arg_array.GetArray(), arg_array.GetNumBytes(), &result, 'D');
Jeff Hao6474d192013-03-26 14:08:09 -0700674 EXPECT_EQ(0.0, result.GetD());
Elliott Hughes77405792012-03-15 15:22:12 -0700675
Jeff Hao5d917302013-02-27 17:57:33 -0800676 value.SetD(1.0);
677 value2.SetD(2.0);
678 value3.SetD(3.0);
679 value4.SetD(4.0);
680 value5.SetD(5.0);
681 args[0] = value.GetJ();
682 args[1] = value.GetJ() >> 32;
683 args[2] = value2.GetJ();
684 args[3] = value2.GetJ() >> 32;
685 args[4] = value3.GetJ();
686 args[5] = value3.GetJ() >> 32;
687 args[6] = value4.GetJ();
688 args[7] = value4.GetJ() >> 32;
689 args[8] = value5.GetJ();
690 args[9] = value5.GetJ() >> 32;
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700691 result.SetD(0.0);
Sebastien Hertzb95851f2013-03-29 10:36:40 +0100692 method->Invoke(Thread::Current(), arg_array.GetArray(), arg_array.GetNumBytes(), &result, 'D');
Jeff Hao6474d192013-03-26 14:08:09 -0700693 EXPECT_EQ(15.0, result.GetD());
Elliott Hughes77405792012-03-15 15:22:12 -0700694
Jeff Hao5d917302013-02-27 17:57:33 -0800695 value.SetD(1.0);
696 value2.SetD(-2.0);
697 value3.SetD(3.0);
698 value4.SetD(-4.0);
699 value5.SetD(5.0);
700 args[0] = value.GetJ();
701 args[1] = value.GetJ() >> 32;
702 args[2] = value2.GetJ();
703 args[3] = value2.GetJ() >> 32;
704 args[4] = value3.GetJ();
705 args[5] = value3.GetJ() >> 32;
706 args[6] = value4.GetJ();
707 args[7] = value4.GetJ() >> 32;
708 args[8] = value5.GetJ();
709 args[9] = value5.GetJ() >> 32;
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700710 result.SetD(0.0);
Sebastien Hertzb95851f2013-03-29 10:36:40 +0100711 method->Invoke(Thread::Current(), arg_array.GetArray(), arg_array.GetNumBytes(), &result, 'D');
Jeff Hao6474d192013-03-26 14:08:09 -0700712 EXPECT_EQ(3.0, result.GetD());
Elliott Hughes77405792012-03-15 15:22:12 -0700713 }
714
Elliott Hughesa2501992011-08-26 19:39:54 -0700715 JavaVMExt* vm_;
Brian Carlstrom4d571432012-05-16 00:21:41 -0700716 JNIEnv* env_;
Elliott Hughes814e4032011-08-23 12:07:56 -0700717 jclass aioobe_;
Elliott Hughesb264f082012-04-06 17:10:10 -0700718 jclass ase_;
Elliott Hughesb465ab02011-08-24 11:21:21 -0700719 jclass sioobe_;
Elliott Hughes0c9cd562011-08-12 10:59:29 -0700720};
721
Elliott Hughes885c3bd2011-08-22 16:59:20 -0700722TEST_F(JniInternalTest, AllocObject) {
723 jclass c = env_->FindClass("java/lang/String");
724 ASSERT_TRUE(c != NULL);
725 jobject o = env_->AllocObject(c);
726 ASSERT_TRUE(o != NULL);
727
728 // We have an instance of the class we asked for...
729 ASSERT_TRUE(env_->IsInstanceOf(o, c));
730 // ...whose fields haven't been initialized because
731 // we didn't call a constructor.
732 ASSERT_EQ(0, env_->GetIntField(o, env_->GetFieldID(c, "count", "I")));
733 ASSERT_EQ(0, env_->GetIntField(o, env_->GetFieldID(c, "offset", "I")));
734 ASSERT_TRUE(env_->GetObjectField(o, env_->GetFieldID(c, "value", "[C")) == NULL);
735}
736
Elliott Hughesc7ac37f2011-08-12 12:21:58 -0700737TEST_F(JniInternalTest, GetVersion) {
738 ASSERT_EQ(JNI_VERSION_1_6, env_->GetVersion());
739}
740
Elliott Hughes0c9cd562011-08-12 10:59:29 -0700741#define EXPECT_CLASS_FOUND(NAME) \
Elliott Hughesbd935992011-08-22 11:59:34 -0700742 EXPECT_TRUE(env_->FindClass(NAME) != NULL); \
743 EXPECT_FALSE(env_->ExceptionCheck())
Elliott Hughes0c9cd562011-08-12 10:59:29 -0700744
745#define EXPECT_CLASS_NOT_FOUND(NAME) \
Elliott Hughesbd935992011-08-22 11:59:34 -0700746 EXPECT_TRUE(env_->FindClass(NAME) == NULL); \
747 EXPECT_TRUE(env_->ExceptionCheck()); \
748 env_->ExceptionClear()
Elliott Hughes0c9cd562011-08-12 10:59:29 -0700749
750TEST_F(JniInternalTest, FindClass) {
Elliott Hughes0c9cd562011-08-12 10:59:29 -0700751 // Reference types...
Elliott Hughes0c9cd562011-08-12 10:59:29 -0700752 EXPECT_CLASS_FOUND("java/lang/String");
Elliott Hughes0c9cd562011-08-12 10:59:29 -0700753 // ...for arrays too, where you must include "L;".
754 EXPECT_CLASS_FOUND("[Ljava/lang/String;");
Elliott Hughes3f6635a2012-06-19 13:37:49 -0700755 // Primitive arrays are okay too, if the primitive type is valid.
756 EXPECT_CLASS_FOUND("[C");
Elliott Hughesa2501992011-08-26 19:39:54 -0700757
Elliott Hughesb264f082012-04-06 17:10:10 -0700758 {
Elliott Hughesb264f082012-04-06 17:10:10 -0700759 // We support . as well as / for compatibility, if -Xcheck:jni is off.
Elliott Hughes3f6635a2012-06-19 13:37:49 -0700760 CheckJniAbortCatcher check_jni_abort_catcher;
Elliott Hughesb264f082012-04-06 17:10:10 -0700761 EXPECT_CLASS_FOUND("java.lang.String");
Elliott Hughes56ef0422012-06-19 14:35:04 -0700762 check_jni_abort_catcher.Check("illegal class name 'java.lang.String'");
Elliott Hughesb264f082012-04-06 17:10:10 -0700763 EXPECT_CLASS_NOT_FOUND("Ljava.lang.String;");
Elliott Hughes56ef0422012-06-19 14:35:04 -0700764 check_jni_abort_catcher.Check("illegal class name 'Ljava.lang.String;'");
Elliott Hughesb264f082012-04-06 17:10:10 -0700765 EXPECT_CLASS_FOUND("[Ljava.lang.String;");
Elliott Hughes56ef0422012-06-19 14:35:04 -0700766 check_jni_abort_catcher.Check("illegal class name '[Ljava.lang.String;'");
Elliott Hughesb264f082012-04-06 17:10:10 -0700767 EXPECT_CLASS_NOT_FOUND("[java.lang.String");
Elliott Hughes56ef0422012-06-19 14:35:04 -0700768 check_jni_abort_catcher.Check("illegal class name '[java.lang.String'");
Elliott Hughesb264f082012-04-06 17:10:10 -0700769
770 // You can't include the "L;" in a JNI class descriptor.
771 EXPECT_CLASS_NOT_FOUND("Ljava/lang/String;");
Elliott Hughes56ef0422012-06-19 14:35:04 -0700772 check_jni_abort_catcher.Check("illegal class name 'Ljava/lang/String;'");
Elliott Hughes3f6635a2012-06-19 13:37:49 -0700773
Elliott Hughesb264f082012-04-06 17:10:10 -0700774 // But you must include it for an array of any reference type.
775 EXPECT_CLASS_NOT_FOUND("[java/lang/String");
Elliott Hughes56ef0422012-06-19 14:35:04 -0700776 check_jni_abort_catcher.Check("illegal class name '[java/lang/String'");
Elliott Hughes3f6635a2012-06-19 13:37:49 -0700777
778 EXPECT_CLASS_NOT_FOUND("[K");
Elliott Hughes56ef0422012-06-19 14:35:04 -0700779 check_jni_abort_catcher.Check("illegal class name '[K'");
Elliott Hughesb264f082012-04-06 17:10:10 -0700780 }
Elliott Hughesa2501992011-08-26 19:39:54 -0700781
Elliott Hughes0c9cd562011-08-12 10:59:29 -0700782 // But primitive types aren't allowed...
783 EXPECT_CLASS_NOT_FOUND("C");
784 EXPECT_CLASS_NOT_FOUND("K");
785}
786
Elliott Hughescdf53122011-08-19 15:46:09 -0700787#define EXPECT_EXCEPTION(exception_class) \
788 do { \
789 EXPECT_TRUE(env_->ExceptionCheck()); \
790 jthrowable exception = env_->ExceptionOccurred(); \
791 EXPECT_NE(static_cast<jthrowable>(NULL), exception); \
Elliott Hughescdf53122011-08-19 15:46:09 -0700792 env_->ExceptionClear(); \
Elliott Hughesa2501992011-08-26 19:39:54 -0700793 EXPECT_TRUE(env_->IsInstanceOf(exception, exception_class)); \
Elliott Hughescdf53122011-08-19 15:46:09 -0700794 } while (false)
795
796TEST_F(JniInternalTest, GetFieldID) {
797 jclass jlnsfe = env_->FindClass("java/lang/NoSuchFieldError");
798 ASSERT_TRUE(jlnsfe != NULL);
799 jclass c = env_->FindClass("java/lang/String");
800 ASSERT_TRUE(c != NULL);
801
802 // Wrong type.
803 jfieldID fid = env_->GetFieldID(c, "count", "J");
804 EXPECT_EQ(static_cast<jfieldID>(NULL), fid);
805 EXPECT_EXCEPTION(jlnsfe);
806
Ian Rogersb17d08b2011-09-02 16:16:49 -0700807 // Wrong type where type doesn't exist.
808 fid = env_->GetFieldID(c, "count", "Lrod/jane/freddy;");
809 EXPECT_EQ(static_cast<jfieldID>(NULL), fid);
810 EXPECT_EXCEPTION(jlnsfe);
811
Elliott Hughescdf53122011-08-19 15:46:09 -0700812 // Wrong name.
813 fid = env_->GetFieldID(c, "Count", "I");
814 EXPECT_EQ(static_cast<jfieldID>(NULL), fid);
815 EXPECT_EXCEPTION(jlnsfe);
816
817 // Good declared field lookup.
818 fid = env_->GetFieldID(c, "count", "I");
819 EXPECT_NE(static_cast<jfieldID>(NULL), fid);
820 EXPECT_TRUE(fid != NULL);
821 EXPECT_FALSE(env_->ExceptionCheck());
822
823 // Good superclass field lookup.
824 c = env_->FindClass("java/lang/StringBuilder");
825 fid = env_->GetFieldID(c, "count", "I");
826 EXPECT_NE(static_cast<jfieldID>(NULL), fid);
827 EXPECT_TRUE(fid != NULL);
828 EXPECT_FALSE(env_->ExceptionCheck());
829
830 // Not instance.
831 fid = env_->GetFieldID(c, "CASE_INSENSITIVE_ORDER", "Ljava/util/Comparator;");
832 EXPECT_EQ(static_cast<jfieldID>(NULL), fid);
833 EXPECT_EXCEPTION(jlnsfe);
834}
835
836TEST_F(JniInternalTest, GetStaticFieldID) {
837 jclass jlnsfe = env_->FindClass("java/lang/NoSuchFieldError");
838 ASSERT_TRUE(jlnsfe != NULL);
839 jclass c = env_->FindClass("java/lang/String");
840 ASSERT_TRUE(c != NULL);
841
842 // Wrong type.
843 jfieldID fid = env_->GetStaticFieldID(c, "CASE_INSENSITIVE_ORDER", "J");
844 EXPECT_EQ(static_cast<jfieldID>(NULL), fid);
845 EXPECT_EXCEPTION(jlnsfe);
846
Ian Rogersb17d08b2011-09-02 16:16:49 -0700847 // Wrong type where type doesn't exist.
848 fid = env_->GetStaticFieldID(c, "CASE_INSENSITIVE_ORDER", "Lrod/jane/freddy;");
849 EXPECT_EQ(static_cast<jfieldID>(NULL), fid);
850 EXPECT_EXCEPTION(jlnsfe);
851
Elliott Hughescdf53122011-08-19 15:46:09 -0700852 // Wrong name.
853 fid = env_->GetStaticFieldID(c, "cASE_INSENSITIVE_ORDER", "Ljava/util/Comparator;");
854 EXPECT_EQ(static_cast<jfieldID>(NULL), fid);
855 EXPECT_EXCEPTION(jlnsfe);
856
857 // Good declared field lookup.
858 fid = env_->GetStaticFieldID(c, "CASE_INSENSITIVE_ORDER", "Ljava/util/Comparator;");
859 EXPECT_NE(static_cast<jfieldID>(NULL), fid);
860 EXPECT_TRUE(fid != NULL);
861 EXPECT_FALSE(env_->ExceptionCheck());
862
863 // Not static.
864 fid = env_->GetStaticFieldID(c, "count", "I");
865 EXPECT_EQ(static_cast<jfieldID>(NULL), fid);
866 EXPECT_EXCEPTION(jlnsfe);
867}
868
Ian Rogers4dd71f12011-08-16 14:16:02 -0700869TEST_F(JniInternalTest, GetMethodID) {
870 jclass jlobject = env_->FindClass("java/lang/Object");
871 jclass jlstring = env_->FindClass("java/lang/String");
872 jclass jlnsme = env_->FindClass("java/lang/NoSuchMethodError");
873
874 // Sanity check that no exceptions are pending
Elliott Hughescdf53122011-08-19 15:46:09 -0700875 ASSERT_FALSE(env_->ExceptionCheck());
Ian Rogers4dd71f12011-08-16 14:16:02 -0700876
877 // Check that java.lang.Object.foo() doesn't exist and NoSuchMethodError is
878 // a pending exception
879 jmethodID method = env_->GetMethodID(jlobject, "foo", "()V");
880 EXPECT_EQ(static_cast<jmethodID>(NULL), method);
Elliott Hughescdf53122011-08-19 15:46:09 -0700881 EXPECT_EXCEPTION(jlnsme);
Ian Rogers4dd71f12011-08-16 14:16:02 -0700882
883 // Check that java.lang.Object.equals() does exist
Ian Rogers4dd71f12011-08-16 14:16:02 -0700884 method = env_->GetMethodID(jlobject, "equals", "(Ljava/lang/Object;)Z");
885 EXPECT_NE(static_cast<jmethodID>(NULL), method);
886 EXPECT_FALSE(env_->ExceptionCheck());
Ian Rogers4dd71f12011-08-16 14:16:02 -0700887
888 // Check that GetMethodID for java.lang.String.valueOf(int) fails as the
889 // method is static
890 method = env_->GetMethodID(jlstring, "valueOf", "(I)Ljava/lang/String;");
891 EXPECT_EQ(static_cast<jmethodID>(NULL), method);
Elliott Hughescdf53122011-08-19 15:46:09 -0700892 EXPECT_EXCEPTION(jlnsme);
Ian Rogers4dd71f12011-08-16 14:16:02 -0700893}
894
895TEST_F(JniInternalTest, GetStaticMethodID) {
896 jclass jlobject = env_->FindClass("java/lang/Object");
897 jclass jlnsme = env_->FindClass("java/lang/NoSuchMethodError");
898
899 // Sanity check that no exceptions are pending
Elliott Hughescdf53122011-08-19 15:46:09 -0700900 ASSERT_FALSE(env_->ExceptionCheck());
Ian Rogers4dd71f12011-08-16 14:16:02 -0700901
902 // Check that java.lang.Object.foo() doesn't exist and NoSuchMethodError is
903 // a pending exception
904 jmethodID method = env_->GetStaticMethodID(jlobject, "foo", "()V");
905 EXPECT_EQ(static_cast<jmethodID>(NULL), method);
Elliott Hughescdf53122011-08-19 15:46:09 -0700906 EXPECT_EXCEPTION(jlnsme);
Ian Rogers4dd71f12011-08-16 14:16:02 -0700907
908 // Check that GetStaticMethodID for java.lang.Object.equals(Object) fails as
909 // the method is not static
910 method = env_->GetStaticMethodID(jlobject, "equals", "(Ljava/lang/Object;)Z");
911 EXPECT_EQ(static_cast<jmethodID>(NULL), method);
Elliott Hughescdf53122011-08-19 15:46:09 -0700912 EXPECT_EXCEPTION(jlnsme);
Ian Rogers4dd71f12011-08-16 14:16:02 -0700913
914 // Check that java.lang.String.valueOf(int) does exist
Ian Rogers4dd71f12011-08-16 14:16:02 -0700915 jclass jlstring = env_->FindClass("java/lang/String");
916 method = env_->GetStaticMethodID(jlstring, "valueOf",
917 "(I)Ljava/lang/String;");
918 EXPECT_NE(static_cast<jmethodID>(NULL), method);
919 EXPECT_FALSE(env_->ExceptionCheck());
Ian Rogers4dd71f12011-08-16 14:16:02 -0700920}
921
Elliott Hughescdf53122011-08-19 15:46:09 -0700922TEST_F(JniInternalTest, FromReflectedField_ToReflectedField) {
923 jclass jlrField = env_->FindClass("java/lang/reflect/Field");
924 jclass c = env_->FindClass("java/lang/String");
925 ASSERT_TRUE(c != NULL);
926 jfieldID fid = env_->GetFieldID(c, "count", "I");
927 ASSERT_TRUE(fid != NULL);
928 // Turn the fid into a java.lang.reflect.Field...
929 jobject field = env_->ToReflectedField(c, fid, JNI_FALSE);
930 ASSERT_TRUE(c != NULL);
931 ASSERT_TRUE(env_->IsInstanceOf(field, jlrField));
932 // ...and back again.
933 jfieldID fid2 = env_->FromReflectedField(field);
934 ASSERT_TRUE(fid2 != NULL);
935}
936
937TEST_F(JniInternalTest, FromReflectedMethod_ToReflectedMethod) {
938 jclass jlrMethod = env_->FindClass("java/lang/reflect/Method");
939 jclass c = env_->FindClass("java/lang/String");
940 ASSERT_TRUE(c != NULL);
941 jmethodID mid = env_->GetMethodID(c, "length", "()I");
942 ASSERT_TRUE(mid != NULL);
943 // Turn the mid into a java.lang.reflect.Method...
944 jobject method = env_->ToReflectedMethod(c, mid, JNI_FALSE);
945 ASSERT_TRUE(c != NULL);
946 ASSERT_TRUE(env_->IsInstanceOf(method, jlrMethod));
947 // ...and back again.
948 jmethodID mid2 = env_->FromReflectedMethod(method);
949 ASSERT_TRUE(mid2 != NULL);
950}
951
Elliott Hughes5174fe62011-08-23 15:12:35 -0700952void BogusMethod() {
953 // You can't pass NULL function pointers to RegisterNatives.
954}
955
Ian Rogers4dd71f12011-08-16 14:16:02 -0700956TEST_F(JniInternalTest, RegisterNatives) {
957 jclass jlobject = env_->FindClass("java/lang/Object");
958 jclass jlnsme = env_->FindClass("java/lang/NoSuchMethodError");
959
960 // Sanity check that no exceptions are pending
Elliott Hughescdf53122011-08-19 15:46:09 -0700961 ASSERT_FALSE(env_->ExceptionCheck());
Ian Rogers4dd71f12011-08-16 14:16:02 -0700962
963 // Check that registering to a non-existent java.lang.Object.foo() causes a
964 // NoSuchMethodError
965 {
Elliott Hughesb25c3f62012-03-26 16:35:06 -0700966 JNINativeMethod methods[] = { { "foo", "()V", NULL } };
Ian Rogers4dd71f12011-08-16 14:16:02 -0700967 env_->RegisterNatives(jlobject, methods, 1);
968 }
Elliott Hughescdf53122011-08-19 15:46:09 -0700969 EXPECT_EXCEPTION(jlnsme);
Ian Rogers4dd71f12011-08-16 14:16:02 -0700970
971 // Check that registering non-native methods causes a NoSuchMethodError
972 {
Elliott Hughesb25c3f62012-03-26 16:35:06 -0700973 JNINativeMethod methods[] = { { "equals", "(Ljava/lang/Object;)Z", NULL } };
Ian Rogers4dd71f12011-08-16 14:16:02 -0700974 env_->RegisterNatives(jlobject, methods, 1);
975 }
Elliott Hughescdf53122011-08-19 15:46:09 -0700976 EXPECT_EXCEPTION(jlnsme);
Ian Rogers4dd71f12011-08-16 14:16:02 -0700977
978 // Check that registering native methods is successful
979 {
Elliott Hughesb25c3f62012-03-26 16:35:06 -0700980 JNINativeMethod methods[] = { { "notify", "()V", reinterpret_cast<void*>(BogusMethod) } };
Ian Rogers4dd71f12011-08-16 14:16:02 -0700981 env_->RegisterNatives(jlobject, methods, 1);
982 }
983 EXPECT_FALSE(env_->ExceptionCheck());
Elliott Hughes5174fe62011-08-23 15:12:35 -0700984
985 env_->UnregisterNatives(jlobject);
Ian Rogers4dd71f12011-08-16 14:16:02 -0700986}
987
Elliott Hughes75770752011-08-24 17:52:38 -0700988#define EXPECT_PRIMITIVE_ARRAY(new_fn, get_region_fn, set_region_fn, get_elements_fn, release_elements_fn, scalar_type, expected_class_descriptor) \
Elliott Hughes814e4032011-08-23 12:07:56 -0700989 jsize size = 4; \
990 /* Allocate an array and check it has the right type and length. */ \
991 scalar_type ## Array a = env_->new_fn(size); \
992 EXPECT_TRUE(a != NULL); \
993 EXPECT_TRUE(env_->IsInstanceOf(a, env_->FindClass(expected_class_descriptor))); \
994 EXPECT_EQ(size, env_->GetArrayLength(a)); \
995 /* AIOOBE for negative start offset. */ \
996 env_->get_region_fn(a, -1, 1, NULL); \
997 EXPECT_EXCEPTION(aioobe_); \
998 env_->set_region_fn(a, -1, 1, NULL); \
999 EXPECT_EXCEPTION(aioobe_); \
1000 /* AIOOBE for negative length. */ \
1001 env_->get_region_fn(a, 0, -1, NULL); \
1002 EXPECT_EXCEPTION(aioobe_); \
1003 env_->set_region_fn(a, 0, -1, NULL); \
1004 EXPECT_EXCEPTION(aioobe_); \
1005 /* AIOOBE for buffer overrun. */ \
1006 env_->get_region_fn(a, size - 1, size, NULL); \
1007 EXPECT_EXCEPTION(aioobe_); \
1008 env_->set_region_fn(a, size - 1, size, NULL); \
1009 EXPECT_EXCEPTION(aioobe_); \
1010 /* Prepare a couple of buffers. */ \
Elliott Hughesee0fa762012-03-26 17:12:41 -07001011 UniquePtr<scalar_type[]> src_buf(new scalar_type[size]); \
1012 UniquePtr<scalar_type[]> dst_buf(new scalar_type[size]); \
Elliott Hughes814e4032011-08-23 12:07:56 -07001013 for (jsize i = 0; i < size; ++i) { src_buf[i] = scalar_type(i); } \
1014 for (jsize i = 0; i < size; ++i) { dst_buf[i] = scalar_type(-1); } \
1015 /* Copy all of src_buf onto the heap. */ \
Elliott Hughesee0fa762012-03-26 17:12:41 -07001016 env_->set_region_fn(a, 0, size, &src_buf[0]); \
Elliott Hughes814e4032011-08-23 12:07:56 -07001017 /* Copy back only part. */ \
1018 env_->get_region_fn(a, 1, size - 2, &dst_buf[1]); \
Elliott Hughesee0fa762012-03-26 17:12:41 -07001019 EXPECT_NE(memcmp(&src_buf[0], &dst_buf[0], size * sizeof(scalar_type)), 0) << "short copy equal"; \
Elliott Hughes814e4032011-08-23 12:07:56 -07001020 /* Copy the missing pieces. */ \
Elliott Hughesee0fa762012-03-26 17:12:41 -07001021 env_->get_region_fn(a, 0, 1, &dst_buf[0]); \
Elliott Hughes814e4032011-08-23 12:07:56 -07001022 env_->get_region_fn(a, size - 1, 1, &dst_buf[size - 1]); \
Elliott Hughesee0fa762012-03-26 17:12:41 -07001023 EXPECT_EQ(memcmp(&src_buf[0], &dst_buf[0], size * sizeof(scalar_type)), 0) << "fixed copy not equal"; \
Elliott Hughes814e4032011-08-23 12:07:56 -07001024 /* Copy back the whole array. */ \
Elliott Hughesee0fa762012-03-26 17:12:41 -07001025 env_->get_region_fn(a, 0, size, &dst_buf[0]); \
1026 EXPECT_EQ(memcmp(&src_buf[0], &dst_buf[0], size * sizeof(scalar_type)), 0) << "full copy not equal"; \
Elliott Hughes75770752011-08-24 17:52:38 -07001027 /* GetPrimitiveArrayCritical */ \
1028 void* v = env_->GetPrimitiveArrayCritical(a, NULL); \
Elliott Hughesee0fa762012-03-26 17:12:41 -07001029 EXPECT_EQ(memcmp(&src_buf[0], v, size * sizeof(scalar_type)), 0) << "GetPrimitiveArrayCritical not equal"; \
Elliott Hughes75770752011-08-24 17:52:38 -07001030 env_->ReleasePrimitiveArrayCritical(a, v, 0); \
1031 /* GetXArrayElements */ \
1032 scalar_type* xs = env_->get_elements_fn(a, NULL); \
Elliott Hughesee0fa762012-03-26 17:12:41 -07001033 EXPECT_EQ(memcmp(&src_buf[0], xs, size * sizeof(scalar_type)), 0) << # get_elements_fn " not equal"; \
Elliott Hughes75770752011-08-24 17:52:38 -07001034 env_->release_elements_fn(a, xs, 0); \
1035 EXPECT_EQ(reinterpret_cast<uintptr_t>(v), reinterpret_cast<uintptr_t>(xs))
Elliott Hughesbd935992011-08-22 11:59:34 -07001036
Elliott Hughes814e4032011-08-23 12:07:56 -07001037TEST_F(JniInternalTest, BooleanArrays) {
Elliott Hughes75770752011-08-24 17:52:38 -07001038 EXPECT_PRIMITIVE_ARRAY(NewBooleanArray, GetBooleanArrayRegion, SetBooleanArrayRegion, GetBooleanArrayElements, ReleaseBooleanArrayElements, jboolean, "[Z");
Elliott Hughes814e4032011-08-23 12:07:56 -07001039}
1040TEST_F(JniInternalTest, ByteArrays) {
Elliott Hughes75770752011-08-24 17:52:38 -07001041 EXPECT_PRIMITIVE_ARRAY(NewByteArray, GetByteArrayRegion, SetByteArrayRegion, GetByteArrayElements, ReleaseByteArrayElements, jbyte, "[B");
Elliott Hughes814e4032011-08-23 12:07:56 -07001042}
1043TEST_F(JniInternalTest, CharArrays) {
Elliott Hughes75770752011-08-24 17:52:38 -07001044 EXPECT_PRIMITIVE_ARRAY(NewCharArray, GetCharArrayRegion, SetCharArrayRegion, GetCharArrayElements, ReleaseCharArrayElements, jchar, "[C");
Elliott Hughes814e4032011-08-23 12:07:56 -07001045}
1046TEST_F(JniInternalTest, DoubleArrays) {
Elliott Hughes75770752011-08-24 17:52:38 -07001047 EXPECT_PRIMITIVE_ARRAY(NewDoubleArray, GetDoubleArrayRegion, SetDoubleArrayRegion, GetDoubleArrayElements, ReleaseDoubleArrayElements, jdouble, "[D");
Elliott Hughes814e4032011-08-23 12:07:56 -07001048}
1049TEST_F(JniInternalTest, FloatArrays) {
Elliott Hughes75770752011-08-24 17:52:38 -07001050 EXPECT_PRIMITIVE_ARRAY(NewFloatArray, GetFloatArrayRegion, SetFloatArrayRegion, GetFloatArrayElements, ReleaseFloatArrayElements, jfloat, "[F");
Elliott Hughes814e4032011-08-23 12:07:56 -07001051}
1052TEST_F(JniInternalTest, IntArrays) {
Elliott Hughes75770752011-08-24 17:52:38 -07001053 EXPECT_PRIMITIVE_ARRAY(NewIntArray, GetIntArrayRegion, SetIntArrayRegion, GetIntArrayElements, ReleaseIntArrayElements, jint, "[I");
Elliott Hughes814e4032011-08-23 12:07:56 -07001054}
1055TEST_F(JniInternalTest, LongArrays) {
Elliott Hughes75770752011-08-24 17:52:38 -07001056 EXPECT_PRIMITIVE_ARRAY(NewLongArray, GetLongArrayRegion, SetLongArrayRegion, GetLongArrayElements, ReleaseLongArrayElements, jlong, "[J");
Elliott Hughes814e4032011-08-23 12:07:56 -07001057}
1058TEST_F(JniInternalTest, ShortArrays) {
Elliott Hughes75770752011-08-24 17:52:38 -07001059 EXPECT_PRIMITIVE_ARRAY(NewShortArray, GetShortArrayRegion, SetShortArrayRegion, GetShortArrayElements, ReleaseShortArrayElements, jshort, "[S");
Elliott Hughesd8ddfd52011-08-15 14:32:53 -07001060}
1061
Elliott Hughesf2682d52011-08-15 16:37:04 -07001062TEST_F(JniInternalTest, NewObjectArray) {
1063 // TODO: death tests for negative array sizes.
1064
Elliott Hughesf2682d52011-08-15 16:37:04 -07001065 // TODO: check non-NULL initial elements.
1066
Elliott Hughesbd935992011-08-22 11:59:34 -07001067 jclass element_class = env_->FindClass("java/lang/String");
1068 ASSERT_TRUE(element_class != NULL);
1069 jclass array_class = env_->FindClass("[Ljava/lang/String;");
1070 ASSERT_TRUE(array_class != NULL);
Elliott Hughesf2682d52011-08-15 16:37:04 -07001071
Elliott Hughesbd935992011-08-22 11:59:34 -07001072 jobjectArray a;
Elliott Hughesf2682d52011-08-15 16:37:04 -07001073
Elliott Hughesbd935992011-08-22 11:59:34 -07001074 a = env_->NewObjectArray(0, element_class, NULL);
1075 EXPECT_TRUE(a != NULL);
1076 EXPECT_TRUE(env_->IsInstanceOf(a, array_class));
1077 EXPECT_EQ(0, env_->GetArrayLength(a));
1078
1079 a = env_->NewObjectArray(1, element_class, NULL);
1080 EXPECT_TRUE(a != NULL);
1081 EXPECT_TRUE(env_->IsInstanceOf(a, array_class));
1082 EXPECT_EQ(1, env_->GetArrayLength(a));
Elliott Hughes75770752011-08-24 17:52:38 -07001083 EXPECT_TRUE(env_->IsSameObject(env_->GetObjectArrayElement(a, 0), NULL));
1084
1085 jstring s = env_->NewStringUTF("poop");
1086 a = env_->NewObjectArray(2, element_class, s);
1087 EXPECT_TRUE(a != NULL);
1088 EXPECT_TRUE(env_->IsInstanceOf(a, array_class));
1089 EXPECT_EQ(2, env_->GetArrayLength(a));
1090 EXPECT_TRUE(env_->IsSameObject(env_->GetObjectArrayElement(a, 0), s));
1091 EXPECT_TRUE(env_->IsSameObject(env_->GetObjectArrayElement(a, 1), s));
Elliott Hughesbd935992011-08-22 11:59:34 -07001092}
1093
1094TEST_F(JniInternalTest, GetArrayLength) {
1095 // Already tested in NewObjectArray/NewPrimitiveArray.
Elliott Hughes8a26c5c2011-08-15 18:35:43 -07001096}
1097
Elliott Hughes37f7a402011-08-22 18:56:01 -07001098TEST_F(JniInternalTest, GetObjectClass) {
1099 jclass string_class = env_->FindClass("java/lang/String");
1100 ASSERT_TRUE(string_class != NULL);
1101 jclass class_class = env_->FindClass("java/lang/Class");
1102 ASSERT_TRUE(class_class != NULL);
1103
1104 jstring s = env_->NewStringUTF("poop");
1105 jclass c = env_->GetObjectClass(s);
1106 ASSERT_TRUE(env_->IsSameObject(string_class, c));
1107
1108 jclass c2 = env_->GetObjectClass(c);
1109 ASSERT_TRUE(env_->IsSameObject(class_class, env_->GetObjectClass(c2)));
1110}
1111
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001112TEST_F(JniInternalTest, GetSuperclass) {
1113 jclass object_class = env_->FindClass("java/lang/Object");
1114 ASSERT_TRUE(object_class != NULL);
1115 jclass string_class = env_->FindClass("java/lang/String");
1116 ASSERT_TRUE(string_class != NULL);
Ian Rogersdc180202012-01-29 14:47:29 -08001117 jclass runnable_interface = env_->FindClass("java/lang/Runnable");
1118 ASSERT_TRUE(runnable_interface != NULL);
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001119 ASSERT_TRUE(env_->IsSameObject(object_class, env_->GetSuperclass(string_class)));
1120 ASSERT_TRUE(env_->GetSuperclass(object_class) == NULL);
Ian Rogersdc180202012-01-29 14:47:29 -08001121 ASSERT_TRUE(env_->IsSameObject(object_class, env_->GetSuperclass(runnable_interface)));
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001122}
1123
Elliott Hughes37f7a402011-08-22 18:56:01 -07001124TEST_F(JniInternalTest, IsAssignableFrom) {
1125 jclass object_class = env_->FindClass("java/lang/Object");
1126 ASSERT_TRUE(object_class != NULL);
1127 jclass string_class = env_->FindClass("java/lang/String");
1128 ASSERT_TRUE(string_class != NULL);
1129
1130 ASSERT_TRUE(env_->IsAssignableFrom(object_class, string_class));
1131 ASSERT_FALSE(env_->IsAssignableFrom(string_class, object_class));
1132}
1133
Elliott Hughesb465ab02011-08-24 11:21:21 -07001134TEST_F(JniInternalTest, GetObjectRefType) {
1135 jclass local = env_->FindClass("java/lang/Object");
1136 ASSERT_TRUE(local != NULL);
1137 EXPECT_EQ(JNILocalRefType, env_->GetObjectRefType(local));
1138
1139 jobject global = env_->NewGlobalRef(local);
1140 EXPECT_EQ(JNIGlobalRefType, env_->GetObjectRefType(global));
1141
1142 jweak weak_global = env_->NewWeakGlobalRef(local);
1143 EXPECT_EQ(JNIWeakGlobalRefType, env_->GetObjectRefType(weak_global));
1144
1145 jobject invalid = reinterpret_cast<jobject>(this);
1146 EXPECT_EQ(JNIInvalidRefType, env_->GetObjectRefType(invalid));
1147
1148 // TODO: invoke a native method and test that its arguments are considered local references.
1149}
1150
Elliott Hughes8a26c5c2011-08-15 18:35:43 -07001151TEST_F(JniInternalTest, NewStringUTF) {
1152 EXPECT_TRUE(env_->NewStringUTF(NULL) == NULL);
Elliott Hughes814e4032011-08-23 12:07:56 -07001153 jstring s;
1154
1155 s = env_->NewStringUTF("");
1156 EXPECT_TRUE(s != NULL);
1157 EXPECT_EQ(0, env_->GetStringLength(s));
1158 EXPECT_EQ(0, env_->GetStringUTFLength(s));
1159 s = env_->NewStringUTF("hello");
1160 EXPECT_TRUE(s != NULL);
1161 EXPECT_EQ(5, env_->GetStringLength(s));
1162 EXPECT_EQ(5, env_->GetStringUTFLength(s));
1163
Elliott Hughes8a26c5c2011-08-15 18:35:43 -07001164 // TODO: check some non-ASCII strings.
Elliott Hughesf2682d52011-08-15 16:37:04 -07001165}
1166
Elliott Hughes814e4032011-08-23 12:07:56 -07001167TEST_F(JniInternalTest, NewString) {
Elliott Hughes814e4032011-08-23 12:07:56 -07001168 jchar chars[] = { 'h', 'i' };
1169 jstring s;
1170 s = env_->NewString(chars, 0);
1171 EXPECT_TRUE(s != NULL);
1172 EXPECT_EQ(0, env_->GetStringLength(s));
1173 EXPECT_EQ(0, env_->GetStringUTFLength(s));
1174 s = env_->NewString(chars, 2);
1175 EXPECT_TRUE(s != NULL);
1176 EXPECT_EQ(2, env_->GetStringLength(s));
1177 EXPECT_EQ(2, env_->GetStringUTFLength(s));
1178
1179 // TODO: check some non-ASCII strings.
1180}
1181
Jesse Wilson25e79a52011-11-18 15:31:58 -05001182TEST_F(JniInternalTest, NewStringNullCharsZeroLength) {
1183 jstring s = env_->NewString(NULL, 0);
1184 EXPECT_TRUE(s != NULL);
1185 EXPECT_EQ(0, env_->GetStringLength(s));
1186}
1187
Brian Carlstrom36258122011-12-09 12:55:51 -08001188// TODO: fix gtest death tests on host http://b/5690440 (and target)
1189TEST_F(JniInternalTest, DISABLED_NewStringNullCharsNonzeroLength) {
Jesse Wilson25e79a52011-11-18 15:31:58 -05001190 ASSERT_DEATH(env_->NewString(NULL, 1), "");
1191}
1192
Elliott Hughesb465ab02011-08-24 11:21:21 -07001193TEST_F(JniInternalTest, GetStringLength_GetStringUTFLength) {
1194 // Already tested in the NewString/NewStringUTF tests.
1195}
1196
1197TEST_F(JniInternalTest, GetStringRegion_GetStringUTFRegion) {
1198 jstring s = env_->NewStringUTF("hello");
1199 ASSERT_TRUE(s != NULL);
1200
1201 env_->GetStringRegion(s, -1, 0, NULL);
1202 EXPECT_EXCEPTION(sioobe_);
1203 env_->GetStringRegion(s, 0, -1, NULL);
1204 EXPECT_EXCEPTION(sioobe_);
1205 env_->GetStringRegion(s, 0, 10, NULL);
1206 EXPECT_EXCEPTION(sioobe_);
1207 env_->GetStringRegion(s, 10, 1, NULL);
1208 EXPECT_EXCEPTION(sioobe_);
1209
1210 jchar chars[4] = { 'x', 'x', 'x', 'x' };
1211 env_->GetStringRegion(s, 1, 2, &chars[1]);
1212 EXPECT_EQ('x', chars[0]);
1213 EXPECT_EQ('e', chars[1]);
1214 EXPECT_EQ('l', chars[2]);
1215 EXPECT_EQ('x', chars[3]);
1216
1217 env_->GetStringUTFRegion(s, -1, 0, NULL);
1218 EXPECT_EXCEPTION(sioobe_);
1219 env_->GetStringUTFRegion(s, 0, -1, NULL);
1220 EXPECT_EXCEPTION(sioobe_);
1221 env_->GetStringUTFRegion(s, 0, 10, NULL);
1222 EXPECT_EXCEPTION(sioobe_);
1223 env_->GetStringUTFRegion(s, 10, 1, NULL);
1224 EXPECT_EXCEPTION(sioobe_);
1225
1226 char bytes[4] = { 'x', 'x', 'x', 'x' };
1227 env_->GetStringUTFRegion(s, 1, 2, &bytes[1]);
1228 EXPECT_EQ('x', bytes[0]);
1229 EXPECT_EQ('e', bytes[1]);
1230 EXPECT_EQ('l', bytes[2]);
1231 EXPECT_EQ('x', bytes[3]);
1232}
1233
Elliott Hughes75770752011-08-24 17:52:38 -07001234TEST_F(JniInternalTest, GetStringUTFChars_ReleaseStringUTFChars) {
Elliott Hughes3f6635a2012-06-19 13:37:49 -07001235 // Passing in a NULL jstring is ignored normally, but caught by -Xcheck:jni.
Elliott Hughesb264f082012-04-06 17:10:10 -07001236 {
Elliott Hughesb264f082012-04-06 17:10:10 -07001237 CheckJniAbortCatcher check_jni_abort_catcher;
1238 EXPECT_TRUE(env_->GetStringUTFChars(NULL, NULL) == NULL);
Elliott Hughes56ef0422012-06-19 14:35:04 -07001239 check_jni_abort_catcher.Check("GetStringUTFChars received null jstring");
Elliott Hughesb264f082012-04-06 17:10:10 -07001240 }
Elliott Hughes75770752011-08-24 17:52:38 -07001241
1242 jstring s = env_->NewStringUTF("hello");
1243 ASSERT_TRUE(s != NULL);
1244
1245 const char* utf = env_->GetStringUTFChars(s, NULL);
1246 EXPECT_STREQ("hello", utf);
1247 env_->ReleaseStringUTFChars(s, utf);
1248
1249 jboolean is_copy = JNI_FALSE;
1250 utf = env_->GetStringUTFChars(s, &is_copy);
1251 EXPECT_EQ(JNI_TRUE, is_copy);
1252 EXPECT_STREQ("hello", utf);
1253 env_->ReleaseStringUTFChars(s, utf);
1254}
1255
1256TEST_F(JniInternalTest, GetStringChars_ReleaseStringChars) {
1257 jstring s = env_->NewStringUTF("hello");
1258 ASSERT_TRUE(s != NULL);
1259
1260 jchar expected[] = { 'h', 'e', 'l', 'l', 'o' };
1261 const jchar* chars = env_->GetStringChars(s, NULL);
1262 EXPECT_EQ(expected[0], chars[0]);
1263 EXPECT_EQ(expected[1], chars[1]);
1264 EXPECT_EQ(expected[2], chars[2]);
1265 EXPECT_EQ(expected[3], chars[3]);
1266 EXPECT_EQ(expected[4], chars[4]);
1267 env_->ReleaseStringChars(s, chars);
1268
1269 jboolean is_copy = JNI_FALSE;
1270 chars = env_->GetStringChars(s, &is_copy);
1271 EXPECT_EQ(JNI_FALSE, is_copy);
1272 EXPECT_EQ(expected[0], chars[0]);
1273 EXPECT_EQ(expected[1], chars[1]);
1274 EXPECT_EQ(expected[2], chars[2]);
1275 EXPECT_EQ(expected[3], chars[3]);
1276 EXPECT_EQ(expected[4], chars[4]);
1277 env_->ReleaseStringChars(s, chars);
1278}
1279
1280TEST_F(JniInternalTest, GetStringCritical_ReleaseStringCritical) {
1281 jstring s = env_->NewStringUTF("hello");
1282 ASSERT_TRUE(s != NULL);
1283
1284 jchar expected[] = { 'h', 'e', 'l', 'l', 'o' };
1285 const jchar* chars = env_->GetStringCritical(s, NULL);
1286 EXPECT_EQ(expected[0], chars[0]);
1287 EXPECT_EQ(expected[1], chars[1]);
1288 EXPECT_EQ(expected[2], chars[2]);
1289 EXPECT_EQ(expected[3], chars[3]);
1290 EXPECT_EQ(expected[4], chars[4]);
1291 env_->ReleaseStringCritical(s, chars);
1292
1293 jboolean is_copy = JNI_FALSE;
1294 chars = env_->GetStringCritical(s, &is_copy);
1295 EXPECT_EQ(JNI_FALSE, is_copy);
1296 EXPECT_EQ(expected[0], chars[0]);
1297 EXPECT_EQ(expected[1], chars[1]);
1298 EXPECT_EQ(expected[2], chars[2]);
1299 EXPECT_EQ(expected[3], chars[3]);
1300 EXPECT_EQ(expected[4], chars[4]);
1301 env_->ReleaseStringCritical(s, chars);
1302}
1303
Elliott Hughes814e4032011-08-23 12:07:56 -07001304TEST_F(JniInternalTest, GetObjectArrayElement_SetObjectArrayElement) {
Elliott Hughesb264f082012-04-06 17:10:10 -07001305 jclass java_lang_Class = env_->FindClass("java/lang/Class");
1306 ASSERT_TRUE(java_lang_Class != NULL);
Elliott Hughes289da822011-08-16 10:11:20 -07001307
Elliott Hughesb264f082012-04-06 17:10:10 -07001308 jobjectArray array = env_->NewObjectArray(1, java_lang_Class, NULL);
Elliott Hughes289da822011-08-16 10:11:20 -07001309 EXPECT_TRUE(array != NULL);
Elliott Hughes814e4032011-08-23 12:07:56 -07001310 EXPECT_TRUE(env_->GetObjectArrayElement(array, 0) == NULL);
Elliott Hughesb264f082012-04-06 17:10:10 -07001311 env_->SetObjectArrayElement(array, 0, java_lang_Class);
1312 EXPECT_TRUE(env_->IsSameObject(env_->GetObjectArrayElement(array, 0), java_lang_Class));
Elliott Hughesa5b897e2011-08-16 11:33:06 -07001313
1314 // ArrayIndexOutOfBounds for negative index.
Elliott Hughesb264f082012-04-06 17:10:10 -07001315 env_->SetObjectArrayElement(array, -1, java_lang_Class);
Elliott Hughes814e4032011-08-23 12:07:56 -07001316 EXPECT_EXCEPTION(aioobe_);
Elliott Hughesa5b897e2011-08-16 11:33:06 -07001317
1318 // ArrayIndexOutOfBounds for too-large index.
Elliott Hughesb264f082012-04-06 17:10:10 -07001319 env_->SetObjectArrayElement(array, 1, java_lang_Class);
Elliott Hughes814e4032011-08-23 12:07:56 -07001320 EXPECT_EXCEPTION(aioobe_);
Elliott Hughesa5b897e2011-08-16 11:33:06 -07001321
Elliott Hughesb264f082012-04-06 17:10:10 -07001322 // ArrayStoreException thrown for bad types.
1323 env_->SetObjectArrayElement(array, 0, env_->NewStringUTF("not a jclass!"));
1324 EXPECT_EXCEPTION(ase_);
Elliott Hughes289da822011-08-16 10:11:20 -07001325}
1326
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001327#define EXPECT_STATIC_PRIMITIVE_FIELD(type, field_name, sig, value1, value2) \
1328 do { \
1329 jfieldID fid = env_->GetStaticFieldID(c, field_name, sig); \
1330 EXPECT_TRUE(fid != NULL); \
1331 env_->SetStatic ## type ## Field(c, fid, value1); \
Brian Carlstrom2e3d1b22012-01-09 18:01:56 -08001332 EXPECT_TRUE(value1 == env_->GetStatic ## type ## Field(c, fid)); \
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001333 env_->SetStatic ## type ## Field(c, fid, value2); \
Brian Carlstrom2e3d1b22012-01-09 18:01:56 -08001334 EXPECT_TRUE(value2 == env_->GetStatic ## type ## Field(c, fid)); \
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001335 } while (false)
1336
1337#define EXPECT_PRIMITIVE_FIELD(instance, type, field_name, sig, value1, value2) \
1338 do { \
1339 jfieldID fid = env_->GetFieldID(c, field_name, sig); \
1340 EXPECT_TRUE(fid != NULL); \
1341 env_->Set ## type ## Field(instance, fid, value1); \
Brian Carlstrom2e3d1b22012-01-09 18:01:56 -08001342 EXPECT_TRUE(value1 == env_->Get ## type ## Field(instance, fid)); \
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001343 env_->Set ## type ## Field(instance, fid, value2); \
Brian Carlstrom2e3d1b22012-01-09 18:01:56 -08001344 EXPECT_TRUE(value2 == env_->Get ## type ## Field(instance, fid)); \
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001345 } while (false)
1346
1347
Ian Rogersc928de92013-02-27 14:30:44 -08001348#if !defined(ART_USE_PORTABLE_COMPILER)
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001349TEST_F(JniInternalTest, GetPrimitiveField_SetPrimitiveField) {
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001350 Thread::Current()->TransitionFromSuspendedToRunnable();
1351 LoadDex("AllFields");
Brian Carlstrombd86bcc2013-03-10 20:26:16 -07001352 bool started = runtime_->Start();
1353 CHECK(started);
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001354
1355 jclass c = env_->FindClass("AllFields");
1356 ASSERT_TRUE(c != NULL);
1357 jobject o = env_->AllocObject(c);
1358 ASSERT_TRUE(o != NULL);
1359
1360 EXPECT_STATIC_PRIMITIVE_FIELD(Boolean, "sZ", "Z", true, false);
1361 EXPECT_STATIC_PRIMITIVE_FIELD(Byte, "sB", "B", 1, 2);
1362 EXPECT_STATIC_PRIMITIVE_FIELD(Char, "sC", "C", 'a', 'b');
1363 EXPECT_STATIC_PRIMITIVE_FIELD(Double, "sD", "D", 1.0, 2.0);
1364 EXPECT_STATIC_PRIMITIVE_FIELD(Float, "sF", "F", 1.0, 2.0);
1365 EXPECT_STATIC_PRIMITIVE_FIELD(Int, "sI", "I", 1, 2);
1366 EXPECT_STATIC_PRIMITIVE_FIELD(Long, "sJ", "J", 1, 2);
1367 EXPECT_STATIC_PRIMITIVE_FIELD(Short, "sS", "S", 1, 2);
1368
1369 EXPECT_PRIMITIVE_FIELD(o, Boolean, "iZ", "Z", true, false);
1370 EXPECT_PRIMITIVE_FIELD(o, Byte, "iB", "B", 1, 2);
1371 EXPECT_PRIMITIVE_FIELD(o, Char, "iC", "C", 'a', 'b');
1372 EXPECT_PRIMITIVE_FIELD(o, Double, "iD", "D", 1.0, 2.0);
1373 EXPECT_PRIMITIVE_FIELD(o, Float, "iF", "F", 1.0, 2.0);
1374 EXPECT_PRIMITIVE_FIELD(o, Int, "iI", "I", 1, 2);
1375 EXPECT_PRIMITIVE_FIELD(o, Long, "iJ", "J", 1, 2);
1376 EXPECT_PRIMITIVE_FIELD(o, Short, "iS", "S", 1, 2);
1377}
1378
1379TEST_F(JniInternalTest, GetObjectField_SetObjectField) {
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001380 Thread::Current()->TransitionFromSuspendedToRunnable();
1381 LoadDex("AllFields");
Brian Carlstrom25c33252011-09-18 15:58:35 -07001382 runtime_->Start();
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001383
1384 jclass c = env_->FindClass("AllFields");
1385 ASSERT_TRUE(c != NULL);
1386 jobject o = env_->AllocObject(c);
1387 ASSERT_TRUE(o != NULL);
1388
1389 jstring s1 = env_->NewStringUTF("hello");
1390 ASSERT_TRUE(s1 != NULL);
1391 jstring s2 = env_->NewStringUTF("world");
1392 ASSERT_TRUE(s2 != NULL);
1393
1394 jfieldID s_fid = env_->GetStaticFieldID(c, "sObject", "Ljava/lang/Object;");
1395 ASSERT_TRUE(s_fid != NULL);
1396 jfieldID i_fid = env_->GetFieldID(c, "iObject", "Ljava/lang/Object;");
1397 ASSERT_TRUE(i_fid != NULL);
1398
1399 env_->SetStaticObjectField(c, s_fid, s1);
1400 ASSERT_TRUE(env_->IsSameObject(s1, env_->GetStaticObjectField(c, s_fid)));
1401 env_->SetStaticObjectField(c, s_fid, s2);
1402 ASSERT_TRUE(env_->IsSameObject(s2, env_->GetStaticObjectField(c, s_fid)));
1403
1404 env_->SetObjectField(o, i_fid, s1);
1405 ASSERT_TRUE(env_->IsSameObject(s1, env_->GetObjectField(o, i_fid)));
1406 env_->SetObjectField(o, i_fid, s2);
1407 ASSERT_TRUE(env_->IsSameObject(s2, env_->GetObjectField(o, i_fid)));
1408}
Shih-wei Liao5b8b1ed2012-02-23 23:48:21 -08001409#endif
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001410
Elliott Hughes18c07532011-08-18 15:50:51 -07001411TEST_F(JniInternalTest, NewLocalRef_NULL) {
1412 EXPECT_TRUE(env_->NewLocalRef(NULL) == NULL);
1413}
1414
1415TEST_F(JniInternalTest, NewLocalRef) {
1416 jstring s = env_->NewStringUTF("");
1417 ASSERT_TRUE(s != NULL);
1418 jobject o = env_->NewLocalRef(s);
1419 EXPECT_TRUE(o != NULL);
1420 EXPECT_TRUE(o != s);
1421
Elliott Hughes2ced6a52011-10-16 18:44:48 -07001422 EXPECT_EQ(JNILocalRefType, env_->GetObjectRefType(o));
Elliott Hughes18c07532011-08-18 15:50:51 -07001423}
1424
1425TEST_F(JniInternalTest, DeleteLocalRef_NULL) {
1426 env_->DeleteLocalRef(NULL);
1427}
1428
1429TEST_F(JniInternalTest, DeleteLocalRef) {
1430 jstring s = env_->NewStringUTF("");
1431 ASSERT_TRUE(s != NULL);
1432 env_->DeleteLocalRef(s);
1433
Elliott Hughes3f6635a2012-06-19 13:37:49 -07001434 // Currently, deleting an already-deleted reference is just a CheckJNI warning.
Elliott Hughesb264f082012-04-06 17:10:10 -07001435 {
Elliott Hughesb264f082012-04-06 17:10:10 -07001436 CheckJniAbortCatcher check_jni_abort_catcher;
1437 env_->DeleteLocalRef(s);
Elliott Hughesa9137c62013-01-09 10:55:21 -08001438
1439 std::string expected(StringPrintf("native code passing in reference to invalid local reference: %p", s));
1440 check_jni_abort_catcher.Check(expected.c_str());
Elliott Hughesb264f082012-04-06 17:10:10 -07001441 }
Elliott Hughes18c07532011-08-18 15:50:51 -07001442
1443 s = env_->NewStringUTF("");
1444 ASSERT_TRUE(s != NULL);
1445 jobject o = env_->NewLocalRef(s);
1446 ASSERT_TRUE(o != NULL);
1447
1448 env_->DeleteLocalRef(s);
1449 env_->DeleteLocalRef(o);
1450}
1451
Elliott Hughes2ced6a52011-10-16 18:44:48 -07001452TEST_F(JniInternalTest, PushLocalFrame_PopLocalFrame) {
1453 jobject original = env_->NewStringUTF("");
1454 ASSERT_TRUE(original != NULL);
1455
1456 jobject outer;
1457 jobject inner1, inner2;
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001458 ScopedObjectAccess soa(env_);
Ian Rogers2dd0e2c2013-01-24 12:42:14 -08001459 mirror::Object* inner2_direct_pointer;
Elliott Hughes2ced6a52011-10-16 18:44:48 -07001460 {
1461 env_->PushLocalFrame(4);
1462 outer = env_->NewLocalRef(original);
1463
1464 {
1465 env_->PushLocalFrame(4);
1466 inner1 = env_->NewLocalRef(outer);
1467 inner2 = env_->NewStringUTF("survivor");
Ian Rogers2dd0e2c2013-01-24 12:42:14 -08001468 inner2_direct_pointer = soa.Decode<mirror::Object*>(inner2);
Elliott Hughes2ced6a52011-10-16 18:44:48 -07001469 env_->PopLocalFrame(inner2);
1470 }
1471
1472 EXPECT_EQ(JNILocalRefType, env_->GetObjectRefType(original));
1473 EXPECT_EQ(JNILocalRefType, env_->GetObjectRefType(outer));
1474 EXPECT_EQ(JNIInvalidRefType, env_->GetObjectRefType(inner1));
1475
1476 // Our local reference for the survivor is invalid because the survivor
1477 // gets a new local reference...
1478 EXPECT_EQ(JNIInvalidRefType, env_->GetObjectRefType(inner2));
1479 // ...but the survivor should be in the local reference table.
Brian Carlstrom4d571432012-05-16 00:21:41 -07001480 JNIEnvExt* env = reinterpret_cast<JNIEnvExt*>(env_);
1481 EXPECT_TRUE(env->locals.ContainsDirectPointer(inner2_direct_pointer));
Elliott Hughes2ced6a52011-10-16 18:44:48 -07001482
1483 env_->PopLocalFrame(NULL);
1484 }
1485 EXPECT_EQ(JNILocalRefType, env_->GetObjectRefType(original));
1486 EXPECT_EQ(JNIInvalidRefType, env_->GetObjectRefType(outer));
1487 EXPECT_EQ(JNIInvalidRefType, env_->GetObjectRefType(inner1));
1488 EXPECT_EQ(JNIInvalidRefType, env_->GetObjectRefType(inner2));
1489}
1490
Elliott Hughes18c07532011-08-18 15:50:51 -07001491TEST_F(JniInternalTest, NewGlobalRef_NULL) {
1492 EXPECT_TRUE(env_->NewGlobalRef(NULL) == NULL);
1493}
1494
1495TEST_F(JniInternalTest, NewGlobalRef) {
1496 jstring s = env_->NewStringUTF("");
1497 ASSERT_TRUE(s != NULL);
1498 jobject o = env_->NewGlobalRef(s);
1499 EXPECT_TRUE(o != NULL);
1500 EXPECT_TRUE(o != s);
1501
1502 // TODO: check that o is a global reference.
1503}
1504
1505TEST_F(JniInternalTest, DeleteGlobalRef_NULL) {
1506 env_->DeleteGlobalRef(NULL);
1507}
1508
1509TEST_F(JniInternalTest, DeleteGlobalRef) {
1510 jstring s = env_->NewStringUTF("");
1511 ASSERT_TRUE(s != NULL);
1512
1513 jobject o = env_->NewGlobalRef(s);
1514 ASSERT_TRUE(o != NULL);
1515 env_->DeleteGlobalRef(o);
1516
Elliott Hughes3f6635a2012-06-19 13:37:49 -07001517 // Currently, deleting an already-deleted reference is just a CheckJNI warning.
Elliott Hughesb264f082012-04-06 17:10:10 -07001518 {
Elliott Hughesb264f082012-04-06 17:10:10 -07001519 CheckJniAbortCatcher check_jni_abort_catcher;
1520 env_->DeleteGlobalRef(o);
Elliott Hughesa9137c62013-01-09 10:55:21 -08001521
1522 std::string expected(StringPrintf("native code passing in reference to invalid global reference: %p", o));
1523 check_jni_abort_catcher.Check(expected.c_str());
Elliott Hughesb264f082012-04-06 17:10:10 -07001524 }
Elliott Hughes18c07532011-08-18 15:50:51 -07001525
1526 jobject o1 = env_->NewGlobalRef(s);
1527 ASSERT_TRUE(o1 != NULL);
1528 jobject o2 = env_->NewGlobalRef(s);
1529 ASSERT_TRUE(o2 != NULL);
1530
1531 env_->DeleteGlobalRef(o1);
1532 env_->DeleteGlobalRef(o2);
1533}
1534
1535TEST_F(JniInternalTest, NewWeakGlobalRef_NULL) {
1536 EXPECT_TRUE(env_->NewWeakGlobalRef(NULL) == NULL);
1537}
1538
1539TEST_F(JniInternalTest, NewWeakGlobalRef) {
1540 jstring s = env_->NewStringUTF("");
1541 ASSERT_TRUE(s != NULL);
1542 jobject o = env_->NewWeakGlobalRef(s);
1543 EXPECT_TRUE(o != NULL);
1544 EXPECT_TRUE(o != s);
1545
1546 // TODO: check that o is a weak global reference.
1547}
1548
1549TEST_F(JniInternalTest, DeleteWeakGlobalRef_NULL) {
1550 env_->DeleteWeakGlobalRef(NULL);
1551}
1552
1553TEST_F(JniInternalTest, DeleteWeakGlobalRef) {
1554 jstring s = env_->NewStringUTF("");
1555 ASSERT_TRUE(s != NULL);
1556
1557 jobject o = env_->NewWeakGlobalRef(s);
1558 ASSERT_TRUE(o != NULL);
1559 env_->DeleteWeakGlobalRef(o);
1560
Elliott Hughes3f6635a2012-06-19 13:37:49 -07001561 // Currently, deleting an already-deleted reference is just a CheckJNI warning.
Elliott Hughesb264f082012-04-06 17:10:10 -07001562 {
Elliott Hughesb264f082012-04-06 17:10:10 -07001563 CheckJniAbortCatcher check_jni_abort_catcher;
1564 env_->DeleteWeakGlobalRef(o);
Elliott Hughesa9137c62013-01-09 10:55:21 -08001565
1566 std::string expected(StringPrintf("native code passing in reference to invalid weak global reference: %p", o));
1567 check_jni_abort_catcher.Check(expected.c_str());
Elliott Hughesb264f082012-04-06 17:10:10 -07001568 }
Elliott Hughes18c07532011-08-18 15:50:51 -07001569
1570 jobject o1 = env_->NewWeakGlobalRef(s);
1571 ASSERT_TRUE(o1 != NULL);
1572 jobject o2 = env_->NewWeakGlobalRef(s);
1573 ASSERT_TRUE(o2 != NULL);
1574
1575 env_->DeleteWeakGlobalRef(o1);
1576 env_->DeleteWeakGlobalRef(o2);
1577}
1578
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001579TEST_F(JniInternalTest, StaticMainMethod) {
Brian Carlstrom265091e2013-01-30 14:08:26 -08001580 TEST_DISABLED_FOR_PORTABLE();
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001581 ScopedObjectAccess soa(Thread::Current());
1582 jobject jclass_loader = LoadDex("Main");
Ian Rogers2dd0e2c2013-01-24 12:42:14 -08001583 SirtRef<mirror::ClassLoader>
1584 class_loader(soa.Self(), soa.Decode<mirror::ClassLoader*>(jclass_loader));
Brian Carlstrom40381fb2011-10-19 14:13:40 -07001585 CompileDirectMethod(class_loader.get(), "Main", "main", "([Ljava/lang/String;)V");
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001586
Ian Rogers2dd0e2c2013-01-24 12:42:14 -08001587 mirror::Class* klass = class_linker_->FindClass("LMain;", class_loader.get());
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001588 ASSERT_TRUE(klass != NULL);
1589
Ian Rogers2dd0e2c2013-01-24 12:42:14 -08001590 mirror::AbstractMethod* method = klass->FindDirectMethod("main", "([Ljava/lang/String;)V");
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001591 ASSERT_TRUE(method != NULL);
1592
Jeff Hao5d917302013-02-27 17:57:33 -08001593 ArgArray arg_array(NULL, 0);
1594 arg_array.Append(0);
1595 JValue result;
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001596
Sebastien Hertzb95851f2013-03-29 10:36:40 +01001597 // Start runtime.
1598 bool started = runtime_->Start();
1599 CHECK(started);
1600 Thread::Current()->TransitionFromSuspendedToRunnable();
1601
1602 method->Invoke(Thread::Current(), arg_array.GetArray(), arg_array.GetNumBytes(), &result, 'V');
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001603}
1604
1605TEST_F(JniInternalTest, StaticNopMethod) {
Brian Carlstrom265091e2013-01-30 14:08:26 -08001606 TEST_DISABLED_FOR_PORTABLE();
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001607 ScopedObjectAccess soa(Thread::Current());
Elliott Hughes77405792012-03-15 15:22:12 -07001608 InvokeNopMethod(true);
1609}
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001610
Elliott Hughes77405792012-03-15 15:22:12 -07001611TEST_F(JniInternalTest, NonStaticNopMethod) {
Brian Carlstrom265091e2013-01-30 14:08:26 -08001612 TEST_DISABLED_FOR_PORTABLE();
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001613 ScopedObjectAccess soa(Thread::Current());
Elliott Hughes77405792012-03-15 15:22:12 -07001614 InvokeNopMethod(false);
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001615}
1616
1617TEST_F(JniInternalTest, StaticIdentityByteMethod) {
Brian Carlstrom265091e2013-01-30 14:08:26 -08001618 TEST_DISABLED_FOR_PORTABLE();
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001619 ScopedObjectAccess soa(Thread::Current());
Elliott Hughes77405792012-03-15 15:22:12 -07001620 InvokeIdentityByteMethod(true);
1621}
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001622
Elliott Hughes77405792012-03-15 15:22:12 -07001623TEST_F(JniInternalTest, NonStaticIdentityByteMethod) {
Brian Carlstrom265091e2013-01-30 14:08:26 -08001624 TEST_DISABLED_FOR_PORTABLE();
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001625 ScopedObjectAccess soa(Thread::Current());
Elliott Hughes77405792012-03-15 15:22:12 -07001626 InvokeIdentityByteMethod(false);
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001627}
1628
1629TEST_F(JniInternalTest, StaticIdentityIntMethod) {
Brian Carlstrom265091e2013-01-30 14:08:26 -08001630 TEST_DISABLED_FOR_PORTABLE();
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001631 ScopedObjectAccess soa(Thread::Current());
Elliott Hughes77405792012-03-15 15:22:12 -07001632 InvokeIdentityIntMethod(true);
1633}
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001634
Elliott Hughes77405792012-03-15 15:22:12 -07001635TEST_F(JniInternalTest, NonStaticIdentityIntMethod) {
Brian Carlstrom265091e2013-01-30 14:08:26 -08001636 TEST_DISABLED_FOR_PORTABLE();
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001637 ScopedObjectAccess soa(Thread::Current());
Elliott Hughes77405792012-03-15 15:22:12 -07001638 InvokeIdentityIntMethod(false);
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001639}
1640
1641TEST_F(JniInternalTest, StaticIdentityDoubleMethod) {
Brian Carlstrom265091e2013-01-30 14:08:26 -08001642 TEST_DISABLED_FOR_PORTABLE();
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001643 ScopedObjectAccess soa(Thread::Current());
Elliott Hughes77405792012-03-15 15:22:12 -07001644 InvokeIdentityDoubleMethod(true);
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001645}
1646
Elliott Hughes77405792012-03-15 15:22:12 -07001647TEST_F(JniInternalTest, NonStaticIdentityDoubleMethod) {
Brian Carlstrom265091e2013-01-30 14:08:26 -08001648 TEST_DISABLED_FOR_PORTABLE();
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001649 ScopedObjectAccess soa(Thread::Current());
Elliott Hughes77405792012-03-15 15:22:12 -07001650 InvokeIdentityDoubleMethod(false);
Shih-wei Liao5b8b1ed2012-02-23 23:48:21 -08001651}
1652
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001653TEST_F(JniInternalTest, StaticSumIntIntMethod) {
Brian Carlstrom265091e2013-01-30 14:08:26 -08001654 TEST_DISABLED_FOR_PORTABLE();
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001655 ScopedObjectAccess soa(Thread::Current());
Elliott Hughes77405792012-03-15 15:22:12 -07001656 InvokeSumIntIntMethod(true);
1657}
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001658
Elliott Hughes77405792012-03-15 15:22:12 -07001659TEST_F(JniInternalTest, NonStaticSumIntIntMethod) {
Brian Carlstrom265091e2013-01-30 14:08:26 -08001660 TEST_DISABLED_FOR_PORTABLE();
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001661 ScopedObjectAccess soa(Thread::Current());
Elliott Hughes77405792012-03-15 15:22:12 -07001662 InvokeSumIntIntMethod(false);
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001663}
1664
1665TEST_F(JniInternalTest, StaticSumIntIntIntMethod) {
Brian Carlstrom265091e2013-01-30 14:08:26 -08001666 TEST_DISABLED_FOR_PORTABLE();
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001667 ScopedObjectAccess soa(Thread::Current());
Elliott Hughes77405792012-03-15 15:22:12 -07001668 InvokeSumIntIntIntMethod(true);
1669}
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001670
Elliott Hughes77405792012-03-15 15:22:12 -07001671TEST_F(JniInternalTest, NonStaticSumIntIntIntMethod) {
Brian Carlstrom265091e2013-01-30 14:08:26 -08001672 TEST_DISABLED_FOR_PORTABLE();
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001673 ScopedObjectAccess soa(Thread::Current());
Elliott Hughes77405792012-03-15 15:22:12 -07001674 InvokeSumIntIntIntMethod(false);
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001675}
1676
1677TEST_F(JniInternalTest, StaticSumIntIntIntIntMethod) {
Brian Carlstrom265091e2013-01-30 14:08:26 -08001678 TEST_DISABLED_FOR_PORTABLE();
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001679 ScopedObjectAccess soa(Thread::Current());
Elliott Hughes77405792012-03-15 15:22:12 -07001680 InvokeSumIntIntIntIntMethod(true);
1681}
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001682
Elliott Hughes77405792012-03-15 15:22:12 -07001683TEST_F(JniInternalTest, NonStaticSumIntIntIntIntMethod) {
Brian Carlstrom265091e2013-01-30 14:08:26 -08001684 TEST_DISABLED_FOR_PORTABLE();
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001685 ScopedObjectAccess soa(Thread::Current());
Elliott Hughes77405792012-03-15 15:22:12 -07001686 InvokeSumIntIntIntIntMethod(false);
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001687}
1688
1689TEST_F(JniInternalTest, StaticSumIntIntIntIntIntMethod) {
Brian Carlstrom265091e2013-01-30 14:08:26 -08001690 TEST_DISABLED_FOR_PORTABLE();
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001691 ScopedObjectAccess soa(Thread::Current());
Elliott Hughes77405792012-03-15 15:22:12 -07001692 InvokeSumIntIntIntIntIntMethod(true);
1693}
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001694
Elliott Hughes77405792012-03-15 15:22:12 -07001695TEST_F(JniInternalTest, NonStaticSumIntIntIntIntIntMethod) {
Brian Carlstrom265091e2013-01-30 14:08:26 -08001696 TEST_DISABLED_FOR_PORTABLE();
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001697 ScopedObjectAccess soa(Thread::Current());
Elliott Hughes77405792012-03-15 15:22:12 -07001698 InvokeSumIntIntIntIntIntMethod(false);
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001699}
1700
1701TEST_F(JniInternalTest, StaticSumDoubleDoubleMethod) {
Brian Carlstrom265091e2013-01-30 14:08:26 -08001702 TEST_DISABLED_FOR_PORTABLE();
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001703 ScopedObjectAccess soa(Thread::Current());
Elliott Hughes77405792012-03-15 15:22:12 -07001704 InvokeSumDoubleDoubleMethod(true);
1705}
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001706
Elliott Hughes77405792012-03-15 15:22:12 -07001707TEST_F(JniInternalTest, NonStaticSumDoubleDoubleMethod) {
Brian Carlstrom265091e2013-01-30 14:08:26 -08001708 TEST_DISABLED_FOR_PORTABLE();
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001709 ScopedObjectAccess soa(Thread::Current());
Elliott Hughes77405792012-03-15 15:22:12 -07001710 InvokeSumDoubleDoubleMethod(false);
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001711}
1712
1713TEST_F(JniInternalTest, StaticSumDoubleDoubleDoubleMethod) {
Brian Carlstrom265091e2013-01-30 14:08:26 -08001714 TEST_DISABLED_FOR_PORTABLE();
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001715 ScopedObjectAccess soa(Thread::Current());
Elliott Hughes77405792012-03-15 15:22:12 -07001716 InvokeSumDoubleDoubleDoubleMethod(true);
1717}
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001718
Elliott Hughes77405792012-03-15 15:22:12 -07001719TEST_F(JniInternalTest, NonStaticSumDoubleDoubleDoubleMethod) {
Brian Carlstrom265091e2013-01-30 14:08:26 -08001720 TEST_DISABLED_FOR_PORTABLE();
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001721 ScopedObjectAccess soa(Thread::Current());
Elliott Hughes77405792012-03-15 15:22:12 -07001722 InvokeSumDoubleDoubleDoubleMethod(false);
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001723}
1724
1725TEST_F(JniInternalTest, StaticSumDoubleDoubleDoubleDoubleMethod) {
Brian Carlstrom265091e2013-01-30 14:08:26 -08001726 TEST_DISABLED_FOR_PORTABLE();
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001727 ScopedObjectAccess soa(Thread::Current());
Elliott Hughes77405792012-03-15 15:22:12 -07001728 InvokeSumDoubleDoubleDoubleDoubleMethod(true);
1729}
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001730
Elliott Hughes77405792012-03-15 15:22:12 -07001731TEST_F(JniInternalTest, NonStaticSumDoubleDoubleDoubleDoubleMethod) {
Brian Carlstrom265091e2013-01-30 14:08:26 -08001732 TEST_DISABLED_FOR_PORTABLE();
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001733 ScopedObjectAccess soa(Thread::Current());
Elliott Hughes77405792012-03-15 15:22:12 -07001734 InvokeSumDoubleDoubleDoubleDoubleMethod(false);
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001735}
1736
1737TEST_F(JniInternalTest, StaticSumDoubleDoubleDoubleDoubleDoubleMethod) {
Brian Carlstrom265091e2013-01-30 14:08:26 -08001738 TEST_DISABLED_FOR_PORTABLE();
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001739 ScopedObjectAccess soa(Thread::Current());
Elliott Hughes77405792012-03-15 15:22:12 -07001740 InvokeSumDoubleDoubleDoubleDoubleDoubleMethod(true);
1741}
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001742
Elliott Hughes77405792012-03-15 15:22:12 -07001743TEST_F(JniInternalTest, NonStaticSumDoubleDoubleDoubleDoubleDoubleMethod) {
Brian Carlstrom265091e2013-01-30 14:08:26 -08001744 TEST_DISABLED_FOR_PORTABLE();
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001745 ScopedObjectAccess soa(Thread::Current());
Elliott Hughes77405792012-03-15 15:22:12 -07001746 InvokeSumDoubleDoubleDoubleDoubleDoubleMethod(false);
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001747}
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001748
Elliott Hughes37f7a402011-08-22 18:56:01 -07001749TEST_F(JniInternalTest, Throw) {
1750 EXPECT_EQ(JNI_ERR, env_->Throw(NULL));
1751
1752 jclass exception_class = env_->FindClass("java/lang/RuntimeException");
1753 ASSERT_TRUE(exception_class != NULL);
1754 jthrowable exception = reinterpret_cast<jthrowable>(env_->AllocObject(exception_class));
1755 ASSERT_TRUE(exception != NULL);
1756
1757 EXPECT_EQ(JNI_OK, env_->Throw(exception));
1758 EXPECT_TRUE(env_->ExceptionCheck());
Elliott Hughesa2501992011-08-26 19:39:54 -07001759 jthrowable thrown_exception = env_->ExceptionOccurred();
Elliott Hughes37f7a402011-08-22 18:56:01 -07001760 env_->ExceptionClear();
Elliott Hughesa2501992011-08-26 19:39:54 -07001761 EXPECT_TRUE(env_->IsSameObject(exception, thrown_exception));
Elliott Hughes37f7a402011-08-22 18:56:01 -07001762}
1763
1764TEST_F(JniInternalTest, ThrowNew) {
1765 EXPECT_EQ(JNI_ERR, env_->Throw(NULL));
1766
1767 jclass exception_class = env_->FindClass("java/lang/RuntimeException");
1768 ASSERT_TRUE(exception_class != NULL);
1769
Elliott Hughes5cb5ad22011-10-02 12:13:39 -07001770 jthrowable thrown_exception;
1771
Elliott Hughes37f7a402011-08-22 18:56:01 -07001772 EXPECT_EQ(JNI_OK, env_->ThrowNew(exception_class, "hello world"));
1773 EXPECT_TRUE(env_->ExceptionCheck());
Elliott Hughes5cb5ad22011-10-02 12:13:39 -07001774 thrown_exception = env_->ExceptionOccurred();
1775 env_->ExceptionClear();
1776 EXPECT_TRUE(env_->IsInstanceOf(thrown_exception, exception_class));
1777
1778 EXPECT_EQ(JNI_OK, env_->ThrowNew(exception_class, NULL));
1779 EXPECT_TRUE(env_->ExceptionCheck());
1780 thrown_exception = env_->ExceptionOccurred();
Elliott Hughes37f7a402011-08-22 18:56:01 -07001781 env_->ExceptionClear();
Elliott Hughesa2501992011-08-26 19:39:54 -07001782 EXPECT_TRUE(env_->IsInstanceOf(thrown_exception, exception_class));
Elliott Hughes37f7a402011-08-22 18:56:01 -07001783}
1784
Elliott Hughesb465ab02011-08-24 11:21:21 -07001785// TODO: this test is DISABLED until we can actually run java.nio.Buffer's <init>.
1786TEST_F(JniInternalTest, DISABLED_NewDirectBuffer_GetDirectBufferAddress_GetDirectBufferCapacity) {
1787 jclass buffer_class = env_->FindClass("java/nio/Buffer");
1788 ASSERT_TRUE(buffer_class != NULL);
1789
1790 char bytes[1024];
1791 jobject buffer = env_->NewDirectByteBuffer(bytes, sizeof(bytes));
1792 ASSERT_TRUE(buffer != NULL);
1793 ASSERT_TRUE(env_->IsInstanceOf(buffer, buffer_class));
1794 ASSERT_TRUE(env_->GetDirectBufferAddress(buffer) == bytes);
1795 ASSERT_TRUE(env_->GetDirectBufferCapacity(buffer) == sizeof(bytes));
1796}
1797
Ian Rogers6d0b13e2012-02-07 09:25:29 -08001798TEST_F(JniInternalTest, MonitorEnterExit) {
1799 // Create an object to torture
1800 jclass object_class = env_->FindClass("java/lang/Object");
1801 ASSERT_TRUE(object_class != NULL);
1802 jobject object = env_->AllocObject(object_class);
1803 ASSERT_TRUE(object != NULL);
1804
1805 // Expected class of exceptions
1806 jclass imse_class = env_->FindClass("java/lang/IllegalMonitorStateException");
1807 ASSERT_TRUE(imse_class != NULL);
1808
1809 jthrowable thrown_exception;
1810
1811 // Unlock of unowned monitor
1812 env_->MonitorExit(object);
1813 EXPECT_TRUE(env_->ExceptionCheck());
1814 thrown_exception = env_->ExceptionOccurred();
1815 env_->ExceptionClear();
1816 EXPECT_TRUE(env_->IsInstanceOf(thrown_exception, imse_class));
1817
1818 // Lock of unowned monitor
1819 env_->MonitorEnter(object);
1820 EXPECT_FALSE(env_->ExceptionCheck());
1821 // Regular unlock
1822 env_->MonitorExit(object);
1823 EXPECT_FALSE(env_->ExceptionCheck());
1824
1825 // Recursively lock a lot
1826 size_t max_recursive_lock = 1024;
1827 for (size_t i = 0; i < max_recursive_lock; i++) {
1828 env_->MonitorEnter(object);
1829 EXPECT_FALSE(env_->ExceptionCheck());
1830 }
1831 // Recursively unlock a lot
1832 for (size_t i = 0; i < max_recursive_lock; i++) {
1833 env_->MonitorExit(object);
1834 EXPECT_FALSE(env_->ExceptionCheck());
1835 }
1836
1837 // Unlock of unowned monitor
1838 env_->MonitorExit(object);
1839 EXPECT_TRUE(env_->ExceptionCheck());
1840 thrown_exception = env_->ExceptionOccurred();
1841 env_->ExceptionClear();
1842 EXPECT_TRUE(env_->IsInstanceOf(thrown_exception, imse_class));
Elliott Hughesa92853e2012-02-07 16:09:27 -08001843
1844 // It's an error to call MonitorEnter or MonitorExit on NULL.
Elliott Hughesb264f082012-04-06 17:10:10 -07001845 {
1846 CheckJniAbortCatcher check_jni_abort_catcher;
1847 env_->MonitorEnter(NULL);
1848 check_jni_abort_catcher.Check("in call to MonitorEnter");
Elliott Hughesb264f082012-04-06 17:10:10 -07001849
Elliott Hughesb264f082012-04-06 17:10:10 -07001850 env_->MonitorExit(NULL);
1851 check_jni_abort_catcher.Check("in call to MonitorExit");
1852 }
Ian Rogers6d0b13e2012-02-07 09:25:29 -08001853}
1854
Brian Carlstrom4d571432012-05-16 00:21:41 -07001855TEST_F(JniInternalTest, DetachCurrentThread) {
1856 CleanUpJniEnv(); // cleanup now so TearDown won't have junk from wrong JNIEnv
1857 jint ok = vm_->DetachCurrentThread();
1858 EXPECT_EQ(JNI_OK, ok);
1859
1860 jint err = vm_->DetachCurrentThread();
1861 EXPECT_EQ(JNI_ERR, err);
1862 vm_->AttachCurrentThread(&env_, NULL); // need attached thread for CommonTest::TearDown
1863}
1864
Ian Rogers0cfe1fb2011-08-26 03:29:44 -07001865} // namespace art