blob: 9043bcdeb33d5ae1882b974730828d560f01d8e7 [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
Brian Carlstromf734cf52011-08-17 16:28:14 -070013class JniInternalTest : public CommonTest {
Elliott Hughesc7ac37f2011-08-12 12:21:58 -070014 protected:
15 virtual void SetUp() {
Brian Carlstromf734cf52011-08-17 16:28:14 -070016 CommonTest::SetUp();
Elliott Hughesc7ac37f2011-08-12 12:21:58 -070017 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 Hughesbd935992011-08-22 11:59:34 -070027 EXPECT_TRUE(env_->FindClass(NAME) != NULL); \
28 EXPECT_FALSE(env_->ExceptionCheck())
Elliott Hughes0c9cd562011-08-12 10:59:29 -070029
30#define EXPECT_CLASS_NOT_FOUND(NAME) \
Elliott Hughesbd935992011-08-22 11:59:34 -070031 EXPECT_TRUE(env_->FindClass(NAME) == NULL); \
32 EXPECT_TRUE(env_->ExceptionCheck()); \
33 env_->ExceptionClear()
Elliott Hughes0c9cd562011-08-12 10:59:29 -070034
35TEST_F(JniInternalTest, FindClass) {
Elliott Hughes0c9cd562011-08-12 10:59:29 -070036 // TODO: when these tests start failing because you're calling FindClass
37 // with a pending exception, fix EXPECT_CLASS_NOT_FOUND to assert that an
38 // exception was thrown and clear the exception.
39
40 // TODO: . is only allowed as an alternative to / if CheckJNI is off.
41
42 // Reference types...
43 // You can't include the "L;" in a JNI class descriptor.
44 EXPECT_CLASS_FOUND("java/lang/String");
45 EXPECT_CLASS_NOT_FOUND("Ljava/lang/String;");
46 // We support . as well as / for compatibility.
47 EXPECT_CLASS_FOUND("java.lang.String");
48 EXPECT_CLASS_NOT_FOUND("Ljava.lang.String;");
49 // ...for arrays too, where you must include "L;".
50 EXPECT_CLASS_FOUND("[Ljava/lang/String;");
51 EXPECT_CLASS_NOT_FOUND("[java/lang/String");
52 EXPECT_CLASS_FOUND("[Ljava.lang.String;");
53 EXPECT_CLASS_NOT_FOUND("[java.lang.String");
54
55 // Primitive arrays are okay (if the primitive type is valid)...
56 EXPECT_CLASS_FOUND("[C");
57 EXPECT_CLASS_NOT_FOUND("[K");
58 // But primitive types aren't allowed...
59 EXPECT_CLASS_NOT_FOUND("C");
60 EXPECT_CLASS_NOT_FOUND("K");
61}
62
Elliott Hughescdf53122011-08-19 15:46:09 -070063#define EXPECT_EXCEPTION(exception_class) \
64 do { \
65 EXPECT_TRUE(env_->ExceptionCheck()); \
66 jthrowable exception = env_->ExceptionOccurred(); \
67 EXPECT_NE(static_cast<jthrowable>(NULL), exception); \
68 EXPECT_TRUE(env_->IsInstanceOf(exception, exception_class)); \
69 env_->ExceptionClear(); \
70 } while (false)
71
72TEST_F(JniInternalTest, GetFieldID) {
73 jclass jlnsfe = env_->FindClass("java/lang/NoSuchFieldError");
74 ASSERT_TRUE(jlnsfe != NULL);
75 jclass c = env_->FindClass("java/lang/String");
76 ASSERT_TRUE(c != NULL);
77
78 // Wrong type.
79 jfieldID fid = env_->GetFieldID(c, "count", "J");
80 EXPECT_EQ(static_cast<jfieldID>(NULL), fid);
81 EXPECT_EXCEPTION(jlnsfe);
82
83 // Wrong name.
84 fid = env_->GetFieldID(c, "Count", "I");
85 EXPECT_EQ(static_cast<jfieldID>(NULL), fid);
86 EXPECT_EXCEPTION(jlnsfe);
87
88 // Good declared field lookup.
89 fid = env_->GetFieldID(c, "count", "I");
90 EXPECT_NE(static_cast<jfieldID>(NULL), fid);
91 EXPECT_TRUE(fid != NULL);
92 EXPECT_FALSE(env_->ExceptionCheck());
93
94 // Good superclass field lookup.
95 c = env_->FindClass("java/lang/StringBuilder");
96 fid = env_->GetFieldID(c, "count", "I");
97 EXPECT_NE(static_cast<jfieldID>(NULL), fid);
98 EXPECT_TRUE(fid != NULL);
99 EXPECT_FALSE(env_->ExceptionCheck());
100
101 // Not instance.
102 fid = env_->GetFieldID(c, "CASE_INSENSITIVE_ORDER", "Ljava/util/Comparator;");
103 EXPECT_EQ(static_cast<jfieldID>(NULL), fid);
104 EXPECT_EXCEPTION(jlnsfe);
105}
106
107TEST_F(JniInternalTest, GetStaticFieldID) {
108 jclass jlnsfe = env_->FindClass("java/lang/NoSuchFieldError");
109 ASSERT_TRUE(jlnsfe != NULL);
110 jclass c = env_->FindClass("java/lang/String");
111 ASSERT_TRUE(c != NULL);
112
113 // Wrong type.
114 jfieldID fid = env_->GetStaticFieldID(c, "CASE_INSENSITIVE_ORDER", "J");
115 EXPECT_EQ(static_cast<jfieldID>(NULL), fid);
116 EXPECT_EXCEPTION(jlnsfe);
117
118 // Wrong name.
119 fid = env_->GetStaticFieldID(c, "cASE_INSENSITIVE_ORDER", "Ljava/util/Comparator;");
120 EXPECT_EQ(static_cast<jfieldID>(NULL), fid);
121 EXPECT_EXCEPTION(jlnsfe);
122
123 // Good declared field lookup.
124 fid = env_->GetStaticFieldID(c, "CASE_INSENSITIVE_ORDER", "Ljava/util/Comparator;");
125 EXPECT_NE(static_cast<jfieldID>(NULL), fid);
126 EXPECT_TRUE(fid != NULL);
127 EXPECT_FALSE(env_->ExceptionCheck());
128
129 // Not static.
130 fid = env_->GetStaticFieldID(c, "count", "I");
131 EXPECT_EQ(static_cast<jfieldID>(NULL), fid);
132 EXPECT_EXCEPTION(jlnsfe);
133}
134
Ian Rogers4dd71f12011-08-16 14:16:02 -0700135TEST_F(JniInternalTest, GetMethodID) {
136 jclass jlobject = env_->FindClass("java/lang/Object");
137 jclass jlstring = env_->FindClass("java/lang/String");
138 jclass jlnsme = env_->FindClass("java/lang/NoSuchMethodError");
139
140 // Sanity check that no exceptions are pending
Elliott Hughescdf53122011-08-19 15:46:09 -0700141 ASSERT_FALSE(env_->ExceptionCheck());
Ian Rogers4dd71f12011-08-16 14:16:02 -0700142
143 // Check that java.lang.Object.foo() doesn't exist and NoSuchMethodError is
144 // a pending exception
145 jmethodID method = env_->GetMethodID(jlobject, "foo", "()V");
146 EXPECT_EQ(static_cast<jmethodID>(NULL), method);
Elliott Hughescdf53122011-08-19 15:46:09 -0700147 EXPECT_EXCEPTION(jlnsme);
Ian Rogers4dd71f12011-08-16 14:16:02 -0700148
149 // Check that java.lang.Object.equals() does exist
Ian Rogers4dd71f12011-08-16 14:16:02 -0700150 method = env_->GetMethodID(jlobject, "equals", "(Ljava/lang/Object;)Z");
151 EXPECT_NE(static_cast<jmethodID>(NULL), method);
152 EXPECT_FALSE(env_->ExceptionCheck());
Ian Rogers4dd71f12011-08-16 14:16:02 -0700153
154 // Check that GetMethodID for java.lang.String.valueOf(int) fails as the
155 // method is static
156 method = env_->GetMethodID(jlstring, "valueOf", "(I)Ljava/lang/String;");
157 EXPECT_EQ(static_cast<jmethodID>(NULL), method);
Elliott Hughescdf53122011-08-19 15:46:09 -0700158 EXPECT_EXCEPTION(jlnsme);
Ian Rogers4dd71f12011-08-16 14:16:02 -0700159}
160
161TEST_F(JniInternalTest, GetStaticMethodID) {
162 jclass jlobject = env_->FindClass("java/lang/Object");
163 jclass jlnsme = env_->FindClass("java/lang/NoSuchMethodError");
164
165 // Sanity check that no exceptions are pending
Elliott Hughescdf53122011-08-19 15:46:09 -0700166 ASSERT_FALSE(env_->ExceptionCheck());
Ian Rogers4dd71f12011-08-16 14:16:02 -0700167
168 // Check that java.lang.Object.foo() doesn't exist and NoSuchMethodError is
169 // a pending exception
170 jmethodID method = env_->GetStaticMethodID(jlobject, "foo", "()V");
171 EXPECT_EQ(static_cast<jmethodID>(NULL), method);
Elliott Hughescdf53122011-08-19 15:46:09 -0700172 EXPECT_EXCEPTION(jlnsme);
Ian Rogers4dd71f12011-08-16 14:16:02 -0700173
174 // Check that GetStaticMethodID for java.lang.Object.equals(Object) fails as
175 // the method is not static
176 method = env_->GetStaticMethodID(jlobject, "equals", "(Ljava/lang/Object;)Z");
177 EXPECT_EQ(static_cast<jmethodID>(NULL), method);
Elliott Hughescdf53122011-08-19 15:46:09 -0700178 EXPECT_EXCEPTION(jlnsme);
Ian Rogers4dd71f12011-08-16 14:16:02 -0700179
180 // Check that java.lang.String.valueOf(int) does exist
Ian Rogers4dd71f12011-08-16 14:16:02 -0700181 jclass jlstring = env_->FindClass("java/lang/String");
182 method = env_->GetStaticMethodID(jlstring, "valueOf",
183 "(I)Ljava/lang/String;");
184 EXPECT_NE(static_cast<jmethodID>(NULL), method);
185 EXPECT_FALSE(env_->ExceptionCheck());
Ian Rogers4dd71f12011-08-16 14:16:02 -0700186}
187
Elliott Hughescdf53122011-08-19 15:46:09 -0700188TEST_F(JniInternalTest, FromReflectedField_ToReflectedField) {
189 jclass jlrField = env_->FindClass("java/lang/reflect/Field");
190 jclass c = env_->FindClass("java/lang/String");
191 ASSERT_TRUE(c != NULL);
192 jfieldID fid = env_->GetFieldID(c, "count", "I");
193 ASSERT_TRUE(fid != NULL);
194 // Turn the fid into a java.lang.reflect.Field...
195 jobject field = env_->ToReflectedField(c, fid, JNI_FALSE);
196 ASSERT_TRUE(c != NULL);
197 ASSERT_TRUE(env_->IsInstanceOf(field, jlrField));
198 // ...and back again.
199 jfieldID fid2 = env_->FromReflectedField(field);
200 ASSERT_TRUE(fid2 != NULL);
201}
202
203TEST_F(JniInternalTest, FromReflectedMethod_ToReflectedMethod) {
204 jclass jlrMethod = env_->FindClass("java/lang/reflect/Method");
205 jclass c = env_->FindClass("java/lang/String");
206 ASSERT_TRUE(c != NULL);
207 jmethodID mid = env_->GetMethodID(c, "length", "()I");
208 ASSERT_TRUE(mid != NULL);
209 // Turn the mid into a java.lang.reflect.Method...
210 jobject method = env_->ToReflectedMethod(c, mid, JNI_FALSE);
211 ASSERT_TRUE(c != NULL);
212 ASSERT_TRUE(env_->IsInstanceOf(method, jlrMethod));
213 // ...and back again.
214 jmethodID mid2 = env_->FromReflectedMethod(method);
215 ASSERT_TRUE(mid2 != NULL);
216}
217
Ian Rogers4dd71f12011-08-16 14:16:02 -0700218TEST_F(JniInternalTest, RegisterNatives) {
219 jclass jlobject = env_->FindClass("java/lang/Object");
220 jclass jlnsme = env_->FindClass("java/lang/NoSuchMethodError");
221
222 // Sanity check that no exceptions are pending
Elliott Hughescdf53122011-08-19 15:46:09 -0700223 ASSERT_FALSE(env_->ExceptionCheck());
Ian Rogers4dd71f12011-08-16 14:16:02 -0700224
225 // Check that registering to a non-existent java.lang.Object.foo() causes a
226 // NoSuchMethodError
227 {
228 JNINativeMethod methods[] = {{"foo", "()V", NULL}};
229 env_->RegisterNatives(jlobject, methods, 1);
230 }
Elliott Hughescdf53122011-08-19 15:46:09 -0700231 EXPECT_EXCEPTION(jlnsme);
Ian Rogers4dd71f12011-08-16 14:16:02 -0700232
233 // Check that registering non-native methods causes a NoSuchMethodError
234 {
235 JNINativeMethod methods[] = {{"equals", "(Ljava/lang/Object;)Z", NULL}};
236 env_->RegisterNatives(jlobject, methods, 1);
237 }
Elliott Hughescdf53122011-08-19 15:46:09 -0700238 EXPECT_EXCEPTION(jlnsme);
Ian Rogers4dd71f12011-08-16 14:16:02 -0700239
240 // Check that registering native methods is successful
241 {
242 JNINativeMethod methods[] = {{"hashCode", "()I", NULL}};
243 env_->RegisterNatives(jlobject, methods, 1);
244 }
245 EXPECT_FALSE(env_->ExceptionCheck());
246}
247
Elliott Hughesbd935992011-08-22 11:59:34 -0700248#define EXPECT_PRIMITIVE_ARRAY(fn, size, expected_class_name) \
249 do { \
250 jarray a = env_->fn(size); \
251 EXPECT_TRUE(a != NULL); \
252 EXPECT_TRUE(env_->IsInstanceOf(a, \
253 env_->FindClass(expected_class_name))); \
254 EXPECT_EQ(size, env_->GetArrayLength(a)); \
255 } while (false)
256
Elliott Hughesd8ddfd52011-08-15 14:32:53 -0700257TEST_F(JniInternalTest, NewPrimitiveArray) {
258 // TODO: death tests for negative array sizes.
259
Elliott Hughesbd935992011-08-22 11:59:34 -0700260 EXPECT_PRIMITIVE_ARRAY(NewBooleanArray, 0, "[Z");
261 EXPECT_PRIMITIVE_ARRAY(NewByteArray, 0, "[B");
262 EXPECT_PRIMITIVE_ARRAY(NewCharArray, 0, "[C");
263 EXPECT_PRIMITIVE_ARRAY(NewDoubleArray, 0, "[D");
264 EXPECT_PRIMITIVE_ARRAY(NewFloatArray, 0, "[F");
265 EXPECT_PRIMITIVE_ARRAY(NewIntArray, 0, "[I");
266 EXPECT_PRIMITIVE_ARRAY(NewLongArray, 0, "[J");
267 EXPECT_PRIMITIVE_ARRAY(NewShortArray, 0, "[S");
Elliott Hughesf2682d52011-08-15 16:37:04 -0700268
Elliott Hughesbd935992011-08-22 11:59:34 -0700269 EXPECT_PRIMITIVE_ARRAY(NewBooleanArray, 1, "[Z");
270 EXPECT_PRIMITIVE_ARRAY(NewByteArray, 1, "[B");
271 EXPECT_PRIMITIVE_ARRAY(NewCharArray, 1, "[C");
272 EXPECT_PRIMITIVE_ARRAY(NewDoubleArray, 1, "[D");
273 EXPECT_PRIMITIVE_ARRAY(NewFloatArray, 1, "[F");
274 EXPECT_PRIMITIVE_ARRAY(NewIntArray, 1, "[I");
275 EXPECT_PRIMITIVE_ARRAY(NewLongArray, 1, "[J");
276 EXPECT_PRIMITIVE_ARRAY(NewShortArray, 1, "[S");
Elliott Hughesd8ddfd52011-08-15 14:32:53 -0700277}
278
Elliott Hughesf2682d52011-08-15 16:37:04 -0700279TEST_F(JniInternalTest, NewObjectArray) {
280 // TODO: death tests for negative array sizes.
281
Elliott Hughesf2682d52011-08-15 16:37:04 -0700282 // TODO: check non-NULL initial elements.
283
Elliott Hughesbd935992011-08-22 11:59:34 -0700284 jclass element_class = env_->FindClass("java/lang/String");
285 ASSERT_TRUE(element_class != NULL);
286 jclass array_class = env_->FindClass("[Ljava/lang/String;");
287 ASSERT_TRUE(array_class != NULL);
Elliott Hughesf2682d52011-08-15 16:37:04 -0700288
Elliott Hughesbd935992011-08-22 11:59:34 -0700289 jobjectArray a;
Elliott Hughesf2682d52011-08-15 16:37:04 -0700290
Elliott Hughesbd935992011-08-22 11:59:34 -0700291 a = env_->NewObjectArray(0, element_class, NULL);
292 EXPECT_TRUE(a != NULL);
293 EXPECT_TRUE(env_->IsInstanceOf(a, array_class));
294 EXPECT_EQ(0, env_->GetArrayLength(a));
295
296 a = env_->NewObjectArray(1, element_class, NULL);
297 EXPECT_TRUE(a != NULL);
298 EXPECT_TRUE(env_->IsInstanceOf(a, array_class));
299 EXPECT_EQ(1, env_->GetArrayLength(a));
300}
301
302TEST_F(JniInternalTest, GetArrayLength) {
303 // Already tested in NewObjectArray/NewPrimitiveArray.
Elliott Hughes8a26c5c2011-08-15 18:35:43 -0700304}
305
306TEST_F(JniInternalTest, NewStringUTF) {
307 EXPECT_TRUE(env_->NewStringUTF(NULL) == NULL);
308 EXPECT_TRUE(env_->NewStringUTF("") != NULL);
309 EXPECT_TRUE(env_->NewStringUTF("hello") != NULL);
310 // TODO: check some non-ASCII strings.
Elliott Hughesf2682d52011-08-15 16:37:04 -0700311}
312
Elliott Hughes289da822011-08-16 10:11:20 -0700313TEST_F(JniInternalTest, SetObjectArrayElement) {
Elliott Hughescdf53122011-08-19 15:46:09 -0700314 jclass aioobe = env_->FindClass("java/lang/ArrayIndexOutOfBoundsException");
Elliott Hughes289da822011-08-16 10:11:20 -0700315 jclass c = env_->FindClass("[Ljava/lang/Object;");
316 ASSERT_TRUE(c != NULL);
317
318 jobjectArray array = env_->NewObjectArray(1, c, NULL);
319 EXPECT_TRUE(array != NULL);
320 env_->SetObjectArrayElement(array, 0, c);
321 // TODO: check reading value back
Elliott Hughesa5b897e2011-08-16 11:33:06 -0700322
323 // ArrayIndexOutOfBounds for negative index.
Elliott Hughesa5b897e2011-08-16 11:33:06 -0700324 env_->SetObjectArrayElement(array, -1, c);
Elliott Hughescdf53122011-08-19 15:46:09 -0700325 EXPECT_EXCEPTION(aioobe);
Elliott Hughesa5b897e2011-08-16 11:33:06 -0700326
327 // ArrayIndexOutOfBounds for too-large index.
Elliott Hughesa5b897e2011-08-16 11:33:06 -0700328 env_->SetObjectArrayElement(array, 1, c);
Elliott Hughescdf53122011-08-19 15:46:09 -0700329 EXPECT_EXCEPTION(aioobe);
Elliott Hughesa5b897e2011-08-16 11:33:06 -0700330
Elliott Hughes289da822011-08-16 10:11:20 -0700331 // TODO: check ArrayStoreException thrown for bad types.
332}
333
Elliott Hughes18c07532011-08-18 15:50:51 -0700334TEST_F(JniInternalTest, NewLocalRef_NULL) {
335 EXPECT_TRUE(env_->NewLocalRef(NULL) == NULL);
336}
337
338TEST_F(JniInternalTest, NewLocalRef) {
339 jstring s = env_->NewStringUTF("");
340 ASSERT_TRUE(s != NULL);
341 jobject o = env_->NewLocalRef(s);
342 EXPECT_TRUE(o != NULL);
343 EXPECT_TRUE(o != s);
344
345 // TODO: check that o is a local reference.
346}
347
348TEST_F(JniInternalTest, DeleteLocalRef_NULL) {
349 env_->DeleteLocalRef(NULL);
350}
351
352TEST_F(JniInternalTest, DeleteLocalRef) {
353 jstring s = env_->NewStringUTF("");
354 ASSERT_TRUE(s != NULL);
355 env_->DeleteLocalRef(s);
356
357 // Currently, deleting an already-deleted reference is just a warning.
358 env_->DeleteLocalRef(s);
359
360 s = env_->NewStringUTF("");
361 ASSERT_TRUE(s != NULL);
362 jobject o = env_->NewLocalRef(s);
363 ASSERT_TRUE(o != NULL);
364
365 env_->DeleteLocalRef(s);
366 env_->DeleteLocalRef(o);
367}
368
369TEST_F(JniInternalTest, NewGlobalRef_NULL) {
370 EXPECT_TRUE(env_->NewGlobalRef(NULL) == NULL);
371}
372
373TEST_F(JniInternalTest, NewGlobalRef) {
374 jstring s = env_->NewStringUTF("");
375 ASSERT_TRUE(s != NULL);
376 jobject o = env_->NewGlobalRef(s);
377 EXPECT_TRUE(o != NULL);
378 EXPECT_TRUE(o != s);
379
380 // TODO: check that o is a global reference.
381}
382
383TEST_F(JniInternalTest, DeleteGlobalRef_NULL) {
384 env_->DeleteGlobalRef(NULL);
385}
386
387TEST_F(JniInternalTest, DeleteGlobalRef) {
388 jstring s = env_->NewStringUTF("");
389 ASSERT_TRUE(s != NULL);
390
391 jobject o = env_->NewGlobalRef(s);
392 ASSERT_TRUE(o != NULL);
393 env_->DeleteGlobalRef(o);
394
395 // Currently, deleting an already-deleted reference is just a warning.
396 env_->DeleteGlobalRef(o);
397
398 jobject o1 = env_->NewGlobalRef(s);
399 ASSERT_TRUE(o1 != NULL);
400 jobject o2 = env_->NewGlobalRef(s);
401 ASSERT_TRUE(o2 != NULL);
402
403 env_->DeleteGlobalRef(o1);
404 env_->DeleteGlobalRef(o2);
405}
406
407TEST_F(JniInternalTest, NewWeakGlobalRef_NULL) {
408 EXPECT_TRUE(env_->NewWeakGlobalRef(NULL) == NULL);
409}
410
411TEST_F(JniInternalTest, NewWeakGlobalRef) {
412 jstring s = env_->NewStringUTF("");
413 ASSERT_TRUE(s != NULL);
414 jobject o = env_->NewWeakGlobalRef(s);
415 EXPECT_TRUE(o != NULL);
416 EXPECT_TRUE(o != s);
417
418 // TODO: check that o is a weak global reference.
419}
420
421TEST_F(JniInternalTest, DeleteWeakGlobalRef_NULL) {
422 env_->DeleteWeakGlobalRef(NULL);
423}
424
425TEST_F(JniInternalTest, DeleteWeakGlobalRef) {
426 jstring s = env_->NewStringUTF("");
427 ASSERT_TRUE(s != NULL);
428
429 jobject o = env_->NewWeakGlobalRef(s);
430 ASSERT_TRUE(o != NULL);
431 env_->DeleteWeakGlobalRef(o);
432
433 // Currently, deleting an already-deleted reference is just a warning.
434 env_->DeleteWeakGlobalRef(o);
435
436 jobject o1 = env_->NewWeakGlobalRef(s);
437 ASSERT_TRUE(o1 != NULL);
438 jobject o2 = env_->NewWeakGlobalRef(s);
439 ASSERT_TRUE(o2 != NULL);
440
441 env_->DeleteWeakGlobalRef(o1);
442 env_->DeleteWeakGlobalRef(o2);
443}
444
Carl Shapiro9b9ba282011-08-14 15:30:39 -0700445bool EnsureInvokeStub(Method* method);
446
Carl Shapiro9b9ba282011-08-14 15:30:39 -0700447Method::InvokeStub* AllocateStub(Method* method,
448 byte* code,
449 size_t length) {
450 CHECK(method->GetInvokeStub() == NULL);
451 EnsureInvokeStub(method);
452 Method::InvokeStub* stub = method->GetInvokeStub();
453 CHECK(stub != NULL);
buzbeec143c552011-08-20 17:38:58 -0700454 method->SetCode(code, length, kThumb2);
Carl Shapiro9b9ba282011-08-14 15:30:39 -0700455 return stub;
456}
457
Carl Shapiro9b9ba282011-08-14 15:30:39 -0700458#if defined(__arm__)
459TEST_F(JniInternalTest, StaticMainMethod) {
Brian Carlstroma663ea52011-08-19 23:33:41 -0700460 scoped_ptr<DexFile> dex(OpenDexFileBase64(kMainDex, "kMainDex"));
Carl Shapiro9b9ba282011-08-14 15:30:39 -0700461
462 PathClassLoader* class_loader = AllocPathClassLoader(dex.get());
463 ASSERT_TRUE(class_loader != NULL);
464
465 Class* klass = class_linker_->FindClass("LMain;", class_loader);
466 ASSERT_TRUE(klass != NULL);
467
468 Method* method = klass->FindDirectMethod("main", "([Ljava/lang/String;)V");
469 ASSERT_TRUE(method != NULL);
470
471 byte main_LV_code[] = {
472 0x2d, 0xe9, 0x00, 0x40, 0x83, 0xb0, 0xcd, 0xf8, 0x00, 0x00,
473 0xcd, 0xf8, 0x14, 0x10, 0x03, 0xb0, 0xbd, 0xe8, 0x00, 0x80,
474 };
475
476 Method::InvokeStub* stub = AllocateStub(method,
477 main_LV_code,
478 sizeof(main_LV_code));
479
480 Object* arg = NULL;
481
482 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(&arg), NULL);
Carl Shapiro9b9ba282011-08-14 15:30:39 -0700483}
484
485TEST_F(JniInternalTest, StaticNopMethod) {
Brian Carlstroma663ea52011-08-19 23:33:41 -0700486 scoped_ptr<DexFile> dex(OpenDexFileBase64(kStaticLeafMethodsDex, "kStaticLeafMethodsDex"));
Carl Shapiro9b9ba282011-08-14 15:30:39 -0700487
488 PathClassLoader* class_loader = AllocPathClassLoader(dex.get());
489 ASSERT_TRUE(class_loader != NULL);
490
491 Class* klass = class_linker_->FindClass("LStaticLeafMethods;", class_loader);
492 ASSERT_TRUE(klass != NULL);
493
494 Method* method = klass->FindDirectMethod("nop", "()V");
495 ASSERT_TRUE(method != NULL);
496
497 byte nop_V_code[] = {
498 0x2d, 0xe9, 0x00, 0x40, 0x83, 0xb0, 0xcd, 0xf8,
499 0x00, 0x00, 0x03, 0xb0, 0xbd, 0xe8, 0x00, 0x80,
500 };
501
502 Method::InvokeStub* stub = AllocateStub(method,
503 nop_V_code,
504 sizeof(nop_V_code));
505 ASSERT_TRUE(stub);
506
507 (*stub)(method, NULL, NULL, NULL, NULL);
Carl Shapiro9b9ba282011-08-14 15:30:39 -0700508}
509
510TEST_F(JniInternalTest, StaticIdentityByteMethod) {
Brian Carlstroma663ea52011-08-19 23:33:41 -0700511 scoped_ptr<DexFile> dex(OpenDexFileBase64(kStaticLeafMethodsDex, "kStaticLeafMethodsDex"));
Carl Shapiro9b9ba282011-08-14 15:30:39 -0700512
513 PathClassLoader* class_loader = AllocPathClassLoader(dex.get());
514 ASSERT_TRUE(class_loader != NULL);
515
516 Class* klass = class_linker_->FindClass("LStaticLeafMethods;", class_loader);
517 ASSERT_TRUE(klass != NULL);
518
519 Method* method = klass->FindDirectMethod("identity", "(B)B");
520 ASSERT_TRUE(method != NULL);
521
522 byte identity_BB_code[] = {
523 0x2d, 0xe9, 0x00, 0x40, 0x83, 0xb0, 0xcd, 0xf8,
524 0x00, 0x00, 0xcd, 0xf8, 0x14, 0x10, 0x05, 0x98,
525 0x03, 0xb0, 0xbd, 0xe8, 0x00, 0x80, 0x00, 0x00,
526 };
527
528 Method::InvokeStub* stub = AllocateStub(method,
529 identity_BB_code,
530 sizeof(identity_BB_code));
531
532 int arg;
533 JValue result;
534
535 arg = 0;
536 result.b = -1;
537 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(&arg), &result);
538 EXPECT_EQ(0, result.b);
539
540 arg = -1;
541 result.b = 0;
542 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(&arg), &result);
543 EXPECT_EQ(-1, result.b);
544
545 arg = SCHAR_MAX;
546 result.b = 0;
547 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(&arg), &result);
548 EXPECT_EQ(SCHAR_MAX, result.b);
549
550 arg = SCHAR_MIN;
551 result.b = 0;
552 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(&arg), &result);
553 EXPECT_EQ(SCHAR_MIN, result.b);
Carl Shapiro9b9ba282011-08-14 15:30:39 -0700554}
555
556TEST_F(JniInternalTest, StaticIdentityIntMethod) {
Brian Carlstroma663ea52011-08-19 23:33:41 -0700557 scoped_ptr<DexFile> dex(OpenDexFileBase64(kStaticLeafMethodsDex, "kStaticLeafMethodsDex"));
Carl Shapiro9b9ba282011-08-14 15:30:39 -0700558
559 PathClassLoader* class_loader = AllocPathClassLoader(dex.get());
560 ASSERT_TRUE(class_loader != NULL);
561
562 Class* klass = class_linker_->FindClass("LStaticLeafMethods;", class_loader);
563 ASSERT_TRUE(klass != NULL);
564
565 Method* method = klass->FindDirectMethod("identity", "(I)I");
566 ASSERT_TRUE(method != NULL);
567
568 byte identity_II_code[] = {
569 0x2d, 0xe9, 0x00, 0x40, 0x83, 0xb0, 0xcd, 0xf8,
570 0x00, 0x00, 0xcd, 0xf8, 0x14, 0x10, 0x05, 0x98,
571 0x03, 0xb0, 0xbd, 0xe8, 0x00, 0x80, 0x00, 0x00,
572 };
573
574 Method::InvokeStub* stub = AllocateStub(method,
575 identity_II_code,
576 sizeof(identity_II_code));
577
578 int arg;
579 JValue result;
580
581 arg = 0;
582 result.i = -1;
583 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(&arg), &result);
584 EXPECT_EQ(0, result.i);
585
586 arg = -1;
587 result.i = 0;
588 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(&arg), &result);
589 EXPECT_EQ(-1, result.i);
590
591 arg = INT_MAX;
592 result.i = 0;
593 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(&arg), &result);
594 EXPECT_EQ(INT_MAX, result.i);
595
596 arg = INT_MIN;
597 result.i = 0;
598 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(&arg), &result);
599 EXPECT_EQ(INT_MIN, result.i);
Carl Shapiro9b9ba282011-08-14 15:30:39 -0700600}
601
602TEST_F(JniInternalTest, StaticIdentityDoubleMethod) {
Brian Carlstroma663ea52011-08-19 23:33:41 -0700603 scoped_ptr<DexFile> dex(OpenDexFileBase64(kStaticLeafMethodsDex, "kStaticLeafMethodsDex"));
Carl Shapiro9b9ba282011-08-14 15:30:39 -0700604
605 PathClassLoader* class_loader = AllocPathClassLoader(dex.get());
606 ASSERT_TRUE(class_loader != NULL);
607
608 Class* klass = class_linker_->FindClass("LStaticLeafMethods;", class_loader);
609 ASSERT_TRUE(klass != NULL);
610
611 Method* method = klass->FindDirectMethod("identity", "(D)D");
612 ASSERT_TRUE(method != NULL);
613
614 byte identity_DD_code[] = {
615 0x2d, 0xe9, 0x00, 0x40, 0x83, 0xb0, 0xcd, 0xf8,
616 0x00, 0x00, 0xcd, 0xf8, 0x14, 0x10, 0xcd, 0xf8,
617 0x18, 0x20, 0x05, 0x98, 0x06, 0x99, 0x03, 0xb0,
618 0xbd, 0xe8, 0x00, 0x80,
619 };
620
621 Method::InvokeStub* stub = AllocateStub(method,
622 identity_DD_code,
623 sizeof(identity_DD_code));
624
625 double arg;
626 JValue result;
627
628 arg = 0.0;
629 result.d = -1.0;
630 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(&arg), &result);
631 EXPECT_EQ(0.0, result.d);
632
633 arg = -1.0;
634 result.d = 0.0;
635 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(&arg), &result);
636 EXPECT_EQ(-1.0, result.d);
637
638 arg = DBL_MAX;
639 result.d = 0.0;
640 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(&arg), &result);
641 EXPECT_EQ(DBL_MAX, result.d);
642
643 arg = DBL_MIN;
644 result.d = 0.0;
645 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(&arg), &result);
646 EXPECT_EQ(DBL_MIN, result.d);
Carl Shapiro9b9ba282011-08-14 15:30:39 -0700647}
648
649TEST_F(JniInternalTest, StaticSumIntIntMethod) {
Brian Carlstroma663ea52011-08-19 23:33:41 -0700650 scoped_ptr<DexFile> dex(OpenDexFileBase64(kStaticLeafMethodsDex, "kStaticLeafMethodsDex"));
Carl Shapiro9b9ba282011-08-14 15:30:39 -0700651
652 PathClassLoader* class_loader = AllocPathClassLoader(dex.get());
653 ASSERT_TRUE(class_loader != NULL);
654
655 Class* klass = class_linker_->FindClass("LStaticLeafMethods;", class_loader);
656 ASSERT_TRUE(klass != NULL);
657
658 Method* method = klass->FindDirectMethod("sum", "(II)I");
659 ASSERT_TRUE(method != NULL);
660
661 byte sum_III_code[] = {
662 0x2d, 0xe9, 0x00, 0x40, 0x83, 0xb0, 0xcd, 0xf8,
663 0x00, 0x00, 0xcd, 0xf8, 0x14, 0x10, 0xcd, 0xf8,
664 0x18, 0x20, 0x05, 0x98, 0x06, 0x99, 0x42, 0x18,
665 0xcd, 0xf8, 0x04, 0x20, 0x01, 0x98, 0x03, 0xb0,
666 0xbd, 0xe8, 0x00, 0x80,
667 };
668
669 Method::InvokeStub* stub = AllocateStub(method,
670 sum_III_code,
671 sizeof(sum_III_code));
672
673 int args[2];
674 JValue result;
675
676 args[0] = 0;
677 args[1] = 0;
678 result.i = -1;
679 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
680 EXPECT_EQ(0, result.i);
681
682 args[0] = 1;
683 args[1] = 2;
684 result.i = 0;
685 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
686 EXPECT_EQ(3, result.i);
687
688 args[0] = -2;
689 args[1] = 5;
690 result.i = 0;
691 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
692 EXPECT_EQ(3, result.i);
693
694 args[0] = INT_MAX;
695 args[1] = INT_MIN;
696 result.i = 1234;
697 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
698 EXPECT_EQ(-1, result.i);
699
700 args[0] = INT_MAX;
701 args[1] = INT_MAX;
702 result.i = INT_MIN;
703 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
704 EXPECT_EQ(-2, result.i);
Carl Shapiro9b9ba282011-08-14 15:30:39 -0700705}
706
707TEST_F(JniInternalTest, StaticSumIntIntIntMethod) {
Brian Carlstroma663ea52011-08-19 23:33:41 -0700708 scoped_ptr<DexFile> dex(OpenDexFileBase64(kStaticLeafMethodsDex, "kStaticLeafMethodsDex"));
Carl Shapiro9b9ba282011-08-14 15:30:39 -0700709
710 PathClassLoader* class_loader = AllocPathClassLoader(dex.get());
711 ASSERT_TRUE(class_loader != NULL);
712
713 Class* klass = class_linker_->FindClass("LStaticLeafMethods;", class_loader);
714 ASSERT_TRUE(klass != NULL);
715
716 Method* method = klass->FindDirectMethod("sum", "(III)I");
717 ASSERT_TRUE(method != NULL);
718
719 byte sum_IIII_code[] = {
720 0x2d, 0xe9, 0x00, 0x40, 0x83, 0xb0, 0xcd, 0xf8,
721 0x00, 0x00, 0xcd, 0xf8, 0x14, 0x10, 0xcd, 0xf8,
722 0x18, 0x20, 0xcd, 0xf8, 0x1c, 0x30, 0x05, 0x98,
723 0x06, 0x99, 0x42, 0x18, 0xcd, 0xf8, 0x04, 0x20,
724 0x01, 0x9b, 0xdd, 0xf8, 0x1c, 0xc0, 0x13, 0xeb,
725 0x0c, 0x03, 0xcd, 0xf8, 0x04, 0x30, 0x01, 0x98,
726 0x03, 0xb0, 0xbd, 0xe8, 0x00, 0x80, 0x00, 0x00,
727 };
728
729 Method::InvokeStub* stub = AllocateStub(method,
730 sum_IIII_code,
731 sizeof(sum_IIII_code));
732
733 int args[3];
734 JValue result;
735
736 args[0] = 0;
737 args[1] = 0;
738 args[2] = 0;
739 result.i = -1;
740 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
741 EXPECT_EQ(0, result.i);
742
743 args[0] = 1;
744 args[1] = 2;
745 args[2] = 3;
746 result.i = 0;
747 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
748 EXPECT_EQ(6, result.i);
749
750 args[0] = -1;
751 args[1] = 2;
752 args[2] = -3;
753 result.i = 0;
754 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
755 EXPECT_EQ(-2, result.i);
756
757 args[0] = INT_MAX;
758 args[1] = INT_MIN;
759 args[2] = INT_MAX;
760 result.i = 1234;
761 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
762 EXPECT_EQ(2147483646, result.i);
763
764 args[0] = INT_MAX;
765 args[1] = INT_MAX;
766 args[2] = INT_MAX;
767 result.i = INT_MIN;
768 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
769 EXPECT_EQ(2147483645, result.i);
Carl Shapiro9b9ba282011-08-14 15:30:39 -0700770}
771
772TEST_F(JniInternalTest, StaticSumIntIntIntIntMethod) {
Brian Carlstroma663ea52011-08-19 23:33:41 -0700773 scoped_ptr<DexFile> dex(OpenDexFileBase64(kStaticLeafMethodsDex, "kStaticLeafMethodsDex"));
Carl Shapiro9b9ba282011-08-14 15:30:39 -0700774
775 PathClassLoader* class_loader = AllocPathClassLoader(dex.get());
776 ASSERT_TRUE(class_loader != NULL);
777
778 Class* klass = class_linker_->FindClass("LStaticLeafMethods;", class_loader);
779 ASSERT_TRUE(klass != NULL);
780
781 Method* method = klass->FindDirectMethod("sum", "(IIII)I");
782 ASSERT_TRUE(method != NULL);
783
784 byte sum_IIIII_code[] = {
785 0x2d, 0xe9, 0x00, 0x40, 0x83, 0xb0, 0xcd, 0xf8,
786 0x00, 0x00, 0xcd, 0xf8, 0x14, 0x10, 0xcd, 0xf8,
787 0x18, 0x20, 0xcd, 0xf8, 0x1c, 0x30, 0x05, 0x98,
788 0x06, 0x99, 0x42, 0x18, 0xcd, 0xf8, 0x04, 0x20,
789 0x01, 0x9b, 0xdd, 0xf8, 0x1c, 0xc0, 0x13, 0xeb,
790 0x0c, 0x03, 0xcd, 0xf8, 0x04, 0x30, 0x01, 0x98,
791 0x08, 0x99, 0x40, 0x18, 0xcd, 0xf8, 0x04, 0x00,
792 0x01, 0x98, 0x03, 0xb0, 0xbd, 0xe8, 0x00, 0x80,
793 };
794
795 Method::InvokeStub* stub = AllocateStub(method,
796 sum_IIIII_code,
797 sizeof(sum_IIIII_code));
798
799 int args[4];
800 JValue result;
801
802 args[0] = 0;
803 args[1] = 0;
804 args[2] = 0;
805 args[3] = 0;
806 result.i = -1;
807 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
808 EXPECT_EQ(0, result.i);
809
810 args[0] = 1;
811 args[1] = 2;
812 args[2] = 3;
813 args[3] = 4;
814 result.i = 0;
815 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
816 EXPECT_EQ(10, result.i);
817
818 args[0] = -1;
819 args[1] = 2;
820 args[2] = -3;
821 args[3] = 4;
822 result.i = 0;
823 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
824 EXPECT_EQ(2, result.i);
825
826 args[0] = INT_MAX;
827 args[1] = INT_MIN;
828 args[2] = INT_MAX;
829 args[3] = INT_MIN;
830 result.i = 1234;
831 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
832 EXPECT_EQ(-2, result.i);
833
834 args[0] = INT_MAX;
835 args[1] = INT_MAX;
836 args[2] = INT_MAX;
837 args[3] = INT_MAX;
838 result.i = INT_MIN;
839 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
840 EXPECT_EQ(-4, result.i);
Carl Shapiro9b9ba282011-08-14 15:30:39 -0700841}
842
843TEST_F(JniInternalTest, StaticSumIntIntIntIntIntMethod) {
Brian Carlstroma663ea52011-08-19 23:33:41 -0700844 scoped_ptr<DexFile> dex(OpenDexFileBase64(kStaticLeafMethodsDex, "kStaticLeafMethodsDex"));
Carl Shapiro9b9ba282011-08-14 15:30:39 -0700845
846 PathClassLoader* class_loader = AllocPathClassLoader(dex.get());
847 ASSERT_TRUE(class_loader != NULL);
848
849 Class* klass = class_linker_->FindClass("LStaticLeafMethods;", class_loader);
850 ASSERT_TRUE(klass != NULL);
851
852 Method* method = klass->FindDirectMethod("sum", "(IIIII)I");
853 ASSERT_TRUE(method != NULL);
854
855 byte sum_IIIIII_code[] = {
856 0x2d, 0xe9, 0x00, 0x40, 0x83, 0xb0, 0xcd, 0xf8,
857 0x00, 0x00, 0xcd, 0xf8, 0x14, 0x10, 0xcd, 0xf8,
858 0x18, 0x20, 0xcd, 0xf8, 0x1c, 0x30, 0x05, 0x98,
859 0x06, 0x99, 0x42, 0x18, 0xcd, 0xf8, 0x04, 0x20,
860 0x01, 0x9b, 0xdd, 0xf8, 0x1c, 0xc0, 0x13, 0xeb,
861 0x0c, 0x03, 0xcd, 0xf8, 0x04, 0x30, 0x01, 0x98,
862 0x08, 0x99, 0x40, 0x18, 0xcd, 0xf8, 0x04, 0x00,
863 0x01, 0x9a, 0x09, 0x9b, 0xd2, 0x18, 0xcd, 0xf8,
864 0x04, 0x20, 0x01, 0x98, 0x03, 0xb0, 0xbd, 0xe8,
865 0x00, 0x80, 0x00, 0x00,
866 };
867
868 Method::InvokeStub* stub = AllocateStub(method,
869 sum_IIIIII_code,
870 sizeof(sum_IIIIII_code));
871
872 int args[5];
873 JValue result;
874
875 args[0] = 0;
876 args[1] = 0;
877 args[2] = 0;
878 args[3] = 0;
879 args[4] = 0;
880 result.i = -1.0;
881 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
882 EXPECT_EQ(0, result.i);
883
884 args[0] = 1;
885 args[1] = 2;
886 args[2] = 3;
887 args[3] = 4;
888 args[4] = 5;
889 result.i = 0;
890 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
891 EXPECT_EQ(15, result.i);
892
893 args[0] = -1;
894 args[1] = 2;
895 args[2] = -3;
896 args[3] = 4;
897 args[4] = -5;
898 result.i = 0;
899 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
900 EXPECT_EQ(-3, result.i);
901
902 args[0] = INT_MAX;
903 args[1] = INT_MIN;
904 args[2] = INT_MAX;
905 args[3] = INT_MIN;
906 args[4] = INT_MAX;
907 result.i = 1234;
908 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
909 EXPECT_EQ(2147483645, result.i);
910
911 args[0] = INT_MAX;
912 args[1] = INT_MAX;
913 args[2] = INT_MAX;
914 args[3] = INT_MAX;
915 args[4] = INT_MAX;
916 result.i = INT_MIN;
917 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
918 EXPECT_EQ(2147483643, result.i);
Carl Shapiro9b9ba282011-08-14 15:30:39 -0700919}
920
921TEST_F(JniInternalTest, StaticSumDoubleDoubleMethod) {
Brian Carlstroma663ea52011-08-19 23:33:41 -0700922 scoped_ptr<DexFile> dex(OpenDexFileBase64(kStaticLeafMethodsDex, "kStaticLeafMethodsDex"));
Carl Shapiro9b9ba282011-08-14 15:30:39 -0700923
924 PathClassLoader* class_loader = AllocPathClassLoader(dex.get());
925 ASSERT_TRUE(class_loader != NULL);
926
927 Class* klass = class_linker_->FindClass("LStaticLeafMethods;", class_loader);
928 ASSERT_TRUE(klass != NULL);
929
930 Method* method = klass->FindDirectMethod("sum", "(DD)D");
931 ASSERT_TRUE(method != NULL);
932
933 byte sum_DDD_code[] = {
934 0x2d, 0xe9, 0x00, 0x40, 0x87, 0xb0, 0xcd, 0xf8,
935 0x00, 0x00, 0xcd, 0xf8, 0x24, 0x10, 0xcd, 0xf8,
936 0x28, 0x20, 0xcd, 0xf8, 0x2c, 0x30, 0x9d, 0xed,
937 0x09, 0x0b, 0x9d, 0xed, 0x0b, 0x1b, 0x30, 0xee,
938 0x01, 0x2b, 0x8d, 0xed, 0x04, 0x2b, 0x04, 0x98,
939 0x05, 0x99, 0x07, 0xb0, 0xbd, 0xe8, 0x00, 0x80,
940 };
941
942 Method::InvokeStub* stub = AllocateStub(method,
943 sum_DDD_code,
944 sizeof(sum_DDD_code));
945
946 double args[2];
947 JValue result;
948
949 args[0] = 0.0;
950 args[1] = 0.0;
951 result.d = -1.0;
952 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
953 EXPECT_EQ(0.0, result.d);
954
955 args[0] = 1.0;
956 args[1] = 2.0;
957 result.d = 0.0;
958 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
959 EXPECT_EQ(3.0, result.d);
960
961 args[0] = 1.0;
962 args[1] = -2.0;
963 result.d = 0.0;
964 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
965 EXPECT_EQ(-1.0, result.d);
966
967 args[0] = DBL_MAX;
968 args[1] = DBL_MIN;
969 result.d = 0.0;
970 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
971 EXPECT_EQ(1.7976931348623157e308, result.d);
972
973 args[0] = DBL_MAX;
974 args[1] = DBL_MAX;
975 result.d = 0.0;
976 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
977 EXPECT_EQ(INFINITY, result.d);
Carl Shapiro9b9ba282011-08-14 15:30:39 -0700978}
979
980TEST_F(JniInternalTest, StaticSumDoubleDoubleDoubleMethod) {
Brian Carlstroma663ea52011-08-19 23:33:41 -0700981 scoped_ptr<DexFile> dex(OpenDexFileBase64(kStaticLeafMethodsDex, "kStaticLeafMethodsDex"));
Carl Shapiro9b9ba282011-08-14 15:30:39 -0700982
983 PathClassLoader* class_loader = AllocPathClassLoader(dex.get());
984 ASSERT_TRUE(class_loader != NULL);
985
986 Class* klass = class_linker_->FindClass("LStaticLeafMethods;", class_loader);
987 ASSERT_TRUE(klass != NULL);
988
989 Method* method = klass->FindDirectMethod("sum", "(DDD)D");
990 ASSERT_TRUE(method != NULL);
991
992 byte sum_DDDD_code[] = {
993 0x2d, 0xe9, 0x00, 0x40, 0x87, 0xb0, 0xcd, 0xf8,
994 0x00, 0x00, 0xcd, 0xf8, 0x24, 0x10, 0xcd, 0xf8,
995 0x28, 0x20, 0xcd, 0xf8, 0x2c, 0x30, 0x9d, 0xed,
996 0x09, 0x0b, 0x9d, 0xed, 0x0b, 0x1b, 0x30, 0xee,
997 0x01, 0x2b, 0x8d, 0xed, 0x04, 0x2b, 0x9d, 0xed,
998 0x04, 0x3b, 0x9d, 0xed, 0x0d, 0x4b, 0x33, 0xee,
999 0x04, 0x3b, 0x8d, 0xed, 0x04, 0x3b, 0x04, 0x98,
1000 0x05, 0x99, 0x07, 0xb0, 0xbd, 0xe8, 0x00, 0x80,
1001 };
1002
1003 Method::InvokeStub* stub = AllocateStub(method,
1004 sum_DDDD_code,
1005 sizeof(sum_DDDD_code));
1006
1007 double args[3];
1008 JValue result;
1009
1010 args[0] = 0.0;
1011 args[1] = 0.0;
1012 args[2] = 0.0;
1013 result.d = -1.0;
1014 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
1015 EXPECT_EQ(0.0, result.d);
1016
1017 args[0] = 1.0;
1018 args[1] = 2.0;
1019 args[2] = 3.0;
1020 result.d = 0.0;
1021 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
1022 EXPECT_EQ(6.0, result.d);
1023
1024 args[0] = 1.0;
1025 args[1] = -2.0;
1026 args[2] = 3.0;
1027 result.d = 0.0;
1028 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
1029 EXPECT_EQ(2.0, result.d);
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001030}
1031
1032TEST_F(JniInternalTest, StaticSumDoubleDoubleDoubleDoubleMethod) {
Brian Carlstroma663ea52011-08-19 23:33:41 -07001033 scoped_ptr<DexFile> dex(OpenDexFileBase64(kStaticLeafMethodsDex, "kStaticLeafMethodsDex"));
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001034
1035 PathClassLoader* class_loader = AllocPathClassLoader(dex.get());
1036 ASSERT_TRUE(class_loader != NULL);
1037
1038 Class* klass = class_linker_->FindClass("LStaticLeafMethods;", class_loader);
1039 ASSERT_TRUE(klass != NULL);
1040
1041 Method* method = klass->FindDirectMethod("sum", "(DDDD)D");
1042 ASSERT_TRUE(method != NULL);
1043
1044 byte sum_DDDDD_code[] = {
1045 0x2d, 0xe9, 0x00, 0x40, 0x87, 0xb0, 0xcd, 0xf8,
1046 0x00, 0x00, 0xcd, 0xf8, 0x24, 0x10, 0xcd, 0xf8,
1047 0x28, 0x20, 0xcd, 0xf8, 0x2c, 0x30, 0x9d, 0xed,
1048 0x09, 0x0b, 0x9d, 0xed, 0x0b, 0x1b, 0x30, 0xee,
1049 0x01, 0x2b, 0x8d, 0xed, 0x04, 0x2b, 0x9d, 0xed,
1050 0x04, 0x3b, 0x9d, 0xed, 0x0d, 0x4b, 0x33, 0xee,
1051 0x04, 0x3b, 0x8d, 0xed, 0x04, 0x3b, 0x9d, 0xed,
1052 0x04, 0x5b, 0x9d, 0xed, 0x0f, 0x6b, 0x35, 0xee,
1053 0x06, 0x5b, 0x8d, 0xed, 0x04, 0x5b, 0x04, 0x98,
1054 0x05, 0x99, 0x07, 0xb0, 0xbd, 0xe8, 0x00, 0x80,
1055 };
1056
1057 Method::InvokeStub* stub = AllocateStub(method,
1058 sum_DDDDD_code,
1059 sizeof(sum_DDDDD_code));
1060
1061 double args[4];
1062 JValue result;
1063
1064 args[0] = 0.0;
1065 args[1] = 0.0;
1066 args[2] = 0.0;
1067 args[3] = 0.0;
1068 result.d = -1.0;
1069 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
1070 EXPECT_EQ(0.0, result.d);
1071
1072 args[0] = 1.0;
1073 args[1] = 2.0;
1074 args[2] = 3.0;
1075 args[3] = 4.0;
1076 result.d = 0.0;
1077 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
1078 EXPECT_EQ(10.0, result.d);
1079
1080 args[0] = 1.0;
1081 args[1] = -2.0;
1082 args[2] = 3.0;
1083 args[3] = -4.0;
1084 result.d = 0.0;
1085 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
1086 EXPECT_EQ(-2.0, result.d);
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001087}
1088
1089TEST_F(JniInternalTest, StaticSumDoubleDoubleDoubleDoubleDoubleMethod) {
Brian Carlstroma663ea52011-08-19 23:33:41 -07001090 scoped_ptr<DexFile> dex(OpenDexFileBase64(kStaticLeafMethodsDex, "kStaticLeafMethodsDex"));
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001091
1092 PathClassLoader* class_loader = AllocPathClassLoader(dex.get());
1093 ASSERT_TRUE(class_loader != NULL);
1094
1095 Class* klass = class_linker_->FindClass("LStaticLeafMethods;", class_loader);
1096 ASSERT_TRUE(klass != NULL);
1097
1098 Method* method = klass->FindDirectMethod("sum", "(DDDDD)D");
1099 ASSERT_TRUE(method != NULL);
1100
1101 byte sum_DDDDDD_code[] = {
1102 0x2d, 0xe9, 0x00, 0x40, 0x87, 0xb0, 0xcd, 0xf8,
1103 0x00, 0x00, 0xcd, 0xf8, 0x24, 0x10, 0xcd, 0xf8,
1104 0x28, 0x20, 0xcd, 0xf8, 0x2c, 0x30, 0x9d, 0xed,
1105 0x09, 0x0b, 0x9d, 0xed, 0x0b, 0x1b, 0x30, 0xee,
1106 0x01, 0x2b, 0x8d, 0xed, 0x04, 0x2b, 0x9d, 0xed,
1107 0x04, 0x3b, 0x9d, 0xed, 0x0d, 0x4b, 0x33, 0xee,
1108 0x04, 0x3b, 0x8d, 0xed, 0x04, 0x3b, 0x9d, 0xed,
1109 0x04, 0x5b, 0x9d, 0xed, 0x0f, 0x6b, 0x35, 0xee,
1110 0x06, 0x5b, 0x8d, 0xed, 0x04, 0x5b, 0x9d, 0xed,
1111 0x04, 0x7b, 0x9d, 0xed, 0x11, 0x0b, 0x37, 0xee,
1112 0x00, 0x7b, 0x8d, 0xed, 0x04, 0x7b, 0x04, 0x98,
1113 0x05, 0x99, 0x07, 0xb0, 0xbd, 0xe8, 0x00, 0x80,
1114 };
1115
1116 Method::InvokeStub* stub = AllocateStub(method,
1117 sum_DDDDDD_code,
1118 sizeof(sum_DDDDDD_code));
1119
1120 double args[5];
1121 JValue result;
1122
1123 args[0] = 0.0;
1124 args[1] = 0.0;
1125 args[2] = 0.0;
1126 args[3] = 0.0;
1127 args[4] = 0.0;
1128 result.d = -1.0;
1129 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
1130 EXPECT_EQ(0.0, result.d);
1131
1132 args[0] = 1.0;
1133 args[1] = 2.0;
1134 args[2] = 3.0;
1135 args[3] = 4.0;
1136 args[4] = 5.0;
1137 result.d = 0.0;
1138 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
1139 EXPECT_EQ(15.0, result.d);
1140
1141 args[0] = 1.0;
1142 args[1] = -2.0;
1143 args[2] = 3.0;
1144 args[3] = -4.0;
1145 args[4] = 5.0;
1146 result.d = 0.0;
1147 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
1148 EXPECT_EQ(3.0, result.d);
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001149}
1150#endif // __arm__
1151
1152}