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