blob: ddc0408e0ac5b9bf9c4e870aaa81556fb1ea5051 [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
18 // Turn on -verbose:jni for the JNI tests.
19 Runtime::Current()->GetJavaVM()->verbose_jni = true;
20
Elliott Hughesc7ac37f2011-08-12 12:21:58 -070021 env_ = Thread::Current()->GetJniEnv();
Elliott Hughesb465ab02011-08-24 11:21:21 -070022
Elliott Hughes814e4032011-08-23 12:07:56 -070023 aioobe_ = env_->FindClass("java/lang/ArrayIndexOutOfBoundsException");
24 CHECK(aioobe_ != NULL);
Elliott Hughesb465ab02011-08-24 11:21:21 -070025
26 sioobe_ = env_->FindClass("java/lang/StringIndexOutOfBoundsException");
27 CHECK(sioobe_ != NULL);
Elliott Hughesc7ac37f2011-08-12 12:21:58 -070028 }
Elliott Hughesb465ab02011-08-24 11:21:21 -070029
Elliott Hughesc7ac37f2011-08-12 12:21:58 -070030 JNIEnv* env_;
Elliott Hughes814e4032011-08-23 12:07:56 -070031 jclass aioobe_;
Elliott Hughesb465ab02011-08-24 11:21:21 -070032 jclass sioobe_;
Elliott Hughes0c9cd562011-08-12 10:59:29 -070033};
34
Elliott Hughes885c3bd2011-08-22 16:59:20 -070035TEST_F(JniInternalTest, AllocObject) {
36 jclass c = env_->FindClass("java/lang/String");
37 ASSERT_TRUE(c != NULL);
38 jobject o = env_->AllocObject(c);
39 ASSERT_TRUE(o != NULL);
40
41 // We have an instance of the class we asked for...
42 ASSERT_TRUE(env_->IsInstanceOf(o, c));
43 // ...whose fields haven't been initialized because
44 // we didn't call a constructor.
45 ASSERT_EQ(0, env_->GetIntField(o, env_->GetFieldID(c, "count", "I")));
46 ASSERT_EQ(0, env_->GetIntField(o, env_->GetFieldID(c, "offset", "I")));
47 ASSERT_TRUE(env_->GetObjectField(o, env_->GetFieldID(c, "value", "[C")) == NULL);
48}
49
Elliott Hughesc7ac37f2011-08-12 12:21:58 -070050TEST_F(JniInternalTest, GetVersion) {
51 ASSERT_EQ(JNI_VERSION_1_6, env_->GetVersion());
52}
53
Elliott Hughes0c9cd562011-08-12 10:59:29 -070054#define EXPECT_CLASS_FOUND(NAME) \
Elliott Hughesbd935992011-08-22 11:59:34 -070055 EXPECT_TRUE(env_->FindClass(NAME) != NULL); \
56 EXPECT_FALSE(env_->ExceptionCheck())
Elliott Hughes0c9cd562011-08-12 10:59:29 -070057
58#define EXPECT_CLASS_NOT_FOUND(NAME) \
Elliott Hughesbd935992011-08-22 11:59:34 -070059 EXPECT_TRUE(env_->FindClass(NAME) == NULL); \
60 EXPECT_TRUE(env_->ExceptionCheck()); \
61 env_->ExceptionClear()
Elliott Hughes0c9cd562011-08-12 10:59:29 -070062
63TEST_F(JniInternalTest, FindClass) {
Elliott Hughes0c9cd562011-08-12 10:59:29 -070064 // TODO: when these tests start failing because you're calling FindClass
65 // with a pending exception, fix EXPECT_CLASS_NOT_FOUND to assert that an
66 // exception was thrown and clear the exception.
67
68 // TODO: . is only allowed as an alternative to / if CheckJNI is off.
69
70 // Reference types...
71 // You can't include the "L;" in a JNI class descriptor.
72 EXPECT_CLASS_FOUND("java/lang/String");
73 EXPECT_CLASS_NOT_FOUND("Ljava/lang/String;");
74 // We support . as well as / for compatibility.
75 EXPECT_CLASS_FOUND("java.lang.String");
76 EXPECT_CLASS_NOT_FOUND("Ljava.lang.String;");
77 // ...for arrays too, where you must include "L;".
78 EXPECT_CLASS_FOUND("[Ljava/lang/String;");
79 EXPECT_CLASS_NOT_FOUND("[java/lang/String");
80 EXPECT_CLASS_FOUND("[Ljava.lang.String;");
81 EXPECT_CLASS_NOT_FOUND("[java.lang.String");
82
83 // Primitive arrays are okay (if the primitive type is valid)...
84 EXPECT_CLASS_FOUND("[C");
85 EXPECT_CLASS_NOT_FOUND("[K");
86 // But primitive types aren't allowed...
87 EXPECT_CLASS_NOT_FOUND("C");
88 EXPECT_CLASS_NOT_FOUND("K");
89}
90
Elliott Hughescdf53122011-08-19 15:46:09 -070091#define EXPECT_EXCEPTION(exception_class) \
92 do { \
93 EXPECT_TRUE(env_->ExceptionCheck()); \
94 jthrowable exception = env_->ExceptionOccurred(); \
95 EXPECT_NE(static_cast<jthrowable>(NULL), exception); \
96 EXPECT_TRUE(env_->IsInstanceOf(exception, exception_class)); \
97 env_->ExceptionClear(); \
98 } while (false)
99
100TEST_F(JniInternalTest, GetFieldID) {
101 jclass jlnsfe = env_->FindClass("java/lang/NoSuchFieldError");
102 ASSERT_TRUE(jlnsfe != NULL);
103 jclass c = env_->FindClass("java/lang/String");
104 ASSERT_TRUE(c != NULL);
105
106 // Wrong type.
107 jfieldID fid = env_->GetFieldID(c, "count", "J");
108 EXPECT_EQ(static_cast<jfieldID>(NULL), fid);
109 EXPECT_EXCEPTION(jlnsfe);
110
111 // Wrong name.
112 fid = env_->GetFieldID(c, "Count", "I");
113 EXPECT_EQ(static_cast<jfieldID>(NULL), fid);
114 EXPECT_EXCEPTION(jlnsfe);
115
116 // Good declared field lookup.
117 fid = env_->GetFieldID(c, "count", "I");
118 EXPECT_NE(static_cast<jfieldID>(NULL), fid);
119 EXPECT_TRUE(fid != NULL);
120 EXPECT_FALSE(env_->ExceptionCheck());
121
122 // Good superclass field lookup.
123 c = env_->FindClass("java/lang/StringBuilder");
124 fid = env_->GetFieldID(c, "count", "I");
125 EXPECT_NE(static_cast<jfieldID>(NULL), fid);
126 EXPECT_TRUE(fid != NULL);
127 EXPECT_FALSE(env_->ExceptionCheck());
128
129 // Not instance.
130 fid = env_->GetFieldID(c, "CASE_INSENSITIVE_ORDER", "Ljava/util/Comparator;");
131 EXPECT_EQ(static_cast<jfieldID>(NULL), fid);
132 EXPECT_EXCEPTION(jlnsfe);
133}
134
135TEST_F(JniInternalTest, GetStaticFieldID) {
136 jclass jlnsfe = env_->FindClass("java/lang/NoSuchFieldError");
137 ASSERT_TRUE(jlnsfe != NULL);
138 jclass c = env_->FindClass("java/lang/String");
139 ASSERT_TRUE(c != NULL);
140
141 // Wrong type.
142 jfieldID fid = env_->GetStaticFieldID(c, "CASE_INSENSITIVE_ORDER", "J");
143 EXPECT_EQ(static_cast<jfieldID>(NULL), fid);
144 EXPECT_EXCEPTION(jlnsfe);
145
146 // Wrong name.
147 fid = env_->GetStaticFieldID(c, "cASE_INSENSITIVE_ORDER", "Ljava/util/Comparator;");
148 EXPECT_EQ(static_cast<jfieldID>(NULL), fid);
149 EXPECT_EXCEPTION(jlnsfe);
150
151 // Good declared field lookup.
152 fid = env_->GetStaticFieldID(c, "CASE_INSENSITIVE_ORDER", "Ljava/util/Comparator;");
153 EXPECT_NE(static_cast<jfieldID>(NULL), fid);
154 EXPECT_TRUE(fid != NULL);
155 EXPECT_FALSE(env_->ExceptionCheck());
156
157 // Not static.
158 fid = env_->GetStaticFieldID(c, "count", "I");
159 EXPECT_EQ(static_cast<jfieldID>(NULL), fid);
160 EXPECT_EXCEPTION(jlnsfe);
161}
162
Ian Rogers4dd71f12011-08-16 14:16:02 -0700163TEST_F(JniInternalTest, GetMethodID) {
164 jclass jlobject = env_->FindClass("java/lang/Object");
165 jclass jlstring = env_->FindClass("java/lang/String");
166 jclass jlnsme = env_->FindClass("java/lang/NoSuchMethodError");
167
168 // Sanity check that no exceptions are pending
Elliott Hughescdf53122011-08-19 15:46:09 -0700169 ASSERT_FALSE(env_->ExceptionCheck());
Ian Rogers4dd71f12011-08-16 14:16:02 -0700170
171 // Check that java.lang.Object.foo() doesn't exist and NoSuchMethodError is
172 // a pending exception
173 jmethodID method = env_->GetMethodID(jlobject, "foo", "()V");
174 EXPECT_EQ(static_cast<jmethodID>(NULL), method);
Elliott Hughescdf53122011-08-19 15:46:09 -0700175 EXPECT_EXCEPTION(jlnsme);
Ian Rogers4dd71f12011-08-16 14:16:02 -0700176
177 // Check that java.lang.Object.equals() does exist
Ian Rogers4dd71f12011-08-16 14:16:02 -0700178 method = env_->GetMethodID(jlobject, "equals", "(Ljava/lang/Object;)Z");
179 EXPECT_NE(static_cast<jmethodID>(NULL), method);
180 EXPECT_FALSE(env_->ExceptionCheck());
Ian Rogers4dd71f12011-08-16 14:16:02 -0700181
182 // Check that GetMethodID for java.lang.String.valueOf(int) fails as the
183 // method is static
184 method = env_->GetMethodID(jlstring, "valueOf", "(I)Ljava/lang/String;");
185 EXPECT_EQ(static_cast<jmethodID>(NULL), method);
Elliott Hughescdf53122011-08-19 15:46:09 -0700186 EXPECT_EXCEPTION(jlnsme);
Ian Rogers4dd71f12011-08-16 14:16:02 -0700187}
188
189TEST_F(JniInternalTest, GetStaticMethodID) {
190 jclass jlobject = env_->FindClass("java/lang/Object");
191 jclass jlnsme = env_->FindClass("java/lang/NoSuchMethodError");
192
193 // Sanity check that no exceptions are pending
Elliott Hughescdf53122011-08-19 15:46:09 -0700194 ASSERT_FALSE(env_->ExceptionCheck());
Ian Rogers4dd71f12011-08-16 14:16:02 -0700195
196 // Check that java.lang.Object.foo() doesn't exist and NoSuchMethodError is
197 // a pending exception
198 jmethodID method = env_->GetStaticMethodID(jlobject, "foo", "()V");
199 EXPECT_EQ(static_cast<jmethodID>(NULL), method);
Elliott Hughescdf53122011-08-19 15:46:09 -0700200 EXPECT_EXCEPTION(jlnsme);
Ian Rogers4dd71f12011-08-16 14:16:02 -0700201
202 // Check that GetStaticMethodID for java.lang.Object.equals(Object) fails as
203 // the method is not static
204 method = env_->GetStaticMethodID(jlobject, "equals", "(Ljava/lang/Object;)Z");
205 EXPECT_EQ(static_cast<jmethodID>(NULL), method);
Elliott Hughescdf53122011-08-19 15:46:09 -0700206 EXPECT_EXCEPTION(jlnsme);
Ian Rogers4dd71f12011-08-16 14:16:02 -0700207
208 // Check that java.lang.String.valueOf(int) does exist
Ian Rogers4dd71f12011-08-16 14:16:02 -0700209 jclass jlstring = env_->FindClass("java/lang/String");
210 method = env_->GetStaticMethodID(jlstring, "valueOf",
211 "(I)Ljava/lang/String;");
212 EXPECT_NE(static_cast<jmethodID>(NULL), method);
213 EXPECT_FALSE(env_->ExceptionCheck());
Ian Rogers4dd71f12011-08-16 14:16:02 -0700214}
215
Elliott Hughescdf53122011-08-19 15:46:09 -0700216TEST_F(JniInternalTest, FromReflectedField_ToReflectedField) {
217 jclass jlrField = env_->FindClass("java/lang/reflect/Field");
218 jclass c = env_->FindClass("java/lang/String");
219 ASSERT_TRUE(c != NULL);
220 jfieldID fid = env_->GetFieldID(c, "count", "I");
221 ASSERT_TRUE(fid != NULL);
222 // Turn the fid into a java.lang.reflect.Field...
223 jobject field = env_->ToReflectedField(c, fid, JNI_FALSE);
224 ASSERT_TRUE(c != NULL);
225 ASSERT_TRUE(env_->IsInstanceOf(field, jlrField));
226 // ...and back again.
227 jfieldID fid2 = env_->FromReflectedField(field);
228 ASSERT_TRUE(fid2 != NULL);
229}
230
231TEST_F(JniInternalTest, FromReflectedMethod_ToReflectedMethod) {
232 jclass jlrMethod = env_->FindClass("java/lang/reflect/Method");
233 jclass c = env_->FindClass("java/lang/String");
234 ASSERT_TRUE(c != NULL);
235 jmethodID mid = env_->GetMethodID(c, "length", "()I");
236 ASSERT_TRUE(mid != NULL);
237 // Turn the mid into a java.lang.reflect.Method...
238 jobject method = env_->ToReflectedMethod(c, mid, JNI_FALSE);
239 ASSERT_TRUE(c != NULL);
240 ASSERT_TRUE(env_->IsInstanceOf(method, jlrMethod));
241 // ...and back again.
242 jmethodID mid2 = env_->FromReflectedMethod(method);
243 ASSERT_TRUE(mid2 != NULL);
244}
245
Elliott Hughes5174fe62011-08-23 15:12:35 -0700246void BogusMethod() {
247 // You can't pass NULL function pointers to RegisterNatives.
248}
249
Ian Rogers4dd71f12011-08-16 14:16:02 -0700250TEST_F(JniInternalTest, RegisterNatives) {
251 jclass jlobject = env_->FindClass("java/lang/Object");
252 jclass jlnsme = env_->FindClass("java/lang/NoSuchMethodError");
253
254 // Sanity check that no exceptions are pending
Elliott Hughescdf53122011-08-19 15:46:09 -0700255 ASSERT_FALSE(env_->ExceptionCheck());
Ian Rogers4dd71f12011-08-16 14:16:02 -0700256
257 // Check that registering to a non-existent java.lang.Object.foo() causes a
258 // NoSuchMethodError
259 {
260 JNINativeMethod methods[] = {{"foo", "()V", NULL}};
261 env_->RegisterNatives(jlobject, methods, 1);
262 }
Elliott Hughescdf53122011-08-19 15:46:09 -0700263 EXPECT_EXCEPTION(jlnsme);
Ian Rogers4dd71f12011-08-16 14:16:02 -0700264
265 // Check that registering non-native methods causes a NoSuchMethodError
266 {
267 JNINativeMethod methods[] = {{"equals", "(Ljava/lang/Object;)Z", NULL}};
268 env_->RegisterNatives(jlobject, methods, 1);
269 }
Elliott Hughescdf53122011-08-19 15:46:09 -0700270 EXPECT_EXCEPTION(jlnsme);
Ian Rogers4dd71f12011-08-16 14:16:02 -0700271
272 // Check that registering native methods is successful
273 {
Elliott Hughes5174fe62011-08-23 15:12:35 -0700274 JNINativeMethod methods[] = {{"hashCode", "()I", reinterpret_cast<void*>(BogusMethod)}};
Ian Rogers4dd71f12011-08-16 14:16:02 -0700275 env_->RegisterNatives(jlobject, methods, 1);
276 }
277 EXPECT_FALSE(env_->ExceptionCheck());
Elliott Hughes5174fe62011-08-23 15:12:35 -0700278
279 env_->UnregisterNatives(jlobject);
Ian Rogers4dd71f12011-08-16 14:16:02 -0700280}
281
Elliott Hughes75770752011-08-24 17:52:38 -0700282#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 -0700283 jsize size = 4; \
284 /* Allocate an array and check it has the right type and length. */ \
285 scalar_type ## Array a = env_->new_fn(size); \
286 EXPECT_TRUE(a != NULL); \
287 EXPECT_TRUE(env_->IsInstanceOf(a, env_->FindClass(expected_class_descriptor))); \
288 EXPECT_EQ(size, env_->GetArrayLength(a)); \
289 /* AIOOBE for negative start offset. */ \
290 env_->get_region_fn(a, -1, 1, NULL); \
291 EXPECT_EXCEPTION(aioobe_); \
292 env_->set_region_fn(a, -1, 1, NULL); \
293 EXPECT_EXCEPTION(aioobe_); \
294 /* AIOOBE for negative length. */ \
295 env_->get_region_fn(a, 0, -1, NULL); \
296 EXPECT_EXCEPTION(aioobe_); \
297 env_->set_region_fn(a, 0, -1, NULL); \
298 EXPECT_EXCEPTION(aioobe_); \
299 /* AIOOBE for buffer overrun. */ \
300 env_->get_region_fn(a, size - 1, size, NULL); \
301 EXPECT_EXCEPTION(aioobe_); \
302 env_->set_region_fn(a, size - 1, size, NULL); \
303 EXPECT_EXCEPTION(aioobe_); \
304 /* Prepare a couple of buffers. */ \
305 scalar_type src_buf[size]; \
306 scalar_type dst_buf[size]; \
307 for (jsize i = 0; i < size; ++i) { src_buf[i] = scalar_type(i); } \
308 for (jsize i = 0; i < size; ++i) { dst_buf[i] = scalar_type(-1); } \
309 /* Copy all of src_buf onto the heap. */ \
310 env_->set_region_fn(a, 0, size, src_buf); \
311 /* Copy back only part. */ \
312 env_->get_region_fn(a, 1, size - 2, &dst_buf[1]); \
313 EXPECT_FALSE(memcmp(src_buf, dst_buf, sizeof(src_buf)) == 0) << "short copy equal"; \
314 /* Copy the missing pieces. */ \
315 env_->get_region_fn(a, 0, 1, dst_buf); \
316 env_->get_region_fn(a, size - 1, 1, &dst_buf[size - 1]); \
317 EXPECT_TRUE(memcmp(src_buf, dst_buf, sizeof(src_buf)) == 0) << "fixed copy not equal"; \
318 /* Copy back the whole array. */ \
319 env_->get_region_fn(a, 0, size, dst_buf); \
Elliott Hughes75770752011-08-24 17:52:38 -0700320 EXPECT_TRUE(memcmp(src_buf, dst_buf, sizeof(src_buf)) == 0) << "full copy not equal"; \
321 /* GetPrimitiveArrayCritical */ \
322 void* v = env_->GetPrimitiveArrayCritical(a, NULL); \
323 EXPECT_TRUE(memcmp(src_buf, v, sizeof(src_buf)) == 0) << "GetPrimitiveArrayCritical not equal"; \
324 env_->ReleasePrimitiveArrayCritical(a, v, 0); \
325 /* GetXArrayElements */ \
326 scalar_type* xs = env_->get_elements_fn(a, NULL); \
327 EXPECT_TRUE(memcmp(src_buf, xs, sizeof(src_buf)) == 0) << # get_elements_fn " not equal"; \
328 env_->release_elements_fn(a, xs, 0); \
329 EXPECT_EQ(reinterpret_cast<uintptr_t>(v), reinterpret_cast<uintptr_t>(xs))
Elliott Hughesbd935992011-08-22 11:59:34 -0700330
Elliott Hughes814e4032011-08-23 12:07:56 -0700331TEST_F(JniInternalTest, BooleanArrays) {
Elliott Hughes75770752011-08-24 17:52:38 -0700332 EXPECT_PRIMITIVE_ARRAY(NewBooleanArray, GetBooleanArrayRegion, SetBooleanArrayRegion, GetBooleanArrayElements, ReleaseBooleanArrayElements, jboolean, "[Z");
Elliott Hughes814e4032011-08-23 12:07:56 -0700333}
334TEST_F(JniInternalTest, ByteArrays) {
Elliott Hughes75770752011-08-24 17:52:38 -0700335 EXPECT_PRIMITIVE_ARRAY(NewByteArray, GetByteArrayRegion, SetByteArrayRegion, GetByteArrayElements, ReleaseByteArrayElements, jbyte, "[B");
Elliott Hughes814e4032011-08-23 12:07:56 -0700336}
337TEST_F(JniInternalTest, CharArrays) {
Elliott Hughes75770752011-08-24 17:52:38 -0700338 EXPECT_PRIMITIVE_ARRAY(NewCharArray, GetCharArrayRegion, SetCharArrayRegion, GetCharArrayElements, ReleaseCharArrayElements, jchar, "[C");
Elliott Hughes814e4032011-08-23 12:07:56 -0700339}
340TEST_F(JniInternalTest, DoubleArrays) {
Elliott Hughes75770752011-08-24 17:52:38 -0700341 EXPECT_PRIMITIVE_ARRAY(NewDoubleArray, GetDoubleArrayRegion, SetDoubleArrayRegion, GetDoubleArrayElements, ReleaseDoubleArrayElements, jdouble, "[D");
Elliott Hughes814e4032011-08-23 12:07:56 -0700342}
343TEST_F(JniInternalTest, FloatArrays) {
Elliott Hughes75770752011-08-24 17:52:38 -0700344 EXPECT_PRIMITIVE_ARRAY(NewFloatArray, GetFloatArrayRegion, SetFloatArrayRegion, GetFloatArrayElements, ReleaseFloatArrayElements, jfloat, "[F");
Elliott Hughes814e4032011-08-23 12:07:56 -0700345}
346TEST_F(JniInternalTest, IntArrays) {
Elliott Hughes75770752011-08-24 17:52:38 -0700347 EXPECT_PRIMITIVE_ARRAY(NewIntArray, GetIntArrayRegion, SetIntArrayRegion, GetIntArrayElements, ReleaseIntArrayElements, jint, "[I");
Elliott Hughes814e4032011-08-23 12:07:56 -0700348}
349TEST_F(JniInternalTest, LongArrays) {
Elliott Hughes75770752011-08-24 17:52:38 -0700350 EXPECT_PRIMITIVE_ARRAY(NewLongArray, GetLongArrayRegion, SetLongArrayRegion, GetLongArrayElements, ReleaseLongArrayElements, jlong, "[J");
Elliott Hughes814e4032011-08-23 12:07:56 -0700351}
352TEST_F(JniInternalTest, ShortArrays) {
Elliott Hughes75770752011-08-24 17:52:38 -0700353 EXPECT_PRIMITIVE_ARRAY(NewShortArray, GetShortArrayRegion, SetShortArrayRegion, GetShortArrayElements, ReleaseShortArrayElements, jshort, "[S");
Elliott Hughesd8ddfd52011-08-15 14:32:53 -0700354}
355
Elliott Hughesf2682d52011-08-15 16:37:04 -0700356TEST_F(JniInternalTest, NewObjectArray) {
357 // TODO: death tests for negative array sizes.
358
Elliott Hughesf2682d52011-08-15 16:37:04 -0700359 // TODO: check non-NULL initial elements.
360
Elliott Hughesbd935992011-08-22 11:59:34 -0700361 jclass element_class = env_->FindClass("java/lang/String");
362 ASSERT_TRUE(element_class != NULL);
363 jclass array_class = env_->FindClass("[Ljava/lang/String;");
364 ASSERT_TRUE(array_class != NULL);
Elliott Hughesf2682d52011-08-15 16:37:04 -0700365
Elliott Hughesbd935992011-08-22 11:59:34 -0700366 jobjectArray a;
Elliott Hughesf2682d52011-08-15 16:37:04 -0700367
Elliott Hughesbd935992011-08-22 11:59:34 -0700368 a = env_->NewObjectArray(0, element_class, NULL);
369 EXPECT_TRUE(a != NULL);
370 EXPECT_TRUE(env_->IsInstanceOf(a, array_class));
371 EXPECT_EQ(0, env_->GetArrayLength(a));
372
373 a = env_->NewObjectArray(1, element_class, NULL);
374 EXPECT_TRUE(a != NULL);
375 EXPECT_TRUE(env_->IsInstanceOf(a, array_class));
376 EXPECT_EQ(1, env_->GetArrayLength(a));
Elliott Hughes75770752011-08-24 17:52:38 -0700377 EXPECT_TRUE(env_->IsSameObject(env_->GetObjectArrayElement(a, 0), NULL));
378
379 jstring s = env_->NewStringUTF("poop");
380 a = env_->NewObjectArray(2, element_class, s);
381 EXPECT_TRUE(a != NULL);
382 EXPECT_TRUE(env_->IsInstanceOf(a, array_class));
383 EXPECT_EQ(2, env_->GetArrayLength(a));
384 EXPECT_TRUE(env_->IsSameObject(env_->GetObjectArrayElement(a, 0), s));
385 EXPECT_TRUE(env_->IsSameObject(env_->GetObjectArrayElement(a, 1), s));
Elliott Hughesbd935992011-08-22 11:59:34 -0700386}
387
388TEST_F(JniInternalTest, GetArrayLength) {
389 // Already tested in NewObjectArray/NewPrimitiveArray.
Elliott Hughes8a26c5c2011-08-15 18:35:43 -0700390}
391
Elliott Hughes37f7a402011-08-22 18:56:01 -0700392TEST_F(JniInternalTest, GetObjectClass) {
393 jclass string_class = env_->FindClass("java/lang/String");
394 ASSERT_TRUE(string_class != NULL);
395 jclass class_class = env_->FindClass("java/lang/Class");
396 ASSERT_TRUE(class_class != NULL);
397
398 jstring s = env_->NewStringUTF("poop");
399 jclass c = env_->GetObjectClass(s);
400 ASSERT_TRUE(env_->IsSameObject(string_class, c));
401
402 jclass c2 = env_->GetObjectClass(c);
403 ASSERT_TRUE(env_->IsSameObject(class_class, env_->GetObjectClass(c2)));
404}
405
Elliott Hughes885c3bd2011-08-22 16:59:20 -0700406TEST_F(JniInternalTest, GetSuperclass) {
407 jclass object_class = env_->FindClass("java/lang/Object");
408 ASSERT_TRUE(object_class != NULL);
409 jclass string_class = env_->FindClass("java/lang/String");
410 ASSERT_TRUE(string_class != NULL);
411 ASSERT_TRUE(env_->IsSameObject(object_class, env_->GetSuperclass(string_class)));
412 ASSERT_TRUE(env_->GetSuperclass(object_class) == NULL);
413}
414
Elliott Hughes37f7a402011-08-22 18:56:01 -0700415TEST_F(JniInternalTest, IsAssignableFrom) {
416 jclass object_class = env_->FindClass("java/lang/Object");
417 ASSERT_TRUE(object_class != NULL);
418 jclass string_class = env_->FindClass("java/lang/String");
419 ASSERT_TRUE(string_class != NULL);
420
421 ASSERT_TRUE(env_->IsAssignableFrom(object_class, string_class));
422 ASSERT_FALSE(env_->IsAssignableFrom(string_class, object_class));
423}
424
Elliott Hughesb465ab02011-08-24 11:21:21 -0700425TEST_F(JniInternalTest, GetObjectRefType) {
426 jclass local = env_->FindClass("java/lang/Object");
427 ASSERT_TRUE(local != NULL);
428 EXPECT_EQ(JNILocalRefType, env_->GetObjectRefType(local));
429
430 jobject global = env_->NewGlobalRef(local);
431 EXPECT_EQ(JNIGlobalRefType, env_->GetObjectRefType(global));
432
433 jweak weak_global = env_->NewWeakGlobalRef(local);
434 EXPECT_EQ(JNIWeakGlobalRefType, env_->GetObjectRefType(weak_global));
435
436 jobject invalid = reinterpret_cast<jobject>(this);
437 EXPECT_EQ(JNIInvalidRefType, env_->GetObjectRefType(invalid));
438
439 // TODO: invoke a native method and test that its arguments are considered local references.
440}
441
Elliott Hughes8a26c5c2011-08-15 18:35:43 -0700442TEST_F(JniInternalTest, NewStringUTF) {
443 EXPECT_TRUE(env_->NewStringUTF(NULL) == NULL);
Elliott Hughes814e4032011-08-23 12:07:56 -0700444 jstring s;
445
446 s = env_->NewStringUTF("");
447 EXPECT_TRUE(s != NULL);
448 EXPECT_EQ(0, env_->GetStringLength(s));
449 EXPECT_EQ(0, env_->GetStringUTFLength(s));
450 s = env_->NewStringUTF("hello");
451 EXPECT_TRUE(s != NULL);
452 EXPECT_EQ(5, env_->GetStringLength(s));
453 EXPECT_EQ(5, env_->GetStringUTFLength(s));
454
Elliott Hughes8a26c5c2011-08-15 18:35:43 -0700455 // TODO: check some non-ASCII strings.
Elliott Hughesf2682d52011-08-15 16:37:04 -0700456}
457
Elliott Hughes814e4032011-08-23 12:07:56 -0700458TEST_F(JniInternalTest, NewString) {
459 EXPECT_TRUE(env_->NewString(NULL, 0) == NULL);
460
461 jchar chars[] = { 'h', 'i' };
462 jstring s;
463 s = env_->NewString(chars, 0);
464 EXPECT_TRUE(s != NULL);
465 EXPECT_EQ(0, env_->GetStringLength(s));
466 EXPECT_EQ(0, env_->GetStringUTFLength(s));
467 s = env_->NewString(chars, 2);
468 EXPECT_TRUE(s != NULL);
469 EXPECT_EQ(2, env_->GetStringLength(s));
470 EXPECT_EQ(2, env_->GetStringUTFLength(s));
471
472 // TODO: check some non-ASCII strings.
473}
474
Elliott Hughesb465ab02011-08-24 11:21:21 -0700475TEST_F(JniInternalTest, GetStringLength_GetStringUTFLength) {
476 // Already tested in the NewString/NewStringUTF tests.
477}
478
479TEST_F(JniInternalTest, GetStringRegion_GetStringUTFRegion) {
480 jstring s = env_->NewStringUTF("hello");
481 ASSERT_TRUE(s != NULL);
482
483 env_->GetStringRegion(s, -1, 0, NULL);
484 EXPECT_EXCEPTION(sioobe_);
485 env_->GetStringRegion(s, 0, -1, NULL);
486 EXPECT_EXCEPTION(sioobe_);
487 env_->GetStringRegion(s, 0, 10, NULL);
488 EXPECT_EXCEPTION(sioobe_);
489 env_->GetStringRegion(s, 10, 1, NULL);
490 EXPECT_EXCEPTION(sioobe_);
491
492 jchar chars[4] = { 'x', 'x', 'x', 'x' };
493 env_->GetStringRegion(s, 1, 2, &chars[1]);
494 EXPECT_EQ('x', chars[0]);
495 EXPECT_EQ('e', chars[1]);
496 EXPECT_EQ('l', chars[2]);
497 EXPECT_EQ('x', chars[3]);
498
499 env_->GetStringUTFRegion(s, -1, 0, NULL);
500 EXPECT_EXCEPTION(sioobe_);
501 env_->GetStringUTFRegion(s, 0, -1, NULL);
502 EXPECT_EXCEPTION(sioobe_);
503 env_->GetStringUTFRegion(s, 0, 10, NULL);
504 EXPECT_EXCEPTION(sioobe_);
505 env_->GetStringUTFRegion(s, 10, 1, NULL);
506 EXPECT_EXCEPTION(sioobe_);
507
508 char bytes[4] = { 'x', 'x', 'x', 'x' };
509 env_->GetStringUTFRegion(s, 1, 2, &bytes[1]);
510 EXPECT_EQ('x', bytes[0]);
511 EXPECT_EQ('e', bytes[1]);
512 EXPECT_EQ('l', bytes[2]);
513 EXPECT_EQ('x', bytes[3]);
514}
515
Elliott Hughes75770752011-08-24 17:52:38 -0700516TEST_F(JniInternalTest, GetStringUTFChars_ReleaseStringUTFChars) {
517 EXPECT_TRUE(env_->GetStringUTFChars(NULL, NULL) == NULL);
518
519 jstring s = env_->NewStringUTF("hello");
520 ASSERT_TRUE(s != NULL);
521
522 const char* utf = env_->GetStringUTFChars(s, NULL);
523 EXPECT_STREQ("hello", utf);
524 env_->ReleaseStringUTFChars(s, utf);
525
526 jboolean is_copy = JNI_FALSE;
527 utf = env_->GetStringUTFChars(s, &is_copy);
528 EXPECT_EQ(JNI_TRUE, is_copy);
529 EXPECT_STREQ("hello", utf);
530 env_->ReleaseStringUTFChars(s, utf);
531}
532
533TEST_F(JniInternalTest, GetStringChars_ReleaseStringChars) {
534 jstring s = env_->NewStringUTF("hello");
535 ASSERT_TRUE(s != NULL);
536
537 jchar expected[] = { 'h', 'e', 'l', 'l', 'o' };
538 const jchar* chars = env_->GetStringChars(s, NULL);
539 EXPECT_EQ(expected[0], chars[0]);
540 EXPECT_EQ(expected[1], chars[1]);
541 EXPECT_EQ(expected[2], chars[2]);
542 EXPECT_EQ(expected[3], chars[3]);
543 EXPECT_EQ(expected[4], chars[4]);
544 env_->ReleaseStringChars(s, chars);
545
546 jboolean is_copy = JNI_FALSE;
547 chars = env_->GetStringChars(s, &is_copy);
548 EXPECT_EQ(JNI_FALSE, is_copy);
549 EXPECT_EQ(expected[0], chars[0]);
550 EXPECT_EQ(expected[1], chars[1]);
551 EXPECT_EQ(expected[2], chars[2]);
552 EXPECT_EQ(expected[3], chars[3]);
553 EXPECT_EQ(expected[4], chars[4]);
554 env_->ReleaseStringChars(s, chars);
555}
556
557TEST_F(JniInternalTest, GetStringCritical_ReleaseStringCritical) {
558 jstring s = env_->NewStringUTF("hello");
559 ASSERT_TRUE(s != NULL);
560
561 jchar expected[] = { 'h', 'e', 'l', 'l', 'o' };
562 const jchar* chars = env_->GetStringCritical(s, NULL);
563 EXPECT_EQ(expected[0], chars[0]);
564 EXPECT_EQ(expected[1], chars[1]);
565 EXPECT_EQ(expected[2], chars[2]);
566 EXPECT_EQ(expected[3], chars[3]);
567 EXPECT_EQ(expected[4], chars[4]);
568 env_->ReleaseStringCritical(s, chars);
569
570 jboolean is_copy = JNI_FALSE;
571 chars = env_->GetStringCritical(s, &is_copy);
572 EXPECT_EQ(JNI_FALSE, is_copy);
573 EXPECT_EQ(expected[0], chars[0]);
574 EXPECT_EQ(expected[1], chars[1]);
575 EXPECT_EQ(expected[2], chars[2]);
576 EXPECT_EQ(expected[3], chars[3]);
577 EXPECT_EQ(expected[4], chars[4]);
578 env_->ReleaseStringCritical(s, chars);
579}
580
Elliott Hughes814e4032011-08-23 12:07:56 -0700581TEST_F(JniInternalTest, GetObjectArrayElement_SetObjectArrayElement) {
Elliott Hughes289da822011-08-16 10:11:20 -0700582 jclass c = env_->FindClass("[Ljava/lang/Object;");
583 ASSERT_TRUE(c != NULL);
584
585 jobjectArray array = env_->NewObjectArray(1, c, NULL);
586 EXPECT_TRUE(array != NULL);
Elliott Hughes814e4032011-08-23 12:07:56 -0700587 EXPECT_TRUE(env_->GetObjectArrayElement(array, 0) == NULL);
Elliott Hughes289da822011-08-16 10:11:20 -0700588 env_->SetObjectArrayElement(array, 0, c);
Elliott Hughes814e4032011-08-23 12:07:56 -0700589 EXPECT_TRUE(env_->IsSameObject(env_->GetObjectArrayElement(array, 0), c));
Elliott Hughesa5b897e2011-08-16 11:33:06 -0700590
591 // ArrayIndexOutOfBounds for negative index.
Elliott Hughesa5b897e2011-08-16 11:33:06 -0700592 env_->SetObjectArrayElement(array, -1, c);
Elliott Hughes814e4032011-08-23 12:07:56 -0700593 EXPECT_EXCEPTION(aioobe_);
Elliott Hughesa5b897e2011-08-16 11:33:06 -0700594
595 // ArrayIndexOutOfBounds for too-large index.
Elliott Hughesa5b897e2011-08-16 11:33:06 -0700596 env_->SetObjectArrayElement(array, 1, c);
Elliott Hughes814e4032011-08-23 12:07:56 -0700597 EXPECT_EXCEPTION(aioobe_);
Elliott Hughesa5b897e2011-08-16 11:33:06 -0700598
Elliott Hughes289da822011-08-16 10:11:20 -0700599 // TODO: check ArrayStoreException thrown for bad types.
600}
601
Elliott Hughes885c3bd2011-08-22 16:59:20 -0700602#define EXPECT_STATIC_PRIMITIVE_FIELD(type, field_name, sig, value1, value2) \
603 do { \
604 jfieldID fid = env_->GetStaticFieldID(c, field_name, sig); \
605 EXPECT_TRUE(fid != NULL); \
606 env_->SetStatic ## type ## Field(c, fid, value1); \
607 EXPECT_EQ(value1, env_->GetStatic ## type ## Field(c, fid)); \
608 env_->SetStatic ## type ## Field(c, fid, value2); \
609 EXPECT_EQ(value2, env_->GetStatic ## type ## Field(c, fid)); \
610 } while (false)
611
612#define EXPECT_PRIMITIVE_FIELD(instance, type, field_name, sig, value1, value2) \
613 do { \
614 jfieldID fid = env_->GetFieldID(c, field_name, sig); \
615 EXPECT_TRUE(fid != NULL); \
616 env_->Set ## type ## Field(instance, fid, value1); \
617 EXPECT_EQ(value1, env_->Get ## type ## Field(instance, fid)); \
618 env_->Set ## type ## Field(instance, fid, value2); \
619 EXPECT_EQ(value2, env_->Get ## type ## Field(instance, fid)); \
620 } while (false)
621
622
623TEST_F(JniInternalTest, GetPrimitiveField_SetPrimitiveField) {
624 scoped_ptr<DexFile> dex(OpenDexFileBase64(kAllFields, "kAllFields"));
625 PathClassLoader* class_loader = AllocPathClassLoader(dex.get());
626 Thread::Current()->SetClassLoaderOverride(class_loader);
627
628 jclass c = env_->FindClass("AllFields");
629 ASSERT_TRUE(c != NULL);
630 jobject o = env_->AllocObject(c);
631 ASSERT_TRUE(o != NULL);
632
633 EXPECT_STATIC_PRIMITIVE_FIELD(Boolean, "sZ", "Z", true, false);
634 EXPECT_STATIC_PRIMITIVE_FIELD(Byte, "sB", "B", 1, 2);
635 EXPECT_STATIC_PRIMITIVE_FIELD(Char, "sC", "C", 'a', 'b');
636 EXPECT_STATIC_PRIMITIVE_FIELD(Double, "sD", "D", 1.0, 2.0);
637 EXPECT_STATIC_PRIMITIVE_FIELD(Float, "sF", "F", 1.0, 2.0);
638 EXPECT_STATIC_PRIMITIVE_FIELD(Int, "sI", "I", 1, 2);
639 EXPECT_STATIC_PRIMITIVE_FIELD(Long, "sJ", "J", 1, 2);
640 EXPECT_STATIC_PRIMITIVE_FIELD(Short, "sS", "S", 1, 2);
641
642 EXPECT_PRIMITIVE_FIELD(o, Boolean, "iZ", "Z", true, false);
643 EXPECT_PRIMITIVE_FIELD(o, Byte, "iB", "B", 1, 2);
644 EXPECT_PRIMITIVE_FIELD(o, Char, "iC", "C", 'a', 'b');
645 EXPECT_PRIMITIVE_FIELD(o, Double, "iD", "D", 1.0, 2.0);
646 EXPECT_PRIMITIVE_FIELD(o, Float, "iF", "F", 1.0, 2.0);
647 EXPECT_PRIMITIVE_FIELD(o, Int, "iI", "I", 1, 2);
648 EXPECT_PRIMITIVE_FIELD(o, Long, "iJ", "J", 1, 2);
649 EXPECT_PRIMITIVE_FIELD(o, Short, "iS", "S", 1, 2);
650}
651
652TEST_F(JniInternalTest, GetObjectField_SetObjectField) {
653 scoped_ptr<DexFile> dex(OpenDexFileBase64(kAllFields, "kAllFields"));
654 PathClassLoader* class_loader = AllocPathClassLoader(dex.get());
655 Thread::Current()->SetClassLoaderOverride(class_loader);
656
657 jclass c = env_->FindClass("AllFields");
658 ASSERT_TRUE(c != NULL);
659 jobject o = env_->AllocObject(c);
660 ASSERT_TRUE(o != NULL);
661
662 jstring s1 = env_->NewStringUTF("hello");
663 ASSERT_TRUE(s1 != NULL);
664 jstring s2 = env_->NewStringUTF("world");
665 ASSERT_TRUE(s2 != NULL);
666
667 jfieldID s_fid = env_->GetStaticFieldID(c, "sObject", "Ljava/lang/Object;");
668 ASSERT_TRUE(s_fid != NULL);
669 jfieldID i_fid = env_->GetFieldID(c, "iObject", "Ljava/lang/Object;");
670 ASSERT_TRUE(i_fid != NULL);
671
672 env_->SetStaticObjectField(c, s_fid, s1);
673 ASSERT_TRUE(env_->IsSameObject(s1, env_->GetStaticObjectField(c, s_fid)));
674 env_->SetStaticObjectField(c, s_fid, s2);
675 ASSERT_TRUE(env_->IsSameObject(s2, env_->GetStaticObjectField(c, s_fid)));
676
677 env_->SetObjectField(o, i_fid, s1);
678 ASSERT_TRUE(env_->IsSameObject(s1, env_->GetObjectField(o, i_fid)));
679 env_->SetObjectField(o, i_fid, s2);
680 ASSERT_TRUE(env_->IsSameObject(s2, env_->GetObjectField(o, i_fid)));
681}
682
Elliott Hughes18c07532011-08-18 15:50:51 -0700683TEST_F(JniInternalTest, NewLocalRef_NULL) {
684 EXPECT_TRUE(env_->NewLocalRef(NULL) == NULL);
685}
686
687TEST_F(JniInternalTest, NewLocalRef) {
688 jstring s = env_->NewStringUTF("");
689 ASSERT_TRUE(s != NULL);
690 jobject o = env_->NewLocalRef(s);
691 EXPECT_TRUE(o != NULL);
692 EXPECT_TRUE(o != s);
693
694 // TODO: check that o is a local reference.
695}
696
697TEST_F(JniInternalTest, DeleteLocalRef_NULL) {
698 env_->DeleteLocalRef(NULL);
699}
700
701TEST_F(JniInternalTest, DeleteLocalRef) {
702 jstring s = env_->NewStringUTF("");
703 ASSERT_TRUE(s != NULL);
704 env_->DeleteLocalRef(s);
705
706 // Currently, deleting an already-deleted reference is just a warning.
707 env_->DeleteLocalRef(s);
708
709 s = env_->NewStringUTF("");
710 ASSERT_TRUE(s != NULL);
711 jobject o = env_->NewLocalRef(s);
712 ASSERT_TRUE(o != NULL);
713
714 env_->DeleteLocalRef(s);
715 env_->DeleteLocalRef(o);
716}
717
718TEST_F(JniInternalTest, NewGlobalRef_NULL) {
719 EXPECT_TRUE(env_->NewGlobalRef(NULL) == NULL);
720}
721
722TEST_F(JniInternalTest, NewGlobalRef) {
723 jstring s = env_->NewStringUTF("");
724 ASSERT_TRUE(s != NULL);
725 jobject o = env_->NewGlobalRef(s);
726 EXPECT_TRUE(o != NULL);
727 EXPECT_TRUE(o != s);
728
729 // TODO: check that o is a global reference.
730}
731
732TEST_F(JniInternalTest, DeleteGlobalRef_NULL) {
733 env_->DeleteGlobalRef(NULL);
734}
735
736TEST_F(JniInternalTest, DeleteGlobalRef) {
737 jstring s = env_->NewStringUTF("");
738 ASSERT_TRUE(s != NULL);
739
740 jobject o = env_->NewGlobalRef(s);
741 ASSERT_TRUE(o != NULL);
742 env_->DeleteGlobalRef(o);
743
744 // Currently, deleting an already-deleted reference is just a warning.
745 env_->DeleteGlobalRef(o);
746
747 jobject o1 = env_->NewGlobalRef(s);
748 ASSERT_TRUE(o1 != NULL);
749 jobject o2 = env_->NewGlobalRef(s);
750 ASSERT_TRUE(o2 != NULL);
751
752 env_->DeleteGlobalRef(o1);
753 env_->DeleteGlobalRef(o2);
754}
755
756TEST_F(JniInternalTest, NewWeakGlobalRef_NULL) {
757 EXPECT_TRUE(env_->NewWeakGlobalRef(NULL) == NULL);
758}
759
760TEST_F(JniInternalTest, NewWeakGlobalRef) {
761 jstring s = env_->NewStringUTF("");
762 ASSERT_TRUE(s != NULL);
763 jobject o = env_->NewWeakGlobalRef(s);
764 EXPECT_TRUE(o != NULL);
765 EXPECT_TRUE(o != s);
766
767 // TODO: check that o is a weak global reference.
768}
769
770TEST_F(JniInternalTest, DeleteWeakGlobalRef_NULL) {
771 env_->DeleteWeakGlobalRef(NULL);
772}
773
774TEST_F(JniInternalTest, DeleteWeakGlobalRef) {
775 jstring s = env_->NewStringUTF("");
776 ASSERT_TRUE(s != NULL);
777
778 jobject o = env_->NewWeakGlobalRef(s);
779 ASSERT_TRUE(o != NULL);
780 env_->DeleteWeakGlobalRef(o);
781
782 // Currently, deleting an already-deleted reference is just a warning.
783 env_->DeleteWeakGlobalRef(o);
784
785 jobject o1 = env_->NewWeakGlobalRef(s);
786 ASSERT_TRUE(o1 != NULL);
787 jobject o2 = env_->NewWeakGlobalRef(s);
788 ASSERT_TRUE(o2 != NULL);
789
790 env_->DeleteWeakGlobalRef(o1);
791 env_->DeleteWeakGlobalRef(o2);
792}
793
Carl Shapiro9b9ba282011-08-14 15:30:39 -0700794bool EnsureInvokeStub(Method* method);
795
Carl Shapiro9b9ba282011-08-14 15:30:39 -0700796Method::InvokeStub* AllocateStub(Method* method,
797 byte* code,
798 size_t length) {
799 CHECK(method->GetInvokeStub() == NULL);
800 EnsureInvokeStub(method);
801 Method::InvokeStub* stub = method->GetInvokeStub();
802 CHECK(stub != NULL);
buzbeec143c552011-08-20 17:38:58 -0700803 method->SetCode(code, length, kThumb2);
Carl Shapiro9b9ba282011-08-14 15:30:39 -0700804 return stub;
805}
806
Carl Shapiro9b9ba282011-08-14 15:30:39 -0700807#if defined(__arm__)
808TEST_F(JniInternalTest, StaticMainMethod) {
Brian Carlstroma663ea52011-08-19 23:33:41 -0700809 scoped_ptr<DexFile> dex(OpenDexFileBase64(kMainDex, "kMainDex"));
Carl Shapiro9b9ba282011-08-14 15:30:39 -0700810
811 PathClassLoader* class_loader = AllocPathClassLoader(dex.get());
812 ASSERT_TRUE(class_loader != NULL);
813
814 Class* klass = class_linker_->FindClass("LMain;", class_loader);
815 ASSERT_TRUE(klass != NULL);
816
817 Method* method = klass->FindDirectMethod("main", "([Ljava/lang/String;)V");
818 ASSERT_TRUE(method != NULL);
819
820 byte main_LV_code[] = {
821 0x2d, 0xe9, 0x00, 0x40, 0x83, 0xb0, 0xcd, 0xf8, 0x00, 0x00,
822 0xcd, 0xf8, 0x14, 0x10, 0x03, 0xb0, 0xbd, 0xe8, 0x00, 0x80,
823 };
824
825 Method::InvokeStub* stub = AllocateStub(method,
826 main_LV_code,
827 sizeof(main_LV_code));
828
829 Object* arg = NULL;
830
831 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(&arg), NULL);
Carl Shapiro9b9ba282011-08-14 15:30:39 -0700832}
833
834TEST_F(JniInternalTest, StaticNopMethod) {
Brian Carlstroma663ea52011-08-19 23:33:41 -0700835 scoped_ptr<DexFile> dex(OpenDexFileBase64(kStaticLeafMethodsDex, "kStaticLeafMethodsDex"));
Carl Shapiro9b9ba282011-08-14 15:30:39 -0700836
837 PathClassLoader* class_loader = AllocPathClassLoader(dex.get());
838 ASSERT_TRUE(class_loader != NULL);
839
840 Class* klass = class_linker_->FindClass("LStaticLeafMethods;", class_loader);
841 ASSERT_TRUE(klass != NULL);
842
843 Method* method = klass->FindDirectMethod("nop", "()V");
844 ASSERT_TRUE(method != NULL);
845
846 byte nop_V_code[] = {
847 0x2d, 0xe9, 0x00, 0x40, 0x83, 0xb0, 0xcd, 0xf8,
848 0x00, 0x00, 0x03, 0xb0, 0xbd, 0xe8, 0x00, 0x80,
849 };
850
851 Method::InvokeStub* stub = AllocateStub(method,
852 nop_V_code,
853 sizeof(nop_V_code));
854 ASSERT_TRUE(stub);
855
856 (*stub)(method, NULL, NULL, NULL, NULL);
Carl Shapiro9b9ba282011-08-14 15:30:39 -0700857}
858
859TEST_F(JniInternalTest, StaticIdentityByteMethod) {
Brian Carlstroma663ea52011-08-19 23:33:41 -0700860 scoped_ptr<DexFile> dex(OpenDexFileBase64(kStaticLeafMethodsDex, "kStaticLeafMethodsDex"));
Carl Shapiro9b9ba282011-08-14 15:30:39 -0700861
862 PathClassLoader* class_loader = AllocPathClassLoader(dex.get());
863 ASSERT_TRUE(class_loader != NULL);
864
865 Class* klass = class_linker_->FindClass("LStaticLeafMethods;", class_loader);
866 ASSERT_TRUE(klass != NULL);
867
868 Method* method = klass->FindDirectMethod("identity", "(B)B");
869 ASSERT_TRUE(method != NULL);
870
871 byte identity_BB_code[] = {
872 0x2d, 0xe9, 0x00, 0x40, 0x83, 0xb0, 0xcd, 0xf8,
873 0x00, 0x00, 0xcd, 0xf8, 0x14, 0x10, 0x05, 0x98,
874 0x03, 0xb0, 0xbd, 0xe8, 0x00, 0x80, 0x00, 0x00,
875 };
876
877 Method::InvokeStub* stub = AllocateStub(method,
878 identity_BB_code,
879 sizeof(identity_BB_code));
880
881 int arg;
882 JValue result;
883
884 arg = 0;
885 result.b = -1;
886 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(&arg), &result);
887 EXPECT_EQ(0, result.b);
888
889 arg = -1;
890 result.b = 0;
891 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(&arg), &result);
892 EXPECT_EQ(-1, result.b);
893
894 arg = SCHAR_MAX;
895 result.b = 0;
896 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(&arg), &result);
897 EXPECT_EQ(SCHAR_MAX, result.b);
898
899 arg = SCHAR_MIN;
900 result.b = 0;
901 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(&arg), &result);
902 EXPECT_EQ(SCHAR_MIN, result.b);
Carl Shapiro9b9ba282011-08-14 15:30:39 -0700903}
904
905TEST_F(JniInternalTest, StaticIdentityIntMethod) {
Brian Carlstroma663ea52011-08-19 23:33:41 -0700906 scoped_ptr<DexFile> dex(OpenDexFileBase64(kStaticLeafMethodsDex, "kStaticLeafMethodsDex"));
Carl Shapiro9b9ba282011-08-14 15:30:39 -0700907
908 PathClassLoader* class_loader = AllocPathClassLoader(dex.get());
909 ASSERT_TRUE(class_loader != NULL);
910
911 Class* klass = class_linker_->FindClass("LStaticLeafMethods;", class_loader);
912 ASSERT_TRUE(klass != NULL);
913
914 Method* method = klass->FindDirectMethod("identity", "(I)I");
915 ASSERT_TRUE(method != NULL);
916
917 byte identity_II_code[] = {
918 0x2d, 0xe9, 0x00, 0x40, 0x83, 0xb0, 0xcd, 0xf8,
919 0x00, 0x00, 0xcd, 0xf8, 0x14, 0x10, 0x05, 0x98,
920 0x03, 0xb0, 0xbd, 0xe8, 0x00, 0x80, 0x00, 0x00,
921 };
922
923 Method::InvokeStub* stub = AllocateStub(method,
924 identity_II_code,
925 sizeof(identity_II_code));
926
927 int arg;
928 JValue result;
929
930 arg = 0;
931 result.i = -1;
932 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(&arg), &result);
933 EXPECT_EQ(0, result.i);
934
935 arg = -1;
936 result.i = 0;
937 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(&arg), &result);
938 EXPECT_EQ(-1, result.i);
939
940 arg = INT_MAX;
941 result.i = 0;
942 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(&arg), &result);
943 EXPECT_EQ(INT_MAX, result.i);
944
945 arg = INT_MIN;
946 result.i = 0;
947 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(&arg), &result);
948 EXPECT_EQ(INT_MIN, result.i);
Carl Shapiro9b9ba282011-08-14 15:30:39 -0700949}
950
951TEST_F(JniInternalTest, StaticIdentityDoubleMethod) {
Brian Carlstroma663ea52011-08-19 23:33:41 -0700952 scoped_ptr<DexFile> dex(OpenDexFileBase64(kStaticLeafMethodsDex, "kStaticLeafMethodsDex"));
Carl Shapiro9b9ba282011-08-14 15:30:39 -0700953
954 PathClassLoader* class_loader = AllocPathClassLoader(dex.get());
955 ASSERT_TRUE(class_loader != NULL);
956
957 Class* klass = class_linker_->FindClass("LStaticLeafMethods;", class_loader);
958 ASSERT_TRUE(klass != NULL);
959
960 Method* method = klass->FindDirectMethod("identity", "(D)D");
961 ASSERT_TRUE(method != NULL);
962
963 byte identity_DD_code[] = {
964 0x2d, 0xe9, 0x00, 0x40, 0x83, 0xb0, 0xcd, 0xf8,
965 0x00, 0x00, 0xcd, 0xf8, 0x14, 0x10, 0xcd, 0xf8,
966 0x18, 0x20, 0x05, 0x98, 0x06, 0x99, 0x03, 0xb0,
967 0xbd, 0xe8, 0x00, 0x80,
968 };
969
970 Method::InvokeStub* stub = AllocateStub(method,
971 identity_DD_code,
972 sizeof(identity_DD_code));
973
974 double arg;
975 JValue result;
976
977 arg = 0.0;
978 result.d = -1.0;
979 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(&arg), &result);
980 EXPECT_EQ(0.0, result.d);
981
982 arg = -1.0;
983 result.d = 0.0;
984 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(&arg), &result);
985 EXPECT_EQ(-1.0, result.d);
986
987 arg = DBL_MAX;
988 result.d = 0.0;
989 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(&arg), &result);
990 EXPECT_EQ(DBL_MAX, result.d);
991
992 arg = DBL_MIN;
993 result.d = 0.0;
994 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(&arg), &result);
995 EXPECT_EQ(DBL_MIN, result.d);
Carl Shapiro9b9ba282011-08-14 15:30:39 -0700996}
997
998TEST_F(JniInternalTest, StaticSumIntIntMethod) {
Brian Carlstroma663ea52011-08-19 23:33:41 -0700999 scoped_ptr<DexFile> dex(OpenDexFileBase64(kStaticLeafMethodsDex, "kStaticLeafMethodsDex"));
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001000
1001 PathClassLoader* class_loader = AllocPathClassLoader(dex.get());
1002 ASSERT_TRUE(class_loader != NULL);
1003
1004 Class* klass = class_linker_->FindClass("LStaticLeafMethods;", class_loader);
1005 ASSERT_TRUE(klass != NULL);
1006
1007 Method* method = klass->FindDirectMethod("sum", "(II)I");
1008 ASSERT_TRUE(method != NULL);
1009
1010 byte sum_III_code[] = {
1011 0x2d, 0xe9, 0x00, 0x40, 0x83, 0xb0, 0xcd, 0xf8,
1012 0x00, 0x00, 0xcd, 0xf8, 0x14, 0x10, 0xcd, 0xf8,
1013 0x18, 0x20, 0x05, 0x98, 0x06, 0x99, 0x42, 0x18,
1014 0xcd, 0xf8, 0x04, 0x20, 0x01, 0x98, 0x03, 0xb0,
1015 0xbd, 0xe8, 0x00, 0x80,
1016 };
1017
1018 Method::InvokeStub* stub = AllocateStub(method,
1019 sum_III_code,
1020 sizeof(sum_III_code));
1021
1022 int args[2];
1023 JValue result;
1024
1025 args[0] = 0;
1026 args[1] = 0;
1027 result.i = -1;
1028 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
1029 EXPECT_EQ(0, result.i);
1030
1031 args[0] = 1;
1032 args[1] = 2;
1033 result.i = 0;
1034 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
1035 EXPECT_EQ(3, result.i);
1036
1037 args[0] = -2;
1038 args[1] = 5;
1039 result.i = 0;
1040 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
1041 EXPECT_EQ(3, result.i);
1042
1043 args[0] = INT_MAX;
1044 args[1] = INT_MIN;
1045 result.i = 1234;
1046 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
1047 EXPECT_EQ(-1, result.i);
1048
1049 args[0] = INT_MAX;
1050 args[1] = INT_MAX;
1051 result.i = INT_MIN;
1052 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
1053 EXPECT_EQ(-2, result.i);
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001054}
1055
1056TEST_F(JniInternalTest, StaticSumIntIntIntMethod) {
Brian Carlstroma663ea52011-08-19 23:33:41 -07001057 scoped_ptr<DexFile> dex(OpenDexFileBase64(kStaticLeafMethodsDex, "kStaticLeafMethodsDex"));
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001058
1059 PathClassLoader* class_loader = AllocPathClassLoader(dex.get());
1060 ASSERT_TRUE(class_loader != NULL);
1061
1062 Class* klass = class_linker_->FindClass("LStaticLeafMethods;", class_loader);
1063 ASSERT_TRUE(klass != NULL);
1064
1065 Method* method = klass->FindDirectMethod("sum", "(III)I");
1066 ASSERT_TRUE(method != NULL);
1067
1068 byte sum_IIII_code[] = {
1069 0x2d, 0xe9, 0x00, 0x40, 0x83, 0xb0, 0xcd, 0xf8,
1070 0x00, 0x00, 0xcd, 0xf8, 0x14, 0x10, 0xcd, 0xf8,
1071 0x18, 0x20, 0xcd, 0xf8, 0x1c, 0x30, 0x05, 0x98,
1072 0x06, 0x99, 0x42, 0x18, 0xcd, 0xf8, 0x04, 0x20,
1073 0x01, 0x9b, 0xdd, 0xf8, 0x1c, 0xc0, 0x13, 0xeb,
1074 0x0c, 0x03, 0xcd, 0xf8, 0x04, 0x30, 0x01, 0x98,
1075 0x03, 0xb0, 0xbd, 0xe8, 0x00, 0x80, 0x00, 0x00,
1076 };
1077
1078 Method::InvokeStub* stub = AllocateStub(method,
1079 sum_IIII_code,
1080 sizeof(sum_IIII_code));
1081
1082 int args[3];
1083 JValue result;
1084
1085 args[0] = 0;
1086 args[1] = 0;
1087 args[2] = 0;
1088 result.i = -1;
1089 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
1090 EXPECT_EQ(0, result.i);
1091
1092 args[0] = 1;
1093 args[1] = 2;
1094 args[2] = 3;
1095 result.i = 0;
1096 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
1097 EXPECT_EQ(6, result.i);
1098
1099 args[0] = -1;
1100 args[1] = 2;
1101 args[2] = -3;
1102 result.i = 0;
1103 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
1104 EXPECT_EQ(-2, result.i);
1105
1106 args[0] = INT_MAX;
1107 args[1] = INT_MIN;
1108 args[2] = INT_MAX;
1109 result.i = 1234;
1110 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
1111 EXPECT_EQ(2147483646, result.i);
1112
1113 args[0] = INT_MAX;
1114 args[1] = INT_MAX;
1115 args[2] = INT_MAX;
1116 result.i = INT_MIN;
1117 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
1118 EXPECT_EQ(2147483645, result.i);
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001119}
1120
1121TEST_F(JniInternalTest, StaticSumIntIntIntIntMethod) {
Brian Carlstroma663ea52011-08-19 23:33:41 -07001122 scoped_ptr<DexFile> dex(OpenDexFileBase64(kStaticLeafMethodsDex, "kStaticLeafMethodsDex"));
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001123
1124 PathClassLoader* class_loader = AllocPathClassLoader(dex.get());
1125 ASSERT_TRUE(class_loader != NULL);
1126
1127 Class* klass = class_linker_->FindClass("LStaticLeafMethods;", class_loader);
1128 ASSERT_TRUE(klass != NULL);
1129
1130 Method* method = klass->FindDirectMethod("sum", "(IIII)I");
1131 ASSERT_TRUE(method != NULL);
1132
1133 byte sum_IIIII_code[] = {
1134 0x2d, 0xe9, 0x00, 0x40, 0x83, 0xb0, 0xcd, 0xf8,
1135 0x00, 0x00, 0xcd, 0xf8, 0x14, 0x10, 0xcd, 0xf8,
1136 0x18, 0x20, 0xcd, 0xf8, 0x1c, 0x30, 0x05, 0x98,
1137 0x06, 0x99, 0x42, 0x18, 0xcd, 0xf8, 0x04, 0x20,
1138 0x01, 0x9b, 0xdd, 0xf8, 0x1c, 0xc0, 0x13, 0xeb,
1139 0x0c, 0x03, 0xcd, 0xf8, 0x04, 0x30, 0x01, 0x98,
1140 0x08, 0x99, 0x40, 0x18, 0xcd, 0xf8, 0x04, 0x00,
1141 0x01, 0x98, 0x03, 0xb0, 0xbd, 0xe8, 0x00, 0x80,
1142 };
1143
1144 Method::InvokeStub* stub = AllocateStub(method,
1145 sum_IIIII_code,
1146 sizeof(sum_IIIII_code));
1147
1148 int args[4];
1149 JValue result;
1150
1151 args[0] = 0;
1152 args[1] = 0;
1153 args[2] = 0;
1154 args[3] = 0;
1155 result.i = -1;
1156 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
1157 EXPECT_EQ(0, result.i);
1158
1159 args[0] = 1;
1160 args[1] = 2;
1161 args[2] = 3;
1162 args[3] = 4;
1163 result.i = 0;
1164 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
1165 EXPECT_EQ(10, result.i);
1166
1167 args[0] = -1;
1168 args[1] = 2;
1169 args[2] = -3;
1170 args[3] = 4;
1171 result.i = 0;
1172 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
1173 EXPECT_EQ(2, result.i);
1174
1175 args[0] = INT_MAX;
1176 args[1] = INT_MIN;
1177 args[2] = INT_MAX;
1178 args[3] = INT_MIN;
1179 result.i = 1234;
1180 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
1181 EXPECT_EQ(-2, result.i);
1182
1183 args[0] = INT_MAX;
1184 args[1] = INT_MAX;
1185 args[2] = INT_MAX;
1186 args[3] = INT_MAX;
1187 result.i = INT_MIN;
1188 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
1189 EXPECT_EQ(-4, result.i);
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001190}
1191
1192TEST_F(JniInternalTest, StaticSumIntIntIntIntIntMethod) {
Brian Carlstroma663ea52011-08-19 23:33:41 -07001193 scoped_ptr<DexFile> dex(OpenDexFileBase64(kStaticLeafMethodsDex, "kStaticLeafMethodsDex"));
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001194
1195 PathClassLoader* class_loader = AllocPathClassLoader(dex.get());
1196 ASSERT_TRUE(class_loader != NULL);
1197
1198 Class* klass = class_linker_->FindClass("LStaticLeafMethods;", class_loader);
1199 ASSERT_TRUE(klass != NULL);
1200
1201 Method* method = klass->FindDirectMethod("sum", "(IIIII)I");
1202 ASSERT_TRUE(method != NULL);
1203
1204 byte sum_IIIIII_code[] = {
1205 0x2d, 0xe9, 0x00, 0x40, 0x83, 0xb0, 0xcd, 0xf8,
1206 0x00, 0x00, 0xcd, 0xf8, 0x14, 0x10, 0xcd, 0xf8,
1207 0x18, 0x20, 0xcd, 0xf8, 0x1c, 0x30, 0x05, 0x98,
1208 0x06, 0x99, 0x42, 0x18, 0xcd, 0xf8, 0x04, 0x20,
1209 0x01, 0x9b, 0xdd, 0xf8, 0x1c, 0xc0, 0x13, 0xeb,
1210 0x0c, 0x03, 0xcd, 0xf8, 0x04, 0x30, 0x01, 0x98,
1211 0x08, 0x99, 0x40, 0x18, 0xcd, 0xf8, 0x04, 0x00,
1212 0x01, 0x9a, 0x09, 0x9b, 0xd2, 0x18, 0xcd, 0xf8,
1213 0x04, 0x20, 0x01, 0x98, 0x03, 0xb0, 0xbd, 0xe8,
1214 0x00, 0x80, 0x00, 0x00,
1215 };
1216
1217 Method::InvokeStub* stub = AllocateStub(method,
1218 sum_IIIIII_code,
1219 sizeof(sum_IIIIII_code));
1220
1221 int args[5];
1222 JValue result;
1223
1224 args[0] = 0;
1225 args[1] = 0;
1226 args[2] = 0;
1227 args[3] = 0;
1228 args[4] = 0;
1229 result.i = -1.0;
1230 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
1231 EXPECT_EQ(0, result.i);
1232
1233 args[0] = 1;
1234 args[1] = 2;
1235 args[2] = 3;
1236 args[3] = 4;
1237 args[4] = 5;
1238 result.i = 0;
1239 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
1240 EXPECT_EQ(15, result.i);
1241
1242 args[0] = -1;
1243 args[1] = 2;
1244 args[2] = -3;
1245 args[3] = 4;
1246 args[4] = -5;
1247 result.i = 0;
1248 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
1249 EXPECT_EQ(-3, result.i);
1250
1251 args[0] = INT_MAX;
1252 args[1] = INT_MIN;
1253 args[2] = INT_MAX;
1254 args[3] = INT_MIN;
1255 args[4] = INT_MAX;
1256 result.i = 1234;
1257 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
1258 EXPECT_EQ(2147483645, result.i);
1259
1260 args[0] = INT_MAX;
1261 args[1] = INT_MAX;
1262 args[2] = INT_MAX;
1263 args[3] = INT_MAX;
1264 args[4] = INT_MAX;
1265 result.i = INT_MIN;
1266 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
1267 EXPECT_EQ(2147483643, result.i);
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001268}
1269
1270TEST_F(JniInternalTest, StaticSumDoubleDoubleMethod) {
Brian Carlstroma663ea52011-08-19 23:33:41 -07001271 scoped_ptr<DexFile> dex(OpenDexFileBase64(kStaticLeafMethodsDex, "kStaticLeafMethodsDex"));
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001272
1273 PathClassLoader* class_loader = AllocPathClassLoader(dex.get());
1274 ASSERT_TRUE(class_loader != NULL);
1275
1276 Class* klass = class_linker_->FindClass("LStaticLeafMethods;", class_loader);
1277 ASSERT_TRUE(klass != NULL);
1278
1279 Method* method = klass->FindDirectMethod("sum", "(DD)D");
1280 ASSERT_TRUE(method != NULL);
1281
1282 byte sum_DDD_code[] = {
1283 0x2d, 0xe9, 0x00, 0x40, 0x87, 0xb0, 0xcd, 0xf8,
1284 0x00, 0x00, 0xcd, 0xf8, 0x24, 0x10, 0xcd, 0xf8,
1285 0x28, 0x20, 0xcd, 0xf8, 0x2c, 0x30, 0x9d, 0xed,
1286 0x09, 0x0b, 0x9d, 0xed, 0x0b, 0x1b, 0x30, 0xee,
1287 0x01, 0x2b, 0x8d, 0xed, 0x04, 0x2b, 0x04, 0x98,
1288 0x05, 0x99, 0x07, 0xb0, 0xbd, 0xe8, 0x00, 0x80,
1289 };
1290
1291 Method::InvokeStub* stub = AllocateStub(method,
1292 sum_DDD_code,
1293 sizeof(sum_DDD_code));
1294
1295 double args[2];
1296 JValue result;
1297
1298 args[0] = 0.0;
1299 args[1] = 0.0;
1300 result.d = -1.0;
1301 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
1302 EXPECT_EQ(0.0, result.d);
1303
1304 args[0] = 1.0;
1305 args[1] = 2.0;
1306 result.d = 0.0;
1307 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
1308 EXPECT_EQ(3.0, result.d);
1309
1310 args[0] = 1.0;
1311 args[1] = -2.0;
1312 result.d = 0.0;
1313 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
1314 EXPECT_EQ(-1.0, result.d);
1315
1316 args[0] = DBL_MAX;
1317 args[1] = DBL_MIN;
1318 result.d = 0.0;
1319 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
1320 EXPECT_EQ(1.7976931348623157e308, result.d);
1321
1322 args[0] = DBL_MAX;
1323 args[1] = DBL_MAX;
1324 result.d = 0.0;
1325 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
1326 EXPECT_EQ(INFINITY, result.d);
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001327}
1328
1329TEST_F(JniInternalTest, StaticSumDoubleDoubleDoubleMethod) {
Brian Carlstroma663ea52011-08-19 23:33:41 -07001330 scoped_ptr<DexFile> dex(OpenDexFileBase64(kStaticLeafMethodsDex, "kStaticLeafMethodsDex"));
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001331
1332 PathClassLoader* class_loader = AllocPathClassLoader(dex.get());
1333 ASSERT_TRUE(class_loader != NULL);
1334
1335 Class* klass = class_linker_->FindClass("LStaticLeafMethods;", class_loader);
1336 ASSERT_TRUE(klass != NULL);
1337
1338 Method* method = klass->FindDirectMethod("sum", "(DDD)D");
1339 ASSERT_TRUE(method != NULL);
1340
1341 byte sum_DDDD_code[] = {
1342 0x2d, 0xe9, 0x00, 0x40, 0x87, 0xb0, 0xcd, 0xf8,
1343 0x00, 0x00, 0xcd, 0xf8, 0x24, 0x10, 0xcd, 0xf8,
1344 0x28, 0x20, 0xcd, 0xf8, 0x2c, 0x30, 0x9d, 0xed,
1345 0x09, 0x0b, 0x9d, 0xed, 0x0b, 0x1b, 0x30, 0xee,
1346 0x01, 0x2b, 0x8d, 0xed, 0x04, 0x2b, 0x9d, 0xed,
1347 0x04, 0x3b, 0x9d, 0xed, 0x0d, 0x4b, 0x33, 0xee,
1348 0x04, 0x3b, 0x8d, 0xed, 0x04, 0x3b, 0x04, 0x98,
1349 0x05, 0x99, 0x07, 0xb0, 0xbd, 0xe8, 0x00, 0x80,
1350 };
1351
1352 Method::InvokeStub* stub = AllocateStub(method,
1353 sum_DDDD_code,
1354 sizeof(sum_DDDD_code));
1355
1356 double args[3];
1357 JValue result;
1358
1359 args[0] = 0.0;
1360 args[1] = 0.0;
1361 args[2] = 0.0;
1362 result.d = -1.0;
1363 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
1364 EXPECT_EQ(0.0, result.d);
1365
1366 args[0] = 1.0;
1367 args[1] = 2.0;
1368 args[2] = 3.0;
1369 result.d = 0.0;
1370 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
1371 EXPECT_EQ(6.0, result.d);
1372
1373 args[0] = 1.0;
1374 args[1] = -2.0;
1375 args[2] = 3.0;
1376 result.d = 0.0;
1377 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
1378 EXPECT_EQ(2.0, result.d);
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001379}
1380
1381TEST_F(JniInternalTest, StaticSumDoubleDoubleDoubleDoubleMethod) {
Brian Carlstroma663ea52011-08-19 23:33:41 -07001382 scoped_ptr<DexFile> dex(OpenDexFileBase64(kStaticLeafMethodsDex, "kStaticLeafMethodsDex"));
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001383
1384 PathClassLoader* class_loader = AllocPathClassLoader(dex.get());
1385 ASSERT_TRUE(class_loader != NULL);
1386
1387 Class* klass = class_linker_->FindClass("LStaticLeafMethods;", class_loader);
1388 ASSERT_TRUE(klass != NULL);
1389
1390 Method* method = klass->FindDirectMethod("sum", "(DDDD)D");
1391 ASSERT_TRUE(method != NULL);
1392
1393 byte sum_DDDDD_code[] = {
1394 0x2d, 0xe9, 0x00, 0x40, 0x87, 0xb0, 0xcd, 0xf8,
1395 0x00, 0x00, 0xcd, 0xf8, 0x24, 0x10, 0xcd, 0xf8,
1396 0x28, 0x20, 0xcd, 0xf8, 0x2c, 0x30, 0x9d, 0xed,
1397 0x09, 0x0b, 0x9d, 0xed, 0x0b, 0x1b, 0x30, 0xee,
1398 0x01, 0x2b, 0x8d, 0xed, 0x04, 0x2b, 0x9d, 0xed,
1399 0x04, 0x3b, 0x9d, 0xed, 0x0d, 0x4b, 0x33, 0xee,
1400 0x04, 0x3b, 0x8d, 0xed, 0x04, 0x3b, 0x9d, 0xed,
1401 0x04, 0x5b, 0x9d, 0xed, 0x0f, 0x6b, 0x35, 0xee,
1402 0x06, 0x5b, 0x8d, 0xed, 0x04, 0x5b, 0x04, 0x98,
1403 0x05, 0x99, 0x07, 0xb0, 0xbd, 0xe8, 0x00, 0x80,
1404 };
1405
1406 Method::InvokeStub* stub = AllocateStub(method,
1407 sum_DDDDD_code,
1408 sizeof(sum_DDDDD_code));
1409
1410 double args[4];
1411 JValue result;
1412
1413 args[0] = 0.0;
1414 args[1] = 0.0;
1415 args[2] = 0.0;
1416 args[3] = 0.0;
1417 result.d = -1.0;
1418 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
1419 EXPECT_EQ(0.0, result.d);
1420
1421 args[0] = 1.0;
1422 args[1] = 2.0;
1423 args[2] = 3.0;
1424 args[3] = 4.0;
1425 result.d = 0.0;
1426 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
1427 EXPECT_EQ(10.0, result.d);
1428
1429 args[0] = 1.0;
1430 args[1] = -2.0;
1431 args[2] = 3.0;
1432 args[3] = -4.0;
1433 result.d = 0.0;
1434 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
1435 EXPECT_EQ(-2.0, result.d);
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001436}
1437
1438TEST_F(JniInternalTest, StaticSumDoubleDoubleDoubleDoubleDoubleMethod) {
Brian Carlstroma663ea52011-08-19 23:33:41 -07001439 scoped_ptr<DexFile> dex(OpenDexFileBase64(kStaticLeafMethodsDex, "kStaticLeafMethodsDex"));
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001440
1441 PathClassLoader* class_loader = AllocPathClassLoader(dex.get());
1442 ASSERT_TRUE(class_loader != NULL);
1443
1444 Class* klass = class_linker_->FindClass("LStaticLeafMethods;", class_loader);
1445 ASSERT_TRUE(klass != NULL);
1446
1447 Method* method = klass->FindDirectMethod("sum", "(DDDDD)D");
1448 ASSERT_TRUE(method != NULL);
1449
1450 byte sum_DDDDDD_code[] = {
1451 0x2d, 0xe9, 0x00, 0x40, 0x87, 0xb0, 0xcd, 0xf8,
1452 0x00, 0x00, 0xcd, 0xf8, 0x24, 0x10, 0xcd, 0xf8,
1453 0x28, 0x20, 0xcd, 0xf8, 0x2c, 0x30, 0x9d, 0xed,
1454 0x09, 0x0b, 0x9d, 0xed, 0x0b, 0x1b, 0x30, 0xee,
1455 0x01, 0x2b, 0x8d, 0xed, 0x04, 0x2b, 0x9d, 0xed,
1456 0x04, 0x3b, 0x9d, 0xed, 0x0d, 0x4b, 0x33, 0xee,
1457 0x04, 0x3b, 0x8d, 0xed, 0x04, 0x3b, 0x9d, 0xed,
1458 0x04, 0x5b, 0x9d, 0xed, 0x0f, 0x6b, 0x35, 0xee,
1459 0x06, 0x5b, 0x8d, 0xed, 0x04, 0x5b, 0x9d, 0xed,
1460 0x04, 0x7b, 0x9d, 0xed, 0x11, 0x0b, 0x37, 0xee,
1461 0x00, 0x7b, 0x8d, 0xed, 0x04, 0x7b, 0x04, 0x98,
1462 0x05, 0x99, 0x07, 0xb0, 0xbd, 0xe8, 0x00, 0x80,
1463 };
1464
1465 Method::InvokeStub* stub = AllocateStub(method,
1466 sum_DDDDDD_code,
1467 sizeof(sum_DDDDDD_code));
1468
1469 double args[5];
1470 JValue result;
1471
1472 args[0] = 0.0;
1473 args[1] = 0.0;
1474 args[2] = 0.0;
1475 args[3] = 0.0;
1476 args[4] = 0.0;
1477 result.d = -1.0;
1478 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
1479 EXPECT_EQ(0.0, result.d);
1480
1481 args[0] = 1.0;
1482 args[1] = 2.0;
1483 args[2] = 3.0;
1484 args[3] = 4.0;
1485 args[4] = 5.0;
1486 result.d = 0.0;
1487 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
1488 EXPECT_EQ(15.0, result.d);
1489
1490 args[0] = 1.0;
1491 args[1] = -2.0;
1492 args[2] = 3.0;
1493 args[3] = -4.0;
1494 args[4] = 5.0;
1495 result.d = 0.0;
1496 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
1497 EXPECT_EQ(3.0, result.d);
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001498}
1499#endif // __arm__
1500
Elliott Hughes37f7a402011-08-22 18:56:01 -07001501TEST_F(JniInternalTest, Throw) {
1502 EXPECT_EQ(JNI_ERR, env_->Throw(NULL));
1503
1504 jclass exception_class = env_->FindClass("java/lang/RuntimeException");
1505 ASSERT_TRUE(exception_class != NULL);
1506 jthrowable exception = reinterpret_cast<jthrowable>(env_->AllocObject(exception_class));
1507 ASSERT_TRUE(exception != NULL);
1508
1509 EXPECT_EQ(JNI_OK, env_->Throw(exception));
1510 EXPECT_TRUE(env_->ExceptionCheck());
1511 EXPECT_TRUE(env_->IsSameObject(exception, env_->ExceptionOccurred()));
1512 env_->ExceptionClear();
1513}
1514
1515TEST_F(JniInternalTest, ThrowNew) {
1516 EXPECT_EQ(JNI_ERR, env_->Throw(NULL));
1517
1518 jclass exception_class = env_->FindClass("java/lang/RuntimeException");
1519 ASSERT_TRUE(exception_class != NULL);
1520
1521 EXPECT_EQ(JNI_OK, env_->ThrowNew(exception_class, "hello world"));
1522 EXPECT_TRUE(env_->ExceptionCheck());
1523 EXPECT_TRUE(env_->IsInstanceOf(env_->ExceptionOccurred(), exception_class));
1524 env_->ExceptionClear();
1525}
1526
Elliott Hughesb465ab02011-08-24 11:21:21 -07001527// TODO: this test is DISABLED until we can actually run java.nio.Buffer's <init>.
1528TEST_F(JniInternalTest, DISABLED_NewDirectBuffer_GetDirectBufferAddress_GetDirectBufferCapacity) {
1529 jclass buffer_class = env_->FindClass("java/nio/Buffer");
1530 ASSERT_TRUE(buffer_class != NULL);
1531
1532 char bytes[1024];
1533 jobject buffer = env_->NewDirectByteBuffer(bytes, sizeof(bytes));
1534 ASSERT_TRUE(buffer != NULL);
1535 ASSERT_TRUE(env_->IsInstanceOf(buffer, buffer_class));
1536 ASSERT_TRUE(env_->GetDirectBufferAddress(buffer) == bytes);
1537 ASSERT_TRUE(env_->GetDirectBufferCapacity(buffer) == sizeof(bytes));
1538}
1539
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001540}