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