blob: 067d36b11a770996a87cca32932ce2787d4576f6 [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");
Elliott Hughes885c3bd2011-08-22 16:59:20 -0700651
652 jclass c = env_->FindClass("AllFields");
653 ASSERT_TRUE(c != NULL);
654 jobject o = env_->AllocObject(c);
655 ASSERT_TRUE(o != NULL);
656
657 EXPECT_STATIC_PRIMITIVE_FIELD(Boolean, "sZ", "Z", true, false);
658 EXPECT_STATIC_PRIMITIVE_FIELD(Byte, "sB", "B", 1, 2);
659 EXPECT_STATIC_PRIMITIVE_FIELD(Char, "sC", "C", 'a', 'b');
660 EXPECT_STATIC_PRIMITIVE_FIELD(Double, "sD", "D", 1.0, 2.0);
661 EXPECT_STATIC_PRIMITIVE_FIELD(Float, "sF", "F", 1.0, 2.0);
662 EXPECT_STATIC_PRIMITIVE_FIELD(Int, "sI", "I", 1, 2);
663 EXPECT_STATIC_PRIMITIVE_FIELD(Long, "sJ", "J", 1, 2);
664 EXPECT_STATIC_PRIMITIVE_FIELD(Short, "sS", "S", 1, 2);
665
666 EXPECT_PRIMITIVE_FIELD(o, Boolean, "iZ", "Z", true, false);
667 EXPECT_PRIMITIVE_FIELD(o, Byte, "iB", "B", 1, 2);
668 EXPECT_PRIMITIVE_FIELD(o, Char, "iC", "C", 'a', 'b');
669 EXPECT_PRIMITIVE_FIELD(o, Double, "iD", "D", 1.0, 2.0);
670 EXPECT_PRIMITIVE_FIELD(o, Float, "iF", "F", 1.0, 2.0);
671 EXPECT_PRIMITIVE_FIELD(o, Int, "iI", "I", 1, 2);
672 EXPECT_PRIMITIVE_FIELD(o, Long, "iJ", "J", 1, 2);
673 EXPECT_PRIMITIVE_FIELD(o, Short, "iS", "S", 1, 2);
674}
675
676TEST_F(JniInternalTest, GetObjectField_SetObjectField) {
Brian Carlstrom9baa4ae2011-09-01 21:14:14 -0700677 LoadDex("AllFields");
Elliott Hughes885c3bd2011-08-22 16:59:20 -0700678
679 jclass c = env_->FindClass("AllFields");
680 ASSERT_TRUE(c != NULL);
681 jobject o = env_->AllocObject(c);
682 ASSERT_TRUE(o != NULL);
683
684 jstring s1 = env_->NewStringUTF("hello");
685 ASSERT_TRUE(s1 != NULL);
686 jstring s2 = env_->NewStringUTF("world");
687 ASSERT_TRUE(s2 != NULL);
688
689 jfieldID s_fid = env_->GetStaticFieldID(c, "sObject", "Ljava/lang/Object;");
690 ASSERT_TRUE(s_fid != NULL);
691 jfieldID i_fid = env_->GetFieldID(c, "iObject", "Ljava/lang/Object;");
692 ASSERT_TRUE(i_fid != NULL);
693
694 env_->SetStaticObjectField(c, s_fid, s1);
695 ASSERT_TRUE(env_->IsSameObject(s1, env_->GetStaticObjectField(c, s_fid)));
696 env_->SetStaticObjectField(c, s_fid, s2);
697 ASSERT_TRUE(env_->IsSameObject(s2, env_->GetStaticObjectField(c, s_fid)));
698
699 env_->SetObjectField(o, i_fid, s1);
700 ASSERT_TRUE(env_->IsSameObject(s1, env_->GetObjectField(o, i_fid)));
701 env_->SetObjectField(o, i_fid, s2);
702 ASSERT_TRUE(env_->IsSameObject(s2, env_->GetObjectField(o, i_fid)));
703}
704
Elliott Hughes18c07532011-08-18 15:50:51 -0700705TEST_F(JniInternalTest, NewLocalRef_NULL) {
706 EXPECT_TRUE(env_->NewLocalRef(NULL) == NULL);
707}
708
709TEST_F(JniInternalTest, NewLocalRef) {
710 jstring s = env_->NewStringUTF("");
711 ASSERT_TRUE(s != NULL);
712 jobject o = env_->NewLocalRef(s);
713 EXPECT_TRUE(o != NULL);
714 EXPECT_TRUE(o != s);
715
716 // TODO: check that o is a local reference.
717}
718
719TEST_F(JniInternalTest, DeleteLocalRef_NULL) {
720 env_->DeleteLocalRef(NULL);
721}
722
723TEST_F(JniInternalTest, DeleteLocalRef) {
724 jstring s = env_->NewStringUTF("");
725 ASSERT_TRUE(s != NULL);
726 env_->DeleteLocalRef(s);
727
728 // Currently, deleting an already-deleted reference is just a warning.
Elliott Hughesa2501992011-08-26 19:39:54 -0700729 vm_->check_jni_abort_hook = TestCheckJniAbortHook;
Elliott Hughes18c07532011-08-18 15:50:51 -0700730 env_->DeleteLocalRef(s);
Elliott Hughesa2501992011-08-26 19:39:54 -0700731 vm_->check_jni_abort_hook = NULL;
Elliott Hughes18c07532011-08-18 15:50:51 -0700732
733 s = env_->NewStringUTF("");
734 ASSERT_TRUE(s != NULL);
735 jobject o = env_->NewLocalRef(s);
736 ASSERT_TRUE(o != NULL);
737
738 env_->DeleteLocalRef(s);
739 env_->DeleteLocalRef(o);
740}
741
742TEST_F(JniInternalTest, NewGlobalRef_NULL) {
743 EXPECT_TRUE(env_->NewGlobalRef(NULL) == NULL);
744}
745
746TEST_F(JniInternalTest, NewGlobalRef) {
747 jstring s = env_->NewStringUTF("");
748 ASSERT_TRUE(s != NULL);
749 jobject o = env_->NewGlobalRef(s);
750 EXPECT_TRUE(o != NULL);
751 EXPECT_TRUE(o != s);
752
753 // TODO: check that o is a global reference.
754}
755
756TEST_F(JniInternalTest, DeleteGlobalRef_NULL) {
757 env_->DeleteGlobalRef(NULL);
758}
759
760TEST_F(JniInternalTest, DeleteGlobalRef) {
761 jstring s = env_->NewStringUTF("");
762 ASSERT_TRUE(s != NULL);
763
764 jobject o = env_->NewGlobalRef(s);
765 ASSERT_TRUE(o != NULL);
766 env_->DeleteGlobalRef(o);
767
Elliott Hughesa2501992011-08-26 19:39:54 -0700768 vm_->check_jni_abort_hook = TestCheckJniAbortHook;
Elliott Hughes18c07532011-08-18 15:50:51 -0700769 // Currently, deleting an already-deleted reference is just a warning.
770 env_->DeleteGlobalRef(o);
Elliott Hughesa2501992011-08-26 19:39:54 -0700771 vm_->check_jni_abort_hook = NULL;
Elliott Hughes18c07532011-08-18 15:50:51 -0700772
773 jobject o1 = env_->NewGlobalRef(s);
774 ASSERT_TRUE(o1 != NULL);
775 jobject o2 = env_->NewGlobalRef(s);
776 ASSERT_TRUE(o2 != NULL);
777
778 env_->DeleteGlobalRef(o1);
779 env_->DeleteGlobalRef(o2);
780}
781
782TEST_F(JniInternalTest, NewWeakGlobalRef_NULL) {
783 EXPECT_TRUE(env_->NewWeakGlobalRef(NULL) == NULL);
784}
785
786TEST_F(JniInternalTest, NewWeakGlobalRef) {
787 jstring s = env_->NewStringUTF("");
788 ASSERT_TRUE(s != NULL);
789 jobject o = env_->NewWeakGlobalRef(s);
790 EXPECT_TRUE(o != NULL);
791 EXPECT_TRUE(o != s);
792
793 // TODO: check that o is a weak global reference.
794}
795
796TEST_F(JniInternalTest, DeleteWeakGlobalRef_NULL) {
797 env_->DeleteWeakGlobalRef(NULL);
798}
799
800TEST_F(JniInternalTest, DeleteWeakGlobalRef) {
801 jstring s = env_->NewStringUTF("");
802 ASSERT_TRUE(s != NULL);
803
804 jobject o = env_->NewWeakGlobalRef(s);
805 ASSERT_TRUE(o != NULL);
806 env_->DeleteWeakGlobalRef(o);
807
Elliott Hughesa2501992011-08-26 19:39:54 -0700808 vm_->check_jni_abort_hook = TestCheckJniAbortHook;
Elliott Hughes18c07532011-08-18 15:50:51 -0700809 // Currently, deleting an already-deleted reference is just a warning.
810 env_->DeleteWeakGlobalRef(o);
Elliott Hughesa2501992011-08-26 19:39:54 -0700811 vm_->check_jni_abort_hook = NULL;
Elliott Hughes18c07532011-08-18 15:50:51 -0700812
813 jobject o1 = env_->NewWeakGlobalRef(s);
814 ASSERT_TRUE(o1 != NULL);
815 jobject o2 = env_->NewWeakGlobalRef(s);
816 ASSERT_TRUE(o2 != NULL);
817
818 env_->DeleteWeakGlobalRef(o1);
819 env_->DeleteWeakGlobalRef(o2);
820}
821
Carl Shapiro9b9ba282011-08-14 15:30:39 -0700822#if defined(__arm__)
823TEST_F(JniInternalTest, StaticMainMethod) {
Brian Carlstrom9baa4ae2011-09-01 21:14:14 -0700824 const ClassLoader* class_loader = LoadDex("Main");
825 CompileDirectMethod(class_loader, "Main", "main", "([Ljava/lang/String;)V");
Carl Shapiro9b9ba282011-08-14 15:30:39 -0700826
827 Class* klass = class_linker_->FindClass("LMain;", class_loader);
828 ASSERT_TRUE(klass != NULL);
829
830 Method* method = klass->FindDirectMethod("main", "([Ljava/lang/String;)V");
831 ASSERT_TRUE(method != NULL);
832
Brian Carlstrom9baa4ae2011-09-01 21:14:14 -0700833 Method::InvokeStub* stub = method->GetInvokeStub();
Carl Shapiro9b9ba282011-08-14 15:30:39 -0700834
835 Object* arg = NULL;
836
837 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(&arg), NULL);
Carl Shapiro9b9ba282011-08-14 15:30:39 -0700838}
839
840TEST_F(JniInternalTest, StaticNopMethod) {
Brian Carlstrom9baa4ae2011-09-01 21:14:14 -0700841 const ClassLoader* class_loader = LoadDex("StaticLeafMethods");
842 CompileDirectMethod(class_loader, "StaticLeafMethods", "nop", "()V");
Carl Shapiro9b9ba282011-08-14 15:30:39 -0700843
844 Class* klass = class_linker_->FindClass("LStaticLeafMethods;", class_loader);
845 ASSERT_TRUE(klass != NULL);
846
847 Method* method = klass->FindDirectMethod("nop", "()V");
848 ASSERT_TRUE(method != NULL);
849
Brian Carlstrom9baa4ae2011-09-01 21:14:14 -0700850 Method::InvokeStub* stub = method->GetInvokeStub();
Carl Shapiro9b9ba282011-08-14 15:30:39 -0700851
852 (*stub)(method, NULL, NULL, NULL, NULL);
Carl Shapiro9b9ba282011-08-14 15:30:39 -0700853}
854
855TEST_F(JniInternalTest, StaticIdentityByteMethod) {
Brian Carlstrom9baa4ae2011-09-01 21:14:14 -0700856 const ClassLoader* class_loader = LoadDex("StaticLeafMethods");
857 CompileDirectMethod(class_loader, "StaticLeafMethods", "identity", "(B)B");
Carl Shapiro9b9ba282011-08-14 15:30:39 -0700858
859 Class* klass = class_linker_->FindClass("LStaticLeafMethods;", class_loader);
860 ASSERT_TRUE(klass != NULL);
861
862 Method* method = klass->FindDirectMethod("identity", "(B)B");
863 ASSERT_TRUE(method != NULL);
864
Brian Carlstrom9baa4ae2011-09-01 21:14:14 -0700865 Method::InvokeStub* stub = method->GetInvokeStub();
Carl Shapiro9b9ba282011-08-14 15:30:39 -0700866
867 int arg;
868 JValue result;
869
870 arg = 0;
871 result.b = -1;
872 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(&arg), &result);
873 EXPECT_EQ(0, result.b);
874
875 arg = -1;
876 result.b = 0;
877 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(&arg), &result);
878 EXPECT_EQ(-1, result.b);
879
880 arg = SCHAR_MAX;
881 result.b = 0;
882 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(&arg), &result);
883 EXPECT_EQ(SCHAR_MAX, result.b);
884
885 arg = SCHAR_MIN;
886 result.b = 0;
887 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(&arg), &result);
888 EXPECT_EQ(SCHAR_MIN, result.b);
Carl Shapiro9b9ba282011-08-14 15:30:39 -0700889}
890
891TEST_F(JniInternalTest, StaticIdentityIntMethod) {
Brian Carlstrom9baa4ae2011-09-01 21:14:14 -0700892 const ClassLoader* class_loader = LoadDex("StaticLeafMethods");
893 CompileDirectMethod(class_loader, "StaticLeafMethods", "identity", "(I)I");
Carl Shapiro9b9ba282011-08-14 15:30:39 -0700894
895 Class* klass = class_linker_->FindClass("LStaticLeafMethods;", class_loader);
896 ASSERT_TRUE(klass != NULL);
897
898 Method* method = klass->FindDirectMethod("identity", "(I)I");
899 ASSERT_TRUE(method != NULL);
900
Brian Carlstrom9baa4ae2011-09-01 21:14:14 -0700901 Method::InvokeStub* stub = method->GetInvokeStub();
Carl Shapiro9b9ba282011-08-14 15:30:39 -0700902
903 int arg;
904 JValue result;
905
906 arg = 0;
907 result.i = -1;
908 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(&arg), &result);
909 EXPECT_EQ(0, result.i);
910
911 arg = -1;
912 result.i = 0;
913 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(&arg), &result);
914 EXPECT_EQ(-1, result.i);
915
916 arg = INT_MAX;
917 result.i = 0;
918 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(&arg), &result);
919 EXPECT_EQ(INT_MAX, result.i);
920
921 arg = INT_MIN;
922 result.i = 0;
923 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(&arg), &result);
924 EXPECT_EQ(INT_MIN, result.i);
Carl Shapiro9b9ba282011-08-14 15:30:39 -0700925}
926
927TEST_F(JniInternalTest, StaticIdentityDoubleMethod) {
Brian Carlstrom9baa4ae2011-09-01 21:14:14 -0700928 const ClassLoader* class_loader = LoadDex("StaticLeafMethods");
929 CompileDirectMethod(class_loader, "StaticLeafMethods", "identity", "(D)D");
Carl Shapiro9b9ba282011-08-14 15:30:39 -0700930
931 Class* klass = class_linker_->FindClass("LStaticLeafMethods;", class_loader);
932 ASSERT_TRUE(klass != NULL);
933
934 Method* method = klass->FindDirectMethod("identity", "(D)D");
935 ASSERT_TRUE(method != NULL);
936
Brian Carlstrom9baa4ae2011-09-01 21:14:14 -0700937 Method::InvokeStub* stub = method->GetInvokeStub();
Carl Shapiro9b9ba282011-08-14 15:30:39 -0700938
939 double arg;
940 JValue result;
941
942 arg = 0.0;
943 result.d = -1.0;
944 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(&arg), &result);
945 EXPECT_EQ(0.0, result.d);
946
947 arg = -1.0;
948 result.d = 0.0;
949 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(&arg), &result);
950 EXPECT_EQ(-1.0, result.d);
951
952 arg = DBL_MAX;
953 result.d = 0.0;
954 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(&arg), &result);
955 EXPECT_EQ(DBL_MAX, result.d);
956
957 arg = DBL_MIN;
958 result.d = 0.0;
959 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(&arg), &result);
960 EXPECT_EQ(DBL_MIN, result.d);
Carl Shapiro9b9ba282011-08-14 15:30:39 -0700961}
962
963TEST_F(JniInternalTest, StaticSumIntIntMethod) {
Brian Carlstrom9baa4ae2011-09-01 21:14:14 -0700964 const ClassLoader* class_loader = LoadDex("StaticLeafMethods");
965 CompileDirectMethod(class_loader, "StaticLeafMethods", "sum", "(II)I");
Carl Shapiro9b9ba282011-08-14 15:30:39 -0700966
967 Class* klass = class_linker_->FindClass("LStaticLeafMethods;", class_loader);
968 ASSERT_TRUE(klass != NULL);
969
970 Method* method = klass->FindDirectMethod("sum", "(II)I");
971 ASSERT_TRUE(method != NULL);
972
Brian Carlstrom9baa4ae2011-09-01 21:14:14 -0700973 Method::InvokeStub* stub = method->GetInvokeStub();
Carl Shapiro9b9ba282011-08-14 15:30:39 -0700974
975 int args[2];
976 JValue result;
977
978 args[0] = 0;
979 args[1] = 0;
980 result.i = -1;
981 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
982 EXPECT_EQ(0, result.i);
983
984 args[0] = 1;
985 args[1] = 2;
986 result.i = 0;
987 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
988 EXPECT_EQ(3, result.i);
989
990 args[0] = -2;
991 args[1] = 5;
992 result.i = 0;
993 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
994 EXPECT_EQ(3, result.i);
995
996 args[0] = INT_MAX;
997 args[1] = INT_MIN;
998 result.i = 1234;
999 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
1000 EXPECT_EQ(-1, result.i);
1001
1002 args[0] = INT_MAX;
1003 args[1] = INT_MAX;
1004 result.i = INT_MIN;
1005 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
1006 EXPECT_EQ(-2, result.i);
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001007}
1008
1009TEST_F(JniInternalTest, StaticSumIntIntIntMethod) {
Brian Carlstrom9baa4ae2011-09-01 21:14:14 -07001010 const ClassLoader* class_loader = LoadDex("StaticLeafMethods");
1011 CompileDirectMethod(class_loader, "StaticLeafMethods", "sum", "(III)I");
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001012
1013 Class* klass = class_linker_->FindClass("LStaticLeafMethods;", class_loader);
1014 ASSERT_TRUE(klass != NULL);
1015
1016 Method* method = klass->FindDirectMethod("sum", "(III)I");
1017 ASSERT_TRUE(method != NULL);
1018
Brian Carlstrom9baa4ae2011-09-01 21:14:14 -07001019 Method::InvokeStub* stub = method->GetInvokeStub();
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001020
1021 int args[3];
1022 JValue result;
1023
1024 args[0] = 0;
1025 args[1] = 0;
1026 args[2] = 0;
1027 result.i = -1;
1028 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
1029 EXPECT_EQ(0, result.i);
1030
1031 args[0] = 1;
1032 args[1] = 2;
1033 args[2] = 3;
1034 result.i = 0;
1035 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
1036 EXPECT_EQ(6, result.i);
1037
1038 args[0] = -1;
1039 args[1] = 2;
1040 args[2] = -3;
1041 result.i = 0;
1042 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
1043 EXPECT_EQ(-2, result.i);
1044
1045 args[0] = INT_MAX;
1046 args[1] = INT_MIN;
1047 args[2] = INT_MAX;
1048 result.i = 1234;
1049 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
1050 EXPECT_EQ(2147483646, result.i);
1051
1052 args[0] = INT_MAX;
1053 args[1] = INT_MAX;
1054 args[2] = INT_MAX;
1055 result.i = INT_MIN;
1056 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
1057 EXPECT_EQ(2147483645, result.i);
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001058}
1059
1060TEST_F(JniInternalTest, StaticSumIntIntIntIntMethod) {
Brian Carlstrom9baa4ae2011-09-01 21:14:14 -07001061 const ClassLoader* class_loader = LoadDex("StaticLeafMethods");
1062 CompileDirectMethod(class_loader, "StaticLeafMethods", "sum", "(IIII)I");
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001063
1064 Class* klass = class_linker_->FindClass("LStaticLeafMethods;", class_loader);
1065 ASSERT_TRUE(klass != NULL);
1066
1067 Method* method = klass->FindDirectMethod("sum", "(IIII)I");
1068 ASSERT_TRUE(method != NULL);
1069
Brian Carlstrom9baa4ae2011-09-01 21:14:14 -07001070 Method::InvokeStub* stub = method->GetInvokeStub();
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001071
1072 int args[4];
1073 JValue result;
1074
1075 args[0] = 0;
1076 args[1] = 0;
1077 args[2] = 0;
1078 args[3] = 0;
1079 result.i = -1;
1080 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
1081 EXPECT_EQ(0, result.i);
1082
1083 args[0] = 1;
1084 args[1] = 2;
1085 args[2] = 3;
1086 args[3] = 4;
1087 result.i = 0;
1088 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
1089 EXPECT_EQ(10, result.i);
1090
1091 args[0] = -1;
1092 args[1] = 2;
1093 args[2] = -3;
1094 args[3] = 4;
1095 result.i = 0;
1096 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
1097 EXPECT_EQ(2, result.i);
1098
1099 args[0] = INT_MAX;
1100 args[1] = INT_MIN;
1101 args[2] = INT_MAX;
1102 args[3] = INT_MIN;
1103 result.i = 1234;
1104 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
1105 EXPECT_EQ(-2, result.i);
1106
1107 args[0] = INT_MAX;
1108 args[1] = INT_MAX;
1109 args[2] = INT_MAX;
1110 args[3] = INT_MAX;
1111 result.i = INT_MIN;
1112 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
1113 EXPECT_EQ(-4, result.i);
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001114}
1115
1116TEST_F(JniInternalTest, StaticSumIntIntIntIntIntMethod) {
Brian Carlstrom9baa4ae2011-09-01 21:14:14 -07001117 const ClassLoader* class_loader = LoadDex("StaticLeafMethods");
1118 CompileDirectMethod(class_loader, "StaticLeafMethods", "sum", "(IIIII)I");
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001119
1120 Class* klass = class_linker_->FindClass("LStaticLeafMethods;", class_loader);
1121 ASSERT_TRUE(klass != NULL);
1122
1123 Method* method = klass->FindDirectMethod("sum", "(IIIII)I");
1124 ASSERT_TRUE(method != NULL);
1125
Brian Carlstrom9baa4ae2011-09-01 21:14:14 -07001126 Method::InvokeStub* stub = method->GetInvokeStub();
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001127
1128 int args[5];
1129 JValue result;
1130
1131 args[0] = 0;
1132 args[1] = 0;
1133 args[2] = 0;
1134 args[3] = 0;
1135 args[4] = 0;
1136 result.i = -1.0;
1137 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
1138 EXPECT_EQ(0, result.i);
1139
1140 args[0] = 1;
1141 args[1] = 2;
1142 args[2] = 3;
1143 args[3] = 4;
1144 args[4] = 5;
1145 result.i = 0;
1146 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
1147 EXPECT_EQ(15, result.i);
1148
1149 args[0] = -1;
1150 args[1] = 2;
1151 args[2] = -3;
1152 args[3] = 4;
1153 args[4] = -5;
1154 result.i = 0;
1155 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
1156 EXPECT_EQ(-3, result.i);
1157
1158 args[0] = INT_MAX;
1159 args[1] = INT_MIN;
1160 args[2] = INT_MAX;
1161 args[3] = INT_MIN;
1162 args[4] = INT_MAX;
1163 result.i = 1234;
1164 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
1165 EXPECT_EQ(2147483645, result.i);
1166
1167 args[0] = INT_MAX;
1168 args[1] = INT_MAX;
1169 args[2] = INT_MAX;
1170 args[3] = INT_MAX;
1171 args[4] = INT_MAX;
1172 result.i = INT_MIN;
1173 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
1174 EXPECT_EQ(2147483643, result.i);
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001175}
1176
1177TEST_F(JniInternalTest, StaticSumDoubleDoubleMethod) {
Brian Carlstrom9baa4ae2011-09-01 21:14:14 -07001178 const ClassLoader* class_loader = LoadDex("StaticLeafMethods");
1179 CompileDirectMethod(class_loader, "StaticLeafMethods", "sum", "(DD)D");
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001180
1181 Class* klass = class_linker_->FindClass("LStaticLeafMethods;", class_loader);
1182 ASSERT_TRUE(klass != NULL);
1183
1184 Method* method = klass->FindDirectMethod("sum", "(DD)D");
1185 ASSERT_TRUE(method != NULL);
1186
Brian Carlstrom9baa4ae2011-09-01 21:14:14 -07001187 Method::InvokeStub* stub = method->GetInvokeStub();
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001188
1189 double args[2];
1190 JValue result;
1191
1192 args[0] = 0.0;
1193 args[1] = 0.0;
1194 result.d = -1.0;
1195 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
1196 EXPECT_EQ(0.0, result.d);
1197
1198 args[0] = 1.0;
1199 args[1] = 2.0;
1200 result.d = 0.0;
1201 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
1202 EXPECT_EQ(3.0, result.d);
1203
1204 args[0] = 1.0;
1205 args[1] = -2.0;
1206 result.d = 0.0;
1207 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
1208 EXPECT_EQ(-1.0, result.d);
1209
1210 args[0] = DBL_MAX;
1211 args[1] = DBL_MIN;
1212 result.d = 0.0;
1213 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
1214 EXPECT_EQ(1.7976931348623157e308, result.d);
1215
1216 args[0] = DBL_MAX;
1217 args[1] = DBL_MAX;
1218 result.d = 0.0;
1219 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
1220 EXPECT_EQ(INFINITY, result.d);
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001221}
1222
1223TEST_F(JniInternalTest, StaticSumDoubleDoubleDoubleMethod) {
Brian Carlstrom9baa4ae2011-09-01 21:14:14 -07001224 const ClassLoader* class_loader = LoadDex("StaticLeafMethods");
1225 CompileDirectMethod(class_loader, "StaticLeafMethods", "sum", "(DDD)D");
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001226
1227 Class* klass = class_linker_->FindClass("LStaticLeafMethods;", class_loader);
1228 ASSERT_TRUE(klass != NULL);
1229
1230 Method* method = klass->FindDirectMethod("sum", "(DDD)D");
1231 ASSERT_TRUE(method != NULL);
1232
Brian Carlstrom9baa4ae2011-09-01 21:14:14 -07001233 Method::InvokeStub* stub = method->GetInvokeStub();
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001234
1235 double args[3];
1236 JValue result;
1237
1238 args[0] = 0.0;
1239 args[1] = 0.0;
1240 args[2] = 0.0;
1241 result.d = -1.0;
1242 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
1243 EXPECT_EQ(0.0, result.d);
1244
1245 args[0] = 1.0;
1246 args[1] = 2.0;
1247 args[2] = 3.0;
1248 result.d = 0.0;
1249 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
1250 EXPECT_EQ(6.0, result.d);
1251
1252 args[0] = 1.0;
1253 args[1] = -2.0;
1254 args[2] = 3.0;
1255 result.d = 0.0;
1256 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
1257 EXPECT_EQ(2.0, result.d);
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001258}
1259
1260TEST_F(JniInternalTest, StaticSumDoubleDoubleDoubleDoubleMethod) {
Brian Carlstrom9baa4ae2011-09-01 21:14:14 -07001261 const ClassLoader* class_loader = LoadDex("StaticLeafMethods");
1262 CompileDirectMethod(class_loader, "StaticLeafMethods", "sum", "(DDDD)D");
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001263
1264 Class* klass = class_linker_->FindClass("LStaticLeafMethods;", class_loader);
1265 ASSERT_TRUE(klass != NULL);
1266
1267 Method* method = klass->FindDirectMethod("sum", "(DDDD)D");
1268 ASSERT_TRUE(method != NULL);
1269
Brian Carlstrom9baa4ae2011-09-01 21:14:14 -07001270 Method::InvokeStub* stub = method->GetInvokeStub();
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001271
1272 double args[4];
1273 JValue result;
1274
1275 args[0] = 0.0;
1276 args[1] = 0.0;
1277 args[2] = 0.0;
1278 args[3] = 0.0;
1279 result.d = -1.0;
1280 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
1281 EXPECT_EQ(0.0, result.d);
1282
1283 args[0] = 1.0;
1284 args[1] = 2.0;
1285 args[2] = 3.0;
1286 args[3] = 4.0;
1287 result.d = 0.0;
1288 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
1289 EXPECT_EQ(10.0, result.d);
1290
1291 args[0] = 1.0;
1292 args[1] = -2.0;
1293 args[2] = 3.0;
1294 args[3] = -4.0;
1295 result.d = 0.0;
1296 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
1297 EXPECT_EQ(-2.0, result.d);
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001298}
1299
1300TEST_F(JniInternalTest, StaticSumDoubleDoubleDoubleDoubleDoubleMethod) {
Brian Carlstrom9baa4ae2011-09-01 21:14:14 -07001301 const ClassLoader* class_loader = LoadDex("StaticLeafMethods");
1302 CompileDirectMethod(class_loader, "StaticLeafMethods", "sum", "(DDDDD)D");
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001303
1304 Class* klass = class_linker_->FindClass("LStaticLeafMethods;", class_loader);
1305 ASSERT_TRUE(klass != NULL);
1306
1307 Method* method = klass->FindDirectMethod("sum", "(DDDDD)D");
1308 ASSERT_TRUE(method != NULL);
1309
Brian Carlstrom9baa4ae2011-09-01 21:14:14 -07001310 Method::InvokeStub* stub = method->GetInvokeStub();
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001311
1312 double args[5];
1313 JValue result;
1314
1315 args[0] = 0.0;
1316 args[1] = 0.0;
1317 args[2] = 0.0;
1318 args[3] = 0.0;
1319 args[4] = 0.0;
1320 result.d = -1.0;
1321 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
1322 EXPECT_EQ(0.0, result.d);
1323
1324 args[0] = 1.0;
1325 args[1] = 2.0;
1326 args[2] = 3.0;
1327 args[3] = 4.0;
1328 args[4] = 5.0;
1329 result.d = 0.0;
1330 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
1331 EXPECT_EQ(15.0, result.d);
1332
1333 args[0] = 1.0;
1334 args[1] = -2.0;
1335 args[2] = 3.0;
1336 args[3] = -4.0;
1337 args[4] = 5.0;
1338 result.d = 0.0;
1339 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
1340 EXPECT_EQ(3.0, result.d);
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001341}
1342#endif // __arm__
1343
Elliott Hughes37f7a402011-08-22 18:56:01 -07001344TEST_F(JniInternalTest, Throw) {
1345 EXPECT_EQ(JNI_ERR, env_->Throw(NULL));
1346
1347 jclass exception_class = env_->FindClass("java/lang/RuntimeException");
1348 ASSERT_TRUE(exception_class != NULL);
1349 jthrowable exception = reinterpret_cast<jthrowable>(env_->AllocObject(exception_class));
1350 ASSERT_TRUE(exception != NULL);
1351
1352 EXPECT_EQ(JNI_OK, env_->Throw(exception));
1353 EXPECT_TRUE(env_->ExceptionCheck());
Elliott Hughesa2501992011-08-26 19:39:54 -07001354 jthrowable thrown_exception = env_->ExceptionOccurred();
Elliott Hughes37f7a402011-08-22 18:56:01 -07001355 env_->ExceptionClear();
Elliott Hughesa2501992011-08-26 19:39:54 -07001356 EXPECT_TRUE(env_->IsSameObject(exception, thrown_exception));
Elliott Hughes37f7a402011-08-22 18:56:01 -07001357}
1358
1359TEST_F(JniInternalTest, ThrowNew) {
1360 EXPECT_EQ(JNI_ERR, env_->Throw(NULL));
1361
1362 jclass exception_class = env_->FindClass("java/lang/RuntimeException");
1363 ASSERT_TRUE(exception_class != NULL);
1364
1365 EXPECT_EQ(JNI_OK, env_->ThrowNew(exception_class, "hello world"));
1366 EXPECT_TRUE(env_->ExceptionCheck());
Elliott Hughesa2501992011-08-26 19:39:54 -07001367 jthrowable thrown_exception = env_->ExceptionOccurred();
Elliott Hughes37f7a402011-08-22 18:56:01 -07001368 env_->ExceptionClear();
Elliott Hughesa2501992011-08-26 19:39:54 -07001369 EXPECT_TRUE(env_->IsInstanceOf(thrown_exception, exception_class));
Elliott Hughes37f7a402011-08-22 18:56:01 -07001370}
1371
Elliott Hughesb465ab02011-08-24 11:21:21 -07001372// TODO: this test is DISABLED until we can actually run java.nio.Buffer's <init>.
1373TEST_F(JniInternalTest, DISABLED_NewDirectBuffer_GetDirectBufferAddress_GetDirectBufferCapacity) {
1374 jclass buffer_class = env_->FindClass("java/nio/Buffer");
1375 ASSERT_TRUE(buffer_class != NULL);
1376
1377 char bytes[1024];
1378 jobject buffer = env_->NewDirectByteBuffer(bytes, sizeof(bytes));
1379 ASSERT_TRUE(buffer != NULL);
1380 ASSERT_TRUE(env_->IsInstanceOf(buffer, buffer_class));
1381 ASSERT_TRUE(env_->GetDirectBufferAddress(buffer) == bytes);
1382 ASSERT_TRUE(env_->GetDirectBufferCapacity(buffer) == sizeof(bytes));
1383}
1384
Ian Rogers0cfe1fb2011-08-26 03:29:44 -07001385} // namespace art