blob: 28408d25cf0d41d7e78b4b70014a3df2d1994ab2 [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
Ian Rogers1d54e732013-05-02 21:10:01 -070019#include <limits.h>
Elliott Hughesf66330a2012-12-12 17:27:00 -080020#include <cfloat>
Ian Rogers0cfe1fb2011-08-26 03:29:44 -070021#include <cmath>
22
Brian Carlstroma1ce1fe2014-02-24 23:23:58 -080023#include "common_compiler_test.h"
Jeff Hao5d917302013-02-27 17:57:33 -080024#include "invoke_arg_array_builder.h"
Brian Carlstromea46f952013-07-30 01:26:50 -070025#include "mirror/art_method-inl.h"
Ian Rogers4f6ad8a2013-03-18 15:27:28 -070026#include "mirror/class-inl.h"
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080027#include "mirror/object_array-inl.h"
Ian Rogers04d7aa92013-03-16 14:29:17 -070028#include "mirror/object-inl.h"
Elliott Hughes726079d2011-10-07 18:43:44 -070029#include "ScopedLocalRef.h"
Ian Rogers1f539342012-10-03 21:09:42 -070030#include "sirt_ref.h"
Elliott Hughes0c9cd562011-08-12 10:59:29 -070031
32namespace art {
33
Brian Carlstroma1ce1fe2014-02-24 23:23:58 -080034// TODO: Convert to CommonRuntimeTest. Currently MakeExecutable is used.
35class JniInternalTest : public CommonCompilerTest {
Elliott Hughesc7ac37f2011-08-12 12:21:58 -070036 protected:
37 virtual void SetUp() {
Brian Carlstroma1ce1fe2014-02-24 23:23:58 -080038 CommonCompilerTest::SetUp();
Elliott Hughes5174fe62011-08-23 15:12:35 -070039
Elliott Hughesa2501992011-08-26 19:39:54 -070040 vm_ = Runtime::Current()->GetJavaVM();
41
Elliott Hughes5174fe62011-08-23 15:12:35 -070042 // Turn on -verbose:jni for the JNI tests.
Ian Rogers79713632013-08-21 19:06:15 -070043 // gLogVerbosity.jni = true;
Elliott Hughes5174fe62011-08-23 15:12:35 -070044
Brian Carlstrom4d571432012-05-16 00:21:41 -070045 vm_->AttachCurrentThread(&env_, NULL);
Elliott Hughesb465ab02011-08-24 11:21:21 -070046
Brian Carlstromea46f952013-07-30 01:26:50 -070047 ScopedLocalRef<jclass> aioobe(env_,
48 env_->FindClass("java/lang/ArrayIndexOutOfBoundsException"));
Elliott Hughes726079d2011-10-07 18:43:44 -070049 CHECK(aioobe.get() != NULL);
50 aioobe_ = reinterpret_cast<jclass>(env_->NewGlobalRef(aioobe.get()));
Elliott Hughesb465ab02011-08-24 11:21:21 -070051
Elliott Hughesb264f082012-04-06 17:10:10 -070052 ScopedLocalRef<jclass> ase(env_, env_->FindClass("java/lang/ArrayStoreException"));
53 CHECK(ase.get() != NULL);
54 ase_ = reinterpret_cast<jclass>(env_->NewGlobalRef(ase.get()));
55
Brian Carlstromea46f952013-07-30 01:26:50 -070056 ScopedLocalRef<jclass> sioobe(env_,
57 env_->FindClass("java/lang/StringIndexOutOfBoundsException"));
Elliott Hughes726079d2011-10-07 18:43:44 -070058 CHECK(sioobe.get() != NULL);
59 sioobe_ = reinterpret_cast<jclass>(env_->NewGlobalRef(sioobe.get()));
60 }
61
Brian Carlstrom4d571432012-05-16 00:21:41 -070062 void CleanUpJniEnv() {
63 if (aioobe_ != NULL) {
64 env_->DeleteGlobalRef(aioobe_);
65 aioobe_ = NULL;
66 }
67 if (ase_ != NULL) {
68 env_->DeleteGlobalRef(ase_);
69 ase_ = NULL;
70 }
71 if (sioobe_ != NULL) {
72 env_->DeleteGlobalRef(sioobe_);
73 sioobe_ = NULL;
74 }
75 }
76
Elliott Hughes726079d2011-10-07 18:43:44 -070077 virtual void TearDown() {
Brian Carlstrom4d571432012-05-16 00:21:41 -070078 CleanUpJniEnv();
Brian Carlstroma1ce1fe2014-02-24 23:23:58 -080079 CommonCompilerTest::TearDown();
Elliott Hughesc7ac37f2011-08-12 12:21:58 -070080 }
Elliott Hughesb465ab02011-08-24 11:21:21 -070081
Ian Rogers1d99e452014-01-02 17:36:41 -080082 jclass GetPrimitiveClass(char descriptor) {
83 ScopedObjectAccess soa(env_);
84 mirror::Class* c = class_linker_->FindPrimitiveClass(descriptor);
85 CHECK(c != nullptr);
86 return soa.AddLocalReference<jclass>(c);
87 }
88
89 void JniInternalTestMakeExecutable(mirror::ArtMethod** method,
90 mirror::Object** receiver,
91 bool is_static, const char* method_name,
92 const char* method_signature)
Ian Rogersb726dcb2012-09-05 08:57:23 -070093 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Elliott Hughes77405792012-03-15 15:22:12 -070094 const char* class_name = is_static ? "StaticLeafMethods" : "NonStaticLeafMethods";
Ian Rogers00f7d0e2012-07-19 15:28:27 -070095 jobject jclass_loader(LoadDex(class_name));
Ian Rogers1f539342012-10-03 21:09:42 -070096 Thread* self = Thread::Current();
Mathieu Chartier590fee92013-09-13 13:46:47 -070097 SirtRef<mirror::ClassLoader> null_class_loader(self, nullptr);
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080098 SirtRef<mirror::ClassLoader>
Ian Rogers1f539342012-10-03 21:09:42 -070099 class_loader(self,
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800100 ScopedObjectAccessUnchecked(self).Decode<mirror::ClassLoader*>(jclass_loader));
Elliott Hughes77405792012-03-15 15:22:12 -0700101 if (is_static) {
Ian Rogers1d99e452014-01-02 17:36:41 -0800102 MakeExecutable(ScopedObjectAccessUnchecked(self).Decode<mirror::ClassLoader*>(jclass_loader),
103 class_name);
Elliott Hughes77405792012-03-15 15:22:12 -0700104 } else {
Ian Rogers1d99e452014-01-02 17:36:41 -0800105 MakeExecutable(nullptr, "java.lang.Class");
106 MakeExecutable(nullptr, "java.lang.Object");
107 MakeExecutable(ScopedObjectAccessUnchecked(self).Decode<mirror::ClassLoader*>(jclass_loader),
108 class_name);
Elliott Hughes77405792012-03-15 15:22:12 -0700109 }
110
Ian Rogers98379392014-02-24 16:53:16 -0800111 mirror::Class* c = class_linker_->FindClass(self, DotToDescriptor(class_name).c_str(),
112 class_loader);
Elliott Hughes77405792012-03-15 15:22:12 -0700113 CHECK(c != NULL);
114
Ian Rogers1d99e452014-01-02 17:36:41 -0800115 *method = is_static ? c->FindDirectMethod(method_name, method_signature)
116 : c->FindVirtualMethod(method_name, method_signature);
117 CHECK(method != nullptr);
Elliott Hughes77405792012-03-15 15:22:12 -0700118
Ian Rogers1d99e452014-01-02 17:36:41 -0800119 *receiver = (is_static ? nullptr : c->AllocObject(self));
Sebastien Hertzb95851f2013-03-29 10:36:40 +0100120
121 // Start runtime.
122 bool started = runtime_->Start();
123 CHECK(started);
124 self->TransitionFromSuspendedToRunnable();
Elliott Hughes77405792012-03-15 15:22:12 -0700125 }
126
Ian Rogersb726dcb2012-09-05 08:57:23 -0700127 void InvokeNopMethod(bool is_static) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Brian Carlstromea46f952013-07-30 01:26:50 -0700128 mirror::ArtMethod* method;
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800129 mirror::Object* receiver;
Ian Rogers1d99e452014-01-02 17:36:41 -0800130 JniInternalTestMakeExecutable(&method, &receiver, is_static, "nop", "()V");
Jeff Hao5d917302013-02-27 17:57:33 -0800131
Ian Rogers936b37f2014-02-14 00:52:24 -0800132 ArgArray arg_array("V", 1);
Jeff Hao5d917302013-02-27 17:57:33 -0800133 JValue result;
Jeff Hao5d917302013-02-27 17:57:33 -0800134
135 if (!is_static) {
Ian Rogersef7d42f2014-01-06 12:55:46 -0800136 arg_array.Append(receiver);
Jeff Hao5d917302013-02-27 17:57:33 -0800137 }
Sebastien Hertzb95851f2013-03-29 10:36:40 +0100138
Ian Rogers0177e532014-02-11 16:30:46 -0800139 method->Invoke(Thread::Current(), arg_array.GetArray(), arg_array.GetNumBytes(), &result, "V");
Elliott Hughes77405792012-03-15 15:22:12 -0700140 }
141
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700142 void InvokeIdentityByteMethod(bool is_static)
Ian Rogersb726dcb2012-09-05 08:57:23 -0700143 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Brian Carlstromea46f952013-07-30 01:26:50 -0700144 mirror::ArtMethod* method;
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800145 mirror::Object* receiver;
Ian Rogers0177e532014-02-11 16:30:46 -0800146 JniInternalTestMakeExecutable(&method, &receiver, is_static, "identity", "(B)B");
Elliott Hughes77405792012-03-15 15:22:12 -0700147
Ian Rogers936b37f2014-02-14 00:52:24 -0800148 ArgArray arg_array("BB", 2);
Jeff Hao5d917302013-02-27 17:57:33 -0800149 uint32_t* args = arg_array.GetArray();
Elliott Hughes77405792012-03-15 15:22:12 -0700150 JValue result;
151
Jeff Hao5d917302013-02-27 17:57:33 -0800152 if (!is_static) {
Ian Rogersef7d42f2014-01-06 12:55:46 -0800153 arg_array.Append(receiver);
Jeff Hao5d917302013-02-27 17:57:33 -0800154 args++;
155 }
156
Ian Rogersef7d42f2014-01-06 12:55:46 -0800157 arg_array.Append(0U);
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700158 result.SetB(-1);
Ian Rogers0177e532014-02-11 16:30:46 -0800159 method->Invoke(Thread::Current(), arg_array.GetArray(), arg_array.GetNumBytes(), &result, "BB");
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700160 EXPECT_EQ(0, result.GetB());
Elliott Hughes77405792012-03-15 15:22:12 -0700161
Jeff Hao5d917302013-02-27 17:57:33 -0800162 args[0] = -1;
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700163 result.SetB(0);
Ian Rogers0177e532014-02-11 16:30:46 -0800164 method->Invoke(Thread::Current(), arg_array.GetArray(), arg_array.GetNumBytes(), &result, "BB");
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700165 EXPECT_EQ(-1, result.GetB());
Elliott Hughes77405792012-03-15 15:22:12 -0700166
Jeff Hao5d917302013-02-27 17:57:33 -0800167 args[0] = SCHAR_MAX;
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700168 result.SetB(0);
Ian Rogers0177e532014-02-11 16:30:46 -0800169 method->Invoke(Thread::Current(), arg_array.GetArray(), arg_array.GetNumBytes(), &result, "BB");
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700170 EXPECT_EQ(SCHAR_MAX, result.GetB());
Elliott Hughes77405792012-03-15 15:22:12 -0700171
Jeff Hao5d917302013-02-27 17:57:33 -0800172 args[0] = (SCHAR_MIN << 24) >> 24;
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700173 result.SetB(0);
Ian Rogers0177e532014-02-11 16:30:46 -0800174 method->Invoke(Thread::Current(), arg_array.GetArray(), arg_array.GetNumBytes(), &result, "BB");
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700175 EXPECT_EQ(SCHAR_MIN, result.GetB());
Elliott Hughes77405792012-03-15 15:22:12 -0700176 }
177
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700178 void InvokeIdentityIntMethod(bool is_static)
Ian Rogersb726dcb2012-09-05 08:57:23 -0700179 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Brian Carlstromea46f952013-07-30 01:26:50 -0700180 mirror::ArtMethod* method;
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800181 mirror::Object* receiver;
Ian Rogers1d99e452014-01-02 17:36:41 -0800182 JniInternalTestMakeExecutable(&method, &receiver, is_static, "identity", "(I)I");
Elliott Hughes77405792012-03-15 15:22:12 -0700183
Ian Rogers936b37f2014-02-14 00:52:24 -0800184 ArgArray arg_array("II", 2);
Jeff Hao5d917302013-02-27 17:57:33 -0800185 uint32_t* args = arg_array.GetArray();
Elliott Hughes77405792012-03-15 15:22:12 -0700186 JValue result;
187
Jeff Hao5d917302013-02-27 17:57:33 -0800188 if (!is_static) {
Ian Rogersef7d42f2014-01-06 12:55:46 -0800189 arg_array.Append(receiver);
Jeff Hao5d917302013-02-27 17:57:33 -0800190 args++;
191 }
192
Ian Rogersef7d42f2014-01-06 12:55:46 -0800193 arg_array.Append(0U);
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700194 result.SetI(-1);
Ian Rogers0177e532014-02-11 16:30:46 -0800195 method->Invoke(Thread::Current(), arg_array.GetArray(), arg_array.GetNumBytes(), &result, "II");
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700196 EXPECT_EQ(0, result.GetI());
Elliott Hughes77405792012-03-15 15:22:12 -0700197
Jeff Hao5d917302013-02-27 17:57:33 -0800198 args[0] = -1;
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700199 result.SetI(0);
Ian Rogers0177e532014-02-11 16:30:46 -0800200 method->Invoke(Thread::Current(), arg_array.GetArray(), arg_array.GetNumBytes(), &result, "II");
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700201 EXPECT_EQ(-1, result.GetI());
Elliott Hughes77405792012-03-15 15:22:12 -0700202
Jeff Hao5d917302013-02-27 17:57:33 -0800203 args[0] = INT_MAX;
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700204 result.SetI(0);
Ian Rogers0177e532014-02-11 16:30:46 -0800205 method->Invoke(Thread::Current(), arg_array.GetArray(), arg_array.GetNumBytes(), &result, "II");
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700206 EXPECT_EQ(INT_MAX, result.GetI());
Elliott Hughes77405792012-03-15 15:22:12 -0700207
Jeff Hao5d917302013-02-27 17:57:33 -0800208 args[0] = INT_MIN;
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700209 result.SetI(0);
Ian Rogers0177e532014-02-11 16:30:46 -0800210 method->Invoke(Thread::Current(), arg_array.GetArray(), arg_array.GetNumBytes(), &result, "II");
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700211 EXPECT_EQ(INT_MIN, result.GetI());
Elliott Hughes77405792012-03-15 15:22:12 -0700212 }
213
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700214 void InvokeIdentityDoubleMethod(bool is_static)
Ian Rogersb726dcb2012-09-05 08:57:23 -0700215 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Brian Carlstromea46f952013-07-30 01:26:50 -0700216 mirror::ArtMethod* method;
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800217 mirror::Object* receiver;
Ian Rogers1d99e452014-01-02 17:36:41 -0800218 JniInternalTestMakeExecutable(&method, &receiver, is_static, "identity", "(D)D");
Elliott Hughes77405792012-03-15 15:22:12 -0700219
Ian Rogers936b37f2014-02-14 00:52:24 -0800220 ArgArray arg_array("DD", 2);
Jeff Hao5d917302013-02-27 17:57:33 -0800221 uint32_t* args = arg_array.GetArray();
222 JValue value;
Elliott Hughes77405792012-03-15 15:22:12 -0700223 JValue result;
224
Jeff Hao5d917302013-02-27 17:57:33 -0800225 if (!is_static) {
Ian Rogersef7d42f2014-01-06 12:55:46 -0800226 arg_array.Append(receiver);
Jeff Hao5d917302013-02-27 17:57:33 -0800227 args++;
228 }
229
230 value.SetD(0.0);
231 arg_array.AppendWide(value.GetJ());
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700232 result.SetD(-1.0);
Ian Rogers0177e532014-02-11 16:30:46 -0800233 method->Invoke(Thread::Current(), arg_array.GetArray(), arg_array.GetNumBytes(), &result, "DD");
Jeff Hao6474d192013-03-26 14:08:09 -0700234 EXPECT_EQ(0.0, result.GetD());
Elliott Hughes77405792012-03-15 15:22:12 -0700235
Jeff Hao5d917302013-02-27 17:57:33 -0800236 value.SetD(-1.0);
237 args[0] = value.GetJ();
238 args[1] = value.GetJ() >> 32;
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700239 result.SetD(0.0);
Ian Rogers0177e532014-02-11 16:30:46 -0800240 method->Invoke(Thread::Current(), arg_array.GetArray(), arg_array.GetNumBytes(), &result, "DD");
Jeff Hao6474d192013-03-26 14:08:09 -0700241 EXPECT_EQ(-1.0, result.GetD());
Elliott Hughes77405792012-03-15 15:22:12 -0700242
Jeff Hao5d917302013-02-27 17:57:33 -0800243 value.SetD(DBL_MAX);
244 args[0] = value.GetJ();
245 args[1] = value.GetJ() >> 32;
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700246 result.SetD(0.0);
Ian Rogers0177e532014-02-11 16:30:46 -0800247 method->Invoke(Thread::Current(), arg_array.GetArray(), arg_array.GetNumBytes(), &result, "DD");
Jeff Hao6474d192013-03-26 14:08:09 -0700248 EXPECT_EQ(DBL_MAX, result.GetD());
Elliott Hughes77405792012-03-15 15:22:12 -0700249
Jeff Hao5d917302013-02-27 17:57:33 -0800250 value.SetD(DBL_MIN);
251 args[0] = value.GetJ();
252 args[1] = value.GetJ() >> 32;
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700253 result.SetD(0.0);
Ian Rogers0177e532014-02-11 16:30:46 -0800254 method->Invoke(Thread::Current(), arg_array.GetArray(), arg_array.GetNumBytes(), &result, "DD");
Jeff Hao6474d192013-03-26 14:08:09 -0700255 EXPECT_EQ(DBL_MIN, result.GetD());
Elliott Hughes77405792012-03-15 15:22:12 -0700256 }
257
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700258 void InvokeSumIntIntMethod(bool is_static)
Ian Rogersb726dcb2012-09-05 08:57:23 -0700259 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Brian Carlstromea46f952013-07-30 01:26:50 -0700260 mirror::ArtMethod* method;
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800261 mirror::Object* receiver;
Ian Rogers1d99e452014-01-02 17:36:41 -0800262 JniInternalTestMakeExecutable(&method, &receiver, is_static, "sum", "(II)I");
Elliott Hughes77405792012-03-15 15:22:12 -0700263
Ian Rogers936b37f2014-02-14 00:52:24 -0800264 ArgArray arg_array("III", 3);
Jeff Hao5d917302013-02-27 17:57:33 -0800265 uint32_t* args = arg_array.GetArray();
Elliott Hughes77405792012-03-15 15:22:12 -0700266 JValue result;
Jeff Hao5d917302013-02-27 17:57:33 -0800267
268 if (!is_static) {
Ian Rogersef7d42f2014-01-06 12:55:46 -0800269 arg_array.Append(receiver);
Jeff Hao5d917302013-02-27 17:57:33 -0800270 args++;
271 }
272
Ian Rogersef7d42f2014-01-06 12:55:46 -0800273 arg_array.Append(0U);
274 arg_array.Append(0U);
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700275 result.SetI(-1);
Ian Rogers0177e532014-02-11 16:30:46 -0800276 method->Invoke(Thread::Current(), arg_array.GetArray(), arg_array.GetNumBytes(), &result, "III");
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700277 EXPECT_EQ(0, result.GetI());
Elliott Hughes77405792012-03-15 15:22:12 -0700278
Jeff Hao5d917302013-02-27 17:57:33 -0800279 args[0] = 1;
280 args[1] = 2;
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700281 result.SetI(0);
Ian Rogers0177e532014-02-11 16:30:46 -0800282 method->Invoke(Thread::Current(), arg_array.GetArray(), arg_array.GetNumBytes(), &result, "III");
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700283 EXPECT_EQ(3, result.GetI());
Elliott Hughes77405792012-03-15 15:22:12 -0700284
Jeff Hao5d917302013-02-27 17:57:33 -0800285 args[0] = -2;
286 args[1] = 5;
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700287 result.SetI(0);
Ian Rogers0177e532014-02-11 16:30:46 -0800288 method->Invoke(Thread::Current(), arg_array.GetArray(), arg_array.GetNumBytes(), &result, "III");
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700289 EXPECT_EQ(3, result.GetI());
Elliott Hughes77405792012-03-15 15:22:12 -0700290
Jeff Hao5d917302013-02-27 17:57:33 -0800291 args[0] = INT_MAX;
292 args[1] = INT_MIN;
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700293 result.SetI(1234);
Ian Rogers0177e532014-02-11 16:30:46 -0800294 method->Invoke(Thread::Current(), arg_array.GetArray(), arg_array.GetNumBytes(), &result, "III");
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700295 EXPECT_EQ(-1, result.GetI());
Elliott Hughes77405792012-03-15 15:22:12 -0700296
Jeff Hao5d917302013-02-27 17:57:33 -0800297 args[0] = INT_MAX;
298 args[1] = INT_MAX;
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700299 result.SetI(INT_MIN);
Ian Rogers0177e532014-02-11 16:30:46 -0800300 method->Invoke(Thread::Current(), arg_array.GetArray(), arg_array.GetNumBytes(), &result, "III");
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700301 EXPECT_EQ(-2, result.GetI());
Elliott Hughes77405792012-03-15 15:22:12 -0700302 }
303
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700304 void InvokeSumIntIntIntMethod(bool is_static)
Ian Rogersb726dcb2012-09-05 08:57:23 -0700305 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Brian Carlstromea46f952013-07-30 01:26:50 -0700306 mirror::ArtMethod* method;
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800307 mirror::Object* receiver;
Ian Rogers1d99e452014-01-02 17:36:41 -0800308 JniInternalTestMakeExecutable(&method, &receiver, is_static, "sum", "(III)I");
Elliott Hughes77405792012-03-15 15:22:12 -0700309
Ian Rogers936b37f2014-02-14 00:52:24 -0800310 ArgArray arg_array("IIII", 4);
Jeff Hao5d917302013-02-27 17:57:33 -0800311 uint32_t* args = arg_array.GetArray();
Elliott Hughes77405792012-03-15 15:22:12 -0700312 JValue result;
Jeff Hao5d917302013-02-27 17:57:33 -0800313
314 if (!is_static) {
Ian Rogersef7d42f2014-01-06 12:55:46 -0800315 arg_array.Append(receiver);
Jeff Hao5d917302013-02-27 17:57:33 -0800316 args++;
317 }
318
Ian Rogersef7d42f2014-01-06 12:55:46 -0800319 arg_array.Append(0U);
320 arg_array.Append(0U);
321 arg_array.Append(0U);
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700322 result.SetI(-1);
Ian Rogers0177e532014-02-11 16:30:46 -0800323 method->Invoke(Thread::Current(), arg_array.GetArray(), arg_array.GetNumBytes(), &result,
324 "IIII");
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700325 EXPECT_EQ(0, result.GetI());
Elliott Hughes77405792012-03-15 15:22:12 -0700326
Jeff Hao5d917302013-02-27 17:57:33 -0800327 args[0] = 1;
328 args[1] = 2;
329 args[2] = 3;
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700330 result.SetI(0);
Ian Rogers0177e532014-02-11 16:30:46 -0800331 method->Invoke(Thread::Current(), arg_array.GetArray(), arg_array.GetNumBytes(), &result,
332 "IIII");
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700333 EXPECT_EQ(6, result.GetI());
Elliott Hughes77405792012-03-15 15:22:12 -0700334
Jeff Hao5d917302013-02-27 17:57:33 -0800335 args[0] = -1;
336 args[1] = 2;
337 args[2] = -3;
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700338 result.SetI(0);
Ian Rogers0177e532014-02-11 16:30:46 -0800339 method->Invoke(Thread::Current(), arg_array.GetArray(), arg_array.GetNumBytes(), &result,
340 "IIII");
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700341 EXPECT_EQ(-2, result.GetI());
Elliott Hughes77405792012-03-15 15:22:12 -0700342
Jeff Hao5d917302013-02-27 17:57:33 -0800343 args[0] = INT_MAX;
344 args[1] = INT_MIN;
345 args[2] = INT_MAX;
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700346 result.SetI(1234);
Ian Rogers0177e532014-02-11 16:30:46 -0800347 method->Invoke(Thread::Current(), arg_array.GetArray(), arg_array.GetNumBytes(), &result,
348 "IIII");
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700349 EXPECT_EQ(2147483646, result.GetI());
Elliott Hughes77405792012-03-15 15:22:12 -0700350
Jeff Hao5d917302013-02-27 17:57:33 -0800351 args[0] = INT_MAX;
352 args[1] = INT_MAX;
353 args[2] = INT_MAX;
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700354 result.SetI(INT_MIN);
Ian Rogers0177e532014-02-11 16:30:46 -0800355 method->Invoke(Thread::Current(), arg_array.GetArray(), arg_array.GetNumBytes(), &result,
356 "IIII");
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700357 EXPECT_EQ(2147483645, result.GetI());
Elliott Hughes77405792012-03-15 15:22:12 -0700358 }
359
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700360 void InvokeSumIntIntIntIntMethod(bool is_static)
Ian Rogersb726dcb2012-09-05 08:57:23 -0700361 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Brian Carlstromea46f952013-07-30 01:26:50 -0700362 mirror::ArtMethod* method;
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800363 mirror::Object* receiver;
Ian Rogers1d99e452014-01-02 17:36:41 -0800364 JniInternalTestMakeExecutable(&method, &receiver, is_static, "sum", "(IIII)I");
Elliott Hughes77405792012-03-15 15:22:12 -0700365
Ian Rogers936b37f2014-02-14 00:52:24 -0800366 ArgArray arg_array("IIIII", 5);
Jeff Hao5d917302013-02-27 17:57:33 -0800367 uint32_t* args = arg_array.GetArray();
Elliott Hughes77405792012-03-15 15:22:12 -0700368 JValue result;
Jeff Hao5d917302013-02-27 17:57:33 -0800369
370 if (!is_static) {
Ian Rogersef7d42f2014-01-06 12:55:46 -0800371 arg_array.Append(receiver);
Jeff Hao5d917302013-02-27 17:57:33 -0800372 args++;
373 }
374
Ian Rogersef7d42f2014-01-06 12:55:46 -0800375 arg_array.Append(0U);
376 arg_array.Append(0U);
377 arg_array.Append(0U);
378 arg_array.Append(0U);
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700379 result.SetI(-1);
Ian Rogers0177e532014-02-11 16:30:46 -0800380 method->Invoke(Thread::Current(), arg_array.GetArray(), arg_array.GetNumBytes(), &result,
381 "IIIII");
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700382 EXPECT_EQ(0, result.GetI());
Elliott Hughes77405792012-03-15 15:22:12 -0700383
Jeff Hao5d917302013-02-27 17:57:33 -0800384 args[0] = 1;
385 args[1] = 2;
386 args[2] = 3;
387 args[3] = 4;
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700388 result.SetI(0);
Ian Rogers0177e532014-02-11 16:30:46 -0800389 method->Invoke(Thread::Current(), arg_array.GetArray(), arg_array.GetNumBytes(), &result,
390 "IIIII");
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700391 EXPECT_EQ(10, result.GetI());
Elliott Hughes77405792012-03-15 15:22:12 -0700392
Jeff Hao5d917302013-02-27 17:57:33 -0800393 args[0] = -1;
394 args[1] = 2;
395 args[2] = -3;
396 args[3] = 4;
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700397 result.SetI(0);
Ian Rogers0177e532014-02-11 16:30:46 -0800398 method->Invoke(Thread::Current(), arg_array.GetArray(), arg_array.GetNumBytes(), &result,
399 "IIIII");
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700400 EXPECT_EQ(2, result.GetI());
Elliott Hughes77405792012-03-15 15:22:12 -0700401
Jeff Hao5d917302013-02-27 17:57:33 -0800402 args[0] = INT_MAX;
403 args[1] = INT_MIN;
404 args[2] = INT_MAX;
405 args[3] = INT_MIN;
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700406 result.SetI(1234);
Ian Rogers0177e532014-02-11 16:30:46 -0800407 method->Invoke(Thread::Current(), arg_array.GetArray(), arg_array.GetNumBytes(), &result,
408 "IIIII");
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700409 EXPECT_EQ(-2, result.GetI());
Elliott Hughes77405792012-03-15 15:22:12 -0700410
Jeff Hao5d917302013-02-27 17:57:33 -0800411 args[0] = INT_MAX;
412 args[1] = INT_MAX;
413 args[2] = INT_MAX;
414 args[3] = INT_MAX;
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700415 result.SetI(INT_MIN);
Ian Rogers0177e532014-02-11 16:30:46 -0800416 method->Invoke(Thread::Current(), arg_array.GetArray(), arg_array.GetNumBytes(), &result,
417 "IIIII");
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700418 EXPECT_EQ(-4, result.GetI());
Elliott Hughes77405792012-03-15 15:22:12 -0700419 }
420
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700421 void InvokeSumIntIntIntIntIntMethod(bool is_static)
Ian Rogersb726dcb2012-09-05 08:57:23 -0700422 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Brian Carlstromea46f952013-07-30 01:26:50 -0700423 mirror::ArtMethod* method;
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800424 mirror::Object* receiver;
Ian Rogers1d99e452014-01-02 17:36:41 -0800425 JniInternalTestMakeExecutable(&method, &receiver, is_static, "sum", "(IIIII)I");
Elliott Hughes77405792012-03-15 15:22:12 -0700426
Ian Rogers936b37f2014-02-14 00:52:24 -0800427 ArgArray arg_array("IIIIII", 6);
Jeff Hao5d917302013-02-27 17:57:33 -0800428 uint32_t* args = arg_array.GetArray();
Elliott Hughes77405792012-03-15 15:22:12 -0700429 JValue result;
Jeff Hao5d917302013-02-27 17:57:33 -0800430
431 if (!is_static) {
Ian Rogersef7d42f2014-01-06 12:55:46 -0800432 arg_array.Append(receiver);
Jeff Hao5d917302013-02-27 17:57:33 -0800433 args++;
434 }
435
Ian Rogersef7d42f2014-01-06 12:55:46 -0800436 arg_array.Append(0U);
437 arg_array.Append(0U);
438 arg_array.Append(0U);
439 arg_array.Append(0U);
440 arg_array.Append(0U);
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700441 result.SetI(-1.0);
Ian Rogers0177e532014-02-11 16:30:46 -0800442 method->Invoke(Thread::Current(), arg_array.GetArray(), arg_array.GetNumBytes(), &result,
443 "IIIIII");
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700444 EXPECT_EQ(0, result.GetI());
Elliott Hughes77405792012-03-15 15:22:12 -0700445
Jeff Hao5d917302013-02-27 17:57:33 -0800446 args[0] = 1;
447 args[1] = 2;
448 args[2] = 3;
449 args[3] = 4;
450 args[4] = 5;
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700451 result.SetI(0);
Ian Rogers0177e532014-02-11 16:30:46 -0800452 method->Invoke(Thread::Current(), arg_array.GetArray(), arg_array.GetNumBytes(), &result,
453 "IIIIII");
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700454 EXPECT_EQ(15, result.GetI());
Elliott Hughes77405792012-03-15 15:22:12 -0700455
Jeff Hao5d917302013-02-27 17:57:33 -0800456 args[0] = -1;
457 args[1] = 2;
458 args[2] = -3;
459 args[3] = 4;
460 args[4] = -5;
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700461 result.SetI(0);
Ian Rogers0177e532014-02-11 16:30:46 -0800462 method->Invoke(Thread::Current(), arg_array.GetArray(), arg_array.GetNumBytes(), &result,
463 "IIIIII");
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700464 EXPECT_EQ(-3, result.GetI());
Elliott Hughes77405792012-03-15 15:22:12 -0700465
Jeff Hao5d917302013-02-27 17:57:33 -0800466 args[0] = INT_MAX;
467 args[1] = INT_MIN;
468 args[2] = INT_MAX;
469 args[3] = INT_MIN;
470 args[4] = INT_MAX;
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700471 result.SetI(1234);
Ian Rogers0177e532014-02-11 16:30:46 -0800472 method->Invoke(Thread::Current(), arg_array.GetArray(), arg_array.GetNumBytes(), &result,
473 "IIIIII");
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700474 EXPECT_EQ(2147483645, result.GetI());
Elliott Hughes77405792012-03-15 15:22:12 -0700475
Jeff Hao5d917302013-02-27 17:57:33 -0800476 args[0] = INT_MAX;
477 args[1] = INT_MAX;
478 args[2] = INT_MAX;
479 args[3] = INT_MAX;
480 args[4] = INT_MAX;
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700481 result.SetI(INT_MIN);
Ian Rogers0177e532014-02-11 16:30:46 -0800482 method->Invoke(Thread::Current(), arg_array.GetArray(), arg_array.GetNumBytes(), &result,
483 "IIIIII");
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700484 EXPECT_EQ(2147483643, result.GetI());
Elliott Hughes77405792012-03-15 15:22:12 -0700485 }
486
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700487 void InvokeSumDoubleDoubleMethod(bool is_static)
Ian Rogersb726dcb2012-09-05 08:57:23 -0700488 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Brian Carlstromea46f952013-07-30 01:26:50 -0700489 mirror::ArtMethod* method;
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800490 mirror::Object* receiver;
Ian Rogers1d99e452014-01-02 17:36:41 -0800491 JniInternalTestMakeExecutable(&method, &receiver, is_static, "sum", "(DD)D");
Elliott Hughes77405792012-03-15 15:22:12 -0700492
Ian Rogers936b37f2014-02-14 00:52:24 -0800493 ArgArray arg_array("DDD", 3);
Jeff Hao5d917302013-02-27 17:57:33 -0800494 uint32_t* args = arg_array.GetArray();
495 JValue value;
496 JValue value2;
Elliott Hughes77405792012-03-15 15:22:12 -0700497 JValue result;
498
Jeff Hao5d917302013-02-27 17:57:33 -0800499 if (!is_static) {
Ian Rogersef7d42f2014-01-06 12:55:46 -0800500 arg_array.Append(receiver);
Jeff Hao5d917302013-02-27 17:57:33 -0800501 args++;
502 }
503
504 value.SetD(0.0);
505 value2.SetD(0.0);
506 arg_array.AppendWide(value.GetJ());
507 arg_array.AppendWide(value2.GetJ());
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700508 result.SetD(-1.0);
Ian Rogers0177e532014-02-11 16:30:46 -0800509 method->Invoke(Thread::Current(), arg_array.GetArray(), arg_array.GetNumBytes(), &result,
510 "DDD");
Jeff Hao6474d192013-03-26 14:08:09 -0700511 EXPECT_EQ(0.0, result.GetD());
Elliott Hughes77405792012-03-15 15:22:12 -0700512
Jeff Hao5d917302013-02-27 17:57:33 -0800513 value.SetD(1.0);
514 value2.SetD(2.0);
515 args[0] = value.GetJ();
516 args[1] = value.GetJ() >> 32;
517 args[2] = value2.GetJ();
518 args[3] = value2.GetJ() >> 32;
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700519 result.SetD(0.0);
Ian Rogers0177e532014-02-11 16:30:46 -0800520 method->Invoke(Thread::Current(), arg_array.GetArray(), arg_array.GetNumBytes(), &result,
521 "DDD");
Jeff Hao6474d192013-03-26 14:08:09 -0700522 EXPECT_EQ(3.0, result.GetD());
Elliott Hughes77405792012-03-15 15:22:12 -0700523
Jeff Hao5d917302013-02-27 17:57:33 -0800524 value.SetD(1.0);
525 value2.SetD(-2.0);
526 args[0] = value.GetJ();
527 args[1] = value.GetJ() >> 32;
528 args[2] = value2.GetJ();
529 args[3] = value2.GetJ() >> 32;
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700530 result.SetD(0.0);
Ian Rogers0177e532014-02-11 16:30:46 -0800531 method->Invoke(Thread::Current(), arg_array.GetArray(), arg_array.GetNumBytes(), &result,
532 "DDD");
Jeff Hao6474d192013-03-26 14:08:09 -0700533 EXPECT_EQ(-1.0, result.GetD());
Elliott Hughes77405792012-03-15 15:22:12 -0700534
Jeff Hao5d917302013-02-27 17:57:33 -0800535 value.SetD(DBL_MAX);
536 value2.SetD(DBL_MIN);
537 args[0] = value.GetJ();
538 args[1] = value.GetJ() >> 32;
539 args[2] = value2.GetJ();
540 args[3] = value2.GetJ() >> 32;
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700541 result.SetD(0.0);
Ian Rogers0177e532014-02-11 16:30:46 -0800542 method->Invoke(Thread::Current(), arg_array.GetArray(), arg_array.GetNumBytes(), &result,
543 "DDD");
Jeff Hao6474d192013-03-26 14:08:09 -0700544 EXPECT_EQ(1.7976931348623157e308, result.GetD());
Elliott Hughes77405792012-03-15 15:22:12 -0700545
Jeff Hao5d917302013-02-27 17:57:33 -0800546 value.SetD(DBL_MAX);
547 value2.SetD(DBL_MAX);
548 args[0] = value.GetJ();
549 args[1] = value.GetJ() >> 32;
550 args[2] = value2.GetJ();
551 args[3] = value2.GetJ() >> 32;
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700552 result.SetD(0.0);
Ian Rogers0177e532014-02-11 16:30:46 -0800553 method->Invoke(Thread::Current(), arg_array.GetArray(), arg_array.GetNumBytes(), &result,
554 "DDD");
Jeff Hao6474d192013-03-26 14:08:09 -0700555 EXPECT_EQ(INFINITY, result.GetD());
Elliott Hughes77405792012-03-15 15:22:12 -0700556 }
557
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700558 void InvokeSumDoubleDoubleDoubleMethod(bool is_static)
Ian Rogersb726dcb2012-09-05 08:57:23 -0700559 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Brian Carlstromea46f952013-07-30 01:26:50 -0700560 mirror::ArtMethod* method;
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800561 mirror::Object* receiver;
Ian Rogers1d99e452014-01-02 17:36:41 -0800562 JniInternalTestMakeExecutable(&method, &receiver, is_static, "sum", "(DDD)D");
Elliott Hughes77405792012-03-15 15:22:12 -0700563
Ian Rogers936b37f2014-02-14 00:52:24 -0800564 ArgArray arg_array("DDDD", 4);
Jeff Hao5d917302013-02-27 17:57:33 -0800565 uint32_t* args = arg_array.GetArray();
566 JValue value;
567 JValue value2;
568 JValue value3;
Elliott Hughes77405792012-03-15 15:22:12 -0700569 JValue result;
570
Jeff Hao5d917302013-02-27 17:57:33 -0800571 if (!is_static) {
Ian Rogersef7d42f2014-01-06 12:55:46 -0800572 arg_array.Append(receiver);
Jeff Hao5d917302013-02-27 17:57:33 -0800573 args++;
574 }
575
576 value.SetD(0.0);
577 value2.SetD(0.0);
578 value3.SetD(0.0);
579 arg_array.AppendWide(value.GetJ());
580 arg_array.AppendWide(value2.GetJ());
581 arg_array.AppendWide(value3.GetJ());
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700582 result.SetD(-1.0);
Ian Rogers0177e532014-02-11 16:30:46 -0800583 method->Invoke(Thread::Current(), arg_array.GetArray(), arg_array.GetNumBytes(), &result,
584 "DDDD");
Jeff Hao6474d192013-03-26 14:08:09 -0700585 EXPECT_EQ(0.0, result.GetD());
Elliott Hughes77405792012-03-15 15:22:12 -0700586
Jeff Hao5d917302013-02-27 17:57:33 -0800587 value.SetD(1.0);
588 value2.SetD(2.0);
589 value3.SetD(3.0);
590 args[0] = value.GetJ();
591 args[1] = value.GetJ() >> 32;
592 args[2] = value2.GetJ();
593 args[3] = value2.GetJ() >> 32;
594 args[4] = value3.GetJ();
595 args[5] = value3.GetJ() >> 32;
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700596 result.SetD(0.0);
Ian Rogers0177e532014-02-11 16:30:46 -0800597 method->Invoke(Thread::Current(), arg_array.GetArray(), arg_array.GetNumBytes(), &result,
598 "DDDD");
Jeff Hao6474d192013-03-26 14:08:09 -0700599 EXPECT_EQ(6.0, result.GetD());
Elliott Hughes77405792012-03-15 15:22:12 -0700600
Jeff Hao5d917302013-02-27 17:57:33 -0800601 value.SetD(1.0);
602 value2.SetD(-2.0);
603 value3.SetD(3.0);
604 args[0] = value.GetJ();
605 args[1] = value.GetJ() >> 32;
606 args[2] = value2.GetJ();
607 args[3] = value2.GetJ() >> 32;
608 args[4] = value3.GetJ();
609 args[5] = value3.GetJ() >> 32;
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700610 result.SetD(0.0);
Ian Rogers0177e532014-02-11 16:30:46 -0800611 method->Invoke(Thread::Current(), arg_array.GetArray(), arg_array.GetNumBytes(), &result,
612 "DDDD");
Jeff Hao6474d192013-03-26 14:08:09 -0700613 EXPECT_EQ(2.0, result.GetD());
Elliott Hughes77405792012-03-15 15:22:12 -0700614 }
615
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700616 void InvokeSumDoubleDoubleDoubleDoubleMethod(bool is_static)
Ian Rogersb726dcb2012-09-05 08:57:23 -0700617 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Brian Carlstromea46f952013-07-30 01:26:50 -0700618 mirror::ArtMethod* method;
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800619 mirror::Object* receiver;
Ian Rogers1d99e452014-01-02 17:36:41 -0800620 JniInternalTestMakeExecutable(&method, &receiver, is_static, "sum", "(DDDD)D");
Elliott Hughes77405792012-03-15 15:22:12 -0700621
Ian Rogers936b37f2014-02-14 00:52:24 -0800622 ArgArray arg_array("DDDDD", 5);
Jeff Hao5d917302013-02-27 17:57:33 -0800623 uint32_t* args = arg_array.GetArray();
624 JValue value;
625 JValue value2;
626 JValue value3;
627 JValue value4;
Elliott Hughes77405792012-03-15 15:22:12 -0700628 JValue result;
629
Jeff Hao5d917302013-02-27 17:57:33 -0800630 if (!is_static) {
Ian Rogersef7d42f2014-01-06 12:55:46 -0800631 arg_array.Append(receiver);
Jeff Hao5d917302013-02-27 17:57:33 -0800632 args++;
633 }
634
635 value.SetD(0.0);
636 value2.SetD(0.0);
637 value3.SetD(0.0);
638 value4.SetD(0.0);
639 arg_array.AppendWide(value.GetJ());
640 arg_array.AppendWide(value2.GetJ());
641 arg_array.AppendWide(value3.GetJ());
642 arg_array.AppendWide(value4.GetJ());
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700643 result.SetD(-1.0);
Ian Rogers0177e532014-02-11 16:30:46 -0800644 method->Invoke(Thread::Current(), arg_array.GetArray(), arg_array.GetNumBytes(), &result,
645 "DDDDD");
Jeff Hao6474d192013-03-26 14:08:09 -0700646 EXPECT_EQ(0.0, result.GetD());
Elliott Hughes77405792012-03-15 15:22:12 -0700647
Jeff Hao5d917302013-02-27 17:57:33 -0800648 value.SetD(1.0);
649 value2.SetD(2.0);
650 value3.SetD(3.0);
651 value4.SetD(4.0);
652 args[0] = value.GetJ();
653 args[1] = value.GetJ() >> 32;
654 args[2] = value2.GetJ();
655 args[3] = value2.GetJ() >> 32;
656 args[4] = value3.GetJ();
657 args[5] = value3.GetJ() >> 32;
658 args[6] = value4.GetJ();
659 args[7] = value4.GetJ() >> 32;
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700660 result.SetD(0.0);
Ian Rogers0177e532014-02-11 16:30:46 -0800661 method->Invoke(Thread::Current(), arg_array.GetArray(), arg_array.GetNumBytes(), &result,
662 "DDDDD");
Jeff Hao6474d192013-03-26 14:08:09 -0700663 EXPECT_EQ(10.0, result.GetD());
Elliott Hughes77405792012-03-15 15:22:12 -0700664
Jeff Hao5d917302013-02-27 17:57:33 -0800665 value.SetD(1.0);
666 value2.SetD(-2.0);
667 value3.SetD(3.0);
668 value4.SetD(-4.0);
669 args[0] = value.GetJ();
670 args[1] = value.GetJ() >> 32;
671 args[2] = value2.GetJ();
672 args[3] = value2.GetJ() >> 32;
673 args[4] = value3.GetJ();
674 args[5] = value3.GetJ() >> 32;
675 args[6] = value4.GetJ();
676 args[7] = value4.GetJ() >> 32;
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700677 result.SetD(0.0);
Ian Rogers0177e532014-02-11 16:30:46 -0800678 method->Invoke(Thread::Current(), arg_array.GetArray(), arg_array.GetNumBytes(), &result,
679 "DDDDD");
Jeff Hao6474d192013-03-26 14:08:09 -0700680 EXPECT_EQ(-2.0, result.GetD());
Elliott Hughes77405792012-03-15 15:22:12 -0700681 }
682
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700683 void InvokeSumDoubleDoubleDoubleDoubleDoubleMethod(bool is_static)
Ian Rogersb726dcb2012-09-05 08:57:23 -0700684 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Brian Carlstromea46f952013-07-30 01:26:50 -0700685 mirror::ArtMethod* method;
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800686 mirror::Object* receiver;
Ian Rogers1d99e452014-01-02 17:36:41 -0800687 JniInternalTestMakeExecutable(&method, &receiver, is_static, "sum", "(DDDDD)D");
Elliott Hughes77405792012-03-15 15:22:12 -0700688
Ian Rogers936b37f2014-02-14 00:52:24 -0800689 ArgArray arg_array("DDDDDD", 6);
Jeff Hao5d917302013-02-27 17:57:33 -0800690 uint32_t* args = arg_array.GetArray();
691 JValue value;
692 JValue value2;
693 JValue value3;
694 JValue value4;
695 JValue value5;
Elliott Hughes77405792012-03-15 15:22:12 -0700696 JValue result;
697
Jeff Hao5d917302013-02-27 17:57:33 -0800698 if (!is_static) {
Ian Rogersef7d42f2014-01-06 12:55:46 -0800699 arg_array.Append(receiver);
Jeff Hao5d917302013-02-27 17:57:33 -0800700 args++;
701 }
702
703 value.SetD(0.0);
704 value2.SetD(0.0);
705 value3.SetD(0.0);
706 value4.SetD(0.0);
707 value5.SetD(0.0);
708 arg_array.AppendWide(value.GetJ());
709 arg_array.AppendWide(value2.GetJ());
710 arg_array.AppendWide(value3.GetJ());
711 arg_array.AppendWide(value4.GetJ());
712 arg_array.AppendWide(value5.GetJ());
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700713 result.SetD(-1.0);
Ian Rogers0177e532014-02-11 16:30:46 -0800714 method->Invoke(Thread::Current(), arg_array.GetArray(), arg_array.GetNumBytes(), &result,
715 "DDDDDD");
Jeff Hao6474d192013-03-26 14:08:09 -0700716 EXPECT_EQ(0.0, result.GetD());
Elliott Hughes77405792012-03-15 15:22:12 -0700717
Jeff Hao5d917302013-02-27 17:57:33 -0800718 value.SetD(1.0);
719 value2.SetD(2.0);
720 value3.SetD(3.0);
721 value4.SetD(4.0);
722 value5.SetD(5.0);
723 args[0] = value.GetJ();
724 args[1] = value.GetJ() >> 32;
725 args[2] = value2.GetJ();
726 args[3] = value2.GetJ() >> 32;
727 args[4] = value3.GetJ();
728 args[5] = value3.GetJ() >> 32;
729 args[6] = value4.GetJ();
730 args[7] = value4.GetJ() >> 32;
731 args[8] = value5.GetJ();
732 args[9] = value5.GetJ() >> 32;
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700733 result.SetD(0.0);
Ian Rogers0177e532014-02-11 16:30:46 -0800734 method->Invoke(Thread::Current(), arg_array.GetArray(), arg_array.GetNumBytes(), &result,
735 "DDDDDD");
Jeff Hao6474d192013-03-26 14:08:09 -0700736 EXPECT_EQ(15.0, result.GetD());
Elliott Hughes77405792012-03-15 15:22:12 -0700737
Jeff Hao5d917302013-02-27 17:57:33 -0800738 value.SetD(1.0);
739 value2.SetD(-2.0);
740 value3.SetD(3.0);
741 value4.SetD(-4.0);
742 value5.SetD(5.0);
743 args[0] = value.GetJ();
744 args[1] = value.GetJ() >> 32;
745 args[2] = value2.GetJ();
746 args[3] = value2.GetJ() >> 32;
747 args[4] = value3.GetJ();
748 args[5] = value3.GetJ() >> 32;
749 args[6] = value4.GetJ();
750 args[7] = value4.GetJ() >> 32;
751 args[8] = value5.GetJ();
752 args[9] = value5.GetJ() >> 32;
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700753 result.SetD(0.0);
Ian Rogers0177e532014-02-11 16:30:46 -0800754 method->Invoke(Thread::Current(), arg_array.GetArray(), arg_array.GetNumBytes(), &result,
755 "DDDDDD");
Jeff Hao6474d192013-03-26 14:08:09 -0700756 EXPECT_EQ(3.0, result.GetD());
Elliott Hughes77405792012-03-15 15:22:12 -0700757 }
758
Elliott Hughesa2501992011-08-26 19:39:54 -0700759 JavaVMExt* vm_;
Brian Carlstrom4d571432012-05-16 00:21:41 -0700760 JNIEnv* env_;
Elliott Hughes814e4032011-08-23 12:07:56 -0700761 jclass aioobe_;
Elliott Hughesb264f082012-04-06 17:10:10 -0700762 jclass ase_;
Elliott Hughesb465ab02011-08-24 11:21:21 -0700763 jclass sioobe_;
Elliott Hughes0c9cd562011-08-12 10:59:29 -0700764};
765
Elliott Hughes885c3bd2011-08-22 16:59:20 -0700766TEST_F(JniInternalTest, AllocObject) {
767 jclass c = env_->FindClass("java/lang/String");
768 ASSERT_TRUE(c != NULL);
769 jobject o = env_->AllocObject(c);
770 ASSERT_TRUE(o != NULL);
771
772 // We have an instance of the class we asked for...
773 ASSERT_TRUE(env_->IsInstanceOf(o, c));
774 // ...whose fields haven't been initialized because
775 // we didn't call a constructor.
776 ASSERT_EQ(0, env_->GetIntField(o, env_->GetFieldID(c, "count", "I")));
777 ASSERT_EQ(0, env_->GetIntField(o, env_->GetFieldID(c, "offset", "I")));
778 ASSERT_TRUE(env_->GetObjectField(o, env_->GetFieldID(c, "value", "[C")) == NULL);
779}
780
Elliott Hughesc7ac37f2011-08-12 12:21:58 -0700781TEST_F(JniInternalTest, GetVersion) {
782 ASSERT_EQ(JNI_VERSION_1_6, env_->GetVersion());
783}
784
Elliott Hughes0c9cd562011-08-12 10:59:29 -0700785#define EXPECT_CLASS_FOUND(NAME) \
Elliott Hughesbd935992011-08-22 11:59:34 -0700786 EXPECT_TRUE(env_->FindClass(NAME) != NULL); \
787 EXPECT_FALSE(env_->ExceptionCheck())
Elliott Hughes0c9cd562011-08-12 10:59:29 -0700788
789#define EXPECT_CLASS_NOT_FOUND(NAME) \
Elliott Hughesbd935992011-08-22 11:59:34 -0700790 EXPECT_TRUE(env_->FindClass(NAME) == NULL); \
791 EXPECT_TRUE(env_->ExceptionCheck()); \
792 env_->ExceptionClear()
Elliott Hughes0c9cd562011-08-12 10:59:29 -0700793
794TEST_F(JniInternalTest, FindClass) {
Elliott Hughes0c9cd562011-08-12 10:59:29 -0700795 // Reference types...
Elliott Hughes0c9cd562011-08-12 10:59:29 -0700796 EXPECT_CLASS_FOUND("java/lang/String");
Elliott Hughes0c9cd562011-08-12 10:59:29 -0700797 // ...for arrays too, where you must include "L;".
798 EXPECT_CLASS_FOUND("[Ljava/lang/String;");
Elliott Hughes3f6635a2012-06-19 13:37:49 -0700799 // Primitive arrays are okay too, if the primitive type is valid.
800 EXPECT_CLASS_FOUND("[C");
Elliott Hughesa2501992011-08-26 19:39:54 -0700801
Elliott Hughesb264f082012-04-06 17:10:10 -0700802 {
Elliott Hughesb264f082012-04-06 17:10:10 -0700803 // We support . as well as / for compatibility, if -Xcheck:jni is off.
Elliott Hughes3f6635a2012-06-19 13:37:49 -0700804 CheckJniAbortCatcher check_jni_abort_catcher;
Elliott Hughesb264f082012-04-06 17:10:10 -0700805 EXPECT_CLASS_FOUND("java.lang.String");
Elliott Hughes56ef0422012-06-19 14:35:04 -0700806 check_jni_abort_catcher.Check("illegal class name 'java.lang.String'");
Elliott Hughesb264f082012-04-06 17:10:10 -0700807 EXPECT_CLASS_NOT_FOUND("Ljava.lang.String;");
Elliott Hughes56ef0422012-06-19 14:35:04 -0700808 check_jni_abort_catcher.Check("illegal class name 'Ljava.lang.String;'");
Elliott Hughesb264f082012-04-06 17:10:10 -0700809 EXPECT_CLASS_FOUND("[Ljava.lang.String;");
Elliott Hughes56ef0422012-06-19 14:35:04 -0700810 check_jni_abort_catcher.Check("illegal class name '[Ljava.lang.String;'");
Elliott Hughesb264f082012-04-06 17:10:10 -0700811 EXPECT_CLASS_NOT_FOUND("[java.lang.String");
Elliott Hughes56ef0422012-06-19 14:35:04 -0700812 check_jni_abort_catcher.Check("illegal class name '[java.lang.String'");
Elliott Hughesb264f082012-04-06 17:10:10 -0700813
814 // You can't include the "L;" in a JNI class descriptor.
815 EXPECT_CLASS_NOT_FOUND("Ljava/lang/String;");
Elliott Hughes56ef0422012-06-19 14:35:04 -0700816 check_jni_abort_catcher.Check("illegal class name 'Ljava/lang/String;'");
Elliott Hughes3f6635a2012-06-19 13:37:49 -0700817
Elliott Hughesb264f082012-04-06 17:10:10 -0700818 // But you must include it for an array of any reference type.
819 EXPECT_CLASS_NOT_FOUND("[java/lang/String");
Elliott Hughes56ef0422012-06-19 14:35:04 -0700820 check_jni_abort_catcher.Check("illegal class name '[java/lang/String'");
Elliott Hughes3f6635a2012-06-19 13:37:49 -0700821
822 EXPECT_CLASS_NOT_FOUND("[K");
Elliott Hughes56ef0422012-06-19 14:35:04 -0700823 check_jni_abort_catcher.Check("illegal class name '[K'");
Elliott Hughesb264f082012-04-06 17:10:10 -0700824 }
Elliott Hughesa2501992011-08-26 19:39:54 -0700825
Elliott Hughes0c9cd562011-08-12 10:59:29 -0700826 // But primitive types aren't allowed...
827 EXPECT_CLASS_NOT_FOUND("C");
828 EXPECT_CLASS_NOT_FOUND("K");
829}
830
Elliott Hughescdf53122011-08-19 15:46:09 -0700831#define EXPECT_EXCEPTION(exception_class) \
832 do { \
833 EXPECT_TRUE(env_->ExceptionCheck()); \
834 jthrowable exception = env_->ExceptionOccurred(); \
835 EXPECT_NE(static_cast<jthrowable>(NULL), exception); \
Elliott Hughescdf53122011-08-19 15:46:09 -0700836 env_->ExceptionClear(); \
Elliott Hughesa2501992011-08-26 19:39:54 -0700837 EXPECT_TRUE(env_->IsInstanceOf(exception, exception_class)); \
Elliott Hughescdf53122011-08-19 15:46:09 -0700838 } while (false)
839
840TEST_F(JniInternalTest, GetFieldID) {
841 jclass jlnsfe = env_->FindClass("java/lang/NoSuchFieldError");
842 ASSERT_TRUE(jlnsfe != NULL);
843 jclass c = env_->FindClass("java/lang/String");
844 ASSERT_TRUE(c != NULL);
845
846 // Wrong type.
847 jfieldID fid = env_->GetFieldID(c, "count", "J");
848 EXPECT_EQ(static_cast<jfieldID>(NULL), fid);
849 EXPECT_EXCEPTION(jlnsfe);
850
Ian Rogersb17d08b2011-09-02 16:16:49 -0700851 // Wrong type where type doesn't exist.
852 fid = env_->GetFieldID(c, "count", "Lrod/jane/freddy;");
853 EXPECT_EQ(static_cast<jfieldID>(NULL), fid);
854 EXPECT_EXCEPTION(jlnsfe);
855
Elliott Hughescdf53122011-08-19 15:46:09 -0700856 // Wrong name.
857 fid = env_->GetFieldID(c, "Count", "I");
858 EXPECT_EQ(static_cast<jfieldID>(NULL), fid);
859 EXPECT_EXCEPTION(jlnsfe);
860
861 // Good declared field lookup.
862 fid = env_->GetFieldID(c, "count", "I");
863 EXPECT_NE(static_cast<jfieldID>(NULL), fid);
864 EXPECT_TRUE(fid != NULL);
865 EXPECT_FALSE(env_->ExceptionCheck());
866
867 // Good superclass field lookup.
868 c = env_->FindClass("java/lang/StringBuilder");
869 fid = env_->GetFieldID(c, "count", "I");
870 EXPECT_NE(static_cast<jfieldID>(NULL), fid);
871 EXPECT_TRUE(fid != NULL);
872 EXPECT_FALSE(env_->ExceptionCheck());
873
874 // Not instance.
875 fid = env_->GetFieldID(c, "CASE_INSENSITIVE_ORDER", "Ljava/util/Comparator;");
876 EXPECT_EQ(static_cast<jfieldID>(NULL), fid);
877 EXPECT_EXCEPTION(jlnsfe);
878}
879
880TEST_F(JniInternalTest, GetStaticFieldID) {
881 jclass jlnsfe = env_->FindClass("java/lang/NoSuchFieldError");
882 ASSERT_TRUE(jlnsfe != NULL);
883 jclass c = env_->FindClass("java/lang/String");
884 ASSERT_TRUE(c != NULL);
885
886 // Wrong type.
887 jfieldID fid = env_->GetStaticFieldID(c, "CASE_INSENSITIVE_ORDER", "J");
888 EXPECT_EQ(static_cast<jfieldID>(NULL), fid);
889 EXPECT_EXCEPTION(jlnsfe);
890
Ian Rogersb17d08b2011-09-02 16:16:49 -0700891 // Wrong type where type doesn't exist.
892 fid = env_->GetStaticFieldID(c, "CASE_INSENSITIVE_ORDER", "Lrod/jane/freddy;");
893 EXPECT_EQ(static_cast<jfieldID>(NULL), fid);
894 EXPECT_EXCEPTION(jlnsfe);
895
Elliott Hughescdf53122011-08-19 15:46:09 -0700896 // Wrong name.
897 fid = env_->GetStaticFieldID(c, "cASE_INSENSITIVE_ORDER", "Ljava/util/Comparator;");
898 EXPECT_EQ(static_cast<jfieldID>(NULL), fid);
899 EXPECT_EXCEPTION(jlnsfe);
900
901 // Good declared field lookup.
902 fid = env_->GetStaticFieldID(c, "CASE_INSENSITIVE_ORDER", "Ljava/util/Comparator;");
903 EXPECT_NE(static_cast<jfieldID>(NULL), fid);
904 EXPECT_TRUE(fid != NULL);
905 EXPECT_FALSE(env_->ExceptionCheck());
906
907 // Not static.
908 fid = env_->GetStaticFieldID(c, "count", "I");
909 EXPECT_EQ(static_cast<jfieldID>(NULL), fid);
910 EXPECT_EXCEPTION(jlnsfe);
911}
912
Ian Rogers4dd71f12011-08-16 14:16:02 -0700913TEST_F(JniInternalTest, GetMethodID) {
914 jclass jlobject = env_->FindClass("java/lang/Object");
915 jclass jlstring = env_->FindClass("java/lang/String");
916 jclass jlnsme = env_->FindClass("java/lang/NoSuchMethodError");
917
918 // Sanity check that no exceptions are pending
Elliott Hughescdf53122011-08-19 15:46:09 -0700919 ASSERT_FALSE(env_->ExceptionCheck());
Ian Rogers4dd71f12011-08-16 14:16:02 -0700920
921 // Check that java.lang.Object.foo() doesn't exist and NoSuchMethodError is
922 // a pending exception
923 jmethodID method = env_->GetMethodID(jlobject, "foo", "()V");
924 EXPECT_EQ(static_cast<jmethodID>(NULL), method);
Elliott Hughescdf53122011-08-19 15:46:09 -0700925 EXPECT_EXCEPTION(jlnsme);
Ian Rogers4dd71f12011-08-16 14:16:02 -0700926
927 // Check that java.lang.Object.equals() does exist
Ian Rogers4dd71f12011-08-16 14:16:02 -0700928 method = env_->GetMethodID(jlobject, "equals", "(Ljava/lang/Object;)Z");
929 EXPECT_NE(static_cast<jmethodID>(NULL), method);
930 EXPECT_FALSE(env_->ExceptionCheck());
Ian Rogers4dd71f12011-08-16 14:16:02 -0700931
932 // Check that GetMethodID for java.lang.String.valueOf(int) fails as the
933 // method is static
934 method = env_->GetMethodID(jlstring, "valueOf", "(I)Ljava/lang/String;");
935 EXPECT_EQ(static_cast<jmethodID>(NULL), method);
Elliott Hughescdf53122011-08-19 15:46:09 -0700936 EXPECT_EXCEPTION(jlnsme);
Brian Carlstromea46f952013-07-30 01:26:50 -0700937
938 // Check that GetMethodID for java.lang.NoSuchMethodError.<init>(String) finds the constructor
939 method = env_->GetMethodID(jlnsme, "<init>", "(Ljava/lang/String;)V");
940 EXPECT_NE(static_cast<jmethodID>(NULL), method);
941 EXPECT_FALSE(env_->ExceptionCheck());
Ian Rogers4dd71f12011-08-16 14:16:02 -0700942}
943
944TEST_F(JniInternalTest, GetStaticMethodID) {
945 jclass jlobject = env_->FindClass("java/lang/Object");
946 jclass jlnsme = env_->FindClass("java/lang/NoSuchMethodError");
947
948 // Sanity check that no exceptions are pending
Elliott Hughescdf53122011-08-19 15:46:09 -0700949 ASSERT_FALSE(env_->ExceptionCheck());
Ian Rogers4dd71f12011-08-16 14:16:02 -0700950
951 // Check that java.lang.Object.foo() doesn't exist and NoSuchMethodError is
952 // a pending exception
953 jmethodID method = env_->GetStaticMethodID(jlobject, "foo", "()V");
954 EXPECT_EQ(static_cast<jmethodID>(NULL), method);
Elliott Hughescdf53122011-08-19 15:46:09 -0700955 EXPECT_EXCEPTION(jlnsme);
Ian Rogers4dd71f12011-08-16 14:16:02 -0700956
957 // Check that GetStaticMethodID for java.lang.Object.equals(Object) fails as
958 // the method is not static
959 method = env_->GetStaticMethodID(jlobject, "equals", "(Ljava/lang/Object;)Z");
960 EXPECT_EQ(static_cast<jmethodID>(NULL), method);
Elliott Hughescdf53122011-08-19 15:46:09 -0700961 EXPECT_EXCEPTION(jlnsme);
Ian Rogers4dd71f12011-08-16 14:16:02 -0700962
963 // Check that java.lang.String.valueOf(int) does exist
Ian Rogers4dd71f12011-08-16 14:16:02 -0700964 jclass jlstring = env_->FindClass("java/lang/String");
965 method = env_->GetStaticMethodID(jlstring, "valueOf",
966 "(I)Ljava/lang/String;");
967 EXPECT_NE(static_cast<jmethodID>(NULL), method);
968 EXPECT_FALSE(env_->ExceptionCheck());
Ian Rogers4dd71f12011-08-16 14:16:02 -0700969}
970
Elliott Hughescdf53122011-08-19 15:46:09 -0700971TEST_F(JniInternalTest, FromReflectedField_ToReflectedField) {
972 jclass jlrField = env_->FindClass("java/lang/reflect/Field");
973 jclass c = env_->FindClass("java/lang/String");
974 ASSERT_TRUE(c != NULL);
975 jfieldID fid = env_->GetFieldID(c, "count", "I");
976 ASSERT_TRUE(fid != NULL);
977 // Turn the fid into a java.lang.reflect.Field...
978 jobject field = env_->ToReflectedField(c, fid, JNI_FALSE);
979 ASSERT_TRUE(c != NULL);
980 ASSERT_TRUE(env_->IsInstanceOf(field, jlrField));
981 // ...and back again.
982 jfieldID fid2 = env_->FromReflectedField(field);
983 ASSERT_TRUE(fid2 != NULL);
Brian Carlstromea46f952013-07-30 01:26:50 -0700984 // Make sure we can actually use it.
985 jstring s = env_->NewStringUTF("poop");
986 ASSERT_EQ(4, env_->GetIntField(s, fid2));
Elliott Hughescdf53122011-08-19 15:46:09 -0700987}
988
989TEST_F(JniInternalTest, FromReflectedMethod_ToReflectedMethod) {
990 jclass jlrMethod = env_->FindClass("java/lang/reflect/Method");
991 jclass c = env_->FindClass("java/lang/String");
992 ASSERT_TRUE(c != NULL);
993 jmethodID mid = env_->GetMethodID(c, "length", "()I");
994 ASSERT_TRUE(mid != NULL);
995 // Turn the mid into a java.lang.reflect.Method...
996 jobject method = env_->ToReflectedMethod(c, mid, JNI_FALSE);
997 ASSERT_TRUE(c != NULL);
998 ASSERT_TRUE(env_->IsInstanceOf(method, jlrMethod));
999 // ...and back again.
1000 jmethodID mid2 = env_->FromReflectedMethod(method);
1001 ASSERT_TRUE(mid2 != NULL);
Brian Carlstromea46f952013-07-30 01:26:50 -07001002 // Make sure we can actually use it.
1003 jstring s = env_->NewStringUTF("poop");
1004 // TODO: this should return 4, but the runtime skips the method
1005 // invoke because the runtime isn't started. In the future it would
1006 // be nice to use interpretter for things like this. This still does
1007 // validate that we have a sane jmethodID value.
1008 ASSERT_EQ(0, env_->CallIntMethod(s, mid2));
Elliott Hughescdf53122011-08-19 15:46:09 -07001009}
1010
Elliott Hughes5174fe62011-08-23 15:12:35 -07001011void BogusMethod() {
1012 // You can't pass NULL function pointers to RegisterNatives.
1013}
1014
Ian Rogers4dd71f12011-08-16 14:16:02 -07001015TEST_F(JniInternalTest, RegisterNatives) {
1016 jclass jlobject = env_->FindClass("java/lang/Object");
1017 jclass jlnsme = env_->FindClass("java/lang/NoSuchMethodError");
1018
1019 // Sanity check that no exceptions are pending
Elliott Hughescdf53122011-08-19 15:46:09 -07001020 ASSERT_FALSE(env_->ExceptionCheck());
Ian Rogers4dd71f12011-08-16 14:16:02 -07001021
1022 // Check that registering to a non-existent java.lang.Object.foo() causes a
1023 // NoSuchMethodError
1024 {
Elliott Hughesb25c3f62012-03-26 16:35:06 -07001025 JNINativeMethod methods[] = { { "foo", "()V", NULL } };
Ian Rogers4dd71f12011-08-16 14:16:02 -07001026 env_->RegisterNatives(jlobject, methods, 1);
1027 }
Elliott Hughescdf53122011-08-19 15:46:09 -07001028 EXPECT_EXCEPTION(jlnsme);
Ian Rogers4dd71f12011-08-16 14:16:02 -07001029
1030 // Check that registering non-native methods causes a NoSuchMethodError
1031 {
Elliott Hughesb25c3f62012-03-26 16:35:06 -07001032 JNINativeMethod methods[] = { { "equals", "(Ljava/lang/Object;)Z", NULL } };
Ian Rogers4dd71f12011-08-16 14:16:02 -07001033 env_->RegisterNatives(jlobject, methods, 1);
1034 }
Elliott Hughescdf53122011-08-19 15:46:09 -07001035 EXPECT_EXCEPTION(jlnsme);
Ian Rogers4dd71f12011-08-16 14:16:02 -07001036
1037 // Check that registering native methods is successful
1038 {
Elliott Hughesb25c3f62012-03-26 16:35:06 -07001039 JNINativeMethod methods[] = { { "notify", "()V", reinterpret_cast<void*>(BogusMethod) } };
Ian Rogers4dd71f12011-08-16 14:16:02 -07001040 env_->RegisterNatives(jlobject, methods, 1);
1041 }
1042 EXPECT_FALSE(env_->ExceptionCheck());
Elliott Hughes5174fe62011-08-23 15:12:35 -07001043
1044 env_->UnregisterNatives(jlobject);
Ian Rogers4dd71f12011-08-16 14:16:02 -07001045}
1046
Brian Carlstromea46f952013-07-30 01:26:50 -07001047#define EXPECT_PRIMITIVE_ARRAY(new_fn, \
1048 get_region_fn, \
1049 set_region_fn, \
1050 get_elements_fn, \
1051 release_elements_fn, \
1052 scalar_type, \
1053 expected_class_descriptor) \
Ian Rogers1d99e452014-01-02 17:36:41 -08001054 { \
1055 CheckJniAbortCatcher jni_abort_catcher; \
1056 /* Allocate an negative sized array and check it has the right failure type. */ \
1057 env_->new_fn(-1); \
1058 jni_abort_catcher.Check("negative array length: -1"); \
1059 env_->new_fn(std::numeric_limits<jint>::min()); \
1060 jni_abort_catcher.Check("negative array length: -2147483648"); \
1061 } \
Elliott Hughes814e4032011-08-23 12:07:56 -07001062 jsize size = 4; \
Elliott Hughesd7d7f6e2013-09-18 12:00:45 -07001063 \
Elliott Hughes814e4032011-08-23 12:07:56 -07001064 /* Allocate an array and check it has the right type and length. */ \
1065 scalar_type ## Array a = env_->new_fn(size); \
1066 EXPECT_TRUE(a != NULL); \
1067 EXPECT_TRUE(env_->IsInstanceOf(a, env_->FindClass(expected_class_descriptor))); \
1068 EXPECT_EQ(size, env_->GetArrayLength(a)); \
Elliott Hughesd7d7f6e2013-09-18 12:00:45 -07001069 \
1070 /* GetPrimitiveArrayRegion/SetPrimitiveArrayRegion */ \
Elliott Hughes814e4032011-08-23 12:07:56 -07001071 /* AIOOBE for negative start offset. */ \
1072 env_->get_region_fn(a, -1, 1, NULL); \
1073 EXPECT_EXCEPTION(aioobe_); \
1074 env_->set_region_fn(a, -1, 1, NULL); \
1075 EXPECT_EXCEPTION(aioobe_); \
Elliott Hughesd7d7f6e2013-09-18 12:00:45 -07001076 \
Elliott Hughes814e4032011-08-23 12:07:56 -07001077 /* AIOOBE for negative length. */ \
1078 env_->get_region_fn(a, 0, -1, NULL); \
1079 EXPECT_EXCEPTION(aioobe_); \
1080 env_->set_region_fn(a, 0, -1, NULL); \
1081 EXPECT_EXCEPTION(aioobe_); \
Elliott Hughesd7d7f6e2013-09-18 12:00:45 -07001082 \
Elliott Hughes814e4032011-08-23 12:07:56 -07001083 /* AIOOBE for buffer overrun. */ \
1084 env_->get_region_fn(a, size - 1, size, NULL); \
1085 EXPECT_EXCEPTION(aioobe_); \
1086 env_->set_region_fn(a, size - 1, size, NULL); \
1087 EXPECT_EXCEPTION(aioobe_); \
Elliott Hughesd7d7f6e2013-09-18 12:00:45 -07001088 \
1089 /* It's okay for the buffer to be NULL as long as the length is 0. */ \
1090 env_->get_region_fn(a, 2, 0, NULL); \
1091 /* Even if the offset is invalid... */ \
1092 env_->get_region_fn(a, 123, 0, NULL); \
1093 EXPECT_EXCEPTION(aioobe_); \
1094 \
1095 /* It's okay for the buffer to be NULL as long as the length is 0. */ \
1096 env_->set_region_fn(a, 2, 0, NULL); \
1097 /* Even if the offset is invalid... */ \
1098 env_->set_region_fn(a, 123, 0, NULL); \
1099 EXPECT_EXCEPTION(aioobe_); \
1100 \
Elliott Hughes814e4032011-08-23 12:07:56 -07001101 /* Prepare a couple of buffers. */ \
Elliott Hughesee0fa762012-03-26 17:12:41 -07001102 UniquePtr<scalar_type[]> src_buf(new scalar_type[size]); \
1103 UniquePtr<scalar_type[]> dst_buf(new scalar_type[size]); \
Elliott Hughes814e4032011-08-23 12:07:56 -07001104 for (jsize i = 0; i < size; ++i) { src_buf[i] = scalar_type(i); } \
1105 for (jsize i = 0; i < size; ++i) { dst_buf[i] = scalar_type(-1); } \
Elliott Hughesd7d7f6e2013-09-18 12:00:45 -07001106 \
Elliott Hughes814e4032011-08-23 12:07:56 -07001107 /* Copy all of src_buf onto the heap. */ \
Elliott Hughesee0fa762012-03-26 17:12:41 -07001108 env_->set_region_fn(a, 0, size, &src_buf[0]); \
Elliott Hughes814e4032011-08-23 12:07:56 -07001109 /* Copy back only part. */ \
1110 env_->get_region_fn(a, 1, size - 2, &dst_buf[1]); \
Brian Carlstromea46f952013-07-30 01:26:50 -07001111 EXPECT_NE(memcmp(&src_buf[0], &dst_buf[0], size * sizeof(scalar_type)), 0) \
1112 << "short copy equal"; \
Elliott Hughes814e4032011-08-23 12:07:56 -07001113 /* Copy the missing pieces. */ \
Elliott Hughesee0fa762012-03-26 17:12:41 -07001114 env_->get_region_fn(a, 0, 1, &dst_buf[0]); \
Elliott Hughes814e4032011-08-23 12:07:56 -07001115 env_->get_region_fn(a, size - 1, 1, &dst_buf[size - 1]); \
Brian Carlstromea46f952013-07-30 01:26:50 -07001116 EXPECT_EQ(memcmp(&src_buf[0], &dst_buf[0], size * sizeof(scalar_type)), 0) \
1117 << "fixed copy not equal"; \
Elliott Hughes814e4032011-08-23 12:07:56 -07001118 /* Copy back the whole array. */ \
Elliott Hughesee0fa762012-03-26 17:12:41 -07001119 env_->get_region_fn(a, 0, size, &dst_buf[0]); \
Brian Carlstromea46f952013-07-30 01:26:50 -07001120 EXPECT_EQ(memcmp(&src_buf[0], &dst_buf[0], size * sizeof(scalar_type)), 0) \
1121 << "full copy not equal"; \
Elliott Hughes75770752011-08-24 17:52:38 -07001122 /* GetPrimitiveArrayCritical */ \
1123 void* v = env_->GetPrimitiveArrayCritical(a, NULL); \
Brian Carlstromea46f952013-07-30 01:26:50 -07001124 EXPECT_EQ(memcmp(&src_buf[0], v, size * sizeof(scalar_type)), 0) \
1125 << "GetPrimitiveArrayCritical not equal"; \
Elliott Hughes75770752011-08-24 17:52:38 -07001126 env_->ReleasePrimitiveArrayCritical(a, v, 0); \
1127 /* GetXArrayElements */ \
1128 scalar_type* xs = env_->get_elements_fn(a, NULL); \
Brian Carlstromea46f952013-07-30 01:26:50 -07001129 EXPECT_EQ(memcmp(&src_buf[0], xs, size * sizeof(scalar_type)), 0) \
1130 << # get_elements_fn " not equal"; \
Elliott Hughes75770752011-08-24 17:52:38 -07001131 env_->release_elements_fn(a, xs, 0); \
Elliott Hughesbd935992011-08-22 11:59:34 -07001132
Elliott Hughes814e4032011-08-23 12:07:56 -07001133TEST_F(JniInternalTest, BooleanArrays) {
Brian Carlstromea46f952013-07-30 01:26:50 -07001134 EXPECT_PRIMITIVE_ARRAY(NewBooleanArray, GetBooleanArrayRegion, SetBooleanArrayRegion,
1135 GetBooleanArrayElements, ReleaseBooleanArrayElements, jboolean, "[Z");
Elliott Hughes814e4032011-08-23 12:07:56 -07001136}
1137TEST_F(JniInternalTest, ByteArrays) {
Brian Carlstromea46f952013-07-30 01:26:50 -07001138 EXPECT_PRIMITIVE_ARRAY(NewByteArray, GetByteArrayRegion, SetByteArrayRegion,
1139 GetByteArrayElements, ReleaseByteArrayElements, jbyte, "[B");
Elliott Hughes814e4032011-08-23 12:07:56 -07001140}
1141TEST_F(JniInternalTest, CharArrays) {
Brian Carlstromea46f952013-07-30 01:26:50 -07001142 EXPECT_PRIMITIVE_ARRAY(NewCharArray, GetCharArrayRegion, SetCharArrayRegion,
1143 GetCharArrayElements, ReleaseCharArrayElements, jchar, "[C");
Elliott Hughes814e4032011-08-23 12:07:56 -07001144}
1145TEST_F(JniInternalTest, DoubleArrays) {
Brian Carlstromea46f952013-07-30 01:26:50 -07001146 EXPECT_PRIMITIVE_ARRAY(NewDoubleArray, GetDoubleArrayRegion, SetDoubleArrayRegion,
1147 GetDoubleArrayElements, ReleaseDoubleArrayElements, jdouble, "[D");
Elliott Hughes814e4032011-08-23 12:07:56 -07001148}
1149TEST_F(JniInternalTest, FloatArrays) {
Brian Carlstromea46f952013-07-30 01:26:50 -07001150 EXPECT_PRIMITIVE_ARRAY(NewFloatArray, GetFloatArrayRegion, SetFloatArrayRegion,
1151 GetFloatArrayElements, ReleaseFloatArrayElements, jfloat, "[F");
Elliott Hughes814e4032011-08-23 12:07:56 -07001152}
1153TEST_F(JniInternalTest, IntArrays) {
Brian Carlstromea46f952013-07-30 01:26:50 -07001154 EXPECT_PRIMITIVE_ARRAY(NewIntArray, GetIntArrayRegion, SetIntArrayRegion,
1155 GetIntArrayElements, ReleaseIntArrayElements, jint, "[I");
Elliott Hughes814e4032011-08-23 12:07:56 -07001156}
1157TEST_F(JniInternalTest, LongArrays) {
Brian Carlstromea46f952013-07-30 01:26:50 -07001158 EXPECT_PRIMITIVE_ARRAY(NewLongArray, GetLongArrayRegion, SetLongArrayRegion,
1159 GetLongArrayElements, ReleaseLongArrayElements, jlong, "[J");
Elliott Hughes814e4032011-08-23 12:07:56 -07001160}
1161TEST_F(JniInternalTest, ShortArrays) {
Brian Carlstromea46f952013-07-30 01:26:50 -07001162 EXPECT_PRIMITIVE_ARRAY(NewShortArray, GetShortArrayRegion, SetShortArrayRegion,
1163 GetShortArrayElements, ReleaseShortArrayElements, jshort, "[S");
Elliott Hughesd8ddfd52011-08-15 14:32:53 -07001164}
1165
Elliott Hughesf2682d52011-08-15 16:37:04 -07001166TEST_F(JniInternalTest, NewObjectArray) {
Elliott Hughesbd935992011-08-22 11:59:34 -07001167 jclass element_class = env_->FindClass("java/lang/String");
Ian Rogers1d99e452014-01-02 17:36:41 -08001168 ASSERT_TRUE(element_class != nullptr);
Elliott Hughesbd935992011-08-22 11:59:34 -07001169 jclass array_class = env_->FindClass("[Ljava/lang/String;");
Ian Rogers1d99e452014-01-02 17:36:41 -08001170 ASSERT_TRUE(array_class != nullptr);
Elliott Hughesf2682d52011-08-15 16:37:04 -07001171
Ian Rogers1d99e452014-01-02 17:36:41 -08001172 jobjectArray a = env_->NewObjectArray(0, element_class, nullptr);
1173 EXPECT_TRUE(a != nullptr);
Elliott Hughesbd935992011-08-22 11:59:34 -07001174 EXPECT_TRUE(env_->IsInstanceOf(a, array_class));
1175 EXPECT_EQ(0, env_->GetArrayLength(a));
1176
Ian Rogers1d99e452014-01-02 17:36:41 -08001177 a = env_->NewObjectArray(1, element_class, nullptr);
1178 EXPECT_TRUE(a != nullptr);
Elliott Hughesbd935992011-08-22 11:59:34 -07001179 EXPECT_TRUE(env_->IsInstanceOf(a, array_class));
1180 EXPECT_EQ(1, env_->GetArrayLength(a));
Ian Rogers1d99e452014-01-02 17:36:41 -08001181 EXPECT_TRUE(env_->IsSameObject(env_->GetObjectArrayElement(a, 0), nullptr));
1182}
1183
1184TEST_F(JniInternalTest, NewObjectArrayWithNegativeLength) {
1185 jclass element_class = env_->FindClass("java/lang/String");
1186 ASSERT_TRUE(element_class != nullptr);
1187 jclass array_class = env_->FindClass("[Ljava/lang/String;");
1188 ASSERT_TRUE(array_class != nullptr);
1189 CheckJniAbortCatcher jni_abort_catcher;
1190
1191 env_->NewObjectArray(-1, element_class, nullptr);
1192 jni_abort_catcher.Check("negative array length: -1");
1193
1194 env_->NewObjectArray(std::numeric_limits<jint>::min(), element_class, nullptr);
1195 jni_abort_catcher.Check("negative array length: -2147483648");
1196}
1197
1198TEST_F(JniInternalTest, NewObjectArrayWithPrimitiveClasses) {
1199 const char* primitive_descriptors = "VZBSCIJFD";
1200 const char* primitive_names[] = {
1201 "void", "boolean", "byte", "short", "char", "int", "long", "float", "double"
1202 };
1203 ASSERT_EQ(strlen(primitive_descriptors), arraysize(primitive_names));
1204
1205 CheckJniAbortCatcher jni_abort_catcher;
1206 for (size_t i = 0; i < strlen(primitive_descriptors); ++i) {
1207 jclass primitive_class = GetPrimitiveClass(primitive_descriptors[i]);
1208 env_->NewObjectArray(1, primitive_class, nullptr);
1209 std::string error_msg(StringPrintf("not an object type: %s", primitive_names[i]));
1210 jni_abort_catcher.Check(error_msg.c_str());
1211 }
1212}
1213
1214TEST_F(JniInternalTest, NewObjectArrayWithInitialValue) {
1215 jclass element_class = env_->FindClass("java/lang/String");
1216 ASSERT_TRUE(element_class != nullptr);
1217 jclass array_class = env_->FindClass("[Ljava/lang/String;");
1218 ASSERT_TRUE(array_class != nullptr);
Elliott Hughes75770752011-08-24 17:52:38 -07001219
1220 jstring s = env_->NewStringUTF("poop");
Ian Rogers1d99e452014-01-02 17:36:41 -08001221 jobjectArray a = env_->NewObjectArray(2, element_class, s);
1222 EXPECT_TRUE(a != nullptr);
Elliott Hughes75770752011-08-24 17:52:38 -07001223 EXPECT_TRUE(env_->IsInstanceOf(a, array_class));
1224 EXPECT_EQ(2, env_->GetArrayLength(a));
1225 EXPECT_TRUE(env_->IsSameObject(env_->GetObjectArrayElement(a, 0), s));
1226 EXPECT_TRUE(env_->IsSameObject(env_->GetObjectArrayElement(a, 1), s));
Ian Rogers1d99e452014-01-02 17:36:41 -08001227
1228 // Attempt to incorrect create an array of strings with initial value of string arrays.
1229 CheckJniAbortCatcher jni_abort_catcher;
1230 env_->NewObjectArray(2, element_class, a);
1231 jni_abort_catcher.Check("cannot assign object of type 'java.lang.String[]' to array with element "
1232 "type of 'java.lang.String'");
Elliott Hughesbd935992011-08-22 11:59:34 -07001233}
1234
1235TEST_F(JniInternalTest, GetArrayLength) {
1236 // Already tested in NewObjectArray/NewPrimitiveArray.
Elliott Hughes8a26c5c2011-08-15 18:35:43 -07001237}
1238
Elliott Hughes37f7a402011-08-22 18:56:01 -07001239TEST_F(JniInternalTest, GetObjectClass) {
1240 jclass string_class = env_->FindClass("java/lang/String");
1241 ASSERT_TRUE(string_class != NULL);
1242 jclass class_class = env_->FindClass("java/lang/Class");
1243 ASSERT_TRUE(class_class != NULL);
1244
1245 jstring s = env_->NewStringUTF("poop");
1246 jclass c = env_->GetObjectClass(s);
1247 ASSERT_TRUE(env_->IsSameObject(string_class, c));
1248
1249 jclass c2 = env_->GetObjectClass(c);
1250 ASSERT_TRUE(env_->IsSameObject(class_class, env_->GetObjectClass(c2)));
1251}
1252
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001253TEST_F(JniInternalTest, GetSuperclass) {
1254 jclass object_class = env_->FindClass("java/lang/Object");
1255 ASSERT_TRUE(object_class != NULL);
1256 jclass string_class = env_->FindClass("java/lang/String");
1257 ASSERT_TRUE(string_class != NULL);
Ian Rogersdc180202012-01-29 14:47:29 -08001258 jclass runnable_interface = env_->FindClass("java/lang/Runnable");
1259 ASSERT_TRUE(runnable_interface != NULL);
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001260 ASSERT_TRUE(env_->IsSameObject(object_class, env_->GetSuperclass(string_class)));
1261 ASSERT_TRUE(env_->GetSuperclass(object_class) == NULL);
Ian Rogersdc180202012-01-29 14:47:29 -08001262 ASSERT_TRUE(env_->IsSameObject(object_class, env_->GetSuperclass(runnable_interface)));
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001263}
1264
Elliott Hughes37f7a402011-08-22 18:56:01 -07001265TEST_F(JniInternalTest, IsAssignableFrom) {
1266 jclass object_class = env_->FindClass("java/lang/Object");
1267 ASSERT_TRUE(object_class != NULL);
1268 jclass string_class = env_->FindClass("java/lang/String");
1269 ASSERT_TRUE(string_class != NULL);
1270
1271 ASSERT_TRUE(env_->IsAssignableFrom(object_class, string_class));
1272 ASSERT_FALSE(env_->IsAssignableFrom(string_class, object_class));
1273}
1274
Elliott Hughesb465ab02011-08-24 11:21:21 -07001275TEST_F(JniInternalTest, GetObjectRefType) {
1276 jclass local = env_->FindClass("java/lang/Object");
1277 ASSERT_TRUE(local != NULL);
1278 EXPECT_EQ(JNILocalRefType, env_->GetObjectRefType(local));
1279
1280 jobject global = env_->NewGlobalRef(local);
1281 EXPECT_EQ(JNIGlobalRefType, env_->GetObjectRefType(global));
1282
1283 jweak weak_global = env_->NewWeakGlobalRef(local);
1284 EXPECT_EQ(JNIWeakGlobalRefType, env_->GetObjectRefType(weak_global));
1285
1286 jobject invalid = reinterpret_cast<jobject>(this);
1287 EXPECT_EQ(JNIInvalidRefType, env_->GetObjectRefType(invalid));
1288
1289 // TODO: invoke a native method and test that its arguments are considered local references.
1290}
1291
Mathieu Chartier08599992013-12-20 17:17:55 -08001292TEST_F(JniInternalTest, StaleWeakGlobal) {
1293 jclass java_lang_Class = env_->FindClass("java/lang/Class");
1294 ASSERT_TRUE(java_lang_Class != NULL);
1295 jobjectArray local_ref = env_->NewObjectArray(1, java_lang_Class, NULL);
1296 ASSERT_TRUE(local_ref != NULL);
1297 jweak weak_global = env_->NewWeakGlobalRef(local_ref);
1298 ASSERT_TRUE(weak_global != NULL);
1299 env_->DeleteLocalRef(local_ref);
1300 Runtime::Current()->GetHeap()->CollectGarbage(false); // GC should clear the weak global.
1301 jobject new_global_ref = env_->NewGlobalRef(weak_global);
1302 EXPECT_TRUE(new_global_ref == NULL);
1303 jobject new_local_ref = env_->NewLocalRef(weak_global);
1304 EXPECT_TRUE(new_local_ref == NULL);
1305}
1306
Elliott Hughes8a26c5c2011-08-15 18:35:43 -07001307TEST_F(JniInternalTest, NewStringUTF) {
1308 EXPECT_TRUE(env_->NewStringUTF(NULL) == NULL);
Elliott Hughes814e4032011-08-23 12:07:56 -07001309 jstring s;
1310
1311 s = env_->NewStringUTF("");
1312 EXPECT_TRUE(s != NULL);
1313 EXPECT_EQ(0, env_->GetStringLength(s));
1314 EXPECT_EQ(0, env_->GetStringUTFLength(s));
1315 s = env_->NewStringUTF("hello");
1316 EXPECT_TRUE(s != NULL);
1317 EXPECT_EQ(5, env_->GetStringLength(s));
1318 EXPECT_EQ(5, env_->GetStringUTFLength(s));
1319
Elliott Hughes8a26c5c2011-08-15 18:35:43 -07001320 // TODO: check some non-ASCII strings.
Elliott Hughesf2682d52011-08-15 16:37:04 -07001321}
1322
Elliott Hughes814e4032011-08-23 12:07:56 -07001323TEST_F(JniInternalTest, NewString) {
Elliott Hughes814e4032011-08-23 12:07:56 -07001324 jchar chars[] = { 'h', 'i' };
1325 jstring s;
1326 s = env_->NewString(chars, 0);
1327 EXPECT_TRUE(s != NULL);
1328 EXPECT_EQ(0, env_->GetStringLength(s));
1329 EXPECT_EQ(0, env_->GetStringUTFLength(s));
1330 s = env_->NewString(chars, 2);
1331 EXPECT_TRUE(s != NULL);
1332 EXPECT_EQ(2, env_->GetStringLength(s));
1333 EXPECT_EQ(2, env_->GetStringUTFLength(s));
1334
1335 // TODO: check some non-ASCII strings.
1336}
1337
Jesse Wilson25e79a52011-11-18 15:31:58 -05001338TEST_F(JniInternalTest, NewStringNullCharsZeroLength) {
Ian Rogers1d99e452014-01-02 17:36:41 -08001339 jstring s = env_->NewString(nullptr, 0);
1340 EXPECT_TRUE(s != nullptr);
Jesse Wilson25e79a52011-11-18 15:31:58 -05001341 EXPECT_EQ(0, env_->GetStringLength(s));
1342}
1343
Ian Rogers1d99e452014-01-02 17:36:41 -08001344TEST_F(JniInternalTest, NewStringNullCharsNonzeroLength) {
1345 CheckJniAbortCatcher jni_abort_catcher;
1346 env_->NewString(nullptr, 1);
1347 jni_abort_catcher.Check("chars == null && char_count > 0");
1348}
1349
1350TEST_F(JniInternalTest, NewStringNegativeLength) {
1351 CheckJniAbortCatcher jni_abort_catcher;
1352 env_->NewString(nullptr, -1);
1353 jni_abort_catcher.Check("char_count < 0: -1");
1354 env_->NewString(nullptr, std::numeric_limits<jint>::min());
1355 jni_abort_catcher.Check("char_count < 0: -2147483648");
Jesse Wilson25e79a52011-11-18 15:31:58 -05001356}
1357
Elliott Hughesb465ab02011-08-24 11:21:21 -07001358TEST_F(JniInternalTest, GetStringLength_GetStringUTFLength) {
1359 // Already tested in the NewString/NewStringUTF tests.
1360}
1361
1362TEST_F(JniInternalTest, GetStringRegion_GetStringUTFRegion) {
1363 jstring s = env_->NewStringUTF("hello");
1364 ASSERT_TRUE(s != NULL);
1365
1366 env_->GetStringRegion(s, -1, 0, NULL);
1367 EXPECT_EXCEPTION(sioobe_);
1368 env_->GetStringRegion(s, 0, -1, NULL);
1369 EXPECT_EXCEPTION(sioobe_);
1370 env_->GetStringRegion(s, 0, 10, NULL);
1371 EXPECT_EXCEPTION(sioobe_);
1372 env_->GetStringRegion(s, 10, 1, NULL);
1373 EXPECT_EXCEPTION(sioobe_);
1374
1375 jchar chars[4] = { 'x', 'x', 'x', 'x' };
1376 env_->GetStringRegion(s, 1, 2, &chars[1]);
1377 EXPECT_EQ('x', chars[0]);
1378 EXPECT_EQ('e', chars[1]);
1379 EXPECT_EQ('l', chars[2]);
1380 EXPECT_EQ('x', chars[3]);
1381
Elliott Hughesd7d7f6e2013-09-18 12:00:45 -07001382 // It's okay for the buffer to be NULL as long as the length is 0.
1383 env_->GetStringRegion(s, 2, 0, NULL);
1384 // Even if the offset is invalid...
1385 env_->GetStringRegion(s, 123, 0, NULL);
1386 EXPECT_EXCEPTION(sioobe_);
1387
Elliott Hughesb465ab02011-08-24 11:21:21 -07001388 env_->GetStringUTFRegion(s, -1, 0, NULL);
1389 EXPECT_EXCEPTION(sioobe_);
1390 env_->GetStringUTFRegion(s, 0, -1, NULL);
1391 EXPECT_EXCEPTION(sioobe_);
1392 env_->GetStringUTFRegion(s, 0, 10, NULL);
1393 EXPECT_EXCEPTION(sioobe_);
1394 env_->GetStringUTFRegion(s, 10, 1, NULL);
1395 EXPECT_EXCEPTION(sioobe_);
1396
1397 char bytes[4] = { 'x', 'x', 'x', 'x' };
1398 env_->GetStringUTFRegion(s, 1, 2, &bytes[1]);
1399 EXPECT_EQ('x', bytes[0]);
1400 EXPECT_EQ('e', bytes[1]);
1401 EXPECT_EQ('l', bytes[2]);
1402 EXPECT_EQ('x', bytes[3]);
Elliott Hughesd7d7f6e2013-09-18 12:00:45 -07001403
1404 // It's okay for the buffer to be NULL as long as the length is 0.
1405 env_->GetStringUTFRegion(s, 2, 0, NULL);
1406 // Even if the offset is invalid...
1407 env_->GetStringUTFRegion(s, 123, 0, NULL);
1408 EXPECT_EXCEPTION(sioobe_);
Elliott Hughesb465ab02011-08-24 11:21:21 -07001409}
1410
Elliott Hughes75770752011-08-24 17:52:38 -07001411TEST_F(JniInternalTest, GetStringUTFChars_ReleaseStringUTFChars) {
Elliott Hughes3f6635a2012-06-19 13:37:49 -07001412 // Passing in a NULL jstring is ignored normally, but caught by -Xcheck:jni.
Elliott Hughesb264f082012-04-06 17:10:10 -07001413 {
Elliott Hughesb264f082012-04-06 17:10:10 -07001414 CheckJniAbortCatcher check_jni_abort_catcher;
1415 EXPECT_TRUE(env_->GetStringUTFChars(NULL, NULL) == NULL);
Elliott Hughes56ef0422012-06-19 14:35:04 -07001416 check_jni_abort_catcher.Check("GetStringUTFChars received null jstring");
Elliott Hughesb264f082012-04-06 17:10:10 -07001417 }
Elliott Hughes75770752011-08-24 17:52:38 -07001418
1419 jstring s = env_->NewStringUTF("hello");
1420 ASSERT_TRUE(s != NULL);
1421
1422 const char* utf = env_->GetStringUTFChars(s, NULL);
1423 EXPECT_STREQ("hello", utf);
1424 env_->ReleaseStringUTFChars(s, utf);
1425
1426 jboolean is_copy = JNI_FALSE;
1427 utf = env_->GetStringUTFChars(s, &is_copy);
1428 EXPECT_EQ(JNI_TRUE, is_copy);
1429 EXPECT_STREQ("hello", utf);
1430 env_->ReleaseStringUTFChars(s, utf);
1431}
1432
1433TEST_F(JniInternalTest, GetStringChars_ReleaseStringChars) {
1434 jstring s = env_->NewStringUTF("hello");
1435 ASSERT_TRUE(s != NULL);
1436
1437 jchar expected[] = { 'h', 'e', 'l', 'l', 'o' };
1438 const jchar* chars = env_->GetStringChars(s, NULL);
1439 EXPECT_EQ(expected[0], chars[0]);
1440 EXPECT_EQ(expected[1], chars[1]);
1441 EXPECT_EQ(expected[2], chars[2]);
1442 EXPECT_EQ(expected[3], chars[3]);
1443 EXPECT_EQ(expected[4], chars[4]);
1444 env_->ReleaseStringChars(s, chars);
1445
1446 jboolean is_copy = JNI_FALSE;
1447 chars = env_->GetStringChars(s, &is_copy);
Mathieu Chartier590fee92013-09-13 13:46:47 -07001448 EXPECT_EQ(JNI_TRUE, is_copy);
Elliott Hughes75770752011-08-24 17:52:38 -07001449 EXPECT_EQ(expected[0], chars[0]);
1450 EXPECT_EQ(expected[1], chars[1]);
1451 EXPECT_EQ(expected[2], chars[2]);
1452 EXPECT_EQ(expected[3], chars[3]);
1453 EXPECT_EQ(expected[4], chars[4]);
1454 env_->ReleaseStringChars(s, chars);
1455}
1456
1457TEST_F(JniInternalTest, GetStringCritical_ReleaseStringCritical) {
1458 jstring s = env_->NewStringUTF("hello");
1459 ASSERT_TRUE(s != NULL);
1460
1461 jchar expected[] = { 'h', 'e', 'l', 'l', 'o' };
1462 const jchar* chars = env_->GetStringCritical(s, NULL);
1463 EXPECT_EQ(expected[0], chars[0]);
1464 EXPECT_EQ(expected[1], chars[1]);
1465 EXPECT_EQ(expected[2], chars[2]);
1466 EXPECT_EQ(expected[3], chars[3]);
1467 EXPECT_EQ(expected[4], chars[4]);
1468 env_->ReleaseStringCritical(s, chars);
1469
1470 jboolean is_copy = JNI_FALSE;
1471 chars = env_->GetStringCritical(s, &is_copy);
Mathieu Chartier590fee92013-09-13 13:46:47 -07001472 // TODO: Fix GetStringCritical to use the same mechanism as GetPrimitiveArrayElementsCritical.
1473 EXPECT_EQ(JNI_TRUE, is_copy);
Elliott Hughes75770752011-08-24 17:52:38 -07001474 EXPECT_EQ(expected[0], chars[0]);
1475 EXPECT_EQ(expected[1], chars[1]);
1476 EXPECT_EQ(expected[2], chars[2]);
1477 EXPECT_EQ(expected[3], chars[3]);
1478 EXPECT_EQ(expected[4], chars[4]);
1479 env_->ReleaseStringCritical(s, chars);
1480}
1481
Elliott Hughes814e4032011-08-23 12:07:56 -07001482TEST_F(JniInternalTest, GetObjectArrayElement_SetObjectArrayElement) {
Elliott Hughesb264f082012-04-06 17:10:10 -07001483 jclass java_lang_Class = env_->FindClass("java/lang/Class");
1484 ASSERT_TRUE(java_lang_Class != NULL);
Elliott Hughes289da822011-08-16 10:11:20 -07001485
Elliott Hughesb264f082012-04-06 17:10:10 -07001486 jobjectArray array = env_->NewObjectArray(1, java_lang_Class, NULL);
Elliott Hughes289da822011-08-16 10:11:20 -07001487 EXPECT_TRUE(array != NULL);
Elliott Hughes814e4032011-08-23 12:07:56 -07001488 EXPECT_TRUE(env_->GetObjectArrayElement(array, 0) == NULL);
Elliott Hughesb264f082012-04-06 17:10:10 -07001489 env_->SetObjectArrayElement(array, 0, java_lang_Class);
1490 EXPECT_TRUE(env_->IsSameObject(env_->GetObjectArrayElement(array, 0), java_lang_Class));
Elliott Hughesa5b897e2011-08-16 11:33:06 -07001491
1492 // ArrayIndexOutOfBounds for negative index.
Elliott Hughesb264f082012-04-06 17:10:10 -07001493 env_->SetObjectArrayElement(array, -1, java_lang_Class);
Elliott Hughes814e4032011-08-23 12:07:56 -07001494 EXPECT_EXCEPTION(aioobe_);
Elliott Hughesa5b897e2011-08-16 11:33:06 -07001495
1496 // ArrayIndexOutOfBounds for too-large index.
Elliott Hughesb264f082012-04-06 17:10:10 -07001497 env_->SetObjectArrayElement(array, 1, java_lang_Class);
Elliott Hughes814e4032011-08-23 12:07:56 -07001498 EXPECT_EXCEPTION(aioobe_);
Elliott Hughesa5b897e2011-08-16 11:33:06 -07001499
Elliott Hughesb264f082012-04-06 17:10:10 -07001500 // ArrayStoreException thrown for bad types.
1501 env_->SetObjectArrayElement(array, 0, env_->NewStringUTF("not a jclass!"));
1502 EXPECT_EXCEPTION(ase_);
Elliott Hughes289da822011-08-16 10:11:20 -07001503}
1504
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001505#define EXPECT_STATIC_PRIMITIVE_FIELD(type, field_name, sig, value1, value2) \
1506 do { \
1507 jfieldID fid = env_->GetStaticFieldID(c, field_name, sig); \
1508 EXPECT_TRUE(fid != NULL); \
1509 env_->SetStatic ## type ## Field(c, fid, value1); \
Brian Carlstrom2e3d1b22012-01-09 18:01:56 -08001510 EXPECT_TRUE(value1 == env_->GetStatic ## type ## Field(c, fid)); \
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001511 env_->SetStatic ## type ## Field(c, fid, value2); \
Brian Carlstrom2e3d1b22012-01-09 18:01:56 -08001512 EXPECT_TRUE(value2 == env_->GetStatic ## type ## Field(c, fid)); \
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001513 } while (false)
1514
1515#define EXPECT_PRIMITIVE_FIELD(instance, type, field_name, sig, value1, value2) \
1516 do { \
1517 jfieldID fid = env_->GetFieldID(c, field_name, sig); \
1518 EXPECT_TRUE(fid != NULL); \
1519 env_->Set ## type ## Field(instance, fid, value1); \
Brian Carlstrom2e3d1b22012-01-09 18:01:56 -08001520 EXPECT_TRUE(value1 == env_->Get ## type ## Field(instance, fid)); \
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001521 env_->Set ## type ## Field(instance, fid, value2); \
Brian Carlstrom2e3d1b22012-01-09 18:01:56 -08001522 EXPECT_TRUE(value2 == env_->Get ## type ## Field(instance, fid)); \
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001523 } while (false)
1524
1525
1526TEST_F(JniInternalTest, GetPrimitiveField_SetPrimitiveField) {
Ian Rogersef7d42f2014-01-06 12:55:46 -08001527 TEST_DISABLED_FOR_PORTABLE();
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001528 Thread::Current()->TransitionFromSuspendedToRunnable();
1529 LoadDex("AllFields");
Brian Carlstrombd86bcc2013-03-10 20:26:16 -07001530 bool started = runtime_->Start();
1531 CHECK(started);
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001532
1533 jclass c = env_->FindClass("AllFields");
1534 ASSERT_TRUE(c != NULL);
1535 jobject o = env_->AllocObject(c);
1536 ASSERT_TRUE(o != NULL);
1537
1538 EXPECT_STATIC_PRIMITIVE_FIELD(Boolean, "sZ", "Z", true, false);
1539 EXPECT_STATIC_PRIMITIVE_FIELD(Byte, "sB", "B", 1, 2);
1540 EXPECT_STATIC_PRIMITIVE_FIELD(Char, "sC", "C", 'a', 'b');
1541 EXPECT_STATIC_PRIMITIVE_FIELD(Double, "sD", "D", 1.0, 2.0);
1542 EXPECT_STATIC_PRIMITIVE_FIELD(Float, "sF", "F", 1.0, 2.0);
1543 EXPECT_STATIC_PRIMITIVE_FIELD(Int, "sI", "I", 1, 2);
1544 EXPECT_STATIC_PRIMITIVE_FIELD(Long, "sJ", "J", 1, 2);
1545 EXPECT_STATIC_PRIMITIVE_FIELD(Short, "sS", "S", 1, 2);
1546
1547 EXPECT_PRIMITIVE_FIELD(o, Boolean, "iZ", "Z", true, false);
1548 EXPECT_PRIMITIVE_FIELD(o, Byte, "iB", "B", 1, 2);
1549 EXPECT_PRIMITIVE_FIELD(o, Char, "iC", "C", 'a', 'b');
1550 EXPECT_PRIMITIVE_FIELD(o, Double, "iD", "D", 1.0, 2.0);
1551 EXPECT_PRIMITIVE_FIELD(o, Float, "iF", "F", 1.0, 2.0);
1552 EXPECT_PRIMITIVE_FIELD(o, Int, "iI", "I", 1, 2);
1553 EXPECT_PRIMITIVE_FIELD(o, Long, "iJ", "J", 1, 2);
1554 EXPECT_PRIMITIVE_FIELD(o, Short, "iS", "S", 1, 2);
1555}
1556
1557TEST_F(JniInternalTest, GetObjectField_SetObjectField) {
Ian Rogersef7d42f2014-01-06 12:55:46 -08001558 TEST_DISABLED_FOR_PORTABLE();
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001559 Thread::Current()->TransitionFromSuspendedToRunnable();
1560 LoadDex("AllFields");
Brian Carlstrom25c33252011-09-18 15:58:35 -07001561 runtime_->Start();
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001562
1563 jclass c = env_->FindClass("AllFields");
1564 ASSERT_TRUE(c != NULL);
1565 jobject o = env_->AllocObject(c);
1566 ASSERT_TRUE(o != NULL);
1567
1568 jstring s1 = env_->NewStringUTF("hello");
1569 ASSERT_TRUE(s1 != NULL);
1570 jstring s2 = env_->NewStringUTF("world");
1571 ASSERT_TRUE(s2 != NULL);
1572
1573 jfieldID s_fid = env_->GetStaticFieldID(c, "sObject", "Ljava/lang/Object;");
1574 ASSERT_TRUE(s_fid != NULL);
1575 jfieldID i_fid = env_->GetFieldID(c, "iObject", "Ljava/lang/Object;");
1576 ASSERT_TRUE(i_fid != NULL);
1577
1578 env_->SetStaticObjectField(c, s_fid, s1);
1579 ASSERT_TRUE(env_->IsSameObject(s1, env_->GetStaticObjectField(c, s_fid)));
1580 env_->SetStaticObjectField(c, s_fid, s2);
1581 ASSERT_TRUE(env_->IsSameObject(s2, env_->GetStaticObjectField(c, s_fid)));
1582
1583 env_->SetObjectField(o, i_fid, s1);
1584 ASSERT_TRUE(env_->IsSameObject(s1, env_->GetObjectField(o, i_fid)));
1585 env_->SetObjectField(o, i_fid, s2);
1586 ASSERT_TRUE(env_->IsSameObject(s2, env_->GetObjectField(o, i_fid)));
1587}
1588
Elliott Hughes18c07532011-08-18 15:50:51 -07001589TEST_F(JniInternalTest, NewLocalRef_NULL) {
1590 EXPECT_TRUE(env_->NewLocalRef(NULL) == NULL);
1591}
1592
1593TEST_F(JniInternalTest, NewLocalRef) {
1594 jstring s = env_->NewStringUTF("");
1595 ASSERT_TRUE(s != NULL);
1596 jobject o = env_->NewLocalRef(s);
1597 EXPECT_TRUE(o != NULL);
1598 EXPECT_TRUE(o != s);
1599
Elliott Hughes2ced6a52011-10-16 18:44:48 -07001600 EXPECT_EQ(JNILocalRefType, env_->GetObjectRefType(o));
Elliott Hughes18c07532011-08-18 15:50:51 -07001601}
1602
1603TEST_F(JniInternalTest, DeleteLocalRef_NULL) {
1604 env_->DeleteLocalRef(NULL);
1605}
1606
1607TEST_F(JniInternalTest, DeleteLocalRef) {
1608 jstring s = env_->NewStringUTF("");
1609 ASSERT_TRUE(s != NULL);
1610 env_->DeleteLocalRef(s);
1611
Elliott Hughes3f6635a2012-06-19 13:37:49 -07001612 // Currently, deleting an already-deleted reference is just a CheckJNI warning.
Elliott Hughesb264f082012-04-06 17:10:10 -07001613 {
Elliott Hughesb264f082012-04-06 17:10:10 -07001614 CheckJniAbortCatcher check_jni_abort_catcher;
1615 env_->DeleteLocalRef(s);
Elliott Hughesa9137c62013-01-09 10:55:21 -08001616
Brian Carlstromea46f952013-07-30 01:26:50 -07001617 std::string expected(StringPrintf("native code passing in reference to "
1618 "invalid local reference: %p", s));
Elliott Hughesa9137c62013-01-09 10:55:21 -08001619 check_jni_abort_catcher.Check(expected.c_str());
Elliott Hughesb264f082012-04-06 17:10:10 -07001620 }
Elliott Hughes18c07532011-08-18 15:50:51 -07001621
1622 s = env_->NewStringUTF("");
1623 ASSERT_TRUE(s != NULL);
1624 jobject o = env_->NewLocalRef(s);
1625 ASSERT_TRUE(o != NULL);
1626
1627 env_->DeleteLocalRef(s);
1628 env_->DeleteLocalRef(o);
1629}
1630
Elliott Hughesaa836f72013-08-20 16:57:23 -07001631TEST_F(JniInternalTest, PushLocalFrame_10395422) {
1632 // The JNI specification is ambiguous about whether the given capacity is to be interpreted as a
1633 // maximum or as a minimum, but it seems like it's supposed to be a minimum, and that's how
1634 // Android historically treated it, and it's how the RI treats it. It's also the more useful
1635 // interpretation!
1636 ASSERT_EQ(JNI_OK, env_->PushLocalFrame(0));
1637 env_->PopLocalFrame(NULL);
1638
1639 // Negative capacities are not allowed.
1640 ASSERT_EQ(JNI_ERR, env_->PushLocalFrame(-1));
1641
1642 // And it's okay to have an upper limit. Ours is currently 512.
1643 ASSERT_EQ(JNI_ERR, env_->PushLocalFrame(8192));
1644}
1645
Elliott Hughes2ced6a52011-10-16 18:44:48 -07001646TEST_F(JniInternalTest, PushLocalFrame_PopLocalFrame) {
1647 jobject original = env_->NewStringUTF("");
1648 ASSERT_TRUE(original != NULL);
1649
1650 jobject outer;
1651 jobject inner1, inner2;
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001652 ScopedObjectAccess soa(env_);
Ian Rogers2dd0e2c2013-01-24 12:42:14 -08001653 mirror::Object* inner2_direct_pointer;
Elliott Hughes2ced6a52011-10-16 18:44:48 -07001654 {
Elliott Hughesaa836f72013-08-20 16:57:23 -07001655 ASSERT_EQ(JNI_OK, env_->PushLocalFrame(4));
Elliott Hughes2ced6a52011-10-16 18:44:48 -07001656 outer = env_->NewLocalRef(original);
1657
1658 {
Elliott Hughesaa836f72013-08-20 16:57:23 -07001659 ASSERT_EQ(JNI_OK, env_->PushLocalFrame(4));
Elliott Hughes2ced6a52011-10-16 18:44:48 -07001660 inner1 = env_->NewLocalRef(outer);
1661 inner2 = env_->NewStringUTF("survivor");
Ian Rogers2dd0e2c2013-01-24 12:42:14 -08001662 inner2_direct_pointer = soa.Decode<mirror::Object*>(inner2);
Elliott Hughes2ced6a52011-10-16 18:44:48 -07001663 env_->PopLocalFrame(inner2);
1664 }
1665
1666 EXPECT_EQ(JNILocalRefType, env_->GetObjectRefType(original));
1667 EXPECT_EQ(JNILocalRefType, env_->GetObjectRefType(outer));
1668 EXPECT_EQ(JNIInvalidRefType, env_->GetObjectRefType(inner1));
1669
1670 // Our local reference for the survivor is invalid because the survivor
1671 // gets a new local reference...
1672 EXPECT_EQ(JNIInvalidRefType, env_->GetObjectRefType(inner2));
1673 // ...but the survivor should be in the local reference table.
Brian Carlstrom4d571432012-05-16 00:21:41 -07001674 JNIEnvExt* env = reinterpret_cast<JNIEnvExt*>(env_);
1675 EXPECT_TRUE(env->locals.ContainsDirectPointer(inner2_direct_pointer));
Elliott Hughes2ced6a52011-10-16 18:44:48 -07001676
1677 env_->PopLocalFrame(NULL);
1678 }
1679 EXPECT_EQ(JNILocalRefType, env_->GetObjectRefType(original));
1680 EXPECT_EQ(JNIInvalidRefType, env_->GetObjectRefType(outer));
1681 EXPECT_EQ(JNIInvalidRefType, env_->GetObjectRefType(inner1));
1682 EXPECT_EQ(JNIInvalidRefType, env_->GetObjectRefType(inner2));
1683}
1684
Elliott Hughes18c07532011-08-18 15:50:51 -07001685TEST_F(JniInternalTest, NewGlobalRef_NULL) {
1686 EXPECT_TRUE(env_->NewGlobalRef(NULL) == NULL);
1687}
1688
1689TEST_F(JniInternalTest, NewGlobalRef) {
1690 jstring s = env_->NewStringUTF("");
1691 ASSERT_TRUE(s != NULL);
1692 jobject o = env_->NewGlobalRef(s);
1693 EXPECT_TRUE(o != NULL);
1694 EXPECT_TRUE(o != s);
1695
1696 // TODO: check that o is a global reference.
1697}
1698
1699TEST_F(JniInternalTest, DeleteGlobalRef_NULL) {
1700 env_->DeleteGlobalRef(NULL);
1701}
1702
1703TEST_F(JniInternalTest, DeleteGlobalRef) {
1704 jstring s = env_->NewStringUTF("");
1705 ASSERT_TRUE(s != NULL);
1706
1707 jobject o = env_->NewGlobalRef(s);
1708 ASSERT_TRUE(o != NULL);
1709 env_->DeleteGlobalRef(o);
1710
Elliott Hughes3f6635a2012-06-19 13:37:49 -07001711 // Currently, deleting an already-deleted reference is just a CheckJNI warning.
Elliott Hughesb264f082012-04-06 17:10:10 -07001712 {
Elliott Hughesb264f082012-04-06 17:10:10 -07001713 CheckJniAbortCatcher check_jni_abort_catcher;
1714 env_->DeleteGlobalRef(o);
Elliott Hughesa9137c62013-01-09 10:55:21 -08001715
Brian Carlstromea46f952013-07-30 01:26:50 -07001716 std::string expected(StringPrintf("native code passing in reference to "
1717 "invalid global reference: %p", o));
Elliott Hughesa9137c62013-01-09 10:55:21 -08001718 check_jni_abort_catcher.Check(expected.c_str());
Elliott Hughesb264f082012-04-06 17:10:10 -07001719 }
Elliott Hughes18c07532011-08-18 15:50:51 -07001720
1721 jobject o1 = env_->NewGlobalRef(s);
1722 ASSERT_TRUE(o1 != NULL);
1723 jobject o2 = env_->NewGlobalRef(s);
1724 ASSERT_TRUE(o2 != NULL);
1725
1726 env_->DeleteGlobalRef(o1);
1727 env_->DeleteGlobalRef(o2);
1728}
1729
1730TEST_F(JniInternalTest, NewWeakGlobalRef_NULL) {
1731 EXPECT_TRUE(env_->NewWeakGlobalRef(NULL) == NULL);
1732}
1733
1734TEST_F(JniInternalTest, NewWeakGlobalRef) {
1735 jstring s = env_->NewStringUTF("");
1736 ASSERT_TRUE(s != NULL);
1737 jobject o = env_->NewWeakGlobalRef(s);
1738 EXPECT_TRUE(o != NULL);
1739 EXPECT_TRUE(o != s);
1740
1741 // TODO: check that o is a weak global reference.
1742}
1743
1744TEST_F(JniInternalTest, DeleteWeakGlobalRef_NULL) {
1745 env_->DeleteWeakGlobalRef(NULL);
1746}
1747
1748TEST_F(JniInternalTest, DeleteWeakGlobalRef) {
1749 jstring s = env_->NewStringUTF("");
1750 ASSERT_TRUE(s != NULL);
1751
1752 jobject o = env_->NewWeakGlobalRef(s);
1753 ASSERT_TRUE(o != NULL);
1754 env_->DeleteWeakGlobalRef(o);
1755
Elliott Hughes3f6635a2012-06-19 13:37:49 -07001756 // Currently, deleting an already-deleted reference is just a CheckJNI warning.
Elliott Hughesb264f082012-04-06 17:10:10 -07001757 {
Elliott Hughesb264f082012-04-06 17:10:10 -07001758 CheckJniAbortCatcher check_jni_abort_catcher;
1759 env_->DeleteWeakGlobalRef(o);
Elliott Hughesa9137c62013-01-09 10:55:21 -08001760
Brian Carlstromea46f952013-07-30 01:26:50 -07001761 std::string expected(StringPrintf("native code passing in reference to "
1762 "invalid weak global reference: %p", o));
Elliott Hughesa9137c62013-01-09 10:55:21 -08001763 check_jni_abort_catcher.Check(expected.c_str());
Elliott Hughesb264f082012-04-06 17:10:10 -07001764 }
Elliott Hughes18c07532011-08-18 15:50:51 -07001765
1766 jobject o1 = env_->NewWeakGlobalRef(s);
1767 ASSERT_TRUE(o1 != NULL);
1768 jobject o2 = env_->NewWeakGlobalRef(s);
1769 ASSERT_TRUE(o2 != NULL);
1770
1771 env_->DeleteWeakGlobalRef(o1);
1772 env_->DeleteWeakGlobalRef(o2);
1773}
1774
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001775TEST_F(JniInternalTest, StaticMainMethod) {
Brian Carlstrom265091e2013-01-30 14:08:26 -08001776 TEST_DISABLED_FOR_PORTABLE();
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001777 ScopedObjectAccess soa(Thread::Current());
1778 jobject jclass_loader = LoadDex("Main");
Ian Rogers2dd0e2c2013-01-24 12:42:14 -08001779 SirtRef<mirror::ClassLoader>
1780 class_loader(soa.Self(), soa.Decode<mirror::ClassLoader*>(jclass_loader));
Mathieu Chartier590fee92013-09-13 13:46:47 -07001781 CompileDirectMethod(class_loader, "Main", "main", "([Ljava/lang/String;)V");
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001782
Ian Rogers98379392014-02-24 16:53:16 -08001783 mirror::Class* klass = class_linker_->FindClass(soa.Self(), "LMain;", class_loader);
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001784 ASSERT_TRUE(klass != NULL);
1785
Brian Carlstromea46f952013-07-30 01:26:50 -07001786 mirror::ArtMethod* method = klass->FindDirectMethod("main", "([Ljava/lang/String;)V");
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001787 ASSERT_TRUE(method != NULL);
1788
Ian Rogers936b37f2014-02-14 00:52:24 -08001789 ArgArray arg_array("VL", 2);
Ian Rogersef7d42f2014-01-06 12:55:46 -08001790 arg_array.Append(0U);
Jeff Hao5d917302013-02-27 17:57:33 -08001791 JValue result;
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001792
Sebastien Hertzb95851f2013-03-29 10:36:40 +01001793 // Start runtime.
1794 bool started = runtime_->Start();
1795 CHECK(started);
1796 Thread::Current()->TransitionFromSuspendedToRunnable();
1797
Ian Rogers0177e532014-02-11 16:30:46 -08001798 method->Invoke(Thread::Current(), arg_array.GetArray(), arg_array.GetNumBytes(), &result, "VL");
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001799}
1800
1801TEST_F(JniInternalTest, StaticNopMethod) {
Brian Carlstrom265091e2013-01-30 14:08:26 -08001802 TEST_DISABLED_FOR_PORTABLE();
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001803 ScopedObjectAccess soa(Thread::Current());
Elliott Hughes77405792012-03-15 15:22:12 -07001804 InvokeNopMethod(true);
1805}
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001806
Elliott Hughes77405792012-03-15 15:22:12 -07001807TEST_F(JniInternalTest, NonStaticNopMethod) {
Brian Carlstrom265091e2013-01-30 14:08:26 -08001808 TEST_DISABLED_FOR_PORTABLE();
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001809 ScopedObjectAccess soa(Thread::Current());
Elliott Hughes77405792012-03-15 15:22:12 -07001810 InvokeNopMethod(false);
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001811}
1812
1813TEST_F(JniInternalTest, StaticIdentityByteMethod) {
Brian Carlstrom265091e2013-01-30 14:08:26 -08001814 TEST_DISABLED_FOR_PORTABLE();
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001815 ScopedObjectAccess soa(Thread::Current());
Elliott Hughes77405792012-03-15 15:22:12 -07001816 InvokeIdentityByteMethod(true);
1817}
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001818
Elliott Hughes77405792012-03-15 15:22:12 -07001819TEST_F(JniInternalTest, NonStaticIdentityByteMethod) {
Brian Carlstrom265091e2013-01-30 14:08:26 -08001820 TEST_DISABLED_FOR_PORTABLE();
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001821 ScopedObjectAccess soa(Thread::Current());
Elliott Hughes77405792012-03-15 15:22:12 -07001822 InvokeIdentityByteMethod(false);
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001823}
1824
1825TEST_F(JniInternalTest, StaticIdentityIntMethod) {
Brian Carlstrom265091e2013-01-30 14:08:26 -08001826 TEST_DISABLED_FOR_PORTABLE();
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001827 ScopedObjectAccess soa(Thread::Current());
Elliott Hughes77405792012-03-15 15:22:12 -07001828 InvokeIdentityIntMethod(true);
1829}
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001830
Elliott Hughes77405792012-03-15 15:22:12 -07001831TEST_F(JniInternalTest, NonStaticIdentityIntMethod) {
Brian Carlstrom265091e2013-01-30 14:08:26 -08001832 TEST_DISABLED_FOR_PORTABLE();
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001833 ScopedObjectAccess soa(Thread::Current());
Elliott Hughes77405792012-03-15 15:22:12 -07001834 InvokeIdentityIntMethod(false);
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001835}
1836
1837TEST_F(JniInternalTest, StaticIdentityDoubleMethod) {
Brian Carlstrom265091e2013-01-30 14:08:26 -08001838 TEST_DISABLED_FOR_PORTABLE();
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001839 ScopedObjectAccess soa(Thread::Current());
Elliott Hughes77405792012-03-15 15:22:12 -07001840 InvokeIdentityDoubleMethod(true);
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001841}
1842
Elliott Hughes77405792012-03-15 15:22:12 -07001843TEST_F(JniInternalTest, NonStaticIdentityDoubleMethod) {
Brian Carlstrom265091e2013-01-30 14:08:26 -08001844 TEST_DISABLED_FOR_PORTABLE();
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001845 ScopedObjectAccess soa(Thread::Current());
Elliott Hughes77405792012-03-15 15:22:12 -07001846 InvokeIdentityDoubleMethod(false);
Shih-wei Liao5b8b1ed2012-02-23 23:48:21 -08001847}
1848
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001849TEST_F(JniInternalTest, StaticSumIntIntMethod) {
Brian Carlstrom265091e2013-01-30 14:08:26 -08001850 TEST_DISABLED_FOR_PORTABLE();
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001851 ScopedObjectAccess soa(Thread::Current());
Elliott Hughes77405792012-03-15 15:22:12 -07001852 InvokeSumIntIntMethod(true);
1853}
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001854
Elliott Hughes77405792012-03-15 15:22:12 -07001855TEST_F(JniInternalTest, NonStaticSumIntIntMethod) {
Brian Carlstrom265091e2013-01-30 14:08:26 -08001856 TEST_DISABLED_FOR_PORTABLE();
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001857 ScopedObjectAccess soa(Thread::Current());
Elliott Hughes77405792012-03-15 15:22:12 -07001858 InvokeSumIntIntMethod(false);
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001859}
1860
1861TEST_F(JniInternalTest, StaticSumIntIntIntMethod) {
Brian Carlstrom265091e2013-01-30 14:08:26 -08001862 TEST_DISABLED_FOR_PORTABLE();
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001863 ScopedObjectAccess soa(Thread::Current());
Elliott Hughes77405792012-03-15 15:22:12 -07001864 InvokeSumIntIntIntMethod(true);
1865}
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001866
Elliott Hughes77405792012-03-15 15:22:12 -07001867TEST_F(JniInternalTest, NonStaticSumIntIntIntMethod) {
Brian Carlstrom265091e2013-01-30 14:08:26 -08001868 TEST_DISABLED_FOR_PORTABLE();
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001869 ScopedObjectAccess soa(Thread::Current());
Elliott Hughes77405792012-03-15 15:22:12 -07001870 InvokeSumIntIntIntMethod(false);
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001871}
1872
1873TEST_F(JniInternalTest, StaticSumIntIntIntIntMethod) {
Brian Carlstrom265091e2013-01-30 14:08:26 -08001874 TEST_DISABLED_FOR_PORTABLE();
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001875 ScopedObjectAccess soa(Thread::Current());
Elliott Hughes77405792012-03-15 15:22:12 -07001876 InvokeSumIntIntIntIntMethod(true);
1877}
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001878
Elliott Hughes77405792012-03-15 15:22:12 -07001879TEST_F(JniInternalTest, NonStaticSumIntIntIntIntMethod) {
Brian Carlstrom265091e2013-01-30 14:08:26 -08001880 TEST_DISABLED_FOR_PORTABLE();
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001881 ScopedObjectAccess soa(Thread::Current());
Elliott Hughes77405792012-03-15 15:22:12 -07001882 InvokeSumIntIntIntIntMethod(false);
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001883}
1884
1885TEST_F(JniInternalTest, StaticSumIntIntIntIntIntMethod) {
Brian Carlstrom265091e2013-01-30 14:08:26 -08001886 TEST_DISABLED_FOR_PORTABLE();
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001887 ScopedObjectAccess soa(Thread::Current());
Elliott Hughes77405792012-03-15 15:22:12 -07001888 InvokeSumIntIntIntIntIntMethod(true);
1889}
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001890
Elliott Hughes77405792012-03-15 15:22:12 -07001891TEST_F(JniInternalTest, NonStaticSumIntIntIntIntIntMethod) {
Brian Carlstrom265091e2013-01-30 14:08:26 -08001892 TEST_DISABLED_FOR_PORTABLE();
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001893 ScopedObjectAccess soa(Thread::Current());
Elliott Hughes77405792012-03-15 15:22:12 -07001894 InvokeSumIntIntIntIntIntMethod(false);
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001895}
1896
1897TEST_F(JniInternalTest, StaticSumDoubleDoubleMethod) {
Brian Carlstrom265091e2013-01-30 14:08:26 -08001898 TEST_DISABLED_FOR_PORTABLE();
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001899 ScopedObjectAccess soa(Thread::Current());
Elliott Hughes77405792012-03-15 15:22:12 -07001900 InvokeSumDoubleDoubleMethod(true);
1901}
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001902
Elliott Hughes77405792012-03-15 15:22:12 -07001903TEST_F(JniInternalTest, NonStaticSumDoubleDoubleMethod) {
Brian Carlstrom265091e2013-01-30 14:08:26 -08001904 TEST_DISABLED_FOR_PORTABLE();
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001905 ScopedObjectAccess soa(Thread::Current());
Elliott Hughes77405792012-03-15 15:22:12 -07001906 InvokeSumDoubleDoubleMethod(false);
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001907}
1908
1909TEST_F(JniInternalTest, StaticSumDoubleDoubleDoubleMethod) {
Brian Carlstrom265091e2013-01-30 14:08:26 -08001910 TEST_DISABLED_FOR_PORTABLE();
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001911 ScopedObjectAccess soa(Thread::Current());
Elliott Hughes77405792012-03-15 15:22:12 -07001912 InvokeSumDoubleDoubleDoubleMethod(true);
1913}
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001914
Elliott Hughes77405792012-03-15 15:22:12 -07001915TEST_F(JniInternalTest, NonStaticSumDoubleDoubleDoubleMethod) {
Brian Carlstrom265091e2013-01-30 14:08:26 -08001916 TEST_DISABLED_FOR_PORTABLE();
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001917 ScopedObjectAccess soa(Thread::Current());
Elliott Hughes77405792012-03-15 15:22:12 -07001918 InvokeSumDoubleDoubleDoubleMethod(false);
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001919}
1920
1921TEST_F(JniInternalTest, StaticSumDoubleDoubleDoubleDoubleMethod) {
Brian Carlstrom265091e2013-01-30 14:08:26 -08001922 TEST_DISABLED_FOR_PORTABLE();
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001923 ScopedObjectAccess soa(Thread::Current());
Elliott Hughes77405792012-03-15 15:22:12 -07001924 InvokeSumDoubleDoubleDoubleDoubleMethod(true);
1925}
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001926
Elliott Hughes77405792012-03-15 15:22:12 -07001927TEST_F(JniInternalTest, NonStaticSumDoubleDoubleDoubleDoubleMethod) {
Brian Carlstrom265091e2013-01-30 14:08:26 -08001928 TEST_DISABLED_FOR_PORTABLE();
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001929 ScopedObjectAccess soa(Thread::Current());
Elliott Hughes77405792012-03-15 15:22:12 -07001930 InvokeSumDoubleDoubleDoubleDoubleMethod(false);
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001931}
1932
1933TEST_F(JniInternalTest, StaticSumDoubleDoubleDoubleDoubleDoubleMethod) {
Brian Carlstrom265091e2013-01-30 14:08:26 -08001934 TEST_DISABLED_FOR_PORTABLE();
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001935 ScopedObjectAccess soa(Thread::Current());
Elliott Hughes77405792012-03-15 15:22:12 -07001936 InvokeSumDoubleDoubleDoubleDoubleDoubleMethod(true);
1937}
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001938
Elliott Hughes77405792012-03-15 15:22:12 -07001939TEST_F(JniInternalTest, NonStaticSumDoubleDoubleDoubleDoubleDoubleMethod) {
Brian Carlstrom265091e2013-01-30 14:08:26 -08001940 TEST_DISABLED_FOR_PORTABLE();
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001941 ScopedObjectAccess soa(Thread::Current());
Elliott Hughes77405792012-03-15 15:22:12 -07001942 InvokeSumDoubleDoubleDoubleDoubleDoubleMethod(false);
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001943}
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001944
Elliott Hughes37f7a402011-08-22 18:56:01 -07001945TEST_F(JniInternalTest, Throw) {
1946 EXPECT_EQ(JNI_ERR, env_->Throw(NULL));
1947
1948 jclass exception_class = env_->FindClass("java/lang/RuntimeException");
1949 ASSERT_TRUE(exception_class != NULL);
1950 jthrowable exception = reinterpret_cast<jthrowable>(env_->AllocObject(exception_class));
1951 ASSERT_TRUE(exception != NULL);
1952
1953 EXPECT_EQ(JNI_OK, env_->Throw(exception));
1954 EXPECT_TRUE(env_->ExceptionCheck());
Elliott Hughesa2501992011-08-26 19:39:54 -07001955 jthrowable thrown_exception = env_->ExceptionOccurred();
Elliott Hughes37f7a402011-08-22 18:56:01 -07001956 env_->ExceptionClear();
Elliott Hughesa2501992011-08-26 19:39:54 -07001957 EXPECT_TRUE(env_->IsSameObject(exception, thrown_exception));
Elliott Hughes37f7a402011-08-22 18:56:01 -07001958}
1959
1960TEST_F(JniInternalTest, ThrowNew) {
1961 EXPECT_EQ(JNI_ERR, env_->Throw(NULL));
1962
1963 jclass exception_class = env_->FindClass("java/lang/RuntimeException");
1964 ASSERT_TRUE(exception_class != NULL);
1965
Elliott Hughes5cb5ad22011-10-02 12:13:39 -07001966 jthrowable thrown_exception;
1967
Elliott Hughes37f7a402011-08-22 18:56:01 -07001968 EXPECT_EQ(JNI_OK, env_->ThrowNew(exception_class, "hello world"));
1969 EXPECT_TRUE(env_->ExceptionCheck());
Elliott Hughes5cb5ad22011-10-02 12:13:39 -07001970 thrown_exception = env_->ExceptionOccurred();
1971 env_->ExceptionClear();
1972 EXPECT_TRUE(env_->IsInstanceOf(thrown_exception, exception_class));
1973
1974 EXPECT_EQ(JNI_OK, env_->ThrowNew(exception_class, NULL));
1975 EXPECT_TRUE(env_->ExceptionCheck());
1976 thrown_exception = env_->ExceptionOccurred();
Elliott Hughes37f7a402011-08-22 18:56:01 -07001977 env_->ExceptionClear();
Elliott Hughesa2501992011-08-26 19:39:54 -07001978 EXPECT_TRUE(env_->IsInstanceOf(thrown_exception, exception_class));
Elliott Hughes37f7a402011-08-22 18:56:01 -07001979}
1980
Ian Rogers1d99e452014-01-02 17:36:41 -08001981TEST_F(JniInternalTest, NewDirectBuffer_GetDirectBufferAddress_GetDirectBufferCapacity) {
1982 // Start runtime.
1983 Thread* self = Thread::Current();
1984 self->TransitionFromSuspendedToRunnable();
1985 MakeExecutable(nullptr, "java.lang.Class");
1986 MakeExecutable(nullptr, "java.lang.Object");
1987 MakeExecutable(nullptr, "java.nio.DirectByteBuffer");
1988 MakeExecutable(nullptr, "java.nio.MemoryBlock");
1989 MakeExecutable(nullptr, "java.nio.MemoryBlock$UnmanagedBlock");
1990 MakeExecutable(nullptr, "java.nio.MappedByteBuffer");
1991 MakeExecutable(nullptr, "java.nio.ByteBuffer");
1992 MakeExecutable(nullptr, "java.nio.Buffer");
1993 // TODO: we only load a dex file here as starting the runtime relies upon it.
1994 const char* class_name = "StaticLeafMethods";
1995 LoadDex(class_name);
1996 bool started = runtime_->Start();
1997 ASSERT_TRUE(started);
1998
Elliott Hughesb465ab02011-08-24 11:21:21 -07001999 jclass buffer_class = env_->FindClass("java/nio/Buffer");
2000 ASSERT_TRUE(buffer_class != NULL);
2001
2002 char bytes[1024];
2003 jobject buffer = env_->NewDirectByteBuffer(bytes, sizeof(bytes));
2004 ASSERT_TRUE(buffer != NULL);
2005 ASSERT_TRUE(env_->IsInstanceOf(buffer, buffer_class));
2006 ASSERT_TRUE(env_->GetDirectBufferAddress(buffer) == bytes);
2007 ASSERT_TRUE(env_->GetDirectBufferCapacity(buffer) == sizeof(bytes));
2008}
2009
Ian Rogers6d0b13e2012-02-07 09:25:29 -08002010TEST_F(JniInternalTest, MonitorEnterExit) {
2011 // Create an object to torture
2012 jclass object_class = env_->FindClass("java/lang/Object");
2013 ASSERT_TRUE(object_class != NULL);
2014 jobject object = env_->AllocObject(object_class);
2015 ASSERT_TRUE(object != NULL);
2016
2017 // Expected class of exceptions
2018 jclass imse_class = env_->FindClass("java/lang/IllegalMonitorStateException");
2019 ASSERT_TRUE(imse_class != NULL);
2020
2021 jthrowable thrown_exception;
2022
2023 // Unlock of unowned monitor
2024 env_->MonitorExit(object);
2025 EXPECT_TRUE(env_->ExceptionCheck());
2026 thrown_exception = env_->ExceptionOccurred();
2027 env_->ExceptionClear();
2028 EXPECT_TRUE(env_->IsInstanceOf(thrown_exception, imse_class));
2029
2030 // Lock of unowned monitor
2031 env_->MonitorEnter(object);
2032 EXPECT_FALSE(env_->ExceptionCheck());
2033 // Regular unlock
2034 env_->MonitorExit(object);
2035 EXPECT_FALSE(env_->ExceptionCheck());
2036
2037 // Recursively lock a lot
2038 size_t max_recursive_lock = 1024;
2039 for (size_t i = 0; i < max_recursive_lock; i++) {
2040 env_->MonitorEnter(object);
2041 EXPECT_FALSE(env_->ExceptionCheck());
2042 }
2043 // Recursively unlock a lot
2044 for (size_t i = 0; i < max_recursive_lock; i++) {
2045 env_->MonitorExit(object);
2046 EXPECT_FALSE(env_->ExceptionCheck());
2047 }
2048
2049 // Unlock of unowned monitor
2050 env_->MonitorExit(object);
2051 EXPECT_TRUE(env_->ExceptionCheck());
2052 thrown_exception = env_->ExceptionOccurred();
2053 env_->ExceptionClear();
2054 EXPECT_TRUE(env_->IsInstanceOf(thrown_exception, imse_class));
Elliott Hughesa92853e2012-02-07 16:09:27 -08002055
2056 // It's an error to call MonitorEnter or MonitorExit on NULL.
Elliott Hughesb264f082012-04-06 17:10:10 -07002057 {
2058 CheckJniAbortCatcher check_jni_abort_catcher;
2059 env_->MonitorEnter(NULL);
2060 check_jni_abort_catcher.Check("in call to MonitorEnter");
Elliott Hughesb264f082012-04-06 17:10:10 -07002061
Elliott Hughesb264f082012-04-06 17:10:10 -07002062 env_->MonitorExit(NULL);
2063 check_jni_abort_catcher.Check("in call to MonitorExit");
2064 }
Ian Rogers6d0b13e2012-02-07 09:25:29 -08002065}
2066
Brian Carlstrom4d571432012-05-16 00:21:41 -07002067TEST_F(JniInternalTest, DetachCurrentThread) {
2068 CleanUpJniEnv(); // cleanup now so TearDown won't have junk from wrong JNIEnv
2069 jint ok = vm_->DetachCurrentThread();
2070 EXPECT_EQ(JNI_OK, ok);
2071
2072 jint err = vm_->DetachCurrentThread();
2073 EXPECT_EQ(JNI_ERR, err);
Brian Carlstroma1ce1fe2014-02-24 23:23:58 -08002074 vm_->AttachCurrentThread(&env_, NULL); // need attached thread for CommonRuntimeTest::TearDown
Brian Carlstrom4d571432012-05-16 00:21:41 -07002075}
2076
Ian Rogers0cfe1fb2011-08-26 03:29:44 -07002077} // namespace art