blob: 62f606821d34770fea641a28293dd9156754bad5 [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 Hughes885c3bd2011-08-22 16:59:20 -070022TEST_F(JniInternalTest, AllocObject) {
23 jclass c = env_->FindClass("java/lang/String");
24 ASSERT_TRUE(c != NULL);
25 jobject o = env_->AllocObject(c);
26 ASSERT_TRUE(o != NULL);
27
28 // We have an instance of the class we asked for...
29 ASSERT_TRUE(env_->IsInstanceOf(o, c));
30 // ...whose fields haven't been initialized because
31 // we didn't call a constructor.
32 ASSERT_EQ(0, env_->GetIntField(o, env_->GetFieldID(c, "count", "I")));
33 ASSERT_EQ(0, env_->GetIntField(o, env_->GetFieldID(c, "offset", "I")));
34 ASSERT_TRUE(env_->GetObjectField(o, env_->GetFieldID(c, "value", "[C")) == NULL);
35}
36
Elliott Hughesc7ac37f2011-08-12 12:21:58 -070037TEST_F(JniInternalTest, GetVersion) {
38 ASSERT_EQ(JNI_VERSION_1_6, env_->GetVersion());
39}
40
Elliott Hughes0c9cd562011-08-12 10:59:29 -070041#define EXPECT_CLASS_FOUND(NAME) \
Elliott Hughesbd935992011-08-22 11:59:34 -070042 EXPECT_TRUE(env_->FindClass(NAME) != NULL); \
43 EXPECT_FALSE(env_->ExceptionCheck())
Elliott Hughes0c9cd562011-08-12 10:59:29 -070044
45#define EXPECT_CLASS_NOT_FOUND(NAME) \
Elliott Hughesbd935992011-08-22 11:59:34 -070046 EXPECT_TRUE(env_->FindClass(NAME) == NULL); \
47 EXPECT_TRUE(env_->ExceptionCheck()); \
48 env_->ExceptionClear()
Elliott Hughes0c9cd562011-08-12 10:59:29 -070049
50TEST_F(JniInternalTest, FindClass) {
Elliott Hughes0c9cd562011-08-12 10:59:29 -070051 // TODO: when these tests start failing because you're calling FindClass
52 // with a pending exception, fix EXPECT_CLASS_NOT_FOUND to assert that an
53 // exception was thrown and clear the exception.
54
55 // TODO: . is only allowed as an alternative to / if CheckJNI is off.
56
57 // Reference types...
58 // You can't include the "L;" in a JNI class descriptor.
59 EXPECT_CLASS_FOUND("java/lang/String");
60 EXPECT_CLASS_NOT_FOUND("Ljava/lang/String;");
61 // We support . as well as / for compatibility.
62 EXPECT_CLASS_FOUND("java.lang.String");
63 EXPECT_CLASS_NOT_FOUND("Ljava.lang.String;");
64 // ...for arrays too, where you must include "L;".
65 EXPECT_CLASS_FOUND("[Ljava/lang/String;");
66 EXPECT_CLASS_NOT_FOUND("[java/lang/String");
67 EXPECT_CLASS_FOUND("[Ljava.lang.String;");
68 EXPECT_CLASS_NOT_FOUND("[java.lang.String");
69
70 // Primitive arrays are okay (if the primitive type is valid)...
71 EXPECT_CLASS_FOUND("[C");
72 EXPECT_CLASS_NOT_FOUND("[K");
73 // But primitive types aren't allowed...
74 EXPECT_CLASS_NOT_FOUND("C");
75 EXPECT_CLASS_NOT_FOUND("K");
76}
77
Elliott Hughescdf53122011-08-19 15:46:09 -070078#define EXPECT_EXCEPTION(exception_class) \
79 do { \
80 EXPECT_TRUE(env_->ExceptionCheck()); \
81 jthrowable exception = env_->ExceptionOccurred(); \
82 EXPECT_NE(static_cast<jthrowable>(NULL), exception); \
83 EXPECT_TRUE(env_->IsInstanceOf(exception, exception_class)); \
84 env_->ExceptionClear(); \
85 } while (false)
86
87TEST_F(JniInternalTest, GetFieldID) {
88 jclass jlnsfe = env_->FindClass("java/lang/NoSuchFieldError");
89 ASSERT_TRUE(jlnsfe != NULL);
90 jclass c = env_->FindClass("java/lang/String");
91 ASSERT_TRUE(c != NULL);
92
93 // Wrong type.
94 jfieldID fid = env_->GetFieldID(c, "count", "J");
95 EXPECT_EQ(static_cast<jfieldID>(NULL), fid);
96 EXPECT_EXCEPTION(jlnsfe);
97
98 // Wrong name.
99 fid = env_->GetFieldID(c, "Count", "I");
100 EXPECT_EQ(static_cast<jfieldID>(NULL), fid);
101 EXPECT_EXCEPTION(jlnsfe);
102
103 // Good declared field lookup.
104 fid = env_->GetFieldID(c, "count", "I");
105 EXPECT_NE(static_cast<jfieldID>(NULL), fid);
106 EXPECT_TRUE(fid != NULL);
107 EXPECT_FALSE(env_->ExceptionCheck());
108
109 // Good superclass field lookup.
110 c = env_->FindClass("java/lang/StringBuilder");
111 fid = env_->GetFieldID(c, "count", "I");
112 EXPECT_NE(static_cast<jfieldID>(NULL), fid);
113 EXPECT_TRUE(fid != NULL);
114 EXPECT_FALSE(env_->ExceptionCheck());
115
116 // Not instance.
117 fid = env_->GetFieldID(c, "CASE_INSENSITIVE_ORDER", "Ljava/util/Comparator;");
118 EXPECT_EQ(static_cast<jfieldID>(NULL), fid);
119 EXPECT_EXCEPTION(jlnsfe);
120}
121
122TEST_F(JniInternalTest, GetStaticFieldID) {
123 jclass jlnsfe = env_->FindClass("java/lang/NoSuchFieldError");
124 ASSERT_TRUE(jlnsfe != NULL);
125 jclass c = env_->FindClass("java/lang/String");
126 ASSERT_TRUE(c != NULL);
127
128 // Wrong type.
129 jfieldID fid = env_->GetStaticFieldID(c, "CASE_INSENSITIVE_ORDER", "J");
130 EXPECT_EQ(static_cast<jfieldID>(NULL), fid);
131 EXPECT_EXCEPTION(jlnsfe);
132
133 // Wrong name.
134 fid = env_->GetStaticFieldID(c, "cASE_INSENSITIVE_ORDER", "Ljava/util/Comparator;");
135 EXPECT_EQ(static_cast<jfieldID>(NULL), fid);
136 EXPECT_EXCEPTION(jlnsfe);
137
138 // Good declared field lookup.
139 fid = env_->GetStaticFieldID(c, "CASE_INSENSITIVE_ORDER", "Ljava/util/Comparator;");
140 EXPECT_NE(static_cast<jfieldID>(NULL), fid);
141 EXPECT_TRUE(fid != NULL);
142 EXPECT_FALSE(env_->ExceptionCheck());
143
144 // Not static.
145 fid = env_->GetStaticFieldID(c, "count", "I");
146 EXPECT_EQ(static_cast<jfieldID>(NULL), fid);
147 EXPECT_EXCEPTION(jlnsfe);
148}
149
Ian Rogers4dd71f12011-08-16 14:16:02 -0700150TEST_F(JniInternalTest, GetMethodID) {
151 jclass jlobject = env_->FindClass("java/lang/Object");
152 jclass jlstring = env_->FindClass("java/lang/String");
153 jclass jlnsme = env_->FindClass("java/lang/NoSuchMethodError");
154
155 // Sanity check that no exceptions are pending
Elliott Hughescdf53122011-08-19 15:46:09 -0700156 ASSERT_FALSE(env_->ExceptionCheck());
Ian Rogers4dd71f12011-08-16 14:16:02 -0700157
158 // Check that java.lang.Object.foo() doesn't exist and NoSuchMethodError is
159 // a pending exception
160 jmethodID method = env_->GetMethodID(jlobject, "foo", "()V");
161 EXPECT_EQ(static_cast<jmethodID>(NULL), method);
Elliott Hughescdf53122011-08-19 15:46:09 -0700162 EXPECT_EXCEPTION(jlnsme);
Ian Rogers4dd71f12011-08-16 14:16:02 -0700163
164 // Check that java.lang.Object.equals() does exist
Ian Rogers4dd71f12011-08-16 14:16:02 -0700165 method = env_->GetMethodID(jlobject, "equals", "(Ljava/lang/Object;)Z");
166 EXPECT_NE(static_cast<jmethodID>(NULL), method);
167 EXPECT_FALSE(env_->ExceptionCheck());
Ian Rogers4dd71f12011-08-16 14:16:02 -0700168
169 // Check that GetMethodID for java.lang.String.valueOf(int) fails as the
170 // method is static
171 method = env_->GetMethodID(jlstring, "valueOf", "(I)Ljava/lang/String;");
172 EXPECT_EQ(static_cast<jmethodID>(NULL), method);
Elliott Hughescdf53122011-08-19 15:46:09 -0700173 EXPECT_EXCEPTION(jlnsme);
Ian Rogers4dd71f12011-08-16 14:16:02 -0700174}
175
176TEST_F(JniInternalTest, GetStaticMethodID) {
177 jclass jlobject = env_->FindClass("java/lang/Object");
178 jclass jlnsme = env_->FindClass("java/lang/NoSuchMethodError");
179
180 // Sanity check that no exceptions are pending
Elliott Hughescdf53122011-08-19 15:46:09 -0700181 ASSERT_FALSE(env_->ExceptionCheck());
Ian Rogers4dd71f12011-08-16 14:16:02 -0700182
183 // Check that java.lang.Object.foo() doesn't exist and NoSuchMethodError is
184 // a pending exception
185 jmethodID method = env_->GetStaticMethodID(jlobject, "foo", "()V");
186 EXPECT_EQ(static_cast<jmethodID>(NULL), method);
Elliott Hughescdf53122011-08-19 15:46:09 -0700187 EXPECT_EXCEPTION(jlnsme);
Ian Rogers4dd71f12011-08-16 14:16:02 -0700188
189 // Check that GetStaticMethodID for java.lang.Object.equals(Object) fails as
190 // the method is not static
191 method = env_->GetStaticMethodID(jlobject, "equals", "(Ljava/lang/Object;)Z");
192 EXPECT_EQ(static_cast<jmethodID>(NULL), method);
Elliott Hughescdf53122011-08-19 15:46:09 -0700193 EXPECT_EXCEPTION(jlnsme);
Ian Rogers4dd71f12011-08-16 14:16:02 -0700194
195 // Check that java.lang.String.valueOf(int) does exist
Ian Rogers4dd71f12011-08-16 14:16:02 -0700196 jclass jlstring = env_->FindClass("java/lang/String");
197 method = env_->GetStaticMethodID(jlstring, "valueOf",
198 "(I)Ljava/lang/String;");
199 EXPECT_NE(static_cast<jmethodID>(NULL), method);
200 EXPECT_FALSE(env_->ExceptionCheck());
Ian Rogers4dd71f12011-08-16 14:16:02 -0700201}
202
Elliott Hughescdf53122011-08-19 15:46:09 -0700203TEST_F(JniInternalTest, FromReflectedField_ToReflectedField) {
204 jclass jlrField = env_->FindClass("java/lang/reflect/Field");
205 jclass c = env_->FindClass("java/lang/String");
206 ASSERT_TRUE(c != NULL);
207 jfieldID fid = env_->GetFieldID(c, "count", "I");
208 ASSERT_TRUE(fid != NULL);
209 // Turn the fid into a java.lang.reflect.Field...
210 jobject field = env_->ToReflectedField(c, fid, JNI_FALSE);
211 ASSERT_TRUE(c != NULL);
212 ASSERT_TRUE(env_->IsInstanceOf(field, jlrField));
213 // ...and back again.
214 jfieldID fid2 = env_->FromReflectedField(field);
215 ASSERT_TRUE(fid2 != NULL);
216}
217
218TEST_F(JniInternalTest, FromReflectedMethod_ToReflectedMethod) {
219 jclass jlrMethod = env_->FindClass("java/lang/reflect/Method");
220 jclass c = env_->FindClass("java/lang/String");
221 ASSERT_TRUE(c != NULL);
222 jmethodID mid = env_->GetMethodID(c, "length", "()I");
223 ASSERT_TRUE(mid != NULL);
224 // Turn the mid into a java.lang.reflect.Method...
225 jobject method = env_->ToReflectedMethod(c, mid, JNI_FALSE);
226 ASSERT_TRUE(c != NULL);
227 ASSERT_TRUE(env_->IsInstanceOf(method, jlrMethod));
228 // ...and back again.
229 jmethodID mid2 = env_->FromReflectedMethod(method);
230 ASSERT_TRUE(mid2 != NULL);
231}
232
Ian Rogers4dd71f12011-08-16 14:16:02 -0700233TEST_F(JniInternalTest, RegisterNatives) {
234 jclass jlobject = env_->FindClass("java/lang/Object");
235 jclass jlnsme = env_->FindClass("java/lang/NoSuchMethodError");
236
237 // Sanity check that no exceptions are pending
Elliott Hughescdf53122011-08-19 15:46:09 -0700238 ASSERT_FALSE(env_->ExceptionCheck());
Ian Rogers4dd71f12011-08-16 14:16:02 -0700239
240 // Check that registering to a non-existent java.lang.Object.foo() causes a
241 // NoSuchMethodError
242 {
243 JNINativeMethod methods[] = {{"foo", "()V", NULL}};
244 env_->RegisterNatives(jlobject, methods, 1);
245 }
Elliott Hughescdf53122011-08-19 15:46:09 -0700246 EXPECT_EXCEPTION(jlnsme);
Ian Rogers4dd71f12011-08-16 14:16:02 -0700247
248 // Check that registering non-native methods causes a NoSuchMethodError
249 {
250 JNINativeMethod methods[] = {{"equals", "(Ljava/lang/Object;)Z", NULL}};
251 env_->RegisterNatives(jlobject, methods, 1);
252 }
Elliott Hughescdf53122011-08-19 15:46:09 -0700253 EXPECT_EXCEPTION(jlnsme);
Ian Rogers4dd71f12011-08-16 14:16:02 -0700254
255 // Check that registering native methods is successful
256 {
257 JNINativeMethod methods[] = {{"hashCode", "()I", NULL}};
258 env_->RegisterNatives(jlobject, methods, 1);
259 }
260 EXPECT_FALSE(env_->ExceptionCheck());
261}
262
Elliott Hughesbd935992011-08-22 11:59:34 -0700263#define EXPECT_PRIMITIVE_ARRAY(fn, size, expected_class_name) \
264 do { \
265 jarray a = env_->fn(size); \
266 EXPECT_TRUE(a != NULL); \
267 EXPECT_TRUE(env_->IsInstanceOf(a, \
268 env_->FindClass(expected_class_name))); \
269 EXPECT_EQ(size, env_->GetArrayLength(a)); \
270 } while (false)
271
Elliott Hughesd8ddfd52011-08-15 14:32:53 -0700272TEST_F(JniInternalTest, NewPrimitiveArray) {
273 // TODO: death tests for negative array sizes.
274
Elliott Hughesbd935992011-08-22 11:59:34 -0700275 EXPECT_PRIMITIVE_ARRAY(NewBooleanArray, 0, "[Z");
276 EXPECT_PRIMITIVE_ARRAY(NewByteArray, 0, "[B");
277 EXPECT_PRIMITIVE_ARRAY(NewCharArray, 0, "[C");
278 EXPECT_PRIMITIVE_ARRAY(NewDoubleArray, 0, "[D");
279 EXPECT_PRIMITIVE_ARRAY(NewFloatArray, 0, "[F");
280 EXPECT_PRIMITIVE_ARRAY(NewIntArray, 0, "[I");
281 EXPECT_PRIMITIVE_ARRAY(NewLongArray, 0, "[J");
282 EXPECT_PRIMITIVE_ARRAY(NewShortArray, 0, "[S");
Elliott Hughesf2682d52011-08-15 16:37:04 -0700283
Elliott Hughesbd935992011-08-22 11:59:34 -0700284 EXPECT_PRIMITIVE_ARRAY(NewBooleanArray, 1, "[Z");
285 EXPECT_PRIMITIVE_ARRAY(NewByteArray, 1, "[B");
286 EXPECT_PRIMITIVE_ARRAY(NewCharArray, 1, "[C");
287 EXPECT_PRIMITIVE_ARRAY(NewDoubleArray, 1, "[D");
288 EXPECT_PRIMITIVE_ARRAY(NewFloatArray, 1, "[F");
289 EXPECT_PRIMITIVE_ARRAY(NewIntArray, 1, "[I");
290 EXPECT_PRIMITIVE_ARRAY(NewLongArray, 1, "[J");
291 EXPECT_PRIMITIVE_ARRAY(NewShortArray, 1, "[S");
Elliott Hughesd8ddfd52011-08-15 14:32:53 -0700292}
293
Elliott Hughesf2682d52011-08-15 16:37:04 -0700294TEST_F(JniInternalTest, NewObjectArray) {
295 // TODO: death tests for negative array sizes.
296
Elliott Hughesf2682d52011-08-15 16:37:04 -0700297 // TODO: check non-NULL initial elements.
298
Elliott Hughesbd935992011-08-22 11:59:34 -0700299 jclass element_class = env_->FindClass("java/lang/String");
300 ASSERT_TRUE(element_class != NULL);
301 jclass array_class = env_->FindClass("[Ljava/lang/String;");
302 ASSERT_TRUE(array_class != NULL);
Elliott Hughesf2682d52011-08-15 16:37:04 -0700303
Elliott Hughesbd935992011-08-22 11:59:34 -0700304 jobjectArray a;
Elliott Hughesf2682d52011-08-15 16:37:04 -0700305
Elliott Hughesbd935992011-08-22 11:59:34 -0700306 a = env_->NewObjectArray(0, element_class, NULL);
307 EXPECT_TRUE(a != NULL);
308 EXPECT_TRUE(env_->IsInstanceOf(a, array_class));
309 EXPECT_EQ(0, env_->GetArrayLength(a));
310
311 a = env_->NewObjectArray(1, element_class, NULL);
312 EXPECT_TRUE(a != NULL);
313 EXPECT_TRUE(env_->IsInstanceOf(a, array_class));
314 EXPECT_EQ(1, env_->GetArrayLength(a));
315}
316
317TEST_F(JniInternalTest, GetArrayLength) {
318 // Already tested in NewObjectArray/NewPrimitiveArray.
Elliott Hughes8a26c5c2011-08-15 18:35:43 -0700319}
320
Elliott Hughes885c3bd2011-08-22 16:59:20 -0700321TEST_F(JniInternalTest, GetSuperclass) {
322 jclass object_class = env_->FindClass("java/lang/Object");
323 ASSERT_TRUE(object_class != NULL);
324 jclass string_class = env_->FindClass("java/lang/String");
325 ASSERT_TRUE(string_class != NULL);
326 ASSERT_TRUE(env_->IsSameObject(object_class, env_->GetSuperclass(string_class)));
327 ASSERT_TRUE(env_->GetSuperclass(object_class) == NULL);
328}
329
Elliott Hughes8a26c5c2011-08-15 18:35:43 -0700330TEST_F(JniInternalTest, NewStringUTF) {
331 EXPECT_TRUE(env_->NewStringUTF(NULL) == NULL);
332 EXPECT_TRUE(env_->NewStringUTF("") != NULL);
333 EXPECT_TRUE(env_->NewStringUTF("hello") != NULL);
334 // TODO: check some non-ASCII strings.
Elliott Hughesf2682d52011-08-15 16:37:04 -0700335}
336
Elliott Hughes289da822011-08-16 10:11:20 -0700337TEST_F(JniInternalTest, SetObjectArrayElement) {
Elliott Hughescdf53122011-08-19 15:46:09 -0700338 jclass aioobe = env_->FindClass("java/lang/ArrayIndexOutOfBoundsException");
Elliott Hughes289da822011-08-16 10:11:20 -0700339 jclass c = env_->FindClass("[Ljava/lang/Object;");
340 ASSERT_TRUE(c != NULL);
341
342 jobjectArray array = env_->NewObjectArray(1, c, NULL);
343 EXPECT_TRUE(array != NULL);
344 env_->SetObjectArrayElement(array, 0, c);
345 // TODO: check reading value back
Elliott Hughesa5b897e2011-08-16 11:33:06 -0700346
347 // ArrayIndexOutOfBounds for negative index.
Elliott Hughesa5b897e2011-08-16 11:33:06 -0700348 env_->SetObjectArrayElement(array, -1, c);
Elliott Hughescdf53122011-08-19 15:46:09 -0700349 EXPECT_EXCEPTION(aioobe);
Elliott Hughesa5b897e2011-08-16 11:33:06 -0700350
351 // ArrayIndexOutOfBounds for too-large index.
Elliott Hughesa5b897e2011-08-16 11:33:06 -0700352 env_->SetObjectArrayElement(array, 1, c);
Elliott Hughescdf53122011-08-19 15:46:09 -0700353 EXPECT_EXCEPTION(aioobe);
Elliott Hughesa5b897e2011-08-16 11:33:06 -0700354
Elliott Hughes289da822011-08-16 10:11:20 -0700355 // TODO: check ArrayStoreException thrown for bad types.
356}
357
Elliott Hughes885c3bd2011-08-22 16:59:20 -0700358#define EXPECT_STATIC_PRIMITIVE_FIELD(type, field_name, sig, value1, value2) \
359 do { \
360 jfieldID fid = env_->GetStaticFieldID(c, field_name, sig); \
361 EXPECT_TRUE(fid != NULL); \
362 env_->SetStatic ## type ## Field(c, fid, value1); \
363 EXPECT_EQ(value1, env_->GetStatic ## type ## Field(c, fid)); \
364 env_->SetStatic ## type ## Field(c, fid, value2); \
365 EXPECT_EQ(value2, env_->GetStatic ## type ## Field(c, fid)); \
366 } while (false)
367
368#define EXPECT_PRIMITIVE_FIELD(instance, type, field_name, sig, value1, value2) \
369 do { \
370 jfieldID fid = env_->GetFieldID(c, field_name, sig); \
371 EXPECT_TRUE(fid != NULL); \
372 env_->Set ## type ## Field(instance, fid, value1); \
373 EXPECT_EQ(value1, env_->Get ## type ## Field(instance, fid)); \
374 env_->Set ## type ## Field(instance, fid, value2); \
375 EXPECT_EQ(value2, env_->Get ## type ## Field(instance, fid)); \
376 } while (false)
377
378
379TEST_F(JniInternalTest, GetPrimitiveField_SetPrimitiveField) {
380 scoped_ptr<DexFile> dex(OpenDexFileBase64(kAllFields, "kAllFields"));
381 PathClassLoader* class_loader = AllocPathClassLoader(dex.get());
382 Thread::Current()->SetClassLoaderOverride(class_loader);
383
384 jclass c = env_->FindClass("AllFields");
385 ASSERT_TRUE(c != NULL);
386 jobject o = env_->AllocObject(c);
387 ASSERT_TRUE(o != NULL);
388
389 EXPECT_STATIC_PRIMITIVE_FIELD(Boolean, "sZ", "Z", true, false);
390 EXPECT_STATIC_PRIMITIVE_FIELD(Byte, "sB", "B", 1, 2);
391 EXPECT_STATIC_PRIMITIVE_FIELD(Char, "sC", "C", 'a', 'b');
392 EXPECT_STATIC_PRIMITIVE_FIELD(Double, "sD", "D", 1.0, 2.0);
393 EXPECT_STATIC_PRIMITIVE_FIELD(Float, "sF", "F", 1.0, 2.0);
394 EXPECT_STATIC_PRIMITIVE_FIELD(Int, "sI", "I", 1, 2);
395 EXPECT_STATIC_PRIMITIVE_FIELD(Long, "sJ", "J", 1, 2);
396 EXPECT_STATIC_PRIMITIVE_FIELD(Short, "sS", "S", 1, 2);
397
398 EXPECT_PRIMITIVE_FIELD(o, Boolean, "iZ", "Z", true, false);
399 EXPECT_PRIMITIVE_FIELD(o, Byte, "iB", "B", 1, 2);
400 EXPECT_PRIMITIVE_FIELD(o, Char, "iC", "C", 'a', 'b');
401 EXPECT_PRIMITIVE_FIELD(o, Double, "iD", "D", 1.0, 2.0);
402 EXPECT_PRIMITIVE_FIELD(o, Float, "iF", "F", 1.0, 2.0);
403 EXPECT_PRIMITIVE_FIELD(o, Int, "iI", "I", 1, 2);
404 EXPECT_PRIMITIVE_FIELD(o, Long, "iJ", "J", 1, 2);
405 EXPECT_PRIMITIVE_FIELD(o, Short, "iS", "S", 1, 2);
406}
407
408TEST_F(JniInternalTest, GetObjectField_SetObjectField) {
409 scoped_ptr<DexFile> dex(OpenDexFileBase64(kAllFields, "kAllFields"));
410 PathClassLoader* class_loader = AllocPathClassLoader(dex.get());
411 Thread::Current()->SetClassLoaderOverride(class_loader);
412
413 jclass c = env_->FindClass("AllFields");
414 ASSERT_TRUE(c != NULL);
415 jobject o = env_->AllocObject(c);
416 ASSERT_TRUE(o != NULL);
417
418 jstring s1 = env_->NewStringUTF("hello");
419 ASSERT_TRUE(s1 != NULL);
420 jstring s2 = env_->NewStringUTF("world");
421 ASSERT_TRUE(s2 != NULL);
422
423 jfieldID s_fid = env_->GetStaticFieldID(c, "sObject", "Ljava/lang/Object;");
424 ASSERT_TRUE(s_fid != NULL);
425 jfieldID i_fid = env_->GetFieldID(c, "iObject", "Ljava/lang/Object;");
426 ASSERT_TRUE(i_fid != NULL);
427
428 env_->SetStaticObjectField(c, s_fid, s1);
429 ASSERT_TRUE(env_->IsSameObject(s1, env_->GetStaticObjectField(c, s_fid)));
430 env_->SetStaticObjectField(c, s_fid, s2);
431 ASSERT_TRUE(env_->IsSameObject(s2, env_->GetStaticObjectField(c, s_fid)));
432
433 env_->SetObjectField(o, i_fid, s1);
434 ASSERT_TRUE(env_->IsSameObject(s1, env_->GetObjectField(o, i_fid)));
435 env_->SetObjectField(o, i_fid, s2);
436 ASSERT_TRUE(env_->IsSameObject(s2, env_->GetObjectField(o, i_fid)));
437}
438
Elliott Hughes18c07532011-08-18 15:50:51 -0700439TEST_F(JniInternalTest, NewLocalRef_NULL) {
440 EXPECT_TRUE(env_->NewLocalRef(NULL) == NULL);
441}
442
443TEST_F(JniInternalTest, NewLocalRef) {
444 jstring s = env_->NewStringUTF("");
445 ASSERT_TRUE(s != NULL);
446 jobject o = env_->NewLocalRef(s);
447 EXPECT_TRUE(o != NULL);
448 EXPECT_TRUE(o != s);
449
450 // TODO: check that o is a local reference.
451}
452
453TEST_F(JniInternalTest, DeleteLocalRef_NULL) {
454 env_->DeleteLocalRef(NULL);
455}
456
457TEST_F(JniInternalTest, DeleteLocalRef) {
458 jstring s = env_->NewStringUTF("");
459 ASSERT_TRUE(s != NULL);
460 env_->DeleteLocalRef(s);
461
462 // Currently, deleting an already-deleted reference is just a warning.
463 env_->DeleteLocalRef(s);
464
465 s = env_->NewStringUTF("");
466 ASSERT_TRUE(s != NULL);
467 jobject o = env_->NewLocalRef(s);
468 ASSERT_TRUE(o != NULL);
469
470 env_->DeleteLocalRef(s);
471 env_->DeleteLocalRef(o);
472}
473
474TEST_F(JniInternalTest, NewGlobalRef_NULL) {
475 EXPECT_TRUE(env_->NewGlobalRef(NULL) == NULL);
476}
477
478TEST_F(JniInternalTest, NewGlobalRef) {
479 jstring s = env_->NewStringUTF("");
480 ASSERT_TRUE(s != NULL);
481 jobject o = env_->NewGlobalRef(s);
482 EXPECT_TRUE(o != NULL);
483 EXPECT_TRUE(o != s);
484
485 // TODO: check that o is a global reference.
486}
487
488TEST_F(JniInternalTest, DeleteGlobalRef_NULL) {
489 env_->DeleteGlobalRef(NULL);
490}
491
492TEST_F(JniInternalTest, DeleteGlobalRef) {
493 jstring s = env_->NewStringUTF("");
494 ASSERT_TRUE(s != NULL);
495
496 jobject o = env_->NewGlobalRef(s);
497 ASSERT_TRUE(o != NULL);
498 env_->DeleteGlobalRef(o);
499
500 // Currently, deleting an already-deleted reference is just a warning.
501 env_->DeleteGlobalRef(o);
502
503 jobject o1 = env_->NewGlobalRef(s);
504 ASSERT_TRUE(o1 != NULL);
505 jobject o2 = env_->NewGlobalRef(s);
506 ASSERT_TRUE(o2 != NULL);
507
508 env_->DeleteGlobalRef(o1);
509 env_->DeleteGlobalRef(o2);
510}
511
512TEST_F(JniInternalTest, NewWeakGlobalRef_NULL) {
513 EXPECT_TRUE(env_->NewWeakGlobalRef(NULL) == NULL);
514}
515
516TEST_F(JniInternalTest, NewWeakGlobalRef) {
517 jstring s = env_->NewStringUTF("");
518 ASSERT_TRUE(s != NULL);
519 jobject o = env_->NewWeakGlobalRef(s);
520 EXPECT_TRUE(o != NULL);
521 EXPECT_TRUE(o != s);
522
523 // TODO: check that o is a weak global reference.
524}
525
526TEST_F(JniInternalTest, DeleteWeakGlobalRef_NULL) {
527 env_->DeleteWeakGlobalRef(NULL);
528}
529
530TEST_F(JniInternalTest, DeleteWeakGlobalRef) {
531 jstring s = env_->NewStringUTF("");
532 ASSERT_TRUE(s != NULL);
533
534 jobject o = env_->NewWeakGlobalRef(s);
535 ASSERT_TRUE(o != NULL);
536 env_->DeleteWeakGlobalRef(o);
537
538 // Currently, deleting an already-deleted reference is just a warning.
539 env_->DeleteWeakGlobalRef(o);
540
541 jobject o1 = env_->NewWeakGlobalRef(s);
542 ASSERT_TRUE(o1 != NULL);
543 jobject o2 = env_->NewWeakGlobalRef(s);
544 ASSERT_TRUE(o2 != NULL);
545
546 env_->DeleteWeakGlobalRef(o1);
547 env_->DeleteWeakGlobalRef(o2);
548}
549
Carl Shapiro9b9ba282011-08-14 15:30:39 -0700550bool EnsureInvokeStub(Method* method);
551
Carl Shapiro9b9ba282011-08-14 15:30:39 -0700552Method::InvokeStub* AllocateStub(Method* method,
553 byte* code,
554 size_t length) {
555 CHECK(method->GetInvokeStub() == NULL);
556 EnsureInvokeStub(method);
557 Method::InvokeStub* stub = method->GetInvokeStub();
558 CHECK(stub != NULL);
buzbeec143c552011-08-20 17:38:58 -0700559 method->SetCode(code, length, kThumb2);
Carl Shapiro9b9ba282011-08-14 15:30:39 -0700560 return stub;
561}
562
Carl Shapiro9b9ba282011-08-14 15:30:39 -0700563#if defined(__arm__)
564TEST_F(JniInternalTest, StaticMainMethod) {
Brian Carlstroma663ea52011-08-19 23:33:41 -0700565 scoped_ptr<DexFile> dex(OpenDexFileBase64(kMainDex, "kMainDex"));
Carl Shapiro9b9ba282011-08-14 15:30:39 -0700566
567 PathClassLoader* class_loader = AllocPathClassLoader(dex.get());
568 ASSERT_TRUE(class_loader != NULL);
569
570 Class* klass = class_linker_->FindClass("LMain;", class_loader);
571 ASSERT_TRUE(klass != NULL);
572
573 Method* method = klass->FindDirectMethod("main", "([Ljava/lang/String;)V");
574 ASSERT_TRUE(method != NULL);
575
576 byte main_LV_code[] = {
577 0x2d, 0xe9, 0x00, 0x40, 0x83, 0xb0, 0xcd, 0xf8, 0x00, 0x00,
578 0xcd, 0xf8, 0x14, 0x10, 0x03, 0xb0, 0xbd, 0xe8, 0x00, 0x80,
579 };
580
581 Method::InvokeStub* stub = AllocateStub(method,
582 main_LV_code,
583 sizeof(main_LV_code));
584
585 Object* arg = NULL;
586
587 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(&arg), NULL);
Carl Shapiro9b9ba282011-08-14 15:30:39 -0700588}
589
590TEST_F(JniInternalTest, StaticNopMethod) {
Brian Carlstroma663ea52011-08-19 23:33:41 -0700591 scoped_ptr<DexFile> dex(OpenDexFileBase64(kStaticLeafMethodsDex, "kStaticLeafMethodsDex"));
Carl Shapiro9b9ba282011-08-14 15:30:39 -0700592
593 PathClassLoader* class_loader = AllocPathClassLoader(dex.get());
594 ASSERT_TRUE(class_loader != NULL);
595
596 Class* klass = class_linker_->FindClass("LStaticLeafMethods;", class_loader);
597 ASSERT_TRUE(klass != NULL);
598
599 Method* method = klass->FindDirectMethod("nop", "()V");
600 ASSERT_TRUE(method != NULL);
601
602 byte nop_V_code[] = {
603 0x2d, 0xe9, 0x00, 0x40, 0x83, 0xb0, 0xcd, 0xf8,
604 0x00, 0x00, 0x03, 0xb0, 0xbd, 0xe8, 0x00, 0x80,
605 };
606
607 Method::InvokeStub* stub = AllocateStub(method,
608 nop_V_code,
609 sizeof(nop_V_code));
610 ASSERT_TRUE(stub);
611
612 (*stub)(method, NULL, NULL, NULL, NULL);
Carl Shapiro9b9ba282011-08-14 15:30:39 -0700613}
614
615TEST_F(JniInternalTest, StaticIdentityByteMethod) {
Brian Carlstroma663ea52011-08-19 23:33:41 -0700616 scoped_ptr<DexFile> dex(OpenDexFileBase64(kStaticLeafMethodsDex, "kStaticLeafMethodsDex"));
Carl Shapiro9b9ba282011-08-14 15:30:39 -0700617
618 PathClassLoader* class_loader = AllocPathClassLoader(dex.get());
619 ASSERT_TRUE(class_loader != NULL);
620
621 Class* klass = class_linker_->FindClass("LStaticLeafMethods;", class_loader);
622 ASSERT_TRUE(klass != NULL);
623
624 Method* method = klass->FindDirectMethod("identity", "(B)B");
625 ASSERT_TRUE(method != NULL);
626
627 byte identity_BB_code[] = {
628 0x2d, 0xe9, 0x00, 0x40, 0x83, 0xb0, 0xcd, 0xf8,
629 0x00, 0x00, 0xcd, 0xf8, 0x14, 0x10, 0x05, 0x98,
630 0x03, 0xb0, 0xbd, 0xe8, 0x00, 0x80, 0x00, 0x00,
631 };
632
633 Method::InvokeStub* stub = AllocateStub(method,
634 identity_BB_code,
635 sizeof(identity_BB_code));
636
637 int arg;
638 JValue result;
639
640 arg = 0;
641 result.b = -1;
642 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(&arg), &result);
643 EXPECT_EQ(0, result.b);
644
645 arg = -1;
646 result.b = 0;
647 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(&arg), &result);
648 EXPECT_EQ(-1, result.b);
649
650 arg = SCHAR_MAX;
651 result.b = 0;
652 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(&arg), &result);
653 EXPECT_EQ(SCHAR_MAX, result.b);
654
655 arg = SCHAR_MIN;
656 result.b = 0;
657 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(&arg), &result);
658 EXPECT_EQ(SCHAR_MIN, result.b);
Carl Shapiro9b9ba282011-08-14 15:30:39 -0700659}
660
661TEST_F(JniInternalTest, StaticIdentityIntMethod) {
Brian Carlstroma663ea52011-08-19 23:33:41 -0700662 scoped_ptr<DexFile> dex(OpenDexFileBase64(kStaticLeafMethodsDex, "kStaticLeafMethodsDex"));
Carl Shapiro9b9ba282011-08-14 15:30:39 -0700663
664 PathClassLoader* class_loader = AllocPathClassLoader(dex.get());
665 ASSERT_TRUE(class_loader != NULL);
666
667 Class* klass = class_linker_->FindClass("LStaticLeafMethods;", class_loader);
668 ASSERT_TRUE(klass != NULL);
669
670 Method* method = klass->FindDirectMethod("identity", "(I)I");
671 ASSERT_TRUE(method != NULL);
672
673 byte identity_II_code[] = {
674 0x2d, 0xe9, 0x00, 0x40, 0x83, 0xb0, 0xcd, 0xf8,
675 0x00, 0x00, 0xcd, 0xf8, 0x14, 0x10, 0x05, 0x98,
676 0x03, 0xb0, 0xbd, 0xe8, 0x00, 0x80, 0x00, 0x00,
677 };
678
679 Method::InvokeStub* stub = AllocateStub(method,
680 identity_II_code,
681 sizeof(identity_II_code));
682
683 int arg;
684 JValue result;
685
686 arg = 0;
687 result.i = -1;
688 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(&arg), &result);
689 EXPECT_EQ(0, result.i);
690
691 arg = -1;
692 result.i = 0;
693 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(&arg), &result);
694 EXPECT_EQ(-1, result.i);
695
696 arg = INT_MAX;
697 result.i = 0;
698 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(&arg), &result);
699 EXPECT_EQ(INT_MAX, result.i);
700
701 arg = INT_MIN;
702 result.i = 0;
703 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(&arg), &result);
704 EXPECT_EQ(INT_MIN, result.i);
Carl Shapiro9b9ba282011-08-14 15:30:39 -0700705}
706
707TEST_F(JniInternalTest, StaticIdentityDoubleMethod) {
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("identity", "(D)D");
717 ASSERT_TRUE(method != NULL);
718
719 byte identity_DD_code[] = {
720 0x2d, 0xe9, 0x00, 0x40, 0x83, 0xb0, 0xcd, 0xf8,
721 0x00, 0x00, 0xcd, 0xf8, 0x14, 0x10, 0xcd, 0xf8,
722 0x18, 0x20, 0x05, 0x98, 0x06, 0x99, 0x03, 0xb0,
723 0xbd, 0xe8, 0x00, 0x80,
724 };
725
726 Method::InvokeStub* stub = AllocateStub(method,
727 identity_DD_code,
728 sizeof(identity_DD_code));
729
730 double arg;
731 JValue result;
732
733 arg = 0.0;
734 result.d = -1.0;
735 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(&arg), &result);
736 EXPECT_EQ(0.0, result.d);
737
738 arg = -1.0;
739 result.d = 0.0;
740 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(&arg), &result);
741 EXPECT_EQ(-1.0, result.d);
742
743 arg = DBL_MAX;
744 result.d = 0.0;
745 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(&arg), &result);
746 EXPECT_EQ(DBL_MAX, result.d);
747
748 arg = DBL_MIN;
749 result.d = 0.0;
750 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(&arg), &result);
751 EXPECT_EQ(DBL_MIN, result.d);
Carl Shapiro9b9ba282011-08-14 15:30:39 -0700752}
753
754TEST_F(JniInternalTest, StaticSumIntIntMethod) {
Brian Carlstroma663ea52011-08-19 23:33:41 -0700755 scoped_ptr<DexFile> dex(OpenDexFileBase64(kStaticLeafMethodsDex, "kStaticLeafMethodsDex"));
Carl Shapiro9b9ba282011-08-14 15:30:39 -0700756
757 PathClassLoader* class_loader = AllocPathClassLoader(dex.get());
758 ASSERT_TRUE(class_loader != NULL);
759
760 Class* klass = class_linker_->FindClass("LStaticLeafMethods;", class_loader);
761 ASSERT_TRUE(klass != NULL);
762
763 Method* method = klass->FindDirectMethod("sum", "(II)I");
764 ASSERT_TRUE(method != NULL);
765
766 byte sum_III_code[] = {
767 0x2d, 0xe9, 0x00, 0x40, 0x83, 0xb0, 0xcd, 0xf8,
768 0x00, 0x00, 0xcd, 0xf8, 0x14, 0x10, 0xcd, 0xf8,
769 0x18, 0x20, 0x05, 0x98, 0x06, 0x99, 0x42, 0x18,
770 0xcd, 0xf8, 0x04, 0x20, 0x01, 0x98, 0x03, 0xb0,
771 0xbd, 0xe8, 0x00, 0x80,
772 };
773
774 Method::InvokeStub* stub = AllocateStub(method,
775 sum_III_code,
776 sizeof(sum_III_code));
777
778 int args[2];
779 JValue result;
780
781 args[0] = 0;
782 args[1] = 0;
783 result.i = -1;
784 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
785 EXPECT_EQ(0, result.i);
786
787 args[0] = 1;
788 args[1] = 2;
789 result.i = 0;
790 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
791 EXPECT_EQ(3, result.i);
792
793 args[0] = -2;
794 args[1] = 5;
795 result.i = 0;
796 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
797 EXPECT_EQ(3, result.i);
798
799 args[0] = INT_MAX;
800 args[1] = INT_MIN;
801 result.i = 1234;
802 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
803 EXPECT_EQ(-1, result.i);
804
805 args[0] = INT_MAX;
806 args[1] = INT_MAX;
807 result.i = INT_MIN;
808 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
809 EXPECT_EQ(-2, result.i);
Carl Shapiro9b9ba282011-08-14 15:30:39 -0700810}
811
812TEST_F(JniInternalTest, StaticSumIntIntIntMethod) {
Brian Carlstroma663ea52011-08-19 23:33:41 -0700813 scoped_ptr<DexFile> dex(OpenDexFileBase64(kStaticLeafMethodsDex, "kStaticLeafMethodsDex"));
Carl Shapiro9b9ba282011-08-14 15:30:39 -0700814
815 PathClassLoader* class_loader = AllocPathClassLoader(dex.get());
816 ASSERT_TRUE(class_loader != NULL);
817
818 Class* klass = class_linker_->FindClass("LStaticLeafMethods;", class_loader);
819 ASSERT_TRUE(klass != NULL);
820
821 Method* method = klass->FindDirectMethod("sum", "(III)I");
822 ASSERT_TRUE(method != NULL);
823
824 byte sum_IIII_code[] = {
825 0x2d, 0xe9, 0x00, 0x40, 0x83, 0xb0, 0xcd, 0xf8,
826 0x00, 0x00, 0xcd, 0xf8, 0x14, 0x10, 0xcd, 0xf8,
827 0x18, 0x20, 0xcd, 0xf8, 0x1c, 0x30, 0x05, 0x98,
828 0x06, 0x99, 0x42, 0x18, 0xcd, 0xf8, 0x04, 0x20,
829 0x01, 0x9b, 0xdd, 0xf8, 0x1c, 0xc0, 0x13, 0xeb,
830 0x0c, 0x03, 0xcd, 0xf8, 0x04, 0x30, 0x01, 0x98,
831 0x03, 0xb0, 0xbd, 0xe8, 0x00, 0x80, 0x00, 0x00,
832 };
833
834 Method::InvokeStub* stub = AllocateStub(method,
835 sum_IIII_code,
836 sizeof(sum_IIII_code));
837
838 int args[3];
839 JValue result;
840
841 args[0] = 0;
842 args[1] = 0;
843 args[2] = 0;
844 result.i = -1;
845 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
846 EXPECT_EQ(0, result.i);
847
848 args[0] = 1;
849 args[1] = 2;
850 args[2] = 3;
851 result.i = 0;
852 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
853 EXPECT_EQ(6, result.i);
854
855 args[0] = -1;
856 args[1] = 2;
857 args[2] = -3;
858 result.i = 0;
859 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
860 EXPECT_EQ(-2, result.i);
861
862 args[0] = INT_MAX;
863 args[1] = INT_MIN;
864 args[2] = INT_MAX;
865 result.i = 1234;
866 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
867 EXPECT_EQ(2147483646, result.i);
868
869 args[0] = INT_MAX;
870 args[1] = INT_MAX;
871 args[2] = INT_MAX;
872 result.i = INT_MIN;
873 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
874 EXPECT_EQ(2147483645, result.i);
Carl Shapiro9b9ba282011-08-14 15:30:39 -0700875}
876
877TEST_F(JniInternalTest, StaticSumIntIntIntIntMethod) {
Brian Carlstroma663ea52011-08-19 23:33:41 -0700878 scoped_ptr<DexFile> dex(OpenDexFileBase64(kStaticLeafMethodsDex, "kStaticLeafMethodsDex"));
Carl Shapiro9b9ba282011-08-14 15:30:39 -0700879
880 PathClassLoader* class_loader = AllocPathClassLoader(dex.get());
881 ASSERT_TRUE(class_loader != NULL);
882
883 Class* klass = class_linker_->FindClass("LStaticLeafMethods;", class_loader);
884 ASSERT_TRUE(klass != NULL);
885
886 Method* method = klass->FindDirectMethod("sum", "(IIII)I");
887 ASSERT_TRUE(method != NULL);
888
889 byte sum_IIIII_code[] = {
890 0x2d, 0xe9, 0x00, 0x40, 0x83, 0xb0, 0xcd, 0xf8,
891 0x00, 0x00, 0xcd, 0xf8, 0x14, 0x10, 0xcd, 0xf8,
892 0x18, 0x20, 0xcd, 0xf8, 0x1c, 0x30, 0x05, 0x98,
893 0x06, 0x99, 0x42, 0x18, 0xcd, 0xf8, 0x04, 0x20,
894 0x01, 0x9b, 0xdd, 0xf8, 0x1c, 0xc0, 0x13, 0xeb,
895 0x0c, 0x03, 0xcd, 0xf8, 0x04, 0x30, 0x01, 0x98,
896 0x08, 0x99, 0x40, 0x18, 0xcd, 0xf8, 0x04, 0x00,
897 0x01, 0x98, 0x03, 0xb0, 0xbd, 0xe8, 0x00, 0x80,
898 };
899
900 Method::InvokeStub* stub = AllocateStub(method,
901 sum_IIIII_code,
902 sizeof(sum_IIIII_code));
903
904 int args[4];
905 JValue result;
906
907 args[0] = 0;
908 args[1] = 0;
909 args[2] = 0;
910 args[3] = 0;
911 result.i = -1;
912 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
913 EXPECT_EQ(0, result.i);
914
915 args[0] = 1;
916 args[1] = 2;
917 args[2] = 3;
918 args[3] = 4;
919 result.i = 0;
920 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
921 EXPECT_EQ(10, result.i);
922
923 args[0] = -1;
924 args[1] = 2;
925 args[2] = -3;
926 args[3] = 4;
927 result.i = 0;
928 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
929 EXPECT_EQ(2, result.i);
930
931 args[0] = INT_MAX;
932 args[1] = INT_MIN;
933 args[2] = INT_MAX;
934 args[3] = INT_MIN;
935 result.i = 1234;
936 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
937 EXPECT_EQ(-2, result.i);
938
939 args[0] = INT_MAX;
940 args[1] = INT_MAX;
941 args[2] = INT_MAX;
942 args[3] = INT_MAX;
943 result.i = INT_MIN;
944 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
945 EXPECT_EQ(-4, result.i);
Carl Shapiro9b9ba282011-08-14 15:30:39 -0700946}
947
948TEST_F(JniInternalTest, StaticSumIntIntIntIntIntMethod) {
Brian Carlstroma663ea52011-08-19 23:33:41 -0700949 scoped_ptr<DexFile> dex(OpenDexFileBase64(kStaticLeafMethodsDex, "kStaticLeafMethodsDex"));
Carl Shapiro9b9ba282011-08-14 15:30:39 -0700950
951 PathClassLoader* class_loader = AllocPathClassLoader(dex.get());
952 ASSERT_TRUE(class_loader != NULL);
953
954 Class* klass = class_linker_->FindClass("LStaticLeafMethods;", class_loader);
955 ASSERT_TRUE(klass != NULL);
956
957 Method* method = klass->FindDirectMethod("sum", "(IIIII)I");
958 ASSERT_TRUE(method != NULL);
959
960 byte sum_IIIIII_code[] = {
961 0x2d, 0xe9, 0x00, 0x40, 0x83, 0xb0, 0xcd, 0xf8,
962 0x00, 0x00, 0xcd, 0xf8, 0x14, 0x10, 0xcd, 0xf8,
963 0x18, 0x20, 0xcd, 0xf8, 0x1c, 0x30, 0x05, 0x98,
964 0x06, 0x99, 0x42, 0x18, 0xcd, 0xf8, 0x04, 0x20,
965 0x01, 0x9b, 0xdd, 0xf8, 0x1c, 0xc0, 0x13, 0xeb,
966 0x0c, 0x03, 0xcd, 0xf8, 0x04, 0x30, 0x01, 0x98,
967 0x08, 0x99, 0x40, 0x18, 0xcd, 0xf8, 0x04, 0x00,
968 0x01, 0x9a, 0x09, 0x9b, 0xd2, 0x18, 0xcd, 0xf8,
969 0x04, 0x20, 0x01, 0x98, 0x03, 0xb0, 0xbd, 0xe8,
970 0x00, 0x80, 0x00, 0x00,
971 };
972
973 Method::InvokeStub* stub = AllocateStub(method,
974 sum_IIIIII_code,
975 sizeof(sum_IIIIII_code));
976
977 int args[5];
978 JValue result;
979
980 args[0] = 0;
981 args[1] = 0;
982 args[2] = 0;
983 args[3] = 0;
984 args[4] = 0;
985 result.i = -1.0;
986 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
987 EXPECT_EQ(0, result.i);
988
989 args[0] = 1;
990 args[1] = 2;
991 args[2] = 3;
992 args[3] = 4;
993 args[4] = 5;
994 result.i = 0;
995 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
996 EXPECT_EQ(15, result.i);
997
998 args[0] = -1;
999 args[1] = 2;
1000 args[2] = -3;
1001 args[3] = 4;
1002 args[4] = -5;
1003 result.i = 0;
1004 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
1005 EXPECT_EQ(-3, result.i);
1006
1007 args[0] = INT_MAX;
1008 args[1] = INT_MIN;
1009 args[2] = INT_MAX;
1010 args[3] = INT_MIN;
1011 args[4] = INT_MAX;
1012 result.i = 1234;
1013 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
1014 EXPECT_EQ(2147483645, result.i);
1015
1016 args[0] = INT_MAX;
1017 args[1] = INT_MAX;
1018 args[2] = INT_MAX;
1019 args[3] = INT_MAX;
1020 args[4] = INT_MAX;
1021 result.i = INT_MIN;
1022 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
1023 EXPECT_EQ(2147483643, result.i);
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001024}
1025
1026TEST_F(JniInternalTest, StaticSumDoubleDoubleMethod) {
Brian Carlstroma663ea52011-08-19 23:33:41 -07001027 scoped_ptr<DexFile> dex(OpenDexFileBase64(kStaticLeafMethodsDex, "kStaticLeafMethodsDex"));
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001028
1029 PathClassLoader* class_loader = AllocPathClassLoader(dex.get());
1030 ASSERT_TRUE(class_loader != NULL);
1031
1032 Class* klass = class_linker_->FindClass("LStaticLeafMethods;", class_loader);
1033 ASSERT_TRUE(klass != NULL);
1034
1035 Method* method = klass->FindDirectMethod("sum", "(DD)D");
1036 ASSERT_TRUE(method != NULL);
1037
1038 byte sum_DDD_code[] = {
1039 0x2d, 0xe9, 0x00, 0x40, 0x87, 0xb0, 0xcd, 0xf8,
1040 0x00, 0x00, 0xcd, 0xf8, 0x24, 0x10, 0xcd, 0xf8,
1041 0x28, 0x20, 0xcd, 0xf8, 0x2c, 0x30, 0x9d, 0xed,
1042 0x09, 0x0b, 0x9d, 0xed, 0x0b, 0x1b, 0x30, 0xee,
1043 0x01, 0x2b, 0x8d, 0xed, 0x04, 0x2b, 0x04, 0x98,
1044 0x05, 0x99, 0x07, 0xb0, 0xbd, 0xe8, 0x00, 0x80,
1045 };
1046
1047 Method::InvokeStub* stub = AllocateStub(method,
1048 sum_DDD_code,
1049 sizeof(sum_DDD_code));
1050
1051 double args[2];
1052 JValue result;
1053
1054 args[0] = 0.0;
1055 args[1] = 0.0;
1056 result.d = -1.0;
1057 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
1058 EXPECT_EQ(0.0, result.d);
1059
1060 args[0] = 1.0;
1061 args[1] = 2.0;
1062 result.d = 0.0;
1063 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
1064 EXPECT_EQ(3.0, result.d);
1065
1066 args[0] = 1.0;
1067 args[1] = -2.0;
1068 result.d = 0.0;
1069 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
1070 EXPECT_EQ(-1.0, result.d);
1071
1072 args[0] = DBL_MAX;
1073 args[1] = DBL_MIN;
1074 result.d = 0.0;
1075 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
1076 EXPECT_EQ(1.7976931348623157e308, result.d);
1077
1078 args[0] = DBL_MAX;
1079 args[1] = DBL_MAX;
1080 result.d = 0.0;
1081 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
1082 EXPECT_EQ(INFINITY, result.d);
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001083}
1084
1085TEST_F(JniInternalTest, StaticSumDoubleDoubleDoubleMethod) {
Brian Carlstroma663ea52011-08-19 23:33:41 -07001086 scoped_ptr<DexFile> dex(OpenDexFileBase64(kStaticLeafMethodsDex, "kStaticLeafMethodsDex"));
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001087
1088 PathClassLoader* class_loader = AllocPathClassLoader(dex.get());
1089 ASSERT_TRUE(class_loader != NULL);
1090
1091 Class* klass = class_linker_->FindClass("LStaticLeafMethods;", class_loader);
1092 ASSERT_TRUE(klass != NULL);
1093
1094 Method* method = klass->FindDirectMethod("sum", "(DDD)D");
1095 ASSERT_TRUE(method != NULL);
1096
1097 byte sum_DDDD_code[] = {
1098 0x2d, 0xe9, 0x00, 0x40, 0x87, 0xb0, 0xcd, 0xf8,
1099 0x00, 0x00, 0xcd, 0xf8, 0x24, 0x10, 0xcd, 0xf8,
1100 0x28, 0x20, 0xcd, 0xf8, 0x2c, 0x30, 0x9d, 0xed,
1101 0x09, 0x0b, 0x9d, 0xed, 0x0b, 0x1b, 0x30, 0xee,
1102 0x01, 0x2b, 0x8d, 0xed, 0x04, 0x2b, 0x9d, 0xed,
1103 0x04, 0x3b, 0x9d, 0xed, 0x0d, 0x4b, 0x33, 0xee,
1104 0x04, 0x3b, 0x8d, 0xed, 0x04, 0x3b, 0x04, 0x98,
1105 0x05, 0x99, 0x07, 0xb0, 0xbd, 0xe8, 0x00, 0x80,
1106 };
1107
1108 Method::InvokeStub* stub = AllocateStub(method,
1109 sum_DDDD_code,
1110 sizeof(sum_DDDD_code));
1111
1112 double args[3];
1113 JValue result;
1114
1115 args[0] = 0.0;
1116 args[1] = 0.0;
1117 args[2] = 0.0;
1118 result.d = -1.0;
1119 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
1120 EXPECT_EQ(0.0, result.d);
1121
1122 args[0] = 1.0;
1123 args[1] = 2.0;
1124 args[2] = 3.0;
1125 result.d = 0.0;
1126 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
1127 EXPECT_EQ(6.0, result.d);
1128
1129 args[0] = 1.0;
1130 args[1] = -2.0;
1131 args[2] = 3.0;
1132 result.d = 0.0;
1133 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
1134 EXPECT_EQ(2.0, result.d);
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001135}
1136
1137TEST_F(JniInternalTest, StaticSumDoubleDoubleDoubleDoubleMethod) {
Brian Carlstroma663ea52011-08-19 23:33:41 -07001138 scoped_ptr<DexFile> dex(OpenDexFileBase64(kStaticLeafMethodsDex, "kStaticLeafMethodsDex"));
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001139
1140 PathClassLoader* class_loader = AllocPathClassLoader(dex.get());
1141 ASSERT_TRUE(class_loader != NULL);
1142
1143 Class* klass = class_linker_->FindClass("LStaticLeafMethods;", class_loader);
1144 ASSERT_TRUE(klass != NULL);
1145
1146 Method* method = klass->FindDirectMethod("sum", "(DDDD)D");
1147 ASSERT_TRUE(method != NULL);
1148
1149 byte sum_DDDDD_code[] = {
1150 0x2d, 0xe9, 0x00, 0x40, 0x87, 0xb0, 0xcd, 0xf8,
1151 0x00, 0x00, 0xcd, 0xf8, 0x24, 0x10, 0xcd, 0xf8,
1152 0x28, 0x20, 0xcd, 0xf8, 0x2c, 0x30, 0x9d, 0xed,
1153 0x09, 0x0b, 0x9d, 0xed, 0x0b, 0x1b, 0x30, 0xee,
1154 0x01, 0x2b, 0x8d, 0xed, 0x04, 0x2b, 0x9d, 0xed,
1155 0x04, 0x3b, 0x9d, 0xed, 0x0d, 0x4b, 0x33, 0xee,
1156 0x04, 0x3b, 0x8d, 0xed, 0x04, 0x3b, 0x9d, 0xed,
1157 0x04, 0x5b, 0x9d, 0xed, 0x0f, 0x6b, 0x35, 0xee,
1158 0x06, 0x5b, 0x8d, 0xed, 0x04, 0x5b, 0x04, 0x98,
1159 0x05, 0x99, 0x07, 0xb0, 0xbd, 0xe8, 0x00, 0x80,
1160 };
1161
1162 Method::InvokeStub* stub = AllocateStub(method,
1163 sum_DDDDD_code,
1164 sizeof(sum_DDDDD_code));
1165
1166 double args[4];
1167 JValue result;
1168
1169 args[0] = 0.0;
1170 args[1] = 0.0;
1171 args[2] = 0.0;
1172 args[3] = 0.0;
1173 result.d = -1.0;
1174 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
1175 EXPECT_EQ(0.0, result.d);
1176
1177 args[0] = 1.0;
1178 args[1] = 2.0;
1179 args[2] = 3.0;
1180 args[3] = 4.0;
1181 result.d = 0.0;
1182 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
1183 EXPECT_EQ(10.0, result.d);
1184
1185 args[0] = 1.0;
1186 args[1] = -2.0;
1187 args[2] = 3.0;
1188 args[3] = -4.0;
1189 result.d = 0.0;
1190 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
1191 EXPECT_EQ(-2.0, result.d);
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001192}
1193
1194TEST_F(JniInternalTest, StaticSumDoubleDoubleDoubleDoubleDoubleMethod) {
Brian Carlstroma663ea52011-08-19 23:33:41 -07001195 scoped_ptr<DexFile> dex(OpenDexFileBase64(kStaticLeafMethodsDex, "kStaticLeafMethodsDex"));
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001196
1197 PathClassLoader* class_loader = AllocPathClassLoader(dex.get());
1198 ASSERT_TRUE(class_loader != NULL);
1199
1200 Class* klass = class_linker_->FindClass("LStaticLeafMethods;", class_loader);
1201 ASSERT_TRUE(klass != NULL);
1202
1203 Method* method = klass->FindDirectMethod("sum", "(DDDDD)D");
1204 ASSERT_TRUE(method != NULL);
1205
1206 byte sum_DDDDDD_code[] = {
1207 0x2d, 0xe9, 0x00, 0x40, 0x87, 0xb0, 0xcd, 0xf8,
1208 0x00, 0x00, 0xcd, 0xf8, 0x24, 0x10, 0xcd, 0xf8,
1209 0x28, 0x20, 0xcd, 0xf8, 0x2c, 0x30, 0x9d, 0xed,
1210 0x09, 0x0b, 0x9d, 0xed, 0x0b, 0x1b, 0x30, 0xee,
1211 0x01, 0x2b, 0x8d, 0xed, 0x04, 0x2b, 0x9d, 0xed,
1212 0x04, 0x3b, 0x9d, 0xed, 0x0d, 0x4b, 0x33, 0xee,
1213 0x04, 0x3b, 0x8d, 0xed, 0x04, 0x3b, 0x9d, 0xed,
1214 0x04, 0x5b, 0x9d, 0xed, 0x0f, 0x6b, 0x35, 0xee,
1215 0x06, 0x5b, 0x8d, 0xed, 0x04, 0x5b, 0x9d, 0xed,
1216 0x04, 0x7b, 0x9d, 0xed, 0x11, 0x0b, 0x37, 0xee,
1217 0x00, 0x7b, 0x8d, 0xed, 0x04, 0x7b, 0x04, 0x98,
1218 0x05, 0x99, 0x07, 0xb0, 0xbd, 0xe8, 0x00, 0x80,
1219 };
1220
1221 Method::InvokeStub* stub = AllocateStub(method,
1222 sum_DDDDDD_code,
1223 sizeof(sum_DDDDDD_code));
1224
1225 double args[5];
1226 JValue result;
1227
1228 args[0] = 0.0;
1229 args[1] = 0.0;
1230 args[2] = 0.0;
1231 args[3] = 0.0;
1232 args[4] = 0.0;
1233 result.d = -1.0;
1234 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
1235 EXPECT_EQ(0.0, result.d);
1236
1237 args[0] = 1.0;
1238 args[1] = 2.0;
1239 args[2] = 3.0;
1240 args[3] = 4.0;
1241 args[4] = 5.0;
1242 result.d = 0.0;
1243 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
1244 EXPECT_EQ(15.0, result.d);
1245
1246 args[0] = 1.0;
1247 args[1] = -2.0;
1248 args[2] = 3.0;
1249 args[3] = -4.0;
1250 args[4] = 5.0;
1251 result.d = 0.0;
1252 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
1253 EXPECT_EQ(3.0, result.d);
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001254}
1255#endif // __arm__
1256
1257}