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