blob: 95e22ba3015b18b65744d090a65c0c050c020d73 [file] [log] [blame]
Elliott Hughes0c9cd562011-08-12 10:59:29 -07001// Copyright 2011 Google Inc. All Rights Reserved.
2
Carl Shapiro9b9ba282011-08-14 15:30:39 -07003#include "jni_internal.h"
Elliott Hughes0c9cd562011-08-12 10:59:29 -07004
Carl Shapiro9b9ba282011-08-14 15:30:39 -07005#include <sys/mman.h>
6
Ian Rogers0cfe1fb2011-08-26 03:29:44 -07007#include <cmath>
8
Carl Shapiro9b9ba282011-08-14 15:30:39 -07009#include "common_test.h"
Elliott Hughes0c9cd562011-08-12 10:59:29 -070010
11namespace art {
12
Brian Carlstromf734cf52011-08-17 16:28:14 -070013class JniInternalTest : public CommonTest {
Elliott Hughesc7ac37f2011-08-12 12:21:58 -070014 protected:
15 virtual void SetUp() {
Brian Carlstromf734cf52011-08-17 16:28:14 -070016 CommonTest::SetUp();
Elliott Hughes5174fe62011-08-23 15:12:35 -070017
Elliott Hughesa2501992011-08-26 19:39:54 -070018 vm_ = Runtime::Current()->GetJavaVM();
19
Elliott Hughes5174fe62011-08-23 15:12:35 -070020 // Turn on -verbose:jni for the JNI tests.
Elliott Hughesa2501992011-08-26 19:39:54 -070021 vm_->verbose_jni = true;
Elliott Hughes5174fe62011-08-23 15:12:35 -070022
Elliott Hughesc7ac37f2011-08-12 12:21:58 -070023 env_ = Thread::Current()->GetJniEnv();
Elliott Hughesb465ab02011-08-24 11:21:21 -070024
Elliott Hughes814e4032011-08-23 12:07:56 -070025 aioobe_ = env_->FindClass("java/lang/ArrayIndexOutOfBoundsException");
26 CHECK(aioobe_ != NULL);
Elliott Hughesb465ab02011-08-24 11:21:21 -070027
28 sioobe_ = env_->FindClass("java/lang/StringIndexOutOfBoundsException");
29 CHECK(sioobe_ != NULL);
Elliott Hughesc7ac37f2011-08-12 12:21:58 -070030 }
Elliott Hughesb465ab02011-08-24 11:21:21 -070031
Elliott Hughesa2501992011-08-26 19:39:54 -070032 JavaVMExt* vm_;
33 JNIEnvExt* env_;
Elliott Hughes814e4032011-08-23 12:07:56 -070034 jclass aioobe_;
Elliott Hughesb465ab02011-08-24 11:21:21 -070035 jclass sioobe_;
Elliott Hughes0c9cd562011-08-12 10:59:29 -070036};
37
Elliott Hughes885c3bd2011-08-22 16:59:20 -070038TEST_F(JniInternalTest, AllocObject) {
39 jclass c = env_->FindClass("java/lang/String");
40 ASSERT_TRUE(c != NULL);
41 jobject o = env_->AllocObject(c);
42 ASSERT_TRUE(o != NULL);
43
44 // We have an instance of the class we asked for...
45 ASSERT_TRUE(env_->IsInstanceOf(o, c));
46 // ...whose fields haven't been initialized because
47 // we didn't call a constructor.
48 ASSERT_EQ(0, env_->GetIntField(o, env_->GetFieldID(c, "count", "I")));
49 ASSERT_EQ(0, env_->GetIntField(o, env_->GetFieldID(c, "offset", "I")));
50 ASSERT_TRUE(env_->GetObjectField(o, env_->GetFieldID(c, "value", "[C")) == NULL);
51}
52
Elliott Hughesc7ac37f2011-08-12 12:21:58 -070053TEST_F(JniInternalTest, GetVersion) {
54 ASSERT_EQ(JNI_VERSION_1_6, env_->GetVersion());
55}
56
Elliott Hughes0c9cd562011-08-12 10:59:29 -070057#define EXPECT_CLASS_FOUND(NAME) \
Elliott Hughesbd935992011-08-22 11:59:34 -070058 EXPECT_TRUE(env_->FindClass(NAME) != NULL); \
59 EXPECT_FALSE(env_->ExceptionCheck())
Elliott Hughes0c9cd562011-08-12 10:59:29 -070060
61#define EXPECT_CLASS_NOT_FOUND(NAME) \
Elliott Hughesbd935992011-08-22 11:59:34 -070062 EXPECT_TRUE(env_->FindClass(NAME) == NULL); \
63 EXPECT_TRUE(env_->ExceptionCheck()); \
64 env_->ExceptionClear()
Elliott Hughes0c9cd562011-08-12 10:59:29 -070065
Elliott Hughesa2501992011-08-26 19:39:54 -070066std::string gCheckJniAbortMessage;
67void TestCheckJniAbortHook(const std::string& reason) {
68 gCheckJniAbortMessage = reason;
69}
70
Elliott Hughes0c9cd562011-08-12 10:59:29 -070071TEST_F(JniInternalTest, FindClass) {
Elliott Hughes0c9cd562011-08-12 10:59:29 -070072 // Reference types...
Elliott Hughes0c9cd562011-08-12 10:59:29 -070073 EXPECT_CLASS_FOUND("java/lang/String");
Elliott Hughes0c9cd562011-08-12 10:59:29 -070074 // ...for arrays too, where you must include "L;".
75 EXPECT_CLASS_FOUND("[Ljava/lang/String;");
Elliott Hughesa2501992011-08-26 19:39:54 -070076
77 vm_->check_jni_abort_hook = TestCheckJniAbortHook;
78 // We support . as well as / for compatibility, if -Xcheck:jni is off.
79 EXPECT_CLASS_FOUND("java.lang.String");
80 EXPECT_CLASS_NOT_FOUND("Ljava.lang.String;");
Elliott Hughes0c9cd562011-08-12 10:59:29 -070081 EXPECT_CLASS_FOUND("[Ljava.lang.String;");
82 EXPECT_CLASS_NOT_FOUND("[java.lang.String");
83
Elliott Hughesa2501992011-08-26 19:39:54 -070084 // You can't include the "L;" in a JNI class descriptor.
85 EXPECT_CLASS_NOT_FOUND("Ljava/lang/String;");
86 // But you must include it for an array of any reference type.
87 EXPECT_CLASS_NOT_FOUND("[java/lang/String");
88 vm_->check_jni_abort_hook = NULL;
89
Elliott Hughes0c9cd562011-08-12 10:59:29 -070090 // Primitive arrays are okay (if the primitive type is valid)...
91 EXPECT_CLASS_FOUND("[C");
Elliott Hughesa2501992011-08-26 19:39:54 -070092 vm_->check_jni_abort_hook = TestCheckJniAbortHook;
Elliott Hughes0c9cd562011-08-12 10:59:29 -070093 EXPECT_CLASS_NOT_FOUND("[K");
Elliott Hughesa2501992011-08-26 19:39:54 -070094 vm_->check_jni_abort_hook = NULL;
Elliott Hughes0c9cd562011-08-12 10:59:29 -070095 // But primitive types aren't allowed...
96 EXPECT_CLASS_NOT_FOUND("C");
97 EXPECT_CLASS_NOT_FOUND("K");
98}
99
Elliott Hughescdf53122011-08-19 15:46:09 -0700100#define EXPECT_EXCEPTION(exception_class) \
101 do { \
102 EXPECT_TRUE(env_->ExceptionCheck()); \
103 jthrowable exception = env_->ExceptionOccurred(); \
104 EXPECT_NE(static_cast<jthrowable>(NULL), exception); \
Elliott Hughescdf53122011-08-19 15:46:09 -0700105 env_->ExceptionClear(); \
Elliott Hughesa2501992011-08-26 19:39:54 -0700106 EXPECT_TRUE(env_->IsInstanceOf(exception, exception_class)); \
Elliott Hughescdf53122011-08-19 15:46:09 -0700107 } while (false)
108
109TEST_F(JniInternalTest, GetFieldID) {
110 jclass jlnsfe = env_->FindClass("java/lang/NoSuchFieldError");
111 ASSERT_TRUE(jlnsfe != NULL);
112 jclass c = env_->FindClass("java/lang/String");
113 ASSERT_TRUE(c != NULL);
114
115 // Wrong type.
116 jfieldID fid = env_->GetFieldID(c, "count", "J");
117 EXPECT_EQ(static_cast<jfieldID>(NULL), fid);
118 EXPECT_EXCEPTION(jlnsfe);
119
Ian Rogersb17d08b2011-09-02 16:16:49 -0700120 // Wrong type where type doesn't exist.
121 fid = env_->GetFieldID(c, "count", "Lrod/jane/freddy;");
122 EXPECT_EQ(static_cast<jfieldID>(NULL), fid);
123 EXPECT_EXCEPTION(jlnsfe);
124
Elliott Hughescdf53122011-08-19 15:46:09 -0700125 // Wrong name.
126 fid = env_->GetFieldID(c, "Count", "I");
127 EXPECT_EQ(static_cast<jfieldID>(NULL), fid);
128 EXPECT_EXCEPTION(jlnsfe);
129
130 // Good declared field lookup.
131 fid = env_->GetFieldID(c, "count", "I");
132 EXPECT_NE(static_cast<jfieldID>(NULL), fid);
133 EXPECT_TRUE(fid != NULL);
134 EXPECT_FALSE(env_->ExceptionCheck());
135
136 // Good superclass field lookup.
137 c = env_->FindClass("java/lang/StringBuilder");
138 fid = env_->GetFieldID(c, "count", "I");
139 EXPECT_NE(static_cast<jfieldID>(NULL), fid);
140 EXPECT_TRUE(fid != NULL);
141 EXPECT_FALSE(env_->ExceptionCheck());
142
143 // Not instance.
144 fid = env_->GetFieldID(c, "CASE_INSENSITIVE_ORDER", "Ljava/util/Comparator;");
145 EXPECT_EQ(static_cast<jfieldID>(NULL), fid);
146 EXPECT_EXCEPTION(jlnsfe);
147}
148
149TEST_F(JniInternalTest, GetStaticFieldID) {
150 jclass jlnsfe = env_->FindClass("java/lang/NoSuchFieldError");
151 ASSERT_TRUE(jlnsfe != NULL);
152 jclass c = env_->FindClass("java/lang/String");
153 ASSERT_TRUE(c != NULL);
154
155 // Wrong type.
156 jfieldID fid = env_->GetStaticFieldID(c, "CASE_INSENSITIVE_ORDER", "J");
157 EXPECT_EQ(static_cast<jfieldID>(NULL), fid);
158 EXPECT_EXCEPTION(jlnsfe);
159
Ian Rogersb17d08b2011-09-02 16:16:49 -0700160 // Wrong type where type doesn't exist.
161 fid = env_->GetStaticFieldID(c, "CASE_INSENSITIVE_ORDER", "Lrod/jane/freddy;");
162 EXPECT_EQ(static_cast<jfieldID>(NULL), fid);
163 EXPECT_EXCEPTION(jlnsfe);
164
Elliott Hughescdf53122011-08-19 15:46:09 -0700165 // Wrong name.
166 fid = env_->GetStaticFieldID(c, "cASE_INSENSITIVE_ORDER", "Ljava/util/Comparator;");
167 EXPECT_EQ(static_cast<jfieldID>(NULL), fid);
168 EXPECT_EXCEPTION(jlnsfe);
169
170 // Good declared field lookup.
171 fid = env_->GetStaticFieldID(c, "CASE_INSENSITIVE_ORDER", "Ljava/util/Comparator;");
172 EXPECT_NE(static_cast<jfieldID>(NULL), fid);
173 EXPECT_TRUE(fid != NULL);
174 EXPECT_FALSE(env_->ExceptionCheck());
175
176 // Not static.
177 fid = env_->GetStaticFieldID(c, "count", "I");
178 EXPECT_EQ(static_cast<jfieldID>(NULL), fid);
179 EXPECT_EXCEPTION(jlnsfe);
180}
181
Ian Rogers4dd71f12011-08-16 14:16:02 -0700182TEST_F(JniInternalTest, GetMethodID) {
183 jclass jlobject = env_->FindClass("java/lang/Object");
184 jclass jlstring = env_->FindClass("java/lang/String");
185 jclass jlnsme = env_->FindClass("java/lang/NoSuchMethodError");
186
187 // Sanity check that no exceptions are pending
Elliott Hughescdf53122011-08-19 15:46:09 -0700188 ASSERT_FALSE(env_->ExceptionCheck());
Ian Rogers4dd71f12011-08-16 14:16:02 -0700189
190 // Check that java.lang.Object.foo() doesn't exist and NoSuchMethodError is
191 // a pending exception
192 jmethodID method = env_->GetMethodID(jlobject, "foo", "()V");
193 EXPECT_EQ(static_cast<jmethodID>(NULL), method);
Elliott Hughescdf53122011-08-19 15:46:09 -0700194 EXPECT_EXCEPTION(jlnsme);
Ian Rogers4dd71f12011-08-16 14:16:02 -0700195
196 // Check that java.lang.Object.equals() does exist
Ian Rogers4dd71f12011-08-16 14:16:02 -0700197 method = env_->GetMethodID(jlobject, "equals", "(Ljava/lang/Object;)Z");
198 EXPECT_NE(static_cast<jmethodID>(NULL), method);
199 EXPECT_FALSE(env_->ExceptionCheck());
Ian Rogers4dd71f12011-08-16 14:16:02 -0700200
201 // Check that GetMethodID for java.lang.String.valueOf(int) fails as the
202 // method is static
203 method = env_->GetMethodID(jlstring, "valueOf", "(I)Ljava/lang/String;");
204 EXPECT_EQ(static_cast<jmethodID>(NULL), method);
Elliott Hughescdf53122011-08-19 15:46:09 -0700205 EXPECT_EXCEPTION(jlnsme);
Ian Rogers4dd71f12011-08-16 14:16:02 -0700206}
207
208TEST_F(JniInternalTest, GetStaticMethodID) {
209 jclass jlobject = env_->FindClass("java/lang/Object");
210 jclass jlnsme = env_->FindClass("java/lang/NoSuchMethodError");
211
212 // Sanity check that no exceptions are pending
Elliott Hughescdf53122011-08-19 15:46:09 -0700213 ASSERT_FALSE(env_->ExceptionCheck());
Ian Rogers4dd71f12011-08-16 14:16:02 -0700214
215 // Check that java.lang.Object.foo() doesn't exist and NoSuchMethodError is
216 // a pending exception
217 jmethodID method = env_->GetStaticMethodID(jlobject, "foo", "()V");
218 EXPECT_EQ(static_cast<jmethodID>(NULL), method);
Elliott Hughescdf53122011-08-19 15:46:09 -0700219 EXPECT_EXCEPTION(jlnsme);
Ian Rogers4dd71f12011-08-16 14:16:02 -0700220
221 // Check that GetStaticMethodID for java.lang.Object.equals(Object) fails as
222 // the method is not static
223 method = env_->GetStaticMethodID(jlobject, "equals", "(Ljava/lang/Object;)Z");
224 EXPECT_EQ(static_cast<jmethodID>(NULL), method);
Elliott Hughescdf53122011-08-19 15:46:09 -0700225 EXPECT_EXCEPTION(jlnsme);
Ian Rogers4dd71f12011-08-16 14:16:02 -0700226
227 // Check that java.lang.String.valueOf(int) does exist
Ian Rogers4dd71f12011-08-16 14:16:02 -0700228 jclass jlstring = env_->FindClass("java/lang/String");
229 method = env_->GetStaticMethodID(jlstring, "valueOf",
230 "(I)Ljava/lang/String;");
231 EXPECT_NE(static_cast<jmethodID>(NULL), method);
232 EXPECT_FALSE(env_->ExceptionCheck());
Ian Rogers4dd71f12011-08-16 14:16:02 -0700233}
234
Elliott Hughescdf53122011-08-19 15:46:09 -0700235TEST_F(JniInternalTest, FromReflectedField_ToReflectedField) {
236 jclass jlrField = env_->FindClass("java/lang/reflect/Field");
237 jclass c = env_->FindClass("java/lang/String");
238 ASSERT_TRUE(c != NULL);
239 jfieldID fid = env_->GetFieldID(c, "count", "I");
240 ASSERT_TRUE(fid != NULL);
241 // Turn the fid into a java.lang.reflect.Field...
242 jobject field = env_->ToReflectedField(c, fid, JNI_FALSE);
243 ASSERT_TRUE(c != NULL);
244 ASSERT_TRUE(env_->IsInstanceOf(field, jlrField));
245 // ...and back again.
246 jfieldID fid2 = env_->FromReflectedField(field);
247 ASSERT_TRUE(fid2 != NULL);
248}
249
250TEST_F(JniInternalTest, FromReflectedMethod_ToReflectedMethod) {
251 jclass jlrMethod = env_->FindClass("java/lang/reflect/Method");
252 jclass c = env_->FindClass("java/lang/String");
253 ASSERT_TRUE(c != NULL);
254 jmethodID mid = env_->GetMethodID(c, "length", "()I");
255 ASSERT_TRUE(mid != NULL);
256 // Turn the mid into a java.lang.reflect.Method...
257 jobject method = env_->ToReflectedMethod(c, mid, JNI_FALSE);
258 ASSERT_TRUE(c != NULL);
259 ASSERT_TRUE(env_->IsInstanceOf(method, jlrMethod));
260 // ...and back again.
261 jmethodID mid2 = env_->FromReflectedMethod(method);
262 ASSERT_TRUE(mid2 != NULL);
263}
264
Elliott Hughes5174fe62011-08-23 15:12:35 -0700265void BogusMethod() {
266 // You can't pass NULL function pointers to RegisterNatives.
267}
268
Ian Rogers4dd71f12011-08-16 14:16:02 -0700269TEST_F(JniInternalTest, RegisterNatives) {
270 jclass jlobject = env_->FindClass("java/lang/Object");
271 jclass jlnsme = env_->FindClass("java/lang/NoSuchMethodError");
272
273 // Sanity check that no exceptions are pending
Elliott Hughescdf53122011-08-19 15:46:09 -0700274 ASSERT_FALSE(env_->ExceptionCheck());
Ian Rogers4dd71f12011-08-16 14:16:02 -0700275
276 // Check that registering to a non-existent java.lang.Object.foo() causes a
277 // NoSuchMethodError
278 {
279 JNINativeMethod methods[] = {{"foo", "()V", NULL}};
280 env_->RegisterNatives(jlobject, methods, 1);
281 }
Elliott Hughescdf53122011-08-19 15:46:09 -0700282 EXPECT_EXCEPTION(jlnsme);
Ian Rogers4dd71f12011-08-16 14:16:02 -0700283
284 // Check that registering non-native methods causes a NoSuchMethodError
285 {
286 JNINativeMethod methods[] = {{"equals", "(Ljava/lang/Object;)Z", NULL}};
287 env_->RegisterNatives(jlobject, methods, 1);
288 }
Elliott Hughescdf53122011-08-19 15:46:09 -0700289 EXPECT_EXCEPTION(jlnsme);
Ian Rogers4dd71f12011-08-16 14:16:02 -0700290
291 // Check that registering native methods is successful
292 {
Elliott Hughesad7c2a32011-08-31 11:58:10 -0700293 JNINativeMethod methods[] = {{"getClass", "()Ljava/lang/Class;", reinterpret_cast<void*>(BogusMethod)}};
Ian Rogers4dd71f12011-08-16 14:16:02 -0700294 env_->RegisterNatives(jlobject, methods, 1);
295 }
296 EXPECT_FALSE(env_->ExceptionCheck());
Elliott Hughes5174fe62011-08-23 15:12:35 -0700297
298 env_->UnregisterNatives(jlobject);
Ian Rogers4dd71f12011-08-16 14:16:02 -0700299}
300
Elliott Hughes75770752011-08-24 17:52:38 -0700301#define EXPECT_PRIMITIVE_ARRAY(new_fn, get_region_fn, set_region_fn, get_elements_fn, release_elements_fn, scalar_type, expected_class_descriptor) \
Elliott Hughes814e4032011-08-23 12:07:56 -0700302 jsize size = 4; \
303 /* Allocate an array and check it has the right type and length. */ \
304 scalar_type ## Array a = env_->new_fn(size); \
305 EXPECT_TRUE(a != NULL); \
306 EXPECT_TRUE(env_->IsInstanceOf(a, env_->FindClass(expected_class_descriptor))); \
307 EXPECT_EQ(size, env_->GetArrayLength(a)); \
308 /* AIOOBE for negative start offset. */ \
309 env_->get_region_fn(a, -1, 1, NULL); \
310 EXPECT_EXCEPTION(aioobe_); \
311 env_->set_region_fn(a, -1, 1, NULL); \
312 EXPECT_EXCEPTION(aioobe_); \
313 /* AIOOBE for negative length. */ \
314 env_->get_region_fn(a, 0, -1, NULL); \
315 EXPECT_EXCEPTION(aioobe_); \
316 env_->set_region_fn(a, 0, -1, NULL); \
317 EXPECT_EXCEPTION(aioobe_); \
318 /* AIOOBE for buffer overrun. */ \
319 env_->get_region_fn(a, size - 1, size, NULL); \
320 EXPECT_EXCEPTION(aioobe_); \
321 env_->set_region_fn(a, size - 1, size, NULL); \
322 EXPECT_EXCEPTION(aioobe_); \
323 /* Prepare a couple of buffers. */ \
324 scalar_type src_buf[size]; \
325 scalar_type dst_buf[size]; \
326 for (jsize i = 0; i < size; ++i) { src_buf[i] = scalar_type(i); } \
327 for (jsize i = 0; i < size; ++i) { dst_buf[i] = scalar_type(-1); } \
328 /* Copy all of src_buf onto the heap. */ \
329 env_->set_region_fn(a, 0, size, src_buf); \
330 /* Copy back only part. */ \
331 env_->get_region_fn(a, 1, size - 2, &dst_buf[1]); \
332 EXPECT_FALSE(memcmp(src_buf, dst_buf, sizeof(src_buf)) == 0) << "short copy equal"; \
333 /* Copy the missing pieces. */ \
334 env_->get_region_fn(a, 0, 1, dst_buf); \
335 env_->get_region_fn(a, size - 1, 1, &dst_buf[size - 1]); \
336 EXPECT_TRUE(memcmp(src_buf, dst_buf, sizeof(src_buf)) == 0) << "fixed copy not equal"; \
337 /* Copy back the whole array. */ \
338 env_->get_region_fn(a, 0, size, dst_buf); \
Elliott Hughes75770752011-08-24 17:52:38 -0700339 EXPECT_TRUE(memcmp(src_buf, dst_buf, sizeof(src_buf)) == 0) << "full copy not equal"; \
340 /* GetPrimitiveArrayCritical */ \
341 void* v = env_->GetPrimitiveArrayCritical(a, NULL); \
342 EXPECT_TRUE(memcmp(src_buf, v, sizeof(src_buf)) == 0) << "GetPrimitiveArrayCritical not equal"; \
343 env_->ReleasePrimitiveArrayCritical(a, v, 0); \
344 /* GetXArrayElements */ \
345 scalar_type* xs = env_->get_elements_fn(a, NULL); \
346 EXPECT_TRUE(memcmp(src_buf, xs, sizeof(src_buf)) == 0) << # get_elements_fn " not equal"; \
347 env_->release_elements_fn(a, xs, 0); \
348 EXPECT_EQ(reinterpret_cast<uintptr_t>(v), reinterpret_cast<uintptr_t>(xs))
Elliott Hughesbd935992011-08-22 11:59:34 -0700349
Elliott Hughes814e4032011-08-23 12:07:56 -0700350TEST_F(JniInternalTest, BooleanArrays) {
Elliott Hughes75770752011-08-24 17:52:38 -0700351 EXPECT_PRIMITIVE_ARRAY(NewBooleanArray, GetBooleanArrayRegion, SetBooleanArrayRegion, GetBooleanArrayElements, ReleaseBooleanArrayElements, jboolean, "[Z");
Elliott Hughes814e4032011-08-23 12:07:56 -0700352}
353TEST_F(JniInternalTest, ByteArrays) {
Elliott Hughes75770752011-08-24 17:52:38 -0700354 EXPECT_PRIMITIVE_ARRAY(NewByteArray, GetByteArrayRegion, SetByteArrayRegion, GetByteArrayElements, ReleaseByteArrayElements, jbyte, "[B");
Elliott Hughes814e4032011-08-23 12:07:56 -0700355}
356TEST_F(JniInternalTest, CharArrays) {
Elliott Hughes75770752011-08-24 17:52:38 -0700357 EXPECT_PRIMITIVE_ARRAY(NewCharArray, GetCharArrayRegion, SetCharArrayRegion, GetCharArrayElements, ReleaseCharArrayElements, jchar, "[C");
Elliott Hughes814e4032011-08-23 12:07:56 -0700358}
359TEST_F(JniInternalTest, DoubleArrays) {
Elliott Hughes75770752011-08-24 17:52:38 -0700360 EXPECT_PRIMITIVE_ARRAY(NewDoubleArray, GetDoubleArrayRegion, SetDoubleArrayRegion, GetDoubleArrayElements, ReleaseDoubleArrayElements, jdouble, "[D");
Elliott Hughes814e4032011-08-23 12:07:56 -0700361}
362TEST_F(JniInternalTest, FloatArrays) {
Elliott Hughes75770752011-08-24 17:52:38 -0700363 EXPECT_PRIMITIVE_ARRAY(NewFloatArray, GetFloatArrayRegion, SetFloatArrayRegion, GetFloatArrayElements, ReleaseFloatArrayElements, jfloat, "[F");
Elliott Hughes814e4032011-08-23 12:07:56 -0700364}
365TEST_F(JniInternalTest, IntArrays) {
Elliott Hughes75770752011-08-24 17:52:38 -0700366 EXPECT_PRIMITIVE_ARRAY(NewIntArray, GetIntArrayRegion, SetIntArrayRegion, GetIntArrayElements, ReleaseIntArrayElements, jint, "[I");
Elliott Hughes814e4032011-08-23 12:07:56 -0700367}
368TEST_F(JniInternalTest, LongArrays) {
Elliott Hughes75770752011-08-24 17:52:38 -0700369 EXPECT_PRIMITIVE_ARRAY(NewLongArray, GetLongArrayRegion, SetLongArrayRegion, GetLongArrayElements, ReleaseLongArrayElements, jlong, "[J");
Elliott Hughes814e4032011-08-23 12:07:56 -0700370}
371TEST_F(JniInternalTest, ShortArrays) {
Elliott Hughes75770752011-08-24 17:52:38 -0700372 EXPECT_PRIMITIVE_ARRAY(NewShortArray, GetShortArrayRegion, SetShortArrayRegion, GetShortArrayElements, ReleaseShortArrayElements, jshort, "[S");
Elliott Hughesd8ddfd52011-08-15 14:32:53 -0700373}
374
Elliott Hughesf2682d52011-08-15 16:37:04 -0700375TEST_F(JniInternalTest, NewObjectArray) {
376 // TODO: death tests for negative array sizes.
377
Elliott Hughesf2682d52011-08-15 16:37:04 -0700378 // TODO: check non-NULL initial elements.
379
Elliott Hughesbd935992011-08-22 11:59:34 -0700380 jclass element_class = env_->FindClass("java/lang/String");
381 ASSERT_TRUE(element_class != NULL);
382 jclass array_class = env_->FindClass("[Ljava/lang/String;");
383 ASSERT_TRUE(array_class != NULL);
Elliott Hughesf2682d52011-08-15 16:37:04 -0700384
Elliott Hughesbd935992011-08-22 11:59:34 -0700385 jobjectArray a;
Elliott Hughesf2682d52011-08-15 16:37:04 -0700386
Elliott Hughesbd935992011-08-22 11:59:34 -0700387 a = env_->NewObjectArray(0, element_class, NULL);
388 EXPECT_TRUE(a != NULL);
389 EXPECT_TRUE(env_->IsInstanceOf(a, array_class));
390 EXPECT_EQ(0, env_->GetArrayLength(a));
391
392 a = env_->NewObjectArray(1, element_class, NULL);
393 EXPECT_TRUE(a != NULL);
394 EXPECT_TRUE(env_->IsInstanceOf(a, array_class));
395 EXPECT_EQ(1, env_->GetArrayLength(a));
Elliott Hughes75770752011-08-24 17:52:38 -0700396 EXPECT_TRUE(env_->IsSameObject(env_->GetObjectArrayElement(a, 0), NULL));
397
398 jstring s = env_->NewStringUTF("poop");
399 a = env_->NewObjectArray(2, element_class, s);
400 EXPECT_TRUE(a != NULL);
401 EXPECT_TRUE(env_->IsInstanceOf(a, array_class));
402 EXPECT_EQ(2, env_->GetArrayLength(a));
403 EXPECT_TRUE(env_->IsSameObject(env_->GetObjectArrayElement(a, 0), s));
404 EXPECT_TRUE(env_->IsSameObject(env_->GetObjectArrayElement(a, 1), s));
Elliott Hughesbd935992011-08-22 11:59:34 -0700405}
406
407TEST_F(JniInternalTest, GetArrayLength) {
408 // Already tested in NewObjectArray/NewPrimitiveArray.
Elliott Hughes8a26c5c2011-08-15 18:35:43 -0700409}
410
Elliott Hughes37f7a402011-08-22 18:56:01 -0700411TEST_F(JniInternalTest, GetObjectClass) {
412 jclass string_class = env_->FindClass("java/lang/String");
413 ASSERT_TRUE(string_class != NULL);
414 jclass class_class = env_->FindClass("java/lang/Class");
415 ASSERT_TRUE(class_class != NULL);
416
417 jstring s = env_->NewStringUTF("poop");
418 jclass c = env_->GetObjectClass(s);
419 ASSERT_TRUE(env_->IsSameObject(string_class, c));
420
421 jclass c2 = env_->GetObjectClass(c);
422 ASSERT_TRUE(env_->IsSameObject(class_class, env_->GetObjectClass(c2)));
423}
424
Elliott Hughes885c3bd2011-08-22 16:59:20 -0700425TEST_F(JniInternalTest, GetSuperclass) {
426 jclass object_class = env_->FindClass("java/lang/Object");
427 ASSERT_TRUE(object_class != NULL);
428 jclass string_class = env_->FindClass("java/lang/String");
429 ASSERT_TRUE(string_class != NULL);
430 ASSERT_TRUE(env_->IsSameObject(object_class, env_->GetSuperclass(string_class)));
431 ASSERT_TRUE(env_->GetSuperclass(object_class) == NULL);
432}
433
Elliott Hughes37f7a402011-08-22 18:56:01 -0700434TEST_F(JniInternalTest, IsAssignableFrom) {
435 jclass object_class = env_->FindClass("java/lang/Object");
436 ASSERT_TRUE(object_class != NULL);
437 jclass string_class = env_->FindClass("java/lang/String");
438 ASSERT_TRUE(string_class != NULL);
439
440 ASSERT_TRUE(env_->IsAssignableFrom(object_class, string_class));
441 ASSERT_FALSE(env_->IsAssignableFrom(string_class, object_class));
442}
443
Elliott Hughesb465ab02011-08-24 11:21:21 -0700444TEST_F(JniInternalTest, GetObjectRefType) {
445 jclass local = env_->FindClass("java/lang/Object");
446 ASSERT_TRUE(local != NULL);
447 EXPECT_EQ(JNILocalRefType, env_->GetObjectRefType(local));
448
449 jobject global = env_->NewGlobalRef(local);
450 EXPECT_EQ(JNIGlobalRefType, env_->GetObjectRefType(global));
451
452 jweak weak_global = env_->NewWeakGlobalRef(local);
453 EXPECT_EQ(JNIWeakGlobalRefType, env_->GetObjectRefType(weak_global));
454
455 jobject invalid = reinterpret_cast<jobject>(this);
456 EXPECT_EQ(JNIInvalidRefType, env_->GetObjectRefType(invalid));
457
458 // TODO: invoke a native method and test that its arguments are considered local references.
459}
460
Elliott Hughes8a26c5c2011-08-15 18:35:43 -0700461TEST_F(JniInternalTest, NewStringUTF) {
462 EXPECT_TRUE(env_->NewStringUTF(NULL) == NULL);
Elliott Hughes814e4032011-08-23 12:07:56 -0700463 jstring s;
464
465 s = env_->NewStringUTF("");
466 EXPECT_TRUE(s != NULL);
467 EXPECT_EQ(0, env_->GetStringLength(s));
468 EXPECT_EQ(0, env_->GetStringUTFLength(s));
469 s = env_->NewStringUTF("hello");
470 EXPECT_TRUE(s != NULL);
471 EXPECT_EQ(5, env_->GetStringLength(s));
472 EXPECT_EQ(5, env_->GetStringUTFLength(s));
473
Elliott Hughes8a26c5c2011-08-15 18:35:43 -0700474 // TODO: check some non-ASCII strings.
Elliott Hughesf2682d52011-08-15 16:37:04 -0700475}
476
Elliott Hughes814e4032011-08-23 12:07:56 -0700477TEST_F(JniInternalTest, NewString) {
478 EXPECT_TRUE(env_->NewString(NULL, 0) == NULL);
479
480 jchar chars[] = { 'h', 'i' };
481 jstring s;
482 s = env_->NewString(chars, 0);
483 EXPECT_TRUE(s != NULL);
484 EXPECT_EQ(0, env_->GetStringLength(s));
485 EXPECT_EQ(0, env_->GetStringUTFLength(s));
486 s = env_->NewString(chars, 2);
487 EXPECT_TRUE(s != NULL);
488 EXPECT_EQ(2, env_->GetStringLength(s));
489 EXPECT_EQ(2, env_->GetStringUTFLength(s));
490
491 // TODO: check some non-ASCII strings.
492}
493
Elliott Hughesb465ab02011-08-24 11:21:21 -0700494TEST_F(JniInternalTest, GetStringLength_GetStringUTFLength) {
495 // Already tested in the NewString/NewStringUTF tests.
496}
497
498TEST_F(JniInternalTest, GetStringRegion_GetStringUTFRegion) {
499 jstring s = env_->NewStringUTF("hello");
500 ASSERT_TRUE(s != NULL);
501
502 env_->GetStringRegion(s, -1, 0, NULL);
503 EXPECT_EXCEPTION(sioobe_);
504 env_->GetStringRegion(s, 0, -1, NULL);
505 EXPECT_EXCEPTION(sioobe_);
506 env_->GetStringRegion(s, 0, 10, NULL);
507 EXPECT_EXCEPTION(sioobe_);
508 env_->GetStringRegion(s, 10, 1, NULL);
509 EXPECT_EXCEPTION(sioobe_);
510
511 jchar chars[4] = { 'x', 'x', 'x', 'x' };
512 env_->GetStringRegion(s, 1, 2, &chars[1]);
513 EXPECT_EQ('x', chars[0]);
514 EXPECT_EQ('e', chars[1]);
515 EXPECT_EQ('l', chars[2]);
516 EXPECT_EQ('x', chars[3]);
517
518 env_->GetStringUTFRegion(s, -1, 0, NULL);
519 EXPECT_EXCEPTION(sioobe_);
520 env_->GetStringUTFRegion(s, 0, -1, NULL);
521 EXPECT_EXCEPTION(sioobe_);
522 env_->GetStringUTFRegion(s, 0, 10, NULL);
523 EXPECT_EXCEPTION(sioobe_);
524 env_->GetStringUTFRegion(s, 10, 1, NULL);
525 EXPECT_EXCEPTION(sioobe_);
526
527 char bytes[4] = { 'x', 'x', 'x', 'x' };
528 env_->GetStringUTFRegion(s, 1, 2, &bytes[1]);
529 EXPECT_EQ('x', bytes[0]);
530 EXPECT_EQ('e', bytes[1]);
531 EXPECT_EQ('l', bytes[2]);
532 EXPECT_EQ('x', bytes[3]);
533}
534
Elliott Hughes75770752011-08-24 17:52:38 -0700535TEST_F(JniInternalTest, GetStringUTFChars_ReleaseStringUTFChars) {
Elliott Hughesa2501992011-08-26 19:39:54 -0700536 vm_->check_jni_abort_hook = TestCheckJniAbortHook;
537 // Passing in a NULL jstring is ignored normally, but caught by -Xcheck:jni.
Elliott Hughes75770752011-08-24 17:52:38 -0700538 EXPECT_TRUE(env_->GetStringUTFChars(NULL, NULL) == NULL);
Elliott Hughesa2501992011-08-26 19:39:54 -0700539 vm_->check_jni_abort_hook = NULL;
Elliott Hughes75770752011-08-24 17:52:38 -0700540
541 jstring s = env_->NewStringUTF("hello");
542 ASSERT_TRUE(s != NULL);
543
544 const char* utf = env_->GetStringUTFChars(s, NULL);
545 EXPECT_STREQ("hello", utf);
546 env_->ReleaseStringUTFChars(s, utf);
547
548 jboolean is_copy = JNI_FALSE;
549 utf = env_->GetStringUTFChars(s, &is_copy);
550 EXPECT_EQ(JNI_TRUE, is_copy);
551 EXPECT_STREQ("hello", utf);
552 env_->ReleaseStringUTFChars(s, utf);
553}
554
555TEST_F(JniInternalTest, GetStringChars_ReleaseStringChars) {
556 jstring s = env_->NewStringUTF("hello");
557 ASSERT_TRUE(s != NULL);
558
559 jchar expected[] = { 'h', 'e', 'l', 'l', 'o' };
560 const jchar* chars = env_->GetStringChars(s, NULL);
561 EXPECT_EQ(expected[0], chars[0]);
562 EXPECT_EQ(expected[1], chars[1]);
563 EXPECT_EQ(expected[2], chars[2]);
564 EXPECT_EQ(expected[3], chars[3]);
565 EXPECT_EQ(expected[4], chars[4]);
566 env_->ReleaseStringChars(s, chars);
567
568 jboolean is_copy = JNI_FALSE;
569 chars = env_->GetStringChars(s, &is_copy);
570 EXPECT_EQ(JNI_FALSE, is_copy);
571 EXPECT_EQ(expected[0], chars[0]);
572 EXPECT_EQ(expected[1], chars[1]);
573 EXPECT_EQ(expected[2], chars[2]);
574 EXPECT_EQ(expected[3], chars[3]);
575 EXPECT_EQ(expected[4], chars[4]);
576 env_->ReleaseStringChars(s, chars);
577}
578
579TEST_F(JniInternalTest, GetStringCritical_ReleaseStringCritical) {
580 jstring s = env_->NewStringUTF("hello");
581 ASSERT_TRUE(s != NULL);
582
583 jchar expected[] = { 'h', 'e', 'l', 'l', 'o' };
584 const jchar* chars = env_->GetStringCritical(s, NULL);
585 EXPECT_EQ(expected[0], chars[0]);
586 EXPECT_EQ(expected[1], chars[1]);
587 EXPECT_EQ(expected[2], chars[2]);
588 EXPECT_EQ(expected[3], chars[3]);
589 EXPECT_EQ(expected[4], chars[4]);
590 env_->ReleaseStringCritical(s, chars);
591
592 jboolean is_copy = JNI_FALSE;
593 chars = env_->GetStringCritical(s, &is_copy);
594 EXPECT_EQ(JNI_FALSE, is_copy);
595 EXPECT_EQ(expected[0], chars[0]);
596 EXPECT_EQ(expected[1], chars[1]);
597 EXPECT_EQ(expected[2], chars[2]);
598 EXPECT_EQ(expected[3], chars[3]);
599 EXPECT_EQ(expected[4], chars[4]);
600 env_->ReleaseStringCritical(s, chars);
601}
602
Elliott Hughes814e4032011-08-23 12:07:56 -0700603TEST_F(JniInternalTest, GetObjectArrayElement_SetObjectArrayElement) {
Brian Carlstrom5b8e4c82011-09-18 01:38:59 -0700604 jclass c = env_->FindClass("java/lang/Object");
Elliott Hughes289da822011-08-16 10:11:20 -0700605 ASSERT_TRUE(c != NULL);
606
607 jobjectArray array = env_->NewObjectArray(1, c, NULL);
608 EXPECT_TRUE(array != NULL);
Elliott Hughes814e4032011-08-23 12:07:56 -0700609 EXPECT_TRUE(env_->GetObjectArrayElement(array, 0) == NULL);
Elliott Hughes289da822011-08-16 10:11:20 -0700610 env_->SetObjectArrayElement(array, 0, c);
Elliott Hughes814e4032011-08-23 12:07:56 -0700611 EXPECT_TRUE(env_->IsSameObject(env_->GetObjectArrayElement(array, 0), c));
Elliott Hughesa5b897e2011-08-16 11:33:06 -0700612
613 // ArrayIndexOutOfBounds for negative index.
Elliott Hughesa5b897e2011-08-16 11:33:06 -0700614 env_->SetObjectArrayElement(array, -1, c);
Elliott Hughes814e4032011-08-23 12:07:56 -0700615 EXPECT_EXCEPTION(aioobe_);
Elliott Hughesa5b897e2011-08-16 11:33:06 -0700616
617 // ArrayIndexOutOfBounds for too-large index.
Elliott Hughesa5b897e2011-08-16 11:33:06 -0700618 env_->SetObjectArrayElement(array, 1, c);
Elliott Hughes814e4032011-08-23 12:07:56 -0700619 EXPECT_EXCEPTION(aioobe_);
Elliott Hughesa5b897e2011-08-16 11:33:06 -0700620
Elliott Hughes289da822011-08-16 10:11:20 -0700621 // TODO: check ArrayStoreException thrown for bad types.
622}
623
Elliott Hughes885c3bd2011-08-22 16:59:20 -0700624#define EXPECT_STATIC_PRIMITIVE_FIELD(type, field_name, sig, value1, value2) \
625 do { \
626 jfieldID fid = env_->GetStaticFieldID(c, field_name, sig); \
627 EXPECT_TRUE(fid != NULL); \
628 env_->SetStatic ## type ## Field(c, fid, value1); \
629 EXPECT_EQ(value1, env_->GetStatic ## type ## Field(c, fid)); \
630 env_->SetStatic ## type ## Field(c, fid, value2); \
631 EXPECT_EQ(value2, env_->GetStatic ## type ## Field(c, fid)); \
632 } while (false)
633
634#define EXPECT_PRIMITIVE_FIELD(instance, type, field_name, sig, value1, value2) \
635 do { \
636 jfieldID fid = env_->GetFieldID(c, field_name, sig); \
637 EXPECT_TRUE(fid != NULL); \
638 env_->Set ## type ## Field(instance, fid, value1); \
639 EXPECT_EQ(value1, env_->Get ## type ## Field(instance, fid)); \
640 env_->Set ## type ## Field(instance, fid, value2); \
641 EXPECT_EQ(value2, env_->Get ## type ## Field(instance, fid)); \
642 } while (false)
643
644
645TEST_F(JniInternalTest, GetPrimitiveField_SetPrimitiveField) {
Brian Carlstrom9baa4ae2011-09-01 21:14:14 -0700646 LoadDex("AllFields");
Brian Carlstrom25c33252011-09-18 15:58:35 -0700647 runtime_->Start();
Elliott Hughes885c3bd2011-08-22 16:59:20 -0700648
649 jclass c = env_->FindClass("AllFields");
650 ASSERT_TRUE(c != NULL);
651 jobject o = env_->AllocObject(c);
652 ASSERT_TRUE(o != NULL);
653
654 EXPECT_STATIC_PRIMITIVE_FIELD(Boolean, "sZ", "Z", true, false);
655 EXPECT_STATIC_PRIMITIVE_FIELD(Byte, "sB", "B", 1, 2);
656 EXPECT_STATIC_PRIMITIVE_FIELD(Char, "sC", "C", 'a', 'b');
657 EXPECT_STATIC_PRIMITIVE_FIELD(Double, "sD", "D", 1.0, 2.0);
658 EXPECT_STATIC_PRIMITIVE_FIELD(Float, "sF", "F", 1.0, 2.0);
659 EXPECT_STATIC_PRIMITIVE_FIELD(Int, "sI", "I", 1, 2);
660 EXPECT_STATIC_PRIMITIVE_FIELD(Long, "sJ", "J", 1, 2);
661 EXPECT_STATIC_PRIMITIVE_FIELD(Short, "sS", "S", 1, 2);
662
663 EXPECT_PRIMITIVE_FIELD(o, Boolean, "iZ", "Z", true, false);
664 EXPECT_PRIMITIVE_FIELD(o, Byte, "iB", "B", 1, 2);
665 EXPECT_PRIMITIVE_FIELD(o, Char, "iC", "C", 'a', 'b');
666 EXPECT_PRIMITIVE_FIELD(o, Double, "iD", "D", 1.0, 2.0);
667 EXPECT_PRIMITIVE_FIELD(o, Float, "iF", "F", 1.0, 2.0);
668 EXPECT_PRIMITIVE_FIELD(o, Int, "iI", "I", 1, 2);
669 EXPECT_PRIMITIVE_FIELD(o, Long, "iJ", "J", 1, 2);
670 EXPECT_PRIMITIVE_FIELD(o, Short, "iS", "S", 1, 2);
671}
672
673TEST_F(JniInternalTest, GetObjectField_SetObjectField) {
Brian Carlstrom9baa4ae2011-09-01 21:14:14 -0700674 LoadDex("AllFields");
Brian Carlstrom25c33252011-09-18 15:58:35 -0700675 runtime_->Start();
Elliott Hughes885c3bd2011-08-22 16:59:20 -0700676
677 jclass c = env_->FindClass("AllFields");
678 ASSERT_TRUE(c != NULL);
679 jobject o = env_->AllocObject(c);
680 ASSERT_TRUE(o != NULL);
681
682 jstring s1 = env_->NewStringUTF("hello");
683 ASSERT_TRUE(s1 != NULL);
684 jstring s2 = env_->NewStringUTF("world");
685 ASSERT_TRUE(s2 != NULL);
686
687 jfieldID s_fid = env_->GetStaticFieldID(c, "sObject", "Ljava/lang/Object;");
688 ASSERT_TRUE(s_fid != NULL);
689 jfieldID i_fid = env_->GetFieldID(c, "iObject", "Ljava/lang/Object;");
690 ASSERT_TRUE(i_fid != NULL);
691
692 env_->SetStaticObjectField(c, s_fid, s1);
693 ASSERT_TRUE(env_->IsSameObject(s1, env_->GetStaticObjectField(c, s_fid)));
694 env_->SetStaticObjectField(c, s_fid, s2);
695 ASSERT_TRUE(env_->IsSameObject(s2, env_->GetStaticObjectField(c, s_fid)));
696
697 env_->SetObjectField(o, i_fid, s1);
698 ASSERT_TRUE(env_->IsSameObject(s1, env_->GetObjectField(o, i_fid)));
699 env_->SetObjectField(o, i_fid, s2);
700 ASSERT_TRUE(env_->IsSameObject(s2, env_->GetObjectField(o, i_fid)));
701}
702
Elliott Hughes18c07532011-08-18 15:50:51 -0700703TEST_F(JniInternalTest, NewLocalRef_NULL) {
704 EXPECT_TRUE(env_->NewLocalRef(NULL) == NULL);
705}
706
707TEST_F(JniInternalTest, NewLocalRef) {
708 jstring s = env_->NewStringUTF("");
709 ASSERT_TRUE(s != NULL);
710 jobject o = env_->NewLocalRef(s);
711 EXPECT_TRUE(o != NULL);
712 EXPECT_TRUE(o != s);
713
714 // TODO: check that o is a local reference.
715}
716
717TEST_F(JniInternalTest, DeleteLocalRef_NULL) {
718 env_->DeleteLocalRef(NULL);
719}
720
721TEST_F(JniInternalTest, DeleteLocalRef) {
722 jstring s = env_->NewStringUTF("");
723 ASSERT_TRUE(s != NULL);
724 env_->DeleteLocalRef(s);
725
726 // Currently, deleting an already-deleted reference is just a warning.
Elliott Hughesa2501992011-08-26 19:39:54 -0700727 vm_->check_jni_abort_hook = TestCheckJniAbortHook;
Elliott Hughes18c07532011-08-18 15:50:51 -0700728 env_->DeleteLocalRef(s);
Elliott Hughesa2501992011-08-26 19:39:54 -0700729 vm_->check_jni_abort_hook = NULL;
Elliott Hughes18c07532011-08-18 15:50:51 -0700730
731 s = env_->NewStringUTF("");
732 ASSERT_TRUE(s != NULL);
733 jobject o = env_->NewLocalRef(s);
734 ASSERT_TRUE(o != NULL);
735
736 env_->DeleteLocalRef(s);
737 env_->DeleteLocalRef(o);
738}
739
740TEST_F(JniInternalTest, NewGlobalRef_NULL) {
741 EXPECT_TRUE(env_->NewGlobalRef(NULL) == NULL);
742}
743
744TEST_F(JniInternalTest, NewGlobalRef) {
745 jstring s = env_->NewStringUTF("");
746 ASSERT_TRUE(s != NULL);
747 jobject o = env_->NewGlobalRef(s);
748 EXPECT_TRUE(o != NULL);
749 EXPECT_TRUE(o != s);
750
751 // TODO: check that o is a global reference.
752}
753
754TEST_F(JniInternalTest, DeleteGlobalRef_NULL) {
755 env_->DeleteGlobalRef(NULL);
756}
757
758TEST_F(JniInternalTest, DeleteGlobalRef) {
759 jstring s = env_->NewStringUTF("");
760 ASSERT_TRUE(s != NULL);
761
762 jobject o = env_->NewGlobalRef(s);
763 ASSERT_TRUE(o != NULL);
764 env_->DeleteGlobalRef(o);
765
Elliott Hughesa2501992011-08-26 19:39:54 -0700766 vm_->check_jni_abort_hook = TestCheckJniAbortHook;
Elliott Hughes18c07532011-08-18 15:50:51 -0700767 // Currently, deleting an already-deleted reference is just a warning.
768 env_->DeleteGlobalRef(o);
Elliott Hughesa2501992011-08-26 19:39:54 -0700769 vm_->check_jni_abort_hook = NULL;
Elliott Hughes18c07532011-08-18 15:50:51 -0700770
771 jobject o1 = env_->NewGlobalRef(s);
772 ASSERT_TRUE(o1 != NULL);
773 jobject o2 = env_->NewGlobalRef(s);
774 ASSERT_TRUE(o2 != NULL);
775
776 env_->DeleteGlobalRef(o1);
777 env_->DeleteGlobalRef(o2);
778}
779
780TEST_F(JniInternalTest, NewWeakGlobalRef_NULL) {
781 EXPECT_TRUE(env_->NewWeakGlobalRef(NULL) == NULL);
782}
783
784TEST_F(JniInternalTest, NewWeakGlobalRef) {
785 jstring s = env_->NewStringUTF("");
786 ASSERT_TRUE(s != NULL);
787 jobject o = env_->NewWeakGlobalRef(s);
788 EXPECT_TRUE(o != NULL);
789 EXPECT_TRUE(o != s);
790
791 // TODO: check that o is a weak global reference.
792}
793
794TEST_F(JniInternalTest, DeleteWeakGlobalRef_NULL) {
795 env_->DeleteWeakGlobalRef(NULL);
796}
797
798TEST_F(JniInternalTest, DeleteWeakGlobalRef) {
799 jstring s = env_->NewStringUTF("");
800 ASSERT_TRUE(s != NULL);
801
802 jobject o = env_->NewWeakGlobalRef(s);
803 ASSERT_TRUE(o != NULL);
804 env_->DeleteWeakGlobalRef(o);
805
Elliott Hughesa2501992011-08-26 19:39:54 -0700806 vm_->check_jni_abort_hook = TestCheckJniAbortHook;
Elliott Hughes18c07532011-08-18 15:50:51 -0700807 // Currently, deleting an already-deleted reference is just a warning.
808 env_->DeleteWeakGlobalRef(o);
Elliott Hughesa2501992011-08-26 19:39:54 -0700809 vm_->check_jni_abort_hook = NULL;
Elliott Hughes18c07532011-08-18 15:50:51 -0700810
811 jobject o1 = env_->NewWeakGlobalRef(s);
812 ASSERT_TRUE(o1 != NULL);
813 jobject o2 = env_->NewWeakGlobalRef(s);
814 ASSERT_TRUE(o2 != NULL);
815
816 env_->DeleteWeakGlobalRef(o1);
817 env_->DeleteWeakGlobalRef(o2);
818}
819
Carl Shapiro9b9ba282011-08-14 15:30:39 -0700820#if defined(__arm__)
821TEST_F(JniInternalTest, StaticMainMethod) {
Brian Carlstrom9baa4ae2011-09-01 21:14:14 -0700822 const ClassLoader* class_loader = LoadDex("Main");
823 CompileDirectMethod(class_loader, "Main", "main", "([Ljava/lang/String;)V");
Carl Shapiro9b9ba282011-08-14 15:30:39 -0700824
825 Class* klass = class_linker_->FindClass("LMain;", class_loader);
826 ASSERT_TRUE(klass != NULL);
827
828 Method* method = klass->FindDirectMethod("main", "([Ljava/lang/String;)V");
829 ASSERT_TRUE(method != NULL);
830
Brian Carlstrom9baa4ae2011-09-01 21:14:14 -0700831 Method::InvokeStub* stub = method->GetInvokeStub();
Carl Shapiro9b9ba282011-08-14 15:30:39 -0700832
833 Object* arg = NULL;
834
Ian Rogersff1ed472011-09-20 13:46:24 -0700835 (*stub)(method, NULL, Thread::Current(), reinterpret_cast<byte*>(&arg), NULL);
Carl Shapiro9b9ba282011-08-14 15:30:39 -0700836}
837
838TEST_F(JniInternalTest, StaticNopMethod) {
Brian Carlstrom9baa4ae2011-09-01 21:14:14 -0700839 const ClassLoader* class_loader = LoadDex("StaticLeafMethods");
840 CompileDirectMethod(class_loader, "StaticLeafMethods", "nop", "()V");
Carl Shapiro9b9ba282011-08-14 15:30:39 -0700841
842 Class* klass = class_linker_->FindClass("LStaticLeafMethods;", class_loader);
843 ASSERT_TRUE(klass != NULL);
844
845 Method* method = klass->FindDirectMethod("nop", "()V");
846 ASSERT_TRUE(method != NULL);
847
Brian Carlstrom9baa4ae2011-09-01 21:14:14 -0700848 Method::InvokeStub* stub = method->GetInvokeStub();
Carl Shapiro9b9ba282011-08-14 15:30:39 -0700849
Ian Rogersff1ed472011-09-20 13:46:24 -0700850 (*stub)(method, NULL, Thread::Current(), NULL, NULL);
Carl Shapiro9b9ba282011-08-14 15:30:39 -0700851}
852
853TEST_F(JniInternalTest, StaticIdentityByteMethod) {
Brian Carlstrom9baa4ae2011-09-01 21:14:14 -0700854 const ClassLoader* class_loader = LoadDex("StaticLeafMethods");
855 CompileDirectMethod(class_loader, "StaticLeafMethods", "identity", "(B)B");
Carl Shapiro9b9ba282011-08-14 15:30:39 -0700856
857 Class* klass = class_linker_->FindClass("LStaticLeafMethods;", class_loader);
858 ASSERT_TRUE(klass != NULL);
859
860 Method* method = klass->FindDirectMethod("identity", "(B)B");
861 ASSERT_TRUE(method != NULL);
862
Brian Carlstrom9baa4ae2011-09-01 21:14:14 -0700863 Method::InvokeStub* stub = method->GetInvokeStub();
Carl Shapiro9b9ba282011-08-14 15:30:39 -0700864
865 int arg;
866 JValue result;
867
868 arg = 0;
869 result.b = -1;
Ian Rogersff1ed472011-09-20 13:46:24 -0700870 (*stub)(method, NULL, Thread::Current(), reinterpret_cast<byte*>(&arg), &result);
Carl Shapiro9b9ba282011-08-14 15:30:39 -0700871 EXPECT_EQ(0, result.b);
872
873 arg = -1;
874 result.b = 0;
Ian Rogersff1ed472011-09-20 13:46:24 -0700875 (*stub)(method, NULL, Thread::Current(), reinterpret_cast<byte*>(&arg), &result);
Carl Shapiro9b9ba282011-08-14 15:30:39 -0700876 EXPECT_EQ(-1, result.b);
877
878 arg = SCHAR_MAX;
879 result.b = 0;
Ian Rogersff1ed472011-09-20 13:46:24 -0700880 (*stub)(method, NULL, Thread::Current(), reinterpret_cast<byte*>(&arg), &result);
Carl Shapiro9b9ba282011-08-14 15:30:39 -0700881 EXPECT_EQ(SCHAR_MAX, result.b);
882
883 arg = SCHAR_MIN;
884 result.b = 0;
Ian Rogersff1ed472011-09-20 13:46:24 -0700885 (*stub)(method, NULL, Thread::Current(), reinterpret_cast<byte*>(&arg), &result);
Carl Shapiro9b9ba282011-08-14 15:30:39 -0700886 EXPECT_EQ(SCHAR_MIN, result.b);
Carl Shapiro9b9ba282011-08-14 15:30:39 -0700887}
888
889TEST_F(JniInternalTest, StaticIdentityIntMethod) {
Brian Carlstrom9baa4ae2011-09-01 21:14:14 -0700890 const ClassLoader* class_loader = LoadDex("StaticLeafMethods");
891 CompileDirectMethod(class_loader, "StaticLeafMethods", "identity", "(I)I");
Carl Shapiro9b9ba282011-08-14 15:30:39 -0700892
893 Class* klass = class_linker_->FindClass("LStaticLeafMethods;", class_loader);
894 ASSERT_TRUE(klass != NULL);
895
896 Method* method = klass->FindDirectMethod("identity", "(I)I");
897 ASSERT_TRUE(method != NULL);
898
Brian Carlstrom9baa4ae2011-09-01 21:14:14 -0700899 Method::InvokeStub* stub = method->GetInvokeStub();
Carl Shapiro9b9ba282011-08-14 15:30:39 -0700900
901 int arg;
902 JValue result;
903
904 arg = 0;
905 result.i = -1;
Ian Rogersff1ed472011-09-20 13:46:24 -0700906 (*stub)(method, NULL, Thread::Current(), reinterpret_cast<byte*>(&arg), &result);
Carl Shapiro9b9ba282011-08-14 15:30:39 -0700907 EXPECT_EQ(0, result.i);
908
909 arg = -1;
910 result.i = 0;
Ian Rogersff1ed472011-09-20 13:46:24 -0700911 (*stub)(method, NULL, Thread::Current(), reinterpret_cast<byte*>(&arg), &result);
Carl Shapiro9b9ba282011-08-14 15:30:39 -0700912 EXPECT_EQ(-1, result.i);
913
914 arg = INT_MAX;
915 result.i = 0;
Ian Rogersff1ed472011-09-20 13:46:24 -0700916 (*stub)(method, NULL, Thread::Current(), reinterpret_cast<byte*>(&arg), &result);
Carl Shapiro9b9ba282011-08-14 15:30:39 -0700917 EXPECT_EQ(INT_MAX, result.i);
918
919 arg = INT_MIN;
920 result.i = 0;
Ian Rogersff1ed472011-09-20 13:46:24 -0700921 (*stub)(method, NULL, Thread::Current(), reinterpret_cast<byte*>(&arg), &result);
Carl Shapiro9b9ba282011-08-14 15:30:39 -0700922 EXPECT_EQ(INT_MIN, result.i);
Carl Shapiro9b9ba282011-08-14 15:30:39 -0700923}
924
925TEST_F(JniInternalTest, StaticIdentityDoubleMethod) {
Brian Carlstrom9baa4ae2011-09-01 21:14:14 -0700926 const ClassLoader* class_loader = LoadDex("StaticLeafMethods");
927 CompileDirectMethod(class_loader, "StaticLeafMethods", "identity", "(D)D");
Carl Shapiro9b9ba282011-08-14 15:30:39 -0700928
929 Class* klass = class_linker_->FindClass("LStaticLeafMethods;", class_loader);
930 ASSERT_TRUE(klass != NULL);
931
932 Method* method = klass->FindDirectMethod("identity", "(D)D");
933 ASSERT_TRUE(method != NULL);
934
Brian Carlstrom9baa4ae2011-09-01 21:14:14 -0700935 Method::InvokeStub* stub = method->GetInvokeStub();
Carl Shapiro9b9ba282011-08-14 15:30:39 -0700936
937 double arg;
938 JValue result;
939
940 arg = 0.0;
941 result.d = -1.0;
Ian Rogersff1ed472011-09-20 13:46:24 -0700942 (*stub)(method, NULL, Thread::Current(), reinterpret_cast<byte*>(&arg), &result);
Carl Shapiro9b9ba282011-08-14 15:30:39 -0700943 EXPECT_EQ(0.0, result.d);
944
945 arg = -1.0;
946 result.d = 0.0;
Ian Rogersff1ed472011-09-20 13:46:24 -0700947 (*stub)(method, NULL, Thread::Current(), reinterpret_cast<byte*>(&arg), &result);
Carl Shapiro9b9ba282011-08-14 15:30:39 -0700948 EXPECT_EQ(-1.0, result.d);
949
950 arg = DBL_MAX;
951 result.d = 0.0;
Ian Rogersff1ed472011-09-20 13:46:24 -0700952 (*stub)(method, NULL, Thread::Current(), reinterpret_cast<byte*>(&arg), &result);
Carl Shapiro9b9ba282011-08-14 15:30:39 -0700953 EXPECT_EQ(DBL_MAX, result.d);
954
955 arg = DBL_MIN;
956 result.d = 0.0;
Ian Rogersff1ed472011-09-20 13:46:24 -0700957 (*stub)(method, NULL, Thread::Current(), reinterpret_cast<byte*>(&arg), &result);
Carl Shapiro9b9ba282011-08-14 15:30:39 -0700958 EXPECT_EQ(DBL_MIN, result.d);
Carl Shapiro9b9ba282011-08-14 15:30:39 -0700959}
960
961TEST_F(JniInternalTest, StaticSumIntIntMethod) {
Brian Carlstrom9baa4ae2011-09-01 21:14:14 -0700962 const ClassLoader* class_loader = LoadDex("StaticLeafMethods");
963 CompileDirectMethod(class_loader, "StaticLeafMethods", "sum", "(II)I");
Carl Shapiro9b9ba282011-08-14 15:30:39 -0700964
965 Class* klass = class_linker_->FindClass("LStaticLeafMethods;", class_loader);
966 ASSERT_TRUE(klass != NULL);
967
968 Method* method = klass->FindDirectMethod("sum", "(II)I");
969 ASSERT_TRUE(method != NULL);
970
Brian Carlstrom9baa4ae2011-09-01 21:14:14 -0700971 Method::InvokeStub* stub = method->GetInvokeStub();
Carl Shapiro9b9ba282011-08-14 15:30:39 -0700972
973 int args[2];
974 JValue result;
975
976 args[0] = 0;
977 args[1] = 0;
978 result.i = -1;
Ian Rogersff1ed472011-09-20 13:46:24 -0700979 (*stub)(method, NULL, Thread::Current(), reinterpret_cast<byte*>(args), &result);
Carl Shapiro9b9ba282011-08-14 15:30:39 -0700980 EXPECT_EQ(0, result.i);
981
982 args[0] = 1;
983 args[1] = 2;
984 result.i = 0;
Ian Rogersff1ed472011-09-20 13:46:24 -0700985 (*stub)(method, NULL, Thread::Current(), reinterpret_cast<byte*>(args), &result);
Carl Shapiro9b9ba282011-08-14 15:30:39 -0700986 EXPECT_EQ(3, result.i);
987
988 args[0] = -2;
989 args[1] = 5;
990 result.i = 0;
Ian Rogersff1ed472011-09-20 13:46:24 -0700991 (*stub)(method, NULL, Thread::Current(), reinterpret_cast<byte*>(args), &result);
Carl Shapiro9b9ba282011-08-14 15:30:39 -0700992 EXPECT_EQ(3, result.i);
993
994 args[0] = INT_MAX;
995 args[1] = INT_MIN;
996 result.i = 1234;
Ian Rogersff1ed472011-09-20 13:46:24 -0700997 (*stub)(method, NULL, Thread::Current(), reinterpret_cast<byte*>(args), &result);
Carl Shapiro9b9ba282011-08-14 15:30:39 -0700998 EXPECT_EQ(-1, result.i);
999
1000 args[0] = INT_MAX;
1001 args[1] = INT_MAX;
1002 result.i = INT_MIN;
Ian Rogersff1ed472011-09-20 13:46:24 -07001003 (*stub)(method, NULL, Thread::Current(), reinterpret_cast<byte*>(args), &result);
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001004 EXPECT_EQ(-2, result.i);
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001005}
1006
1007TEST_F(JniInternalTest, StaticSumIntIntIntMethod) {
Brian Carlstrom9baa4ae2011-09-01 21:14:14 -07001008 const ClassLoader* class_loader = LoadDex("StaticLeafMethods");
1009 CompileDirectMethod(class_loader, "StaticLeafMethods", "sum", "(III)I");
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001010
1011 Class* klass = class_linker_->FindClass("LStaticLeafMethods;", class_loader);
1012 ASSERT_TRUE(klass != NULL);
1013
1014 Method* method = klass->FindDirectMethod("sum", "(III)I");
1015 ASSERT_TRUE(method != NULL);
1016
Brian Carlstrom9baa4ae2011-09-01 21:14:14 -07001017 Method::InvokeStub* stub = method->GetInvokeStub();
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001018
1019 int args[3];
1020 JValue result;
1021
1022 args[0] = 0;
1023 args[1] = 0;
1024 args[2] = 0;
1025 result.i = -1;
Ian Rogersff1ed472011-09-20 13:46:24 -07001026 (*stub)(method, NULL, Thread::Current(), reinterpret_cast<byte*>(args), &result);
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001027 EXPECT_EQ(0, result.i);
1028
1029 args[0] = 1;
1030 args[1] = 2;
1031 args[2] = 3;
1032 result.i = 0;
Ian Rogersff1ed472011-09-20 13:46:24 -07001033 (*stub)(method, NULL, Thread::Current(), reinterpret_cast<byte*>(args), &result);
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001034 EXPECT_EQ(6, result.i);
1035
1036 args[0] = -1;
1037 args[1] = 2;
1038 args[2] = -3;
1039 result.i = 0;
Ian Rogersff1ed472011-09-20 13:46:24 -07001040 (*stub)(method, NULL, Thread::Current(), reinterpret_cast<byte*>(args), &result);
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001041 EXPECT_EQ(-2, result.i);
1042
1043 args[0] = INT_MAX;
1044 args[1] = INT_MIN;
1045 args[2] = INT_MAX;
1046 result.i = 1234;
Ian Rogersff1ed472011-09-20 13:46:24 -07001047 (*stub)(method, NULL, Thread::Current(), reinterpret_cast<byte*>(args), &result);
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001048 EXPECT_EQ(2147483646, result.i);
1049
1050 args[0] = INT_MAX;
1051 args[1] = INT_MAX;
1052 args[2] = INT_MAX;
1053 result.i = INT_MIN;
Ian Rogersff1ed472011-09-20 13:46:24 -07001054 (*stub)(method, NULL, Thread::Current(), reinterpret_cast<byte*>(args), &result);
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001055 EXPECT_EQ(2147483645, result.i);
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001056}
1057
1058TEST_F(JniInternalTest, StaticSumIntIntIntIntMethod) {
Brian Carlstrom9baa4ae2011-09-01 21:14:14 -07001059 const ClassLoader* class_loader = LoadDex("StaticLeafMethods");
1060 CompileDirectMethod(class_loader, "StaticLeafMethods", "sum", "(IIII)I");
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001061
1062 Class* klass = class_linker_->FindClass("LStaticLeafMethods;", class_loader);
1063 ASSERT_TRUE(klass != NULL);
1064
1065 Method* method = klass->FindDirectMethod("sum", "(IIII)I");
1066 ASSERT_TRUE(method != NULL);
1067
Brian Carlstrom9baa4ae2011-09-01 21:14:14 -07001068 Method::InvokeStub* stub = method->GetInvokeStub();
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001069
1070 int args[4];
1071 JValue result;
1072
1073 args[0] = 0;
1074 args[1] = 0;
1075 args[2] = 0;
1076 args[3] = 0;
1077 result.i = -1;
Ian Rogersff1ed472011-09-20 13:46:24 -07001078 (*stub)(method, NULL, Thread::Current(), reinterpret_cast<byte*>(args), &result);
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001079 EXPECT_EQ(0, result.i);
1080
1081 args[0] = 1;
1082 args[1] = 2;
1083 args[2] = 3;
1084 args[3] = 4;
1085 result.i = 0;
Ian Rogersff1ed472011-09-20 13:46:24 -07001086 (*stub)(method, NULL, Thread::Current(), reinterpret_cast<byte*>(args), &result);
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001087 EXPECT_EQ(10, result.i);
1088
1089 args[0] = -1;
1090 args[1] = 2;
1091 args[2] = -3;
1092 args[3] = 4;
1093 result.i = 0;
Ian Rogersff1ed472011-09-20 13:46:24 -07001094 (*stub)(method, NULL, Thread::Current(), reinterpret_cast<byte*>(args), &result);
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001095 EXPECT_EQ(2, result.i);
1096
1097 args[0] = INT_MAX;
1098 args[1] = INT_MIN;
1099 args[2] = INT_MAX;
1100 args[3] = INT_MIN;
1101 result.i = 1234;
Ian Rogersff1ed472011-09-20 13:46:24 -07001102 (*stub)(method, NULL, Thread::Current(), reinterpret_cast<byte*>(args), &result);
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001103 EXPECT_EQ(-2, result.i);
1104
1105 args[0] = INT_MAX;
1106 args[1] = INT_MAX;
1107 args[2] = INT_MAX;
1108 args[3] = INT_MAX;
1109 result.i = INT_MIN;
Ian Rogersff1ed472011-09-20 13:46:24 -07001110 (*stub)(method, NULL, Thread::Current(), reinterpret_cast<byte*>(args), &result);
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001111 EXPECT_EQ(-4, result.i);
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001112}
1113
1114TEST_F(JniInternalTest, StaticSumIntIntIntIntIntMethod) {
Brian Carlstrom9baa4ae2011-09-01 21:14:14 -07001115 const ClassLoader* class_loader = LoadDex("StaticLeafMethods");
1116 CompileDirectMethod(class_loader, "StaticLeafMethods", "sum", "(IIIII)I");
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001117
1118 Class* klass = class_linker_->FindClass("LStaticLeafMethods;", class_loader);
1119 ASSERT_TRUE(klass != NULL);
1120
1121 Method* method = klass->FindDirectMethod("sum", "(IIIII)I");
1122 ASSERT_TRUE(method != NULL);
1123
Brian Carlstrom9baa4ae2011-09-01 21:14:14 -07001124 Method::InvokeStub* stub = method->GetInvokeStub();
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001125
1126 int args[5];
1127 JValue result;
1128
1129 args[0] = 0;
1130 args[1] = 0;
1131 args[2] = 0;
1132 args[3] = 0;
1133 args[4] = 0;
1134 result.i = -1.0;
Ian Rogersff1ed472011-09-20 13:46:24 -07001135 (*stub)(method, NULL, Thread::Current(), reinterpret_cast<byte*>(args), &result);
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001136 EXPECT_EQ(0, result.i);
1137
1138 args[0] = 1;
1139 args[1] = 2;
1140 args[2] = 3;
1141 args[3] = 4;
1142 args[4] = 5;
1143 result.i = 0;
Ian Rogersff1ed472011-09-20 13:46:24 -07001144 (*stub)(method, NULL, Thread::Current(), reinterpret_cast<byte*>(args), &result);
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001145 EXPECT_EQ(15, result.i);
1146
1147 args[0] = -1;
1148 args[1] = 2;
1149 args[2] = -3;
1150 args[3] = 4;
1151 args[4] = -5;
1152 result.i = 0;
Ian Rogersff1ed472011-09-20 13:46:24 -07001153 (*stub)(method, NULL, Thread::Current(), reinterpret_cast<byte*>(args), &result);
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001154 EXPECT_EQ(-3, result.i);
1155
1156 args[0] = INT_MAX;
1157 args[1] = INT_MIN;
1158 args[2] = INT_MAX;
1159 args[3] = INT_MIN;
1160 args[4] = INT_MAX;
1161 result.i = 1234;
Ian Rogersff1ed472011-09-20 13:46:24 -07001162 (*stub)(method, NULL, Thread::Current(), reinterpret_cast<byte*>(args), &result);
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001163 EXPECT_EQ(2147483645, result.i);
1164
1165 args[0] = INT_MAX;
1166 args[1] = INT_MAX;
1167 args[2] = INT_MAX;
1168 args[3] = INT_MAX;
1169 args[4] = INT_MAX;
1170 result.i = INT_MIN;
Ian Rogersff1ed472011-09-20 13:46:24 -07001171 (*stub)(method, NULL, Thread::Current(), reinterpret_cast<byte*>(args), &result);
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001172 EXPECT_EQ(2147483643, result.i);
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001173}
1174
1175TEST_F(JniInternalTest, StaticSumDoubleDoubleMethod) {
Brian Carlstrom9baa4ae2011-09-01 21:14:14 -07001176 const ClassLoader* class_loader = LoadDex("StaticLeafMethods");
1177 CompileDirectMethod(class_loader, "StaticLeafMethods", "sum", "(DD)D");
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001178
1179 Class* klass = class_linker_->FindClass("LStaticLeafMethods;", class_loader);
1180 ASSERT_TRUE(klass != NULL);
1181
1182 Method* method = klass->FindDirectMethod("sum", "(DD)D");
1183 ASSERT_TRUE(method != NULL);
1184
Brian Carlstrom9baa4ae2011-09-01 21:14:14 -07001185 Method::InvokeStub* stub = method->GetInvokeStub();
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001186
1187 double args[2];
1188 JValue result;
1189
1190 args[0] = 0.0;
1191 args[1] = 0.0;
1192 result.d = -1.0;
Ian Rogersff1ed472011-09-20 13:46:24 -07001193 (*stub)(method, NULL, Thread::Current(), reinterpret_cast<byte*>(args), &result);
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001194 EXPECT_EQ(0.0, result.d);
1195
1196 args[0] = 1.0;
1197 args[1] = 2.0;
1198 result.d = 0.0;
Ian Rogersff1ed472011-09-20 13:46:24 -07001199 (*stub)(method, NULL, Thread::Current(), reinterpret_cast<byte*>(args), &result);
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001200 EXPECT_EQ(3.0, result.d);
1201
1202 args[0] = 1.0;
1203 args[1] = -2.0;
1204 result.d = 0.0;
Ian Rogersff1ed472011-09-20 13:46:24 -07001205 (*stub)(method, NULL, Thread::Current(), reinterpret_cast<byte*>(args), &result);
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001206 EXPECT_EQ(-1.0, result.d);
1207
1208 args[0] = DBL_MAX;
1209 args[1] = DBL_MIN;
1210 result.d = 0.0;
Ian Rogersff1ed472011-09-20 13:46:24 -07001211 (*stub)(method, NULL, Thread::Current(), reinterpret_cast<byte*>(args), &result);
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001212 EXPECT_EQ(1.7976931348623157e308, result.d);
1213
1214 args[0] = DBL_MAX;
1215 args[1] = DBL_MAX;
1216 result.d = 0.0;
Ian Rogersff1ed472011-09-20 13:46:24 -07001217 (*stub)(method, NULL, Thread::Current(), reinterpret_cast<byte*>(args), &result);
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001218 EXPECT_EQ(INFINITY, result.d);
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001219}
1220
1221TEST_F(JniInternalTest, StaticSumDoubleDoubleDoubleMethod) {
Brian Carlstrom9baa4ae2011-09-01 21:14:14 -07001222 const ClassLoader* class_loader = LoadDex("StaticLeafMethods");
1223 CompileDirectMethod(class_loader, "StaticLeafMethods", "sum", "(DDD)D");
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001224
1225 Class* klass = class_linker_->FindClass("LStaticLeafMethods;", class_loader);
1226 ASSERT_TRUE(klass != NULL);
1227
1228 Method* method = klass->FindDirectMethod("sum", "(DDD)D");
1229 ASSERT_TRUE(method != NULL);
1230
Brian Carlstrom9baa4ae2011-09-01 21:14:14 -07001231 Method::InvokeStub* stub = method->GetInvokeStub();
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001232
1233 double args[3];
1234 JValue result;
1235
1236 args[0] = 0.0;
1237 args[1] = 0.0;
1238 args[2] = 0.0;
1239 result.d = -1.0;
Ian Rogersff1ed472011-09-20 13:46:24 -07001240 (*stub)(method, NULL, Thread::Current(), reinterpret_cast<byte*>(args), &result);
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001241 EXPECT_EQ(0.0, result.d);
1242
1243 args[0] = 1.0;
1244 args[1] = 2.0;
1245 args[2] = 3.0;
1246 result.d = 0.0;
Ian Rogersff1ed472011-09-20 13:46:24 -07001247 (*stub)(method, NULL, Thread::Current(), reinterpret_cast<byte*>(args), &result);
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001248 EXPECT_EQ(6.0, result.d);
1249
1250 args[0] = 1.0;
1251 args[1] = -2.0;
1252 args[2] = 3.0;
1253 result.d = 0.0;
Ian Rogersff1ed472011-09-20 13:46:24 -07001254 (*stub)(method, NULL, Thread::Current(), reinterpret_cast<byte*>(args), &result);
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001255 EXPECT_EQ(2.0, result.d);
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001256}
1257
1258TEST_F(JniInternalTest, StaticSumDoubleDoubleDoubleDoubleMethod) {
Brian Carlstrom9baa4ae2011-09-01 21:14:14 -07001259 const ClassLoader* class_loader = LoadDex("StaticLeafMethods");
1260 CompileDirectMethod(class_loader, "StaticLeafMethods", "sum", "(DDDD)D");
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001261
1262 Class* klass = class_linker_->FindClass("LStaticLeafMethods;", class_loader);
1263 ASSERT_TRUE(klass != NULL);
1264
1265 Method* method = klass->FindDirectMethod("sum", "(DDDD)D");
1266 ASSERT_TRUE(method != NULL);
1267
Brian Carlstrom9baa4ae2011-09-01 21:14:14 -07001268 Method::InvokeStub* stub = method->GetInvokeStub();
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001269
1270 double args[4];
1271 JValue result;
1272
1273 args[0] = 0.0;
1274 args[1] = 0.0;
1275 args[2] = 0.0;
1276 args[3] = 0.0;
1277 result.d = -1.0;
Ian Rogersff1ed472011-09-20 13:46:24 -07001278 (*stub)(method, NULL, Thread::Current(), reinterpret_cast<byte*>(args), &result);
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001279 EXPECT_EQ(0.0, result.d);
1280
1281 args[0] = 1.0;
1282 args[1] = 2.0;
1283 args[2] = 3.0;
1284 args[3] = 4.0;
1285 result.d = 0.0;
Ian Rogersff1ed472011-09-20 13:46:24 -07001286 (*stub)(method, NULL, Thread::Current(), reinterpret_cast<byte*>(args), &result);
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001287 EXPECT_EQ(10.0, result.d);
1288
1289 args[0] = 1.0;
1290 args[1] = -2.0;
1291 args[2] = 3.0;
1292 args[3] = -4.0;
1293 result.d = 0.0;
Ian Rogersff1ed472011-09-20 13:46:24 -07001294 (*stub)(method, NULL, Thread::Current(), reinterpret_cast<byte*>(args), &result);
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001295 EXPECT_EQ(-2.0, result.d);
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001296}
1297
1298TEST_F(JniInternalTest, StaticSumDoubleDoubleDoubleDoubleDoubleMethod) {
Brian Carlstrom9baa4ae2011-09-01 21:14:14 -07001299 const ClassLoader* class_loader = LoadDex("StaticLeafMethods");
1300 CompileDirectMethod(class_loader, "StaticLeafMethods", "sum", "(DDDDD)D");
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001301
1302 Class* klass = class_linker_->FindClass("LStaticLeafMethods;", class_loader);
1303 ASSERT_TRUE(klass != NULL);
1304
1305 Method* method = klass->FindDirectMethod("sum", "(DDDDD)D");
1306 ASSERT_TRUE(method != NULL);
1307
Brian Carlstrom9baa4ae2011-09-01 21:14:14 -07001308 Method::InvokeStub* stub = method->GetInvokeStub();
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001309
1310 double args[5];
1311 JValue result;
1312
1313 args[0] = 0.0;
1314 args[1] = 0.0;
1315 args[2] = 0.0;
1316 args[3] = 0.0;
1317 args[4] = 0.0;
1318 result.d = -1.0;
Ian Rogersff1ed472011-09-20 13:46:24 -07001319 (*stub)(method, NULL, Thread::Current(), reinterpret_cast<byte*>(args), &result);
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001320 EXPECT_EQ(0.0, result.d);
1321
1322 args[0] = 1.0;
1323 args[1] = 2.0;
1324 args[2] = 3.0;
1325 args[3] = 4.0;
1326 args[4] = 5.0;
1327 result.d = 0.0;
Ian Rogersff1ed472011-09-20 13:46:24 -07001328 (*stub)(method, NULL, Thread::Current(), reinterpret_cast<byte*>(args), &result);
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001329 EXPECT_EQ(15.0, result.d);
1330
1331 args[0] = 1.0;
1332 args[1] = -2.0;
1333 args[2] = 3.0;
1334 args[3] = -4.0;
1335 args[4] = 5.0;
1336 result.d = 0.0;
Ian Rogersff1ed472011-09-20 13:46:24 -07001337 (*stub)(method, NULL, Thread::Current(), reinterpret_cast<byte*>(args), &result);
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001338 EXPECT_EQ(3.0, result.d);
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001339}
1340#endif // __arm__
1341
Elliott Hughes37f7a402011-08-22 18:56:01 -07001342TEST_F(JniInternalTest, Throw) {
1343 EXPECT_EQ(JNI_ERR, env_->Throw(NULL));
1344
1345 jclass exception_class = env_->FindClass("java/lang/RuntimeException");
1346 ASSERT_TRUE(exception_class != NULL);
1347 jthrowable exception = reinterpret_cast<jthrowable>(env_->AllocObject(exception_class));
1348 ASSERT_TRUE(exception != NULL);
1349
1350 EXPECT_EQ(JNI_OK, env_->Throw(exception));
1351 EXPECT_TRUE(env_->ExceptionCheck());
Elliott Hughesa2501992011-08-26 19:39:54 -07001352 jthrowable thrown_exception = env_->ExceptionOccurred();
Elliott Hughes37f7a402011-08-22 18:56:01 -07001353 env_->ExceptionClear();
Elliott Hughesa2501992011-08-26 19:39:54 -07001354 EXPECT_TRUE(env_->IsSameObject(exception, thrown_exception));
Elliott Hughes37f7a402011-08-22 18:56:01 -07001355}
1356
1357TEST_F(JniInternalTest, ThrowNew) {
1358 EXPECT_EQ(JNI_ERR, env_->Throw(NULL));
1359
1360 jclass exception_class = env_->FindClass("java/lang/RuntimeException");
1361 ASSERT_TRUE(exception_class != NULL);
1362
Elliott Hughes5cb5ad22011-10-02 12:13:39 -07001363 jthrowable thrown_exception;
1364
Elliott Hughes37f7a402011-08-22 18:56:01 -07001365 EXPECT_EQ(JNI_OK, env_->ThrowNew(exception_class, "hello world"));
1366 EXPECT_TRUE(env_->ExceptionCheck());
Elliott Hughes5cb5ad22011-10-02 12:13:39 -07001367 thrown_exception = env_->ExceptionOccurred();
1368 env_->ExceptionClear();
1369 EXPECT_TRUE(env_->IsInstanceOf(thrown_exception, exception_class));
1370
1371 EXPECT_EQ(JNI_OK, env_->ThrowNew(exception_class, NULL));
1372 EXPECT_TRUE(env_->ExceptionCheck());
1373 thrown_exception = env_->ExceptionOccurred();
Elliott Hughes37f7a402011-08-22 18:56:01 -07001374 env_->ExceptionClear();
Elliott Hughesa2501992011-08-26 19:39:54 -07001375 EXPECT_TRUE(env_->IsInstanceOf(thrown_exception, exception_class));
Elliott Hughes37f7a402011-08-22 18:56:01 -07001376}
1377
Elliott Hughesb465ab02011-08-24 11:21:21 -07001378// TODO: this test is DISABLED until we can actually run java.nio.Buffer's <init>.
1379TEST_F(JniInternalTest, DISABLED_NewDirectBuffer_GetDirectBufferAddress_GetDirectBufferCapacity) {
1380 jclass buffer_class = env_->FindClass("java/nio/Buffer");
1381 ASSERT_TRUE(buffer_class != NULL);
1382
1383 char bytes[1024];
1384 jobject buffer = env_->NewDirectByteBuffer(bytes, sizeof(bytes));
1385 ASSERT_TRUE(buffer != NULL);
1386 ASSERT_TRUE(env_->IsInstanceOf(buffer, buffer_class));
1387 ASSERT_TRUE(env_->GetDirectBufferAddress(buffer) == bytes);
1388 ASSERT_TRUE(env_->GetDirectBufferCapacity(buffer) == sizeof(bytes));
1389}
1390
Ian Rogers0cfe1fb2011-08-26 03:29:44 -07001391} // namespace art