blob: 325d1ecd9fcee2ae5a467a259a588d26408c1604 [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 <sys/mman.h>
6
Ian Rogers0cfe1fb2011-08-26 03:29:44 -07007#include <cmath>
8
Carl Shapiro9b9ba282011-08-14 15:30:39 -07009#include "common_test.h"
Elliott Hughes0c9cd562011-08-12 10:59:29 -070010
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 Hughes5174fe62011-08-23 15:12:35 -070017
Elliott Hughesa2501992011-08-26 19:39:54 -070018 vm_ = Runtime::Current()->GetJavaVM();
19
Elliott Hughes5174fe62011-08-23 15:12:35 -070020 // Turn on -verbose:jni for the JNI tests.
Elliott Hughesa2501992011-08-26 19:39:54 -070021 vm_->verbose_jni = true;
Elliott Hughes5174fe62011-08-23 15:12:35 -070022
Elliott Hughesc7ac37f2011-08-12 12:21:58 -070023 env_ = Thread::Current()->GetJniEnv();
Elliott Hughesb465ab02011-08-24 11:21:21 -070024
Elliott Hughes814e4032011-08-23 12:07:56 -070025 aioobe_ = env_->FindClass("java/lang/ArrayIndexOutOfBoundsException");
26 CHECK(aioobe_ != NULL);
Elliott Hughesb465ab02011-08-24 11:21:21 -070027
28 sioobe_ = env_->FindClass("java/lang/StringIndexOutOfBoundsException");
29 CHECK(sioobe_ != NULL);
Elliott Hughesc7ac37f2011-08-12 12:21:58 -070030 }
Elliott Hughesb465ab02011-08-24 11:21:21 -070031
Elliott Hughesa2501992011-08-26 19:39:54 -070032 JavaVMExt* vm_;
33 JNIEnvExt* env_;
Elliott Hughes814e4032011-08-23 12:07:56 -070034 jclass aioobe_;
Elliott Hughesb465ab02011-08-24 11:21:21 -070035 jclass sioobe_;
Elliott Hughes0c9cd562011-08-12 10:59:29 -070036};
37
Elliott Hughes885c3bd2011-08-22 16:59:20 -070038TEST_F(JniInternalTest, AllocObject) {
39 jclass c = env_->FindClass("java/lang/String");
40 ASSERT_TRUE(c != NULL);
41 jobject o = env_->AllocObject(c);
42 ASSERT_TRUE(o != NULL);
43
44 // We have an instance of the class we asked for...
45 ASSERT_TRUE(env_->IsInstanceOf(o, c));
46 // ...whose fields haven't been initialized because
47 // we didn't call a constructor.
48 ASSERT_EQ(0, env_->GetIntField(o, env_->GetFieldID(c, "count", "I")));
49 ASSERT_EQ(0, env_->GetIntField(o, env_->GetFieldID(c, "offset", "I")));
50 ASSERT_TRUE(env_->GetObjectField(o, env_->GetFieldID(c, "value", "[C")) == NULL);
51}
52
Elliott Hughesc7ac37f2011-08-12 12:21:58 -070053TEST_F(JniInternalTest, GetVersion) {
54 ASSERT_EQ(JNI_VERSION_1_6, env_->GetVersion());
55}
56
Elliott Hughes0c9cd562011-08-12 10:59:29 -070057#define EXPECT_CLASS_FOUND(NAME) \
Elliott Hughesbd935992011-08-22 11:59:34 -070058 EXPECT_TRUE(env_->FindClass(NAME) != NULL); \
59 EXPECT_FALSE(env_->ExceptionCheck())
Elliott Hughes0c9cd562011-08-12 10:59:29 -070060
61#define EXPECT_CLASS_NOT_FOUND(NAME) \
Elliott Hughesbd935992011-08-22 11:59:34 -070062 EXPECT_TRUE(env_->FindClass(NAME) == NULL); \
63 EXPECT_TRUE(env_->ExceptionCheck()); \
64 env_->ExceptionClear()
Elliott Hughes0c9cd562011-08-12 10:59:29 -070065
Elliott Hughesa2501992011-08-26 19:39:54 -070066std::string gCheckJniAbortMessage;
67void TestCheckJniAbortHook(const std::string& reason) {
68 gCheckJniAbortMessage = reason;
69}
70
Elliott Hughes0c9cd562011-08-12 10:59:29 -070071TEST_F(JniInternalTest, FindClass) {
Elliott Hughes0c9cd562011-08-12 10:59:29 -070072 // TODO: when these tests start failing because you're calling FindClass
73 // with a pending exception, fix EXPECT_CLASS_NOT_FOUND to assert that an
74 // exception was thrown and clear the exception.
75
Elliott Hughes0c9cd562011-08-12 10:59:29 -070076 // Reference types...
Elliott Hughes0c9cd562011-08-12 10:59:29 -070077 EXPECT_CLASS_FOUND("java/lang/String");
Elliott Hughes0c9cd562011-08-12 10:59:29 -070078 // ...for arrays too, where you must include "L;".
79 EXPECT_CLASS_FOUND("[Ljava/lang/String;");
Elliott Hughesa2501992011-08-26 19:39:54 -070080
81 vm_->check_jni_abort_hook = TestCheckJniAbortHook;
82 // We support . as well as / for compatibility, if -Xcheck:jni is off.
83 EXPECT_CLASS_FOUND("java.lang.String");
84 EXPECT_CLASS_NOT_FOUND("Ljava.lang.String;");
Elliott Hughes0c9cd562011-08-12 10:59:29 -070085 EXPECT_CLASS_FOUND("[Ljava.lang.String;");
86 EXPECT_CLASS_NOT_FOUND("[java.lang.String");
87
Elliott Hughesa2501992011-08-26 19:39:54 -070088 // You can't include the "L;" in a JNI class descriptor.
89 EXPECT_CLASS_NOT_FOUND("Ljava/lang/String;");
90 // But you must include it for an array of any reference type.
91 EXPECT_CLASS_NOT_FOUND("[java/lang/String");
92 vm_->check_jni_abort_hook = NULL;
93
Elliott Hughes0c9cd562011-08-12 10:59:29 -070094 // Primitive arrays are okay (if the primitive type is valid)...
95 EXPECT_CLASS_FOUND("[C");
Elliott Hughesa2501992011-08-26 19:39:54 -070096 vm_->check_jni_abort_hook = TestCheckJniAbortHook;
Elliott Hughes0c9cd562011-08-12 10:59:29 -070097 EXPECT_CLASS_NOT_FOUND("[K");
Elliott Hughesa2501992011-08-26 19:39:54 -070098 vm_->check_jni_abort_hook = NULL;
Elliott Hughes0c9cd562011-08-12 10:59:29 -070099 // But primitive types aren't allowed...
100 EXPECT_CLASS_NOT_FOUND("C");
101 EXPECT_CLASS_NOT_FOUND("K");
102}
103
Elliott Hughescdf53122011-08-19 15:46:09 -0700104#define EXPECT_EXCEPTION(exception_class) \
105 do { \
106 EXPECT_TRUE(env_->ExceptionCheck()); \
107 jthrowable exception = env_->ExceptionOccurred(); \
108 EXPECT_NE(static_cast<jthrowable>(NULL), exception); \
Elliott Hughescdf53122011-08-19 15:46:09 -0700109 env_->ExceptionClear(); \
Elliott Hughesa2501992011-08-26 19:39:54 -0700110 EXPECT_TRUE(env_->IsInstanceOf(exception, exception_class)); \
Elliott Hughescdf53122011-08-19 15:46:09 -0700111 } while (false)
112
113TEST_F(JniInternalTest, GetFieldID) {
114 jclass jlnsfe = env_->FindClass("java/lang/NoSuchFieldError");
115 ASSERT_TRUE(jlnsfe != NULL);
116 jclass c = env_->FindClass("java/lang/String");
117 ASSERT_TRUE(c != NULL);
118
119 // Wrong type.
120 jfieldID fid = env_->GetFieldID(c, "count", "J");
121 EXPECT_EQ(static_cast<jfieldID>(NULL), fid);
122 EXPECT_EXCEPTION(jlnsfe);
123
Ian Rogersb17d08b2011-09-02 16:16:49 -0700124 // Wrong type where type doesn't exist.
125 fid = env_->GetFieldID(c, "count", "Lrod/jane/freddy;");
126 EXPECT_EQ(static_cast<jfieldID>(NULL), fid);
127 EXPECT_EXCEPTION(jlnsfe);
128
Elliott Hughescdf53122011-08-19 15:46:09 -0700129 // Wrong name.
130 fid = env_->GetFieldID(c, "Count", "I");
131 EXPECT_EQ(static_cast<jfieldID>(NULL), fid);
132 EXPECT_EXCEPTION(jlnsfe);
133
134 // Good declared field lookup.
135 fid = env_->GetFieldID(c, "count", "I");
136 EXPECT_NE(static_cast<jfieldID>(NULL), fid);
137 EXPECT_TRUE(fid != NULL);
138 EXPECT_FALSE(env_->ExceptionCheck());
139
140 // Good superclass field lookup.
141 c = env_->FindClass("java/lang/StringBuilder");
142 fid = env_->GetFieldID(c, "count", "I");
143 EXPECT_NE(static_cast<jfieldID>(NULL), fid);
144 EXPECT_TRUE(fid != NULL);
145 EXPECT_FALSE(env_->ExceptionCheck());
146
147 // Not instance.
148 fid = env_->GetFieldID(c, "CASE_INSENSITIVE_ORDER", "Ljava/util/Comparator;");
149 EXPECT_EQ(static_cast<jfieldID>(NULL), fid);
150 EXPECT_EXCEPTION(jlnsfe);
151}
152
153TEST_F(JniInternalTest, GetStaticFieldID) {
154 jclass jlnsfe = env_->FindClass("java/lang/NoSuchFieldError");
155 ASSERT_TRUE(jlnsfe != NULL);
156 jclass c = env_->FindClass("java/lang/String");
157 ASSERT_TRUE(c != NULL);
158
159 // Wrong type.
160 jfieldID fid = env_->GetStaticFieldID(c, "CASE_INSENSITIVE_ORDER", "J");
161 EXPECT_EQ(static_cast<jfieldID>(NULL), fid);
162 EXPECT_EXCEPTION(jlnsfe);
163
Ian Rogersb17d08b2011-09-02 16:16:49 -0700164 // Wrong type where type doesn't exist.
165 fid = env_->GetStaticFieldID(c, "CASE_INSENSITIVE_ORDER", "Lrod/jane/freddy;");
166 EXPECT_EQ(static_cast<jfieldID>(NULL), fid);
167 EXPECT_EXCEPTION(jlnsfe);
168
Elliott Hughescdf53122011-08-19 15:46:09 -0700169 // Wrong name.
170 fid = env_->GetStaticFieldID(c, "cASE_INSENSITIVE_ORDER", "Ljava/util/Comparator;");
171 EXPECT_EQ(static_cast<jfieldID>(NULL), fid);
172 EXPECT_EXCEPTION(jlnsfe);
173
174 // Good declared field lookup.
175 fid = env_->GetStaticFieldID(c, "CASE_INSENSITIVE_ORDER", "Ljava/util/Comparator;");
176 EXPECT_NE(static_cast<jfieldID>(NULL), fid);
177 EXPECT_TRUE(fid != NULL);
178 EXPECT_FALSE(env_->ExceptionCheck());
179
180 // Not static.
181 fid = env_->GetStaticFieldID(c, "count", "I");
182 EXPECT_EQ(static_cast<jfieldID>(NULL), fid);
183 EXPECT_EXCEPTION(jlnsfe);
184}
185
Ian Rogers4dd71f12011-08-16 14:16:02 -0700186TEST_F(JniInternalTest, GetMethodID) {
187 jclass jlobject = env_->FindClass("java/lang/Object");
188 jclass jlstring = env_->FindClass("java/lang/String");
189 jclass jlnsme = env_->FindClass("java/lang/NoSuchMethodError");
190
191 // Sanity check that no exceptions are pending
Elliott Hughescdf53122011-08-19 15:46:09 -0700192 ASSERT_FALSE(env_->ExceptionCheck());
Ian Rogers4dd71f12011-08-16 14:16:02 -0700193
194 // Check that java.lang.Object.foo() doesn't exist and NoSuchMethodError is
195 // a pending exception
196 jmethodID method = env_->GetMethodID(jlobject, "foo", "()V");
197 EXPECT_EQ(static_cast<jmethodID>(NULL), method);
Elliott Hughescdf53122011-08-19 15:46:09 -0700198 EXPECT_EXCEPTION(jlnsme);
Ian Rogers4dd71f12011-08-16 14:16:02 -0700199
200 // Check that java.lang.Object.equals() does exist
Ian Rogers4dd71f12011-08-16 14:16:02 -0700201 method = env_->GetMethodID(jlobject, "equals", "(Ljava/lang/Object;)Z");
202 EXPECT_NE(static_cast<jmethodID>(NULL), method);
203 EXPECT_FALSE(env_->ExceptionCheck());
Ian Rogers4dd71f12011-08-16 14:16:02 -0700204
205 // Check that GetMethodID for java.lang.String.valueOf(int) fails as the
206 // method is static
207 method = env_->GetMethodID(jlstring, "valueOf", "(I)Ljava/lang/String;");
208 EXPECT_EQ(static_cast<jmethodID>(NULL), method);
Elliott Hughescdf53122011-08-19 15:46:09 -0700209 EXPECT_EXCEPTION(jlnsme);
Ian Rogers4dd71f12011-08-16 14:16:02 -0700210}
211
212TEST_F(JniInternalTest, GetStaticMethodID) {
213 jclass jlobject = env_->FindClass("java/lang/Object");
214 jclass jlnsme = env_->FindClass("java/lang/NoSuchMethodError");
215
216 // Sanity check that no exceptions are pending
Elliott Hughescdf53122011-08-19 15:46:09 -0700217 ASSERT_FALSE(env_->ExceptionCheck());
Ian Rogers4dd71f12011-08-16 14:16:02 -0700218
219 // Check that java.lang.Object.foo() doesn't exist and NoSuchMethodError is
220 // a pending exception
221 jmethodID method = env_->GetStaticMethodID(jlobject, "foo", "()V");
222 EXPECT_EQ(static_cast<jmethodID>(NULL), method);
Elliott Hughescdf53122011-08-19 15:46:09 -0700223 EXPECT_EXCEPTION(jlnsme);
Ian Rogers4dd71f12011-08-16 14:16:02 -0700224
225 // Check that GetStaticMethodID for java.lang.Object.equals(Object) fails as
226 // the method is not static
227 method = env_->GetStaticMethodID(jlobject, "equals", "(Ljava/lang/Object;)Z");
228 EXPECT_EQ(static_cast<jmethodID>(NULL), method);
Elliott Hughescdf53122011-08-19 15:46:09 -0700229 EXPECT_EXCEPTION(jlnsme);
Ian Rogers4dd71f12011-08-16 14:16:02 -0700230
231 // Check that java.lang.String.valueOf(int) does exist
Ian Rogers4dd71f12011-08-16 14:16:02 -0700232 jclass jlstring = env_->FindClass("java/lang/String");
233 method = env_->GetStaticMethodID(jlstring, "valueOf",
234 "(I)Ljava/lang/String;");
235 EXPECT_NE(static_cast<jmethodID>(NULL), method);
236 EXPECT_FALSE(env_->ExceptionCheck());
Ian Rogers4dd71f12011-08-16 14:16:02 -0700237}
238
Elliott Hughescdf53122011-08-19 15:46:09 -0700239TEST_F(JniInternalTest, FromReflectedField_ToReflectedField) {
240 jclass jlrField = env_->FindClass("java/lang/reflect/Field");
241 jclass c = env_->FindClass("java/lang/String");
242 ASSERT_TRUE(c != NULL);
243 jfieldID fid = env_->GetFieldID(c, "count", "I");
244 ASSERT_TRUE(fid != NULL);
245 // Turn the fid into a java.lang.reflect.Field...
246 jobject field = env_->ToReflectedField(c, fid, JNI_FALSE);
247 ASSERT_TRUE(c != NULL);
248 ASSERT_TRUE(env_->IsInstanceOf(field, jlrField));
249 // ...and back again.
250 jfieldID fid2 = env_->FromReflectedField(field);
251 ASSERT_TRUE(fid2 != NULL);
252}
253
254TEST_F(JniInternalTest, FromReflectedMethod_ToReflectedMethod) {
255 jclass jlrMethod = env_->FindClass("java/lang/reflect/Method");
256 jclass c = env_->FindClass("java/lang/String");
257 ASSERT_TRUE(c != NULL);
258 jmethodID mid = env_->GetMethodID(c, "length", "()I");
259 ASSERT_TRUE(mid != NULL);
260 // Turn the mid into a java.lang.reflect.Method...
261 jobject method = env_->ToReflectedMethod(c, mid, JNI_FALSE);
262 ASSERT_TRUE(c != NULL);
263 ASSERT_TRUE(env_->IsInstanceOf(method, jlrMethod));
264 // ...and back again.
265 jmethodID mid2 = env_->FromReflectedMethod(method);
266 ASSERT_TRUE(mid2 != NULL);
267}
268
Elliott Hughes5174fe62011-08-23 15:12:35 -0700269void BogusMethod() {
270 // You can't pass NULL function pointers to RegisterNatives.
271}
272
Ian Rogers4dd71f12011-08-16 14:16:02 -0700273TEST_F(JniInternalTest, RegisterNatives) {
274 jclass jlobject = env_->FindClass("java/lang/Object");
275 jclass jlnsme = env_->FindClass("java/lang/NoSuchMethodError");
276
277 // Sanity check that no exceptions are pending
Elliott Hughescdf53122011-08-19 15:46:09 -0700278 ASSERT_FALSE(env_->ExceptionCheck());
Ian Rogers4dd71f12011-08-16 14:16:02 -0700279
280 // Check that registering to a non-existent java.lang.Object.foo() causes a
281 // NoSuchMethodError
282 {
283 JNINativeMethod methods[] = {{"foo", "()V", NULL}};
284 env_->RegisterNatives(jlobject, methods, 1);
285 }
Elliott Hughescdf53122011-08-19 15:46:09 -0700286 EXPECT_EXCEPTION(jlnsme);
Ian Rogers4dd71f12011-08-16 14:16:02 -0700287
288 // Check that registering non-native methods causes a NoSuchMethodError
289 {
290 JNINativeMethod methods[] = {{"equals", "(Ljava/lang/Object;)Z", NULL}};
291 env_->RegisterNatives(jlobject, methods, 1);
292 }
Elliott Hughescdf53122011-08-19 15:46:09 -0700293 EXPECT_EXCEPTION(jlnsme);
Ian Rogers4dd71f12011-08-16 14:16:02 -0700294
295 // Check that registering native methods is successful
296 {
Elliott Hughesad7c2a32011-08-31 11:58:10 -0700297 JNINativeMethod methods[] = {{"getClass", "()Ljava/lang/Class;", reinterpret_cast<void*>(BogusMethod)}};
Ian Rogers4dd71f12011-08-16 14:16:02 -0700298 env_->RegisterNatives(jlobject, methods, 1);
299 }
300 EXPECT_FALSE(env_->ExceptionCheck());
Elliott Hughes5174fe62011-08-23 15:12:35 -0700301
302 env_->UnregisterNatives(jlobject);
Ian Rogers4dd71f12011-08-16 14:16:02 -0700303}
304
Elliott Hughes75770752011-08-24 17:52:38 -0700305#define EXPECT_PRIMITIVE_ARRAY(new_fn, get_region_fn, set_region_fn, get_elements_fn, release_elements_fn, scalar_type, expected_class_descriptor) \
Elliott Hughes814e4032011-08-23 12:07:56 -0700306 jsize size = 4; \
307 /* Allocate an array and check it has the right type and length. */ \
308 scalar_type ## Array a = env_->new_fn(size); \
309 EXPECT_TRUE(a != NULL); \
310 EXPECT_TRUE(env_->IsInstanceOf(a, env_->FindClass(expected_class_descriptor))); \
311 EXPECT_EQ(size, env_->GetArrayLength(a)); \
312 /* AIOOBE for negative start offset. */ \
313 env_->get_region_fn(a, -1, 1, NULL); \
314 EXPECT_EXCEPTION(aioobe_); \
315 env_->set_region_fn(a, -1, 1, NULL); \
316 EXPECT_EXCEPTION(aioobe_); \
317 /* AIOOBE for negative length. */ \
318 env_->get_region_fn(a, 0, -1, NULL); \
319 EXPECT_EXCEPTION(aioobe_); \
320 env_->set_region_fn(a, 0, -1, NULL); \
321 EXPECT_EXCEPTION(aioobe_); \
322 /* AIOOBE for buffer overrun. */ \
323 env_->get_region_fn(a, size - 1, size, NULL); \
324 EXPECT_EXCEPTION(aioobe_); \
325 env_->set_region_fn(a, size - 1, size, NULL); \
326 EXPECT_EXCEPTION(aioobe_); \
327 /* Prepare a couple of buffers. */ \
328 scalar_type src_buf[size]; \
329 scalar_type dst_buf[size]; \
330 for (jsize i = 0; i < size; ++i) { src_buf[i] = scalar_type(i); } \
331 for (jsize i = 0; i < size; ++i) { dst_buf[i] = scalar_type(-1); } \
332 /* Copy all of src_buf onto the heap. */ \
333 env_->set_region_fn(a, 0, size, src_buf); \
334 /* Copy back only part. */ \
335 env_->get_region_fn(a, 1, size - 2, &dst_buf[1]); \
336 EXPECT_FALSE(memcmp(src_buf, dst_buf, sizeof(src_buf)) == 0) << "short copy equal"; \
337 /* Copy the missing pieces. */ \
338 env_->get_region_fn(a, 0, 1, dst_buf); \
339 env_->get_region_fn(a, size - 1, 1, &dst_buf[size - 1]); \
340 EXPECT_TRUE(memcmp(src_buf, dst_buf, sizeof(src_buf)) == 0) << "fixed copy not equal"; \
341 /* Copy back the whole array. */ \
342 env_->get_region_fn(a, 0, size, dst_buf); \
Elliott Hughes75770752011-08-24 17:52:38 -0700343 EXPECT_TRUE(memcmp(src_buf, dst_buf, sizeof(src_buf)) == 0) << "full copy not equal"; \
344 /* GetPrimitiveArrayCritical */ \
345 void* v = env_->GetPrimitiveArrayCritical(a, NULL); \
346 EXPECT_TRUE(memcmp(src_buf, v, sizeof(src_buf)) == 0) << "GetPrimitiveArrayCritical not equal"; \
347 env_->ReleasePrimitiveArrayCritical(a, v, 0); \
348 /* GetXArrayElements */ \
349 scalar_type* xs = env_->get_elements_fn(a, NULL); \
350 EXPECT_TRUE(memcmp(src_buf, xs, sizeof(src_buf)) == 0) << # get_elements_fn " not equal"; \
351 env_->release_elements_fn(a, xs, 0); \
352 EXPECT_EQ(reinterpret_cast<uintptr_t>(v), reinterpret_cast<uintptr_t>(xs))
Elliott Hughesbd935992011-08-22 11:59:34 -0700353
Elliott Hughes814e4032011-08-23 12:07:56 -0700354TEST_F(JniInternalTest, BooleanArrays) {
Elliott Hughes75770752011-08-24 17:52:38 -0700355 EXPECT_PRIMITIVE_ARRAY(NewBooleanArray, GetBooleanArrayRegion, SetBooleanArrayRegion, GetBooleanArrayElements, ReleaseBooleanArrayElements, jboolean, "[Z");
Elliott Hughes814e4032011-08-23 12:07:56 -0700356}
357TEST_F(JniInternalTest, ByteArrays) {
Elliott Hughes75770752011-08-24 17:52:38 -0700358 EXPECT_PRIMITIVE_ARRAY(NewByteArray, GetByteArrayRegion, SetByteArrayRegion, GetByteArrayElements, ReleaseByteArrayElements, jbyte, "[B");
Elliott Hughes814e4032011-08-23 12:07:56 -0700359}
360TEST_F(JniInternalTest, CharArrays) {
Elliott Hughes75770752011-08-24 17:52:38 -0700361 EXPECT_PRIMITIVE_ARRAY(NewCharArray, GetCharArrayRegion, SetCharArrayRegion, GetCharArrayElements, ReleaseCharArrayElements, jchar, "[C");
Elliott Hughes814e4032011-08-23 12:07:56 -0700362}
363TEST_F(JniInternalTest, DoubleArrays) {
Elliott Hughes75770752011-08-24 17:52:38 -0700364 EXPECT_PRIMITIVE_ARRAY(NewDoubleArray, GetDoubleArrayRegion, SetDoubleArrayRegion, GetDoubleArrayElements, ReleaseDoubleArrayElements, jdouble, "[D");
Elliott Hughes814e4032011-08-23 12:07:56 -0700365}
366TEST_F(JniInternalTest, FloatArrays) {
Elliott Hughes75770752011-08-24 17:52:38 -0700367 EXPECT_PRIMITIVE_ARRAY(NewFloatArray, GetFloatArrayRegion, SetFloatArrayRegion, GetFloatArrayElements, ReleaseFloatArrayElements, jfloat, "[F");
Elliott Hughes814e4032011-08-23 12:07:56 -0700368}
369TEST_F(JniInternalTest, IntArrays) {
Elliott Hughes75770752011-08-24 17:52:38 -0700370 EXPECT_PRIMITIVE_ARRAY(NewIntArray, GetIntArrayRegion, SetIntArrayRegion, GetIntArrayElements, ReleaseIntArrayElements, jint, "[I");
Elliott Hughes814e4032011-08-23 12:07:56 -0700371}
372TEST_F(JniInternalTest, LongArrays) {
Elliott Hughes75770752011-08-24 17:52:38 -0700373 EXPECT_PRIMITIVE_ARRAY(NewLongArray, GetLongArrayRegion, SetLongArrayRegion, GetLongArrayElements, ReleaseLongArrayElements, jlong, "[J");
Elliott Hughes814e4032011-08-23 12:07:56 -0700374}
375TEST_F(JniInternalTest, ShortArrays) {
Elliott Hughes75770752011-08-24 17:52:38 -0700376 EXPECT_PRIMITIVE_ARRAY(NewShortArray, GetShortArrayRegion, SetShortArrayRegion, GetShortArrayElements, ReleaseShortArrayElements, jshort, "[S");
Elliott Hughesd8ddfd52011-08-15 14:32:53 -0700377}
378
Elliott Hughesf2682d52011-08-15 16:37:04 -0700379TEST_F(JniInternalTest, NewObjectArray) {
380 // TODO: death tests for negative array sizes.
381
Elliott Hughesf2682d52011-08-15 16:37:04 -0700382 // TODO: check non-NULL initial elements.
383
Elliott Hughesbd935992011-08-22 11:59:34 -0700384 jclass element_class = env_->FindClass("java/lang/String");
385 ASSERT_TRUE(element_class != NULL);
386 jclass array_class = env_->FindClass("[Ljava/lang/String;");
387 ASSERT_TRUE(array_class != NULL);
Elliott Hughesf2682d52011-08-15 16:37:04 -0700388
Elliott Hughesbd935992011-08-22 11:59:34 -0700389 jobjectArray a;
Elliott Hughesf2682d52011-08-15 16:37:04 -0700390
Elliott Hughesbd935992011-08-22 11:59:34 -0700391 a = env_->NewObjectArray(0, element_class, NULL);
392 EXPECT_TRUE(a != NULL);
393 EXPECT_TRUE(env_->IsInstanceOf(a, array_class));
394 EXPECT_EQ(0, env_->GetArrayLength(a));
395
396 a = env_->NewObjectArray(1, element_class, NULL);
397 EXPECT_TRUE(a != NULL);
398 EXPECT_TRUE(env_->IsInstanceOf(a, array_class));
399 EXPECT_EQ(1, env_->GetArrayLength(a));
Elliott Hughes75770752011-08-24 17:52:38 -0700400 EXPECT_TRUE(env_->IsSameObject(env_->GetObjectArrayElement(a, 0), NULL));
401
402 jstring s = env_->NewStringUTF("poop");
403 a = env_->NewObjectArray(2, element_class, s);
404 EXPECT_TRUE(a != NULL);
405 EXPECT_TRUE(env_->IsInstanceOf(a, array_class));
406 EXPECT_EQ(2, env_->GetArrayLength(a));
407 EXPECT_TRUE(env_->IsSameObject(env_->GetObjectArrayElement(a, 0), s));
408 EXPECT_TRUE(env_->IsSameObject(env_->GetObjectArrayElement(a, 1), s));
Elliott Hughesbd935992011-08-22 11:59:34 -0700409}
410
411TEST_F(JniInternalTest, GetArrayLength) {
412 // Already tested in NewObjectArray/NewPrimitiveArray.
Elliott Hughes8a26c5c2011-08-15 18:35:43 -0700413}
414
Elliott Hughes37f7a402011-08-22 18:56:01 -0700415TEST_F(JniInternalTest, GetObjectClass) {
416 jclass string_class = env_->FindClass("java/lang/String");
417 ASSERT_TRUE(string_class != NULL);
418 jclass class_class = env_->FindClass("java/lang/Class");
419 ASSERT_TRUE(class_class != NULL);
420
421 jstring s = env_->NewStringUTF("poop");
422 jclass c = env_->GetObjectClass(s);
423 ASSERT_TRUE(env_->IsSameObject(string_class, c));
424
425 jclass c2 = env_->GetObjectClass(c);
426 ASSERT_TRUE(env_->IsSameObject(class_class, env_->GetObjectClass(c2)));
427}
428
Elliott Hughes885c3bd2011-08-22 16:59:20 -0700429TEST_F(JniInternalTest, GetSuperclass) {
430 jclass object_class = env_->FindClass("java/lang/Object");
431 ASSERT_TRUE(object_class != NULL);
432 jclass string_class = env_->FindClass("java/lang/String");
433 ASSERT_TRUE(string_class != NULL);
434 ASSERT_TRUE(env_->IsSameObject(object_class, env_->GetSuperclass(string_class)));
435 ASSERT_TRUE(env_->GetSuperclass(object_class) == NULL);
436}
437
Elliott Hughes37f7a402011-08-22 18:56:01 -0700438TEST_F(JniInternalTest, IsAssignableFrom) {
439 jclass object_class = env_->FindClass("java/lang/Object");
440 ASSERT_TRUE(object_class != NULL);
441 jclass string_class = env_->FindClass("java/lang/String");
442 ASSERT_TRUE(string_class != NULL);
443
444 ASSERT_TRUE(env_->IsAssignableFrom(object_class, string_class));
445 ASSERT_FALSE(env_->IsAssignableFrom(string_class, object_class));
446}
447
Elliott Hughesb465ab02011-08-24 11:21:21 -0700448TEST_F(JniInternalTest, GetObjectRefType) {
449 jclass local = env_->FindClass("java/lang/Object");
450 ASSERT_TRUE(local != NULL);
451 EXPECT_EQ(JNILocalRefType, env_->GetObjectRefType(local));
452
453 jobject global = env_->NewGlobalRef(local);
454 EXPECT_EQ(JNIGlobalRefType, env_->GetObjectRefType(global));
455
456 jweak weak_global = env_->NewWeakGlobalRef(local);
457 EXPECT_EQ(JNIWeakGlobalRefType, env_->GetObjectRefType(weak_global));
458
459 jobject invalid = reinterpret_cast<jobject>(this);
460 EXPECT_EQ(JNIInvalidRefType, env_->GetObjectRefType(invalid));
461
462 // TODO: invoke a native method and test that its arguments are considered local references.
463}
464
Elliott Hughes8a26c5c2011-08-15 18:35:43 -0700465TEST_F(JniInternalTest, NewStringUTF) {
466 EXPECT_TRUE(env_->NewStringUTF(NULL) == NULL);
Elliott Hughes814e4032011-08-23 12:07:56 -0700467 jstring s;
468
469 s = env_->NewStringUTF("");
470 EXPECT_TRUE(s != NULL);
471 EXPECT_EQ(0, env_->GetStringLength(s));
472 EXPECT_EQ(0, env_->GetStringUTFLength(s));
473 s = env_->NewStringUTF("hello");
474 EXPECT_TRUE(s != NULL);
475 EXPECT_EQ(5, env_->GetStringLength(s));
476 EXPECT_EQ(5, env_->GetStringUTFLength(s));
477
Elliott Hughes8a26c5c2011-08-15 18:35:43 -0700478 // TODO: check some non-ASCII strings.
Elliott Hughesf2682d52011-08-15 16:37:04 -0700479}
480
Elliott Hughes814e4032011-08-23 12:07:56 -0700481TEST_F(JniInternalTest, NewString) {
482 EXPECT_TRUE(env_->NewString(NULL, 0) == NULL);
483
484 jchar chars[] = { 'h', 'i' };
485 jstring s;
486 s = env_->NewString(chars, 0);
487 EXPECT_TRUE(s != NULL);
488 EXPECT_EQ(0, env_->GetStringLength(s));
489 EXPECT_EQ(0, env_->GetStringUTFLength(s));
490 s = env_->NewString(chars, 2);
491 EXPECT_TRUE(s != NULL);
492 EXPECT_EQ(2, env_->GetStringLength(s));
493 EXPECT_EQ(2, env_->GetStringUTFLength(s));
494
495 // TODO: check some non-ASCII strings.
496}
497
Elliott Hughesb465ab02011-08-24 11:21:21 -0700498TEST_F(JniInternalTest, GetStringLength_GetStringUTFLength) {
499 // Already tested in the NewString/NewStringUTF tests.
500}
501
502TEST_F(JniInternalTest, GetStringRegion_GetStringUTFRegion) {
503 jstring s = env_->NewStringUTF("hello");
504 ASSERT_TRUE(s != NULL);
505
506 env_->GetStringRegion(s, -1, 0, NULL);
507 EXPECT_EXCEPTION(sioobe_);
508 env_->GetStringRegion(s, 0, -1, NULL);
509 EXPECT_EXCEPTION(sioobe_);
510 env_->GetStringRegion(s, 0, 10, NULL);
511 EXPECT_EXCEPTION(sioobe_);
512 env_->GetStringRegion(s, 10, 1, NULL);
513 EXPECT_EXCEPTION(sioobe_);
514
515 jchar chars[4] = { 'x', 'x', 'x', 'x' };
516 env_->GetStringRegion(s, 1, 2, &chars[1]);
517 EXPECT_EQ('x', chars[0]);
518 EXPECT_EQ('e', chars[1]);
519 EXPECT_EQ('l', chars[2]);
520 EXPECT_EQ('x', chars[3]);
521
522 env_->GetStringUTFRegion(s, -1, 0, NULL);
523 EXPECT_EXCEPTION(sioobe_);
524 env_->GetStringUTFRegion(s, 0, -1, NULL);
525 EXPECT_EXCEPTION(sioobe_);
526 env_->GetStringUTFRegion(s, 0, 10, NULL);
527 EXPECT_EXCEPTION(sioobe_);
528 env_->GetStringUTFRegion(s, 10, 1, NULL);
529 EXPECT_EXCEPTION(sioobe_);
530
531 char bytes[4] = { 'x', 'x', 'x', 'x' };
532 env_->GetStringUTFRegion(s, 1, 2, &bytes[1]);
533 EXPECT_EQ('x', bytes[0]);
534 EXPECT_EQ('e', bytes[1]);
535 EXPECT_EQ('l', bytes[2]);
536 EXPECT_EQ('x', bytes[3]);
537}
538
Elliott Hughes75770752011-08-24 17:52:38 -0700539TEST_F(JniInternalTest, GetStringUTFChars_ReleaseStringUTFChars) {
Elliott Hughesa2501992011-08-26 19:39:54 -0700540 vm_->check_jni_abort_hook = TestCheckJniAbortHook;
541 // Passing in a NULL jstring is ignored normally, but caught by -Xcheck:jni.
Elliott Hughes75770752011-08-24 17:52:38 -0700542 EXPECT_TRUE(env_->GetStringUTFChars(NULL, NULL) == NULL);
Elliott Hughesa2501992011-08-26 19:39:54 -0700543 vm_->check_jni_abort_hook = NULL;
Elliott Hughes75770752011-08-24 17:52:38 -0700544
545 jstring s = env_->NewStringUTF("hello");
546 ASSERT_TRUE(s != NULL);
547
548 const char* utf = env_->GetStringUTFChars(s, NULL);
549 EXPECT_STREQ("hello", utf);
550 env_->ReleaseStringUTFChars(s, utf);
551
552 jboolean is_copy = JNI_FALSE;
553 utf = env_->GetStringUTFChars(s, &is_copy);
554 EXPECT_EQ(JNI_TRUE, is_copy);
555 EXPECT_STREQ("hello", utf);
556 env_->ReleaseStringUTFChars(s, utf);
557}
558
559TEST_F(JniInternalTest, GetStringChars_ReleaseStringChars) {
560 jstring s = env_->NewStringUTF("hello");
561 ASSERT_TRUE(s != NULL);
562
563 jchar expected[] = { 'h', 'e', 'l', 'l', 'o' };
564 const jchar* chars = env_->GetStringChars(s, NULL);
565 EXPECT_EQ(expected[0], chars[0]);
566 EXPECT_EQ(expected[1], chars[1]);
567 EXPECT_EQ(expected[2], chars[2]);
568 EXPECT_EQ(expected[3], chars[3]);
569 EXPECT_EQ(expected[4], chars[4]);
570 env_->ReleaseStringChars(s, chars);
571
572 jboolean is_copy = JNI_FALSE;
573 chars = env_->GetStringChars(s, &is_copy);
574 EXPECT_EQ(JNI_FALSE, is_copy);
575 EXPECT_EQ(expected[0], chars[0]);
576 EXPECT_EQ(expected[1], chars[1]);
577 EXPECT_EQ(expected[2], chars[2]);
578 EXPECT_EQ(expected[3], chars[3]);
579 EXPECT_EQ(expected[4], chars[4]);
580 env_->ReleaseStringChars(s, chars);
581}
582
583TEST_F(JniInternalTest, GetStringCritical_ReleaseStringCritical) {
584 jstring s = env_->NewStringUTF("hello");
585 ASSERT_TRUE(s != NULL);
586
587 jchar expected[] = { 'h', 'e', 'l', 'l', 'o' };
588 const jchar* chars = env_->GetStringCritical(s, NULL);
589 EXPECT_EQ(expected[0], chars[0]);
590 EXPECT_EQ(expected[1], chars[1]);
591 EXPECT_EQ(expected[2], chars[2]);
592 EXPECT_EQ(expected[3], chars[3]);
593 EXPECT_EQ(expected[4], chars[4]);
594 env_->ReleaseStringCritical(s, chars);
595
596 jboolean is_copy = JNI_FALSE;
597 chars = env_->GetStringCritical(s, &is_copy);
598 EXPECT_EQ(JNI_FALSE, is_copy);
599 EXPECT_EQ(expected[0], chars[0]);
600 EXPECT_EQ(expected[1], chars[1]);
601 EXPECT_EQ(expected[2], chars[2]);
602 EXPECT_EQ(expected[3], chars[3]);
603 EXPECT_EQ(expected[4], chars[4]);
604 env_->ReleaseStringCritical(s, chars);
605}
606
Elliott Hughes814e4032011-08-23 12:07:56 -0700607TEST_F(JniInternalTest, GetObjectArrayElement_SetObjectArrayElement) {
Elliott Hughes289da822011-08-16 10:11:20 -0700608 jclass c = env_->FindClass("[Ljava/lang/Object;");
609 ASSERT_TRUE(c != NULL);
610
611 jobjectArray array = env_->NewObjectArray(1, c, NULL);
612 EXPECT_TRUE(array != NULL);
Elliott Hughes814e4032011-08-23 12:07:56 -0700613 EXPECT_TRUE(env_->GetObjectArrayElement(array, 0) == NULL);
Elliott Hughes289da822011-08-16 10:11:20 -0700614 env_->SetObjectArrayElement(array, 0, c);
Elliott Hughes814e4032011-08-23 12:07:56 -0700615 EXPECT_TRUE(env_->IsSameObject(env_->GetObjectArrayElement(array, 0), c));
Elliott Hughesa5b897e2011-08-16 11:33:06 -0700616
617 // ArrayIndexOutOfBounds for negative index.
Elliott Hughesa5b897e2011-08-16 11:33:06 -0700618 env_->SetObjectArrayElement(array, -1, c);
Elliott Hughes814e4032011-08-23 12:07:56 -0700619 EXPECT_EXCEPTION(aioobe_);
Elliott Hughesa5b897e2011-08-16 11:33:06 -0700620
621 // ArrayIndexOutOfBounds for too-large index.
Elliott Hughesa5b897e2011-08-16 11:33:06 -0700622 env_->SetObjectArrayElement(array, 1, c);
Elliott Hughes814e4032011-08-23 12:07:56 -0700623 EXPECT_EXCEPTION(aioobe_);
Elliott Hughesa5b897e2011-08-16 11:33:06 -0700624
Elliott Hughes289da822011-08-16 10:11:20 -0700625 // TODO: check ArrayStoreException thrown for bad types.
626}
627
Elliott Hughes885c3bd2011-08-22 16:59:20 -0700628#define EXPECT_STATIC_PRIMITIVE_FIELD(type, field_name, sig, value1, value2) \
629 do { \
630 jfieldID fid = env_->GetStaticFieldID(c, field_name, sig); \
631 EXPECT_TRUE(fid != NULL); \
632 env_->SetStatic ## type ## Field(c, fid, value1); \
633 EXPECT_EQ(value1, env_->GetStatic ## type ## Field(c, fid)); \
634 env_->SetStatic ## type ## Field(c, fid, value2); \
635 EXPECT_EQ(value2, env_->GetStatic ## type ## Field(c, fid)); \
636 } while (false)
637
638#define EXPECT_PRIMITIVE_FIELD(instance, type, field_name, sig, value1, value2) \
639 do { \
640 jfieldID fid = env_->GetFieldID(c, field_name, sig); \
641 EXPECT_TRUE(fid != NULL); \
642 env_->Set ## type ## Field(instance, fid, value1); \
643 EXPECT_EQ(value1, env_->Get ## type ## Field(instance, fid)); \
644 env_->Set ## type ## Field(instance, fid, value2); \
645 EXPECT_EQ(value2, env_->Get ## type ## Field(instance, fid)); \
646 } while (false)
647
648
649TEST_F(JniInternalTest, GetPrimitiveField_SetPrimitiveField) {
Elliott Hughes90a33692011-08-30 13:27:07 -0700650 UniquePtr<const DexFile> dex(OpenTestDexFile("AllFields"));
Brian Carlstrom8a487412011-08-29 20:08:52 -0700651 const PathClassLoader* class_loader = AllocPathClassLoader(dex.get());
Elliott Hughes885c3bd2011-08-22 16:59:20 -0700652 Thread::Current()->SetClassLoaderOverride(class_loader);
653
654 jclass c = env_->FindClass("AllFields");
655 ASSERT_TRUE(c != NULL);
656 jobject o = env_->AllocObject(c);
657 ASSERT_TRUE(o != NULL);
658
659 EXPECT_STATIC_PRIMITIVE_FIELD(Boolean, "sZ", "Z", true, false);
660 EXPECT_STATIC_PRIMITIVE_FIELD(Byte, "sB", "B", 1, 2);
661 EXPECT_STATIC_PRIMITIVE_FIELD(Char, "sC", "C", 'a', 'b');
662 EXPECT_STATIC_PRIMITIVE_FIELD(Double, "sD", "D", 1.0, 2.0);
663 EXPECT_STATIC_PRIMITIVE_FIELD(Float, "sF", "F", 1.0, 2.0);
664 EXPECT_STATIC_PRIMITIVE_FIELD(Int, "sI", "I", 1, 2);
665 EXPECT_STATIC_PRIMITIVE_FIELD(Long, "sJ", "J", 1, 2);
666 EXPECT_STATIC_PRIMITIVE_FIELD(Short, "sS", "S", 1, 2);
667
668 EXPECT_PRIMITIVE_FIELD(o, Boolean, "iZ", "Z", true, false);
669 EXPECT_PRIMITIVE_FIELD(o, Byte, "iB", "B", 1, 2);
670 EXPECT_PRIMITIVE_FIELD(o, Char, "iC", "C", 'a', 'b');
671 EXPECT_PRIMITIVE_FIELD(o, Double, "iD", "D", 1.0, 2.0);
672 EXPECT_PRIMITIVE_FIELD(o, Float, "iF", "F", 1.0, 2.0);
673 EXPECT_PRIMITIVE_FIELD(o, Int, "iI", "I", 1, 2);
674 EXPECT_PRIMITIVE_FIELD(o, Long, "iJ", "J", 1, 2);
675 EXPECT_PRIMITIVE_FIELD(o, Short, "iS", "S", 1, 2);
676}
677
678TEST_F(JniInternalTest, GetObjectField_SetObjectField) {
Elliott Hughes90a33692011-08-30 13:27:07 -0700679 UniquePtr<const DexFile> dex(OpenTestDexFile("AllFields"));
Brian Carlstrom8a487412011-08-29 20:08:52 -0700680 const PathClassLoader* class_loader = AllocPathClassLoader(dex.get());
Elliott Hughes885c3bd2011-08-22 16:59:20 -0700681 Thread::Current()->SetClassLoaderOverride(class_loader);
682
683 jclass c = env_->FindClass("AllFields");
684 ASSERT_TRUE(c != NULL);
685 jobject o = env_->AllocObject(c);
686 ASSERT_TRUE(o != NULL);
687
688 jstring s1 = env_->NewStringUTF("hello");
689 ASSERT_TRUE(s1 != NULL);
690 jstring s2 = env_->NewStringUTF("world");
691 ASSERT_TRUE(s2 != NULL);
692
693 jfieldID s_fid = env_->GetStaticFieldID(c, "sObject", "Ljava/lang/Object;");
694 ASSERT_TRUE(s_fid != NULL);
695 jfieldID i_fid = env_->GetFieldID(c, "iObject", "Ljava/lang/Object;");
696 ASSERT_TRUE(i_fid != NULL);
697
698 env_->SetStaticObjectField(c, s_fid, s1);
699 ASSERT_TRUE(env_->IsSameObject(s1, env_->GetStaticObjectField(c, s_fid)));
700 env_->SetStaticObjectField(c, s_fid, s2);
701 ASSERT_TRUE(env_->IsSameObject(s2, env_->GetStaticObjectField(c, s_fid)));
702
703 env_->SetObjectField(o, i_fid, s1);
704 ASSERT_TRUE(env_->IsSameObject(s1, env_->GetObjectField(o, i_fid)));
705 env_->SetObjectField(o, i_fid, s2);
706 ASSERT_TRUE(env_->IsSameObject(s2, env_->GetObjectField(o, i_fid)));
707}
708
Elliott Hughes18c07532011-08-18 15:50:51 -0700709TEST_F(JniInternalTest, NewLocalRef_NULL) {
710 EXPECT_TRUE(env_->NewLocalRef(NULL) == NULL);
711}
712
713TEST_F(JniInternalTest, NewLocalRef) {
714 jstring s = env_->NewStringUTF("");
715 ASSERT_TRUE(s != NULL);
716 jobject o = env_->NewLocalRef(s);
717 EXPECT_TRUE(o != NULL);
718 EXPECT_TRUE(o != s);
719
720 // TODO: check that o is a local reference.
721}
722
723TEST_F(JniInternalTest, DeleteLocalRef_NULL) {
724 env_->DeleteLocalRef(NULL);
725}
726
727TEST_F(JniInternalTest, DeleteLocalRef) {
728 jstring s = env_->NewStringUTF("");
729 ASSERT_TRUE(s != NULL);
730 env_->DeleteLocalRef(s);
731
732 // Currently, deleting an already-deleted reference is just a warning.
Elliott Hughesa2501992011-08-26 19:39:54 -0700733 vm_->check_jni_abort_hook = TestCheckJniAbortHook;
Elliott Hughes18c07532011-08-18 15:50:51 -0700734 env_->DeleteLocalRef(s);
Elliott Hughesa2501992011-08-26 19:39:54 -0700735 vm_->check_jni_abort_hook = NULL;
Elliott Hughes18c07532011-08-18 15:50:51 -0700736
737 s = env_->NewStringUTF("");
738 ASSERT_TRUE(s != NULL);
739 jobject o = env_->NewLocalRef(s);
740 ASSERT_TRUE(o != NULL);
741
742 env_->DeleteLocalRef(s);
743 env_->DeleteLocalRef(o);
744}
745
746TEST_F(JniInternalTest, NewGlobalRef_NULL) {
747 EXPECT_TRUE(env_->NewGlobalRef(NULL) == NULL);
748}
749
750TEST_F(JniInternalTest, NewGlobalRef) {
751 jstring s = env_->NewStringUTF("");
752 ASSERT_TRUE(s != NULL);
753 jobject o = env_->NewGlobalRef(s);
754 EXPECT_TRUE(o != NULL);
755 EXPECT_TRUE(o != s);
756
757 // TODO: check that o is a global reference.
758}
759
760TEST_F(JniInternalTest, DeleteGlobalRef_NULL) {
761 env_->DeleteGlobalRef(NULL);
762}
763
764TEST_F(JniInternalTest, DeleteGlobalRef) {
765 jstring s = env_->NewStringUTF("");
766 ASSERT_TRUE(s != NULL);
767
768 jobject o = env_->NewGlobalRef(s);
769 ASSERT_TRUE(o != NULL);
770 env_->DeleteGlobalRef(o);
771
Elliott Hughesa2501992011-08-26 19:39:54 -0700772 vm_->check_jni_abort_hook = TestCheckJniAbortHook;
Elliott Hughes18c07532011-08-18 15:50:51 -0700773 // Currently, deleting an already-deleted reference is just a warning.
774 env_->DeleteGlobalRef(o);
Elliott Hughesa2501992011-08-26 19:39:54 -0700775 vm_->check_jni_abort_hook = NULL;
Elliott Hughes18c07532011-08-18 15:50:51 -0700776
777 jobject o1 = env_->NewGlobalRef(s);
778 ASSERT_TRUE(o1 != NULL);
779 jobject o2 = env_->NewGlobalRef(s);
780 ASSERT_TRUE(o2 != NULL);
781
782 env_->DeleteGlobalRef(o1);
783 env_->DeleteGlobalRef(o2);
784}
785
786TEST_F(JniInternalTest, NewWeakGlobalRef_NULL) {
787 EXPECT_TRUE(env_->NewWeakGlobalRef(NULL) == NULL);
788}
789
790TEST_F(JniInternalTest, NewWeakGlobalRef) {
791 jstring s = env_->NewStringUTF("");
792 ASSERT_TRUE(s != NULL);
793 jobject o = env_->NewWeakGlobalRef(s);
794 EXPECT_TRUE(o != NULL);
795 EXPECT_TRUE(o != s);
796
797 // TODO: check that o is a weak global reference.
798}
799
800TEST_F(JniInternalTest, DeleteWeakGlobalRef_NULL) {
801 env_->DeleteWeakGlobalRef(NULL);
802}
803
804TEST_F(JniInternalTest, DeleteWeakGlobalRef) {
805 jstring s = env_->NewStringUTF("");
806 ASSERT_TRUE(s != NULL);
807
808 jobject o = env_->NewWeakGlobalRef(s);
809 ASSERT_TRUE(o != NULL);
810 env_->DeleteWeakGlobalRef(o);
811
Elliott Hughesa2501992011-08-26 19:39:54 -0700812 vm_->check_jni_abort_hook = TestCheckJniAbortHook;
Elliott Hughes18c07532011-08-18 15:50:51 -0700813 // Currently, deleting an already-deleted reference is just a warning.
814 env_->DeleteWeakGlobalRef(o);
Elliott Hughesa2501992011-08-26 19:39:54 -0700815 vm_->check_jni_abort_hook = NULL;
Elliott Hughes18c07532011-08-18 15:50:51 -0700816
817 jobject o1 = env_->NewWeakGlobalRef(s);
818 ASSERT_TRUE(o1 != NULL);
819 jobject o2 = env_->NewWeakGlobalRef(s);
820 ASSERT_TRUE(o2 != NULL);
821
822 env_->DeleteWeakGlobalRef(o1);
823 env_->DeleteWeakGlobalRef(o2);
824}
825
Elliott Hughes79082e32011-08-25 12:07:32 -0700826void EnsureInvokeStub(Method* method);
Carl Shapiro9b9ba282011-08-14 15:30:39 -0700827
Carl Shapiro9b9ba282011-08-14 15:30:39 -0700828Method::InvokeStub* AllocateStub(Method* method,
829 byte* code,
830 size_t length) {
831 CHECK(method->GetInvokeStub() == NULL);
832 EnsureInvokeStub(method);
833 Method::InvokeStub* stub = method->GetInvokeStub();
834 CHECK(stub != NULL);
buzbeec143c552011-08-20 17:38:58 -0700835 method->SetCode(code, length, kThumb2);
Carl Shapiro9b9ba282011-08-14 15:30:39 -0700836 return stub;
837}
838
Carl Shapiro9b9ba282011-08-14 15:30:39 -0700839#if defined(__arm__)
840TEST_F(JniInternalTest, StaticMainMethod) {
Elliott Hughes90a33692011-08-30 13:27:07 -0700841 UniquePtr<const DexFile> dex(OpenTestDexFile("Main"));
Carl Shapiro9b9ba282011-08-14 15:30:39 -0700842
Brian Carlstrom8a487412011-08-29 20:08:52 -0700843 const PathClassLoader* class_loader = AllocPathClassLoader(dex.get());
Carl Shapiro9b9ba282011-08-14 15:30:39 -0700844 ASSERT_TRUE(class_loader != NULL);
845
846 Class* klass = class_linker_->FindClass("LMain;", class_loader);
847 ASSERT_TRUE(klass != NULL);
848
849 Method* method = klass->FindDirectMethod("main", "([Ljava/lang/String;)V");
850 ASSERT_TRUE(method != NULL);
851
852 byte main_LV_code[] = {
853 0x2d, 0xe9, 0x00, 0x40, 0x83, 0xb0, 0xcd, 0xf8, 0x00, 0x00,
854 0xcd, 0xf8, 0x14, 0x10, 0x03, 0xb0, 0xbd, 0xe8, 0x00, 0x80,
855 };
856
857 Method::InvokeStub* stub = AllocateStub(method,
858 main_LV_code,
859 sizeof(main_LV_code));
860
861 Object* arg = NULL;
862
863 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(&arg), NULL);
Carl Shapiro9b9ba282011-08-14 15:30:39 -0700864}
865
866TEST_F(JniInternalTest, StaticNopMethod) {
Elliott Hughes90a33692011-08-30 13:27:07 -0700867 UniquePtr<const DexFile> dex(OpenTestDexFile("StaticLeafMethods"));
Carl Shapiro9b9ba282011-08-14 15:30:39 -0700868
Brian Carlstrom8a487412011-08-29 20:08:52 -0700869 const PathClassLoader* class_loader = AllocPathClassLoader(dex.get());
Carl Shapiro9b9ba282011-08-14 15:30:39 -0700870 ASSERT_TRUE(class_loader != NULL);
871
872 Class* klass = class_linker_->FindClass("LStaticLeafMethods;", class_loader);
873 ASSERT_TRUE(klass != NULL);
874
875 Method* method = klass->FindDirectMethod("nop", "()V");
876 ASSERT_TRUE(method != NULL);
877
878 byte nop_V_code[] = {
879 0x2d, 0xe9, 0x00, 0x40, 0x83, 0xb0, 0xcd, 0xf8,
880 0x00, 0x00, 0x03, 0xb0, 0xbd, 0xe8, 0x00, 0x80,
881 };
882
883 Method::InvokeStub* stub = AllocateStub(method,
884 nop_V_code,
885 sizeof(nop_V_code));
886 ASSERT_TRUE(stub);
887
888 (*stub)(method, NULL, NULL, NULL, NULL);
Carl Shapiro9b9ba282011-08-14 15:30:39 -0700889}
890
891TEST_F(JniInternalTest, StaticIdentityByteMethod) {
Elliott Hughes90a33692011-08-30 13:27:07 -0700892 UniquePtr<const DexFile> dex(OpenTestDexFile("StaticLeafMethods"));
Carl Shapiro9b9ba282011-08-14 15:30:39 -0700893
Brian Carlstrom8a487412011-08-29 20:08:52 -0700894 const PathClassLoader* class_loader = AllocPathClassLoader(dex.get());
Carl Shapiro9b9ba282011-08-14 15:30:39 -0700895 ASSERT_TRUE(class_loader != NULL);
896
897 Class* klass = class_linker_->FindClass("LStaticLeafMethods;", class_loader);
898 ASSERT_TRUE(klass != NULL);
899
900 Method* method = klass->FindDirectMethod("identity", "(B)B");
901 ASSERT_TRUE(method != NULL);
902
903 byte identity_BB_code[] = {
904 0x2d, 0xe9, 0x00, 0x40, 0x83, 0xb0, 0xcd, 0xf8,
905 0x00, 0x00, 0xcd, 0xf8, 0x14, 0x10, 0x05, 0x98,
906 0x03, 0xb0, 0xbd, 0xe8, 0x00, 0x80, 0x00, 0x00,
907 };
908
909 Method::InvokeStub* stub = AllocateStub(method,
910 identity_BB_code,
911 sizeof(identity_BB_code));
912
913 int arg;
914 JValue result;
915
916 arg = 0;
917 result.b = -1;
918 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(&arg), &result);
919 EXPECT_EQ(0, result.b);
920
921 arg = -1;
922 result.b = 0;
923 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(&arg), &result);
924 EXPECT_EQ(-1, result.b);
925
926 arg = SCHAR_MAX;
927 result.b = 0;
928 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(&arg), &result);
929 EXPECT_EQ(SCHAR_MAX, result.b);
930
931 arg = SCHAR_MIN;
932 result.b = 0;
933 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(&arg), &result);
934 EXPECT_EQ(SCHAR_MIN, result.b);
Carl Shapiro9b9ba282011-08-14 15:30:39 -0700935}
936
937TEST_F(JniInternalTest, StaticIdentityIntMethod) {
Elliott Hughes90a33692011-08-30 13:27:07 -0700938 UniquePtr<const DexFile> dex(OpenTestDexFile("StaticLeafMethods"));
Carl Shapiro9b9ba282011-08-14 15:30:39 -0700939
Brian Carlstrom8a487412011-08-29 20:08:52 -0700940 const PathClassLoader* class_loader = AllocPathClassLoader(dex.get());
Carl Shapiro9b9ba282011-08-14 15:30:39 -0700941 ASSERT_TRUE(class_loader != NULL);
942
943 Class* klass = class_linker_->FindClass("LStaticLeafMethods;", class_loader);
944 ASSERT_TRUE(klass != NULL);
945
946 Method* method = klass->FindDirectMethod("identity", "(I)I");
947 ASSERT_TRUE(method != NULL);
948
949 byte identity_II_code[] = {
950 0x2d, 0xe9, 0x00, 0x40, 0x83, 0xb0, 0xcd, 0xf8,
951 0x00, 0x00, 0xcd, 0xf8, 0x14, 0x10, 0x05, 0x98,
952 0x03, 0xb0, 0xbd, 0xe8, 0x00, 0x80, 0x00, 0x00,
953 };
954
955 Method::InvokeStub* stub = AllocateStub(method,
956 identity_II_code,
957 sizeof(identity_II_code));
958
959 int arg;
960 JValue result;
961
962 arg = 0;
963 result.i = -1;
964 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(&arg), &result);
965 EXPECT_EQ(0, result.i);
966
967 arg = -1;
968 result.i = 0;
969 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(&arg), &result);
970 EXPECT_EQ(-1, result.i);
971
972 arg = INT_MAX;
973 result.i = 0;
974 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(&arg), &result);
975 EXPECT_EQ(INT_MAX, result.i);
976
977 arg = INT_MIN;
978 result.i = 0;
979 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(&arg), &result);
980 EXPECT_EQ(INT_MIN, result.i);
Carl Shapiro9b9ba282011-08-14 15:30:39 -0700981}
982
983TEST_F(JniInternalTest, StaticIdentityDoubleMethod) {
Elliott Hughes90a33692011-08-30 13:27:07 -0700984 UniquePtr<const DexFile> dex(OpenTestDexFile("StaticLeafMethods"));
Carl Shapiro9b9ba282011-08-14 15:30:39 -0700985
Brian Carlstrom8a487412011-08-29 20:08:52 -0700986 const PathClassLoader* class_loader = AllocPathClassLoader(dex.get());
Carl Shapiro9b9ba282011-08-14 15:30:39 -0700987 ASSERT_TRUE(class_loader != NULL);
988
989 Class* klass = class_linker_->FindClass("LStaticLeafMethods;", class_loader);
990 ASSERT_TRUE(klass != NULL);
991
992 Method* method = klass->FindDirectMethod("identity", "(D)D");
993 ASSERT_TRUE(method != NULL);
994
995 byte identity_DD_code[] = {
996 0x2d, 0xe9, 0x00, 0x40, 0x83, 0xb0, 0xcd, 0xf8,
997 0x00, 0x00, 0xcd, 0xf8, 0x14, 0x10, 0xcd, 0xf8,
998 0x18, 0x20, 0x05, 0x98, 0x06, 0x99, 0x03, 0xb0,
999 0xbd, 0xe8, 0x00, 0x80,
1000 };
1001
1002 Method::InvokeStub* stub = AllocateStub(method,
1003 identity_DD_code,
1004 sizeof(identity_DD_code));
1005
1006 double arg;
1007 JValue result;
1008
1009 arg = 0.0;
1010 result.d = -1.0;
1011 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(&arg), &result);
1012 EXPECT_EQ(0.0, result.d);
1013
1014 arg = -1.0;
1015 result.d = 0.0;
1016 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(&arg), &result);
1017 EXPECT_EQ(-1.0, result.d);
1018
1019 arg = DBL_MAX;
1020 result.d = 0.0;
1021 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(&arg), &result);
1022 EXPECT_EQ(DBL_MAX, result.d);
1023
1024 arg = DBL_MIN;
1025 result.d = 0.0;
1026 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(&arg), &result);
1027 EXPECT_EQ(DBL_MIN, result.d);
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001028}
1029
1030TEST_F(JniInternalTest, StaticSumIntIntMethod) {
Elliott Hughes90a33692011-08-30 13:27:07 -07001031 UniquePtr<const DexFile> dex(OpenTestDexFile("StaticLeafMethods"));
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001032
Brian Carlstrom8a487412011-08-29 20:08:52 -07001033 const PathClassLoader* class_loader = AllocPathClassLoader(dex.get());
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001034 ASSERT_TRUE(class_loader != NULL);
1035
1036 Class* klass = class_linker_->FindClass("LStaticLeafMethods;", class_loader);
1037 ASSERT_TRUE(klass != NULL);
1038
1039 Method* method = klass->FindDirectMethod("sum", "(II)I");
1040 ASSERT_TRUE(method != NULL);
1041
1042 byte sum_III_code[] = {
1043 0x2d, 0xe9, 0x00, 0x40, 0x83, 0xb0, 0xcd, 0xf8,
1044 0x00, 0x00, 0xcd, 0xf8, 0x14, 0x10, 0xcd, 0xf8,
1045 0x18, 0x20, 0x05, 0x98, 0x06, 0x99, 0x42, 0x18,
1046 0xcd, 0xf8, 0x04, 0x20, 0x01, 0x98, 0x03, 0xb0,
1047 0xbd, 0xe8, 0x00, 0x80,
1048 };
1049
1050 Method::InvokeStub* stub = AllocateStub(method,
1051 sum_III_code,
1052 sizeof(sum_III_code));
1053
1054 int args[2];
1055 JValue result;
1056
1057 args[0] = 0;
1058 args[1] = 0;
1059 result.i = -1;
1060 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
1061 EXPECT_EQ(0, result.i);
1062
1063 args[0] = 1;
1064 args[1] = 2;
1065 result.i = 0;
1066 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
1067 EXPECT_EQ(3, result.i);
1068
1069 args[0] = -2;
1070 args[1] = 5;
1071 result.i = 0;
1072 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
1073 EXPECT_EQ(3, result.i);
1074
1075 args[0] = INT_MAX;
1076 args[1] = INT_MIN;
1077 result.i = 1234;
1078 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
1079 EXPECT_EQ(-1, result.i);
1080
1081 args[0] = INT_MAX;
1082 args[1] = INT_MAX;
1083 result.i = INT_MIN;
1084 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
1085 EXPECT_EQ(-2, result.i);
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001086}
1087
1088TEST_F(JniInternalTest, StaticSumIntIntIntMethod) {
Elliott Hughes90a33692011-08-30 13:27:07 -07001089 UniquePtr<const DexFile> dex(OpenTestDexFile("StaticLeafMethods"));
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001090
Brian Carlstrom8a487412011-08-29 20:08:52 -07001091 const PathClassLoader* class_loader = AllocPathClassLoader(dex.get());
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001092 ASSERT_TRUE(class_loader != NULL);
1093
1094 Class* klass = class_linker_->FindClass("LStaticLeafMethods;", class_loader);
1095 ASSERT_TRUE(klass != NULL);
1096
1097 Method* method = klass->FindDirectMethod("sum", "(III)I");
1098 ASSERT_TRUE(method != NULL);
1099
1100 byte sum_IIII_code[] = {
1101 0x2d, 0xe9, 0x00, 0x40, 0x83, 0xb0, 0xcd, 0xf8,
1102 0x00, 0x00, 0xcd, 0xf8, 0x14, 0x10, 0xcd, 0xf8,
1103 0x18, 0x20, 0xcd, 0xf8, 0x1c, 0x30, 0x05, 0x98,
1104 0x06, 0x99, 0x42, 0x18, 0xcd, 0xf8, 0x04, 0x20,
1105 0x01, 0x9b, 0xdd, 0xf8, 0x1c, 0xc0, 0x13, 0xeb,
1106 0x0c, 0x03, 0xcd, 0xf8, 0x04, 0x30, 0x01, 0x98,
1107 0x03, 0xb0, 0xbd, 0xe8, 0x00, 0x80, 0x00, 0x00,
1108 };
1109
1110 Method::InvokeStub* stub = AllocateStub(method,
1111 sum_IIII_code,
1112 sizeof(sum_IIII_code));
1113
1114 int args[3];
1115 JValue result;
1116
1117 args[0] = 0;
1118 args[1] = 0;
1119 args[2] = 0;
1120 result.i = -1;
1121 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
1122 EXPECT_EQ(0, result.i);
1123
1124 args[0] = 1;
1125 args[1] = 2;
1126 args[2] = 3;
1127 result.i = 0;
1128 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
1129 EXPECT_EQ(6, result.i);
1130
1131 args[0] = -1;
1132 args[1] = 2;
1133 args[2] = -3;
1134 result.i = 0;
1135 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
1136 EXPECT_EQ(-2, result.i);
1137
1138 args[0] = INT_MAX;
1139 args[1] = INT_MIN;
1140 args[2] = INT_MAX;
1141 result.i = 1234;
1142 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
1143 EXPECT_EQ(2147483646, result.i);
1144
1145 args[0] = INT_MAX;
1146 args[1] = INT_MAX;
1147 args[2] = INT_MAX;
1148 result.i = INT_MIN;
1149 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
1150 EXPECT_EQ(2147483645, result.i);
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001151}
1152
1153TEST_F(JniInternalTest, StaticSumIntIntIntIntMethod) {
Elliott Hughes90a33692011-08-30 13:27:07 -07001154 UniquePtr<const DexFile> dex(OpenTestDexFile("StaticLeafMethods"));
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001155
Brian Carlstrom8a487412011-08-29 20:08:52 -07001156 const PathClassLoader* class_loader = AllocPathClassLoader(dex.get());
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001157 ASSERT_TRUE(class_loader != NULL);
1158
1159 Class* klass = class_linker_->FindClass("LStaticLeafMethods;", class_loader);
1160 ASSERT_TRUE(klass != NULL);
1161
1162 Method* method = klass->FindDirectMethod("sum", "(IIII)I");
1163 ASSERT_TRUE(method != NULL);
1164
1165 byte sum_IIIII_code[] = {
1166 0x2d, 0xe9, 0x00, 0x40, 0x83, 0xb0, 0xcd, 0xf8,
1167 0x00, 0x00, 0xcd, 0xf8, 0x14, 0x10, 0xcd, 0xf8,
1168 0x18, 0x20, 0xcd, 0xf8, 0x1c, 0x30, 0x05, 0x98,
1169 0x06, 0x99, 0x42, 0x18, 0xcd, 0xf8, 0x04, 0x20,
1170 0x01, 0x9b, 0xdd, 0xf8, 0x1c, 0xc0, 0x13, 0xeb,
1171 0x0c, 0x03, 0xcd, 0xf8, 0x04, 0x30, 0x01, 0x98,
1172 0x08, 0x99, 0x40, 0x18, 0xcd, 0xf8, 0x04, 0x00,
1173 0x01, 0x98, 0x03, 0xb0, 0xbd, 0xe8, 0x00, 0x80,
1174 };
1175
1176 Method::InvokeStub* stub = AllocateStub(method,
1177 sum_IIIII_code,
1178 sizeof(sum_IIIII_code));
1179
1180 int args[4];
1181 JValue result;
1182
1183 args[0] = 0;
1184 args[1] = 0;
1185 args[2] = 0;
1186 args[3] = 0;
1187 result.i = -1;
1188 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
1189 EXPECT_EQ(0, result.i);
1190
1191 args[0] = 1;
1192 args[1] = 2;
1193 args[2] = 3;
1194 args[3] = 4;
1195 result.i = 0;
1196 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
1197 EXPECT_EQ(10, result.i);
1198
1199 args[0] = -1;
1200 args[1] = 2;
1201 args[2] = -3;
1202 args[3] = 4;
1203 result.i = 0;
1204 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
1205 EXPECT_EQ(2, result.i);
1206
1207 args[0] = INT_MAX;
1208 args[1] = INT_MIN;
1209 args[2] = INT_MAX;
1210 args[3] = INT_MIN;
1211 result.i = 1234;
1212 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
1213 EXPECT_EQ(-2, result.i);
1214
1215 args[0] = INT_MAX;
1216 args[1] = INT_MAX;
1217 args[2] = INT_MAX;
1218 args[3] = INT_MAX;
1219 result.i = INT_MIN;
1220 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
1221 EXPECT_EQ(-4, result.i);
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001222}
1223
1224TEST_F(JniInternalTest, StaticSumIntIntIntIntIntMethod) {
Elliott Hughes90a33692011-08-30 13:27:07 -07001225 UniquePtr<const DexFile> dex(OpenTestDexFile("StaticLeafMethods"));
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001226
Brian Carlstrom8a487412011-08-29 20:08:52 -07001227 const PathClassLoader* class_loader = AllocPathClassLoader(dex.get());
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001228 ASSERT_TRUE(class_loader != NULL);
1229
1230 Class* klass = class_linker_->FindClass("LStaticLeafMethods;", class_loader);
1231 ASSERT_TRUE(klass != NULL);
1232
1233 Method* method = klass->FindDirectMethod("sum", "(IIIII)I");
1234 ASSERT_TRUE(method != NULL);
1235
1236 byte sum_IIIIII_code[] = {
1237 0x2d, 0xe9, 0x00, 0x40, 0x83, 0xb0, 0xcd, 0xf8,
1238 0x00, 0x00, 0xcd, 0xf8, 0x14, 0x10, 0xcd, 0xf8,
1239 0x18, 0x20, 0xcd, 0xf8, 0x1c, 0x30, 0x05, 0x98,
1240 0x06, 0x99, 0x42, 0x18, 0xcd, 0xf8, 0x04, 0x20,
1241 0x01, 0x9b, 0xdd, 0xf8, 0x1c, 0xc0, 0x13, 0xeb,
1242 0x0c, 0x03, 0xcd, 0xf8, 0x04, 0x30, 0x01, 0x98,
1243 0x08, 0x99, 0x40, 0x18, 0xcd, 0xf8, 0x04, 0x00,
1244 0x01, 0x9a, 0x09, 0x9b, 0xd2, 0x18, 0xcd, 0xf8,
1245 0x04, 0x20, 0x01, 0x98, 0x03, 0xb0, 0xbd, 0xe8,
1246 0x00, 0x80, 0x00, 0x00,
1247 };
1248
1249 Method::InvokeStub* stub = AllocateStub(method,
1250 sum_IIIIII_code,
1251 sizeof(sum_IIIIII_code));
1252
1253 int args[5];
1254 JValue result;
1255
1256 args[0] = 0;
1257 args[1] = 0;
1258 args[2] = 0;
1259 args[3] = 0;
1260 args[4] = 0;
1261 result.i = -1.0;
1262 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
1263 EXPECT_EQ(0, result.i);
1264
1265 args[0] = 1;
1266 args[1] = 2;
1267 args[2] = 3;
1268 args[3] = 4;
1269 args[4] = 5;
1270 result.i = 0;
1271 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
1272 EXPECT_EQ(15, result.i);
1273
1274 args[0] = -1;
1275 args[1] = 2;
1276 args[2] = -3;
1277 args[3] = 4;
1278 args[4] = -5;
1279 result.i = 0;
1280 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
1281 EXPECT_EQ(-3, result.i);
1282
1283 args[0] = INT_MAX;
1284 args[1] = INT_MIN;
1285 args[2] = INT_MAX;
1286 args[3] = INT_MIN;
1287 args[4] = INT_MAX;
1288 result.i = 1234;
1289 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
1290 EXPECT_EQ(2147483645, result.i);
1291
1292 args[0] = INT_MAX;
1293 args[1] = INT_MAX;
1294 args[2] = INT_MAX;
1295 args[3] = INT_MAX;
1296 args[4] = INT_MAX;
1297 result.i = INT_MIN;
1298 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
1299 EXPECT_EQ(2147483643, result.i);
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001300}
1301
1302TEST_F(JniInternalTest, StaticSumDoubleDoubleMethod) {
Elliott Hughes90a33692011-08-30 13:27:07 -07001303 UniquePtr<const DexFile> dex(OpenTestDexFile("StaticLeafMethods"));
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001304
Brian Carlstrom8a487412011-08-29 20:08:52 -07001305 const PathClassLoader* class_loader = AllocPathClassLoader(dex.get());
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001306 ASSERT_TRUE(class_loader != NULL);
1307
1308 Class* klass = class_linker_->FindClass("LStaticLeafMethods;", class_loader);
1309 ASSERT_TRUE(klass != NULL);
1310
1311 Method* method = klass->FindDirectMethod("sum", "(DD)D");
1312 ASSERT_TRUE(method != NULL);
1313
1314 byte sum_DDD_code[] = {
1315 0x2d, 0xe9, 0x00, 0x40, 0x87, 0xb0, 0xcd, 0xf8,
1316 0x00, 0x00, 0xcd, 0xf8, 0x24, 0x10, 0xcd, 0xf8,
1317 0x28, 0x20, 0xcd, 0xf8, 0x2c, 0x30, 0x9d, 0xed,
1318 0x09, 0x0b, 0x9d, 0xed, 0x0b, 0x1b, 0x30, 0xee,
1319 0x01, 0x2b, 0x8d, 0xed, 0x04, 0x2b, 0x04, 0x98,
1320 0x05, 0x99, 0x07, 0xb0, 0xbd, 0xe8, 0x00, 0x80,
1321 };
1322
1323 Method::InvokeStub* stub = AllocateStub(method,
1324 sum_DDD_code,
1325 sizeof(sum_DDD_code));
1326
1327 double args[2];
1328 JValue result;
1329
1330 args[0] = 0.0;
1331 args[1] = 0.0;
1332 result.d = -1.0;
1333 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
1334 EXPECT_EQ(0.0, result.d);
1335
1336 args[0] = 1.0;
1337 args[1] = 2.0;
1338 result.d = 0.0;
1339 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
1340 EXPECT_EQ(3.0, result.d);
1341
1342 args[0] = 1.0;
1343 args[1] = -2.0;
1344 result.d = 0.0;
1345 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
1346 EXPECT_EQ(-1.0, result.d);
1347
1348 args[0] = DBL_MAX;
1349 args[1] = DBL_MIN;
1350 result.d = 0.0;
1351 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
1352 EXPECT_EQ(1.7976931348623157e308, result.d);
1353
1354 args[0] = DBL_MAX;
1355 args[1] = DBL_MAX;
1356 result.d = 0.0;
1357 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
1358 EXPECT_EQ(INFINITY, result.d);
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001359}
1360
1361TEST_F(JniInternalTest, StaticSumDoubleDoubleDoubleMethod) {
Elliott Hughes90a33692011-08-30 13:27:07 -07001362 UniquePtr<const DexFile> dex(OpenTestDexFile("StaticLeafMethods"));
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001363
Brian Carlstrom8a487412011-08-29 20:08:52 -07001364 const PathClassLoader* class_loader = AllocPathClassLoader(dex.get());
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001365 ASSERT_TRUE(class_loader != NULL);
1366
1367 Class* klass = class_linker_->FindClass("LStaticLeafMethods;", class_loader);
1368 ASSERT_TRUE(klass != NULL);
1369
1370 Method* method = klass->FindDirectMethod("sum", "(DDD)D");
1371 ASSERT_TRUE(method != NULL);
1372
1373 byte sum_DDDD_code[] = {
1374 0x2d, 0xe9, 0x00, 0x40, 0x87, 0xb0, 0xcd, 0xf8,
1375 0x00, 0x00, 0xcd, 0xf8, 0x24, 0x10, 0xcd, 0xf8,
1376 0x28, 0x20, 0xcd, 0xf8, 0x2c, 0x30, 0x9d, 0xed,
1377 0x09, 0x0b, 0x9d, 0xed, 0x0b, 0x1b, 0x30, 0xee,
1378 0x01, 0x2b, 0x8d, 0xed, 0x04, 0x2b, 0x9d, 0xed,
1379 0x04, 0x3b, 0x9d, 0xed, 0x0d, 0x4b, 0x33, 0xee,
1380 0x04, 0x3b, 0x8d, 0xed, 0x04, 0x3b, 0x04, 0x98,
1381 0x05, 0x99, 0x07, 0xb0, 0xbd, 0xe8, 0x00, 0x80,
1382 };
1383
1384 Method::InvokeStub* stub = AllocateStub(method,
1385 sum_DDDD_code,
1386 sizeof(sum_DDDD_code));
1387
1388 double args[3];
1389 JValue result;
1390
1391 args[0] = 0.0;
1392 args[1] = 0.0;
1393 args[2] = 0.0;
1394 result.d = -1.0;
1395 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
1396 EXPECT_EQ(0.0, result.d);
1397
1398 args[0] = 1.0;
1399 args[1] = 2.0;
1400 args[2] = 3.0;
1401 result.d = 0.0;
1402 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
1403 EXPECT_EQ(6.0, result.d);
1404
1405 args[0] = 1.0;
1406 args[1] = -2.0;
1407 args[2] = 3.0;
1408 result.d = 0.0;
1409 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
1410 EXPECT_EQ(2.0, result.d);
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001411}
1412
1413TEST_F(JniInternalTest, StaticSumDoubleDoubleDoubleDoubleMethod) {
Elliott Hughes90a33692011-08-30 13:27:07 -07001414 UniquePtr<const DexFile> dex(OpenTestDexFile("StaticLeafMethods"));
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001415
Brian Carlstrom8a487412011-08-29 20:08:52 -07001416 const PathClassLoader* class_loader = AllocPathClassLoader(dex.get());
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001417 ASSERT_TRUE(class_loader != NULL);
1418
1419 Class* klass = class_linker_->FindClass("LStaticLeafMethods;", class_loader);
1420 ASSERT_TRUE(klass != NULL);
1421
1422 Method* method = klass->FindDirectMethod("sum", "(DDDD)D");
1423 ASSERT_TRUE(method != NULL);
1424
1425 byte sum_DDDDD_code[] = {
1426 0x2d, 0xe9, 0x00, 0x40, 0x87, 0xb0, 0xcd, 0xf8,
1427 0x00, 0x00, 0xcd, 0xf8, 0x24, 0x10, 0xcd, 0xf8,
1428 0x28, 0x20, 0xcd, 0xf8, 0x2c, 0x30, 0x9d, 0xed,
1429 0x09, 0x0b, 0x9d, 0xed, 0x0b, 0x1b, 0x30, 0xee,
1430 0x01, 0x2b, 0x8d, 0xed, 0x04, 0x2b, 0x9d, 0xed,
1431 0x04, 0x3b, 0x9d, 0xed, 0x0d, 0x4b, 0x33, 0xee,
1432 0x04, 0x3b, 0x8d, 0xed, 0x04, 0x3b, 0x9d, 0xed,
1433 0x04, 0x5b, 0x9d, 0xed, 0x0f, 0x6b, 0x35, 0xee,
1434 0x06, 0x5b, 0x8d, 0xed, 0x04, 0x5b, 0x04, 0x98,
1435 0x05, 0x99, 0x07, 0xb0, 0xbd, 0xe8, 0x00, 0x80,
1436 };
1437
1438 Method::InvokeStub* stub = AllocateStub(method,
1439 sum_DDDDD_code,
1440 sizeof(sum_DDDDD_code));
1441
1442 double args[4];
1443 JValue result;
1444
1445 args[0] = 0.0;
1446 args[1] = 0.0;
1447 args[2] = 0.0;
1448 args[3] = 0.0;
1449 result.d = -1.0;
1450 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
1451 EXPECT_EQ(0.0, result.d);
1452
1453 args[0] = 1.0;
1454 args[1] = 2.0;
1455 args[2] = 3.0;
1456 args[3] = 4.0;
1457 result.d = 0.0;
1458 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
1459 EXPECT_EQ(10.0, result.d);
1460
1461 args[0] = 1.0;
1462 args[1] = -2.0;
1463 args[2] = 3.0;
1464 args[3] = -4.0;
1465 result.d = 0.0;
1466 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
1467 EXPECT_EQ(-2.0, result.d);
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001468}
1469
1470TEST_F(JniInternalTest, StaticSumDoubleDoubleDoubleDoubleDoubleMethod) {
Elliott Hughes90a33692011-08-30 13:27:07 -07001471 UniquePtr<const DexFile> dex(OpenTestDexFile("StaticLeafMethods"));
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001472
Brian Carlstrom8a487412011-08-29 20:08:52 -07001473 const PathClassLoader* class_loader = AllocPathClassLoader(dex.get());
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001474 ASSERT_TRUE(class_loader != NULL);
1475
1476 Class* klass = class_linker_->FindClass("LStaticLeafMethods;", class_loader);
1477 ASSERT_TRUE(klass != NULL);
1478
1479 Method* method = klass->FindDirectMethod("sum", "(DDDDD)D");
1480 ASSERT_TRUE(method != NULL);
1481
1482 byte sum_DDDDDD_code[] = {
1483 0x2d, 0xe9, 0x00, 0x40, 0x87, 0xb0, 0xcd, 0xf8,
1484 0x00, 0x00, 0xcd, 0xf8, 0x24, 0x10, 0xcd, 0xf8,
1485 0x28, 0x20, 0xcd, 0xf8, 0x2c, 0x30, 0x9d, 0xed,
1486 0x09, 0x0b, 0x9d, 0xed, 0x0b, 0x1b, 0x30, 0xee,
1487 0x01, 0x2b, 0x8d, 0xed, 0x04, 0x2b, 0x9d, 0xed,
1488 0x04, 0x3b, 0x9d, 0xed, 0x0d, 0x4b, 0x33, 0xee,
1489 0x04, 0x3b, 0x8d, 0xed, 0x04, 0x3b, 0x9d, 0xed,
1490 0x04, 0x5b, 0x9d, 0xed, 0x0f, 0x6b, 0x35, 0xee,
1491 0x06, 0x5b, 0x8d, 0xed, 0x04, 0x5b, 0x9d, 0xed,
1492 0x04, 0x7b, 0x9d, 0xed, 0x11, 0x0b, 0x37, 0xee,
1493 0x00, 0x7b, 0x8d, 0xed, 0x04, 0x7b, 0x04, 0x98,
1494 0x05, 0x99, 0x07, 0xb0, 0xbd, 0xe8, 0x00, 0x80,
1495 };
1496
1497 Method::InvokeStub* stub = AllocateStub(method,
1498 sum_DDDDDD_code,
1499 sizeof(sum_DDDDDD_code));
1500
1501 double args[5];
1502 JValue result;
1503
1504 args[0] = 0.0;
1505 args[1] = 0.0;
1506 args[2] = 0.0;
1507 args[3] = 0.0;
1508 args[4] = 0.0;
1509 result.d = -1.0;
1510 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
1511 EXPECT_EQ(0.0, result.d);
1512
1513 args[0] = 1.0;
1514 args[1] = 2.0;
1515 args[2] = 3.0;
1516 args[3] = 4.0;
1517 args[4] = 5.0;
1518 result.d = 0.0;
1519 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
1520 EXPECT_EQ(15.0, result.d);
1521
1522 args[0] = 1.0;
1523 args[1] = -2.0;
1524 args[2] = 3.0;
1525 args[3] = -4.0;
1526 args[4] = 5.0;
1527 result.d = 0.0;
1528 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
1529 EXPECT_EQ(3.0, result.d);
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001530}
1531#endif // __arm__
1532
Elliott Hughes37f7a402011-08-22 18:56:01 -07001533TEST_F(JniInternalTest, Throw) {
1534 EXPECT_EQ(JNI_ERR, env_->Throw(NULL));
1535
1536 jclass exception_class = env_->FindClass("java/lang/RuntimeException");
1537 ASSERT_TRUE(exception_class != NULL);
1538 jthrowable exception = reinterpret_cast<jthrowable>(env_->AllocObject(exception_class));
1539 ASSERT_TRUE(exception != NULL);
1540
1541 EXPECT_EQ(JNI_OK, env_->Throw(exception));
1542 EXPECT_TRUE(env_->ExceptionCheck());
Elliott Hughesa2501992011-08-26 19:39:54 -07001543 jthrowable thrown_exception = env_->ExceptionOccurred();
Elliott Hughes37f7a402011-08-22 18:56:01 -07001544 env_->ExceptionClear();
Elliott Hughesa2501992011-08-26 19:39:54 -07001545 EXPECT_TRUE(env_->IsSameObject(exception, thrown_exception));
Elliott Hughes37f7a402011-08-22 18:56:01 -07001546}
1547
1548TEST_F(JniInternalTest, ThrowNew) {
1549 EXPECT_EQ(JNI_ERR, env_->Throw(NULL));
1550
1551 jclass exception_class = env_->FindClass("java/lang/RuntimeException");
1552 ASSERT_TRUE(exception_class != NULL);
1553
1554 EXPECT_EQ(JNI_OK, env_->ThrowNew(exception_class, "hello world"));
1555 EXPECT_TRUE(env_->ExceptionCheck());
Elliott Hughesa2501992011-08-26 19:39:54 -07001556 jthrowable thrown_exception = env_->ExceptionOccurred();
Elliott Hughes37f7a402011-08-22 18:56:01 -07001557 env_->ExceptionClear();
Elliott Hughesa2501992011-08-26 19:39:54 -07001558 EXPECT_TRUE(env_->IsInstanceOf(thrown_exception, exception_class));
Elliott Hughes37f7a402011-08-22 18:56:01 -07001559}
1560
Elliott Hughesb465ab02011-08-24 11:21:21 -07001561// TODO: this test is DISABLED until we can actually run java.nio.Buffer's <init>.
1562TEST_F(JniInternalTest, DISABLED_NewDirectBuffer_GetDirectBufferAddress_GetDirectBufferCapacity) {
1563 jclass buffer_class = env_->FindClass("java/nio/Buffer");
1564 ASSERT_TRUE(buffer_class != NULL);
1565
1566 char bytes[1024];
1567 jobject buffer = env_->NewDirectByteBuffer(bytes, sizeof(bytes));
1568 ASSERT_TRUE(buffer != NULL);
1569 ASSERT_TRUE(env_->IsInstanceOf(buffer, buffer_class));
1570 ASSERT_TRUE(env_->GetDirectBufferAddress(buffer) == bytes);
1571 ASSERT_TRUE(env_->GetDirectBufferCapacity(buffer) == sizeof(bytes));
1572}
1573
Ian Rogers0cfe1fb2011-08-26 03:29:44 -07001574} // namespace art