blob: 0964b6223b4a6fba783d493d735f846e3f7f8015 [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 Hughes814e4032011-08-23 12:07:56 -0700282#define EXPECT_PRIMITIVE_ARRAY(new_fn, get_region_fn, set_region_fn, scalar_type, expected_class_descriptor) \
283 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); \
320 EXPECT_TRUE(memcmp(src_buf, dst_buf, sizeof(src_buf)) == 0) << "full copy not equal"
Elliott Hughesbd935992011-08-22 11:59:34 -0700321
Elliott Hughes814e4032011-08-23 12:07:56 -0700322TEST_F(JniInternalTest, BooleanArrays) {
323 EXPECT_PRIMITIVE_ARRAY(NewBooleanArray, GetBooleanArrayRegion, SetBooleanArrayRegion, jboolean, "[Z");
324}
325TEST_F(JniInternalTest, ByteArrays) {
326 EXPECT_PRIMITIVE_ARRAY(NewByteArray, GetByteArrayRegion, SetByteArrayRegion, jbyte, "[B");
327}
328TEST_F(JniInternalTest, CharArrays) {
329 EXPECT_PRIMITIVE_ARRAY(NewCharArray, GetCharArrayRegion, SetCharArrayRegion, jchar, "[C");
330}
331TEST_F(JniInternalTest, DoubleArrays) {
332 EXPECT_PRIMITIVE_ARRAY(NewDoubleArray, GetDoubleArrayRegion, SetDoubleArrayRegion, jdouble, "[D");
333}
334TEST_F(JniInternalTest, FloatArrays) {
335 EXPECT_PRIMITIVE_ARRAY(NewFloatArray, GetFloatArrayRegion, SetFloatArrayRegion, jfloat, "[F");
336}
337TEST_F(JniInternalTest, IntArrays) {
338 EXPECT_PRIMITIVE_ARRAY(NewIntArray, GetIntArrayRegion, SetIntArrayRegion, jint, "[I");
339}
340TEST_F(JniInternalTest, LongArrays) {
341 EXPECT_PRIMITIVE_ARRAY(NewLongArray, GetLongArrayRegion, SetLongArrayRegion, jlong, "[J");
342}
343TEST_F(JniInternalTest, ShortArrays) {
344 EXPECT_PRIMITIVE_ARRAY(NewShortArray, GetShortArrayRegion, SetShortArrayRegion, jshort, "[S");
Elliott Hughesd8ddfd52011-08-15 14:32:53 -0700345}
346
Elliott Hughesf2682d52011-08-15 16:37:04 -0700347TEST_F(JniInternalTest, NewObjectArray) {
348 // TODO: death tests for negative array sizes.
349
Elliott Hughesf2682d52011-08-15 16:37:04 -0700350 // TODO: check non-NULL initial elements.
351
Elliott Hughesbd935992011-08-22 11:59:34 -0700352 jclass element_class = env_->FindClass("java/lang/String");
353 ASSERT_TRUE(element_class != NULL);
354 jclass array_class = env_->FindClass("[Ljava/lang/String;");
355 ASSERT_TRUE(array_class != NULL);
Elliott Hughesf2682d52011-08-15 16:37:04 -0700356
Elliott Hughesbd935992011-08-22 11:59:34 -0700357 jobjectArray a;
Elliott Hughesf2682d52011-08-15 16:37:04 -0700358
Elliott Hughesbd935992011-08-22 11:59:34 -0700359 a = env_->NewObjectArray(0, element_class, NULL);
360 EXPECT_TRUE(a != NULL);
361 EXPECT_TRUE(env_->IsInstanceOf(a, array_class));
362 EXPECT_EQ(0, env_->GetArrayLength(a));
363
364 a = env_->NewObjectArray(1, element_class, NULL);
365 EXPECT_TRUE(a != NULL);
366 EXPECT_TRUE(env_->IsInstanceOf(a, array_class));
367 EXPECT_EQ(1, env_->GetArrayLength(a));
368}
369
370TEST_F(JniInternalTest, GetArrayLength) {
371 // Already tested in NewObjectArray/NewPrimitiveArray.
Elliott Hughes8a26c5c2011-08-15 18:35:43 -0700372}
373
Elliott Hughes37f7a402011-08-22 18:56:01 -0700374TEST_F(JniInternalTest, GetObjectClass) {
375 jclass string_class = env_->FindClass("java/lang/String");
376 ASSERT_TRUE(string_class != NULL);
377 jclass class_class = env_->FindClass("java/lang/Class");
378 ASSERT_TRUE(class_class != NULL);
379
380 jstring s = env_->NewStringUTF("poop");
381 jclass c = env_->GetObjectClass(s);
382 ASSERT_TRUE(env_->IsSameObject(string_class, c));
383
384 jclass c2 = env_->GetObjectClass(c);
385 ASSERT_TRUE(env_->IsSameObject(class_class, env_->GetObjectClass(c2)));
386}
387
Elliott Hughes885c3bd2011-08-22 16:59:20 -0700388TEST_F(JniInternalTest, GetSuperclass) {
389 jclass object_class = env_->FindClass("java/lang/Object");
390 ASSERT_TRUE(object_class != NULL);
391 jclass string_class = env_->FindClass("java/lang/String");
392 ASSERT_TRUE(string_class != NULL);
393 ASSERT_TRUE(env_->IsSameObject(object_class, env_->GetSuperclass(string_class)));
394 ASSERT_TRUE(env_->GetSuperclass(object_class) == NULL);
395}
396
Elliott Hughes37f7a402011-08-22 18:56:01 -0700397TEST_F(JniInternalTest, IsAssignableFrom) {
398 jclass object_class = env_->FindClass("java/lang/Object");
399 ASSERT_TRUE(object_class != NULL);
400 jclass string_class = env_->FindClass("java/lang/String");
401 ASSERT_TRUE(string_class != NULL);
402
403 ASSERT_TRUE(env_->IsAssignableFrom(object_class, string_class));
404 ASSERT_FALSE(env_->IsAssignableFrom(string_class, object_class));
405}
406
Elliott Hughesb465ab02011-08-24 11:21:21 -0700407TEST_F(JniInternalTest, GetObjectRefType) {
408 jclass local = env_->FindClass("java/lang/Object");
409 ASSERT_TRUE(local != NULL);
410 EXPECT_EQ(JNILocalRefType, env_->GetObjectRefType(local));
411
412 jobject global = env_->NewGlobalRef(local);
413 EXPECT_EQ(JNIGlobalRefType, env_->GetObjectRefType(global));
414
415 jweak weak_global = env_->NewWeakGlobalRef(local);
416 EXPECT_EQ(JNIWeakGlobalRefType, env_->GetObjectRefType(weak_global));
417
418 jobject invalid = reinterpret_cast<jobject>(this);
419 EXPECT_EQ(JNIInvalidRefType, env_->GetObjectRefType(invalid));
420
421 // TODO: invoke a native method and test that its arguments are considered local references.
422}
423
Elliott Hughes8a26c5c2011-08-15 18:35:43 -0700424TEST_F(JniInternalTest, NewStringUTF) {
425 EXPECT_TRUE(env_->NewStringUTF(NULL) == NULL);
Elliott Hughes814e4032011-08-23 12:07:56 -0700426 jstring s;
427
428 s = env_->NewStringUTF("");
429 EXPECT_TRUE(s != NULL);
430 EXPECT_EQ(0, env_->GetStringLength(s));
431 EXPECT_EQ(0, env_->GetStringUTFLength(s));
432 s = env_->NewStringUTF("hello");
433 EXPECT_TRUE(s != NULL);
434 EXPECT_EQ(5, env_->GetStringLength(s));
435 EXPECT_EQ(5, env_->GetStringUTFLength(s));
436
Elliott Hughes8a26c5c2011-08-15 18:35:43 -0700437 // TODO: check some non-ASCII strings.
Elliott Hughesf2682d52011-08-15 16:37:04 -0700438}
439
Elliott Hughes814e4032011-08-23 12:07:56 -0700440TEST_F(JniInternalTest, NewString) {
441 EXPECT_TRUE(env_->NewString(NULL, 0) == NULL);
442
443 jchar chars[] = { 'h', 'i' };
444 jstring s;
445 s = env_->NewString(chars, 0);
446 EXPECT_TRUE(s != NULL);
447 EXPECT_EQ(0, env_->GetStringLength(s));
448 EXPECT_EQ(0, env_->GetStringUTFLength(s));
449 s = env_->NewString(chars, 2);
450 EXPECT_TRUE(s != NULL);
451 EXPECT_EQ(2, env_->GetStringLength(s));
452 EXPECT_EQ(2, env_->GetStringUTFLength(s));
453
454 // TODO: check some non-ASCII strings.
455}
456
Elliott Hughesb465ab02011-08-24 11:21:21 -0700457TEST_F(JniInternalTest, GetStringLength_GetStringUTFLength) {
458 // Already tested in the NewString/NewStringUTF tests.
459}
460
461TEST_F(JniInternalTest, GetStringRegion_GetStringUTFRegion) {
462 jstring s = env_->NewStringUTF("hello");
463 ASSERT_TRUE(s != NULL);
464
465 env_->GetStringRegion(s, -1, 0, NULL);
466 EXPECT_EXCEPTION(sioobe_);
467 env_->GetStringRegion(s, 0, -1, NULL);
468 EXPECT_EXCEPTION(sioobe_);
469 env_->GetStringRegion(s, 0, 10, NULL);
470 EXPECT_EXCEPTION(sioobe_);
471 env_->GetStringRegion(s, 10, 1, NULL);
472 EXPECT_EXCEPTION(sioobe_);
473
474 jchar chars[4] = { 'x', 'x', 'x', 'x' };
475 env_->GetStringRegion(s, 1, 2, &chars[1]);
476 EXPECT_EQ('x', chars[0]);
477 EXPECT_EQ('e', chars[1]);
478 EXPECT_EQ('l', chars[2]);
479 EXPECT_EQ('x', chars[3]);
480
481 env_->GetStringUTFRegion(s, -1, 0, NULL);
482 EXPECT_EXCEPTION(sioobe_);
483 env_->GetStringUTFRegion(s, 0, -1, NULL);
484 EXPECT_EXCEPTION(sioobe_);
485 env_->GetStringUTFRegion(s, 0, 10, NULL);
486 EXPECT_EXCEPTION(sioobe_);
487 env_->GetStringUTFRegion(s, 10, 1, NULL);
488 EXPECT_EXCEPTION(sioobe_);
489
490 char bytes[4] = { 'x', 'x', 'x', 'x' };
491 env_->GetStringUTFRegion(s, 1, 2, &bytes[1]);
492 EXPECT_EQ('x', bytes[0]);
493 EXPECT_EQ('e', bytes[1]);
494 EXPECT_EQ('l', bytes[2]);
495 EXPECT_EQ('x', bytes[3]);
496}
497
Elliott Hughes814e4032011-08-23 12:07:56 -0700498TEST_F(JniInternalTest, GetObjectArrayElement_SetObjectArrayElement) {
Elliott Hughes289da822011-08-16 10:11:20 -0700499 jclass c = env_->FindClass("[Ljava/lang/Object;");
500 ASSERT_TRUE(c != NULL);
501
502 jobjectArray array = env_->NewObjectArray(1, c, NULL);
503 EXPECT_TRUE(array != NULL);
Elliott Hughes814e4032011-08-23 12:07:56 -0700504 EXPECT_TRUE(env_->GetObjectArrayElement(array, 0) == NULL);
Elliott Hughes289da822011-08-16 10:11:20 -0700505 env_->SetObjectArrayElement(array, 0, c);
Elliott Hughes814e4032011-08-23 12:07:56 -0700506 EXPECT_TRUE(env_->IsSameObject(env_->GetObjectArrayElement(array, 0), c));
Elliott Hughesa5b897e2011-08-16 11:33:06 -0700507
508 // ArrayIndexOutOfBounds for negative index.
Elliott Hughesa5b897e2011-08-16 11:33:06 -0700509 env_->SetObjectArrayElement(array, -1, c);
Elliott Hughes814e4032011-08-23 12:07:56 -0700510 EXPECT_EXCEPTION(aioobe_);
Elliott Hughesa5b897e2011-08-16 11:33:06 -0700511
512 // ArrayIndexOutOfBounds for too-large index.
Elliott Hughesa5b897e2011-08-16 11:33:06 -0700513 env_->SetObjectArrayElement(array, 1, c);
Elliott Hughes814e4032011-08-23 12:07:56 -0700514 EXPECT_EXCEPTION(aioobe_);
Elliott Hughesa5b897e2011-08-16 11:33:06 -0700515
Elliott Hughes289da822011-08-16 10:11:20 -0700516 // TODO: check ArrayStoreException thrown for bad types.
517}
518
Elliott Hughes885c3bd2011-08-22 16:59:20 -0700519#define EXPECT_STATIC_PRIMITIVE_FIELD(type, field_name, sig, value1, value2) \
520 do { \
521 jfieldID fid = env_->GetStaticFieldID(c, field_name, sig); \
522 EXPECT_TRUE(fid != NULL); \
523 env_->SetStatic ## type ## Field(c, fid, value1); \
524 EXPECT_EQ(value1, env_->GetStatic ## type ## Field(c, fid)); \
525 env_->SetStatic ## type ## Field(c, fid, value2); \
526 EXPECT_EQ(value2, env_->GetStatic ## type ## Field(c, fid)); \
527 } while (false)
528
529#define EXPECT_PRIMITIVE_FIELD(instance, type, field_name, sig, value1, value2) \
530 do { \
531 jfieldID fid = env_->GetFieldID(c, field_name, sig); \
532 EXPECT_TRUE(fid != NULL); \
533 env_->Set ## type ## Field(instance, fid, value1); \
534 EXPECT_EQ(value1, env_->Get ## type ## Field(instance, fid)); \
535 env_->Set ## type ## Field(instance, fid, value2); \
536 EXPECT_EQ(value2, env_->Get ## type ## Field(instance, fid)); \
537 } while (false)
538
539
540TEST_F(JniInternalTest, GetPrimitiveField_SetPrimitiveField) {
541 scoped_ptr<DexFile> dex(OpenDexFileBase64(kAllFields, "kAllFields"));
542 PathClassLoader* class_loader = AllocPathClassLoader(dex.get());
543 Thread::Current()->SetClassLoaderOverride(class_loader);
544
545 jclass c = env_->FindClass("AllFields");
546 ASSERT_TRUE(c != NULL);
547 jobject o = env_->AllocObject(c);
548 ASSERT_TRUE(o != NULL);
549
550 EXPECT_STATIC_PRIMITIVE_FIELD(Boolean, "sZ", "Z", true, false);
551 EXPECT_STATIC_PRIMITIVE_FIELD(Byte, "sB", "B", 1, 2);
552 EXPECT_STATIC_PRIMITIVE_FIELD(Char, "sC", "C", 'a', 'b');
553 EXPECT_STATIC_PRIMITIVE_FIELD(Double, "sD", "D", 1.0, 2.0);
554 EXPECT_STATIC_PRIMITIVE_FIELD(Float, "sF", "F", 1.0, 2.0);
555 EXPECT_STATIC_PRIMITIVE_FIELD(Int, "sI", "I", 1, 2);
556 EXPECT_STATIC_PRIMITIVE_FIELD(Long, "sJ", "J", 1, 2);
557 EXPECT_STATIC_PRIMITIVE_FIELD(Short, "sS", "S", 1, 2);
558
559 EXPECT_PRIMITIVE_FIELD(o, Boolean, "iZ", "Z", true, false);
560 EXPECT_PRIMITIVE_FIELD(o, Byte, "iB", "B", 1, 2);
561 EXPECT_PRIMITIVE_FIELD(o, Char, "iC", "C", 'a', 'b');
562 EXPECT_PRIMITIVE_FIELD(o, Double, "iD", "D", 1.0, 2.0);
563 EXPECT_PRIMITIVE_FIELD(o, Float, "iF", "F", 1.0, 2.0);
564 EXPECT_PRIMITIVE_FIELD(o, Int, "iI", "I", 1, 2);
565 EXPECT_PRIMITIVE_FIELD(o, Long, "iJ", "J", 1, 2);
566 EXPECT_PRIMITIVE_FIELD(o, Short, "iS", "S", 1, 2);
567}
568
569TEST_F(JniInternalTest, GetObjectField_SetObjectField) {
570 scoped_ptr<DexFile> dex(OpenDexFileBase64(kAllFields, "kAllFields"));
571 PathClassLoader* class_loader = AllocPathClassLoader(dex.get());
572 Thread::Current()->SetClassLoaderOverride(class_loader);
573
574 jclass c = env_->FindClass("AllFields");
575 ASSERT_TRUE(c != NULL);
576 jobject o = env_->AllocObject(c);
577 ASSERT_TRUE(o != NULL);
578
579 jstring s1 = env_->NewStringUTF("hello");
580 ASSERT_TRUE(s1 != NULL);
581 jstring s2 = env_->NewStringUTF("world");
582 ASSERT_TRUE(s2 != NULL);
583
584 jfieldID s_fid = env_->GetStaticFieldID(c, "sObject", "Ljava/lang/Object;");
585 ASSERT_TRUE(s_fid != NULL);
586 jfieldID i_fid = env_->GetFieldID(c, "iObject", "Ljava/lang/Object;");
587 ASSERT_TRUE(i_fid != NULL);
588
589 env_->SetStaticObjectField(c, s_fid, s1);
590 ASSERT_TRUE(env_->IsSameObject(s1, env_->GetStaticObjectField(c, s_fid)));
591 env_->SetStaticObjectField(c, s_fid, s2);
592 ASSERT_TRUE(env_->IsSameObject(s2, env_->GetStaticObjectField(c, s_fid)));
593
594 env_->SetObjectField(o, i_fid, s1);
595 ASSERT_TRUE(env_->IsSameObject(s1, env_->GetObjectField(o, i_fid)));
596 env_->SetObjectField(o, i_fid, s2);
597 ASSERT_TRUE(env_->IsSameObject(s2, env_->GetObjectField(o, i_fid)));
598}
599
Elliott Hughes18c07532011-08-18 15:50:51 -0700600TEST_F(JniInternalTest, NewLocalRef_NULL) {
601 EXPECT_TRUE(env_->NewLocalRef(NULL) == NULL);
602}
603
604TEST_F(JniInternalTest, NewLocalRef) {
605 jstring s = env_->NewStringUTF("");
606 ASSERT_TRUE(s != NULL);
607 jobject o = env_->NewLocalRef(s);
608 EXPECT_TRUE(o != NULL);
609 EXPECT_TRUE(o != s);
610
611 // TODO: check that o is a local reference.
612}
613
614TEST_F(JniInternalTest, DeleteLocalRef_NULL) {
615 env_->DeleteLocalRef(NULL);
616}
617
618TEST_F(JniInternalTest, DeleteLocalRef) {
619 jstring s = env_->NewStringUTF("");
620 ASSERT_TRUE(s != NULL);
621 env_->DeleteLocalRef(s);
622
623 // Currently, deleting an already-deleted reference is just a warning.
624 env_->DeleteLocalRef(s);
625
626 s = env_->NewStringUTF("");
627 ASSERT_TRUE(s != NULL);
628 jobject o = env_->NewLocalRef(s);
629 ASSERT_TRUE(o != NULL);
630
631 env_->DeleteLocalRef(s);
632 env_->DeleteLocalRef(o);
633}
634
635TEST_F(JniInternalTest, NewGlobalRef_NULL) {
636 EXPECT_TRUE(env_->NewGlobalRef(NULL) == NULL);
637}
638
639TEST_F(JniInternalTest, NewGlobalRef) {
640 jstring s = env_->NewStringUTF("");
641 ASSERT_TRUE(s != NULL);
642 jobject o = env_->NewGlobalRef(s);
643 EXPECT_TRUE(o != NULL);
644 EXPECT_TRUE(o != s);
645
646 // TODO: check that o is a global reference.
647}
648
649TEST_F(JniInternalTest, DeleteGlobalRef_NULL) {
650 env_->DeleteGlobalRef(NULL);
651}
652
653TEST_F(JniInternalTest, DeleteGlobalRef) {
654 jstring s = env_->NewStringUTF("");
655 ASSERT_TRUE(s != NULL);
656
657 jobject o = env_->NewGlobalRef(s);
658 ASSERT_TRUE(o != NULL);
659 env_->DeleteGlobalRef(o);
660
661 // Currently, deleting an already-deleted reference is just a warning.
662 env_->DeleteGlobalRef(o);
663
664 jobject o1 = env_->NewGlobalRef(s);
665 ASSERT_TRUE(o1 != NULL);
666 jobject o2 = env_->NewGlobalRef(s);
667 ASSERT_TRUE(o2 != NULL);
668
669 env_->DeleteGlobalRef(o1);
670 env_->DeleteGlobalRef(o2);
671}
672
673TEST_F(JniInternalTest, NewWeakGlobalRef_NULL) {
674 EXPECT_TRUE(env_->NewWeakGlobalRef(NULL) == NULL);
675}
676
677TEST_F(JniInternalTest, NewWeakGlobalRef) {
678 jstring s = env_->NewStringUTF("");
679 ASSERT_TRUE(s != NULL);
680 jobject o = env_->NewWeakGlobalRef(s);
681 EXPECT_TRUE(o != NULL);
682 EXPECT_TRUE(o != s);
683
684 // TODO: check that o is a weak global reference.
685}
686
687TEST_F(JniInternalTest, DeleteWeakGlobalRef_NULL) {
688 env_->DeleteWeakGlobalRef(NULL);
689}
690
691TEST_F(JniInternalTest, DeleteWeakGlobalRef) {
692 jstring s = env_->NewStringUTF("");
693 ASSERT_TRUE(s != NULL);
694
695 jobject o = env_->NewWeakGlobalRef(s);
696 ASSERT_TRUE(o != NULL);
697 env_->DeleteWeakGlobalRef(o);
698
699 // Currently, deleting an already-deleted reference is just a warning.
700 env_->DeleteWeakGlobalRef(o);
701
702 jobject o1 = env_->NewWeakGlobalRef(s);
703 ASSERT_TRUE(o1 != NULL);
704 jobject o2 = env_->NewWeakGlobalRef(s);
705 ASSERT_TRUE(o2 != NULL);
706
707 env_->DeleteWeakGlobalRef(o1);
708 env_->DeleteWeakGlobalRef(o2);
709}
710
Carl Shapiro9b9ba282011-08-14 15:30:39 -0700711bool EnsureInvokeStub(Method* method);
712
Carl Shapiro9b9ba282011-08-14 15:30:39 -0700713Method::InvokeStub* AllocateStub(Method* method,
714 byte* code,
715 size_t length) {
716 CHECK(method->GetInvokeStub() == NULL);
717 EnsureInvokeStub(method);
718 Method::InvokeStub* stub = method->GetInvokeStub();
719 CHECK(stub != NULL);
buzbeec143c552011-08-20 17:38:58 -0700720 method->SetCode(code, length, kThumb2);
Carl Shapiro9b9ba282011-08-14 15:30:39 -0700721 return stub;
722}
723
Carl Shapiro9b9ba282011-08-14 15:30:39 -0700724#if defined(__arm__)
725TEST_F(JniInternalTest, StaticMainMethod) {
Brian Carlstroma663ea52011-08-19 23:33:41 -0700726 scoped_ptr<DexFile> dex(OpenDexFileBase64(kMainDex, "kMainDex"));
Carl Shapiro9b9ba282011-08-14 15:30:39 -0700727
728 PathClassLoader* class_loader = AllocPathClassLoader(dex.get());
729 ASSERT_TRUE(class_loader != NULL);
730
731 Class* klass = class_linker_->FindClass("LMain;", class_loader);
732 ASSERT_TRUE(klass != NULL);
733
734 Method* method = klass->FindDirectMethod("main", "([Ljava/lang/String;)V");
735 ASSERT_TRUE(method != NULL);
736
737 byte main_LV_code[] = {
738 0x2d, 0xe9, 0x00, 0x40, 0x83, 0xb0, 0xcd, 0xf8, 0x00, 0x00,
739 0xcd, 0xf8, 0x14, 0x10, 0x03, 0xb0, 0xbd, 0xe8, 0x00, 0x80,
740 };
741
742 Method::InvokeStub* stub = AllocateStub(method,
743 main_LV_code,
744 sizeof(main_LV_code));
745
746 Object* arg = NULL;
747
748 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(&arg), NULL);
Carl Shapiro9b9ba282011-08-14 15:30:39 -0700749}
750
751TEST_F(JniInternalTest, StaticNopMethod) {
Brian Carlstroma663ea52011-08-19 23:33:41 -0700752 scoped_ptr<DexFile> dex(OpenDexFileBase64(kStaticLeafMethodsDex, "kStaticLeafMethodsDex"));
Carl Shapiro9b9ba282011-08-14 15:30:39 -0700753
754 PathClassLoader* class_loader = AllocPathClassLoader(dex.get());
755 ASSERT_TRUE(class_loader != NULL);
756
757 Class* klass = class_linker_->FindClass("LStaticLeafMethods;", class_loader);
758 ASSERT_TRUE(klass != NULL);
759
760 Method* method = klass->FindDirectMethod("nop", "()V");
761 ASSERT_TRUE(method != NULL);
762
763 byte nop_V_code[] = {
764 0x2d, 0xe9, 0x00, 0x40, 0x83, 0xb0, 0xcd, 0xf8,
765 0x00, 0x00, 0x03, 0xb0, 0xbd, 0xe8, 0x00, 0x80,
766 };
767
768 Method::InvokeStub* stub = AllocateStub(method,
769 nop_V_code,
770 sizeof(nop_V_code));
771 ASSERT_TRUE(stub);
772
773 (*stub)(method, NULL, NULL, NULL, NULL);
Carl Shapiro9b9ba282011-08-14 15:30:39 -0700774}
775
776TEST_F(JniInternalTest, StaticIdentityByteMethod) {
Brian Carlstroma663ea52011-08-19 23:33:41 -0700777 scoped_ptr<DexFile> dex(OpenDexFileBase64(kStaticLeafMethodsDex, "kStaticLeafMethodsDex"));
Carl Shapiro9b9ba282011-08-14 15:30:39 -0700778
779 PathClassLoader* class_loader = AllocPathClassLoader(dex.get());
780 ASSERT_TRUE(class_loader != NULL);
781
782 Class* klass = class_linker_->FindClass("LStaticLeafMethods;", class_loader);
783 ASSERT_TRUE(klass != NULL);
784
785 Method* method = klass->FindDirectMethod("identity", "(B)B");
786 ASSERT_TRUE(method != NULL);
787
788 byte identity_BB_code[] = {
789 0x2d, 0xe9, 0x00, 0x40, 0x83, 0xb0, 0xcd, 0xf8,
790 0x00, 0x00, 0xcd, 0xf8, 0x14, 0x10, 0x05, 0x98,
791 0x03, 0xb0, 0xbd, 0xe8, 0x00, 0x80, 0x00, 0x00,
792 };
793
794 Method::InvokeStub* stub = AllocateStub(method,
795 identity_BB_code,
796 sizeof(identity_BB_code));
797
798 int arg;
799 JValue result;
800
801 arg = 0;
802 result.b = -1;
803 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(&arg), &result);
804 EXPECT_EQ(0, result.b);
805
806 arg = -1;
807 result.b = 0;
808 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(&arg), &result);
809 EXPECT_EQ(-1, result.b);
810
811 arg = SCHAR_MAX;
812 result.b = 0;
813 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(&arg), &result);
814 EXPECT_EQ(SCHAR_MAX, result.b);
815
816 arg = SCHAR_MIN;
817 result.b = 0;
818 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(&arg), &result);
819 EXPECT_EQ(SCHAR_MIN, result.b);
Carl Shapiro9b9ba282011-08-14 15:30:39 -0700820}
821
822TEST_F(JniInternalTest, StaticIdentityIntMethod) {
Brian Carlstroma663ea52011-08-19 23:33:41 -0700823 scoped_ptr<DexFile> dex(OpenDexFileBase64(kStaticLeafMethodsDex, "kStaticLeafMethodsDex"));
Carl Shapiro9b9ba282011-08-14 15:30:39 -0700824
825 PathClassLoader* class_loader = AllocPathClassLoader(dex.get());
826 ASSERT_TRUE(class_loader != NULL);
827
828 Class* klass = class_linker_->FindClass("LStaticLeafMethods;", class_loader);
829 ASSERT_TRUE(klass != NULL);
830
831 Method* method = klass->FindDirectMethod("identity", "(I)I");
832 ASSERT_TRUE(method != NULL);
833
834 byte identity_II_code[] = {
835 0x2d, 0xe9, 0x00, 0x40, 0x83, 0xb0, 0xcd, 0xf8,
836 0x00, 0x00, 0xcd, 0xf8, 0x14, 0x10, 0x05, 0x98,
837 0x03, 0xb0, 0xbd, 0xe8, 0x00, 0x80, 0x00, 0x00,
838 };
839
840 Method::InvokeStub* stub = AllocateStub(method,
841 identity_II_code,
842 sizeof(identity_II_code));
843
844 int arg;
845 JValue result;
846
847 arg = 0;
848 result.i = -1;
849 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(&arg), &result);
850 EXPECT_EQ(0, result.i);
851
852 arg = -1;
853 result.i = 0;
854 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(&arg), &result);
855 EXPECT_EQ(-1, result.i);
856
857 arg = INT_MAX;
858 result.i = 0;
859 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(&arg), &result);
860 EXPECT_EQ(INT_MAX, result.i);
861
862 arg = INT_MIN;
863 result.i = 0;
864 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(&arg), &result);
865 EXPECT_EQ(INT_MIN, result.i);
Carl Shapiro9b9ba282011-08-14 15:30:39 -0700866}
867
868TEST_F(JniInternalTest, StaticIdentityDoubleMethod) {
Brian Carlstroma663ea52011-08-19 23:33:41 -0700869 scoped_ptr<DexFile> dex(OpenDexFileBase64(kStaticLeafMethodsDex, "kStaticLeafMethodsDex"));
Carl Shapiro9b9ba282011-08-14 15:30:39 -0700870
871 PathClassLoader* class_loader = AllocPathClassLoader(dex.get());
872 ASSERT_TRUE(class_loader != NULL);
873
874 Class* klass = class_linker_->FindClass("LStaticLeafMethods;", class_loader);
875 ASSERT_TRUE(klass != NULL);
876
877 Method* method = klass->FindDirectMethod("identity", "(D)D");
878 ASSERT_TRUE(method != NULL);
879
880 byte identity_DD_code[] = {
881 0x2d, 0xe9, 0x00, 0x40, 0x83, 0xb0, 0xcd, 0xf8,
882 0x00, 0x00, 0xcd, 0xf8, 0x14, 0x10, 0xcd, 0xf8,
883 0x18, 0x20, 0x05, 0x98, 0x06, 0x99, 0x03, 0xb0,
884 0xbd, 0xe8, 0x00, 0x80,
885 };
886
887 Method::InvokeStub* stub = AllocateStub(method,
888 identity_DD_code,
889 sizeof(identity_DD_code));
890
891 double arg;
892 JValue result;
893
894 arg = 0.0;
895 result.d = -1.0;
896 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(&arg), &result);
897 EXPECT_EQ(0.0, result.d);
898
899 arg = -1.0;
900 result.d = 0.0;
901 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(&arg), &result);
902 EXPECT_EQ(-1.0, result.d);
903
904 arg = DBL_MAX;
905 result.d = 0.0;
906 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(&arg), &result);
907 EXPECT_EQ(DBL_MAX, result.d);
908
909 arg = DBL_MIN;
910 result.d = 0.0;
911 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(&arg), &result);
912 EXPECT_EQ(DBL_MIN, result.d);
Carl Shapiro9b9ba282011-08-14 15:30:39 -0700913}
914
915TEST_F(JniInternalTest, StaticSumIntIntMethod) {
Brian Carlstroma663ea52011-08-19 23:33:41 -0700916 scoped_ptr<DexFile> dex(OpenDexFileBase64(kStaticLeafMethodsDex, "kStaticLeafMethodsDex"));
Carl Shapiro9b9ba282011-08-14 15:30:39 -0700917
918 PathClassLoader* class_loader = AllocPathClassLoader(dex.get());
919 ASSERT_TRUE(class_loader != NULL);
920
921 Class* klass = class_linker_->FindClass("LStaticLeafMethods;", class_loader);
922 ASSERT_TRUE(klass != NULL);
923
924 Method* method = klass->FindDirectMethod("sum", "(II)I");
925 ASSERT_TRUE(method != NULL);
926
927 byte sum_III_code[] = {
928 0x2d, 0xe9, 0x00, 0x40, 0x83, 0xb0, 0xcd, 0xf8,
929 0x00, 0x00, 0xcd, 0xf8, 0x14, 0x10, 0xcd, 0xf8,
930 0x18, 0x20, 0x05, 0x98, 0x06, 0x99, 0x42, 0x18,
931 0xcd, 0xf8, 0x04, 0x20, 0x01, 0x98, 0x03, 0xb0,
932 0xbd, 0xe8, 0x00, 0x80,
933 };
934
935 Method::InvokeStub* stub = AllocateStub(method,
936 sum_III_code,
937 sizeof(sum_III_code));
938
939 int args[2];
940 JValue result;
941
942 args[0] = 0;
943 args[1] = 0;
944 result.i = -1;
945 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
946 EXPECT_EQ(0, result.i);
947
948 args[0] = 1;
949 args[1] = 2;
950 result.i = 0;
951 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
952 EXPECT_EQ(3, result.i);
953
954 args[0] = -2;
955 args[1] = 5;
956 result.i = 0;
957 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
958 EXPECT_EQ(3, result.i);
959
960 args[0] = INT_MAX;
961 args[1] = INT_MIN;
962 result.i = 1234;
963 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
964 EXPECT_EQ(-1, result.i);
965
966 args[0] = INT_MAX;
967 args[1] = INT_MAX;
968 result.i = INT_MIN;
969 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
970 EXPECT_EQ(-2, result.i);
Carl Shapiro9b9ba282011-08-14 15:30:39 -0700971}
972
973TEST_F(JniInternalTest, StaticSumIntIntIntMethod) {
Brian Carlstroma663ea52011-08-19 23:33:41 -0700974 scoped_ptr<DexFile> dex(OpenDexFileBase64(kStaticLeafMethodsDex, "kStaticLeafMethodsDex"));
Carl Shapiro9b9ba282011-08-14 15:30:39 -0700975
976 PathClassLoader* class_loader = AllocPathClassLoader(dex.get());
977 ASSERT_TRUE(class_loader != NULL);
978
979 Class* klass = class_linker_->FindClass("LStaticLeafMethods;", class_loader);
980 ASSERT_TRUE(klass != NULL);
981
982 Method* method = klass->FindDirectMethod("sum", "(III)I");
983 ASSERT_TRUE(method != NULL);
984
985 byte sum_IIII_code[] = {
986 0x2d, 0xe9, 0x00, 0x40, 0x83, 0xb0, 0xcd, 0xf8,
987 0x00, 0x00, 0xcd, 0xf8, 0x14, 0x10, 0xcd, 0xf8,
988 0x18, 0x20, 0xcd, 0xf8, 0x1c, 0x30, 0x05, 0x98,
989 0x06, 0x99, 0x42, 0x18, 0xcd, 0xf8, 0x04, 0x20,
990 0x01, 0x9b, 0xdd, 0xf8, 0x1c, 0xc0, 0x13, 0xeb,
991 0x0c, 0x03, 0xcd, 0xf8, 0x04, 0x30, 0x01, 0x98,
992 0x03, 0xb0, 0xbd, 0xe8, 0x00, 0x80, 0x00, 0x00,
993 };
994
995 Method::InvokeStub* stub = AllocateStub(method,
996 sum_IIII_code,
997 sizeof(sum_IIII_code));
998
999 int args[3];
1000 JValue result;
1001
1002 args[0] = 0;
1003 args[1] = 0;
1004 args[2] = 0;
1005 result.i = -1;
1006 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
1007 EXPECT_EQ(0, result.i);
1008
1009 args[0] = 1;
1010 args[1] = 2;
1011 args[2] = 3;
1012 result.i = 0;
1013 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
1014 EXPECT_EQ(6, result.i);
1015
1016 args[0] = -1;
1017 args[1] = 2;
1018 args[2] = -3;
1019 result.i = 0;
1020 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
1021 EXPECT_EQ(-2, result.i);
1022
1023 args[0] = INT_MAX;
1024 args[1] = INT_MIN;
1025 args[2] = INT_MAX;
1026 result.i = 1234;
1027 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
1028 EXPECT_EQ(2147483646, result.i);
1029
1030 args[0] = INT_MAX;
1031 args[1] = INT_MAX;
1032 args[2] = INT_MAX;
1033 result.i = INT_MIN;
1034 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
1035 EXPECT_EQ(2147483645, result.i);
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001036}
1037
1038TEST_F(JniInternalTest, StaticSumIntIntIntIntMethod) {
Brian Carlstroma663ea52011-08-19 23:33:41 -07001039 scoped_ptr<DexFile> dex(OpenDexFileBase64(kStaticLeafMethodsDex, "kStaticLeafMethodsDex"));
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001040
1041 PathClassLoader* class_loader = AllocPathClassLoader(dex.get());
1042 ASSERT_TRUE(class_loader != NULL);
1043
1044 Class* klass = class_linker_->FindClass("LStaticLeafMethods;", class_loader);
1045 ASSERT_TRUE(klass != NULL);
1046
1047 Method* method = klass->FindDirectMethod("sum", "(IIII)I");
1048 ASSERT_TRUE(method != NULL);
1049
1050 byte sum_IIIII_code[] = {
1051 0x2d, 0xe9, 0x00, 0x40, 0x83, 0xb0, 0xcd, 0xf8,
1052 0x00, 0x00, 0xcd, 0xf8, 0x14, 0x10, 0xcd, 0xf8,
1053 0x18, 0x20, 0xcd, 0xf8, 0x1c, 0x30, 0x05, 0x98,
1054 0x06, 0x99, 0x42, 0x18, 0xcd, 0xf8, 0x04, 0x20,
1055 0x01, 0x9b, 0xdd, 0xf8, 0x1c, 0xc0, 0x13, 0xeb,
1056 0x0c, 0x03, 0xcd, 0xf8, 0x04, 0x30, 0x01, 0x98,
1057 0x08, 0x99, 0x40, 0x18, 0xcd, 0xf8, 0x04, 0x00,
1058 0x01, 0x98, 0x03, 0xb0, 0xbd, 0xe8, 0x00, 0x80,
1059 };
1060
1061 Method::InvokeStub* stub = AllocateStub(method,
1062 sum_IIIII_code,
1063 sizeof(sum_IIIII_code));
1064
1065 int args[4];
1066 JValue result;
1067
1068 args[0] = 0;
1069 args[1] = 0;
1070 args[2] = 0;
1071 args[3] = 0;
1072 result.i = -1;
1073 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
1074 EXPECT_EQ(0, result.i);
1075
1076 args[0] = 1;
1077 args[1] = 2;
1078 args[2] = 3;
1079 args[3] = 4;
1080 result.i = 0;
1081 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
1082 EXPECT_EQ(10, result.i);
1083
1084 args[0] = -1;
1085 args[1] = 2;
1086 args[2] = -3;
1087 args[3] = 4;
1088 result.i = 0;
1089 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
1090 EXPECT_EQ(2, result.i);
1091
1092 args[0] = INT_MAX;
1093 args[1] = INT_MIN;
1094 args[2] = INT_MAX;
1095 args[3] = INT_MIN;
1096 result.i = 1234;
1097 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
1098 EXPECT_EQ(-2, result.i);
1099
1100 args[0] = INT_MAX;
1101 args[1] = INT_MAX;
1102 args[2] = INT_MAX;
1103 args[3] = INT_MAX;
1104 result.i = INT_MIN;
1105 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
1106 EXPECT_EQ(-4, result.i);
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001107}
1108
1109TEST_F(JniInternalTest, StaticSumIntIntIntIntIntMethod) {
Brian Carlstroma663ea52011-08-19 23:33:41 -07001110 scoped_ptr<DexFile> dex(OpenDexFileBase64(kStaticLeafMethodsDex, "kStaticLeafMethodsDex"));
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001111
1112 PathClassLoader* class_loader = AllocPathClassLoader(dex.get());
1113 ASSERT_TRUE(class_loader != NULL);
1114
1115 Class* klass = class_linker_->FindClass("LStaticLeafMethods;", class_loader);
1116 ASSERT_TRUE(klass != NULL);
1117
1118 Method* method = klass->FindDirectMethod("sum", "(IIIII)I");
1119 ASSERT_TRUE(method != NULL);
1120
1121 byte sum_IIIIII_code[] = {
1122 0x2d, 0xe9, 0x00, 0x40, 0x83, 0xb0, 0xcd, 0xf8,
1123 0x00, 0x00, 0xcd, 0xf8, 0x14, 0x10, 0xcd, 0xf8,
1124 0x18, 0x20, 0xcd, 0xf8, 0x1c, 0x30, 0x05, 0x98,
1125 0x06, 0x99, 0x42, 0x18, 0xcd, 0xf8, 0x04, 0x20,
1126 0x01, 0x9b, 0xdd, 0xf8, 0x1c, 0xc0, 0x13, 0xeb,
1127 0x0c, 0x03, 0xcd, 0xf8, 0x04, 0x30, 0x01, 0x98,
1128 0x08, 0x99, 0x40, 0x18, 0xcd, 0xf8, 0x04, 0x00,
1129 0x01, 0x9a, 0x09, 0x9b, 0xd2, 0x18, 0xcd, 0xf8,
1130 0x04, 0x20, 0x01, 0x98, 0x03, 0xb0, 0xbd, 0xe8,
1131 0x00, 0x80, 0x00, 0x00,
1132 };
1133
1134 Method::InvokeStub* stub = AllocateStub(method,
1135 sum_IIIIII_code,
1136 sizeof(sum_IIIIII_code));
1137
1138 int args[5];
1139 JValue result;
1140
1141 args[0] = 0;
1142 args[1] = 0;
1143 args[2] = 0;
1144 args[3] = 0;
1145 args[4] = 0;
1146 result.i = -1.0;
1147 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
1148 EXPECT_EQ(0, result.i);
1149
1150 args[0] = 1;
1151 args[1] = 2;
1152 args[2] = 3;
1153 args[3] = 4;
1154 args[4] = 5;
1155 result.i = 0;
1156 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
1157 EXPECT_EQ(15, result.i);
1158
1159 args[0] = -1;
1160 args[1] = 2;
1161 args[2] = -3;
1162 args[3] = 4;
1163 args[4] = -5;
1164 result.i = 0;
1165 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
1166 EXPECT_EQ(-3, result.i);
1167
1168 args[0] = INT_MAX;
1169 args[1] = INT_MIN;
1170 args[2] = INT_MAX;
1171 args[3] = INT_MIN;
1172 args[4] = INT_MAX;
1173 result.i = 1234;
1174 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
1175 EXPECT_EQ(2147483645, result.i);
1176
1177 args[0] = INT_MAX;
1178 args[1] = INT_MAX;
1179 args[2] = INT_MAX;
1180 args[3] = INT_MAX;
1181 args[4] = INT_MAX;
1182 result.i = INT_MIN;
1183 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
1184 EXPECT_EQ(2147483643, result.i);
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001185}
1186
1187TEST_F(JniInternalTest, StaticSumDoubleDoubleMethod) {
Brian Carlstroma663ea52011-08-19 23:33:41 -07001188 scoped_ptr<DexFile> dex(OpenDexFileBase64(kStaticLeafMethodsDex, "kStaticLeafMethodsDex"));
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001189
1190 PathClassLoader* class_loader = AllocPathClassLoader(dex.get());
1191 ASSERT_TRUE(class_loader != NULL);
1192
1193 Class* klass = class_linker_->FindClass("LStaticLeafMethods;", class_loader);
1194 ASSERT_TRUE(klass != NULL);
1195
1196 Method* method = klass->FindDirectMethod("sum", "(DD)D");
1197 ASSERT_TRUE(method != NULL);
1198
1199 byte sum_DDD_code[] = {
1200 0x2d, 0xe9, 0x00, 0x40, 0x87, 0xb0, 0xcd, 0xf8,
1201 0x00, 0x00, 0xcd, 0xf8, 0x24, 0x10, 0xcd, 0xf8,
1202 0x28, 0x20, 0xcd, 0xf8, 0x2c, 0x30, 0x9d, 0xed,
1203 0x09, 0x0b, 0x9d, 0xed, 0x0b, 0x1b, 0x30, 0xee,
1204 0x01, 0x2b, 0x8d, 0xed, 0x04, 0x2b, 0x04, 0x98,
1205 0x05, 0x99, 0x07, 0xb0, 0xbd, 0xe8, 0x00, 0x80,
1206 };
1207
1208 Method::InvokeStub* stub = AllocateStub(method,
1209 sum_DDD_code,
1210 sizeof(sum_DDD_code));
1211
1212 double args[2];
1213 JValue result;
1214
1215 args[0] = 0.0;
1216 args[1] = 0.0;
1217 result.d = -1.0;
1218 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
1219 EXPECT_EQ(0.0, result.d);
1220
1221 args[0] = 1.0;
1222 args[1] = 2.0;
1223 result.d = 0.0;
1224 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
1225 EXPECT_EQ(3.0, result.d);
1226
1227 args[0] = 1.0;
1228 args[1] = -2.0;
1229 result.d = 0.0;
1230 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
1231 EXPECT_EQ(-1.0, result.d);
1232
1233 args[0] = DBL_MAX;
1234 args[1] = DBL_MIN;
1235 result.d = 0.0;
1236 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
1237 EXPECT_EQ(1.7976931348623157e308, result.d);
1238
1239 args[0] = DBL_MAX;
1240 args[1] = DBL_MAX;
1241 result.d = 0.0;
1242 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
1243 EXPECT_EQ(INFINITY, result.d);
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001244}
1245
1246TEST_F(JniInternalTest, StaticSumDoubleDoubleDoubleMethod) {
Brian Carlstroma663ea52011-08-19 23:33:41 -07001247 scoped_ptr<DexFile> dex(OpenDexFileBase64(kStaticLeafMethodsDex, "kStaticLeafMethodsDex"));
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001248
1249 PathClassLoader* class_loader = AllocPathClassLoader(dex.get());
1250 ASSERT_TRUE(class_loader != NULL);
1251
1252 Class* klass = class_linker_->FindClass("LStaticLeafMethods;", class_loader);
1253 ASSERT_TRUE(klass != NULL);
1254
1255 Method* method = klass->FindDirectMethod("sum", "(DDD)D");
1256 ASSERT_TRUE(method != NULL);
1257
1258 byte sum_DDDD_code[] = {
1259 0x2d, 0xe9, 0x00, 0x40, 0x87, 0xb0, 0xcd, 0xf8,
1260 0x00, 0x00, 0xcd, 0xf8, 0x24, 0x10, 0xcd, 0xf8,
1261 0x28, 0x20, 0xcd, 0xf8, 0x2c, 0x30, 0x9d, 0xed,
1262 0x09, 0x0b, 0x9d, 0xed, 0x0b, 0x1b, 0x30, 0xee,
1263 0x01, 0x2b, 0x8d, 0xed, 0x04, 0x2b, 0x9d, 0xed,
1264 0x04, 0x3b, 0x9d, 0xed, 0x0d, 0x4b, 0x33, 0xee,
1265 0x04, 0x3b, 0x8d, 0xed, 0x04, 0x3b, 0x04, 0x98,
1266 0x05, 0x99, 0x07, 0xb0, 0xbd, 0xe8, 0x00, 0x80,
1267 };
1268
1269 Method::InvokeStub* stub = AllocateStub(method,
1270 sum_DDDD_code,
1271 sizeof(sum_DDDD_code));
1272
1273 double args[3];
1274 JValue result;
1275
1276 args[0] = 0.0;
1277 args[1] = 0.0;
1278 args[2] = 0.0;
1279 result.d = -1.0;
1280 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
1281 EXPECT_EQ(0.0, result.d);
1282
1283 args[0] = 1.0;
1284 args[1] = 2.0;
1285 args[2] = 3.0;
1286 result.d = 0.0;
1287 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
1288 EXPECT_EQ(6.0, result.d);
1289
1290 args[0] = 1.0;
1291 args[1] = -2.0;
1292 args[2] = 3.0;
1293 result.d = 0.0;
1294 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
1295 EXPECT_EQ(2.0, result.d);
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001296}
1297
1298TEST_F(JniInternalTest, StaticSumDoubleDoubleDoubleDoubleMethod) {
Brian Carlstroma663ea52011-08-19 23:33:41 -07001299 scoped_ptr<DexFile> dex(OpenDexFileBase64(kStaticLeafMethodsDex, "kStaticLeafMethodsDex"));
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001300
1301 PathClassLoader* class_loader = AllocPathClassLoader(dex.get());
1302 ASSERT_TRUE(class_loader != NULL);
1303
1304 Class* klass = class_linker_->FindClass("LStaticLeafMethods;", class_loader);
1305 ASSERT_TRUE(klass != NULL);
1306
1307 Method* method = klass->FindDirectMethod("sum", "(DDDD)D");
1308 ASSERT_TRUE(method != NULL);
1309
1310 byte sum_DDDDD_code[] = {
1311 0x2d, 0xe9, 0x00, 0x40, 0x87, 0xb0, 0xcd, 0xf8,
1312 0x00, 0x00, 0xcd, 0xf8, 0x24, 0x10, 0xcd, 0xf8,
1313 0x28, 0x20, 0xcd, 0xf8, 0x2c, 0x30, 0x9d, 0xed,
1314 0x09, 0x0b, 0x9d, 0xed, 0x0b, 0x1b, 0x30, 0xee,
1315 0x01, 0x2b, 0x8d, 0xed, 0x04, 0x2b, 0x9d, 0xed,
1316 0x04, 0x3b, 0x9d, 0xed, 0x0d, 0x4b, 0x33, 0xee,
1317 0x04, 0x3b, 0x8d, 0xed, 0x04, 0x3b, 0x9d, 0xed,
1318 0x04, 0x5b, 0x9d, 0xed, 0x0f, 0x6b, 0x35, 0xee,
1319 0x06, 0x5b, 0x8d, 0xed, 0x04, 0x5b, 0x04, 0x98,
1320 0x05, 0x99, 0x07, 0xb0, 0xbd, 0xe8, 0x00, 0x80,
1321 };
1322
1323 Method::InvokeStub* stub = AllocateStub(method,
1324 sum_DDDDD_code,
1325 sizeof(sum_DDDDD_code));
1326
1327 double args[4];
1328 JValue result;
1329
1330 args[0] = 0.0;
1331 args[1] = 0.0;
1332 args[2] = 0.0;
1333 args[3] = 0.0;
1334 result.d = -1.0;
1335 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
1336 EXPECT_EQ(0.0, result.d);
1337
1338 args[0] = 1.0;
1339 args[1] = 2.0;
1340 args[2] = 3.0;
1341 args[3] = 4.0;
1342 result.d = 0.0;
1343 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
1344 EXPECT_EQ(10.0, result.d);
1345
1346 args[0] = 1.0;
1347 args[1] = -2.0;
1348 args[2] = 3.0;
1349 args[3] = -4.0;
1350 result.d = 0.0;
1351 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
1352 EXPECT_EQ(-2.0, result.d);
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001353}
1354
1355TEST_F(JniInternalTest, StaticSumDoubleDoubleDoubleDoubleDoubleMethod) {
Brian Carlstroma663ea52011-08-19 23:33:41 -07001356 scoped_ptr<DexFile> dex(OpenDexFileBase64(kStaticLeafMethodsDex, "kStaticLeafMethodsDex"));
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001357
1358 PathClassLoader* class_loader = AllocPathClassLoader(dex.get());
1359 ASSERT_TRUE(class_loader != NULL);
1360
1361 Class* klass = class_linker_->FindClass("LStaticLeafMethods;", class_loader);
1362 ASSERT_TRUE(klass != NULL);
1363
1364 Method* method = klass->FindDirectMethod("sum", "(DDDDD)D");
1365 ASSERT_TRUE(method != NULL);
1366
1367 byte sum_DDDDDD_code[] = {
1368 0x2d, 0xe9, 0x00, 0x40, 0x87, 0xb0, 0xcd, 0xf8,
1369 0x00, 0x00, 0xcd, 0xf8, 0x24, 0x10, 0xcd, 0xf8,
1370 0x28, 0x20, 0xcd, 0xf8, 0x2c, 0x30, 0x9d, 0xed,
1371 0x09, 0x0b, 0x9d, 0xed, 0x0b, 0x1b, 0x30, 0xee,
1372 0x01, 0x2b, 0x8d, 0xed, 0x04, 0x2b, 0x9d, 0xed,
1373 0x04, 0x3b, 0x9d, 0xed, 0x0d, 0x4b, 0x33, 0xee,
1374 0x04, 0x3b, 0x8d, 0xed, 0x04, 0x3b, 0x9d, 0xed,
1375 0x04, 0x5b, 0x9d, 0xed, 0x0f, 0x6b, 0x35, 0xee,
1376 0x06, 0x5b, 0x8d, 0xed, 0x04, 0x5b, 0x9d, 0xed,
1377 0x04, 0x7b, 0x9d, 0xed, 0x11, 0x0b, 0x37, 0xee,
1378 0x00, 0x7b, 0x8d, 0xed, 0x04, 0x7b, 0x04, 0x98,
1379 0x05, 0x99, 0x07, 0xb0, 0xbd, 0xe8, 0x00, 0x80,
1380 };
1381
1382 Method::InvokeStub* stub = AllocateStub(method,
1383 sum_DDDDDD_code,
1384 sizeof(sum_DDDDDD_code));
1385
1386 double args[5];
1387 JValue result;
1388
1389 args[0] = 0.0;
1390 args[1] = 0.0;
1391 args[2] = 0.0;
1392 args[3] = 0.0;
1393 args[4] = 0.0;
1394 result.d = -1.0;
1395 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
1396 EXPECT_EQ(0.0, result.d);
1397
1398 args[0] = 1.0;
1399 args[1] = 2.0;
1400 args[2] = 3.0;
1401 args[3] = 4.0;
1402 args[4] = 5.0;
1403 result.d = 0.0;
1404 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
1405 EXPECT_EQ(15.0, result.d);
1406
1407 args[0] = 1.0;
1408 args[1] = -2.0;
1409 args[2] = 3.0;
1410 args[3] = -4.0;
1411 args[4] = 5.0;
1412 result.d = 0.0;
1413 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
1414 EXPECT_EQ(3.0, result.d);
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001415}
1416#endif // __arm__
1417
Elliott Hughes37f7a402011-08-22 18:56:01 -07001418TEST_F(JniInternalTest, Throw) {
1419 EXPECT_EQ(JNI_ERR, env_->Throw(NULL));
1420
1421 jclass exception_class = env_->FindClass("java/lang/RuntimeException");
1422 ASSERT_TRUE(exception_class != NULL);
1423 jthrowable exception = reinterpret_cast<jthrowable>(env_->AllocObject(exception_class));
1424 ASSERT_TRUE(exception != NULL);
1425
1426 EXPECT_EQ(JNI_OK, env_->Throw(exception));
1427 EXPECT_TRUE(env_->ExceptionCheck());
1428 EXPECT_TRUE(env_->IsSameObject(exception, env_->ExceptionOccurred()));
1429 env_->ExceptionClear();
1430}
1431
1432TEST_F(JniInternalTest, ThrowNew) {
1433 EXPECT_EQ(JNI_ERR, env_->Throw(NULL));
1434
1435 jclass exception_class = env_->FindClass("java/lang/RuntimeException");
1436 ASSERT_TRUE(exception_class != NULL);
1437
1438 EXPECT_EQ(JNI_OK, env_->ThrowNew(exception_class, "hello world"));
1439 EXPECT_TRUE(env_->ExceptionCheck());
1440 EXPECT_TRUE(env_->IsInstanceOf(env_->ExceptionOccurred(), exception_class));
1441 env_->ExceptionClear();
1442}
1443
Elliott Hughesb465ab02011-08-24 11:21:21 -07001444// TODO: this test is DISABLED until we can actually run java.nio.Buffer's <init>.
1445TEST_F(JniInternalTest, DISABLED_NewDirectBuffer_GetDirectBufferAddress_GetDirectBufferCapacity) {
1446 jclass buffer_class = env_->FindClass("java/nio/Buffer");
1447 ASSERT_TRUE(buffer_class != NULL);
1448
1449 char bytes[1024];
1450 jobject buffer = env_->NewDirectByteBuffer(bytes, sizeof(bytes));
1451 ASSERT_TRUE(buffer != NULL);
1452 ASSERT_TRUE(env_->IsInstanceOf(buffer, buffer_class));
1453 ASSERT_TRUE(env_->GetDirectBufferAddress(buffer) == bytes);
1454 ASSERT_TRUE(env_->GetDirectBufferCapacity(buffer) == sizeof(bytes));
1455}
1456
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001457}