blob: 63bc45cbd25a42ebae692bb6d3398a768da66c31 [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
Carl Shapiro9b9ba282011-08-14 15:30:39 -070023#include "common_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 Carlstromf734cf52011-08-17 16:28:14 -070034class JniInternalTest : public CommonTest {
Elliott Hughesc7ac37f2011-08-12 12:21:58 -070035 protected:
36 virtual void SetUp() {
Brian Carlstromf734cf52011-08-17 16:28:14 -070037 CommonTest::SetUp();
Elliott Hughes5174fe62011-08-23 15:12:35 -070038
Elliott Hughesa2501992011-08-26 19:39:54 -070039 vm_ = Runtime::Current()->GetJavaVM();
40
Elliott Hughes5174fe62011-08-23 15:12:35 -070041 // Turn on -verbose:jni for the JNI tests.
Ian Rogers79713632013-08-21 19:06:15 -070042 // gLogVerbosity.jni = true;
Elliott Hughes5174fe62011-08-23 15:12:35 -070043
Brian Carlstrom4d571432012-05-16 00:21:41 -070044 vm_->AttachCurrentThread(&env_, NULL);
Elliott Hughesb465ab02011-08-24 11:21:21 -070045
Brian Carlstromea46f952013-07-30 01:26:50 -070046 ScopedLocalRef<jclass> aioobe(env_,
47 env_->FindClass("java/lang/ArrayIndexOutOfBoundsException"));
Elliott Hughes726079d2011-10-07 18:43:44 -070048 CHECK(aioobe.get() != NULL);
49 aioobe_ = reinterpret_cast<jclass>(env_->NewGlobalRef(aioobe.get()));
Elliott Hughesb465ab02011-08-24 11:21:21 -070050
Elliott Hughesb264f082012-04-06 17:10:10 -070051 ScopedLocalRef<jclass> ase(env_, env_->FindClass("java/lang/ArrayStoreException"));
52 CHECK(ase.get() != NULL);
53 ase_ = reinterpret_cast<jclass>(env_->NewGlobalRef(ase.get()));
54
Brian Carlstromea46f952013-07-30 01:26:50 -070055 ScopedLocalRef<jclass> sioobe(env_,
56 env_->FindClass("java/lang/StringIndexOutOfBoundsException"));
Elliott Hughes726079d2011-10-07 18:43:44 -070057 CHECK(sioobe.get() != NULL);
58 sioobe_ = reinterpret_cast<jclass>(env_->NewGlobalRef(sioobe.get()));
59 }
60
Brian Carlstrom4d571432012-05-16 00:21:41 -070061 void CleanUpJniEnv() {
62 if (aioobe_ != NULL) {
63 env_->DeleteGlobalRef(aioobe_);
64 aioobe_ = NULL;
65 }
66 if (ase_ != NULL) {
67 env_->DeleteGlobalRef(ase_);
68 ase_ = NULL;
69 }
70 if (sioobe_ != NULL) {
71 env_->DeleteGlobalRef(sioobe_);
72 sioobe_ = NULL;
73 }
74 }
75
Elliott Hughes726079d2011-10-07 18:43:44 -070076 virtual void TearDown() {
Brian Carlstrom4d571432012-05-16 00:21:41 -070077 CleanUpJniEnv();
Elliott Hughes726079d2011-10-07 18:43:44 -070078 CommonTest::TearDown();
Elliott Hughesc7ac37f2011-08-12 12:21:58 -070079 }
Elliott Hughesb465ab02011-08-24 11:21:21 -070080
Ian Rogers1d99e452014-01-02 17:36:41 -080081 jclass GetPrimitiveClass(char descriptor) {
82 ScopedObjectAccess soa(env_);
83 mirror::Class* c = class_linker_->FindPrimitiveClass(descriptor);
84 CHECK(c != nullptr);
85 return soa.AddLocalReference<jclass>(c);
86 }
87
88 void JniInternalTestMakeExecutable(mirror::ArtMethod** method,
89 mirror::Object** receiver,
90 bool is_static, const char* method_name,
91 const char* method_signature)
Ian Rogersb726dcb2012-09-05 08:57:23 -070092 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Elliott Hughes77405792012-03-15 15:22:12 -070093 const char* class_name = is_static ? "StaticLeafMethods" : "NonStaticLeafMethods";
Ian Rogers00f7d0e2012-07-19 15:28:27 -070094 jobject jclass_loader(LoadDex(class_name));
Ian Rogers1f539342012-10-03 21:09:42 -070095 Thread* self = Thread::Current();
Mathieu Chartier590fee92013-09-13 13:46:47 -070096 SirtRef<mirror::ClassLoader> null_class_loader(self, nullptr);
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080097 SirtRef<mirror::ClassLoader>
Ian Rogers1f539342012-10-03 21:09:42 -070098 class_loader(self,
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080099 ScopedObjectAccessUnchecked(self).Decode<mirror::ClassLoader*>(jclass_loader));
Elliott Hughes77405792012-03-15 15:22:12 -0700100 if (is_static) {
Ian Rogers1d99e452014-01-02 17:36:41 -0800101 MakeExecutable(ScopedObjectAccessUnchecked(self).Decode<mirror::ClassLoader*>(jclass_loader),
102 class_name);
Elliott Hughes77405792012-03-15 15:22:12 -0700103 } else {
Ian Rogers1d99e452014-01-02 17:36:41 -0800104 MakeExecutable(nullptr, "java.lang.Class");
105 MakeExecutable(nullptr, "java.lang.Object");
106 MakeExecutable(ScopedObjectAccessUnchecked(self).Decode<mirror::ClassLoader*>(jclass_loader),
107 class_name);
Elliott Hughes77405792012-03-15 15:22:12 -0700108 }
109
Ian Rogers98379392014-02-24 16:53:16 -0800110 mirror::Class* c = class_linker_->FindClass(self, DotToDescriptor(class_name).c_str(),
111 class_loader);
Elliott Hughes77405792012-03-15 15:22:12 -0700112 CHECK(c != NULL);
113
Ian Rogers1d99e452014-01-02 17:36:41 -0800114 *method = is_static ? c->FindDirectMethod(method_name, method_signature)
115 : c->FindVirtualMethod(method_name, method_signature);
116 CHECK(method != nullptr);
Elliott Hughes77405792012-03-15 15:22:12 -0700117
Ian Rogers1d99e452014-01-02 17:36:41 -0800118 *receiver = (is_static ? nullptr : c->AllocObject(self));
Sebastien Hertzb95851f2013-03-29 10:36:40 +0100119
120 // Start runtime.
121 bool started = runtime_->Start();
122 CHECK(started);
123 self->TransitionFromSuspendedToRunnable();
Elliott Hughes77405792012-03-15 15:22:12 -0700124 }
125
Ian Rogersb726dcb2012-09-05 08:57:23 -0700126 void InvokeNopMethod(bool is_static) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Brian Carlstromea46f952013-07-30 01:26:50 -0700127 mirror::ArtMethod* method;
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800128 mirror::Object* receiver;
Ian Rogers1d99e452014-01-02 17:36:41 -0800129 JniInternalTestMakeExecutable(&method, &receiver, is_static, "nop", "()V");
Jeff Hao5d917302013-02-27 17:57:33 -0800130
Ian Rogers936b37f2014-02-14 00:52:24 -0800131 ArgArray arg_array("V", 1);
Jeff Hao5d917302013-02-27 17:57:33 -0800132 JValue result;
Jeff Hao5d917302013-02-27 17:57:33 -0800133
134 if (!is_static) {
Ian Rogersef7d42f2014-01-06 12:55:46 -0800135 arg_array.Append(receiver);
Jeff Hao5d917302013-02-27 17:57:33 -0800136 }
Sebastien Hertzb95851f2013-03-29 10:36:40 +0100137
Ian Rogers0177e532014-02-11 16:30:46 -0800138 method->Invoke(Thread::Current(), arg_array.GetArray(), arg_array.GetNumBytes(), &result, "V");
Elliott Hughes77405792012-03-15 15:22:12 -0700139 }
140
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700141 void InvokeIdentityByteMethod(bool is_static)
Ian Rogersb726dcb2012-09-05 08:57:23 -0700142 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Brian Carlstromea46f952013-07-30 01:26:50 -0700143 mirror::ArtMethod* method;
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800144 mirror::Object* receiver;
Ian Rogers0177e532014-02-11 16:30:46 -0800145 JniInternalTestMakeExecutable(&method, &receiver, is_static, "identity", "(B)B");
Elliott Hughes77405792012-03-15 15:22:12 -0700146
Ian Rogers936b37f2014-02-14 00:52:24 -0800147 ArgArray arg_array("BB", 2);
Jeff Hao5d917302013-02-27 17:57:33 -0800148 uint32_t* args = arg_array.GetArray();
Elliott Hughes77405792012-03-15 15:22:12 -0700149 JValue result;
150
Jeff Hao5d917302013-02-27 17:57:33 -0800151 if (!is_static) {
Ian Rogersef7d42f2014-01-06 12:55:46 -0800152 arg_array.Append(receiver);
Jeff Hao5d917302013-02-27 17:57:33 -0800153 args++;
154 }
155
Ian Rogersef7d42f2014-01-06 12:55:46 -0800156 arg_array.Append(0U);
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700157 result.SetB(-1);
Ian Rogers0177e532014-02-11 16:30:46 -0800158 method->Invoke(Thread::Current(), arg_array.GetArray(), arg_array.GetNumBytes(), &result, "BB");
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700159 EXPECT_EQ(0, result.GetB());
Elliott Hughes77405792012-03-15 15:22:12 -0700160
Jeff Hao5d917302013-02-27 17:57:33 -0800161 args[0] = -1;
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700162 result.SetB(0);
Ian Rogers0177e532014-02-11 16:30:46 -0800163 method->Invoke(Thread::Current(), arg_array.GetArray(), arg_array.GetNumBytes(), &result, "BB");
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700164 EXPECT_EQ(-1, result.GetB());
Elliott Hughes77405792012-03-15 15:22:12 -0700165
Jeff Hao5d917302013-02-27 17:57:33 -0800166 args[0] = SCHAR_MAX;
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700167 result.SetB(0);
Ian Rogers0177e532014-02-11 16:30:46 -0800168 method->Invoke(Thread::Current(), arg_array.GetArray(), arg_array.GetNumBytes(), &result, "BB");
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700169 EXPECT_EQ(SCHAR_MAX, result.GetB());
Elliott Hughes77405792012-03-15 15:22:12 -0700170
Jeff Hao5d917302013-02-27 17:57:33 -0800171 args[0] = (SCHAR_MIN << 24) >> 24;
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700172 result.SetB(0);
Ian Rogers0177e532014-02-11 16:30:46 -0800173 method->Invoke(Thread::Current(), arg_array.GetArray(), arg_array.GetNumBytes(), &result, "BB");
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700174 EXPECT_EQ(SCHAR_MIN, result.GetB());
Elliott Hughes77405792012-03-15 15:22:12 -0700175 }
176
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700177 void InvokeIdentityIntMethod(bool is_static)
Ian Rogersb726dcb2012-09-05 08:57:23 -0700178 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Brian Carlstromea46f952013-07-30 01:26:50 -0700179 mirror::ArtMethod* method;
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800180 mirror::Object* receiver;
Ian Rogers1d99e452014-01-02 17:36:41 -0800181 JniInternalTestMakeExecutable(&method, &receiver, is_static, "identity", "(I)I");
Elliott Hughes77405792012-03-15 15:22:12 -0700182
Ian Rogers936b37f2014-02-14 00:52:24 -0800183 ArgArray arg_array("II", 2);
Jeff Hao5d917302013-02-27 17:57:33 -0800184 uint32_t* args = arg_array.GetArray();
Elliott Hughes77405792012-03-15 15:22:12 -0700185 JValue result;
186
Jeff Hao5d917302013-02-27 17:57:33 -0800187 if (!is_static) {
Ian Rogersef7d42f2014-01-06 12:55:46 -0800188 arg_array.Append(receiver);
Jeff Hao5d917302013-02-27 17:57:33 -0800189 args++;
190 }
191
Ian Rogersef7d42f2014-01-06 12:55:46 -0800192 arg_array.Append(0U);
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700193 result.SetI(-1);
Ian Rogers0177e532014-02-11 16:30:46 -0800194 method->Invoke(Thread::Current(), arg_array.GetArray(), arg_array.GetNumBytes(), &result, "II");
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700195 EXPECT_EQ(0, result.GetI());
Elliott Hughes77405792012-03-15 15:22:12 -0700196
Jeff Hao5d917302013-02-27 17:57:33 -0800197 args[0] = -1;
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700198 result.SetI(0);
Ian Rogers0177e532014-02-11 16:30:46 -0800199 method->Invoke(Thread::Current(), arg_array.GetArray(), arg_array.GetNumBytes(), &result, "II");
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700200 EXPECT_EQ(-1, result.GetI());
Elliott Hughes77405792012-03-15 15:22:12 -0700201
Jeff Hao5d917302013-02-27 17:57:33 -0800202 args[0] = INT_MAX;
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700203 result.SetI(0);
Ian Rogers0177e532014-02-11 16:30:46 -0800204 method->Invoke(Thread::Current(), arg_array.GetArray(), arg_array.GetNumBytes(), &result, "II");
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700205 EXPECT_EQ(INT_MAX, result.GetI());
Elliott Hughes77405792012-03-15 15:22:12 -0700206
Jeff Hao5d917302013-02-27 17:57:33 -0800207 args[0] = INT_MIN;
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700208 result.SetI(0);
Ian Rogers0177e532014-02-11 16:30:46 -0800209 method->Invoke(Thread::Current(), arg_array.GetArray(), arg_array.GetNumBytes(), &result, "II");
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700210 EXPECT_EQ(INT_MIN, result.GetI());
Elliott Hughes77405792012-03-15 15:22:12 -0700211 }
212
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700213 void InvokeIdentityDoubleMethod(bool is_static)
Ian Rogersb726dcb2012-09-05 08:57:23 -0700214 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Brian Carlstromea46f952013-07-30 01:26:50 -0700215 mirror::ArtMethod* method;
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800216 mirror::Object* receiver;
Ian Rogers1d99e452014-01-02 17:36:41 -0800217 JniInternalTestMakeExecutable(&method, &receiver, is_static, "identity", "(D)D");
Elliott Hughes77405792012-03-15 15:22:12 -0700218
Ian Rogers936b37f2014-02-14 00:52:24 -0800219 ArgArray arg_array("DD", 2);
Jeff Hao5d917302013-02-27 17:57:33 -0800220 uint32_t* args = arg_array.GetArray();
221 JValue value;
Elliott Hughes77405792012-03-15 15:22:12 -0700222 JValue result;
223
Jeff Hao5d917302013-02-27 17:57:33 -0800224 if (!is_static) {
Ian Rogersef7d42f2014-01-06 12:55:46 -0800225 arg_array.Append(receiver);
Jeff Hao5d917302013-02-27 17:57:33 -0800226 args++;
227 }
228
229 value.SetD(0.0);
230 arg_array.AppendWide(value.GetJ());
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700231 result.SetD(-1.0);
Ian Rogers0177e532014-02-11 16:30:46 -0800232 method->Invoke(Thread::Current(), arg_array.GetArray(), arg_array.GetNumBytes(), &result, "DD");
Jeff Hao6474d192013-03-26 14:08:09 -0700233 EXPECT_EQ(0.0, result.GetD());
Elliott Hughes77405792012-03-15 15:22:12 -0700234
Jeff Hao5d917302013-02-27 17:57:33 -0800235 value.SetD(-1.0);
236 args[0] = value.GetJ();
237 args[1] = value.GetJ() >> 32;
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700238 result.SetD(0.0);
Ian Rogers0177e532014-02-11 16:30:46 -0800239 method->Invoke(Thread::Current(), arg_array.GetArray(), arg_array.GetNumBytes(), &result, "DD");
Jeff Hao6474d192013-03-26 14:08:09 -0700240 EXPECT_EQ(-1.0, result.GetD());
Elliott Hughes77405792012-03-15 15:22:12 -0700241
Jeff Hao5d917302013-02-27 17:57:33 -0800242 value.SetD(DBL_MAX);
243 args[0] = value.GetJ();
244 args[1] = value.GetJ() >> 32;
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700245 result.SetD(0.0);
Ian Rogers0177e532014-02-11 16:30:46 -0800246 method->Invoke(Thread::Current(), arg_array.GetArray(), arg_array.GetNumBytes(), &result, "DD");
Jeff Hao6474d192013-03-26 14:08:09 -0700247 EXPECT_EQ(DBL_MAX, result.GetD());
Elliott Hughes77405792012-03-15 15:22:12 -0700248
Jeff Hao5d917302013-02-27 17:57:33 -0800249 value.SetD(DBL_MIN);
250 args[0] = value.GetJ();
251 args[1] = value.GetJ() >> 32;
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700252 result.SetD(0.0);
Ian Rogers0177e532014-02-11 16:30:46 -0800253 method->Invoke(Thread::Current(), arg_array.GetArray(), arg_array.GetNumBytes(), &result, "DD");
Jeff Hao6474d192013-03-26 14:08:09 -0700254 EXPECT_EQ(DBL_MIN, result.GetD());
Elliott Hughes77405792012-03-15 15:22:12 -0700255 }
256
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700257 void InvokeSumIntIntMethod(bool is_static)
Ian Rogersb726dcb2012-09-05 08:57:23 -0700258 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Brian Carlstromea46f952013-07-30 01:26:50 -0700259 mirror::ArtMethod* method;
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800260 mirror::Object* receiver;
Ian Rogers1d99e452014-01-02 17:36:41 -0800261 JniInternalTestMakeExecutable(&method, &receiver, is_static, "sum", "(II)I");
Elliott Hughes77405792012-03-15 15:22:12 -0700262
Ian Rogers936b37f2014-02-14 00:52:24 -0800263 ArgArray arg_array("III", 3);
Jeff Hao5d917302013-02-27 17:57:33 -0800264 uint32_t* args = arg_array.GetArray();
Elliott Hughes77405792012-03-15 15:22:12 -0700265 JValue result;
Jeff Hao5d917302013-02-27 17:57:33 -0800266
267 if (!is_static) {
Ian Rogersef7d42f2014-01-06 12:55:46 -0800268 arg_array.Append(receiver);
Jeff Hao5d917302013-02-27 17:57:33 -0800269 args++;
270 }
271
Ian Rogersef7d42f2014-01-06 12:55:46 -0800272 arg_array.Append(0U);
273 arg_array.Append(0U);
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700274 result.SetI(-1);
Ian Rogers0177e532014-02-11 16:30:46 -0800275 method->Invoke(Thread::Current(), arg_array.GetArray(), arg_array.GetNumBytes(), &result, "III");
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700276 EXPECT_EQ(0, result.GetI());
Elliott Hughes77405792012-03-15 15:22:12 -0700277
Jeff Hao5d917302013-02-27 17:57:33 -0800278 args[0] = 1;
279 args[1] = 2;
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700280 result.SetI(0);
Ian Rogers0177e532014-02-11 16:30:46 -0800281 method->Invoke(Thread::Current(), arg_array.GetArray(), arg_array.GetNumBytes(), &result, "III");
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700282 EXPECT_EQ(3, result.GetI());
Elliott Hughes77405792012-03-15 15:22:12 -0700283
Jeff Hao5d917302013-02-27 17:57:33 -0800284 args[0] = -2;
285 args[1] = 5;
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700286 result.SetI(0);
Ian Rogers0177e532014-02-11 16:30:46 -0800287 method->Invoke(Thread::Current(), arg_array.GetArray(), arg_array.GetNumBytes(), &result, "III");
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700288 EXPECT_EQ(3, result.GetI());
Elliott Hughes77405792012-03-15 15:22:12 -0700289
Jeff Hao5d917302013-02-27 17:57:33 -0800290 args[0] = INT_MAX;
291 args[1] = INT_MIN;
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700292 result.SetI(1234);
Ian Rogers0177e532014-02-11 16:30:46 -0800293 method->Invoke(Thread::Current(), arg_array.GetArray(), arg_array.GetNumBytes(), &result, "III");
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700294 EXPECT_EQ(-1, result.GetI());
Elliott Hughes77405792012-03-15 15:22:12 -0700295
Jeff Hao5d917302013-02-27 17:57:33 -0800296 args[0] = INT_MAX;
297 args[1] = INT_MAX;
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700298 result.SetI(INT_MIN);
Ian Rogers0177e532014-02-11 16:30:46 -0800299 method->Invoke(Thread::Current(), arg_array.GetArray(), arg_array.GetNumBytes(), &result, "III");
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700300 EXPECT_EQ(-2, result.GetI());
Elliott Hughes77405792012-03-15 15:22:12 -0700301 }
302
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700303 void InvokeSumIntIntIntMethod(bool is_static)
Ian Rogersb726dcb2012-09-05 08:57:23 -0700304 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Brian Carlstromea46f952013-07-30 01:26:50 -0700305 mirror::ArtMethod* method;
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800306 mirror::Object* receiver;
Ian Rogers1d99e452014-01-02 17:36:41 -0800307 JniInternalTestMakeExecutable(&method, &receiver, is_static, "sum", "(III)I");
Elliott Hughes77405792012-03-15 15:22:12 -0700308
Ian Rogers936b37f2014-02-14 00:52:24 -0800309 ArgArray arg_array("IIII", 4);
Jeff Hao5d917302013-02-27 17:57:33 -0800310 uint32_t* args = arg_array.GetArray();
Elliott Hughes77405792012-03-15 15:22:12 -0700311 JValue result;
Jeff Hao5d917302013-02-27 17:57:33 -0800312
313 if (!is_static) {
Ian Rogersef7d42f2014-01-06 12:55:46 -0800314 arg_array.Append(receiver);
Jeff Hao5d917302013-02-27 17:57:33 -0800315 args++;
316 }
317
Ian Rogersef7d42f2014-01-06 12:55:46 -0800318 arg_array.Append(0U);
319 arg_array.Append(0U);
320 arg_array.Append(0U);
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700321 result.SetI(-1);
Ian Rogers0177e532014-02-11 16:30:46 -0800322 method->Invoke(Thread::Current(), arg_array.GetArray(), arg_array.GetNumBytes(), &result,
323 "IIII");
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700324 EXPECT_EQ(0, result.GetI());
Elliott Hughes77405792012-03-15 15:22:12 -0700325
Jeff Hao5d917302013-02-27 17:57:33 -0800326 args[0] = 1;
327 args[1] = 2;
328 args[2] = 3;
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700329 result.SetI(0);
Ian Rogers0177e532014-02-11 16:30:46 -0800330 method->Invoke(Thread::Current(), arg_array.GetArray(), arg_array.GetNumBytes(), &result,
331 "IIII");
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700332 EXPECT_EQ(6, result.GetI());
Elliott Hughes77405792012-03-15 15:22:12 -0700333
Jeff Hao5d917302013-02-27 17:57:33 -0800334 args[0] = -1;
335 args[1] = 2;
336 args[2] = -3;
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700337 result.SetI(0);
Ian Rogers0177e532014-02-11 16:30:46 -0800338 method->Invoke(Thread::Current(), arg_array.GetArray(), arg_array.GetNumBytes(), &result,
339 "IIII");
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700340 EXPECT_EQ(-2, result.GetI());
Elliott Hughes77405792012-03-15 15:22:12 -0700341
Jeff Hao5d917302013-02-27 17:57:33 -0800342 args[0] = INT_MAX;
343 args[1] = INT_MIN;
344 args[2] = INT_MAX;
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700345 result.SetI(1234);
Ian Rogers0177e532014-02-11 16:30:46 -0800346 method->Invoke(Thread::Current(), arg_array.GetArray(), arg_array.GetNumBytes(), &result,
347 "IIII");
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700348 EXPECT_EQ(2147483646, result.GetI());
Elliott Hughes77405792012-03-15 15:22:12 -0700349
Jeff Hao5d917302013-02-27 17:57:33 -0800350 args[0] = INT_MAX;
351 args[1] = INT_MAX;
352 args[2] = INT_MAX;
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700353 result.SetI(INT_MIN);
Ian Rogers0177e532014-02-11 16:30:46 -0800354 method->Invoke(Thread::Current(), arg_array.GetArray(), arg_array.GetNumBytes(), &result,
355 "IIII");
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700356 EXPECT_EQ(2147483645, result.GetI());
Elliott Hughes77405792012-03-15 15:22:12 -0700357 }
358
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700359 void InvokeSumIntIntIntIntMethod(bool is_static)
Ian Rogersb726dcb2012-09-05 08:57:23 -0700360 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Brian Carlstromea46f952013-07-30 01:26:50 -0700361 mirror::ArtMethod* method;
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800362 mirror::Object* receiver;
Ian Rogers1d99e452014-01-02 17:36:41 -0800363 JniInternalTestMakeExecutable(&method, &receiver, is_static, "sum", "(IIII)I");
Elliott Hughes77405792012-03-15 15:22:12 -0700364
Ian Rogers936b37f2014-02-14 00:52:24 -0800365 ArgArray arg_array("IIIII", 5);
Jeff Hao5d917302013-02-27 17:57:33 -0800366 uint32_t* args = arg_array.GetArray();
Elliott Hughes77405792012-03-15 15:22:12 -0700367 JValue result;
Jeff Hao5d917302013-02-27 17:57:33 -0800368
369 if (!is_static) {
Ian Rogersef7d42f2014-01-06 12:55:46 -0800370 arg_array.Append(receiver);
Jeff Hao5d917302013-02-27 17:57:33 -0800371 args++;
372 }
373
Ian Rogersef7d42f2014-01-06 12:55:46 -0800374 arg_array.Append(0U);
375 arg_array.Append(0U);
376 arg_array.Append(0U);
377 arg_array.Append(0U);
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700378 result.SetI(-1);
Ian Rogers0177e532014-02-11 16:30:46 -0800379 method->Invoke(Thread::Current(), arg_array.GetArray(), arg_array.GetNumBytes(), &result,
380 "IIIII");
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700381 EXPECT_EQ(0, result.GetI());
Elliott Hughes77405792012-03-15 15:22:12 -0700382
Jeff Hao5d917302013-02-27 17:57:33 -0800383 args[0] = 1;
384 args[1] = 2;
385 args[2] = 3;
386 args[3] = 4;
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700387 result.SetI(0);
Ian Rogers0177e532014-02-11 16:30:46 -0800388 method->Invoke(Thread::Current(), arg_array.GetArray(), arg_array.GetNumBytes(), &result,
389 "IIIII");
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700390 EXPECT_EQ(10, result.GetI());
Elliott Hughes77405792012-03-15 15:22:12 -0700391
Jeff Hao5d917302013-02-27 17:57:33 -0800392 args[0] = -1;
393 args[1] = 2;
394 args[2] = -3;
395 args[3] = 4;
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700396 result.SetI(0);
Ian Rogers0177e532014-02-11 16:30:46 -0800397 method->Invoke(Thread::Current(), arg_array.GetArray(), arg_array.GetNumBytes(), &result,
398 "IIIII");
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700399 EXPECT_EQ(2, result.GetI());
Elliott Hughes77405792012-03-15 15:22:12 -0700400
Jeff Hao5d917302013-02-27 17:57:33 -0800401 args[0] = INT_MAX;
402 args[1] = INT_MIN;
403 args[2] = INT_MAX;
404 args[3] = INT_MIN;
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700405 result.SetI(1234);
Ian Rogers0177e532014-02-11 16:30:46 -0800406 method->Invoke(Thread::Current(), arg_array.GetArray(), arg_array.GetNumBytes(), &result,
407 "IIIII");
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700408 EXPECT_EQ(-2, result.GetI());
Elliott Hughes77405792012-03-15 15:22:12 -0700409
Jeff Hao5d917302013-02-27 17:57:33 -0800410 args[0] = INT_MAX;
411 args[1] = INT_MAX;
412 args[2] = INT_MAX;
413 args[3] = INT_MAX;
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700414 result.SetI(INT_MIN);
Ian Rogers0177e532014-02-11 16:30:46 -0800415 method->Invoke(Thread::Current(), arg_array.GetArray(), arg_array.GetNumBytes(), &result,
416 "IIIII");
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700417 EXPECT_EQ(-4, result.GetI());
Elliott Hughes77405792012-03-15 15:22:12 -0700418 }
419
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700420 void InvokeSumIntIntIntIntIntMethod(bool is_static)
Ian Rogersb726dcb2012-09-05 08:57:23 -0700421 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Brian Carlstromea46f952013-07-30 01:26:50 -0700422 mirror::ArtMethod* method;
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800423 mirror::Object* receiver;
Ian Rogers1d99e452014-01-02 17:36:41 -0800424 JniInternalTestMakeExecutable(&method, &receiver, is_static, "sum", "(IIIII)I");
Elliott Hughes77405792012-03-15 15:22:12 -0700425
Ian Rogers936b37f2014-02-14 00:52:24 -0800426 ArgArray arg_array("IIIIII", 6);
Jeff Hao5d917302013-02-27 17:57:33 -0800427 uint32_t* args = arg_array.GetArray();
Elliott Hughes77405792012-03-15 15:22:12 -0700428 JValue result;
Jeff Hao5d917302013-02-27 17:57:33 -0800429
430 if (!is_static) {
Ian Rogersef7d42f2014-01-06 12:55:46 -0800431 arg_array.Append(receiver);
Jeff Hao5d917302013-02-27 17:57:33 -0800432 args++;
433 }
434
Ian Rogersef7d42f2014-01-06 12:55:46 -0800435 arg_array.Append(0U);
436 arg_array.Append(0U);
437 arg_array.Append(0U);
438 arg_array.Append(0U);
439 arg_array.Append(0U);
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700440 result.SetI(-1.0);
Ian Rogers0177e532014-02-11 16:30:46 -0800441 method->Invoke(Thread::Current(), arg_array.GetArray(), arg_array.GetNumBytes(), &result,
442 "IIIIII");
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700443 EXPECT_EQ(0, result.GetI());
Elliott Hughes77405792012-03-15 15:22:12 -0700444
Jeff Hao5d917302013-02-27 17:57:33 -0800445 args[0] = 1;
446 args[1] = 2;
447 args[2] = 3;
448 args[3] = 4;
449 args[4] = 5;
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700450 result.SetI(0);
Ian Rogers0177e532014-02-11 16:30:46 -0800451 method->Invoke(Thread::Current(), arg_array.GetArray(), arg_array.GetNumBytes(), &result,
452 "IIIIII");
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700453 EXPECT_EQ(15, result.GetI());
Elliott Hughes77405792012-03-15 15:22:12 -0700454
Jeff Hao5d917302013-02-27 17:57:33 -0800455 args[0] = -1;
456 args[1] = 2;
457 args[2] = -3;
458 args[3] = 4;
459 args[4] = -5;
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700460 result.SetI(0);
Ian Rogers0177e532014-02-11 16:30:46 -0800461 method->Invoke(Thread::Current(), arg_array.GetArray(), arg_array.GetNumBytes(), &result,
462 "IIIIII");
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700463 EXPECT_EQ(-3, result.GetI());
Elliott Hughes77405792012-03-15 15:22:12 -0700464
Jeff Hao5d917302013-02-27 17:57:33 -0800465 args[0] = INT_MAX;
466 args[1] = INT_MIN;
467 args[2] = INT_MAX;
468 args[3] = INT_MIN;
469 args[4] = INT_MAX;
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700470 result.SetI(1234);
Ian Rogers0177e532014-02-11 16:30:46 -0800471 method->Invoke(Thread::Current(), arg_array.GetArray(), arg_array.GetNumBytes(), &result,
472 "IIIIII");
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700473 EXPECT_EQ(2147483645, result.GetI());
Elliott Hughes77405792012-03-15 15:22:12 -0700474
Jeff Hao5d917302013-02-27 17:57:33 -0800475 args[0] = INT_MAX;
476 args[1] = INT_MAX;
477 args[2] = INT_MAX;
478 args[3] = INT_MAX;
479 args[4] = INT_MAX;
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700480 result.SetI(INT_MIN);
Ian Rogers0177e532014-02-11 16:30:46 -0800481 method->Invoke(Thread::Current(), arg_array.GetArray(), arg_array.GetNumBytes(), &result,
482 "IIIIII");
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700483 EXPECT_EQ(2147483643, result.GetI());
Elliott Hughes77405792012-03-15 15:22:12 -0700484 }
485
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700486 void InvokeSumDoubleDoubleMethod(bool is_static)
Ian Rogersb726dcb2012-09-05 08:57:23 -0700487 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Brian Carlstromea46f952013-07-30 01:26:50 -0700488 mirror::ArtMethod* method;
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800489 mirror::Object* receiver;
Ian Rogers1d99e452014-01-02 17:36:41 -0800490 JniInternalTestMakeExecutable(&method, &receiver, is_static, "sum", "(DD)D");
Elliott Hughes77405792012-03-15 15:22:12 -0700491
Ian Rogers936b37f2014-02-14 00:52:24 -0800492 ArgArray arg_array("DDD", 3);
Jeff Hao5d917302013-02-27 17:57:33 -0800493 uint32_t* args = arg_array.GetArray();
494 JValue value;
495 JValue value2;
Elliott Hughes77405792012-03-15 15:22:12 -0700496 JValue result;
497
Jeff Hao5d917302013-02-27 17:57:33 -0800498 if (!is_static) {
Ian Rogersef7d42f2014-01-06 12:55:46 -0800499 arg_array.Append(receiver);
Jeff Hao5d917302013-02-27 17:57:33 -0800500 args++;
501 }
502
503 value.SetD(0.0);
504 value2.SetD(0.0);
505 arg_array.AppendWide(value.GetJ());
506 arg_array.AppendWide(value2.GetJ());
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700507 result.SetD(-1.0);
Ian Rogers0177e532014-02-11 16:30:46 -0800508 method->Invoke(Thread::Current(), arg_array.GetArray(), arg_array.GetNumBytes(), &result,
509 "DDD");
Jeff Hao6474d192013-03-26 14:08:09 -0700510 EXPECT_EQ(0.0, result.GetD());
Elliott Hughes77405792012-03-15 15:22:12 -0700511
Jeff Hao5d917302013-02-27 17:57:33 -0800512 value.SetD(1.0);
513 value2.SetD(2.0);
514 args[0] = value.GetJ();
515 args[1] = value.GetJ() >> 32;
516 args[2] = value2.GetJ();
517 args[3] = value2.GetJ() >> 32;
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700518 result.SetD(0.0);
Ian Rogers0177e532014-02-11 16:30:46 -0800519 method->Invoke(Thread::Current(), arg_array.GetArray(), arg_array.GetNumBytes(), &result,
520 "DDD");
Jeff Hao6474d192013-03-26 14:08:09 -0700521 EXPECT_EQ(3.0, result.GetD());
Elliott Hughes77405792012-03-15 15:22:12 -0700522
Jeff Hao5d917302013-02-27 17:57:33 -0800523 value.SetD(1.0);
524 value2.SetD(-2.0);
525 args[0] = value.GetJ();
526 args[1] = value.GetJ() >> 32;
527 args[2] = value2.GetJ();
528 args[3] = value2.GetJ() >> 32;
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700529 result.SetD(0.0);
Ian Rogers0177e532014-02-11 16:30:46 -0800530 method->Invoke(Thread::Current(), arg_array.GetArray(), arg_array.GetNumBytes(), &result,
531 "DDD");
Jeff Hao6474d192013-03-26 14:08:09 -0700532 EXPECT_EQ(-1.0, result.GetD());
Elliott Hughes77405792012-03-15 15:22:12 -0700533
Jeff Hao5d917302013-02-27 17:57:33 -0800534 value.SetD(DBL_MAX);
535 value2.SetD(DBL_MIN);
536 args[0] = value.GetJ();
537 args[1] = value.GetJ() >> 32;
538 args[2] = value2.GetJ();
539 args[3] = value2.GetJ() >> 32;
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700540 result.SetD(0.0);
Ian Rogers0177e532014-02-11 16:30:46 -0800541 method->Invoke(Thread::Current(), arg_array.GetArray(), arg_array.GetNumBytes(), &result,
542 "DDD");
Jeff Hao6474d192013-03-26 14:08:09 -0700543 EXPECT_EQ(1.7976931348623157e308, result.GetD());
Elliott Hughes77405792012-03-15 15:22:12 -0700544
Jeff Hao5d917302013-02-27 17:57:33 -0800545 value.SetD(DBL_MAX);
546 value2.SetD(DBL_MAX);
547 args[0] = value.GetJ();
548 args[1] = value.GetJ() >> 32;
549 args[2] = value2.GetJ();
550 args[3] = value2.GetJ() >> 32;
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700551 result.SetD(0.0);
Ian Rogers0177e532014-02-11 16:30:46 -0800552 method->Invoke(Thread::Current(), arg_array.GetArray(), arg_array.GetNumBytes(), &result,
553 "DDD");
Jeff Hao6474d192013-03-26 14:08:09 -0700554 EXPECT_EQ(INFINITY, result.GetD());
Elliott Hughes77405792012-03-15 15:22:12 -0700555 }
556
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700557 void InvokeSumDoubleDoubleDoubleMethod(bool is_static)
Ian Rogersb726dcb2012-09-05 08:57:23 -0700558 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Brian Carlstromea46f952013-07-30 01:26:50 -0700559 mirror::ArtMethod* method;
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800560 mirror::Object* receiver;
Ian Rogers1d99e452014-01-02 17:36:41 -0800561 JniInternalTestMakeExecutable(&method, &receiver, is_static, "sum", "(DDD)D");
Elliott Hughes77405792012-03-15 15:22:12 -0700562
Ian Rogers936b37f2014-02-14 00:52:24 -0800563 ArgArray arg_array("DDDD", 4);
Jeff Hao5d917302013-02-27 17:57:33 -0800564 uint32_t* args = arg_array.GetArray();
565 JValue value;
566 JValue value2;
567 JValue value3;
Elliott Hughes77405792012-03-15 15:22:12 -0700568 JValue result;
569
Jeff Hao5d917302013-02-27 17:57:33 -0800570 if (!is_static) {
Ian Rogersef7d42f2014-01-06 12:55:46 -0800571 arg_array.Append(receiver);
Jeff Hao5d917302013-02-27 17:57:33 -0800572 args++;
573 }
574
575 value.SetD(0.0);
576 value2.SetD(0.0);
577 value3.SetD(0.0);
578 arg_array.AppendWide(value.GetJ());
579 arg_array.AppendWide(value2.GetJ());
580 arg_array.AppendWide(value3.GetJ());
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700581 result.SetD(-1.0);
Ian Rogers0177e532014-02-11 16:30:46 -0800582 method->Invoke(Thread::Current(), arg_array.GetArray(), arg_array.GetNumBytes(), &result,
583 "DDDD");
Jeff Hao6474d192013-03-26 14:08:09 -0700584 EXPECT_EQ(0.0, result.GetD());
Elliott Hughes77405792012-03-15 15:22:12 -0700585
Jeff Hao5d917302013-02-27 17:57:33 -0800586 value.SetD(1.0);
587 value2.SetD(2.0);
588 value3.SetD(3.0);
589 args[0] = value.GetJ();
590 args[1] = value.GetJ() >> 32;
591 args[2] = value2.GetJ();
592 args[3] = value2.GetJ() >> 32;
593 args[4] = value3.GetJ();
594 args[5] = value3.GetJ() >> 32;
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700595 result.SetD(0.0);
Ian Rogers0177e532014-02-11 16:30:46 -0800596 method->Invoke(Thread::Current(), arg_array.GetArray(), arg_array.GetNumBytes(), &result,
597 "DDDD");
Jeff Hao6474d192013-03-26 14:08:09 -0700598 EXPECT_EQ(6.0, result.GetD());
Elliott Hughes77405792012-03-15 15:22:12 -0700599
Jeff Hao5d917302013-02-27 17:57:33 -0800600 value.SetD(1.0);
601 value2.SetD(-2.0);
602 value3.SetD(3.0);
603 args[0] = value.GetJ();
604 args[1] = value.GetJ() >> 32;
605 args[2] = value2.GetJ();
606 args[3] = value2.GetJ() >> 32;
607 args[4] = value3.GetJ();
608 args[5] = value3.GetJ() >> 32;
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700609 result.SetD(0.0);
Ian Rogers0177e532014-02-11 16:30:46 -0800610 method->Invoke(Thread::Current(), arg_array.GetArray(), arg_array.GetNumBytes(), &result,
611 "DDDD");
Jeff Hao6474d192013-03-26 14:08:09 -0700612 EXPECT_EQ(2.0, result.GetD());
Elliott Hughes77405792012-03-15 15:22:12 -0700613 }
614
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700615 void InvokeSumDoubleDoubleDoubleDoubleMethod(bool is_static)
Ian Rogersb726dcb2012-09-05 08:57:23 -0700616 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Brian Carlstromea46f952013-07-30 01:26:50 -0700617 mirror::ArtMethod* method;
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800618 mirror::Object* receiver;
Ian Rogers1d99e452014-01-02 17:36:41 -0800619 JniInternalTestMakeExecutable(&method, &receiver, is_static, "sum", "(DDDD)D");
Elliott Hughes77405792012-03-15 15:22:12 -0700620
Ian Rogers936b37f2014-02-14 00:52:24 -0800621 ArgArray arg_array("DDDDD", 5);
Jeff Hao5d917302013-02-27 17:57:33 -0800622 uint32_t* args = arg_array.GetArray();
623 JValue value;
624 JValue value2;
625 JValue value3;
626 JValue value4;
Elliott Hughes77405792012-03-15 15:22:12 -0700627 JValue result;
628
Jeff Hao5d917302013-02-27 17:57:33 -0800629 if (!is_static) {
Ian Rogersef7d42f2014-01-06 12:55:46 -0800630 arg_array.Append(receiver);
Jeff Hao5d917302013-02-27 17:57:33 -0800631 args++;
632 }
633
634 value.SetD(0.0);
635 value2.SetD(0.0);
636 value3.SetD(0.0);
637 value4.SetD(0.0);
638 arg_array.AppendWide(value.GetJ());
639 arg_array.AppendWide(value2.GetJ());
640 arg_array.AppendWide(value3.GetJ());
641 arg_array.AppendWide(value4.GetJ());
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700642 result.SetD(-1.0);
Ian Rogers0177e532014-02-11 16:30:46 -0800643 method->Invoke(Thread::Current(), arg_array.GetArray(), arg_array.GetNumBytes(), &result,
644 "DDDDD");
Jeff Hao6474d192013-03-26 14:08:09 -0700645 EXPECT_EQ(0.0, result.GetD());
Elliott Hughes77405792012-03-15 15:22:12 -0700646
Jeff Hao5d917302013-02-27 17:57:33 -0800647 value.SetD(1.0);
648 value2.SetD(2.0);
649 value3.SetD(3.0);
650 value4.SetD(4.0);
651 args[0] = value.GetJ();
652 args[1] = value.GetJ() >> 32;
653 args[2] = value2.GetJ();
654 args[3] = value2.GetJ() >> 32;
655 args[4] = value3.GetJ();
656 args[5] = value3.GetJ() >> 32;
657 args[6] = value4.GetJ();
658 args[7] = value4.GetJ() >> 32;
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700659 result.SetD(0.0);
Ian Rogers0177e532014-02-11 16:30:46 -0800660 method->Invoke(Thread::Current(), arg_array.GetArray(), arg_array.GetNumBytes(), &result,
661 "DDDDD");
Jeff Hao6474d192013-03-26 14:08:09 -0700662 EXPECT_EQ(10.0, result.GetD());
Elliott Hughes77405792012-03-15 15:22:12 -0700663
Jeff Hao5d917302013-02-27 17:57:33 -0800664 value.SetD(1.0);
665 value2.SetD(-2.0);
666 value3.SetD(3.0);
667 value4.SetD(-4.0);
668 args[0] = value.GetJ();
669 args[1] = value.GetJ() >> 32;
670 args[2] = value2.GetJ();
671 args[3] = value2.GetJ() >> 32;
672 args[4] = value3.GetJ();
673 args[5] = value3.GetJ() >> 32;
674 args[6] = value4.GetJ();
675 args[7] = value4.GetJ() >> 32;
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700676 result.SetD(0.0);
Ian Rogers0177e532014-02-11 16:30:46 -0800677 method->Invoke(Thread::Current(), arg_array.GetArray(), arg_array.GetNumBytes(), &result,
678 "DDDDD");
Jeff Hao6474d192013-03-26 14:08:09 -0700679 EXPECT_EQ(-2.0, result.GetD());
Elliott Hughes77405792012-03-15 15:22:12 -0700680 }
681
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700682 void InvokeSumDoubleDoubleDoubleDoubleDoubleMethod(bool is_static)
Ian Rogersb726dcb2012-09-05 08:57:23 -0700683 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Brian Carlstromea46f952013-07-30 01:26:50 -0700684 mirror::ArtMethod* method;
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800685 mirror::Object* receiver;
Ian Rogers1d99e452014-01-02 17:36:41 -0800686 JniInternalTestMakeExecutable(&method, &receiver, is_static, "sum", "(DDDDD)D");
Elliott Hughes77405792012-03-15 15:22:12 -0700687
Ian Rogers936b37f2014-02-14 00:52:24 -0800688 ArgArray arg_array("DDDDDD", 6);
Jeff Hao5d917302013-02-27 17:57:33 -0800689 uint32_t* args = arg_array.GetArray();
690 JValue value;
691 JValue value2;
692 JValue value3;
693 JValue value4;
694 JValue value5;
Elliott Hughes77405792012-03-15 15:22:12 -0700695 JValue result;
696
Jeff Hao5d917302013-02-27 17:57:33 -0800697 if (!is_static) {
Ian Rogersef7d42f2014-01-06 12:55:46 -0800698 arg_array.Append(receiver);
Jeff Hao5d917302013-02-27 17:57:33 -0800699 args++;
700 }
701
702 value.SetD(0.0);
703 value2.SetD(0.0);
704 value3.SetD(0.0);
705 value4.SetD(0.0);
706 value5.SetD(0.0);
707 arg_array.AppendWide(value.GetJ());
708 arg_array.AppendWide(value2.GetJ());
709 arg_array.AppendWide(value3.GetJ());
710 arg_array.AppendWide(value4.GetJ());
711 arg_array.AppendWide(value5.GetJ());
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700712 result.SetD(-1.0);
Ian Rogers0177e532014-02-11 16:30:46 -0800713 method->Invoke(Thread::Current(), arg_array.GetArray(), arg_array.GetNumBytes(), &result,
714 "DDDDDD");
Jeff Hao6474d192013-03-26 14:08:09 -0700715 EXPECT_EQ(0.0, result.GetD());
Elliott Hughes77405792012-03-15 15:22:12 -0700716
Jeff Hao5d917302013-02-27 17:57:33 -0800717 value.SetD(1.0);
718 value2.SetD(2.0);
719 value3.SetD(3.0);
720 value4.SetD(4.0);
721 value5.SetD(5.0);
722 args[0] = value.GetJ();
723 args[1] = value.GetJ() >> 32;
724 args[2] = value2.GetJ();
725 args[3] = value2.GetJ() >> 32;
726 args[4] = value3.GetJ();
727 args[5] = value3.GetJ() >> 32;
728 args[6] = value4.GetJ();
729 args[7] = value4.GetJ() >> 32;
730 args[8] = value5.GetJ();
731 args[9] = value5.GetJ() >> 32;
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700732 result.SetD(0.0);
Ian Rogers0177e532014-02-11 16:30:46 -0800733 method->Invoke(Thread::Current(), arg_array.GetArray(), arg_array.GetNumBytes(), &result,
734 "DDDDDD");
Jeff Hao6474d192013-03-26 14:08:09 -0700735 EXPECT_EQ(15.0, result.GetD());
Elliott Hughes77405792012-03-15 15:22:12 -0700736
Jeff Hao5d917302013-02-27 17:57:33 -0800737 value.SetD(1.0);
738 value2.SetD(-2.0);
739 value3.SetD(3.0);
740 value4.SetD(-4.0);
741 value5.SetD(5.0);
742 args[0] = value.GetJ();
743 args[1] = value.GetJ() >> 32;
744 args[2] = value2.GetJ();
745 args[3] = value2.GetJ() >> 32;
746 args[4] = value3.GetJ();
747 args[5] = value3.GetJ() >> 32;
748 args[6] = value4.GetJ();
749 args[7] = value4.GetJ() >> 32;
750 args[8] = value5.GetJ();
751 args[9] = value5.GetJ() >> 32;
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700752 result.SetD(0.0);
Ian Rogers0177e532014-02-11 16:30:46 -0800753 method->Invoke(Thread::Current(), arg_array.GetArray(), arg_array.GetNumBytes(), &result,
754 "DDDDDD");
Jeff Hao6474d192013-03-26 14:08:09 -0700755 EXPECT_EQ(3.0, result.GetD());
Elliott Hughes77405792012-03-15 15:22:12 -0700756 }
757
Elliott Hughesa2501992011-08-26 19:39:54 -0700758 JavaVMExt* vm_;
Brian Carlstrom4d571432012-05-16 00:21:41 -0700759 JNIEnv* env_;
Elliott Hughes814e4032011-08-23 12:07:56 -0700760 jclass aioobe_;
Elliott Hughesb264f082012-04-06 17:10:10 -0700761 jclass ase_;
Elliott Hughesb465ab02011-08-24 11:21:21 -0700762 jclass sioobe_;
Elliott Hughes0c9cd562011-08-12 10:59:29 -0700763};
764
Elliott Hughes885c3bd2011-08-22 16:59:20 -0700765TEST_F(JniInternalTest, AllocObject) {
766 jclass c = env_->FindClass("java/lang/String");
767 ASSERT_TRUE(c != NULL);
768 jobject o = env_->AllocObject(c);
769 ASSERT_TRUE(o != NULL);
770
771 // We have an instance of the class we asked for...
772 ASSERT_TRUE(env_->IsInstanceOf(o, c));
773 // ...whose fields haven't been initialized because
774 // we didn't call a constructor.
775 ASSERT_EQ(0, env_->GetIntField(o, env_->GetFieldID(c, "count", "I")));
776 ASSERT_EQ(0, env_->GetIntField(o, env_->GetFieldID(c, "offset", "I")));
777 ASSERT_TRUE(env_->GetObjectField(o, env_->GetFieldID(c, "value", "[C")) == NULL);
778}
779
Elliott Hughesc7ac37f2011-08-12 12:21:58 -0700780TEST_F(JniInternalTest, GetVersion) {
781 ASSERT_EQ(JNI_VERSION_1_6, env_->GetVersion());
782}
783
Elliott Hughes0c9cd562011-08-12 10:59:29 -0700784#define EXPECT_CLASS_FOUND(NAME) \
Elliott Hughesbd935992011-08-22 11:59:34 -0700785 EXPECT_TRUE(env_->FindClass(NAME) != NULL); \
786 EXPECT_FALSE(env_->ExceptionCheck())
Elliott Hughes0c9cd562011-08-12 10:59:29 -0700787
788#define EXPECT_CLASS_NOT_FOUND(NAME) \
Elliott Hughesbd935992011-08-22 11:59:34 -0700789 EXPECT_TRUE(env_->FindClass(NAME) == NULL); \
790 EXPECT_TRUE(env_->ExceptionCheck()); \
791 env_->ExceptionClear()
Elliott Hughes0c9cd562011-08-12 10:59:29 -0700792
793TEST_F(JniInternalTest, FindClass) {
Elliott Hughes0c9cd562011-08-12 10:59:29 -0700794 // Reference types...
Elliott Hughes0c9cd562011-08-12 10:59:29 -0700795 EXPECT_CLASS_FOUND("java/lang/String");
Elliott Hughes0c9cd562011-08-12 10:59:29 -0700796 // ...for arrays too, where you must include "L;".
797 EXPECT_CLASS_FOUND("[Ljava/lang/String;");
Elliott Hughes3f6635a2012-06-19 13:37:49 -0700798 // Primitive arrays are okay too, if the primitive type is valid.
799 EXPECT_CLASS_FOUND("[C");
Elliott Hughesa2501992011-08-26 19:39:54 -0700800
Elliott Hughesb264f082012-04-06 17:10:10 -0700801 {
Elliott Hughesb264f082012-04-06 17:10:10 -0700802 // We support . as well as / for compatibility, if -Xcheck:jni is off.
Elliott Hughes3f6635a2012-06-19 13:37:49 -0700803 CheckJniAbortCatcher check_jni_abort_catcher;
Elliott Hughesb264f082012-04-06 17:10:10 -0700804 EXPECT_CLASS_FOUND("java.lang.String");
Elliott Hughes56ef0422012-06-19 14:35:04 -0700805 check_jni_abort_catcher.Check("illegal class name 'java.lang.String'");
Elliott Hughesb264f082012-04-06 17:10:10 -0700806 EXPECT_CLASS_NOT_FOUND("Ljava.lang.String;");
Elliott Hughes56ef0422012-06-19 14:35:04 -0700807 check_jni_abort_catcher.Check("illegal class name 'Ljava.lang.String;'");
Elliott Hughesb264f082012-04-06 17:10:10 -0700808 EXPECT_CLASS_FOUND("[Ljava.lang.String;");
Elliott Hughes56ef0422012-06-19 14:35:04 -0700809 check_jni_abort_catcher.Check("illegal class name '[Ljava.lang.String;'");
Elliott Hughesb264f082012-04-06 17:10:10 -0700810 EXPECT_CLASS_NOT_FOUND("[java.lang.String");
Elliott Hughes56ef0422012-06-19 14:35:04 -0700811 check_jni_abort_catcher.Check("illegal class name '[java.lang.String'");
Elliott Hughesb264f082012-04-06 17:10:10 -0700812
813 // You can't include the "L;" in a JNI class descriptor.
814 EXPECT_CLASS_NOT_FOUND("Ljava/lang/String;");
Elliott Hughes56ef0422012-06-19 14:35:04 -0700815 check_jni_abort_catcher.Check("illegal class name 'Ljava/lang/String;'");
Elliott Hughes3f6635a2012-06-19 13:37:49 -0700816
Elliott Hughesb264f082012-04-06 17:10:10 -0700817 // But you must include it for an array of any reference type.
818 EXPECT_CLASS_NOT_FOUND("[java/lang/String");
Elliott Hughes56ef0422012-06-19 14:35:04 -0700819 check_jni_abort_catcher.Check("illegal class name '[java/lang/String'");
Elliott Hughes3f6635a2012-06-19 13:37:49 -0700820
821 EXPECT_CLASS_NOT_FOUND("[K");
Elliott Hughes56ef0422012-06-19 14:35:04 -0700822 check_jni_abort_catcher.Check("illegal class name '[K'");
Elliott Hughesb264f082012-04-06 17:10:10 -0700823 }
Elliott Hughesa2501992011-08-26 19:39:54 -0700824
Elliott Hughes0c9cd562011-08-12 10:59:29 -0700825 // But primitive types aren't allowed...
826 EXPECT_CLASS_NOT_FOUND("C");
827 EXPECT_CLASS_NOT_FOUND("K");
828}
829
Elliott Hughescdf53122011-08-19 15:46:09 -0700830#define EXPECT_EXCEPTION(exception_class) \
831 do { \
832 EXPECT_TRUE(env_->ExceptionCheck()); \
833 jthrowable exception = env_->ExceptionOccurred(); \
834 EXPECT_NE(static_cast<jthrowable>(NULL), exception); \
Elliott Hughescdf53122011-08-19 15:46:09 -0700835 env_->ExceptionClear(); \
Elliott Hughesa2501992011-08-26 19:39:54 -0700836 EXPECT_TRUE(env_->IsInstanceOf(exception, exception_class)); \
Elliott Hughescdf53122011-08-19 15:46:09 -0700837 } while (false)
838
839TEST_F(JniInternalTest, GetFieldID) {
840 jclass jlnsfe = env_->FindClass("java/lang/NoSuchFieldError");
841 ASSERT_TRUE(jlnsfe != NULL);
842 jclass c = env_->FindClass("java/lang/String");
843 ASSERT_TRUE(c != NULL);
844
845 // Wrong type.
846 jfieldID fid = env_->GetFieldID(c, "count", "J");
847 EXPECT_EQ(static_cast<jfieldID>(NULL), fid);
848 EXPECT_EXCEPTION(jlnsfe);
849
Ian Rogersb17d08b2011-09-02 16:16:49 -0700850 // Wrong type where type doesn't exist.
851 fid = env_->GetFieldID(c, "count", "Lrod/jane/freddy;");
852 EXPECT_EQ(static_cast<jfieldID>(NULL), fid);
853 EXPECT_EXCEPTION(jlnsfe);
854
Elliott Hughescdf53122011-08-19 15:46:09 -0700855 // Wrong name.
856 fid = env_->GetFieldID(c, "Count", "I");
857 EXPECT_EQ(static_cast<jfieldID>(NULL), fid);
858 EXPECT_EXCEPTION(jlnsfe);
859
860 // Good declared field lookup.
861 fid = env_->GetFieldID(c, "count", "I");
862 EXPECT_NE(static_cast<jfieldID>(NULL), fid);
863 EXPECT_TRUE(fid != NULL);
864 EXPECT_FALSE(env_->ExceptionCheck());
865
866 // Good superclass field lookup.
867 c = env_->FindClass("java/lang/StringBuilder");
868 fid = env_->GetFieldID(c, "count", "I");
869 EXPECT_NE(static_cast<jfieldID>(NULL), fid);
870 EXPECT_TRUE(fid != NULL);
871 EXPECT_FALSE(env_->ExceptionCheck());
872
873 // Not instance.
874 fid = env_->GetFieldID(c, "CASE_INSENSITIVE_ORDER", "Ljava/util/Comparator;");
875 EXPECT_EQ(static_cast<jfieldID>(NULL), fid);
876 EXPECT_EXCEPTION(jlnsfe);
877}
878
879TEST_F(JniInternalTest, GetStaticFieldID) {
880 jclass jlnsfe = env_->FindClass("java/lang/NoSuchFieldError");
881 ASSERT_TRUE(jlnsfe != NULL);
882 jclass c = env_->FindClass("java/lang/String");
883 ASSERT_TRUE(c != NULL);
884
885 // Wrong type.
886 jfieldID fid = env_->GetStaticFieldID(c, "CASE_INSENSITIVE_ORDER", "J");
887 EXPECT_EQ(static_cast<jfieldID>(NULL), fid);
888 EXPECT_EXCEPTION(jlnsfe);
889
Ian Rogersb17d08b2011-09-02 16:16:49 -0700890 // Wrong type where type doesn't exist.
891 fid = env_->GetStaticFieldID(c, "CASE_INSENSITIVE_ORDER", "Lrod/jane/freddy;");
892 EXPECT_EQ(static_cast<jfieldID>(NULL), fid);
893 EXPECT_EXCEPTION(jlnsfe);
894
Elliott Hughescdf53122011-08-19 15:46:09 -0700895 // Wrong name.
896 fid = env_->GetStaticFieldID(c, "cASE_INSENSITIVE_ORDER", "Ljava/util/Comparator;");
897 EXPECT_EQ(static_cast<jfieldID>(NULL), fid);
898 EXPECT_EXCEPTION(jlnsfe);
899
900 // Good declared field lookup.
901 fid = env_->GetStaticFieldID(c, "CASE_INSENSITIVE_ORDER", "Ljava/util/Comparator;");
902 EXPECT_NE(static_cast<jfieldID>(NULL), fid);
903 EXPECT_TRUE(fid != NULL);
904 EXPECT_FALSE(env_->ExceptionCheck());
905
906 // Not static.
907 fid = env_->GetStaticFieldID(c, "count", "I");
908 EXPECT_EQ(static_cast<jfieldID>(NULL), fid);
909 EXPECT_EXCEPTION(jlnsfe);
910}
911
Ian Rogers4dd71f12011-08-16 14:16:02 -0700912TEST_F(JniInternalTest, GetMethodID) {
913 jclass jlobject = env_->FindClass("java/lang/Object");
914 jclass jlstring = env_->FindClass("java/lang/String");
915 jclass jlnsme = env_->FindClass("java/lang/NoSuchMethodError");
916
917 // Sanity check that no exceptions are pending
Elliott Hughescdf53122011-08-19 15:46:09 -0700918 ASSERT_FALSE(env_->ExceptionCheck());
Ian Rogers4dd71f12011-08-16 14:16:02 -0700919
920 // Check that java.lang.Object.foo() doesn't exist and NoSuchMethodError is
921 // a pending exception
922 jmethodID method = env_->GetMethodID(jlobject, "foo", "()V");
923 EXPECT_EQ(static_cast<jmethodID>(NULL), method);
Elliott Hughescdf53122011-08-19 15:46:09 -0700924 EXPECT_EXCEPTION(jlnsme);
Ian Rogers4dd71f12011-08-16 14:16:02 -0700925
926 // Check that java.lang.Object.equals() does exist
Ian Rogers4dd71f12011-08-16 14:16:02 -0700927 method = env_->GetMethodID(jlobject, "equals", "(Ljava/lang/Object;)Z");
928 EXPECT_NE(static_cast<jmethodID>(NULL), method);
929 EXPECT_FALSE(env_->ExceptionCheck());
Ian Rogers4dd71f12011-08-16 14:16:02 -0700930
931 // Check that GetMethodID for java.lang.String.valueOf(int) fails as the
932 // method is static
933 method = env_->GetMethodID(jlstring, "valueOf", "(I)Ljava/lang/String;");
934 EXPECT_EQ(static_cast<jmethodID>(NULL), method);
Elliott Hughescdf53122011-08-19 15:46:09 -0700935 EXPECT_EXCEPTION(jlnsme);
Brian Carlstromea46f952013-07-30 01:26:50 -0700936
937 // Check that GetMethodID for java.lang.NoSuchMethodError.<init>(String) finds the constructor
938 method = env_->GetMethodID(jlnsme, "<init>", "(Ljava/lang/String;)V");
939 EXPECT_NE(static_cast<jmethodID>(NULL), method);
940 EXPECT_FALSE(env_->ExceptionCheck());
Ian Rogers4dd71f12011-08-16 14:16:02 -0700941}
942
943TEST_F(JniInternalTest, GetStaticMethodID) {
944 jclass jlobject = env_->FindClass("java/lang/Object");
945 jclass jlnsme = env_->FindClass("java/lang/NoSuchMethodError");
946
947 // Sanity check that no exceptions are pending
Elliott Hughescdf53122011-08-19 15:46:09 -0700948 ASSERT_FALSE(env_->ExceptionCheck());
Ian Rogers4dd71f12011-08-16 14:16:02 -0700949
950 // Check that java.lang.Object.foo() doesn't exist and NoSuchMethodError is
951 // a pending exception
952 jmethodID method = env_->GetStaticMethodID(jlobject, "foo", "()V");
953 EXPECT_EQ(static_cast<jmethodID>(NULL), method);
Elliott Hughescdf53122011-08-19 15:46:09 -0700954 EXPECT_EXCEPTION(jlnsme);
Ian Rogers4dd71f12011-08-16 14:16:02 -0700955
956 // Check that GetStaticMethodID for java.lang.Object.equals(Object) fails as
957 // the method is not static
958 method = env_->GetStaticMethodID(jlobject, "equals", "(Ljava/lang/Object;)Z");
959 EXPECT_EQ(static_cast<jmethodID>(NULL), method);
Elliott Hughescdf53122011-08-19 15:46:09 -0700960 EXPECT_EXCEPTION(jlnsme);
Ian Rogers4dd71f12011-08-16 14:16:02 -0700961
962 // Check that java.lang.String.valueOf(int) does exist
Ian Rogers4dd71f12011-08-16 14:16:02 -0700963 jclass jlstring = env_->FindClass("java/lang/String");
964 method = env_->GetStaticMethodID(jlstring, "valueOf",
965 "(I)Ljava/lang/String;");
966 EXPECT_NE(static_cast<jmethodID>(NULL), method);
967 EXPECT_FALSE(env_->ExceptionCheck());
Ian Rogers4dd71f12011-08-16 14:16:02 -0700968}
969
Elliott Hughescdf53122011-08-19 15:46:09 -0700970TEST_F(JniInternalTest, FromReflectedField_ToReflectedField) {
971 jclass jlrField = env_->FindClass("java/lang/reflect/Field");
972 jclass c = env_->FindClass("java/lang/String");
973 ASSERT_TRUE(c != NULL);
974 jfieldID fid = env_->GetFieldID(c, "count", "I");
975 ASSERT_TRUE(fid != NULL);
976 // Turn the fid into a java.lang.reflect.Field...
977 jobject field = env_->ToReflectedField(c, fid, JNI_FALSE);
978 ASSERT_TRUE(c != NULL);
979 ASSERT_TRUE(env_->IsInstanceOf(field, jlrField));
980 // ...and back again.
981 jfieldID fid2 = env_->FromReflectedField(field);
982 ASSERT_TRUE(fid2 != NULL);
Brian Carlstromea46f952013-07-30 01:26:50 -0700983 // Make sure we can actually use it.
984 jstring s = env_->NewStringUTF("poop");
985 ASSERT_EQ(4, env_->GetIntField(s, fid2));
Elliott Hughescdf53122011-08-19 15:46:09 -0700986}
987
988TEST_F(JniInternalTest, FromReflectedMethod_ToReflectedMethod) {
989 jclass jlrMethod = env_->FindClass("java/lang/reflect/Method");
990 jclass c = env_->FindClass("java/lang/String");
991 ASSERT_TRUE(c != NULL);
992 jmethodID mid = env_->GetMethodID(c, "length", "()I");
993 ASSERT_TRUE(mid != NULL);
994 // Turn the mid into a java.lang.reflect.Method...
995 jobject method = env_->ToReflectedMethod(c, mid, JNI_FALSE);
996 ASSERT_TRUE(c != NULL);
997 ASSERT_TRUE(env_->IsInstanceOf(method, jlrMethod));
998 // ...and back again.
999 jmethodID mid2 = env_->FromReflectedMethod(method);
1000 ASSERT_TRUE(mid2 != NULL);
Brian Carlstromea46f952013-07-30 01:26:50 -07001001 // Make sure we can actually use it.
1002 jstring s = env_->NewStringUTF("poop");
1003 // TODO: this should return 4, but the runtime skips the method
1004 // invoke because the runtime isn't started. In the future it would
1005 // be nice to use interpretter for things like this. This still does
1006 // validate that we have a sane jmethodID value.
1007 ASSERT_EQ(0, env_->CallIntMethod(s, mid2));
Elliott Hughescdf53122011-08-19 15:46:09 -07001008}
1009
Elliott Hughes5174fe62011-08-23 15:12:35 -07001010void BogusMethod() {
1011 // You can't pass NULL function pointers to RegisterNatives.
1012}
1013
Ian Rogers4dd71f12011-08-16 14:16:02 -07001014TEST_F(JniInternalTest, RegisterNatives) {
1015 jclass jlobject = env_->FindClass("java/lang/Object");
1016 jclass jlnsme = env_->FindClass("java/lang/NoSuchMethodError");
1017
1018 // Sanity check that no exceptions are pending
Elliott Hughescdf53122011-08-19 15:46:09 -07001019 ASSERT_FALSE(env_->ExceptionCheck());
Ian Rogers4dd71f12011-08-16 14:16:02 -07001020
1021 // Check that registering to a non-existent java.lang.Object.foo() causes a
1022 // NoSuchMethodError
1023 {
Elliott Hughesb25c3f62012-03-26 16:35:06 -07001024 JNINativeMethod methods[] = { { "foo", "()V", NULL } };
Ian Rogers4dd71f12011-08-16 14:16:02 -07001025 env_->RegisterNatives(jlobject, methods, 1);
1026 }
Elliott Hughescdf53122011-08-19 15:46:09 -07001027 EXPECT_EXCEPTION(jlnsme);
Ian Rogers4dd71f12011-08-16 14:16:02 -07001028
1029 // Check that registering non-native methods causes a NoSuchMethodError
1030 {
Elliott Hughesb25c3f62012-03-26 16:35:06 -07001031 JNINativeMethod methods[] = { { "equals", "(Ljava/lang/Object;)Z", NULL } };
Ian Rogers4dd71f12011-08-16 14:16:02 -07001032 env_->RegisterNatives(jlobject, methods, 1);
1033 }
Elliott Hughescdf53122011-08-19 15:46:09 -07001034 EXPECT_EXCEPTION(jlnsme);
Ian Rogers4dd71f12011-08-16 14:16:02 -07001035
1036 // Check that registering native methods is successful
1037 {
Elliott Hughesb25c3f62012-03-26 16:35:06 -07001038 JNINativeMethod methods[] = { { "notify", "()V", reinterpret_cast<void*>(BogusMethod) } };
Ian Rogers4dd71f12011-08-16 14:16:02 -07001039 env_->RegisterNatives(jlobject, methods, 1);
1040 }
1041 EXPECT_FALSE(env_->ExceptionCheck());
Elliott Hughes5174fe62011-08-23 15:12:35 -07001042
1043 env_->UnregisterNatives(jlobject);
Ian Rogers4dd71f12011-08-16 14:16:02 -07001044}
1045
Brian Carlstromea46f952013-07-30 01:26:50 -07001046#define EXPECT_PRIMITIVE_ARRAY(new_fn, \
1047 get_region_fn, \
1048 set_region_fn, \
1049 get_elements_fn, \
1050 release_elements_fn, \
1051 scalar_type, \
1052 expected_class_descriptor) \
Ian Rogers1d99e452014-01-02 17:36:41 -08001053 { \
1054 CheckJniAbortCatcher jni_abort_catcher; \
1055 /* Allocate an negative sized array and check it has the right failure type. */ \
1056 env_->new_fn(-1); \
1057 jni_abort_catcher.Check("negative array length: -1"); \
1058 env_->new_fn(std::numeric_limits<jint>::min()); \
1059 jni_abort_catcher.Check("negative array length: -2147483648"); \
1060 } \
Elliott Hughes814e4032011-08-23 12:07:56 -07001061 jsize size = 4; \
Elliott Hughesd7d7f6e2013-09-18 12:00:45 -07001062 \
Elliott Hughes814e4032011-08-23 12:07:56 -07001063 /* Allocate an array and check it has the right type and length. */ \
1064 scalar_type ## Array a = env_->new_fn(size); \
1065 EXPECT_TRUE(a != NULL); \
1066 EXPECT_TRUE(env_->IsInstanceOf(a, env_->FindClass(expected_class_descriptor))); \
1067 EXPECT_EQ(size, env_->GetArrayLength(a)); \
Elliott Hughesd7d7f6e2013-09-18 12:00:45 -07001068 \
1069 /* GetPrimitiveArrayRegion/SetPrimitiveArrayRegion */ \
Elliott Hughes814e4032011-08-23 12:07:56 -07001070 /* AIOOBE for negative start offset. */ \
1071 env_->get_region_fn(a, -1, 1, NULL); \
1072 EXPECT_EXCEPTION(aioobe_); \
1073 env_->set_region_fn(a, -1, 1, NULL); \
1074 EXPECT_EXCEPTION(aioobe_); \
Elliott Hughesd7d7f6e2013-09-18 12:00:45 -07001075 \
Elliott Hughes814e4032011-08-23 12:07:56 -07001076 /* AIOOBE for negative length. */ \
1077 env_->get_region_fn(a, 0, -1, NULL); \
1078 EXPECT_EXCEPTION(aioobe_); \
1079 env_->set_region_fn(a, 0, -1, NULL); \
1080 EXPECT_EXCEPTION(aioobe_); \
Elliott Hughesd7d7f6e2013-09-18 12:00:45 -07001081 \
Elliott Hughes814e4032011-08-23 12:07:56 -07001082 /* AIOOBE for buffer overrun. */ \
1083 env_->get_region_fn(a, size - 1, size, NULL); \
1084 EXPECT_EXCEPTION(aioobe_); \
1085 env_->set_region_fn(a, size - 1, size, NULL); \
1086 EXPECT_EXCEPTION(aioobe_); \
Elliott Hughesd7d7f6e2013-09-18 12:00:45 -07001087 \
1088 /* It's okay for the buffer to be NULL as long as the length is 0. */ \
1089 env_->get_region_fn(a, 2, 0, NULL); \
1090 /* Even if the offset is invalid... */ \
1091 env_->get_region_fn(a, 123, 0, NULL); \
1092 EXPECT_EXCEPTION(aioobe_); \
1093 \
1094 /* It's okay for the buffer to be NULL as long as the length is 0. */ \
1095 env_->set_region_fn(a, 2, 0, NULL); \
1096 /* Even if the offset is invalid... */ \
1097 env_->set_region_fn(a, 123, 0, NULL); \
1098 EXPECT_EXCEPTION(aioobe_); \
1099 \
Elliott Hughes814e4032011-08-23 12:07:56 -07001100 /* Prepare a couple of buffers. */ \
Elliott Hughesee0fa762012-03-26 17:12:41 -07001101 UniquePtr<scalar_type[]> src_buf(new scalar_type[size]); \
1102 UniquePtr<scalar_type[]> dst_buf(new scalar_type[size]); \
Elliott Hughes814e4032011-08-23 12:07:56 -07001103 for (jsize i = 0; i < size; ++i) { src_buf[i] = scalar_type(i); } \
1104 for (jsize i = 0; i < size; ++i) { dst_buf[i] = scalar_type(-1); } \
Elliott Hughesd7d7f6e2013-09-18 12:00:45 -07001105 \
Elliott Hughes814e4032011-08-23 12:07:56 -07001106 /* Copy all of src_buf onto the heap. */ \
Elliott Hughesee0fa762012-03-26 17:12:41 -07001107 env_->set_region_fn(a, 0, size, &src_buf[0]); \
Elliott Hughes814e4032011-08-23 12:07:56 -07001108 /* Copy back only part. */ \
1109 env_->get_region_fn(a, 1, size - 2, &dst_buf[1]); \
Brian Carlstromea46f952013-07-30 01:26:50 -07001110 EXPECT_NE(memcmp(&src_buf[0], &dst_buf[0], size * sizeof(scalar_type)), 0) \
1111 << "short copy equal"; \
Elliott Hughes814e4032011-08-23 12:07:56 -07001112 /* Copy the missing pieces. */ \
Elliott Hughesee0fa762012-03-26 17:12:41 -07001113 env_->get_region_fn(a, 0, 1, &dst_buf[0]); \
Elliott Hughes814e4032011-08-23 12:07:56 -07001114 env_->get_region_fn(a, size - 1, 1, &dst_buf[size - 1]); \
Brian Carlstromea46f952013-07-30 01:26:50 -07001115 EXPECT_EQ(memcmp(&src_buf[0], &dst_buf[0], size * sizeof(scalar_type)), 0) \
1116 << "fixed copy not equal"; \
Elliott Hughes814e4032011-08-23 12:07:56 -07001117 /* Copy back the whole array. */ \
Elliott Hughesee0fa762012-03-26 17:12:41 -07001118 env_->get_region_fn(a, 0, size, &dst_buf[0]); \
Brian Carlstromea46f952013-07-30 01:26:50 -07001119 EXPECT_EQ(memcmp(&src_buf[0], &dst_buf[0], size * sizeof(scalar_type)), 0) \
1120 << "full copy not equal"; \
Elliott Hughes75770752011-08-24 17:52:38 -07001121 /* GetPrimitiveArrayCritical */ \
1122 void* v = env_->GetPrimitiveArrayCritical(a, NULL); \
Brian Carlstromea46f952013-07-30 01:26:50 -07001123 EXPECT_EQ(memcmp(&src_buf[0], v, size * sizeof(scalar_type)), 0) \
1124 << "GetPrimitiveArrayCritical not equal"; \
Elliott Hughes75770752011-08-24 17:52:38 -07001125 env_->ReleasePrimitiveArrayCritical(a, v, 0); \
1126 /* GetXArrayElements */ \
1127 scalar_type* xs = env_->get_elements_fn(a, NULL); \
Brian Carlstromea46f952013-07-30 01:26:50 -07001128 EXPECT_EQ(memcmp(&src_buf[0], xs, size * sizeof(scalar_type)), 0) \
1129 << # get_elements_fn " not equal"; \
Elliott Hughes75770752011-08-24 17:52:38 -07001130 env_->release_elements_fn(a, xs, 0); \
Elliott Hughesbd935992011-08-22 11:59:34 -07001131
Elliott Hughes814e4032011-08-23 12:07:56 -07001132TEST_F(JniInternalTest, BooleanArrays) {
Brian Carlstromea46f952013-07-30 01:26:50 -07001133 EXPECT_PRIMITIVE_ARRAY(NewBooleanArray, GetBooleanArrayRegion, SetBooleanArrayRegion,
1134 GetBooleanArrayElements, ReleaseBooleanArrayElements, jboolean, "[Z");
Elliott Hughes814e4032011-08-23 12:07:56 -07001135}
1136TEST_F(JniInternalTest, ByteArrays) {
Brian Carlstromea46f952013-07-30 01:26:50 -07001137 EXPECT_PRIMITIVE_ARRAY(NewByteArray, GetByteArrayRegion, SetByteArrayRegion,
1138 GetByteArrayElements, ReleaseByteArrayElements, jbyte, "[B");
Elliott Hughes814e4032011-08-23 12:07:56 -07001139}
1140TEST_F(JniInternalTest, CharArrays) {
Brian Carlstromea46f952013-07-30 01:26:50 -07001141 EXPECT_PRIMITIVE_ARRAY(NewCharArray, GetCharArrayRegion, SetCharArrayRegion,
1142 GetCharArrayElements, ReleaseCharArrayElements, jchar, "[C");
Elliott Hughes814e4032011-08-23 12:07:56 -07001143}
1144TEST_F(JniInternalTest, DoubleArrays) {
Brian Carlstromea46f952013-07-30 01:26:50 -07001145 EXPECT_PRIMITIVE_ARRAY(NewDoubleArray, GetDoubleArrayRegion, SetDoubleArrayRegion,
1146 GetDoubleArrayElements, ReleaseDoubleArrayElements, jdouble, "[D");
Elliott Hughes814e4032011-08-23 12:07:56 -07001147}
1148TEST_F(JniInternalTest, FloatArrays) {
Brian Carlstromea46f952013-07-30 01:26:50 -07001149 EXPECT_PRIMITIVE_ARRAY(NewFloatArray, GetFloatArrayRegion, SetFloatArrayRegion,
1150 GetFloatArrayElements, ReleaseFloatArrayElements, jfloat, "[F");
Elliott Hughes814e4032011-08-23 12:07:56 -07001151}
1152TEST_F(JniInternalTest, IntArrays) {
Brian Carlstromea46f952013-07-30 01:26:50 -07001153 EXPECT_PRIMITIVE_ARRAY(NewIntArray, GetIntArrayRegion, SetIntArrayRegion,
1154 GetIntArrayElements, ReleaseIntArrayElements, jint, "[I");
Elliott Hughes814e4032011-08-23 12:07:56 -07001155}
1156TEST_F(JniInternalTest, LongArrays) {
Brian Carlstromea46f952013-07-30 01:26:50 -07001157 EXPECT_PRIMITIVE_ARRAY(NewLongArray, GetLongArrayRegion, SetLongArrayRegion,
1158 GetLongArrayElements, ReleaseLongArrayElements, jlong, "[J");
Elliott Hughes814e4032011-08-23 12:07:56 -07001159}
1160TEST_F(JniInternalTest, ShortArrays) {
Brian Carlstromea46f952013-07-30 01:26:50 -07001161 EXPECT_PRIMITIVE_ARRAY(NewShortArray, GetShortArrayRegion, SetShortArrayRegion,
1162 GetShortArrayElements, ReleaseShortArrayElements, jshort, "[S");
Elliott Hughesd8ddfd52011-08-15 14:32:53 -07001163}
1164
Elliott Hughesf2682d52011-08-15 16:37:04 -07001165TEST_F(JniInternalTest, NewObjectArray) {
Elliott Hughesbd935992011-08-22 11:59:34 -07001166 jclass element_class = env_->FindClass("java/lang/String");
Ian Rogers1d99e452014-01-02 17:36:41 -08001167 ASSERT_TRUE(element_class != nullptr);
Elliott Hughesbd935992011-08-22 11:59:34 -07001168 jclass array_class = env_->FindClass("[Ljava/lang/String;");
Ian Rogers1d99e452014-01-02 17:36:41 -08001169 ASSERT_TRUE(array_class != nullptr);
Elliott Hughesf2682d52011-08-15 16:37:04 -07001170
Ian Rogers1d99e452014-01-02 17:36:41 -08001171 jobjectArray a = env_->NewObjectArray(0, element_class, nullptr);
1172 EXPECT_TRUE(a != nullptr);
Elliott Hughesbd935992011-08-22 11:59:34 -07001173 EXPECT_TRUE(env_->IsInstanceOf(a, array_class));
1174 EXPECT_EQ(0, env_->GetArrayLength(a));
1175
Ian Rogers1d99e452014-01-02 17:36:41 -08001176 a = env_->NewObjectArray(1, element_class, nullptr);
1177 EXPECT_TRUE(a != nullptr);
Elliott Hughesbd935992011-08-22 11:59:34 -07001178 EXPECT_TRUE(env_->IsInstanceOf(a, array_class));
1179 EXPECT_EQ(1, env_->GetArrayLength(a));
Ian Rogers1d99e452014-01-02 17:36:41 -08001180 EXPECT_TRUE(env_->IsSameObject(env_->GetObjectArrayElement(a, 0), nullptr));
1181}
1182
1183TEST_F(JniInternalTest, NewObjectArrayWithNegativeLength) {
1184 jclass element_class = env_->FindClass("java/lang/String");
1185 ASSERT_TRUE(element_class != nullptr);
1186 jclass array_class = env_->FindClass("[Ljava/lang/String;");
1187 ASSERT_TRUE(array_class != nullptr);
1188 CheckJniAbortCatcher jni_abort_catcher;
1189
1190 env_->NewObjectArray(-1, element_class, nullptr);
1191 jni_abort_catcher.Check("negative array length: -1");
1192
1193 env_->NewObjectArray(std::numeric_limits<jint>::min(), element_class, nullptr);
1194 jni_abort_catcher.Check("negative array length: -2147483648");
1195}
1196
1197TEST_F(JniInternalTest, NewObjectArrayWithPrimitiveClasses) {
1198 const char* primitive_descriptors = "VZBSCIJFD";
1199 const char* primitive_names[] = {
1200 "void", "boolean", "byte", "short", "char", "int", "long", "float", "double"
1201 };
1202 ASSERT_EQ(strlen(primitive_descriptors), arraysize(primitive_names));
1203
1204 CheckJniAbortCatcher jni_abort_catcher;
1205 for (size_t i = 0; i < strlen(primitive_descriptors); ++i) {
1206 jclass primitive_class = GetPrimitiveClass(primitive_descriptors[i]);
1207 env_->NewObjectArray(1, primitive_class, nullptr);
1208 std::string error_msg(StringPrintf("not an object type: %s", primitive_names[i]));
1209 jni_abort_catcher.Check(error_msg.c_str());
1210 }
1211}
1212
1213TEST_F(JniInternalTest, NewObjectArrayWithInitialValue) {
1214 jclass element_class = env_->FindClass("java/lang/String");
1215 ASSERT_TRUE(element_class != nullptr);
1216 jclass array_class = env_->FindClass("[Ljava/lang/String;");
1217 ASSERT_TRUE(array_class != nullptr);
Elliott Hughes75770752011-08-24 17:52:38 -07001218
1219 jstring s = env_->NewStringUTF("poop");
Ian Rogers1d99e452014-01-02 17:36:41 -08001220 jobjectArray a = env_->NewObjectArray(2, element_class, s);
1221 EXPECT_TRUE(a != nullptr);
Elliott Hughes75770752011-08-24 17:52:38 -07001222 EXPECT_TRUE(env_->IsInstanceOf(a, array_class));
1223 EXPECT_EQ(2, env_->GetArrayLength(a));
1224 EXPECT_TRUE(env_->IsSameObject(env_->GetObjectArrayElement(a, 0), s));
1225 EXPECT_TRUE(env_->IsSameObject(env_->GetObjectArrayElement(a, 1), s));
Ian Rogers1d99e452014-01-02 17:36:41 -08001226
1227 // Attempt to incorrect create an array of strings with initial value of string arrays.
1228 CheckJniAbortCatcher jni_abort_catcher;
1229 env_->NewObjectArray(2, element_class, a);
1230 jni_abort_catcher.Check("cannot assign object of type 'java.lang.String[]' to array with element "
1231 "type of 'java.lang.String'");
Elliott Hughesbd935992011-08-22 11:59:34 -07001232}
1233
1234TEST_F(JniInternalTest, GetArrayLength) {
1235 // Already tested in NewObjectArray/NewPrimitiveArray.
Elliott Hughes8a26c5c2011-08-15 18:35:43 -07001236}
1237
Elliott Hughes37f7a402011-08-22 18:56:01 -07001238TEST_F(JniInternalTest, GetObjectClass) {
1239 jclass string_class = env_->FindClass("java/lang/String");
1240 ASSERT_TRUE(string_class != NULL);
1241 jclass class_class = env_->FindClass("java/lang/Class");
1242 ASSERT_TRUE(class_class != NULL);
1243
1244 jstring s = env_->NewStringUTF("poop");
1245 jclass c = env_->GetObjectClass(s);
1246 ASSERT_TRUE(env_->IsSameObject(string_class, c));
1247
1248 jclass c2 = env_->GetObjectClass(c);
1249 ASSERT_TRUE(env_->IsSameObject(class_class, env_->GetObjectClass(c2)));
1250}
1251
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001252TEST_F(JniInternalTest, GetSuperclass) {
1253 jclass object_class = env_->FindClass("java/lang/Object");
1254 ASSERT_TRUE(object_class != NULL);
1255 jclass string_class = env_->FindClass("java/lang/String");
1256 ASSERT_TRUE(string_class != NULL);
Ian Rogersdc180202012-01-29 14:47:29 -08001257 jclass runnable_interface = env_->FindClass("java/lang/Runnable");
1258 ASSERT_TRUE(runnable_interface != NULL);
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001259 ASSERT_TRUE(env_->IsSameObject(object_class, env_->GetSuperclass(string_class)));
1260 ASSERT_TRUE(env_->GetSuperclass(object_class) == NULL);
Ian Rogersdc180202012-01-29 14:47:29 -08001261 ASSERT_TRUE(env_->IsSameObject(object_class, env_->GetSuperclass(runnable_interface)));
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001262}
1263
Elliott Hughes37f7a402011-08-22 18:56:01 -07001264TEST_F(JniInternalTest, IsAssignableFrom) {
1265 jclass object_class = env_->FindClass("java/lang/Object");
1266 ASSERT_TRUE(object_class != NULL);
1267 jclass string_class = env_->FindClass("java/lang/String");
1268 ASSERT_TRUE(string_class != NULL);
1269
1270 ASSERT_TRUE(env_->IsAssignableFrom(object_class, string_class));
1271 ASSERT_FALSE(env_->IsAssignableFrom(string_class, object_class));
1272}
1273
Elliott Hughesb465ab02011-08-24 11:21:21 -07001274TEST_F(JniInternalTest, GetObjectRefType) {
1275 jclass local = env_->FindClass("java/lang/Object");
1276 ASSERT_TRUE(local != NULL);
1277 EXPECT_EQ(JNILocalRefType, env_->GetObjectRefType(local));
1278
1279 jobject global = env_->NewGlobalRef(local);
1280 EXPECT_EQ(JNIGlobalRefType, env_->GetObjectRefType(global));
1281
1282 jweak weak_global = env_->NewWeakGlobalRef(local);
1283 EXPECT_EQ(JNIWeakGlobalRefType, env_->GetObjectRefType(weak_global));
1284
1285 jobject invalid = reinterpret_cast<jobject>(this);
1286 EXPECT_EQ(JNIInvalidRefType, env_->GetObjectRefType(invalid));
1287
1288 // TODO: invoke a native method and test that its arguments are considered local references.
1289}
1290
Mathieu Chartier08599992013-12-20 17:17:55 -08001291TEST_F(JniInternalTest, StaleWeakGlobal) {
1292 jclass java_lang_Class = env_->FindClass("java/lang/Class");
1293 ASSERT_TRUE(java_lang_Class != NULL);
1294 jobjectArray local_ref = env_->NewObjectArray(1, java_lang_Class, NULL);
1295 ASSERT_TRUE(local_ref != NULL);
1296 jweak weak_global = env_->NewWeakGlobalRef(local_ref);
1297 ASSERT_TRUE(weak_global != NULL);
1298 env_->DeleteLocalRef(local_ref);
1299 Runtime::Current()->GetHeap()->CollectGarbage(false); // GC should clear the weak global.
1300 jobject new_global_ref = env_->NewGlobalRef(weak_global);
1301 EXPECT_TRUE(new_global_ref == NULL);
1302 jobject new_local_ref = env_->NewLocalRef(weak_global);
1303 EXPECT_TRUE(new_local_ref == NULL);
1304}
1305
Elliott Hughes8a26c5c2011-08-15 18:35:43 -07001306TEST_F(JniInternalTest, NewStringUTF) {
1307 EXPECT_TRUE(env_->NewStringUTF(NULL) == NULL);
Elliott Hughes814e4032011-08-23 12:07:56 -07001308 jstring s;
1309
1310 s = env_->NewStringUTF("");
1311 EXPECT_TRUE(s != NULL);
1312 EXPECT_EQ(0, env_->GetStringLength(s));
1313 EXPECT_EQ(0, env_->GetStringUTFLength(s));
1314 s = env_->NewStringUTF("hello");
1315 EXPECT_TRUE(s != NULL);
1316 EXPECT_EQ(5, env_->GetStringLength(s));
1317 EXPECT_EQ(5, env_->GetStringUTFLength(s));
1318
Elliott Hughes8a26c5c2011-08-15 18:35:43 -07001319 // TODO: check some non-ASCII strings.
Elliott Hughesf2682d52011-08-15 16:37:04 -07001320}
1321
Elliott Hughes814e4032011-08-23 12:07:56 -07001322TEST_F(JniInternalTest, NewString) {
Elliott Hughes814e4032011-08-23 12:07:56 -07001323 jchar chars[] = { 'h', 'i' };
1324 jstring s;
1325 s = env_->NewString(chars, 0);
1326 EXPECT_TRUE(s != NULL);
1327 EXPECT_EQ(0, env_->GetStringLength(s));
1328 EXPECT_EQ(0, env_->GetStringUTFLength(s));
1329 s = env_->NewString(chars, 2);
1330 EXPECT_TRUE(s != NULL);
1331 EXPECT_EQ(2, env_->GetStringLength(s));
1332 EXPECT_EQ(2, env_->GetStringUTFLength(s));
1333
1334 // TODO: check some non-ASCII strings.
1335}
1336
Jesse Wilson25e79a52011-11-18 15:31:58 -05001337TEST_F(JniInternalTest, NewStringNullCharsZeroLength) {
Ian Rogers1d99e452014-01-02 17:36:41 -08001338 jstring s = env_->NewString(nullptr, 0);
1339 EXPECT_TRUE(s != nullptr);
Jesse Wilson25e79a52011-11-18 15:31:58 -05001340 EXPECT_EQ(0, env_->GetStringLength(s));
1341}
1342
Ian Rogers1d99e452014-01-02 17:36:41 -08001343TEST_F(JniInternalTest, NewStringNullCharsNonzeroLength) {
1344 CheckJniAbortCatcher jni_abort_catcher;
1345 env_->NewString(nullptr, 1);
1346 jni_abort_catcher.Check("chars == null && char_count > 0");
1347}
1348
1349TEST_F(JniInternalTest, NewStringNegativeLength) {
1350 CheckJniAbortCatcher jni_abort_catcher;
1351 env_->NewString(nullptr, -1);
1352 jni_abort_catcher.Check("char_count < 0: -1");
1353 env_->NewString(nullptr, std::numeric_limits<jint>::min());
1354 jni_abort_catcher.Check("char_count < 0: -2147483648");
Jesse Wilson25e79a52011-11-18 15:31:58 -05001355}
1356
Elliott Hughesb465ab02011-08-24 11:21:21 -07001357TEST_F(JniInternalTest, GetStringLength_GetStringUTFLength) {
1358 // Already tested in the NewString/NewStringUTF tests.
1359}
1360
1361TEST_F(JniInternalTest, GetStringRegion_GetStringUTFRegion) {
1362 jstring s = env_->NewStringUTF("hello");
1363 ASSERT_TRUE(s != NULL);
1364
1365 env_->GetStringRegion(s, -1, 0, NULL);
1366 EXPECT_EXCEPTION(sioobe_);
1367 env_->GetStringRegion(s, 0, -1, NULL);
1368 EXPECT_EXCEPTION(sioobe_);
1369 env_->GetStringRegion(s, 0, 10, NULL);
1370 EXPECT_EXCEPTION(sioobe_);
1371 env_->GetStringRegion(s, 10, 1, NULL);
1372 EXPECT_EXCEPTION(sioobe_);
1373
1374 jchar chars[4] = { 'x', 'x', 'x', 'x' };
1375 env_->GetStringRegion(s, 1, 2, &chars[1]);
1376 EXPECT_EQ('x', chars[0]);
1377 EXPECT_EQ('e', chars[1]);
1378 EXPECT_EQ('l', chars[2]);
1379 EXPECT_EQ('x', chars[3]);
1380
Elliott Hughesd7d7f6e2013-09-18 12:00:45 -07001381 // It's okay for the buffer to be NULL as long as the length is 0.
1382 env_->GetStringRegion(s, 2, 0, NULL);
1383 // Even if the offset is invalid...
1384 env_->GetStringRegion(s, 123, 0, NULL);
1385 EXPECT_EXCEPTION(sioobe_);
1386
Elliott Hughesb465ab02011-08-24 11:21:21 -07001387 env_->GetStringUTFRegion(s, -1, 0, NULL);
1388 EXPECT_EXCEPTION(sioobe_);
1389 env_->GetStringUTFRegion(s, 0, -1, NULL);
1390 EXPECT_EXCEPTION(sioobe_);
1391 env_->GetStringUTFRegion(s, 0, 10, NULL);
1392 EXPECT_EXCEPTION(sioobe_);
1393 env_->GetStringUTFRegion(s, 10, 1, NULL);
1394 EXPECT_EXCEPTION(sioobe_);
1395
1396 char bytes[4] = { 'x', 'x', 'x', 'x' };
1397 env_->GetStringUTFRegion(s, 1, 2, &bytes[1]);
1398 EXPECT_EQ('x', bytes[0]);
1399 EXPECT_EQ('e', bytes[1]);
1400 EXPECT_EQ('l', bytes[2]);
1401 EXPECT_EQ('x', bytes[3]);
Elliott Hughesd7d7f6e2013-09-18 12:00:45 -07001402
1403 // It's okay for the buffer to be NULL as long as the length is 0.
1404 env_->GetStringUTFRegion(s, 2, 0, NULL);
1405 // Even if the offset is invalid...
1406 env_->GetStringUTFRegion(s, 123, 0, NULL);
1407 EXPECT_EXCEPTION(sioobe_);
Elliott Hughesb465ab02011-08-24 11:21:21 -07001408}
1409
Elliott Hughes75770752011-08-24 17:52:38 -07001410TEST_F(JniInternalTest, GetStringUTFChars_ReleaseStringUTFChars) {
Elliott Hughes3f6635a2012-06-19 13:37:49 -07001411 // Passing in a NULL jstring is ignored normally, but caught by -Xcheck:jni.
Elliott Hughesb264f082012-04-06 17:10:10 -07001412 {
Elliott Hughesb264f082012-04-06 17:10:10 -07001413 CheckJniAbortCatcher check_jni_abort_catcher;
1414 EXPECT_TRUE(env_->GetStringUTFChars(NULL, NULL) == NULL);
Elliott Hughes56ef0422012-06-19 14:35:04 -07001415 check_jni_abort_catcher.Check("GetStringUTFChars received null jstring");
Elliott Hughesb264f082012-04-06 17:10:10 -07001416 }
Elliott Hughes75770752011-08-24 17:52:38 -07001417
1418 jstring s = env_->NewStringUTF("hello");
1419 ASSERT_TRUE(s != NULL);
1420
1421 const char* utf = env_->GetStringUTFChars(s, NULL);
1422 EXPECT_STREQ("hello", utf);
1423 env_->ReleaseStringUTFChars(s, utf);
1424
1425 jboolean is_copy = JNI_FALSE;
1426 utf = env_->GetStringUTFChars(s, &is_copy);
1427 EXPECT_EQ(JNI_TRUE, is_copy);
1428 EXPECT_STREQ("hello", utf);
1429 env_->ReleaseStringUTFChars(s, utf);
1430}
1431
1432TEST_F(JniInternalTest, GetStringChars_ReleaseStringChars) {
1433 jstring s = env_->NewStringUTF("hello");
1434 ASSERT_TRUE(s != NULL);
1435
1436 jchar expected[] = { 'h', 'e', 'l', 'l', 'o' };
1437 const jchar* chars = env_->GetStringChars(s, NULL);
1438 EXPECT_EQ(expected[0], chars[0]);
1439 EXPECT_EQ(expected[1], chars[1]);
1440 EXPECT_EQ(expected[2], chars[2]);
1441 EXPECT_EQ(expected[3], chars[3]);
1442 EXPECT_EQ(expected[4], chars[4]);
1443 env_->ReleaseStringChars(s, chars);
1444
1445 jboolean is_copy = JNI_FALSE;
1446 chars = env_->GetStringChars(s, &is_copy);
Mathieu Chartier590fee92013-09-13 13:46:47 -07001447 EXPECT_EQ(JNI_TRUE, is_copy);
Elliott Hughes75770752011-08-24 17:52:38 -07001448 EXPECT_EQ(expected[0], chars[0]);
1449 EXPECT_EQ(expected[1], chars[1]);
1450 EXPECT_EQ(expected[2], chars[2]);
1451 EXPECT_EQ(expected[3], chars[3]);
1452 EXPECT_EQ(expected[4], chars[4]);
1453 env_->ReleaseStringChars(s, chars);
1454}
1455
1456TEST_F(JniInternalTest, GetStringCritical_ReleaseStringCritical) {
1457 jstring s = env_->NewStringUTF("hello");
1458 ASSERT_TRUE(s != NULL);
1459
1460 jchar expected[] = { 'h', 'e', 'l', 'l', 'o' };
1461 const jchar* chars = env_->GetStringCritical(s, NULL);
1462 EXPECT_EQ(expected[0], chars[0]);
1463 EXPECT_EQ(expected[1], chars[1]);
1464 EXPECT_EQ(expected[2], chars[2]);
1465 EXPECT_EQ(expected[3], chars[3]);
1466 EXPECT_EQ(expected[4], chars[4]);
1467 env_->ReleaseStringCritical(s, chars);
1468
1469 jboolean is_copy = JNI_FALSE;
1470 chars = env_->GetStringCritical(s, &is_copy);
Mathieu Chartier590fee92013-09-13 13:46:47 -07001471 // TODO: Fix GetStringCritical to use the same mechanism as GetPrimitiveArrayElementsCritical.
1472 EXPECT_EQ(JNI_TRUE, is_copy);
Elliott Hughes75770752011-08-24 17:52:38 -07001473 EXPECT_EQ(expected[0], chars[0]);
1474 EXPECT_EQ(expected[1], chars[1]);
1475 EXPECT_EQ(expected[2], chars[2]);
1476 EXPECT_EQ(expected[3], chars[3]);
1477 EXPECT_EQ(expected[4], chars[4]);
1478 env_->ReleaseStringCritical(s, chars);
1479}
1480
Elliott Hughes814e4032011-08-23 12:07:56 -07001481TEST_F(JniInternalTest, GetObjectArrayElement_SetObjectArrayElement) {
Elliott Hughesb264f082012-04-06 17:10:10 -07001482 jclass java_lang_Class = env_->FindClass("java/lang/Class");
1483 ASSERT_TRUE(java_lang_Class != NULL);
Elliott Hughes289da822011-08-16 10:11:20 -07001484
Elliott Hughesb264f082012-04-06 17:10:10 -07001485 jobjectArray array = env_->NewObjectArray(1, java_lang_Class, NULL);
Elliott Hughes289da822011-08-16 10:11:20 -07001486 EXPECT_TRUE(array != NULL);
Elliott Hughes814e4032011-08-23 12:07:56 -07001487 EXPECT_TRUE(env_->GetObjectArrayElement(array, 0) == NULL);
Elliott Hughesb264f082012-04-06 17:10:10 -07001488 env_->SetObjectArrayElement(array, 0, java_lang_Class);
1489 EXPECT_TRUE(env_->IsSameObject(env_->GetObjectArrayElement(array, 0), java_lang_Class));
Elliott Hughesa5b897e2011-08-16 11:33:06 -07001490
1491 // ArrayIndexOutOfBounds for negative index.
Elliott Hughesb264f082012-04-06 17:10:10 -07001492 env_->SetObjectArrayElement(array, -1, java_lang_Class);
Elliott Hughes814e4032011-08-23 12:07:56 -07001493 EXPECT_EXCEPTION(aioobe_);
Elliott Hughesa5b897e2011-08-16 11:33:06 -07001494
1495 // ArrayIndexOutOfBounds for too-large index.
Elliott Hughesb264f082012-04-06 17:10:10 -07001496 env_->SetObjectArrayElement(array, 1, java_lang_Class);
Elliott Hughes814e4032011-08-23 12:07:56 -07001497 EXPECT_EXCEPTION(aioobe_);
Elliott Hughesa5b897e2011-08-16 11:33:06 -07001498
Elliott Hughesb264f082012-04-06 17:10:10 -07001499 // ArrayStoreException thrown for bad types.
1500 env_->SetObjectArrayElement(array, 0, env_->NewStringUTF("not a jclass!"));
1501 EXPECT_EXCEPTION(ase_);
Elliott Hughes289da822011-08-16 10:11:20 -07001502}
1503
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001504#define EXPECT_STATIC_PRIMITIVE_FIELD(type, field_name, sig, value1, value2) \
1505 do { \
1506 jfieldID fid = env_->GetStaticFieldID(c, field_name, sig); \
1507 EXPECT_TRUE(fid != NULL); \
1508 env_->SetStatic ## type ## Field(c, fid, value1); \
Brian Carlstrom2e3d1b22012-01-09 18:01:56 -08001509 EXPECT_TRUE(value1 == env_->GetStatic ## type ## Field(c, fid)); \
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001510 env_->SetStatic ## type ## Field(c, fid, value2); \
Brian Carlstrom2e3d1b22012-01-09 18:01:56 -08001511 EXPECT_TRUE(value2 == env_->GetStatic ## type ## Field(c, fid)); \
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001512 } while (false)
1513
1514#define EXPECT_PRIMITIVE_FIELD(instance, type, field_name, sig, value1, value2) \
1515 do { \
1516 jfieldID fid = env_->GetFieldID(c, field_name, sig); \
1517 EXPECT_TRUE(fid != NULL); \
1518 env_->Set ## type ## Field(instance, fid, value1); \
Brian Carlstrom2e3d1b22012-01-09 18:01:56 -08001519 EXPECT_TRUE(value1 == env_->Get ## type ## Field(instance, fid)); \
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001520 env_->Set ## type ## Field(instance, fid, value2); \
Brian Carlstrom2e3d1b22012-01-09 18:01:56 -08001521 EXPECT_TRUE(value2 == env_->Get ## type ## Field(instance, fid)); \
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001522 } while (false)
1523
1524
1525TEST_F(JniInternalTest, GetPrimitiveField_SetPrimitiveField) {
Ian Rogersef7d42f2014-01-06 12:55:46 -08001526 TEST_DISABLED_FOR_PORTABLE();
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001527 Thread::Current()->TransitionFromSuspendedToRunnable();
1528 LoadDex("AllFields");
Brian Carlstrombd86bcc2013-03-10 20:26:16 -07001529 bool started = runtime_->Start();
1530 CHECK(started);
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001531
1532 jclass c = env_->FindClass("AllFields");
1533 ASSERT_TRUE(c != NULL);
1534 jobject o = env_->AllocObject(c);
1535 ASSERT_TRUE(o != NULL);
1536
1537 EXPECT_STATIC_PRIMITIVE_FIELD(Boolean, "sZ", "Z", true, false);
1538 EXPECT_STATIC_PRIMITIVE_FIELD(Byte, "sB", "B", 1, 2);
1539 EXPECT_STATIC_PRIMITIVE_FIELD(Char, "sC", "C", 'a', 'b');
1540 EXPECT_STATIC_PRIMITIVE_FIELD(Double, "sD", "D", 1.0, 2.0);
1541 EXPECT_STATIC_PRIMITIVE_FIELD(Float, "sF", "F", 1.0, 2.0);
1542 EXPECT_STATIC_PRIMITIVE_FIELD(Int, "sI", "I", 1, 2);
1543 EXPECT_STATIC_PRIMITIVE_FIELD(Long, "sJ", "J", 1, 2);
1544 EXPECT_STATIC_PRIMITIVE_FIELD(Short, "sS", "S", 1, 2);
1545
1546 EXPECT_PRIMITIVE_FIELD(o, Boolean, "iZ", "Z", true, false);
1547 EXPECT_PRIMITIVE_FIELD(o, Byte, "iB", "B", 1, 2);
1548 EXPECT_PRIMITIVE_FIELD(o, Char, "iC", "C", 'a', 'b');
1549 EXPECT_PRIMITIVE_FIELD(o, Double, "iD", "D", 1.0, 2.0);
1550 EXPECT_PRIMITIVE_FIELD(o, Float, "iF", "F", 1.0, 2.0);
1551 EXPECT_PRIMITIVE_FIELD(o, Int, "iI", "I", 1, 2);
1552 EXPECT_PRIMITIVE_FIELD(o, Long, "iJ", "J", 1, 2);
1553 EXPECT_PRIMITIVE_FIELD(o, Short, "iS", "S", 1, 2);
1554}
1555
1556TEST_F(JniInternalTest, GetObjectField_SetObjectField) {
Ian Rogersef7d42f2014-01-06 12:55:46 -08001557 TEST_DISABLED_FOR_PORTABLE();
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001558 Thread::Current()->TransitionFromSuspendedToRunnable();
1559 LoadDex("AllFields");
Brian Carlstrom25c33252011-09-18 15:58:35 -07001560 runtime_->Start();
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001561
1562 jclass c = env_->FindClass("AllFields");
1563 ASSERT_TRUE(c != NULL);
1564 jobject o = env_->AllocObject(c);
1565 ASSERT_TRUE(o != NULL);
1566
1567 jstring s1 = env_->NewStringUTF("hello");
1568 ASSERT_TRUE(s1 != NULL);
1569 jstring s2 = env_->NewStringUTF("world");
1570 ASSERT_TRUE(s2 != NULL);
1571
1572 jfieldID s_fid = env_->GetStaticFieldID(c, "sObject", "Ljava/lang/Object;");
1573 ASSERT_TRUE(s_fid != NULL);
1574 jfieldID i_fid = env_->GetFieldID(c, "iObject", "Ljava/lang/Object;");
1575 ASSERT_TRUE(i_fid != NULL);
1576
1577 env_->SetStaticObjectField(c, s_fid, s1);
1578 ASSERT_TRUE(env_->IsSameObject(s1, env_->GetStaticObjectField(c, s_fid)));
1579 env_->SetStaticObjectField(c, s_fid, s2);
1580 ASSERT_TRUE(env_->IsSameObject(s2, env_->GetStaticObjectField(c, s_fid)));
1581
1582 env_->SetObjectField(o, i_fid, s1);
1583 ASSERT_TRUE(env_->IsSameObject(s1, env_->GetObjectField(o, i_fid)));
1584 env_->SetObjectField(o, i_fid, s2);
1585 ASSERT_TRUE(env_->IsSameObject(s2, env_->GetObjectField(o, i_fid)));
1586}
1587
Elliott Hughes18c07532011-08-18 15:50:51 -07001588TEST_F(JniInternalTest, NewLocalRef_NULL) {
1589 EXPECT_TRUE(env_->NewLocalRef(NULL) == NULL);
1590}
1591
1592TEST_F(JniInternalTest, NewLocalRef) {
1593 jstring s = env_->NewStringUTF("");
1594 ASSERT_TRUE(s != NULL);
1595 jobject o = env_->NewLocalRef(s);
1596 EXPECT_TRUE(o != NULL);
1597 EXPECT_TRUE(o != s);
1598
Elliott Hughes2ced6a52011-10-16 18:44:48 -07001599 EXPECT_EQ(JNILocalRefType, env_->GetObjectRefType(o));
Elliott Hughes18c07532011-08-18 15:50:51 -07001600}
1601
1602TEST_F(JniInternalTest, DeleteLocalRef_NULL) {
1603 env_->DeleteLocalRef(NULL);
1604}
1605
1606TEST_F(JniInternalTest, DeleteLocalRef) {
1607 jstring s = env_->NewStringUTF("");
1608 ASSERT_TRUE(s != NULL);
1609 env_->DeleteLocalRef(s);
1610
Elliott Hughes3f6635a2012-06-19 13:37:49 -07001611 // Currently, deleting an already-deleted reference is just a CheckJNI warning.
Elliott Hughesb264f082012-04-06 17:10:10 -07001612 {
Elliott Hughesb264f082012-04-06 17:10:10 -07001613 CheckJniAbortCatcher check_jni_abort_catcher;
1614 env_->DeleteLocalRef(s);
Elliott Hughesa9137c62013-01-09 10:55:21 -08001615
Brian Carlstromea46f952013-07-30 01:26:50 -07001616 std::string expected(StringPrintf("native code passing in reference to "
1617 "invalid local reference: %p", s));
Elliott Hughesa9137c62013-01-09 10:55:21 -08001618 check_jni_abort_catcher.Check(expected.c_str());
Elliott Hughesb264f082012-04-06 17:10:10 -07001619 }
Elliott Hughes18c07532011-08-18 15:50:51 -07001620
1621 s = env_->NewStringUTF("");
1622 ASSERT_TRUE(s != NULL);
1623 jobject o = env_->NewLocalRef(s);
1624 ASSERT_TRUE(o != NULL);
1625
1626 env_->DeleteLocalRef(s);
1627 env_->DeleteLocalRef(o);
1628}
1629
Elliott Hughesaa836f72013-08-20 16:57:23 -07001630TEST_F(JniInternalTest, PushLocalFrame_10395422) {
1631 // The JNI specification is ambiguous about whether the given capacity is to be interpreted as a
1632 // maximum or as a minimum, but it seems like it's supposed to be a minimum, and that's how
1633 // Android historically treated it, and it's how the RI treats it. It's also the more useful
1634 // interpretation!
1635 ASSERT_EQ(JNI_OK, env_->PushLocalFrame(0));
1636 env_->PopLocalFrame(NULL);
1637
1638 // Negative capacities are not allowed.
1639 ASSERT_EQ(JNI_ERR, env_->PushLocalFrame(-1));
1640
1641 // And it's okay to have an upper limit. Ours is currently 512.
1642 ASSERT_EQ(JNI_ERR, env_->PushLocalFrame(8192));
1643}
1644
Elliott Hughes2ced6a52011-10-16 18:44:48 -07001645TEST_F(JniInternalTest, PushLocalFrame_PopLocalFrame) {
1646 jobject original = env_->NewStringUTF("");
1647 ASSERT_TRUE(original != NULL);
1648
1649 jobject outer;
1650 jobject inner1, inner2;
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001651 ScopedObjectAccess soa(env_);
Ian Rogers2dd0e2c2013-01-24 12:42:14 -08001652 mirror::Object* inner2_direct_pointer;
Elliott Hughes2ced6a52011-10-16 18:44:48 -07001653 {
Elliott Hughesaa836f72013-08-20 16:57:23 -07001654 ASSERT_EQ(JNI_OK, env_->PushLocalFrame(4));
Elliott Hughes2ced6a52011-10-16 18:44:48 -07001655 outer = env_->NewLocalRef(original);
1656
1657 {
Elliott Hughesaa836f72013-08-20 16:57:23 -07001658 ASSERT_EQ(JNI_OK, env_->PushLocalFrame(4));
Elliott Hughes2ced6a52011-10-16 18:44:48 -07001659 inner1 = env_->NewLocalRef(outer);
1660 inner2 = env_->NewStringUTF("survivor");
Ian Rogers2dd0e2c2013-01-24 12:42:14 -08001661 inner2_direct_pointer = soa.Decode<mirror::Object*>(inner2);
Elliott Hughes2ced6a52011-10-16 18:44:48 -07001662 env_->PopLocalFrame(inner2);
1663 }
1664
1665 EXPECT_EQ(JNILocalRefType, env_->GetObjectRefType(original));
1666 EXPECT_EQ(JNILocalRefType, env_->GetObjectRefType(outer));
1667 EXPECT_EQ(JNIInvalidRefType, env_->GetObjectRefType(inner1));
1668
1669 // Our local reference for the survivor is invalid because the survivor
1670 // gets a new local reference...
1671 EXPECT_EQ(JNIInvalidRefType, env_->GetObjectRefType(inner2));
1672 // ...but the survivor should be in the local reference table.
Brian Carlstrom4d571432012-05-16 00:21:41 -07001673 JNIEnvExt* env = reinterpret_cast<JNIEnvExt*>(env_);
1674 EXPECT_TRUE(env->locals.ContainsDirectPointer(inner2_direct_pointer));
Elliott Hughes2ced6a52011-10-16 18:44:48 -07001675
1676 env_->PopLocalFrame(NULL);
1677 }
1678 EXPECT_EQ(JNILocalRefType, env_->GetObjectRefType(original));
1679 EXPECT_EQ(JNIInvalidRefType, env_->GetObjectRefType(outer));
1680 EXPECT_EQ(JNIInvalidRefType, env_->GetObjectRefType(inner1));
1681 EXPECT_EQ(JNIInvalidRefType, env_->GetObjectRefType(inner2));
1682}
1683
Elliott Hughes18c07532011-08-18 15:50:51 -07001684TEST_F(JniInternalTest, NewGlobalRef_NULL) {
1685 EXPECT_TRUE(env_->NewGlobalRef(NULL) == NULL);
1686}
1687
1688TEST_F(JniInternalTest, NewGlobalRef) {
1689 jstring s = env_->NewStringUTF("");
1690 ASSERT_TRUE(s != NULL);
1691 jobject o = env_->NewGlobalRef(s);
1692 EXPECT_TRUE(o != NULL);
1693 EXPECT_TRUE(o != s);
1694
1695 // TODO: check that o is a global reference.
1696}
1697
1698TEST_F(JniInternalTest, DeleteGlobalRef_NULL) {
1699 env_->DeleteGlobalRef(NULL);
1700}
1701
1702TEST_F(JniInternalTest, DeleteGlobalRef) {
1703 jstring s = env_->NewStringUTF("");
1704 ASSERT_TRUE(s != NULL);
1705
1706 jobject o = env_->NewGlobalRef(s);
1707 ASSERT_TRUE(o != NULL);
1708 env_->DeleteGlobalRef(o);
1709
Elliott Hughes3f6635a2012-06-19 13:37:49 -07001710 // Currently, deleting an already-deleted reference is just a CheckJNI warning.
Elliott Hughesb264f082012-04-06 17:10:10 -07001711 {
Elliott Hughesb264f082012-04-06 17:10:10 -07001712 CheckJniAbortCatcher check_jni_abort_catcher;
1713 env_->DeleteGlobalRef(o);
Elliott Hughesa9137c62013-01-09 10:55:21 -08001714
Brian Carlstromea46f952013-07-30 01:26:50 -07001715 std::string expected(StringPrintf("native code passing in reference to "
1716 "invalid global reference: %p", o));
Elliott Hughesa9137c62013-01-09 10:55:21 -08001717 check_jni_abort_catcher.Check(expected.c_str());
Elliott Hughesb264f082012-04-06 17:10:10 -07001718 }
Elliott Hughes18c07532011-08-18 15:50:51 -07001719
1720 jobject o1 = env_->NewGlobalRef(s);
1721 ASSERT_TRUE(o1 != NULL);
1722 jobject o2 = env_->NewGlobalRef(s);
1723 ASSERT_TRUE(o2 != NULL);
1724
1725 env_->DeleteGlobalRef(o1);
1726 env_->DeleteGlobalRef(o2);
1727}
1728
1729TEST_F(JniInternalTest, NewWeakGlobalRef_NULL) {
1730 EXPECT_TRUE(env_->NewWeakGlobalRef(NULL) == NULL);
1731}
1732
1733TEST_F(JniInternalTest, NewWeakGlobalRef) {
1734 jstring s = env_->NewStringUTF("");
1735 ASSERT_TRUE(s != NULL);
1736 jobject o = env_->NewWeakGlobalRef(s);
1737 EXPECT_TRUE(o != NULL);
1738 EXPECT_TRUE(o != s);
1739
1740 // TODO: check that o is a weak global reference.
1741}
1742
1743TEST_F(JniInternalTest, DeleteWeakGlobalRef_NULL) {
1744 env_->DeleteWeakGlobalRef(NULL);
1745}
1746
1747TEST_F(JniInternalTest, DeleteWeakGlobalRef) {
1748 jstring s = env_->NewStringUTF("");
1749 ASSERT_TRUE(s != NULL);
1750
1751 jobject o = env_->NewWeakGlobalRef(s);
1752 ASSERT_TRUE(o != NULL);
1753 env_->DeleteWeakGlobalRef(o);
1754
Elliott Hughes3f6635a2012-06-19 13:37:49 -07001755 // Currently, deleting an already-deleted reference is just a CheckJNI warning.
Elliott Hughesb264f082012-04-06 17:10:10 -07001756 {
Elliott Hughesb264f082012-04-06 17:10:10 -07001757 CheckJniAbortCatcher check_jni_abort_catcher;
1758 env_->DeleteWeakGlobalRef(o);
Elliott Hughesa9137c62013-01-09 10:55:21 -08001759
Brian Carlstromea46f952013-07-30 01:26:50 -07001760 std::string expected(StringPrintf("native code passing in reference to "
1761 "invalid weak global reference: %p", o));
Elliott Hughesa9137c62013-01-09 10:55:21 -08001762 check_jni_abort_catcher.Check(expected.c_str());
Elliott Hughesb264f082012-04-06 17:10:10 -07001763 }
Elliott Hughes18c07532011-08-18 15:50:51 -07001764
1765 jobject o1 = env_->NewWeakGlobalRef(s);
1766 ASSERT_TRUE(o1 != NULL);
1767 jobject o2 = env_->NewWeakGlobalRef(s);
1768 ASSERT_TRUE(o2 != NULL);
1769
1770 env_->DeleteWeakGlobalRef(o1);
1771 env_->DeleteWeakGlobalRef(o2);
1772}
1773
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001774TEST_F(JniInternalTest, StaticMainMethod) {
Brian Carlstrom265091e2013-01-30 14:08:26 -08001775 TEST_DISABLED_FOR_PORTABLE();
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001776 ScopedObjectAccess soa(Thread::Current());
1777 jobject jclass_loader = LoadDex("Main");
Ian Rogers2dd0e2c2013-01-24 12:42:14 -08001778 SirtRef<mirror::ClassLoader>
1779 class_loader(soa.Self(), soa.Decode<mirror::ClassLoader*>(jclass_loader));
Mathieu Chartier590fee92013-09-13 13:46:47 -07001780 CompileDirectMethod(class_loader, "Main", "main", "([Ljava/lang/String;)V");
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001781
Ian Rogers98379392014-02-24 16:53:16 -08001782 mirror::Class* klass = class_linker_->FindClass(soa.Self(), "LMain;", class_loader);
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001783 ASSERT_TRUE(klass != NULL);
1784
Brian Carlstromea46f952013-07-30 01:26:50 -07001785 mirror::ArtMethod* method = klass->FindDirectMethod("main", "([Ljava/lang/String;)V");
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001786 ASSERT_TRUE(method != NULL);
1787
Ian Rogers936b37f2014-02-14 00:52:24 -08001788 ArgArray arg_array("VL", 2);
Ian Rogersef7d42f2014-01-06 12:55:46 -08001789 arg_array.Append(0U);
Jeff Hao5d917302013-02-27 17:57:33 -08001790 JValue result;
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001791
Sebastien Hertzb95851f2013-03-29 10:36:40 +01001792 // Start runtime.
1793 bool started = runtime_->Start();
1794 CHECK(started);
1795 Thread::Current()->TransitionFromSuspendedToRunnable();
1796
Ian Rogers0177e532014-02-11 16:30:46 -08001797 method->Invoke(Thread::Current(), arg_array.GetArray(), arg_array.GetNumBytes(), &result, "VL");
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001798}
1799
1800TEST_F(JniInternalTest, StaticNopMethod) {
Brian Carlstrom265091e2013-01-30 14:08:26 -08001801 TEST_DISABLED_FOR_PORTABLE();
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001802 ScopedObjectAccess soa(Thread::Current());
Elliott Hughes77405792012-03-15 15:22:12 -07001803 InvokeNopMethod(true);
1804}
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001805
Elliott Hughes77405792012-03-15 15:22:12 -07001806TEST_F(JniInternalTest, NonStaticNopMethod) {
Brian Carlstrom265091e2013-01-30 14:08:26 -08001807 TEST_DISABLED_FOR_PORTABLE();
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001808 ScopedObjectAccess soa(Thread::Current());
Elliott Hughes77405792012-03-15 15:22:12 -07001809 InvokeNopMethod(false);
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001810}
1811
1812TEST_F(JniInternalTest, StaticIdentityByteMethod) {
Brian Carlstrom265091e2013-01-30 14:08:26 -08001813 TEST_DISABLED_FOR_PORTABLE();
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001814 ScopedObjectAccess soa(Thread::Current());
Elliott Hughes77405792012-03-15 15:22:12 -07001815 InvokeIdentityByteMethod(true);
1816}
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001817
Elliott Hughes77405792012-03-15 15:22:12 -07001818TEST_F(JniInternalTest, NonStaticIdentityByteMethod) {
Brian Carlstrom265091e2013-01-30 14:08:26 -08001819 TEST_DISABLED_FOR_PORTABLE();
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001820 ScopedObjectAccess soa(Thread::Current());
Elliott Hughes77405792012-03-15 15:22:12 -07001821 InvokeIdentityByteMethod(false);
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001822}
1823
1824TEST_F(JniInternalTest, StaticIdentityIntMethod) {
Brian Carlstrom265091e2013-01-30 14:08:26 -08001825 TEST_DISABLED_FOR_PORTABLE();
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001826 ScopedObjectAccess soa(Thread::Current());
Elliott Hughes77405792012-03-15 15:22:12 -07001827 InvokeIdentityIntMethod(true);
1828}
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001829
Elliott Hughes77405792012-03-15 15:22:12 -07001830TEST_F(JniInternalTest, NonStaticIdentityIntMethod) {
Brian Carlstrom265091e2013-01-30 14:08:26 -08001831 TEST_DISABLED_FOR_PORTABLE();
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001832 ScopedObjectAccess soa(Thread::Current());
Elliott Hughes77405792012-03-15 15:22:12 -07001833 InvokeIdentityIntMethod(false);
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001834}
1835
1836TEST_F(JniInternalTest, StaticIdentityDoubleMethod) {
Brian Carlstrom265091e2013-01-30 14:08:26 -08001837 TEST_DISABLED_FOR_PORTABLE();
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001838 ScopedObjectAccess soa(Thread::Current());
Elliott Hughes77405792012-03-15 15:22:12 -07001839 InvokeIdentityDoubleMethod(true);
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001840}
1841
Elliott Hughes77405792012-03-15 15:22:12 -07001842TEST_F(JniInternalTest, NonStaticIdentityDoubleMethod) {
Brian Carlstrom265091e2013-01-30 14:08:26 -08001843 TEST_DISABLED_FOR_PORTABLE();
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001844 ScopedObjectAccess soa(Thread::Current());
Elliott Hughes77405792012-03-15 15:22:12 -07001845 InvokeIdentityDoubleMethod(false);
Shih-wei Liao5b8b1ed2012-02-23 23:48:21 -08001846}
1847
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001848TEST_F(JniInternalTest, StaticSumIntIntMethod) {
Brian Carlstrom265091e2013-01-30 14:08:26 -08001849 TEST_DISABLED_FOR_PORTABLE();
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001850 ScopedObjectAccess soa(Thread::Current());
Elliott Hughes77405792012-03-15 15:22:12 -07001851 InvokeSumIntIntMethod(true);
1852}
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001853
Elliott Hughes77405792012-03-15 15:22:12 -07001854TEST_F(JniInternalTest, NonStaticSumIntIntMethod) {
Brian Carlstrom265091e2013-01-30 14:08:26 -08001855 TEST_DISABLED_FOR_PORTABLE();
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001856 ScopedObjectAccess soa(Thread::Current());
Elliott Hughes77405792012-03-15 15:22:12 -07001857 InvokeSumIntIntMethod(false);
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001858}
1859
1860TEST_F(JniInternalTest, StaticSumIntIntIntMethod) {
Brian Carlstrom265091e2013-01-30 14:08:26 -08001861 TEST_DISABLED_FOR_PORTABLE();
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001862 ScopedObjectAccess soa(Thread::Current());
Elliott Hughes77405792012-03-15 15:22:12 -07001863 InvokeSumIntIntIntMethod(true);
1864}
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001865
Elliott Hughes77405792012-03-15 15:22:12 -07001866TEST_F(JniInternalTest, NonStaticSumIntIntIntMethod) {
Brian Carlstrom265091e2013-01-30 14:08:26 -08001867 TEST_DISABLED_FOR_PORTABLE();
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001868 ScopedObjectAccess soa(Thread::Current());
Elliott Hughes77405792012-03-15 15:22:12 -07001869 InvokeSumIntIntIntMethod(false);
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001870}
1871
1872TEST_F(JniInternalTest, StaticSumIntIntIntIntMethod) {
Brian Carlstrom265091e2013-01-30 14:08:26 -08001873 TEST_DISABLED_FOR_PORTABLE();
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001874 ScopedObjectAccess soa(Thread::Current());
Elliott Hughes77405792012-03-15 15:22:12 -07001875 InvokeSumIntIntIntIntMethod(true);
1876}
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001877
Elliott Hughes77405792012-03-15 15:22:12 -07001878TEST_F(JniInternalTest, NonStaticSumIntIntIntIntMethod) {
Brian Carlstrom265091e2013-01-30 14:08:26 -08001879 TEST_DISABLED_FOR_PORTABLE();
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001880 ScopedObjectAccess soa(Thread::Current());
Elliott Hughes77405792012-03-15 15:22:12 -07001881 InvokeSumIntIntIntIntMethod(false);
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001882}
1883
1884TEST_F(JniInternalTest, StaticSumIntIntIntIntIntMethod) {
Brian Carlstrom265091e2013-01-30 14:08:26 -08001885 TEST_DISABLED_FOR_PORTABLE();
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001886 ScopedObjectAccess soa(Thread::Current());
Elliott Hughes77405792012-03-15 15:22:12 -07001887 InvokeSumIntIntIntIntIntMethod(true);
1888}
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001889
Elliott Hughes77405792012-03-15 15:22:12 -07001890TEST_F(JniInternalTest, NonStaticSumIntIntIntIntIntMethod) {
Brian Carlstrom265091e2013-01-30 14:08:26 -08001891 TEST_DISABLED_FOR_PORTABLE();
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001892 ScopedObjectAccess soa(Thread::Current());
Elliott Hughes77405792012-03-15 15:22:12 -07001893 InvokeSumIntIntIntIntIntMethod(false);
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001894}
1895
1896TEST_F(JniInternalTest, StaticSumDoubleDoubleMethod) {
Brian Carlstrom265091e2013-01-30 14:08:26 -08001897 TEST_DISABLED_FOR_PORTABLE();
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001898 ScopedObjectAccess soa(Thread::Current());
Elliott Hughes77405792012-03-15 15:22:12 -07001899 InvokeSumDoubleDoubleMethod(true);
1900}
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001901
Elliott Hughes77405792012-03-15 15:22:12 -07001902TEST_F(JniInternalTest, NonStaticSumDoubleDoubleMethod) {
Brian Carlstrom265091e2013-01-30 14:08:26 -08001903 TEST_DISABLED_FOR_PORTABLE();
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001904 ScopedObjectAccess soa(Thread::Current());
Elliott Hughes77405792012-03-15 15:22:12 -07001905 InvokeSumDoubleDoubleMethod(false);
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001906}
1907
1908TEST_F(JniInternalTest, StaticSumDoubleDoubleDoubleMethod) {
Brian Carlstrom265091e2013-01-30 14:08:26 -08001909 TEST_DISABLED_FOR_PORTABLE();
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001910 ScopedObjectAccess soa(Thread::Current());
Elliott Hughes77405792012-03-15 15:22:12 -07001911 InvokeSumDoubleDoubleDoubleMethod(true);
1912}
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001913
Elliott Hughes77405792012-03-15 15:22:12 -07001914TEST_F(JniInternalTest, NonStaticSumDoubleDoubleDoubleMethod) {
Brian Carlstrom265091e2013-01-30 14:08:26 -08001915 TEST_DISABLED_FOR_PORTABLE();
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001916 ScopedObjectAccess soa(Thread::Current());
Elliott Hughes77405792012-03-15 15:22:12 -07001917 InvokeSumDoubleDoubleDoubleMethod(false);
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001918}
1919
1920TEST_F(JniInternalTest, StaticSumDoubleDoubleDoubleDoubleMethod) {
Brian Carlstrom265091e2013-01-30 14:08:26 -08001921 TEST_DISABLED_FOR_PORTABLE();
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001922 ScopedObjectAccess soa(Thread::Current());
Elliott Hughes77405792012-03-15 15:22:12 -07001923 InvokeSumDoubleDoubleDoubleDoubleMethod(true);
1924}
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001925
Elliott Hughes77405792012-03-15 15:22:12 -07001926TEST_F(JniInternalTest, NonStaticSumDoubleDoubleDoubleDoubleMethod) {
Brian Carlstrom265091e2013-01-30 14:08:26 -08001927 TEST_DISABLED_FOR_PORTABLE();
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001928 ScopedObjectAccess soa(Thread::Current());
Elliott Hughes77405792012-03-15 15:22:12 -07001929 InvokeSumDoubleDoubleDoubleDoubleMethod(false);
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001930}
1931
1932TEST_F(JniInternalTest, StaticSumDoubleDoubleDoubleDoubleDoubleMethod) {
Brian Carlstrom265091e2013-01-30 14:08:26 -08001933 TEST_DISABLED_FOR_PORTABLE();
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001934 ScopedObjectAccess soa(Thread::Current());
Elliott Hughes77405792012-03-15 15:22:12 -07001935 InvokeSumDoubleDoubleDoubleDoubleDoubleMethod(true);
1936}
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001937
Elliott Hughes77405792012-03-15 15:22:12 -07001938TEST_F(JniInternalTest, NonStaticSumDoubleDoubleDoubleDoubleDoubleMethod) {
Brian Carlstrom265091e2013-01-30 14:08:26 -08001939 TEST_DISABLED_FOR_PORTABLE();
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001940 ScopedObjectAccess soa(Thread::Current());
Elliott Hughes77405792012-03-15 15:22:12 -07001941 InvokeSumDoubleDoubleDoubleDoubleDoubleMethod(false);
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001942}
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001943
Elliott Hughes37f7a402011-08-22 18:56:01 -07001944TEST_F(JniInternalTest, Throw) {
1945 EXPECT_EQ(JNI_ERR, env_->Throw(NULL));
1946
1947 jclass exception_class = env_->FindClass("java/lang/RuntimeException");
1948 ASSERT_TRUE(exception_class != NULL);
1949 jthrowable exception = reinterpret_cast<jthrowable>(env_->AllocObject(exception_class));
1950 ASSERT_TRUE(exception != NULL);
1951
1952 EXPECT_EQ(JNI_OK, env_->Throw(exception));
1953 EXPECT_TRUE(env_->ExceptionCheck());
Elliott Hughesa2501992011-08-26 19:39:54 -07001954 jthrowable thrown_exception = env_->ExceptionOccurred();
Elliott Hughes37f7a402011-08-22 18:56:01 -07001955 env_->ExceptionClear();
Elliott Hughesa2501992011-08-26 19:39:54 -07001956 EXPECT_TRUE(env_->IsSameObject(exception, thrown_exception));
Elliott Hughes37f7a402011-08-22 18:56:01 -07001957}
1958
1959TEST_F(JniInternalTest, ThrowNew) {
1960 EXPECT_EQ(JNI_ERR, env_->Throw(NULL));
1961
1962 jclass exception_class = env_->FindClass("java/lang/RuntimeException");
1963 ASSERT_TRUE(exception_class != NULL);
1964
Elliott Hughes5cb5ad22011-10-02 12:13:39 -07001965 jthrowable thrown_exception;
1966
Elliott Hughes37f7a402011-08-22 18:56:01 -07001967 EXPECT_EQ(JNI_OK, env_->ThrowNew(exception_class, "hello world"));
1968 EXPECT_TRUE(env_->ExceptionCheck());
Elliott Hughes5cb5ad22011-10-02 12:13:39 -07001969 thrown_exception = env_->ExceptionOccurred();
1970 env_->ExceptionClear();
1971 EXPECT_TRUE(env_->IsInstanceOf(thrown_exception, exception_class));
1972
1973 EXPECT_EQ(JNI_OK, env_->ThrowNew(exception_class, NULL));
1974 EXPECT_TRUE(env_->ExceptionCheck());
1975 thrown_exception = env_->ExceptionOccurred();
Elliott Hughes37f7a402011-08-22 18:56:01 -07001976 env_->ExceptionClear();
Elliott Hughesa2501992011-08-26 19:39:54 -07001977 EXPECT_TRUE(env_->IsInstanceOf(thrown_exception, exception_class));
Elliott Hughes37f7a402011-08-22 18:56:01 -07001978}
1979
Ian Rogers1d99e452014-01-02 17:36:41 -08001980TEST_F(JniInternalTest, NewDirectBuffer_GetDirectBufferAddress_GetDirectBufferCapacity) {
1981 // Start runtime.
1982 Thread* self = Thread::Current();
1983 self->TransitionFromSuspendedToRunnable();
1984 MakeExecutable(nullptr, "java.lang.Class");
1985 MakeExecutable(nullptr, "java.lang.Object");
1986 MakeExecutable(nullptr, "java.nio.DirectByteBuffer");
1987 MakeExecutable(nullptr, "java.nio.MemoryBlock");
1988 MakeExecutable(nullptr, "java.nio.MemoryBlock$UnmanagedBlock");
1989 MakeExecutable(nullptr, "java.nio.MappedByteBuffer");
1990 MakeExecutable(nullptr, "java.nio.ByteBuffer");
1991 MakeExecutable(nullptr, "java.nio.Buffer");
1992 // TODO: we only load a dex file here as starting the runtime relies upon it.
1993 const char* class_name = "StaticLeafMethods";
1994 LoadDex(class_name);
1995 bool started = runtime_->Start();
1996 ASSERT_TRUE(started);
1997
Elliott Hughesb465ab02011-08-24 11:21:21 -07001998 jclass buffer_class = env_->FindClass("java/nio/Buffer");
1999 ASSERT_TRUE(buffer_class != NULL);
2000
2001 char bytes[1024];
2002 jobject buffer = env_->NewDirectByteBuffer(bytes, sizeof(bytes));
2003 ASSERT_TRUE(buffer != NULL);
2004 ASSERT_TRUE(env_->IsInstanceOf(buffer, buffer_class));
2005 ASSERT_TRUE(env_->GetDirectBufferAddress(buffer) == bytes);
2006 ASSERT_TRUE(env_->GetDirectBufferCapacity(buffer) == sizeof(bytes));
2007}
2008
Ian Rogers6d0b13e2012-02-07 09:25:29 -08002009TEST_F(JniInternalTest, MonitorEnterExit) {
2010 // Create an object to torture
2011 jclass object_class = env_->FindClass("java/lang/Object");
2012 ASSERT_TRUE(object_class != NULL);
2013 jobject object = env_->AllocObject(object_class);
2014 ASSERT_TRUE(object != NULL);
2015
2016 // Expected class of exceptions
2017 jclass imse_class = env_->FindClass("java/lang/IllegalMonitorStateException");
2018 ASSERT_TRUE(imse_class != NULL);
2019
2020 jthrowable thrown_exception;
2021
2022 // Unlock of unowned monitor
2023 env_->MonitorExit(object);
2024 EXPECT_TRUE(env_->ExceptionCheck());
2025 thrown_exception = env_->ExceptionOccurred();
2026 env_->ExceptionClear();
2027 EXPECT_TRUE(env_->IsInstanceOf(thrown_exception, imse_class));
2028
2029 // Lock of unowned monitor
2030 env_->MonitorEnter(object);
2031 EXPECT_FALSE(env_->ExceptionCheck());
2032 // Regular unlock
2033 env_->MonitorExit(object);
2034 EXPECT_FALSE(env_->ExceptionCheck());
2035
2036 // Recursively lock a lot
2037 size_t max_recursive_lock = 1024;
2038 for (size_t i = 0; i < max_recursive_lock; i++) {
2039 env_->MonitorEnter(object);
2040 EXPECT_FALSE(env_->ExceptionCheck());
2041 }
2042 // Recursively unlock a lot
2043 for (size_t i = 0; i < max_recursive_lock; i++) {
2044 env_->MonitorExit(object);
2045 EXPECT_FALSE(env_->ExceptionCheck());
2046 }
2047
2048 // Unlock of unowned monitor
2049 env_->MonitorExit(object);
2050 EXPECT_TRUE(env_->ExceptionCheck());
2051 thrown_exception = env_->ExceptionOccurred();
2052 env_->ExceptionClear();
2053 EXPECT_TRUE(env_->IsInstanceOf(thrown_exception, imse_class));
Elliott Hughesa92853e2012-02-07 16:09:27 -08002054
2055 // It's an error to call MonitorEnter or MonitorExit on NULL.
Elliott Hughesb264f082012-04-06 17:10:10 -07002056 {
2057 CheckJniAbortCatcher check_jni_abort_catcher;
2058 env_->MonitorEnter(NULL);
2059 check_jni_abort_catcher.Check("in call to MonitorEnter");
Elliott Hughesb264f082012-04-06 17:10:10 -07002060
Elliott Hughesb264f082012-04-06 17:10:10 -07002061 env_->MonitorExit(NULL);
2062 check_jni_abort_catcher.Check("in call to MonitorExit");
2063 }
Ian Rogers6d0b13e2012-02-07 09:25:29 -08002064}
2065
Brian Carlstrom4d571432012-05-16 00:21:41 -07002066TEST_F(JniInternalTest, DetachCurrentThread) {
2067 CleanUpJniEnv(); // cleanup now so TearDown won't have junk from wrong JNIEnv
2068 jint ok = vm_->DetachCurrentThread();
2069 EXPECT_EQ(JNI_OK, ok);
2070
2071 jint err = vm_->DetachCurrentThread();
2072 EXPECT_EQ(JNI_ERR, err);
2073 vm_->AttachCurrentThread(&env_, NULL); // need attached thread for CommonTest::TearDown
2074}
2075
Ian Rogers0cfe1fb2011-08-26 03:29:44 -07002076} // namespace art