blob: f2051697768df1394e9354697c1c443c2cf3e840 [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 Hughes37f7a402011-08-22 18:56:01 -0700321TEST_F(JniInternalTest, GetObjectClass) {
322 jclass string_class = env_->FindClass("java/lang/String");
323 ASSERT_TRUE(string_class != NULL);
324 jclass class_class = env_->FindClass("java/lang/Class");
325 ASSERT_TRUE(class_class != NULL);
326
327 jstring s = env_->NewStringUTF("poop");
328 jclass c = env_->GetObjectClass(s);
329 ASSERT_TRUE(env_->IsSameObject(string_class, c));
330
331 jclass c2 = env_->GetObjectClass(c);
332 ASSERT_TRUE(env_->IsSameObject(class_class, env_->GetObjectClass(c2)));
333}
334
Elliott Hughes885c3bd2011-08-22 16:59:20 -0700335TEST_F(JniInternalTest, GetSuperclass) {
336 jclass object_class = env_->FindClass("java/lang/Object");
337 ASSERT_TRUE(object_class != NULL);
338 jclass string_class = env_->FindClass("java/lang/String");
339 ASSERT_TRUE(string_class != NULL);
340 ASSERT_TRUE(env_->IsSameObject(object_class, env_->GetSuperclass(string_class)));
341 ASSERT_TRUE(env_->GetSuperclass(object_class) == NULL);
342}
343
Elliott Hughes37f7a402011-08-22 18:56:01 -0700344TEST_F(JniInternalTest, IsAssignableFrom) {
345 jclass object_class = env_->FindClass("java/lang/Object");
346 ASSERT_TRUE(object_class != NULL);
347 jclass string_class = env_->FindClass("java/lang/String");
348 ASSERT_TRUE(string_class != NULL);
349
350 ASSERT_TRUE(env_->IsAssignableFrom(object_class, string_class));
351 ASSERT_FALSE(env_->IsAssignableFrom(string_class, object_class));
352}
353
Elliott Hughes8a26c5c2011-08-15 18:35:43 -0700354TEST_F(JniInternalTest, NewStringUTF) {
355 EXPECT_TRUE(env_->NewStringUTF(NULL) == NULL);
356 EXPECT_TRUE(env_->NewStringUTF("") != NULL);
357 EXPECT_TRUE(env_->NewStringUTF("hello") != NULL);
358 // TODO: check some non-ASCII strings.
Elliott Hughesf2682d52011-08-15 16:37:04 -0700359}
360
Elliott Hughes289da822011-08-16 10:11:20 -0700361TEST_F(JniInternalTest, SetObjectArrayElement) {
Elliott Hughescdf53122011-08-19 15:46:09 -0700362 jclass aioobe = env_->FindClass("java/lang/ArrayIndexOutOfBoundsException");
Elliott Hughes289da822011-08-16 10:11:20 -0700363 jclass c = env_->FindClass("[Ljava/lang/Object;");
364 ASSERT_TRUE(c != NULL);
365
366 jobjectArray array = env_->NewObjectArray(1, c, NULL);
367 EXPECT_TRUE(array != NULL);
368 env_->SetObjectArrayElement(array, 0, c);
369 // TODO: check reading value back
Elliott Hughesa5b897e2011-08-16 11:33:06 -0700370
371 // ArrayIndexOutOfBounds for negative index.
Elliott Hughesa5b897e2011-08-16 11:33:06 -0700372 env_->SetObjectArrayElement(array, -1, c);
Elliott Hughescdf53122011-08-19 15:46:09 -0700373 EXPECT_EXCEPTION(aioobe);
Elliott Hughesa5b897e2011-08-16 11:33:06 -0700374
375 // ArrayIndexOutOfBounds for too-large index.
Elliott Hughesa5b897e2011-08-16 11:33:06 -0700376 env_->SetObjectArrayElement(array, 1, c);
Elliott Hughescdf53122011-08-19 15:46:09 -0700377 EXPECT_EXCEPTION(aioobe);
Elliott Hughesa5b897e2011-08-16 11:33:06 -0700378
Elliott Hughes289da822011-08-16 10:11:20 -0700379 // TODO: check ArrayStoreException thrown for bad types.
380}
381
Elliott Hughes885c3bd2011-08-22 16:59:20 -0700382#define EXPECT_STATIC_PRIMITIVE_FIELD(type, field_name, sig, value1, value2) \
383 do { \
384 jfieldID fid = env_->GetStaticFieldID(c, field_name, sig); \
385 EXPECT_TRUE(fid != NULL); \
386 env_->SetStatic ## type ## Field(c, fid, value1); \
387 EXPECT_EQ(value1, env_->GetStatic ## type ## Field(c, fid)); \
388 env_->SetStatic ## type ## Field(c, fid, value2); \
389 EXPECT_EQ(value2, env_->GetStatic ## type ## Field(c, fid)); \
390 } while (false)
391
392#define EXPECT_PRIMITIVE_FIELD(instance, type, field_name, sig, value1, value2) \
393 do { \
394 jfieldID fid = env_->GetFieldID(c, field_name, sig); \
395 EXPECT_TRUE(fid != NULL); \
396 env_->Set ## type ## Field(instance, fid, value1); \
397 EXPECT_EQ(value1, env_->Get ## type ## Field(instance, fid)); \
398 env_->Set ## type ## Field(instance, fid, value2); \
399 EXPECT_EQ(value2, env_->Get ## type ## Field(instance, fid)); \
400 } while (false)
401
402
403TEST_F(JniInternalTest, GetPrimitiveField_SetPrimitiveField) {
404 scoped_ptr<DexFile> dex(OpenDexFileBase64(kAllFields, "kAllFields"));
405 PathClassLoader* class_loader = AllocPathClassLoader(dex.get());
406 Thread::Current()->SetClassLoaderOverride(class_loader);
407
408 jclass c = env_->FindClass("AllFields");
409 ASSERT_TRUE(c != NULL);
410 jobject o = env_->AllocObject(c);
411 ASSERT_TRUE(o != NULL);
412
413 EXPECT_STATIC_PRIMITIVE_FIELD(Boolean, "sZ", "Z", true, false);
414 EXPECT_STATIC_PRIMITIVE_FIELD(Byte, "sB", "B", 1, 2);
415 EXPECT_STATIC_PRIMITIVE_FIELD(Char, "sC", "C", 'a', 'b');
416 EXPECT_STATIC_PRIMITIVE_FIELD(Double, "sD", "D", 1.0, 2.0);
417 EXPECT_STATIC_PRIMITIVE_FIELD(Float, "sF", "F", 1.0, 2.0);
418 EXPECT_STATIC_PRIMITIVE_FIELD(Int, "sI", "I", 1, 2);
419 EXPECT_STATIC_PRIMITIVE_FIELD(Long, "sJ", "J", 1, 2);
420 EXPECT_STATIC_PRIMITIVE_FIELD(Short, "sS", "S", 1, 2);
421
422 EXPECT_PRIMITIVE_FIELD(o, Boolean, "iZ", "Z", true, false);
423 EXPECT_PRIMITIVE_FIELD(o, Byte, "iB", "B", 1, 2);
424 EXPECT_PRIMITIVE_FIELD(o, Char, "iC", "C", 'a', 'b');
425 EXPECT_PRIMITIVE_FIELD(o, Double, "iD", "D", 1.0, 2.0);
426 EXPECT_PRIMITIVE_FIELD(o, Float, "iF", "F", 1.0, 2.0);
427 EXPECT_PRIMITIVE_FIELD(o, Int, "iI", "I", 1, 2);
428 EXPECT_PRIMITIVE_FIELD(o, Long, "iJ", "J", 1, 2);
429 EXPECT_PRIMITIVE_FIELD(o, Short, "iS", "S", 1, 2);
430}
431
432TEST_F(JniInternalTest, GetObjectField_SetObjectField) {
433 scoped_ptr<DexFile> dex(OpenDexFileBase64(kAllFields, "kAllFields"));
434 PathClassLoader* class_loader = AllocPathClassLoader(dex.get());
435 Thread::Current()->SetClassLoaderOverride(class_loader);
436
437 jclass c = env_->FindClass("AllFields");
438 ASSERT_TRUE(c != NULL);
439 jobject o = env_->AllocObject(c);
440 ASSERT_TRUE(o != NULL);
441
442 jstring s1 = env_->NewStringUTF("hello");
443 ASSERT_TRUE(s1 != NULL);
444 jstring s2 = env_->NewStringUTF("world");
445 ASSERT_TRUE(s2 != NULL);
446
447 jfieldID s_fid = env_->GetStaticFieldID(c, "sObject", "Ljava/lang/Object;");
448 ASSERT_TRUE(s_fid != NULL);
449 jfieldID i_fid = env_->GetFieldID(c, "iObject", "Ljava/lang/Object;");
450 ASSERT_TRUE(i_fid != NULL);
451
452 env_->SetStaticObjectField(c, s_fid, s1);
453 ASSERT_TRUE(env_->IsSameObject(s1, env_->GetStaticObjectField(c, s_fid)));
454 env_->SetStaticObjectField(c, s_fid, s2);
455 ASSERT_TRUE(env_->IsSameObject(s2, env_->GetStaticObjectField(c, s_fid)));
456
457 env_->SetObjectField(o, i_fid, s1);
458 ASSERT_TRUE(env_->IsSameObject(s1, env_->GetObjectField(o, i_fid)));
459 env_->SetObjectField(o, i_fid, s2);
460 ASSERT_TRUE(env_->IsSameObject(s2, env_->GetObjectField(o, i_fid)));
461}
462
Elliott Hughes18c07532011-08-18 15:50:51 -0700463TEST_F(JniInternalTest, NewLocalRef_NULL) {
464 EXPECT_TRUE(env_->NewLocalRef(NULL) == NULL);
465}
466
467TEST_F(JniInternalTest, NewLocalRef) {
468 jstring s = env_->NewStringUTF("");
469 ASSERT_TRUE(s != NULL);
470 jobject o = env_->NewLocalRef(s);
471 EXPECT_TRUE(o != NULL);
472 EXPECT_TRUE(o != s);
473
474 // TODO: check that o is a local reference.
475}
476
477TEST_F(JniInternalTest, DeleteLocalRef_NULL) {
478 env_->DeleteLocalRef(NULL);
479}
480
481TEST_F(JniInternalTest, DeleteLocalRef) {
482 jstring s = env_->NewStringUTF("");
483 ASSERT_TRUE(s != NULL);
484 env_->DeleteLocalRef(s);
485
486 // Currently, deleting an already-deleted reference is just a warning.
487 env_->DeleteLocalRef(s);
488
489 s = env_->NewStringUTF("");
490 ASSERT_TRUE(s != NULL);
491 jobject o = env_->NewLocalRef(s);
492 ASSERT_TRUE(o != NULL);
493
494 env_->DeleteLocalRef(s);
495 env_->DeleteLocalRef(o);
496}
497
498TEST_F(JniInternalTest, NewGlobalRef_NULL) {
499 EXPECT_TRUE(env_->NewGlobalRef(NULL) == NULL);
500}
501
502TEST_F(JniInternalTest, NewGlobalRef) {
503 jstring s = env_->NewStringUTF("");
504 ASSERT_TRUE(s != NULL);
505 jobject o = env_->NewGlobalRef(s);
506 EXPECT_TRUE(o != NULL);
507 EXPECT_TRUE(o != s);
508
509 // TODO: check that o is a global reference.
510}
511
512TEST_F(JniInternalTest, DeleteGlobalRef_NULL) {
513 env_->DeleteGlobalRef(NULL);
514}
515
516TEST_F(JniInternalTest, DeleteGlobalRef) {
517 jstring s = env_->NewStringUTF("");
518 ASSERT_TRUE(s != NULL);
519
520 jobject o = env_->NewGlobalRef(s);
521 ASSERT_TRUE(o != NULL);
522 env_->DeleteGlobalRef(o);
523
524 // Currently, deleting an already-deleted reference is just a warning.
525 env_->DeleteGlobalRef(o);
526
527 jobject o1 = env_->NewGlobalRef(s);
528 ASSERT_TRUE(o1 != NULL);
529 jobject o2 = env_->NewGlobalRef(s);
530 ASSERT_TRUE(o2 != NULL);
531
532 env_->DeleteGlobalRef(o1);
533 env_->DeleteGlobalRef(o2);
534}
535
536TEST_F(JniInternalTest, NewWeakGlobalRef_NULL) {
537 EXPECT_TRUE(env_->NewWeakGlobalRef(NULL) == NULL);
538}
539
540TEST_F(JniInternalTest, NewWeakGlobalRef) {
541 jstring s = env_->NewStringUTF("");
542 ASSERT_TRUE(s != NULL);
543 jobject o = env_->NewWeakGlobalRef(s);
544 EXPECT_TRUE(o != NULL);
545 EXPECT_TRUE(o != s);
546
547 // TODO: check that o is a weak global reference.
548}
549
550TEST_F(JniInternalTest, DeleteWeakGlobalRef_NULL) {
551 env_->DeleteWeakGlobalRef(NULL);
552}
553
554TEST_F(JniInternalTest, DeleteWeakGlobalRef) {
555 jstring s = env_->NewStringUTF("");
556 ASSERT_TRUE(s != NULL);
557
558 jobject o = env_->NewWeakGlobalRef(s);
559 ASSERT_TRUE(o != NULL);
560 env_->DeleteWeakGlobalRef(o);
561
562 // Currently, deleting an already-deleted reference is just a warning.
563 env_->DeleteWeakGlobalRef(o);
564
565 jobject o1 = env_->NewWeakGlobalRef(s);
566 ASSERT_TRUE(o1 != NULL);
567 jobject o2 = env_->NewWeakGlobalRef(s);
568 ASSERT_TRUE(o2 != NULL);
569
570 env_->DeleteWeakGlobalRef(o1);
571 env_->DeleteWeakGlobalRef(o2);
572}
573
Carl Shapiro9b9ba282011-08-14 15:30:39 -0700574bool EnsureInvokeStub(Method* method);
575
Carl Shapiro9b9ba282011-08-14 15:30:39 -0700576Method::InvokeStub* AllocateStub(Method* method,
577 byte* code,
578 size_t length) {
579 CHECK(method->GetInvokeStub() == NULL);
580 EnsureInvokeStub(method);
581 Method::InvokeStub* stub = method->GetInvokeStub();
582 CHECK(stub != NULL);
buzbeec143c552011-08-20 17:38:58 -0700583 method->SetCode(code, length, kThumb2);
Carl Shapiro9b9ba282011-08-14 15:30:39 -0700584 return stub;
585}
586
Carl Shapiro9b9ba282011-08-14 15:30:39 -0700587#if defined(__arm__)
588TEST_F(JniInternalTest, StaticMainMethod) {
Brian Carlstroma663ea52011-08-19 23:33:41 -0700589 scoped_ptr<DexFile> dex(OpenDexFileBase64(kMainDex, "kMainDex"));
Carl Shapiro9b9ba282011-08-14 15:30:39 -0700590
591 PathClassLoader* class_loader = AllocPathClassLoader(dex.get());
592 ASSERT_TRUE(class_loader != NULL);
593
594 Class* klass = class_linker_->FindClass("LMain;", class_loader);
595 ASSERT_TRUE(klass != NULL);
596
597 Method* method = klass->FindDirectMethod("main", "([Ljava/lang/String;)V");
598 ASSERT_TRUE(method != NULL);
599
600 byte main_LV_code[] = {
601 0x2d, 0xe9, 0x00, 0x40, 0x83, 0xb0, 0xcd, 0xf8, 0x00, 0x00,
602 0xcd, 0xf8, 0x14, 0x10, 0x03, 0xb0, 0xbd, 0xe8, 0x00, 0x80,
603 };
604
605 Method::InvokeStub* stub = AllocateStub(method,
606 main_LV_code,
607 sizeof(main_LV_code));
608
609 Object* arg = NULL;
610
611 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(&arg), NULL);
Carl Shapiro9b9ba282011-08-14 15:30:39 -0700612}
613
614TEST_F(JniInternalTest, StaticNopMethod) {
Brian Carlstroma663ea52011-08-19 23:33:41 -0700615 scoped_ptr<DexFile> dex(OpenDexFileBase64(kStaticLeafMethodsDex, "kStaticLeafMethodsDex"));
Carl Shapiro9b9ba282011-08-14 15:30:39 -0700616
617 PathClassLoader* class_loader = AllocPathClassLoader(dex.get());
618 ASSERT_TRUE(class_loader != NULL);
619
620 Class* klass = class_linker_->FindClass("LStaticLeafMethods;", class_loader);
621 ASSERT_TRUE(klass != NULL);
622
623 Method* method = klass->FindDirectMethod("nop", "()V");
624 ASSERT_TRUE(method != NULL);
625
626 byte nop_V_code[] = {
627 0x2d, 0xe9, 0x00, 0x40, 0x83, 0xb0, 0xcd, 0xf8,
628 0x00, 0x00, 0x03, 0xb0, 0xbd, 0xe8, 0x00, 0x80,
629 };
630
631 Method::InvokeStub* stub = AllocateStub(method,
632 nop_V_code,
633 sizeof(nop_V_code));
634 ASSERT_TRUE(stub);
635
636 (*stub)(method, NULL, NULL, NULL, NULL);
Carl Shapiro9b9ba282011-08-14 15:30:39 -0700637}
638
639TEST_F(JniInternalTest, StaticIdentityByteMethod) {
Brian Carlstroma663ea52011-08-19 23:33:41 -0700640 scoped_ptr<DexFile> dex(OpenDexFileBase64(kStaticLeafMethodsDex, "kStaticLeafMethodsDex"));
Carl Shapiro9b9ba282011-08-14 15:30:39 -0700641
642 PathClassLoader* class_loader = AllocPathClassLoader(dex.get());
643 ASSERT_TRUE(class_loader != NULL);
644
645 Class* klass = class_linker_->FindClass("LStaticLeafMethods;", class_loader);
646 ASSERT_TRUE(klass != NULL);
647
648 Method* method = klass->FindDirectMethod("identity", "(B)B");
649 ASSERT_TRUE(method != NULL);
650
651 byte identity_BB_code[] = {
652 0x2d, 0xe9, 0x00, 0x40, 0x83, 0xb0, 0xcd, 0xf8,
653 0x00, 0x00, 0xcd, 0xf8, 0x14, 0x10, 0x05, 0x98,
654 0x03, 0xb0, 0xbd, 0xe8, 0x00, 0x80, 0x00, 0x00,
655 };
656
657 Method::InvokeStub* stub = AllocateStub(method,
658 identity_BB_code,
659 sizeof(identity_BB_code));
660
661 int arg;
662 JValue result;
663
664 arg = 0;
665 result.b = -1;
666 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(&arg), &result);
667 EXPECT_EQ(0, result.b);
668
669 arg = -1;
670 result.b = 0;
671 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(&arg), &result);
672 EXPECT_EQ(-1, result.b);
673
674 arg = SCHAR_MAX;
675 result.b = 0;
676 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(&arg), &result);
677 EXPECT_EQ(SCHAR_MAX, result.b);
678
679 arg = SCHAR_MIN;
680 result.b = 0;
681 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(&arg), &result);
682 EXPECT_EQ(SCHAR_MIN, result.b);
Carl Shapiro9b9ba282011-08-14 15:30:39 -0700683}
684
685TEST_F(JniInternalTest, StaticIdentityIntMethod) {
Brian Carlstroma663ea52011-08-19 23:33:41 -0700686 scoped_ptr<DexFile> dex(OpenDexFileBase64(kStaticLeafMethodsDex, "kStaticLeafMethodsDex"));
Carl Shapiro9b9ba282011-08-14 15:30:39 -0700687
688 PathClassLoader* class_loader = AllocPathClassLoader(dex.get());
689 ASSERT_TRUE(class_loader != NULL);
690
691 Class* klass = class_linker_->FindClass("LStaticLeafMethods;", class_loader);
692 ASSERT_TRUE(klass != NULL);
693
694 Method* method = klass->FindDirectMethod("identity", "(I)I");
695 ASSERT_TRUE(method != NULL);
696
697 byte identity_II_code[] = {
698 0x2d, 0xe9, 0x00, 0x40, 0x83, 0xb0, 0xcd, 0xf8,
699 0x00, 0x00, 0xcd, 0xf8, 0x14, 0x10, 0x05, 0x98,
700 0x03, 0xb0, 0xbd, 0xe8, 0x00, 0x80, 0x00, 0x00,
701 };
702
703 Method::InvokeStub* stub = AllocateStub(method,
704 identity_II_code,
705 sizeof(identity_II_code));
706
707 int arg;
708 JValue result;
709
710 arg = 0;
711 result.i = -1;
712 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(&arg), &result);
713 EXPECT_EQ(0, result.i);
714
715 arg = -1;
716 result.i = 0;
717 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(&arg), &result);
718 EXPECT_EQ(-1, result.i);
719
720 arg = INT_MAX;
721 result.i = 0;
722 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(&arg), &result);
723 EXPECT_EQ(INT_MAX, result.i);
724
725 arg = INT_MIN;
726 result.i = 0;
727 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(&arg), &result);
728 EXPECT_EQ(INT_MIN, result.i);
Carl Shapiro9b9ba282011-08-14 15:30:39 -0700729}
730
731TEST_F(JniInternalTest, StaticIdentityDoubleMethod) {
Brian Carlstroma663ea52011-08-19 23:33:41 -0700732 scoped_ptr<DexFile> dex(OpenDexFileBase64(kStaticLeafMethodsDex, "kStaticLeafMethodsDex"));
Carl Shapiro9b9ba282011-08-14 15:30:39 -0700733
734 PathClassLoader* class_loader = AllocPathClassLoader(dex.get());
735 ASSERT_TRUE(class_loader != NULL);
736
737 Class* klass = class_linker_->FindClass("LStaticLeafMethods;", class_loader);
738 ASSERT_TRUE(klass != NULL);
739
740 Method* method = klass->FindDirectMethod("identity", "(D)D");
741 ASSERT_TRUE(method != NULL);
742
743 byte identity_DD_code[] = {
744 0x2d, 0xe9, 0x00, 0x40, 0x83, 0xb0, 0xcd, 0xf8,
745 0x00, 0x00, 0xcd, 0xf8, 0x14, 0x10, 0xcd, 0xf8,
746 0x18, 0x20, 0x05, 0x98, 0x06, 0x99, 0x03, 0xb0,
747 0xbd, 0xe8, 0x00, 0x80,
748 };
749
750 Method::InvokeStub* stub = AllocateStub(method,
751 identity_DD_code,
752 sizeof(identity_DD_code));
753
754 double arg;
755 JValue result;
756
757 arg = 0.0;
758 result.d = -1.0;
759 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(&arg), &result);
760 EXPECT_EQ(0.0, result.d);
761
762 arg = -1.0;
763 result.d = 0.0;
764 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(&arg), &result);
765 EXPECT_EQ(-1.0, result.d);
766
767 arg = DBL_MAX;
768 result.d = 0.0;
769 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(&arg), &result);
770 EXPECT_EQ(DBL_MAX, result.d);
771
772 arg = DBL_MIN;
773 result.d = 0.0;
774 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(&arg), &result);
775 EXPECT_EQ(DBL_MIN, result.d);
Carl Shapiro9b9ba282011-08-14 15:30:39 -0700776}
777
778TEST_F(JniInternalTest, StaticSumIntIntMethod) {
Brian Carlstroma663ea52011-08-19 23:33:41 -0700779 scoped_ptr<DexFile> dex(OpenDexFileBase64(kStaticLeafMethodsDex, "kStaticLeafMethodsDex"));
Carl Shapiro9b9ba282011-08-14 15:30:39 -0700780
781 PathClassLoader* class_loader = AllocPathClassLoader(dex.get());
782 ASSERT_TRUE(class_loader != NULL);
783
784 Class* klass = class_linker_->FindClass("LStaticLeafMethods;", class_loader);
785 ASSERT_TRUE(klass != NULL);
786
787 Method* method = klass->FindDirectMethod("sum", "(II)I");
788 ASSERT_TRUE(method != NULL);
789
790 byte sum_III_code[] = {
791 0x2d, 0xe9, 0x00, 0x40, 0x83, 0xb0, 0xcd, 0xf8,
792 0x00, 0x00, 0xcd, 0xf8, 0x14, 0x10, 0xcd, 0xf8,
793 0x18, 0x20, 0x05, 0x98, 0x06, 0x99, 0x42, 0x18,
794 0xcd, 0xf8, 0x04, 0x20, 0x01, 0x98, 0x03, 0xb0,
795 0xbd, 0xe8, 0x00, 0x80,
796 };
797
798 Method::InvokeStub* stub = AllocateStub(method,
799 sum_III_code,
800 sizeof(sum_III_code));
801
802 int args[2];
803 JValue result;
804
805 args[0] = 0;
806 args[1] = 0;
807 result.i = -1;
808 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
809 EXPECT_EQ(0, result.i);
810
811 args[0] = 1;
812 args[1] = 2;
813 result.i = 0;
814 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
815 EXPECT_EQ(3, result.i);
816
817 args[0] = -2;
818 args[1] = 5;
819 result.i = 0;
820 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
821 EXPECT_EQ(3, result.i);
822
823 args[0] = INT_MAX;
824 args[1] = INT_MIN;
825 result.i = 1234;
826 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
827 EXPECT_EQ(-1, result.i);
828
829 args[0] = INT_MAX;
830 args[1] = INT_MAX;
831 result.i = INT_MIN;
832 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
833 EXPECT_EQ(-2, result.i);
Carl Shapiro9b9ba282011-08-14 15:30:39 -0700834}
835
836TEST_F(JniInternalTest, StaticSumIntIntIntMethod) {
Brian Carlstroma663ea52011-08-19 23:33:41 -0700837 scoped_ptr<DexFile> dex(OpenDexFileBase64(kStaticLeafMethodsDex, "kStaticLeafMethodsDex"));
Carl Shapiro9b9ba282011-08-14 15:30:39 -0700838
839 PathClassLoader* class_loader = AllocPathClassLoader(dex.get());
840 ASSERT_TRUE(class_loader != NULL);
841
842 Class* klass = class_linker_->FindClass("LStaticLeafMethods;", class_loader);
843 ASSERT_TRUE(klass != NULL);
844
845 Method* method = klass->FindDirectMethod("sum", "(III)I");
846 ASSERT_TRUE(method != NULL);
847
848 byte sum_IIII_code[] = {
849 0x2d, 0xe9, 0x00, 0x40, 0x83, 0xb0, 0xcd, 0xf8,
850 0x00, 0x00, 0xcd, 0xf8, 0x14, 0x10, 0xcd, 0xf8,
851 0x18, 0x20, 0xcd, 0xf8, 0x1c, 0x30, 0x05, 0x98,
852 0x06, 0x99, 0x42, 0x18, 0xcd, 0xf8, 0x04, 0x20,
853 0x01, 0x9b, 0xdd, 0xf8, 0x1c, 0xc0, 0x13, 0xeb,
854 0x0c, 0x03, 0xcd, 0xf8, 0x04, 0x30, 0x01, 0x98,
855 0x03, 0xb0, 0xbd, 0xe8, 0x00, 0x80, 0x00, 0x00,
856 };
857
858 Method::InvokeStub* stub = AllocateStub(method,
859 sum_IIII_code,
860 sizeof(sum_IIII_code));
861
862 int args[3];
863 JValue result;
864
865 args[0] = 0;
866 args[1] = 0;
867 args[2] = 0;
868 result.i = -1;
869 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
870 EXPECT_EQ(0, result.i);
871
872 args[0] = 1;
873 args[1] = 2;
874 args[2] = 3;
875 result.i = 0;
876 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
877 EXPECT_EQ(6, result.i);
878
879 args[0] = -1;
880 args[1] = 2;
881 args[2] = -3;
882 result.i = 0;
883 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
884 EXPECT_EQ(-2, result.i);
885
886 args[0] = INT_MAX;
887 args[1] = INT_MIN;
888 args[2] = INT_MAX;
889 result.i = 1234;
890 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
891 EXPECT_EQ(2147483646, result.i);
892
893 args[0] = INT_MAX;
894 args[1] = INT_MAX;
895 args[2] = INT_MAX;
896 result.i = INT_MIN;
897 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
898 EXPECT_EQ(2147483645, result.i);
Carl Shapiro9b9ba282011-08-14 15:30:39 -0700899}
900
901TEST_F(JniInternalTest, StaticSumIntIntIntIntMethod) {
Brian Carlstroma663ea52011-08-19 23:33:41 -0700902 scoped_ptr<DexFile> dex(OpenDexFileBase64(kStaticLeafMethodsDex, "kStaticLeafMethodsDex"));
Carl Shapiro9b9ba282011-08-14 15:30:39 -0700903
904 PathClassLoader* class_loader = AllocPathClassLoader(dex.get());
905 ASSERT_TRUE(class_loader != NULL);
906
907 Class* klass = class_linker_->FindClass("LStaticLeafMethods;", class_loader);
908 ASSERT_TRUE(klass != NULL);
909
910 Method* method = klass->FindDirectMethod("sum", "(IIII)I");
911 ASSERT_TRUE(method != NULL);
912
913 byte sum_IIIII_code[] = {
914 0x2d, 0xe9, 0x00, 0x40, 0x83, 0xb0, 0xcd, 0xf8,
915 0x00, 0x00, 0xcd, 0xf8, 0x14, 0x10, 0xcd, 0xf8,
916 0x18, 0x20, 0xcd, 0xf8, 0x1c, 0x30, 0x05, 0x98,
917 0x06, 0x99, 0x42, 0x18, 0xcd, 0xf8, 0x04, 0x20,
918 0x01, 0x9b, 0xdd, 0xf8, 0x1c, 0xc0, 0x13, 0xeb,
919 0x0c, 0x03, 0xcd, 0xf8, 0x04, 0x30, 0x01, 0x98,
920 0x08, 0x99, 0x40, 0x18, 0xcd, 0xf8, 0x04, 0x00,
921 0x01, 0x98, 0x03, 0xb0, 0xbd, 0xe8, 0x00, 0x80,
922 };
923
924 Method::InvokeStub* stub = AllocateStub(method,
925 sum_IIIII_code,
926 sizeof(sum_IIIII_code));
927
928 int args[4];
929 JValue result;
930
931 args[0] = 0;
932 args[1] = 0;
933 args[2] = 0;
934 args[3] = 0;
935 result.i = -1;
936 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
937 EXPECT_EQ(0, result.i);
938
939 args[0] = 1;
940 args[1] = 2;
941 args[2] = 3;
942 args[3] = 4;
943 result.i = 0;
944 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
945 EXPECT_EQ(10, result.i);
946
947 args[0] = -1;
948 args[1] = 2;
949 args[2] = -3;
950 args[3] = 4;
951 result.i = 0;
952 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
953 EXPECT_EQ(2, result.i);
954
955 args[0] = INT_MAX;
956 args[1] = INT_MIN;
957 args[2] = INT_MAX;
958 args[3] = INT_MIN;
959 result.i = 1234;
960 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
961 EXPECT_EQ(-2, result.i);
962
963 args[0] = INT_MAX;
964 args[1] = INT_MAX;
965 args[2] = INT_MAX;
966 args[3] = INT_MAX;
967 result.i = INT_MIN;
968 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
969 EXPECT_EQ(-4, result.i);
Carl Shapiro9b9ba282011-08-14 15:30:39 -0700970}
971
972TEST_F(JniInternalTest, StaticSumIntIntIntIntIntMethod) {
Brian Carlstroma663ea52011-08-19 23:33:41 -0700973 scoped_ptr<DexFile> dex(OpenDexFileBase64(kStaticLeafMethodsDex, "kStaticLeafMethodsDex"));
Carl Shapiro9b9ba282011-08-14 15:30:39 -0700974
975 PathClassLoader* class_loader = AllocPathClassLoader(dex.get());
976 ASSERT_TRUE(class_loader != NULL);
977
978 Class* klass = class_linker_->FindClass("LStaticLeafMethods;", class_loader);
979 ASSERT_TRUE(klass != NULL);
980
981 Method* method = klass->FindDirectMethod("sum", "(IIIII)I");
982 ASSERT_TRUE(method != NULL);
983
984 byte sum_IIIIII_code[] = {
985 0x2d, 0xe9, 0x00, 0x40, 0x83, 0xb0, 0xcd, 0xf8,
986 0x00, 0x00, 0xcd, 0xf8, 0x14, 0x10, 0xcd, 0xf8,
987 0x18, 0x20, 0xcd, 0xf8, 0x1c, 0x30, 0x05, 0x98,
988 0x06, 0x99, 0x42, 0x18, 0xcd, 0xf8, 0x04, 0x20,
989 0x01, 0x9b, 0xdd, 0xf8, 0x1c, 0xc0, 0x13, 0xeb,
990 0x0c, 0x03, 0xcd, 0xf8, 0x04, 0x30, 0x01, 0x98,
991 0x08, 0x99, 0x40, 0x18, 0xcd, 0xf8, 0x04, 0x00,
992 0x01, 0x9a, 0x09, 0x9b, 0xd2, 0x18, 0xcd, 0xf8,
993 0x04, 0x20, 0x01, 0x98, 0x03, 0xb0, 0xbd, 0xe8,
994 0x00, 0x80, 0x00, 0x00,
995 };
996
997 Method::InvokeStub* stub = AllocateStub(method,
998 sum_IIIIII_code,
999 sizeof(sum_IIIIII_code));
1000
1001 int args[5];
1002 JValue result;
1003
1004 args[0] = 0;
1005 args[1] = 0;
1006 args[2] = 0;
1007 args[3] = 0;
1008 args[4] = 0;
1009 result.i = -1.0;
1010 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
1011 EXPECT_EQ(0, result.i);
1012
1013 args[0] = 1;
1014 args[1] = 2;
1015 args[2] = 3;
1016 args[3] = 4;
1017 args[4] = 5;
1018 result.i = 0;
1019 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
1020 EXPECT_EQ(15, result.i);
1021
1022 args[0] = -1;
1023 args[1] = 2;
1024 args[2] = -3;
1025 args[3] = 4;
1026 args[4] = -5;
1027 result.i = 0;
1028 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
1029 EXPECT_EQ(-3, result.i);
1030
1031 args[0] = INT_MAX;
1032 args[1] = INT_MIN;
1033 args[2] = INT_MAX;
1034 args[3] = INT_MIN;
1035 args[4] = INT_MAX;
1036 result.i = 1234;
1037 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
1038 EXPECT_EQ(2147483645, result.i);
1039
1040 args[0] = INT_MAX;
1041 args[1] = INT_MAX;
1042 args[2] = INT_MAX;
1043 args[3] = INT_MAX;
1044 args[4] = INT_MAX;
1045 result.i = INT_MIN;
1046 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
1047 EXPECT_EQ(2147483643, result.i);
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001048}
1049
1050TEST_F(JniInternalTest, StaticSumDoubleDoubleMethod) {
Brian Carlstroma663ea52011-08-19 23:33:41 -07001051 scoped_ptr<DexFile> dex(OpenDexFileBase64(kStaticLeafMethodsDex, "kStaticLeafMethodsDex"));
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001052
1053 PathClassLoader* class_loader = AllocPathClassLoader(dex.get());
1054 ASSERT_TRUE(class_loader != NULL);
1055
1056 Class* klass = class_linker_->FindClass("LStaticLeafMethods;", class_loader);
1057 ASSERT_TRUE(klass != NULL);
1058
1059 Method* method = klass->FindDirectMethod("sum", "(DD)D");
1060 ASSERT_TRUE(method != NULL);
1061
1062 byte sum_DDD_code[] = {
1063 0x2d, 0xe9, 0x00, 0x40, 0x87, 0xb0, 0xcd, 0xf8,
1064 0x00, 0x00, 0xcd, 0xf8, 0x24, 0x10, 0xcd, 0xf8,
1065 0x28, 0x20, 0xcd, 0xf8, 0x2c, 0x30, 0x9d, 0xed,
1066 0x09, 0x0b, 0x9d, 0xed, 0x0b, 0x1b, 0x30, 0xee,
1067 0x01, 0x2b, 0x8d, 0xed, 0x04, 0x2b, 0x04, 0x98,
1068 0x05, 0x99, 0x07, 0xb0, 0xbd, 0xe8, 0x00, 0x80,
1069 };
1070
1071 Method::InvokeStub* stub = AllocateStub(method,
1072 sum_DDD_code,
1073 sizeof(sum_DDD_code));
1074
1075 double args[2];
1076 JValue result;
1077
1078 args[0] = 0.0;
1079 args[1] = 0.0;
1080 result.d = -1.0;
1081 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
1082 EXPECT_EQ(0.0, result.d);
1083
1084 args[0] = 1.0;
1085 args[1] = 2.0;
1086 result.d = 0.0;
1087 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
1088 EXPECT_EQ(3.0, result.d);
1089
1090 args[0] = 1.0;
1091 args[1] = -2.0;
1092 result.d = 0.0;
1093 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
1094 EXPECT_EQ(-1.0, result.d);
1095
1096 args[0] = DBL_MAX;
1097 args[1] = DBL_MIN;
1098 result.d = 0.0;
1099 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
1100 EXPECT_EQ(1.7976931348623157e308, result.d);
1101
1102 args[0] = DBL_MAX;
1103 args[1] = DBL_MAX;
1104 result.d = 0.0;
1105 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
1106 EXPECT_EQ(INFINITY, result.d);
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001107}
1108
1109TEST_F(JniInternalTest, StaticSumDoubleDoubleDoubleMethod) {
Brian Carlstroma663ea52011-08-19 23:33:41 -07001110 scoped_ptr<DexFile> dex(OpenDexFileBase64(kStaticLeafMethodsDex, "kStaticLeafMethodsDex"));
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001111
1112 PathClassLoader* class_loader = AllocPathClassLoader(dex.get());
1113 ASSERT_TRUE(class_loader != NULL);
1114
1115 Class* klass = class_linker_->FindClass("LStaticLeafMethods;", class_loader);
1116 ASSERT_TRUE(klass != NULL);
1117
1118 Method* method = klass->FindDirectMethod("sum", "(DDD)D");
1119 ASSERT_TRUE(method != NULL);
1120
1121 byte sum_DDDD_code[] = {
1122 0x2d, 0xe9, 0x00, 0x40, 0x87, 0xb0, 0xcd, 0xf8,
1123 0x00, 0x00, 0xcd, 0xf8, 0x24, 0x10, 0xcd, 0xf8,
1124 0x28, 0x20, 0xcd, 0xf8, 0x2c, 0x30, 0x9d, 0xed,
1125 0x09, 0x0b, 0x9d, 0xed, 0x0b, 0x1b, 0x30, 0xee,
1126 0x01, 0x2b, 0x8d, 0xed, 0x04, 0x2b, 0x9d, 0xed,
1127 0x04, 0x3b, 0x9d, 0xed, 0x0d, 0x4b, 0x33, 0xee,
1128 0x04, 0x3b, 0x8d, 0xed, 0x04, 0x3b, 0x04, 0x98,
1129 0x05, 0x99, 0x07, 0xb0, 0xbd, 0xe8, 0x00, 0x80,
1130 };
1131
1132 Method::InvokeStub* stub = AllocateStub(method,
1133 sum_DDDD_code,
1134 sizeof(sum_DDDD_code));
1135
1136 double args[3];
1137 JValue result;
1138
1139 args[0] = 0.0;
1140 args[1] = 0.0;
1141 args[2] = 0.0;
1142 result.d = -1.0;
1143 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
1144 EXPECT_EQ(0.0, result.d);
1145
1146 args[0] = 1.0;
1147 args[1] = 2.0;
1148 args[2] = 3.0;
1149 result.d = 0.0;
1150 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
1151 EXPECT_EQ(6.0, result.d);
1152
1153 args[0] = 1.0;
1154 args[1] = -2.0;
1155 args[2] = 3.0;
1156 result.d = 0.0;
1157 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
1158 EXPECT_EQ(2.0, result.d);
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001159}
1160
1161TEST_F(JniInternalTest, StaticSumDoubleDoubleDoubleDoubleMethod) {
Brian Carlstroma663ea52011-08-19 23:33:41 -07001162 scoped_ptr<DexFile> dex(OpenDexFileBase64(kStaticLeafMethodsDex, "kStaticLeafMethodsDex"));
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001163
1164 PathClassLoader* class_loader = AllocPathClassLoader(dex.get());
1165 ASSERT_TRUE(class_loader != NULL);
1166
1167 Class* klass = class_linker_->FindClass("LStaticLeafMethods;", class_loader);
1168 ASSERT_TRUE(klass != NULL);
1169
1170 Method* method = klass->FindDirectMethod("sum", "(DDDD)D");
1171 ASSERT_TRUE(method != NULL);
1172
1173 byte sum_DDDDD_code[] = {
1174 0x2d, 0xe9, 0x00, 0x40, 0x87, 0xb0, 0xcd, 0xf8,
1175 0x00, 0x00, 0xcd, 0xf8, 0x24, 0x10, 0xcd, 0xf8,
1176 0x28, 0x20, 0xcd, 0xf8, 0x2c, 0x30, 0x9d, 0xed,
1177 0x09, 0x0b, 0x9d, 0xed, 0x0b, 0x1b, 0x30, 0xee,
1178 0x01, 0x2b, 0x8d, 0xed, 0x04, 0x2b, 0x9d, 0xed,
1179 0x04, 0x3b, 0x9d, 0xed, 0x0d, 0x4b, 0x33, 0xee,
1180 0x04, 0x3b, 0x8d, 0xed, 0x04, 0x3b, 0x9d, 0xed,
1181 0x04, 0x5b, 0x9d, 0xed, 0x0f, 0x6b, 0x35, 0xee,
1182 0x06, 0x5b, 0x8d, 0xed, 0x04, 0x5b, 0x04, 0x98,
1183 0x05, 0x99, 0x07, 0xb0, 0xbd, 0xe8, 0x00, 0x80,
1184 };
1185
1186 Method::InvokeStub* stub = AllocateStub(method,
1187 sum_DDDDD_code,
1188 sizeof(sum_DDDDD_code));
1189
1190 double args[4];
1191 JValue result;
1192
1193 args[0] = 0.0;
1194 args[1] = 0.0;
1195 args[2] = 0.0;
1196 args[3] = 0.0;
1197 result.d = -1.0;
1198 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
1199 EXPECT_EQ(0.0, result.d);
1200
1201 args[0] = 1.0;
1202 args[1] = 2.0;
1203 args[2] = 3.0;
1204 args[3] = 4.0;
1205 result.d = 0.0;
1206 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
1207 EXPECT_EQ(10.0, result.d);
1208
1209 args[0] = 1.0;
1210 args[1] = -2.0;
1211 args[2] = 3.0;
1212 args[3] = -4.0;
1213 result.d = 0.0;
1214 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
1215 EXPECT_EQ(-2.0, result.d);
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001216}
1217
1218TEST_F(JniInternalTest, StaticSumDoubleDoubleDoubleDoubleDoubleMethod) {
Brian Carlstroma663ea52011-08-19 23:33:41 -07001219 scoped_ptr<DexFile> dex(OpenDexFileBase64(kStaticLeafMethodsDex, "kStaticLeafMethodsDex"));
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001220
1221 PathClassLoader* class_loader = AllocPathClassLoader(dex.get());
1222 ASSERT_TRUE(class_loader != NULL);
1223
1224 Class* klass = class_linker_->FindClass("LStaticLeafMethods;", class_loader);
1225 ASSERT_TRUE(klass != NULL);
1226
1227 Method* method = klass->FindDirectMethod("sum", "(DDDDD)D");
1228 ASSERT_TRUE(method != NULL);
1229
1230 byte sum_DDDDDD_code[] = {
1231 0x2d, 0xe9, 0x00, 0x40, 0x87, 0xb0, 0xcd, 0xf8,
1232 0x00, 0x00, 0xcd, 0xf8, 0x24, 0x10, 0xcd, 0xf8,
1233 0x28, 0x20, 0xcd, 0xf8, 0x2c, 0x30, 0x9d, 0xed,
1234 0x09, 0x0b, 0x9d, 0xed, 0x0b, 0x1b, 0x30, 0xee,
1235 0x01, 0x2b, 0x8d, 0xed, 0x04, 0x2b, 0x9d, 0xed,
1236 0x04, 0x3b, 0x9d, 0xed, 0x0d, 0x4b, 0x33, 0xee,
1237 0x04, 0x3b, 0x8d, 0xed, 0x04, 0x3b, 0x9d, 0xed,
1238 0x04, 0x5b, 0x9d, 0xed, 0x0f, 0x6b, 0x35, 0xee,
1239 0x06, 0x5b, 0x8d, 0xed, 0x04, 0x5b, 0x9d, 0xed,
1240 0x04, 0x7b, 0x9d, 0xed, 0x11, 0x0b, 0x37, 0xee,
1241 0x00, 0x7b, 0x8d, 0xed, 0x04, 0x7b, 0x04, 0x98,
1242 0x05, 0x99, 0x07, 0xb0, 0xbd, 0xe8, 0x00, 0x80,
1243 };
1244
1245 Method::InvokeStub* stub = AllocateStub(method,
1246 sum_DDDDDD_code,
1247 sizeof(sum_DDDDDD_code));
1248
1249 double args[5];
1250 JValue result;
1251
1252 args[0] = 0.0;
1253 args[1] = 0.0;
1254 args[2] = 0.0;
1255 args[3] = 0.0;
1256 args[4] = 0.0;
1257 result.d = -1.0;
1258 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
1259 EXPECT_EQ(0.0, result.d);
1260
1261 args[0] = 1.0;
1262 args[1] = 2.0;
1263 args[2] = 3.0;
1264 args[3] = 4.0;
1265 args[4] = 5.0;
1266 result.d = 0.0;
1267 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
1268 EXPECT_EQ(15.0, result.d);
1269
1270 args[0] = 1.0;
1271 args[1] = -2.0;
1272 args[2] = 3.0;
1273 args[3] = -4.0;
1274 args[4] = 5.0;
1275 result.d = 0.0;
1276 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
1277 EXPECT_EQ(3.0, result.d);
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001278}
1279#endif // __arm__
1280
Elliott Hughes37f7a402011-08-22 18:56:01 -07001281TEST_F(JniInternalTest, Throw) {
1282 EXPECT_EQ(JNI_ERR, env_->Throw(NULL));
1283
1284 jclass exception_class = env_->FindClass("java/lang/RuntimeException");
1285 ASSERT_TRUE(exception_class != NULL);
1286 jthrowable exception = reinterpret_cast<jthrowable>(env_->AllocObject(exception_class));
1287 ASSERT_TRUE(exception != NULL);
1288
1289 EXPECT_EQ(JNI_OK, env_->Throw(exception));
1290 EXPECT_TRUE(env_->ExceptionCheck());
1291 EXPECT_TRUE(env_->IsSameObject(exception, env_->ExceptionOccurred()));
1292 env_->ExceptionClear();
1293}
1294
1295TEST_F(JniInternalTest, ThrowNew) {
1296 EXPECT_EQ(JNI_ERR, env_->Throw(NULL));
1297
1298 jclass exception_class = env_->FindClass("java/lang/RuntimeException");
1299 ASSERT_TRUE(exception_class != NULL);
1300
1301 EXPECT_EQ(JNI_OK, env_->ThrowNew(exception_class, "hello world"));
1302 EXPECT_TRUE(env_->ExceptionCheck());
1303 EXPECT_TRUE(env_->IsInstanceOf(env_->ExceptionOccurred(), exception_class));
1304 env_->ExceptionClear();
1305}
1306
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001307}