blob: 79d156de27760dc89eeb3777d38597101265ecd0 [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
Brian Carlstromea46f952013-07-30 01:26:50 -070081 void DoCompile(mirror::ArtMethod*& method,
Jeff Hao5d917302013-02-27 17:57:33 -080082 mirror::Object*& receiver,
83 bool is_static, const char* method_name,
84 const char* method_signature)
Ian Rogersb726dcb2012-09-05 08:57:23 -070085 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Elliott Hughes77405792012-03-15 15:22:12 -070086 const char* class_name = is_static ? "StaticLeafMethods" : "NonStaticLeafMethods";
Ian Rogers00f7d0e2012-07-19 15:28:27 -070087 jobject jclass_loader(LoadDex(class_name));
Ian Rogers1f539342012-10-03 21:09:42 -070088 Thread* self = Thread::Current();
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080089 SirtRef<mirror::ClassLoader>
Ian Rogers1f539342012-10-03 21:09:42 -070090 class_loader(self,
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080091 ScopedObjectAccessUnchecked(self).Decode<mirror::ClassLoader*>(jclass_loader));
Elliott Hughes77405792012-03-15 15:22:12 -070092 if (is_static) {
93 CompileDirectMethod(class_loader.get(), class_name, method_name, method_signature);
94 } else {
95 CompileVirtualMethod(NULL, "java.lang.Class", "isFinalizable", "()Z");
96 CompileDirectMethod(NULL, "java.lang.Object", "<init>", "()V");
97 CompileVirtualMethod(class_loader.get(), class_name, method_name, method_signature);
98 }
99
Brian Carlstromea46f952013-07-30 01:26:50 -0700100 mirror::Class* c = class_linker_->FindClass(DotToDescriptor(class_name).c_str(),
101 class_loader.get());
Elliott Hughes77405792012-03-15 15:22:12 -0700102 CHECK(c != NULL);
103
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700104 method = is_static ? c->FindDirectMethod(method_name, method_signature)
105 : c->FindVirtualMethod(method_name, method_signature);
Elliott Hughes77405792012-03-15 15:22:12 -0700106 CHECK(method != NULL);
107
Ian Rogers50b35e22012-10-04 10:09:15 -0700108 receiver = (is_static ? NULL : c->AllocObject(self));
Sebastien Hertzb95851f2013-03-29 10:36:40 +0100109
110 // Start runtime.
111 bool started = runtime_->Start();
112 CHECK(started);
113 self->TransitionFromSuspendedToRunnable();
Elliott Hughes77405792012-03-15 15:22:12 -0700114 }
115
Ian Rogersb726dcb2012-09-05 08:57:23 -0700116 void InvokeNopMethod(bool is_static) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Brian Carlstromea46f952013-07-30 01:26:50 -0700117 mirror::ArtMethod* method;
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800118 mirror::Object* receiver;
Jeff Hao5d917302013-02-27 17:57:33 -0800119 DoCompile(method, receiver, is_static, "nop", "()V");
120
121 ArgArray arg_array(NULL, 0);
122 JValue result;
Jeff Hao5d917302013-02-27 17:57:33 -0800123
124 if (!is_static) {
125 arg_array.Append(reinterpret_cast<uint32_t>(receiver));
126 }
Sebastien Hertzb95851f2013-03-29 10:36:40 +0100127
128 method->Invoke(Thread::Current(), arg_array.GetArray(), arg_array.GetNumBytes(), &result, 'V');
Elliott Hughes77405792012-03-15 15:22:12 -0700129 }
130
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700131 void InvokeIdentityByteMethod(bool is_static)
Ian Rogersb726dcb2012-09-05 08:57:23 -0700132 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Brian Carlstromea46f952013-07-30 01:26:50 -0700133 mirror::ArtMethod* method;
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800134 mirror::Object* receiver;
Jeff Hao5d917302013-02-27 17:57:33 -0800135 DoCompile(method, receiver, is_static, "identity", "(I)I");
Elliott Hughes77405792012-03-15 15:22:12 -0700136
Jeff Hao5d917302013-02-27 17:57:33 -0800137 ArgArray arg_array(NULL, 0);
138 uint32_t* args = arg_array.GetArray();
Elliott Hughes77405792012-03-15 15:22:12 -0700139 JValue result;
140
Jeff Hao5d917302013-02-27 17:57:33 -0800141 if (!is_static) {
142 arg_array.Append(reinterpret_cast<uint32_t>(receiver));
143 args++;
144 }
145
146 arg_array.Append(0);
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700147 result.SetB(-1);
Sebastien Hertzb95851f2013-03-29 10:36:40 +0100148 method->Invoke(Thread::Current(), arg_array.GetArray(), arg_array.GetNumBytes(), &result, 'B');
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700149 EXPECT_EQ(0, result.GetB());
Elliott Hughes77405792012-03-15 15:22:12 -0700150
Jeff Hao5d917302013-02-27 17:57:33 -0800151 args[0] = -1;
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700152 result.SetB(0);
Sebastien Hertzb95851f2013-03-29 10:36:40 +0100153 method->Invoke(Thread::Current(), arg_array.GetArray(), arg_array.GetNumBytes(), &result, 'B');
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700154 EXPECT_EQ(-1, result.GetB());
Elliott Hughes77405792012-03-15 15:22:12 -0700155
Jeff Hao5d917302013-02-27 17:57:33 -0800156 args[0] = SCHAR_MAX;
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700157 result.SetB(0);
Sebastien Hertzb95851f2013-03-29 10:36:40 +0100158 method->Invoke(Thread::Current(), arg_array.GetArray(), arg_array.GetNumBytes(), &result, 'B');
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700159 EXPECT_EQ(SCHAR_MAX, result.GetB());
Elliott Hughes77405792012-03-15 15:22:12 -0700160
Jeff Hao5d917302013-02-27 17:57:33 -0800161 args[0] = (SCHAR_MIN << 24) >> 24;
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700162 result.SetB(0);
Sebastien Hertzb95851f2013-03-29 10:36:40 +0100163 method->Invoke(Thread::Current(), arg_array.GetArray(), arg_array.GetNumBytes(), &result, 'B');
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700164 EXPECT_EQ(SCHAR_MIN, result.GetB());
Elliott Hughes77405792012-03-15 15:22:12 -0700165 }
166
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700167 void InvokeIdentityIntMethod(bool is_static)
Ian Rogersb726dcb2012-09-05 08:57:23 -0700168 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Brian Carlstromea46f952013-07-30 01:26:50 -0700169 mirror::ArtMethod* method;
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800170 mirror::Object* receiver;
Jeff Hao5d917302013-02-27 17:57:33 -0800171 DoCompile(method, receiver, is_static, "identity", "(I)I");
Elliott Hughes77405792012-03-15 15:22:12 -0700172
Jeff Hao5d917302013-02-27 17:57:33 -0800173 ArgArray arg_array(NULL, 0);
174 uint32_t* args = arg_array.GetArray();
Elliott Hughes77405792012-03-15 15:22:12 -0700175 JValue result;
176
Jeff Hao5d917302013-02-27 17:57:33 -0800177 if (!is_static) {
178 arg_array.Append(reinterpret_cast<uint32_t>(receiver));
179 args++;
180 }
181
182 arg_array.Append(0);
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700183 result.SetI(-1);
Sebastien Hertzb95851f2013-03-29 10:36:40 +0100184 method->Invoke(Thread::Current(), arg_array.GetArray(), arg_array.GetNumBytes(), &result, 'I');
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700185 EXPECT_EQ(0, result.GetI());
Elliott Hughes77405792012-03-15 15:22:12 -0700186
Jeff Hao5d917302013-02-27 17:57:33 -0800187 args[0] = -1;
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700188 result.SetI(0);
Sebastien Hertzb95851f2013-03-29 10:36:40 +0100189 method->Invoke(Thread::Current(), arg_array.GetArray(), arg_array.GetNumBytes(), &result, 'I');
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700190 EXPECT_EQ(-1, result.GetI());
Elliott Hughes77405792012-03-15 15:22:12 -0700191
Jeff Hao5d917302013-02-27 17:57:33 -0800192 args[0] = INT_MAX;
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700193 result.SetI(0);
Sebastien Hertzb95851f2013-03-29 10:36:40 +0100194 method->Invoke(Thread::Current(), arg_array.GetArray(), arg_array.GetNumBytes(), &result, 'I');
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700195 EXPECT_EQ(INT_MAX, result.GetI());
Elliott Hughes77405792012-03-15 15:22:12 -0700196
Jeff Hao5d917302013-02-27 17:57:33 -0800197 args[0] = INT_MIN;
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700198 result.SetI(0);
Sebastien Hertzb95851f2013-03-29 10:36:40 +0100199 method->Invoke(Thread::Current(), arg_array.GetArray(), arg_array.GetNumBytes(), &result, 'I');
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700200 EXPECT_EQ(INT_MIN, result.GetI());
Elliott Hughes77405792012-03-15 15:22:12 -0700201 }
202
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700203 void InvokeIdentityDoubleMethod(bool is_static)
Ian Rogersb726dcb2012-09-05 08:57:23 -0700204 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Brian Carlstromea46f952013-07-30 01:26:50 -0700205 mirror::ArtMethod* method;
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800206 mirror::Object* receiver;
Jeff Hao5d917302013-02-27 17:57:33 -0800207 DoCompile(method, receiver, is_static, "identity", "(D)D");
Elliott Hughes77405792012-03-15 15:22:12 -0700208
Jeff Hao5d917302013-02-27 17:57:33 -0800209 ArgArray arg_array(NULL, 0);
210 uint32_t* args = arg_array.GetArray();
211 JValue value;
Elliott Hughes77405792012-03-15 15:22:12 -0700212 JValue result;
213
Jeff Hao5d917302013-02-27 17:57:33 -0800214 if (!is_static) {
215 arg_array.Append(reinterpret_cast<uint32_t>(receiver));
216 args++;
217 }
218
219 value.SetD(0.0);
220 arg_array.AppendWide(value.GetJ());
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700221 result.SetD(-1.0);
Sebastien Hertzb95851f2013-03-29 10:36:40 +0100222 method->Invoke(Thread::Current(), arg_array.GetArray(), arg_array.GetNumBytes(), &result, 'D');
Jeff Hao6474d192013-03-26 14:08:09 -0700223 EXPECT_EQ(0.0, result.GetD());
Elliott Hughes77405792012-03-15 15:22:12 -0700224
Jeff Hao5d917302013-02-27 17:57:33 -0800225 value.SetD(-1.0);
226 args[0] = value.GetJ();
227 args[1] = value.GetJ() >> 32;
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700228 result.SetD(0.0);
Sebastien Hertzb95851f2013-03-29 10:36:40 +0100229 method->Invoke(Thread::Current(), arg_array.GetArray(), arg_array.GetNumBytes(), &result, 'D');
Jeff Hao6474d192013-03-26 14:08:09 -0700230 EXPECT_EQ(-1.0, result.GetD());
Elliott Hughes77405792012-03-15 15:22:12 -0700231
Jeff Hao5d917302013-02-27 17:57:33 -0800232 value.SetD(DBL_MAX);
233 args[0] = value.GetJ();
234 args[1] = value.GetJ() >> 32;
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700235 result.SetD(0.0);
Sebastien Hertzb95851f2013-03-29 10:36:40 +0100236 method->Invoke(Thread::Current(), arg_array.GetArray(), arg_array.GetNumBytes(), &result, 'D');
Jeff Hao6474d192013-03-26 14:08:09 -0700237 EXPECT_EQ(DBL_MAX, result.GetD());
Elliott Hughes77405792012-03-15 15:22:12 -0700238
Jeff Hao5d917302013-02-27 17:57:33 -0800239 value.SetD(DBL_MIN);
240 args[0] = value.GetJ();
241 args[1] = value.GetJ() >> 32;
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700242 result.SetD(0.0);
Sebastien Hertzb95851f2013-03-29 10:36:40 +0100243 method->Invoke(Thread::Current(), arg_array.GetArray(), arg_array.GetNumBytes(), &result, 'D');
Jeff Hao6474d192013-03-26 14:08:09 -0700244 EXPECT_EQ(DBL_MIN, result.GetD());
Elliott Hughes77405792012-03-15 15:22:12 -0700245 }
246
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700247 void InvokeSumIntIntMethod(bool is_static)
Ian Rogersb726dcb2012-09-05 08:57:23 -0700248 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Brian Carlstromea46f952013-07-30 01:26:50 -0700249 mirror::ArtMethod* method;
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800250 mirror::Object* receiver;
Jeff Hao5d917302013-02-27 17:57:33 -0800251 DoCompile(method, receiver, is_static, "sum", "(II)I");
Elliott Hughes77405792012-03-15 15:22:12 -0700252
Jeff Hao5d917302013-02-27 17:57:33 -0800253 ArgArray arg_array(NULL, 0);
254 uint32_t* args = arg_array.GetArray();
Elliott Hughes77405792012-03-15 15:22:12 -0700255 JValue result;
Jeff Hao5d917302013-02-27 17:57:33 -0800256
257 if (!is_static) {
258 arg_array.Append(reinterpret_cast<uint32_t>(receiver));
259 args++;
260 }
261
262 arg_array.Append(0);
263 arg_array.Append(0);
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700264 result.SetI(-1);
Sebastien Hertzb95851f2013-03-29 10:36:40 +0100265 method->Invoke(Thread::Current(), arg_array.GetArray(), arg_array.GetNumBytes(), &result, 'I');
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700266 EXPECT_EQ(0, result.GetI());
Elliott Hughes77405792012-03-15 15:22:12 -0700267
Jeff Hao5d917302013-02-27 17:57:33 -0800268 args[0] = 1;
269 args[1] = 2;
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700270 result.SetI(0);
Sebastien Hertzb95851f2013-03-29 10:36:40 +0100271 method->Invoke(Thread::Current(), arg_array.GetArray(), arg_array.GetNumBytes(), &result, 'I');
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700272 EXPECT_EQ(3, result.GetI());
Elliott Hughes77405792012-03-15 15:22:12 -0700273
Jeff Hao5d917302013-02-27 17:57:33 -0800274 args[0] = -2;
275 args[1] = 5;
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700276 result.SetI(0);
Sebastien Hertzb95851f2013-03-29 10:36:40 +0100277 method->Invoke(Thread::Current(), arg_array.GetArray(), arg_array.GetNumBytes(), &result, 'I');
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700278 EXPECT_EQ(3, result.GetI());
Elliott Hughes77405792012-03-15 15:22:12 -0700279
Jeff Hao5d917302013-02-27 17:57:33 -0800280 args[0] = INT_MAX;
281 args[1] = INT_MIN;
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700282 result.SetI(1234);
Sebastien Hertzb95851f2013-03-29 10:36:40 +0100283 method->Invoke(Thread::Current(), arg_array.GetArray(), arg_array.GetNumBytes(), &result, 'I');
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700284 EXPECT_EQ(-1, result.GetI());
Elliott Hughes77405792012-03-15 15:22:12 -0700285
Jeff Hao5d917302013-02-27 17:57:33 -0800286 args[0] = INT_MAX;
287 args[1] = INT_MAX;
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700288 result.SetI(INT_MIN);
Sebastien Hertzb95851f2013-03-29 10:36:40 +0100289 method->Invoke(Thread::Current(), arg_array.GetArray(), arg_array.GetNumBytes(), &result, 'I');
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700290 EXPECT_EQ(-2, result.GetI());
Elliott Hughes77405792012-03-15 15:22:12 -0700291 }
292
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700293 void InvokeSumIntIntIntMethod(bool is_static)
Ian Rogersb726dcb2012-09-05 08:57:23 -0700294 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Brian Carlstromea46f952013-07-30 01:26:50 -0700295 mirror::ArtMethod* method;
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800296 mirror::Object* receiver;
Jeff Hao5d917302013-02-27 17:57:33 -0800297 DoCompile(method, receiver, is_static, "sum", "(III)I");
Elliott Hughes77405792012-03-15 15:22:12 -0700298
Jeff Hao5d917302013-02-27 17:57:33 -0800299 ArgArray arg_array(NULL, 0);
300 uint32_t* args = arg_array.GetArray();
Elliott Hughes77405792012-03-15 15:22:12 -0700301 JValue result;
Jeff Hao5d917302013-02-27 17:57:33 -0800302
303 if (!is_static) {
304 arg_array.Append(reinterpret_cast<uint32_t>(receiver));
305 args++;
306 }
307
308 arg_array.Append(0);
309 arg_array.Append(0);
310 arg_array.Append(0);
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700311 result.SetI(-1);
Sebastien Hertzb95851f2013-03-29 10:36:40 +0100312 method->Invoke(Thread::Current(), arg_array.GetArray(), arg_array.GetNumBytes(), &result, 'I');
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700313 EXPECT_EQ(0, result.GetI());
Elliott Hughes77405792012-03-15 15:22:12 -0700314
Jeff Hao5d917302013-02-27 17:57:33 -0800315 args[0] = 1;
316 args[1] = 2;
317 args[2] = 3;
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700318 result.SetI(0);
Sebastien Hertzb95851f2013-03-29 10:36:40 +0100319 method->Invoke(Thread::Current(), arg_array.GetArray(), arg_array.GetNumBytes(), &result, 'I');
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700320 EXPECT_EQ(6, result.GetI());
Elliott Hughes77405792012-03-15 15:22:12 -0700321
Jeff Hao5d917302013-02-27 17:57:33 -0800322 args[0] = -1;
323 args[1] = 2;
324 args[2] = -3;
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700325 result.SetI(0);
Sebastien Hertzb95851f2013-03-29 10:36:40 +0100326 method->Invoke(Thread::Current(), arg_array.GetArray(), arg_array.GetNumBytes(), &result, 'I');
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700327 EXPECT_EQ(-2, result.GetI());
Elliott Hughes77405792012-03-15 15:22:12 -0700328
Jeff Hao5d917302013-02-27 17:57:33 -0800329 args[0] = INT_MAX;
330 args[1] = INT_MIN;
331 args[2] = INT_MAX;
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700332 result.SetI(1234);
Sebastien Hertzb95851f2013-03-29 10:36:40 +0100333 method->Invoke(Thread::Current(), arg_array.GetArray(), arg_array.GetNumBytes(), &result, 'I');
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700334 EXPECT_EQ(2147483646, result.GetI());
Elliott Hughes77405792012-03-15 15:22:12 -0700335
Jeff Hao5d917302013-02-27 17:57:33 -0800336 args[0] = INT_MAX;
337 args[1] = INT_MAX;
338 args[2] = INT_MAX;
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700339 result.SetI(INT_MIN);
Sebastien Hertzb95851f2013-03-29 10:36:40 +0100340 method->Invoke(Thread::Current(), arg_array.GetArray(), arg_array.GetNumBytes(), &result, 'I');
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700341 EXPECT_EQ(2147483645, result.GetI());
Elliott Hughes77405792012-03-15 15:22:12 -0700342 }
343
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700344 void InvokeSumIntIntIntIntMethod(bool is_static)
Ian Rogersb726dcb2012-09-05 08:57:23 -0700345 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Brian Carlstromea46f952013-07-30 01:26:50 -0700346 mirror::ArtMethod* method;
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800347 mirror::Object* receiver;
Jeff Hao5d917302013-02-27 17:57:33 -0800348 DoCompile(method, receiver, is_static, "sum", "(IIII)I");
Elliott Hughes77405792012-03-15 15:22:12 -0700349
Jeff Hao5d917302013-02-27 17:57:33 -0800350 ArgArray arg_array(NULL, 0);
351 uint32_t* args = arg_array.GetArray();
Elliott Hughes77405792012-03-15 15:22:12 -0700352 JValue result;
Jeff Hao5d917302013-02-27 17:57:33 -0800353
354 if (!is_static) {
355 arg_array.Append(reinterpret_cast<uint32_t>(receiver));
356 args++;
357 }
358
359 arg_array.Append(0);
360 arg_array.Append(0);
361 arg_array.Append(0);
362 arg_array.Append(0);
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700363 result.SetI(-1);
Sebastien Hertzb95851f2013-03-29 10:36:40 +0100364 method->Invoke(Thread::Current(), arg_array.GetArray(), arg_array.GetNumBytes(), &result, 'I');
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700365 EXPECT_EQ(0, result.GetI());
Elliott Hughes77405792012-03-15 15:22:12 -0700366
Jeff Hao5d917302013-02-27 17:57:33 -0800367 args[0] = 1;
368 args[1] = 2;
369 args[2] = 3;
370 args[3] = 4;
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700371 result.SetI(0);
Sebastien Hertzb95851f2013-03-29 10:36:40 +0100372 method->Invoke(Thread::Current(), arg_array.GetArray(), arg_array.GetNumBytes(), &result, 'I');
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700373 EXPECT_EQ(10, result.GetI());
Elliott Hughes77405792012-03-15 15:22:12 -0700374
Jeff Hao5d917302013-02-27 17:57:33 -0800375 args[0] = -1;
376 args[1] = 2;
377 args[2] = -3;
378 args[3] = 4;
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700379 result.SetI(0);
Sebastien Hertzb95851f2013-03-29 10:36:40 +0100380 method->Invoke(Thread::Current(), arg_array.GetArray(), arg_array.GetNumBytes(), &result, 'I');
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700381 EXPECT_EQ(2, result.GetI());
Elliott Hughes77405792012-03-15 15:22:12 -0700382
Jeff Hao5d917302013-02-27 17:57:33 -0800383 args[0] = INT_MAX;
384 args[1] = INT_MIN;
385 args[2] = INT_MAX;
386 args[3] = INT_MIN;
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700387 result.SetI(1234);
Sebastien Hertzb95851f2013-03-29 10:36:40 +0100388 method->Invoke(Thread::Current(), arg_array.GetArray(), arg_array.GetNumBytes(), &result, 'I');
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700389 EXPECT_EQ(-2, result.GetI());
Elliott Hughes77405792012-03-15 15:22:12 -0700390
Jeff Hao5d917302013-02-27 17:57:33 -0800391 args[0] = INT_MAX;
392 args[1] = INT_MAX;
393 args[2] = INT_MAX;
394 args[3] = INT_MAX;
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700395 result.SetI(INT_MIN);
Sebastien Hertzb95851f2013-03-29 10:36:40 +0100396 method->Invoke(Thread::Current(), arg_array.GetArray(), arg_array.GetNumBytes(), &result, 'I');
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700397 EXPECT_EQ(-4, result.GetI());
Elliott Hughes77405792012-03-15 15:22:12 -0700398 }
399
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700400 void InvokeSumIntIntIntIntIntMethod(bool is_static)
Ian Rogersb726dcb2012-09-05 08:57:23 -0700401 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Brian Carlstromea46f952013-07-30 01:26:50 -0700402 mirror::ArtMethod* method;
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800403 mirror::Object* receiver;
Jeff Hao5d917302013-02-27 17:57:33 -0800404 DoCompile(method, receiver, is_static, "sum", "(IIIII)I");
Elliott Hughes77405792012-03-15 15:22:12 -0700405
Jeff Hao5d917302013-02-27 17:57:33 -0800406 ArgArray arg_array(NULL, 0);
407 uint32_t* args = arg_array.GetArray();
Elliott Hughes77405792012-03-15 15:22:12 -0700408 JValue result;
Jeff Hao5d917302013-02-27 17:57:33 -0800409
410 if (!is_static) {
411 arg_array.Append(reinterpret_cast<uint32_t>(receiver));
412 args++;
413 }
414
415 arg_array.Append(0);
416 arg_array.Append(0);
417 arg_array.Append(0);
418 arg_array.Append(0);
419 arg_array.Append(0);
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700420 result.SetI(-1.0);
Sebastien Hertzb95851f2013-03-29 10:36:40 +0100421 method->Invoke(Thread::Current(), arg_array.GetArray(), arg_array.GetNumBytes(), &result, 'I');
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700422 EXPECT_EQ(0, result.GetI());
Elliott Hughes77405792012-03-15 15:22:12 -0700423
Jeff Hao5d917302013-02-27 17:57:33 -0800424 args[0] = 1;
425 args[1] = 2;
426 args[2] = 3;
427 args[3] = 4;
428 args[4] = 5;
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700429 result.SetI(0);
Sebastien Hertzb95851f2013-03-29 10:36:40 +0100430 method->Invoke(Thread::Current(), arg_array.GetArray(), arg_array.GetNumBytes(), &result, 'I');
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700431 EXPECT_EQ(15, result.GetI());
Elliott Hughes77405792012-03-15 15:22:12 -0700432
Jeff Hao5d917302013-02-27 17:57:33 -0800433 args[0] = -1;
434 args[1] = 2;
435 args[2] = -3;
436 args[3] = 4;
437 args[4] = -5;
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700438 result.SetI(0);
Sebastien Hertzb95851f2013-03-29 10:36:40 +0100439 method->Invoke(Thread::Current(), arg_array.GetArray(), arg_array.GetNumBytes(), &result, 'I');
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700440 EXPECT_EQ(-3, result.GetI());
Elliott Hughes77405792012-03-15 15:22:12 -0700441
Jeff Hao5d917302013-02-27 17:57:33 -0800442 args[0] = INT_MAX;
443 args[1] = INT_MIN;
444 args[2] = INT_MAX;
445 args[3] = INT_MIN;
446 args[4] = INT_MAX;
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700447 result.SetI(1234);
Sebastien Hertzb95851f2013-03-29 10:36:40 +0100448 method->Invoke(Thread::Current(), arg_array.GetArray(), arg_array.GetNumBytes(), &result, 'I');
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700449 EXPECT_EQ(2147483645, result.GetI());
Elliott Hughes77405792012-03-15 15:22:12 -0700450
Jeff Hao5d917302013-02-27 17:57:33 -0800451 args[0] = INT_MAX;
452 args[1] = INT_MAX;
453 args[2] = INT_MAX;
454 args[3] = INT_MAX;
455 args[4] = INT_MAX;
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700456 result.SetI(INT_MIN);
Sebastien Hertzb95851f2013-03-29 10:36:40 +0100457 method->Invoke(Thread::Current(), arg_array.GetArray(), arg_array.GetNumBytes(), &result, 'I');
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700458 EXPECT_EQ(2147483643, result.GetI());
Elliott Hughes77405792012-03-15 15:22:12 -0700459 }
460
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700461 void InvokeSumDoubleDoubleMethod(bool is_static)
Ian Rogersb726dcb2012-09-05 08:57:23 -0700462 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Brian Carlstromea46f952013-07-30 01:26:50 -0700463 mirror::ArtMethod* method;
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800464 mirror::Object* receiver;
Jeff Hao5d917302013-02-27 17:57:33 -0800465 DoCompile(method, receiver, is_static, "sum", "(DD)D");
Elliott Hughes77405792012-03-15 15:22:12 -0700466
Jeff Hao5d917302013-02-27 17:57:33 -0800467 ArgArray arg_array(NULL, 0);
468 uint32_t* args = arg_array.GetArray();
469 JValue value;
470 JValue value2;
Elliott Hughes77405792012-03-15 15:22:12 -0700471 JValue result;
472
Jeff Hao5d917302013-02-27 17:57:33 -0800473 if (!is_static) {
474 arg_array.Append(reinterpret_cast<uint32_t>(receiver));
475 args++;
476 }
477
478 value.SetD(0.0);
479 value2.SetD(0.0);
480 arg_array.AppendWide(value.GetJ());
481 arg_array.AppendWide(value2.GetJ());
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700482 result.SetD(-1.0);
Sebastien Hertzb95851f2013-03-29 10:36:40 +0100483 method->Invoke(Thread::Current(), arg_array.GetArray(), arg_array.GetNumBytes(), &result, 'D');
Jeff Hao6474d192013-03-26 14:08:09 -0700484 EXPECT_EQ(0.0, result.GetD());
Elliott Hughes77405792012-03-15 15:22:12 -0700485
Jeff Hao5d917302013-02-27 17:57:33 -0800486 value.SetD(1.0);
487 value2.SetD(2.0);
488 args[0] = value.GetJ();
489 args[1] = value.GetJ() >> 32;
490 args[2] = value2.GetJ();
491 args[3] = value2.GetJ() >> 32;
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700492 result.SetD(0.0);
Sebastien Hertzb95851f2013-03-29 10:36:40 +0100493 method->Invoke(Thread::Current(), arg_array.GetArray(), arg_array.GetNumBytes(), &result, 'D');
Jeff Hao6474d192013-03-26 14:08:09 -0700494 EXPECT_EQ(3.0, result.GetD());
Elliott Hughes77405792012-03-15 15:22:12 -0700495
Jeff Hao5d917302013-02-27 17:57:33 -0800496 value.SetD(1.0);
497 value2.SetD(-2.0);
498 args[0] = value.GetJ();
499 args[1] = value.GetJ() >> 32;
500 args[2] = value2.GetJ();
501 args[3] = value2.GetJ() >> 32;
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700502 result.SetD(0.0);
Sebastien Hertzb95851f2013-03-29 10:36:40 +0100503 method->Invoke(Thread::Current(), arg_array.GetArray(), arg_array.GetNumBytes(), &result, 'D');
Jeff Hao6474d192013-03-26 14:08:09 -0700504 EXPECT_EQ(-1.0, result.GetD());
Elliott Hughes77405792012-03-15 15:22:12 -0700505
Jeff Hao5d917302013-02-27 17:57:33 -0800506 value.SetD(DBL_MAX);
507 value2.SetD(DBL_MIN);
508 args[0] = value.GetJ();
509 args[1] = value.GetJ() >> 32;
510 args[2] = value2.GetJ();
511 args[3] = value2.GetJ() >> 32;
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700512 result.SetD(0.0);
Sebastien Hertzb95851f2013-03-29 10:36:40 +0100513 method->Invoke(Thread::Current(), arg_array.GetArray(), arg_array.GetNumBytes(), &result, 'D');
Jeff Hao6474d192013-03-26 14:08:09 -0700514 EXPECT_EQ(1.7976931348623157e308, result.GetD());
Elliott Hughes77405792012-03-15 15:22:12 -0700515
Jeff Hao5d917302013-02-27 17:57:33 -0800516 value.SetD(DBL_MAX);
517 value2.SetD(DBL_MAX);
518 args[0] = value.GetJ();
519 args[1] = value.GetJ() >> 32;
520 args[2] = value2.GetJ();
521 args[3] = value2.GetJ() >> 32;
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700522 result.SetD(0.0);
Sebastien Hertzb95851f2013-03-29 10:36:40 +0100523 method->Invoke(Thread::Current(), arg_array.GetArray(), arg_array.GetNumBytes(), &result, 'D');
Jeff Hao6474d192013-03-26 14:08:09 -0700524 EXPECT_EQ(INFINITY, result.GetD());
Elliott Hughes77405792012-03-15 15:22:12 -0700525 }
526
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700527 void InvokeSumDoubleDoubleDoubleMethod(bool is_static)
Ian Rogersb726dcb2012-09-05 08:57:23 -0700528 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Brian Carlstromea46f952013-07-30 01:26:50 -0700529 mirror::ArtMethod* method;
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800530 mirror::Object* receiver;
Jeff Hao5d917302013-02-27 17:57:33 -0800531 DoCompile(method, receiver, is_static, "sum", "(DDD)D");
Elliott Hughes77405792012-03-15 15:22:12 -0700532
Jeff Hao5d917302013-02-27 17:57:33 -0800533 ArgArray arg_array(NULL, 0);
534 uint32_t* args = arg_array.GetArray();
535 JValue value;
536 JValue value2;
537 JValue value3;
Elliott Hughes77405792012-03-15 15:22:12 -0700538 JValue result;
539
Jeff Hao5d917302013-02-27 17:57:33 -0800540 if (!is_static) {
541 arg_array.Append(reinterpret_cast<uint32_t>(receiver));
542 args++;
543 }
544
545 value.SetD(0.0);
546 value2.SetD(0.0);
547 value3.SetD(0.0);
548 arg_array.AppendWide(value.GetJ());
549 arg_array.AppendWide(value2.GetJ());
550 arg_array.AppendWide(value3.GetJ());
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700551 result.SetD(-1.0);
Sebastien Hertzb95851f2013-03-29 10:36:40 +0100552 method->Invoke(Thread::Current(), arg_array.GetArray(), arg_array.GetNumBytes(), &result, 'D');
Jeff Hao6474d192013-03-26 14:08:09 -0700553 EXPECT_EQ(0.0, result.GetD());
Elliott Hughes77405792012-03-15 15:22:12 -0700554
Jeff Hao5d917302013-02-27 17:57:33 -0800555 value.SetD(1.0);
556 value2.SetD(2.0);
557 value3.SetD(3.0);
558 args[0] = value.GetJ();
559 args[1] = value.GetJ() >> 32;
560 args[2] = value2.GetJ();
561 args[3] = value2.GetJ() >> 32;
562 args[4] = value3.GetJ();
563 args[5] = value3.GetJ() >> 32;
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700564 result.SetD(0.0);
Sebastien Hertzb95851f2013-03-29 10:36:40 +0100565 method->Invoke(Thread::Current(), arg_array.GetArray(), arg_array.GetNumBytes(), &result, 'D');
Jeff Hao6474d192013-03-26 14:08:09 -0700566 EXPECT_EQ(6.0, result.GetD());
Elliott Hughes77405792012-03-15 15:22:12 -0700567
Jeff Hao5d917302013-02-27 17:57:33 -0800568 value.SetD(1.0);
569 value2.SetD(-2.0);
570 value3.SetD(3.0);
571 args[0] = value.GetJ();
572 args[1] = value.GetJ() >> 32;
573 args[2] = value2.GetJ();
574 args[3] = value2.GetJ() >> 32;
575 args[4] = value3.GetJ();
576 args[5] = value3.GetJ() >> 32;
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700577 result.SetD(0.0);
Sebastien Hertzb95851f2013-03-29 10:36:40 +0100578 method->Invoke(Thread::Current(), arg_array.GetArray(), arg_array.GetNumBytes(), &result, 'D');
Jeff Hao6474d192013-03-26 14:08:09 -0700579 EXPECT_EQ(2.0, result.GetD());
Elliott Hughes77405792012-03-15 15:22:12 -0700580 }
581
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700582 void InvokeSumDoubleDoubleDoubleDoubleMethod(bool is_static)
Ian Rogersb726dcb2012-09-05 08:57:23 -0700583 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Brian Carlstromea46f952013-07-30 01:26:50 -0700584 mirror::ArtMethod* method;
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800585 mirror::Object* receiver;
Jeff Hao5d917302013-02-27 17:57:33 -0800586 DoCompile(method, receiver, is_static, "sum", "(DDDD)D");
Elliott Hughes77405792012-03-15 15:22:12 -0700587
Jeff Hao5d917302013-02-27 17:57:33 -0800588 ArgArray arg_array(NULL, 0);
589 uint32_t* args = arg_array.GetArray();
590 JValue value;
591 JValue value2;
592 JValue value3;
593 JValue value4;
Elliott Hughes77405792012-03-15 15:22:12 -0700594 JValue result;
595
Jeff Hao5d917302013-02-27 17:57:33 -0800596 if (!is_static) {
597 arg_array.Append(reinterpret_cast<uint32_t>(receiver));
598 args++;
599 }
600
601 value.SetD(0.0);
602 value2.SetD(0.0);
603 value3.SetD(0.0);
604 value4.SetD(0.0);
605 arg_array.AppendWide(value.GetJ());
606 arg_array.AppendWide(value2.GetJ());
607 arg_array.AppendWide(value3.GetJ());
608 arg_array.AppendWide(value4.GetJ());
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700609 result.SetD(-1.0);
Sebastien Hertzb95851f2013-03-29 10:36:40 +0100610 method->Invoke(Thread::Current(), arg_array.GetArray(), arg_array.GetNumBytes(), &result, 'D');
Jeff Hao6474d192013-03-26 14:08:09 -0700611 EXPECT_EQ(0.0, result.GetD());
Elliott Hughes77405792012-03-15 15:22:12 -0700612
Jeff Hao5d917302013-02-27 17:57:33 -0800613 value.SetD(1.0);
614 value2.SetD(2.0);
615 value3.SetD(3.0);
616 value4.SetD(4.0);
617 args[0] = value.GetJ();
618 args[1] = value.GetJ() >> 32;
619 args[2] = value2.GetJ();
620 args[3] = value2.GetJ() >> 32;
621 args[4] = value3.GetJ();
622 args[5] = value3.GetJ() >> 32;
623 args[6] = value4.GetJ();
624 args[7] = value4.GetJ() >> 32;
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700625 result.SetD(0.0);
Sebastien Hertzb95851f2013-03-29 10:36:40 +0100626 method->Invoke(Thread::Current(), arg_array.GetArray(), arg_array.GetNumBytes(), &result, 'D');
Jeff Hao6474d192013-03-26 14:08:09 -0700627 EXPECT_EQ(10.0, result.GetD());
Elliott Hughes77405792012-03-15 15:22:12 -0700628
Jeff Hao5d917302013-02-27 17:57:33 -0800629 value.SetD(1.0);
630 value2.SetD(-2.0);
631 value3.SetD(3.0);
632 value4.SetD(-4.0);
633 args[0] = value.GetJ();
634 args[1] = value.GetJ() >> 32;
635 args[2] = value2.GetJ();
636 args[3] = value2.GetJ() >> 32;
637 args[4] = value3.GetJ();
638 args[5] = value3.GetJ() >> 32;
639 args[6] = value4.GetJ();
640 args[7] = value4.GetJ() >> 32;
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700641 result.SetD(0.0);
Sebastien Hertzb95851f2013-03-29 10:36:40 +0100642 method->Invoke(Thread::Current(), arg_array.GetArray(), arg_array.GetNumBytes(), &result, 'D');
Jeff Hao6474d192013-03-26 14:08:09 -0700643 EXPECT_EQ(-2.0, result.GetD());
Elliott Hughes77405792012-03-15 15:22:12 -0700644 }
645
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700646 void InvokeSumDoubleDoubleDoubleDoubleDoubleMethod(bool is_static)
Ian Rogersb726dcb2012-09-05 08:57:23 -0700647 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Brian Carlstromea46f952013-07-30 01:26:50 -0700648 mirror::ArtMethod* method;
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800649 mirror::Object* receiver;
Jeff Hao5d917302013-02-27 17:57:33 -0800650 DoCompile(method, receiver, is_static, "sum", "(DDDDD)D");
Elliott Hughes77405792012-03-15 15:22:12 -0700651
Jeff Hao5d917302013-02-27 17:57:33 -0800652 ArgArray arg_array(NULL, 0);
653 uint32_t* args = arg_array.GetArray();
654 JValue value;
655 JValue value2;
656 JValue value3;
657 JValue value4;
658 JValue value5;
Elliott Hughes77405792012-03-15 15:22:12 -0700659 JValue result;
660
Jeff Hao5d917302013-02-27 17:57:33 -0800661 if (!is_static) {
662 arg_array.Append(reinterpret_cast<uint32_t>(receiver));
663 args++;
664 }
665
666 value.SetD(0.0);
667 value2.SetD(0.0);
668 value3.SetD(0.0);
669 value4.SetD(0.0);
670 value5.SetD(0.0);
671 arg_array.AppendWide(value.GetJ());
672 arg_array.AppendWide(value2.GetJ());
673 arg_array.AppendWide(value3.GetJ());
674 arg_array.AppendWide(value4.GetJ());
675 arg_array.AppendWide(value5.GetJ());
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700676 result.SetD(-1.0);
Sebastien Hertzb95851f2013-03-29 10:36:40 +0100677 method->Invoke(Thread::Current(), arg_array.GetArray(), arg_array.GetNumBytes(), &result, 'D');
Jeff Hao6474d192013-03-26 14:08:09 -0700678 EXPECT_EQ(0.0, result.GetD());
Elliott Hughes77405792012-03-15 15:22:12 -0700679
Jeff Hao5d917302013-02-27 17:57:33 -0800680 value.SetD(1.0);
681 value2.SetD(2.0);
682 value3.SetD(3.0);
683 value4.SetD(4.0);
684 value5.SetD(5.0);
685 args[0] = value.GetJ();
686 args[1] = value.GetJ() >> 32;
687 args[2] = value2.GetJ();
688 args[3] = value2.GetJ() >> 32;
689 args[4] = value3.GetJ();
690 args[5] = value3.GetJ() >> 32;
691 args[6] = value4.GetJ();
692 args[7] = value4.GetJ() >> 32;
693 args[8] = value5.GetJ();
694 args[9] = value5.GetJ() >> 32;
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700695 result.SetD(0.0);
Sebastien Hertzb95851f2013-03-29 10:36:40 +0100696 method->Invoke(Thread::Current(), arg_array.GetArray(), arg_array.GetNumBytes(), &result, 'D');
Jeff Hao6474d192013-03-26 14:08:09 -0700697 EXPECT_EQ(15.0, result.GetD());
Elliott Hughes77405792012-03-15 15:22:12 -0700698
Jeff Hao5d917302013-02-27 17:57:33 -0800699 value.SetD(1.0);
700 value2.SetD(-2.0);
701 value3.SetD(3.0);
702 value4.SetD(-4.0);
703 value5.SetD(5.0);
704 args[0] = value.GetJ();
705 args[1] = value.GetJ() >> 32;
706 args[2] = value2.GetJ();
707 args[3] = value2.GetJ() >> 32;
708 args[4] = value3.GetJ();
709 args[5] = value3.GetJ() >> 32;
710 args[6] = value4.GetJ();
711 args[7] = value4.GetJ() >> 32;
712 args[8] = value5.GetJ();
713 args[9] = value5.GetJ() >> 32;
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700714 result.SetD(0.0);
Sebastien Hertzb95851f2013-03-29 10:36:40 +0100715 method->Invoke(Thread::Current(), arg_array.GetArray(), arg_array.GetNumBytes(), &result, 'D');
Jeff Hao6474d192013-03-26 14:08:09 -0700716 EXPECT_EQ(3.0, result.GetD());
Elliott Hughes77405792012-03-15 15:22:12 -0700717 }
718
Elliott Hughesa2501992011-08-26 19:39:54 -0700719 JavaVMExt* vm_;
Brian Carlstrom4d571432012-05-16 00:21:41 -0700720 JNIEnv* env_;
Elliott Hughes814e4032011-08-23 12:07:56 -0700721 jclass aioobe_;
Elliott Hughesb264f082012-04-06 17:10:10 -0700722 jclass ase_;
Elliott Hughesb465ab02011-08-24 11:21:21 -0700723 jclass sioobe_;
Elliott Hughes0c9cd562011-08-12 10:59:29 -0700724};
725
Elliott Hughes885c3bd2011-08-22 16:59:20 -0700726TEST_F(JniInternalTest, AllocObject) {
727 jclass c = env_->FindClass("java/lang/String");
728 ASSERT_TRUE(c != NULL);
729 jobject o = env_->AllocObject(c);
730 ASSERT_TRUE(o != NULL);
731
732 // We have an instance of the class we asked for...
733 ASSERT_TRUE(env_->IsInstanceOf(o, c));
734 // ...whose fields haven't been initialized because
735 // we didn't call a constructor.
736 ASSERT_EQ(0, env_->GetIntField(o, env_->GetFieldID(c, "count", "I")));
737 ASSERT_EQ(0, env_->GetIntField(o, env_->GetFieldID(c, "offset", "I")));
738 ASSERT_TRUE(env_->GetObjectField(o, env_->GetFieldID(c, "value", "[C")) == NULL);
739}
740
Elliott Hughesc7ac37f2011-08-12 12:21:58 -0700741TEST_F(JniInternalTest, GetVersion) {
742 ASSERT_EQ(JNI_VERSION_1_6, env_->GetVersion());
743}
744
Elliott Hughes0c9cd562011-08-12 10:59:29 -0700745#define EXPECT_CLASS_FOUND(NAME) \
Elliott Hughesbd935992011-08-22 11:59:34 -0700746 EXPECT_TRUE(env_->FindClass(NAME) != NULL); \
747 EXPECT_FALSE(env_->ExceptionCheck())
Elliott Hughes0c9cd562011-08-12 10:59:29 -0700748
749#define EXPECT_CLASS_NOT_FOUND(NAME) \
Elliott Hughesbd935992011-08-22 11:59:34 -0700750 EXPECT_TRUE(env_->FindClass(NAME) == NULL); \
751 EXPECT_TRUE(env_->ExceptionCheck()); \
752 env_->ExceptionClear()
Elliott Hughes0c9cd562011-08-12 10:59:29 -0700753
754TEST_F(JniInternalTest, FindClass) {
Elliott Hughes0c9cd562011-08-12 10:59:29 -0700755 // Reference types...
Elliott Hughes0c9cd562011-08-12 10:59:29 -0700756 EXPECT_CLASS_FOUND("java/lang/String");
Elliott Hughes0c9cd562011-08-12 10:59:29 -0700757 // ...for arrays too, where you must include "L;".
758 EXPECT_CLASS_FOUND("[Ljava/lang/String;");
Elliott Hughes3f6635a2012-06-19 13:37:49 -0700759 // Primitive arrays are okay too, if the primitive type is valid.
760 EXPECT_CLASS_FOUND("[C");
Elliott Hughesa2501992011-08-26 19:39:54 -0700761
Elliott Hughesb264f082012-04-06 17:10:10 -0700762 {
Elliott Hughesb264f082012-04-06 17:10:10 -0700763 // We support . as well as / for compatibility, if -Xcheck:jni is off.
Elliott Hughes3f6635a2012-06-19 13:37:49 -0700764 CheckJniAbortCatcher check_jni_abort_catcher;
Elliott Hughesb264f082012-04-06 17:10:10 -0700765 EXPECT_CLASS_FOUND("java.lang.String");
Elliott Hughes56ef0422012-06-19 14:35:04 -0700766 check_jni_abort_catcher.Check("illegal class name 'java.lang.String'");
Elliott Hughesb264f082012-04-06 17:10:10 -0700767 EXPECT_CLASS_NOT_FOUND("Ljava.lang.String;");
Elliott Hughes56ef0422012-06-19 14:35:04 -0700768 check_jni_abort_catcher.Check("illegal class name 'Ljava.lang.String;'");
Elliott Hughesb264f082012-04-06 17:10:10 -0700769 EXPECT_CLASS_FOUND("[Ljava.lang.String;");
Elliott Hughes56ef0422012-06-19 14:35:04 -0700770 check_jni_abort_catcher.Check("illegal class name '[Ljava.lang.String;'");
Elliott Hughesb264f082012-04-06 17:10:10 -0700771 EXPECT_CLASS_NOT_FOUND("[java.lang.String");
Elliott Hughes56ef0422012-06-19 14:35:04 -0700772 check_jni_abort_catcher.Check("illegal class name '[java.lang.String'");
Elliott Hughesb264f082012-04-06 17:10:10 -0700773
774 // You can't include the "L;" in a JNI class descriptor.
775 EXPECT_CLASS_NOT_FOUND("Ljava/lang/String;");
Elliott Hughes56ef0422012-06-19 14:35:04 -0700776 check_jni_abort_catcher.Check("illegal class name 'Ljava/lang/String;'");
Elliott Hughes3f6635a2012-06-19 13:37:49 -0700777
Elliott Hughesb264f082012-04-06 17:10:10 -0700778 // But you must include it for an array of any reference type.
779 EXPECT_CLASS_NOT_FOUND("[java/lang/String");
Elliott Hughes56ef0422012-06-19 14:35:04 -0700780 check_jni_abort_catcher.Check("illegal class name '[java/lang/String'");
Elliott Hughes3f6635a2012-06-19 13:37:49 -0700781
782 EXPECT_CLASS_NOT_FOUND("[K");
Elliott Hughes56ef0422012-06-19 14:35:04 -0700783 check_jni_abort_catcher.Check("illegal class name '[K'");
Elliott Hughesb264f082012-04-06 17:10:10 -0700784 }
Elliott Hughesa2501992011-08-26 19:39:54 -0700785
Elliott Hughes0c9cd562011-08-12 10:59:29 -0700786 // But primitive types aren't allowed...
787 EXPECT_CLASS_NOT_FOUND("C");
788 EXPECT_CLASS_NOT_FOUND("K");
789}
790
Elliott Hughescdf53122011-08-19 15:46:09 -0700791#define EXPECT_EXCEPTION(exception_class) \
792 do { \
793 EXPECT_TRUE(env_->ExceptionCheck()); \
794 jthrowable exception = env_->ExceptionOccurred(); \
795 EXPECT_NE(static_cast<jthrowable>(NULL), exception); \
Elliott Hughescdf53122011-08-19 15:46:09 -0700796 env_->ExceptionClear(); \
Elliott Hughesa2501992011-08-26 19:39:54 -0700797 EXPECT_TRUE(env_->IsInstanceOf(exception, exception_class)); \
Elliott Hughescdf53122011-08-19 15:46:09 -0700798 } while (false)
799
800TEST_F(JniInternalTest, GetFieldID) {
801 jclass jlnsfe = env_->FindClass("java/lang/NoSuchFieldError");
802 ASSERT_TRUE(jlnsfe != NULL);
803 jclass c = env_->FindClass("java/lang/String");
804 ASSERT_TRUE(c != NULL);
805
806 // Wrong type.
807 jfieldID fid = env_->GetFieldID(c, "count", "J");
808 EXPECT_EQ(static_cast<jfieldID>(NULL), fid);
809 EXPECT_EXCEPTION(jlnsfe);
810
Ian Rogersb17d08b2011-09-02 16:16:49 -0700811 // Wrong type where type doesn't exist.
812 fid = env_->GetFieldID(c, "count", "Lrod/jane/freddy;");
813 EXPECT_EQ(static_cast<jfieldID>(NULL), fid);
814 EXPECT_EXCEPTION(jlnsfe);
815
Elliott Hughescdf53122011-08-19 15:46:09 -0700816 // Wrong name.
817 fid = env_->GetFieldID(c, "Count", "I");
818 EXPECT_EQ(static_cast<jfieldID>(NULL), fid);
819 EXPECT_EXCEPTION(jlnsfe);
820
821 // Good declared field lookup.
822 fid = env_->GetFieldID(c, "count", "I");
823 EXPECT_NE(static_cast<jfieldID>(NULL), fid);
824 EXPECT_TRUE(fid != NULL);
825 EXPECT_FALSE(env_->ExceptionCheck());
826
827 // Good superclass field lookup.
828 c = env_->FindClass("java/lang/StringBuilder");
829 fid = env_->GetFieldID(c, "count", "I");
830 EXPECT_NE(static_cast<jfieldID>(NULL), fid);
831 EXPECT_TRUE(fid != NULL);
832 EXPECT_FALSE(env_->ExceptionCheck());
833
834 // Not instance.
835 fid = env_->GetFieldID(c, "CASE_INSENSITIVE_ORDER", "Ljava/util/Comparator;");
836 EXPECT_EQ(static_cast<jfieldID>(NULL), fid);
837 EXPECT_EXCEPTION(jlnsfe);
838}
839
840TEST_F(JniInternalTest, GetStaticFieldID) {
841 jclass jlnsfe = env_->FindClass("java/lang/NoSuchFieldError");
842 ASSERT_TRUE(jlnsfe != NULL);
843 jclass c = env_->FindClass("java/lang/String");
844 ASSERT_TRUE(c != NULL);
845
846 // Wrong type.
847 jfieldID fid = env_->GetStaticFieldID(c, "CASE_INSENSITIVE_ORDER", "J");
848 EXPECT_EQ(static_cast<jfieldID>(NULL), fid);
849 EXPECT_EXCEPTION(jlnsfe);
850
Ian Rogersb17d08b2011-09-02 16:16:49 -0700851 // Wrong type where type doesn't exist.
852 fid = env_->GetStaticFieldID(c, "CASE_INSENSITIVE_ORDER", "Lrod/jane/freddy;");
853 EXPECT_EQ(static_cast<jfieldID>(NULL), fid);
854 EXPECT_EXCEPTION(jlnsfe);
855
Elliott Hughescdf53122011-08-19 15:46:09 -0700856 // Wrong name.
857 fid = env_->GetStaticFieldID(c, "cASE_INSENSITIVE_ORDER", "Ljava/util/Comparator;");
858 EXPECT_EQ(static_cast<jfieldID>(NULL), fid);
859 EXPECT_EXCEPTION(jlnsfe);
860
861 // Good declared field lookup.
862 fid = env_->GetStaticFieldID(c, "CASE_INSENSITIVE_ORDER", "Ljava/util/Comparator;");
863 EXPECT_NE(static_cast<jfieldID>(NULL), fid);
864 EXPECT_TRUE(fid != NULL);
865 EXPECT_FALSE(env_->ExceptionCheck());
866
867 // Not static.
868 fid = env_->GetStaticFieldID(c, "count", "I");
869 EXPECT_EQ(static_cast<jfieldID>(NULL), fid);
870 EXPECT_EXCEPTION(jlnsfe);
871}
872
Ian Rogers4dd71f12011-08-16 14:16:02 -0700873TEST_F(JniInternalTest, GetMethodID) {
874 jclass jlobject = env_->FindClass("java/lang/Object");
875 jclass jlstring = env_->FindClass("java/lang/String");
876 jclass jlnsme = env_->FindClass("java/lang/NoSuchMethodError");
877
878 // Sanity check that no exceptions are pending
Elliott Hughescdf53122011-08-19 15:46:09 -0700879 ASSERT_FALSE(env_->ExceptionCheck());
Ian Rogers4dd71f12011-08-16 14:16:02 -0700880
881 // Check that java.lang.Object.foo() doesn't exist and NoSuchMethodError is
882 // a pending exception
883 jmethodID method = env_->GetMethodID(jlobject, "foo", "()V");
884 EXPECT_EQ(static_cast<jmethodID>(NULL), method);
Elliott Hughescdf53122011-08-19 15:46:09 -0700885 EXPECT_EXCEPTION(jlnsme);
Ian Rogers4dd71f12011-08-16 14:16:02 -0700886
887 // Check that java.lang.Object.equals() does exist
Ian Rogers4dd71f12011-08-16 14:16:02 -0700888 method = env_->GetMethodID(jlobject, "equals", "(Ljava/lang/Object;)Z");
889 EXPECT_NE(static_cast<jmethodID>(NULL), method);
890 EXPECT_FALSE(env_->ExceptionCheck());
Ian Rogers4dd71f12011-08-16 14:16:02 -0700891
892 // Check that GetMethodID for java.lang.String.valueOf(int) fails as the
893 // method is static
894 method = env_->GetMethodID(jlstring, "valueOf", "(I)Ljava/lang/String;");
895 EXPECT_EQ(static_cast<jmethodID>(NULL), method);
Elliott Hughescdf53122011-08-19 15:46:09 -0700896 EXPECT_EXCEPTION(jlnsme);
Brian Carlstromea46f952013-07-30 01:26:50 -0700897
898 // Check that GetMethodID for java.lang.NoSuchMethodError.<init>(String) finds the constructor
899 method = env_->GetMethodID(jlnsme, "<init>", "(Ljava/lang/String;)V");
900 EXPECT_NE(static_cast<jmethodID>(NULL), method);
901 EXPECT_FALSE(env_->ExceptionCheck());
Ian Rogers4dd71f12011-08-16 14:16:02 -0700902}
903
904TEST_F(JniInternalTest, GetStaticMethodID) {
905 jclass jlobject = env_->FindClass("java/lang/Object");
906 jclass jlnsme = env_->FindClass("java/lang/NoSuchMethodError");
907
908 // Sanity check that no exceptions are pending
Elliott Hughescdf53122011-08-19 15:46:09 -0700909 ASSERT_FALSE(env_->ExceptionCheck());
Ian Rogers4dd71f12011-08-16 14:16:02 -0700910
911 // Check that java.lang.Object.foo() doesn't exist and NoSuchMethodError is
912 // a pending exception
913 jmethodID method = env_->GetStaticMethodID(jlobject, "foo", "()V");
914 EXPECT_EQ(static_cast<jmethodID>(NULL), method);
Elliott Hughescdf53122011-08-19 15:46:09 -0700915 EXPECT_EXCEPTION(jlnsme);
Ian Rogers4dd71f12011-08-16 14:16:02 -0700916
917 // Check that GetStaticMethodID for java.lang.Object.equals(Object) fails as
918 // the method is not static
919 method = env_->GetStaticMethodID(jlobject, "equals", "(Ljava/lang/Object;)Z");
920 EXPECT_EQ(static_cast<jmethodID>(NULL), method);
Elliott Hughescdf53122011-08-19 15:46:09 -0700921 EXPECT_EXCEPTION(jlnsme);
Ian Rogers4dd71f12011-08-16 14:16:02 -0700922
923 // Check that java.lang.String.valueOf(int) does exist
Ian Rogers4dd71f12011-08-16 14:16:02 -0700924 jclass jlstring = env_->FindClass("java/lang/String");
925 method = env_->GetStaticMethodID(jlstring, "valueOf",
926 "(I)Ljava/lang/String;");
927 EXPECT_NE(static_cast<jmethodID>(NULL), method);
928 EXPECT_FALSE(env_->ExceptionCheck());
Ian Rogers4dd71f12011-08-16 14:16:02 -0700929}
930
Elliott Hughescdf53122011-08-19 15:46:09 -0700931TEST_F(JniInternalTest, FromReflectedField_ToReflectedField) {
932 jclass jlrField = env_->FindClass("java/lang/reflect/Field");
933 jclass c = env_->FindClass("java/lang/String");
934 ASSERT_TRUE(c != NULL);
935 jfieldID fid = env_->GetFieldID(c, "count", "I");
936 ASSERT_TRUE(fid != NULL);
937 // Turn the fid into a java.lang.reflect.Field...
938 jobject field = env_->ToReflectedField(c, fid, JNI_FALSE);
939 ASSERT_TRUE(c != NULL);
940 ASSERT_TRUE(env_->IsInstanceOf(field, jlrField));
941 // ...and back again.
942 jfieldID fid2 = env_->FromReflectedField(field);
943 ASSERT_TRUE(fid2 != NULL);
Brian Carlstromea46f952013-07-30 01:26:50 -0700944 // Make sure we can actually use it.
945 jstring s = env_->NewStringUTF("poop");
946 ASSERT_EQ(4, env_->GetIntField(s, fid2));
Elliott Hughescdf53122011-08-19 15:46:09 -0700947}
948
949TEST_F(JniInternalTest, FromReflectedMethod_ToReflectedMethod) {
950 jclass jlrMethod = env_->FindClass("java/lang/reflect/Method");
951 jclass c = env_->FindClass("java/lang/String");
952 ASSERT_TRUE(c != NULL);
953 jmethodID mid = env_->GetMethodID(c, "length", "()I");
954 ASSERT_TRUE(mid != NULL);
955 // Turn the mid into a java.lang.reflect.Method...
956 jobject method = env_->ToReflectedMethod(c, mid, JNI_FALSE);
957 ASSERT_TRUE(c != NULL);
958 ASSERT_TRUE(env_->IsInstanceOf(method, jlrMethod));
959 // ...and back again.
960 jmethodID mid2 = env_->FromReflectedMethod(method);
961 ASSERT_TRUE(mid2 != NULL);
Brian Carlstromea46f952013-07-30 01:26:50 -0700962 // Make sure we can actually use it.
963 jstring s = env_->NewStringUTF("poop");
964 // TODO: this should return 4, but the runtime skips the method
965 // invoke because the runtime isn't started. In the future it would
966 // be nice to use interpretter for things like this. This still does
967 // validate that we have a sane jmethodID value.
968 ASSERT_EQ(0, env_->CallIntMethod(s, mid2));
Elliott Hughescdf53122011-08-19 15:46:09 -0700969}
970
Elliott Hughes5174fe62011-08-23 15:12:35 -0700971void BogusMethod() {
972 // You can't pass NULL function pointers to RegisterNatives.
973}
974
Ian Rogers4dd71f12011-08-16 14:16:02 -0700975TEST_F(JniInternalTest, RegisterNatives) {
976 jclass jlobject = env_->FindClass("java/lang/Object");
977 jclass jlnsme = env_->FindClass("java/lang/NoSuchMethodError");
978
979 // Sanity check that no exceptions are pending
Elliott Hughescdf53122011-08-19 15:46:09 -0700980 ASSERT_FALSE(env_->ExceptionCheck());
Ian Rogers4dd71f12011-08-16 14:16:02 -0700981
982 // Check that registering to a non-existent java.lang.Object.foo() causes a
983 // NoSuchMethodError
984 {
Elliott Hughesb25c3f62012-03-26 16:35:06 -0700985 JNINativeMethod methods[] = { { "foo", "()V", NULL } };
Ian Rogers4dd71f12011-08-16 14:16:02 -0700986 env_->RegisterNatives(jlobject, methods, 1);
987 }
Elliott Hughescdf53122011-08-19 15:46:09 -0700988 EXPECT_EXCEPTION(jlnsme);
Ian Rogers4dd71f12011-08-16 14:16:02 -0700989
990 // Check that registering non-native methods causes a NoSuchMethodError
991 {
Elliott Hughesb25c3f62012-03-26 16:35:06 -0700992 JNINativeMethod methods[] = { { "equals", "(Ljava/lang/Object;)Z", NULL } };
Ian Rogers4dd71f12011-08-16 14:16:02 -0700993 env_->RegisterNatives(jlobject, methods, 1);
994 }
Elliott Hughescdf53122011-08-19 15:46:09 -0700995 EXPECT_EXCEPTION(jlnsme);
Ian Rogers4dd71f12011-08-16 14:16:02 -0700996
997 // Check that registering native methods is successful
998 {
Elliott Hughesb25c3f62012-03-26 16:35:06 -0700999 JNINativeMethod methods[] = { { "notify", "()V", reinterpret_cast<void*>(BogusMethod) } };
Ian Rogers4dd71f12011-08-16 14:16:02 -07001000 env_->RegisterNatives(jlobject, methods, 1);
1001 }
1002 EXPECT_FALSE(env_->ExceptionCheck());
Elliott Hughes5174fe62011-08-23 15:12:35 -07001003
1004 env_->UnregisterNatives(jlobject);
Ian Rogers4dd71f12011-08-16 14:16:02 -07001005}
1006
Brian Carlstromea46f952013-07-30 01:26:50 -07001007#define EXPECT_PRIMITIVE_ARRAY(new_fn, \
1008 get_region_fn, \
1009 set_region_fn, \
1010 get_elements_fn, \
1011 release_elements_fn, \
1012 scalar_type, \
1013 expected_class_descriptor) \
Elliott Hughes814e4032011-08-23 12:07:56 -07001014 jsize size = 4; \
1015 /* Allocate an array and check it has the right type and length. */ \
1016 scalar_type ## Array a = env_->new_fn(size); \
1017 EXPECT_TRUE(a != NULL); \
1018 EXPECT_TRUE(env_->IsInstanceOf(a, env_->FindClass(expected_class_descriptor))); \
1019 EXPECT_EQ(size, env_->GetArrayLength(a)); \
1020 /* AIOOBE for negative start offset. */ \
1021 env_->get_region_fn(a, -1, 1, NULL); \
1022 EXPECT_EXCEPTION(aioobe_); \
1023 env_->set_region_fn(a, -1, 1, NULL); \
1024 EXPECT_EXCEPTION(aioobe_); \
1025 /* AIOOBE for negative length. */ \
1026 env_->get_region_fn(a, 0, -1, NULL); \
1027 EXPECT_EXCEPTION(aioobe_); \
1028 env_->set_region_fn(a, 0, -1, NULL); \
1029 EXPECT_EXCEPTION(aioobe_); \
1030 /* AIOOBE for buffer overrun. */ \
1031 env_->get_region_fn(a, size - 1, size, NULL); \
1032 EXPECT_EXCEPTION(aioobe_); \
1033 env_->set_region_fn(a, size - 1, size, NULL); \
1034 EXPECT_EXCEPTION(aioobe_); \
1035 /* Prepare a couple of buffers. */ \
Elliott Hughesee0fa762012-03-26 17:12:41 -07001036 UniquePtr<scalar_type[]> src_buf(new scalar_type[size]); \
1037 UniquePtr<scalar_type[]> dst_buf(new scalar_type[size]); \
Elliott Hughes814e4032011-08-23 12:07:56 -07001038 for (jsize i = 0; i < size; ++i) { src_buf[i] = scalar_type(i); } \
1039 for (jsize i = 0; i < size; ++i) { dst_buf[i] = scalar_type(-1); } \
1040 /* Copy all of src_buf onto the heap. */ \
Elliott Hughesee0fa762012-03-26 17:12:41 -07001041 env_->set_region_fn(a, 0, size, &src_buf[0]); \
Elliott Hughes814e4032011-08-23 12:07:56 -07001042 /* Copy back only part. */ \
1043 env_->get_region_fn(a, 1, size - 2, &dst_buf[1]); \
Brian Carlstromea46f952013-07-30 01:26:50 -07001044 EXPECT_NE(memcmp(&src_buf[0], &dst_buf[0], size * sizeof(scalar_type)), 0) \
1045 << "short copy equal"; \
Elliott Hughes814e4032011-08-23 12:07:56 -07001046 /* Copy the missing pieces. */ \
Elliott Hughesee0fa762012-03-26 17:12:41 -07001047 env_->get_region_fn(a, 0, 1, &dst_buf[0]); \
Elliott Hughes814e4032011-08-23 12:07:56 -07001048 env_->get_region_fn(a, size - 1, 1, &dst_buf[size - 1]); \
Brian Carlstromea46f952013-07-30 01:26:50 -07001049 EXPECT_EQ(memcmp(&src_buf[0], &dst_buf[0], size * sizeof(scalar_type)), 0) \
1050 << "fixed copy not equal"; \
Elliott Hughes814e4032011-08-23 12:07:56 -07001051 /* Copy back the whole array. */ \
Elliott Hughesee0fa762012-03-26 17:12:41 -07001052 env_->get_region_fn(a, 0, size, &dst_buf[0]); \
Brian Carlstromea46f952013-07-30 01:26:50 -07001053 EXPECT_EQ(memcmp(&src_buf[0], &dst_buf[0], size * sizeof(scalar_type)), 0) \
1054 << "full copy not equal"; \
Elliott Hughes75770752011-08-24 17:52:38 -07001055 /* GetPrimitiveArrayCritical */ \
1056 void* v = env_->GetPrimitiveArrayCritical(a, NULL); \
Brian Carlstromea46f952013-07-30 01:26:50 -07001057 EXPECT_EQ(memcmp(&src_buf[0], v, size * sizeof(scalar_type)), 0) \
1058 << "GetPrimitiveArrayCritical not equal"; \
Elliott Hughes75770752011-08-24 17:52:38 -07001059 env_->ReleasePrimitiveArrayCritical(a, v, 0); \
1060 /* GetXArrayElements */ \
1061 scalar_type* xs = env_->get_elements_fn(a, NULL); \
Brian Carlstromea46f952013-07-30 01:26:50 -07001062 EXPECT_EQ(memcmp(&src_buf[0], xs, size * sizeof(scalar_type)), 0) \
1063 << # get_elements_fn " not equal"; \
Elliott Hughes75770752011-08-24 17:52:38 -07001064 env_->release_elements_fn(a, xs, 0); \
1065 EXPECT_EQ(reinterpret_cast<uintptr_t>(v), reinterpret_cast<uintptr_t>(xs))
Elliott Hughesbd935992011-08-22 11:59:34 -07001066
Elliott Hughes814e4032011-08-23 12:07:56 -07001067TEST_F(JniInternalTest, BooleanArrays) {
Brian Carlstromea46f952013-07-30 01:26:50 -07001068 EXPECT_PRIMITIVE_ARRAY(NewBooleanArray, GetBooleanArrayRegion, SetBooleanArrayRegion,
1069 GetBooleanArrayElements, ReleaseBooleanArrayElements, jboolean, "[Z");
Elliott Hughes814e4032011-08-23 12:07:56 -07001070}
1071TEST_F(JniInternalTest, ByteArrays) {
Brian Carlstromea46f952013-07-30 01:26:50 -07001072 EXPECT_PRIMITIVE_ARRAY(NewByteArray, GetByteArrayRegion, SetByteArrayRegion,
1073 GetByteArrayElements, ReleaseByteArrayElements, jbyte, "[B");
Elliott Hughes814e4032011-08-23 12:07:56 -07001074}
1075TEST_F(JniInternalTest, CharArrays) {
Brian Carlstromea46f952013-07-30 01:26:50 -07001076 EXPECT_PRIMITIVE_ARRAY(NewCharArray, GetCharArrayRegion, SetCharArrayRegion,
1077 GetCharArrayElements, ReleaseCharArrayElements, jchar, "[C");
Elliott Hughes814e4032011-08-23 12:07:56 -07001078}
1079TEST_F(JniInternalTest, DoubleArrays) {
Brian Carlstromea46f952013-07-30 01:26:50 -07001080 EXPECT_PRIMITIVE_ARRAY(NewDoubleArray, GetDoubleArrayRegion, SetDoubleArrayRegion,
1081 GetDoubleArrayElements, ReleaseDoubleArrayElements, jdouble, "[D");
Elliott Hughes814e4032011-08-23 12:07:56 -07001082}
1083TEST_F(JniInternalTest, FloatArrays) {
Brian Carlstromea46f952013-07-30 01:26:50 -07001084 EXPECT_PRIMITIVE_ARRAY(NewFloatArray, GetFloatArrayRegion, SetFloatArrayRegion,
1085 GetFloatArrayElements, ReleaseFloatArrayElements, jfloat, "[F");
Elliott Hughes814e4032011-08-23 12:07:56 -07001086}
1087TEST_F(JniInternalTest, IntArrays) {
Brian Carlstromea46f952013-07-30 01:26:50 -07001088 EXPECT_PRIMITIVE_ARRAY(NewIntArray, GetIntArrayRegion, SetIntArrayRegion,
1089 GetIntArrayElements, ReleaseIntArrayElements, jint, "[I");
Elliott Hughes814e4032011-08-23 12:07:56 -07001090}
1091TEST_F(JniInternalTest, LongArrays) {
Brian Carlstromea46f952013-07-30 01:26:50 -07001092 EXPECT_PRIMITIVE_ARRAY(NewLongArray, GetLongArrayRegion, SetLongArrayRegion,
1093 GetLongArrayElements, ReleaseLongArrayElements, jlong, "[J");
Elliott Hughes814e4032011-08-23 12:07:56 -07001094}
1095TEST_F(JniInternalTest, ShortArrays) {
Brian Carlstromea46f952013-07-30 01:26:50 -07001096 EXPECT_PRIMITIVE_ARRAY(NewShortArray, GetShortArrayRegion, SetShortArrayRegion,
1097 GetShortArrayElements, ReleaseShortArrayElements, jshort, "[S");
Elliott Hughesd8ddfd52011-08-15 14:32:53 -07001098}
1099
Elliott Hughesf2682d52011-08-15 16:37:04 -07001100TEST_F(JniInternalTest, NewObjectArray) {
1101 // TODO: death tests for negative array sizes.
1102
Elliott Hughesf2682d52011-08-15 16:37:04 -07001103 // TODO: check non-NULL initial elements.
1104
Elliott Hughesbd935992011-08-22 11:59:34 -07001105 jclass element_class = env_->FindClass("java/lang/String");
1106 ASSERT_TRUE(element_class != NULL);
1107 jclass array_class = env_->FindClass("[Ljava/lang/String;");
1108 ASSERT_TRUE(array_class != NULL);
Elliott Hughesf2682d52011-08-15 16:37:04 -07001109
Elliott Hughesbd935992011-08-22 11:59:34 -07001110 jobjectArray a;
Elliott Hughesf2682d52011-08-15 16:37:04 -07001111
Elliott Hughesbd935992011-08-22 11:59:34 -07001112 a = env_->NewObjectArray(0, element_class, NULL);
1113 EXPECT_TRUE(a != NULL);
1114 EXPECT_TRUE(env_->IsInstanceOf(a, array_class));
1115 EXPECT_EQ(0, env_->GetArrayLength(a));
1116
1117 a = env_->NewObjectArray(1, element_class, NULL);
1118 EXPECT_TRUE(a != NULL);
1119 EXPECT_TRUE(env_->IsInstanceOf(a, array_class));
1120 EXPECT_EQ(1, env_->GetArrayLength(a));
Elliott Hughes75770752011-08-24 17:52:38 -07001121 EXPECT_TRUE(env_->IsSameObject(env_->GetObjectArrayElement(a, 0), NULL));
1122
1123 jstring s = env_->NewStringUTF("poop");
1124 a = env_->NewObjectArray(2, element_class, s);
1125 EXPECT_TRUE(a != NULL);
1126 EXPECT_TRUE(env_->IsInstanceOf(a, array_class));
1127 EXPECT_EQ(2, env_->GetArrayLength(a));
1128 EXPECT_TRUE(env_->IsSameObject(env_->GetObjectArrayElement(a, 0), s));
1129 EXPECT_TRUE(env_->IsSameObject(env_->GetObjectArrayElement(a, 1), s));
Elliott Hughesbd935992011-08-22 11:59:34 -07001130}
1131
1132TEST_F(JniInternalTest, GetArrayLength) {
1133 // Already tested in NewObjectArray/NewPrimitiveArray.
Elliott Hughes8a26c5c2011-08-15 18:35:43 -07001134}
1135
Elliott Hughes37f7a402011-08-22 18:56:01 -07001136TEST_F(JniInternalTest, GetObjectClass) {
1137 jclass string_class = env_->FindClass("java/lang/String");
1138 ASSERT_TRUE(string_class != NULL);
1139 jclass class_class = env_->FindClass("java/lang/Class");
1140 ASSERT_TRUE(class_class != NULL);
1141
1142 jstring s = env_->NewStringUTF("poop");
1143 jclass c = env_->GetObjectClass(s);
1144 ASSERT_TRUE(env_->IsSameObject(string_class, c));
1145
1146 jclass c2 = env_->GetObjectClass(c);
1147 ASSERT_TRUE(env_->IsSameObject(class_class, env_->GetObjectClass(c2)));
1148}
1149
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001150TEST_F(JniInternalTest, GetSuperclass) {
1151 jclass object_class = env_->FindClass("java/lang/Object");
1152 ASSERT_TRUE(object_class != NULL);
1153 jclass string_class = env_->FindClass("java/lang/String");
1154 ASSERT_TRUE(string_class != NULL);
Ian Rogersdc180202012-01-29 14:47:29 -08001155 jclass runnable_interface = env_->FindClass("java/lang/Runnable");
1156 ASSERT_TRUE(runnable_interface != NULL);
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001157 ASSERT_TRUE(env_->IsSameObject(object_class, env_->GetSuperclass(string_class)));
1158 ASSERT_TRUE(env_->GetSuperclass(object_class) == NULL);
Ian Rogersdc180202012-01-29 14:47:29 -08001159 ASSERT_TRUE(env_->IsSameObject(object_class, env_->GetSuperclass(runnable_interface)));
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001160}
1161
Elliott Hughes37f7a402011-08-22 18:56:01 -07001162TEST_F(JniInternalTest, IsAssignableFrom) {
1163 jclass object_class = env_->FindClass("java/lang/Object");
1164 ASSERT_TRUE(object_class != NULL);
1165 jclass string_class = env_->FindClass("java/lang/String");
1166 ASSERT_TRUE(string_class != NULL);
1167
1168 ASSERT_TRUE(env_->IsAssignableFrom(object_class, string_class));
1169 ASSERT_FALSE(env_->IsAssignableFrom(string_class, object_class));
1170}
1171
Elliott Hughesb465ab02011-08-24 11:21:21 -07001172TEST_F(JniInternalTest, GetObjectRefType) {
1173 jclass local = env_->FindClass("java/lang/Object");
1174 ASSERT_TRUE(local != NULL);
1175 EXPECT_EQ(JNILocalRefType, env_->GetObjectRefType(local));
1176
1177 jobject global = env_->NewGlobalRef(local);
1178 EXPECT_EQ(JNIGlobalRefType, env_->GetObjectRefType(global));
1179
1180 jweak weak_global = env_->NewWeakGlobalRef(local);
1181 EXPECT_EQ(JNIWeakGlobalRefType, env_->GetObjectRefType(weak_global));
1182
1183 jobject invalid = reinterpret_cast<jobject>(this);
1184 EXPECT_EQ(JNIInvalidRefType, env_->GetObjectRefType(invalid));
1185
1186 // TODO: invoke a native method and test that its arguments are considered local references.
1187}
1188
Elliott Hughes8a26c5c2011-08-15 18:35:43 -07001189TEST_F(JniInternalTest, NewStringUTF) {
1190 EXPECT_TRUE(env_->NewStringUTF(NULL) == NULL);
Elliott Hughes814e4032011-08-23 12:07:56 -07001191 jstring s;
1192
1193 s = env_->NewStringUTF("");
1194 EXPECT_TRUE(s != NULL);
1195 EXPECT_EQ(0, env_->GetStringLength(s));
1196 EXPECT_EQ(0, env_->GetStringUTFLength(s));
1197 s = env_->NewStringUTF("hello");
1198 EXPECT_TRUE(s != NULL);
1199 EXPECT_EQ(5, env_->GetStringLength(s));
1200 EXPECT_EQ(5, env_->GetStringUTFLength(s));
1201
Elliott Hughes8a26c5c2011-08-15 18:35:43 -07001202 // TODO: check some non-ASCII strings.
Elliott Hughesf2682d52011-08-15 16:37:04 -07001203}
1204
Elliott Hughes814e4032011-08-23 12:07:56 -07001205TEST_F(JniInternalTest, NewString) {
Elliott Hughes814e4032011-08-23 12:07:56 -07001206 jchar chars[] = { 'h', 'i' };
1207 jstring s;
1208 s = env_->NewString(chars, 0);
1209 EXPECT_TRUE(s != NULL);
1210 EXPECT_EQ(0, env_->GetStringLength(s));
1211 EXPECT_EQ(0, env_->GetStringUTFLength(s));
1212 s = env_->NewString(chars, 2);
1213 EXPECT_TRUE(s != NULL);
1214 EXPECT_EQ(2, env_->GetStringLength(s));
1215 EXPECT_EQ(2, env_->GetStringUTFLength(s));
1216
1217 // TODO: check some non-ASCII strings.
1218}
1219
Jesse Wilson25e79a52011-11-18 15:31:58 -05001220TEST_F(JniInternalTest, NewStringNullCharsZeroLength) {
1221 jstring s = env_->NewString(NULL, 0);
1222 EXPECT_TRUE(s != NULL);
1223 EXPECT_EQ(0, env_->GetStringLength(s));
1224}
1225
Brian Carlstrom36258122011-12-09 12:55:51 -08001226// TODO: fix gtest death tests on host http://b/5690440 (and target)
1227TEST_F(JniInternalTest, DISABLED_NewStringNullCharsNonzeroLength) {
Jesse Wilson25e79a52011-11-18 15:31:58 -05001228 ASSERT_DEATH(env_->NewString(NULL, 1), "");
1229}
1230
Elliott Hughesb465ab02011-08-24 11:21:21 -07001231TEST_F(JniInternalTest, GetStringLength_GetStringUTFLength) {
1232 // Already tested in the NewString/NewStringUTF tests.
1233}
1234
1235TEST_F(JniInternalTest, GetStringRegion_GetStringUTFRegion) {
1236 jstring s = env_->NewStringUTF("hello");
1237 ASSERT_TRUE(s != NULL);
1238
1239 env_->GetStringRegion(s, -1, 0, NULL);
1240 EXPECT_EXCEPTION(sioobe_);
1241 env_->GetStringRegion(s, 0, -1, NULL);
1242 EXPECT_EXCEPTION(sioobe_);
1243 env_->GetStringRegion(s, 0, 10, NULL);
1244 EXPECT_EXCEPTION(sioobe_);
1245 env_->GetStringRegion(s, 10, 1, NULL);
1246 EXPECT_EXCEPTION(sioobe_);
1247
1248 jchar chars[4] = { 'x', 'x', 'x', 'x' };
1249 env_->GetStringRegion(s, 1, 2, &chars[1]);
1250 EXPECT_EQ('x', chars[0]);
1251 EXPECT_EQ('e', chars[1]);
1252 EXPECT_EQ('l', chars[2]);
1253 EXPECT_EQ('x', chars[3]);
1254
1255 env_->GetStringUTFRegion(s, -1, 0, NULL);
1256 EXPECT_EXCEPTION(sioobe_);
1257 env_->GetStringUTFRegion(s, 0, -1, NULL);
1258 EXPECT_EXCEPTION(sioobe_);
1259 env_->GetStringUTFRegion(s, 0, 10, NULL);
1260 EXPECT_EXCEPTION(sioobe_);
1261 env_->GetStringUTFRegion(s, 10, 1, NULL);
1262 EXPECT_EXCEPTION(sioobe_);
1263
1264 char bytes[4] = { 'x', 'x', 'x', 'x' };
1265 env_->GetStringUTFRegion(s, 1, 2, &bytes[1]);
1266 EXPECT_EQ('x', bytes[0]);
1267 EXPECT_EQ('e', bytes[1]);
1268 EXPECT_EQ('l', bytes[2]);
1269 EXPECT_EQ('x', bytes[3]);
1270}
1271
Elliott Hughes75770752011-08-24 17:52:38 -07001272TEST_F(JniInternalTest, GetStringUTFChars_ReleaseStringUTFChars) {
Elliott Hughes3f6635a2012-06-19 13:37:49 -07001273 // Passing in a NULL jstring is ignored normally, but caught by -Xcheck:jni.
Elliott Hughesb264f082012-04-06 17:10:10 -07001274 {
Elliott Hughesb264f082012-04-06 17:10:10 -07001275 CheckJniAbortCatcher check_jni_abort_catcher;
1276 EXPECT_TRUE(env_->GetStringUTFChars(NULL, NULL) == NULL);
Elliott Hughes56ef0422012-06-19 14:35:04 -07001277 check_jni_abort_catcher.Check("GetStringUTFChars received null jstring");
Elliott Hughesb264f082012-04-06 17:10:10 -07001278 }
Elliott Hughes75770752011-08-24 17:52:38 -07001279
1280 jstring s = env_->NewStringUTF("hello");
1281 ASSERT_TRUE(s != NULL);
1282
1283 const char* utf = env_->GetStringUTFChars(s, NULL);
1284 EXPECT_STREQ("hello", utf);
1285 env_->ReleaseStringUTFChars(s, utf);
1286
1287 jboolean is_copy = JNI_FALSE;
1288 utf = env_->GetStringUTFChars(s, &is_copy);
1289 EXPECT_EQ(JNI_TRUE, is_copy);
1290 EXPECT_STREQ("hello", utf);
1291 env_->ReleaseStringUTFChars(s, utf);
1292}
1293
1294TEST_F(JniInternalTest, GetStringChars_ReleaseStringChars) {
1295 jstring s = env_->NewStringUTF("hello");
1296 ASSERT_TRUE(s != NULL);
1297
1298 jchar expected[] = { 'h', 'e', 'l', 'l', 'o' };
1299 const jchar* chars = env_->GetStringChars(s, NULL);
1300 EXPECT_EQ(expected[0], chars[0]);
1301 EXPECT_EQ(expected[1], chars[1]);
1302 EXPECT_EQ(expected[2], chars[2]);
1303 EXPECT_EQ(expected[3], chars[3]);
1304 EXPECT_EQ(expected[4], chars[4]);
1305 env_->ReleaseStringChars(s, chars);
1306
1307 jboolean is_copy = JNI_FALSE;
1308 chars = env_->GetStringChars(s, &is_copy);
1309 EXPECT_EQ(JNI_FALSE, is_copy);
1310 EXPECT_EQ(expected[0], chars[0]);
1311 EXPECT_EQ(expected[1], chars[1]);
1312 EXPECT_EQ(expected[2], chars[2]);
1313 EXPECT_EQ(expected[3], chars[3]);
1314 EXPECT_EQ(expected[4], chars[4]);
1315 env_->ReleaseStringChars(s, chars);
1316}
1317
1318TEST_F(JniInternalTest, GetStringCritical_ReleaseStringCritical) {
1319 jstring s = env_->NewStringUTF("hello");
1320 ASSERT_TRUE(s != NULL);
1321
1322 jchar expected[] = { 'h', 'e', 'l', 'l', 'o' };
1323 const jchar* chars = env_->GetStringCritical(s, NULL);
1324 EXPECT_EQ(expected[0], chars[0]);
1325 EXPECT_EQ(expected[1], chars[1]);
1326 EXPECT_EQ(expected[2], chars[2]);
1327 EXPECT_EQ(expected[3], chars[3]);
1328 EXPECT_EQ(expected[4], chars[4]);
1329 env_->ReleaseStringCritical(s, chars);
1330
1331 jboolean is_copy = JNI_FALSE;
1332 chars = env_->GetStringCritical(s, &is_copy);
1333 EXPECT_EQ(JNI_FALSE, is_copy);
1334 EXPECT_EQ(expected[0], chars[0]);
1335 EXPECT_EQ(expected[1], chars[1]);
1336 EXPECT_EQ(expected[2], chars[2]);
1337 EXPECT_EQ(expected[3], chars[3]);
1338 EXPECT_EQ(expected[4], chars[4]);
1339 env_->ReleaseStringCritical(s, chars);
1340}
1341
Elliott Hughes814e4032011-08-23 12:07:56 -07001342TEST_F(JniInternalTest, GetObjectArrayElement_SetObjectArrayElement) {
Elliott Hughesb264f082012-04-06 17:10:10 -07001343 jclass java_lang_Class = env_->FindClass("java/lang/Class");
1344 ASSERT_TRUE(java_lang_Class != NULL);
Elliott Hughes289da822011-08-16 10:11:20 -07001345
Elliott Hughesb264f082012-04-06 17:10:10 -07001346 jobjectArray array = env_->NewObjectArray(1, java_lang_Class, NULL);
Elliott Hughes289da822011-08-16 10:11:20 -07001347 EXPECT_TRUE(array != NULL);
Elliott Hughes814e4032011-08-23 12:07:56 -07001348 EXPECT_TRUE(env_->GetObjectArrayElement(array, 0) == NULL);
Elliott Hughesb264f082012-04-06 17:10:10 -07001349 env_->SetObjectArrayElement(array, 0, java_lang_Class);
1350 EXPECT_TRUE(env_->IsSameObject(env_->GetObjectArrayElement(array, 0), java_lang_Class));
Elliott Hughesa5b897e2011-08-16 11:33:06 -07001351
1352 // ArrayIndexOutOfBounds for negative index.
Elliott Hughesb264f082012-04-06 17:10:10 -07001353 env_->SetObjectArrayElement(array, -1, java_lang_Class);
Elliott Hughes814e4032011-08-23 12:07:56 -07001354 EXPECT_EXCEPTION(aioobe_);
Elliott Hughesa5b897e2011-08-16 11:33:06 -07001355
1356 // ArrayIndexOutOfBounds for too-large index.
Elliott Hughesb264f082012-04-06 17:10:10 -07001357 env_->SetObjectArrayElement(array, 1, java_lang_Class);
Elliott Hughes814e4032011-08-23 12:07:56 -07001358 EXPECT_EXCEPTION(aioobe_);
Elliott Hughesa5b897e2011-08-16 11:33:06 -07001359
Elliott Hughesb264f082012-04-06 17:10:10 -07001360 // ArrayStoreException thrown for bad types.
1361 env_->SetObjectArrayElement(array, 0, env_->NewStringUTF("not a jclass!"));
1362 EXPECT_EXCEPTION(ase_);
Elliott Hughes289da822011-08-16 10:11:20 -07001363}
1364
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001365#define EXPECT_STATIC_PRIMITIVE_FIELD(type, field_name, sig, value1, value2) \
1366 do { \
1367 jfieldID fid = env_->GetStaticFieldID(c, field_name, sig); \
1368 EXPECT_TRUE(fid != NULL); \
1369 env_->SetStatic ## type ## Field(c, fid, value1); \
Brian Carlstrom2e3d1b22012-01-09 18:01:56 -08001370 EXPECT_TRUE(value1 == env_->GetStatic ## type ## Field(c, fid)); \
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001371 env_->SetStatic ## type ## Field(c, fid, value2); \
Brian Carlstrom2e3d1b22012-01-09 18:01:56 -08001372 EXPECT_TRUE(value2 == env_->GetStatic ## type ## Field(c, fid)); \
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001373 } while (false)
1374
1375#define EXPECT_PRIMITIVE_FIELD(instance, type, field_name, sig, value1, value2) \
1376 do { \
1377 jfieldID fid = env_->GetFieldID(c, field_name, sig); \
1378 EXPECT_TRUE(fid != NULL); \
1379 env_->Set ## type ## Field(instance, fid, value1); \
Brian Carlstrom2e3d1b22012-01-09 18:01:56 -08001380 EXPECT_TRUE(value1 == env_->Get ## type ## Field(instance, fid)); \
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001381 env_->Set ## type ## Field(instance, fid, value2); \
Brian Carlstrom2e3d1b22012-01-09 18:01:56 -08001382 EXPECT_TRUE(value2 == env_->Get ## type ## Field(instance, fid)); \
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001383 } while (false)
1384
1385
Ian Rogersc928de92013-02-27 14:30:44 -08001386#if !defined(ART_USE_PORTABLE_COMPILER)
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001387TEST_F(JniInternalTest, GetPrimitiveField_SetPrimitiveField) {
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001388 Thread::Current()->TransitionFromSuspendedToRunnable();
1389 LoadDex("AllFields");
Brian Carlstrombd86bcc2013-03-10 20:26:16 -07001390 bool started = runtime_->Start();
1391 CHECK(started);
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001392
1393 jclass c = env_->FindClass("AllFields");
1394 ASSERT_TRUE(c != NULL);
1395 jobject o = env_->AllocObject(c);
1396 ASSERT_TRUE(o != NULL);
1397
1398 EXPECT_STATIC_PRIMITIVE_FIELD(Boolean, "sZ", "Z", true, false);
1399 EXPECT_STATIC_PRIMITIVE_FIELD(Byte, "sB", "B", 1, 2);
1400 EXPECT_STATIC_PRIMITIVE_FIELD(Char, "sC", "C", 'a', 'b');
1401 EXPECT_STATIC_PRIMITIVE_FIELD(Double, "sD", "D", 1.0, 2.0);
1402 EXPECT_STATIC_PRIMITIVE_FIELD(Float, "sF", "F", 1.0, 2.0);
1403 EXPECT_STATIC_PRIMITIVE_FIELD(Int, "sI", "I", 1, 2);
1404 EXPECT_STATIC_PRIMITIVE_FIELD(Long, "sJ", "J", 1, 2);
1405 EXPECT_STATIC_PRIMITIVE_FIELD(Short, "sS", "S", 1, 2);
1406
1407 EXPECT_PRIMITIVE_FIELD(o, Boolean, "iZ", "Z", true, false);
1408 EXPECT_PRIMITIVE_FIELD(o, Byte, "iB", "B", 1, 2);
1409 EXPECT_PRIMITIVE_FIELD(o, Char, "iC", "C", 'a', 'b');
1410 EXPECT_PRIMITIVE_FIELD(o, Double, "iD", "D", 1.0, 2.0);
1411 EXPECT_PRIMITIVE_FIELD(o, Float, "iF", "F", 1.0, 2.0);
1412 EXPECT_PRIMITIVE_FIELD(o, Int, "iI", "I", 1, 2);
1413 EXPECT_PRIMITIVE_FIELD(o, Long, "iJ", "J", 1, 2);
1414 EXPECT_PRIMITIVE_FIELD(o, Short, "iS", "S", 1, 2);
1415}
1416
1417TEST_F(JniInternalTest, GetObjectField_SetObjectField) {
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001418 Thread::Current()->TransitionFromSuspendedToRunnable();
1419 LoadDex("AllFields");
Brian Carlstrom25c33252011-09-18 15:58:35 -07001420 runtime_->Start();
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001421
1422 jclass c = env_->FindClass("AllFields");
1423 ASSERT_TRUE(c != NULL);
1424 jobject o = env_->AllocObject(c);
1425 ASSERT_TRUE(o != NULL);
1426
1427 jstring s1 = env_->NewStringUTF("hello");
1428 ASSERT_TRUE(s1 != NULL);
1429 jstring s2 = env_->NewStringUTF("world");
1430 ASSERT_TRUE(s2 != NULL);
1431
1432 jfieldID s_fid = env_->GetStaticFieldID(c, "sObject", "Ljava/lang/Object;");
1433 ASSERT_TRUE(s_fid != NULL);
1434 jfieldID i_fid = env_->GetFieldID(c, "iObject", "Ljava/lang/Object;");
1435 ASSERT_TRUE(i_fid != NULL);
1436
1437 env_->SetStaticObjectField(c, s_fid, s1);
1438 ASSERT_TRUE(env_->IsSameObject(s1, env_->GetStaticObjectField(c, s_fid)));
1439 env_->SetStaticObjectField(c, s_fid, s2);
1440 ASSERT_TRUE(env_->IsSameObject(s2, env_->GetStaticObjectField(c, s_fid)));
1441
1442 env_->SetObjectField(o, i_fid, s1);
1443 ASSERT_TRUE(env_->IsSameObject(s1, env_->GetObjectField(o, i_fid)));
1444 env_->SetObjectField(o, i_fid, s2);
1445 ASSERT_TRUE(env_->IsSameObject(s2, env_->GetObjectField(o, i_fid)));
1446}
Shih-wei Liao5b8b1ed2012-02-23 23:48:21 -08001447#endif
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001448
Elliott Hughes18c07532011-08-18 15:50:51 -07001449TEST_F(JniInternalTest, NewLocalRef_NULL) {
1450 EXPECT_TRUE(env_->NewLocalRef(NULL) == NULL);
1451}
1452
1453TEST_F(JniInternalTest, NewLocalRef) {
1454 jstring s = env_->NewStringUTF("");
1455 ASSERT_TRUE(s != NULL);
1456 jobject o = env_->NewLocalRef(s);
1457 EXPECT_TRUE(o != NULL);
1458 EXPECT_TRUE(o != s);
1459
Elliott Hughes2ced6a52011-10-16 18:44:48 -07001460 EXPECT_EQ(JNILocalRefType, env_->GetObjectRefType(o));
Elliott Hughes18c07532011-08-18 15:50:51 -07001461}
1462
1463TEST_F(JniInternalTest, DeleteLocalRef_NULL) {
1464 env_->DeleteLocalRef(NULL);
1465}
1466
1467TEST_F(JniInternalTest, DeleteLocalRef) {
1468 jstring s = env_->NewStringUTF("");
1469 ASSERT_TRUE(s != NULL);
1470 env_->DeleteLocalRef(s);
1471
Elliott Hughes3f6635a2012-06-19 13:37:49 -07001472 // Currently, deleting an already-deleted reference is just a CheckJNI warning.
Elliott Hughesb264f082012-04-06 17:10:10 -07001473 {
Elliott Hughesb264f082012-04-06 17:10:10 -07001474 CheckJniAbortCatcher check_jni_abort_catcher;
1475 env_->DeleteLocalRef(s);
Elliott Hughesa9137c62013-01-09 10:55:21 -08001476
Brian Carlstromea46f952013-07-30 01:26:50 -07001477 std::string expected(StringPrintf("native code passing in reference to "
1478 "invalid local reference: %p", s));
Elliott Hughesa9137c62013-01-09 10:55:21 -08001479 check_jni_abort_catcher.Check(expected.c_str());
Elliott Hughesb264f082012-04-06 17:10:10 -07001480 }
Elliott Hughes18c07532011-08-18 15:50:51 -07001481
1482 s = env_->NewStringUTF("");
1483 ASSERT_TRUE(s != NULL);
1484 jobject o = env_->NewLocalRef(s);
1485 ASSERT_TRUE(o != NULL);
1486
1487 env_->DeleteLocalRef(s);
1488 env_->DeleteLocalRef(o);
1489}
1490
Elliott Hughesaa836f72013-08-20 16:57:23 -07001491TEST_F(JniInternalTest, PushLocalFrame_10395422) {
1492 // The JNI specification is ambiguous about whether the given capacity is to be interpreted as a
1493 // maximum or as a minimum, but it seems like it's supposed to be a minimum, and that's how
1494 // Android historically treated it, and it's how the RI treats it. It's also the more useful
1495 // interpretation!
1496 ASSERT_EQ(JNI_OK, env_->PushLocalFrame(0));
1497 env_->PopLocalFrame(NULL);
1498
1499 // Negative capacities are not allowed.
1500 ASSERT_EQ(JNI_ERR, env_->PushLocalFrame(-1));
1501
1502 // And it's okay to have an upper limit. Ours is currently 512.
1503 ASSERT_EQ(JNI_ERR, env_->PushLocalFrame(8192));
1504}
1505
Elliott Hughes2ced6a52011-10-16 18:44:48 -07001506TEST_F(JniInternalTest, PushLocalFrame_PopLocalFrame) {
1507 jobject original = env_->NewStringUTF("");
1508 ASSERT_TRUE(original != NULL);
1509
1510 jobject outer;
1511 jobject inner1, inner2;
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001512 ScopedObjectAccess soa(env_);
Ian Rogers2dd0e2c2013-01-24 12:42:14 -08001513 mirror::Object* inner2_direct_pointer;
Elliott Hughes2ced6a52011-10-16 18:44:48 -07001514 {
Elliott Hughesaa836f72013-08-20 16:57:23 -07001515 ASSERT_EQ(JNI_OK, env_->PushLocalFrame(4));
Elliott Hughes2ced6a52011-10-16 18:44:48 -07001516 outer = env_->NewLocalRef(original);
1517
1518 {
Elliott Hughesaa836f72013-08-20 16:57:23 -07001519 ASSERT_EQ(JNI_OK, env_->PushLocalFrame(4));
Elliott Hughes2ced6a52011-10-16 18:44:48 -07001520 inner1 = env_->NewLocalRef(outer);
1521 inner2 = env_->NewStringUTF("survivor");
Ian Rogers2dd0e2c2013-01-24 12:42:14 -08001522 inner2_direct_pointer = soa.Decode<mirror::Object*>(inner2);
Elliott Hughes2ced6a52011-10-16 18:44:48 -07001523 env_->PopLocalFrame(inner2);
1524 }
1525
1526 EXPECT_EQ(JNILocalRefType, env_->GetObjectRefType(original));
1527 EXPECT_EQ(JNILocalRefType, env_->GetObjectRefType(outer));
1528 EXPECT_EQ(JNIInvalidRefType, env_->GetObjectRefType(inner1));
1529
1530 // Our local reference for the survivor is invalid because the survivor
1531 // gets a new local reference...
1532 EXPECT_EQ(JNIInvalidRefType, env_->GetObjectRefType(inner2));
1533 // ...but the survivor should be in the local reference table.
Brian Carlstrom4d571432012-05-16 00:21:41 -07001534 JNIEnvExt* env = reinterpret_cast<JNIEnvExt*>(env_);
1535 EXPECT_TRUE(env->locals.ContainsDirectPointer(inner2_direct_pointer));
Elliott Hughes2ced6a52011-10-16 18:44:48 -07001536
1537 env_->PopLocalFrame(NULL);
1538 }
1539 EXPECT_EQ(JNILocalRefType, env_->GetObjectRefType(original));
1540 EXPECT_EQ(JNIInvalidRefType, env_->GetObjectRefType(outer));
1541 EXPECT_EQ(JNIInvalidRefType, env_->GetObjectRefType(inner1));
1542 EXPECT_EQ(JNIInvalidRefType, env_->GetObjectRefType(inner2));
1543}
1544
Elliott Hughes18c07532011-08-18 15:50:51 -07001545TEST_F(JniInternalTest, NewGlobalRef_NULL) {
1546 EXPECT_TRUE(env_->NewGlobalRef(NULL) == NULL);
1547}
1548
1549TEST_F(JniInternalTest, NewGlobalRef) {
1550 jstring s = env_->NewStringUTF("");
1551 ASSERT_TRUE(s != NULL);
1552 jobject o = env_->NewGlobalRef(s);
1553 EXPECT_TRUE(o != NULL);
1554 EXPECT_TRUE(o != s);
1555
1556 // TODO: check that o is a global reference.
1557}
1558
1559TEST_F(JniInternalTest, DeleteGlobalRef_NULL) {
1560 env_->DeleteGlobalRef(NULL);
1561}
1562
1563TEST_F(JniInternalTest, DeleteGlobalRef) {
1564 jstring s = env_->NewStringUTF("");
1565 ASSERT_TRUE(s != NULL);
1566
1567 jobject o = env_->NewGlobalRef(s);
1568 ASSERT_TRUE(o != NULL);
1569 env_->DeleteGlobalRef(o);
1570
Elliott Hughes3f6635a2012-06-19 13:37:49 -07001571 // Currently, deleting an already-deleted reference is just a CheckJNI warning.
Elliott Hughesb264f082012-04-06 17:10:10 -07001572 {
Elliott Hughesb264f082012-04-06 17:10:10 -07001573 CheckJniAbortCatcher check_jni_abort_catcher;
1574 env_->DeleteGlobalRef(o);
Elliott Hughesa9137c62013-01-09 10:55:21 -08001575
Brian Carlstromea46f952013-07-30 01:26:50 -07001576 std::string expected(StringPrintf("native code passing in reference to "
1577 "invalid global reference: %p", o));
Elliott Hughesa9137c62013-01-09 10:55:21 -08001578 check_jni_abort_catcher.Check(expected.c_str());
Elliott Hughesb264f082012-04-06 17:10:10 -07001579 }
Elliott Hughes18c07532011-08-18 15:50:51 -07001580
1581 jobject o1 = env_->NewGlobalRef(s);
1582 ASSERT_TRUE(o1 != NULL);
1583 jobject o2 = env_->NewGlobalRef(s);
1584 ASSERT_TRUE(o2 != NULL);
1585
1586 env_->DeleteGlobalRef(o1);
1587 env_->DeleteGlobalRef(o2);
1588}
1589
1590TEST_F(JniInternalTest, NewWeakGlobalRef_NULL) {
1591 EXPECT_TRUE(env_->NewWeakGlobalRef(NULL) == NULL);
1592}
1593
1594TEST_F(JniInternalTest, NewWeakGlobalRef) {
1595 jstring s = env_->NewStringUTF("");
1596 ASSERT_TRUE(s != NULL);
1597 jobject o = env_->NewWeakGlobalRef(s);
1598 EXPECT_TRUE(o != NULL);
1599 EXPECT_TRUE(o != s);
1600
1601 // TODO: check that o is a weak global reference.
1602}
1603
1604TEST_F(JniInternalTest, DeleteWeakGlobalRef_NULL) {
1605 env_->DeleteWeakGlobalRef(NULL);
1606}
1607
1608TEST_F(JniInternalTest, DeleteWeakGlobalRef) {
1609 jstring s = env_->NewStringUTF("");
1610 ASSERT_TRUE(s != NULL);
1611
1612 jobject o = env_->NewWeakGlobalRef(s);
1613 ASSERT_TRUE(o != NULL);
1614 env_->DeleteWeakGlobalRef(o);
1615
Elliott Hughes3f6635a2012-06-19 13:37:49 -07001616 // Currently, deleting an already-deleted reference is just a CheckJNI warning.
Elliott Hughesb264f082012-04-06 17:10:10 -07001617 {
Elliott Hughesb264f082012-04-06 17:10:10 -07001618 CheckJniAbortCatcher check_jni_abort_catcher;
1619 env_->DeleteWeakGlobalRef(o);
Elliott Hughesa9137c62013-01-09 10:55:21 -08001620
Brian Carlstromea46f952013-07-30 01:26:50 -07001621 std::string expected(StringPrintf("native code passing in reference to "
1622 "invalid weak global reference: %p", o));
Elliott Hughesa9137c62013-01-09 10:55:21 -08001623 check_jni_abort_catcher.Check(expected.c_str());
Elliott Hughesb264f082012-04-06 17:10:10 -07001624 }
Elliott Hughes18c07532011-08-18 15:50:51 -07001625
1626 jobject o1 = env_->NewWeakGlobalRef(s);
1627 ASSERT_TRUE(o1 != NULL);
1628 jobject o2 = env_->NewWeakGlobalRef(s);
1629 ASSERT_TRUE(o2 != NULL);
1630
1631 env_->DeleteWeakGlobalRef(o1);
1632 env_->DeleteWeakGlobalRef(o2);
1633}
1634
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001635TEST_F(JniInternalTest, StaticMainMethod) {
Brian Carlstrom265091e2013-01-30 14:08:26 -08001636 TEST_DISABLED_FOR_PORTABLE();
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001637 ScopedObjectAccess soa(Thread::Current());
1638 jobject jclass_loader = LoadDex("Main");
Ian Rogers2dd0e2c2013-01-24 12:42:14 -08001639 SirtRef<mirror::ClassLoader>
1640 class_loader(soa.Self(), soa.Decode<mirror::ClassLoader*>(jclass_loader));
Brian Carlstrom40381fb2011-10-19 14:13:40 -07001641 CompileDirectMethod(class_loader.get(), "Main", "main", "([Ljava/lang/String;)V");
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001642
Ian Rogers2dd0e2c2013-01-24 12:42:14 -08001643 mirror::Class* klass = class_linker_->FindClass("LMain;", class_loader.get());
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001644 ASSERT_TRUE(klass != NULL);
1645
Brian Carlstromea46f952013-07-30 01:26:50 -07001646 mirror::ArtMethod* method = klass->FindDirectMethod("main", "([Ljava/lang/String;)V");
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001647 ASSERT_TRUE(method != NULL);
1648
Jeff Hao5d917302013-02-27 17:57:33 -08001649 ArgArray arg_array(NULL, 0);
1650 arg_array.Append(0);
1651 JValue result;
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001652
Sebastien Hertzb95851f2013-03-29 10:36:40 +01001653 // Start runtime.
1654 bool started = runtime_->Start();
1655 CHECK(started);
1656 Thread::Current()->TransitionFromSuspendedToRunnable();
1657
1658 method->Invoke(Thread::Current(), arg_array.GetArray(), arg_array.GetNumBytes(), &result, 'V');
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001659}
1660
1661TEST_F(JniInternalTest, StaticNopMethod) {
Brian Carlstrom265091e2013-01-30 14:08:26 -08001662 TEST_DISABLED_FOR_PORTABLE();
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001663 ScopedObjectAccess soa(Thread::Current());
Elliott Hughes77405792012-03-15 15:22:12 -07001664 InvokeNopMethod(true);
1665}
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001666
Elliott Hughes77405792012-03-15 15:22:12 -07001667TEST_F(JniInternalTest, NonStaticNopMethod) {
Brian Carlstrom265091e2013-01-30 14:08:26 -08001668 TEST_DISABLED_FOR_PORTABLE();
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001669 ScopedObjectAccess soa(Thread::Current());
Elliott Hughes77405792012-03-15 15:22:12 -07001670 InvokeNopMethod(false);
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001671}
1672
1673TEST_F(JniInternalTest, StaticIdentityByteMethod) {
Brian Carlstrom265091e2013-01-30 14:08:26 -08001674 TEST_DISABLED_FOR_PORTABLE();
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001675 ScopedObjectAccess soa(Thread::Current());
Elliott Hughes77405792012-03-15 15:22:12 -07001676 InvokeIdentityByteMethod(true);
1677}
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001678
Elliott Hughes77405792012-03-15 15:22:12 -07001679TEST_F(JniInternalTest, NonStaticIdentityByteMethod) {
Brian Carlstrom265091e2013-01-30 14:08:26 -08001680 TEST_DISABLED_FOR_PORTABLE();
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001681 ScopedObjectAccess soa(Thread::Current());
Elliott Hughes77405792012-03-15 15:22:12 -07001682 InvokeIdentityByteMethod(false);
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001683}
1684
1685TEST_F(JniInternalTest, StaticIdentityIntMethod) {
Brian Carlstrom265091e2013-01-30 14:08:26 -08001686 TEST_DISABLED_FOR_PORTABLE();
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001687 ScopedObjectAccess soa(Thread::Current());
Elliott Hughes77405792012-03-15 15:22:12 -07001688 InvokeIdentityIntMethod(true);
1689}
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001690
Elliott Hughes77405792012-03-15 15:22:12 -07001691TEST_F(JniInternalTest, NonStaticIdentityIntMethod) {
Brian Carlstrom265091e2013-01-30 14:08:26 -08001692 TEST_DISABLED_FOR_PORTABLE();
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001693 ScopedObjectAccess soa(Thread::Current());
Elliott Hughes77405792012-03-15 15:22:12 -07001694 InvokeIdentityIntMethod(false);
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001695}
1696
1697TEST_F(JniInternalTest, StaticIdentityDoubleMethod) {
Brian Carlstrom265091e2013-01-30 14:08:26 -08001698 TEST_DISABLED_FOR_PORTABLE();
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001699 ScopedObjectAccess soa(Thread::Current());
Elliott Hughes77405792012-03-15 15:22:12 -07001700 InvokeIdentityDoubleMethod(true);
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001701}
1702
Elliott Hughes77405792012-03-15 15:22:12 -07001703TEST_F(JniInternalTest, NonStaticIdentityDoubleMethod) {
Brian Carlstrom265091e2013-01-30 14:08:26 -08001704 TEST_DISABLED_FOR_PORTABLE();
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001705 ScopedObjectAccess soa(Thread::Current());
Elliott Hughes77405792012-03-15 15:22:12 -07001706 InvokeIdentityDoubleMethod(false);
Shih-wei Liao5b8b1ed2012-02-23 23:48:21 -08001707}
1708
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001709TEST_F(JniInternalTest, StaticSumIntIntMethod) {
Brian Carlstrom265091e2013-01-30 14:08:26 -08001710 TEST_DISABLED_FOR_PORTABLE();
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001711 ScopedObjectAccess soa(Thread::Current());
Elliott Hughes77405792012-03-15 15:22:12 -07001712 InvokeSumIntIntMethod(true);
1713}
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001714
Elliott Hughes77405792012-03-15 15:22:12 -07001715TEST_F(JniInternalTest, NonStaticSumIntIntMethod) {
Brian Carlstrom265091e2013-01-30 14:08:26 -08001716 TEST_DISABLED_FOR_PORTABLE();
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001717 ScopedObjectAccess soa(Thread::Current());
Elliott Hughes77405792012-03-15 15:22:12 -07001718 InvokeSumIntIntMethod(false);
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001719}
1720
1721TEST_F(JniInternalTest, StaticSumIntIntIntMethod) {
Brian Carlstrom265091e2013-01-30 14:08:26 -08001722 TEST_DISABLED_FOR_PORTABLE();
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001723 ScopedObjectAccess soa(Thread::Current());
Elliott Hughes77405792012-03-15 15:22:12 -07001724 InvokeSumIntIntIntMethod(true);
1725}
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001726
Elliott Hughes77405792012-03-15 15:22:12 -07001727TEST_F(JniInternalTest, NonStaticSumIntIntIntMethod) {
Brian Carlstrom265091e2013-01-30 14:08:26 -08001728 TEST_DISABLED_FOR_PORTABLE();
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001729 ScopedObjectAccess soa(Thread::Current());
Elliott Hughes77405792012-03-15 15:22:12 -07001730 InvokeSumIntIntIntMethod(false);
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001731}
1732
1733TEST_F(JniInternalTest, StaticSumIntIntIntIntMethod) {
Brian Carlstrom265091e2013-01-30 14:08:26 -08001734 TEST_DISABLED_FOR_PORTABLE();
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001735 ScopedObjectAccess soa(Thread::Current());
Elliott Hughes77405792012-03-15 15:22:12 -07001736 InvokeSumIntIntIntIntMethod(true);
1737}
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001738
Elliott Hughes77405792012-03-15 15:22:12 -07001739TEST_F(JniInternalTest, NonStaticSumIntIntIntIntMethod) {
Brian Carlstrom265091e2013-01-30 14:08:26 -08001740 TEST_DISABLED_FOR_PORTABLE();
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001741 ScopedObjectAccess soa(Thread::Current());
Elliott Hughes77405792012-03-15 15:22:12 -07001742 InvokeSumIntIntIntIntMethod(false);
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001743}
1744
1745TEST_F(JniInternalTest, StaticSumIntIntIntIntIntMethod) {
Brian Carlstrom265091e2013-01-30 14:08:26 -08001746 TEST_DISABLED_FOR_PORTABLE();
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001747 ScopedObjectAccess soa(Thread::Current());
Elliott Hughes77405792012-03-15 15:22:12 -07001748 InvokeSumIntIntIntIntIntMethod(true);
1749}
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001750
Elliott Hughes77405792012-03-15 15:22:12 -07001751TEST_F(JniInternalTest, NonStaticSumIntIntIntIntIntMethod) {
Brian Carlstrom265091e2013-01-30 14:08:26 -08001752 TEST_DISABLED_FOR_PORTABLE();
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001753 ScopedObjectAccess soa(Thread::Current());
Elliott Hughes77405792012-03-15 15:22:12 -07001754 InvokeSumIntIntIntIntIntMethod(false);
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001755}
1756
1757TEST_F(JniInternalTest, StaticSumDoubleDoubleMethod) {
Brian Carlstrom265091e2013-01-30 14:08:26 -08001758 TEST_DISABLED_FOR_PORTABLE();
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001759 ScopedObjectAccess soa(Thread::Current());
Elliott Hughes77405792012-03-15 15:22:12 -07001760 InvokeSumDoubleDoubleMethod(true);
1761}
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001762
Elliott Hughes77405792012-03-15 15:22:12 -07001763TEST_F(JniInternalTest, NonStaticSumDoubleDoubleMethod) {
Brian Carlstrom265091e2013-01-30 14:08:26 -08001764 TEST_DISABLED_FOR_PORTABLE();
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001765 ScopedObjectAccess soa(Thread::Current());
Elliott Hughes77405792012-03-15 15:22:12 -07001766 InvokeSumDoubleDoubleMethod(false);
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001767}
1768
1769TEST_F(JniInternalTest, StaticSumDoubleDoubleDoubleMethod) {
Brian Carlstrom265091e2013-01-30 14:08:26 -08001770 TEST_DISABLED_FOR_PORTABLE();
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001771 ScopedObjectAccess soa(Thread::Current());
Elliott Hughes77405792012-03-15 15:22:12 -07001772 InvokeSumDoubleDoubleDoubleMethod(true);
1773}
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001774
Elliott Hughes77405792012-03-15 15:22:12 -07001775TEST_F(JniInternalTest, NonStaticSumDoubleDoubleDoubleMethod) {
Brian Carlstrom265091e2013-01-30 14:08:26 -08001776 TEST_DISABLED_FOR_PORTABLE();
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001777 ScopedObjectAccess soa(Thread::Current());
Elliott Hughes77405792012-03-15 15:22:12 -07001778 InvokeSumDoubleDoubleDoubleMethod(false);
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001779}
1780
1781TEST_F(JniInternalTest, StaticSumDoubleDoubleDoubleDoubleMethod) {
Brian Carlstrom265091e2013-01-30 14:08:26 -08001782 TEST_DISABLED_FOR_PORTABLE();
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001783 ScopedObjectAccess soa(Thread::Current());
Elliott Hughes77405792012-03-15 15:22:12 -07001784 InvokeSumDoubleDoubleDoubleDoubleMethod(true);
1785}
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001786
Elliott Hughes77405792012-03-15 15:22:12 -07001787TEST_F(JniInternalTest, NonStaticSumDoubleDoubleDoubleDoubleMethod) {
Brian Carlstrom265091e2013-01-30 14:08:26 -08001788 TEST_DISABLED_FOR_PORTABLE();
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001789 ScopedObjectAccess soa(Thread::Current());
Elliott Hughes77405792012-03-15 15:22:12 -07001790 InvokeSumDoubleDoubleDoubleDoubleMethod(false);
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001791}
1792
1793TEST_F(JniInternalTest, StaticSumDoubleDoubleDoubleDoubleDoubleMethod) {
Brian Carlstrom265091e2013-01-30 14:08:26 -08001794 TEST_DISABLED_FOR_PORTABLE();
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001795 ScopedObjectAccess soa(Thread::Current());
Elliott Hughes77405792012-03-15 15:22:12 -07001796 InvokeSumDoubleDoubleDoubleDoubleDoubleMethod(true);
1797}
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001798
Elliott Hughes77405792012-03-15 15:22:12 -07001799TEST_F(JniInternalTest, NonStaticSumDoubleDoubleDoubleDoubleDoubleMethod) {
Brian Carlstrom265091e2013-01-30 14:08:26 -08001800 TEST_DISABLED_FOR_PORTABLE();
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001801 ScopedObjectAccess soa(Thread::Current());
Elliott Hughes77405792012-03-15 15:22:12 -07001802 InvokeSumDoubleDoubleDoubleDoubleDoubleMethod(false);
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001803}
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001804
Elliott Hughes37f7a402011-08-22 18:56:01 -07001805TEST_F(JniInternalTest, Throw) {
1806 EXPECT_EQ(JNI_ERR, env_->Throw(NULL));
1807
1808 jclass exception_class = env_->FindClass("java/lang/RuntimeException");
1809 ASSERT_TRUE(exception_class != NULL);
1810 jthrowable exception = reinterpret_cast<jthrowable>(env_->AllocObject(exception_class));
1811 ASSERT_TRUE(exception != NULL);
1812
1813 EXPECT_EQ(JNI_OK, env_->Throw(exception));
1814 EXPECT_TRUE(env_->ExceptionCheck());
Elliott Hughesa2501992011-08-26 19:39:54 -07001815 jthrowable thrown_exception = env_->ExceptionOccurred();
Elliott Hughes37f7a402011-08-22 18:56:01 -07001816 env_->ExceptionClear();
Elliott Hughesa2501992011-08-26 19:39:54 -07001817 EXPECT_TRUE(env_->IsSameObject(exception, thrown_exception));
Elliott Hughes37f7a402011-08-22 18:56:01 -07001818}
1819
1820TEST_F(JniInternalTest, ThrowNew) {
1821 EXPECT_EQ(JNI_ERR, env_->Throw(NULL));
1822
1823 jclass exception_class = env_->FindClass("java/lang/RuntimeException");
1824 ASSERT_TRUE(exception_class != NULL);
1825
Elliott Hughes5cb5ad22011-10-02 12:13:39 -07001826 jthrowable thrown_exception;
1827
Elliott Hughes37f7a402011-08-22 18:56:01 -07001828 EXPECT_EQ(JNI_OK, env_->ThrowNew(exception_class, "hello world"));
1829 EXPECT_TRUE(env_->ExceptionCheck());
Elliott Hughes5cb5ad22011-10-02 12:13:39 -07001830 thrown_exception = env_->ExceptionOccurred();
1831 env_->ExceptionClear();
1832 EXPECT_TRUE(env_->IsInstanceOf(thrown_exception, exception_class));
1833
1834 EXPECT_EQ(JNI_OK, env_->ThrowNew(exception_class, NULL));
1835 EXPECT_TRUE(env_->ExceptionCheck());
1836 thrown_exception = env_->ExceptionOccurred();
Elliott Hughes37f7a402011-08-22 18:56:01 -07001837 env_->ExceptionClear();
Elliott Hughesa2501992011-08-26 19:39:54 -07001838 EXPECT_TRUE(env_->IsInstanceOf(thrown_exception, exception_class));
Elliott Hughes37f7a402011-08-22 18:56:01 -07001839}
1840
Elliott Hughesb465ab02011-08-24 11:21:21 -07001841// TODO: this test is DISABLED until we can actually run java.nio.Buffer's <init>.
1842TEST_F(JniInternalTest, DISABLED_NewDirectBuffer_GetDirectBufferAddress_GetDirectBufferCapacity) {
1843 jclass buffer_class = env_->FindClass("java/nio/Buffer");
1844 ASSERT_TRUE(buffer_class != NULL);
1845
1846 char bytes[1024];
1847 jobject buffer = env_->NewDirectByteBuffer(bytes, sizeof(bytes));
1848 ASSERT_TRUE(buffer != NULL);
1849 ASSERT_TRUE(env_->IsInstanceOf(buffer, buffer_class));
1850 ASSERT_TRUE(env_->GetDirectBufferAddress(buffer) == bytes);
1851 ASSERT_TRUE(env_->GetDirectBufferCapacity(buffer) == sizeof(bytes));
1852}
1853
Ian Rogers6d0b13e2012-02-07 09:25:29 -08001854TEST_F(JniInternalTest, MonitorEnterExit) {
1855 // Create an object to torture
1856 jclass object_class = env_->FindClass("java/lang/Object");
1857 ASSERT_TRUE(object_class != NULL);
1858 jobject object = env_->AllocObject(object_class);
1859 ASSERT_TRUE(object != NULL);
1860
1861 // Expected class of exceptions
1862 jclass imse_class = env_->FindClass("java/lang/IllegalMonitorStateException");
1863 ASSERT_TRUE(imse_class != NULL);
1864
1865 jthrowable thrown_exception;
1866
1867 // Unlock of unowned monitor
1868 env_->MonitorExit(object);
1869 EXPECT_TRUE(env_->ExceptionCheck());
1870 thrown_exception = env_->ExceptionOccurred();
1871 env_->ExceptionClear();
1872 EXPECT_TRUE(env_->IsInstanceOf(thrown_exception, imse_class));
1873
1874 // Lock of unowned monitor
1875 env_->MonitorEnter(object);
1876 EXPECT_FALSE(env_->ExceptionCheck());
1877 // Regular unlock
1878 env_->MonitorExit(object);
1879 EXPECT_FALSE(env_->ExceptionCheck());
1880
1881 // Recursively lock a lot
1882 size_t max_recursive_lock = 1024;
1883 for (size_t i = 0; i < max_recursive_lock; i++) {
1884 env_->MonitorEnter(object);
1885 EXPECT_FALSE(env_->ExceptionCheck());
1886 }
1887 // Recursively unlock a lot
1888 for (size_t i = 0; i < max_recursive_lock; i++) {
1889 env_->MonitorExit(object);
1890 EXPECT_FALSE(env_->ExceptionCheck());
1891 }
1892
1893 // Unlock of unowned monitor
1894 env_->MonitorExit(object);
1895 EXPECT_TRUE(env_->ExceptionCheck());
1896 thrown_exception = env_->ExceptionOccurred();
1897 env_->ExceptionClear();
1898 EXPECT_TRUE(env_->IsInstanceOf(thrown_exception, imse_class));
Elliott Hughesa92853e2012-02-07 16:09:27 -08001899
1900 // It's an error to call MonitorEnter or MonitorExit on NULL.
Elliott Hughesb264f082012-04-06 17:10:10 -07001901 {
1902 CheckJniAbortCatcher check_jni_abort_catcher;
1903 env_->MonitorEnter(NULL);
1904 check_jni_abort_catcher.Check("in call to MonitorEnter");
Elliott Hughesb264f082012-04-06 17:10:10 -07001905
Elliott Hughesb264f082012-04-06 17:10:10 -07001906 env_->MonitorExit(NULL);
1907 check_jni_abort_catcher.Check("in call to MonitorExit");
1908 }
Ian Rogers6d0b13e2012-02-07 09:25:29 -08001909}
1910
Brian Carlstrom4d571432012-05-16 00:21:41 -07001911TEST_F(JniInternalTest, DetachCurrentThread) {
1912 CleanUpJniEnv(); // cleanup now so TearDown won't have junk from wrong JNIEnv
1913 jint ok = vm_->DetachCurrentThread();
1914 EXPECT_EQ(JNI_OK, ok);
1915
1916 jint err = vm_->DetachCurrentThread();
1917 EXPECT_EQ(JNI_ERR, err);
1918 vm_->AttachCurrentThread(&env_, NULL); // need attached thread for CommonTest::TearDown
1919}
1920
Ian Rogers0cfe1fb2011-08-26 03:29:44 -07001921} // namespace art