blob: 53b8334dad27f27d79ff2e1285382a6dfc1e307b [file] [log] [blame]
Elliott Hughes0c9cd562011-08-12 10:59:29 -07001// Copyright 2011 Google Inc. All Rights Reserved.
2
Carl Shapiro9b9ba282011-08-14 15:30:39 -07003#include "jni_internal.h"
Elliott Hughes0c9cd562011-08-12 10:59:29 -07004
Carl Shapiro9b9ba282011-08-14 15:30:39 -07005#include <cmath>
6#include <sys/mman.h>
7
8#include "common_test.h"
Elliott Hughes0c9cd562011-08-12 10:59:29 -07009#include "gtest/gtest.h"
10
11namespace art {
12
Brian Carlstromf734cf52011-08-17 16:28:14 -070013class JniInternalTest : public CommonTest {
Elliott Hughesc7ac37f2011-08-12 12:21:58 -070014 protected:
15 virtual void SetUp() {
Brian Carlstromf734cf52011-08-17 16:28:14 -070016 CommonTest::SetUp();
Elliott Hughesc7ac37f2011-08-12 12:21:58 -070017 env_ = Thread::Current()->GetJniEnv();
Elliott Hughes814e4032011-08-23 12:07:56 -070018 aioobe_ = env_->FindClass("java/lang/ArrayIndexOutOfBoundsException");
19 CHECK(aioobe_ != NULL);
Elliott Hughesc7ac37f2011-08-12 12:21:58 -070020 }
21 JNIEnv* env_;
Elliott Hughes814e4032011-08-23 12:07:56 -070022 jclass aioobe_;
Elliott Hughes0c9cd562011-08-12 10:59:29 -070023};
24
Elliott Hughes885c3bd2011-08-22 16:59:20 -070025TEST_F(JniInternalTest, AllocObject) {
26 jclass c = env_->FindClass("java/lang/String");
27 ASSERT_TRUE(c != NULL);
28 jobject o = env_->AllocObject(c);
29 ASSERT_TRUE(o != NULL);
30
31 // We have an instance of the class we asked for...
32 ASSERT_TRUE(env_->IsInstanceOf(o, c));
33 // ...whose fields haven't been initialized because
34 // we didn't call a constructor.
35 ASSERT_EQ(0, env_->GetIntField(o, env_->GetFieldID(c, "count", "I")));
36 ASSERT_EQ(0, env_->GetIntField(o, env_->GetFieldID(c, "offset", "I")));
37 ASSERT_TRUE(env_->GetObjectField(o, env_->GetFieldID(c, "value", "[C")) == NULL);
38}
39
Elliott Hughesc7ac37f2011-08-12 12:21:58 -070040TEST_F(JniInternalTest, GetVersion) {
41 ASSERT_EQ(JNI_VERSION_1_6, env_->GetVersion());
42}
43
Elliott Hughes0c9cd562011-08-12 10:59:29 -070044#define EXPECT_CLASS_FOUND(NAME) \
Elliott Hughesbd935992011-08-22 11:59:34 -070045 EXPECT_TRUE(env_->FindClass(NAME) != NULL); \
46 EXPECT_FALSE(env_->ExceptionCheck())
Elliott Hughes0c9cd562011-08-12 10:59:29 -070047
48#define EXPECT_CLASS_NOT_FOUND(NAME) \
Elliott Hughesbd935992011-08-22 11:59:34 -070049 EXPECT_TRUE(env_->FindClass(NAME) == NULL); \
50 EXPECT_TRUE(env_->ExceptionCheck()); \
51 env_->ExceptionClear()
Elliott Hughes0c9cd562011-08-12 10:59:29 -070052
53TEST_F(JniInternalTest, FindClass) {
Elliott Hughes0c9cd562011-08-12 10:59:29 -070054 // TODO: when these tests start failing because you're calling FindClass
55 // with a pending exception, fix EXPECT_CLASS_NOT_FOUND to assert that an
56 // exception was thrown and clear the exception.
57
58 // TODO: . is only allowed as an alternative to / if CheckJNI is off.
59
60 // Reference types...
61 // You can't include the "L;" in a JNI class descriptor.
62 EXPECT_CLASS_FOUND("java/lang/String");
63 EXPECT_CLASS_NOT_FOUND("Ljava/lang/String;");
64 // We support . as well as / for compatibility.
65 EXPECT_CLASS_FOUND("java.lang.String");
66 EXPECT_CLASS_NOT_FOUND("Ljava.lang.String;");
67 // ...for arrays too, where you must include "L;".
68 EXPECT_CLASS_FOUND("[Ljava/lang/String;");
69 EXPECT_CLASS_NOT_FOUND("[java/lang/String");
70 EXPECT_CLASS_FOUND("[Ljava.lang.String;");
71 EXPECT_CLASS_NOT_FOUND("[java.lang.String");
72
73 // Primitive arrays are okay (if the primitive type is valid)...
74 EXPECT_CLASS_FOUND("[C");
75 EXPECT_CLASS_NOT_FOUND("[K");
76 // But primitive types aren't allowed...
77 EXPECT_CLASS_NOT_FOUND("C");
78 EXPECT_CLASS_NOT_FOUND("K");
79}
80
Elliott Hughescdf53122011-08-19 15:46:09 -070081#define EXPECT_EXCEPTION(exception_class) \
82 do { \
83 EXPECT_TRUE(env_->ExceptionCheck()); \
84 jthrowable exception = env_->ExceptionOccurred(); \
85 EXPECT_NE(static_cast<jthrowable>(NULL), exception); \
86 EXPECT_TRUE(env_->IsInstanceOf(exception, exception_class)); \
87 env_->ExceptionClear(); \
88 } while (false)
89
90TEST_F(JniInternalTest, GetFieldID) {
91 jclass jlnsfe = env_->FindClass("java/lang/NoSuchFieldError");
92 ASSERT_TRUE(jlnsfe != NULL);
93 jclass c = env_->FindClass("java/lang/String");
94 ASSERT_TRUE(c != NULL);
95
96 // Wrong type.
97 jfieldID fid = env_->GetFieldID(c, "count", "J");
98 EXPECT_EQ(static_cast<jfieldID>(NULL), fid);
99 EXPECT_EXCEPTION(jlnsfe);
100
101 // Wrong name.
102 fid = env_->GetFieldID(c, "Count", "I");
103 EXPECT_EQ(static_cast<jfieldID>(NULL), fid);
104 EXPECT_EXCEPTION(jlnsfe);
105
106 // Good declared field lookup.
107 fid = env_->GetFieldID(c, "count", "I");
108 EXPECT_NE(static_cast<jfieldID>(NULL), fid);
109 EXPECT_TRUE(fid != NULL);
110 EXPECT_FALSE(env_->ExceptionCheck());
111
112 // Good superclass field lookup.
113 c = env_->FindClass("java/lang/StringBuilder");
114 fid = env_->GetFieldID(c, "count", "I");
115 EXPECT_NE(static_cast<jfieldID>(NULL), fid);
116 EXPECT_TRUE(fid != NULL);
117 EXPECT_FALSE(env_->ExceptionCheck());
118
119 // Not instance.
120 fid = env_->GetFieldID(c, "CASE_INSENSITIVE_ORDER", "Ljava/util/Comparator;");
121 EXPECT_EQ(static_cast<jfieldID>(NULL), fid);
122 EXPECT_EXCEPTION(jlnsfe);
123}
124
125TEST_F(JniInternalTest, GetStaticFieldID) {
126 jclass jlnsfe = env_->FindClass("java/lang/NoSuchFieldError");
127 ASSERT_TRUE(jlnsfe != NULL);
128 jclass c = env_->FindClass("java/lang/String");
129 ASSERT_TRUE(c != NULL);
130
131 // Wrong type.
132 jfieldID fid = env_->GetStaticFieldID(c, "CASE_INSENSITIVE_ORDER", "J");
133 EXPECT_EQ(static_cast<jfieldID>(NULL), fid);
134 EXPECT_EXCEPTION(jlnsfe);
135
136 // Wrong name.
137 fid = env_->GetStaticFieldID(c, "cASE_INSENSITIVE_ORDER", "Ljava/util/Comparator;");
138 EXPECT_EQ(static_cast<jfieldID>(NULL), fid);
139 EXPECT_EXCEPTION(jlnsfe);
140
141 // Good declared field lookup.
142 fid = env_->GetStaticFieldID(c, "CASE_INSENSITIVE_ORDER", "Ljava/util/Comparator;");
143 EXPECT_NE(static_cast<jfieldID>(NULL), fid);
144 EXPECT_TRUE(fid != NULL);
145 EXPECT_FALSE(env_->ExceptionCheck());
146
147 // Not static.
148 fid = env_->GetStaticFieldID(c, "count", "I");
149 EXPECT_EQ(static_cast<jfieldID>(NULL), fid);
150 EXPECT_EXCEPTION(jlnsfe);
151}
152
Ian Rogers4dd71f12011-08-16 14:16:02 -0700153TEST_F(JniInternalTest, GetMethodID) {
154 jclass jlobject = env_->FindClass("java/lang/Object");
155 jclass jlstring = env_->FindClass("java/lang/String");
156 jclass jlnsme = env_->FindClass("java/lang/NoSuchMethodError");
157
158 // Sanity check that no exceptions are pending
Elliott Hughescdf53122011-08-19 15:46:09 -0700159 ASSERT_FALSE(env_->ExceptionCheck());
Ian Rogers4dd71f12011-08-16 14:16:02 -0700160
161 // Check that java.lang.Object.foo() doesn't exist and NoSuchMethodError is
162 // a pending exception
163 jmethodID method = env_->GetMethodID(jlobject, "foo", "()V");
164 EXPECT_EQ(static_cast<jmethodID>(NULL), method);
Elliott Hughescdf53122011-08-19 15:46:09 -0700165 EXPECT_EXCEPTION(jlnsme);
Ian Rogers4dd71f12011-08-16 14:16:02 -0700166
167 // Check that java.lang.Object.equals() does exist
Ian Rogers4dd71f12011-08-16 14:16:02 -0700168 method = env_->GetMethodID(jlobject, "equals", "(Ljava/lang/Object;)Z");
169 EXPECT_NE(static_cast<jmethodID>(NULL), method);
170 EXPECT_FALSE(env_->ExceptionCheck());
Ian Rogers4dd71f12011-08-16 14:16:02 -0700171
172 // Check that GetMethodID for java.lang.String.valueOf(int) fails as the
173 // method is static
174 method = env_->GetMethodID(jlstring, "valueOf", "(I)Ljava/lang/String;");
175 EXPECT_EQ(static_cast<jmethodID>(NULL), method);
Elliott Hughescdf53122011-08-19 15:46:09 -0700176 EXPECT_EXCEPTION(jlnsme);
Ian Rogers4dd71f12011-08-16 14:16:02 -0700177}
178
179TEST_F(JniInternalTest, GetStaticMethodID) {
180 jclass jlobject = env_->FindClass("java/lang/Object");
181 jclass jlnsme = env_->FindClass("java/lang/NoSuchMethodError");
182
183 // Sanity check that no exceptions are pending
Elliott Hughescdf53122011-08-19 15:46:09 -0700184 ASSERT_FALSE(env_->ExceptionCheck());
Ian Rogers4dd71f12011-08-16 14:16:02 -0700185
186 // Check that java.lang.Object.foo() doesn't exist and NoSuchMethodError is
187 // a pending exception
188 jmethodID method = env_->GetStaticMethodID(jlobject, "foo", "()V");
189 EXPECT_EQ(static_cast<jmethodID>(NULL), method);
Elliott Hughescdf53122011-08-19 15:46:09 -0700190 EXPECT_EXCEPTION(jlnsme);
Ian Rogers4dd71f12011-08-16 14:16:02 -0700191
192 // Check that GetStaticMethodID for java.lang.Object.equals(Object) fails as
193 // the method is not static
194 method = env_->GetStaticMethodID(jlobject, "equals", "(Ljava/lang/Object;)Z");
195 EXPECT_EQ(static_cast<jmethodID>(NULL), method);
Elliott Hughescdf53122011-08-19 15:46:09 -0700196 EXPECT_EXCEPTION(jlnsme);
Ian Rogers4dd71f12011-08-16 14:16:02 -0700197
198 // Check that java.lang.String.valueOf(int) does exist
Ian Rogers4dd71f12011-08-16 14:16:02 -0700199 jclass jlstring = env_->FindClass("java/lang/String");
200 method = env_->GetStaticMethodID(jlstring, "valueOf",
201 "(I)Ljava/lang/String;");
202 EXPECT_NE(static_cast<jmethodID>(NULL), method);
203 EXPECT_FALSE(env_->ExceptionCheck());
Ian Rogers4dd71f12011-08-16 14:16:02 -0700204}
205
Elliott Hughescdf53122011-08-19 15:46:09 -0700206TEST_F(JniInternalTest, FromReflectedField_ToReflectedField) {
207 jclass jlrField = env_->FindClass("java/lang/reflect/Field");
208 jclass c = env_->FindClass("java/lang/String");
209 ASSERT_TRUE(c != NULL);
210 jfieldID fid = env_->GetFieldID(c, "count", "I");
211 ASSERT_TRUE(fid != NULL);
212 // Turn the fid into a java.lang.reflect.Field...
213 jobject field = env_->ToReflectedField(c, fid, JNI_FALSE);
214 ASSERT_TRUE(c != NULL);
215 ASSERT_TRUE(env_->IsInstanceOf(field, jlrField));
216 // ...and back again.
217 jfieldID fid2 = env_->FromReflectedField(field);
218 ASSERT_TRUE(fid2 != NULL);
219}
220
221TEST_F(JniInternalTest, FromReflectedMethod_ToReflectedMethod) {
222 jclass jlrMethod = env_->FindClass("java/lang/reflect/Method");
223 jclass c = env_->FindClass("java/lang/String");
224 ASSERT_TRUE(c != NULL);
225 jmethodID mid = env_->GetMethodID(c, "length", "()I");
226 ASSERT_TRUE(mid != NULL);
227 // Turn the mid into a java.lang.reflect.Method...
228 jobject method = env_->ToReflectedMethod(c, mid, JNI_FALSE);
229 ASSERT_TRUE(c != NULL);
230 ASSERT_TRUE(env_->IsInstanceOf(method, jlrMethod));
231 // ...and back again.
232 jmethodID mid2 = env_->FromReflectedMethod(method);
233 ASSERT_TRUE(mid2 != NULL);
234}
235
Ian Rogers4dd71f12011-08-16 14:16:02 -0700236TEST_F(JniInternalTest, RegisterNatives) {
237 jclass jlobject = env_->FindClass("java/lang/Object");
238 jclass jlnsme = env_->FindClass("java/lang/NoSuchMethodError");
239
240 // Sanity check that no exceptions are pending
Elliott Hughescdf53122011-08-19 15:46:09 -0700241 ASSERT_FALSE(env_->ExceptionCheck());
Ian Rogers4dd71f12011-08-16 14:16:02 -0700242
243 // Check that registering to a non-existent java.lang.Object.foo() causes a
244 // NoSuchMethodError
245 {
246 JNINativeMethod methods[] = {{"foo", "()V", NULL}};
247 env_->RegisterNatives(jlobject, methods, 1);
248 }
Elliott Hughescdf53122011-08-19 15:46:09 -0700249 EXPECT_EXCEPTION(jlnsme);
Ian Rogers4dd71f12011-08-16 14:16:02 -0700250
251 // Check that registering non-native methods causes a NoSuchMethodError
252 {
253 JNINativeMethod methods[] = {{"equals", "(Ljava/lang/Object;)Z", NULL}};
254 env_->RegisterNatives(jlobject, methods, 1);
255 }
Elliott Hughescdf53122011-08-19 15:46:09 -0700256 EXPECT_EXCEPTION(jlnsme);
Ian Rogers4dd71f12011-08-16 14:16:02 -0700257
258 // Check that registering native methods is successful
259 {
260 JNINativeMethod methods[] = {{"hashCode", "()I", NULL}};
261 env_->RegisterNatives(jlobject, methods, 1);
262 }
263 EXPECT_FALSE(env_->ExceptionCheck());
264}
265
Elliott Hughes814e4032011-08-23 12:07:56 -0700266#define EXPECT_PRIMITIVE_ARRAY(new_fn, get_region_fn, set_region_fn, scalar_type, expected_class_descriptor) \
267 jsize size = 4; \
268 /* Allocate an array and check it has the right type and length. */ \
269 scalar_type ## Array a = env_->new_fn(size); \
270 EXPECT_TRUE(a != NULL); \
271 EXPECT_TRUE(env_->IsInstanceOf(a, env_->FindClass(expected_class_descriptor))); \
272 EXPECT_EQ(size, env_->GetArrayLength(a)); \
273 /* AIOOBE for negative start offset. */ \
274 env_->get_region_fn(a, -1, 1, NULL); \
275 EXPECT_EXCEPTION(aioobe_); \
276 env_->set_region_fn(a, -1, 1, NULL); \
277 EXPECT_EXCEPTION(aioobe_); \
278 /* AIOOBE for negative length. */ \
279 env_->get_region_fn(a, 0, -1, NULL); \
280 EXPECT_EXCEPTION(aioobe_); \
281 env_->set_region_fn(a, 0, -1, NULL); \
282 EXPECT_EXCEPTION(aioobe_); \
283 /* AIOOBE for buffer overrun. */ \
284 env_->get_region_fn(a, size - 1, size, NULL); \
285 EXPECT_EXCEPTION(aioobe_); \
286 env_->set_region_fn(a, size - 1, size, NULL); \
287 EXPECT_EXCEPTION(aioobe_); \
288 /* Prepare a couple of buffers. */ \
289 scalar_type src_buf[size]; \
290 scalar_type dst_buf[size]; \
291 for (jsize i = 0; i < size; ++i) { src_buf[i] = scalar_type(i); } \
292 for (jsize i = 0; i < size; ++i) { dst_buf[i] = scalar_type(-1); } \
293 /* Copy all of src_buf onto the heap. */ \
294 env_->set_region_fn(a, 0, size, src_buf); \
295 /* Copy back only part. */ \
296 env_->get_region_fn(a, 1, size - 2, &dst_buf[1]); \
297 EXPECT_FALSE(memcmp(src_buf, dst_buf, sizeof(src_buf)) == 0) << "short copy equal"; \
298 /* Copy the missing pieces. */ \
299 env_->get_region_fn(a, 0, 1, dst_buf); \
300 env_->get_region_fn(a, size - 1, 1, &dst_buf[size - 1]); \
301 EXPECT_TRUE(memcmp(src_buf, dst_buf, sizeof(src_buf)) == 0) << "fixed copy not equal"; \
302 /* Copy back the whole array. */ \
303 env_->get_region_fn(a, 0, size, dst_buf); \
304 EXPECT_TRUE(memcmp(src_buf, dst_buf, sizeof(src_buf)) == 0) << "full copy not equal"
Elliott Hughesbd935992011-08-22 11:59:34 -0700305
Elliott Hughes814e4032011-08-23 12:07:56 -0700306TEST_F(JniInternalTest, BooleanArrays) {
307 EXPECT_PRIMITIVE_ARRAY(NewBooleanArray, GetBooleanArrayRegion, SetBooleanArrayRegion, jboolean, "[Z");
308}
309TEST_F(JniInternalTest, ByteArrays) {
310 EXPECT_PRIMITIVE_ARRAY(NewByteArray, GetByteArrayRegion, SetByteArrayRegion, jbyte, "[B");
311}
312TEST_F(JniInternalTest, CharArrays) {
313 EXPECT_PRIMITIVE_ARRAY(NewCharArray, GetCharArrayRegion, SetCharArrayRegion, jchar, "[C");
314}
315TEST_F(JniInternalTest, DoubleArrays) {
316 EXPECT_PRIMITIVE_ARRAY(NewDoubleArray, GetDoubleArrayRegion, SetDoubleArrayRegion, jdouble, "[D");
317}
318TEST_F(JniInternalTest, FloatArrays) {
319 EXPECT_PRIMITIVE_ARRAY(NewFloatArray, GetFloatArrayRegion, SetFloatArrayRegion, jfloat, "[F");
320}
321TEST_F(JniInternalTest, IntArrays) {
322 EXPECT_PRIMITIVE_ARRAY(NewIntArray, GetIntArrayRegion, SetIntArrayRegion, jint, "[I");
323}
324TEST_F(JniInternalTest, LongArrays) {
325 EXPECT_PRIMITIVE_ARRAY(NewLongArray, GetLongArrayRegion, SetLongArrayRegion, jlong, "[J");
326}
327TEST_F(JniInternalTest, ShortArrays) {
328 EXPECT_PRIMITIVE_ARRAY(NewShortArray, GetShortArrayRegion, SetShortArrayRegion, jshort, "[S");
Elliott Hughesd8ddfd52011-08-15 14:32:53 -0700329}
330
Elliott Hughesf2682d52011-08-15 16:37:04 -0700331TEST_F(JniInternalTest, NewObjectArray) {
332 // TODO: death tests for negative array sizes.
333
Elliott Hughesf2682d52011-08-15 16:37:04 -0700334 // TODO: check non-NULL initial elements.
335
Elliott Hughesbd935992011-08-22 11:59:34 -0700336 jclass element_class = env_->FindClass("java/lang/String");
337 ASSERT_TRUE(element_class != NULL);
338 jclass array_class = env_->FindClass("[Ljava/lang/String;");
339 ASSERT_TRUE(array_class != NULL);
Elliott Hughesf2682d52011-08-15 16:37:04 -0700340
Elliott Hughesbd935992011-08-22 11:59:34 -0700341 jobjectArray a;
Elliott Hughesf2682d52011-08-15 16:37:04 -0700342
Elliott Hughesbd935992011-08-22 11:59:34 -0700343 a = env_->NewObjectArray(0, element_class, NULL);
344 EXPECT_TRUE(a != NULL);
345 EXPECT_TRUE(env_->IsInstanceOf(a, array_class));
346 EXPECT_EQ(0, env_->GetArrayLength(a));
347
348 a = env_->NewObjectArray(1, element_class, NULL);
349 EXPECT_TRUE(a != NULL);
350 EXPECT_TRUE(env_->IsInstanceOf(a, array_class));
351 EXPECT_EQ(1, env_->GetArrayLength(a));
352}
353
354TEST_F(JniInternalTest, GetArrayLength) {
355 // Already tested in NewObjectArray/NewPrimitiveArray.
Elliott Hughes8a26c5c2011-08-15 18:35:43 -0700356}
357
Elliott Hughes37f7a402011-08-22 18:56:01 -0700358TEST_F(JniInternalTest, GetObjectClass) {
359 jclass string_class = env_->FindClass("java/lang/String");
360 ASSERT_TRUE(string_class != NULL);
361 jclass class_class = env_->FindClass("java/lang/Class");
362 ASSERT_TRUE(class_class != NULL);
363
364 jstring s = env_->NewStringUTF("poop");
365 jclass c = env_->GetObjectClass(s);
366 ASSERT_TRUE(env_->IsSameObject(string_class, c));
367
368 jclass c2 = env_->GetObjectClass(c);
369 ASSERT_TRUE(env_->IsSameObject(class_class, env_->GetObjectClass(c2)));
370}
371
Elliott Hughes885c3bd2011-08-22 16:59:20 -0700372TEST_F(JniInternalTest, GetSuperclass) {
373 jclass object_class = env_->FindClass("java/lang/Object");
374 ASSERT_TRUE(object_class != NULL);
375 jclass string_class = env_->FindClass("java/lang/String");
376 ASSERT_TRUE(string_class != NULL);
377 ASSERT_TRUE(env_->IsSameObject(object_class, env_->GetSuperclass(string_class)));
378 ASSERT_TRUE(env_->GetSuperclass(object_class) == NULL);
379}
380
Elliott Hughes37f7a402011-08-22 18:56:01 -0700381TEST_F(JniInternalTest, IsAssignableFrom) {
382 jclass object_class = env_->FindClass("java/lang/Object");
383 ASSERT_TRUE(object_class != NULL);
384 jclass string_class = env_->FindClass("java/lang/String");
385 ASSERT_TRUE(string_class != NULL);
386
387 ASSERT_TRUE(env_->IsAssignableFrom(object_class, string_class));
388 ASSERT_FALSE(env_->IsAssignableFrom(string_class, object_class));
389}
390
Elliott Hughes8a26c5c2011-08-15 18:35:43 -0700391TEST_F(JniInternalTest, NewStringUTF) {
392 EXPECT_TRUE(env_->NewStringUTF(NULL) == NULL);
Elliott Hughes814e4032011-08-23 12:07:56 -0700393 jstring s;
394
395 s = env_->NewStringUTF("");
396 EXPECT_TRUE(s != NULL);
397 EXPECT_EQ(0, env_->GetStringLength(s));
398 EXPECT_EQ(0, env_->GetStringUTFLength(s));
399 s = env_->NewStringUTF("hello");
400 EXPECT_TRUE(s != NULL);
401 EXPECT_EQ(5, env_->GetStringLength(s));
402 EXPECT_EQ(5, env_->GetStringUTFLength(s));
403
Elliott Hughes8a26c5c2011-08-15 18:35:43 -0700404 // TODO: check some non-ASCII strings.
Elliott Hughesf2682d52011-08-15 16:37:04 -0700405}
406
Elliott Hughes814e4032011-08-23 12:07:56 -0700407TEST_F(JniInternalTest, NewString) {
408 EXPECT_TRUE(env_->NewString(NULL, 0) == NULL);
409
410 jchar chars[] = { 'h', 'i' };
411 jstring s;
412 s = env_->NewString(chars, 0);
413 EXPECT_TRUE(s != NULL);
414 EXPECT_EQ(0, env_->GetStringLength(s));
415 EXPECT_EQ(0, env_->GetStringUTFLength(s));
416 s = env_->NewString(chars, 2);
417 EXPECT_TRUE(s != NULL);
418 EXPECT_EQ(2, env_->GetStringLength(s));
419 EXPECT_EQ(2, env_->GetStringUTFLength(s));
420
421 // TODO: check some non-ASCII strings.
422}
423
424TEST_F(JniInternalTest, GetObjectArrayElement_SetObjectArrayElement) {
Elliott Hughes289da822011-08-16 10:11:20 -0700425 jclass c = env_->FindClass("[Ljava/lang/Object;");
426 ASSERT_TRUE(c != NULL);
427
428 jobjectArray array = env_->NewObjectArray(1, c, NULL);
429 EXPECT_TRUE(array != NULL);
Elliott Hughes814e4032011-08-23 12:07:56 -0700430 EXPECT_TRUE(env_->GetObjectArrayElement(array, 0) == NULL);
Elliott Hughes289da822011-08-16 10:11:20 -0700431 env_->SetObjectArrayElement(array, 0, c);
Elliott Hughes814e4032011-08-23 12:07:56 -0700432 EXPECT_TRUE(env_->IsSameObject(env_->GetObjectArrayElement(array, 0), c));
Elliott Hughesa5b897e2011-08-16 11:33:06 -0700433
434 // ArrayIndexOutOfBounds for negative index.
Elliott Hughesa5b897e2011-08-16 11:33:06 -0700435 env_->SetObjectArrayElement(array, -1, c);
Elliott Hughes814e4032011-08-23 12:07:56 -0700436 EXPECT_EXCEPTION(aioobe_);
Elliott Hughesa5b897e2011-08-16 11:33:06 -0700437
438 // ArrayIndexOutOfBounds for too-large index.
Elliott Hughesa5b897e2011-08-16 11:33:06 -0700439 env_->SetObjectArrayElement(array, 1, c);
Elliott Hughes814e4032011-08-23 12:07:56 -0700440 EXPECT_EXCEPTION(aioobe_);
Elliott Hughesa5b897e2011-08-16 11:33:06 -0700441
Elliott Hughes289da822011-08-16 10:11:20 -0700442 // TODO: check ArrayStoreException thrown for bad types.
443}
444
Elliott Hughes885c3bd2011-08-22 16:59:20 -0700445#define EXPECT_STATIC_PRIMITIVE_FIELD(type, field_name, sig, value1, value2) \
446 do { \
447 jfieldID fid = env_->GetStaticFieldID(c, field_name, sig); \
448 EXPECT_TRUE(fid != NULL); \
449 env_->SetStatic ## type ## Field(c, fid, value1); \
450 EXPECT_EQ(value1, env_->GetStatic ## type ## Field(c, fid)); \
451 env_->SetStatic ## type ## Field(c, fid, value2); \
452 EXPECT_EQ(value2, env_->GetStatic ## type ## Field(c, fid)); \
453 } while (false)
454
455#define EXPECT_PRIMITIVE_FIELD(instance, type, field_name, sig, value1, value2) \
456 do { \
457 jfieldID fid = env_->GetFieldID(c, field_name, sig); \
458 EXPECT_TRUE(fid != NULL); \
459 env_->Set ## type ## Field(instance, fid, value1); \
460 EXPECT_EQ(value1, env_->Get ## type ## Field(instance, fid)); \
461 env_->Set ## type ## Field(instance, fid, value2); \
462 EXPECT_EQ(value2, env_->Get ## type ## Field(instance, fid)); \
463 } while (false)
464
465
466TEST_F(JniInternalTest, GetPrimitiveField_SetPrimitiveField) {
467 scoped_ptr<DexFile> dex(OpenDexFileBase64(kAllFields, "kAllFields"));
468 PathClassLoader* class_loader = AllocPathClassLoader(dex.get());
469 Thread::Current()->SetClassLoaderOverride(class_loader);
470
471 jclass c = env_->FindClass("AllFields");
472 ASSERT_TRUE(c != NULL);
473 jobject o = env_->AllocObject(c);
474 ASSERT_TRUE(o != NULL);
475
476 EXPECT_STATIC_PRIMITIVE_FIELD(Boolean, "sZ", "Z", true, false);
477 EXPECT_STATIC_PRIMITIVE_FIELD(Byte, "sB", "B", 1, 2);
478 EXPECT_STATIC_PRIMITIVE_FIELD(Char, "sC", "C", 'a', 'b');
479 EXPECT_STATIC_PRIMITIVE_FIELD(Double, "sD", "D", 1.0, 2.0);
480 EXPECT_STATIC_PRIMITIVE_FIELD(Float, "sF", "F", 1.0, 2.0);
481 EXPECT_STATIC_PRIMITIVE_FIELD(Int, "sI", "I", 1, 2);
482 EXPECT_STATIC_PRIMITIVE_FIELD(Long, "sJ", "J", 1, 2);
483 EXPECT_STATIC_PRIMITIVE_FIELD(Short, "sS", "S", 1, 2);
484
485 EXPECT_PRIMITIVE_FIELD(o, Boolean, "iZ", "Z", true, false);
486 EXPECT_PRIMITIVE_FIELD(o, Byte, "iB", "B", 1, 2);
487 EXPECT_PRIMITIVE_FIELD(o, Char, "iC", "C", 'a', 'b');
488 EXPECT_PRIMITIVE_FIELD(o, Double, "iD", "D", 1.0, 2.0);
489 EXPECT_PRIMITIVE_FIELD(o, Float, "iF", "F", 1.0, 2.0);
490 EXPECT_PRIMITIVE_FIELD(o, Int, "iI", "I", 1, 2);
491 EXPECT_PRIMITIVE_FIELD(o, Long, "iJ", "J", 1, 2);
492 EXPECT_PRIMITIVE_FIELD(o, Short, "iS", "S", 1, 2);
493}
494
495TEST_F(JniInternalTest, GetObjectField_SetObjectField) {
496 scoped_ptr<DexFile> dex(OpenDexFileBase64(kAllFields, "kAllFields"));
497 PathClassLoader* class_loader = AllocPathClassLoader(dex.get());
498 Thread::Current()->SetClassLoaderOverride(class_loader);
499
500 jclass c = env_->FindClass("AllFields");
501 ASSERT_TRUE(c != NULL);
502 jobject o = env_->AllocObject(c);
503 ASSERT_TRUE(o != NULL);
504
505 jstring s1 = env_->NewStringUTF("hello");
506 ASSERT_TRUE(s1 != NULL);
507 jstring s2 = env_->NewStringUTF("world");
508 ASSERT_TRUE(s2 != NULL);
509
510 jfieldID s_fid = env_->GetStaticFieldID(c, "sObject", "Ljava/lang/Object;");
511 ASSERT_TRUE(s_fid != NULL);
512 jfieldID i_fid = env_->GetFieldID(c, "iObject", "Ljava/lang/Object;");
513 ASSERT_TRUE(i_fid != NULL);
514
515 env_->SetStaticObjectField(c, s_fid, s1);
516 ASSERT_TRUE(env_->IsSameObject(s1, env_->GetStaticObjectField(c, s_fid)));
517 env_->SetStaticObjectField(c, s_fid, s2);
518 ASSERT_TRUE(env_->IsSameObject(s2, env_->GetStaticObjectField(c, s_fid)));
519
520 env_->SetObjectField(o, i_fid, s1);
521 ASSERT_TRUE(env_->IsSameObject(s1, env_->GetObjectField(o, i_fid)));
522 env_->SetObjectField(o, i_fid, s2);
523 ASSERT_TRUE(env_->IsSameObject(s2, env_->GetObjectField(o, i_fid)));
524}
525
Elliott Hughes18c07532011-08-18 15:50:51 -0700526TEST_F(JniInternalTest, NewLocalRef_NULL) {
527 EXPECT_TRUE(env_->NewLocalRef(NULL) == NULL);
528}
529
530TEST_F(JniInternalTest, NewLocalRef) {
531 jstring s = env_->NewStringUTF("");
532 ASSERT_TRUE(s != NULL);
533 jobject o = env_->NewLocalRef(s);
534 EXPECT_TRUE(o != NULL);
535 EXPECT_TRUE(o != s);
536
537 // TODO: check that o is a local reference.
538}
539
540TEST_F(JniInternalTest, DeleteLocalRef_NULL) {
541 env_->DeleteLocalRef(NULL);
542}
543
544TEST_F(JniInternalTest, DeleteLocalRef) {
545 jstring s = env_->NewStringUTF("");
546 ASSERT_TRUE(s != NULL);
547 env_->DeleteLocalRef(s);
548
549 // Currently, deleting an already-deleted reference is just a warning.
550 env_->DeleteLocalRef(s);
551
552 s = env_->NewStringUTF("");
553 ASSERT_TRUE(s != NULL);
554 jobject o = env_->NewLocalRef(s);
555 ASSERT_TRUE(o != NULL);
556
557 env_->DeleteLocalRef(s);
558 env_->DeleteLocalRef(o);
559}
560
561TEST_F(JniInternalTest, NewGlobalRef_NULL) {
562 EXPECT_TRUE(env_->NewGlobalRef(NULL) == NULL);
563}
564
565TEST_F(JniInternalTest, NewGlobalRef) {
566 jstring s = env_->NewStringUTF("");
567 ASSERT_TRUE(s != NULL);
568 jobject o = env_->NewGlobalRef(s);
569 EXPECT_TRUE(o != NULL);
570 EXPECT_TRUE(o != s);
571
572 // TODO: check that o is a global reference.
573}
574
575TEST_F(JniInternalTest, DeleteGlobalRef_NULL) {
576 env_->DeleteGlobalRef(NULL);
577}
578
579TEST_F(JniInternalTest, DeleteGlobalRef) {
580 jstring s = env_->NewStringUTF("");
581 ASSERT_TRUE(s != NULL);
582
583 jobject o = env_->NewGlobalRef(s);
584 ASSERT_TRUE(o != NULL);
585 env_->DeleteGlobalRef(o);
586
587 // Currently, deleting an already-deleted reference is just a warning.
588 env_->DeleteGlobalRef(o);
589
590 jobject o1 = env_->NewGlobalRef(s);
591 ASSERT_TRUE(o1 != NULL);
592 jobject o2 = env_->NewGlobalRef(s);
593 ASSERT_TRUE(o2 != NULL);
594
595 env_->DeleteGlobalRef(o1);
596 env_->DeleteGlobalRef(o2);
597}
598
599TEST_F(JniInternalTest, NewWeakGlobalRef_NULL) {
600 EXPECT_TRUE(env_->NewWeakGlobalRef(NULL) == NULL);
601}
602
603TEST_F(JniInternalTest, NewWeakGlobalRef) {
604 jstring s = env_->NewStringUTF("");
605 ASSERT_TRUE(s != NULL);
606 jobject o = env_->NewWeakGlobalRef(s);
607 EXPECT_TRUE(o != NULL);
608 EXPECT_TRUE(o != s);
609
610 // TODO: check that o is a weak global reference.
611}
612
613TEST_F(JniInternalTest, DeleteWeakGlobalRef_NULL) {
614 env_->DeleteWeakGlobalRef(NULL);
615}
616
617TEST_F(JniInternalTest, DeleteWeakGlobalRef) {
618 jstring s = env_->NewStringUTF("");
619 ASSERT_TRUE(s != NULL);
620
621 jobject o = env_->NewWeakGlobalRef(s);
622 ASSERT_TRUE(o != NULL);
623 env_->DeleteWeakGlobalRef(o);
624
625 // Currently, deleting an already-deleted reference is just a warning.
626 env_->DeleteWeakGlobalRef(o);
627
628 jobject o1 = env_->NewWeakGlobalRef(s);
629 ASSERT_TRUE(o1 != NULL);
630 jobject o2 = env_->NewWeakGlobalRef(s);
631 ASSERT_TRUE(o2 != NULL);
632
633 env_->DeleteWeakGlobalRef(o1);
634 env_->DeleteWeakGlobalRef(o2);
635}
636
Carl Shapiro9b9ba282011-08-14 15:30:39 -0700637bool EnsureInvokeStub(Method* method);
638
Carl Shapiro9b9ba282011-08-14 15:30:39 -0700639Method::InvokeStub* AllocateStub(Method* method,
640 byte* code,
641 size_t length) {
642 CHECK(method->GetInvokeStub() == NULL);
643 EnsureInvokeStub(method);
644 Method::InvokeStub* stub = method->GetInvokeStub();
645 CHECK(stub != NULL);
buzbeec143c552011-08-20 17:38:58 -0700646 method->SetCode(code, length, kThumb2);
Carl Shapiro9b9ba282011-08-14 15:30:39 -0700647 return stub;
648}
649
Carl Shapiro9b9ba282011-08-14 15:30:39 -0700650#if defined(__arm__)
651TEST_F(JniInternalTest, StaticMainMethod) {
Brian Carlstroma663ea52011-08-19 23:33:41 -0700652 scoped_ptr<DexFile> dex(OpenDexFileBase64(kMainDex, "kMainDex"));
Carl Shapiro9b9ba282011-08-14 15:30:39 -0700653
654 PathClassLoader* class_loader = AllocPathClassLoader(dex.get());
655 ASSERT_TRUE(class_loader != NULL);
656
657 Class* klass = class_linker_->FindClass("LMain;", class_loader);
658 ASSERT_TRUE(klass != NULL);
659
660 Method* method = klass->FindDirectMethod("main", "([Ljava/lang/String;)V");
661 ASSERT_TRUE(method != NULL);
662
663 byte main_LV_code[] = {
664 0x2d, 0xe9, 0x00, 0x40, 0x83, 0xb0, 0xcd, 0xf8, 0x00, 0x00,
665 0xcd, 0xf8, 0x14, 0x10, 0x03, 0xb0, 0xbd, 0xe8, 0x00, 0x80,
666 };
667
668 Method::InvokeStub* stub = AllocateStub(method,
669 main_LV_code,
670 sizeof(main_LV_code));
671
672 Object* arg = NULL;
673
674 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(&arg), NULL);
Carl Shapiro9b9ba282011-08-14 15:30:39 -0700675}
676
677TEST_F(JniInternalTest, StaticNopMethod) {
Brian Carlstroma663ea52011-08-19 23:33:41 -0700678 scoped_ptr<DexFile> dex(OpenDexFileBase64(kStaticLeafMethodsDex, "kStaticLeafMethodsDex"));
Carl Shapiro9b9ba282011-08-14 15:30:39 -0700679
680 PathClassLoader* class_loader = AllocPathClassLoader(dex.get());
681 ASSERT_TRUE(class_loader != NULL);
682
683 Class* klass = class_linker_->FindClass("LStaticLeafMethods;", class_loader);
684 ASSERT_TRUE(klass != NULL);
685
686 Method* method = klass->FindDirectMethod("nop", "()V");
687 ASSERT_TRUE(method != NULL);
688
689 byte nop_V_code[] = {
690 0x2d, 0xe9, 0x00, 0x40, 0x83, 0xb0, 0xcd, 0xf8,
691 0x00, 0x00, 0x03, 0xb0, 0xbd, 0xe8, 0x00, 0x80,
692 };
693
694 Method::InvokeStub* stub = AllocateStub(method,
695 nop_V_code,
696 sizeof(nop_V_code));
697 ASSERT_TRUE(stub);
698
699 (*stub)(method, NULL, NULL, NULL, NULL);
Carl Shapiro9b9ba282011-08-14 15:30:39 -0700700}
701
702TEST_F(JniInternalTest, StaticIdentityByteMethod) {
Brian Carlstroma663ea52011-08-19 23:33:41 -0700703 scoped_ptr<DexFile> dex(OpenDexFileBase64(kStaticLeafMethodsDex, "kStaticLeafMethodsDex"));
Carl Shapiro9b9ba282011-08-14 15:30:39 -0700704
705 PathClassLoader* class_loader = AllocPathClassLoader(dex.get());
706 ASSERT_TRUE(class_loader != NULL);
707
708 Class* klass = class_linker_->FindClass("LStaticLeafMethods;", class_loader);
709 ASSERT_TRUE(klass != NULL);
710
711 Method* method = klass->FindDirectMethod("identity", "(B)B");
712 ASSERT_TRUE(method != NULL);
713
714 byte identity_BB_code[] = {
715 0x2d, 0xe9, 0x00, 0x40, 0x83, 0xb0, 0xcd, 0xf8,
716 0x00, 0x00, 0xcd, 0xf8, 0x14, 0x10, 0x05, 0x98,
717 0x03, 0xb0, 0xbd, 0xe8, 0x00, 0x80, 0x00, 0x00,
718 };
719
720 Method::InvokeStub* stub = AllocateStub(method,
721 identity_BB_code,
722 sizeof(identity_BB_code));
723
724 int arg;
725 JValue result;
726
727 arg = 0;
728 result.b = -1;
729 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(&arg), &result);
730 EXPECT_EQ(0, result.b);
731
732 arg = -1;
733 result.b = 0;
734 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(&arg), &result);
735 EXPECT_EQ(-1, result.b);
736
737 arg = SCHAR_MAX;
738 result.b = 0;
739 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(&arg), &result);
740 EXPECT_EQ(SCHAR_MAX, result.b);
741
742 arg = SCHAR_MIN;
743 result.b = 0;
744 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(&arg), &result);
745 EXPECT_EQ(SCHAR_MIN, result.b);
Carl Shapiro9b9ba282011-08-14 15:30:39 -0700746}
747
748TEST_F(JniInternalTest, StaticIdentityIntMethod) {
Brian Carlstroma663ea52011-08-19 23:33:41 -0700749 scoped_ptr<DexFile> dex(OpenDexFileBase64(kStaticLeafMethodsDex, "kStaticLeafMethodsDex"));
Carl Shapiro9b9ba282011-08-14 15:30:39 -0700750
751 PathClassLoader* class_loader = AllocPathClassLoader(dex.get());
752 ASSERT_TRUE(class_loader != NULL);
753
754 Class* klass = class_linker_->FindClass("LStaticLeafMethods;", class_loader);
755 ASSERT_TRUE(klass != NULL);
756
757 Method* method = klass->FindDirectMethod("identity", "(I)I");
758 ASSERT_TRUE(method != NULL);
759
760 byte identity_II_code[] = {
761 0x2d, 0xe9, 0x00, 0x40, 0x83, 0xb0, 0xcd, 0xf8,
762 0x00, 0x00, 0xcd, 0xf8, 0x14, 0x10, 0x05, 0x98,
763 0x03, 0xb0, 0xbd, 0xe8, 0x00, 0x80, 0x00, 0x00,
764 };
765
766 Method::InvokeStub* stub = AllocateStub(method,
767 identity_II_code,
768 sizeof(identity_II_code));
769
770 int arg;
771 JValue result;
772
773 arg = 0;
774 result.i = -1;
775 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(&arg), &result);
776 EXPECT_EQ(0, result.i);
777
778 arg = -1;
779 result.i = 0;
780 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(&arg), &result);
781 EXPECT_EQ(-1, result.i);
782
783 arg = INT_MAX;
784 result.i = 0;
785 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(&arg), &result);
786 EXPECT_EQ(INT_MAX, result.i);
787
788 arg = INT_MIN;
789 result.i = 0;
790 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(&arg), &result);
791 EXPECT_EQ(INT_MIN, result.i);
Carl Shapiro9b9ba282011-08-14 15:30:39 -0700792}
793
794TEST_F(JniInternalTest, StaticIdentityDoubleMethod) {
Brian Carlstroma663ea52011-08-19 23:33:41 -0700795 scoped_ptr<DexFile> dex(OpenDexFileBase64(kStaticLeafMethodsDex, "kStaticLeafMethodsDex"));
Carl Shapiro9b9ba282011-08-14 15:30:39 -0700796
797 PathClassLoader* class_loader = AllocPathClassLoader(dex.get());
798 ASSERT_TRUE(class_loader != NULL);
799
800 Class* klass = class_linker_->FindClass("LStaticLeafMethods;", class_loader);
801 ASSERT_TRUE(klass != NULL);
802
803 Method* method = klass->FindDirectMethod("identity", "(D)D");
804 ASSERT_TRUE(method != NULL);
805
806 byte identity_DD_code[] = {
807 0x2d, 0xe9, 0x00, 0x40, 0x83, 0xb0, 0xcd, 0xf8,
808 0x00, 0x00, 0xcd, 0xf8, 0x14, 0x10, 0xcd, 0xf8,
809 0x18, 0x20, 0x05, 0x98, 0x06, 0x99, 0x03, 0xb0,
810 0xbd, 0xe8, 0x00, 0x80,
811 };
812
813 Method::InvokeStub* stub = AllocateStub(method,
814 identity_DD_code,
815 sizeof(identity_DD_code));
816
817 double arg;
818 JValue result;
819
820 arg = 0.0;
821 result.d = -1.0;
822 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(&arg), &result);
823 EXPECT_EQ(0.0, result.d);
824
825 arg = -1.0;
826 result.d = 0.0;
827 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(&arg), &result);
828 EXPECT_EQ(-1.0, result.d);
829
830 arg = DBL_MAX;
831 result.d = 0.0;
832 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(&arg), &result);
833 EXPECT_EQ(DBL_MAX, result.d);
834
835 arg = DBL_MIN;
836 result.d = 0.0;
837 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(&arg), &result);
838 EXPECT_EQ(DBL_MIN, result.d);
Carl Shapiro9b9ba282011-08-14 15:30:39 -0700839}
840
841TEST_F(JniInternalTest, StaticSumIntIntMethod) {
Brian Carlstroma663ea52011-08-19 23:33:41 -0700842 scoped_ptr<DexFile> dex(OpenDexFileBase64(kStaticLeafMethodsDex, "kStaticLeafMethodsDex"));
Carl Shapiro9b9ba282011-08-14 15:30:39 -0700843
844 PathClassLoader* class_loader = AllocPathClassLoader(dex.get());
845 ASSERT_TRUE(class_loader != NULL);
846
847 Class* klass = class_linker_->FindClass("LStaticLeafMethods;", class_loader);
848 ASSERT_TRUE(klass != NULL);
849
850 Method* method = klass->FindDirectMethod("sum", "(II)I");
851 ASSERT_TRUE(method != NULL);
852
853 byte sum_III_code[] = {
854 0x2d, 0xe9, 0x00, 0x40, 0x83, 0xb0, 0xcd, 0xf8,
855 0x00, 0x00, 0xcd, 0xf8, 0x14, 0x10, 0xcd, 0xf8,
856 0x18, 0x20, 0x05, 0x98, 0x06, 0x99, 0x42, 0x18,
857 0xcd, 0xf8, 0x04, 0x20, 0x01, 0x98, 0x03, 0xb0,
858 0xbd, 0xe8, 0x00, 0x80,
859 };
860
861 Method::InvokeStub* stub = AllocateStub(method,
862 sum_III_code,
863 sizeof(sum_III_code));
864
865 int args[2];
866 JValue result;
867
868 args[0] = 0;
869 args[1] = 0;
870 result.i = -1;
871 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
872 EXPECT_EQ(0, result.i);
873
874 args[0] = 1;
875 args[1] = 2;
876 result.i = 0;
877 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
878 EXPECT_EQ(3, result.i);
879
880 args[0] = -2;
881 args[1] = 5;
882 result.i = 0;
883 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
884 EXPECT_EQ(3, result.i);
885
886 args[0] = INT_MAX;
887 args[1] = INT_MIN;
888 result.i = 1234;
889 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
890 EXPECT_EQ(-1, result.i);
891
892 args[0] = INT_MAX;
893 args[1] = INT_MAX;
894 result.i = INT_MIN;
895 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
896 EXPECT_EQ(-2, result.i);
Carl Shapiro9b9ba282011-08-14 15:30:39 -0700897}
898
899TEST_F(JniInternalTest, StaticSumIntIntIntMethod) {
Brian Carlstroma663ea52011-08-19 23:33:41 -0700900 scoped_ptr<DexFile> dex(OpenDexFileBase64(kStaticLeafMethodsDex, "kStaticLeafMethodsDex"));
Carl Shapiro9b9ba282011-08-14 15:30:39 -0700901
902 PathClassLoader* class_loader = AllocPathClassLoader(dex.get());
903 ASSERT_TRUE(class_loader != NULL);
904
905 Class* klass = class_linker_->FindClass("LStaticLeafMethods;", class_loader);
906 ASSERT_TRUE(klass != NULL);
907
908 Method* method = klass->FindDirectMethod("sum", "(III)I");
909 ASSERT_TRUE(method != NULL);
910
911 byte sum_IIII_code[] = {
912 0x2d, 0xe9, 0x00, 0x40, 0x83, 0xb0, 0xcd, 0xf8,
913 0x00, 0x00, 0xcd, 0xf8, 0x14, 0x10, 0xcd, 0xf8,
914 0x18, 0x20, 0xcd, 0xf8, 0x1c, 0x30, 0x05, 0x98,
915 0x06, 0x99, 0x42, 0x18, 0xcd, 0xf8, 0x04, 0x20,
916 0x01, 0x9b, 0xdd, 0xf8, 0x1c, 0xc0, 0x13, 0xeb,
917 0x0c, 0x03, 0xcd, 0xf8, 0x04, 0x30, 0x01, 0x98,
918 0x03, 0xb0, 0xbd, 0xe8, 0x00, 0x80, 0x00, 0x00,
919 };
920
921 Method::InvokeStub* stub = AllocateStub(method,
922 sum_IIII_code,
923 sizeof(sum_IIII_code));
924
925 int args[3];
926 JValue result;
927
928 args[0] = 0;
929 args[1] = 0;
930 args[2] = 0;
931 result.i = -1;
932 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
933 EXPECT_EQ(0, result.i);
934
935 args[0] = 1;
936 args[1] = 2;
937 args[2] = 3;
938 result.i = 0;
939 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
940 EXPECT_EQ(6, result.i);
941
942 args[0] = -1;
943 args[1] = 2;
944 args[2] = -3;
945 result.i = 0;
946 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
947 EXPECT_EQ(-2, result.i);
948
949 args[0] = INT_MAX;
950 args[1] = INT_MIN;
951 args[2] = INT_MAX;
952 result.i = 1234;
953 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
954 EXPECT_EQ(2147483646, result.i);
955
956 args[0] = INT_MAX;
957 args[1] = INT_MAX;
958 args[2] = INT_MAX;
959 result.i = INT_MIN;
960 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
961 EXPECT_EQ(2147483645, result.i);
Carl Shapiro9b9ba282011-08-14 15:30:39 -0700962}
963
964TEST_F(JniInternalTest, StaticSumIntIntIntIntMethod) {
Brian Carlstroma663ea52011-08-19 23:33:41 -0700965 scoped_ptr<DexFile> dex(OpenDexFileBase64(kStaticLeafMethodsDex, "kStaticLeafMethodsDex"));
Carl Shapiro9b9ba282011-08-14 15:30:39 -0700966
967 PathClassLoader* class_loader = AllocPathClassLoader(dex.get());
968 ASSERT_TRUE(class_loader != NULL);
969
970 Class* klass = class_linker_->FindClass("LStaticLeafMethods;", class_loader);
971 ASSERT_TRUE(klass != NULL);
972
973 Method* method = klass->FindDirectMethod("sum", "(IIII)I");
974 ASSERT_TRUE(method != NULL);
975
976 byte sum_IIIII_code[] = {
977 0x2d, 0xe9, 0x00, 0x40, 0x83, 0xb0, 0xcd, 0xf8,
978 0x00, 0x00, 0xcd, 0xf8, 0x14, 0x10, 0xcd, 0xf8,
979 0x18, 0x20, 0xcd, 0xf8, 0x1c, 0x30, 0x05, 0x98,
980 0x06, 0x99, 0x42, 0x18, 0xcd, 0xf8, 0x04, 0x20,
981 0x01, 0x9b, 0xdd, 0xf8, 0x1c, 0xc0, 0x13, 0xeb,
982 0x0c, 0x03, 0xcd, 0xf8, 0x04, 0x30, 0x01, 0x98,
983 0x08, 0x99, 0x40, 0x18, 0xcd, 0xf8, 0x04, 0x00,
984 0x01, 0x98, 0x03, 0xb0, 0xbd, 0xe8, 0x00, 0x80,
985 };
986
987 Method::InvokeStub* stub = AllocateStub(method,
988 sum_IIIII_code,
989 sizeof(sum_IIIII_code));
990
991 int args[4];
992 JValue result;
993
994 args[0] = 0;
995 args[1] = 0;
996 args[2] = 0;
997 args[3] = 0;
998 result.i = -1;
999 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
1000 EXPECT_EQ(0, result.i);
1001
1002 args[0] = 1;
1003 args[1] = 2;
1004 args[2] = 3;
1005 args[3] = 4;
1006 result.i = 0;
1007 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
1008 EXPECT_EQ(10, result.i);
1009
1010 args[0] = -1;
1011 args[1] = 2;
1012 args[2] = -3;
1013 args[3] = 4;
1014 result.i = 0;
1015 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
1016 EXPECT_EQ(2, result.i);
1017
1018 args[0] = INT_MAX;
1019 args[1] = INT_MIN;
1020 args[2] = INT_MAX;
1021 args[3] = INT_MIN;
1022 result.i = 1234;
1023 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
1024 EXPECT_EQ(-2, result.i);
1025
1026 args[0] = INT_MAX;
1027 args[1] = INT_MAX;
1028 args[2] = INT_MAX;
1029 args[3] = INT_MAX;
1030 result.i = INT_MIN;
1031 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
1032 EXPECT_EQ(-4, result.i);
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001033}
1034
1035TEST_F(JniInternalTest, StaticSumIntIntIntIntIntMethod) {
Brian Carlstroma663ea52011-08-19 23:33:41 -07001036 scoped_ptr<DexFile> dex(OpenDexFileBase64(kStaticLeafMethodsDex, "kStaticLeafMethodsDex"));
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001037
1038 PathClassLoader* class_loader = AllocPathClassLoader(dex.get());
1039 ASSERT_TRUE(class_loader != NULL);
1040
1041 Class* klass = class_linker_->FindClass("LStaticLeafMethods;", class_loader);
1042 ASSERT_TRUE(klass != NULL);
1043
1044 Method* method = klass->FindDirectMethod("sum", "(IIIII)I");
1045 ASSERT_TRUE(method != NULL);
1046
1047 byte sum_IIIIII_code[] = {
1048 0x2d, 0xe9, 0x00, 0x40, 0x83, 0xb0, 0xcd, 0xf8,
1049 0x00, 0x00, 0xcd, 0xf8, 0x14, 0x10, 0xcd, 0xf8,
1050 0x18, 0x20, 0xcd, 0xf8, 0x1c, 0x30, 0x05, 0x98,
1051 0x06, 0x99, 0x42, 0x18, 0xcd, 0xf8, 0x04, 0x20,
1052 0x01, 0x9b, 0xdd, 0xf8, 0x1c, 0xc0, 0x13, 0xeb,
1053 0x0c, 0x03, 0xcd, 0xf8, 0x04, 0x30, 0x01, 0x98,
1054 0x08, 0x99, 0x40, 0x18, 0xcd, 0xf8, 0x04, 0x00,
1055 0x01, 0x9a, 0x09, 0x9b, 0xd2, 0x18, 0xcd, 0xf8,
1056 0x04, 0x20, 0x01, 0x98, 0x03, 0xb0, 0xbd, 0xe8,
1057 0x00, 0x80, 0x00, 0x00,
1058 };
1059
1060 Method::InvokeStub* stub = AllocateStub(method,
1061 sum_IIIIII_code,
1062 sizeof(sum_IIIIII_code));
1063
1064 int args[5];
1065 JValue result;
1066
1067 args[0] = 0;
1068 args[1] = 0;
1069 args[2] = 0;
1070 args[3] = 0;
1071 args[4] = 0;
1072 result.i = -1.0;
1073 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
1074 EXPECT_EQ(0, result.i);
1075
1076 args[0] = 1;
1077 args[1] = 2;
1078 args[2] = 3;
1079 args[3] = 4;
1080 args[4] = 5;
1081 result.i = 0;
1082 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
1083 EXPECT_EQ(15, result.i);
1084
1085 args[0] = -1;
1086 args[1] = 2;
1087 args[2] = -3;
1088 args[3] = 4;
1089 args[4] = -5;
1090 result.i = 0;
1091 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
1092 EXPECT_EQ(-3, result.i);
1093
1094 args[0] = INT_MAX;
1095 args[1] = INT_MIN;
1096 args[2] = INT_MAX;
1097 args[3] = INT_MIN;
1098 args[4] = INT_MAX;
1099 result.i = 1234;
1100 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
1101 EXPECT_EQ(2147483645, result.i);
1102
1103 args[0] = INT_MAX;
1104 args[1] = INT_MAX;
1105 args[2] = INT_MAX;
1106 args[3] = INT_MAX;
1107 args[4] = INT_MAX;
1108 result.i = INT_MIN;
1109 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
1110 EXPECT_EQ(2147483643, result.i);
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001111}
1112
1113TEST_F(JniInternalTest, StaticSumDoubleDoubleMethod) {
Brian Carlstroma663ea52011-08-19 23:33:41 -07001114 scoped_ptr<DexFile> dex(OpenDexFileBase64(kStaticLeafMethodsDex, "kStaticLeafMethodsDex"));
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001115
1116 PathClassLoader* class_loader = AllocPathClassLoader(dex.get());
1117 ASSERT_TRUE(class_loader != NULL);
1118
1119 Class* klass = class_linker_->FindClass("LStaticLeafMethods;", class_loader);
1120 ASSERT_TRUE(klass != NULL);
1121
1122 Method* method = klass->FindDirectMethod("sum", "(DD)D");
1123 ASSERT_TRUE(method != NULL);
1124
1125 byte sum_DDD_code[] = {
1126 0x2d, 0xe9, 0x00, 0x40, 0x87, 0xb0, 0xcd, 0xf8,
1127 0x00, 0x00, 0xcd, 0xf8, 0x24, 0x10, 0xcd, 0xf8,
1128 0x28, 0x20, 0xcd, 0xf8, 0x2c, 0x30, 0x9d, 0xed,
1129 0x09, 0x0b, 0x9d, 0xed, 0x0b, 0x1b, 0x30, 0xee,
1130 0x01, 0x2b, 0x8d, 0xed, 0x04, 0x2b, 0x04, 0x98,
1131 0x05, 0x99, 0x07, 0xb0, 0xbd, 0xe8, 0x00, 0x80,
1132 };
1133
1134 Method::InvokeStub* stub = AllocateStub(method,
1135 sum_DDD_code,
1136 sizeof(sum_DDD_code));
1137
1138 double args[2];
1139 JValue result;
1140
1141 args[0] = 0.0;
1142 args[1] = 0.0;
1143 result.d = -1.0;
1144 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
1145 EXPECT_EQ(0.0, result.d);
1146
1147 args[0] = 1.0;
1148 args[1] = 2.0;
1149 result.d = 0.0;
1150 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
1151 EXPECT_EQ(3.0, result.d);
1152
1153 args[0] = 1.0;
1154 args[1] = -2.0;
1155 result.d = 0.0;
1156 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
1157 EXPECT_EQ(-1.0, result.d);
1158
1159 args[0] = DBL_MAX;
1160 args[1] = DBL_MIN;
1161 result.d = 0.0;
1162 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
1163 EXPECT_EQ(1.7976931348623157e308, result.d);
1164
1165 args[0] = DBL_MAX;
1166 args[1] = DBL_MAX;
1167 result.d = 0.0;
1168 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
1169 EXPECT_EQ(INFINITY, result.d);
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001170}
1171
1172TEST_F(JniInternalTest, StaticSumDoubleDoubleDoubleMethod) {
Brian Carlstroma663ea52011-08-19 23:33:41 -07001173 scoped_ptr<DexFile> dex(OpenDexFileBase64(kStaticLeafMethodsDex, "kStaticLeafMethodsDex"));
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001174
1175 PathClassLoader* class_loader = AllocPathClassLoader(dex.get());
1176 ASSERT_TRUE(class_loader != NULL);
1177
1178 Class* klass = class_linker_->FindClass("LStaticLeafMethods;", class_loader);
1179 ASSERT_TRUE(klass != NULL);
1180
1181 Method* method = klass->FindDirectMethod("sum", "(DDD)D");
1182 ASSERT_TRUE(method != NULL);
1183
1184 byte sum_DDDD_code[] = {
1185 0x2d, 0xe9, 0x00, 0x40, 0x87, 0xb0, 0xcd, 0xf8,
1186 0x00, 0x00, 0xcd, 0xf8, 0x24, 0x10, 0xcd, 0xf8,
1187 0x28, 0x20, 0xcd, 0xf8, 0x2c, 0x30, 0x9d, 0xed,
1188 0x09, 0x0b, 0x9d, 0xed, 0x0b, 0x1b, 0x30, 0xee,
1189 0x01, 0x2b, 0x8d, 0xed, 0x04, 0x2b, 0x9d, 0xed,
1190 0x04, 0x3b, 0x9d, 0xed, 0x0d, 0x4b, 0x33, 0xee,
1191 0x04, 0x3b, 0x8d, 0xed, 0x04, 0x3b, 0x04, 0x98,
1192 0x05, 0x99, 0x07, 0xb0, 0xbd, 0xe8, 0x00, 0x80,
1193 };
1194
1195 Method::InvokeStub* stub = AllocateStub(method,
1196 sum_DDDD_code,
1197 sizeof(sum_DDDD_code));
1198
1199 double args[3];
1200 JValue result;
1201
1202 args[0] = 0.0;
1203 args[1] = 0.0;
1204 args[2] = 0.0;
1205 result.d = -1.0;
1206 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
1207 EXPECT_EQ(0.0, result.d);
1208
1209 args[0] = 1.0;
1210 args[1] = 2.0;
1211 args[2] = 3.0;
1212 result.d = 0.0;
1213 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
1214 EXPECT_EQ(6.0, result.d);
1215
1216 args[0] = 1.0;
1217 args[1] = -2.0;
1218 args[2] = 3.0;
1219 result.d = 0.0;
1220 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
1221 EXPECT_EQ(2.0, result.d);
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001222}
1223
1224TEST_F(JniInternalTest, StaticSumDoubleDoubleDoubleDoubleMethod) {
Brian Carlstroma663ea52011-08-19 23:33:41 -07001225 scoped_ptr<DexFile> dex(OpenDexFileBase64(kStaticLeafMethodsDex, "kStaticLeafMethodsDex"));
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001226
1227 PathClassLoader* class_loader = AllocPathClassLoader(dex.get());
1228 ASSERT_TRUE(class_loader != NULL);
1229
1230 Class* klass = class_linker_->FindClass("LStaticLeafMethods;", class_loader);
1231 ASSERT_TRUE(klass != NULL);
1232
1233 Method* method = klass->FindDirectMethod("sum", "(DDDD)D");
1234 ASSERT_TRUE(method != NULL);
1235
1236 byte sum_DDDDD_code[] = {
1237 0x2d, 0xe9, 0x00, 0x40, 0x87, 0xb0, 0xcd, 0xf8,
1238 0x00, 0x00, 0xcd, 0xf8, 0x24, 0x10, 0xcd, 0xf8,
1239 0x28, 0x20, 0xcd, 0xf8, 0x2c, 0x30, 0x9d, 0xed,
1240 0x09, 0x0b, 0x9d, 0xed, 0x0b, 0x1b, 0x30, 0xee,
1241 0x01, 0x2b, 0x8d, 0xed, 0x04, 0x2b, 0x9d, 0xed,
1242 0x04, 0x3b, 0x9d, 0xed, 0x0d, 0x4b, 0x33, 0xee,
1243 0x04, 0x3b, 0x8d, 0xed, 0x04, 0x3b, 0x9d, 0xed,
1244 0x04, 0x5b, 0x9d, 0xed, 0x0f, 0x6b, 0x35, 0xee,
1245 0x06, 0x5b, 0x8d, 0xed, 0x04, 0x5b, 0x04, 0x98,
1246 0x05, 0x99, 0x07, 0xb0, 0xbd, 0xe8, 0x00, 0x80,
1247 };
1248
1249 Method::InvokeStub* stub = AllocateStub(method,
1250 sum_DDDDD_code,
1251 sizeof(sum_DDDDD_code));
1252
1253 double args[4];
1254 JValue result;
1255
1256 args[0] = 0.0;
1257 args[1] = 0.0;
1258 args[2] = 0.0;
1259 args[3] = 0.0;
1260 result.d = -1.0;
1261 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
1262 EXPECT_EQ(0.0, result.d);
1263
1264 args[0] = 1.0;
1265 args[1] = 2.0;
1266 args[2] = 3.0;
1267 args[3] = 4.0;
1268 result.d = 0.0;
1269 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
1270 EXPECT_EQ(10.0, result.d);
1271
1272 args[0] = 1.0;
1273 args[1] = -2.0;
1274 args[2] = 3.0;
1275 args[3] = -4.0;
1276 result.d = 0.0;
1277 (*stub)(method, NULL, NULL, reinterpret_cast<byte*>(args), &result);
1278 EXPECT_EQ(-2.0, result.d);
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001279}
1280
1281TEST_F(JniInternalTest, StaticSumDoubleDoubleDoubleDoubleDoubleMethod) {
Brian Carlstroma663ea52011-08-19 23:33:41 -07001282 scoped_ptr<DexFile> dex(OpenDexFileBase64(kStaticLeafMethodsDex, "kStaticLeafMethodsDex"));
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001283
1284 PathClassLoader* class_loader = AllocPathClassLoader(dex.get());
1285 ASSERT_TRUE(class_loader != NULL);
1286
1287 Class* klass = class_linker_->FindClass("LStaticLeafMethods;", class_loader);
1288 ASSERT_TRUE(klass != NULL);
1289
1290 Method* method = klass->FindDirectMethod("sum", "(DDDDD)D");
1291 ASSERT_TRUE(method != NULL);
1292
1293 byte sum_DDDDDD_code[] = {
1294 0x2d, 0xe9, 0x00, 0x40, 0x87, 0xb0, 0xcd, 0xf8,
1295 0x00, 0x00, 0xcd, 0xf8, 0x24, 0x10, 0xcd, 0xf8,
1296 0x28, 0x20, 0xcd, 0xf8, 0x2c, 0x30, 0x9d, 0xed,
1297 0x09, 0x0b, 0x9d, 0xed, 0x0b, 0x1b, 0x30, 0xee,
1298 0x01, 0x2b, 0x8d, 0xed, 0x04, 0x2b, 0x9d, 0xed,
1299 0x04, 0x3b, 0x9d, 0xed, 0x0d, 0x4b, 0x33, 0xee,
1300 0x04, 0x3b, 0x8d, 0xed, 0x04, 0x3b, 0x9d, 0xed,
1301 0x04, 0x5b, 0x9d, 0xed, 0x0f, 0x6b, 0x35, 0xee,
1302 0x06, 0x5b, 0x8d, 0xed, 0x04, 0x5b, 0x9d, 0xed,
1303 0x04, 0x7b, 0x9d, 0xed, 0x11, 0x0b, 0x37, 0xee,
1304 0x00, 0x7b, 0x8d, 0xed, 0x04, 0x7b, 0x04, 0x98,
1305 0x05, 0x99, 0x07, 0xb0, 0xbd, 0xe8, 0x00, 0x80,
1306 };
1307
1308 Method::InvokeStub* stub = AllocateStub(method,
1309 sum_DDDDDD_code,
1310 sizeof(sum_DDDDDD_code));
1311
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());
1354 EXPECT_TRUE(env_->IsSameObject(exception, env_->ExceptionOccurred()));
1355 env_->ExceptionClear();
1356}
1357
1358TEST_F(JniInternalTest, ThrowNew) {
1359 EXPECT_EQ(JNI_ERR, env_->Throw(NULL));
1360
1361 jclass exception_class = env_->FindClass("java/lang/RuntimeException");
1362 ASSERT_TRUE(exception_class != NULL);
1363
1364 EXPECT_EQ(JNI_OK, env_->ThrowNew(exception_class, "hello world"));
1365 EXPECT_TRUE(env_->ExceptionCheck());
1366 EXPECT_TRUE(env_->IsInstanceOf(env_->ExceptionOccurred(), exception_class));
1367 env_->ExceptionClear();
1368}
1369
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001370}