blob: 81fda42df176328af55b1273d8d2ecc7bd6488a8 [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 Hughes814e4032011-08-23 12:07:56 -070022 aioobe_ = env_->FindClass("java/lang/ArrayIndexOutOfBoundsException");
23 CHECK(aioobe_ != NULL);
Elliott Hughesc7ac37f2011-08-12 12:21:58 -070024 }
25 JNIEnv* env_;
Elliott Hughes814e4032011-08-23 12:07:56 -070026 jclass aioobe_;
Elliott Hughes0c9cd562011-08-12 10:59:29 -070027};
28
Elliott Hughes885c3bd2011-08-22 16:59:20 -070029TEST_F(JniInternalTest, AllocObject) {
30 jclass c = env_->FindClass("java/lang/String");
31 ASSERT_TRUE(c != NULL);
32 jobject o = env_->AllocObject(c);
33 ASSERT_TRUE(o != NULL);
34
35 // We have an instance of the class we asked for...
36 ASSERT_TRUE(env_->IsInstanceOf(o, c));
37 // ...whose fields haven't been initialized because
38 // we didn't call a constructor.
39 ASSERT_EQ(0, env_->GetIntField(o, env_->GetFieldID(c, "count", "I")));
40 ASSERT_EQ(0, env_->GetIntField(o, env_->GetFieldID(c, "offset", "I")));
41 ASSERT_TRUE(env_->GetObjectField(o, env_->GetFieldID(c, "value", "[C")) == NULL);
42}
43
Elliott Hughesc7ac37f2011-08-12 12:21:58 -070044TEST_F(JniInternalTest, GetVersion) {
45 ASSERT_EQ(JNI_VERSION_1_6, env_->GetVersion());
46}
47
Elliott Hughes0c9cd562011-08-12 10:59:29 -070048#define EXPECT_CLASS_FOUND(NAME) \
Elliott Hughesbd935992011-08-22 11:59:34 -070049 EXPECT_TRUE(env_->FindClass(NAME) != NULL); \
50 EXPECT_FALSE(env_->ExceptionCheck())
Elliott Hughes0c9cd562011-08-12 10:59:29 -070051
52#define EXPECT_CLASS_NOT_FOUND(NAME) \
Elliott Hughesbd935992011-08-22 11:59:34 -070053 EXPECT_TRUE(env_->FindClass(NAME) == NULL); \
54 EXPECT_TRUE(env_->ExceptionCheck()); \
55 env_->ExceptionClear()
Elliott Hughes0c9cd562011-08-12 10:59:29 -070056
57TEST_F(JniInternalTest, FindClass) {
Elliott Hughes0c9cd562011-08-12 10:59:29 -070058 // TODO: when these tests start failing because you're calling FindClass
59 // with a pending exception, fix EXPECT_CLASS_NOT_FOUND to assert that an
60 // exception was thrown and clear the exception.
61
62 // TODO: . is only allowed as an alternative to / if CheckJNI is off.
63
64 // Reference types...
65 // You can't include the "L;" in a JNI class descriptor.
66 EXPECT_CLASS_FOUND("java/lang/String");
67 EXPECT_CLASS_NOT_FOUND("Ljava/lang/String;");
68 // We support . as well as / for compatibility.
69 EXPECT_CLASS_FOUND("java.lang.String");
70 EXPECT_CLASS_NOT_FOUND("Ljava.lang.String;");
71 // ...for arrays too, where you must include "L;".
72 EXPECT_CLASS_FOUND("[Ljava/lang/String;");
73 EXPECT_CLASS_NOT_FOUND("[java/lang/String");
74 EXPECT_CLASS_FOUND("[Ljava.lang.String;");
75 EXPECT_CLASS_NOT_FOUND("[java.lang.String");
76
77 // Primitive arrays are okay (if the primitive type is valid)...
78 EXPECT_CLASS_FOUND("[C");
79 EXPECT_CLASS_NOT_FOUND("[K");
80 // But primitive types aren't allowed...
81 EXPECT_CLASS_NOT_FOUND("C");
82 EXPECT_CLASS_NOT_FOUND("K");
83}
84
Elliott Hughescdf53122011-08-19 15:46:09 -070085#define EXPECT_EXCEPTION(exception_class) \
86 do { \
87 EXPECT_TRUE(env_->ExceptionCheck()); \
88 jthrowable exception = env_->ExceptionOccurred(); \
89 EXPECT_NE(static_cast<jthrowable>(NULL), exception); \
90 EXPECT_TRUE(env_->IsInstanceOf(exception, exception_class)); \
91 env_->ExceptionClear(); \
92 } while (false)
93
94TEST_F(JniInternalTest, GetFieldID) {
95 jclass jlnsfe = env_->FindClass("java/lang/NoSuchFieldError");
96 ASSERT_TRUE(jlnsfe != NULL);
97 jclass c = env_->FindClass("java/lang/String");
98 ASSERT_TRUE(c != NULL);
99
100 // Wrong type.
101 jfieldID fid = env_->GetFieldID(c, "count", "J");
102 EXPECT_EQ(static_cast<jfieldID>(NULL), fid);
103 EXPECT_EXCEPTION(jlnsfe);
104
105 // Wrong name.
106 fid = env_->GetFieldID(c, "Count", "I");
107 EXPECT_EQ(static_cast<jfieldID>(NULL), fid);
108 EXPECT_EXCEPTION(jlnsfe);
109
110 // Good declared field lookup.
111 fid = env_->GetFieldID(c, "count", "I");
112 EXPECT_NE(static_cast<jfieldID>(NULL), fid);
113 EXPECT_TRUE(fid != NULL);
114 EXPECT_FALSE(env_->ExceptionCheck());
115
116 // Good superclass field lookup.
117 c = env_->FindClass("java/lang/StringBuilder");
118 fid = env_->GetFieldID(c, "count", "I");
119 EXPECT_NE(static_cast<jfieldID>(NULL), fid);
120 EXPECT_TRUE(fid != NULL);
121 EXPECT_FALSE(env_->ExceptionCheck());
122
123 // Not instance.
124 fid = env_->GetFieldID(c, "CASE_INSENSITIVE_ORDER", "Ljava/util/Comparator;");
125 EXPECT_EQ(static_cast<jfieldID>(NULL), fid);
126 EXPECT_EXCEPTION(jlnsfe);
127}
128
129TEST_F(JniInternalTest, GetStaticFieldID) {
130 jclass jlnsfe = env_->FindClass("java/lang/NoSuchFieldError");
131 ASSERT_TRUE(jlnsfe != NULL);
132 jclass c = env_->FindClass("java/lang/String");
133 ASSERT_TRUE(c != NULL);
134
135 // Wrong type.
136 jfieldID fid = env_->GetStaticFieldID(c, "CASE_INSENSITIVE_ORDER", "J");
137 EXPECT_EQ(static_cast<jfieldID>(NULL), fid);
138 EXPECT_EXCEPTION(jlnsfe);
139
140 // Wrong name.
141 fid = env_->GetStaticFieldID(c, "cASE_INSENSITIVE_ORDER", "Ljava/util/Comparator;");
142 EXPECT_EQ(static_cast<jfieldID>(NULL), fid);
143 EXPECT_EXCEPTION(jlnsfe);
144
145 // Good declared field lookup.
146 fid = env_->GetStaticFieldID(c, "CASE_INSENSITIVE_ORDER", "Ljava/util/Comparator;");
147 EXPECT_NE(static_cast<jfieldID>(NULL), fid);
148 EXPECT_TRUE(fid != NULL);
149 EXPECT_FALSE(env_->ExceptionCheck());
150
151 // Not static.
152 fid = env_->GetStaticFieldID(c, "count", "I");
153 EXPECT_EQ(static_cast<jfieldID>(NULL), fid);
154 EXPECT_EXCEPTION(jlnsfe);
155}
156
Ian Rogers4dd71f12011-08-16 14:16:02 -0700157TEST_F(JniInternalTest, GetMethodID) {
158 jclass jlobject = env_->FindClass("java/lang/Object");
159 jclass jlstring = env_->FindClass("java/lang/String");
160 jclass jlnsme = env_->FindClass("java/lang/NoSuchMethodError");
161
162 // Sanity check that no exceptions are pending
Elliott Hughescdf53122011-08-19 15:46:09 -0700163 ASSERT_FALSE(env_->ExceptionCheck());
Ian Rogers4dd71f12011-08-16 14:16:02 -0700164
165 // Check that java.lang.Object.foo() doesn't exist and NoSuchMethodError is
166 // a pending exception
167 jmethodID method = env_->GetMethodID(jlobject, "foo", "()V");
168 EXPECT_EQ(static_cast<jmethodID>(NULL), method);
Elliott Hughescdf53122011-08-19 15:46:09 -0700169 EXPECT_EXCEPTION(jlnsme);
Ian Rogers4dd71f12011-08-16 14:16:02 -0700170
171 // Check that java.lang.Object.equals() does exist
Ian Rogers4dd71f12011-08-16 14:16:02 -0700172 method = env_->GetMethodID(jlobject, "equals", "(Ljava/lang/Object;)Z");
173 EXPECT_NE(static_cast<jmethodID>(NULL), method);
174 EXPECT_FALSE(env_->ExceptionCheck());
Ian Rogers4dd71f12011-08-16 14:16:02 -0700175
176 // Check that GetMethodID for java.lang.String.valueOf(int) fails as the
177 // method is static
178 method = env_->GetMethodID(jlstring, "valueOf", "(I)Ljava/lang/String;");
179 EXPECT_EQ(static_cast<jmethodID>(NULL), method);
Elliott Hughescdf53122011-08-19 15:46:09 -0700180 EXPECT_EXCEPTION(jlnsme);
Ian Rogers4dd71f12011-08-16 14:16:02 -0700181}
182
183TEST_F(JniInternalTest, GetStaticMethodID) {
184 jclass jlobject = env_->FindClass("java/lang/Object");
185 jclass jlnsme = env_->FindClass("java/lang/NoSuchMethodError");
186
187 // Sanity check that no exceptions are pending
Elliott Hughescdf53122011-08-19 15:46:09 -0700188 ASSERT_FALSE(env_->ExceptionCheck());
Ian Rogers4dd71f12011-08-16 14:16:02 -0700189
190 // Check that java.lang.Object.foo() doesn't exist and NoSuchMethodError is
191 // a pending exception
192 jmethodID method = env_->GetStaticMethodID(jlobject, "foo", "()V");
193 EXPECT_EQ(static_cast<jmethodID>(NULL), method);
Elliott Hughescdf53122011-08-19 15:46:09 -0700194 EXPECT_EXCEPTION(jlnsme);
Ian Rogers4dd71f12011-08-16 14:16:02 -0700195
196 // Check that GetStaticMethodID for java.lang.Object.equals(Object) fails as
197 // the method is not static
198 method = env_->GetStaticMethodID(jlobject, "equals", "(Ljava/lang/Object;)Z");
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 java.lang.String.valueOf(int) does exist
Ian Rogers4dd71f12011-08-16 14:16:02 -0700203 jclass jlstring = env_->FindClass("java/lang/String");
204 method = env_->GetStaticMethodID(jlstring, "valueOf",
205 "(I)Ljava/lang/String;");
206 EXPECT_NE(static_cast<jmethodID>(NULL), method);
207 EXPECT_FALSE(env_->ExceptionCheck());
Ian Rogers4dd71f12011-08-16 14:16:02 -0700208}
209
Elliott Hughescdf53122011-08-19 15:46:09 -0700210TEST_F(JniInternalTest, FromReflectedField_ToReflectedField) {
211 jclass jlrField = env_->FindClass("java/lang/reflect/Field");
212 jclass c = env_->FindClass("java/lang/String");
213 ASSERT_TRUE(c != NULL);
214 jfieldID fid = env_->GetFieldID(c, "count", "I");
215 ASSERT_TRUE(fid != NULL);
216 // Turn the fid into a java.lang.reflect.Field...
217 jobject field = env_->ToReflectedField(c, fid, JNI_FALSE);
218 ASSERT_TRUE(c != NULL);
219 ASSERT_TRUE(env_->IsInstanceOf(field, jlrField));
220 // ...and back again.
221 jfieldID fid2 = env_->FromReflectedField(field);
222 ASSERT_TRUE(fid2 != NULL);
223}
224
225TEST_F(JniInternalTest, FromReflectedMethod_ToReflectedMethod) {
226 jclass jlrMethod = env_->FindClass("java/lang/reflect/Method");
227 jclass c = env_->FindClass("java/lang/String");
228 ASSERT_TRUE(c != NULL);
229 jmethodID mid = env_->GetMethodID(c, "length", "()I");
230 ASSERT_TRUE(mid != NULL);
231 // Turn the mid into a java.lang.reflect.Method...
232 jobject method = env_->ToReflectedMethod(c, mid, JNI_FALSE);
233 ASSERT_TRUE(c != NULL);
234 ASSERT_TRUE(env_->IsInstanceOf(method, jlrMethod));
235 // ...and back again.
236 jmethodID mid2 = env_->FromReflectedMethod(method);
237 ASSERT_TRUE(mid2 != NULL);
238}
239
Elliott Hughes5174fe62011-08-23 15:12:35 -0700240void BogusMethod() {
241 // You can't pass NULL function pointers to RegisterNatives.
242}
243
Ian Rogers4dd71f12011-08-16 14:16:02 -0700244TEST_F(JniInternalTest, RegisterNatives) {
245 jclass jlobject = env_->FindClass("java/lang/Object");
246 jclass jlnsme = env_->FindClass("java/lang/NoSuchMethodError");
247
248 // Sanity check that no exceptions are pending
Elliott Hughescdf53122011-08-19 15:46:09 -0700249 ASSERT_FALSE(env_->ExceptionCheck());
Ian Rogers4dd71f12011-08-16 14:16:02 -0700250
251 // Check that registering to a non-existent java.lang.Object.foo() causes a
252 // NoSuchMethodError
253 {
254 JNINativeMethod methods[] = {{"foo", "()V", NULL}};
255 env_->RegisterNatives(jlobject, methods, 1);
256 }
Elliott Hughescdf53122011-08-19 15:46:09 -0700257 EXPECT_EXCEPTION(jlnsme);
Ian Rogers4dd71f12011-08-16 14:16:02 -0700258
259 // Check that registering non-native methods causes a NoSuchMethodError
260 {
261 JNINativeMethod methods[] = {{"equals", "(Ljava/lang/Object;)Z", NULL}};
262 env_->RegisterNatives(jlobject, methods, 1);
263 }
Elliott Hughescdf53122011-08-19 15:46:09 -0700264 EXPECT_EXCEPTION(jlnsme);
Ian Rogers4dd71f12011-08-16 14:16:02 -0700265
266 // Check that registering native methods is successful
267 {
Elliott Hughes5174fe62011-08-23 15:12:35 -0700268 JNINativeMethod methods[] = {{"hashCode", "()I", reinterpret_cast<void*>(BogusMethod)}};
Ian Rogers4dd71f12011-08-16 14:16:02 -0700269 env_->RegisterNatives(jlobject, methods, 1);
270 }
271 EXPECT_FALSE(env_->ExceptionCheck());
Elliott Hughes5174fe62011-08-23 15:12:35 -0700272
273 env_->UnregisterNatives(jlobject);
Ian Rogers4dd71f12011-08-16 14:16:02 -0700274}
275
Elliott Hughes814e4032011-08-23 12:07:56 -0700276#define EXPECT_PRIMITIVE_ARRAY(new_fn, get_region_fn, set_region_fn, scalar_type, expected_class_descriptor) \
277 jsize size = 4; \
278 /* Allocate an array and check it has the right type and length. */ \
279 scalar_type ## Array a = env_->new_fn(size); \
280 EXPECT_TRUE(a != NULL); \
281 EXPECT_TRUE(env_->IsInstanceOf(a, env_->FindClass(expected_class_descriptor))); \
282 EXPECT_EQ(size, env_->GetArrayLength(a)); \
283 /* AIOOBE for negative start offset. */ \
284 env_->get_region_fn(a, -1, 1, NULL); \
285 EXPECT_EXCEPTION(aioobe_); \
286 env_->set_region_fn(a, -1, 1, NULL); \
287 EXPECT_EXCEPTION(aioobe_); \
288 /* AIOOBE for negative length. */ \
289 env_->get_region_fn(a, 0, -1, NULL); \
290 EXPECT_EXCEPTION(aioobe_); \
291 env_->set_region_fn(a, 0, -1, NULL); \
292 EXPECT_EXCEPTION(aioobe_); \
293 /* AIOOBE for buffer overrun. */ \
294 env_->get_region_fn(a, size - 1, size, NULL); \
295 EXPECT_EXCEPTION(aioobe_); \
296 env_->set_region_fn(a, size - 1, size, NULL); \
297 EXPECT_EXCEPTION(aioobe_); \
298 /* Prepare a couple of buffers. */ \
299 scalar_type src_buf[size]; \
300 scalar_type dst_buf[size]; \
301 for (jsize i = 0; i < size; ++i) { src_buf[i] = scalar_type(i); } \
302 for (jsize i = 0; i < size; ++i) { dst_buf[i] = scalar_type(-1); } \
303 /* Copy all of src_buf onto the heap. */ \
304 env_->set_region_fn(a, 0, size, src_buf); \
305 /* Copy back only part. */ \
306 env_->get_region_fn(a, 1, size - 2, &dst_buf[1]); \
307 EXPECT_FALSE(memcmp(src_buf, dst_buf, sizeof(src_buf)) == 0) << "short copy equal"; \
308 /* Copy the missing pieces. */ \
309 env_->get_region_fn(a, 0, 1, dst_buf); \
310 env_->get_region_fn(a, size - 1, 1, &dst_buf[size - 1]); \
311 EXPECT_TRUE(memcmp(src_buf, dst_buf, sizeof(src_buf)) == 0) << "fixed copy not equal"; \
312 /* Copy back the whole array. */ \
313 env_->get_region_fn(a, 0, size, dst_buf); \
314 EXPECT_TRUE(memcmp(src_buf, dst_buf, sizeof(src_buf)) == 0) << "full copy not equal"
Elliott Hughesbd935992011-08-22 11:59:34 -0700315
Elliott Hughes814e4032011-08-23 12:07:56 -0700316TEST_F(JniInternalTest, BooleanArrays) {
317 EXPECT_PRIMITIVE_ARRAY(NewBooleanArray, GetBooleanArrayRegion, SetBooleanArrayRegion, jboolean, "[Z");
318}
319TEST_F(JniInternalTest, ByteArrays) {
320 EXPECT_PRIMITIVE_ARRAY(NewByteArray, GetByteArrayRegion, SetByteArrayRegion, jbyte, "[B");
321}
322TEST_F(JniInternalTest, CharArrays) {
323 EXPECT_PRIMITIVE_ARRAY(NewCharArray, GetCharArrayRegion, SetCharArrayRegion, jchar, "[C");
324}
325TEST_F(JniInternalTest, DoubleArrays) {
326 EXPECT_PRIMITIVE_ARRAY(NewDoubleArray, GetDoubleArrayRegion, SetDoubleArrayRegion, jdouble, "[D");
327}
328TEST_F(JniInternalTest, FloatArrays) {
329 EXPECT_PRIMITIVE_ARRAY(NewFloatArray, GetFloatArrayRegion, SetFloatArrayRegion, jfloat, "[F");
330}
331TEST_F(JniInternalTest, IntArrays) {
332 EXPECT_PRIMITIVE_ARRAY(NewIntArray, GetIntArrayRegion, SetIntArrayRegion, jint, "[I");
333}
334TEST_F(JniInternalTest, LongArrays) {
335 EXPECT_PRIMITIVE_ARRAY(NewLongArray, GetLongArrayRegion, SetLongArrayRegion, jlong, "[J");
336}
337TEST_F(JniInternalTest, ShortArrays) {
338 EXPECT_PRIMITIVE_ARRAY(NewShortArray, GetShortArrayRegion, SetShortArrayRegion, jshort, "[S");
Elliott Hughesd8ddfd52011-08-15 14:32:53 -0700339}
340
Elliott Hughesf2682d52011-08-15 16:37:04 -0700341TEST_F(JniInternalTest, NewObjectArray) {
342 // TODO: death tests for negative array sizes.
343
Elliott Hughesf2682d52011-08-15 16:37:04 -0700344 // TODO: check non-NULL initial elements.
345
Elliott Hughesbd935992011-08-22 11:59:34 -0700346 jclass element_class = env_->FindClass("java/lang/String");
347 ASSERT_TRUE(element_class != NULL);
348 jclass array_class = env_->FindClass("[Ljava/lang/String;");
349 ASSERT_TRUE(array_class != NULL);
Elliott Hughesf2682d52011-08-15 16:37:04 -0700350
Elliott Hughesbd935992011-08-22 11:59:34 -0700351 jobjectArray a;
Elliott Hughesf2682d52011-08-15 16:37:04 -0700352
Elliott Hughesbd935992011-08-22 11:59:34 -0700353 a = env_->NewObjectArray(0, element_class, NULL);
354 EXPECT_TRUE(a != NULL);
355 EXPECT_TRUE(env_->IsInstanceOf(a, array_class));
356 EXPECT_EQ(0, env_->GetArrayLength(a));
357
358 a = env_->NewObjectArray(1, element_class, NULL);
359 EXPECT_TRUE(a != NULL);
360 EXPECT_TRUE(env_->IsInstanceOf(a, array_class));
361 EXPECT_EQ(1, env_->GetArrayLength(a));
362}
363
364TEST_F(JniInternalTest, GetArrayLength) {
365 // Already tested in NewObjectArray/NewPrimitiveArray.
Elliott Hughes8a26c5c2011-08-15 18:35:43 -0700366}
367
Elliott Hughes37f7a402011-08-22 18:56:01 -0700368TEST_F(JniInternalTest, GetObjectClass) {
369 jclass string_class = env_->FindClass("java/lang/String");
370 ASSERT_TRUE(string_class != NULL);
371 jclass class_class = env_->FindClass("java/lang/Class");
372 ASSERT_TRUE(class_class != NULL);
373
374 jstring s = env_->NewStringUTF("poop");
375 jclass c = env_->GetObjectClass(s);
376 ASSERT_TRUE(env_->IsSameObject(string_class, c));
377
378 jclass c2 = env_->GetObjectClass(c);
379 ASSERT_TRUE(env_->IsSameObject(class_class, env_->GetObjectClass(c2)));
380}
381
Elliott Hughes885c3bd2011-08-22 16:59:20 -0700382TEST_F(JniInternalTest, GetSuperclass) {
383 jclass object_class = env_->FindClass("java/lang/Object");
384 ASSERT_TRUE(object_class != NULL);
385 jclass string_class = env_->FindClass("java/lang/String");
386 ASSERT_TRUE(string_class != NULL);
387 ASSERT_TRUE(env_->IsSameObject(object_class, env_->GetSuperclass(string_class)));
388 ASSERT_TRUE(env_->GetSuperclass(object_class) == NULL);
389}
390
Elliott Hughes37f7a402011-08-22 18:56:01 -0700391TEST_F(JniInternalTest, IsAssignableFrom) {
392 jclass object_class = env_->FindClass("java/lang/Object");
393 ASSERT_TRUE(object_class != NULL);
394 jclass string_class = env_->FindClass("java/lang/String");
395 ASSERT_TRUE(string_class != NULL);
396
397 ASSERT_TRUE(env_->IsAssignableFrom(object_class, string_class));
398 ASSERT_FALSE(env_->IsAssignableFrom(string_class, object_class));
399}
400
Elliott Hughes8a26c5c2011-08-15 18:35:43 -0700401TEST_F(JniInternalTest, NewStringUTF) {
402 EXPECT_TRUE(env_->NewStringUTF(NULL) == NULL);
Elliott Hughes814e4032011-08-23 12:07:56 -0700403 jstring s;
404
405 s = env_->NewStringUTF("");
406 EXPECT_TRUE(s != NULL);
407 EXPECT_EQ(0, env_->GetStringLength(s));
408 EXPECT_EQ(0, env_->GetStringUTFLength(s));
409 s = env_->NewStringUTF("hello");
410 EXPECT_TRUE(s != NULL);
411 EXPECT_EQ(5, env_->GetStringLength(s));
412 EXPECT_EQ(5, env_->GetStringUTFLength(s));
413
Elliott Hughes8a26c5c2011-08-15 18:35:43 -0700414 // TODO: check some non-ASCII strings.
Elliott Hughesf2682d52011-08-15 16:37:04 -0700415}
416
Elliott Hughes814e4032011-08-23 12:07:56 -0700417TEST_F(JniInternalTest, NewString) {
418 EXPECT_TRUE(env_->NewString(NULL, 0) == NULL);
419
420 jchar chars[] = { 'h', 'i' };
421 jstring s;
422 s = env_->NewString(chars, 0);
423 EXPECT_TRUE(s != NULL);
424 EXPECT_EQ(0, env_->GetStringLength(s));
425 EXPECT_EQ(0, env_->GetStringUTFLength(s));
426 s = env_->NewString(chars, 2);
427 EXPECT_TRUE(s != NULL);
428 EXPECT_EQ(2, env_->GetStringLength(s));
429 EXPECT_EQ(2, env_->GetStringUTFLength(s));
430
431 // TODO: check some non-ASCII strings.
432}
433
434TEST_F(JniInternalTest, GetObjectArrayElement_SetObjectArrayElement) {
Elliott Hughes289da822011-08-16 10:11:20 -0700435 jclass c = env_->FindClass("[Ljava/lang/Object;");
436 ASSERT_TRUE(c != NULL);
437
438 jobjectArray array = env_->NewObjectArray(1, c, NULL);
439 EXPECT_TRUE(array != NULL);
Elliott Hughes814e4032011-08-23 12:07:56 -0700440 EXPECT_TRUE(env_->GetObjectArrayElement(array, 0) == NULL);
Elliott Hughes289da822011-08-16 10:11:20 -0700441 env_->SetObjectArrayElement(array, 0, c);
Elliott Hughes814e4032011-08-23 12:07:56 -0700442 EXPECT_TRUE(env_->IsSameObject(env_->GetObjectArrayElement(array, 0), c));
Elliott Hughesa5b897e2011-08-16 11:33:06 -0700443
444 // ArrayIndexOutOfBounds for negative index.
Elliott Hughesa5b897e2011-08-16 11:33:06 -0700445 env_->SetObjectArrayElement(array, -1, c);
Elliott Hughes814e4032011-08-23 12:07:56 -0700446 EXPECT_EXCEPTION(aioobe_);
Elliott Hughesa5b897e2011-08-16 11:33:06 -0700447
448 // ArrayIndexOutOfBounds for too-large index.
Elliott Hughesa5b897e2011-08-16 11:33:06 -0700449 env_->SetObjectArrayElement(array, 1, c);
Elliott Hughes814e4032011-08-23 12:07:56 -0700450 EXPECT_EXCEPTION(aioobe_);
Elliott Hughesa5b897e2011-08-16 11:33:06 -0700451
Elliott Hughes289da822011-08-16 10:11:20 -0700452 // TODO: check ArrayStoreException thrown for bad types.
453}
454
Elliott Hughes885c3bd2011-08-22 16:59:20 -0700455#define EXPECT_STATIC_PRIMITIVE_FIELD(type, field_name, sig, value1, value2) \
456 do { \
457 jfieldID fid = env_->GetStaticFieldID(c, field_name, sig); \
458 EXPECT_TRUE(fid != NULL); \
459 env_->SetStatic ## type ## Field(c, fid, value1); \
460 EXPECT_EQ(value1, env_->GetStatic ## type ## Field(c, fid)); \
461 env_->SetStatic ## type ## Field(c, fid, value2); \
462 EXPECT_EQ(value2, env_->GetStatic ## type ## Field(c, fid)); \
463 } while (false)
464
465#define EXPECT_PRIMITIVE_FIELD(instance, type, field_name, sig, value1, value2) \
466 do { \
467 jfieldID fid = env_->GetFieldID(c, field_name, sig); \
468 EXPECT_TRUE(fid != NULL); \
469 env_->Set ## type ## Field(instance, fid, value1); \
470 EXPECT_EQ(value1, env_->Get ## type ## Field(instance, fid)); \
471 env_->Set ## type ## Field(instance, fid, value2); \
472 EXPECT_EQ(value2, env_->Get ## type ## Field(instance, fid)); \
473 } while (false)
474
475
476TEST_F(JniInternalTest, GetPrimitiveField_SetPrimitiveField) {
477 scoped_ptr<DexFile> dex(OpenDexFileBase64(kAllFields, "kAllFields"));
478 PathClassLoader* class_loader = AllocPathClassLoader(dex.get());
479 Thread::Current()->SetClassLoaderOverride(class_loader);
480
481 jclass c = env_->FindClass("AllFields");
482 ASSERT_TRUE(c != NULL);
483 jobject o = env_->AllocObject(c);
484 ASSERT_TRUE(o != NULL);
485
486 EXPECT_STATIC_PRIMITIVE_FIELD(Boolean, "sZ", "Z", true, false);
487 EXPECT_STATIC_PRIMITIVE_FIELD(Byte, "sB", "B", 1, 2);
488 EXPECT_STATIC_PRIMITIVE_FIELD(Char, "sC", "C", 'a', 'b');
489 EXPECT_STATIC_PRIMITIVE_FIELD(Double, "sD", "D", 1.0, 2.0);
490 EXPECT_STATIC_PRIMITIVE_FIELD(Float, "sF", "F", 1.0, 2.0);
491 EXPECT_STATIC_PRIMITIVE_FIELD(Int, "sI", "I", 1, 2);
492 EXPECT_STATIC_PRIMITIVE_FIELD(Long, "sJ", "J", 1, 2);
493 EXPECT_STATIC_PRIMITIVE_FIELD(Short, "sS", "S", 1, 2);
494
495 EXPECT_PRIMITIVE_FIELD(o, Boolean, "iZ", "Z", true, false);
496 EXPECT_PRIMITIVE_FIELD(o, Byte, "iB", "B", 1, 2);
497 EXPECT_PRIMITIVE_FIELD(o, Char, "iC", "C", 'a', 'b');
498 EXPECT_PRIMITIVE_FIELD(o, Double, "iD", "D", 1.0, 2.0);
499 EXPECT_PRIMITIVE_FIELD(o, Float, "iF", "F", 1.0, 2.0);
500 EXPECT_PRIMITIVE_FIELD(o, Int, "iI", "I", 1, 2);
501 EXPECT_PRIMITIVE_FIELD(o, Long, "iJ", "J", 1, 2);
502 EXPECT_PRIMITIVE_FIELD(o, Short, "iS", "S", 1, 2);
503}
504
505TEST_F(JniInternalTest, GetObjectField_SetObjectField) {
506 scoped_ptr<DexFile> dex(OpenDexFileBase64(kAllFields, "kAllFields"));
507 PathClassLoader* class_loader = AllocPathClassLoader(dex.get());
508 Thread::Current()->SetClassLoaderOverride(class_loader);
509
510 jclass c = env_->FindClass("AllFields");
511 ASSERT_TRUE(c != NULL);
512 jobject o = env_->AllocObject(c);
513 ASSERT_TRUE(o != NULL);
514
515 jstring s1 = env_->NewStringUTF("hello");
516 ASSERT_TRUE(s1 != NULL);
517 jstring s2 = env_->NewStringUTF("world");
518 ASSERT_TRUE(s2 != NULL);
519
520 jfieldID s_fid = env_->GetStaticFieldID(c, "sObject", "Ljava/lang/Object;");
521 ASSERT_TRUE(s_fid != NULL);
522 jfieldID i_fid = env_->GetFieldID(c, "iObject", "Ljava/lang/Object;");
523 ASSERT_TRUE(i_fid != NULL);
524
525 env_->SetStaticObjectField(c, s_fid, s1);
526 ASSERT_TRUE(env_->IsSameObject(s1, env_->GetStaticObjectField(c, s_fid)));
527 env_->SetStaticObjectField(c, s_fid, s2);
528 ASSERT_TRUE(env_->IsSameObject(s2, env_->GetStaticObjectField(c, s_fid)));
529
530 env_->SetObjectField(o, i_fid, s1);
531 ASSERT_TRUE(env_->IsSameObject(s1, env_->GetObjectField(o, i_fid)));
532 env_->SetObjectField(o, i_fid, s2);
533 ASSERT_TRUE(env_->IsSameObject(s2, env_->GetObjectField(o, i_fid)));
534}
535
Elliott Hughes18c07532011-08-18 15:50:51 -0700536TEST_F(JniInternalTest, NewLocalRef_NULL) {
537 EXPECT_TRUE(env_->NewLocalRef(NULL) == NULL);
538}
539
540TEST_F(JniInternalTest, NewLocalRef) {
541 jstring s = env_->NewStringUTF("");
542 ASSERT_TRUE(s != NULL);
543 jobject o = env_->NewLocalRef(s);
544 EXPECT_TRUE(o != NULL);
545 EXPECT_TRUE(o != s);
546
547 // TODO: check that o is a local reference.
548}
549
550TEST_F(JniInternalTest, DeleteLocalRef_NULL) {
551 env_->DeleteLocalRef(NULL);
552}
553
554TEST_F(JniInternalTest, DeleteLocalRef) {
555 jstring s = env_->NewStringUTF("");
556 ASSERT_TRUE(s != NULL);
557 env_->DeleteLocalRef(s);
558
559 // Currently, deleting an already-deleted reference is just a warning.
560 env_->DeleteLocalRef(s);
561
562 s = env_->NewStringUTF("");
563 ASSERT_TRUE(s != NULL);
564 jobject o = env_->NewLocalRef(s);
565 ASSERT_TRUE(o != NULL);
566
567 env_->DeleteLocalRef(s);
568 env_->DeleteLocalRef(o);
569}
570
571TEST_F(JniInternalTest, NewGlobalRef_NULL) {
572 EXPECT_TRUE(env_->NewGlobalRef(NULL) == NULL);
573}
574
575TEST_F(JniInternalTest, NewGlobalRef) {
576 jstring s = env_->NewStringUTF("");
577 ASSERT_TRUE(s != NULL);
578 jobject o = env_->NewGlobalRef(s);
579 EXPECT_TRUE(o != NULL);
580 EXPECT_TRUE(o != s);
581
582 // TODO: check that o is a global reference.
583}
584
585TEST_F(JniInternalTest, DeleteGlobalRef_NULL) {
586 env_->DeleteGlobalRef(NULL);
587}
588
589TEST_F(JniInternalTest, DeleteGlobalRef) {
590 jstring s = env_->NewStringUTF("");
591 ASSERT_TRUE(s != NULL);
592
593 jobject o = env_->NewGlobalRef(s);
594 ASSERT_TRUE(o != NULL);
595 env_->DeleteGlobalRef(o);
596
597 // Currently, deleting an already-deleted reference is just a warning.
598 env_->DeleteGlobalRef(o);
599
600 jobject o1 = env_->NewGlobalRef(s);
601 ASSERT_TRUE(o1 != NULL);
602 jobject o2 = env_->NewGlobalRef(s);
603 ASSERT_TRUE(o2 != NULL);
604
605 env_->DeleteGlobalRef(o1);
606 env_->DeleteGlobalRef(o2);
607}
608
609TEST_F(JniInternalTest, NewWeakGlobalRef_NULL) {
610 EXPECT_TRUE(env_->NewWeakGlobalRef(NULL) == NULL);
611}
612
613TEST_F(JniInternalTest, NewWeakGlobalRef) {
614 jstring s = env_->NewStringUTF("");
615 ASSERT_TRUE(s != NULL);
616 jobject o = env_->NewWeakGlobalRef(s);
617 EXPECT_TRUE(o != NULL);
618 EXPECT_TRUE(o != s);
619
620 // TODO: check that o is a weak global reference.
621}
622
623TEST_F(JniInternalTest, DeleteWeakGlobalRef_NULL) {
624 env_->DeleteWeakGlobalRef(NULL);
625}
626
627TEST_F(JniInternalTest, DeleteWeakGlobalRef) {
628 jstring s = env_->NewStringUTF("");
629 ASSERT_TRUE(s != NULL);
630
631 jobject o = env_->NewWeakGlobalRef(s);
632 ASSERT_TRUE(o != NULL);
633 env_->DeleteWeakGlobalRef(o);
634
635 // Currently, deleting an already-deleted reference is just a warning.
636 env_->DeleteWeakGlobalRef(o);
637
638 jobject o1 = env_->NewWeakGlobalRef(s);
639 ASSERT_TRUE(o1 != NULL);
640 jobject o2 = env_->NewWeakGlobalRef(s);
641 ASSERT_TRUE(o2 != NULL);
642
643 env_->DeleteWeakGlobalRef(o1);
644 env_->DeleteWeakGlobalRef(o2);
645}
646
Carl Shapiro9b9ba282011-08-14 15:30:39 -0700647bool EnsureInvokeStub(Method* method);
648
Carl Shapiro9b9ba282011-08-14 15:30:39 -0700649Method::InvokeStub* AllocateStub(Method* method,
650 byte* code,
651 size_t length) {
652 CHECK(method->GetInvokeStub() == NULL);
653 EnsureInvokeStub(method);
654 Method::InvokeStub* stub = method->GetInvokeStub();
655 CHECK(stub != NULL);
buzbeec143c552011-08-20 17:38:58 -0700656 method->SetCode(code, length, kThumb2);
Carl Shapiro9b9ba282011-08-14 15:30:39 -0700657 return stub;
658}
659
Carl Shapiro9b9ba282011-08-14 15:30:39 -0700660#if defined(__arm__)
661TEST_F(JniInternalTest, StaticMainMethod) {
Brian Carlstroma663ea52011-08-19 23:33:41 -0700662 scoped_ptr<DexFile> dex(OpenDexFileBase64(kMainDex, "kMainDex"));
Carl Shapiro9b9ba282011-08-14 15:30:39 -0700663
664 PathClassLoader* class_loader = AllocPathClassLoader(dex.get());
665 ASSERT_TRUE(class_loader != NULL);
666
667 Class* klass = class_linker_->FindClass("LMain;", class_loader);
668 ASSERT_TRUE(klass != NULL);
669
670 Method* method = klass->FindDirectMethod("main", "([Ljava/lang/String;)V");
671 ASSERT_TRUE(method != NULL);
672
673 byte main_LV_code[] = {
674 0x2d, 0xe9, 0x00, 0x40, 0x83, 0xb0, 0xcd, 0xf8, 0x00, 0x00,
675 0xcd, 0xf8, 0x14, 0x10, 0x03, 0xb0, 0xbd, 0xe8, 0x00, 0x80,
676 };
677
678 Method::InvokeStub* stub = AllocateStub(method,
679 main_LV_code,
680 sizeof(main_LV_code));
681
682 Object* arg = NULL;
683
684 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(&arg), NULL);
Carl Shapiro9b9ba282011-08-14 15:30:39 -0700685}
686
687TEST_F(JniInternalTest, StaticNopMethod) {
Brian Carlstroma663ea52011-08-19 23:33:41 -0700688 scoped_ptr<DexFile> dex(OpenDexFileBase64(kStaticLeafMethodsDex, "kStaticLeafMethodsDex"));
Carl Shapiro9b9ba282011-08-14 15:30:39 -0700689
690 PathClassLoader* class_loader = AllocPathClassLoader(dex.get());
691 ASSERT_TRUE(class_loader != NULL);
692
693 Class* klass = class_linker_->FindClass("LStaticLeafMethods;", class_loader);
694 ASSERT_TRUE(klass != NULL);
695
696 Method* method = klass->FindDirectMethod("nop", "()V");
697 ASSERT_TRUE(method != NULL);
698
699 byte nop_V_code[] = {
700 0x2d, 0xe9, 0x00, 0x40, 0x83, 0xb0, 0xcd, 0xf8,
701 0x00, 0x00, 0x03, 0xb0, 0xbd, 0xe8, 0x00, 0x80,
702 };
703
704 Method::InvokeStub* stub = AllocateStub(method,
705 nop_V_code,
706 sizeof(nop_V_code));
707 ASSERT_TRUE(stub);
708
709 (*stub)(method, NULL, NULL, NULL, NULL);
Carl Shapiro9b9ba282011-08-14 15:30:39 -0700710}
711
712TEST_F(JniInternalTest, StaticIdentityByteMethod) {
Brian Carlstroma663ea52011-08-19 23:33:41 -0700713 scoped_ptr<DexFile> dex(OpenDexFileBase64(kStaticLeafMethodsDex, "kStaticLeafMethodsDex"));
Carl Shapiro9b9ba282011-08-14 15:30:39 -0700714
715 PathClassLoader* class_loader = AllocPathClassLoader(dex.get());
716 ASSERT_TRUE(class_loader != NULL);
717
718 Class* klass = class_linker_->FindClass("LStaticLeafMethods;", class_loader);
719 ASSERT_TRUE(klass != NULL);
720
721 Method* method = klass->FindDirectMethod("identity", "(B)B");
722 ASSERT_TRUE(method != NULL);
723
724 byte identity_BB_code[] = {
725 0x2d, 0xe9, 0x00, 0x40, 0x83, 0xb0, 0xcd, 0xf8,
726 0x00, 0x00, 0xcd, 0xf8, 0x14, 0x10, 0x05, 0x98,
727 0x03, 0xb0, 0xbd, 0xe8, 0x00, 0x80, 0x00, 0x00,
728 };
729
730 Method::InvokeStub* stub = AllocateStub(method,
731 identity_BB_code,
732 sizeof(identity_BB_code));
733
734 int arg;
735 JValue result;
736
737 arg = 0;
738 result.b = -1;
739 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(&arg), &result);
740 EXPECT_EQ(0, result.b);
741
742 arg = -1;
743 result.b = 0;
744 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(&arg), &result);
745 EXPECT_EQ(-1, result.b);
746
747 arg = SCHAR_MAX;
748 result.b = 0;
749 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(&arg), &result);
750 EXPECT_EQ(SCHAR_MAX, result.b);
751
752 arg = SCHAR_MIN;
753 result.b = 0;
754 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(&arg), &result);
755 EXPECT_EQ(SCHAR_MIN, result.b);
Carl Shapiro9b9ba282011-08-14 15:30:39 -0700756}
757
758TEST_F(JniInternalTest, StaticIdentityIntMethod) {
Brian Carlstroma663ea52011-08-19 23:33:41 -0700759 scoped_ptr<DexFile> dex(OpenDexFileBase64(kStaticLeafMethodsDex, "kStaticLeafMethodsDex"));
Carl Shapiro9b9ba282011-08-14 15:30:39 -0700760
761 PathClassLoader* class_loader = AllocPathClassLoader(dex.get());
762 ASSERT_TRUE(class_loader != NULL);
763
764 Class* klass = class_linker_->FindClass("LStaticLeafMethods;", class_loader);
765 ASSERT_TRUE(klass != NULL);
766
767 Method* method = klass->FindDirectMethod("identity", "(I)I");
768 ASSERT_TRUE(method != NULL);
769
770 byte identity_II_code[] = {
771 0x2d, 0xe9, 0x00, 0x40, 0x83, 0xb0, 0xcd, 0xf8,
772 0x00, 0x00, 0xcd, 0xf8, 0x14, 0x10, 0x05, 0x98,
773 0x03, 0xb0, 0xbd, 0xe8, 0x00, 0x80, 0x00, 0x00,
774 };
775
776 Method::InvokeStub* stub = AllocateStub(method,
777 identity_II_code,
778 sizeof(identity_II_code));
779
780 int arg;
781 JValue result;
782
783 arg = 0;
784 result.i = -1;
785 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(&arg), &result);
786 EXPECT_EQ(0, result.i);
787
788 arg = -1;
789 result.i = 0;
790 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(&arg), &result);
791 EXPECT_EQ(-1, result.i);
792
793 arg = INT_MAX;
794 result.i = 0;
795 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(&arg), &result);
796 EXPECT_EQ(INT_MAX, result.i);
797
798 arg = INT_MIN;
799 result.i = 0;
800 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(&arg), &result);
801 EXPECT_EQ(INT_MIN, result.i);
Carl Shapiro9b9ba282011-08-14 15:30:39 -0700802}
803
804TEST_F(JniInternalTest, StaticIdentityDoubleMethod) {
Brian Carlstroma663ea52011-08-19 23:33:41 -0700805 scoped_ptr<DexFile> dex(OpenDexFileBase64(kStaticLeafMethodsDex, "kStaticLeafMethodsDex"));
Carl Shapiro9b9ba282011-08-14 15:30:39 -0700806
807 PathClassLoader* class_loader = AllocPathClassLoader(dex.get());
808 ASSERT_TRUE(class_loader != NULL);
809
810 Class* klass = class_linker_->FindClass("LStaticLeafMethods;", class_loader);
811 ASSERT_TRUE(klass != NULL);
812
813 Method* method = klass->FindDirectMethod("identity", "(D)D");
814 ASSERT_TRUE(method != NULL);
815
816 byte identity_DD_code[] = {
817 0x2d, 0xe9, 0x00, 0x40, 0x83, 0xb0, 0xcd, 0xf8,
818 0x00, 0x00, 0xcd, 0xf8, 0x14, 0x10, 0xcd, 0xf8,
819 0x18, 0x20, 0x05, 0x98, 0x06, 0x99, 0x03, 0xb0,
820 0xbd, 0xe8, 0x00, 0x80,
821 };
822
823 Method::InvokeStub* stub = AllocateStub(method,
824 identity_DD_code,
825 sizeof(identity_DD_code));
826
827 double arg;
828 JValue result;
829
830 arg = 0.0;
831 result.d = -1.0;
832 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(&arg), &result);
833 EXPECT_EQ(0.0, result.d);
834
835 arg = -1.0;
836 result.d = 0.0;
837 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(&arg), &result);
838 EXPECT_EQ(-1.0, result.d);
839
840 arg = DBL_MAX;
841 result.d = 0.0;
842 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(&arg), &result);
843 EXPECT_EQ(DBL_MAX, result.d);
844
845 arg = DBL_MIN;
846 result.d = 0.0;
847 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(&arg), &result);
848 EXPECT_EQ(DBL_MIN, result.d);
Carl Shapiro9b9ba282011-08-14 15:30:39 -0700849}
850
851TEST_F(JniInternalTest, StaticSumIntIntMethod) {
Brian Carlstroma663ea52011-08-19 23:33:41 -0700852 scoped_ptr<DexFile> dex(OpenDexFileBase64(kStaticLeafMethodsDex, "kStaticLeafMethodsDex"));
Carl Shapiro9b9ba282011-08-14 15:30:39 -0700853
854 PathClassLoader* class_loader = AllocPathClassLoader(dex.get());
855 ASSERT_TRUE(class_loader != NULL);
856
857 Class* klass = class_linker_->FindClass("LStaticLeafMethods;", class_loader);
858 ASSERT_TRUE(klass != NULL);
859
860 Method* method = klass->FindDirectMethod("sum", "(II)I");
861 ASSERT_TRUE(method != NULL);
862
863 byte sum_III_code[] = {
864 0x2d, 0xe9, 0x00, 0x40, 0x83, 0xb0, 0xcd, 0xf8,
865 0x00, 0x00, 0xcd, 0xf8, 0x14, 0x10, 0xcd, 0xf8,
866 0x18, 0x20, 0x05, 0x98, 0x06, 0x99, 0x42, 0x18,
867 0xcd, 0xf8, 0x04, 0x20, 0x01, 0x98, 0x03, 0xb0,
868 0xbd, 0xe8, 0x00, 0x80,
869 };
870
871 Method::InvokeStub* stub = AllocateStub(method,
872 sum_III_code,
873 sizeof(sum_III_code));
874
875 int args[2];
876 JValue result;
877
878 args[0] = 0;
879 args[1] = 0;
880 result.i = -1;
881 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
882 EXPECT_EQ(0, result.i);
883
884 args[0] = 1;
885 args[1] = 2;
886 result.i = 0;
887 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
888 EXPECT_EQ(3, result.i);
889
890 args[0] = -2;
891 args[1] = 5;
892 result.i = 0;
893 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
894 EXPECT_EQ(3, result.i);
895
896 args[0] = INT_MAX;
897 args[1] = INT_MIN;
898 result.i = 1234;
899 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
900 EXPECT_EQ(-1, result.i);
901
902 args[0] = INT_MAX;
903 args[1] = INT_MAX;
904 result.i = INT_MIN;
905 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
906 EXPECT_EQ(-2, result.i);
Carl Shapiro9b9ba282011-08-14 15:30:39 -0700907}
908
909TEST_F(JniInternalTest, StaticSumIntIntIntMethod) {
Brian Carlstroma663ea52011-08-19 23:33:41 -0700910 scoped_ptr<DexFile> dex(OpenDexFileBase64(kStaticLeafMethodsDex, "kStaticLeafMethodsDex"));
Carl Shapiro9b9ba282011-08-14 15:30:39 -0700911
912 PathClassLoader* class_loader = AllocPathClassLoader(dex.get());
913 ASSERT_TRUE(class_loader != NULL);
914
915 Class* klass = class_linker_->FindClass("LStaticLeafMethods;", class_loader);
916 ASSERT_TRUE(klass != NULL);
917
918 Method* method = klass->FindDirectMethod("sum", "(III)I");
919 ASSERT_TRUE(method != NULL);
920
921 byte sum_IIII_code[] = {
922 0x2d, 0xe9, 0x00, 0x40, 0x83, 0xb0, 0xcd, 0xf8,
923 0x00, 0x00, 0xcd, 0xf8, 0x14, 0x10, 0xcd, 0xf8,
924 0x18, 0x20, 0xcd, 0xf8, 0x1c, 0x30, 0x05, 0x98,
925 0x06, 0x99, 0x42, 0x18, 0xcd, 0xf8, 0x04, 0x20,
926 0x01, 0x9b, 0xdd, 0xf8, 0x1c, 0xc0, 0x13, 0xeb,
927 0x0c, 0x03, 0xcd, 0xf8, 0x04, 0x30, 0x01, 0x98,
928 0x03, 0xb0, 0xbd, 0xe8, 0x00, 0x80, 0x00, 0x00,
929 };
930
931 Method::InvokeStub* stub = AllocateStub(method,
932 sum_IIII_code,
933 sizeof(sum_IIII_code));
934
935 int args[3];
936 JValue result;
937
938 args[0] = 0;
939 args[1] = 0;
940 args[2] = 0;
941 result.i = -1;
942 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
943 EXPECT_EQ(0, result.i);
944
945 args[0] = 1;
946 args[1] = 2;
947 args[2] = 3;
948 result.i = 0;
949 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
950 EXPECT_EQ(6, result.i);
951
952 args[0] = -1;
953 args[1] = 2;
954 args[2] = -3;
955 result.i = 0;
956 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
957 EXPECT_EQ(-2, result.i);
958
959 args[0] = INT_MAX;
960 args[1] = INT_MIN;
961 args[2] = INT_MAX;
962 result.i = 1234;
963 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
964 EXPECT_EQ(2147483646, result.i);
965
966 args[0] = INT_MAX;
967 args[1] = INT_MAX;
968 args[2] = INT_MAX;
969 result.i = INT_MIN;
970 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
971 EXPECT_EQ(2147483645, result.i);
Carl Shapiro9b9ba282011-08-14 15:30:39 -0700972}
973
974TEST_F(JniInternalTest, StaticSumIntIntIntIntMethod) {
Brian Carlstroma663ea52011-08-19 23:33:41 -0700975 scoped_ptr<DexFile> dex(OpenDexFileBase64(kStaticLeafMethodsDex, "kStaticLeafMethodsDex"));
Carl Shapiro9b9ba282011-08-14 15:30:39 -0700976
977 PathClassLoader* class_loader = AllocPathClassLoader(dex.get());
978 ASSERT_TRUE(class_loader != NULL);
979
980 Class* klass = class_linker_->FindClass("LStaticLeafMethods;", class_loader);
981 ASSERT_TRUE(klass != NULL);
982
983 Method* method = klass->FindDirectMethod("sum", "(IIII)I");
984 ASSERT_TRUE(method != NULL);
985
986 byte sum_IIIII_code[] = {
987 0x2d, 0xe9, 0x00, 0x40, 0x83, 0xb0, 0xcd, 0xf8,
988 0x00, 0x00, 0xcd, 0xf8, 0x14, 0x10, 0xcd, 0xf8,
989 0x18, 0x20, 0xcd, 0xf8, 0x1c, 0x30, 0x05, 0x98,
990 0x06, 0x99, 0x42, 0x18, 0xcd, 0xf8, 0x04, 0x20,
991 0x01, 0x9b, 0xdd, 0xf8, 0x1c, 0xc0, 0x13, 0xeb,
992 0x0c, 0x03, 0xcd, 0xf8, 0x04, 0x30, 0x01, 0x98,
993 0x08, 0x99, 0x40, 0x18, 0xcd, 0xf8, 0x04, 0x00,
994 0x01, 0x98, 0x03, 0xb0, 0xbd, 0xe8, 0x00, 0x80,
995 };
996
997 Method::InvokeStub* stub = AllocateStub(method,
998 sum_IIIII_code,
999 sizeof(sum_IIIII_code));
1000
1001 int args[4];
1002 JValue result;
1003
1004 args[0] = 0;
1005 args[1] = 0;
1006 args[2] = 0;
1007 args[3] = 0;
1008 result.i = -1;
1009 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
1010 EXPECT_EQ(0, result.i);
1011
1012 args[0] = 1;
1013 args[1] = 2;
1014 args[2] = 3;
1015 args[3] = 4;
1016 result.i = 0;
1017 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
1018 EXPECT_EQ(10, result.i);
1019
1020 args[0] = -1;
1021 args[1] = 2;
1022 args[2] = -3;
1023 args[3] = 4;
1024 result.i = 0;
1025 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
1026 EXPECT_EQ(2, result.i);
1027
1028 args[0] = INT_MAX;
1029 args[1] = INT_MIN;
1030 args[2] = INT_MAX;
1031 args[3] = INT_MIN;
1032 result.i = 1234;
1033 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
1034 EXPECT_EQ(-2, result.i);
1035
1036 args[0] = INT_MAX;
1037 args[1] = INT_MAX;
1038 args[2] = INT_MAX;
1039 args[3] = INT_MAX;
1040 result.i = INT_MIN;
1041 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
1042 EXPECT_EQ(-4, result.i);
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001043}
1044
1045TEST_F(JniInternalTest, StaticSumIntIntIntIntIntMethod) {
Brian Carlstroma663ea52011-08-19 23:33:41 -07001046 scoped_ptr<DexFile> dex(OpenDexFileBase64(kStaticLeafMethodsDex, "kStaticLeafMethodsDex"));
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001047
1048 PathClassLoader* class_loader = AllocPathClassLoader(dex.get());
1049 ASSERT_TRUE(class_loader != NULL);
1050
1051 Class* klass = class_linker_->FindClass("LStaticLeafMethods;", class_loader);
1052 ASSERT_TRUE(klass != NULL);
1053
1054 Method* method = klass->FindDirectMethod("sum", "(IIIII)I");
1055 ASSERT_TRUE(method != NULL);
1056
1057 byte sum_IIIIII_code[] = {
1058 0x2d, 0xe9, 0x00, 0x40, 0x83, 0xb0, 0xcd, 0xf8,
1059 0x00, 0x00, 0xcd, 0xf8, 0x14, 0x10, 0xcd, 0xf8,
1060 0x18, 0x20, 0xcd, 0xf8, 0x1c, 0x30, 0x05, 0x98,
1061 0x06, 0x99, 0x42, 0x18, 0xcd, 0xf8, 0x04, 0x20,
1062 0x01, 0x9b, 0xdd, 0xf8, 0x1c, 0xc0, 0x13, 0xeb,
1063 0x0c, 0x03, 0xcd, 0xf8, 0x04, 0x30, 0x01, 0x98,
1064 0x08, 0x99, 0x40, 0x18, 0xcd, 0xf8, 0x04, 0x00,
1065 0x01, 0x9a, 0x09, 0x9b, 0xd2, 0x18, 0xcd, 0xf8,
1066 0x04, 0x20, 0x01, 0x98, 0x03, 0xb0, 0xbd, 0xe8,
1067 0x00, 0x80, 0x00, 0x00,
1068 };
1069
1070 Method::InvokeStub* stub = AllocateStub(method,
1071 sum_IIIIII_code,
1072 sizeof(sum_IIIIII_code));
1073
1074 int args[5];
1075 JValue result;
1076
1077 args[0] = 0;
1078 args[1] = 0;
1079 args[2] = 0;
1080 args[3] = 0;
1081 args[4] = 0;
1082 result.i = -1.0;
1083 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
1084 EXPECT_EQ(0, result.i);
1085
1086 args[0] = 1;
1087 args[1] = 2;
1088 args[2] = 3;
1089 args[3] = 4;
1090 args[4] = 5;
1091 result.i = 0;
1092 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
1093 EXPECT_EQ(15, result.i);
1094
1095 args[0] = -1;
1096 args[1] = 2;
1097 args[2] = -3;
1098 args[3] = 4;
1099 args[4] = -5;
1100 result.i = 0;
1101 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
1102 EXPECT_EQ(-3, result.i);
1103
1104 args[0] = INT_MAX;
1105 args[1] = INT_MIN;
1106 args[2] = INT_MAX;
1107 args[3] = INT_MIN;
1108 args[4] = INT_MAX;
1109 result.i = 1234;
1110 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
1111 EXPECT_EQ(2147483645, result.i);
1112
1113 args[0] = INT_MAX;
1114 args[1] = INT_MAX;
1115 args[2] = INT_MAX;
1116 args[3] = INT_MAX;
1117 args[4] = INT_MAX;
1118 result.i = INT_MIN;
1119 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
1120 EXPECT_EQ(2147483643, result.i);
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001121}
1122
1123TEST_F(JniInternalTest, StaticSumDoubleDoubleMethod) {
Brian Carlstroma663ea52011-08-19 23:33:41 -07001124 scoped_ptr<DexFile> dex(OpenDexFileBase64(kStaticLeafMethodsDex, "kStaticLeafMethodsDex"));
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001125
1126 PathClassLoader* class_loader = AllocPathClassLoader(dex.get());
1127 ASSERT_TRUE(class_loader != NULL);
1128
1129 Class* klass = class_linker_->FindClass("LStaticLeafMethods;", class_loader);
1130 ASSERT_TRUE(klass != NULL);
1131
1132 Method* method = klass->FindDirectMethod("sum", "(DD)D");
1133 ASSERT_TRUE(method != NULL);
1134
1135 byte sum_DDD_code[] = {
1136 0x2d, 0xe9, 0x00, 0x40, 0x87, 0xb0, 0xcd, 0xf8,
1137 0x00, 0x00, 0xcd, 0xf8, 0x24, 0x10, 0xcd, 0xf8,
1138 0x28, 0x20, 0xcd, 0xf8, 0x2c, 0x30, 0x9d, 0xed,
1139 0x09, 0x0b, 0x9d, 0xed, 0x0b, 0x1b, 0x30, 0xee,
1140 0x01, 0x2b, 0x8d, 0xed, 0x04, 0x2b, 0x04, 0x98,
1141 0x05, 0x99, 0x07, 0xb0, 0xbd, 0xe8, 0x00, 0x80,
1142 };
1143
1144 Method::InvokeStub* stub = AllocateStub(method,
1145 sum_DDD_code,
1146 sizeof(sum_DDD_code));
1147
1148 double args[2];
1149 JValue result;
1150
1151 args[0] = 0.0;
1152 args[1] = 0.0;
1153 result.d = -1.0;
1154 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
1155 EXPECT_EQ(0.0, result.d);
1156
1157 args[0] = 1.0;
1158 args[1] = 2.0;
1159 result.d = 0.0;
1160 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
1161 EXPECT_EQ(3.0, result.d);
1162
1163 args[0] = 1.0;
1164 args[1] = -2.0;
1165 result.d = 0.0;
1166 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
1167 EXPECT_EQ(-1.0, result.d);
1168
1169 args[0] = DBL_MAX;
1170 args[1] = DBL_MIN;
1171 result.d = 0.0;
1172 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
1173 EXPECT_EQ(1.7976931348623157e308, result.d);
1174
1175 args[0] = DBL_MAX;
1176 args[1] = DBL_MAX;
1177 result.d = 0.0;
1178 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
1179 EXPECT_EQ(INFINITY, result.d);
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001180}
1181
1182TEST_F(JniInternalTest, StaticSumDoubleDoubleDoubleMethod) {
Brian Carlstroma663ea52011-08-19 23:33:41 -07001183 scoped_ptr<DexFile> dex(OpenDexFileBase64(kStaticLeafMethodsDex, "kStaticLeafMethodsDex"));
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001184
1185 PathClassLoader* class_loader = AllocPathClassLoader(dex.get());
1186 ASSERT_TRUE(class_loader != NULL);
1187
1188 Class* klass = class_linker_->FindClass("LStaticLeafMethods;", class_loader);
1189 ASSERT_TRUE(klass != NULL);
1190
1191 Method* method = klass->FindDirectMethod("sum", "(DDD)D");
1192 ASSERT_TRUE(method != NULL);
1193
1194 byte sum_DDDD_code[] = {
1195 0x2d, 0xe9, 0x00, 0x40, 0x87, 0xb0, 0xcd, 0xf8,
1196 0x00, 0x00, 0xcd, 0xf8, 0x24, 0x10, 0xcd, 0xf8,
1197 0x28, 0x20, 0xcd, 0xf8, 0x2c, 0x30, 0x9d, 0xed,
1198 0x09, 0x0b, 0x9d, 0xed, 0x0b, 0x1b, 0x30, 0xee,
1199 0x01, 0x2b, 0x8d, 0xed, 0x04, 0x2b, 0x9d, 0xed,
1200 0x04, 0x3b, 0x9d, 0xed, 0x0d, 0x4b, 0x33, 0xee,
1201 0x04, 0x3b, 0x8d, 0xed, 0x04, 0x3b, 0x04, 0x98,
1202 0x05, 0x99, 0x07, 0xb0, 0xbd, 0xe8, 0x00, 0x80,
1203 };
1204
1205 Method::InvokeStub* stub = AllocateStub(method,
1206 sum_DDDD_code,
1207 sizeof(sum_DDDD_code));
1208
1209 double args[3];
1210 JValue result;
1211
1212 args[0] = 0.0;
1213 args[1] = 0.0;
1214 args[2] = 0.0;
1215 result.d = -1.0;
1216 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
1217 EXPECT_EQ(0.0, result.d);
1218
1219 args[0] = 1.0;
1220 args[1] = 2.0;
1221 args[2] = 3.0;
1222 result.d = 0.0;
1223 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
1224 EXPECT_EQ(6.0, result.d);
1225
1226 args[0] = 1.0;
1227 args[1] = -2.0;
1228 args[2] = 3.0;
1229 result.d = 0.0;
1230 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
1231 EXPECT_EQ(2.0, result.d);
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001232}
1233
1234TEST_F(JniInternalTest, StaticSumDoubleDoubleDoubleDoubleMethod) {
Brian Carlstroma663ea52011-08-19 23:33:41 -07001235 scoped_ptr<DexFile> dex(OpenDexFileBase64(kStaticLeafMethodsDex, "kStaticLeafMethodsDex"));
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001236
1237 PathClassLoader* class_loader = AllocPathClassLoader(dex.get());
1238 ASSERT_TRUE(class_loader != NULL);
1239
1240 Class* klass = class_linker_->FindClass("LStaticLeafMethods;", class_loader);
1241 ASSERT_TRUE(klass != NULL);
1242
1243 Method* method = klass->FindDirectMethod("sum", "(DDDD)D");
1244 ASSERT_TRUE(method != NULL);
1245
1246 byte sum_DDDDD_code[] = {
1247 0x2d, 0xe9, 0x00, 0x40, 0x87, 0xb0, 0xcd, 0xf8,
1248 0x00, 0x00, 0xcd, 0xf8, 0x24, 0x10, 0xcd, 0xf8,
1249 0x28, 0x20, 0xcd, 0xf8, 0x2c, 0x30, 0x9d, 0xed,
1250 0x09, 0x0b, 0x9d, 0xed, 0x0b, 0x1b, 0x30, 0xee,
1251 0x01, 0x2b, 0x8d, 0xed, 0x04, 0x2b, 0x9d, 0xed,
1252 0x04, 0x3b, 0x9d, 0xed, 0x0d, 0x4b, 0x33, 0xee,
1253 0x04, 0x3b, 0x8d, 0xed, 0x04, 0x3b, 0x9d, 0xed,
1254 0x04, 0x5b, 0x9d, 0xed, 0x0f, 0x6b, 0x35, 0xee,
1255 0x06, 0x5b, 0x8d, 0xed, 0x04, 0x5b, 0x04, 0x98,
1256 0x05, 0x99, 0x07, 0xb0, 0xbd, 0xe8, 0x00, 0x80,
1257 };
1258
1259 Method::InvokeStub* stub = AllocateStub(method,
1260 sum_DDDDD_code,
1261 sizeof(sum_DDDDD_code));
1262
1263 double args[4];
1264 JValue result;
1265
1266 args[0] = 0.0;
1267 args[1] = 0.0;
1268 args[2] = 0.0;
1269 args[3] = 0.0;
1270 result.d = -1.0;
1271 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
1272 EXPECT_EQ(0.0, result.d);
1273
1274 args[0] = 1.0;
1275 args[1] = 2.0;
1276 args[2] = 3.0;
1277 args[3] = 4.0;
1278 result.d = 0.0;
1279 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
1280 EXPECT_EQ(10.0, result.d);
1281
1282 args[0] = 1.0;
1283 args[1] = -2.0;
1284 args[2] = 3.0;
1285 args[3] = -4.0;
1286 result.d = 0.0;
1287 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
1288 EXPECT_EQ(-2.0, result.d);
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001289}
1290
1291TEST_F(JniInternalTest, StaticSumDoubleDoubleDoubleDoubleDoubleMethod) {
Brian Carlstroma663ea52011-08-19 23:33:41 -07001292 scoped_ptr<DexFile> dex(OpenDexFileBase64(kStaticLeafMethodsDex, "kStaticLeafMethodsDex"));
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001293
1294 PathClassLoader* class_loader = AllocPathClassLoader(dex.get());
1295 ASSERT_TRUE(class_loader != NULL);
1296
1297 Class* klass = class_linker_->FindClass("LStaticLeafMethods;", class_loader);
1298 ASSERT_TRUE(klass != NULL);
1299
1300 Method* method = klass->FindDirectMethod("sum", "(DDDDD)D");
1301 ASSERT_TRUE(method != NULL);
1302
1303 byte sum_DDDDDD_code[] = {
1304 0x2d, 0xe9, 0x00, 0x40, 0x87, 0xb0, 0xcd, 0xf8,
1305 0x00, 0x00, 0xcd, 0xf8, 0x24, 0x10, 0xcd, 0xf8,
1306 0x28, 0x20, 0xcd, 0xf8, 0x2c, 0x30, 0x9d, 0xed,
1307 0x09, 0x0b, 0x9d, 0xed, 0x0b, 0x1b, 0x30, 0xee,
1308 0x01, 0x2b, 0x8d, 0xed, 0x04, 0x2b, 0x9d, 0xed,
1309 0x04, 0x3b, 0x9d, 0xed, 0x0d, 0x4b, 0x33, 0xee,
1310 0x04, 0x3b, 0x8d, 0xed, 0x04, 0x3b, 0x9d, 0xed,
1311 0x04, 0x5b, 0x9d, 0xed, 0x0f, 0x6b, 0x35, 0xee,
1312 0x06, 0x5b, 0x8d, 0xed, 0x04, 0x5b, 0x9d, 0xed,
1313 0x04, 0x7b, 0x9d, 0xed, 0x11, 0x0b, 0x37, 0xee,
1314 0x00, 0x7b, 0x8d, 0xed, 0x04, 0x7b, 0x04, 0x98,
1315 0x05, 0x99, 0x07, 0xb0, 0xbd, 0xe8, 0x00, 0x80,
1316 };
1317
1318 Method::InvokeStub* stub = AllocateStub(method,
1319 sum_DDDDDD_code,
1320 sizeof(sum_DDDDDD_code));
1321
1322 double args[5];
1323 JValue result;
1324
1325 args[0] = 0.0;
1326 args[1] = 0.0;
1327 args[2] = 0.0;
1328 args[3] = 0.0;
1329 args[4] = 0.0;
1330 result.d = -1.0;
1331 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
1332 EXPECT_EQ(0.0, result.d);
1333
1334 args[0] = 1.0;
1335 args[1] = 2.0;
1336 args[2] = 3.0;
1337 args[3] = 4.0;
1338 args[4] = 5.0;
1339 result.d = 0.0;
1340 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
1341 EXPECT_EQ(15.0, result.d);
1342
1343 args[0] = 1.0;
1344 args[1] = -2.0;
1345 args[2] = 3.0;
1346 args[3] = -4.0;
1347 args[4] = 5.0;
1348 result.d = 0.0;
1349 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
1350 EXPECT_EQ(3.0, result.d);
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001351}
1352#endif // __arm__
1353
Elliott Hughes37f7a402011-08-22 18:56:01 -07001354TEST_F(JniInternalTest, Throw) {
1355 EXPECT_EQ(JNI_ERR, env_->Throw(NULL));
1356
1357 jclass exception_class = env_->FindClass("java/lang/RuntimeException");
1358 ASSERT_TRUE(exception_class != NULL);
1359 jthrowable exception = reinterpret_cast<jthrowable>(env_->AllocObject(exception_class));
1360 ASSERT_TRUE(exception != NULL);
1361
1362 EXPECT_EQ(JNI_OK, env_->Throw(exception));
1363 EXPECT_TRUE(env_->ExceptionCheck());
1364 EXPECT_TRUE(env_->IsSameObject(exception, env_->ExceptionOccurred()));
1365 env_->ExceptionClear();
1366}
1367
1368TEST_F(JniInternalTest, ThrowNew) {
1369 EXPECT_EQ(JNI_ERR, env_->Throw(NULL));
1370
1371 jclass exception_class = env_->FindClass("java/lang/RuntimeException");
1372 ASSERT_TRUE(exception_class != NULL);
1373
1374 EXPECT_EQ(JNI_OK, env_->ThrowNew(exception_class, "hello world"));
1375 EXPECT_TRUE(env_->ExceptionCheck());
1376 EXPECT_TRUE(env_->IsInstanceOf(env_->ExceptionOccurred(), exception_class));
1377 env_->ExceptionClear();
1378}
1379
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001380}