blob: c389580ebfc9f1d3d4365b3276b06f04d6d83c03 [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; \
Elliott Hughesd7d7f6e2013-09-18 12:00:45 -07001015 \
Elliott Hughes814e4032011-08-23 12:07:56 -07001016 /* Allocate an array and check it has the right type and length. */ \
1017 scalar_type ## Array a = env_->new_fn(size); \
1018 EXPECT_TRUE(a != NULL); \
1019 EXPECT_TRUE(env_->IsInstanceOf(a, env_->FindClass(expected_class_descriptor))); \
1020 EXPECT_EQ(size, env_->GetArrayLength(a)); \
Elliott Hughesd7d7f6e2013-09-18 12:00:45 -07001021 \
1022 /* GetPrimitiveArrayRegion/SetPrimitiveArrayRegion */ \
Elliott Hughes814e4032011-08-23 12:07:56 -07001023 /* AIOOBE for negative start offset. */ \
1024 env_->get_region_fn(a, -1, 1, NULL); \
1025 EXPECT_EXCEPTION(aioobe_); \
1026 env_->set_region_fn(a, -1, 1, NULL); \
1027 EXPECT_EXCEPTION(aioobe_); \
Elliott Hughesd7d7f6e2013-09-18 12:00:45 -07001028 \
Elliott Hughes814e4032011-08-23 12:07:56 -07001029 /* AIOOBE for negative length. */ \
1030 env_->get_region_fn(a, 0, -1, NULL); \
1031 EXPECT_EXCEPTION(aioobe_); \
1032 env_->set_region_fn(a, 0, -1, NULL); \
1033 EXPECT_EXCEPTION(aioobe_); \
Elliott Hughesd7d7f6e2013-09-18 12:00:45 -07001034 \
Elliott Hughes814e4032011-08-23 12:07:56 -07001035 /* AIOOBE for buffer overrun. */ \
1036 env_->get_region_fn(a, size - 1, size, NULL); \
1037 EXPECT_EXCEPTION(aioobe_); \
1038 env_->set_region_fn(a, size - 1, size, NULL); \
1039 EXPECT_EXCEPTION(aioobe_); \
Elliott Hughesd7d7f6e2013-09-18 12:00:45 -07001040 \
1041 /* It's okay for the buffer to be NULL as long as the length is 0. */ \
1042 env_->get_region_fn(a, 2, 0, NULL); \
1043 /* Even if the offset is invalid... */ \
1044 env_->get_region_fn(a, 123, 0, NULL); \
1045 EXPECT_EXCEPTION(aioobe_); \
1046 \
1047 /* It's okay for the buffer to be NULL as long as the length is 0. */ \
1048 env_->set_region_fn(a, 2, 0, NULL); \
1049 /* Even if the offset is invalid... */ \
1050 env_->set_region_fn(a, 123, 0, NULL); \
1051 EXPECT_EXCEPTION(aioobe_); \
1052 \
Elliott Hughes814e4032011-08-23 12:07:56 -07001053 /* Prepare a couple of buffers. */ \
Elliott Hughesee0fa762012-03-26 17:12:41 -07001054 UniquePtr<scalar_type[]> src_buf(new scalar_type[size]); \
1055 UniquePtr<scalar_type[]> dst_buf(new scalar_type[size]); \
Elliott Hughes814e4032011-08-23 12:07:56 -07001056 for (jsize i = 0; i < size; ++i) { src_buf[i] = scalar_type(i); } \
1057 for (jsize i = 0; i < size; ++i) { dst_buf[i] = scalar_type(-1); } \
Elliott Hughesd7d7f6e2013-09-18 12:00:45 -07001058 \
Elliott Hughes814e4032011-08-23 12:07:56 -07001059 /* Copy all of src_buf onto the heap. */ \
Elliott Hughesee0fa762012-03-26 17:12:41 -07001060 env_->set_region_fn(a, 0, size, &src_buf[0]); \
Elliott Hughes814e4032011-08-23 12:07:56 -07001061 /* Copy back only part. */ \
1062 env_->get_region_fn(a, 1, size - 2, &dst_buf[1]); \
Brian Carlstromea46f952013-07-30 01:26:50 -07001063 EXPECT_NE(memcmp(&src_buf[0], &dst_buf[0], size * sizeof(scalar_type)), 0) \
1064 << "short copy equal"; \
Elliott Hughes814e4032011-08-23 12:07:56 -07001065 /* Copy the missing pieces. */ \
Elliott Hughesee0fa762012-03-26 17:12:41 -07001066 env_->get_region_fn(a, 0, 1, &dst_buf[0]); \
Elliott Hughes814e4032011-08-23 12:07:56 -07001067 env_->get_region_fn(a, size - 1, 1, &dst_buf[size - 1]); \
Brian Carlstromea46f952013-07-30 01:26:50 -07001068 EXPECT_EQ(memcmp(&src_buf[0], &dst_buf[0], size * sizeof(scalar_type)), 0) \
1069 << "fixed copy not equal"; \
Elliott Hughes814e4032011-08-23 12:07:56 -07001070 /* Copy back the whole array. */ \
Elliott Hughesee0fa762012-03-26 17:12:41 -07001071 env_->get_region_fn(a, 0, size, &dst_buf[0]); \
Brian Carlstromea46f952013-07-30 01:26:50 -07001072 EXPECT_EQ(memcmp(&src_buf[0], &dst_buf[0], size * sizeof(scalar_type)), 0) \
1073 << "full copy not equal"; \
Elliott Hughes75770752011-08-24 17:52:38 -07001074 /* GetPrimitiveArrayCritical */ \
1075 void* v = env_->GetPrimitiveArrayCritical(a, NULL); \
Brian Carlstromea46f952013-07-30 01:26:50 -07001076 EXPECT_EQ(memcmp(&src_buf[0], v, size * sizeof(scalar_type)), 0) \
1077 << "GetPrimitiveArrayCritical not equal"; \
Elliott Hughes75770752011-08-24 17:52:38 -07001078 env_->ReleasePrimitiveArrayCritical(a, v, 0); \
1079 /* GetXArrayElements */ \
1080 scalar_type* xs = env_->get_elements_fn(a, NULL); \
Brian Carlstromea46f952013-07-30 01:26:50 -07001081 EXPECT_EQ(memcmp(&src_buf[0], xs, size * sizeof(scalar_type)), 0) \
1082 << # get_elements_fn " not equal"; \
Elliott Hughes75770752011-08-24 17:52:38 -07001083 env_->release_elements_fn(a, xs, 0); \
1084 EXPECT_EQ(reinterpret_cast<uintptr_t>(v), reinterpret_cast<uintptr_t>(xs))
Elliott Hughesbd935992011-08-22 11:59:34 -07001085
Elliott Hughes814e4032011-08-23 12:07:56 -07001086TEST_F(JniInternalTest, BooleanArrays) {
Brian Carlstromea46f952013-07-30 01:26:50 -07001087 EXPECT_PRIMITIVE_ARRAY(NewBooleanArray, GetBooleanArrayRegion, SetBooleanArrayRegion,
1088 GetBooleanArrayElements, ReleaseBooleanArrayElements, jboolean, "[Z");
Elliott Hughes814e4032011-08-23 12:07:56 -07001089}
1090TEST_F(JniInternalTest, ByteArrays) {
Brian Carlstromea46f952013-07-30 01:26:50 -07001091 EXPECT_PRIMITIVE_ARRAY(NewByteArray, GetByteArrayRegion, SetByteArrayRegion,
1092 GetByteArrayElements, ReleaseByteArrayElements, jbyte, "[B");
Elliott Hughes814e4032011-08-23 12:07:56 -07001093}
1094TEST_F(JniInternalTest, CharArrays) {
Brian Carlstromea46f952013-07-30 01:26:50 -07001095 EXPECT_PRIMITIVE_ARRAY(NewCharArray, GetCharArrayRegion, SetCharArrayRegion,
1096 GetCharArrayElements, ReleaseCharArrayElements, jchar, "[C");
Elliott Hughes814e4032011-08-23 12:07:56 -07001097}
1098TEST_F(JniInternalTest, DoubleArrays) {
Brian Carlstromea46f952013-07-30 01:26:50 -07001099 EXPECT_PRIMITIVE_ARRAY(NewDoubleArray, GetDoubleArrayRegion, SetDoubleArrayRegion,
1100 GetDoubleArrayElements, ReleaseDoubleArrayElements, jdouble, "[D");
Elliott Hughes814e4032011-08-23 12:07:56 -07001101}
1102TEST_F(JniInternalTest, FloatArrays) {
Brian Carlstromea46f952013-07-30 01:26:50 -07001103 EXPECT_PRIMITIVE_ARRAY(NewFloatArray, GetFloatArrayRegion, SetFloatArrayRegion,
1104 GetFloatArrayElements, ReleaseFloatArrayElements, jfloat, "[F");
Elliott Hughes814e4032011-08-23 12:07:56 -07001105}
1106TEST_F(JniInternalTest, IntArrays) {
Brian Carlstromea46f952013-07-30 01:26:50 -07001107 EXPECT_PRIMITIVE_ARRAY(NewIntArray, GetIntArrayRegion, SetIntArrayRegion,
1108 GetIntArrayElements, ReleaseIntArrayElements, jint, "[I");
Elliott Hughes814e4032011-08-23 12:07:56 -07001109}
1110TEST_F(JniInternalTest, LongArrays) {
Brian Carlstromea46f952013-07-30 01:26:50 -07001111 EXPECT_PRIMITIVE_ARRAY(NewLongArray, GetLongArrayRegion, SetLongArrayRegion,
1112 GetLongArrayElements, ReleaseLongArrayElements, jlong, "[J");
Elliott Hughes814e4032011-08-23 12:07:56 -07001113}
1114TEST_F(JniInternalTest, ShortArrays) {
Brian Carlstromea46f952013-07-30 01:26:50 -07001115 EXPECT_PRIMITIVE_ARRAY(NewShortArray, GetShortArrayRegion, SetShortArrayRegion,
1116 GetShortArrayElements, ReleaseShortArrayElements, jshort, "[S");
Elliott Hughesd8ddfd52011-08-15 14:32:53 -07001117}
1118
Elliott Hughesf2682d52011-08-15 16:37:04 -07001119TEST_F(JniInternalTest, NewObjectArray) {
1120 // TODO: death tests for negative array sizes.
1121
Elliott Hughesf2682d52011-08-15 16:37:04 -07001122 // TODO: check non-NULL initial elements.
1123
Elliott Hughesbd935992011-08-22 11:59:34 -07001124 jclass element_class = env_->FindClass("java/lang/String");
1125 ASSERT_TRUE(element_class != NULL);
1126 jclass array_class = env_->FindClass("[Ljava/lang/String;");
1127 ASSERT_TRUE(array_class != NULL);
Elliott Hughesf2682d52011-08-15 16:37:04 -07001128
Elliott Hughesbd935992011-08-22 11:59:34 -07001129 jobjectArray a;
Elliott Hughesf2682d52011-08-15 16:37:04 -07001130
Elliott Hughesbd935992011-08-22 11:59:34 -07001131 a = env_->NewObjectArray(0, element_class, NULL);
1132 EXPECT_TRUE(a != NULL);
1133 EXPECT_TRUE(env_->IsInstanceOf(a, array_class));
1134 EXPECT_EQ(0, env_->GetArrayLength(a));
1135
1136 a = env_->NewObjectArray(1, element_class, NULL);
1137 EXPECT_TRUE(a != NULL);
1138 EXPECT_TRUE(env_->IsInstanceOf(a, array_class));
1139 EXPECT_EQ(1, env_->GetArrayLength(a));
Elliott Hughes75770752011-08-24 17:52:38 -07001140 EXPECT_TRUE(env_->IsSameObject(env_->GetObjectArrayElement(a, 0), NULL));
1141
1142 jstring s = env_->NewStringUTF("poop");
1143 a = env_->NewObjectArray(2, element_class, s);
1144 EXPECT_TRUE(a != NULL);
1145 EXPECT_TRUE(env_->IsInstanceOf(a, array_class));
1146 EXPECT_EQ(2, env_->GetArrayLength(a));
1147 EXPECT_TRUE(env_->IsSameObject(env_->GetObjectArrayElement(a, 0), s));
1148 EXPECT_TRUE(env_->IsSameObject(env_->GetObjectArrayElement(a, 1), s));
Elliott Hughesbd935992011-08-22 11:59:34 -07001149}
1150
1151TEST_F(JniInternalTest, GetArrayLength) {
1152 // Already tested in NewObjectArray/NewPrimitiveArray.
Elliott Hughes8a26c5c2011-08-15 18:35:43 -07001153}
1154
Elliott Hughes37f7a402011-08-22 18:56:01 -07001155TEST_F(JniInternalTest, GetObjectClass) {
1156 jclass string_class = env_->FindClass("java/lang/String");
1157 ASSERT_TRUE(string_class != NULL);
1158 jclass class_class = env_->FindClass("java/lang/Class");
1159 ASSERT_TRUE(class_class != NULL);
1160
1161 jstring s = env_->NewStringUTF("poop");
1162 jclass c = env_->GetObjectClass(s);
1163 ASSERT_TRUE(env_->IsSameObject(string_class, c));
1164
1165 jclass c2 = env_->GetObjectClass(c);
1166 ASSERT_TRUE(env_->IsSameObject(class_class, env_->GetObjectClass(c2)));
1167}
1168
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001169TEST_F(JniInternalTest, GetSuperclass) {
1170 jclass object_class = env_->FindClass("java/lang/Object");
1171 ASSERT_TRUE(object_class != NULL);
1172 jclass string_class = env_->FindClass("java/lang/String");
1173 ASSERT_TRUE(string_class != NULL);
Ian Rogersdc180202012-01-29 14:47:29 -08001174 jclass runnable_interface = env_->FindClass("java/lang/Runnable");
1175 ASSERT_TRUE(runnable_interface != NULL);
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001176 ASSERT_TRUE(env_->IsSameObject(object_class, env_->GetSuperclass(string_class)));
1177 ASSERT_TRUE(env_->GetSuperclass(object_class) == NULL);
Ian Rogersdc180202012-01-29 14:47:29 -08001178 ASSERT_TRUE(env_->IsSameObject(object_class, env_->GetSuperclass(runnable_interface)));
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001179}
1180
Elliott Hughes37f7a402011-08-22 18:56:01 -07001181TEST_F(JniInternalTest, IsAssignableFrom) {
1182 jclass object_class = env_->FindClass("java/lang/Object");
1183 ASSERT_TRUE(object_class != NULL);
1184 jclass string_class = env_->FindClass("java/lang/String");
1185 ASSERT_TRUE(string_class != NULL);
1186
1187 ASSERT_TRUE(env_->IsAssignableFrom(object_class, string_class));
1188 ASSERT_FALSE(env_->IsAssignableFrom(string_class, object_class));
1189}
1190
Elliott Hughesb465ab02011-08-24 11:21:21 -07001191TEST_F(JniInternalTest, GetObjectRefType) {
1192 jclass local = env_->FindClass("java/lang/Object");
1193 ASSERT_TRUE(local != NULL);
1194 EXPECT_EQ(JNILocalRefType, env_->GetObjectRefType(local));
1195
1196 jobject global = env_->NewGlobalRef(local);
1197 EXPECT_EQ(JNIGlobalRefType, env_->GetObjectRefType(global));
1198
1199 jweak weak_global = env_->NewWeakGlobalRef(local);
1200 EXPECT_EQ(JNIWeakGlobalRefType, env_->GetObjectRefType(weak_global));
1201
1202 jobject invalid = reinterpret_cast<jobject>(this);
1203 EXPECT_EQ(JNIInvalidRefType, env_->GetObjectRefType(invalid));
1204
1205 // TODO: invoke a native method and test that its arguments are considered local references.
1206}
1207
Elliott Hughes8a26c5c2011-08-15 18:35:43 -07001208TEST_F(JniInternalTest, NewStringUTF) {
1209 EXPECT_TRUE(env_->NewStringUTF(NULL) == NULL);
Elliott Hughes814e4032011-08-23 12:07:56 -07001210 jstring s;
1211
1212 s = env_->NewStringUTF("");
1213 EXPECT_TRUE(s != NULL);
1214 EXPECT_EQ(0, env_->GetStringLength(s));
1215 EXPECT_EQ(0, env_->GetStringUTFLength(s));
1216 s = env_->NewStringUTF("hello");
1217 EXPECT_TRUE(s != NULL);
1218 EXPECT_EQ(5, env_->GetStringLength(s));
1219 EXPECT_EQ(5, env_->GetStringUTFLength(s));
1220
Elliott Hughes8a26c5c2011-08-15 18:35:43 -07001221 // TODO: check some non-ASCII strings.
Elliott Hughesf2682d52011-08-15 16:37:04 -07001222}
1223
Elliott Hughes814e4032011-08-23 12:07:56 -07001224TEST_F(JniInternalTest, NewString) {
Elliott Hughes814e4032011-08-23 12:07:56 -07001225 jchar chars[] = { 'h', 'i' };
1226 jstring s;
1227 s = env_->NewString(chars, 0);
1228 EXPECT_TRUE(s != NULL);
1229 EXPECT_EQ(0, env_->GetStringLength(s));
1230 EXPECT_EQ(0, env_->GetStringUTFLength(s));
1231 s = env_->NewString(chars, 2);
1232 EXPECT_TRUE(s != NULL);
1233 EXPECT_EQ(2, env_->GetStringLength(s));
1234 EXPECT_EQ(2, env_->GetStringUTFLength(s));
1235
1236 // TODO: check some non-ASCII strings.
1237}
1238
Jesse Wilson25e79a52011-11-18 15:31:58 -05001239TEST_F(JniInternalTest, NewStringNullCharsZeroLength) {
1240 jstring s = env_->NewString(NULL, 0);
1241 EXPECT_TRUE(s != NULL);
1242 EXPECT_EQ(0, env_->GetStringLength(s));
1243}
1244
Brian Carlstrom36258122011-12-09 12:55:51 -08001245// TODO: fix gtest death tests on host http://b/5690440 (and target)
1246TEST_F(JniInternalTest, DISABLED_NewStringNullCharsNonzeroLength) {
Jesse Wilson25e79a52011-11-18 15:31:58 -05001247 ASSERT_DEATH(env_->NewString(NULL, 1), "");
1248}
1249
Elliott Hughesb465ab02011-08-24 11:21:21 -07001250TEST_F(JniInternalTest, GetStringLength_GetStringUTFLength) {
1251 // Already tested in the NewString/NewStringUTF tests.
1252}
1253
1254TEST_F(JniInternalTest, GetStringRegion_GetStringUTFRegion) {
1255 jstring s = env_->NewStringUTF("hello");
1256 ASSERT_TRUE(s != NULL);
1257
1258 env_->GetStringRegion(s, -1, 0, NULL);
1259 EXPECT_EXCEPTION(sioobe_);
1260 env_->GetStringRegion(s, 0, -1, NULL);
1261 EXPECT_EXCEPTION(sioobe_);
1262 env_->GetStringRegion(s, 0, 10, NULL);
1263 EXPECT_EXCEPTION(sioobe_);
1264 env_->GetStringRegion(s, 10, 1, NULL);
1265 EXPECT_EXCEPTION(sioobe_);
1266
1267 jchar chars[4] = { 'x', 'x', 'x', 'x' };
1268 env_->GetStringRegion(s, 1, 2, &chars[1]);
1269 EXPECT_EQ('x', chars[0]);
1270 EXPECT_EQ('e', chars[1]);
1271 EXPECT_EQ('l', chars[2]);
1272 EXPECT_EQ('x', chars[3]);
1273
Elliott Hughesd7d7f6e2013-09-18 12:00:45 -07001274 // It's okay for the buffer to be NULL as long as the length is 0.
1275 env_->GetStringRegion(s, 2, 0, NULL);
1276 // Even if the offset is invalid...
1277 env_->GetStringRegion(s, 123, 0, NULL);
1278 EXPECT_EXCEPTION(sioobe_);
1279
Elliott Hughesb465ab02011-08-24 11:21:21 -07001280 env_->GetStringUTFRegion(s, -1, 0, NULL);
1281 EXPECT_EXCEPTION(sioobe_);
1282 env_->GetStringUTFRegion(s, 0, -1, NULL);
1283 EXPECT_EXCEPTION(sioobe_);
1284 env_->GetStringUTFRegion(s, 0, 10, NULL);
1285 EXPECT_EXCEPTION(sioobe_);
1286 env_->GetStringUTFRegion(s, 10, 1, NULL);
1287 EXPECT_EXCEPTION(sioobe_);
1288
1289 char bytes[4] = { 'x', 'x', 'x', 'x' };
1290 env_->GetStringUTFRegion(s, 1, 2, &bytes[1]);
1291 EXPECT_EQ('x', bytes[0]);
1292 EXPECT_EQ('e', bytes[1]);
1293 EXPECT_EQ('l', bytes[2]);
1294 EXPECT_EQ('x', bytes[3]);
Elliott Hughesd7d7f6e2013-09-18 12:00:45 -07001295
1296 // It's okay for the buffer to be NULL as long as the length is 0.
1297 env_->GetStringUTFRegion(s, 2, 0, NULL);
1298 // Even if the offset is invalid...
1299 env_->GetStringUTFRegion(s, 123, 0, NULL);
1300 EXPECT_EXCEPTION(sioobe_);
Elliott Hughesb465ab02011-08-24 11:21:21 -07001301}
1302
Elliott Hughes75770752011-08-24 17:52:38 -07001303TEST_F(JniInternalTest, GetStringUTFChars_ReleaseStringUTFChars) {
Elliott Hughes3f6635a2012-06-19 13:37:49 -07001304 // Passing in a NULL jstring is ignored normally, but caught by -Xcheck:jni.
Elliott Hughesb264f082012-04-06 17:10:10 -07001305 {
Elliott Hughesb264f082012-04-06 17:10:10 -07001306 CheckJniAbortCatcher check_jni_abort_catcher;
1307 EXPECT_TRUE(env_->GetStringUTFChars(NULL, NULL) == NULL);
Elliott Hughes56ef0422012-06-19 14:35:04 -07001308 check_jni_abort_catcher.Check("GetStringUTFChars received null jstring");
Elliott Hughesb264f082012-04-06 17:10:10 -07001309 }
Elliott Hughes75770752011-08-24 17:52:38 -07001310
1311 jstring s = env_->NewStringUTF("hello");
1312 ASSERT_TRUE(s != NULL);
1313
1314 const char* utf = env_->GetStringUTFChars(s, NULL);
1315 EXPECT_STREQ("hello", utf);
1316 env_->ReleaseStringUTFChars(s, utf);
1317
1318 jboolean is_copy = JNI_FALSE;
1319 utf = env_->GetStringUTFChars(s, &is_copy);
1320 EXPECT_EQ(JNI_TRUE, is_copy);
1321 EXPECT_STREQ("hello", utf);
1322 env_->ReleaseStringUTFChars(s, utf);
1323}
1324
1325TEST_F(JniInternalTest, GetStringChars_ReleaseStringChars) {
1326 jstring s = env_->NewStringUTF("hello");
1327 ASSERT_TRUE(s != NULL);
1328
1329 jchar expected[] = { 'h', 'e', 'l', 'l', 'o' };
1330 const jchar* chars = env_->GetStringChars(s, NULL);
1331 EXPECT_EQ(expected[0], chars[0]);
1332 EXPECT_EQ(expected[1], chars[1]);
1333 EXPECT_EQ(expected[2], chars[2]);
1334 EXPECT_EQ(expected[3], chars[3]);
1335 EXPECT_EQ(expected[4], chars[4]);
1336 env_->ReleaseStringChars(s, chars);
1337
1338 jboolean is_copy = JNI_FALSE;
1339 chars = env_->GetStringChars(s, &is_copy);
1340 EXPECT_EQ(JNI_FALSE, is_copy);
1341 EXPECT_EQ(expected[0], chars[0]);
1342 EXPECT_EQ(expected[1], chars[1]);
1343 EXPECT_EQ(expected[2], chars[2]);
1344 EXPECT_EQ(expected[3], chars[3]);
1345 EXPECT_EQ(expected[4], chars[4]);
1346 env_->ReleaseStringChars(s, chars);
1347}
1348
1349TEST_F(JniInternalTest, GetStringCritical_ReleaseStringCritical) {
1350 jstring s = env_->NewStringUTF("hello");
1351 ASSERT_TRUE(s != NULL);
1352
1353 jchar expected[] = { 'h', 'e', 'l', 'l', 'o' };
1354 const jchar* chars = env_->GetStringCritical(s, NULL);
1355 EXPECT_EQ(expected[0], chars[0]);
1356 EXPECT_EQ(expected[1], chars[1]);
1357 EXPECT_EQ(expected[2], chars[2]);
1358 EXPECT_EQ(expected[3], chars[3]);
1359 EXPECT_EQ(expected[4], chars[4]);
1360 env_->ReleaseStringCritical(s, chars);
1361
1362 jboolean is_copy = JNI_FALSE;
1363 chars = env_->GetStringCritical(s, &is_copy);
1364 EXPECT_EQ(JNI_FALSE, is_copy);
1365 EXPECT_EQ(expected[0], chars[0]);
1366 EXPECT_EQ(expected[1], chars[1]);
1367 EXPECT_EQ(expected[2], chars[2]);
1368 EXPECT_EQ(expected[3], chars[3]);
1369 EXPECT_EQ(expected[4], chars[4]);
1370 env_->ReleaseStringCritical(s, chars);
1371}
1372
Elliott Hughes814e4032011-08-23 12:07:56 -07001373TEST_F(JniInternalTest, GetObjectArrayElement_SetObjectArrayElement) {
Elliott Hughesb264f082012-04-06 17:10:10 -07001374 jclass java_lang_Class = env_->FindClass("java/lang/Class");
1375 ASSERT_TRUE(java_lang_Class != NULL);
Elliott Hughes289da822011-08-16 10:11:20 -07001376
Elliott Hughesb264f082012-04-06 17:10:10 -07001377 jobjectArray array = env_->NewObjectArray(1, java_lang_Class, NULL);
Elliott Hughes289da822011-08-16 10:11:20 -07001378 EXPECT_TRUE(array != NULL);
Elliott Hughes814e4032011-08-23 12:07:56 -07001379 EXPECT_TRUE(env_->GetObjectArrayElement(array, 0) == NULL);
Elliott Hughesb264f082012-04-06 17:10:10 -07001380 env_->SetObjectArrayElement(array, 0, java_lang_Class);
1381 EXPECT_TRUE(env_->IsSameObject(env_->GetObjectArrayElement(array, 0), java_lang_Class));
Elliott Hughesa5b897e2011-08-16 11:33:06 -07001382
1383 // ArrayIndexOutOfBounds for negative index.
Elliott Hughesb264f082012-04-06 17:10:10 -07001384 env_->SetObjectArrayElement(array, -1, java_lang_Class);
Elliott Hughes814e4032011-08-23 12:07:56 -07001385 EXPECT_EXCEPTION(aioobe_);
Elliott Hughesa5b897e2011-08-16 11:33:06 -07001386
1387 // ArrayIndexOutOfBounds for too-large index.
Elliott Hughesb264f082012-04-06 17:10:10 -07001388 env_->SetObjectArrayElement(array, 1, java_lang_Class);
Elliott Hughes814e4032011-08-23 12:07:56 -07001389 EXPECT_EXCEPTION(aioobe_);
Elliott Hughesa5b897e2011-08-16 11:33:06 -07001390
Elliott Hughesb264f082012-04-06 17:10:10 -07001391 // ArrayStoreException thrown for bad types.
1392 env_->SetObjectArrayElement(array, 0, env_->NewStringUTF("not a jclass!"));
1393 EXPECT_EXCEPTION(ase_);
Elliott Hughes289da822011-08-16 10:11:20 -07001394}
1395
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001396#define EXPECT_STATIC_PRIMITIVE_FIELD(type, field_name, sig, value1, value2) \
1397 do { \
1398 jfieldID fid = env_->GetStaticFieldID(c, field_name, sig); \
1399 EXPECT_TRUE(fid != NULL); \
1400 env_->SetStatic ## type ## Field(c, fid, value1); \
Brian Carlstrom2e3d1b22012-01-09 18:01:56 -08001401 EXPECT_TRUE(value1 == env_->GetStatic ## type ## Field(c, fid)); \
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001402 env_->SetStatic ## type ## Field(c, fid, value2); \
Brian Carlstrom2e3d1b22012-01-09 18:01:56 -08001403 EXPECT_TRUE(value2 == env_->GetStatic ## type ## Field(c, fid)); \
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001404 } while (false)
1405
1406#define EXPECT_PRIMITIVE_FIELD(instance, type, field_name, sig, value1, value2) \
1407 do { \
1408 jfieldID fid = env_->GetFieldID(c, field_name, sig); \
1409 EXPECT_TRUE(fid != NULL); \
1410 env_->Set ## type ## Field(instance, fid, value1); \
Brian Carlstrom2e3d1b22012-01-09 18:01:56 -08001411 EXPECT_TRUE(value1 == env_->Get ## type ## Field(instance, fid)); \
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001412 env_->Set ## type ## Field(instance, fid, value2); \
Brian Carlstrom2e3d1b22012-01-09 18:01:56 -08001413 EXPECT_TRUE(value2 == env_->Get ## type ## Field(instance, fid)); \
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001414 } while (false)
1415
1416
Ian Rogersc928de92013-02-27 14:30:44 -08001417#if !defined(ART_USE_PORTABLE_COMPILER)
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001418TEST_F(JniInternalTest, GetPrimitiveField_SetPrimitiveField) {
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001419 Thread::Current()->TransitionFromSuspendedToRunnable();
1420 LoadDex("AllFields");
Brian Carlstrombd86bcc2013-03-10 20:26:16 -07001421 bool started = runtime_->Start();
1422 CHECK(started);
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001423
1424 jclass c = env_->FindClass("AllFields");
1425 ASSERT_TRUE(c != NULL);
1426 jobject o = env_->AllocObject(c);
1427 ASSERT_TRUE(o != NULL);
1428
1429 EXPECT_STATIC_PRIMITIVE_FIELD(Boolean, "sZ", "Z", true, false);
1430 EXPECT_STATIC_PRIMITIVE_FIELD(Byte, "sB", "B", 1, 2);
1431 EXPECT_STATIC_PRIMITIVE_FIELD(Char, "sC", "C", 'a', 'b');
1432 EXPECT_STATIC_PRIMITIVE_FIELD(Double, "sD", "D", 1.0, 2.0);
1433 EXPECT_STATIC_PRIMITIVE_FIELD(Float, "sF", "F", 1.0, 2.0);
1434 EXPECT_STATIC_PRIMITIVE_FIELD(Int, "sI", "I", 1, 2);
1435 EXPECT_STATIC_PRIMITIVE_FIELD(Long, "sJ", "J", 1, 2);
1436 EXPECT_STATIC_PRIMITIVE_FIELD(Short, "sS", "S", 1, 2);
1437
1438 EXPECT_PRIMITIVE_FIELD(o, Boolean, "iZ", "Z", true, false);
1439 EXPECT_PRIMITIVE_FIELD(o, Byte, "iB", "B", 1, 2);
1440 EXPECT_PRIMITIVE_FIELD(o, Char, "iC", "C", 'a', 'b');
1441 EXPECT_PRIMITIVE_FIELD(o, Double, "iD", "D", 1.0, 2.0);
1442 EXPECT_PRIMITIVE_FIELD(o, Float, "iF", "F", 1.0, 2.0);
1443 EXPECT_PRIMITIVE_FIELD(o, Int, "iI", "I", 1, 2);
1444 EXPECT_PRIMITIVE_FIELD(o, Long, "iJ", "J", 1, 2);
1445 EXPECT_PRIMITIVE_FIELD(o, Short, "iS", "S", 1, 2);
1446}
1447
1448TEST_F(JniInternalTest, GetObjectField_SetObjectField) {
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001449 Thread::Current()->TransitionFromSuspendedToRunnable();
1450 LoadDex("AllFields");
Brian Carlstrom25c33252011-09-18 15:58:35 -07001451 runtime_->Start();
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001452
1453 jclass c = env_->FindClass("AllFields");
1454 ASSERT_TRUE(c != NULL);
1455 jobject o = env_->AllocObject(c);
1456 ASSERT_TRUE(o != NULL);
1457
1458 jstring s1 = env_->NewStringUTF("hello");
1459 ASSERT_TRUE(s1 != NULL);
1460 jstring s2 = env_->NewStringUTF("world");
1461 ASSERT_TRUE(s2 != NULL);
1462
1463 jfieldID s_fid = env_->GetStaticFieldID(c, "sObject", "Ljava/lang/Object;");
1464 ASSERT_TRUE(s_fid != NULL);
1465 jfieldID i_fid = env_->GetFieldID(c, "iObject", "Ljava/lang/Object;");
1466 ASSERT_TRUE(i_fid != NULL);
1467
1468 env_->SetStaticObjectField(c, s_fid, s1);
1469 ASSERT_TRUE(env_->IsSameObject(s1, env_->GetStaticObjectField(c, s_fid)));
1470 env_->SetStaticObjectField(c, s_fid, s2);
1471 ASSERT_TRUE(env_->IsSameObject(s2, env_->GetStaticObjectField(c, s_fid)));
1472
1473 env_->SetObjectField(o, i_fid, s1);
1474 ASSERT_TRUE(env_->IsSameObject(s1, env_->GetObjectField(o, i_fid)));
1475 env_->SetObjectField(o, i_fid, s2);
1476 ASSERT_TRUE(env_->IsSameObject(s2, env_->GetObjectField(o, i_fid)));
1477}
Shih-wei Liao5b8b1ed2012-02-23 23:48:21 -08001478#endif
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001479
Elliott Hughes18c07532011-08-18 15:50:51 -07001480TEST_F(JniInternalTest, NewLocalRef_NULL) {
1481 EXPECT_TRUE(env_->NewLocalRef(NULL) == NULL);
1482}
1483
1484TEST_F(JniInternalTest, NewLocalRef) {
1485 jstring s = env_->NewStringUTF("");
1486 ASSERT_TRUE(s != NULL);
1487 jobject o = env_->NewLocalRef(s);
1488 EXPECT_TRUE(o != NULL);
1489 EXPECT_TRUE(o != s);
1490
Elliott Hughes2ced6a52011-10-16 18:44:48 -07001491 EXPECT_EQ(JNILocalRefType, env_->GetObjectRefType(o));
Elliott Hughes18c07532011-08-18 15:50:51 -07001492}
1493
1494TEST_F(JniInternalTest, DeleteLocalRef_NULL) {
1495 env_->DeleteLocalRef(NULL);
1496}
1497
1498TEST_F(JniInternalTest, DeleteLocalRef) {
1499 jstring s = env_->NewStringUTF("");
1500 ASSERT_TRUE(s != NULL);
1501 env_->DeleteLocalRef(s);
1502
Elliott Hughes3f6635a2012-06-19 13:37:49 -07001503 // Currently, deleting an already-deleted reference is just a CheckJNI warning.
Elliott Hughesb264f082012-04-06 17:10:10 -07001504 {
Elliott Hughesb264f082012-04-06 17:10:10 -07001505 CheckJniAbortCatcher check_jni_abort_catcher;
1506 env_->DeleteLocalRef(s);
Elliott Hughesa9137c62013-01-09 10:55:21 -08001507
Brian Carlstromea46f952013-07-30 01:26:50 -07001508 std::string expected(StringPrintf("native code passing in reference to "
1509 "invalid local reference: %p", s));
Elliott Hughesa9137c62013-01-09 10:55:21 -08001510 check_jni_abort_catcher.Check(expected.c_str());
Elliott Hughesb264f082012-04-06 17:10:10 -07001511 }
Elliott Hughes18c07532011-08-18 15:50:51 -07001512
1513 s = env_->NewStringUTF("");
1514 ASSERT_TRUE(s != NULL);
1515 jobject o = env_->NewLocalRef(s);
1516 ASSERT_TRUE(o != NULL);
1517
1518 env_->DeleteLocalRef(s);
1519 env_->DeleteLocalRef(o);
1520}
1521
Elliott Hughesaa836f72013-08-20 16:57:23 -07001522TEST_F(JniInternalTest, PushLocalFrame_10395422) {
1523 // The JNI specification is ambiguous about whether the given capacity is to be interpreted as a
1524 // maximum or as a minimum, but it seems like it's supposed to be a minimum, and that's how
1525 // Android historically treated it, and it's how the RI treats it. It's also the more useful
1526 // interpretation!
1527 ASSERT_EQ(JNI_OK, env_->PushLocalFrame(0));
1528 env_->PopLocalFrame(NULL);
1529
1530 // Negative capacities are not allowed.
1531 ASSERT_EQ(JNI_ERR, env_->PushLocalFrame(-1));
1532
1533 // And it's okay to have an upper limit. Ours is currently 512.
1534 ASSERT_EQ(JNI_ERR, env_->PushLocalFrame(8192));
1535}
1536
Elliott Hughes2ced6a52011-10-16 18:44:48 -07001537TEST_F(JniInternalTest, PushLocalFrame_PopLocalFrame) {
1538 jobject original = env_->NewStringUTF("");
1539 ASSERT_TRUE(original != NULL);
1540
1541 jobject outer;
1542 jobject inner1, inner2;
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001543 ScopedObjectAccess soa(env_);
Ian Rogers2dd0e2c2013-01-24 12:42:14 -08001544 mirror::Object* inner2_direct_pointer;
Elliott Hughes2ced6a52011-10-16 18:44:48 -07001545 {
Elliott Hughesaa836f72013-08-20 16:57:23 -07001546 ASSERT_EQ(JNI_OK, env_->PushLocalFrame(4));
Elliott Hughes2ced6a52011-10-16 18:44:48 -07001547 outer = env_->NewLocalRef(original);
1548
1549 {
Elliott Hughesaa836f72013-08-20 16:57:23 -07001550 ASSERT_EQ(JNI_OK, env_->PushLocalFrame(4));
Elliott Hughes2ced6a52011-10-16 18:44:48 -07001551 inner1 = env_->NewLocalRef(outer);
1552 inner2 = env_->NewStringUTF("survivor");
Ian Rogers2dd0e2c2013-01-24 12:42:14 -08001553 inner2_direct_pointer = soa.Decode<mirror::Object*>(inner2);
Elliott Hughes2ced6a52011-10-16 18:44:48 -07001554 env_->PopLocalFrame(inner2);
1555 }
1556
1557 EXPECT_EQ(JNILocalRefType, env_->GetObjectRefType(original));
1558 EXPECT_EQ(JNILocalRefType, env_->GetObjectRefType(outer));
1559 EXPECT_EQ(JNIInvalidRefType, env_->GetObjectRefType(inner1));
1560
1561 // Our local reference for the survivor is invalid because the survivor
1562 // gets a new local reference...
1563 EXPECT_EQ(JNIInvalidRefType, env_->GetObjectRefType(inner2));
1564 // ...but the survivor should be in the local reference table.
Brian Carlstrom4d571432012-05-16 00:21:41 -07001565 JNIEnvExt* env = reinterpret_cast<JNIEnvExt*>(env_);
1566 EXPECT_TRUE(env->locals.ContainsDirectPointer(inner2_direct_pointer));
Elliott Hughes2ced6a52011-10-16 18:44:48 -07001567
1568 env_->PopLocalFrame(NULL);
1569 }
1570 EXPECT_EQ(JNILocalRefType, env_->GetObjectRefType(original));
1571 EXPECT_EQ(JNIInvalidRefType, env_->GetObjectRefType(outer));
1572 EXPECT_EQ(JNIInvalidRefType, env_->GetObjectRefType(inner1));
1573 EXPECT_EQ(JNIInvalidRefType, env_->GetObjectRefType(inner2));
1574}
1575
Elliott Hughes18c07532011-08-18 15:50:51 -07001576TEST_F(JniInternalTest, NewGlobalRef_NULL) {
1577 EXPECT_TRUE(env_->NewGlobalRef(NULL) == NULL);
1578}
1579
1580TEST_F(JniInternalTest, NewGlobalRef) {
1581 jstring s = env_->NewStringUTF("");
1582 ASSERT_TRUE(s != NULL);
1583 jobject o = env_->NewGlobalRef(s);
1584 EXPECT_TRUE(o != NULL);
1585 EXPECT_TRUE(o != s);
1586
1587 // TODO: check that o is a global reference.
1588}
1589
1590TEST_F(JniInternalTest, DeleteGlobalRef_NULL) {
1591 env_->DeleteGlobalRef(NULL);
1592}
1593
1594TEST_F(JniInternalTest, DeleteGlobalRef) {
1595 jstring s = env_->NewStringUTF("");
1596 ASSERT_TRUE(s != NULL);
1597
1598 jobject o = env_->NewGlobalRef(s);
1599 ASSERT_TRUE(o != NULL);
1600 env_->DeleteGlobalRef(o);
1601
Elliott Hughes3f6635a2012-06-19 13:37:49 -07001602 // Currently, deleting an already-deleted reference is just a CheckJNI warning.
Elliott Hughesb264f082012-04-06 17:10:10 -07001603 {
Elliott Hughesb264f082012-04-06 17:10:10 -07001604 CheckJniAbortCatcher check_jni_abort_catcher;
1605 env_->DeleteGlobalRef(o);
Elliott Hughesa9137c62013-01-09 10:55:21 -08001606
Brian Carlstromea46f952013-07-30 01:26:50 -07001607 std::string expected(StringPrintf("native code passing in reference to "
1608 "invalid global reference: %p", o));
Elliott Hughesa9137c62013-01-09 10:55:21 -08001609 check_jni_abort_catcher.Check(expected.c_str());
Elliott Hughesb264f082012-04-06 17:10:10 -07001610 }
Elliott Hughes18c07532011-08-18 15:50:51 -07001611
1612 jobject o1 = env_->NewGlobalRef(s);
1613 ASSERT_TRUE(o1 != NULL);
1614 jobject o2 = env_->NewGlobalRef(s);
1615 ASSERT_TRUE(o2 != NULL);
1616
1617 env_->DeleteGlobalRef(o1);
1618 env_->DeleteGlobalRef(o2);
1619}
1620
1621TEST_F(JniInternalTest, NewWeakGlobalRef_NULL) {
1622 EXPECT_TRUE(env_->NewWeakGlobalRef(NULL) == NULL);
1623}
1624
1625TEST_F(JniInternalTest, NewWeakGlobalRef) {
1626 jstring s = env_->NewStringUTF("");
1627 ASSERT_TRUE(s != NULL);
1628 jobject o = env_->NewWeakGlobalRef(s);
1629 EXPECT_TRUE(o != NULL);
1630 EXPECT_TRUE(o != s);
1631
1632 // TODO: check that o is a weak global reference.
1633}
1634
1635TEST_F(JniInternalTest, DeleteWeakGlobalRef_NULL) {
1636 env_->DeleteWeakGlobalRef(NULL);
1637}
1638
1639TEST_F(JniInternalTest, DeleteWeakGlobalRef) {
1640 jstring s = env_->NewStringUTF("");
1641 ASSERT_TRUE(s != NULL);
1642
1643 jobject o = env_->NewWeakGlobalRef(s);
1644 ASSERT_TRUE(o != NULL);
1645 env_->DeleteWeakGlobalRef(o);
1646
Elliott Hughes3f6635a2012-06-19 13:37:49 -07001647 // Currently, deleting an already-deleted reference is just a CheckJNI warning.
Elliott Hughesb264f082012-04-06 17:10:10 -07001648 {
Elliott Hughesb264f082012-04-06 17:10:10 -07001649 CheckJniAbortCatcher check_jni_abort_catcher;
1650 env_->DeleteWeakGlobalRef(o);
Elliott Hughesa9137c62013-01-09 10:55:21 -08001651
Brian Carlstromea46f952013-07-30 01:26:50 -07001652 std::string expected(StringPrintf("native code passing in reference to "
1653 "invalid weak global reference: %p", o));
Elliott Hughesa9137c62013-01-09 10:55:21 -08001654 check_jni_abort_catcher.Check(expected.c_str());
Elliott Hughesb264f082012-04-06 17:10:10 -07001655 }
Elliott Hughes18c07532011-08-18 15:50:51 -07001656
1657 jobject o1 = env_->NewWeakGlobalRef(s);
1658 ASSERT_TRUE(o1 != NULL);
1659 jobject o2 = env_->NewWeakGlobalRef(s);
1660 ASSERT_TRUE(o2 != NULL);
1661
1662 env_->DeleteWeakGlobalRef(o1);
1663 env_->DeleteWeakGlobalRef(o2);
1664}
1665
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001666TEST_F(JniInternalTest, StaticMainMethod) {
Brian Carlstrom265091e2013-01-30 14:08:26 -08001667 TEST_DISABLED_FOR_PORTABLE();
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001668 ScopedObjectAccess soa(Thread::Current());
1669 jobject jclass_loader = LoadDex("Main");
Ian Rogers2dd0e2c2013-01-24 12:42:14 -08001670 SirtRef<mirror::ClassLoader>
1671 class_loader(soa.Self(), soa.Decode<mirror::ClassLoader*>(jclass_loader));
Brian Carlstrom40381fb2011-10-19 14:13:40 -07001672 CompileDirectMethod(class_loader.get(), "Main", "main", "([Ljava/lang/String;)V");
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001673
Ian Rogers2dd0e2c2013-01-24 12:42:14 -08001674 mirror::Class* klass = class_linker_->FindClass("LMain;", class_loader.get());
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001675 ASSERT_TRUE(klass != NULL);
1676
Brian Carlstromea46f952013-07-30 01:26:50 -07001677 mirror::ArtMethod* method = klass->FindDirectMethod("main", "([Ljava/lang/String;)V");
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001678 ASSERT_TRUE(method != NULL);
1679
Jeff Hao5d917302013-02-27 17:57:33 -08001680 ArgArray arg_array(NULL, 0);
1681 arg_array.Append(0);
1682 JValue result;
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001683
Sebastien Hertzb95851f2013-03-29 10:36:40 +01001684 // Start runtime.
1685 bool started = runtime_->Start();
1686 CHECK(started);
1687 Thread::Current()->TransitionFromSuspendedToRunnable();
1688
1689 method->Invoke(Thread::Current(), arg_array.GetArray(), arg_array.GetNumBytes(), &result, 'V');
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001690}
1691
1692TEST_F(JniInternalTest, StaticNopMethod) {
Brian Carlstrom265091e2013-01-30 14:08:26 -08001693 TEST_DISABLED_FOR_PORTABLE();
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001694 ScopedObjectAccess soa(Thread::Current());
Elliott Hughes77405792012-03-15 15:22:12 -07001695 InvokeNopMethod(true);
1696}
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001697
Elliott Hughes77405792012-03-15 15:22:12 -07001698TEST_F(JniInternalTest, NonStaticNopMethod) {
Brian Carlstrom265091e2013-01-30 14:08:26 -08001699 TEST_DISABLED_FOR_PORTABLE();
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001700 ScopedObjectAccess soa(Thread::Current());
Elliott Hughes77405792012-03-15 15:22:12 -07001701 InvokeNopMethod(false);
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001702}
1703
1704TEST_F(JniInternalTest, StaticIdentityByteMethod) {
Brian Carlstrom265091e2013-01-30 14:08:26 -08001705 TEST_DISABLED_FOR_PORTABLE();
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001706 ScopedObjectAccess soa(Thread::Current());
Elliott Hughes77405792012-03-15 15:22:12 -07001707 InvokeIdentityByteMethod(true);
1708}
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001709
Elliott Hughes77405792012-03-15 15:22:12 -07001710TEST_F(JniInternalTest, NonStaticIdentityByteMethod) {
Brian Carlstrom265091e2013-01-30 14:08:26 -08001711 TEST_DISABLED_FOR_PORTABLE();
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001712 ScopedObjectAccess soa(Thread::Current());
Elliott Hughes77405792012-03-15 15:22:12 -07001713 InvokeIdentityByteMethod(false);
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001714}
1715
1716TEST_F(JniInternalTest, StaticIdentityIntMethod) {
Brian Carlstrom265091e2013-01-30 14:08:26 -08001717 TEST_DISABLED_FOR_PORTABLE();
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001718 ScopedObjectAccess soa(Thread::Current());
Elliott Hughes77405792012-03-15 15:22:12 -07001719 InvokeIdentityIntMethod(true);
1720}
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001721
Elliott Hughes77405792012-03-15 15:22:12 -07001722TEST_F(JniInternalTest, NonStaticIdentityIntMethod) {
Brian Carlstrom265091e2013-01-30 14:08:26 -08001723 TEST_DISABLED_FOR_PORTABLE();
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001724 ScopedObjectAccess soa(Thread::Current());
Elliott Hughes77405792012-03-15 15:22:12 -07001725 InvokeIdentityIntMethod(false);
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001726}
1727
1728TEST_F(JniInternalTest, StaticIdentityDoubleMethod) {
Brian Carlstrom265091e2013-01-30 14:08:26 -08001729 TEST_DISABLED_FOR_PORTABLE();
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001730 ScopedObjectAccess soa(Thread::Current());
Elliott Hughes77405792012-03-15 15:22:12 -07001731 InvokeIdentityDoubleMethod(true);
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001732}
1733
Elliott Hughes77405792012-03-15 15:22:12 -07001734TEST_F(JniInternalTest, NonStaticIdentityDoubleMethod) {
Brian Carlstrom265091e2013-01-30 14:08:26 -08001735 TEST_DISABLED_FOR_PORTABLE();
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001736 ScopedObjectAccess soa(Thread::Current());
Elliott Hughes77405792012-03-15 15:22:12 -07001737 InvokeIdentityDoubleMethod(false);
Shih-wei Liao5b8b1ed2012-02-23 23:48:21 -08001738}
1739
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001740TEST_F(JniInternalTest, StaticSumIntIntMethod) {
Brian Carlstrom265091e2013-01-30 14:08:26 -08001741 TEST_DISABLED_FOR_PORTABLE();
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001742 ScopedObjectAccess soa(Thread::Current());
Elliott Hughes77405792012-03-15 15:22:12 -07001743 InvokeSumIntIntMethod(true);
1744}
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001745
Elliott Hughes77405792012-03-15 15:22:12 -07001746TEST_F(JniInternalTest, NonStaticSumIntIntMethod) {
Brian Carlstrom265091e2013-01-30 14:08:26 -08001747 TEST_DISABLED_FOR_PORTABLE();
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001748 ScopedObjectAccess soa(Thread::Current());
Elliott Hughes77405792012-03-15 15:22:12 -07001749 InvokeSumIntIntMethod(false);
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001750}
1751
1752TEST_F(JniInternalTest, StaticSumIntIntIntMethod) {
Brian Carlstrom265091e2013-01-30 14:08:26 -08001753 TEST_DISABLED_FOR_PORTABLE();
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001754 ScopedObjectAccess soa(Thread::Current());
Elliott Hughes77405792012-03-15 15:22:12 -07001755 InvokeSumIntIntIntMethod(true);
1756}
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001757
Elliott Hughes77405792012-03-15 15:22:12 -07001758TEST_F(JniInternalTest, NonStaticSumIntIntIntMethod) {
Brian Carlstrom265091e2013-01-30 14:08:26 -08001759 TEST_DISABLED_FOR_PORTABLE();
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001760 ScopedObjectAccess soa(Thread::Current());
Elliott Hughes77405792012-03-15 15:22:12 -07001761 InvokeSumIntIntIntMethod(false);
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001762}
1763
1764TEST_F(JniInternalTest, StaticSumIntIntIntIntMethod) {
Brian Carlstrom265091e2013-01-30 14:08:26 -08001765 TEST_DISABLED_FOR_PORTABLE();
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001766 ScopedObjectAccess soa(Thread::Current());
Elliott Hughes77405792012-03-15 15:22:12 -07001767 InvokeSumIntIntIntIntMethod(true);
1768}
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001769
Elliott Hughes77405792012-03-15 15:22:12 -07001770TEST_F(JniInternalTest, NonStaticSumIntIntIntIntMethod) {
Brian Carlstrom265091e2013-01-30 14:08:26 -08001771 TEST_DISABLED_FOR_PORTABLE();
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001772 ScopedObjectAccess soa(Thread::Current());
Elliott Hughes77405792012-03-15 15:22:12 -07001773 InvokeSumIntIntIntIntMethod(false);
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001774}
1775
1776TEST_F(JniInternalTest, StaticSumIntIntIntIntIntMethod) {
Brian Carlstrom265091e2013-01-30 14:08:26 -08001777 TEST_DISABLED_FOR_PORTABLE();
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001778 ScopedObjectAccess soa(Thread::Current());
Elliott Hughes77405792012-03-15 15:22:12 -07001779 InvokeSumIntIntIntIntIntMethod(true);
1780}
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001781
Elliott Hughes77405792012-03-15 15:22:12 -07001782TEST_F(JniInternalTest, NonStaticSumIntIntIntIntIntMethod) {
Brian Carlstrom265091e2013-01-30 14:08:26 -08001783 TEST_DISABLED_FOR_PORTABLE();
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001784 ScopedObjectAccess soa(Thread::Current());
Elliott Hughes77405792012-03-15 15:22:12 -07001785 InvokeSumIntIntIntIntIntMethod(false);
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001786}
1787
1788TEST_F(JniInternalTest, StaticSumDoubleDoubleMethod) {
Brian Carlstrom265091e2013-01-30 14:08:26 -08001789 TEST_DISABLED_FOR_PORTABLE();
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001790 ScopedObjectAccess soa(Thread::Current());
Elliott Hughes77405792012-03-15 15:22:12 -07001791 InvokeSumDoubleDoubleMethod(true);
1792}
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001793
Elliott Hughes77405792012-03-15 15:22:12 -07001794TEST_F(JniInternalTest, NonStaticSumDoubleDoubleMethod) {
Brian Carlstrom265091e2013-01-30 14:08:26 -08001795 TEST_DISABLED_FOR_PORTABLE();
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001796 ScopedObjectAccess soa(Thread::Current());
Elliott Hughes77405792012-03-15 15:22:12 -07001797 InvokeSumDoubleDoubleMethod(false);
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001798}
1799
1800TEST_F(JniInternalTest, StaticSumDoubleDoubleDoubleMethod) {
Brian Carlstrom265091e2013-01-30 14:08:26 -08001801 TEST_DISABLED_FOR_PORTABLE();
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001802 ScopedObjectAccess soa(Thread::Current());
Elliott Hughes77405792012-03-15 15:22:12 -07001803 InvokeSumDoubleDoubleDoubleMethod(true);
1804}
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001805
Elliott Hughes77405792012-03-15 15:22:12 -07001806TEST_F(JniInternalTest, NonStaticSumDoubleDoubleDoubleMethod) {
Brian Carlstrom265091e2013-01-30 14:08:26 -08001807 TEST_DISABLED_FOR_PORTABLE();
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001808 ScopedObjectAccess soa(Thread::Current());
Elliott Hughes77405792012-03-15 15:22:12 -07001809 InvokeSumDoubleDoubleDoubleMethod(false);
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001810}
1811
1812TEST_F(JniInternalTest, StaticSumDoubleDoubleDoubleDoubleMethod) {
Brian Carlstrom265091e2013-01-30 14:08:26 -08001813 TEST_DISABLED_FOR_PORTABLE();
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001814 ScopedObjectAccess soa(Thread::Current());
Elliott Hughes77405792012-03-15 15:22:12 -07001815 InvokeSumDoubleDoubleDoubleDoubleMethod(true);
1816}
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001817
Elliott Hughes77405792012-03-15 15:22:12 -07001818TEST_F(JniInternalTest, NonStaticSumDoubleDoubleDoubleDoubleMethod) {
Brian Carlstrom265091e2013-01-30 14:08:26 -08001819 TEST_DISABLED_FOR_PORTABLE();
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001820 ScopedObjectAccess soa(Thread::Current());
Elliott Hughes77405792012-03-15 15:22:12 -07001821 InvokeSumDoubleDoubleDoubleDoubleMethod(false);
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001822}
1823
1824TEST_F(JniInternalTest, StaticSumDoubleDoubleDoubleDoubleDoubleMethod) {
Brian Carlstrom265091e2013-01-30 14:08:26 -08001825 TEST_DISABLED_FOR_PORTABLE();
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001826 ScopedObjectAccess soa(Thread::Current());
Elliott Hughes77405792012-03-15 15:22:12 -07001827 InvokeSumDoubleDoubleDoubleDoubleDoubleMethod(true);
1828}
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001829
Elliott Hughes77405792012-03-15 15:22:12 -07001830TEST_F(JniInternalTest, NonStaticSumDoubleDoubleDoubleDoubleDoubleMethod) {
Brian Carlstrom265091e2013-01-30 14:08:26 -08001831 TEST_DISABLED_FOR_PORTABLE();
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001832 ScopedObjectAccess soa(Thread::Current());
Elliott Hughes77405792012-03-15 15:22:12 -07001833 InvokeSumDoubleDoubleDoubleDoubleDoubleMethod(false);
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001834}
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001835
Elliott Hughes37f7a402011-08-22 18:56:01 -07001836TEST_F(JniInternalTest, Throw) {
1837 EXPECT_EQ(JNI_ERR, env_->Throw(NULL));
1838
1839 jclass exception_class = env_->FindClass("java/lang/RuntimeException");
1840 ASSERT_TRUE(exception_class != NULL);
1841 jthrowable exception = reinterpret_cast<jthrowable>(env_->AllocObject(exception_class));
1842 ASSERT_TRUE(exception != NULL);
1843
1844 EXPECT_EQ(JNI_OK, env_->Throw(exception));
1845 EXPECT_TRUE(env_->ExceptionCheck());
Elliott Hughesa2501992011-08-26 19:39:54 -07001846 jthrowable thrown_exception = env_->ExceptionOccurred();
Elliott Hughes37f7a402011-08-22 18:56:01 -07001847 env_->ExceptionClear();
Elliott Hughesa2501992011-08-26 19:39:54 -07001848 EXPECT_TRUE(env_->IsSameObject(exception, thrown_exception));
Elliott Hughes37f7a402011-08-22 18:56:01 -07001849}
1850
1851TEST_F(JniInternalTest, ThrowNew) {
1852 EXPECT_EQ(JNI_ERR, env_->Throw(NULL));
1853
1854 jclass exception_class = env_->FindClass("java/lang/RuntimeException");
1855 ASSERT_TRUE(exception_class != NULL);
1856
Elliott Hughes5cb5ad22011-10-02 12:13:39 -07001857 jthrowable thrown_exception;
1858
Elliott Hughes37f7a402011-08-22 18:56:01 -07001859 EXPECT_EQ(JNI_OK, env_->ThrowNew(exception_class, "hello world"));
1860 EXPECT_TRUE(env_->ExceptionCheck());
Elliott Hughes5cb5ad22011-10-02 12:13:39 -07001861 thrown_exception = env_->ExceptionOccurred();
1862 env_->ExceptionClear();
1863 EXPECT_TRUE(env_->IsInstanceOf(thrown_exception, exception_class));
1864
1865 EXPECT_EQ(JNI_OK, env_->ThrowNew(exception_class, NULL));
1866 EXPECT_TRUE(env_->ExceptionCheck());
1867 thrown_exception = env_->ExceptionOccurred();
Elliott Hughes37f7a402011-08-22 18:56:01 -07001868 env_->ExceptionClear();
Elliott Hughesa2501992011-08-26 19:39:54 -07001869 EXPECT_TRUE(env_->IsInstanceOf(thrown_exception, exception_class));
Elliott Hughes37f7a402011-08-22 18:56:01 -07001870}
1871
Elliott Hughesb465ab02011-08-24 11:21:21 -07001872// TODO: this test is DISABLED until we can actually run java.nio.Buffer's <init>.
1873TEST_F(JniInternalTest, DISABLED_NewDirectBuffer_GetDirectBufferAddress_GetDirectBufferCapacity) {
1874 jclass buffer_class = env_->FindClass("java/nio/Buffer");
1875 ASSERT_TRUE(buffer_class != NULL);
1876
1877 char bytes[1024];
1878 jobject buffer = env_->NewDirectByteBuffer(bytes, sizeof(bytes));
1879 ASSERT_TRUE(buffer != NULL);
1880 ASSERT_TRUE(env_->IsInstanceOf(buffer, buffer_class));
1881 ASSERT_TRUE(env_->GetDirectBufferAddress(buffer) == bytes);
1882 ASSERT_TRUE(env_->GetDirectBufferCapacity(buffer) == sizeof(bytes));
1883}
1884
Ian Rogers6d0b13e2012-02-07 09:25:29 -08001885TEST_F(JniInternalTest, MonitorEnterExit) {
1886 // Create an object to torture
1887 jclass object_class = env_->FindClass("java/lang/Object");
1888 ASSERT_TRUE(object_class != NULL);
1889 jobject object = env_->AllocObject(object_class);
1890 ASSERT_TRUE(object != NULL);
1891
1892 // Expected class of exceptions
1893 jclass imse_class = env_->FindClass("java/lang/IllegalMonitorStateException");
1894 ASSERT_TRUE(imse_class != NULL);
1895
1896 jthrowable thrown_exception;
1897
1898 // Unlock of unowned monitor
1899 env_->MonitorExit(object);
1900 EXPECT_TRUE(env_->ExceptionCheck());
1901 thrown_exception = env_->ExceptionOccurred();
1902 env_->ExceptionClear();
1903 EXPECT_TRUE(env_->IsInstanceOf(thrown_exception, imse_class));
1904
1905 // Lock of unowned monitor
1906 env_->MonitorEnter(object);
1907 EXPECT_FALSE(env_->ExceptionCheck());
1908 // Regular unlock
1909 env_->MonitorExit(object);
1910 EXPECT_FALSE(env_->ExceptionCheck());
1911
1912 // Recursively lock a lot
1913 size_t max_recursive_lock = 1024;
1914 for (size_t i = 0; i < max_recursive_lock; i++) {
1915 env_->MonitorEnter(object);
1916 EXPECT_FALSE(env_->ExceptionCheck());
1917 }
1918 // Recursively unlock a lot
1919 for (size_t i = 0; i < max_recursive_lock; i++) {
1920 env_->MonitorExit(object);
1921 EXPECT_FALSE(env_->ExceptionCheck());
1922 }
1923
1924 // Unlock of unowned monitor
1925 env_->MonitorExit(object);
1926 EXPECT_TRUE(env_->ExceptionCheck());
1927 thrown_exception = env_->ExceptionOccurred();
1928 env_->ExceptionClear();
1929 EXPECT_TRUE(env_->IsInstanceOf(thrown_exception, imse_class));
Elliott Hughesa92853e2012-02-07 16:09:27 -08001930
1931 // It's an error to call MonitorEnter or MonitorExit on NULL.
Elliott Hughesb264f082012-04-06 17:10:10 -07001932 {
1933 CheckJniAbortCatcher check_jni_abort_catcher;
1934 env_->MonitorEnter(NULL);
1935 check_jni_abort_catcher.Check("in call to MonitorEnter");
Elliott Hughesb264f082012-04-06 17:10:10 -07001936
Elliott Hughesb264f082012-04-06 17:10:10 -07001937 env_->MonitorExit(NULL);
1938 check_jni_abort_catcher.Check("in call to MonitorExit");
1939 }
Ian Rogers6d0b13e2012-02-07 09:25:29 -08001940}
1941
Brian Carlstrom4d571432012-05-16 00:21:41 -07001942TEST_F(JniInternalTest, DetachCurrentThread) {
1943 CleanUpJniEnv(); // cleanup now so TearDown won't have junk from wrong JNIEnv
1944 jint ok = vm_->DetachCurrentThread();
1945 EXPECT_EQ(JNI_OK, ok);
1946
1947 jint err = vm_->DetachCurrentThread();
1948 EXPECT_EQ(JNI_ERR, err);
1949 vm_->AttachCurrentThread(&env_, NULL); // need attached thread for CommonTest::TearDown
1950}
1951
Ian Rogers0cfe1fb2011-08-26 03:29:44 -07001952} // namespace art