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