blob: 6c5d6f2741354c759ccd707c36626ab3b3ee84ae [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 Hughesc7ac37f2011-08-12 12:21:58 -070017 env_ = Thread::Current()->GetJniEnv();
18 }
19 JNIEnv* env_;
Elliott Hughes0c9cd562011-08-12 10:59:29 -070020};
21
Elliott Hughesc7ac37f2011-08-12 12:21:58 -070022TEST_F(JniInternalTest, GetVersion) {
23 ASSERT_EQ(JNI_VERSION_1_6, env_->GetVersion());
24}
25
Elliott Hughes0c9cd562011-08-12 10:59:29 -070026#define EXPECT_CLASS_FOUND(NAME) \
Elliott Hughesc7ac37f2011-08-12 12:21:58 -070027 EXPECT_TRUE(env_->FindClass(NAME) != NULL)
Elliott Hughes0c9cd562011-08-12 10:59:29 -070028
29#define EXPECT_CLASS_NOT_FOUND(NAME) \
Elliott Hughesc7ac37f2011-08-12 12:21:58 -070030 EXPECT_TRUE(env_->FindClass(NAME) == NULL)
Elliott Hughes0c9cd562011-08-12 10:59:29 -070031
32TEST_F(JniInternalTest, FindClass) {
Elliott Hughes0c9cd562011-08-12 10:59:29 -070033 // TODO: when these tests start failing because you're calling FindClass
34 // with a pending exception, fix EXPECT_CLASS_NOT_FOUND to assert that an
35 // exception was thrown and clear the exception.
36
37 // TODO: . is only allowed as an alternative to / if CheckJNI is off.
38
39 // Reference types...
40 // You can't include the "L;" in a JNI class descriptor.
41 EXPECT_CLASS_FOUND("java/lang/String");
42 EXPECT_CLASS_NOT_FOUND("Ljava/lang/String;");
43 // We support . as well as / for compatibility.
44 EXPECT_CLASS_FOUND("java.lang.String");
45 EXPECT_CLASS_NOT_FOUND("Ljava.lang.String;");
46 // ...for arrays too, where you must include "L;".
47 EXPECT_CLASS_FOUND("[Ljava/lang/String;");
48 EXPECT_CLASS_NOT_FOUND("[java/lang/String");
49 EXPECT_CLASS_FOUND("[Ljava.lang.String;");
50 EXPECT_CLASS_NOT_FOUND("[java.lang.String");
51
52 // Primitive arrays are okay (if the primitive type is valid)...
53 EXPECT_CLASS_FOUND("[C");
54 EXPECT_CLASS_NOT_FOUND("[K");
55 // But primitive types aren't allowed...
56 EXPECT_CLASS_NOT_FOUND("C");
57 EXPECT_CLASS_NOT_FOUND("K");
58}
59
Elliott Hughescdf53122011-08-19 15:46:09 -070060#define EXPECT_EXCEPTION(exception_class) \
61 do { \
62 EXPECT_TRUE(env_->ExceptionCheck()); \
63 jthrowable exception = env_->ExceptionOccurred(); \
64 EXPECT_NE(static_cast<jthrowable>(NULL), exception); \
65 EXPECT_TRUE(env_->IsInstanceOf(exception, exception_class)); \
66 env_->ExceptionClear(); \
67 } while (false)
68
69TEST_F(JniInternalTest, GetFieldID) {
70 jclass jlnsfe = env_->FindClass("java/lang/NoSuchFieldError");
71 ASSERT_TRUE(jlnsfe != NULL);
72 jclass c = env_->FindClass("java/lang/String");
73 ASSERT_TRUE(c != NULL);
74
75 // Wrong type.
76 jfieldID fid = env_->GetFieldID(c, "count", "J");
77 EXPECT_EQ(static_cast<jfieldID>(NULL), fid);
78 EXPECT_EXCEPTION(jlnsfe);
79
80 // Wrong name.
81 fid = env_->GetFieldID(c, "Count", "I");
82 EXPECT_EQ(static_cast<jfieldID>(NULL), fid);
83 EXPECT_EXCEPTION(jlnsfe);
84
85 // Good declared field lookup.
86 fid = env_->GetFieldID(c, "count", "I");
87 EXPECT_NE(static_cast<jfieldID>(NULL), fid);
88 EXPECT_TRUE(fid != NULL);
89 EXPECT_FALSE(env_->ExceptionCheck());
90
91 // Good superclass field lookup.
92 c = env_->FindClass("java/lang/StringBuilder");
93 fid = env_->GetFieldID(c, "count", "I");
94 EXPECT_NE(static_cast<jfieldID>(NULL), fid);
95 EXPECT_TRUE(fid != NULL);
96 EXPECT_FALSE(env_->ExceptionCheck());
97
98 // Not instance.
99 fid = env_->GetFieldID(c, "CASE_INSENSITIVE_ORDER", "Ljava/util/Comparator;");
100 EXPECT_EQ(static_cast<jfieldID>(NULL), fid);
101 EXPECT_EXCEPTION(jlnsfe);
102}
103
104TEST_F(JniInternalTest, GetStaticFieldID) {
105 jclass jlnsfe = env_->FindClass("java/lang/NoSuchFieldError");
106 ASSERT_TRUE(jlnsfe != NULL);
107 jclass c = env_->FindClass("java/lang/String");
108 ASSERT_TRUE(c != NULL);
109
110 // Wrong type.
111 jfieldID fid = env_->GetStaticFieldID(c, "CASE_INSENSITIVE_ORDER", "J");
112 EXPECT_EQ(static_cast<jfieldID>(NULL), fid);
113 EXPECT_EXCEPTION(jlnsfe);
114
115 // Wrong name.
116 fid = env_->GetStaticFieldID(c, "cASE_INSENSITIVE_ORDER", "Ljava/util/Comparator;");
117 EXPECT_EQ(static_cast<jfieldID>(NULL), fid);
118 EXPECT_EXCEPTION(jlnsfe);
119
120 // Good declared field lookup.
121 fid = env_->GetStaticFieldID(c, "CASE_INSENSITIVE_ORDER", "Ljava/util/Comparator;");
122 EXPECT_NE(static_cast<jfieldID>(NULL), fid);
123 EXPECT_TRUE(fid != NULL);
124 EXPECT_FALSE(env_->ExceptionCheck());
125
126 // Not static.
127 fid = env_->GetStaticFieldID(c, "count", "I");
128 EXPECT_EQ(static_cast<jfieldID>(NULL), fid);
129 EXPECT_EXCEPTION(jlnsfe);
130}
131
Ian Rogers4dd71f12011-08-16 14:16:02 -0700132TEST_F(JniInternalTest, GetMethodID) {
133 jclass jlobject = env_->FindClass("java/lang/Object");
134 jclass jlstring = env_->FindClass("java/lang/String");
135 jclass jlnsme = env_->FindClass("java/lang/NoSuchMethodError");
136
137 // Sanity check that no exceptions are pending
Elliott Hughescdf53122011-08-19 15:46:09 -0700138 ASSERT_FALSE(env_->ExceptionCheck());
Ian Rogers4dd71f12011-08-16 14:16:02 -0700139
140 // Check that java.lang.Object.foo() doesn't exist and NoSuchMethodError is
141 // a pending exception
142 jmethodID method = env_->GetMethodID(jlobject, "foo", "()V");
143 EXPECT_EQ(static_cast<jmethodID>(NULL), method);
Elliott Hughescdf53122011-08-19 15:46:09 -0700144 EXPECT_EXCEPTION(jlnsme);
Ian Rogers4dd71f12011-08-16 14:16:02 -0700145
146 // Check that java.lang.Object.equals() does exist
Ian Rogers4dd71f12011-08-16 14:16:02 -0700147 method = env_->GetMethodID(jlobject, "equals", "(Ljava/lang/Object;)Z");
148 EXPECT_NE(static_cast<jmethodID>(NULL), method);
149 EXPECT_FALSE(env_->ExceptionCheck());
Ian Rogers4dd71f12011-08-16 14:16:02 -0700150
151 // Check that GetMethodID for java.lang.String.valueOf(int) fails as the
152 // method is static
153 method = env_->GetMethodID(jlstring, "valueOf", "(I)Ljava/lang/String;");
154 EXPECT_EQ(static_cast<jmethodID>(NULL), method);
Elliott Hughescdf53122011-08-19 15:46:09 -0700155 EXPECT_EXCEPTION(jlnsme);
Ian Rogers4dd71f12011-08-16 14:16:02 -0700156}
157
158TEST_F(JniInternalTest, GetStaticMethodID) {
159 jclass jlobject = env_->FindClass("java/lang/Object");
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_->GetStaticMethodID(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 GetStaticMethodID for java.lang.Object.equals(Object) fails as
172 // the method is not static
173 method = env_->GetStaticMethodID(jlobject, "equals", "(Ljava/lang/Object;)Z");
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.String.valueOf(int) does exist
Ian Rogers4dd71f12011-08-16 14:16:02 -0700178 jclass jlstring = env_->FindClass("java/lang/String");
179 method = env_->GetStaticMethodID(jlstring, "valueOf",
180 "(I)Ljava/lang/String;");
181 EXPECT_NE(static_cast<jmethodID>(NULL), method);
182 EXPECT_FALSE(env_->ExceptionCheck());
Ian Rogers4dd71f12011-08-16 14:16:02 -0700183}
184
Elliott Hughescdf53122011-08-19 15:46:09 -0700185TEST_F(JniInternalTest, FromReflectedField_ToReflectedField) {
186 jclass jlrField = env_->FindClass("java/lang/reflect/Field");
187 jclass c = env_->FindClass("java/lang/String");
188 ASSERT_TRUE(c != NULL);
189 jfieldID fid = env_->GetFieldID(c, "count", "I");
190 ASSERT_TRUE(fid != NULL);
191 // Turn the fid into a java.lang.reflect.Field...
192 jobject field = env_->ToReflectedField(c, fid, JNI_FALSE);
193 ASSERT_TRUE(c != NULL);
194 ASSERT_TRUE(env_->IsInstanceOf(field, jlrField));
195 // ...and back again.
196 jfieldID fid2 = env_->FromReflectedField(field);
197 ASSERT_TRUE(fid2 != NULL);
198}
199
200TEST_F(JniInternalTest, FromReflectedMethod_ToReflectedMethod) {
201 jclass jlrMethod = env_->FindClass("java/lang/reflect/Method");
202 jclass c = env_->FindClass("java/lang/String");
203 ASSERT_TRUE(c != NULL);
204 jmethodID mid = env_->GetMethodID(c, "length", "()I");
205 ASSERT_TRUE(mid != NULL);
206 // Turn the mid into a java.lang.reflect.Method...
207 jobject method = env_->ToReflectedMethod(c, mid, JNI_FALSE);
208 ASSERT_TRUE(c != NULL);
209 ASSERT_TRUE(env_->IsInstanceOf(method, jlrMethod));
210 // ...and back again.
211 jmethodID mid2 = env_->FromReflectedMethod(method);
212 ASSERT_TRUE(mid2 != NULL);
213}
214
Ian Rogers4dd71f12011-08-16 14:16:02 -0700215TEST_F(JniInternalTest, RegisterNatives) {
216 jclass jlobject = env_->FindClass("java/lang/Object");
217 jclass jlnsme = env_->FindClass("java/lang/NoSuchMethodError");
218
219 // Sanity check that no exceptions are pending
Elliott Hughescdf53122011-08-19 15:46:09 -0700220 ASSERT_FALSE(env_->ExceptionCheck());
Ian Rogers4dd71f12011-08-16 14:16:02 -0700221
222 // Check that registering to a non-existent java.lang.Object.foo() causes a
223 // NoSuchMethodError
224 {
225 JNINativeMethod methods[] = {{"foo", "()V", NULL}};
226 env_->RegisterNatives(jlobject, methods, 1);
227 }
Elliott Hughescdf53122011-08-19 15:46:09 -0700228 EXPECT_EXCEPTION(jlnsme);
Ian Rogers4dd71f12011-08-16 14:16:02 -0700229
230 // Check that registering non-native methods causes a NoSuchMethodError
231 {
232 JNINativeMethod methods[] = {{"equals", "(Ljava/lang/Object;)Z", NULL}};
233 env_->RegisterNatives(jlobject, methods, 1);
234 }
Elliott Hughescdf53122011-08-19 15:46:09 -0700235 EXPECT_EXCEPTION(jlnsme);
Ian Rogers4dd71f12011-08-16 14:16:02 -0700236
237 // Check that registering native methods is successful
238 {
239 JNINativeMethod methods[] = {{"hashCode", "()I", NULL}};
240 env_->RegisterNatives(jlobject, methods, 1);
241 }
242 EXPECT_FALSE(env_->ExceptionCheck());
243}
244
Elliott Hughesd8ddfd52011-08-15 14:32:53 -0700245TEST_F(JniInternalTest, NewPrimitiveArray) {
246 // TODO: death tests for negative array sizes.
247
Elliott Hughesf2682d52011-08-15 16:37:04 -0700248 // TODO: check returned array size.
249
250 // TODO: check returned array class.
251
Elliott Hughes8a26c5c2011-08-15 18:35:43 -0700252 EXPECT_TRUE(env_->NewBooleanArray(0) != NULL);
253 EXPECT_TRUE(env_->NewByteArray(0) != NULL);
254 EXPECT_TRUE(env_->NewCharArray(0) != NULL);
255 EXPECT_TRUE(env_->NewDoubleArray(0) != NULL);
256 EXPECT_TRUE(env_->NewFloatArray(0) != NULL);
257 EXPECT_TRUE(env_->NewIntArray(0) != NULL);
258 EXPECT_TRUE(env_->NewLongArray(0) != NULL);
259 EXPECT_TRUE(env_->NewShortArray(0) != NULL);
Elliott Hughesd8ddfd52011-08-15 14:32:53 -0700260
Elliott Hughes8a26c5c2011-08-15 18:35:43 -0700261 EXPECT_TRUE(env_->NewBooleanArray(1) != NULL);
262 EXPECT_TRUE(env_->NewByteArray(1) != NULL);
263 EXPECT_TRUE(env_->NewCharArray(1) != NULL);
264 EXPECT_TRUE(env_->NewDoubleArray(1) != NULL);
265 EXPECT_TRUE(env_->NewFloatArray(1) != NULL);
266 EXPECT_TRUE(env_->NewIntArray(1) != NULL);
267 EXPECT_TRUE(env_->NewLongArray(1) != NULL);
268 EXPECT_TRUE(env_->NewShortArray(1) != NULL);
Elliott Hughesd8ddfd52011-08-15 14:32:53 -0700269}
270
Elliott Hughesf2682d52011-08-15 16:37:04 -0700271TEST_F(JniInternalTest, NewObjectArray) {
272 // TODO: death tests for negative array sizes.
273
274 // TODO: check returned array size.
275
276 // TODO: check returned array class.
277
278 // TODO: check non-NULL initial elements.
279
Elliott Hughes289da822011-08-16 10:11:20 -0700280 jclass c = env_->FindClass("[Ljava/lang/String;");
281 ASSERT_TRUE(c != NULL);
Elliott Hughesf2682d52011-08-15 16:37:04 -0700282
Elliott Hughes8a26c5c2011-08-15 18:35:43 -0700283 EXPECT_TRUE(env_->NewObjectArray(0, c, NULL) != NULL);
Elliott Hughesf2682d52011-08-15 16:37:04 -0700284
Elliott Hughes8a26c5c2011-08-15 18:35:43 -0700285 EXPECT_TRUE(env_->NewObjectArray(1, c, NULL) != NULL);
286}
287
288TEST_F(JniInternalTest, NewStringUTF) {
289 EXPECT_TRUE(env_->NewStringUTF(NULL) == NULL);
290 EXPECT_TRUE(env_->NewStringUTF("") != NULL);
291 EXPECT_TRUE(env_->NewStringUTF("hello") != NULL);
292 // TODO: check some non-ASCII strings.
Elliott Hughesf2682d52011-08-15 16:37:04 -0700293}
294
Elliott Hughes289da822011-08-16 10:11:20 -0700295TEST_F(JniInternalTest, SetObjectArrayElement) {
Elliott Hughescdf53122011-08-19 15:46:09 -0700296 jclass aioobe = env_->FindClass("java/lang/ArrayIndexOutOfBoundsException");
Elliott Hughes289da822011-08-16 10:11:20 -0700297 jclass c = env_->FindClass("[Ljava/lang/Object;");
298 ASSERT_TRUE(c != NULL);
299
300 jobjectArray array = env_->NewObjectArray(1, c, NULL);
301 EXPECT_TRUE(array != NULL);
302 env_->SetObjectArrayElement(array, 0, c);
303 // TODO: check reading value back
Elliott Hughesa5b897e2011-08-16 11:33:06 -0700304
305 // ArrayIndexOutOfBounds for negative index.
Elliott Hughesa5b897e2011-08-16 11:33:06 -0700306 env_->SetObjectArrayElement(array, -1, c);
Elliott Hughescdf53122011-08-19 15:46:09 -0700307 EXPECT_EXCEPTION(aioobe);
Elliott Hughesa5b897e2011-08-16 11:33:06 -0700308
309 // ArrayIndexOutOfBounds for too-large index.
Elliott Hughesa5b897e2011-08-16 11:33:06 -0700310 env_->SetObjectArrayElement(array, 1, c);
Elliott Hughescdf53122011-08-19 15:46:09 -0700311 EXPECT_EXCEPTION(aioobe);
Elliott Hughesa5b897e2011-08-16 11:33:06 -0700312
Elliott Hughes289da822011-08-16 10:11:20 -0700313 // TODO: check ArrayStoreException thrown for bad types.
314}
315
Elliott Hughes18c07532011-08-18 15:50:51 -0700316TEST_F(JniInternalTest, NewLocalRef_NULL) {
317 EXPECT_TRUE(env_->NewLocalRef(NULL) == NULL);
318}
319
320TEST_F(JniInternalTest, NewLocalRef) {
321 jstring s = env_->NewStringUTF("");
322 ASSERT_TRUE(s != NULL);
323 jobject o = env_->NewLocalRef(s);
324 EXPECT_TRUE(o != NULL);
325 EXPECT_TRUE(o != s);
326
327 // TODO: check that o is a local reference.
328}
329
330TEST_F(JniInternalTest, DeleteLocalRef_NULL) {
331 env_->DeleteLocalRef(NULL);
332}
333
334TEST_F(JniInternalTest, DeleteLocalRef) {
335 jstring s = env_->NewStringUTF("");
336 ASSERT_TRUE(s != NULL);
337 env_->DeleteLocalRef(s);
338
339 // Currently, deleting an already-deleted reference is just a warning.
340 env_->DeleteLocalRef(s);
341
342 s = env_->NewStringUTF("");
343 ASSERT_TRUE(s != NULL);
344 jobject o = env_->NewLocalRef(s);
345 ASSERT_TRUE(o != NULL);
346
347 env_->DeleteLocalRef(s);
348 env_->DeleteLocalRef(o);
349}
350
351TEST_F(JniInternalTest, NewGlobalRef_NULL) {
352 EXPECT_TRUE(env_->NewGlobalRef(NULL) == NULL);
353}
354
355TEST_F(JniInternalTest, NewGlobalRef) {
356 jstring s = env_->NewStringUTF("");
357 ASSERT_TRUE(s != NULL);
358 jobject o = env_->NewGlobalRef(s);
359 EXPECT_TRUE(o != NULL);
360 EXPECT_TRUE(o != s);
361
362 // TODO: check that o is a global reference.
363}
364
365TEST_F(JniInternalTest, DeleteGlobalRef_NULL) {
366 env_->DeleteGlobalRef(NULL);
367}
368
369TEST_F(JniInternalTest, DeleteGlobalRef) {
370 jstring s = env_->NewStringUTF("");
371 ASSERT_TRUE(s != NULL);
372
373 jobject o = env_->NewGlobalRef(s);
374 ASSERT_TRUE(o != NULL);
375 env_->DeleteGlobalRef(o);
376
377 // Currently, deleting an already-deleted reference is just a warning.
378 env_->DeleteGlobalRef(o);
379
380 jobject o1 = env_->NewGlobalRef(s);
381 ASSERT_TRUE(o1 != NULL);
382 jobject o2 = env_->NewGlobalRef(s);
383 ASSERT_TRUE(o2 != NULL);
384
385 env_->DeleteGlobalRef(o1);
386 env_->DeleteGlobalRef(o2);
387}
388
389TEST_F(JniInternalTest, NewWeakGlobalRef_NULL) {
390 EXPECT_TRUE(env_->NewWeakGlobalRef(NULL) == NULL);
391}
392
393TEST_F(JniInternalTest, NewWeakGlobalRef) {
394 jstring s = env_->NewStringUTF("");
395 ASSERT_TRUE(s != NULL);
396 jobject o = env_->NewWeakGlobalRef(s);
397 EXPECT_TRUE(o != NULL);
398 EXPECT_TRUE(o != s);
399
400 // TODO: check that o is a weak global reference.
401}
402
403TEST_F(JniInternalTest, DeleteWeakGlobalRef_NULL) {
404 env_->DeleteWeakGlobalRef(NULL);
405}
406
407TEST_F(JniInternalTest, DeleteWeakGlobalRef) {
408 jstring s = env_->NewStringUTF("");
409 ASSERT_TRUE(s != NULL);
410
411 jobject o = env_->NewWeakGlobalRef(s);
412 ASSERT_TRUE(o != NULL);
413 env_->DeleteWeakGlobalRef(o);
414
415 // Currently, deleting an already-deleted reference is just a warning.
416 env_->DeleteWeakGlobalRef(o);
417
418 jobject o1 = env_->NewWeakGlobalRef(s);
419 ASSERT_TRUE(o1 != NULL);
420 jobject o2 = env_->NewWeakGlobalRef(s);
421 ASSERT_TRUE(o2 != NULL);
422
423 env_->DeleteWeakGlobalRef(o1);
424 env_->DeleteWeakGlobalRef(o2);
425}
426
Carl Shapiro9b9ba282011-08-14 15:30:39 -0700427bool EnsureInvokeStub(Method* method);
428
429byte* AllocateCode(void* code, size_t length) {
430 int prot = PROT_READ | PROT_WRITE | PROT_EXEC;
431 void* addr = mmap(NULL, length, prot, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
432 CHECK(addr != MAP_FAILED);
433 memcpy(addr, code, length);
434 __builtin___clear_cache(addr, (byte*)addr + length);
435 // Set the low-order bit so a BLX will switch to Thumb mode.
436 return reinterpret_cast<byte*>(reinterpret_cast<uintptr_t>(addr) | 1);
437}
438
439Method::InvokeStub* AllocateStub(Method* method,
440 byte* code,
441 size_t length) {
442 CHECK(method->GetInvokeStub() == NULL);
443 EnsureInvokeStub(method);
444 Method::InvokeStub* stub = method->GetInvokeStub();
445 CHECK(stub != NULL);
446 method->SetCode(AllocateCode(code, length));
447 CHECK(method->GetCode() != NULL);
448 return stub;
449}
450
451void FreeStub(Method* method, size_t length) {
452 void* addr = const_cast<void*>(method->GetCode());
453 munmap(addr, length);
454 method->SetCode(NULL);
455}
456
457#if defined(__arm__)
458TEST_F(JniInternalTest, StaticMainMethod) {
459 scoped_ptr<DexFile> dex(OpenDexFileBase64(kMainDex));
460
461 PathClassLoader* class_loader = AllocPathClassLoader(dex.get());
462 ASSERT_TRUE(class_loader != NULL);
463
464 Class* klass = class_linker_->FindClass("LMain;", class_loader);
465 ASSERT_TRUE(klass != NULL);
466
467 Method* method = klass->FindDirectMethod("main", "([Ljava/lang/String;)V");
468 ASSERT_TRUE(method != NULL);
469
470 byte main_LV_code[] = {
471 0x2d, 0xe9, 0x00, 0x40, 0x83, 0xb0, 0xcd, 0xf8, 0x00, 0x00,
472 0xcd, 0xf8, 0x14, 0x10, 0x03, 0xb0, 0xbd, 0xe8, 0x00, 0x80,
473 };
474
475 Method::InvokeStub* stub = AllocateStub(method,
476 main_LV_code,
477 sizeof(main_LV_code));
478
479 Object* arg = NULL;
480
481 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(&arg), NULL);
482
483 FreeStub(method, sizeof(main_LV_code));
484}
485
486TEST_F(JniInternalTest, StaticNopMethod) {
487 scoped_ptr<DexFile> dex(OpenDexFileBase64(kStaticLeafMethodsDex));
488
489 PathClassLoader* class_loader = AllocPathClassLoader(dex.get());
490 ASSERT_TRUE(class_loader != NULL);
491
492 Class* klass = class_linker_->FindClass("LStaticLeafMethods;", class_loader);
493 ASSERT_TRUE(klass != NULL);
494
495 Method* method = klass->FindDirectMethod("nop", "()V");
496 ASSERT_TRUE(method != NULL);
497
498 byte nop_V_code[] = {
499 0x2d, 0xe9, 0x00, 0x40, 0x83, 0xb0, 0xcd, 0xf8,
500 0x00, 0x00, 0x03, 0xb0, 0xbd, 0xe8, 0x00, 0x80,
501 };
502
503 Method::InvokeStub* stub = AllocateStub(method,
504 nop_V_code,
505 sizeof(nop_V_code));
506 ASSERT_TRUE(stub);
507
508 (*stub)(method, NULL, NULL, NULL, NULL);
509
510 FreeStub(method, sizeof(nop_V_code));
511}
512
513TEST_F(JniInternalTest, StaticIdentityByteMethod) {
514 scoped_ptr<DexFile> dex(OpenDexFileBase64(kStaticLeafMethodsDex));
515
516 PathClassLoader* class_loader = AllocPathClassLoader(dex.get());
517 ASSERT_TRUE(class_loader != NULL);
518
519 Class* klass = class_linker_->FindClass("LStaticLeafMethods;", class_loader);
520 ASSERT_TRUE(klass != NULL);
521
522 Method* method = klass->FindDirectMethod("identity", "(B)B");
523 ASSERT_TRUE(method != NULL);
524
525 byte identity_BB_code[] = {
526 0x2d, 0xe9, 0x00, 0x40, 0x83, 0xb0, 0xcd, 0xf8,
527 0x00, 0x00, 0xcd, 0xf8, 0x14, 0x10, 0x05, 0x98,
528 0x03, 0xb0, 0xbd, 0xe8, 0x00, 0x80, 0x00, 0x00,
529 };
530
531 Method::InvokeStub* stub = AllocateStub(method,
532 identity_BB_code,
533 sizeof(identity_BB_code));
534
535 int arg;
536 JValue result;
537
538 arg = 0;
539 result.b = -1;
540 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(&arg), &result);
541 EXPECT_EQ(0, result.b);
542
543 arg = -1;
544 result.b = 0;
545 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(&arg), &result);
546 EXPECT_EQ(-1, result.b);
547
548 arg = SCHAR_MAX;
549 result.b = 0;
550 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(&arg), &result);
551 EXPECT_EQ(SCHAR_MAX, result.b);
552
553 arg = SCHAR_MIN;
554 result.b = 0;
555 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(&arg), &result);
556 EXPECT_EQ(SCHAR_MIN, result.b);
557
558 FreeStub(method, sizeof(identity_BB_code));
559}
560
561TEST_F(JniInternalTest, StaticIdentityIntMethod) {
562 scoped_ptr<DexFile> dex(OpenDexFileBase64(kStaticLeafMethodsDex));
563
564 PathClassLoader* class_loader = AllocPathClassLoader(dex.get());
565 ASSERT_TRUE(class_loader != NULL);
566
567 Class* klass = class_linker_->FindClass("LStaticLeafMethods;", class_loader);
568 ASSERT_TRUE(klass != NULL);
569
570 Method* method = klass->FindDirectMethod("identity", "(I)I");
571 ASSERT_TRUE(method != NULL);
572
573 byte identity_II_code[] = {
574 0x2d, 0xe9, 0x00, 0x40, 0x83, 0xb0, 0xcd, 0xf8,
575 0x00, 0x00, 0xcd, 0xf8, 0x14, 0x10, 0x05, 0x98,
576 0x03, 0xb0, 0xbd, 0xe8, 0x00, 0x80, 0x00, 0x00,
577 };
578
579 Method::InvokeStub* stub = AllocateStub(method,
580 identity_II_code,
581 sizeof(identity_II_code));
582
583 int arg;
584 JValue result;
585
586 arg = 0;
587 result.i = -1;
588 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(&arg), &result);
589 EXPECT_EQ(0, result.i);
590
591 arg = -1;
592 result.i = 0;
593 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(&arg), &result);
594 EXPECT_EQ(-1, result.i);
595
596 arg = INT_MAX;
597 result.i = 0;
598 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(&arg), &result);
599 EXPECT_EQ(INT_MAX, result.i);
600
601 arg = INT_MIN;
602 result.i = 0;
603 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(&arg), &result);
604 EXPECT_EQ(INT_MIN, result.i);
605
606 FreeStub(method, sizeof(identity_II_code));
607}
608
609TEST_F(JniInternalTest, StaticIdentityDoubleMethod) {
610 scoped_ptr<DexFile> dex(OpenDexFileBase64(kStaticLeafMethodsDex));
611
612 PathClassLoader* class_loader = AllocPathClassLoader(dex.get());
613 ASSERT_TRUE(class_loader != NULL);
614
615 Class* klass = class_linker_->FindClass("LStaticLeafMethods;", class_loader);
616 ASSERT_TRUE(klass != NULL);
617
618 Method* method = klass->FindDirectMethod("identity", "(D)D");
619 ASSERT_TRUE(method != NULL);
620
621 byte identity_DD_code[] = {
622 0x2d, 0xe9, 0x00, 0x40, 0x83, 0xb0, 0xcd, 0xf8,
623 0x00, 0x00, 0xcd, 0xf8, 0x14, 0x10, 0xcd, 0xf8,
624 0x18, 0x20, 0x05, 0x98, 0x06, 0x99, 0x03, 0xb0,
625 0xbd, 0xe8, 0x00, 0x80,
626 };
627
628 Method::InvokeStub* stub = AllocateStub(method,
629 identity_DD_code,
630 sizeof(identity_DD_code));
631
632 double arg;
633 JValue result;
634
635 arg = 0.0;
636 result.d = -1.0;
637 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(&arg), &result);
638 EXPECT_EQ(0.0, result.d);
639
640 arg = -1.0;
641 result.d = 0.0;
642 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(&arg), &result);
643 EXPECT_EQ(-1.0, result.d);
644
645 arg = DBL_MAX;
646 result.d = 0.0;
647 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(&arg), &result);
648 EXPECT_EQ(DBL_MAX, result.d);
649
650 arg = DBL_MIN;
651 result.d = 0.0;
652 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(&arg), &result);
653 EXPECT_EQ(DBL_MIN, result.d);
654
655 FreeStub(method, sizeof(identity_DD_code));
656}
657
658TEST_F(JniInternalTest, StaticSumIntIntMethod) {
659 scoped_ptr<DexFile> dex(OpenDexFileBase64(kStaticLeafMethodsDex));
660
661 PathClassLoader* class_loader = AllocPathClassLoader(dex.get());
662 ASSERT_TRUE(class_loader != NULL);
663
664 Class* klass = class_linker_->FindClass("LStaticLeafMethods;", class_loader);
665 ASSERT_TRUE(klass != NULL);
666
667 Method* method = klass->FindDirectMethod("sum", "(II)I");
668 ASSERT_TRUE(method != NULL);
669
670 byte sum_III_code[] = {
671 0x2d, 0xe9, 0x00, 0x40, 0x83, 0xb0, 0xcd, 0xf8,
672 0x00, 0x00, 0xcd, 0xf8, 0x14, 0x10, 0xcd, 0xf8,
673 0x18, 0x20, 0x05, 0x98, 0x06, 0x99, 0x42, 0x18,
674 0xcd, 0xf8, 0x04, 0x20, 0x01, 0x98, 0x03, 0xb0,
675 0xbd, 0xe8, 0x00, 0x80,
676 };
677
678 Method::InvokeStub* stub = AllocateStub(method,
679 sum_III_code,
680 sizeof(sum_III_code));
681
682 int args[2];
683 JValue result;
684
685 args[0] = 0;
686 args[1] = 0;
687 result.i = -1;
688 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
689 EXPECT_EQ(0, result.i);
690
691 args[0] = 1;
692 args[1] = 2;
693 result.i = 0;
694 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
695 EXPECT_EQ(3, result.i);
696
697 args[0] = -2;
698 args[1] = 5;
699 result.i = 0;
700 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
701 EXPECT_EQ(3, result.i);
702
703 args[0] = INT_MAX;
704 args[1] = INT_MIN;
705 result.i = 1234;
706 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
707 EXPECT_EQ(-1, result.i);
708
709 args[0] = INT_MAX;
710 args[1] = INT_MAX;
711 result.i = INT_MIN;
712 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
713 EXPECT_EQ(-2, result.i);
714
715 FreeStub(method, sizeof(sum_III_code));
716}
717
718TEST_F(JniInternalTest, StaticSumIntIntIntMethod) {
719 scoped_ptr<DexFile> dex(OpenDexFileBase64(kStaticLeafMethodsDex));
720
721 PathClassLoader* class_loader = AllocPathClassLoader(dex.get());
722 ASSERT_TRUE(class_loader != NULL);
723
724 Class* klass = class_linker_->FindClass("LStaticLeafMethods;", class_loader);
725 ASSERT_TRUE(klass != NULL);
726
727 Method* method = klass->FindDirectMethod("sum", "(III)I");
728 ASSERT_TRUE(method != NULL);
729
730 byte sum_IIII_code[] = {
731 0x2d, 0xe9, 0x00, 0x40, 0x83, 0xb0, 0xcd, 0xf8,
732 0x00, 0x00, 0xcd, 0xf8, 0x14, 0x10, 0xcd, 0xf8,
733 0x18, 0x20, 0xcd, 0xf8, 0x1c, 0x30, 0x05, 0x98,
734 0x06, 0x99, 0x42, 0x18, 0xcd, 0xf8, 0x04, 0x20,
735 0x01, 0x9b, 0xdd, 0xf8, 0x1c, 0xc0, 0x13, 0xeb,
736 0x0c, 0x03, 0xcd, 0xf8, 0x04, 0x30, 0x01, 0x98,
737 0x03, 0xb0, 0xbd, 0xe8, 0x00, 0x80, 0x00, 0x00,
738 };
739
740 Method::InvokeStub* stub = AllocateStub(method,
741 sum_IIII_code,
742 sizeof(sum_IIII_code));
743
744 int args[3];
745 JValue result;
746
747 args[0] = 0;
748 args[1] = 0;
749 args[2] = 0;
750 result.i = -1;
751 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
752 EXPECT_EQ(0, result.i);
753
754 args[0] = 1;
755 args[1] = 2;
756 args[2] = 3;
757 result.i = 0;
758 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
759 EXPECT_EQ(6, result.i);
760
761 args[0] = -1;
762 args[1] = 2;
763 args[2] = -3;
764 result.i = 0;
765 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
766 EXPECT_EQ(-2, result.i);
767
768 args[0] = INT_MAX;
769 args[1] = INT_MIN;
770 args[2] = INT_MAX;
771 result.i = 1234;
772 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
773 EXPECT_EQ(2147483646, result.i);
774
775 args[0] = INT_MAX;
776 args[1] = INT_MAX;
777 args[2] = INT_MAX;
778 result.i = INT_MIN;
779 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
780 EXPECT_EQ(2147483645, result.i);
781
782 FreeStub(method, sizeof(sum_IIII_code));
783}
784
785TEST_F(JniInternalTest, StaticSumIntIntIntIntMethod) {
786 scoped_ptr<DexFile> dex(OpenDexFileBase64(kStaticLeafMethodsDex));
787
788 PathClassLoader* class_loader = AllocPathClassLoader(dex.get());
789 ASSERT_TRUE(class_loader != NULL);
790
791 Class* klass = class_linker_->FindClass("LStaticLeafMethods;", class_loader);
792 ASSERT_TRUE(klass != NULL);
793
794 Method* method = klass->FindDirectMethod("sum", "(IIII)I");
795 ASSERT_TRUE(method != NULL);
796
797 byte sum_IIIII_code[] = {
798 0x2d, 0xe9, 0x00, 0x40, 0x83, 0xb0, 0xcd, 0xf8,
799 0x00, 0x00, 0xcd, 0xf8, 0x14, 0x10, 0xcd, 0xf8,
800 0x18, 0x20, 0xcd, 0xf8, 0x1c, 0x30, 0x05, 0x98,
801 0x06, 0x99, 0x42, 0x18, 0xcd, 0xf8, 0x04, 0x20,
802 0x01, 0x9b, 0xdd, 0xf8, 0x1c, 0xc0, 0x13, 0xeb,
803 0x0c, 0x03, 0xcd, 0xf8, 0x04, 0x30, 0x01, 0x98,
804 0x08, 0x99, 0x40, 0x18, 0xcd, 0xf8, 0x04, 0x00,
805 0x01, 0x98, 0x03, 0xb0, 0xbd, 0xe8, 0x00, 0x80,
806 };
807
808 Method::InvokeStub* stub = AllocateStub(method,
809 sum_IIIII_code,
810 sizeof(sum_IIIII_code));
811
812 int args[4];
813 JValue result;
814
815 args[0] = 0;
816 args[1] = 0;
817 args[2] = 0;
818 args[3] = 0;
819 result.i = -1;
820 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
821 EXPECT_EQ(0, result.i);
822
823 args[0] = 1;
824 args[1] = 2;
825 args[2] = 3;
826 args[3] = 4;
827 result.i = 0;
828 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
829 EXPECT_EQ(10, result.i);
830
831 args[0] = -1;
832 args[1] = 2;
833 args[2] = -3;
834 args[3] = 4;
835 result.i = 0;
836 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
837 EXPECT_EQ(2, result.i);
838
839 args[0] = INT_MAX;
840 args[1] = INT_MIN;
841 args[2] = INT_MAX;
842 args[3] = INT_MIN;
843 result.i = 1234;
844 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
845 EXPECT_EQ(-2, result.i);
846
847 args[0] = INT_MAX;
848 args[1] = INT_MAX;
849 args[2] = INT_MAX;
850 args[3] = INT_MAX;
851 result.i = INT_MIN;
852 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
853 EXPECT_EQ(-4, result.i);
854
855 FreeStub(method, sizeof(sum_IIIII_code));
856}
857
858TEST_F(JniInternalTest, StaticSumIntIntIntIntIntMethod) {
859 scoped_ptr<DexFile> dex(OpenDexFileBase64(kStaticLeafMethodsDex));
860
861 PathClassLoader* class_loader = AllocPathClassLoader(dex.get());
862 ASSERT_TRUE(class_loader != NULL);
863
864 Class* klass = class_linker_->FindClass("LStaticLeafMethods;", class_loader);
865 ASSERT_TRUE(klass != NULL);
866
867 Method* method = klass->FindDirectMethod("sum", "(IIIII)I");
868 ASSERT_TRUE(method != NULL);
869
870 byte sum_IIIIII_code[] = {
871 0x2d, 0xe9, 0x00, 0x40, 0x83, 0xb0, 0xcd, 0xf8,
872 0x00, 0x00, 0xcd, 0xf8, 0x14, 0x10, 0xcd, 0xf8,
873 0x18, 0x20, 0xcd, 0xf8, 0x1c, 0x30, 0x05, 0x98,
874 0x06, 0x99, 0x42, 0x18, 0xcd, 0xf8, 0x04, 0x20,
875 0x01, 0x9b, 0xdd, 0xf8, 0x1c, 0xc0, 0x13, 0xeb,
876 0x0c, 0x03, 0xcd, 0xf8, 0x04, 0x30, 0x01, 0x98,
877 0x08, 0x99, 0x40, 0x18, 0xcd, 0xf8, 0x04, 0x00,
878 0x01, 0x9a, 0x09, 0x9b, 0xd2, 0x18, 0xcd, 0xf8,
879 0x04, 0x20, 0x01, 0x98, 0x03, 0xb0, 0xbd, 0xe8,
880 0x00, 0x80, 0x00, 0x00,
881 };
882
883 Method::InvokeStub* stub = AllocateStub(method,
884 sum_IIIIII_code,
885 sizeof(sum_IIIIII_code));
886
887 int args[5];
888 JValue result;
889
890 args[0] = 0;
891 args[1] = 0;
892 args[2] = 0;
893 args[3] = 0;
894 args[4] = 0;
895 result.i = -1.0;
896 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
897 EXPECT_EQ(0, result.i);
898
899 args[0] = 1;
900 args[1] = 2;
901 args[2] = 3;
902 args[3] = 4;
903 args[4] = 5;
904 result.i = 0;
905 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
906 EXPECT_EQ(15, result.i);
907
908 args[0] = -1;
909 args[1] = 2;
910 args[2] = -3;
911 args[3] = 4;
912 args[4] = -5;
913 result.i = 0;
914 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
915 EXPECT_EQ(-3, result.i);
916
917 args[0] = INT_MAX;
918 args[1] = INT_MIN;
919 args[2] = INT_MAX;
920 args[3] = INT_MIN;
921 args[4] = INT_MAX;
922 result.i = 1234;
923 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
924 EXPECT_EQ(2147483645, result.i);
925
926 args[0] = INT_MAX;
927 args[1] = INT_MAX;
928 args[2] = INT_MAX;
929 args[3] = INT_MAX;
930 args[4] = INT_MAX;
931 result.i = INT_MIN;
932 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
933 EXPECT_EQ(2147483643, result.i);
934
935 FreeStub(method, sizeof(sum_IIIIII_code));
936}
937
938TEST_F(JniInternalTest, StaticSumDoubleDoubleMethod) {
939 scoped_ptr<DexFile> dex(OpenDexFileBase64(kStaticLeafMethodsDex));
940
941 PathClassLoader* class_loader = AllocPathClassLoader(dex.get());
942 ASSERT_TRUE(class_loader != NULL);
943
944 Class* klass = class_linker_->FindClass("LStaticLeafMethods;", class_loader);
945 ASSERT_TRUE(klass != NULL);
946
947 Method* method = klass->FindDirectMethod("sum", "(DD)D");
948 ASSERT_TRUE(method != NULL);
949
950 byte sum_DDD_code[] = {
951 0x2d, 0xe9, 0x00, 0x40, 0x87, 0xb0, 0xcd, 0xf8,
952 0x00, 0x00, 0xcd, 0xf8, 0x24, 0x10, 0xcd, 0xf8,
953 0x28, 0x20, 0xcd, 0xf8, 0x2c, 0x30, 0x9d, 0xed,
954 0x09, 0x0b, 0x9d, 0xed, 0x0b, 0x1b, 0x30, 0xee,
955 0x01, 0x2b, 0x8d, 0xed, 0x04, 0x2b, 0x04, 0x98,
956 0x05, 0x99, 0x07, 0xb0, 0xbd, 0xe8, 0x00, 0x80,
957 };
958
959 Method::InvokeStub* stub = AllocateStub(method,
960 sum_DDD_code,
961 sizeof(sum_DDD_code));
962
963 double args[2];
964 JValue result;
965
966 args[0] = 0.0;
967 args[1] = 0.0;
968 result.d = -1.0;
969 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
970 EXPECT_EQ(0.0, result.d);
971
972 args[0] = 1.0;
973 args[1] = 2.0;
974 result.d = 0.0;
975 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
976 EXPECT_EQ(3.0, result.d);
977
978 args[0] = 1.0;
979 args[1] = -2.0;
980 result.d = 0.0;
981 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
982 EXPECT_EQ(-1.0, result.d);
983
984 args[0] = DBL_MAX;
985 args[1] = DBL_MIN;
986 result.d = 0.0;
987 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
988 EXPECT_EQ(1.7976931348623157e308, result.d);
989
990 args[0] = DBL_MAX;
991 args[1] = DBL_MAX;
992 result.d = 0.0;
993 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
994 EXPECT_EQ(INFINITY, result.d);
995
996 FreeStub(method, sizeof(sum_DDD_code));
997}
998
999TEST_F(JniInternalTest, StaticSumDoubleDoubleDoubleMethod) {
1000 scoped_ptr<DexFile> dex(OpenDexFileBase64(kStaticLeafMethodsDex));
1001
1002 PathClassLoader* class_loader = AllocPathClassLoader(dex.get());
1003 ASSERT_TRUE(class_loader != NULL);
1004
1005 Class* klass = class_linker_->FindClass("LStaticLeafMethods;", class_loader);
1006 ASSERT_TRUE(klass != NULL);
1007
1008 Method* method = klass->FindDirectMethod("sum", "(DDD)D");
1009 ASSERT_TRUE(method != NULL);
1010
1011 byte sum_DDDD_code[] = {
1012 0x2d, 0xe9, 0x00, 0x40, 0x87, 0xb0, 0xcd, 0xf8,
1013 0x00, 0x00, 0xcd, 0xf8, 0x24, 0x10, 0xcd, 0xf8,
1014 0x28, 0x20, 0xcd, 0xf8, 0x2c, 0x30, 0x9d, 0xed,
1015 0x09, 0x0b, 0x9d, 0xed, 0x0b, 0x1b, 0x30, 0xee,
1016 0x01, 0x2b, 0x8d, 0xed, 0x04, 0x2b, 0x9d, 0xed,
1017 0x04, 0x3b, 0x9d, 0xed, 0x0d, 0x4b, 0x33, 0xee,
1018 0x04, 0x3b, 0x8d, 0xed, 0x04, 0x3b, 0x04, 0x98,
1019 0x05, 0x99, 0x07, 0xb0, 0xbd, 0xe8, 0x00, 0x80,
1020 };
1021
1022 Method::InvokeStub* stub = AllocateStub(method,
1023 sum_DDDD_code,
1024 sizeof(sum_DDDD_code));
1025
1026 double args[3];
1027 JValue result;
1028
1029 args[0] = 0.0;
1030 args[1] = 0.0;
1031 args[2] = 0.0;
1032 result.d = -1.0;
1033 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
1034 EXPECT_EQ(0.0, result.d);
1035
1036 args[0] = 1.0;
1037 args[1] = 2.0;
1038 args[2] = 3.0;
1039 result.d = 0.0;
1040 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
1041 EXPECT_EQ(6.0, result.d);
1042
1043 args[0] = 1.0;
1044 args[1] = -2.0;
1045 args[2] = 3.0;
1046 result.d = 0.0;
1047 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
1048 EXPECT_EQ(2.0, result.d);
1049
1050 FreeStub(method, sizeof(sum_DDDD_code));
1051}
1052
1053TEST_F(JniInternalTest, StaticSumDoubleDoubleDoubleDoubleMethod) {
1054 scoped_ptr<DexFile> dex(OpenDexFileBase64(kStaticLeafMethodsDex));
1055
1056 PathClassLoader* class_loader = AllocPathClassLoader(dex.get());
1057 ASSERT_TRUE(class_loader != NULL);
1058
1059 Class* klass = class_linker_->FindClass("LStaticLeafMethods;", class_loader);
1060 ASSERT_TRUE(klass != NULL);
1061
1062 Method* method = klass->FindDirectMethod("sum", "(DDDD)D");
1063 ASSERT_TRUE(method != NULL);
1064
1065 byte sum_DDDDD_code[] = {
1066 0x2d, 0xe9, 0x00, 0x40, 0x87, 0xb0, 0xcd, 0xf8,
1067 0x00, 0x00, 0xcd, 0xf8, 0x24, 0x10, 0xcd, 0xf8,
1068 0x28, 0x20, 0xcd, 0xf8, 0x2c, 0x30, 0x9d, 0xed,
1069 0x09, 0x0b, 0x9d, 0xed, 0x0b, 0x1b, 0x30, 0xee,
1070 0x01, 0x2b, 0x8d, 0xed, 0x04, 0x2b, 0x9d, 0xed,
1071 0x04, 0x3b, 0x9d, 0xed, 0x0d, 0x4b, 0x33, 0xee,
1072 0x04, 0x3b, 0x8d, 0xed, 0x04, 0x3b, 0x9d, 0xed,
1073 0x04, 0x5b, 0x9d, 0xed, 0x0f, 0x6b, 0x35, 0xee,
1074 0x06, 0x5b, 0x8d, 0xed, 0x04, 0x5b, 0x04, 0x98,
1075 0x05, 0x99, 0x07, 0xb0, 0xbd, 0xe8, 0x00, 0x80,
1076 };
1077
1078 Method::InvokeStub* stub = AllocateStub(method,
1079 sum_DDDDD_code,
1080 sizeof(sum_DDDDD_code));
1081
1082 double args[4];
1083 JValue result;
1084
1085 args[0] = 0.0;
1086 args[1] = 0.0;
1087 args[2] = 0.0;
1088 args[3] = 0.0;
1089 result.d = -1.0;
1090 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
1091 EXPECT_EQ(0.0, result.d);
1092
1093 args[0] = 1.0;
1094 args[1] = 2.0;
1095 args[2] = 3.0;
1096 args[3] = 4.0;
1097 result.d = 0.0;
1098 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
1099 EXPECT_EQ(10.0, result.d);
1100
1101 args[0] = 1.0;
1102 args[1] = -2.0;
1103 args[2] = 3.0;
1104 args[3] = -4.0;
1105 result.d = 0.0;
1106 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
1107 EXPECT_EQ(-2.0, result.d);
1108
1109 FreeStub(method, sizeof(sum_DDDDD_code));
1110}
1111
1112TEST_F(JniInternalTest, StaticSumDoubleDoubleDoubleDoubleDoubleMethod) {
1113 scoped_ptr<DexFile> dex(OpenDexFileBase64(kStaticLeafMethodsDex));
1114
1115 PathClassLoader* class_loader = AllocPathClassLoader(dex.get());
1116 ASSERT_TRUE(class_loader != NULL);
1117
1118 Class* klass = class_linker_->FindClass("LStaticLeafMethods;", class_loader);
1119 ASSERT_TRUE(klass != NULL);
1120
1121 Method* method = klass->FindDirectMethod("sum", "(DDDDD)D");
1122 ASSERT_TRUE(method != NULL);
1123
1124 byte sum_DDDDDD_code[] = {
1125 0x2d, 0xe9, 0x00, 0x40, 0x87, 0xb0, 0xcd, 0xf8,
1126 0x00, 0x00, 0xcd, 0xf8, 0x24, 0x10, 0xcd, 0xf8,
1127 0x28, 0x20, 0xcd, 0xf8, 0x2c, 0x30, 0x9d, 0xed,
1128 0x09, 0x0b, 0x9d, 0xed, 0x0b, 0x1b, 0x30, 0xee,
1129 0x01, 0x2b, 0x8d, 0xed, 0x04, 0x2b, 0x9d, 0xed,
1130 0x04, 0x3b, 0x9d, 0xed, 0x0d, 0x4b, 0x33, 0xee,
1131 0x04, 0x3b, 0x8d, 0xed, 0x04, 0x3b, 0x9d, 0xed,
1132 0x04, 0x5b, 0x9d, 0xed, 0x0f, 0x6b, 0x35, 0xee,
1133 0x06, 0x5b, 0x8d, 0xed, 0x04, 0x5b, 0x9d, 0xed,
1134 0x04, 0x7b, 0x9d, 0xed, 0x11, 0x0b, 0x37, 0xee,
1135 0x00, 0x7b, 0x8d, 0xed, 0x04, 0x7b, 0x04, 0x98,
1136 0x05, 0x99, 0x07, 0xb0, 0xbd, 0xe8, 0x00, 0x80,
1137 };
1138
1139 Method::InvokeStub* stub = AllocateStub(method,
1140 sum_DDDDDD_code,
1141 sizeof(sum_DDDDDD_code));
1142
1143 double args[5];
1144 JValue result;
1145
1146 args[0] = 0.0;
1147 args[1] = 0.0;
1148 args[2] = 0.0;
1149 args[3] = 0.0;
1150 args[4] = 0.0;
1151 result.d = -1.0;
1152 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
1153 EXPECT_EQ(0.0, result.d);
1154
1155 args[0] = 1.0;
1156 args[1] = 2.0;
1157 args[2] = 3.0;
1158 args[3] = 4.0;
1159 args[4] = 5.0;
1160 result.d = 0.0;
1161 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
1162 EXPECT_EQ(15.0, result.d);
1163
1164 args[0] = 1.0;
1165 args[1] = -2.0;
1166 args[2] = 3.0;
1167 args[3] = -4.0;
1168 args[4] = 5.0;
1169 result.d = 0.0;
1170 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
1171 EXPECT_EQ(3.0, result.d);
1172
1173 FreeStub(method, sizeof(sum_DDDDDD_code));
1174}
1175#endif // __arm__
1176
1177}