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