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