blob: 9957565da300eca6ad3462b3c5c699215be26489 [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
Ian Rogers4dd71f12011-08-16 14:16:02 -070060TEST_F(JniInternalTest, GetMethodID) {
61 jclass jlobject = env_->FindClass("java/lang/Object");
62 jclass jlstring = env_->FindClass("java/lang/String");
63 jclass jlnsme = env_->FindClass("java/lang/NoSuchMethodError");
64
65 // Sanity check that no exceptions are pending
66 EXPECT_FALSE(env_->ExceptionCheck());
67
68 // Check that java.lang.Object.foo() doesn't exist and NoSuchMethodError is
69 // a pending exception
70 jmethodID method = env_->GetMethodID(jlobject, "foo", "()V");
71 EXPECT_EQ(static_cast<jmethodID>(NULL), method);
72 EXPECT_TRUE(env_->ExceptionCheck());
73 jthrowable exception = env_->ExceptionOccurred();
74 EXPECT_NE(static_cast<jthrowable>(NULL), exception);
75 EXPECT_TRUE(env_->IsInstanceOf(exception, jlnsme));
76 env_->ExceptionClear();
77
78 // Check that java.lang.Object.equals() does exist
79#if defined(__arm__)
80 method = env_->GetMethodID(jlobject, "equals", "(Ljava/lang/Object;)Z");
81 EXPECT_NE(static_cast<jmethodID>(NULL), method);
82 EXPECT_FALSE(env_->ExceptionCheck());
83#endif
84
85 // Check that GetMethodID for java.lang.String.valueOf(int) fails as the
86 // method is static
87 method = env_->GetMethodID(jlstring, "valueOf", "(I)Ljava/lang/String;");
88 EXPECT_EQ(static_cast<jmethodID>(NULL), method);
89 EXPECT_TRUE(env_->ExceptionCheck());
90 exception = env_->ExceptionOccurred();
91 EXPECT_NE(static_cast<jthrowable>(NULL), exception);
92 EXPECT_TRUE(env_->IsInstanceOf(exception, jlnsme));
93 env_->ExceptionClear();
94}
95
96TEST_F(JniInternalTest, GetStaticMethodID) {
97 jclass jlobject = env_->FindClass("java/lang/Object");
98 jclass jlnsme = env_->FindClass("java/lang/NoSuchMethodError");
99
100 // Sanity check that no exceptions are pending
101 EXPECT_FALSE(env_->ExceptionCheck());
102
103 // Check that java.lang.Object.foo() doesn't exist and NoSuchMethodError is
104 // a pending exception
105 jmethodID method = env_->GetStaticMethodID(jlobject, "foo", "()V");
106 EXPECT_EQ(static_cast<jmethodID>(NULL), method);
107 EXPECT_TRUE(env_->ExceptionCheck());
108 jthrowable exception = env_->ExceptionOccurred();
109 EXPECT_NE(static_cast<jthrowable>(NULL), exception);
110 EXPECT_TRUE(env_->IsInstanceOf(exception, jlnsme));
111 env_->ExceptionClear();
112
113 // Check that GetStaticMethodID for java.lang.Object.equals(Object) fails as
114 // the method is not static
115 method = env_->GetStaticMethodID(jlobject, "equals", "(Ljava/lang/Object;)Z");
116 EXPECT_EQ(static_cast<jmethodID>(NULL), method);
117 EXPECT_TRUE(env_->ExceptionCheck());
118 exception = env_->ExceptionOccurred();
119 EXPECT_NE(static_cast<jthrowable>(NULL), exception);
120 EXPECT_TRUE(env_->IsInstanceOf(exception, jlnsme));
121 env_->ExceptionClear();
122
123 // Check that java.lang.String.valueOf(int) does exist
124#if defined(__arm__)
125 jclass jlstring = env_->FindClass("java/lang/String");
126 method = env_->GetStaticMethodID(jlstring, "valueOf",
127 "(I)Ljava/lang/String;");
128 EXPECT_NE(static_cast<jmethodID>(NULL), method);
129 EXPECT_FALSE(env_->ExceptionCheck());
130#endif
131}
132
133TEST_F(JniInternalTest, RegisterNatives) {
134 jclass jlobject = env_->FindClass("java/lang/Object");
135 jclass jlnsme = env_->FindClass("java/lang/NoSuchMethodError");
136
137 // Sanity check that no exceptions are pending
138 EXPECT_FALSE(env_->ExceptionCheck());
139
140 // Check that registering to a non-existent java.lang.Object.foo() causes a
141 // NoSuchMethodError
142 {
143 JNINativeMethod methods[] = {{"foo", "()V", NULL}};
144 env_->RegisterNatives(jlobject, methods, 1);
145 }
146 EXPECT_TRUE(env_->ExceptionCheck());
147 jthrowable exception = env_->ExceptionOccurred();
148 EXPECT_NE(static_cast<jthrowable>(NULL), exception);
149 EXPECT_TRUE(env_->IsInstanceOf(exception, jlnsme));
150 env_->ExceptionClear();
151
152 // Check that registering non-native methods causes a NoSuchMethodError
153 {
154 JNINativeMethod methods[] = {{"equals", "(Ljava/lang/Object;)Z", NULL}};
155 env_->RegisterNatives(jlobject, methods, 1);
156 }
157 EXPECT_TRUE(env_->ExceptionCheck());
158 exception = env_->ExceptionOccurred();
159 EXPECT_NE(static_cast<jthrowable>(NULL), exception);
160 EXPECT_TRUE(env_->IsInstanceOf(exception, jlnsme));
161 env_->ExceptionClear();
162
163 // Check that registering native methods is successful
164 {
165 JNINativeMethod methods[] = {{"hashCode", "()I", NULL}};
166 env_->RegisterNatives(jlobject, methods, 1);
167 }
168 EXPECT_FALSE(env_->ExceptionCheck());
169}
170
Elliott Hughesd8ddfd52011-08-15 14:32:53 -0700171TEST_F(JniInternalTest, NewPrimitiveArray) {
172 // TODO: death tests for negative array sizes.
173
Elliott Hughesf2682d52011-08-15 16:37:04 -0700174 // TODO: check returned array size.
175
176 // TODO: check returned array class.
177
Elliott Hughes8a26c5c2011-08-15 18:35:43 -0700178 EXPECT_TRUE(env_->NewBooleanArray(0) != NULL);
179 EXPECT_TRUE(env_->NewByteArray(0) != NULL);
180 EXPECT_TRUE(env_->NewCharArray(0) != NULL);
181 EXPECT_TRUE(env_->NewDoubleArray(0) != NULL);
182 EXPECT_TRUE(env_->NewFloatArray(0) != NULL);
183 EXPECT_TRUE(env_->NewIntArray(0) != NULL);
184 EXPECT_TRUE(env_->NewLongArray(0) != NULL);
185 EXPECT_TRUE(env_->NewShortArray(0) != NULL);
Elliott Hughesd8ddfd52011-08-15 14:32:53 -0700186
Elliott Hughes8a26c5c2011-08-15 18:35:43 -0700187 EXPECT_TRUE(env_->NewBooleanArray(1) != NULL);
188 EXPECT_TRUE(env_->NewByteArray(1) != NULL);
189 EXPECT_TRUE(env_->NewCharArray(1) != NULL);
190 EXPECT_TRUE(env_->NewDoubleArray(1) != NULL);
191 EXPECT_TRUE(env_->NewFloatArray(1) != NULL);
192 EXPECT_TRUE(env_->NewIntArray(1) != NULL);
193 EXPECT_TRUE(env_->NewLongArray(1) != NULL);
194 EXPECT_TRUE(env_->NewShortArray(1) != NULL);
Elliott Hughesd8ddfd52011-08-15 14:32:53 -0700195}
196
Elliott Hughesf2682d52011-08-15 16:37:04 -0700197TEST_F(JniInternalTest, NewObjectArray) {
198 // TODO: death tests for negative array sizes.
199
200 // TODO: check returned array size.
201
202 // TODO: check returned array class.
203
204 // TODO: check non-NULL initial elements.
205
Elliott Hughes289da822011-08-16 10:11:20 -0700206 jclass c = env_->FindClass("[Ljava/lang/String;");
207 ASSERT_TRUE(c != NULL);
Elliott Hughesf2682d52011-08-15 16:37:04 -0700208
Elliott Hughes8a26c5c2011-08-15 18:35:43 -0700209 EXPECT_TRUE(env_->NewObjectArray(0, c, NULL) != NULL);
Elliott Hughesf2682d52011-08-15 16:37:04 -0700210
Elliott Hughes8a26c5c2011-08-15 18:35:43 -0700211 EXPECT_TRUE(env_->NewObjectArray(1, c, NULL) != NULL);
212}
213
214TEST_F(JniInternalTest, NewStringUTF) {
215 EXPECT_TRUE(env_->NewStringUTF(NULL) == NULL);
216 EXPECT_TRUE(env_->NewStringUTF("") != NULL);
217 EXPECT_TRUE(env_->NewStringUTF("hello") != NULL);
218 // TODO: check some non-ASCII strings.
Elliott Hughesf2682d52011-08-15 16:37:04 -0700219}
220
Elliott Hughes289da822011-08-16 10:11:20 -0700221TEST_F(JniInternalTest, SetObjectArrayElement) {
222 jclass c = env_->FindClass("[Ljava/lang/Object;");
223 ASSERT_TRUE(c != NULL);
224
225 jobjectArray array = env_->NewObjectArray(1, c, NULL);
226 EXPECT_TRUE(array != NULL);
227 env_->SetObjectArrayElement(array, 0, c);
228 // TODO: check reading value back
Elliott Hughesa5b897e2011-08-16 11:33:06 -0700229
230 // ArrayIndexOutOfBounds for negative index.
231 // TODO: check exception type
232 env_->SetObjectArrayElement(array, -1, c);
233 EXPECT_TRUE(env_->ExceptionCheck());
234 env_->ExceptionClear();
235
236 // ArrayIndexOutOfBounds for too-large index.
237 // TODO: check exception type
238 env_->SetObjectArrayElement(array, 1, c);
239 EXPECT_TRUE(env_->ExceptionCheck());
240 env_->ExceptionClear();
241
Elliott Hughes289da822011-08-16 10:11:20 -0700242 // TODO: check ArrayStoreException thrown for bad types.
243}
244
Elliott Hughes18c07532011-08-18 15:50:51 -0700245TEST_F(JniInternalTest, NewLocalRef_NULL) {
246 EXPECT_TRUE(env_->NewLocalRef(NULL) == NULL);
247}
248
249TEST_F(JniInternalTest, NewLocalRef) {
250 jstring s = env_->NewStringUTF("");
251 ASSERT_TRUE(s != NULL);
252 jobject o = env_->NewLocalRef(s);
253 EXPECT_TRUE(o != NULL);
254 EXPECT_TRUE(o != s);
255
256 // TODO: check that o is a local reference.
257}
258
259TEST_F(JniInternalTest, DeleteLocalRef_NULL) {
260 env_->DeleteLocalRef(NULL);
261}
262
263TEST_F(JniInternalTest, DeleteLocalRef) {
264 jstring s = env_->NewStringUTF("");
265 ASSERT_TRUE(s != NULL);
266 env_->DeleteLocalRef(s);
267
268 // Currently, deleting an already-deleted reference is just a warning.
269 env_->DeleteLocalRef(s);
270
271 s = env_->NewStringUTF("");
272 ASSERT_TRUE(s != NULL);
273 jobject o = env_->NewLocalRef(s);
274 ASSERT_TRUE(o != NULL);
275
276 env_->DeleteLocalRef(s);
277 env_->DeleteLocalRef(o);
278}
279
280TEST_F(JniInternalTest, NewGlobalRef_NULL) {
281 EXPECT_TRUE(env_->NewGlobalRef(NULL) == NULL);
282}
283
284TEST_F(JniInternalTest, NewGlobalRef) {
285 jstring s = env_->NewStringUTF("");
286 ASSERT_TRUE(s != NULL);
287 jobject o = env_->NewGlobalRef(s);
288 EXPECT_TRUE(o != NULL);
289 EXPECT_TRUE(o != s);
290
291 // TODO: check that o is a global reference.
292}
293
294TEST_F(JniInternalTest, DeleteGlobalRef_NULL) {
295 env_->DeleteGlobalRef(NULL);
296}
297
298TEST_F(JniInternalTest, DeleteGlobalRef) {
299 jstring s = env_->NewStringUTF("");
300 ASSERT_TRUE(s != NULL);
301
302 jobject o = env_->NewGlobalRef(s);
303 ASSERT_TRUE(o != NULL);
304 env_->DeleteGlobalRef(o);
305
306 // Currently, deleting an already-deleted reference is just a warning.
307 env_->DeleteGlobalRef(o);
308
309 jobject o1 = env_->NewGlobalRef(s);
310 ASSERT_TRUE(o1 != NULL);
311 jobject o2 = env_->NewGlobalRef(s);
312 ASSERT_TRUE(o2 != NULL);
313
314 env_->DeleteGlobalRef(o1);
315 env_->DeleteGlobalRef(o2);
316}
317
318TEST_F(JniInternalTest, NewWeakGlobalRef_NULL) {
319 EXPECT_TRUE(env_->NewWeakGlobalRef(NULL) == NULL);
320}
321
322TEST_F(JniInternalTest, NewWeakGlobalRef) {
323 jstring s = env_->NewStringUTF("");
324 ASSERT_TRUE(s != NULL);
325 jobject o = env_->NewWeakGlobalRef(s);
326 EXPECT_TRUE(o != NULL);
327 EXPECT_TRUE(o != s);
328
329 // TODO: check that o is a weak global reference.
330}
331
332TEST_F(JniInternalTest, DeleteWeakGlobalRef_NULL) {
333 env_->DeleteWeakGlobalRef(NULL);
334}
335
336TEST_F(JniInternalTest, DeleteWeakGlobalRef) {
337 jstring s = env_->NewStringUTF("");
338 ASSERT_TRUE(s != NULL);
339
340 jobject o = env_->NewWeakGlobalRef(s);
341 ASSERT_TRUE(o != NULL);
342 env_->DeleteWeakGlobalRef(o);
343
344 // Currently, deleting an already-deleted reference is just a warning.
345 env_->DeleteWeakGlobalRef(o);
346
347 jobject o1 = env_->NewWeakGlobalRef(s);
348 ASSERT_TRUE(o1 != NULL);
349 jobject o2 = env_->NewWeakGlobalRef(s);
350 ASSERT_TRUE(o2 != NULL);
351
352 env_->DeleteWeakGlobalRef(o1);
353 env_->DeleteWeakGlobalRef(o2);
354}
355
Carl Shapiro9b9ba282011-08-14 15:30:39 -0700356bool EnsureInvokeStub(Method* method);
357
358byte* AllocateCode(void* code, size_t length) {
359 int prot = PROT_READ | PROT_WRITE | PROT_EXEC;
360 void* addr = mmap(NULL, length, prot, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
361 CHECK(addr != MAP_FAILED);
362 memcpy(addr, code, length);
363 __builtin___clear_cache(addr, (byte*)addr + length);
364 // Set the low-order bit so a BLX will switch to Thumb mode.
365 return reinterpret_cast<byte*>(reinterpret_cast<uintptr_t>(addr) | 1);
366}
367
368Method::InvokeStub* AllocateStub(Method* method,
369 byte* code,
370 size_t length) {
371 CHECK(method->GetInvokeStub() == NULL);
372 EnsureInvokeStub(method);
373 Method::InvokeStub* stub = method->GetInvokeStub();
374 CHECK(stub != NULL);
375 method->SetCode(AllocateCode(code, length));
376 CHECK(method->GetCode() != NULL);
377 return stub;
378}
379
380void FreeStub(Method* method, size_t length) {
381 void* addr = const_cast<void*>(method->GetCode());
382 munmap(addr, length);
383 method->SetCode(NULL);
384}
385
386#if defined(__arm__)
387TEST_F(JniInternalTest, StaticMainMethod) {
388 scoped_ptr<DexFile> dex(OpenDexFileBase64(kMainDex));
389
390 PathClassLoader* class_loader = AllocPathClassLoader(dex.get());
391 ASSERT_TRUE(class_loader != NULL);
392
393 Class* klass = class_linker_->FindClass("LMain;", class_loader);
394 ASSERT_TRUE(klass != NULL);
395
396 Method* method = klass->FindDirectMethod("main", "([Ljava/lang/String;)V");
397 ASSERT_TRUE(method != NULL);
398
399 byte main_LV_code[] = {
400 0x2d, 0xe9, 0x00, 0x40, 0x83, 0xb0, 0xcd, 0xf8, 0x00, 0x00,
401 0xcd, 0xf8, 0x14, 0x10, 0x03, 0xb0, 0xbd, 0xe8, 0x00, 0x80,
402 };
403
404 Method::InvokeStub* stub = AllocateStub(method,
405 main_LV_code,
406 sizeof(main_LV_code));
407
408 Object* arg = NULL;
409
410 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(&arg), NULL);
411
412 FreeStub(method, sizeof(main_LV_code));
413}
414
415TEST_F(JniInternalTest, StaticNopMethod) {
416 scoped_ptr<DexFile> dex(OpenDexFileBase64(kStaticLeafMethodsDex));
417
418 PathClassLoader* class_loader = AllocPathClassLoader(dex.get());
419 ASSERT_TRUE(class_loader != NULL);
420
421 Class* klass = class_linker_->FindClass("LStaticLeafMethods;", class_loader);
422 ASSERT_TRUE(klass != NULL);
423
424 Method* method = klass->FindDirectMethod("nop", "()V");
425 ASSERT_TRUE(method != NULL);
426
427 byte nop_V_code[] = {
428 0x2d, 0xe9, 0x00, 0x40, 0x83, 0xb0, 0xcd, 0xf8,
429 0x00, 0x00, 0x03, 0xb0, 0xbd, 0xe8, 0x00, 0x80,
430 };
431
432 Method::InvokeStub* stub = AllocateStub(method,
433 nop_V_code,
434 sizeof(nop_V_code));
435 ASSERT_TRUE(stub);
436
437 (*stub)(method, NULL, NULL, NULL, NULL);
438
439 FreeStub(method, sizeof(nop_V_code));
440}
441
442TEST_F(JniInternalTest, StaticIdentityByteMethod) {
443 scoped_ptr<DexFile> dex(OpenDexFileBase64(kStaticLeafMethodsDex));
444
445 PathClassLoader* class_loader = AllocPathClassLoader(dex.get());
446 ASSERT_TRUE(class_loader != NULL);
447
448 Class* klass = class_linker_->FindClass("LStaticLeafMethods;", class_loader);
449 ASSERT_TRUE(klass != NULL);
450
451 Method* method = klass->FindDirectMethod("identity", "(B)B");
452 ASSERT_TRUE(method != NULL);
453
454 byte identity_BB_code[] = {
455 0x2d, 0xe9, 0x00, 0x40, 0x83, 0xb0, 0xcd, 0xf8,
456 0x00, 0x00, 0xcd, 0xf8, 0x14, 0x10, 0x05, 0x98,
457 0x03, 0xb0, 0xbd, 0xe8, 0x00, 0x80, 0x00, 0x00,
458 };
459
460 Method::InvokeStub* stub = AllocateStub(method,
461 identity_BB_code,
462 sizeof(identity_BB_code));
463
464 int arg;
465 JValue result;
466
467 arg = 0;
468 result.b = -1;
469 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(&arg), &result);
470 EXPECT_EQ(0, result.b);
471
472 arg = -1;
473 result.b = 0;
474 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(&arg), &result);
475 EXPECT_EQ(-1, result.b);
476
477 arg = SCHAR_MAX;
478 result.b = 0;
479 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(&arg), &result);
480 EXPECT_EQ(SCHAR_MAX, result.b);
481
482 arg = SCHAR_MIN;
483 result.b = 0;
484 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(&arg), &result);
485 EXPECT_EQ(SCHAR_MIN, result.b);
486
487 FreeStub(method, sizeof(identity_BB_code));
488}
489
490TEST_F(JniInternalTest, StaticIdentityIntMethod) {
491 scoped_ptr<DexFile> dex(OpenDexFileBase64(kStaticLeafMethodsDex));
492
493 PathClassLoader* class_loader = AllocPathClassLoader(dex.get());
494 ASSERT_TRUE(class_loader != NULL);
495
496 Class* klass = class_linker_->FindClass("LStaticLeafMethods;", class_loader);
497 ASSERT_TRUE(klass != NULL);
498
499 Method* method = klass->FindDirectMethod("identity", "(I)I");
500 ASSERT_TRUE(method != NULL);
501
502 byte identity_II_code[] = {
503 0x2d, 0xe9, 0x00, 0x40, 0x83, 0xb0, 0xcd, 0xf8,
504 0x00, 0x00, 0xcd, 0xf8, 0x14, 0x10, 0x05, 0x98,
505 0x03, 0xb0, 0xbd, 0xe8, 0x00, 0x80, 0x00, 0x00,
506 };
507
508 Method::InvokeStub* stub = AllocateStub(method,
509 identity_II_code,
510 sizeof(identity_II_code));
511
512 int arg;
513 JValue result;
514
515 arg = 0;
516 result.i = -1;
517 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(&arg), &result);
518 EXPECT_EQ(0, result.i);
519
520 arg = -1;
521 result.i = 0;
522 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(&arg), &result);
523 EXPECT_EQ(-1, result.i);
524
525 arg = INT_MAX;
526 result.i = 0;
527 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(&arg), &result);
528 EXPECT_EQ(INT_MAX, result.i);
529
530 arg = INT_MIN;
531 result.i = 0;
532 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(&arg), &result);
533 EXPECT_EQ(INT_MIN, result.i);
534
535 FreeStub(method, sizeof(identity_II_code));
536}
537
538TEST_F(JniInternalTest, StaticIdentityDoubleMethod) {
539 scoped_ptr<DexFile> dex(OpenDexFileBase64(kStaticLeafMethodsDex));
540
541 PathClassLoader* class_loader = AllocPathClassLoader(dex.get());
542 ASSERT_TRUE(class_loader != NULL);
543
544 Class* klass = class_linker_->FindClass("LStaticLeafMethods;", class_loader);
545 ASSERT_TRUE(klass != NULL);
546
547 Method* method = klass->FindDirectMethod("identity", "(D)D");
548 ASSERT_TRUE(method != NULL);
549
550 byte identity_DD_code[] = {
551 0x2d, 0xe9, 0x00, 0x40, 0x83, 0xb0, 0xcd, 0xf8,
552 0x00, 0x00, 0xcd, 0xf8, 0x14, 0x10, 0xcd, 0xf8,
553 0x18, 0x20, 0x05, 0x98, 0x06, 0x99, 0x03, 0xb0,
554 0xbd, 0xe8, 0x00, 0x80,
555 };
556
557 Method::InvokeStub* stub = AllocateStub(method,
558 identity_DD_code,
559 sizeof(identity_DD_code));
560
561 double arg;
562 JValue result;
563
564 arg = 0.0;
565 result.d = -1.0;
566 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(&arg), &result);
567 EXPECT_EQ(0.0, result.d);
568
569 arg = -1.0;
570 result.d = 0.0;
571 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(&arg), &result);
572 EXPECT_EQ(-1.0, result.d);
573
574 arg = DBL_MAX;
575 result.d = 0.0;
576 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(&arg), &result);
577 EXPECT_EQ(DBL_MAX, result.d);
578
579 arg = DBL_MIN;
580 result.d = 0.0;
581 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(&arg), &result);
582 EXPECT_EQ(DBL_MIN, result.d);
583
584 FreeStub(method, sizeof(identity_DD_code));
585}
586
587TEST_F(JniInternalTest, StaticSumIntIntMethod) {
588 scoped_ptr<DexFile> dex(OpenDexFileBase64(kStaticLeafMethodsDex));
589
590 PathClassLoader* class_loader = AllocPathClassLoader(dex.get());
591 ASSERT_TRUE(class_loader != NULL);
592
593 Class* klass = class_linker_->FindClass("LStaticLeafMethods;", class_loader);
594 ASSERT_TRUE(klass != NULL);
595
596 Method* method = klass->FindDirectMethod("sum", "(II)I");
597 ASSERT_TRUE(method != NULL);
598
599 byte sum_III_code[] = {
600 0x2d, 0xe9, 0x00, 0x40, 0x83, 0xb0, 0xcd, 0xf8,
601 0x00, 0x00, 0xcd, 0xf8, 0x14, 0x10, 0xcd, 0xf8,
602 0x18, 0x20, 0x05, 0x98, 0x06, 0x99, 0x42, 0x18,
603 0xcd, 0xf8, 0x04, 0x20, 0x01, 0x98, 0x03, 0xb0,
604 0xbd, 0xe8, 0x00, 0x80,
605 };
606
607 Method::InvokeStub* stub = AllocateStub(method,
608 sum_III_code,
609 sizeof(sum_III_code));
610
611 int args[2];
612 JValue result;
613
614 args[0] = 0;
615 args[1] = 0;
616 result.i = -1;
617 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
618 EXPECT_EQ(0, result.i);
619
620 args[0] = 1;
621 args[1] = 2;
622 result.i = 0;
623 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
624 EXPECT_EQ(3, result.i);
625
626 args[0] = -2;
627 args[1] = 5;
628 result.i = 0;
629 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
630 EXPECT_EQ(3, result.i);
631
632 args[0] = INT_MAX;
633 args[1] = INT_MIN;
634 result.i = 1234;
635 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
636 EXPECT_EQ(-1, result.i);
637
638 args[0] = INT_MAX;
639 args[1] = INT_MAX;
640 result.i = INT_MIN;
641 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
642 EXPECT_EQ(-2, result.i);
643
644 FreeStub(method, sizeof(sum_III_code));
645}
646
647TEST_F(JniInternalTest, StaticSumIntIntIntMethod) {
648 scoped_ptr<DexFile> dex(OpenDexFileBase64(kStaticLeafMethodsDex));
649
650 PathClassLoader* class_loader = AllocPathClassLoader(dex.get());
651 ASSERT_TRUE(class_loader != NULL);
652
653 Class* klass = class_linker_->FindClass("LStaticLeafMethods;", class_loader);
654 ASSERT_TRUE(klass != NULL);
655
656 Method* method = klass->FindDirectMethod("sum", "(III)I");
657 ASSERT_TRUE(method != NULL);
658
659 byte sum_IIII_code[] = {
660 0x2d, 0xe9, 0x00, 0x40, 0x83, 0xb0, 0xcd, 0xf8,
661 0x00, 0x00, 0xcd, 0xf8, 0x14, 0x10, 0xcd, 0xf8,
662 0x18, 0x20, 0xcd, 0xf8, 0x1c, 0x30, 0x05, 0x98,
663 0x06, 0x99, 0x42, 0x18, 0xcd, 0xf8, 0x04, 0x20,
664 0x01, 0x9b, 0xdd, 0xf8, 0x1c, 0xc0, 0x13, 0xeb,
665 0x0c, 0x03, 0xcd, 0xf8, 0x04, 0x30, 0x01, 0x98,
666 0x03, 0xb0, 0xbd, 0xe8, 0x00, 0x80, 0x00, 0x00,
667 };
668
669 Method::InvokeStub* stub = AllocateStub(method,
670 sum_IIII_code,
671 sizeof(sum_IIII_code));
672
673 int args[3];
674 JValue result;
675
676 args[0] = 0;
677 args[1] = 0;
678 args[2] = 0;
679 result.i = -1;
680 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
681 EXPECT_EQ(0, result.i);
682
683 args[0] = 1;
684 args[1] = 2;
685 args[2] = 3;
686 result.i = 0;
687 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
688 EXPECT_EQ(6, result.i);
689
690 args[0] = -1;
691 args[1] = 2;
692 args[2] = -3;
693 result.i = 0;
694 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
695 EXPECT_EQ(-2, result.i);
696
697 args[0] = INT_MAX;
698 args[1] = INT_MIN;
699 args[2] = INT_MAX;
700 result.i = 1234;
701 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
702 EXPECT_EQ(2147483646, result.i);
703
704 args[0] = INT_MAX;
705 args[1] = INT_MAX;
706 args[2] = INT_MAX;
707 result.i = INT_MIN;
708 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
709 EXPECT_EQ(2147483645, result.i);
710
711 FreeStub(method, sizeof(sum_IIII_code));
712}
713
714TEST_F(JniInternalTest, StaticSumIntIntIntIntMethod) {
715 scoped_ptr<DexFile> dex(OpenDexFileBase64(kStaticLeafMethodsDex));
716
717 PathClassLoader* class_loader = AllocPathClassLoader(dex.get());
718 ASSERT_TRUE(class_loader != NULL);
719
720 Class* klass = class_linker_->FindClass("LStaticLeafMethods;", class_loader);
721 ASSERT_TRUE(klass != NULL);
722
723 Method* method = klass->FindDirectMethod("sum", "(IIII)I");
724 ASSERT_TRUE(method != NULL);
725
726 byte sum_IIIII_code[] = {
727 0x2d, 0xe9, 0x00, 0x40, 0x83, 0xb0, 0xcd, 0xf8,
728 0x00, 0x00, 0xcd, 0xf8, 0x14, 0x10, 0xcd, 0xf8,
729 0x18, 0x20, 0xcd, 0xf8, 0x1c, 0x30, 0x05, 0x98,
730 0x06, 0x99, 0x42, 0x18, 0xcd, 0xf8, 0x04, 0x20,
731 0x01, 0x9b, 0xdd, 0xf8, 0x1c, 0xc0, 0x13, 0xeb,
732 0x0c, 0x03, 0xcd, 0xf8, 0x04, 0x30, 0x01, 0x98,
733 0x08, 0x99, 0x40, 0x18, 0xcd, 0xf8, 0x04, 0x00,
734 0x01, 0x98, 0x03, 0xb0, 0xbd, 0xe8, 0x00, 0x80,
735 };
736
737 Method::InvokeStub* stub = AllocateStub(method,
738 sum_IIIII_code,
739 sizeof(sum_IIIII_code));
740
741 int args[4];
742 JValue result;
743
744 args[0] = 0;
745 args[1] = 0;
746 args[2] = 0;
747 args[3] = 0;
748 result.i = -1;
749 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
750 EXPECT_EQ(0, result.i);
751
752 args[0] = 1;
753 args[1] = 2;
754 args[2] = 3;
755 args[3] = 4;
756 result.i = 0;
757 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
758 EXPECT_EQ(10, result.i);
759
760 args[0] = -1;
761 args[1] = 2;
762 args[2] = -3;
763 args[3] = 4;
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 args[3] = INT_MIN;
772 result.i = 1234;
773 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
774 EXPECT_EQ(-2, result.i);
775
776 args[0] = INT_MAX;
777 args[1] = INT_MAX;
778 args[2] = INT_MAX;
779 args[3] = INT_MAX;
780 result.i = INT_MIN;
781 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
782 EXPECT_EQ(-4, result.i);
783
784 FreeStub(method, sizeof(sum_IIIII_code));
785}
786
787TEST_F(JniInternalTest, StaticSumIntIntIntIntIntMethod) {
788 scoped_ptr<DexFile> dex(OpenDexFileBase64(kStaticLeafMethodsDex));
789
790 PathClassLoader* class_loader = AllocPathClassLoader(dex.get());
791 ASSERT_TRUE(class_loader != NULL);
792
793 Class* klass = class_linker_->FindClass("LStaticLeafMethods;", class_loader);
794 ASSERT_TRUE(klass != NULL);
795
796 Method* method = klass->FindDirectMethod("sum", "(IIIII)I");
797 ASSERT_TRUE(method != NULL);
798
799 byte sum_IIIIII_code[] = {
800 0x2d, 0xe9, 0x00, 0x40, 0x83, 0xb0, 0xcd, 0xf8,
801 0x00, 0x00, 0xcd, 0xf8, 0x14, 0x10, 0xcd, 0xf8,
802 0x18, 0x20, 0xcd, 0xf8, 0x1c, 0x30, 0x05, 0x98,
803 0x06, 0x99, 0x42, 0x18, 0xcd, 0xf8, 0x04, 0x20,
804 0x01, 0x9b, 0xdd, 0xf8, 0x1c, 0xc0, 0x13, 0xeb,
805 0x0c, 0x03, 0xcd, 0xf8, 0x04, 0x30, 0x01, 0x98,
806 0x08, 0x99, 0x40, 0x18, 0xcd, 0xf8, 0x04, 0x00,
807 0x01, 0x9a, 0x09, 0x9b, 0xd2, 0x18, 0xcd, 0xf8,
808 0x04, 0x20, 0x01, 0x98, 0x03, 0xb0, 0xbd, 0xe8,
809 0x00, 0x80, 0x00, 0x00,
810 };
811
812 Method::InvokeStub* stub = AllocateStub(method,
813 sum_IIIIII_code,
814 sizeof(sum_IIIIII_code));
815
816 int args[5];
817 JValue result;
818
819 args[0] = 0;
820 args[1] = 0;
821 args[2] = 0;
822 args[3] = 0;
823 args[4] = 0;
824 result.i = -1.0;
825 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
826 EXPECT_EQ(0, result.i);
827
828 args[0] = 1;
829 args[1] = 2;
830 args[2] = 3;
831 args[3] = 4;
832 args[4] = 5;
833 result.i = 0;
834 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
835 EXPECT_EQ(15, result.i);
836
837 args[0] = -1;
838 args[1] = 2;
839 args[2] = -3;
840 args[3] = 4;
841 args[4] = -5;
842 result.i = 0;
843 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
844 EXPECT_EQ(-3, result.i);
845
846 args[0] = INT_MAX;
847 args[1] = INT_MIN;
848 args[2] = INT_MAX;
849 args[3] = INT_MIN;
850 args[4] = INT_MAX;
851 result.i = 1234;
852 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
853 EXPECT_EQ(2147483645, result.i);
854
855 args[0] = INT_MAX;
856 args[1] = INT_MAX;
857 args[2] = INT_MAX;
858 args[3] = INT_MAX;
859 args[4] = INT_MAX;
860 result.i = INT_MIN;
861 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
862 EXPECT_EQ(2147483643, result.i);
863
864 FreeStub(method, sizeof(sum_IIIIII_code));
865}
866
867TEST_F(JniInternalTest, StaticSumDoubleDoubleMethod) {
868 scoped_ptr<DexFile> dex(OpenDexFileBase64(kStaticLeafMethodsDex));
869
870 PathClassLoader* class_loader = AllocPathClassLoader(dex.get());
871 ASSERT_TRUE(class_loader != NULL);
872
873 Class* klass = class_linker_->FindClass("LStaticLeafMethods;", class_loader);
874 ASSERT_TRUE(klass != NULL);
875
876 Method* method = klass->FindDirectMethod("sum", "(DD)D");
877 ASSERT_TRUE(method != NULL);
878
879 byte sum_DDD_code[] = {
880 0x2d, 0xe9, 0x00, 0x40, 0x87, 0xb0, 0xcd, 0xf8,
881 0x00, 0x00, 0xcd, 0xf8, 0x24, 0x10, 0xcd, 0xf8,
882 0x28, 0x20, 0xcd, 0xf8, 0x2c, 0x30, 0x9d, 0xed,
883 0x09, 0x0b, 0x9d, 0xed, 0x0b, 0x1b, 0x30, 0xee,
884 0x01, 0x2b, 0x8d, 0xed, 0x04, 0x2b, 0x04, 0x98,
885 0x05, 0x99, 0x07, 0xb0, 0xbd, 0xe8, 0x00, 0x80,
886 };
887
888 Method::InvokeStub* stub = AllocateStub(method,
889 sum_DDD_code,
890 sizeof(sum_DDD_code));
891
892 double args[2];
893 JValue result;
894
895 args[0] = 0.0;
896 args[1] = 0.0;
897 result.d = -1.0;
898 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
899 EXPECT_EQ(0.0, result.d);
900
901 args[0] = 1.0;
902 args[1] = 2.0;
903 result.d = 0.0;
904 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
905 EXPECT_EQ(3.0, result.d);
906
907 args[0] = 1.0;
908 args[1] = -2.0;
909 result.d = 0.0;
910 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
911 EXPECT_EQ(-1.0, result.d);
912
913 args[0] = DBL_MAX;
914 args[1] = DBL_MIN;
915 result.d = 0.0;
916 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
917 EXPECT_EQ(1.7976931348623157e308, result.d);
918
919 args[0] = DBL_MAX;
920 args[1] = DBL_MAX;
921 result.d = 0.0;
922 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
923 EXPECT_EQ(INFINITY, result.d);
924
925 FreeStub(method, sizeof(sum_DDD_code));
926}
927
928TEST_F(JniInternalTest, StaticSumDoubleDoubleDoubleMethod) {
929 scoped_ptr<DexFile> dex(OpenDexFileBase64(kStaticLeafMethodsDex));
930
931 PathClassLoader* class_loader = AllocPathClassLoader(dex.get());
932 ASSERT_TRUE(class_loader != NULL);
933
934 Class* klass = class_linker_->FindClass("LStaticLeafMethods;", class_loader);
935 ASSERT_TRUE(klass != NULL);
936
937 Method* method = klass->FindDirectMethod("sum", "(DDD)D");
938 ASSERT_TRUE(method != NULL);
939
940 byte sum_DDDD_code[] = {
941 0x2d, 0xe9, 0x00, 0x40, 0x87, 0xb0, 0xcd, 0xf8,
942 0x00, 0x00, 0xcd, 0xf8, 0x24, 0x10, 0xcd, 0xf8,
943 0x28, 0x20, 0xcd, 0xf8, 0x2c, 0x30, 0x9d, 0xed,
944 0x09, 0x0b, 0x9d, 0xed, 0x0b, 0x1b, 0x30, 0xee,
945 0x01, 0x2b, 0x8d, 0xed, 0x04, 0x2b, 0x9d, 0xed,
946 0x04, 0x3b, 0x9d, 0xed, 0x0d, 0x4b, 0x33, 0xee,
947 0x04, 0x3b, 0x8d, 0xed, 0x04, 0x3b, 0x04, 0x98,
948 0x05, 0x99, 0x07, 0xb0, 0xbd, 0xe8, 0x00, 0x80,
949 };
950
951 Method::InvokeStub* stub = AllocateStub(method,
952 sum_DDDD_code,
953 sizeof(sum_DDDD_code));
954
955 double args[3];
956 JValue result;
957
958 args[0] = 0.0;
959 args[1] = 0.0;
960 args[2] = 0.0;
961 result.d = -1.0;
962 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
963 EXPECT_EQ(0.0, result.d);
964
965 args[0] = 1.0;
966 args[1] = 2.0;
967 args[2] = 3.0;
968 result.d = 0.0;
969 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
970 EXPECT_EQ(6.0, result.d);
971
972 args[0] = 1.0;
973 args[1] = -2.0;
974 args[2] = 3.0;
975 result.d = 0.0;
976 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
977 EXPECT_EQ(2.0, result.d);
978
979 FreeStub(method, sizeof(sum_DDDD_code));
980}
981
982TEST_F(JniInternalTest, StaticSumDoubleDoubleDoubleDoubleMethod) {
983 scoped_ptr<DexFile> dex(OpenDexFileBase64(kStaticLeafMethodsDex));
984
985 PathClassLoader* class_loader = AllocPathClassLoader(dex.get());
986 ASSERT_TRUE(class_loader != NULL);
987
988 Class* klass = class_linker_->FindClass("LStaticLeafMethods;", class_loader);
989 ASSERT_TRUE(klass != NULL);
990
991 Method* method = klass->FindDirectMethod("sum", "(DDDD)D");
992 ASSERT_TRUE(method != NULL);
993
994 byte sum_DDDDD_code[] = {
995 0x2d, 0xe9, 0x00, 0x40, 0x87, 0xb0, 0xcd, 0xf8,
996 0x00, 0x00, 0xcd, 0xf8, 0x24, 0x10, 0xcd, 0xf8,
997 0x28, 0x20, 0xcd, 0xf8, 0x2c, 0x30, 0x9d, 0xed,
998 0x09, 0x0b, 0x9d, 0xed, 0x0b, 0x1b, 0x30, 0xee,
999 0x01, 0x2b, 0x8d, 0xed, 0x04, 0x2b, 0x9d, 0xed,
1000 0x04, 0x3b, 0x9d, 0xed, 0x0d, 0x4b, 0x33, 0xee,
1001 0x04, 0x3b, 0x8d, 0xed, 0x04, 0x3b, 0x9d, 0xed,
1002 0x04, 0x5b, 0x9d, 0xed, 0x0f, 0x6b, 0x35, 0xee,
1003 0x06, 0x5b, 0x8d, 0xed, 0x04, 0x5b, 0x04, 0x98,
1004 0x05, 0x99, 0x07, 0xb0, 0xbd, 0xe8, 0x00, 0x80,
1005 };
1006
1007 Method::InvokeStub* stub = AllocateStub(method,
1008 sum_DDDDD_code,
1009 sizeof(sum_DDDDD_code));
1010
1011 double args[4];
1012 JValue result;
1013
1014 args[0] = 0.0;
1015 args[1] = 0.0;
1016 args[2] = 0.0;
1017 args[3] = 0.0;
1018 result.d = -1.0;
1019 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
1020 EXPECT_EQ(0.0, result.d);
1021
1022 args[0] = 1.0;
1023 args[1] = 2.0;
1024 args[2] = 3.0;
1025 args[3] = 4.0;
1026 result.d = 0.0;
1027 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
1028 EXPECT_EQ(10.0, result.d);
1029
1030 args[0] = 1.0;
1031 args[1] = -2.0;
1032 args[2] = 3.0;
1033 args[3] = -4.0;
1034 result.d = 0.0;
1035 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
1036 EXPECT_EQ(-2.0, result.d);
1037
1038 FreeStub(method, sizeof(sum_DDDDD_code));
1039}
1040
1041TEST_F(JniInternalTest, StaticSumDoubleDoubleDoubleDoubleDoubleMethod) {
1042 scoped_ptr<DexFile> dex(OpenDexFileBase64(kStaticLeafMethodsDex));
1043
1044 PathClassLoader* class_loader = AllocPathClassLoader(dex.get());
1045 ASSERT_TRUE(class_loader != NULL);
1046
1047 Class* klass = class_linker_->FindClass("LStaticLeafMethods;", class_loader);
1048 ASSERT_TRUE(klass != NULL);
1049
1050 Method* method = klass->FindDirectMethod("sum", "(DDDDD)D");
1051 ASSERT_TRUE(method != NULL);
1052
1053 byte sum_DDDDDD_code[] = {
1054 0x2d, 0xe9, 0x00, 0x40, 0x87, 0xb0, 0xcd, 0xf8,
1055 0x00, 0x00, 0xcd, 0xf8, 0x24, 0x10, 0xcd, 0xf8,
1056 0x28, 0x20, 0xcd, 0xf8, 0x2c, 0x30, 0x9d, 0xed,
1057 0x09, 0x0b, 0x9d, 0xed, 0x0b, 0x1b, 0x30, 0xee,
1058 0x01, 0x2b, 0x8d, 0xed, 0x04, 0x2b, 0x9d, 0xed,
1059 0x04, 0x3b, 0x9d, 0xed, 0x0d, 0x4b, 0x33, 0xee,
1060 0x04, 0x3b, 0x8d, 0xed, 0x04, 0x3b, 0x9d, 0xed,
1061 0x04, 0x5b, 0x9d, 0xed, 0x0f, 0x6b, 0x35, 0xee,
1062 0x06, 0x5b, 0x8d, 0xed, 0x04, 0x5b, 0x9d, 0xed,
1063 0x04, 0x7b, 0x9d, 0xed, 0x11, 0x0b, 0x37, 0xee,
1064 0x00, 0x7b, 0x8d, 0xed, 0x04, 0x7b, 0x04, 0x98,
1065 0x05, 0x99, 0x07, 0xb0, 0xbd, 0xe8, 0x00, 0x80,
1066 };
1067
1068 Method::InvokeStub* stub = AllocateStub(method,
1069 sum_DDDDDD_code,
1070 sizeof(sum_DDDDDD_code));
1071
1072 double args[5];
1073 JValue result;
1074
1075 args[0] = 0.0;
1076 args[1] = 0.0;
1077 args[2] = 0.0;
1078 args[3] = 0.0;
1079 args[4] = 0.0;
1080 result.d = -1.0;
1081 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
1082 EXPECT_EQ(0.0, result.d);
1083
1084 args[0] = 1.0;
1085 args[1] = 2.0;
1086 args[2] = 3.0;
1087 args[3] = 4.0;
1088 args[4] = 5.0;
1089 result.d = 0.0;
1090 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
1091 EXPECT_EQ(15.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 args[4] = 5.0;
1098 result.d = 0.0;
1099 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
1100 EXPECT_EQ(3.0, result.d);
1101
1102 FreeStub(method, sizeof(sum_DDDDDD_code));
1103}
1104#endif // __arm__
1105
1106}