OSDN Git Service

Revert "Prune uses library classes even without profile DO NOT MERGE"
[android-x86/art.git] / runtime / jni_internal_test.cc
1 /*
2  * Copyright (C) 2011 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 #include "jni_internal.h"
18
19 #include "art_method-inl.h"
20 #include "common_compiler_test.h"
21 #include "indirect_reference_table.h"
22 #include "java_vm_ext.h"
23 #include "jni_env_ext.h"
24 #include "mirror/string-inl.h"
25 #include "scoped_thread_state_change.h"
26 #include "ScopedLocalRef.h"
27
28 namespace art {
29
30 // TODO: Convert to CommonRuntimeTest. Currently MakeExecutable is used.
31 class JniInternalTest : public CommonCompilerTest {
32  protected:
33   virtual void SetUp() {
34     CommonCompilerTest::SetUp();
35
36     vm_ = Runtime::Current()->GetJavaVM();
37
38     // Turn on -verbose:jni for the JNI tests.
39     // gLogVerbosity.jni = true;
40
41     vm_->AttachCurrentThread(&env_, nullptr);
42
43     ScopedLocalRef<jclass> aioobe(env_,
44                                   env_->FindClass("java/lang/ArrayIndexOutOfBoundsException"));
45     CHECK(aioobe.get() != nullptr);
46     aioobe_ = reinterpret_cast<jclass>(env_->NewGlobalRef(aioobe.get()));
47
48     ScopedLocalRef<jclass> ase(env_, env_->FindClass("java/lang/ArrayStoreException"));
49     CHECK(ase.get() != nullptr);
50     ase_ = reinterpret_cast<jclass>(env_->NewGlobalRef(ase.get()));
51
52     ScopedLocalRef<jclass> sioobe(env_,
53                                   env_->FindClass("java/lang/StringIndexOutOfBoundsException"));
54     CHECK(sioobe.get() != nullptr);
55     sioobe_ = reinterpret_cast<jclass>(env_->NewGlobalRef(sioobe.get()));
56   }
57
58   void ExpectException(jclass exception_class) {
59     ScopedObjectAccess soa(env_);
60     EXPECT_TRUE(env_->ExceptionCheck())
61         << PrettyDescriptor(soa.Decode<mirror::Class*>(exception_class));
62     jthrowable exception = env_->ExceptionOccurred();
63     EXPECT_NE(nullptr, exception);
64     env_->ExceptionClear();
65     EXPECT_TRUE(env_->IsInstanceOf(exception, exception_class));
66   }
67
68   void CleanUpJniEnv() {
69     if (aioobe_ != nullptr) {
70       env_->DeleteGlobalRef(aioobe_);
71       aioobe_ = nullptr;
72     }
73     if (ase_ != nullptr) {
74       env_->DeleteGlobalRef(ase_);
75       ase_ = nullptr;
76     }
77     if (sioobe_ != nullptr) {
78       env_->DeleteGlobalRef(sioobe_);
79       sioobe_ = nullptr;
80     }
81   }
82
83   virtual void TearDown() OVERRIDE {
84     CleanUpJniEnv();
85     CommonCompilerTest::TearDown();
86   }
87
88   jclass GetPrimitiveClass(char descriptor) {
89     ScopedObjectAccess soa(env_);
90     mirror::Class* c = class_linker_->FindPrimitiveClass(descriptor);
91     CHECK(c != nullptr);
92     return soa.AddLocalReference<jclass>(c);
93   }
94
95   void ExpectClassFound(const char* name) {
96     EXPECT_NE(env_->FindClass(name), nullptr) << name;
97     EXPECT_FALSE(env_->ExceptionCheck()) << name;
98   }
99
100   void ExpectClassNotFound(const char* name, bool check_jni, const char* check_jni_msg,
101                            CheckJniAbortCatcher* abort_catcher) {
102     EXPECT_EQ(env_->FindClass(name), nullptr) << name;
103     if (!check_jni || check_jni_msg == nullptr) {
104       EXPECT_TRUE(env_->ExceptionCheck()) << name;
105       env_->ExceptionClear();
106     } else {
107       abort_catcher->Check(check_jni_msg);
108     }
109   }
110
111   void FindClassTest(bool check_jni) {
112     bool old_check_jni = vm_->SetCheckJniEnabled(check_jni);
113     CheckJniAbortCatcher check_jni_abort_catcher;
114
115     // Null argument is always an abort.
116     env_->FindClass(nullptr);
117     check_jni_abort_catcher.Check(check_jni ? "non-nullable const char* was NULL"
118                                             : "name == null");
119
120     // Reference types...
121     ExpectClassFound("java/lang/String");
122     // ...for arrays too, where you must include "L;".
123     ExpectClassFound("[Ljava/lang/String;");
124     // Primitive arrays are okay too, if the primitive type is valid.
125     ExpectClassFound("[C");
126
127     // But primitive types aren't allowed...
128     ExpectClassNotFound("C", check_jni, nullptr, &check_jni_abort_catcher);
129     ExpectClassNotFound("V", check_jni, nullptr, &check_jni_abort_catcher);
130     ExpectClassNotFound("K", check_jni, nullptr, &check_jni_abort_catcher);
131
132     if (check_jni) {
133       // Check JNI will reject invalid class names as aborts but without pending exceptions.
134       EXPECT_EQ(env_->FindClass("java.lang.String"), nullptr);
135       EXPECT_FALSE(env_->ExceptionCheck());
136       check_jni_abort_catcher.Check("illegal class name 'java.lang.String'");
137
138       EXPECT_EQ(env_->FindClass("[Ljava.lang.String;"), nullptr);
139       EXPECT_FALSE(env_->ExceptionCheck());
140       check_jni_abort_catcher.Check("illegal class name '[Ljava.lang.String;'");
141     } else {
142       // Without check JNI we're tolerant and replace '.' with '/'.
143       ExpectClassFound("java.lang.String");
144       ExpectClassFound("[Ljava.lang.String;");
145     }
146
147     ExpectClassNotFound("Ljava.lang.String;", check_jni, "illegal class name 'Ljava.lang.String;'",
148                         &check_jni_abort_catcher);
149     ExpectClassNotFound("[java.lang.String", check_jni, "illegal class name '[java.lang.String'",
150                         &check_jni_abort_catcher);
151
152     // You can't include the "L;" in a JNI class descriptor.
153     ExpectClassNotFound("Ljava/lang/String;", check_jni, "illegal class name 'Ljava/lang/String;'",
154                         &check_jni_abort_catcher);
155
156     // But you must include it for an array of any reference type.
157     ExpectClassNotFound("[java/lang/String", check_jni, "illegal class name '[java/lang/String'",
158                         &check_jni_abort_catcher);
159
160     ExpectClassNotFound("[K", check_jni, "illegal class name '[K'", &check_jni_abort_catcher);
161
162     // Void arrays aren't allowed.
163     ExpectClassNotFound("[V", check_jni, "illegal class name '[V'", &check_jni_abort_catcher);
164
165     EXPECT_EQ(check_jni, vm_->SetCheckJniEnabled(old_check_jni));
166   }
167
168   void GetFieldIdBadArgumentTest(bool check_jni) {
169     bool old_check_jni = vm_->SetCheckJniEnabled(check_jni);
170     CheckJniAbortCatcher check_jni_abort_catcher;
171
172     jclass c = env_->FindClass("java/lang/String");
173     ASSERT_NE(c, nullptr);
174
175     jfieldID fid = env_->GetFieldID(nullptr, "count", "I");
176     EXPECT_EQ(nullptr, fid);
177     check_jni_abort_catcher.Check(check_jni ? "GetFieldID received NULL jclass"
178                                             : "java_class == null");
179     fid = env_->GetFieldID(c, nullptr, "I");
180     EXPECT_EQ(nullptr, fid);
181     check_jni_abort_catcher.Check(check_jni ? "non-nullable const char* was NULL"
182                                             : "name == null");
183     fid = env_->GetFieldID(c, "count", nullptr);
184     EXPECT_EQ(nullptr, fid);
185     check_jni_abort_catcher.Check(check_jni ? "non-nullable const char* was NULL"
186                                             : "sig == null");
187
188     EXPECT_EQ(check_jni, vm_->SetCheckJniEnabled(old_check_jni));
189   }
190
191   void GetStaticFieldIdBadArgumentTest(bool check_jni) {
192     bool old_check_jni = vm_->SetCheckJniEnabled(check_jni);
193     CheckJniAbortCatcher check_jni_abort_catcher;
194
195     jclass c = env_->FindClass("java/lang/String");
196     ASSERT_NE(c, nullptr);
197
198     jfieldID fid = env_->GetStaticFieldID(nullptr, "CASE_INSENSITIVE_ORDER", "Ljava/util/Comparator;");
199     EXPECT_EQ(nullptr, fid);
200     check_jni_abort_catcher.Check(check_jni ? "GetStaticFieldID received NULL jclass"
201                                             : "java_class == null");
202     fid = env_->GetStaticFieldID(c, nullptr, "Ljava/util/Comparator;");
203     EXPECT_EQ(nullptr, fid);
204     check_jni_abort_catcher.Check(check_jni ? "non-nullable const char* was NULL"
205                                             : "name == null");
206     fid = env_->GetStaticFieldID(c, "CASE_INSENSITIVE_ORDER", nullptr);
207     EXPECT_EQ(nullptr, fid);
208     check_jni_abort_catcher.Check(check_jni ? "non-nullable const char* was NULL"
209                                             : "sig == null");
210
211     EXPECT_EQ(check_jni, vm_->SetCheckJniEnabled(old_check_jni));
212   }
213
214   void GetMethodIdBadArgumentTest(bool check_jni) {
215     bool old_check_jni = vm_->SetCheckJniEnabled(check_jni);
216     CheckJniAbortCatcher check_jni_abort_catcher;
217
218     jmethodID method = env_->GetMethodID(nullptr, "<init>", "(Ljava/lang/String;)V");
219     EXPECT_EQ(nullptr, method);
220     check_jni_abort_catcher.Check(check_jni ? "GetMethodID received NULL jclass"
221                                             : "java_class == null");
222     jclass jlnsme = env_->FindClass("java/lang/NoSuchMethodError");
223     ASSERT_TRUE(jlnsme != nullptr);
224     method = env_->GetMethodID(jlnsme, nullptr, "(Ljava/lang/String;)V");
225     EXPECT_EQ(nullptr, method);
226     check_jni_abort_catcher.Check(check_jni ? "non-nullable const char* was NULL"
227                                             : "name == null");
228     method = env_->GetMethodID(jlnsme, "<init>", nullptr);
229     EXPECT_EQ(nullptr, method);
230     check_jni_abort_catcher.Check(check_jni ? "non-nullable const char* was NULL"
231                                             : "sig == null");
232
233     EXPECT_EQ(check_jni, vm_->SetCheckJniEnabled(old_check_jni));
234   }
235
236   void GetStaticMethodIdBadArgumentTest(bool check_jni) {
237     bool old_check_jni = vm_->SetCheckJniEnabled(check_jni);
238     CheckJniAbortCatcher check_jni_abort_catcher;
239
240     jmethodID method = env_->GetStaticMethodID(nullptr, "valueOf", "(I)Ljava/lang/String;");
241     EXPECT_EQ(nullptr, method);
242     check_jni_abort_catcher.Check(check_jni ? "GetStaticMethodID received NULL jclass"
243                                             : "java_class == null");
244     jclass jlstring = env_->FindClass("java/lang/String");
245     method = env_->GetStaticMethodID(jlstring, nullptr, "(I)Ljava/lang/String;");
246     EXPECT_EQ(nullptr, method);
247     check_jni_abort_catcher.Check(check_jni ? "non-nullable const char* was NULL"
248                                             : "name == null");
249     method = env_->GetStaticMethodID(jlstring, "valueOf", nullptr);
250     EXPECT_EQ(nullptr, method);
251     check_jni_abort_catcher.Check(check_jni ? "non-nullable const char* was NULL"
252                                             : "sig == null");
253
254     EXPECT_EQ(check_jni, vm_->SetCheckJniEnabled(old_check_jni));
255   }
256
257   void GetFromReflectedField_ToReflectedFieldBadArgumentTest(bool check_jni) {
258     bool old_check_jni = vm_->SetCheckJniEnabled(check_jni);
259     CheckJniAbortCatcher check_jni_abort_catcher;
260
261     jclass c = env_->FindClass("java/lang/String");
262     ASSERT_NE(c, nullptr);
263     jfieldID fid = env_->GetFieldID(c, "count", "I");
264     ASSERT_NE(fid, nullptr);
265
266     // Check class argument for null argument, not checked in non-check JNI.
267     jobject field = env_->ToReflectedField(nullptr, fid, JNI_FALSE);
268     if (check_jni) {
269       EXPECT_EQ(field, nullptr);
270       check_jni_abort_catcher.Check("ToReflectedField received NULL jclass");
271     } else {
272       EXPECT_NE(field, nullptr);
273     }
274
275     field = env_->ToReflectedField(c, nullptr, JNI_FALSE);
276     EXPECT_EQ(field, nullptr);
277     check_jni_abort_catcher.Check(check_jni ? "jfieldID was NULL"
278                                             : "fid == null");
279
280     fid = env_->FromReflectedField(nullptr);
281     ASSERT_EQ(fid, nullptr);
282     check_jni_abort_catcher.Check(check_jni ? "expected non-null java.lang.reflect.Field"
283                                             : "jlr_field == null");
284
285     EXPECT_EQ(check_jni, vm_->SetCheckJniEnabled(old_check_jni));
286   }
287
288   void GetFromReflectedMethod_ToReflectedMethodBadArgumentTest(bool check_jni) {
289     bool old_check_jni = vm_->SetCheckJniEnabled(check_jni);
290     CheckJniAbortCatcher check_jni_abort_catcher;
291
292     jclass c = env_->FindClass("java/lang/String");
293     ASSERT_NE(c, nullptr);
294     jmethodID mid = env_->GetMethodID(c, "<init>", "()V");
295     ASSERT_NE(mid, nullptr);
296
297     // Check class argument for null argument, not checked in non-check JNI.
298     jobject method = env_->ToReflectedMethod(nullptr, mid, JNI_FALSE);
299     if (check_jni) {
300       EXPECT_EQ(method, nullptr);
301       check_jni_abort_catcher.Check("ToReflectedMethod received NULL jclass");
302     } else {
303       EXPECT_NE(method, nullptr);
304     }
305
306     method = env_->ToReflectedMethod(c, nullptr, JNI_FALSE);
307     EXPECT_EQ(method, nullptr);
308     check_jni_abort_catcher.Check(check_jni ? "jmethodID was NULL"
309                                             : "mid == null");
310     mid = env_->FromReflectedMethod(method);
311     ASSERT_EQ(mid, nullptr);
312     check_jni_abort_catcher.Check(check_jni ? "expected non-null method" : "jlr_method == null");
313
314     EXPECT_EQ(check_jni, vm_->SetCheckJniEnabled(old_check_jni));
315   }
316
317   void RegisterAndUnregisterNativesBadArguments(bool check_jni,
318                                                 CheckJniAbortCatcher* check_jni_abort_catcher) {
319     bool old_check_jni = vm_->SetCheckJniEnabled(check_jni);
320     // Passing a class of null is a failure.
321     {
322       JNINativeMethod methods[] = { };
323       EXPECT_EQ(env_->RegisterNatives(nullptr, methods, 0), JNI_ERR);
324       check_jni_abort_catcher->Check(check_jni ? "RegisterNatives received NULL jclass"
325                                                : "java_class == null");
326     }
327
328     // Passing methods as null is a failure.
329     jclass jlobject = env_->FindClass("java/lang/Object");
330     EXPECT_EQ(env_->RegisterNatives(jlobject, nullptr, 1), JNI_ERR);
331     check_jni_abort_catcher->Check("methods == null");
332
333     // Unregisters null is a failure.
334     EXPECT_EQ(env_->UnregisterNatives(nullptr), JNI_ERR);
335     check_jni_abort_catcher->Check(check_jni ? "UnregisterNatives received NULL jclass"
336                                              : "java_class == null");
337
338     EXPECT_EQ(check_jni, vm_->SetCheckJniEnabled(old_check_jni));
339   }
340
341
342   void GetPrimitiveArrayElementsOfWrongType(bool check_jni) {
343     bool old_check_jni = vm_->SetCheckJniEnabled(check_jni);
344     CheckJniAbortCatcher jni_abort_catcher;
345
346     jbooleanArray array = env_->NewBooleanArray(10);
347     jboolean is_copy;
348     EXPECT_EQ(env_->GetByteArrayElements(reinterpret_cast<jbyteArray>(array), &is_copy), nullptr);
349     jni_abort_catcher.Check(
350         check_jni ? "incompatible array type boolean[] expected byte[]"
351             : "attempt to get byte primitive array elements with an object of type boolean[]");
352     EXPECT_EQ(env_->GetShortArrayElements(reinterpret_cast<jshortArray>(array), &is_copy), nullptr);
353     jni_abort_catcher.Check(
354         check_jni ? "incompatible array type boolean[] expected short[]"
355             : "attempt to get short primitive array elements with an object of type boolean[]");
356     EXPECT_EQ(env_->GetCharArrayElements(reinterpret_cast<jcharArray>(array), &is_copy), nullptr);
357     jni_abort_catcher.Check(
358         check_jni ? "incompatible array type boolean[] expected char[]"
359             : "attempt to get char primitive array elements with an object of type boolean[]");
360     EXPECT_EQ(env_->GetIntArrayElements(reinterpret_cast<jintArray>(array), &is_copy), nullptr);
361     jni_abort_catcher.Check(
362         check_jni ? "incompatible array type boolean[] expected int[]"
363             : "attempt to get int primitive array elements with an object of type boolean[]");
364     EXPECT_EQ(env_->GetLongArrayElements(reinterpret_cast<jlongArray>(array), &is_copy), nullptr);
365     jni_abort_catcher.Check(
366         check_jni ? "incompatible array type boolean[] expected long[]"
367             : "attempt to get long primitive array elements with an object of type boolean[]");
368     EXPECT_EQ(env_->GetFloatArrayElements(reinterpret_cast<jfloatArray>(array), &is_copy), nullptr);
369     jni_abort_catcher.Check(
370         check_jni ? "incompatible array type boolean[] expected float[]"
371             : "attempt to get float primitive array elements with an object of type boolean[]");
372     EXPECT_EQ(env_->GetDoubleArrayElements(reinterpret_cast<jdoubleArray>(array), &is_copy), nullptr);
373     jni_abort_catcher.Check(
374         check_jni ? "incompatible array type boolean[] expected double[]"
375             : "attempt to get double primitive array elements with an object of type boolean[]");
376     jbyteArray array2 = env_->NewByteArray(10);
377     EXPECT_EQ(env_->GetBooleanArrayElements(reinterpret_cast<jbooleanArray>(array2), &is_copy),
378               nullptr);
379     jni_abort_catcher.Check(
380         check_jni ? "incompatible array type byte[] expected boolean[]"
381             : "attempt to get boolean primitive array elements with an object of type byte[]");
382     jobject object = env_->NewStringUTF("Test String");
383     EXPECT_EQ(env_->GetBooleanArrayElements(reinterpret_cast<jbooleanArray>(object), &is_copy),
384               nullptr);
385     jni_abort_catcher.Check(
386         check_jni ? "jarray argument has non-array type: java.lang.String"
387         : "attempt to get boolean primitive array elements with an object of type java.lang.String");
388
389     EXPECT_EQ(check_jni, vm_->SetCheckJniEnabled(old_check_jni));
390   }
391
392   void ReleasePrimitiveArrayElementsOfWrongType(bool check_jni) {
393     bool old_check_jni = vm_->SetCheckJniEnabled(check_jni);
394     CheckJniAbortCatcher jni_abort_catcher;
395     {
396       jbooleanArray array = env_->NewBooleanArray(10);
397       ASSERT_TRUE(array != nullptr);
398       jboolean is_copy;
399       jboolean* elements = env_->GetBooleanArrayElements(array, &is_copy);
400       ASSERT_TRUE(elements != nullptr);
401       env_->ReleaseByteArrayElements(reinterpret_cast<jbyteArray>(array),
402                                      reinterpret_cast<jbyte*>(elements), 0);
403       jni_abort_catcher.Check(
404           check_jni ? "incompatible array type boolean[] expected byte[]"
405               : "attempt to release byte primitive array elements with an object of type boolean[]");
406       env_->ReleaseShortArrayElements(reinterpret_cast<jshortArray>(array),
407                                       reinterpret_cast<jshort*>(elements), 0);
408       jni_abort_catcher.Check(
409           check_jni ? "incompatible array type boolean[] expected short[]"
410               : "attempt to release short primitive array elements with an object of type boolean[]");
411       env_->ReleaseCharArrayElements(reinterpret_cast<jcharArray>(array),
412                                      reinterpret_cast<jchar*>(elements), 0);
413       jni_abort_catcher.Check(
414           check_jni ? "incompatible array type boolean[] expected char[]"
415               : "attempt to release char primitive array elements with an object of type boolean[]");
416       env_->ReleaseIntArrayElements(reinterpret_cast<jintArray>(array),
417                                     reinterpret_cast<jint*>(elements), 0);
418       jni_abort_catcher.Check(
419           check_jni ? "incompatible array type boolean[] expected int[]"
420               : "attempt to release int primitive array elements with an object of type boolean[]");
421       env_->ReleaseLongArrayElements(reinterpret_cast<jlongArray>(array),
422                                      reinterpret_cast<jlong*>(elements), 0);
423       jni_abort_catcher.Check(
424           check_jni ? "incompatible array type boolean[] expected long[]"
425               : "attempt to release long primitive array elements with an object of type boolean[]");
426       env_->ReleaseFloatArrayElements(reinterpret_cast<jfloatArray>(array),
427                                       reinterpret_cast<jfloat*>(elements), 0);
428       jni_abort_catcher.Check(
429           check_jni ? "incompatible array type boolean[] expected float[]"
430               : "attempt to release float primitive array elements with an object of type boolean[]");
431       env_->ReleaseDoubleArrayElements(reinterpret_cast<jdoubleArray>(array),
432                                        reinterpret_cast<jdouble*>(elements), 0);
433       jni_abort_catcher.Check(
434           check_jni ? "incompatible array type boolean[] expected double[]"
435               : "attempt to release double primitive array elements with an object of type boolean[]");
436
437       // Don't leak the elements array.
438       env_->ReleaseBooleanArrayElements(array, elements, 0);
439     }
440     {
441       jbyteArray array = env_->NewByteArray(10);
442       jboolean is_copy;
443       jbyte* elements = env_->GetByteArrayElements(array, &is_copy);
444
445       env_->ReleaseBooleanArrayElements(reinterpret_cast<jbooleanArray>(array),
446                                         reinterpret_cast<jboolean*>(elements), 0);
447       jni_abort_catcher.Check(
448           check_jni ? "incompatible array type byte[] expected boolean[]"
449               : "attempt to release boolean primitive array elements with an object of type byte[]");
450       jobject object = env_->NewStringUTF("Test String");
451       env_->ReleaseBooleanArrayElements(reinterpret_cast<jbooleanArray>(object),
452                                         reinterpret_cast<jboolean*>(elements), 0);
453       jni_abort_catcher.Check(
454           check_jni ? "jarray argument has non-array type: java.lang.String"
455               : "attempt to release boolean primitive array elements with an object of type "
456               "java.lang.String");
457
458       // Don't leak the elements array.
459       env_->ReleaseByteArrayElements(array, elements, 0);
460     }
461     EXPECT_EQ(check_jni, vm_->SetCheckJniEnabled(old_check_jni));
462   }
463
464   void GetReleasePrimitiveArrayCriticalOfWrongType(bool check_jni) {
465     bool old_check_jni = vm_->SetCheckJniEnabled(check_jni);
466     CheckJniAbortCatcher jni_abort_catcher;
467
468     jobject object = env_->NewStringUTF("Test String");
469     jboolean is_copy;
470     void* elements = env_->GetPrimitiveArrayCritical(reinterpret_cast<jarray>(object), &is_copy);
471     jni_abort_catcher.Check(check_jni ? "jarray argument has non-array type: java.lang.String"
472         : "expected primitive array, given java.lang.String");
473     env_->ReleasePrimitiveArrayCritical(reinterpret_cast<jarray>(object), elements, 0);
474     jni_abort_catcher.Check(check_jni ? "jarray argument has non-array type: java.lang.String"
475         : "expected primitive array, given java.lang.String");
476
477     EXPECT_EQ(check_jni, vm_->SetCheckJniEnabled(old_check_jni));
478   }
479
480   void GetPrimitiveArrayRegionElementsOfWrongType(bool check_jni) {
481     bool old_check_jni = vm_->SetCheckJniEnabled(check_jni);
482     CheckJniAbortCatcher jni_abort_catcher;
483     constexpr size_t kLength = 10;
484     jbooleanArray array = env_->NewBooleanArray(kLength);
485     ASSERT_TRUE(array != nullptr);
486     jboolean elements[kLength];
487     env_->GetByteArrayRegion(reinterpret_cast<jbyteArray>(array), 0, kLength,
488                              reinterpret_cast<jbyte*>(elements));
489     jni_abort_catcher.Check(
490         check_jni ? "incompatible array type boolean[] expected byte[]"
491             : "attempt to get region of byte primitive array elements with an object of type boolean[]");
492     env_->GetShortArrayRegion(reinterpret_cast<jshortArray>(array), 0, kLength,
493                               reinterpret_cast<jshort*>(elements));
494     jni_abort_catcher.Check(
495         check_jni ? "incompatible array type boolean[] expected short[]"
496             : "attempt to get region of short primitive array elements with an object of type boolean[]");
497     env_->GetCharArrayRegion(reinterpret_cast<jcharArray>(array), 0, kLength,
498                              reinterpret_cast<jchar*>(elements));
499     jni_abort_catcher.Check(
500         check_jni ? "incompatible array type boolean[] expected char[]"
501             : "attempt to get region of char primitive array elements with an object of type boolean[]");
502     env_->GetIntArrayRegion(reinterpret_cast<jintArray>(array), 0, kLength,
503                             reinterpret_cast<jint*>(elements));
504     jni_abort_catcher.Check(
505         check_jni ? "incompatible array type boolean[] expected int[]"
506             : "attempt to get region of int primitive array elements with an object of type boolean[]");
507     env_->GetLongArrayRegion(reinterpret_cast<jlongArray>(array), 0, kLength,
508                              reinterpret_cast<jlong*>(elements));
509     jni_abort_catcher.Check(
510         check_jni ? "incompatible array type boolean[] expected long[]"
511             : "attempt to get region of long primitive array elements with an object of type boolean[]");
512     env_->GetFloatArrayRegion(reinterpret_cast<jfloatArray>(array), 0, kLength,
513                               reinterpret_cast<jfloat*>(elements));
514     jni_abort_catcher.Check(
515         check_jni ? "incompatible array type boolean[] expected float[]"
516             : "attempt to get region of float primitive array elements with an object of type boolean[]");
517     env_->GetDoubleArrayRegion(reinterpret_cast<jdoubleArray>(array), 0, kLength,
518                                reinterpret_cast<jdouble*>(elements));
519     jni_abort_catcher.Check(
520         check_jni ? "incompatible array type boolean[] expected double[]"
521             : "attempt to get region of double primitive array elements with an object of type boolean[]");
522     jbyteArray array2 = env_->NewByteArray(10);
523     env_->GetBooleanArrayRegion(reinterpret_cast<jbooleanArray>(array2), 0, kLength,
524                                 reinterpret_cast<jboolean*>(elements));
525     jni_abort_catcher.Check(
526         check_jni ? "incompatible array type byte[] expected boolean[]"
527             : "attempt to get region of boolean primitive array elements with an object of type byte[]");
528     jobject object = env_->NewStringUTF("Test String");
529     env_->GetBooleanArrayRegion(reinterpret_cast<jbooleanArray>(object), 0, kLength,
530                                 reinterpret_cast<jboolean*>(elements));
531     jni_abort_catcher.Check(check_jni ? "jarray argument has non-array type: java.lang.String"
532         : "attempt to get region of boolean primitive array elements with an object of type "
533           "java.lang.String");
534
535     EXPECT_EQ(check_jni, vm_->SetCheckJniEnabled(old_check_jni));
536   }
537
538   void SetPrimitiveArrayRegionElementsOfWrongType(bool check_jni) {
539     bool old_check_jni = vm_->SetCheckJniEnabled(check_jni);
540     CheckJniAbortCatcher jni_abort_catcher;
541     constexpr size_t kLength = 10;
542     jbooleanArray array = env_->NewBooleanArray(kLength);
543     ASSERT_TRUE(array != nullptr);
544     jboolean elements[kLength];
545     env_->SetByteArrayRegion(reinterpret_cast<jbyteArray>(array), 0, kLength,
546                              reinterpret_cast<jbyte*>(elements));
547     jni_abort_catcher.Check(
548         check_jni ? "incompatible array type boolean[] expected byte[]"
549             : "attempt to set region of byte primitive array elements with an object of type boolean[]");
550     env_->SetShortArrayRegion(reinterpret_cast<jshortArray>(array), 0, kLength,
551                               reinterpret_cast<jshort*>(elements));
552     jni_abort_catcher.Check(
553         check_jni ? "incompatible array type boolean[] expected short[]"
554             : "attempt to set region of short primitive array elements with an object of type boolean[]");
555     env_->SetCharArrayRegion(reinterpret_cast<jcharArray>(array), 0, kLength,
556                              reinterpret_cast<jchar*>(elements));
557     jni_abort_catcher.Check(
558         check_jni ? "incompatible array type boolean[] expected char[]"
559             : "attempt to set region of char primitive array elements with an object of type boolean[]");
560     env_->SetIntArrayRegion(reinterpret_cast<jintArray>(array), 0, kLength,
561                             reinterpret_cast<jint*>(elements));
562     jni_abort_catcher.Check(
563         check_jni ? "incompatible array type boolean[] expected int[]"
564             : "attempt to set region of int primitive array elements with an object of type boolean[]");
565     env_->SetLongArrayRegion(reinterpret_cast<jlongArray>(array), 0, kLength,
566                              reinterpret_cast<jlong*>(elements));
567     jni_abort_catcher.Check(
568         check_jni ? "incompatible array type boolean[] expected long[]"
569             : "attempt to set region of long primitive array elements with an object of type boolean[]");
570     env_->SetFloatArrayRegion(reinterpret_cast<jfloatArray>(array), 0, kLength,
571                               reinterpret_cast<jfloat*>(elements));
572     jni_abort_catcher.Check(
573         check_jni ? "incompatible array type boolean[] expected float[]"
574             : "attempt to set region of float primitive array elements with an object of type boolean[]");
575     env_->SetDoubleArrayRegion(reinterpret_cast<jdoubleArray>(array), 0, kLength,
576                                reinterpret_cast<jdouble*>(elements));
577     jni_abort_catcher.Check(
578         check_jni ? "incompatible array type boolean[] expected double[]"
579             : "attempt to set region of double primitive array elements with an object of type boolean[]");
580     jbyteArray array2 = env_->NewByteArray(10);
581     env_->SetBooleanArrayRegion(reinterpret_cast<jbooleanArray>(array2), 0, kLength,
582                                 reinterpret_cast<jboolean*>(elements));
583     jni_abort_catcher.Check(
584         check_jni ? "incompatible array type byte[] expected boolean[]"
585             : "attempt to set region of boolean primitive array elements with an object of type byte[]");
586     jobject object = env_->NewStringUTF("Test String");
587     env_->SetBooleanArrayRegion(reinterpret_cast<jbooleanArray>(object), 0, kLength,
588                                 reinterpret_cast<jboolean*>(elements));
589     jni_abort_catcher.Check(check_jni ? "jarray argument has non-array type: java.lang.String"
590         : "attempt to set region of boolean primitive array elements with an object of type "
591           "java.lang.String");
592     EXPECT_EQ(check_jni, vm_->SetCheckJniEnabled(old_check_jni));
593   }
594
595   void NewObjectArrayBadArguments(bool check_jni) {
596     bool old_check_jni = vm_->SetCheckJniEnabled(check_jni);
597     CheckJniAbortCatcher jni_abort_catcher;
598
599     jclass element_class = env_->FindClass("java/lang/String");
600     ASSERT_NE(element_class, nullptr);
601
602     env_->NewObjectArray(-1, element_class, nullptr);
603     jni_abort_catcher.Check(check_jni ? "negative jsize: -1" : "negative array length: -1");
604
605     env_->NewObjectArray(std::numeric_limits<jint>::min(), element_class, nullptr);
606     jni_abort_catcher.Check(check_jni ? "negative jsize: -2147483648"
607         : "negative array length: -2147483648");
608
609     EXPECT_EQ(check_jni, vm_->SetCheckJniEnabled(old_check_jni));
610   }
611
612   void SetUpForTest(bool direct, const char* method_name, const char* method_sig,
613                     void* native_fnptr) {
614     // Initialize class loader and set generic JNI entrypoint.
615     // Note: this code is adapted from the jni_compiler_test, and taken with minimal modifications.
616     if (!runtime_->IsStarted()) {
617       {
618         ScopedObjectAccess soa(Thread::Current());
619         class_loader_ = LoadDex("MyClassNatives");
620         StackHandleScope<1> hs(soa.Self());
621         Handle<mirror::ClassLoader> loader(
622             hs.NewHandle(soa.Decode<mirror::ClassLoader*>(class_loader_)));
623         mirror::Class* c = class_linker_->FindClass(soa.Self(), "LMyClassNatives;", loader);
624         const auto pointer_size = class_linker_->GetImagePointerSize();
625         ArtMethod* method = direct ? c->FindDirectMethod(method_name, method_sig, pointer_size) :
626             c->FindVirtualMethod(method_name, method_sig, pointer_size);
627         ASSERT_TRUE(method != nullptr) << method_name << " " << method_sig;
628         method->SetEntryPointFromQuickCompiledCode(class_linker_->GetRuntimeQuickGenericJniStub());
629       }
630       // Start runtime.
631       Thread::Current()->TransitionFromSuspendedToRunnable();
632       bool started = runtime_->Start();
633       CHECK(started);
634     }
635     // JNI operations after runtime start.
636     env_ = Thread::Current()->GetJniEnv();
637     jklass_ = env_->FindClass("MyClassNatives");
638     ASSERT_TRUE(jklass_ != nullptr) << method_name << " " << method_sig;
639
640     if (direct) {
641       jmethod_ = env_->GetStaticMethodID(jklass_, method_name, method_sig);
642     } else {
643       jmethod_ = env_->GetMethodID(jklass_, method_name, method_sig);
644     }
645     ASSERT_TRUE(jmethod_ != nullptr) << method_name << " " << method_sig;
646
647     if (native_fnptr != nullptr) {
648       JNINativeMethod methods[] = { { method_name, method_sig, native_fnptr } };
649       ASSERT_EQ(JNI_OK, env_->RegisterNatives(jklass_, methods, 1))
650           << method_name << " " << method_sig;
651     } else {
652       env_->UnregisterNatives(jklass_);
653     }
654
655     jmethodID constructor = env_->GetMethodID(jklass_, "<init>", "()V");
656     jobj_ = env_->NewObject(jklass_, constructor);
657     ASSERT_TRUE(jobj_ != nullptr) << method_name << " " << method_sig;
658   }
659
660   JavaVMExt* vm_;
661   JNIEnv* env_;
662   jclass aioobe_;
663   jclass ase_;
664   jclass sioobe_;
665
666   jclass jklass_;
667   jobject jobj_;
668   jobject class_loader_;
669   jmethodID jmethod_;
670 };
671
672 TEST_F(JniInternalTest, AllocObject) {
673   jclass c = env_->FindClass("java/lang/String");
674   ASSERT_NE(c, nullptr);
675   jobject o = env_->AllocObject(c);
676   ASSERT_NE(o, nullptr);
677
678   // We have an instance of the class we asked for...
679   ASSERT_TRUE(env_->IsInstanceOf(o, c));
680   // ...whose fields haven't been initialized because
681   // we didn't call a constructor.
682   ASSERT_EQ(0, env_->GetIntField(o, env_->GetFieldID(c, "count", "I")));
683 }
684
685 TEST_F(JniInternalTest, GetVersion) {
686   ASSERT_EQ(JNI_VERSION_1_6, env_->GetVersion());
687 }
688
689 TEST_F(JniInternalTest, FindClass) {
690   // This tests leads to warnings in the log.
691   ScopedLogSeverity sls(LogSeverity::ERROR);
692
693   FindClassTest(false);
694   FindClassTest(true);
695 }
696
697 TEST_F(JniInternalTest, GetFieldID) {
698   jclass jlnsfe = env_->FindClass("java/lang/NoSuchFieldError");
699   ASSERT_NE(jlnsfe, nullptr);
700   jclass c = env_->FindClass("java/lang/String");
701   ASSERT_NE(c, nullptr);
702
703   // Wrong type.
704   jfieldID fid = env_->GetFieldID(c, "count", "J");
705   EXPECT_EQ(nullptr, fid);
706   ExpectException(jlnsfe);
707
708   // Wrong type where type doesn't exist.
709   fid = env_->GetFieldID(c, "count", "Lrod/jane/freddy;");
710   EXPECT_EQ(nullptr, fid);
711   ExpectException(jlnsfe);
712
713   // Wrong name.
714   fid = env_->GetFieldID(c, "Count", "I");
715   EXPECT_EQ(nullptr, fid);
716   ExpectException(jlnsfe);
717
718   // Good declared field lookup.
719   fid = env_->GetFieldID(c, "count", "I");
720   EXPECT_NE(nullptr, fid);
721   EXPECT_FALSE(env_->ExceptionCheck());
722
723   // Good superclass field lookup.
724   c = env_->FindClass("java/lang/StringBuilder");
725   fid = env_->GetFieldID(c, "count", "I");
726   EXPECT_NE(nullptr, fid);
727   EXPECT_NE(fid, nullptr);
728   EXPECT_FALSE(env_->ExceptionCheck());
729
730   // Not instance.
731   fid = env_->GetFieldID(c, "CASE_INSENSITIVE_ORDER", "Ljava/util/Comparator;");
732   EXPECT_EQ(nullptr, fid);
733   ExpectException(jlnsfe);
734
735   // Bad arguments.
736   GetFieldIdBadArgumentTest(false);
737   GetFieldIdBadArgumentTest(true);
738 }
739
740 TEST_F(JniInternalTest, GetStaticFieldID) {
741   jclass jlnsfe = env_->FindClass("java/lang/NoSuchFieldError");
742   ASSERT_NE(jlnsfe, nullptr);
743   jclass c = env_->FindClass("java/lang/String");
744   ASSERT_NE(c, nullptr);
745
746   // Wrong type.
747   jfieldID fid = env_->GetStaticFieldID(c, "CASE_INSENSITIVE_ORDER", "J");
748   EXPECT_EQ(nullptr, fid);
749   ExpectException(jlnsfe);
750
751   // Wrong type where type doesn't exist.
752   fid = env_->GetStaticFieldID(c, "CASE_INSENSITIVE_ORDER", "Lrod/jane/freddy;");
753   EXPECT_EQ(nullptr, fid);
754   ExpectException(jlnsfe);
755
756   // Wrong name.
757   fid = env_->GetStaticFieldID(c, "cASE_INSENSITIVE_ORDER", "Ljava/util/Comparator;");
758   EXPECT_EQ(nullptr, fid);
759   ExpectException(jlnsfe);
760
761   // Good declared field lookup.
762   fid = env_->GetStaticFieldID(c, "CASE_INSENSITIVE_ORDER", "Ljava/util/Comparator;");
763   EXPECT_NE(nullptr, fid);
764   EXPECT_NE(fid, nullptr);
765   EXPECT_FALSE(env_->ExceptionCheck());
766
767   // Not static.
768   fid = env_->GetStaticFieldID(c, "count", "I");
769   EXPECT_EQ(nullptr, fid);
770   ExpectException(jlnsfe);
771
772   // Bad arguments.
773   GetStaticFieldIdBadArgumentTest(false);
774   GetStaticFieldIdBadArgumentTest(true);
775 }
776
777 TEST_F(JniInternalTest, GetMethodID) {
778   jclass jlobject = env_->FindClass("java/lang/Object");
779   jclass jlstring = env_->FindClass("java/lang/String");
780   jclass jlnsme = env_->FindClass("java/lang/NoSuchMethodError");
781   jclass jncrbc = env_->FindClass("java/nio/channels/ReadableByteChannel");
782
783   // Sanity check that no exceptions are pending.
784   ASSERT_FALSE(env_->ExceptionCheck());
785
786   // Check that java.lang.Object.foo() doesn't exist and NoSuchMethodError is
787   // a pending exception.
788   jmethodID method = env_->GetMethodID(jlobject, "foo", "()V");
789   EXPECT_EQ(nullptr, method);
790   ExpectException(jlnsme);
791
792   // Check that java.lang.Object.equals() does exist.
793   method = env_->GetMethodID(jlobject, "equals", "(Ljava/lang/Object;)Z");
794   EXPECT_NE(nullptr, method);
795   EXPECT_FALSE(env_->ExceptionCheck());
796
797   // Check that GetMethodID for java.lang.String.valueOf(int) fails as the
798   // method is static.
799   method = env_->GetMethodID(jlstring, "valueOf", "(I)Ljava/lang/String;");
800   EXPECT_EQ(nullptr, method);
801   ExpectException(jlnsme);
802
803   // Check that GetMethodID for java.lang.NoSuchMethodError.<init>(String) finds the constructor.
804   method = env_->GetMethodID(jlnsme, "<init>", "(Ljava/lang/String;)V");
805   EXPECT_NE(nullptr, method);
806   EXPECT_FALSE(env_->ExceptionCheck());
807
808   // Check that GetMethodID can find a interface method inherited from another interface.
809   method = env_->GetMethodID(jncrbc, "close", "()V");
810   EXPECT_NE(nullptr, method);
811   EXPECT_FALSE(env_->ExceptionCheck());
812
813   // Bad arguments.
814   GetMethodIdBadArgumentTest(false);
815   GetMethodIdBadArgumentTest(true);
816 }
817
818 TEST_F(JniInternalTest, CallVoidMethodNullReceiver) {
819   jclass jlobject = env_->FindClass("java/lang/Object");
820   jmethodID method;
821
822   // Check that GetMethodID for java.lang.NoSuchMethodError.<init>(String) finds the constructor.
823   method = env_->GetMethodID(jlobject, "<init>", "()V");
824   EXPECT_NE(nullptr, method);
825   EXPECT_FALSE(env_->ExceptionCheck());
826
827   // Null object to CallVoidMethod.
828   CheckJniAbortCatcher check_jni_abort_catcher;
829   env_->CallVoidMethod(nullptr, method);
830   check_jni_abort_catcher.Check("null");
831 }
832
833 TEST_F(JniInternalTest, GetStaticMethodID) {
834   jclass jlobject = env_->FindClass("java/lang/Object");
835   jclass jlnsme = env_->FindClass("java/lang/NoSuchMethodError");
836
837   // Sanity check that no exceptions are pending
838   ASSERT_FALSE(env_->ExceptionCheck());
839
840   // Check that java.lang.Object.foo() doesn't exist and NoSuchMethodError is
841   // a pending exception
842   jmethodID method = env_->GetStaticMethodID(jlobject, "foo", "()V");
843   EXPECT_EQ(nullptr, method);
844   ExpectException(jlnsme);
845
846   // Check that GetStaticMethodID for java.lang.Object.equals(Object) fails as
847   // the method is not static
848   method = env_->GetStaticMethodID(jlobject, "equals", "(Ljava/lang/Object;)Z");
849   EXPECT_EQ(nullptr, method);
850   ExpectException(jlnsme);
851
852   // Check that java.lang.String.valueOf(int) does exist
853   jclass jlstring = env_->FindClass("java/lang/String");
854   method = env_->GetStaticMethodID(jlstring, "valueOf", "(I)Ljava/lang/String;");
855   EXPECT_NE(nullptr, method);
856   EXPECT_FALSE(env_->ExceptionCheck());
857
858   // Bad arguments.
859   GetStaticMethodIdBadArgumentTest(false);
860   GetStaticMethodIdBadArgumentTest(true);
861 }
862
863 TEST_F(JniInternalTest, FromReflectedField_ToReflectedField) {
864   jclass jlrField = env_->FindClass("java/lang/reflect/Field");
865   jclass c = env_->FindClass("java/lang/String");
866   ASSERT_NE(c, nullptr);
867   jfieldID fid = env_->GetFieldID(c, "count", "I");
868   ASSERT_NE(fid, nullptr);
869   // Turn the fid into a java.lang.reflect.Field...
870   jobject field = env_->ToReflectedField(c, fid, JNI_FALSE);
871   for (size_t i = 0; i <= kLocalsMax; ++i) {
872     // Regression test for b/18396311, ToReflectedField leaking local refs causing a local
873     // reference table overflows with 512 references to ArtField
874     env_->DeleteLocalRef(env_->ToReflectedField(c, fid, JNI_FALSE));
875   }
876   ASSERT_NE(c, nullptr);
877   ASSERT_TRUE(env_->IsInstanceOf(field, jlrField));
878   // ...and back again.
879   jfieldID fid2 = env_->FromReflectedField(field);
880   ASSERT_NE(fid2, nullptr);
881   // Make sure we can actually use it.
882   jstring s = env_->NewStringUTF("poop");
883   ASSERT_EQ(4, env_->GetIntField(s, fid2));
884
885   // Bad arguments.
886   GetFromReflectedField_ToReflectedFieldBadArgumentTest(false);
887   GetFromReflectedField_ToReflectedFieldBadArgumentTest(true);
888 }
889
890 TEST_F(JniInternalTest, FromReflectedMethod_ToReflectedMethod) {
891   jclass jlrMethod = env_->FindClass("java/lang/reflect/Method");
892   ASSERT_NE(jlrMethod, nullptr);
893   jclass jlrConstructor = env_->FindClass("java/lang/reflect/Constructor");
894   ASSERT_NE(jlrConstructor, nullptr);
895   jclass c = env_->FindClass("java/lang/String");
896   ASSERT_NE(c, nullptr);
897
898   jmethodID mid = env_->GetMethodID(c, "<init>", "()V");
899   ASSERT_NE(mid, nullptr);
900   // Turn the mid into a java.lang.reflect.Constructor...
901   jobject method = env_->ToReflectedMethod(c, mid, JNI_FALSE);
902   for (size_t i = 0; i <= kLocalsMax; ++i) {
903     // Regression test for b/18396311, ToReflectedMethod leaking local refs causing a local
904     // reference table overflows with 512 references to ArtMethod
905     env_->DeleteLocalRef(env_->ToReflectedMethod(c, mid, JNI_FALSE));
906   }
907   ASSERT_NE(method, nullptr);
908   ASSERT_TRUE(env_->IsInstanceOf(method, jlrConstructor));
909   // ...and back again.
910   jmethodID mid2 = env_->FromReflectedMethod(method);
911   ASSERT_NE(mid2, nullptr);
912   // Make sure we can actually use it.
913   jstring s = reinterpret_cast<jstring>(env_->AllocObject(c));
914   ASSERT_NE(s, nullptr);
915   env_->CallVoidMethod(s, mid2);
916   ASSERT_EQ(JNI_FALSE, env_->ExceptionCheck());
917   env_->ExceptionClear();
918
919   mid = env_->GetMethodID(c, "length", "()I");
920   ASSERT_NE(mid, nullptr);
921   // Turn the mid into a java.lang.reflect.Method...
922   method = env_->ToReflectedMethod(c, mid, JNI_FALSE);
923   ASSERT_NE(method, nullptr);
924   ASSERT_TRUE(env_->IsInstanceOf(method, jlrMethod));
925   // ...and back again.
926   mid2 = env_->FromReflectedMethod(method);
927   ASSERT_NE(mid2, nullptr);
928   // Make sure we can actually use it.
929   s = env_->NewStringUTF("poop");
930   ASSERT_NE(s, nullptr);
931   ASSERT_EQ(4, env_->CallIntMethod(s, mid2));
932
933   // Bad arguments.
934   GetFromReflectedMethod_ToReflectedMethodBadArgumentTest(false);
935   GetFromReflectedMethod_ToReflectedMethodBadArgumentTest(true);
936 }
937
938 static void BogusMethod() {
939   // You can't pass null function pointers to RegisterNatives.
940 }
941
942 TEST_F(JniInternalTest, RegisterAndUnregisterNatives) {
943   jclass jlobject = env_->FindClass("java/lang/Object");
944   jclass jlnsme = env_->FindClass("java/lang/NoSuchMethodError");
945   void* native_function = reinterpret_cast<void*>(BogusMethod);
946
947   // Sanity check that no exceptions are pending.
948   ASSERT_FALSE(env_->ExceptionCheck());
949
950   // The following can print errors to the log we'd like to ignore.
951   {
952     ScopedLogSeverity sls(LogSeverity::FATAL);
953     // Check that registering method without name causes a NoSuchMethodError.
954     {
955       JNINativeMethod methods[] = { { nullptr, "()V", native_function } };
956       EXPECT_EQ(env_->RegisterNatives(jlobject, methods, 1), JNI_ERR);
957     }
958     ExpectException(jlnsme);
959
960     // Check that registering method without signature causes a NoSuchMethodError.
961     {
962       JNINativeMethod methods[] = { { "notify", nullptr, native_function } };
963       EXPECT_EQ(env_->RegisterNatives(jlobject, methods, 1), JNI_ERR);
964     }
965     ExpectException(jlnsme);
966
967     // Check that registering method without function causes a NoSuchMethodError.
968     {
969       JNINativeMethod methods[] = { { "notify", "()V", nullptr } };
970       EXPECT_EQ(env_->RegisterNatives(jlobject, methods, 1), JNI_ERR);
971     }
972     ExpectException(jlnsme);
973
974     // Check that registering to a non-existent java.lang.Object.foo() causes a NoSuchMethodError.
975     {
976       JNINativeMethod methods[] = { { "foo", "()V", native_function } };
977       EXPECT_EQ(env_->RegisterNatives(jlobject, methods, 1), JNI_ERR);
978     }
979     ExpectException(jlnsme);
980
981     // Check that registering non-native methods causes a NoSuchMethodError.
982     {
983       JNINativeMethod methods[] = { { "equals", "(Ljava/lang/Object;)Z", native_function } };
984       EXPECT_EQ(env_->RegisterNatives(jlobject, methods, 1), JNI_ERR);
985     }
986     ExpectException(jlnsme);
987   }
988
989   // Check that registering native methods is successful.
990   {
991     JNINativeMethod methods[] = { { "notify", "()V", native_function } };
992     EXPECT_EQ(env_->RegisterNatives(jlobject, methods, 1), JNI_OK);
993   }
994   EXPECT_FALSE(env_->ExceptionCheck());
995   EXPECT_EQ(env_->UnregisterNatives(jlobject), JNI_OK);
996
997   // Check that registering no methods isn't a failure.
998   {
999     JNINativeMethod methods[] = { };
1000     EXPECT_EQ(env_->RegisterNatives(jlobject, methods, 0), JNI_OK);
1001   }
1002   EXPECT_FALSE(env_->ExceptionCheck());
1003   EXPECT_EQ(env_->UnregisterNatives(jlobject), JNI_OK);
1004
1005   // Check that registering a -ve number of methods is a failure.
1006   CheckJniAbortCatcher check_jni_abort_catcher;
1007   for (int i = -10; i < 0; ++i) {
1008     JNINativeMethod methods[] = { };
1009     EXPECT_EQ(env_->RegisterNatives(jlobject, methods, i), JNI_ERR);
1010     check_jni_abort_catcher.Check("negative method count: ");
1011   }
1012   EXPECT_FALSE(env_->ExceptionCheck());
1013
1014   // Unregistering a class with no natives is a warning.
1015   EXPECT_EQ(env_->UnregisterNatives(jlnsme), JNI_OK);
1016
1017   RegisterAndUnregisterNativesBadArguments(false, &check_jni_abort_catcher);
1018   RegisterAndUnregisterNativesBadArguments(true, &check_jni_abort_catcher);
1019 }
1020
1021 #define EXPECT_PRIMITIVE_ARRAY(new_fn, \
1022                                get_region_fn, \
1023                                set_region_fn, \
1024                                get_elements_fn, \
1025                                release_elements_fn, \
1026                                scalar_type, \
1027                                expected_class_descriptor) \
1028   jsize size = 4; \
1029   \
1030   { \
1031     CheckJniAbortCatcher jni_abort_catcher; \
1032     down_cast<JNIEnvExt*>(env_)->SetCheckJniEnabled(false); \
1033     /* Allocate an negative sized array and check it has the right failure type. */ \
1034     EXPECT_EQ(env_->new_fn(-1), nullptr); \
1035     jni_abort_catcher.Check("negative array length: -1"); \
1036     EXPECT_EQ(env_->new_fn(std::numeric_limits<jint>::min()), nullptr); \
1037     jni_abort_catcher.Check("negative array length: -2147483648"); \
1038     /* Pass the array as null. */ \
1039     EXPECT_EQ(0, env_->GetArrayLength(nullptr)); \
1040     jni_abort_catcher.Check("java_array == null"); \
1041     env_->get_region_fn(nullptr, 0, 0, nullptr); \
1042     jni_abort_catcher.Check("java_array == null"); \
1043     env_->set_region_fn(nullptr, 0, 0, nullptr); \
1044     jni_abort_catcher.Check("java_array == null"); \
1045     env_->get_elements_fn(nullptr, nullptr); \
1046     jni_abort_catcher.Check("java_array == null"); \
1047     env_->release_elements_fn(nullptr, nullptr, 0); \
1048     jni_abort_catcher.Check("java_array == null"); \
1049     /* Pass the elements for region as null. */ \
1050     scalar_type ## Array a = env_->new_fn(size); \
1051     env_->get_region_fn(a, 0, size, nullptr); \
1052     jni_abort_catcher.Check("buf == null"); \
1053     env_->set_region_fn(a, 0, size, nullptr); \
1054     jni_abort_catcher.Check("buf == null"); \
1055     down_cast<JNIEnvExt*>(env_)->SetCheckJniEnabled(true); \
1056   } \
1057   /* Allocate an array and check it has the right type and length. */ \
1058   scalar_type ## Array a = env_->new_fn(size); \
1059   EXPECT_NE(a, nullptr); \
1060   EXPECT_TRUE(env_->IsInstanceOf(a, env_->FindClass(expected_class_descriptor))); \
1061   EXPECT_EQ(size, env_->GetArrayLength(a)); \
1062   \
1063   /* GetPrimitiveArrayRegion/SetPrimitiveArrayRegion */ \
1064   /* AIOOBE for negative start offset. */ \
1065   env_->get_region_fn(a, -1, 1, nullptr); \
1066   ExpectException(aioobe_); \
1067   env_->set_region_fn(a, -1, 1, nullptr); \
1068   ExpectException(aioobe_); \
1069   \
1070   /* AIOOBE for negative length. */ \
1071   env_->get_region_fn(a, 0, -1, nullptr); \
1072   ExpectException(aioobe_); \
1073   env_->set_region_fn(a, 0, -1, nullptr); \
1074   ExpectException(aioobe_); \
1075   \
1076   /* AIOOBE for buffer overrun. */ \
1077   env_->get_region_fn(a, size - 1, size, nullptr); \
1078   ExpectException(aioobe_); \
1079   env_->set_region_fn(a, size - 1, size, nullptr); \
1080   ExpectException(aioobe_); \
1081   \
1082   /* Regression test against integer overflow in range check. */ \
1083   env_->get_region_fn(a, 0x7fffffff, 0x7fffffff, nullptr); \
1084   ExpectException(aioobe_); \
1085   env_->set_region_fn(a, 0x7fffffff, 0x7fffffff, nullptr); \
1086   ExpectException(aioobe_); \
1087   \
1088   /* It's okay for the buffer to be null as long as the length is 0. */ \
1089   env_->get_region_fn(a, 2, 0, nullptr); \
1090   /* Even if the offset is invalid... */ \
1091   env_->get_region_fn(a, 123, 0, nullptr); \
1092   ExpectException(aioobe_); \
1093   \
1094   /* It's okay for the buffer to be null as long as the length is 0. */ \
1095   env_->set_region_fn(a, 2, 0, nullptr); \
1096   /* Even if the offset is invalid... */ \
1097   env_->set_region_fn(a, 123, 0, nullptr); \
1098   ExpectException(aioobe_); \
1099   \
1100   /* Prepare a couple of buffers. */ \
1101   std::unique_ptr<scalar_type[]> src_buf(new scalar_type[size]); \
1102   std::unique_ptr<scalar_type[]> dst_buf(new scalar_type[size]); \
1103   for (jsize i = 0; i < size; ++i) { src_buf[i] = scalar_type(i); } \
1104   for (jsize i = 0; i < size; ++i) { dst_buf[i] = scalar_type(-1); } \
1105   \
1106   /* Copy all of src_buf onto the heap. */ \
1107   env_->set_region_fn(a, 0, size, &src_buf[0]); \
1108   /* Copy back only part. */ \
1109   env_->get_region_fn(a, 1, size - 2, &dst_buf[1]); \
1110   EXPECT_NE(memcmp(&src_buf[0], &dst_buf[0], size * sizeof(scalar_type)), 0) \
1111     << "short copy equal"; \
1112   /* Copy the missing pieces. */ \
1113   env_->get_region_fn(a, 0, 1, &dst_buf[0]); \
1114   env_->get_region_fn(a, size - 1, 1, &dst_buf[size - 1]); \
1115   EXPECT_EQ(memcmp(&src_buf[0], &dst_buf[0], size * sizeof(scalar_type)), 0) \
1116     << "fixed copy not equal"; \
1117   /* Copy back the whole array. */ \
1118   env_->get_region_fn(a, 0, size, &dst_buf[0]); \
1119   EXPECT_EQ(memcmp(&src_buf[0], &dst_buf[0], size * sizeof(scalar_type)), 0) \
1120     << "full copy not equal"; \
1121   /* GetPrimitiveArrayCritical */ \
1122   void* v = env_->GetPrimitiveArrayCritical(a, nullptr); \
1123   EXPECT_EQ(memcmp(&src_buf[0], v, size * sizeof(scalar_type)), 0) \
1124     << "GetPrimitiveArrayCritical not equal"; \
1125   env_->ReleasePrimitiveArrayCritical(a, v, 0); \
1126   /* GetXArrayElements */ \
1127   scalar_type* xs = env_->get_elements_fn(a, nullptr); \
1128   EXPECT_EQ(memcmp(&src_buf[0], xs, size * sizeof(scalar_type)), 0) \
1129     << # get_elements_fn " not equal"; \
1130   env_->release_elements_fn(a, xs, 0); \
1131
1132 TEST_F(JniInternalTest, BooleanArrays) {
1133   EXPECT_PRIMITIVE_ARRAY(NewBooleanArray, GetBooleanArrayRegion, SetBooleanArrayRegion,
1134                          GetBooleanArrayElements, ReleaseBooleanArrayElements, jboolean, "[Z");
1135 }
1136 TEST_F(JniInternalTest, ByteArrays) {
1137   EXPECT_PRIMITIVE_ARRAY(NewByteArray, GetByteArrayRegion, SetByteArrayRegion,
1138                          GetByteArrayElements, ReleaseByteArrayElements, jbyte, "[B");
1139 }
1140 TEST_F(JniInternalTest, CharArrays) {
1141   EXPECT_PRIMITIVE_ARRAY(NewCharArray, GetCharArrayRegion, SetCharArrayRegion,
1142                          GetCharArrayElements, ReleaseCharArrayElements, jchar, "[C");
1143 }
1144 TEST_F(JniInternalTest, DoubleArrays) {
1145   EXPECT_PRIMITIVE_ARRAY(NewDoubleArray, GetDoubleArrayRegion, SetDoubleArrayRegion,
1146                          GetDoubleArrayElements, ReleaseDoubleArrayElements, jdouble, "[D");
1147 }
1148 TEST_F(JniInternalTest, FloatArrays) {
1149   EXPECT_PRIMITIVE_ARRAY(NewFloatArray, GetFloatArrayRegion, SetFloatArrayRegion,
1150                          GetFloatArrayElements, ReleaseFloatArrayElements, jfloat, "[F");
1151 }
1152 TEST_F(JniInternalTest, IntArrays) {
1153   EXPECT_PRIMITIVE_ARRAY(NewIntArray, GetIntArrayRegion, SetIntArrayRegion,
1154                          GetIntArrayElements, ReleaseIntArrayElements, jint, "[I");
1155 }
1156 TEST_F(JniInternalTest, LongArrays) {
1157   EXPECT_PRIMITIVE_ARRAY(NewLongArray, GetLongArrayRegion, SetLongArrayRegion,
1158                          GetLongArrayElements, ReleaseLongArrayElements, jlong, "[J");
1159 }
1160 TEST_F(JniInternalTest, ShortArrays) {
1161   EXPECT_PRIMITIVE_ARRAY(NewShortArray, GetShortArrayRegion, SetShortArrayRegion,
1162                          GetShortArrayElements, ReleaseShortArrayElements, jshort, "[S");
1163 }
1164
1165 TEST_F(JniInternalTest, GetPrimitiveArrayElementsOfWrongType) {
1166   GetPrimitiveArrayElementsOfWrongType(false);
1167   GetPrimitiveArrayElementsOfWrongType(true);
1168 }
1169
1170 TEST_F(JniInternalTest, ReleasePrimitiveArrayElementsOfWrongType) {
1171   ReleasePrimitiveArrayElementsOfWrongType(false);
1172   ReleasePrimitiveArrayElementsOfWrongType(true);
1173 }
1174
1175 TEST_F(JniInternalTest, GetReleasePrimitiveArrayCriticalOfWrongType) {
1176   GetReleasePrimitiveArrayCriticalOfWrongType(false);
1177   GetReleasePrimitiveArrayCriticalOfWrongType(true);
1178 }
1179
1180 TEST_F(JniInternalTest, GetPrimitiveArrayRegionElementsOfWrongType) {
1181   GetPrimitiveArrayRegionElementsOfWrongType(false);
1182   GetPrimitiveArrayRegionElementsOfWrongType(true);
1183 }
1184
1185 TEST_F(JniInternalTest, SetPrimitiveArrayRegionElementsOfWrongType) {
1186   SetPrimitiveArrayRegionElementsOfWrongType(false);
1187   SetPrimitiveArrayRegionElementsOfWrongType(true);
1188 }
1189
1190 TEST_F(JniInternalTest, NewObjectArray) {
1191   jclass element_class = env_->FindClass("java/lang/String");
1192   ASSERT_NE(element_class, nullptr);
1193   jclass array_class = env_->FindClass("[Ljava/lang/String;");
1194   ASSERT_NE(array_class, nullptr);
1195
1196   jobjectArray a = env_->NewObjectArray(0, element_class, nullptr);
1197   EXPECT_NE(a, nullptr);
1198   EXPECT_TRUE(env_->IsInstanceOf(a, array_class));
1199   EXPECT_EQ(0, env_->GetArrayLength(a));
1200
1201   a = env_->NewObjectArray(1, element_class, nullptr);
1202   EXPECT_NE(a, nullptr);
1203   EXPECT_TRUE(env_->IsInstanceOf(a, array_class));
1204   EXPECT_EQ(1, env_->GetArrayLength(a));
1205   EXPECT_TRUE(env_->IsSameObject(env_->GetObjectArrayElement(a, 0), nullptr));
1206
1207   // Negative array length checks.
1208   NewObjectArrayBadArguments(false);
1209   NewObjectArrayBadArguments(true);
1210 }
1211
1212 TEST_F(JniInternalTest, NewObjectArrayWithPrimitiveClasses) {
1213   const char* primitive_descriptors = "VZBSCIJFD";
1214   const char* primitive_names[] = {
1215       "void", "boolean", "byte", "short", "char", "int", "long", "float", "double"
1216   };
1217   ASSERT_EQ(strlen(primitive_descriptors), arraysize(primitive_names));
1218
1219   bool old_check_jni = vm_->SetCheckJniEnabled(false);
1220   CheckJniAbortCatcher jni_abort_catcher;
1221   for (size_t i = 0; i < strlen(primitive_descriptors); ++i) {
1222     env_->NewObjectArray(0, nullptr, nullptr);
1223     jni_abort_catcher.Check("element_jclass == null");
1224     jclass primitive_class = GetPrimitiveClass(primitive_descriptors[i]);
1225     env_->NewObjectArray(1, primitive_class, nullptr);
1226     std::string error_msg(StringPrintf("not an object type: %s", primitive_names[i]));
1227     jni_abort_catcher.Check(error_msg.c_str());
1228   }
1229   EXPECT_FALSE(vm_->SetCheckJniEnabled(true));
1230   for (size_t i = 0; i < strlen(primitive_descriptors); ++i) {
1231     env_->NewObjectArray(0, nullptr, nullptr);
1232     jni_abort_catcher.Check("NewObjectArray received NULL jclass");
1233     jclass primitive_class = GetPrimitiveClass(primitive_descriptors[i]);
1234     env_->NewObjectArray(1, primitive_class, nullptr);
1235     std::string error_msg(StringPrintf("not an object type: %s", primitive_names[i]));
1236     jni_abort_catcher.Check(error_msg.c_str());
1237   }
1238   EXPECT_TRUE(vm_->SetCheckJniEnabled(old_check_jni));
1239 }
1240
1241 TEST_F(JniInternalTest, NewObjectArrayWithInitialValue) {
1242   jclass element_class = env_->FindClass("java/lang/String");
1243   ASSERT_NE(element_class, nullptr);
1244   jclass array_class = env_->FindClass("[Ljava/lang/String;");
1245   ASSERT_NE(array_class, nullptr);
1246
1247   jstring s = env_->NewStringUTF("poop");
1248   jobjectArray a = env_->NewObjectArray(2, element_class, s);
1249   EXPECT_NE(a, nullptr);
1250   EXPECT_TRUE(env_->IsInstanceOf(a, array_class));
1251   EXPECT_EQ(2, env_->GetArrayLength(a));
1252   EXPECT_TRUE(env_->IsSameObject(env_->GetObjectArrayElement(a, 0), s));
1253   EXPECT_TRUE(env_->IsSameObject(env_->GetObjectArrayElement(a, 1), s));
1254
1255   // Attempt to incorrect create an array of strings with initial value of string arrays.
1256   CheckJniAbortCatcher jni_abort_catcher;
1257   env_->NewObjectArray(2, element_class, a);
1258   jni_abort_catcher.Check("cannot assign object of type 'java.lang.String[]' to array with element "
1259                           "type of 'java.lang.String'");
1260 }
1261
1262 TEST_F(JniInternalTest, GetArrayLength) {
1263   // Already tested in NewObjectArray/NewPrimitiveArray except for null.
1264   CheckJniAbortCatcher jni_abort_catcher;
1265   bool old_check_jni = vm_->SetCheckJniEnabled(false);
1266   EXPECT_EQ(0, env_->GetArrayLength(nullptr));
1267   jni_abort_catcher.Check("java_array == null");
1268   EXPECT_FALSE(vm_->SetCheckJniEnabled(true));
1269   EXPECT_EQ(JNI_ERR, env_->GetArrayLength(nullptr));
1270   jni_abort_catcher.Check("jarray was NULL");
1271   EXPECT_TRUE(vm_->SetCheckJniEnabled(old_check_jni));
1272 }
1273
1274 TEST_F(JniInternalTest, GetObjectClass) {
1275   jclass string_class = env_->FindClass("java/lang/String");
1276   ASSERT_NE(string_class, nullptr);
1277   jclass class_class = env_->FindClass("java/lang/Class");
1278   ASSERT_NE(class_class, nullptr);
1279
1280   jstring s = env_->NewStringUTF("poop");
1281   jclass c = env_->GetObjectClass(s);
1282   ASSERT_TRUE(env_->IsSameObject(string_class, c));
1283
1284   jclass c2 = env_->GetObjectClass(c);
1285   ASSERT_TRUE(env_->IsSameObject(class_class, env_->GetObjectClass(c2)));
1286
1287   // Null as object should fail.
1288   CheckJniAbortCatcher jni_abort_catcher;
1289   EXPECT_EQ(env_->GetObjectClass(nullptr), nullptr);
1290   jni_abort_catcher.Check("java_object == null");
1291 }
1292
1293 TEST_F(JniInternalTest, GetSuperclass) {
1294   jclass object_class = env_->FindClass("java/lang/Object");
1295   ASSERT_NE(object_class, nullptr);
1296   jclass string_class = env_->FindClass("java/lang/String");
1297   ASSERT_NE(string_class, nullptr);
1298   jclass runnable_interface = env_->FindClass("java/lang/Runnable");
1299   ASSERT_NE(runnable_interface, nullptr);
1300   ASSERT_TRUE(env_->IsSameObject(object_class, env_->GetSuperclass(string_class)));
1301   ASSERT_EQ(env_->GetSuperclass(object_class), nullptr);
1302   ASSERT_EQ(env_->GetSuperclass(runnable_interface), nullptr);
1303
1304   // Null as class should fail.
1305   CheckJniAbortCatcher jni_abort_catcher;
1306   bool old_check_jni = vm_->SetCheckJniEnabled(false);
1307   EXPECT_EQ(env_->GetSuperclass(nullptr), nullptr);
1308   jni_abort_catcher.Check("java_class == null");
1309   EXPECT_FALSE(vm_->SetCheckJniEnabled(true));
1310   EXPECT_EQ(env_->GetSuperclass(nullptr), nullptr);
1311   jni_abort_catcher.Check("GetSuperclass received NULL jclass");
1312   EXPECT_TRUE(vm_->SetCheckJniEnabled(old_check_jni));
1313 }
1314
1315 TEST_F(JniInternalTest, IsAssignableFrom) {
1316   jclass object_class = env_->FindClass("java/lang/Object");
1317   ASSERT_NE(object_class, nullptr);
1318   jclass string_class = env_->FindClass("java/lang/String");
1319   ASSERT_NE(string_class, nullptr);
1320
1321   // A superclass is assignable from an instance of its
1322   // subclass but not vice versa.
1323   ASSERT_TRUE(env_->IsAssignableFrom(string_class, object_class));
1324   ASSERT_FALSE(env_->IsAssignableFrom(object_class, string_class));
1325
1326   jclass charsequence_interface = env_->FindClass("java/lang/CharSequence");
1327   ASSERT_NE(charsequence_interface, nullptr);
1328
1329   // An interface is assignable from an instance of an implementing
1330   // class but not vice versa.
1331   ASSERT_TRUE(env_->IsAssignableFrom(string_class, charsequence_interface));
1332   ASSERT_FALSE(env_->IsAssignableFrom(charsequence_interface, string_class));
1333
1334   // Check that arrays are covariant.
1335   jclass string_array_class = env_->FindClass("[Ljava/lang/String;");
1336   ASSERT_NE(string_array_class, nullptr);
1337   jclass object_array_class = env_->FindClass("[Ljava/lang/Object;");
1338   ASSERT_NE(object_array_class, nullptr);
1339   ASSERT_TRUE(env_->IsAssignableFrom(string_array_class, object_array_class));
1340   ASSERT_FALSE(env_->IsAssignableFrom(object_array_class, string_array_class));
1341
1342   // Primitive types are tested in 004-JniTest.
1343
1344   // Null as either class should fail.
1345   CheckJniAbortCatcher jni_abort_catcher;
1346   bool old_check_jni = vm_->SetCheckJniEnabled(false);
1347   EXPECT_EQ(env_->IsAssignableFrom(nullptr, string_class), JNI_FALSE);
1348   jni_abort_catcher.Check("java_class1 == null");
1349   EXPECT_EQ(env_->IsAssignableFrom(object_class, nullptr), JNI_FALSE);
1350   jni_abort_catcher.Check("java_class2 == null");
1351   EXPECT_FALSE(vm_->SetCheckJniEnabled(true));
1352   EXPECT_EQ(env_->IsAssignableFrom(nullptr, string_class), JNI_FALSE);
1353   jni_abort_catcher.Check("IsAssignableFrom received NULL jclass");
1354   EXPECT_EQ(env_->IsAssignableFrom(object_class, nullptr), JNI_FALSE);
1355   jni_abort_catcher.Check("IsAssignableFrom received NULL jclass");
1356   EXPECT_TRUE(vm_->SetCheckJniEnabled(old_check_jni));
1357 }
1358
1359 TEST_F(JniInternalTest, GetObjectRefType) {
1360   jclass local = env_->FindClass("java/lang/Object");
1361   ASSERT_TRUE(local != nullptr);
1362   EXPECT_EQ(JNILocalRefType, env_->GetObjectRefType(local));
1363
1364   jobject global = env_->NewGlobalRef(local);
1365   EXPECT_EQ(JNIGlobalRefType, env_->GetObjectRefType(global));
1366
1367   jweak weak_global = env_->NewWeakGlobalRef(local);
1368   EXPECT_EQ(JNIWeakGlobalRefType, env_->GetObjectRefType(weak_global));
1369
1370   {
1371     CheckJniAbortCatcher jni_abort_catcher;
1372     jobject invalid = reinterpret_cast<jobject>(this);
1373     EXPECT_EQ(JNIInvalidRefType, env_->GetObjectRefType(invalid));
1374     jni_abort_catcher.Check("use of invalid jobject");
1375   }
1376
1377   // TODO: invoke a native method and test that its arguments are considered local references.
1378
1379   // Null as pointer should not fail and return invalid-ref. b/18820997
1380   EXPECT_EQ(JNIInvalidRefType, env_->GetObjectRefType(nullptr));
1381
1382   // TODO: Null as reference should return the original type.
1383   // This requires running a GC so a non-null object gets freed.
1384 }
1385
1386 TEST_F(JniInternalTest, StaleWeakGlobal) {
1387   jclass java_lang_Class = env_->FindClass("java/lang/Class");
1388   ASSERT_NE(java_lang_Class, nullptr);
1389   jobjectArray local_ref = env_->NewObjectArray(1, java_lang_Class, nullptr);
1390   ASSERT_NE(local_ref, nullptr);
1391   jweak weak_global = env_->NewWeakGlobalRef(local_ref);
1392   ASSERT_NE(weak_global, nullptr);
1393   env_->DeleteLocalRef(local_ref);
1394   Runtime::Current()->GetHeap()->CollectGarbage(false);  // GC should clear the weak global.
1395   jobject new_global_ref = env_->NewGlobalRef(weak_global);
1396   EXPECT_EQ(new_global_ref, nullptr);
1397   jobject new_local_ref = env_->NewLocalRef(weak_global);
1398   EXPECT_EQ(new_local_ref, nullptr);
1399 }
1400
1401 TEST_F(JniInternalTest, NewStringUTF) {
1402   EXPECT_EQ(env_->NewStringUTF(nullptr), nullptr);
1403   jstring s;
1404
1405   s = env_->NewStringUTF("");
1406   EXPECT_NE(s, nullptr);
1407   EXPECT_EQ(0, env_->GetStringLength(s));
1408   EXPECT_EQ(0, env_->GetStringUTFLength(s));
1409   s = env_->NewStringUTF("hello");
1410   EXPECT_NE(s, nullptr);
1411   EXPECT_EQ(5, env_->GetStringLength(s));
1412   EXPECT_EQ(5, env_->GetStringUTFLength(s));
1413
1414   // Encoded surrogate pair.
1415   s = env_->NewStringUTF("\xed\xa0\x81\xed\xb0\x80");
1416   EXPECT_NE(s, nullptr);
1417   EXPECT_EQ(2, env_->GetStringLength(s));
1418
1419   // The surrogate pair gets encoded into a 4 byte UTF sequence..
1420   EXPECT_EQ(4, env_->GetStringUTFLength(s));
1421   const char* chars = env_->GetStringUTFChars(s, nullptr);
1422   EXPECT_STREQ("\xf0\x90\x90\x80", chars);
1423   env_->ReleaseStringUTFChars(s, chars);
1424
1425   // .. but is stored as is in the utf-16 representation.
1426   const jchar* jchars = env_->GetStringChars(s, nullptr);
1427   EXPECT_EQ(0xd801, jchars[0]);
1428   EXPECT_EQ(0xdc00, jchars[1]);
1429   env_->ReleaseStringChars(s, jchars);
1430
1431   // 4 byte UTF sequence appended to an encoded surrogate pair.
1432   s = env_->NewStringUTF("\xed\xa0\x81\xed\xb0\x80 \xf0\x9f\x8f\xa0");
1433   EXPECT_NE(s, nullptr);
1434
1435   // The 4 byte sequence {0xf0, 0x9f, 0x8f, 0xa0} is converted into a surrogate
1436   // pair {0xd83c, 0xdfe0}.
1437   EXPECT_EQ(5, env_->GetStringLength(s));
1438   jchars = env_->GetStringChars(s, nullptr);
1439   // The first surrogate pair, encoded as such in the input.
1440   EXPECT_EQ(0xd801, jchars[0]);
1441   EXPECT_EQ(0xdc00, jchars[1]);
1442   // The second surrogate pair, from the 4 byte UTF sequence in the input.
1443   EXPECT_EQ(0xd83c, jchars[3]);
1444   EXPECT_EQ(0xdfe0, jchars[4]);
1445   env_->ReleaseStringChars(s, jchars);
1446
1447   EXPECT_EQ(9, env_->GetStringUTFLength(s));
1448   chars = env_->GetStringUTFChars(s, nullptr);
1449   EXPECT_STREQ("\xf0\x90\x90\x80 \xf0\x9f\x8f\xa0", chars);
1450   env_->ReleaseStringUTFChars(s, chars);
1451
1452   // A string with 1, 2, 3 and 4 byte UTF sequences with spaces
1453   // between them
1454   s = env_->NewStringUTF("\x24 \xc2\xa2 \xe2\x82\xac \xf0\x9f\x8f\xa0");
1455   EXPECT_NE(s, nullptr);
1456   EXPECT_EQ(8, env_->GetStringLength(s));
1457   EXPECT_EQ(13, env_->GetStringUTFLength(s));
1458 }
1459
1460 TEST_F(JniInternalTest, NewString) {
1461   jchar chars[] = { 'h', 'i' };
1462   jstring s;
1463   s = env_->NewString(chars, 0);
1464   EXPECT_NE(s, nullptr);
1465   EXPECT_EQ(0, env_->GetStringLength(s));
1466   EXPECT_EQ(0, env_->GetStringUTFLength(s));
1467   s = env_->NewString(chars, 2);
1468   EXPECT_NE(s, nullptr);
1469   EXPECT_EQ(2, env_->GetStringLength(s));
1470   EXPECT_EQ(2, env_->GetStringUTFLength(s));
1471
1472   // TODO: check some non-ASCII strings.
1473 }
1474
1475 TEST_F(JniInternalTest, NewStringNullCharsZeroLength) {
1476   jstring s = env_->NewString(nullptr, 0);
1477   EXPECT_NE(s, nullptr);
1478   EXPECT_EQ(0, env_->GetStringLength(s));
1479 }
1480
1481 TEST_F(JniInternalTest, NewStringNullCharsNonzeroLength) {
1482   CheckJniAbortCatcher jni_abort_catcher;
1483   env_->NewString(nullptr, 1);
1484   jni_abort_catcher.Check("chars == null && char_count > 0");
1485 }
1486
1487 TEST_F(JniInternalTest, NewStringNegativeLength) {
1488   CheckJniAbortCatcher jni_abort_catcher;
1489   bool old_check_jni = vm_->SetCheckJniEnabled(false);
1490   env_->NewString(nullptr, -1);
1491   jni_abort_catcher.Check("char_count < 0: -1");
1492   env_->NewString(nullptr, std::numeric_limits<jint>::min());
1493   jni_abort_catcher.Check("char_count < 0: -2147483648");
1494   EXPECT_FALSE(vm_->SetCheckJniEnabled(true));
1495   env_->NewString(nullptr, -1);
1496   jni_abort_catcher.Check("negative jsize: -1");
1497   env_->NewString(nullptr, std::numeric_limits<jint>::min());
1498   jni_abort_catcher.Check("negative jsize: -2147483648");
1499   EXPECT_TRUE(vm_->SetCheckJniEnabled(old_check_jni));
1500 }
1501
1502 TEST_F(JniInternalTest, GetStringLength_GetStringUTFLength) {
1503   // Already tested in the NewString/NewStringUTF tests.
1504 }
1505
1506 TEST_F(JniInternalTest, GetStringRegion_GetStringUTFRegion) {
1507   jstring s = env_->NewStringUTF("hello");
1508   ASSERT_TRUE(s != nullptr);
1509
1510   env_->GetStringRegion(s, -1, 0, nullptr);
1511   ExpectException(sioobe_);
1512   env_->GetStringRegion(s, 0, -1, nullptr);
1513   ExpectException(sioobe_);
1514   env_->GetStringRegion(s, 0, 10, nullptr);
1515   ExpectException(sioobe_);
1516   env_->GetStringRegion(s, 10, 1, nullptr);
1517   ExpectException(sioobe_);
1518   // Regression test against integer overflow in range check.
1519   env_->GetStringRegion(s, 0x7fffffff, 0x7fffffff, nullptr);
1520   ExpectException(sioobe_);
1521
1522   jchar chars[4] = { 'x', 'x', 'x', 'x' };
1523   env_->GetStringRegion(s, 1, 2, &chars[1]);
1524   EXPECT_EQ('x', chars[0]);
1525   EXPECT_EQ('e', chars[1]);
1526   EXPECT_EQ('l', chars[2]);
1527   EXPECT_EQ('x', chars[3]);
1528
1529   // It's okay for the buffer to be null as long as the length is 0.
1530   env_->GetStringRegion(s, 2, 0, nullptr);
1531   // Even if the offset is invalid...
1532   env_->GetStringRegion(s, 123, 0, nullptr);
1533   ExpectException(sioobe_);
1534
1535   env_->GetStringUTFRegion(s, -1, 0, nullptr);
1536   ExpectException(sioobe_);
1537   env_->GetStringUTFRegion(s, 0, -1, nullptr);
1538   ExpectException(sioobe_);
1539   env_->GetStringUTFRegion(s, 0, 10, nullptr);
1540   ExpectException(sioobe_);
1541   env_->GetStringUTFRegion(s, 10, 1, nullptr);
1542   ExpectException(sioobe_);
1543   // Regression test against integer overflow in range check.
1544   env_->GetStringUTFRegion(s, 0x7fffffff, 0x7fffffff, nullptr);
1545   ExpectException(sioobe_);
1546
1547   char bytes[4] = { 'x', 'x', 'x', 'x' };
1548   env_->GetStringUTFRegion(s, 1, 2, &bytes[1]);
1549   EXPECT_EQ('x', bytes[0]);
1550   EXPECT_EQ('e', bytes[1]);
1551   EXPECT_EQ('l', bytes[2]);
1552   EXPECT_EQ('x', bytes[3]);
1553
1554   // It's okay for the buffer to be null as long as the length is 0.
1555   env_->GetStringUTFRegion(s, 2, 0, nullptr);
1556   // Even if the offset is invalid...
1557   env_->GetStringUTFRegion(s, 123, 0, nullptr);
1558   ExpectException(sioobe_);
1559 }
1560
1561 TEST_F(JniInternalTest, GetStringUTFChars_ReleaseStringUTFChars) {
1562   // Passing in a null jstring is ignored normally, but caught by -Xcheck:jni.
1563   bool old_check_jni = vm_->SetCheckJniEnabled(false);
1564   {
1565     CheckJniAbortCatcher check_jni_abort_catcher;
1566     EXPECT_EQ(env_->GetStringUTFChars(nullptr, nullptr), nullptr);
1567   }
1568   {
1569     CheckJniAbortCatcher check_jni_abort_catcher;
1570     EXPECT_FALSE(vm_->SetCheckJniEnabled(true));
1571     EXPECT_EQ(env_->GetStringUTFChars(nullptr, nullptr), nullptr);
1572     check_jni_abort_catcher.Check("GetStringUTFChars received NULL jstring");
1573     EXPECT_TRUE(vm_->SetCheckJniEnabled(old_check_jni));
1574   }
1575
1576   jstring s = env_->NewStringUTF("hello");
1577   ASSERT_TRUE(s != nullptr);
1578
1579   const char* utf = env_->GetStringUTFChars(s, nullptr);
1580   EXPECT_STREQ("hello", utf);
1581   env_->ReleaseStringUTFChars(s, utf);
1582
1583   jboolean is_copy = JNI_FALSE;
1584   utf = env_->GetStringUTFChars(s, &is_copy);
1585   EXPECT_EQ(JNI_TRUE, is_copy);
1586   EXPECT_STREQ("hello", utf);
1587   env_->ReleaseStringUTFChars(s, utf);
1588 }
1589
1590 TEST_F(JniInternalTest, GetStringChars_ReleaseStringChars) {
1591   jstring s = env_->NewStringUTF("hello");
1592   ScopedObjectAccess soa(env_);
1593   mirror::String* s_m = soa.Decode<mirror::String*>(s);
1594   ASSERT_TRUE(s != nullptr);
1595
1596   jchar expected[] = { 'h', 'e', 'l', 'l', 'o' };
1597   const jchar* chars = env_->GetStringChars(s, nullptr);
1598   EXPECT_EQ(expected[0], chars[0]);
1599   EXPECT_EQ(expected[1], chars[1]);
1600   EXPECT_EQ(expected[2], chars[2]);
1601   EXPECT_EQ(expected[3], chars[3]);
1602   EXPECT_EQ(expected[4], chars[4]);
1603   env_->ReleaseStringChars(s, chars);
1604
1605   jboolean is_copy = JNI_FALSE;
1606   chars = env_->GetStringChars(s, &is_copy);
1607   if (Runtime::Current()->GetHeap()->IsMovableObject(s_m)) {
1608     EXPECT_EQ(JNI_TRUE, is_copy);
1609   } else {
1610     EXPECT_EQ(JNI_FALSE, is_copy);
1611   }
1612   EXPECT_EQ(expected[0], chars[0]);
1613   EXPECT_EQ(expected[1], chars[1]);
1614   EXPECT_EQ(expected[2], chars[2]);
1615   EXPECT_EQ(expected[3], chars[3]);
1616   EXPECT_EQ(expected[4], chars[4]);
1617   env_->ReleaseStringChars(s, chars);
1618 }
1619
1620 TEST_F(JniInternalTest, GetStringCritical_ReleaseStringCritical) {
1621   jstring s = env_->NewStringUTF("hello");
1622   ASSERT_TRUE(s != nullptr);
1623
1624   jchar expected[] = { 'h', 'e', 'l', 'l', 'o' };
1625   const jchar* chars = env_->GetStringCritical(s, nullptr);
1626   EXPECT_EQ(expected[0], chars[0]);
1627   EXPECT_EQ(expected[1], chars[1]);
1628   EXPECT_EQ(expected[2], chars[2]);
1629   EXPECT_EQ(expected[3], chars[3]);
1630   EXPECT_EQ(expected[4], chars[4]);
1631   env_->ReleaseStringCritical(s, chars);
1632
1633   jboolean is_copy = JNI_TRUE;
1634   chars = env_->GetStringCritical(s, &is_copy);
1635   EXPECT_EQ(JNI_FALSE, is_copy);
1636   EXPECT_EQ(expected[0], chars[0]);
1637   EXPECT_EQ(expected[1], chars[1]);
1638   EXPECT_EQ(expected[2], chars[2]);
1639   EXPECT_EQ(expected[3], chars[3]);
1640   EXPECT_EQ(expected[4], chars[4]);
1641   env_->ReleaseStringCritical(s, chars);
1642 }
1643
1644 TEST_F(JniInternalTest, GetObjectArrayElement_SetObjectArrayElement) {
1645   jclass java_lang_Class = env_->FindClass("java/lang/Class");
1646   ASSERT_TRUE(java_lang_Class != nullptr);
1647
1648   jobjectArray array = env_->NewObjectArray(1, java_lang_Class, nullptr);
1649   EXPECT_NE(array, nullptr);
1650   EXPECT_EQ(env_->GetObjectArrayElement(array, 0), nullptr);
1651   env_->SetObjectArrayElement(array, 0, java_lang_Class);
1652   EXPECT_TRUE(env_->IsSameObject(env_->GetObjectArrayElement(array, 0), java_lang_Class));
1653
1654   // ArrayIndexOutOfBounds for negative index.
1655   env_->SetObjectArrayElement(array, -1, java_lang_Class);
1656   ExpectException(aioobe_);
1657
1658   // ArrayIndexOutOfBounds for too-large index.
1659   env_->SetObjectArrayElement(array, 1, java_lang_Class);
1660   ExpectException(aioobe_);
1661
1662   // ArrayStoreException thrown for bad types.
1663   env_->SetObjectArrayElement(array, 0, env_->NewStringUTF("not a jclass!"));
1664   ExpectException(ase_);
1665
1666   // Null as array should fail.
1667   CheckJniAbortCatcher jni_abort_catcher;
1668   bool old_check_jni = vm_->SetCheckJniEnabled(false);
1669   EXPECT_EQ(nullptr, env_->GetObjectArrayElement(nullptr, 0));
1670   jni_abort_catcher.Check("java_array == null");
1671   env_->SetObjectArrayElement(nullptr, 0, nullptr);
1672   jni_abort_catcher.Check("java_array == null");
1673   EXPECT_FALSE(vm_->SetCheckJniEnabled(true));
1674   EXPECT_EQ(nullptr, env_->GetObjectArrayElement(nullptr, 0));
1675   jni_abort_catcher.Check("jarray was NULL");
1676   env_->SetObjectArrayElement(nullptr, 0, nullptr);
1677   jni_abort_catcher.Check("jarray was NULL");
1678   EXPECT_TRUE(vm_->SetCheckJniEnabled(old_check_jni));
1679 }
1680
1681 #define EXPECT_STATIC_PRIMITIVE_FIELD(expect_eq, type, field_name, sig, value1, value2) \
1682   do { \
1683     jfieldID fid = env_->GetStaticFieldID(c, field_name, sig); \
1684     EXPECT_NE(fid, nullptr); \
1685     env_->SetStatic ## type ## Field(c, fid, value1); \
1686     expect_eq(value1, env_->GetStatic ## type ## Field(c, fid)); \
1687     env_->SetStatic ## type ## Field(c, fid, value2); \
1688     expect_eq(value2, env_->GetStatic ## type ## Field(c, fid)); \
1689     \
1690     bool old_check_jni = vm_->SetCheckJniEnabled(false); \
1691     { \
1692       CheckJniAbortCatcher jni_abort_catcher; \
1693       env_->GetStatic ## type ## Field(nullptr, fid); \
1694       env_->SetStatic ## type ## Field(nullptr, fid, value1); \
1695     } \
1696     CheckJniAbortCatcher jni_abort_catcher; \
1697     env_->GetStatic ## type ## Field(c, nullptr); \
1698     jni_abort_catcher.Check("fid == null"); \
1699     env_->SetStatic ## type ## Field(c, nullptr, value1); \
1700     jni_abort_catcher.Check("fid == null"); \
1701     \
1702     EXPECT_FALSE(vm_->SetCheckJniEnabled(true)); \
1703     env_->GetStatic ## type ## Field(nullptr, fid); \
1704     jni_abort_catcher.Check("received NULL jclass"); \
1705     env_->SetStatic ## type ## Field(nullptr, fid, value1); \
1706     jni_abort_catcher.Check("received NULL jclass"); \
1707     env_->GetStatic ## type ## Field(c, nullptr); \
1708     jni_abort_catcher.Check("jfieldID was NULL"); \
1709     env_->SetStatic ## type ## Field(c, nullptr, value1); \
1710     jni_abort_catcher.Check("jfieldID was NULL"); \
1711     EXPECT_TRUE(vm_->SetCheckJniEnabled(old_check_jni)); \
1712   } while (false)
1713
1714 #define EXPECT_PRIMITIVE_FIELD(expect_eq, instance, type, field_name, sig, value1, value2) \
1715   do { \
1716     jfieldID fid = env_->GetFieldID(c, field_name, sig); \
1717     EXPECT_NE(fid, nullptr); \
1718     env_->Set ## type ## Field(instance, fid, value1); \
1719     expect_eq(value1, env_->Get ## type ## Field(instance, fid)); \
1720     env_->Set ## type ## Field(instance, fid, value2); \
1721     expect_eq(value2, env_->Get ## type ## Field(instance, fid)); \
1722     \
1723     bool old_check_jni = vm_->SetCheckJniEnabled(false); \
1724     CheckJniAbortCatcher jni_abort_catcher; \
1725     env_->Get ## type ## Field(nullptr, fid); \
1726     jni_abort_catcher.Check("obj == null"); \
1727     env_->Set ## type ## Field(nullptr, fid, value1); \
1728     jni_abort_catcher.Check("obj == null"); \
1729     env_->Get ## type ## Field(instance, nullptr); \
1730     jni_abort_catcher.Check("fid == null"); \
1731     env_->Set ## type ## Field(instance, nullptr, value1); \
1732     jni_abort_catcher.Check("fid == null"); \
1733     EXPECT_FALSE(vm_->SetCheckJniEnabled(true)); \
1734     env_->Get ## type ## Field(nullptr, fid); \
1735     jni_abort_catcher.Check("field operation on NULL object:"); \
1736     env_->Set ## type ## Field(nullptr, fid, value1); \
1737     jni_abort_catcher.Check("field operation on NULL object:"); \
1738     env_->Get ## type ## Field(instance, nullptr); \
1739     jni_abort_catcher.Check("jfieldID was NULL"); \
1740     env_->Set ## type ## Field(instance, nullptr, value1); \
1741     jni_abort_catcher.Check("jfieldID was NULL"); \
1742     EXPECT_TRUE(vm_->SetCheckJniEnabled(old_check_jni)); \
1743   } while (false)
1744
1745
1746 TEST_F(JniInternalTest, GetPrimitiveField_SetPrimitiveField) {
1747   Thread::Current()->TransitionFromSuspendedToRunnable();
1748   LoadDex("AllFields");
1749   bool started = runtime_->Start();
1750   ASSERT_TRUE(started);
1751
1752   jclass c = env_->FindClass("AllFields");
1753   ASSERT_NE(c, nullptr);
1754   jobject o = env_->AllocObject(c);
1755   ASSERT_NE(o, nullptr);
1756
1757   EXPECT_STATIC_PRIMITIVE_FIELD(EXPECT_EQ, Boolean, "sZ", "Z", JNI_TRUE, JNI_FALSE);
1758   EXPECT_STATIC_PRIMITIVE_FIELD(EXPECT_EQ, Byte, "sB", "B", 1, 2);
1759   EXPECT_STATIC_PRIMITIVE_FIELD(EXPECT_EQ, Char, "sC", "C", 'a', 'b');
1760   EXPECT_STATIC_PRIMITIVE_FIELD(EXPECT_DOUBLE_EQ, Double, "sD", "D", 1.0, 2.0);
1761   EXPECT_STATIC_PRIMITIVE_FIELD(EXPECT_FLOAT_EQ, Float, "sF", "F", 1.0, 2.0);
1762   EXPECT_STATIC_PRIMITIVE_FIELD(EXPECT_EQ, Int, "sI", "I", 1, 2);
1763   EXPECT_STATIC_PRIMITIVE_FIELD(EXPECT_EQ, Long, "sJ", "J", 1, 2);
1764   EXPECT_STATIC_PRIMITIVE_FIELD(EXPECT_EQ, Short, "sS", "S", 1, 2);
1765
1766   EXPECT_PRIMITIVE_FIELD(EXPECT_EQ, o, Boolean, "iZ", "Z", JNI_TRUE, JNI_FALSE);
1767   EXPECT_PRIMITIVE_FIELD(EXPECT_EQ, o, Byte, "iB", "B", 1, 2);
1768   EXPECT_PRIMITIVE_FIELD(EXPECT_EQ, o, Char, "iC", "C", 'a', 'b');
1769   EXPECT_PRIMITIVE_FIELD(EXPECT_DOUBLE_EQ, o, Double, "iD", "D", 1.0, 2.0);
1770   EXPECT_PRIMITIVE_FIELD(EXPECT_FLOAT_EQ, o, Float, "iF", "F", 1.0, 2.0);
1771   EXPECT_PRIMITIVE_FIELD(EXPECT_EQ, o, Int, "iI", "I", 1, 2);
1772   EXPECT_PRIMITIVE_FIELD(EXPECT_EQ, o, Long, "iJ", "J", 1, 2);
1773   EXPECT_PRIMITIVE_FIELD(EXPECT_EQ, o, Short, "iS", "S", 1, 2);
1774 }
1775
1776 TEST_F(JniInternalTest, GetObjectField_SetObjectField) {
1777   Thread::Current()->TransitionFromSuspendedToRunnable();
1778   LoadDex("AllFields");
1779   runtime_->Start();
1780
1781   jclass c = env_->FindClass("AllFields");
1782   ASSERT_NE(c, nullptr);
1783   jobject o = env_->AllocObject(c);
1784   ASSERT_NE(o, nullptr);
1785
1786   jstring s1 = env_->NewStringUTF("hello");
1787   ASSERT_NE(s1, nullptr);
1788   jstring s2 = env_->NewStringUTF("world");
1789   ASSERT_NE(s2, nullptr);
1790
1791   jfieldID s_fid = env_->GetStaticFieldID(c, "sObject", "Ljava/lang/Object;");
1792   ASSERT_NE(s_fid, nullptr);
1793   jfieldID i_fid = env_->GetFieldID(c, "iObject", "Ljava/lang/Object;");
1794   ASSERT_NE(i_fid, nullptr);
1795
1796   env_->SetStaticObjectField(c, s_fid, s1);
1797   ASSERT_TRUE(env_->IsSameObject(s1, env_->GetStaticObjectField(c, s_fid)));
1798   env_->SetStaticObjectField(c, s_fid, s2);
1799   ASSERT_TRUE(env_->IsSameObject(s2, env_->GetStaticObjectField(c, s_fid)));
1800
1801   env_->SetObjectField(o, i_fid, s1);
1802   ASSERT_TRUE(env_->IsSameObject(s1, env_->GetObjectField(o, i_fid)));
1803   env_->SetObjectField(o, i_fid, s2);
1804   ASSERT_TRUE(env_->IsSameObject(s2, env_->GetObjectField(o, i_fid)));
1805 }
1806
1807 TEST_F(JniInternalTest, NewLocalRef_nullptr) {
1808   EXPECT_EQ(env_->NewLocalRef(nullptr), nullptr);
1809 }
1810
1811 TEST_F(JniInternalTest, NewLocalRef) {
1812   jstring s = env_->NewStringUTF("");
1813   ASSERT_NE(s, nullptr);
1814   jobject o = env_->NewLocalRef(s);
1815   EXPECT_NE(o, nullptr);
1816   EXPECT_NE(o, s);
1817
1818   EXPECT_EQ(JNILocalRefType, env_->GetObjectRefType(o));
1819 }
1820
1821 TEST_F(JniInternalTest, DeleteLocalRef_nullptr) {
1822   env_->DeleteLocalRef(nullptr);
1823 }
1824
1825 TEST_F(JniInternalTest, DeleteLocalRef) {
1826   // This tests leads to warnings and errors in the log.
1827   ScopedLogSeverity sls(LogSeverity::FATAL);
1828
1829   jstring s = env_->NewStringUTF("");
1830   ASSERT_NE(s, nullptr);
1831   env_->DeleteLocalRef(s);
1832
1833   // Currently, deleting an already-deleted reference is just a CheckJNI warning.
1834   {
1835     bool old_check_jni = vm_->SetCheckJniEnabled(false);
1836     {
1837       CheckJniAbortCatcher check_jni_abort_catcher;
1838       env_->DeleteLocalRef(s);
1839     }
1840     CheckJniAbortCatcher check_jni_abort_catcher;
1841     EXPECT_FALSE(vm_->SetCheckJniEnabled(true));
1842     env_->DeleteLocalRef(s);
1843     std::string expected(StringPrintf("use of deleted local reference %p", s));
1844     check_jni_abort_catcher.Check(expected.c_str());
1845     EXPECT_TRUE(vm_->SetCheckJniEnabled(old_check_jni));
1846   }
1847
1848   s = env_->NewStringUTF("");
1849   ASSERT_NE(s, nullptr);
1850   jobject o = env_->NewLocalRef(s);
1851   ASSERT_NE(o, nullptr);
1852
1853   env_->DeleteLocalRef(s);
1854   env_->DeleteLocalRef(o);
1855 }
1856
1857 TEST_F(JniInternalTest, PushLocalFrame_10395422) {
1858   // The JNI specification is ambiguous about whether the given capacity is to be interpreted as a
1859   // maximum or as a minimum, but it seems like it's supposed to be a minimum, and that's how
1860   // Android historically treated it, and it's how the RI treats it. It's also the more useful
1861   // interpretation!
1862   ASSERT_EQ(JNI_OK, env_->PushLocalFrame(0));
1863   env_->PopLocalFrame(nullptr);
1864
1865   // The following two tests will print errors to the log.
1866   ScopedLogSeverity sls(LogSeverity::FATAL);
1867
1868   // Negative capacities are not allowed.
1869   ASSERT_EQ(JNI_ERR, env_->PushLocalFrame(-1));
1870
1871   // And it's okay to have an upper limit. Ours is currently 512.
1872   ASSERT_EQ(JNI_ERR, env_->PushLocalFrame(8192));
1873 }
1874
1875 TEST_F(JniInternalTest, PushLocalFrame_PopLocalFrame) {
1876   // This tests leads to errors in the log.
1877   ScopedLogSeverity sls(LogSeverity::FATAL);
1878
1879   jobject original = env_->NewStringUTF("");
1880   ASSERT_NE(original, nullptr);
1881
1882   jobject outer;
1883   jobject inner1, inner2;
1884   ScopedObjectAccess soa(env_);
1885   {
1886     ASSERT_EQ(JNI_OK, env_->PushLocalFrame(4));
1887     outer = env_->NewLocalRef(original);
1888
1889     {
1890       ASSERT_EQ(JNI_OK, env_->PushLocalFrame(4));
1891       inner1 = env_->NewLocalRef(outer);
1892       inner2 = env_->NewStringUTF("survivor");
1893       EXPECT_NE(env_->PopLocalFrame(inner2), nullptr);
1894     }
1895
1896     EXPECT_EQ(JNILocalRefType, env_->GetObjectRefType(original));
1897     EXPECT_EQ(JNILocalRefType, env_->GetObjectRefType(outer));
1898     {
1899       CheckJniAbortCatcher check_jni_abort_catcher;
1900       EXPECT_EQ(JNIInvalidRefType, env_->GetObjectRefType(inner1));
1901       check_jni_abort_catcher.Check("use of deleted local reference");
1902     }
1903
1904     // Our local reference for the survivor is invalid because the survivor
1905     // gets a new local reference...
1906     {
1907       CheckJniAbortCatcher check_jni_abort_catcher;
1908       EXPECT_EQ(JNIInvalidRefType, env_->GetObjectRefType(inner2));
1909       check_jni_abort_catcher.Check("use of deleted local reference");
1910     }
1911
1912     EXPECT_EQ(env_->PopLocalFrame(nullptr), nullptr);
1913   }
1914   EXPECT_EQ(JNILocalRefType, env_->GetObjectRefType(original));
1915   CheckJniAbortCatcher check_jni_abort_catcher;
1916   EXPECT_EQ(JNIInvalidRefType, env_->GetObjectRefType(outer));
1917   check_jni_abort_catcher.Check("use of deleted local reference");
1918   EXPECT_EQ(JNIInvalidRefType, env_->GetObjectRefType(inner1));
1919   check_jni_abort_catcher.Check("use of deleted local reference");
1920   EXPECT_EQ(JNIInvalidRefType, env_->GetObjectRefType(inner2));
1921   check_jni_abort_catcher.Check("use of deleted local reference");
1922 }
1923
1924 TEST_F(JniInternalTest, NewGlobalRef_nullptr) {
1925   EXPECT_EQ(env_->NewGlobalRef(nullptr), nullptr);
1926 }
1927
1928 TEST_F(JniInternalTest, NewGlobalRef) {
1929   jstring s = env_->NewStringUTF("");
1930   ASSERT_NE(s, nullptr);
1931   jobject o = env_->NewGlobalRef(s);
1932   EXPECT_NE(o, nullptr);
1933   EXPECT_NE(o, s);
1934
1935   EXPECT_EQ(env_->GetObjectRefType(o), JNIGlobalRefType);
1936 }
1937
1938 TEST_F(JniInternalTest, DeleteGlobalRef_nullptr) {
1939   env_->DeleteGlobalRef(nullptr);
1940 }
1941
1942 TEST_F(JniInternalTest, DeleteGlobalRef) {
1943   // This tests leads to warnings and errors in the log.
1944   ScopedLogSeverity sls(LogSeverity::FATAL);
1945
1946   jstring s = env_->NewStringUTF("");
1947   ASSERT_NE(s, nullptr);
1948
1949   jobject o = env_->NewGlobalRef(s);
1950   ASSERT_NE(o, nullptr);
1951   env_->DeleteGlobalRef(o);
1952
1953   // Currently, deleting an already-deleted reference is just a CheckJNI warning.
1954   {
1955     bool old_check_jni = vm_->SetCheckJniEnabled(false);
1956     {
1957       CheckJniAbortCatcher check_jni_abort_catcher;
1958       env_->DeleteGlobalRef(o);
1959     }
1960     CheckJniAbortCatcher check_jni_abort_catcher;
1961     EXPECT_FALSE(vm_->SetCheckJniEnabled(true));
1962     env_->DeleteGlobalRef(o);
1963     std::string expected(StringPrintf("use of deleted global reference %p", o));
1964     check_jni_abort_catcher.Check(expected.c_str());
1965     EXPECT_TRUE(vm_->SetCheckJniEnabled(old_check_jni));
1966   }
1967
1968   jobject o1 = env_->NewGlobalRef(s);
1969   ASSERT_NE(o1, nullptr);
1970   jobject o2 = env_->NewGlobalRef(s);
1971   ASSERT_NE(o2, nullptr);
1972
1973   env_->DeleteGlobalRef(o1);
1974   env_->DeleteGlobalRef(o2);
1975 }
1976
1977 TEST_F(JniInternalTest, NewWeakGlobalRef_nullptr) {
1978   EXPECT_EQ(env_->NewWeakGlobalRef(nullptr),   nullptr);
1979 }
1980
1981 TEST_F(JniInternalTest, NewWeakGlobalRef) {
1982   jstring s = env_->NewStringUTF("");
1983   ASSERT_NE(s, nullptr);
1984   jobject o = env_->NewWeakGlobalRef(s);
1985   EXPECT_NE(o, nullptr);
1986   EXPECT_NE(o, s);
1987
1988   EXPECT_EQ(env_->GetObjectRefType(o), JNIWeakGlobalRefType);
1989 }
1990
1991 TEST_F(JniInternalTest, DeleteWeakGlobalRef_nullptr) {
1992   env_->DeleteWeakGlobalRef(nullptr);
1993 }
1994
1995 TEST_F(JniInternalTest, DeleteWeakGlobalRef) {
1996   // This tests leads to warnings and errors in the log.
1997   ScopedLogSeverity sls(LogSeverity::FATAL);
1998
1999   jstring s = env_->NewStringUTF("");
2000   ASSERT_NE(s, nullptr);
2001
2002   jobject o = env_->NewWeakGlobalRef(s);
2003   ASSERT_NE(o, nullptr);
2004   env_->DeleteWeakGlobalRef(o);
2005
2006   // Currently, deleting an already-deleted reference is just a CheckJNI warning.
2007   {
2008     bool old_check_jni = vm_->SetCheckJniEnabled(false);
2009     {
2010       CheckJniAbortCatcher check_jni_abort_catcher;
2011       env_->DeleteWeakGlobalRef(o);
2012     }
2013     CheckJniAbortCatcher check_jni_abort_catcher;
2014     EXPECT_FALSE(vm_->SetCheckJniEnabled(true));
2015     env_->DeleteWeakGlobalRef(o);
2016     std::string expected(StringPrintf("use of deleted weak global reference %p", o));
2017     check_jni_abort_catcher.Check(expected.c_str());
2018     EXPECT_TRUE(vm_->SetCheckJniEnabled(old_check_jni));
2019   }
2020
2021   jobject o1 = env_->NewWeakGlobalRef(s);
2022   ASSERT_NE(o1, nullptr);
2023   jobject o2 = env_->NewWeakGlobalRef(s);
2024   ASSERT_NE(o2, nullptr);
2025
2026   env_->DeleteWeakGlobalRef(o1);
2027   env_->DeleteWeakGlobalRef(o2);
2028 }
2029
2030 TEST_F(JniInternalTest, ExceptionDescribe) {
2031   // This checks how ExceptionDescribe handles call without exception.
2032   env_->ExceptionClear();
2033   env_->ExceptionDescribe();
2034 }
2035
2036 TEST_F(JniInternalTest, Throw) {
2037   jclass exception_class = env_->FindClass("java/lang/RuntimeException");
2038   ASSERT_TRUE(exception_class != nullptr);
2039   jthrowable exception = reinterpret_cast<jthrowable>(env_->AllocObject(exception_class));
2040   ASSERT_TRUE(exception != nullptr);
2041
2042   EXPECT_EQ(JNI_OK, env_->Throw(exception));
2043   EXPECT_TRUE(env_->ExceptionCheck());
2044   jthrowable thrown_exception = env_->ExceptionOccurred();
2045   env_->ExceptionClear();
2046   EXPECT_TRUE(env_->IsSameObject(exception, thrown_exception));
2047
2048   // Bad argument.
2049   bool old_check_jni = vm_->SetCheckJniEnabled(false);
2050   EXPECT_EQ(JNI_ERR, env_->Throw(nullptr));
2051   EXPECT_FALSE(vm_->SetCheckJniEnabled(true));
2052   CheckJniAbortCatcher check_jni_abort_catcher;
2053   EXPECT_EQ(JNI_ERR, env_->Throw(nullptr));
2054   check_jni_abort_catcher.Check("Throw received NULL jthrowable");
2055   EXPECT_TRUE(vm_->SetCheckJniEnabled(old_check_jni));
2056 }
2057
2058 TEST_F(JniInternalTest, ThrowNew) {
2059   jclass exception_class = env_->FindClass("java/lang/RuntimeException");
2060   ASSERT_TRUE(exception_class != nullptr);
2061
2062   jthrowable thrown_exception;
2063
2064   EXPECT_EQ(JNI_OK, env_->ThrowNew(exception_class, "hello world"));
2065   EXPECT_TRUE(env_->ExceptionCheck());
2066   thrown_exception = env_->ExceptionOccurred();
2067   env_->ExceptionClear();
2068   EXPECT_TRUE(env_->IsInstanceOf(thrown_exception, exception_class));
2069
2070   EXPECT_EQ(JNI_OK, env_->ThrowNew(exception_class, nullptr));
2071   EXPECT_TRUE(env_->ExceptionCheck());
2072   thrown_exception = env_->ExceptionOccurred();
2073   env_->ExceptionClear();
2074   EXPECT_TRUE(env_->IsInstanceOf(thrown_exception, exception_class));
2075
2076   // Bad argument.
2077   bool old_check_jni = vm_->SetCheckJniEnabled(false);
2078   CheckJniAbortCatcher check_jni_abort_catcher;
2079   EXPECT_EQ(JNI_ERR, env_->ThrowNew(nullptr, nullptr));
2080   check_jni_abort_catcher.Check("c == null");
2081   EXPECT_FALSE(vm_->SetCheckJniEnabled(true));
2082   EXPECT_EQ(JNI_ERR, env_->ThrowNew(nullptr, nullptr));
2083   check_jni_abort_catcher.Check("ThrowNew received NULL jclass");
2084   EXPECT_TRUE(vm_->SetCheckJniEnabled(old_check_jni));
2085 }
2086
2087 TEST_F(JniInternalTest, NewDirectBuffer_GetDirectBufferAddress_GetDirectBufferCapacity) {
2088   // Start runtime.
2089   Thread* self = Thread::Current();
2090   self->TransitionFromSuspendedToRunnable();
2091   MakeExecutable(nullptr, "java.lang.Class");
2092   MakeExecutable(nullptr, "java.lang.Object");
2093   MakeExecutable(nullptr, "java.nio.DirectByteBuffer");
2094   MakeExecutable(nullptr, "java.nio.Bits");
2095   MakeExecutable(nullptr, "java.nio.MappedByteBuffer");
2096   MakeExecutable(nullptr, "java.nio.ByteBuffer");
2097   MakeExecutable(nullptr, "java.nio.Buffer");
2098   // TODO: we only load a dex file here as starting the runtime relies upon it.
2099   const char* class_name = "StaticLeafMethods";
2100   LoadDex(class_name);
2101   bool started = runtime_->Start();
2102   ASSERT_TRUE(started);
2103
2104   jclass buffer_class = env_->FindClass("java/nio/Buffer");
2105   ASSERT_NE(buffer_class, nullptr);
2106
2107   char bytes[1024];
2108   jobject buffer = env_->NewDirectByteBuffer(bytes, sizeof(bytes));
2109   ASSERT_NE(buffer, nullptr);
2110   ASSERT_TRUE(env_->IsInstanceOf(buffer, buffer_class));
2111   ASSERT_EQ(env_->GetDirectBufferAddress(buffer), bytes);
2112   ASSERT_EQ(env_->GetDirectBufferCapacity(buffer), static_cast<jlong>(sizeof(bytes)));
2113
2114   {
2115     CheckJniAbortCatcher check_jni_abort_catcher;
2116     env_->NewDirectByteBuffer(bytes, static_cast<jlong>(INT_MAX) + 1);
2117     check_jni_abort_catcher.Check("in call to NewDirectByteBuffer");
2118   }
2119 }
2120
2121 TEST_F(JniInternalTest, MonitorEnterExit) {
2122   // This will print some error messages. Suppress.
2123   ScopedLogSeverity sls(LogSeverity::FATAL);
2124
2125   // Create an object to torture.
2126   jclass object_class = env_->FindClass("java/lang/Object");
2127   ASSERT_NE(object_class, nullptr);
2128   jobject object = env_->AllocObject(object_class);
2129   ASSERT_NE(object, nullptr);
2130
2131   // Expected class of exceptions
2132   jclass imse_class = env_->FindClass("java/lang/IllegalMonitorStateException");
2133   ASSERT_NE(imse_class, nullptr);
2134
2135   jthrowable thrown_exception;
2136
2137   // Unlock of unowned monitor
2138   env_->MonitorExit(object);
2139   EXPECT_TRUE(env_->ExceptionCheck());
2140   thrown_exception = env_->ExceptionOccurred();
2141   env_->ExceptionClear();
2142   EXPECT_TRUE(env_->IsInstanceOf(thrown_exception, imse_class));
2143
2144   // Lock of unowned monitor
2145   env_->MonitorEnter(object);
2146   EXPECT_FALSE(env_->ExceptionCheck());
2147   // Regular unlock
2148   env_->MonitorExit(object);
2149   EXPECT_FALSE(env_->ExceptionCheck());
2150
2151   // Recursively lock a lot
2152   size_t max_recursive_lock = 1024;
2153   for (size_t i = 0; i < max_recursive_lock; i++) {
2154     env_->MonitorEnter(object);
2155     EXPECT_FALSE(env_->ExceptionCheck());
2156   }
2157   // Recursively unlock a lot
2158   for (size_t i = 0; i < max_recursive_lock; i++) {
2159     env_->MonitorExit(object);
2160     EXPECT_FALSE(env_->ExceptionCheck());
2161   }
2162
2163   // Unlock of unowned monitor
2164   env_->MonitorExit(object);
2165   EXPECT_TRUE(env_->ExceptionCheck());
2166   thrown_exception = env_->ExceptionOccurred();
2167   env_->ExceptionClear();
2168   EXPECT_TRUE(env_->IsInstanceOf(thrown_exception, imse_class));
2169
2170   // It's an error to call MonitorEnter or MonitorExit on null.
2171   {
2172     CheckJniAbortCatcher check_jni_abort_catcher;
2173     env_->MonitorEnter(nullptr);
2174     check_jni_abort_catcher.Check("in call to MonitorEnter");
2175     env_->MonitorExit(nullptr);
2176     check_jni_abort_catcher.Check("in call to MonitorExit");
2177   }
2178 }
2179
2180 void Java_MyClassNatives_foo_exit(JNIEnv* env, jobject thisObj) {
2181   // Release the monitor on self. This should trigger an abort.
2182   env->MonitorExit(thisObj);
2183 }
2184
2185 TEST_F(JniInternalTest, MonitorExitLockedInDifferentCall) {
2186   SetUpForTest(false, "foo", "()V", reinterpret_cast<void*>(&Java_MyClassNatives_foo_exit));
2187   ASSERT_NE(jobj_, nullptr);
2188
2189   env_->MonitorEnter(jobj_);
2190   EXPECT_FALSE(env_->ExceptionCheck());
2191
2192   CheckJniAbortCatcher check_jni_abort_catcher;
2193   env_->CallNonvirtualVoidMethod(jobj_, jklass_, jmethod_);
2194   check_jni_abort_catcher.Check("Unlocking monitor that wasn't locked here");
2195 }
2196
2197 void Java_MyClassNatives_foo_enter_no_exit(JNIEnv* env, jobject thisObj) {
2198   // Acquire but don't release the monitor on self. This should trigger an abort on return.
2199   env->MonitorEnter(thisObj);
2200 }
2201
2202 TEST_F(JniInternalTest, MonitorExitNotAllUnlocked) {
2203   SetUpForTest(false,
2204                "foo",
2205                "()V",
2206                reinterpret_cast<void*>(&Java_MyClassNatives_foo_enter_no_exit));
2207   ASSERT_NE(jobj_, nullptr);
2208
2209   CheckJniAbortCatcher check_jni_abort_catcher;
2210   env_->CallNonvirtualVoidMethod(jobj_, jklass_, jmethod_);
2211   check_jni_abort_catcher.Check("Still holding a locked object on JNI end");
2212 }
2213
2214 static bool IsLocked(JNIEnv* env, jobject jobj) {
2215   ScopedObjectAccess soa(env);
2216   LockWord lock_word = soa.Decode<mirror::Object*>(jobj)->GetLockWord(true);
2217   switch (lock_word.GetState()) {
2218     case LockWord::kHashCode:
2219     case LockWord::kUnlocked:
2220       return false;
2221     case LockWord::kThinLocked:
2222       return true;
2223     case LockWord::kFatLocked:
2224       return lock_word.FatLockMonitor()->IsLocked();
2225     default: {
2226       LOG(FATAL) << "Invalid monitor state " << lock_word.GetState();
2227       UNREACHABLE();
2228     }
2229   }
2230 }
2231
2232 TEST_F(JniInternalTest, DetachThreadUnlockJNIMonitors) {
2233   // We need to lock an object, detach, reattach, and check the locks.
2234   //
2235   // As re-attaching will create a different thread, we need to use a global
2236   // ref to keep the object around.
2237
2238   // Create an object to torture.
2239   jobject global_ref;
2240   {
2241     jclass object_class = env_->FindClass("java/lang/Object");
2242     ASSERT_NE(object_class, nullptr);
2243     jobject object = env_->AllocObject(object_class);
2244     ASSERT_NE(object, nullptr);
2245     global_ref = env_->NewGlobalRef(object);
2246   }
2247
2248   // Lock it.
2249   env_->MonitorEnter(global_ref);
2250   ASSERT_TRUE(IsLocked(env_, global_ref));
2251
2252   // Detach and re-attach.
2253   jint detach_result = vm_->DetachCurrentThread();
2254   ASSERT_EQ(detach_result, JNI_OK);
2255   jint attach_result = vm_->AttachCurrentThread(&env_, nullptr);
2256   ASSERT_EQ(attach_result, JNI_OK);
2257
2258   // Look at the global ref, check whether it's still locked.
2259   ASSERT_FALSE(IsLocked(env_, global_ref));
2260
2261   // Delete the global ref.
2262   env_->DeleteGlobalRef(global_ref);
2263 }
2264
2265 // Test the offset computation of IndirectReferenceTable offsets. b/26071368.
2266 TEST_F(JniInternalTest, IndirectReferenceTableOffsets) {
2267   // The segment_state_ field is private, and we want to avoid friend declaration. So we'll check
2268   // by modifying memory.
2269   // The parameters don't really matter here.
2270   IndirectReferenceTable irt(5, 5, IndirectRefKind::kGlobal, true);
2271   uint32_t old_state = irt.GetSegmentState();
2272
2273   // Write some new state directly. We invert parts of old_state to ensure a new value.
2274   uint32_t new_state = old_state ^ 0x07705005;
2275   ASSERT_NE(old_state, new_state);
2276
2277   uint8_t* base = reinterpret_cast<uint8_t*>(&irt);
2278   int32_t segment_state_offset =
2279       IndirectReferenceTable::SegmentStateOffset(sizeof(void*)).Int32Value();
2280   *reinterpret_cast<uint32_t*>(base + segment_state_offset) = new_state;
2281
2282   // Read and compare.
2283   EXPECT_EQ(new_state, irt.GetSegmentState());
2284 }
2285
2286 // Test the offset computation of JNIEnvExt offsets. b/26071368.
2287 TEST_F(JniInternalTest, JNIEnvExtOffsets) {
2288   EXPECT_EQ(OFFSETOF_MEMBER(JNIEnvExt, local_ref_cookie),
2289             JNIEnvExt::LocalRefCookieOffset(sizeof(void*)).Uint32Value());
2290
2291   EXPECT_EQ(OFFSETOF_MEMBER(JNIEnvExt, self), JNIEnvExt::SelfOffset(sizeof(void*)).Uint32Value());
2292
2293   // segment_state_ is private in the IndirectReferenceTable. So this test isn't as good as we'd
2294   // hope it to be.
2295   uint32_t segment_state_now =
2296       OFFSETOF_MEMBER(JNIEnvExt, locals) +
2297       IndirectReferenceTable::SegmentStateOffset(sizeof(void*)).Uint32Value();
2298   uint32_t segment_state_computed = JNIEnvExt::SegmentStateOffset(sizeof(void*)).Uint32Value();
2299   EXPECT_EQ(segment_state_now, segment_state_computed);
2300 }
2301
2302 }  // namespace art