blob: 725d9aa33412b1418e75b468c8612616a73fd1e8 [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) {
Brian Carlstrom5b8e4c82011-09-18 01:38:59 -0700608 jclass c = env_->FindClass("java/lang/Object");
Elliott Hughes289da822011-08-16 10:11:20 -0700609 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) {
Brian Carlstrom9baa4ae2011-09-01 21:14:14 -0700650 LoadDex("AllFields");
Brian Carlstrom25c33252011-09-18 15:58:35 -0700651 runtime_->Start();
Elliott Hughes885c3bd2011-08-22 16:59:20 -0700652
653 jclass c = env_->FindClass("AllFields");
654 ASSERT_TRUE(c != NULL);
655 jobject o = env_->AllocObject(c);
656 ASSERT_TRUE(o != NULL);
657
658 EXPECT_STATIC_PRIMITIVE_FIELD(Boolean, "sZ", "Z", true, false);
659 EXPECT_STATIC_PRIMITIVE_FIELD(Byte, "sB", "B", 1, 2);
660 EXPECT_STATIC_PRIMITIVE_FIELD(Char, "sC", "C", 'a', 'b');
661 EXPECT_STATIC_PRIMITIVE_FIELD(Double, "sD", "D", 1.0, 2.0);
662 EXPECT_STATIC_PRIMITIVE_FIELD(Float, "sF", "F", 1.0, 2.0);
663 EXPECT_STATIC_PRIMITIVE_FIELD(Int, "sI", "I", 1, 2);
664 EXPECT_STATIC_PRIMITIVE_FIELD(Long, "sJ", "J", 1, 2);
665 EXPECT_STATIC_PRIMITIVE_FIELD(Short, "sS", "S", 1, 2);
666
667 EXPECT_PRIMITIVE_FIELD(o, Boolean, "iZ", "Z", true, false);
668 EXPECT_PRIMITIVE_FIELD(o, Byte, "iB", "B", 1, 2);
669 EXPECT_PRIMITIVE_FIELD(o, Char, "iC", "C", 'a', 'b');
670 EXPECT_PRIMITIVE_FIELD(o, Double, "iD", "D", 1.0, 2.0);
671 EXPECT_PRIMITIVE_FIELD(o, Float, "iF", "F", 1.0, 2.0);
672 EXPECT_PRIMITIVE_FIELD(o, Int, "iI", "I", 1, 2);
673 EXPECT_PRIMITIVE_FIELD(o, Long, "iJ", "J", 1, 2);
674 EXPECT_PRIMITIVE_FIELD(o, Short, "iS", "S", 1, 2);
675}
676
677TEST_F(JniInternalTest, GetObjectField_SetObjectField) {
Brian Carlstrom9baa4ae2011-09-01 21:14:14 -0700678 LoadDex("AllFields");
Brian Carlstrom25c33252011-09-18 15:58:35 -0700679 runtime_->Start();
Elliott Hughes885c3bd2011-08-22 16:59:20 -0700680
681 jclass c = env_->FindClass("AllFields");
682 ASSERT_TRUE(c != NULL);
683 jobject o = env_->AllocObject(c);
684 ASSERT_TRUE(o != NULL);
685
686 jstring s1 = env_->NewStringUTF("hello");
687 ASSERT_TRUE(s1 != NULL);
688 jstring s2 = env_->NewStringUTF("world");
689 ASSERT_TRUE(s2 != NULL);
690
691 jfieldID s_fid = env_->GetStaticFieldID(c, "sObject", "Ljava/lang/Object;");
692 ASSERT_TRUE(s_fid != NULL);
693 jfieldID i_fid = env_->GetFieldID(c, "iObject", "Ljava/lang/Object;");
694 ASSERT_TRUE(i_fid != NULL);
695
696 env_->SetStaticObjectField(c, s_fid, s1);
697 ASSERT_TRUE(env_->IsSameObject(s1, env_->GetStaticObjectField(c, s_fid)));
698 env_->SetStaticObjectField(c, s_fid, s2);
699 ASSERT_TRUE(env_->IsSameObject(s2, env_->GetStaticObjectField(c, s_fid)));
700
701 env_->SetObjectField(o, i_fid, s1);
702 ASSERT_TRUE(env_->IsSameObject(s1, env_->GetObjectField(o, i_fid)));
703 env_->SetObjectField(o, i_fid, s2);
704 ASSERT_TRUE(env_->IsSameObject(s2, env_->GetObjectField(o, i_fid)));
705}
706
Elliott Hughes18c07532011-08-18 15:50:51 -0700707TEST_F(JniInternalTest, NewLocalRef_NULL) {
708 EXPECT_TRUE(env_->NewLocalRef(NULL) == NULL);
709}
710
711TEST_F(JniInternalTest, NewLocalRef) {
712 jstring s = env_->NewStringUTF("");
713 ASSERT_TRUE(s != NULL);
714 jobject o = env_->NewLocalRef(s);
715 EXPECT_TRUE(o != NULL);
716 EXPECT_TRUE(o != s);
717
718 // TODO: check that o is a local reference.
719}
720
721TEST_F(JniInternalTest, DeleteLocalRef_NULL) {
722 env_->DeleteLocalRef(NULL);
723}
724
725TEST_F(JniInternalTest, DeleteLocalRef) {
726 jstring s = env_->NewStringUTF("");
727 ASSERT_TRUE(s != NULL);
728 env_->DeleteLocalRef(s);
729
730 // Currently, deleting an already-deleted reference is just a warning.
Elliott Hughesa2501992011-08-26 19:39:54 -0700731 vm_->check_jni_abort_hook = TestCheckJniAbortHook;
Elliott Hughes18c07532011-08-18 15:50:51 -0700732 env_->DeleteLocalRef(s);
Elliott Hughesa2501992011-08-26 19:39:54 -0700733 vm_->check_jni_abort_hook = NULL;
Elliott Hughes18c07532011-08-18 15:50:51 -0700734
735 s = env_->NewStringUTF("");
736 ASSERT_TRUE(s != NULL);
737 jobject o = env_->NewLocalRef(s);
738 ASSERT_TRUE(o != NULL);
739
740 env_->DeleteLocalRef(s);
741 env_->DeleteLocalRef(o);
742}
743
744TEST_F(JniInternalTest, NewGlobalRef_NULL) {
745 EXPECT_TRUE(env_->NewGlobalRef(NULL) == NULL);
746}
747
748TEST_F(JniInternalTest, NewGlobalRef) {
749 jstring s = env_->NewStringUTF("");
750 ASSERT_TRUE(s != NULL);
751 jobject o = env_->NewGlobalRef(s);
752 EXPECT_TRUE(o != NULL);
753 EXPECT_TRUE(o != s);
754
755 // TODO: check that o is a global reference.
756}
757
758TEST_F(JniInternalTest, DeleteGlobalRef_NULL) {
759 env_->DeleteGlobalRef(NULL);
760}
761
762TEST_F(JniInternalTest, DeleteGlobalRef) {
763 jstring s = env_->NewStringUTF("");
764 ASSERT_TRUE(s != NULL);
765
766 jobject o = env_->NewGlobalRef(s);
767 ASSERT_TRUE(o != NULL);
768 env_->DeleteGlobalRef(o);
769
Elliott Hughesa2501992011-08-26 19:39:54 -0700770 vm_->check_jni_abort_hook = TestCheckJniAbortHook;
Elliott Hughes18c07532011-08-18 15:50:51 -0700771 // Currently, deleting an already-deleted reference is just a warning.
772 env_->DeleteGlobalRef(o);
Elliott Hughesa2501992011-08-26 19:39:54 -0700773 vm_->check_jni_abort_hook = NULL;
Elliott Hughes18c07532011-08-18 15:50:51 -0700774
775 jobject o1 = env_->NewGlobalRef(s);
776 ASSERT_TRUE(o1 != NULL);
777 jobject o2 = env_->NewGlobalRef(s);
778 ASSERT_TRUE(o2 != NULL);
779
780 env_->DeleteGlobalRef(o1);
781 env_->DeleteGlobalRef(o2);
782}
783
784TEST_F(JniInternalTest, NewWeakGlobalRef_NULL) {
785 EXPECT_TRUE(env_->NewWeakGlobalRef(NULL) == NULL);
786}
787
788TEST_F(JniInternalTest, NewWeakGlobalRef) {
789 jstring s = env_->NewStringUTF("");
790 ASSERT_TRUE(s != NULL);
791 jobject o = env_->NewWeakGlobalRef(s);
792 EXPECT_TRUE(o != NULL);
793 EXPECT_TRUE(o != s);
794
795 // TODO: check that o is a weak global reference.
796}
797
798TEST_F(JniInternalTest, DeleteWeakGlobalRef_NULL) {
799 env_->DeleteWeakGlobalRef(NULL);
800}
801
802TEST_F(JniInternalTest, DeleteWeakGlobalRef) {
803 jstring s = env_->NewStringUTF("");
804 ASSERT_TRUE(s != NULL);
805
806 jobject o = env_->NewWeakGlobalRef(s);
807 ASSERT_TRUE(o != NULL);
808 env_->DeleteWeakGlobalRef(o);
809
Elliott Hughesa2501992011-08-26 19:39:54 -0700810 vm_->check_jni_abort_hook = TestCheckJniAbortHook;
Elliott Hughes18c07532011-08-18 15:50:51 -0700811 // Currently, deleting an already-deleted reference is just a warning.
812 env_->DeleteWeakGlobalRef(o);
Elliott Hughesa2501992011-08-26 19:39:54 -0700813 vm_->check_jni_abort_hook = NULL;
Elliott Hughes18c07532011-08-18 15:50:51 -0700814
815 jobject o1 = env_->NewWeakGlobalRef(s);
816 ASSERT_TRUE(o1 != NULL);
817 jobject o2 = env_->NewWeakGlobalRef(s);
818 ASSERT_TRUE(o2 != NULL);
819
820 env_->DeleteWeakGlobalRef(o1);
821 env_->DeleteWeakGlobalRef(o2);
822}
823
Carl Shapiro9b9ba282011-08-14 15:30:39 -0700824#if defined(__arm__)
825TEST_F(JniInternalTest, StaticMainMethod) {
Brian Carlstrom9baa4ae2011-09-01 21:14:14 -0700826 const ClassLoader* class_loader = LoadDex("Main");
827 CompileDirectMethod(class_loader, "Main", "main", "([Ljava/lang/String;)V");
Carl Shapiro9b9ba282011-08-14 15:30:39 -0700828
829 Class* klass = class_linker_->FindClass("LMain;", class_loader);
830 ASSERT_TRUE(klass != NULL);
831
832 Method* method = klass->FindDirectMethod("main", "([Ljava/lang/String;)V");
833 ASSERT_TRUE(method != NULL);
834
Brian Carlstrom9baa4ae2011-09-01 21:14:14 -0700835 Method::InvokeStub* stub = method->GetInvokeStub();
Carl Shapiro9b9ba282011-08-14 15:30:39 -0700836
837 Object* arg = NULL;
838
Ian Rogersff1ed472011-09-20 13:46:24 -0700839 (*stub)(method, NULL, Thread::Current(), reinterpret_cast<byte*>(&arg), NULL);
Carl Shapiro9b9ba282011-08-14 15:30:39 -0700840}
841
842TEST_F(JniInternalTest, StaticNopMethod) {
Brian Carlstrom9baa4ae2011-09-01 21:14:14 -0700843 const ClassLoader* class_loader = LoadDex("StaticLeafMethods");
844 CompileDirectMethod(class_loader, "StaticLeafMethods", "nop", "()V");
Carl Shapiro9b9ba282011-08-14 15:30:39 -0700845
846 Class* klass = class_linker_->FindClass("LStaticLeafMethods;", class_loader);
847 ASSERT_TRUE(klass != NULL);
848
849 Method* method = klass->FindDirectMethod("nop", "()V");
850 ASSERT_TRUE(method != NULL);
851
Brian Carlstrom9baa4ae2011-09-01 21:14:14 -0700852 Method::InvokeStub* stub = method->GetInvokeStub();
Carl Shapiro9b9ba282011-08-14 15:30:39 -0700853
Ian Rogersff1ed472011-09-20 13:46:24 -0700854 (*stub)(method, NULL, Thread::Current(), NULL, NULL);
Carl Shapiro9b9ba282011-08-14 15:30:39 -0700855}
856
857TEST_F(JniInternalTest, StaticIdentityByteMethod) {
Brian Carlstrom9baa4ae2011-09-01 21:14:14 -0700858 const ClassLoader* class_loader = LoadDex("StaticLeafMethods");
859 CompileDirectMethod(class_loader, "StaticLeafMethods", "identity", "(B)B");
Carl Shapiro9b9ba282011-08-14 15:30:39 -0700860
861 Class* klass = class_linker_->FindClass("LStaticLeafMethods;", class_loader);
862 ASSERT_TRUE(klass != NULL);
863
864 Method* method = klass->FindDirectMethod("identity", "(B)B");
865 ASSERT_TRUE(method != NULL);
866
Brian Carlstrom9baa4ae2011-09-01 21:14:14 -0700867 Method::InvokeStub* stub = method->GetInvokeStub();
Carl Shapiro9b9ba282011-08-14 15:30:39 -0700868
869 int arg;
870 JValue result;
871
872 arg = 0;
873 result.b = -1;
Ian Rogersff1ed472011-09-20 13:46:24 -0700874 (*stub)(method, NULL, Thread::Current(), reinterpret_cast<byte*>(&arg), &result);
Carl Shapiro9b9ba282011-08-14 15:30:39 -0700875 EXPECT_EQ(0, result.b);
876
877 arg = -1;
878 result.b = 0;
Ian Rogersff1ed472011-09-20 13:46:24 -0700879 (*stub)(method, NULL, Thread::Current(), reinterpret_cast<byte*>(&arg), &result);
Carl Shapiro9b9ba282011-08-14 15:30:39 -0700880 EXPECT_EQ(-1, result.b);
881
882 arg = SCHAR_MAX;
883 result.b = 0;
Ian Rogersff1ed472011-09-20 13:46:24 -0700884 (*stub)(method, NULL, Thread::Current(), reinterpret_cast<byte*>(&arg), &result);
Carl Shapiro9b9ba282011-08-14 15:30:39 -0700885 EXPECT_EQ(SCHAR_MAX, result.b);
886
887 arg = SCHAR_MIN;
888 result.b = 0;
Ian Rogersff1ed472011-09-20 13:46:24 -0700889 (*stub)(method, NULL, Thread::Current(), reinterpret_cast<byte*>(&arg), &result);
Carl Shapiro9b9ba282011-08-14 15:30:39 -0700890 EXPECT_EQ(SCHAR_MIN, result.b);
Carl Shapiro9b9ba282011-08-14 15:30:39 -0700891}
892
893TEST_F(JniInternalTest, StaticIdentityIntMethod) {
Brian Carlstrom9baa4ae2011-09-01 21:14:14 -0700894 const ClassLoader* class_loader = LoadDex("StaticLeafMethods");
895 CompileDirectMethod(class_loader, "StaticLeafMethods", "identity", "(I)I");
Carl Shapiro9b9ba282011-08-14 15:30:39 -0700896
897 Class* klass = class_linker_->FindClass("LStaticLeafMethods;", class_loader);
898 ASSERT_TRUE(klass != NULL);
899
900 Method* method = klass->FindDirectMethod("identity", "(I)I");
901 ASSERT_TRUE(method != NULL);
902
Brian Carlstrom9baa4ae2011-09-01 21:14:14 -0700903 Method::InvokeStub* stub = method->GetInvokeStub();
Carl Shapiro9b9ba282011-08-14 15:30:39 -0700904
905 int arg;
906 JValue result;
907
908 arg = 0;
909 result.i = -1;
Ian Rogersff1ed472011-09-20 13:46:24 -0700910 (*stub)(method, NULL, Thread::Current(), reinterpret_cast<byte*>(&arg), &result);
Carl Shapiro9b9ba282011-08-14 15:30:39 -0700911 EXPECT_EQ(0, result.i);
912
913 arg = -1;
914 result.i = 0;
Ian Rogersff1ed472011-09-20 13:46:24 -0700915 (*stub)(method, NULL, Thread::Current(), reinterpret_cast<byte*>(&arg), &result);
Carl Shapiro9b9ba282011-08-14 15:30:39 -0700916 EXPECT_EQ(-1, result.i);
917
918 arg = INT_MAX;
919 result.i = 0;
Ian Rogersff1ed472011-09-20 13:46:24 -0700920 (*stub)(method, NULL, Thread::Current(), reinterpret_cast<byte*>(&arg), &result);
Carl Shapiro9b9ba282011-08-14 15:30:39 -0700921 EXPECT_EQ(INT_MAX, result.i);
922
923 arg = INT_MIN;
924 result.i = 0;
Ian Rogersff1ed472011-09-20 13:46:24 -0700925 (*stub)(method, NULL, Thread::Current(), reinterpret_cast<byte*>(&arg), &result);
Carl Shapiro9b9ba282011-08-14 15:30:39 -0700926 EXPECT_EQ(INT_MIN, result.i);
Carl Shapiro9b9ba282011-08-14 15:30:39 -0700927}
928
929TEST_F(JniInternalTest, StaticIdentityDoubleMethod) {
Brian Carlstrom9baa4ae2011-09-01 21:14:14 -0700930 const ClassLoader* class_loader = LoadDex("StaticLeafMethods");
931 CompileDirectMethod(class_loader, "StaticLeafMethods", "identity", "(D)D");
Carl Shapiro9b9ba282011-08-14 15:30:39 -0700932
933 Class* klass = class_linker_->FindClass("LStaticLeafMethods;", class_loader);
934 ASSERT_TRUE(klass != NULL);
935
936 Method* method = klass->FindDirectMethod("identity", "(D)D");
937 ASSERT_TRUE(method != NULL);
938
Brian Carlstrom9baa4ae2011-09-01 21:14:14 -0700939 Method::InvokeStub* stub = method->GetInvokeStub();
Carl Shapiro9b9ba282011-08-14 15:30:39 -0700940
941 double arg;
942 JValue result;
943
944 arg = 0.0;
945 result.d = -1.0;
Ian Rogersff1ed472011-09-20 13:46:24 -0700946 (*stub)(method, NULL, Thread::Current(), reinterpret_cast<byte*>(&arg), &result);
Carl Shapiro9b9ba282011-08-14 15:30:39 -0700947 EXPECT_EQ(0.0, result.d);
948
949 arg = -1.0;
950 result.d = 0.0;
Ian Rogersff1ed472011-09-20 13:46:24 -0700951 (*stub)(method, NULL, Thread::Current(), reinterpret_cast<byte*>(&arg), &result);
Carl Shapiro9b9ba282011-08-14 15:30:39 -0700952 EXPECT_EQ(-1.0, result.d);
953
954 arg = DBL_MAX;
955 result.d = 0.0;
Ian Rogersff1ed472011-09-20 13:46:24 -0700956 (*stub)(method, NULL, Thread::Current(), reinterpret_cast<byte*>(&arg), &result);
Carl Shapiro9b9ba282011-08-14 15:30:39 -0700957 EXPECT_EQ(DBL_MAX, result.d);
958
959 arg = DBL_MIN;
960 result.d = 0.0;
Ian Rogersff1ed472011-09-20 13:46:24 -0700961 (*stub)(method, NULL, Thread::Current(), reinterpret_cast<byte*>(&arg), &result);
Carl Shapiro9b9ba282011-08-14 15:30:39 -0700962 EXPECT_EQ(DBL_MIN, result.d);
Carl Shapiro9b9ba282011-08-14 15:30:39 -0700963}
964
965TEST_F(JniInternalTest, StaticSumIntIntMethod) {
Brian Carlstrom9baa4ae2011-09-01 21:14:14 -0700966 const ClassLoader* class_loader = LoadDex("StaticLeafMethods");
967 CompileDirectMethod(class_loader, "StaticLeafMethods", "sum", "(II)I");
Carl Shapiro9b9ba282011-08-14 15:30:39 -0700968
969 Class* klass = class_linker_->FindClass("LStaticLeafMethods;", class_loader);
970 ASSERT_TRUE(klass != NULL);
971
972 Method* method = klass->FindDirectMethod("sum", "(II)I");
973 ASSERT_TRUE(method != NULL);
974
Brian Carlstrom9baa4ae2011-09-01 21:14:14 -0700975 Method::InvokeStub* stub = method->GetInvokeStub();
Carl Shapiro9b9ba282011-08-14 15:30:39 -0700976
977 int args[2];
978 JValue result;
979
980 args[0] = 0;
981 args[1] = 0;
982 result.i = -1;
Ian Rogersff1ed472011-09-20 13:46:24 -0700983 (*stub)(method, NULL, Thread::Current(), reinterpret_cast<byte*>(args), &result);
Carl Shapiro9b9ba282011-08-14 15:30:39 -0700984 EXPECT_EQ(0, result.i);
985
986 args[0] = 1;
987 args[1] = 2;
988 result.i = 0;
Ian Rogersff1ed472011-09-20 13:46:24 -0700989 (*stub)(method, NULL, Thread::Current(), reinterpret_cast<byte*>(args), &result);
Carl Shapiro9b9ba282011-08-14 15:30:39 -0700990 EXPECT_EQ(3, result.i);
991
992 args[0] = -2;
993 args[1] = 5;
994 result.i = 0;
Ian Rogersff1ed472011-09-20 13:46:24 -0700995 (*stub)(method, NULL, Thread::Current(), reinterpret_cast<byte*>(args), &result);
Carl Shapiro9b9ba282011-08-14 15:30:39 -0700996 EXPECT_EQ(3, result.i);
997
998 args[0] = INT_MAX;
999 args[1] = INT_MIN;
1000 result.i = 1234;
Ian Rogersff1ed472011-09-20 13:46:24 -07001001 (*stub)(method, NULL, Thread::Current(), reinterpret_cast<byte*>(args), &result);
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001002 EXPECT_EQ(-1, result.i);
1003
1004 args[0] = INT_MAX;
1005 args[1] = INT_MAX;
1006 result.i = INT_MIN;
Ian Rogersff1ed472011-09-20 13:46:24 -07001007 (*stub)(method, NULL, Thread::Current(), reinterpret_cast<byte*>(args), &result);
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001008 EXPECT_EQ(-2, result.i);
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001009}
1010
1011TEST_F(JniInternalTest, StaticSumIntIntIntMethod) {
Brian Carlstrom9baa4ae2011-09-01 21:14:14 -07001012 const ClassLoader* class_loader = LoadDex("StaticLeafMethods");
1013 CompileDirectMethod(class_loader, "StaticLeafMethods", "sum", "(III)I");
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001014
1015 Class* klass = class_linker_->FindClass("LStaticLeafMethods;", class_loader);
1016 ASSERT_TRUE(klass != NULL);
1017
1018 Method* method = klass->FindDirectMethod("sum", "(III)I");
1019 ASSERT_TRUE(method != NULL);
1020
Brian Carlstrom9baa4ae2011-09-01 21:14:14 -07001021 Method::InvokeStub* stub = method->GetInvokeStub();
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001022
1023 int args[3];
1024 JValue result;
1025
1026 args[0] = 0;
1027 args[1] = 0;
1028 args[2] = 0;
1029 result.i = -1;
Ian Rogersff1ed472011-09-20 13:46:24 -07001030 (*stub)(method, NULL, Thread::Current(), reinterpret_cast<byte*>(args), &result);
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001031 EXPECT_EQ(0, result.i);
1032
1033 args[0] = 1;
1034 args[1] = 2;
1035 args[2] = 3;
1036 result.i = 0;
Ian Rogersff1ed472011-09-20 13:46:24 -07001037 (*stub)(method, NULL, Thread::Current(), reinterpret_cast<byte*>(args), &result);
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001038 EXPECT_EQ(6, result.i);
1039
1040 args[0] = -1;
1041 args[1] = 2;
1042 args[2] = -3;
1043 result.i = 0;
Ian Rogersff1ed472011-09-20 13:46:24 -07001044 (*stub)(method, NULL, Thread::Current(), reinterpret_cast<byte*>(args), &result);
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001045 EXPECT_EQ(-2, result.i);
1046
1047 args[0] = INT_MAX;
1048 args[1] = INT_MIN;
1049 args[2] = INT_MAX;
1050 result.i = 1234;
Ian Rogersff1ed472011-09-20 13:46:24 -07001051 (*stub)(method, NULL, Thread::Current(), reinterpret_cast<byte*>(args), &result);
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001052 EXPECT_EQ(2147483646, result.i);
1053
1054 args[0] = INT_MAX;
1055 args[1] = INT_MAX;
1056 args[2] = INT_MAX;
1057 result.i = INT_MIN;
Ian Rogersff1ed472011-09-20 13:46:24 -07001058 (*stub)(method, NULL, Thread::Current(), reinterpret_cast<byte*>(args), &result);
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001059 EXPECT_EQ(2147483645, result.i);
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001060}
1061
1062TEST_F(JniInternalTest, StaticSumIntIntIntIntMethod) {
Brian Carlstrom9baa4ae2011-09-01 21:14:14 -07001063 const ClassLoader* class_loader = LoadDex("StaticLeafMethods");
1064 CompileDirectMethod(class_loader, "StaticLeafMethods", "sum", "(IIII)I");
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001065
1066 Class* klass = class_linker_->FindClass("LStaticLeafMethods;", class_loader);
1067 ASSERT_TRUE(klass != NULL);
1068
1069 Method* method = klass->FindDirectMethod("sum", "(IIII)I");
1070 ASSERT_TRUE(method != NULL);
1071
Brian Carlstrom9baa4ae2011-09-01 21:14:14 -07001072 Method::InvokeStub* stub = method->GetInvokeStub();
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001073
1074 int args[4];
1075 JValue result;
1076
1077 args[0] = 0;
1078 args[1] = 0;
1079 args[2] = 0;
1080 args[3] = 0;
1081 result.i = -1;
Ian Rogersff1ed472011-09-20 13:46:24 -07001082 (*stub)(method, NULL, Thread::Current(), reinterpret_cast<byte*>(args), &result);
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001083 EXPECT_EQ(0, result.i);
1084
1085 args[0] = 1;
1086 args[1] = 2;
1087 args[2] = 3;
1088 args[3] = 4;
1089 result.i = 0;
Ian Rogersff1ed472011-09-20 13:46:24 -07001090 (*stub)(method, NULL, Thread::Current(), reinterpret_cast<byte*>(args), &result);
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001091 EXPECT_EQ(10, result.i);
1092
1093 args[0] = -1;
1094 args[1] = 2;
1095 args[2] = -3;
1096 args[3] = 4;
1097 result.i = 0;
Ian Rogersff1ed472011-09-20 13:46:24 -07001098 (*stub)(method, NULL, Thread::Current(), reinterpret_cast<byte*>(args), &result);
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001099 EXPECT_EQ(2, result.i);
1100
1101 args[0] = INT_MAX;
1102 args[1] = INT_MIN;
1103 args[2] = INT_MAX;
1104 args[3] = INT_MIN;
1105 result.i = 1234;
Ian Rogersff1ed472011-09-20 13:46:24 -07001106 (*stub)(method, NULL, Thread::Current(), reinterpret_cast<byte*>(args), &result);
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001107 EXPECT_EQ(-2, result.i);
1108
1109 args[0] = INT_MAX;
1110 args[1] = INT_MAX;
1111 args[2] = INT_MAX;
1112 args[3] = INT_MAX;
1113 result.i = INT_MIN;
Ian Rogersff1ed472011-09-20 13:46:24 -07001114 (*stub)(method, NULL, Thread::Current(), reinterpret_cast<byte*>(args), &result);
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001115 EXPECT_EQ(-4, result.i);
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001116}
1117
1118TEST_F(JniInternalTest, StaticSumIntIntIntIntIntMethod) {
Brian Carlstrom9baa4ae2011-09-01 21:14:14 -07001119 const ClassLoader* class_loader = LoadDex("StaticLeafMethods");
1120 CompileDirectMethod(class_loader, "StaticLeafMethods", "sum", "(IIIII)I");
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001121
1122 Class* klass = class_linker_->FindClass("LStaticLeafMethods;", class_loader);
1123 ASSERT_TRUE(klass != NULL);
1124
1125 Method* method = klass->FindDirectMethod("sum", "(IIIII)I");
1126 ASSERT_TRUE(method != NULL);
1127
Brian Carlstrom9baa4ae2011-09-01 21:14:14 -07001128 Method::InvokeStub* stub = method->GetInvokeStub();
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001129
1130 int args[5];
1131 JValue result;
1132
1133 args[0] = 0;
1134 args[1] = 0;
1135 args[2] = 0;
1136 args[3] = 0;
1137 args[4] = 0;
1138 result.i = -1.0;
Ian Rogersff1ed472011-09-20 13:46:24 -07001139 (*stub)(method, NULL, Thread::Current(), reinterpret_cast<byte*>(args), &result);
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001140 EXPECT_EQ(0, result.i);
1141
1142 args[0] = 1;
1143 args[1] = 2;
1144 args[2] = 3;
1145 args[3] = 4;
1146 args[4] = 5;
1147 result.i = 0;
Ian Rogersff1ed472011-09-20 13:46:24 -07001148 (*stub)(method, NULL, Thread::Current(), reinterpret_cast<byte*>(args), &result);
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001149 EXPECT_EQ(15, result.i);
1150
1151 args[0] = -1;
1152 args[1] = 2;
1153 args[2] = -3;
1154 args[3] = 4;
1155 args[4] = -5;
1156 result.i = 0;
Ian Rogersff1ed472011-09-20 13:46:24 -07001157 (*stub)(method, NULL, Thread::Current(), reinterpret_cast<byte*>(args), &result);
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001158 EXPECT_EQ(-3, result.i);
1159
1160 args[0] = INT_MAX;
1161 args[1] = INT_MIN;
1162 args[2] = INT_MAX;
1163 args[3] = INT_MIN;
1164 args[4] = INT_MAX;
1165 result.i = 1234;
Ian Rogersff1ed472011-09-20 13:46:24 -07001166 (*stub)(method, NULL, Thread::Current(), reinterpret_cast<byte*>(args), &result);
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001167 EXPECT_EQ(2147483645, result.i);
1168
1169 args[0] = INT_MAX;
1170 args[1] = INT_MAX;
1171 args[2] = INT_MAX;
1172 args[3] = INT_MAX;
1173 args[4] = INT_MAX;
1174 result.i = INT_MIN;
Ian Rogersff1ed472011-09-20 13:46:24 -07001175 (*stub)(method, NULL, Thread::Current(), reinterpret_cast<byte*>(args), &result);
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001176 EXPECT_EQ(2147483643, result.i);
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001177}
1178
1179TEST_F(JniInternalTest, StaticSumDoubleDoubleMethod) {
Brian Carlstrom9baa4ae2011-09-01 21:14:14 -07001180 const ClassLoader* class_loader = LoadDex("StaticLeafMethods");
1181 CompileDirectMethod(class_loader, "StaticLeafMethods", "sum", "(DD)D");
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001182
1183 Class* klass = class_linker_->FindClass("LStaticLeafMethods;", class_loader);
1184 ASSERT_TRUE(klass != NULL);
1185
1186 Method* method = klass->FindDirectMethod("sum", "(DD)D");
1187 ASSERT_TRUE(method != NULL);
1188
Brian Carlstrom9baa4ae2011-09-01 21:14:14 -07001189 Method::InvokeStub* stub = method->GetInvokeStub();
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001190
1191 double args[2];
1192 JValue result;
1193
1194 args[0] = 0.0;
1195 args[1] = 0.0;
1196 result.d = -1.0;
Ian Rogersff1ed472011-09-20 13:46:24 -07001197 (*stub)(method, NULL, Thread::Current(), reinterpret_cast<byte*>(args), &result);
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001198 EXPECT_EQ(0.0, result.d);
1199
1200 args[0] = 1.0;
1201 args[1] = 2.0;
1202 result.d = 0.0;
Ian Rogersff1ed472011-09-20 13:46:24 -07001203 (*stub)(method, NULL, Thread::Current(), reinterpret_cast<byte*>(args), &result);
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001204 EXPECT_EQ(3.0, result.d);
1205
1206 args[0] = 1.0;
1207 args[1] = -2.0;
1208 result.d = 0.0;
Ian Rogersff1ed472011-09-20 13:46:24 -07001209 (*stub)(method, NULL, Thread::Current(), reinterpret_cast<byte*>(args), &result);
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001210 EXPECT_EQ(-1.0, result.d);
1211
1212 args[0] = DBL_MAX;
1213 args[1] = DBL_MIN;
1214 result.d = 0.0;
Ian Rogersff1ed472011-09-20 13:46:24 -07001215 (*stub)(method, NULL, Thread::Current(), reinterpret_cast<byte*>(args), &result);
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001216 EXPECT_EQ(1.7976931348623157e308, result.d);
1217
1218 args[0] = DBL_MAX;
1219 args[1] = DBL_MAX;
1220 result.d = 0.0;
Ian Rogersff1ed472011-09-20 13:46:24 -07001221 (*stub)(method, NULL, Thread::Current(), reinterpret_cast<byte*>(args), &result);
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001222 EXPECT_EQ(INFINITY, result.d);
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001223}
1224
1225TEST_F(JniInternalTest, StaticSumDoubleDoubleDoubleMethod) {
Brian Carlstrom9baa4ae2011-09-01 21:14:14 -07001226 const ClassLoader* class_loader = LoadDex("StaticLeafMethods");
1227 CompileDirectMethod(class_loader, "StaticLeafMethods", "sum", "(DDD)D");
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001228
1229 Class* klass = class_linker_->FindClass("LStaticLeafMethods;", class_loader);
1230 ASSERT_TRUE(klass != NULL);
1231
1232 Method* method = klass->FindDirectMethod("sum", "(DDD)D");
1233 ASSERT_TRUE(method != NULL);
1234
Brian Carlstrom9baa4ae2011-09-01 21:14:14 -07001235 Method::InvokeStub* stub = method->GetInvokeStub();
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001236
1237 double args[3];
1238 JValue result;
1239
1240 args[0] = 0.0;
1241 args[1] = 0.0;
1242 args[2] = 0.0;
1243 result.d = -1.0;
Ian Rogersff1ed472011-09-20 13:46:24 -07001244 (*stub)(method, NULL, Thread::Current(), reinterpret_cast<byte*>(args), &result);
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001245 EXPECT_EQ(0.0, result.d);
1246
1247 args[0] = 1.0;
1248 args[1] = 2.0;
1249 args[2] = 3.0;
1250 result.d = 0.0;
Ian Rogersff1ed472011-09-20 13:46:24 -07001251 (*stub)(method, NULL, Thread::Current(), reinterpret_cast<byte*>(args), &result);
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001252 EXPECT_EQ(6.0, result.d);
1253
1254 args[0] = 1.0;
1255 args[1] = -2.0;
1256 args[2] = 3.0;
1257 result.d = 0.0;
Ian Rogersff1ed472011-09-20 13:46:24 -07001258 (*stub)(method, NULL, Thread::Current(), reinterpret_cast<byte*>(args), &result);
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001259 EXPECT_EQ(2.0, result.d);
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001260}
1261
1262TEST_F(JniInternalTest, StaticSumDoubleDoubleDoubleDoubleMethod) {
Brian Carlstrom9baa4ae2011-09-01 21:14:14 -07001263 const ClassLoader* class_loader = LoadDex("StaticLeafMethods");
1264 CompileDirectMethod(class_loader, "StaticLeafMethods", "sum", "(DDDD)D");
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001265
1266 Class* klass = class_linker_->FindClass("LStaticLeafMethods;", class_loader);
1267 ASSERT_TRUE(klass != NULL);
1268
1269 Method* method = klass->FindDirectMethod("sum", "(DDDD)D");
1270 ASSERT_TRUE(method != NULL);
1271
Brian Carlstrom9baa4ae2011-09-01 21:14:14 -07001272 Method::InvokeStub* stub = method->GetInvokeStub();
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001273
1274 double args[4];
1275 JValue result;
1276
1277 args[0] = 0.0;
1278 args[1] = 0.0;
1279 args[2] = 0.0;
1280 args[3] = 0.0;
1281 result.d = -1.0;
Ian Rogersff1ed472011-09-20 13:46:24 -07001282 (*stub)(method, NULL, Thread::Current(), reinterpret_cast<byte*>(args), &result);
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001283 EXPECT_EQ(0.0, result.d);
1284
1285 args[0] = 1.0;
1286 args[1] = 2.0;
1287 args[2] = 3.0;
1288 args[3] = 4.0;
1289 result.d = 0.0;
Ian Rogersff1ed472011-09-20 13:46:24 -07001290 (*stub)(method, NULL, Thread::Current(), reinterpret_cast<byte*>(args), &result);
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001291 EXPECT_EQ(10.0, result.d);
1292
1293 args[0] = 1.0;
1294 args[1] = -2.0;
1295 args[2] = 3.0;
1296 args[3] = -4.0;
1297 result.d = 0.0;
Ian Rogersff1ed472011-09-20 13:46:24 -07001298 (*stub)(method, NULL, Thread::Current(), reinterpret_cast<byte*>(args), &result);
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001299 EXPECT_EQ(-2.0, result.d);
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001300}
1301
1302TEST_F(JniInternalTest, StaticSumDoubleDoubleDoubleDoubleDoubleMethod) {
Brian Carlstrom9baa4ae2011-09-01 21:14:14 -07001303 const ClassLoader* class_loader = LoadDex("StaticLeafMethods");
1304 CompileDirectMethod(class_loader, "StaticLeafMethods", "sum", "(DDDDD)D");
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001305
1306 Class* klass = class_linker_->FindClass("LStaticLeafMethods;", class_loader);
1307 ASSERT_TRUE(klass != NULL);
1308
1309 Method* method = klass->FindDirectMethod("sum", "(DDDDD)D");
1310 ASSERT_TRUE(method != NULL);
1311
Brian Carlstrom9baa4ae2011-09-01 21:14:14 -07001312 Method::InvokeStub* stub = method->GetInvokeStub();
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001313
1314 double args[5];
1315 JValue result;
1316
1317 args[0] = 0.0;
1318 args[1] = 0.0;
1319 args[2] = 0.0;
1320 args[3] = 0.0;
1321 args[4] = 0.0;
1322 result.d = -1.0;
Ian Rogersff1ed472011-09-20 13:46:24 -07001323 (*stub)(method, NULL, Thread::Current(), reinterpret_cast<byte*>(args), &result);
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001324 EXPECT_EQ(0.0, result.d);
1325
1326 args[0] = 1.0;
1327 args[1] = 2.0;
1328 args[2] = 3.0;
1329 args[3] = 4.0;
1330 args[4] = 5.0;
1331 result.d = 0.0;
Ian Rogersff1ed472011-09-20 13:46:24 -07001332 (*stub)(method, NULL, Thread::Current(), reinterpret_cast<byte*>(args), &result);
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001333 EXPECT_EQ(15.0, result.d);
1334
1335 args[0] = 1.0;
1336 args[1] = -2.0;
1337 args[2] = 3.0;
1338 args[3] = -4.0;
1339 args[4] = 5.0;
1340 result.d = 0.0;
Ian Rogersff1ed472011-09-20 13:46:24 -07001341 (*stub)(method, NULL, Thread::Current(), reinterpret_cast<byte*>(args), &result);
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001342 EXPECT_EQ(3.0, result.d);
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001343}
1344#endif // __arm__
1345
Elliott Hughes37f7a402011-08-22 18:56:01 -07001346TEST_F(JniInternalTest, Throw) {
1347 EXPECT_EQ(JNI_ERR, env_->Throw(NULL));
1348
1349 jclass exception_class = env_->FindClass("java/lang/RuntimeException");
1350 ASSERT_TRUE(exception_class != NULL);
1351 jthrowable exception = reinterpret_cast<jthrowable>(env_->AllocObject(exception_class));
1352 ASSERT_TRUE(exception != NULL);
1353
1354 EXPECT_EQ(JNI_OK, env_->Throw(exception));
1355 EXPECT_TRUE(env_->ExceptionCheck());
Elliott Hughesa2501992011-08-26 19:39:54 -07001356 jthrowable thrown_exception = env_->ExceptionOccurred();
Elliott Hughes37f7a402011-08-22 18:56:01 -07001357 env_->ExceptionClear();
Elliott Hughesa2501992011-08-26 19:39:54 -07001358 EXPECT_TRUE(env_->IsSameObject(exception, thrown_exception));
Elliott Hughes37f7a402011-08-22 18:56:01 -07001359}
1360
1361TEST_F(JniInternalTest, ThrowNew) {
1362 EXPECT_EQ(JNI_ERR, env_->Throw(NULL));
1363
1364 jclass exception_class = env_->FindClass("java/lang/RuntimeException");
1365 ASSERT_TRUE(exception_class != NULL);
1366
1367 EXPECT_EQ(JNI_OK, env_->ThrowNew(exception_class, "hello world"));
1368 EXPECT_TRUE(env_->ExceptionCheck());
Elliott Hughesa2501992011-08-26 19:39:54 -07001369 jthrowable thrown_exception = env_->ExceptionOccurred();
Elliott Hughes37f7a402011-08-22 18:56:01 -07001370 env_->ExceptionClear();
Elliott Hughesa2501992011-08-26 19:39:54 -07001371 EXPECT_TRUE(env_->IsInstanceOf(thrown_exception, exception_class));
Elliott Hughes37f7a402011-08-22 18:56:01 -07001372}
1373
Elliott Hughesb465ab02011-08-24 11:21:21 -07001374// TODO: this test is DISABLED until we can actually run java.nio.Buffer's <init>.
1375TEST_F(JniInternalTest, DISABLED_NewDirectBuffer_GetDirectBufferAddress_GetDirectBufferCapacity) {
1376 jclass buffer_class = env_->FindClass("java/nio/Buffer");
1377 ASSERT_TRUE(buffer_class != NULL);
1378
1379 char bytes[1024];
1380 jobject buffer = env_->NewDirectByteBuffer(bytes, sizeof(bytes));
1381 ASSERT_TRUE(buffer != NULL);
1382 ASSERT_TRUE(env_->IsInstanceOf(buffer, buffer_class));
1383 ASSERT_TRUE(env_->GetDirectBufferAddress(buffer) == bytes);
1384 ASSERT_TRUE(env_->GetDirectBufferCapacity(buffer) == sizeof(bytes));
1385}
1386
Ian Rogers0cfe1fb2011-08-26 03:29:44 -07001387} // namespace art