blob: 1d0f35f980e11e1318f478134371f0924ae56b5d [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 <cmath>
6#include <sys/mman.h>
7
8#include "common_test.h"
Elliott Hughes0c9cd562011-08-12 10:59:29 -07009#include "gtest/gtest.h"
10
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 // TODO: when these tests start failing because you're calling FindClass
73 // with a pending exception, fix EXPECT_CLASS_NOT_FOUND to assert that an
74 // exception was thrown and clear the exception.
75
Elliott Hughes0c9cd562011-08-12 10:59:29 -070076 // Reference types...
Elliott Hughes0c9cd562011-08-12 10:59:29 -070077 EXPECT_CLASS_FOUND("java/lang/String");
Elliott Hughes0c9cd562011-08-12 10:59:29 -070078 // ...for arrays too, where you must include "L;".
79 EXPECT_CLASS_FOUND("[Ljava/lang/String;");
Elliott Hughesa2501992011-08-26 19:39:54 -070080
81 vm_->check_jni_abort_hook = TestCheckJniAbortHook;
82 // We support . as well as / for compatibility, if -Xcheck:jni is off.
83 EXPECT_CLASS_FOUND("java.lang.String");
84 EXPECT_CLASS_NOT_FOUND("Ljava.lang.String;");
Elliott Hughes0c9cd562011-08-12 10:59:29 -070085 EXPECT_CLASS_FOUND("[Ljava.lang.String;");
86 EXPECT_CLASS_NOT_FOUND("[java.lang.String");
87
Elliott Hughesa2501992011-08-26 19:39:54 -070088 // You can't include the "L;" in a JNI class descriptor.
89 EXPECT_CLASS_NOT_FOUND("Ljava/lang/String;");
90 // But you must include it for an array of any reference type.
91 EXPECT_CLASS_NOT_FOUND("[java/lang/String");
92 vm_->check_jni_abort_hook = NULL;
93
Elliott Hughes0c9cd562011-08-12 10:59:29 -070094 // Primitive arrays are okay (if the primitive type is valid)...
95 EXPECT_CLASS_FOUND("[C");
Elliott Hughesa2501992011-08-26 19:39:54 -070096 vm_->check_jni_abort_hook = TestCheckJniAbortHook;
Elliott Hughes0c9cd562011-08-12 10:59:29 -070097 EXPECT_CLASS_NOT_FOUND("[K");
Elliott Hughesa2501992011-08-26 19:39:54 -070098 vm_->check_jni_abort_hook = NULL;
Elliott Hughes0c9cd562011-08-12 10:59:29 -070099 // But primitive types aren't allowed...
100 EXPECT_CLASS_NOT_FOUND("C");
101 EXPECT_CLASS_NOT_FOUND("K");
102}
103
Elliott Hughescdf53122011-08-19 15:46:09 -0700104#define EXPECT_EXCEPTION(exception_class) \
105 do { \
106 EXPECT_TRUE(env_->ExceptionCheck()); \
107 jthrowable exception = env_->ExceptionOccurred(); \
108 EXPECT_NE(static_cast<jthrowable>(NULL), exception); \
Elliott Hughescdf53122011-08-19 15:46:09 -0700109 env_->ExceptionClear(); \
Elliott Hughesa2501992011-08-26 19:39:54 -0700110 EXPECT_TRUE(env_->IsInstanceOf(exception, exception_class)); \
Elliott Hughescdf53122011-08-19 15:46:09 -0700111 } while (false)
112
113TEST_F(JniInternalTest, GetFieldID) {
114 jclass jlnsfe = env_->FindClass("java/lang/NoSuchFieldError");
115 ASSERT_TRUE(jlnsfe != NULL);
116 jclass c = env_->FindClass("java/lang/String");
117 ASSERT_TRUE(c != NULL);
118
119 // Wrong type.
120 jfieldID fid = env_->GetFieldID(c, "count", "J");
121 EXPECT_EQ(static_cast<jfieldID>(NULL), fid);
122 EXPECT_EXCEPTION(jlnsfe);
123
124 // Wrong name.
125 fid = env_->GetFieldID(c, "Count", "I");
126 EXPECT_EQ(static_cast<jfieldID>(NULL), fid);
127 EXPECT_EXCEPTION(jlnsfe);
128
129 // Good declared field lookup.
130 fid = env_->GetFieldID(c, "count", "I");
131 EXPECT_NE(static_cast<jfieldID>(NULL), fid);
132 EXPECT_TRUE(fid != NULL);
133 EXPECT_FALSE(env_->ExceptionCheck());
134
135 // Good superclass field lookup.
136 c = env_->FindClass("java/lang/StringBuilder");
137 fid = env_->GetFieldID(c, "count", "I");
138 EXPECT_NE(static_cast<jfieldID>(NULL), fid);
139 EXPECT_TRUE(fid != NULL);
140 EXPECT_FALSE(env_->ExceptionCheck());
141
142 // Not instance.
143 fid = env_->GetFieldID(c, "CASE_INSENSITIVE_ORDER", "Ljava/util/Comparator;");
144 EXPECT_EQ(static_cast<jfieldID>(NULL), fid);
145 EXPECT_EXCEPTION(jlnsfe);
146}
147
148TEST_F(JniInternalTest, GetStaticFieldID) {
149 jclass jlnsfe = env_->FindClass("java/lang/NoSuchFieldError");
150 ASSERT_TRUE(jlnsfe != NULL);
151 jclass c = env_->FindClass("java/lang/String");
152 ASSERT_TRUE(c != NULL);
153
154 // Wrong type.
155 jfieldID fid = env_->GetStaticFieldID(c, "CASE_INSENSITIVE_ORDER", "J");
156 EXPECT_EQ(static_cast<jfieldID>(NULL), fid);
157 EXPECT_EXCEPTION(jlnsfe);
158
159 // Wrong name.
160 fid = env_->GetStaticFieldID(c, "cASE_INSENSITIVE_ORDER", "Ljava/util/Comparator;");
161 EXPECT_EQ(static_cast<jfieldID>(NULL), fid);
162 EXPECT_EXCEPTION(jlnsfe);
163
164 // Good declared field lookup.
165 fid = env_->GetStaticFieldID(c, "CASE_INSENSITIVE_ORDER", "Ljava/util/Comparator;");
166 EXPECT_NE(static_cast<jfieldID>(NULL), fid);
167 EXPECT_TRUE(fid != NULL);
168 EXPECT_FALSE(env_->ExceptionCheck());
169
170 // Not static.
171 fid = env_->GetStaticFieldID(c, "count", "I");
172 EXPECT_EQ(static_cast<jfieldID>(NULL), fid);
173 EXPECT_EXCEPTION(jlnsfe);
174}
175
Ian Rogers4dd71f12011-08-16 14:16:02 -0700176TEST_F(JniInternalTest, GetMethodID) {
177 jclass jlobject = env_->FindClass("java/lang/Object");
178 jclass jlstring = env_->FindClass("java/lang/String");
179 jclass jlnsme = env_->FindClass("java/lang/NoSuchMethodError");
180
181 // Sanity check that no exceptions are pending
Elliott Hughescdf53122011-08-19 15:46:09 -0700182 ASSERT_FALSE(env_->ExceptionCheck());
Ian Rogers4dd71f12011-08-16 14:16:02 -0700183
184 // Check that java.lang.Object.foo() doesn't exist and NoSuchMethodError is
185 // a pending exception
186 jmethodID method = env_->GetMethodID(jlobject, "foo", "()V");
187 EXPECT_EQ(static_cast<jmethodID>(NULL), method);
Elliott Hughescdf53122011-08-19 15:46:09 -0700188 EXPECT_EXCEPTION(jlnsme);
Ian Rogers4dd71f12011-08-16 14:16:02 -0700189
190 // Check that java.lang.Object.equals() does exist
Ian Rogers4dd71f12011-08-16 14:16:02 -0700191 method = env_->GetMethodID(jlobject, "equals", "(Ljava/lang/Object;)Z");
192 EXPECT_NE(static_cast<jmethodID>(NULL), method);
193 EXPECT_FALSE(env_->ExceptionCheck());
Ian Rogers4dd71f12011-08-16 14:16:02 -0700194
195 // Check that GetMethodID for java.lang.String.valueOf(int) fails as the
196 // method is static
197 method = env_->GetMethodID(jlstring, "valueOf", "(I)Ljava/lang/String;");
198 EXPECT_EQ(static_cast<jmethodID>(NULL), method);
Elliott Hughescdf53122011-08-19 15:46:09 -0700199 EXPECT_EXCEPTION(jlnsme);
Ian Rogers4dd71f12011-08-16 14:16:02 -0700200}
201
202TEST_F(JniInternalTest, GetStaticMethodID) {
203 jclass jlobject = env_->FindClass("java/lang/Object");
204 jclass jlnsme = env_->FindClass("java/lang/NoSuchMethodError");
205
206 // Sanity check that no exceptions are pending
Elliott Hughescdf53122011-08-19 15:46:09 -0700207 ASSERT_FALSE(env_->ExceptionCheck());
Ian Rogers4dd71f12011-08-16 14:16:02 -0700208
209 // Check that java.lang.Object.foo() doesn't exist and NoSuchMethodError is
210 // a pending exception
211 jmethodID method = env_->GetStaticMethodID(jlobject, "foo", "()V");
212 EXPECT_EQ(static_cast<jmethodID>(NULL), method);
Elliott Hughescdf53122011-08-19 15:46:09 -0700213 EXPECT_EXCEPTION(jlnsme);
Ian Rogers4dd71f12011-08-16 14:16:02 -0700214
215 // Check that GetStaticMethodID for java.lang.Object.equals(Object) fails as
216 // the method is not static
217 method = env_->GetStaticMethodID(jlobject, "equals", "(Ljava/lang/Object;)Z");
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 java.lang.String.valueOf(int) does exist
Ian Rogers4dd71f12011-08-16 14:16:02 -0700222 jclass jlstring = env_->FindClass("java/lang/String");
223 method = env_->GetStaticMethodID(jlstring, "valueOf",
224 "(I)Ljava/lang/String;");
225 EXPECT_NE(static_cast<jmethodID>(NULL), method);
226 EXPECT_FALSE(env_->ExceptionCheck());
Ian Rogers4dd71f12011-08-16 14:16:02 -0700227}
228
Elliott Hughescdf53122011-08-19 15:46:09 -0700229TEST_F(JniInternalTest, FromReflectedField_ToReflectedField) {
230 jclass jlrField = env_->FindClass("java/lang/reflect/Field");
231 jclass c = env_->FindClass("java/lang/String");
232 ASSERT_TRUE(c != NULL);
233 jfieldID fid = env_->GetFieldID(c, "count", "I");
234 ASSERT_TRUE(fid != NULL);
235 // Turn the fid into a java.lang.reflect.Field...
236 jobject field = env_->ToReflectedField(c, fid, JNI_FALSE);
237 ASSERT_TRUE(c != NULL);
238 ASSERT_TRUE(env_->IsInstanceOf(field, jlrField));
239 // ...and back again.
240 jfieldID fid2 = env_->FromReflectedField(field);
241 ASSERT_TRUE(fid2 != NULL);
242}
243
244TEST_F(JniInternalTest, FromReflectedMethod_ToReflectedMethod) {
245 jclass jlrMethod = env_->FindClass("java/lang/reflect/Method");
246 jclass c = env_->FindClass("java/lang/String");
247 ASSERT_TRUE(c != NULL);
248 jmethodID mid = env_->GetMethodID(c, "length", "()I");
249 ASSERT_TRUE(mid != NULL);
250 // Turn the mid into a java.lang.reflect.Method...
251 jobject method = env_->ToReflectedMethod(c, mid, JNI_FALSE);
252 ASSERT_TRUE(c != NULL);
253 ASSERT_TRUE(env_->IsInstanceOf(method, jlrMethod));
254 // ...and back again.
255 jmethodID mid2 = env_->FromReflectedMethod(method);
256 ASSERT_TRUE(mid2 != NULL);
257}
258
Elliott Hughes5174fe62011-08-23 15:12:35 -0700259void BogusMethod() {
260 // You can't pass NULL function pointers to RegisterNatives.
261}
262
Ian Rogers4dd71f12011-08-16 14:16:02 -0700263TEST_F(JniInternalTest, RegisterNatives) {
264 jclass jlobject = env_->FindClass("java/lang/Object");
265 jclass jlnsme = env_->FindClass("java/lang/NoSuchMethodError");
266
267 // Sanity check that no exceptions are pending
Elliott Hughescdf53122011-08-19 15:46:09 -0700268 ASSERT_FALSE(env_->ExceptionCheck());
Ian Rogers4dd71f12011-08-16 14:16:02 -0700269
270 // Check that registering to a non-existent java.lang.Object.foo() causes a
271 // NoSuchMethodError
272 {
273 JNINativeMethod methods[] = {{"foo", "()V", NULL}};
274 env_->RegisterNatives(jlobject, methods, 1);
275 }
Elliott Hughescdf53122011-08-19 15:46:09 -0700276 EXPECT_EXCEPTION(jlnsme);
Ian Rogers4dd71f12011-08-16 14:16:02 -0700277
278 // Check that registering non-native methods causes a NoSuchMethodError
279 {
280 JNINativeMethod methods[] = {{"equals", "(Ljava/lang/Object;)Z", NULL}};
281 env_->RegisterNatives(jlobject, methods, 1);
282 }
Elliott Hughescdf53122011-08-19 15:46:09 -0700283 EXPECT_EXCEPTION(jlnsme);
Ian Rogers4dd71f12011-08-16 14:16:02 -0700284
285 // Check that registering native methods is successful
286 {
Elliott Hughes5174fe62011-08-23 15:12:35 -0700287 JNINativeMethod methods[] = {{"hashCode", "()I", reinterpret_cast<void*>(BogusMethod)}};
Ian Rogers4dd71f12011-08-16 14:16:02 -0700288 env_->RegisterNatives(jlobject, methods, 1);
289 }
290 EXPECT_FALSE(env_->ExceptionCheck());
Elliott Hughes5174fe62011-08-23 15:12:35 -0700291
292 env_->UnregisterNatives(jlobject);
Ian Rogers4dd71f12011-08-16 14:16:02 -0700293}
294
Elliott Hughes75770752011-08-24 17:52:38 -0700295#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 -0700296 jsize size = 4; \
297 /* Allocate an array and check it has the right type and length. */ \
298 scalar_type ## Array a = env_->new_fn(size); \
299 EXPECT_TRUE(a != NULL); \
300 EXPECT_TRUE(env_->IsInstanceOf(a, env_->FindClass(expected_class_descriptor))); \
301 EXPECT_EQ(size, env_->GetArrayLength(a)); \
302 /* AIOOBE for negative start offset. */ \
303 env_->get_region_fn(a, -1, 1, NULL); \
304 EXPECT_EXCEPTION(aioobe_); \
305 env_->set_region_fn(a, -1, 1, NULL); \
306 EXPECT_EXCEPTION(aioobe_); \
307 /* AIOOBE for negative length. */ \
308 env_->get_region_fn(a, 0, -1, NULL); \
309 EXPECT_EXCEPTION(aioobe_); \
310 env_->set_region_fn(a, 0, -1, NULL); \
311 EXPECT_EXCEPTION(aioobe_); \
312 /* AIOOBE for buffer overrun. */ \
313 env_->get_region_fn(a, size - 1, size, NULL); \
314 EXPECT_EXCEPTION(aioobe_); \
315 env_->set_region_fn(a, size - 1, size, NULL); \
316 EXPECT_EXCEPTION(aioobe_); \
317 /* Prepare a couple of buffers. */ \
318 scalar_type src_buf[size]; \
319 scalar_type dst_buf[size]; \
320 for (jsize i = 0; i < size; ++i) { src_buf[i] = scalar_type(i); } \
321 for (jsize i = 0; i < size; ++i) { dst_buf[i] = scalar_type(-1); } \
322 /* Copy all of src_buf onto the heap. */ \
323 env_->set_region_fn(a, 0, size, src_buf); \
324 /* Copy back only part. */ \
325 env_->get_region_fn(a, 1, size - 2, &dst_buf[1]); \
326 EXPECT_FALSE(memcmp(src_buf, dst_buf, sizeof(src_buf)) == 0) << "short copy equal"; \
327 /* Copy the missing pieces. */ \
328 env_->get_region_fn(a, 0, 1, dst_buf); \
329 env_->get_region_fn(a, size - 1, 1, &dst_buf[size - 1]); \
330 EXPECT_TRUE(memcmp(src_buf, dst_buf, sizeof(src_buf)) == 0) << "fixed copy not equal"; \
331 /* Copy back the whole array. */ \
332 env_->get_region_fn(a, 0, size, dst_buf); \
Elliott Hughes75770752011-08-24 17:52:38 -0700333 EXPECT_TRUE(memcmp(src_buf, dst_buf, sizeof(src_buf)) == 0) << "full copy not equal"; \
334 /* GetPrimitiveArrayCritical */ \
335 void* v = env_->GetPrimitiveArrayCritical(a, NULL); \
336 EXPECT_TRUE(memcmp(src_buf, v, sizeof(src_buf)) == 0) << "GetPrimitiveArrayCritical not equal"; \
337 env_->ReleasePrimitiveArrayCritical(a, v, 0); \
338 /* GetXArrayElements */ \
339 scalar_type* xs = env_->get_elements_fn(a, NULL); \
340 EXPECT_TRUE(memcmp(src_buf, xs, sizeof(src_buf)) == 0) << # get_elements_fn " not equal"; \
341 env_->release_elements_fn(a, xs, 0); \
342 EXPECT_EQ(reinterpret_cast<uintptr_t>(v), reinterpret_cast<uintptr_t>(xs))
Elliott Hughesbd935992011-08-22 11:59:34 -0700343
Elliott Hughes814e4032011-08-23 12:07:56 -0700344TEST_F(JniInternalTest, BooleanArrays) {
Elliott Hughes75770752011-08-24 17:52:38 -0700345 EXPECT_PRIMITIVE_ARRAY(NewBooleanArray, GetBooleanArrayRegion, SetBooleanArrayRegion, GetBooleanArrayElements, ReleaseBooleanArrayElements, jboolean, "[Z");
Elliott Hughes814e4032011-08-23 12:07:56 -0700346}
347TEST_F(JniInternalTest, ByteArrays) {
Elliott Hughes75770752011-08-24 17:52:38 -0700348 EXPECT_PRIMITIVE_ARRAY(NewByteArray, GetByteArrayRegion, SetByteArrayRegion, GetByteArrayElements, ReleaseByteArrayElements, jbyte, "[B");
Elliott Hughes814e4032011-08-23 12:07:56 -0700349}
350TEST_F(JniInternalTest, CharArrays) {
Elliott Hughes75770752011-08-24 17:52:38 -0700351 EXPECT_PRIMITIVE_ARRAY(NewCharArray, GetCharArrayRegion, SetCharArrayRegion, GetCharArrayElements, ReleaseCharArrayElements, jchar, "[C");
Elliott Hughes814e4032011-08-23 12:07:56 -0700352}
353TEST_F(JniInternalTest, DoubleArrays) {
Elliott Hughes75770752011-08-24 17:52:38 -0700354 EXPECT_PRIMITIVE_ARRAY(NewDoubleArray, GetDoubleArrayRegion, SetDoubleArrayRegion, GetDoubleArrayElements, ReleaseDoubleArrayElements, jdouble, "[D");
Elliott Hughes814e4032011-08-23 12:07:56 -0700355}
356TEST_F(JniInternalTest, FloatArrays) {
Elliott Hughes75770752011-08-24 17:52:38 -0700357 EXPECT_PRIMITIVE_ARRAY(NewFloatArray, GetFloatArrayRegion, SetFloatArrayRegion, GetFloatArrayElements, ReleaseFloatArrayElements, jfloat, "[F");
Elliott Hughes814e4032011-08-23 12:07:56 -0700358}
359TEST_F(JniInternalTest, IntArrays) {
Elliott Hughes75770752011-08-24 17:52:38 -0700360 EXPECT_PRIMITIVE_ARRAY(NewIntArray, GetIntArrayRegion, SetIntArrayRegion, GetIntArrayElements, ReleaseIntArrayElements, jint, "[I");
Elliott Hughes814e4032011-08-23 12:07:56 -0700361}
362TEST_F(JniInternalTest, LongArrays) {
Elliott Hughes75770752011-08-24 17:52:38 -0700363 EXPECT_PRIMITIVE_ARRAY(NewLongArray, GetLongArrayRegion, SetLongArrayRegion, GetLongArrayElements, ReleaseLongArrayElements, jlong, "[J");
Elliott Hughes814e4032011-08-23 12:07:56 -0700364}
365TEST_F(JniInternalTest, ShortArrays) {
Elliott Hughes75770752011-08-24 17:52:38 -0700366 EXPECT_PRIMITIVE_ARRAY(NewShortArray, GetShortArrayRegion, SetShortArrayRegion, GetShortArrayElements, ReleaseShortArrayElements, jshort, "[S");
Elliott Hughesd8ddfd52011-08-15 14:32:53 -0700367}
368
Elliott Hughesf2682d52011-08-15 16:37:04 -0700369TEST_F(JniInternalTest, NewObjectArray) {
370 // TODO: death tests for negative array sizes.
371
Elliott Hughesf2682d52011-08-15 16:37:04 -0700372 // TODO: check non-NULL initial elements.
373
Elliott Hughesbd935992011-08-22 11:59:34 -0700374 jclass element_class = env_->FindClass("java/lang/String");
375 ASSERT_TRUE(element_class != NULL);
376 jclass array_class = env_->FindClass("[Ljava/lang/String;");
377 ASSERT_TRUE(array_class != NULL);
Elliott Hughesf2682d52011-08-15 16:37:04 -0700378
Elliott Hughesbd935992011-08-22 11:59:34 -0700379 jobjectArray a;
Elliott Hughesf2682d52011-08-15 16:37:04 -0700380
Elliott Hughesbd935992011-08-22 11:59:34 -0700381 a = env_->NewObjectArray(0, element_class, NULL);
382 EXPECT_TRUE(a != NULL);
383 EXPECT_TRUE(env_->IsInstanceOf(a, array_class));
384 EXPECT_EQ(0, env_->GetArrayLength(a));
385
386 a = env_->NewObjectArray(1, element_class, NULL);
387 EXPECT_TRUE(a != NULL);
388 EXPECT_TRUE(env_->IsInstanceOf(a, array_class));
389 EXPECT_EQ(1, env_->GetArrayLength(a));
Elliott Hughes75770752011-08-24 17:52:38 -0700390 EXPECT_TRUE(env_->IsSameObject(env_->GetObjectArrayElement(a, 0), NULL));
391
392 jstring s = env_->NewStringUTF("poop");
393 a = env_->NewObjectArray(2, element_class, s);
394 EXPECT_TRUE(a != NULL);
395 EXPECT_TRUE(env_->IsInstanceOf(a, array_class));
396 EXPECT_EQ(2, env_->GetArrayLength(a));
397 EXPECT_TRUE(env_->IsSameObject(env_->GetObjectArrayElement(a, 0), s));
398 EXPECT_TRUE(env_->IsSameObject(env_->GetObjectArrayElement(a, 1), s));
Elliott Hughesbd935992011-08-22 11:59:34 -0700399}
400
401TEST_F(JniInternalTest, GetArrayLength) {
402 // Already tested in NewObjectArray/NewPrimitiveArray.
Elliott Hughes8a26c5c2011-08-15 18:35:43 -0700403}
404
Elliott Hughes37f7a402011-08-22 18:56:01 -0700405TEST_F(JniInternalTest, GetObjectClass) {
406 jclass string_class = env_->FindClass("java/lang/String");
407 ASSERT_TRUE(string_class != NULL);
408 jclass class_class = env_->FindClass("java/lang/Class");
409 ASSERT_TRUE(class_class != NULL);
410
411 jstring s = env_->NewStringUTF("poop");
412 jclass c = env_->GetObjectClass(s);
413 ASSERT_TRUE(env_->IsSameObject(string_class, c));
414
415 jclass c2 = env_->GetObjectClass(c);
416 ASSERT_TRUE(env_->IsSameObject(class_class, env_->GetObjectClass(c2)));
417}
418
Elliott Hughes885c3bd2011-08-22 16:59:20 -0700419TEST_F(JniInternalTest, GetSuperclass) {
420 jclass object_class = env_->FindClass("java/lang/Object");
421 ASSERT_TRUE(object_class != NULL);
422 jclass string_class = env_->FindClass("java/lang/String");
423 ASSERT_TRUE(string_class != NULL);
424 ASSERT_TRUE(env_->IsSameObject(object_class, env_->GetSuperclass(string_class)));
425 ASSERT_TRUE(env_->GetSuperclass(object_class) == NULL);
426}
427
Elliott Hughes37f7a402011-08-22 18:56:01 -0700428TEST_F(JniInternalTest, IsAssignableFrom) {
429 jclass object_class = env_->FindClass("java/lang/Object");
430 ASSERT_TRUE(object_class != NULL);
431 jclass string_class = env_->FindClass("java/lang/String");
432 ASSERT_TRUE(string_class != NULL);
433
434 ASSERT_TRUE(env_->IsAssignableFrom(object_class, string_class));
435 ASSERT_FALSE(env_->IsAssignableFrom(string_class, object_class));
436}
437
Elliott Hughesb465ab02011-08-24 11:21:21 -0700438TEST_F(JniInternalTest, GetObjectRefType) {
439 jclass local = env_->FindClass("java/lang/Object");
440 ASSERT_TRUE(local != NULL);
441 EXPECT_EQ(JNILocalRefType, env_->GetObjectRefType(local));
442
443 jobject global = env_->NewGlobalRef(local);
444 EXPECT_EQ(JNIGlobalRefType, env_->GetObjectRefType(global));
445
446 jweak weak_global = env_->NewWeakGlobalRef(local);
447 EXPECT_EQ(JNIWeakGlobalRefType, env_->GetObjectRefType(weak_global));
448
449 jobject invalid = reinterpret_cast<jobject>(this);
450 EXPECT_EQ(JNIInvalidRefType, env_->GetObjectRefType(invalid));
451
452 // TODO: invoke a native method and test that its arguments are considered local references.
453}
454
Elliott Hughes8a26c5c2011-08-15 18:35:43 -0700455TEST_F(JniInternalTest, NewStringUTF) {
456 EXPECT_TRUE(env_->NewStringUTF(NULL) == NULL);
Elliott Hughes814e4032011-08-23 12:07:56 -0700457 jstring s;
458
459 s = env_->NewStringUTF("");
460 EXPECT_TRUE(s != NULL);
461 EXPECT_EQ(0, env_->GetStringLength(s));
462 EXPECT_EQ(0, env_->GetStringUTFLength(s));
463 s = env_->NewStringUTF("hello");
464 EXPECT_TRUE(s != NULL);
465 EXPECT_EQ(5, env_->GetStringLength(s));
466 EXPECT_EQ(5, env_->GetStringUTFLength(s));
467
Elliott Hughes8a26c5c2011-08-15 18:35:43 -0700468 // TODO: check some non-ASCII strings.
Elliott Hughesf2682d52011-08-15 16:37:04 -0700469}
470
Elliott Hughes814e4032011-08-23 12:07:56 -0700471TEST_F(JniInternalTest, NewString) {
472 EXPECT_TRUE(env_->NewString(NULL, 0) == NULL);
473
474 jchar chars[] = { 'h', 'i' };
475 jstring s;
476 s = env_->NewString(chars, 0);
477 EXPECT_TRUE(s != NULL);
478 EXPECT_EQ(0, env_->GetStringLength(s));
479 EXPECT_EQ(0, env_->GetStringUTFLength(s));
480 s = env_->NewString(chars, 2);
481 EXPECT_TRUE(s != NULL);
482 EXPECT_EQ(2, env_->GetStringLength(s));
483 EXPECT_EQ(2, env_->GetStringUTFLength(s));
484
485 // TODO: check some non-ASCII strings.
486}
487
Elliott Hughesb465ab02011-08-24 11:21:21 -0700488TEST_F(JniInternalTest, GetStringLength_GetStringUTFLength) {
489 // Already tested in the NewString/NewStringUTF tests.
490}
491
492TEST_F(JniInternalTest, GetStringRegion_GetStringUTFRegion) {
493 jstring s = env_->NewStringUTF("hello");
494 ASSERT_TRUE(s != NULL);
495
496 env_->GetStringRegion(s, -1, 0, NULL);
497 EXPECT_EXCEPTION(sioobe_);
498 env_->GetStringRegion(s, 0, -1, NULL);
499 EXPECT_EXCEPTION(sioobe_);
500 env_->GetStringRegion(s, 0, 10, NULL);
501 EXPECT_EXCEPTION(sioobe_);
502 env_->GetStringRegion(s, 10, 1, NULL);
503 EXPECT_EXCEPTION(sioobe_);
504
505 jchar chars[4] = { 'x', 'x', 'x', 'x' };
506 env_->GetStringRegion(s, 1, 2, &chars[1]);
507 EXPECT_EQ('x', chars[0]);
508 EXPECT_EQ('e', chars[1]);
509 EXPECT_EQ('l', chars[2]);
510 EXPECT_EQ('x', chars[3]);
511
512 env_->GetStringUTFRegion(s, -1, 0, NULL);
513 EXPECT_EXCEPTION(sioobe_);
514 env_->GetStringUTFRegion(s, 0, -1, NULL);
515 EXPECT_EXCEPTION(sioobe_);
516 env_->GetStringUTFRegion(s, 0, 10, NULL);
517 EXPECT_EXCEPTION(sioobe_);
518 env_->GetStringUTFRegion(s, 10, 1, NULL);
519 EXPECT_EXCEPTION(sioobe_);
520
521 char bytes[4] = { 'x', 'x', 'x', 'x' };
522 env_->GetStringUTFRegion(s, 1, 2, &bytes[1]);
523 EXPECT_EQ('x', bytes[0]);
524 EXPECT_EQ('e', bytes[1]);
525 EXPECT_EQ('l', bytes[2]);
526 EXPECT_EQ('x', bytes[3]);
527}
528
Elliott Hughes75770752011-08-24 17:52:38 -0700529TEST_F(JniInternalTest, GetStringUTFChars_ReleaseStringUTFChars) {
Elliott Hughesa2501992011-08-26 19:39:54 -0700530 vm_->check_jni_abort_hook = TestCheckJniAbortHook;
531 // Passing in a NULL jstring is ignored normally, but caught by -Xcheck:jni.
Elliott Hughes75770752011-08-24 17:52:38 -0700532 EXPECT_TRUE(env_->GetStringUTFChars(NULL, NULL) == NULL);
Elliott Hughesa2501992011-08-26 19:39:54 -0700533 vm_->check_jni_abort_hook = NULL;
Elliott Hughes75770752011-08-24 17:52:38 -0700534
535 jstring s = env_->NewStringUTF("hello");
536 ASSERT_TRUE(s != NULL);
537
538 const char* utf = env_->GetStringUTFChars(s, NULL);
539 EXPECT_STREQ("hello", utf);
540 env_->ReleaseStringUTFChars(s, utf);
541
542 jboolean is_copy = JNI_FALSE;
543 utf = env_->GetStringUTFChars(s, &is_copy);
544 EXPECT_EQ(JNI_TRUE, is_copy);
545 EXPECT_STREQ("hello", utf);
546 env_->ReleaseStringUTFChars(s, utf);
547}
548
549TEST_F(JniInternalTest, GetStringChars_ReleaseStringChars) {
550 jstring s = env_->NewStringUTF("hello");
551 ASSERT_TRUE(s != NULL);
552
553 jchar expected[] = { 'h', 'e', 'l', 'l', 'o' };
554 const jchar* chars = env_->GetStringChars(s, NULL);
555 EXPECT_EQ(expected[0], chars[0]);
556 EXPECT_EQ(expected[1], chars[1]);
557 EXPECT_EQ(expected[2], chars[2]);
558 EXPECT_EQ(expected[3], chars[3]);
559 EXPECT_EQ(expected[4], chars[4]);
560 env_->ReleaseStringChars(s, chars);
561
562 jboolean is_copy = JNI_FALSE;
563 chars = env_->GetStringChars(s, &is_copy);
564 EXPECT_EQ(JNI_FALSE, is_copy);
565 EXPECT_EQ(expected[0], chars[0]);
566 EXPECT_EQ(expected[1], chars[1]);
567 EXPECT_EQ(expected[2], chars[2]);
568 EXPECT_EQ(expected[3], chars[3]);
569 EXPECT_EQ(expected[4], chars[4]);
570 env_->ReleaseStringChars(s, chars);
571}
572
573TEST_F(JniInternalTest, GetStringCritical_ReleaseStringCritical) {
574 jstring s = env_->NewStringUTF("hello");
575 ASSERT_TRUE(s != NULL);
576
577 jchar expected[] = { 'h', 'e', 'l', 'l', 'o' };
578 const jchar* chars = env_->GetStringCritical(s, NULL);
579 EXPECT_EQ(expected[0], chars[0]);
580 EXPECT_EQ(expected[1], chars[1]);
581 EXPECT_EQ(expected[2], chars[2]);
582 EXPECT_EQ(expected[3], chars[3]);
583 EXPECT_EQ(expected[4], chars[4]);
584 env_->ReleaseStringCritical(s, chars);
585
586 jboolean is_copy = JNI_FALSE;
587 chars = env_->GetStringCritical(s, &is_copy);
588 EXPECT_EQ(JNI_FALSE, is_copy);
589 EXPECT_EQ(expected[0], chars[0]);
590 EXPECT_EQ(expected[1], chars[1]);
591 EXPECT_EQ(expected[2], chars[2]);
592 EXPECT_EQ(expected[3], chars[3]);
593 EXPECT_EQ(expected[4], chars[4]);
594 env_->ReleaseStringCritical(s, chars);
595}
596
Elliott Hughes814e4032011-08-23 12:07:56 -0700597TEST_F(JniInternalTest, GetObjectArrayElement_SetObjectArrayElement) {
Elliott Hughes289da822011-08-16 10:11:20 -0700598 jclass c = env_->FindClass("[Ljava/lang/Object;");
599 ASSERT_TRUE(c != NULL);
600
601 jobjectArray array = env_->NewObjectArray(1, c, NULL);
602 EXPECT_TRUE(array != NULL);
Elliott Hughes814e4032011-08-23 12:07:56 -0700603 EXPECT_TRUE(env_->GetObjectArrayElement(array, 0) == NULL);
Elliott Hughes289da822011-08-16 10:11:20 -0700604 env_->SetObjectArrayElement(array, 0, c);
Elliott Hughes814e4032011-08-23 12:07:56 -0700605 EXPECT_TRUE(env_->IsSameObject(env_->GetObjectArrayElement(array, 0), c));
Elliott Hughesa5b897e2011-08-16 11:33:06 -0700606
607 // ArrayIndexOutOfBounds for negative index.
Elliott Hughesa5b897e2011-08-16 11:33:06 -0700608 env_->SetObjectArrayElement(array, -1, c);
Elliott Hughes814e4032011-08-23 12:07:56 -0700609 EXPECT_EXCEPTION(aioobe_);
Elliott Hughesa5b897e2011-08-16 11:33:06 -0700610
611 // ArrayIndexOutOfBounds for too-large index.
Elliott Hughesa5b897e2011-08-16 11:33:06 -0700612 env_->SetObjectArrayElement(array, 1, c);
Elliott Hughes814e4032011-08-23 12:07:56 -0700613 EXPECT_EXCEPTION(aioobe_);
Elliott Hughesa5b897e2011-08-16 11:33:06 -0700614
Elliott Hughes289da822011-08-16 10:11:20 -0700615 // TODO: check ArrayStoreException thrown for bad types.
616}
617
Elliott Hughes885c3bd2011-08-22 16:59:20 -0700618#define EXPECT_STATIC_PRIMITIVE_FIELD(type, field_name, sig, value1, value2) \
619 do { \
620 jfieldID fid = env_->GetStaticFieldID(c, field_name, sig); \
621 EXPECT_TRUE(fid != NULL); \
622 env_->SetStatic ## type ## Field(c, fid, value1); \
623 EXPECT_EQ(value1, env_->GetStatic ## type ## Field(c, fid)); \
624 env_->SetStatic ## type ## Field(c, fid, value2); \
625 EXPECT_EQ(value2, env_->GetStatic ## type ## Field(c, fid)); \
626 } while (false)
627
628#define EXPECT_PRIMITIVE_FIELD(instance, type, field_name, sig, value1, value2) \
629 do { \
630 jfieldID fid = env_->GetFieldID(c, field_name, sig); \
631 EXPECT_TRUE(fid != NULL); \
632 env_->Set ## type ## Field(instance, fid, value1); \
633 EXPECT_EQ(value1, env_->Get ## type ## Field(instance, fid)); \
634 env_->Set ## type ## Field(instance, fid, value2); \
635 EXPECT_EQ(value2, env_->Get ## type ## Field(instance, fid)); \
636 } while (false)
637
638
639TEST_F(JniInternalTest, GetPrimitiveField_SetPrimitiveField) {
Elliott Hughes90a33692011-08-30 13:27:07 -0700640 UniquePtr<const DexFile> dex(OpenTestDexFile("AllFields"));
Brian Carlstrom8a487412011-08-29 20:08:52 -0700641 const PathClassLoader* class_loader = AllocPathClassLoader(dex.get());
Elliott Hughes885c3bd2011-08-22 16:59:20 -0700642 Thread::Current()->SetClassLoaderOverride(class_loader);
643
644 jclass c = env_->FindClass("AllFields");
645 ASSERT_TRUE(c != NULL);
646 jobject o = env_->AllocObject(c);
647 ASSERT_TRUE(o != NULL);
648
649 EXPECT_STATIC_PRIMITIVE_FIELD(Boolean, "sZ", "Z", true, false);
650 EXPECT_STATIC_PRIMITIVE_FIELD(Byte, "sB", "B", 1, 2);
651 EXPECT_STATIC_PRIMITIVE_FIELD(Char, "sC", "C", 'a', 'b');
652 EXPECT_STATIC_PRIMITIVE_FIELD(Double, "sD", "D", 1.0, 2.0);
653 EXPECT_STATIC_PRIMITIVE_FIELD(Float, "sF", "F", 1.0, 2.0);
654 EXPECT_STATIC_PRIMITIVE_FIELD(Int, "sI", "I", 1, 2);
655 EXPECT_STATIC_PRIMITIVE_FIELD(Long, "sJ", "J", 1, 2);
656 EXPECT_STATIC_PRIMITIVE_FIELD(Short, "sS", "S", 1, 2);
657
658 EXPECT_PRIMITIVE_FIELD(o, Boolean, "iZ", "Z", true, false);
659 EXPECT_PRIMITIVE_FIELD(o, Byte, "iB", "B", 1, 2);
660 EXPECT_PRIMITIVE_FIELD(o, Char, "iC", "C", 'a', 'b');
661 EXPECT_PRIMITIVE_FIELD(o, Double, "iD", "D", 1.0, 2.0);
662 EXPECT_PRIMITIVE_FIELD(o, Float, "iF", "F", 1.0, 2.0);
663 EXPECT_PRIMITIVE_FIELD(o, Int, "iI", "I", 1, 2);
664 EXPECT_PRIMITIVE_FIELD(o, Long, "iJ", "J", 1, 2);
665 EXPECT_PRIMITIVE_FIELD(o, Short, "iS", "S", 1, 2);
666}
667
668TEST_F(JniInternalTest, GetObjectField_SetObjectField) {
Elliott Hughes90a33692011-08-30 13:27:07 -0700669 UniquePtr<const DexFile> dex(OpenTestDexFile("AllFields"));
Brian Carlstrom8a487412011-08-29 20:08:52 -0700670 const PathClassLoader* class_loader = AllocPathClassLoader(dex.get());
Elliott Hughes885c3bd2011-08-22 16:59:20 -0700671 Thread::Current()->SetClassLoaderOverride(class_loader);
672
673 jclass c = env_->FindClass("AllFields");
674 ASSERT_TRUE(c != NULL);
675 jobject o = env_->AllocObject(c);
676 ASSERT_TRUE(o != NULL);
677
678 jstring s1 = env_->NewStringUTF("hello");
679 ASSERT_TRUE(s1 != NULL);
680 jstring s2 = env_->NewStringUTF("world");
681 ASSERT_TRUE(s2 != NULL);
682
683 jfieldID s_fid = env_->GetStaticFieldID(c, "sObject", "Ljava/lang/Object;");
684 ASSERT_TRUE(s_fid != NULL);
685 jfieldID i_fid = env_->GetFieldID(c, "iObject", "Ljava/lang/Object;");
686 ASSERT_TRUE(i_fid != NULL);
687
688 env_->SetStaticObjectField(c, s_fid, s1);
689 ASSERT_TRUE(env_->IsSameObject(s1, env_->GetStaticObjectField(c, s_fid)));
690 env_->SetStaticObjectField(c, s_fid, s2);
691 ASSERT_TRUE(env_->IsSameObject(s2, env_->GetStaticObjectField(c, s_fid)));
692
693 env_->SetObjectField(o, i_fid, s1);
694 ASSERT_TRUE(env_->IsSameObject(s1, env_->GetObjectField(o, i_fid)));
695 env_->SetObjectField(o, i_fid, s2);
696 ASSERT_TRUE(env_->IsSameObject(s2, env_->GetObjectField(o, i_fid)));
697}
698
Elliott Hughes18c07532011-08-18 15:50:51 -0700699TEST_F(JniInternalTest, NewLocalRef_NULL) {
700 EXPECT_TRUE(env_->NewLocalRef(NULL) == NULL);
701}
702
703TEST_F(JniInternalTest, NewLocalRef) {
704 jstring s = env_->NewStringUTF("");
705 ASSERT_TRUE(s != NULL);
706 jobject o = env_->NewLocalRef(s);
707 EXPECT_TRUE(o != NULL);
708 EXPECT_TRUE(o != s);
709
710 // TODO: check that o is a local reference.
711}
712
713TEST_F(JniInternalTest, DeleteLocalRef_NULL) {
714 env_->DeleteLocalRef(NULL);
715}
716
717TEST_F(JniInternalTest, DeleteLocalRef) {
718 jstring s = env_->NewStringUTF("");
719 ASSERT_TRUE(s != NULL);
720 env_->DeleteLocalRef(s);
721
722 // Currently, deleting an already-deleted reference is just a warning.
Elliott Hughesa2501992011-08-26 19:39:54 -0700723 vm_->check_jni_abort_hook = TestCheckJniAbortHook;
Elliott Hughes18c07532011-08-18 15:50:51 -0700724 env_->DeleteLocalRef(s);
Elliott Hughesa2501992011-08-26 19:39:54 -0700725 vm_->check_jni_abort_hook = NULL;
Elliott Hughes18c07532011-08-18 15:50:51 -0700726
727 s = env_->NewStringUTF("");
728 ASSERT_TRUE(s != NULL);
729 jobject o = env_->NewLocalRef(s);
730 ASSERT_TRUE(o != NULL);
731
732 env_->DeleteLocalRef(s);
733 env_->DeleteLocalRef(o);
734}
735
736TEST_F(JniInternalTest, NewGlobalRef_NULL) {
737 EXPECT_TRUE(env_->NewGlobalRef(NULL) == NULL);
738}
739
740TEST_F(JniInternalTest, NewGlobalRef) {
741 jstring s = env_->NewStringUTF("");
742 ASSERT_TRUE(s != NULL);
743 jobject o = env_->NewGlobalRef(s);
744 EXPECT_TRUE(o != NULL);
745 EXPECT_TRUE(o != s);
746
747 // TODO: check that o is a global reference.
748}
749
750TEST_F(JniInternalTest, DeleteGlobalRef_NULL) {
751 env_->DeleteGlobalRef(NULL);
752}
753
754TEST_F(JniInternalTest, DeleteGlobalRef) {
755 jstring s = env_->NewStringUTF("");
756 ASSERT_TRUE(s != NULL);
757
758 jobject o = env_->NewGlobalRef(s);
759 ASSERT_TRUE(o != NULL);
760 env_->DeleteGlobalRef(o);
761
Elliott Hughesa2501992011-08-26 19:39:54 -0700762 vm_->check_jni_abort_hook = TestCheckJniAbortHook;
Elliott Hughes18c07532011-08-18 15:50:51 -0700763 // Currently, deleting an already-deleted reference is just a warning.
764 env_->DeleteGlobalRef(o);
Elliott Hughesa2501992011-08-26 19:39:54 -0700765 vm_->check_jni_abort_hook = NULL;
Elliott Hughes18c07532011-08-18 15:50:51 -0700766
767 jobject o1 = env_->NewGlobalRef(s);
768 ASSERT_TRUE(o1 != NULL);
769 jobject o2 = env_->NewGlobalRef(s);
770 ASSERT_TRUE(o2 != NULL);
771
772 env_->DeleteGlobalRef(o1);
773 env_->DeleteGlobalRef(o2);
774}
775
776TEST_F(JniInternalTest, NewWeakGlobalRef_NULL) {
777 EXPECT_TRUE(env_->NewWeakGlobalRef(NULL) == NULL);
778}
779
780TEST_F(JniInternalTest, NewWeakGlobalRef) {
781 jstring s = env_->NewStringUTF("");
782 ASSERT_TRUE(s != NULL);
783 jobject o = env_->NewWeakGlobalRef(s);
784 EXPECT_TRUE(o != NULL);
785 EXPECT_TRUE(o != s);
786
787 // TODO: check that o is a weak global reference.
788}
789
790TEST_F(JniInternalTest, DeleteWeakGlobalRef_NULL) {
791 env_->DeleteWeakGlobalRef(NULL);
792}
793
794TEST_F(JniInternalTest, DeleteWeakGlobalRef) {
795 jstring s = env_->NewStringUTF("");
796 ASSERT_TRUE(s != NULL);
797
798 jobject o = env_->NewWeakGlobalRef(s);
799 ASSERT_TRUE(o != NULL);
800 env_->DeleteWeakGlobalRef(o);
801
Elliott Hughesa2501992011-08-26 19:39:54 -0700802 vm_->check_jni_abort_hook = TestCheckJniAbortHook;
Elliott Hughes18c07532011-08-18 15:50:51 -0700803 // Currently, deleting an already-deleted reference is just a warning.
804 env_->DeleteWeakGlobalRef(o);
Elliott Hughesa2501992011-08-26 19:39:54 -0700805 vm_->check_jni_abort_hook = NULL;
Elliott Hughes18c07532011-08-18 15:50:51 -0700806
807 jobject o1 = env_->NewWeakGlobalRef(s);
808 ASSERT_TRUE(o1 != NULL);
809 jobject o2 = env_->NewWeakGlobalRef(s);
810 ASSERT_TRUE(o2 != NULL);
811
812 env_->DeleteWeakGlobalRef(o1);
813 env_->DeleteWeakGlobalRef(o2);
814}
815
Elliott Hughes79082e32011-08-25 12:07:32 -0700816void EnsureInvokeStub(Method* method);
Carl Shapiro9b9ba282011-08-14 15:30:39 -0700817
Carl Shapiro9b9ba282011-08-14 15:30:39 -0700818Method::InvokeStub* AllocateStub(Method* method,
819 byte* code,
820 size_t length) {
821 CHECK(method->GetInvokeStub() == NULL);
822 EnsureInvokeStub(method);
823 Method::InvokeStub* stub = method->GetInvokeStub();
824 CHECK(stub != NULL);
buzbeec143c552011-08-20 17:38:58 -0700825 method->SetCode(code, length, kThumb2);
Carl Shapiro9b9ba282011-08-14 15:30:39 -0700826 return stub;
827}
828
Carl Shapiro9b9ba282011-08-14 15:30:39 -0700829#if defined(__arm__)
830TEST_F(JniInternalTest, StaticMainMethod) {
Elliott Hughes90a33692011-08-30 13:27:07 -0700831 UniquePtr<const DexFile> dex(OpenTestDexFile("Main"));
Carl Shapiro9b9ba282011-08-14 15:30:39 -0700832
Brian Carlstrom8a487412011-08-29 20:08:52 -0700833 const PathClassLoader* class_loader = AllocPathClassLoader(dex.get());
Carl Shapiro9b9ba282011-08-14 15:30:39 -0700834 ASSERT_TRUE(class_loader != NULL);
835
836 Class* klass = class_linker_->FindClass("LMain;", class_loader);
837 ASSERT_TRUE(klass != NULL);
838
839 Method* method = klass->FindDirectMethod("main", "([Ljava/lang/String;)V");
840 ASSERT_TRUE(method != NULL);
841
842 byte main_LV_code[] = {
843 0x2d, 0xe9, 0x00, 0x40, 0x83, 0xb0, 0xcd, 0xf8, 0x00, 0x00,
844 0xcd, 0xf8, 0x14, 0x10, 0x03, 0xb0, 0xbd, 0xe8, 0x00, 0x80,
845 };
846
847 Method::InvokeStub* stub = AllocateStub(method,
848 main_LV_code,
849 sizeof(main_LV_code));
850
851 Object* arg = NULL;
852
853 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(&arg), NULL);
Carl Shapiro9b9ba282011-08-14 15:30:39 -0700854}
855
856TEST_F(JniInternalTest, StaticNopMethod) {
Elliott Hughes90a33692011-08-30 13:27:07 -0700857 UniquePtr<const DexFile> dex(OpenTestDexFile("StaticLeafMethods"));
Carl Shapiro9b9ba282011-08-14 15:30:39 -0700858
Brian Carlstrom8a487412011-08-29 20:08:52 -0700859 const PathClassLoader* class_loader = AllocPathClassLoader(dex.get());
Carl Shapiro9b9ba282011-08-14 15:30:39 -0700860 ASSERT_TRUE(class_loader != NULL);
861
862 Class* klass = class_linker_->FindClass("LStaticLeafMethods;", class_loader);
863 ASSERT_TRUE(klass != NULL);
864
865 Method* method = klass->FindDirectMethod("nop", "()V");
866 ASSERT_TRUE(method != NULL);
867
868 byte nop_V_code[] = {
869 0x2d, 0xe9, 0x00, 0x40, 0x83, 0xb0, 0xcd, 0xf8,
870 0x00, 0x00, 0x03, 0xb0, 0xbd, 0xe8, 0x00, 0x80,
871 };
872
873 Method::InvokeStub* stub = AllocateStub(method,
874 nop_V_code,
875 sizeof(nop_V_code));
876 ASSERT_TRUE(stub);
877
878 (*stub)(method, NULL, NULL, NULL, NULL);
Carl Shapiro9b9ba282011-08-14 15:30:39 -0700879}
880
881TEST_F(JniInternalTest, StaticIdentityByteMethod) {
Elliott Hughes90a33692011-08-30 13:27:07 -0700882 UniquePtr<const DexFile> dex(OpenTestDexFile("StaticLeafMethods"));
Carl Shapiro9b9ba282011-08-14 15:30:39 -0700883
Brian Carlstrom8a487412011-08-29 20:08:52 -0700884 const PathClassLoader* class_loader = AllocPathClassLoader(dex.get());
Carl Shapiro9b9ba282011-08-14 15:30:39 -0700885 ASSERT_TRUE(class_loader != NULL);
886
887 Class* klass = class_linker_->FindClass("LStaticLeafMethods;", class_loader);
888 ASSERT_TRUE(klass != NULL);
889
890 Method* method = klass->FindDirectMethod("identity", "(B)B");
891 ASSERT_TRUE(method != NULL);
892
893 byte identity_BB_code[] = {
894 0x2d, 0xe9, 0x00, 0x40, 0x83, 0xb0, 0xcd, 0xf8,
895 0x00, 0x00, 0xcd, 0xf8, 0x14, 0x10, 0x05, 0x98,
896 0x03, 0xb0, 0xbd, 0xe8, 0x00, 0x80, 0x00, 0x00,
897 };
898
899 Method::InvokeStub* stub = AllocateStub(method,
900 identity_BB_code,
901 sizeof(identity_BB_code));
902
903 int arg;
904 JValue result;
905
906 arg = 0;
907 result.b = -1;
908 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(&arg), &result);
909 EXPECT_EQ(0, result.b);
910
911 arg = -1;
912 result.b = 0;
913 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(&arg), &result);
914 EXPECT_EQ(-1, result.b);
915
916 arg = SCHAR_MAX;
917 result.b = 0;
918 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(&arg), &result);
919 EXPECT_EQ(SCHAR_MAX, result.b);
920
921 arg = SCHAR_MIN;
922 result.b = 0;
923 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(&arg), &result);
924 EXPECT_EQ(SCHAR_MIN, result.b);
Carl Shapiro9b9ba282011-08-14 15:30:39 -0700925}
926
927TEST_F(JniInternalTest, StaticIdentityIntMethod) {
Elliott Hughes90a33692011-08-30 13:27:07 -0700928 UniquePtr<const DexFile> dex(OpenTestDexFile("StaticLeafMethods"));
Carl Shapiro9b9ba282011-08-14 15:30:39 -0700929
Brian Carlstrom8a487412011-08-29 20:08:52 -0700930 const PathClassLoader* class_loader = AllocPathClassLoader(dex.get());
Carl Shapiro9b9ba282011-08-14 15:30:39 -0700931 ASSERT_TRUE(class_loader != NULL);
932
933 Class* klass = class_linker_->FindClass("LStaticLeafMethods;", class_loader);
934 ASSERT_TRUE(klass != NULL);
935
936 Method* method = klass->FindDirectMethod("identity", "(I)I");
937 ASSERT_TRUE(method != NULL);
938
939 byte identity_II_code[] = {
940 0x2d, 0xe9, 0x00, 0x40, 0x83, 0xb0, 0xcd, 0xf8,
941 0x00, 0x00, 0xcd, 0xf8, 0x14, 0x10, 0x05, 0x98,
942 0x03, 0xb0, 0xbd, 0xe8, 0x00, 0x80, 0x00, 0x00,
943 };
944
945 Method::InvokeStub* stub = AllocateStub(method,
946 identity_II_code,
947 sizeof(identity_II_code));
948
949 int arg;
950 JValue result;
951
952 arg = 0;
953 result.i = -1;
954 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(&arg), &result);
955 EXPECT_EQ(0, result.i);
956
957 arg = -1;
958 result.i = 0;
959 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(&arg), &result);
960 EXPECT_EQ(-1, result.i);
961
962 arg = INT_MAX;
963 result.i = 0;
964 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(&arg), &result);
965 EXPECT_EQ(INT_MAX, result.i);
966
967 arg = INT_MIN;
968 result.i = 0;
969 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(&arg), &result);
970 EXPECT_EQ(INT_MIN, result.i);
Carl Shapiro9b9ba282011-08-14 15:30:39 -0700971}
972
973TEST_F(JniInternalTest, StaticIdentityDoubleMethod) {
Elliott Hughes90a33692011-08-30 13:27:07 -0700974 UniquePtr<const DexFile> dex(OpenTestDexFile("StaticLeafMethods"));
Carl Shapiro9b9ba282011-08-14 15:30:39 -0700975
Brian Carlstrom8a487412011-08-29 20:08:52 -0700976 const PathClassLoader* class_loader = AllocPathClassLoader(dex.get());
Carl Shapiro9b9ba282011-08-14 15:30:39 -0700977 ASSERT_TRUE(class_loader != NULL);
978
979 Class* klass = class_linker_->FindClass("LStaticLeafMethods;", class_loader);
980 ASSERT_TRUE(klass != NULL);
981
982 Method* method = klass->FindDirectMethod("identity", "(D)D");
983 ASSERT_TRUE(method != NULL);
984
985 byte identity_DD_code[] = {
986 0x2d, 0xe9, 0x00, 0x40, 0x83, 0xb0, 0xcd, 0xf8,
987 0x00, 0x00, 0xcd, 0xf8, 0x14, 0x10, 0xcd, 0xf8,
988 0x18, 0x20, 0x05, 0x98, 0x06, 0x99, 0x03, 0xb0,
989 0xbd, 0xe8, 0x00, 0x80,
990 };
991
992 Method::InvokeStub* stub = AllocateStub(method,
993 identity_DD_code,
994 sizeof(identity_DD_code));
995
996 double arg;
997 JValue result;
998
999 arg = 0.0;
1000 result.d = -1.0;
1001 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(&arg), &result);
1002 EXPECT_EQ(0.0, result.d);
1003
1004 arg = -1.0;
1005 result.d = 0.0;
1006 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(&arg), &result);
1007 EXPECT_EQ(-1.0, result.d);
1008
1009 arg = DBL_MAX;
1010 result.d = 0.0;
1011 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(&arg), &result);
1012 EXPECT_EQ(DBL_MAX, result.d);
1013
1014 arg = DBL_MIN;
1015 result.d = 0.0;
1016 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(&arg), &result);
1017 EXPECT_EQ(DBL_MIN, result.d);
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001018}
1019
1020TEST_F(JniInternalTest, StaticSumIntIntMethod) {
Elliott Hughes90a33692011-08-30 13:27:07 -07001021 UniquePtr<const DexFile> dex(OpenTestDexFile("StaticLeafMethods"));
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001022
Brian Carlstrom8a487412011-08-29 20:08:52 -07001023 const PathClassLoader* class_loader = AllocPathClassLoader(dex.get());
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001024 ASSERT_TRUE(class_loader != NULL);
1025
1026 Class* klass = class_linker_->FindClass("LStaticLeafMethods;", class_loader);
1027 ASSERT_TRUE(klass != NULL);
1028
1029 Method* method = klass->FindDirectMethod("sum", "(II)I");
1030 ASSERT_TRUE(method != NULL);
1031
1032 byte sum_III_code[] = {
1033 0x2d, 0xe9, 0x00, 0x40, 0x83, 0xb0, 0xcd, 0xf8,
1034 0x00, 0x00, 0xcd, 0xf8, 0x14, 0x10, 0xcd, 0xf8,
1035 0x18, 0x20, 0x05, 0x98, 0x06, 0x99, 0x42, 0x18,
1036 0xcd, 0xf8, 0x04, 0x20, 0x01, 0x98, 0x03, 0xb0,
1037 0xbd, 0xe8, 0x00, 0x80,
1038 };
1039
1040 Method::InvokeStub* stub = AllocateStub(method,
1041 sum_III_code,
1042 sizeof(sum_III_code));
1043
1044 int args[2];
1045 JValue result;
1046
1047 args[0] = 0;
1048 args[1] = 0;
1049 result.i = -1;
1050 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
1051 EXPECT_EQ(0, result.i);
1052
1053 args[0] = 1;
1054 args[1] = 2;
1055 result.i = 0;
1056 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
1057 EXPECT_EQ(3, result.i);
1058
1059 args[0] = -2;
1060 args[1] = 5;
1061 result.i = 0;
1062 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
1063 EXPECT_EQ(3, result.i);
1064
1065 args[0] = INT_MAX;
1066 args[1] = INT_MIN;
1067 result.i = 1234;
1068 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
1069 EXPECT_EQ(-1, result.i);
1070
1071 args[0] = INT_MAX;
1072 args[1] = INT_MAX;
1073 result.i = INT_MIN;
1074 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
1075 EXPECT_EQ(-2, result.i);
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001076}
1077
1078TEST_F(JniInternalTest, StaticSumIntIntIntMethod) {
Elliott Hughes90a33692011-08-30 13:27:07 -07001079 UniquePtr<const DexFile> dex(OpenTestDexFile("StaticLeafMethods"));
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001080
Brian Carlstrom8a487412011-08-29 20:08:52 -07001081 const PathClassLoader* class_loader = AllocPathClassLoader(dex.get());
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001082 ASSERT_TRUE(class_loader != NULL);
1083
1084 Class* klass = class_linker_->FindClass("LStaticLeafMethods;", class_loader);
1085 ASSERT_TRUE(klass != NULL);
1086
1087 Method* method = klass->FindDirectMethod("sum", "(III)I");
1088 ASSERT_TRUE(method != NULL);
1089
1090 byte sum_IIII_code[] = {
1091 0x2d, 0xe9, 0x00, 0x40, 0x83, 0xb0, 0xcd, 0xf8,
1092 0x00, 0x00, 0xcd, 0xf8, 0x14, 0x10, 0xcd, 0xf8,
1093 0x18, 0x20, 0xcd, 0xf8, 0x1c, 0x30, 0x05, 0x98,
1094 0x06, 0x99, 0x42, 0x18, 0xcd, 0xf8, 0x04, 0x20,
1095 0x01, 0x9b, 0xdd, 0xf8, 0x1c, 0xc0, 0x13, 0xeb,
1096 0x0c, 0x03, 0xcd, 0xf8, 0x04, 0x30, 0x01, 0x98,
1097 0x03, 0xb0, 0xbd, 0xe8, 0x00, 0x80, 0x00, 0x00,
1098 };
1099
1100 Method::InvokeStub* stub = AllocateStub(method,
1101 sum_IIII_code,
1102 sizeof(sum_IIII_code));
1103
1104 int args[3];
1105 JValue result;
1106
1107 args[0] = 0;
1108 args[1] = 0;
1109 args[2] = 0;
1110 result.i = -1;
1111 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
1112 EXPECT_EQ(0, result.i);
1113
1114 args[0] = 1;
1115 args[1] = 2;
1116 args[2] = 3;
1117 result.i = 0;
1118 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
1119 EXPECT_EQ(6, result.i);
1120
1121 args[0] = -1;
1122 args[1] = 2;
1123 args[2] = -3;
1124 result.i = 0;
1125 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
1126 EXPECT_EQ(-2, result.i);
1127
1128 args[0] = INT_MAX;
1129 args[1] = INT_MIN;
1130 args[2] = INT_MAX;
1131 result.i = 1234;
1132 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
1133 EXPECT_EQ(2147483646, result.i);
1134
1135 args[0] = INT_MAX;
1136 args[1] = INT_MAX;
1137 args[2] = INT_MAX;
1138 result.i = INT_MIN;
1139 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
1140 EXPECT_EQ(2147483645, result.i);
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001141}
1142
1143TEST_F(JniInternalTest, StaticSumIntIntIntIntMethod) {
Elliott Hughes90a33692011-08-30 13:27:07 -07001144 UniquePtr<const DexFile> dex(OpenTestDexFile("StaticLeafMethods"));
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001145
Brian Carlstrom8a487412011-08-29 20:08:52 -07001146 const PathClassLoader* class_loader = AllocPathClassLoader(dex.get());
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001147 ASSERT_TRUE(class_loader != NULL);
1148
1149 Class* klass = class_linker_->FindClass("LStaticLeafMethods;", class_loader);
1150 ASSERT_TRUE(klass != NULL);
1151
1152 Method* method = klass->FindDirectMethod("sum", "(IIII)I");
1153 ASSERT_TRUE(method != NULL);
1154
1155 byte sum_IIIII_code[] = {
1156 0x2d, 0xe9, 0x00, 0x40, 0x83, 0xb0, 0xcd, 0xf8,
1157 0x00, 0x00, 0xcd, 0xf8, 0x14, 0x10, 0xcd, 0xf8,
1158 0x18, 0x20, 0xcd, 0xf8, 0x1c, 0x30, 0x05, 0x98,
1159 0x06, 0x99, 0x42, 0x18, 0xcd, 0xf8, 0x04, 0x20,
1160 0x01, 0x9b, 0xdd, 0xf8, 0x1c, 0xc0, 0x13, 0xeb,
1161 0x0c, 0x03, 0xcd, 0xf8, 0x04, 0x30, 0x01, 0x98,
1162 0x08, 0x99, 0x40, 0x18, 0xcd, 0xf8, 0x04, 0x00,
1163 0x01, 0x98, 0x03, 0xb0, 0xbd, 0xe8, 0x00, 0x80,
1164 };
1165
1166 Method::InvokeStub* stub = AllocateStub(method,
1167 sum_IIIII_code,
1168 sizeof(sum_IIIII_code));
1169
1170 int args[4];
1171 JValue result;
1172
1173 args[0] = 0;
1174 args[1] = 0;
1175 args[2] = 0;
1176 args[3] = 0;
1177 result.i = -1;
1178 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
1179 EXPECT_EQ(0, result.i);
1180
1181 args[0] = 1;
1182 args[1] = 2;
1183 args[2] = 3;
1184 args[3] = 4;
1185 result.i = 0;
1186 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
1187 EXPECT_EQ(10, result.i);
1188
1189 args[0] = -1;
1190 args[1] = 2;
1191 args[2] = -3;
1192 args[3] = 4;
1193 result.i = 0;
1194 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
1195 EXPECT_EQ(2, result.i);
1196
1197 args[0] = INT_MAX;
1198 args[1] = INT_MIN;
1199 args[2] = INT_MAX;
1200 args[3] = INT_MIN;
1201 result.i = 1234;
1202 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
1203 EXPECT_EQ(-2, result.i);
1204
1205 args[0] = INT_MAX;
1206 args[1] = INT_MAX;
1207 args[2] = INT_MAX;
1208 args[3] = INT_MAX;
1209 result.i = INT_MIN;
1210 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
1211 EXPECT_EQ(-4, result.i);
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001212}
1213
1214TEST_F(JniInternalTest, StaticSumIntIntIntIntIntMethod) {
Elliott Hughes90a33692011-08-30 13:27:07 -07001215 UniquePtr<const DexFile> dex(OpenTestDexFile("StaticLeafMethods"));
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001216
Brian Carlstrom8a487412011-08-29 20:08:52 -07001217 const PathClassLoader* class_loader = AllocPathClassLoader(dex.get());
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001218 ASSERT_TRUE(class_loader != NULL);
1219
1220 Class* klass = class_linker_->FindClass("LStaticLeafMethods;", class_loader);
1221 ASSERT_TRUE(klass != NULL);
1222
1223 Method* method = klass->FindDirectMethod("sum", "(IIIII)I");
1224 ASSERT_TRUE(method != NULL);
1225
1226 byte sum_IIIIII_code[] = {
1227 0x2d, 0xe9, 0x00, 0x40, 0x83, 0xb0, 0xcd, 0xf8,
1228 0x00, 0x00, 0xcd, 0xf8, 0x14, 0x10, 0xcd, 0xf8,
1229 0x18, 0x20, 0xcd, 0xf8, 0x1c, 0x30, 0x05, 0x98,
1230 0x06, 0x99, 0x42, 0x18, 0xcd, 0xf8, 0x04, 0x20,
1231 0x01, 0x9b, 0xdd, 0xf8, 0x1c, 0xc0, 0x13, 0xeb,
1232 0x0c, 0x03, 0xcd, 0xf8, 0x04, 0x30, 0x01, 0x98,
1233 0x08, 0x99, 0x40, 0x18, 0xcd, 0xf8, 0x04, 0x00,
1234 0x01, 0x9a, 0x09, 0x9b, 0xd2, 0x18, 0xcd, 0xf8,
1235 0x04, 0x20, 0x01, 0x98, 0x03, 0xb0, 0xbd, 0xe8,
1236 0x00, 0x80, 0x00, 0x00,
1237 };
1238
1239 Method::InvokeStub* stub = AllocateStub(method,
1240 sum_IIIIII_code,
1241 sizeof(sum_IIIIII_code));
1242
1243 int args[5];
1244 JValue result;
1245
1246 args[0] = 0;
1247 args[1] = 0;
1248 args[2] = 0;
1249 args[3] = 0;
1250 args[4] = 0;
1251 result.i = -1.0;
1252 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
1253 EXPECT_EQ(0, result.i);
1254
1255 args[0] = 1;
1256 args[1] = 2;
1257 args[2] = 3;
1258 args[3] = 4;
1259 args[4] = 5;
1260 result.i = 0;
1261 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
1262 EXPECT_EQ(15, result.i);
1263
1264 args[0] = -1;
1265 args[1] = 2;
1266 args[2] = -3;
1267 args[3] = 4;
1268 args[4] = -5;
1269 result.i = 0;
1270 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
1271 EXPECT_EQ(-3, result.i);
1272
1273 args[0] = INT_MAX;
1274 args[1] = INT_MIN;
1275 args[2] = INT_MAX;
1276 args[3] = INT_MIN;
1277 args[4] = INT_MAX;
1278 result.i = 1234;
1279 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
1280 EXPECT_EQ(2147483645, result.i);
1281
1282 args[0] = INT_MAX;
1283 args[1] = INT_MAX;
1284 args[2] = INT_MAX;
1285 args[3] = INT_MAX;
1286 args[4] = INT_MAX;
1287 result.i = INT_MIN;
1288 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
1289 EXPECT_EQ(2147483643, result.i);
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001290}
1291
1292TEST_F(JniInternalTest, StaticSumDoubleDoubleMethod) {
Elliott Hughes90a33692011-08-30 13:27:07 -07001293 UniquePtr<const DexFile> dex(OpenTestDexFile("StaticLeafMethods"));
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001294
Brian Carlstrom8a487412011-08-29 20:08:52 -07001295 const PathClassLoader* class_loader = AllocPathClassLoader(dex.get());
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001296 ASSERT_TRUE(class_loader != NULL);
1297
1298 Class* klass = class_linker_->FindClass("LStaticLeafMethods;", class_loader);
1299 ASSERT_TRUE(klass != NULL);
1300
1301 Method* method = klass->FindDirectMethod("sum", "(DD)D");
1302 ASSERT_TRUE(method != NULL);
1303
1304 byte sum_DDD_code[] = {
1305 0x2d, 0xe9, 0x00, 0x40, 0x87, 0xb0, 0xcd, 0xf8,
1306 0x00, 0x00, 0xcd, 0xf8, 0x24, 0x10, 0xcd, 0xf8,
1307 0x28, 0x20, 0xcd, 0xf8, 0x2c, 0x30, 0x9d, 0xed,
1308 0x09, 0x0b, 0x9d, 0xed, 0x0b, 0x1b, 0x30, 0xee,
1309 0x01, 0x2b, 0x8d, 0xed, 0x04, 0x2b, 0x04, 0x98,
1310 0x05, 0x99, 0x07, 0xb0, 0xbd, 0xe8, 0x00, 0x80,
1311 };
1312
1313 Method::InvokeStub* stub = AllocateStub(method,
1314 sum_DDD_code,
1315 sizeof(sum_DDD_code));
1316
1317 double args[2];
1318 JValue result;
1319
1320 args[0] = 0.0;
1321 args[1] = 0.0;
1322 result.d = -1.0;
1323 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
1324 EXPECT_EQ(0.0, result.d);
1325
1326 args[0] = 1.0;
1327 args[1] = 2.0;
1328 result.d = 0.0;
1329 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
1330 EXPECT_EQ(3.0, result.d);
1331
1332 args[0] = 1.0;
1333 args[1] = -2.0;
1334 result.d = 0.0;
1335 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
1336 EXPECT_EQ(-1.0, result.d);
1337
1338 args[0] = DBL_MAX;
1339 args[1] = DBL_MIN;
1340 result.d = 0.0;
1341 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
1342 EXPECT_EQ(1.7976931348623157e308, result.d);
1343
1344 args[0] = DBL_MAX;
1345 args[1] = DBL_MAX;
1346 result.d = 0.0;
1347 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
1348 EXPECT_EQ(INFINITY, result.d);
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001349}
1350
1351TEST_F(JniInternalTest, StaticSumDoubleDoubleDoubleMethod) {
Elliott Hughes90a33692011-08-30 13:27:07 -07001352 UniquePtr<const DexFile> dex(OpenTestDexFile("StaticLeafMethods"));
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001353
Brian Carlstrom8a487412011-08-29 20:08:52 -07001354 const PathClassLoader* class_loader = AllocPathClassLoader(dex.get());
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001355 ASSERT_TRUE(class_loader != NULL);
1356
1357 Class* klass = class_linker_->FindClass("LStaticLeafMethods;", class_loader);
1358 ASSERT_TRUE(klass != NULL);
1359
1360 Method* method = klass->FindDirectMethod("sum", "(DDD)D");
1361 ASSERT_TRUE(method != NULL);
1362
1363 byte sum_DDDD_code[] = {
1364 0x2d, 0xe9, 0x00, 0x40, 0x87, 0xb0, 0xcd, 0xf8,
1365 0x00, 0x00, 0xcd, 0xf8, 0x24, 0x10, 0xcd, 0xf8,
1366 0x28, 0x20, 0xcd, 0xf8, 0x2c, 0x30, 0x9d, 0xed,
1367 0x09, 0x0b, 0x9d, 0xed, 0x0b, 0x1b, 0x30, 0xee,
1368 0x01, 0x2b, 0x8d, 0xed, 0x04, 0x2b, 0x9d, 0xed,
1369 0x04, 0x3b, 0x9d, 0xed, 0x0d, 0x4b, 0x33, 0xee,
1370 0x04, 0x3b, 0x8d, 0xed, 0x04, 0x3b, 0x04, 0x98,
1371 0x05, 0x99, 0x07, 0xb0, 0xbd, 0xe8, 0x00, 0x80,
1372 };
1373
1374 Method::InvokeStub* stub = AllocateStub(method,
1375 sum_DDDD_code,
1376 sizeof(sum_DDDD_code));
1377
1378 double args[3];
1379 JValue result;
1380
1381 args[0] = 0.0;
1382 args[1] = 0.0;
1383 args[2] = 0.0;
1384 result.d = -1.0;
1385 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
1386 EXPECT_EQ(0.0, result.d);
1387
1388 args[0] = 1.0;
1389 args[1] = 2.0;
1390 args[2] = 3.0;
1391 result.d = 0.0;
1392 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
1393 EXPECT_EQ(6.0, result.d);
1394
1395 args[0] = 1.0;
1396 args[1] = -2.0;
1397 args[2] = 3.0;
1398 result.d = 0.0;
1399 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
1400 EXPECT_EQ(2.0, result.d);
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001401}
1402
1403TEST_F(JniInternalTest, StaticSumDoubleDoubleDoubleDoubleMethod) {
Elliott Hughes90a33692011-08-30 13:27:07 -07001404 UniquePtr<const DexFile> dex(OpenTestDexFile("StaticLeafMethods"));
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001405
Brian Carlstrom8a487412011-08-29 20:08:52 -07001406 const PathClassLoader* class_loader = AllocPathClassLoader(dex.get());
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001407 ASSERT_TRUE(class_loader != NULL);
1408
1409 Class* klass = class_linker_->FindClass("LStaticLeafMethods;", class_loader);
1410 ASSERT_TRUE(klass != NULL);
1411
1412 Method* method = klass->FindDirectMethod("sum", "(DDDD)D");
1413 ASSERT_TRUE(method != NULL);
1414
1415 byte sum_DDDDD_code[] = {
1416 0x2d, 0xe9, 0x00, 0x40, 0x87, 0xb0, 0xcd, 0xf8,
1417 0x00, 0x00, 0xcd, 0xf8, 0x24, 0x10, 0xcd, 0xf8,
1418 0x28, 0x20, 0xcd, 0xf8, 0x2c, 0x30, 0x9d, 0xed,
1419 0x09, 0x0b, 0x9d, 0xed, 0x0b, 0x1b, 0x30, 0xee,
1420 0x01, 0x2b, 0x8d, 0xed, 0x04, 0x2b, 0x9d, 0xed,
1421 0x04, 0x3b, 0x9d, 0xed, 0x0d, 0x4b, 0x33, 0xee,
1422 0x04, 0x3b, 0x8d, 0xed, 0x04, 0x3b, 0x9d, 0xed,
1423 0x04, 0x5b, 0x9d, 0xed, 0x0f, 0x6b, 0x35, 0xee,
1424 0x06, 0x5b, 0x8d, 0xed, 0x04, 0x5b, 0x04, 0x98,
1425 0x05, 0x99, 0x07, 0xb0, 0xbd, 0xe8, 0x00, 0x80,
1426 };
1427
1428 Method::InvokeStub* stub = AllocateStub(method,
1429 sum_DDDDD_code,
1430 sizeof(sum_DDDDD_code));
1431
1432 double args[4];
1433 JValue result;
1434
1435 args[0] = 0.0;
1436 args[1] = 0.0;
1437 args[2] = 0.0;
1438 args[3] = 0.0;
1439 result.d = -1.0;
1440 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
1441 EXPECT_EQ(0.0, result.d);
1442
1443 args[0] = 1.0;
1444 args[1] = 2.0;
1445 args[2] = 3.0;
1446 args[3] = 4.0;
1447 result.d = 0.0;
1448 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
1449 EXPECT_EQ(10.0, result.d);
1450
1451 args[0] = 1.0;
1452 args[1] = -2.0;
1453 args[2] = 3.0;
1454 args[3] = -4.0;
1455 result.d = 0.0;
1456 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
1457 EXPECT_EQ(-2.0, result.d);
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001458}
1459
1460TEST_F(JniInternalTest, StaticSumDoubleDoubleDoubleDoubleDoubleMethod) {
Elliott Hughes90a33692011-08-30 13:27:07 -07001461 UniquePtr<const DexFile> dex(OpenTestDexFile("StaticLeafMethods"));
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001462
Brian Carlstrom8a487412011-08-29 20:08:52 -07001463 const PathClassLoader* class_loader = AllocPathClassLoader(dex.get());
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001464 ASSERT_TRUE(class_loader != NULL);
1465
1466 Class* klass = class_linker_->FindClass("LStaticLeafMethods;", class_loader);
1467 ASSERT_TRUE(klass != NULL);
1468
1469 Method* method = klass->FindDirectMethod("sum", "(DDDDD)D");
1470 ASSERT_TRUE(method != NULL);
1471
1472 byte sum_DDDDDD_code[] = {
1473 0x2d, 0xe9, 0x00, 0x40, 0x87, 0xb0, 0xcd, 0xf8,
1474 0x00, 0x00, 0xcd, 0xf8, 0x24, 0x10, 0xcd, 0xf8,
1475 0x28, 0x20, 0xcd, 0xf8, 0x2c, 0x30, 0x9d, 0xed,
1476 0x09, 0x0b, 0x9d, 0xed, 0x0b, 0x1b, 0x30, 0xee,
1477 0x01, 0x2b, 0x8d, 0xed, 0x04, 0x2b, 0x9d, 0xed,
1478 0x04, 0x3b, 0x9d, 0xed, 0x0d, 0x4b, 0x33, 0xee,
1479 0x04, 0x3b, 0x8d, 0xed, 0x04, 0x3b, 0x9d, 0xed,
1480 0x04, 0x5b, 0x9d, 0xed, 0x0f, 0x6b, 0x35, 0xee,
1481 0x06, 0x5b, 0x8d, 0xed, 0x04, 0x5b, 0x9d, 0xed,
1482 0x04, 0x7b, 0x9d, 0xed, 0x11, 0x0b, 0x37, 0xee,
1483 0x00, 0x7b, 0x8d, 0xed, 0x04, 0x7b, 0x04, 0x98,
1484 0x05, 0x99, 0x07, 0xb0, 0xbd, 0xe8, 0x00, 0x80,
1485 };
1486
1487 Method::InvokeStub* stub = AllocateStub(method,
1488 sum_DDDDDD_code,
1489 sizeof(sum_DDDDDD_code));
1490
1491 double args[5];
1492 JValue result;
1493
1494 args[0] = 0.0;
1495 args[1] = 0.0;
1496 args[2] = 0.0;
1497 args[3] = 0.0;
1498 args[4] = 0.0;
1499 result.d = -1.0;
1500 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
1501 EXPECT_EQ(0.0, result.d);
1502
1503 args[0] = 1.0;
1504 args[1] = 2.0;
1505 args[2] = 3.0;
1506 args[3] = 4.0;
1507 args[4] = 5.0;
1508 result.d = 0.0;
1509 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
1510 EXPECT_EQ(15.0, result.d);
1511
1512 args[0] = 1.0;
1513 args[1] = -2.0;
1514 args[2] = 3.0;
1515 args[3] = -4.0;
1516 args[4] = 5.0;
1517 result.d = 0.0;
1518 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
1519 EXPECT_EQ(3.0, result.d);
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001520}
1521#endif // __arm__
1522
Elliott Hughes37f7a402011-08-22 18:56:01 -07001523TEST_F(JniInternalTest, Throw) {
1524 EXPECT_EQ(JNI_ERR, env_->Throw(NULL));
1525
1526 jclass exception_class = env_->FindClass("java/lang/RuntimeException");
1527 ASSERT_TRUE(exception_class != NULL);
1528 jthrowable exception = reinterpret_cast<jthrowable>(env_->AllocObject(exception_class));
1529 ASSERT_TRUE(exception != NULL);
1530
1531 EXPECT_EQ(JNI_OK, env_->Throw(exception));
1532 EXPECT_TRUE(env_->ExceptionCheck());
Elliott Hughesa2501992011-08-26 19:39:54 -07001533 jthrowable thrown_exception = env_->ExceptionOccurred();
Elliott Hughes37f7a402011-08-22 18:56:01 -07001534 env_->ExceptionClear();
Elliott Hughesa2501992011-08-26 19:39:54 -07001535 EXPECT_TRUE(env_->IsSameObject(exception, thrown_exception));
Elliott Hughes37f7a402011-08-22 18:56:01 -07001536}
1537
1538TEST_F(JniInternalTest, ThrowNew) {
1539 EXPECT_EQ(JNI_ERR, env_->Throw(NULL));
1540
1541 jclass exception_class = env_->FindClass("java/lang/RuntimeException");
1542 ASSERT_TRUE(exception_class != NULL);
1543
1544 EXPECT_EQ(JNI_OK, env_->ThrowNew(exception_class, "hello world"));
1545 EXPECT_TRUE(env_->ExceptionCheck());
Elliott Hughesa2501992011-08-26 19:39:54 -07001546 jthrowable thrown_exception = env_->ExceptionOccurred();
Elliott Hughes37f7a402011-08-22 18:56:01 -07001547 env_->ExceptionClear();
Elliott Hughesa2501992011-08-26 19:39:54 -07001548 EXPECT_TRUE(env_->IsInstanceOf(thrown_exception, exception_class));
Elliott Hughes37f7a402011-08-22 18:56:01 -07001549}
1550
Elliott Hughesb465ab02011-08-24 11:21:21 -07001551// TODO: this test is DISABLED until we can actually run java.nio.Buffer's <init>.
1552TEST_F(JniInternalTest, DISABLED_NewDirectBuffer_GetDirectBufferAddress_GetDirectBufferCapacity) {
1553 jclass buffer_class = env_->FindClass("java/nio/Buffer");
1554 ASSERT_TRUE(buffer_class != NULL);
1555
1556 char bytes[1024];
1557 jobject buffer = env_->NewDirectByteBuffer(bytes, sizeof(bytes));
1558 ASSERT_TRUE(buffer != NULL);
1559 ASSERT_TRUE(env_->IsInstanceOf(buffer, buffer_class));
1560 ASSERT_TRUE(env_->GetDirectBufferAddress(buffer) == bytes);
1561 ASSERT_TRUE(env_->GetDirectBufferCapacity(buffer) == sizeof(bytes));
1562}
1563
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001564}