blob: 457bae892d53cb601cf413dc8dd291dde7e27bf2 [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
13class JniInternalTest : public RuntimeTest {
Elliott Hughesc7ac37f2011-08-12 12:21:58 -070014 protected:
15 virtual void SetUp() {
16 RuntimeTest::SetUp();
17 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
Carl Shapiro9b9ba282011-08-14 15:30:39 -070060bool EnsureInvokeStub(Method* method);
61
62byte* AllocateCode(void* code, size_t length) {
63 int prot = PROT_READ | PROT_WRITE | PROT_EXEC;
64 void* addr = mmap(NULL, length, prot, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
65 CHECK(addr != MAP_FAILED);
66 memcpy(addr, code, length);
67 __builtin___clear_cache(addr, (byte*)addr + length);
68 // Set the low-order bit so a BLX will switch to Thumb mode.
69 return reinterpret_cast<byte*>(reinterpret_cast<uintptr_t>(addr) | 1);
70}
71
72Method::InvokeStub* AllocateStub(Method* method,
73 byte* code,
74 size_t length) {
75 CHECK(method->GetInvokeStub() == NULL);
76 EnsureInvokeStub(method);
77 Method::InvokeStub* stub = method->GetInvokeStub();
78 CHECK(stub != NULL);
79 method->SetCode(AllocateCode(code, length));
80 CHECK(method->GetCode() != NULL);
81 return stub;
82}
83
84void FreeStub(Method* method, size_t length) {
85 void* addr = const_cast<void*>(method->GetCode());
86 munmap(addr, length);
87 method->SetCode(NULL);
88}
89
90#if defined(__arm__)
91TEST_F(JniInternalTest, StaticMainMethod) {
92 scoped_ptr<DexFile> dex(OpenDexFileBase64(kMainDex));
93
94 PathClassLoader* class_loader = AllocPathClassLoader(dex.get());
95 ASSERT_TRUE(class_loader != NULL);
96
97 Class* klass = class_linker_->FindClass("LMain;", class_loader);
98 ASSERT_TRUE(klass != NULL);
99
100 Method* method = klass->FindDirectMethod("main", "([Ljava/lang/String;)V");
101 ASSERT_TRUE(method != NULL);
102
103 byte main_LV_code[] = {
104 0x2d, 0xe9, 0x00, 0x40, 0x83, 0xb0, 0xcd, 0xf8, 0x00, 0x00,
105 0xcd, 0xf8, 0x14, 0x10, 0x03, 0xb0, 0xbd, 0xe8, 0x00, 0x80,
106 };
107
108 Method::InvokeStub* stub = AllocateStub(method,
109 main_LV_code,
110 sizeof(main_LV_code));
111
112 Object* arg = NULL;
113
114 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(&arg), NULL);
115
116 FreeStub(method, sizeof(main_LV_code));
117}
118
119TEST_F(JniInternalTest, StaticNopMethod) {
120 scoped_ptr<DexFile> dex(OpenDexFileBase64(kStaticLeafMethodsDex));
121
122 PathClassLoader* class_loader = AllocPathClassLoader(dex.get());
123 ASSERT_TRUE(class_loader != NULL);
124
125 Class* klass = class_linker_->FindClass("LStaticLeafMethods;", class_loader);
126 ASSERT_TRUE(klass != NULL);
127
128 Method* method = klass->FindDirectMethod("nop", "()V");
129 ASSERT_TRUE(method != NULL);
130
131 byte nop_V_code[] = {
132 0x2d, 0xe9, 0x00, 0x40, 0x83, 0xb0, 0xcd, 0xf8,
133 0x00, 0x00, 0x03, 0xb0, 0xbd, 0xe8, 0x00, 0x80,
134 };
135
136 Method::InvokeStub* stub = AllocateStub(method,
137 nop_V_code,
138 sizeof(nop_V_code));
139 ASSERT_TRUE(stub);
140
141 (*stub)(method, NULL, NULL, NULL, NULL);
142
143 FreeStub(method, sizeof(nop_V_code));
144}
145
146TEST_F(JniInternalTest, StaticIdentityByteMethod) {
147 scoped_ptr<DexFile> dex(OpenDexFileBase64(kStaticLeafMethodsDex));
148
149 PathClassLoader* class_loader = AllocPathClassLoader(dex.get());
150 ASSERT_TRUE(class_loader != NULL);
151
152 Class* klass = class_linker_->FindClass("LStaticLeafMethods;", class_loader);
153 ASSERT_TRUE(klass != NULL);
154
155 Method* method = klass->FindDirectMethod("identity", "(B)B");
156 ASSERT_TRUE(method != NULL);
157
158 byte identity_BB_code[] = {
159 0x2d, 0xe9, 0x00, 0x40, 0x83, 0xb0, 0xcd, 0xf8,
160 0x00, 0x00, 0xcd, 0xf8, 0x14, 0x10, 0x05, 0x98,
161 0x03, 0xb0, 0xbd, 0xe8, 0x00, 0x80, 0x00, 0x00,
162 };
163
164 Method::InvokeStub* stub = AllocateStub(method,
165 identity_BB_code,
166 sizeof(identity_BB_code));
167
168 int arg;
169 JValue result;
170
171 arg = 0;
172 result.b = -1;
173 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(&arg), &result);
174 EXPECT_EQ(0, result.b);
175
176 arg = -1;
177 result.b = 0;
178 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(&arg), &result);
179 EXPECT_EQ(-1, result.b);
180
181 arg = SCHAR_MAX;
182 result.b = 0;
183 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(&arg), &result);
184 EXPECT_EQ(SCHAR_MAX, result.b);
185
186 arg = SCHAR_MIN;
187 result.b = 0;
188 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(&arg), &result);
189 EXPECT_EQ(SCHAR_MIN, result.b);
190
191 FreeStub(method, sizeof(identity_BB_code));
192}
193
194TEST_F(JniInternalTest, StaticIdentityIntMethod) {
195 scoped_ptr<DexFile> dex(OpenDexFileBase64(kStaticLeafMethodsDex));
196
197 PathClassLoader* class_loader = AllocPathClassLoader(dex.get());
198 ASSERT_TRUE(class_loader != NULL);
199
200 Class* klass = class_linker_->FindClass("LStaticLeafMethods;", class_loader);
201 ASSERT_TRUE(klass != NULL);
202
203 Method* method = klass->FindDirectMethod("identity", "(I)I");
204 ASSERT_TRUE(method != NULL);
205
206 byte identity_II_code[] = {
207 0x2d, 0xe9, 0x00, 0x40, 0x83, 0xb0, 0xcd, 0xf8,
208 0x00, 0x00, 0xcd, 0xf8, 0x14, 0x10, 0x05, 0x98,
209 0x03, 0xb0, 0xbd, 0xe8, 0x00, 0x80, 0x00, 0x00,
210 };
211
212 Method::InvokeStub* stub = AllocateStub(method,
213 identity_II_code,
214 sizeof(identity_II_code));
215
216 int arg;
217 JValue result;
218
219 arg = 0;
220 result.i = -1;
221 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(&arg), &result);
222 EXPECT_EQ(0, result.i);
223
224 arg = -1;
225 result.i = 0;
226 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(&arg), &result);
227 EXPECT_EQ(-1, result.i);
228
229 arg = INT_MAX;
230 result.i = 0;
231 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(&arg), &result);
232 EXPECT_EQ(INT_MAX, result.i);
233
234 arg = INT_MIN;
235 result.i = 0;
236 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(&arg), &result);
237 EXPECT_EQ(INT_MIN, result.i);
238
239 FreeStub(method, sizeof(identity_II_code));
240}
241
242TEST_F(JniInternalTest, StaticIdentityDoubleMethod) {
243 scoped_ptr<DexFile> dex(OpenDexFileBase64(kStaticLeafMethodsDex));
244
245 PathClassLoader* class_loader = AllocPathClassLoader(dex.get());
246 ASSERT_TRUE(class_loader != NULL);
247
248 Class* klass = class_linker_->FindClass("LStaticLeafMethods;", class_loader);
249 ASSERT_TRUE(klass != NULL);
250
251 Method* method = klass->FindDirectMethod("identity", "(D)D");
252 ASSERT_TRUE(method != NULL);
253
254 byte identity_DD_code[] = {
255 0x2d, 0xe9, 0x00, 0x40, 0x83, 0xb0, 0xcd, 0xf8,
256 0x00, 0x00, 0xcd, 0xf8, 0x14, 0x10, 0xcd, 0xf8,
257 0x18, 0x20, 0x05, 0x98, 0x06, 0x99, 0x03, 0xb0,
258 0xbd, 0xe8, 0x00, 0x80,
259 };
260
261 Method::InvokeStub* stub = AllocateStub(method,
262 identity_DD_code,
263 sizeof(identity_DD_code));
264
265 double arg;
266 JValue result;
267
268 arg = 0.0;
269 result.d = -1.0;
270 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(&arg), &result);
271 EXPECT_EQ(0.0, result.d);
272
273 arg = -1.0;
274 result.d = 0.0;
275 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(&arg), &result);
276 EXPECT_EQ(-1.0, result.d);
277
278 arg = DBL_MAX;
279 result.d = 0.0;
280 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(&arg), &result);
281 EXPECT_EQ(DBL_MAX, result.d);
282
283 arg = DBL_MIN;
284 result.d = 0.0;
285 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(&arg), &result);
286 EXPECT_EQ(DBL_MIN, result.d);
287
288 FreeStub(method, sizeof(identity_DD_code));
289}
290
291TEST_F(JniInternalTest, StaticSumIntIntMethod) {
292 scoped_ptr<DexFile> dex(OpenDexFileBase64(kStaticLeafMethodsDex));
293
294 PathClassLoader* class_loader = AllocPathClassLoader(dex.get());
295 ASSERT_TRUE(class_loader != NULL);
296
297 Class* klass = class_linker_->FindClass("LStaticLeafMethods;", class_loader);
298 ASSERT_TRUE(klass != NULL);
299
300 Method* method = klass->FindDirectMethod("sum", "(II)I");
301 ASSERT_TRUE(method != NULL);
302
303 byte sum_III_code[] = {
304 0x2d, 0xe9, 0x00, 0x40, 0x83, 0xb0, 0xcd, 0xf8,
305 0x00, 0x00, 0xcd, 0xf8, 0x14, 0x10, 0xcd, 0xf8,
306 0x18, 0x20, 0x05, 0x98, 0x06, 0x99, 0x42, 0x18,
307 0xcd, 0xf8, 0x04, 0x20, 0x01, 0x98, 0x03, 0xb0,
308 0xbd, 0xe8, 0x00, 0x80,
309 };
310
311 Method::InvokeStub* stub = AllocateStub(method,
312 sum_III_code,
313 sizeof(sum_III_code));
314
315 int args[2];
316 JValue result;
317
318 args[0] = 0;
319 args[1] = 0;
320 result.i = -1;
321 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
322 EXPECT_EQ(0, result.i);
323
324 args[0] = 1;
325 args[1] = 2;
326 result.i = 0;
327 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
328 EXPECT_EQ(3, result.i);
329
330 args[0] = -2;
331 args[1] = 5;
332 result.i = 0;
333 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
334 EXPECT_EQ(3, result.i);
335
336 args[0] = INT_MAX;
337 args[1] = INT_MIN;
338 result.i = 1234;
339 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
340 EXPECT_EQ(-1, result.i);
341
342 args[0] = INT_MAX;
343 args[1] = INT_MAX;
344 result.i = INT_MIN;
345 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
346 EXPECT_EQ(-2, result.i);
347
348 FreeStub(method, sizeof(sum_III_code));
349}
350
351TEST_F(JniInternalTest, StaticSumIntIntIntMethod) {
352 scoped_ptr<DexFile> dex(OpenDexFileBase64(kStaticLeafMethodsDex));
353
354 PathClassLoader* class_loader = AllocPathClassLoader(dex.get());
355 ASSERT_TRUE(class_loader != NULL);
356
357 Class* klass = class_linker_->FindClass("LStaticLeafMethods;", class_loader);
358 ASSERT_TRUE(klass != NULL);
359
360 Method* method = klass->FindDirectMethod("sum", "(III)I");
361 ASSERT_TRUE(method != NULL);
362
363 byte sum_IIII_code[] = {
364 0x2d, 0xe9, 0x00, 0x40, 0x83, 0xb0, 0xcd, 0xf8,
365 0x00, 0x00, 0xcd, 0xf8, 0x14, 0x10, 0xcd, 0xf8,
366 0x18, 0x20, 0xcd, 0xf8, 0x1c, 0x30, 0x05, 0x98,
367 0x06, 0x99, 0x42, 0x18, 0xcd, 0xf8, 0x04, 0x20,
368 0x01, 0x9b, 0xdd, 0xf8, 0x1c, 0xc0, 0x13, 0xeb,
369 0x0c, 0x03, 0xcd, 0xf8, 0x04, 0x30, 0x01, 0x98,
370 0x03, 0xb0, 0xbd, 0xe8, 0x00, 0x80, 0x00, 0x00,
371 };
372
373 Method::InvokeStub* stub = AllocateStub(method,
374 sum_IIII_code,
375 sizeof(sum_IIII_code));
376
377 int args[3];
378 JValue result;
379
380 args[0] = 0;
381 args[1] = 0;
382 args[2] = 0;
383 result.i = -1;
384 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
385 EXPECT_EQ(0, result.i);
386
387 args[0] = 1;
388 args[1] = 2;
389 args[2] = 3;
390 result.i = 0;
391 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
392 EXPECT_EQ(6, result.i);
393
394 args[0] = -1;
395 args[1] = 2;
396 args[2] = -3;
397 result.i = 0;
398 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
399 EXPECT_EQ(-2, result.i);
400
401 args[0] = INT_MAX;
402 args[1] = INT_MIN;
403 args[2] = INT_MAX;
404 result.i = 1234;
405 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
406 EXPECT_EQ(2147483646, result.i);
407
408 args[0] = INT_MAX;
409 args[1] = INT_MAX;
410 args[2] = INT_MAX;
411 result.i = INT_MIN;
412 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
413 EXPECT_EQ(2147483645, result.i);
414
415 FreeStub(method, sizeof(sum_IIII_code));
416}
417
418TEST_F(JniInternalTest, StaticSumIntIntIntIntMethod) {
419 scoped_ptr<DexFile> dex(OpenDexFileBase64(kStaticLeafMethodsDex));
420
421 PathClassLoader* class_loader = AllocPathClassLoader(dex.get());
422 ASSERT_TRUE(class_loader != NULL);
423
424 Class* klass = class_linker_->FindClass("LStaticLeafMethods;", class_loader);
425 ASSERT_TRUE(klass != NULL);
426
427 Method* method = klass->FindDirectMethod("sum", "(IIII)I");
428 ASSERT_TRUE(method != NULL);
429
430 byte sum_IIIII_code[] = {
431 0x2d, 0xe9, 0x00, 0x40, 0x83, 0xb0, 0xcd, 0xf8,
432 0x00, 0x00, 0xcd, 0xf8, 0x14, 0x10, 0xcd, 0xf8,
433 0x18, 0x20, 0xcd, 0xf8, 0x1c, 0x30, 0x05, 0x98,
434 0x06, 0x99, 0x42, 0x18, 0xcd, 0xf8, 0x04, 0x20,
435 0x01, 0x9b, 0xdd, 0xf8, 0x1c, 0xc0, 0x13, 0xeb,
436 0x0c, 0x03, 0xcd, 0xf8, 0x04, 0x30, 0x01, 0x98,
437 0x08, 0x99, 0x40, 0x18, 0xcd, 0xf8, 0x04, 0x00,
438 0x01, 0x98, 0x03, 0xb0, 0xbd, 0xe8, 0x00, 0x80,
439 };
440
441 Method::InvokeStub* stub = AllocateStub(method,
442 sum_IIIII_code,
443 sizeof(sum_IIIII_code));
444
445 int args[4];
446 JValue result;
447
448 args[0] = 0;
449 args[1] = 0;
450 args[2] = 0;
451 args[3] = 0;
452 result.i = -1;
453 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
454 EXPECT_EQ(0, result.i);
455
456 args[0] = 1;
457 args[1] = 2;
458 args[2] = 3;
459 args[3] = 4;
460 result.i = 0;
461 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
462 EXPECT_EQ(10, result.i);
463
464 args[0] = -1;
465 args[1] = 2;
466 args[2] = -3;
467 args[3] = 4;
468 result.i = 0;
469 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
470 EXPECT_EQ(2, result.i);
471
472 args[0] = INT_MAX;
473 args[1] = INT_MIN;
474 args[2] = INT_MAX;
475 args[3] = INT_MIN;
476 result.i = 1234;
477 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
478 EXPECT_EQ(-2, result.i);
479
480 args[0] = INT_MAX;
481 args[1] = INT_MAX;
482 args[2] = INT_MAX;
483 args[3] = INT_MAX;
484 result.i = INT_MIN;
485 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
486 EXPECT_EQ(-4, result.i);
487
488 FreeStub(method, sizeof(sum_IIIII_code));
489}
490
491TEST_F(JniInternalTest, StaticSumIntIntIntIntIntMethod) {
492 scoped_ptr<DexFile> dex(OpenDexFileBase64(kStaticLeafMethodsDex));
493
494 PathClassLoader* class_loader = AllocPathClassLoader(dex.get());
495 ASSERT_TRUE(class_loader != NULL);
496
497 Class* klass = class_linker_->FindClass("LStaticLeafMethods;", class_loader);
498 ASSERT_TRUE(klass != NULL);
499
500 Method* method = klass->FindDirectMethod("sum", "(IIIII)I");
501 ASSERT_TRUE(method != NULL);
502
503 byte sum_IIIIII_code[] = {
504 0x2d, 0xe9, 0x00, 0x40, 0x83, 0xb0, 0xcd, 0xf8,
505 0x00, 0x00, 0xcd, 0xf8, 0x14, 0x10, 0xcd, 0xf8,
506 0x18, 0x20, 0xcd, 0xf8, 0x1c, 0x30, 0x05, 0x98,
507 0x06, 0x99, 0x42, 0x18, 0xcd, 0xf8, 0x04, 0x20,
508 0x01, 0x9b, 0xdd, 0xf8, 0x1c, 0xc0, 0x13, 0xeb,
509 0x0c, 0x03, 0xcd, 0xf8, 0x04, 0x30, 0x01, 0x98,
510 0x08, 0x99, 0x40, 0x18, 0xcd, 0xf8, 0x04, 0x00,
511 0x01, 0x9a, 0x09, 0x9b, 0xd2, 0x18, 0xcd, 0xf8,
512 0x04, 0x20, 0x01, 0x98, 0x03, 0xb0, 0xbd, 0xe8,
513 0x00, 0x80, 0x00, 0x00,
514 };
515
516 Method::InvokeStub* stub = AllocateStub(method,
517 sum_IIIIII_code,
518 sizeof(sum_IIIIII_code));
519
520 int args[5];
521 JValue result;
522
523 args[0] = 0;
524 args[1] = 0;
525 args[2] = 0;
526 args[3] = 0;
527 args[4] = 0;
528 result.i = -1.0;
529 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
530 EXPECT_EQ(0, result.i);
531
532 args[0] = 1;
533 args[1] = 2;
534 args[2] = 3;
535 args[3] = 4;
536 args[4] = 5;
537 result.i = 0;
538 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
539 EXPECT_EQ(15, result.i);
540
541 args[0] = -1;
542 args[1] = 2;
543 args[2] = -3;
544 args[3] = 4;
545 args[4] = -5;
546 result.i = 0;
547 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
548 EXPECT_EQ(-3, result.i);
549
550 args[0] = INT_MAX;
551 args[1] = INT_MIN;
552 args[2] = INT_MAX;
553 args[3] = INT_MIN;
554 args[4] = INT_MAX;
555 result.i = 1234;
556 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
557 EXPECT_EQ(2147483645, result.i);
558
559 args[0] = INT_MAX;
560 args[1] = INT_MAX;
561 args[2] = INT_MAX;
562 args[3] = INT_MAX;
563 args[4] = INT_MAX;
564 result.i = INT_MIN;
565 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
566 EXPECT_EQ(2147483643, result.i);
567
568 FreeStub(method, sizeof(sum_IIIIII_code));
569}
570
571TEST_F(JniInternalTest, StaticSumDoubleDoubleMethod) {
572 scoped_ptr<DexFile> dex(OpenDexFileBase64(kStaticLeafMethodsDex));
573
574 PathClassLoader* class_loader = AllocPathClassLoader(dex.get());
575 ASSERT_TRUE(class_loader != NULL);
576
577 Class* klass = class_linker_->FindClass("LStaticLeafMethods;", class_loader);
578 ASSERT_TRUE(klass != NULL);
579
580 Method* method = klass->FindDirectMethod("sum", "(DD)D");
581 ASSERT_TRUE(method != NULL);
582
583 byte sum_DDD_code[] = {
584 0x2d, 0xe9, 0x00, 0x40, 0x87, 0xb0, 0xcd, 0xf8,
585 0x00, 0x00, 0xcd, 0xf8, 0x24, 0x10, 0xcd, 0xf8,
586 0x28, 0x20, 0xcd, 0xf8, 0x2c, 0x30, 0x9d, 0xed,
587 0x09, 0x0b, 0x9d, 0xed, 0x0b, 0x1b, 0x30, 0xee,
588 0x01, 0x2b, 0x8d, 0xed, 0x04, 0x2b, 0x04, 0x98,
589 0x05, 0x99, 0x07, 0xb0, 0xbd, 0xe8, 0x00, 0x80,
590 };
591
592 Method::InvokeStub* stub = AllocateStub(method,
593 sum_DDD_code,
594 sizeof(sum_DDD_code));
595
596 double args[2];
597 JValue result;
598
599 args[0] = 0.0;
600 args[1] = 0.0;
601 result.d = -1.0;
602 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
603 EXPECT_EQ(0.0, result.d);
604
605 args[0] = 1.0;
606 args[1] = 2.0;
607 result.d = 0.0;
608 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
609 EXPECT_EQ(3.0, result.d);
610
611 args[0] = 1.0;
612 args[1] = -2.0;
613 result.d = 0.0;
614 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
615 EXPECT_EQ(-1.0, result.d);
616
617 args[0] = DBL_MAX;
618 args[1] = DBL_MIN;
619 result.d = 0.0;
620 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
621 EXPECT_EQ(1.7976931348623157e308, result.d);
622
623 args[0] = DBL_MAX;
624 args[1] = DBL_MAX;
625 result.d = 0.0;
626 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
627 EXPECT_EQ(INFINITY, result.d);
628
629 FreeStub(method, sizeof(sum_DDD_code));
630}
631
632TEST_F(JniInternalTest, StaticSumDoubleDoubleDoubleMethod) {
633 scoped_ptr<DexFile> dex(OpenDexFileBase64(kStaticLeafMethodsDex));
634
635 PathClassLoader* class_loader = AllocPathClassLoader(dex.get());
636 ASSERT_TRUE(class_loader != NULL);
637
638 Class* klass = class_linker_->FindClass("LStaticLeafMethods;", class_loader);
639 ASSERT_TRUE(klass != NULL);
640
641 Method* method = klass->FindDirectMethod("sum", "(DDD)D");
642 ASSERT_TRUE(method != NULL);
643
644 byte sum_DDDD_code[] = {
645 0x2d, 0xe9, 0x00, 0x40, 0x87, 0xb0, 0xcd, 0xf8,
646 0x00, 0x00, 0xcd, 0xf8, 0x24, 0x10, 0xcd, 0xf8,
647 0x28, 0x20, 0xcd, 0xf8, 0x2c, 0x30, 0x9d, 0xed,
648 0x09, 0x0b, 0x9d, 0xed, 0x0b, 0x1b, 0x30, 0xee,
649 0x01, 0x2b, 0x8d, 0xed, 0x04, 0x2b, 0x9d, 0xed,
650 0x04, 0x3b, 0x9d, 0xed, 0x0d, 0x4b, 0x33, 0xee,
651 0x04, 0x3b, 0x8d, 0xed, 0x04, 0x3b, 0x04, 0x98,
652 0x05, 0x99, 0x07, 0xb0, 0xbd, 0xe8, 0x00, 0x80,
653 };
654
655 Method::InvokeStub* stub = AllocateStub(method,
656 sum_DDDD_code,
657 sizeof(sum_DDDD_code));
658
659 double args[3];
660 JValue result;
661
662 args[0] = 0.0;
663 args[1] = 0.0;
664 args[2] = 0.0;
665 result.d = -1.0;
666 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
667 EXPECT_EQ(0.0, result.d);
668
669 args[0] = 1.0;
670 args[1] = 2.0;
671 args[2] = 3.0;
672 result.d = 0.0;
673 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
674 EXPECT_EQ(6.0, result.d);
675
676 args[0] = 1.0;
677 args[1] = -2.0;
678 args[2] = 3.0;
679 result.d = 0.0;
680 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
681 EXPECT_EQ(2.0, result.d);
682
683 FreeStub(method, sizeof(sum_DDDD_code));
684}
685
686TEST_F(JniInternalTest, StaticSumDoubleDoubleDoubleDoubleMethod) {
687 scoped_ptr<DexFile> dex(OpenDexFileBase64(kStaticLeafMethodsDex));
688
689 PathClassLoader* class_loader = AllocPathClassLoader(dex.get());
690 ASSERT_TRUE(class_loader != NULL);
691
692 Class* klass = class_linker_->FindClass("LStaticLeafMethods;", class_loader);
693 ASSERT_TRUE(klass != NULL);
694
695 Method* method = klass->FindDirectMethod("sum", "(DDDD)D");
696 ASSERT_TRUE(method != NULL);
697
698 byte sum_DDDDD_code[] = {
699 0x2d, 0xe9, 0x00, 0x40, 0x87, 0xb0, 0xcd, 0xf8,
700 0x00, 0x00, 0xcd, 0xf8, 0x24, 0x10, 0xcd, 0xf8,
701 0x28, 0x20, 0xcd, 0xf8, 0x2c, 0x30, 0x9d, 0xed,
702 0x09, 0x0b, 0x9d, 0xed, 0x0b, 0x1b, 0x30, 0xee,
703 0x01, 0x2b, 0x8d, 0xed, 0x04, 0x2b, 0x9d, 0xed,
704 0x04, 0x3b, 0x9d, 0xed, 0x0d, 0x4b, 0x33, 0xee,
705 0x04, 0x3b, 0x8d, 0xed, 0x04, 0x3b, 0x9d, 0xed,
706 0x04, 0x5b, 0x9d, 0xed, 0x0f, 0x6b, 0x35, 0xee,
707 0x06, 0x5b, 0x8d, 0xed, 0x04, 0x5b, 0x04, 0x98,
708 0x05, 0x99, 0x07, 0xb0, 0xbd, 0xe8, 0x00, 0x80,
709 };
710
711 Method::InvokeStub* stub = AllocateStub(method,
712 sum_DDDDD_code,
713 sizeof(sum_DDDDD_code));
714
715 double args[4];
716 JValue result;
717
718 args[0] = 0.0;
719 args[1] = 0.0;
720 args[2] = 0.0;
721 args[3] = 0.0;
722 result.d = -1.0;
723 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
724 EXPECT_EQ(0.0, result.d);
725
726 args[0] = 1.0;
727 args[1] = 2.0;
728 args[2] = 3.0;
729 args[3] = 4.0;
730 result.d = 0.0;
731 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
732 EXPECT_EQ(10.0, result.d);
733
734 args[0] = 1.0;
735 args[1] = -2.0;
736 args[2] = 3.0;
737 args[3] = -4.0;
738 result.d = 0.0;
739 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
740 EXPECT_EQ(-2.0, result.d);
741
742 FreeStub(method, sizeof(sum_DDDDD_code));
743}
744
745TEST_F(JniInternalTest, StaticSumDoubleDoubleDoubleDoubleDoubleMethod) {
746 scoped_ptr<DexFile> dex(OpenDexFileBase64(kStaticLeafMethodsDex));
747
748 PathClassLoader* class_loader = AllocPathClassLoader(dex.get());
749 ASSERT_TRUE(class_loader != NULL);
750
751 Class* klass = class_linker_->FindClass("LStaticLeafMethods;", class_loader);
752 ASSERT_TRUE(klass != NULL);
753
754 Method* method = klass->FindDirectMethod("sum", "(DDDDD)D");
755 ASSERT_TRUE(method != NULL);
756
757 byte sum_DDDDDD_code[] = {
758 0x2d, 0xe9, 0x00, 0x40, 0x87, 0xb0, 0xcd, 0xf8,
759 0x00, 0x00, 0xcd, 0xf8, 0x24, 0x10, 0xcd, 0xf8,
760 0x28, 0x20, 0xcd, 0xf8, 0x2c, 0x30, 0x9d, 0xed,
761 0x09, 0x0b, 0x9d, 0xed, 0x0b, 0x1b, 0x30, 0xee,
762 0x01, 0x2b, 0x8d, 0xed, 0x04, 0x2b, 0x9d, 0xed,
763 0x04, 0x3b, 0x9d, 0xed, 0x0d, 0x4b, 0x33, 0xee,
764 0x04, 0x3b, 0x8d, 0xed, 0x04, 0x3b, 0x9d, 0xed,
765 0x04, 0x5b, 0x9d, 0xed, 0x0f, 0x6b, 0x35, 0xee,
766 0x06, 0x5b, 0x8d, 0xed, 0x04, 0x5b, 0x9d, 0xed,
767 0x04, 0x7b, 0x9d, 0xed, 0x11, 0x0b, 0x37, 0xee,
768 0x00, 0x7b, 0x8d, 0xed, 0x04, 0x7b, 0x04, 0x98,
769 0x05, 0x99, 0x07, 0xb0, 0xbd, 0xe8, 0x00, 0x80,
770 };
771
772 Method::InvokeStub* stub = AllocateStub(method,
773 sum_DDDDDD_code,
774 sizeof(sum_DDDDDD_code));
775
776 double args[5];
777 JValue result;
778
779 args[0] = 0.0;
780 args[1] = 0.0;
781 args[2] = 0.0;
782 args[3] = 0.0;
783 args[4] = 0.0;
784 result.d = -1.0;
785 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
786 EXPECT_EQ(0.0, result.d);
787
788 args[0] = 1.0;
789 args[1] = 2.0;
790 args[2] = 3.0;
791 args[3] = 4.0;
792 args[4] = 5.0;
793 result.d = 0.0;
794 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
795 EXPECT_EQ(15.0, result.d);
796
797 args[0] = 1.0;
798 args[1] = -2.0;
799 args[2] = 3.0;
800 args[3] = -4.0;
801 args[4] = 5.0;
802 result.d = 0.0;
803 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
804 EXPECT_EQ(3.0, result.d);
805
806 FreeStub(method, sizeof(sum_DDDDDD_code));
807}
808#endif // __arm__
809
810}