• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 <limits.h>
20 #include <cfloat>
21 #include <cmath>
22 
23 #include "common_test.h"
24 #include "invoke_arg_array_builder.h"
25 #include "mirror/art_method-inl.h"
26 #include "mirror/class-inl.h"
27 #include "mirror/object_array-inl.h"
28 #include "mirror/object-inl.h"
29 #include "ScopedLocalRef.h"
30 #include "sirt_ref.h"
31 
32 namespace art {
33 
34 class JniInternalTest : public CommonTest {
35  protected:
SetUp()36   virtual void SetUp() {
37     CommonTest::SetUp();
38 
39     vm_ = Runtime::Current()->GetJavaVM();
40 
41     // Turn on -verbose:jni for the JNI tests.
42     // gLogVerbosity.jni = true;
43 
44     vm_->AttachCurrentThread(&env_, NULL);
45 
46     ScopedLocalRef<jclass> aioobe(env_,
47                                   env_->FindClass("java/lang/ArrayIndexOutOfBoundsException"));
48     CHECK(aioobe.get() != NULL);
49     aioobe_ = reinterpret_cast<jclass>(env_->NewGlobalRef(aioobe.get()));
50 
51     ScopedLocalRef<jclass> ase(env_, env_->FindClass("java/lang/ArrayStoreException"));
52     CHECK(ase.get() != NULL);
53     ase_ = reinterpret_cast<jclass>(env_->NewGlobalRef(ase.get()));
54 
55     ScopedLocalRef<jclass> sioobe(env_,
56                                   env_->FindClass("java/lang/StringIndexOutOfBoundsException"));
57     CHECK(sioobe.get() != NULL);
58     sioobe_ = reinterpret_cast<jclass>(env_->NewGlobalRef(sioobe.get()));
59   }
60 
CleanUpJniEnv()61   void CleanUpJniEnv() {
62     if (aioobe_ != NULL) {
63       env_->DeleteGlobalRef(aioobe_);
64       aioobe_ = NULL;
65     }
66     if (ase_ != NULL) {
67       env_->DeleteGlobalRef(ase_);
68       ase_ = NULL;
69     }
70     if (sioobe_ != NULL) {
71       env_->DeleteGlobalRef(sioobe_);
72       sioobe_ = NULL;
73     }
74   }
75 
TearDown()76   virtual void TearDown() {
77     CleanUpJniEnv();
78     CommonTest::TearDown();
79   }
80 
DoCompile(mirror::ArtMethod * & method,mirror::Object * & receiver,bool is_static,const char * method_name,const char * method_signature)81   void DoCompile(mirror::ArtMethod*& method,
82                  mirror::Object*& receiver,
83                  bool is_static, const char* method_name,
84                  const char* method_signature)
85       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
86     const char* class_name = is_static ? "StaticLeafMethods" : "NonStaticLeafMethods";
87     jobject jclass_loader(LoadDex(class_name));
88     Thread* self = Thread::Current();
89     SirtRef<mirror::ClassLoader>
90         class_loader(self,
91                      ScopedObjectAccessUnchecked(self).Decode<mirror::ClassLoader*>(jclass_loader));
92     if (is_static) {
93       CompileDirectMethod(class_loader.get(), class_name, method_name, method_signature);
94     } else {
95       CompileVirtualMethod(NULL, "java.lang.Class", "isFinalizable", "()Z");
96       CompileDirectMethod(NULL, "java.lang.Object", "<init>", "()V");
97       CompileVirtualMethod(class_loader.get(), class_name, method_name, method_signature);
98     }
99 
100     mirror::Class* c = class_linker_->FindClass(DotToDescriptor(class_name).c_str(),
101                                                 class_loader.get());
102     CHECK(c != NULL);
103 
104     method = is_static ? c->FindDirectMethod(method_name, method_signature)
105                        : c->FindVirtualMethod(method_name, method_signature);
106     CHECK(method != NULL);
107 
108     receiver = (is_static ? NULL : c->AllocObject(self));
109 
110     // Start runtime.
111     bool started = runtime_->Start();
112     CHECK(started);
113     self->TransitionFromSuspendedToRunnable();
114   }
115 
InvokeNopMethod(bool is_static)116   void InvokeNopMethod(bool is_static) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
117     mirror::ArtMethod* method;
118     mirror::Object* receiver;
119     DoCompile(method, receiver, is_static, "nop", "()V");
120 
121     ArgArray arg_array(NULL, 0);
122     JValue result;
123 
124     if (!is_static) {
125       arg_array.Append(reinterpret_cast<uint32_t>(receiver));
126     }
127 
128     method->Invoke(Thread::Current(), arg_array.GetArray(), arg_array.GetNumBytes(), &result, 'V');
129   }
130 
InvokeIdentityByteMethod(bool is_static)131   void InvokeIdentityByteMethod(bool is_static)
132       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
133     mirror::ArtMethod* method;
134     mirror::Object* receiver;
135     DoCompile(method, receiver, is_static, "identity", "(I)I");
136 
137     ArgArray arg_array(NULL, 0);
138     uint32_t* args = arg_array.GetArray();
139     JValue result;
140 
141     if (!is_static) {
142       arg_array.Append(reinterpret_cast<uint32_t>(receiver));
143       args++;
144     }
145 
146     arg_array.Append(0);
147     result.SetB(-1);
148     method->Invoke(Thread::Current(), arg_array.GetArray(), arg_array.GetNumBytes(), &result, 'B');
149     EXPECT_EQ(0, result.GetB());
150 
151     args[0] = -1;
152     result.SetB(0);
153     method->Invoke(Thread::Current(), arg_array.GetArray(), arg_array.GetNumBytes(), &result, 'B');
154     EXPECT_EQ(-1, result.GetB());
155 
156     args[0] = SCHAR_MAX;
157     result.SetB(0);
158     method->Invoke(Thread::Current(), arg_array.GetArray(), arg_array.GetNumBytes(), &result, 'B');
159     EXPECT_EQ(SCHAR_MAX, result.GetB());
160 
161     args[0] = (SCHAR_MIN << 24) >> 24;
162     result.SetB(0);
163     method->Invoke(Thread::Current(), arg_array.GetArray(), arg_array.GetNumBytes(), &result, 'B');
164     EXPECT_EQ(SCHAR_MIN, result.GetB());
165   }
166 
InvokeIdentityIntMethod(bool is_static)167   void InvokeIdentityIntMethod(bool is_static)
168       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
169     mirror::ArtMethod* method;
170     mirror::Object* receiver;
171     DoCompile(method, receiver, is_static, "identity", "(I)I");
172 
173     ArgArray arg_array(NULL, 0);
174     uint32_t* args = arg_array.GetArray();
175     JValue result;
176 
177     if (!is_static) {
178       arg_array.Append(reinterpret_cast<uint32_t>(receiver));
179       args++;
180     }
181 
182     arg_array.Append(0);
183     result.SetI(-1);
184     method->Invoke(Thread::Current(), arg_array.GetArray(), arg_array.GetNumBytes(), &result, 'I');
185     EXPECT_EQ(0, result.GetI());
186 
187     args[0] = -1;
188     result.SetI(0);
189     method->Invoke(Thread::Current(), arg_array.GetArray(), arg_array.GetNumBytes(), &result, 'I');
190     EXPECT_EQ(-1, result.GetI());
191 
192     args[0] = INT_MAX;
193     result.SetI(0);
194     method->Invoke(Thread::Current(), arg_array.GetArray(), arg_array.GetNumBytes(), &result, 'I');
195     EXPECT_EQ(INT_MAX, result.GetI());
196 
197     args[0] = INT_MIN;
198     result.SetI(0);
199     method->Invoke(Thread::Current(), arg_array.GetArray(), arg_array.GetNumBytes(), &result, 'I');
200     EXPECT_EQ(INT_MIN, result.GetI());
201   }
202 
InvokeIdentityDoubleMethod(bool is_static)203   void InvokeIdentityDoubleMethod(bool is_static)
204       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
205     mirror::ArtMethod* method;
206     mirror::Object* receiver;
207     DoCompile(method, receiver, is_static, "identity", "(D)D");
208 
209     ArgArray arg_array(NULL, 0);
210     uint32_t* args = arg_array.GetArray();
211     JValue value;
212     JValue result;
213 
214     if (!is_static) {
215       arg_array.Append(reinterpret_cast<uint32_t>(receiver));
216       args++;
217     }
218 
219     value.SetD(0.0);
220     arg_array.AppendWide(value.GetJ());
221     result.SetD(-1.0);
222     method->Invoke(Thread::Current(), arg_array.GetArray(), arg_array.GetNumBytes(), &result, 'D');
223     EXPECT_EQ(0.0, result.GetD());
224 
225     value.SetD(-1.0);
226     args[0] = value.GetJ();
227     args[1] = value.GetJ() >> 32;
228     result.SetD(0.0);
229     method->Invoke(Thread::Current(), arg_array.GetArray(), arg_array.GetNumBytes(), &result, 'D');
230     EXPECT_EQ(-1.0, result.GetD());
231 
232     value.SetD(DBL_MAX);
233     args[0] = value.GetJ();
234     args[1] = value.GetJ() >> 32;
235     result.SetD(0.0);
236     method->Invoke(Thread::Current(), arg_array.GetArray(), arg_array.GetNumBytes(), &result, 'D');
237     EXPECT_EQ(DBL_MAX, result.GetD());
238 
239     value.SetD(DBL_MIN);
240     args[0] = value.GetJ();
241     args[1] = value.GetJ() >> 32;
242     result.SetD(0.0);
243     method->Invoke(Thread::Current(), arg_array.GetArray(), arg_array.GetNumBytes(), &result, 'D');
244     EXPECT_EQ(DBL_MIN, result.GetD());
245   }
246 
InvokeSumIntIntMethod(bool is_static)247   void InvokeSumIntIntMethod(bool is_static)
248       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
249     mirror::ArtMethod* method;
250     mirror::Object* receiver;
251     DoCompile(method, receiver, is_static, "sum", "(II)I");
252 
253     ArgArray arg_array(NULL, 0);
254     uint32_t* args = arg_array.GetArray();
255     JValue result;
256 
257     if (!is_static) {
258       arg_array.Append(reinterpret_cast<uint32_t>(receiver));
259       args++;
260     }
261 
262     arg_array.Append(0);
263     arg_array.Append(0);
264     result.SetI(-1);
265     method->Invoke(Thread::Current(), arg_array.GetArray(), arg_array.GetNumBytes(), &result, 'I');
266     EXPECT_EQ(0, result.GetI());
267 
268     args[0] = 1;
269     args[1] = 2;
270     result.SetI(0);
271     method->Invoke(Thread::Current(), arg_array.GetArray(), arg_array.GetNumBytes(), &result, 'I');
272     EXPECT_EQ(3, result.GetI());
273 
274     args[0] = -2;
275     args[1] = 5;
276     result.SetI(0);
277     method->Invoke(Thread::Current(), arg_array.GetArray(), arg_array.GetNumBytes(), &result, 'I');
278     EXPECT_EQ(3, result.GetI());
279 
280     args[0] = INT_MAX;
281     args[1] = INT_MIN;
282     result.SetI(1234);
283     method->Invoke(Thread::Current(), arg_array.GetArray(), arg_array.GetNumBytes(), &result, 'I');
284     EXPECT_EQ(-1, result.GetI());
285 
286     args[0] = INT_MAX;
287     args[1] = INT_MAX;
288     result.SetI(INT_MIN);
289     method->Invoke(Thread::Current(), arg_array.GetArray(), arg_array.GetNumBytes(), &result, 'I');
290     EXPECT_EQ(-2, result.GetI());
291   }
292 
InvokeSumIntIntIntMethod(bool is_static)293   void InvokeSumIntIntIntMethod(bool is_static)
294       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
295     mirror::ArtMethod* method;
296     mirror::Object* receiver;
297     DoCompile(method, receiver, is_static, "sum", "(III)I");
298 
299     ArgArray arg_array(NULL, 0);
300     uint32_t* args = arg_array.GetArray();
301     JValue result;
302 
303     if (!is_static) {
304       arg_array.Append(reinterpret_cast<uint32_t>(receiver));
305       args++;
306     }
307 
308     arg_array.Append(0);
309     arg_array.Append(0);
310     arg_array.Append(0);
311     result.SetI(-1);
312     method->Invoke(Thread::Current(), arg_array.GetArray(), arg_array.GetNumBytes(), &result, 'I');
313     EXPECT_EQ(0, result.GetI());
314 
315     args[0] = 1;
316     args[1] = 2;
317     args[2] = 3;
318     result.SetI(0);
319     method->Invoke(Thread::Current(), arg_array.GetArray(), arg_array.GetNumBytes(), &result, 'I');
320     EXPECT_EQ(6, result.GetI());
321 
322     args[0] = -1;
323     args[1] = 2;
324     args[2] = -3;
325     result.SetI(0);
326     method->Invoke(Thread::Current(), arg_array.GetArray(), arg_array.GetNumBytes(), &result, 'I');
327     EXPECT_EQ(-2, result.GetI());
328 
329     args[0] = INT_MAX;
330     args[1] = INT_MIN;
331     args[2] = INT_MAX;
332     result.SetI(1234);
333     method->Invoke(Thread::Current(), arg_array.GetArray(), arg_array.GetNumBytes(), &result, 'I');
334     EXPECT_EQ(2147483646, result.GetI());
335 
336     args[0] = INT_MAX;
337     args[1] = INT_MAX;
338     args[2] = INT_MAX;
339     result.SetI(INT_MIN);
340     method->Invoke(Thread::Current(), arg_array.GetArray(), arg_array.GetNumBytes(), &result, 'I');
341     EXPECT_EQ(2147483645, result.GetI());
342   }
343 
InvokeSumIntIntIntIntMethod(bool is_static)344   void InvokeSumIntIntIntIntMethod(bool is_static)
345       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
346     mirror::ArtMethod* method;
347     mirror::Object* receiver;
348     DoCompile(method, receiver, is_static, "sum", "(IIII)I");
349 
350     ArgArray arg_array(NULL, 0);
351     uint32_t* args = arg_array.GetArray();
352     JValue result;
353 
354     if (!is_static) {
355       arg_array.Append(reinterpret_cast<uint32_t>(receiver));
356       args++;
357     }
358 
359     arg_array.Append(0);
360     arg_array.Append(0);
361     arg_array.Append(0);
362     arg_array.Append(0);
363     result.SetI(-1);
364     method->Invoke(Thread::Current(), arg_array.GetArray(), arg_array.GetNumBytes(), &result, 'I');
365     EXPECT_EQ(0, result.GetI());
366 
367     args[0] = 1;
368     args[1] = 2;
369     args[2] = 3;
370     args[3] = 4;
371     result.SetI(0);
372     method->Invoke(Thread::Current(), arg_array.GetArray(), arg_array.GetNumBytes(), &result, 'I');
373     EXPECT_EQ(10, result.GetI());
374 
375     args[0] = -1;
376     args[1] = 2;
377     args[2] = -3;
378     args[3] = 4;
379     result.SetI(0);
380     method->Invoke(Thread::Current(), arg_array.GetArray(), arg_array.GetNumBytes(), &result, 'I');
381     EXPECT_EQ(2, result.GetI());
382 
383     args[0] = INT_MAX;
384     args[1] = INT_MIN;
385     args[2] = INT_MAX;
386     args[3] = INT_MIN;
387     result.SetI(1234);
388     method->Invoke(Thread::Current(), arg_array.GetArray(), arg_array.GetNumBytes(), &result, 'I');
389     EXPECT_EQ(-2, result.GetI());
390 
391     args[0] = INT_MAX;
392     args[1] = INT_MAX;
393     args[2] = INT_MAX;
394     args[3] = INT_MAX;
395     result.SetI(INT_MIN);
396     method->Invoke(Thread::Current(), arg_array.GetArray(), arg_array.GetNumBytes(), &result, 'I');
397     EXPECT_EQ(-4, result.GetI());
398   }
399 
InvokeSumIntIntIntIntIntMethod(bool is_static)400   void InvokeSumIntIntIntIntIntMethod(bool is_static)
401       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
402     mirror::ArtMethod* method;
403     mirror::Object* receiver;
404     DoCompile(method, receiver, is_static, "sum", "(IIIII)I");
405 
406     ArgArray arg_array(NULL, 0);
407     uint32_t* args = arg_array.GetArray();
408     JValue result;
409 
410     if (!is_static) {
411       arg_array.Append(reinterpret_cast<uint32_t>(receiver));
412       args++;
413     }
414 
415     arg_array.Append(0);
416     arg_array.Append(0);
417     arg_array.Append(0);
418     arg_array.Append(0);
419     arg_array.Append(0);
420     result.SetI(-1.0);
421     method->Invoke(Thread::Current(), arg_array.GetArray(), arg_array.GetNumBytes(), &result, 'I');
422     EXPECT_EQ(0, result.GetI());
423 
424     args[0] = 1;
425     args[1] = 2;
426     args[2] = 3;
427     args[3] = 4;
428     args[4] = 5;
429     result.SetI(0);
430     method->Invoke(Thread::Current(), arg_array.GetArray(), arg_array.GetNumBytes(), &result, 'I');
431     EXPECT_EQ(15, result.GetI());
432 
433     args[0] = -1;
434     args[1] = 2;
435     args[2] = -3;
436     args[3] = 4;
437     args[4] = -5;
438     result.SetI(0);
439     method->Invoke(Thread::Current(), arg_array.GetArray(), arg_array.GetNumBytes(), &result, 'I');
440     EXPECT_EQ(-3, result.GetI());
441 
442     args[0] = INT_MAX;
443     args[1] = INT_MIN;
444     args[2] = INT_MAX;
445     args[3] = INT_MIN;
446     args[4] = INT_MAX;
447     result.SetI(1234);
448     method->Invoke(Thread::Current(), arg_array.GetArray(), arg_array.GetNumBytes(), &result, 'I');
449     EXPECT_EQ(2147483645, result.GetI());
450 
451     args[0] = INT_MAX;
452     args[1] = INT_MAX;
453     args[2] = INT_MAX;
454     args[3] = INT_MAX;
455     args[4] = INT_MAX;
456     result.SetI(INT_MIN);
457     method->Invoke(Thread::Current(), arg_array.GetArray(), arg_array.GetNumBytes(), &result, 'I');
458     EXPECT_EQ(2147483643, result.GetI());
459   }
460 
InvokeSumDoubleDoubleMethod(bool is_static)461   void InvokeSumDoubleDoubleMethod(bool is_static)
462       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
463     mirror::ArtMethod* method;
464     mirror::Object* receiver;
465     DoCompile(method, receiver, is_static, "sum", "(DD)D");
466 
467     ArgArray arg_array(NULL, 0);
468     uint32_t* args = arg_array.GetArray();
469     JValue value;
470     JValue value2;
471     JValue result;
472 
473     if (!is_static) {
474       arg_array.Append(reinterpret_cast<uint32_t>(receiver));
475       args++;
476     }
477 
478     value.SetD(0.0);
479     value2.SetD(0.0);
480     arg_array.AppendWide(value.GetJ());
481     arg_array.AppendWide(value2.GetJ());
482     result.SetD(-1.0);
483     method->Invoke(Thread::Current(), arg_array.GetArray(), arg_array.GetNumBytes(), &result, 'D');
484     EXPECT_EQ(0.0, result.GetD());
485 
486     value.SetD(1.0);
487     value2.SetD(2.0);
488     args[0] = value.GetJ();
489     args[1] = value.GetJ() >> 32;
490     args[2] = value2.GetJ();
491     args[3] = value2.GetJ() >> 32;
492     result.SetD(0.0);
493     method->Invoke(Thread::Current(), arg_array.GetArray(), arg_array.GetNumBytes(), &result, 'D');
494     EXPECT_EQ(3.0, result.GetD());
495 
496     value.SetD(1.0);
497     value2.SetD(-2.0);
498     args[0] = value.GetJ();
499     args[1] = value.GetJ() >> 32;
500     args[2] = value2.GetJ();
501     args[3] = value2.GetJ() >> 32;
502     result.SetD(0.0);
503     method->Invoke(Thread::Current(), arg_array.GetArray(), arg_array.GetNumBytes(), &result, 'D');
504     EXPECT_EQ(-1.0, result.GetD());
505 
506     value.SetD(DBL_MAX);
507     value2.SetD(DBL_MIN);
508     args[0] = value.GetJ();
509     args[1] = value.GetJ() >> 32;
510     args[2] = value2.GetJ();
511     args[3] = value2.GetJ() >> 32;
512     result.SetD(0.0);
513     method->Invoke(Thread::Current(), arg_array.GetArray(), arg_array.GetNumBytes(), &result, 'D');
514     EXPECT_EQ(1.7976931348623157e308, result.GetD());
515 
516     value.SetD(DBL_MAX);
517     value2.SetD(DBL_MAX);
518     args[0] = value.GetJ();
519     args[1] = value.GetJ() >> 32;
520     args[2] = value2.GetJ();
521     args[3] = value2.GetJ() >> 32;
522     result.SetD(0.0);
523     method->Invoke(Thread::Current(), arg_array.GetArray(), arg_array.GetNumBytes(), &result, 'D');
524     EXPECT_EQ(INFINITY, result.GetD());
525   }
526 
InvokeSumDoubleDoubleDoubleMethod(bool is_static)527   void InvokeSumDoubleDoubleDoubleMethod(bool is_static)
528       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
529     mirror::ArtMethod* method;
530     mirror::Object* receiver;
531     DoCompile(method, receiver, is_static, "sum", "(DDD)D");
532 
533     ArgArray arg_array(NULL, 0);
534     uint32_t* args = arg_array.GetArray();
535     JValue value;
536     JValue value2;
537     JValue value3;
538     JValue result;
539 
540     if (!is_static) {
541       arg_array.Append(reinterpret_cast<uint32_t>(receiver));
542       args++;
543     }
544 
545     value.SetD(0.0);
546     value2.SetD(0.0);
547     value3.SetD(0.0);
548     arg_array.AppendWide(value.GetJ());
549     arg_array.AppendWide(value2.GetJ());
550     arg_array.AppendWide(value3.GetJ());
551     result.SetD(-1.0);
552     method->Invoke(Thread::Current(), arg_array.GetArray(), arg_array.GetNumBytes(), &result, 'D');
553     EXPECT_EQ(0.0, result.GetD());
554 
555     value.SetD(1.0);
556     value2.SetD(2.0);
557     value3.SetD(3.0);
558     args[0] = value.GetJ();
559     args[1] = value.GetJ() >> 32;
560     args[2] = value2.GetJ();
561     args[3] = value2.GetJ() >> 32;
562     args[4] = value3.GetJ();
563     args[5] = value3.GetJ() >> 32;
564     result.SetD(0.0);
565     method->Invoke(Thread::Current(), arg_array.GetArray(), arg_array.GetNumBytes(), &result, 'D');
566     EXPECT_EQ(6.0, result.GetD());
567 
568     value.SetD(1.0);
569     value2.SetD(-2.0);
570     value3.SetD(3.0);
571     args[0] = value.GetJ();
572     args[1] = value.GetJ() >> 32;
573     args[2] = value2.GetJ();
574     args[3] = value2.GetJ() >> 32;
575     args[4] = value3.GetJ();
576     args[5] = value3.GetJ() >> 32;
577     result.SetD(0.0);
578     method->Invoke(Thread::Current(), arg_array.GetArray(), arg_array.GetNumBytes(), &result, 'D');
579     EXPECT_EQ(2.0, result.GetD());
580   }
581 
InvokeSumDoubleDoubleDoubleDoubleMethod(bool is_static)582   void InvokeSumDoubleDoubleDoubleDoubleMethod(bool is_static)
583       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
584     mirror::ArtMethod* method;
585     mirror::Object* receiver;
586     DoCompile(method, receiver, is_static, "sum", "(DDDD)D");
587 
588     ArgArray arg_array(NULL, 0);
589     uint32_t* args = arg_array.GetArray();
590     JValue value;
591     JValue value2;
592     JValue value3;
593     JValue value4;
594     JValue result;
595 
596     if (!is_static) {
597       arg_array.Append(reinterpret_cast<uint32_t>(receiver));
598       args++;
599     }
600 
601     value.SetD(0.0);
602     value2.SetD(0.0);
603     value3.SetD(0.0);
604     value4.SetD(0.0);
605     arg_array.AppendWide(value.GetJ());
606     arg_array.AppendWide(value2.GetJ());
607     arg_array.AppendWide(value3.GetJ());
608     arg_array.AppendWide(value4.GetJ());
609     result.SetD(-1.0);
610     method->Invoke(Thread::Current(), arg_array.GetArray(), arg_array.GetNumBytes(), &result, 'D');
611     EXPECT_EQ(0.0, result.GetD());
612 
613     value.SetD(1.0);
614     value2.SetD(2.0);
615     value3.SetD(3.0);
616     value4.SetD(4.0);
617     args[0] = value.GetJ();
618     args[1] = value.GetJ() >> 32;
619     args[2] = value2.GetJ();
620     args[3] = value2.GetJ() >> 32;
621     args[4] = value3.GetJ();
622     args[5] = value3.GetJ() >> 32;
623     args[6] = value4.GetJ();
624     args[7] = value4.GetJ() >> 32;
625     result.SetD(0.0);
626     method->Invoke(Thread::Current(), arg_array.GetArray(), arg_array.GetNumBytes(), &result, 'D');
627     EXPECT_EQ(10.0, result.GetD());
628 
629     value.SetD(1.0);
630     value2.SetD(-2.0);
631     value3.SetD(3.0);
632     value4.SetD(-4.0);
633     args[0] = value.GetJ();
634     args[1] = value.GetJ() >> 32;
635     args[2] = value2.GetJ();
636     args[3] = value2.GetJ() >> 32;
637     args[4] = value3.GetJ();
638     args[5] = value3.GetJ() >> 32;
639     args[6] = value4.GetJ();
640     args[7] = value4.GetJ() >> 32;
641     result.SetD(0.0);
642     method->Invoke(Thread::Current(), arg_array.GetArray(), arg_array.GetNumBytes(), &result, 'D');
643     EXPECT_EQ(-2.0, result.GetD());
644   }
645 
InvokeSumDoubleDoubleDoubleDoubleDoubleMethod(bool is_static)646   void InvokeSumDoubleDoubleDoubleDoubleDoubleMethod(bool is_static)
647       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
648     mirror::ArtMethod* method;
649     mirror::Object* receiver;
650     DoCompile(method, receiver, is_static, "sum", "(DDDDD)D");
651 
652     ArgArray arg_array(NULL, 0);
653     uint32_t* args = arg_array.GetArray();
654     JValue value;
655     JValue value2;
656     JValue value3;
657     JValue value4;
658     JValue value5;
659     JValue result;
660 
661     if (!is_static) {
662       arg_array.Append(reinterpret_cast<uint32_t>(receiver));
663       args++;
664     }
665 
666     value.SetD(0.0);
667     value2.SetD(0.0);
668     value3.SetD(0.0);
669     value4.SetD(0.0);
670     value5.SetD(0.0);
671     arg_array.AppendWide(value.GetJ());
672     arg_array.AppendWide(value2.GetJ());
673     arg_array.AppendWide(value3.GetJ());
674     arg_array.AppendWide(value4.GetJ());
675     arg_array.AppendWide(value5.GetJ());
676     result.SetD(-1.0);
677     method->Invoke(Thread::Current(), arg_array.GetArray(), arg_array.GetNumBytes(), &result, 'D');
678     EXPECT_EQ(0.0, result.GetD());
679 
680     value.SetD(1.0);
681     value2.SetD(2.0);
682     value3.SetD(3.0);
683     value4.SetD(4.0);
684     value5.SetD(5.0);
685     args[0] = value.GetJ();
686     args[1] = value.GetJ() >> 32;
687     args[2] = value2.GetJ();
688     args[3] = value2.GetJ() >> 32;
689     args[4] = value3.GetJ();
690     args[5] = value3.GetJ() >> 32;
691     args[6] = value4.GetJ();
692     args[7] = value4.GetJ() >> 32;
693     args[8] = value5.GetJ();
694     args[9] = value5.GetJ() >> 32;
695     result.SetD(0.0);
696     method->Invoke(Thread::Current(), arg_array.GetArray(), arg_array.GetNumBytes(), &result, 'D');
697     EXPECT_EQ(15.0, result.GetD());
698 
699     value.SetD(1.0);
700     value2.SetD(-2.0);
701     value3.SetD(3.0);
702     value4.SetD(-4.0);
703     value5.SetD(5.0);
704     args[0] = value.GetJ();
705     args[1] = value.GetJ() >> 32;
706     args[2] = value2.GetJ();
707     args[3] = value2.GetJ() >> 32;
708     args[4] = value3.GetJ();
709     args[5] = value3.GetJ() >> 32;
710     args[6] = value4.GetJ();
711     args[7] = value4.GetJ() >> 32;
712     args[8] = value5.GetJ();
713     args[9] = value5.GetJ() >> 32;
714     result.SetD(0.0);
715     method->Invoke(Thread::Current(), arg_array.GetArray(), arg_array.GetNumBytes(), &result, 'D');
716     EXPECT_EQ(3.0, result.GetD());
717   }
718 
719   JavaVMExt* vm_;
720   JNIEnv* env_;
721   jclass aioobe_;
722   jclass ase_;
723   jclass sioobe_;
724 };
725 
TEST_F(JniInternalTest,AllocObject)726 TEST_F(JniInternalTest, AllocObject) {
727   jclass c = env_->FindClass("java/lang/String");
728   ASSERT_TRUE(c != NULL);
729   jobject o = env_->AllocObject(c);
730   ASSERT_TRUE(o != NULL);
731 
732   // We have an instance of the class we asked for...
733   ASSERT_TRUE(env_->IsInstanceOf(o, c));
734   // ...whose fields haven't been initialized because
735   // we didn't call a constructor.
736   ASSERT_EQ(0, env_->GetIntField(o, env_->GetFieldID(c, "count", "I")));
737   ASSERT_EQ(0, env_->GetIntField(o, env_->GetFieldID(c, "offset", "I")));
738   ASSERT_TRUE(env_->GetObjectField(o, env_->GetFieldID(c, "value", "[C")) == NULL);
739 }
740 
TEST_F(JniInternalTest,GetVersion)741 TEST_F(JniInternalTest, GetVersion) {
742   ASSERT_EQ(JNI_VERSION_1_6, env_->GetVersion());
743 }
744 
745 #define EXPECT_CLASS_FOUND(NAME) \
746   EXPECT_TRUE(env_->FindClass(NAME) != NULL); \
747   EXPECT_FALSE(env_->ExceptionCheck())
748 
749 #define EXPECT_CLASS_NOT_FOUND(NAME) \
750   EXPECT_TRUE(env_->FindClass(NAME) == NULL); \
751   EXPECT_TRUE(env_->ExceptionCheck()); \
752   env_->ExceptionClear()
753 
TEST_F(JniInternalTest,FindClass)754 TEST_F(JniInternalTest, FindClass) {
755   // Reference types...
756   EXPECT_CLASS_FOUND("java/lang/String");
757   // ...for arrays too, where you must include "L;".
758   EXPECT_CLASS_FOUND("[Ljava/lang/String;");
759   // Primitive arrays are okay too, if the primitive type is valid.
760   EXPECT_CLASS_FOUND("[C");
761 
762   {
763     // We support . as well as / for compatibility, if -Xcheck:jni is off.
764     CheckJniAbortCatcher check_jni_abort_catcher;
765     EXPECT_CLASS_FOUND("java.lang.String");
766     check_jni_abort_catcher.Check("illegal class name 'java.lang.String'");
767     EXPECT_CLASS_NOT_FOUND("Ljava.lang.String;");
768     check_jni_abort_catcher.Check("illegal class name 'Ljava.lang.String;'");
769     EXPECT_CLASS_FOUND("[Ljava.lang.String;");
770     check_jni_abort_catcher.Check("illegal class name '[Ljava.lang.String;'");
771     EXPECT_CLASS_NOT_FOUND("[java.lang.String");
772     check_jni_abort_catcher.Check("illegal class name '[java.lang.String'");
773 
774     // You can't include the "L;" in a JNI class descriptor.
775     EXPECT_CLASS_NOT_FOUND("Ljava/lang/String;");
776     check_jni_abort_catcher.Check("illegal class name 'Ljava/lang/String;'");
777 
778     // But you must include it for an array of any reference type.
779     EXPECT_CLASS_NOT_FOUND("[java/lang/String");
780     check_jni_abort_catcher.Check("illegal class name '[java/lang/String'");
781 
782     EXPECT_CLASS_NOT_FOUND("[K");
783     check_jni_abort_catcher.Check("illegal class name '[K'");
784   }
785 
786   // But primitive types aren't allowed...
787   EXPECT_CLASS_NOT_FOUND("C");
788   EXPECT_CLASS_NOT_FOUND("K");
789 }
790 
791 #define EXPECT_EXCEPTION(exception_class) \
792   do { \
793     EXPECT_TRUE(env_->ExceptionCheck()); \
794     jthrowable exception = env_->ExceptionOccurred(); \
795     EXPECT_NE(static_cast<jthrowable>(NULL), exception); \
796     env_->ExceptionClear(); \
797     EXPECT_TRUE(env_->IsInstanceOf(exception, exception_class)); \
798   } while (false)
799 
TEST_F(JniInternalTest,GetFieldID)800 TEST_F(JniInternalTest, GetFieldID) {
801   jclass jlnsfe = env_->FindClass("java/lang/NoSuchFieldError");
802   ASSERT_TRUE(jlnsfe != NULL);
803   jclass c = env_->FindClass("java/lang/String");
804   ASSERT_TRUE(c != NULL);
805 
806   // Wrong type.
807   jfieldID fid = env_->GetFieldID(c, "count", "J");
808   EXPECT_EQ(static_cast<jfieldID>(NULL), fid);
809   EXPECT_EXCEPTION(jlnsfe);
810 
811   // Wrong type where type doesn't exist.
812   fid = env_->GetFieldID(c, "count", "Lrod/jane/freddy;");
813   EXPECT_EQ(static_cast<jfieldID>(NULL), fid);
814   EXPECT_EXCEPTION(jlnsfe);
815 
816   // Wrong name.
817   fid = env_->GetFieldID(c, "Count", "I");
818   EXPECT_EQ(static_cast<jfieldID>(NULL), fid);
819   EXPECT_EXCEPTION(jlnsfe);
820 
821   // Good declared field lookup.
822   fid = env_->GetFieldID(c, "count", "I");
823   EXPECT_NE(static_cast<jfieldID>(NULL), fid);
824   EXPECT_TRUE(fid != NULL);
825   EXPECT_FALSE(env_->ExceptionCheck());
826 
827   // Good superclass field lookup.
828   c = env_->FindClass("java/lang/StringBuilder");
829   fid = env_->GetFieldID(c, "count", "I");
830   EXPECT_NE(static_cast<jfieldID>(NULL), fid);
831   EXPECT_TRUE(fid != NULL);
832   EXPECT_FALSE(env_->ExceptionCheck());
833 
834   // Not instance.
835   fid = env_->GetFieldID(c, "CASE_INSENSITIVE_ORDER", "Ljava/util/Comparator;");
836   EXPECT_EQ(static_cast<jfieldID>(NULL), fid);
837   EXPECT_EXCEPTION(jlnsfe);
838 }
839 
TEST_F(JniInternalTest,GetStaticFieldID)840 TEST_F(JniInternalTest, GetStaticFieldID) {
841   jclass jlnsfe = env_->FindClass("java/lang/NoSuchFieldError");
842   ASSERT_TRUE(jlnsfe != NULL);
843   jclass c = env_->FindClass("java/lang/String");
844   ASSERT_TRUE(c != NULL);
845 
846   // Wrong type.
847   jfieldID fid = env_->GetStaticFieldID(c, "CASE_INSENSITIVE_ORDER", "J");
848   EXPECT_EQ(static_cast<jfieldID>(NULL), fid);
849   EXPECT_EXCEPTION(jlnsfe);
850 
851   // Wrong type where type doesn't exist.
852   fid = env_->GetStaticFieldID(c, "CASE_INSENSITIVE_ORDER", "Lrod/jane/freddy;");
853   EXPECT_EQ(static_cast<jfieldID>(NULL), fid);
854   EXPECT_EXCEPTION(jlnsfe);
855 
856   // Wrong name.
857   fid = env_->GetStaticFieldID(c, "cASE_INSENSITIVE_ORDER", "Ljava/util/Comparator;");
858   EXPECT_EQ(static_cast<jfieldID>(NULL), fid);
859   EXPECT_EXCEPTION(jlnsfe);
860 
861   // Good declared field lookup.
862   fid = env_->GetStaticFieldID(c, "CASE_INSENSITIVE_ORDER", "Ljava/util/Comparator;");
863   EXPECT_NE(static_cast<jfieldID>(NULL), fid);
864   EXPECT_TRUE(fid != NULL);
865   EXPECT_FALSE(env_->ExceptionCheck());
866 
867   // Not static.
868   fid = env_->GetStaticFieldID(c, "count", "I");
869   EXPECT_EQ(static_cast<jfieldID>(NULL), fid);
870   EXPECT_EXCEPTION(jlnsfe);
871 }
872 
TEST_F(JniInternalTest,GetMethodID)873 TEST_F(JniInternalTest, GetMethodID) {
874   jclass jlobject = env_->FindClass("java/lang/Object");
875   jclass jlstring = env_->FindClass("java/lang/String");
876   jclass jlnsme = env_->FindClass("java/lang/NoSuchMethodError");
877 
878   // Sanity check that no exceptions are pending
879   ASSERT_FALSE(env_->ExceptionCheck());
880 
881   // Check that java.lang.Object.foo() doesn't exist and NoSuchMethodError is
882   // a pending exception
883   jmethodID method = env_->GetMethodID(jlobject, "foo", "()V");
884   EXPECT_EQ(static_cast<jmethodID>(NULL), method);
885   EXPECT_EXCEPTION(jlnsme);
886 
887   // Check that java.lang.Object.equals() does exist
888   method = env_->GetMethodID(jlobject, "equals", "(Ljava/lang/Object;)Z");
889   EXPECT_NE(static_cast<jmethodID>(NULL), method);
890   EXPECT_FALSE(env_->ExceptionCheck());
891 
892   // Check that GetMethodID for java.lang.String.valueOf(int) fails as the
893   // method is static
894   method = env_->GetMethodID(jlstring, "valueOf", "(I)Ljava/lang/String;");
895   EXPECT_EQ(static_cast<jmethodID>(NULL), method);
896   EXPECT_EXCEPTION(jlnsme);
897 
898   // Check that GetMethodID for java.lang.NoSuchMethodError.<init>(String) finds the constructor
899   method = env_->GetMethodID(jlnsme, "<init>", "(Ljava/lang/String;)V");
900   EXPECT_NE(static_cast<jmethodID>(NULL), method);
901   EXPECT_FALSE(env_->ExceptionCheck());
902 }
903 
TEST_F(JniInternalTest,GetStaticMethodID)904 TEST_F(JniInternalTest, GetStaticMethodID) {
905   jclass jlobject = env_->FindClass("java/lang/Object");
906   jclass jlnsme = env_->FindClass("java/lang/NoSuchMethodError");
907 
908   // Sanity check that no exceptions are pending
909   ASSERT_FALSE(env_->ExceptionCheck());
910 
911   // Check that java.lang.Object.foo() doesn't exist and NoSuchMethodError is
912   // a pending exception
913   jmethodID method = env_->GetStaticMethodID(jlobject, "foo", "()V");
914   EXPECT_EQ(static_cast<jmethodID>(NULL), method);
915   EXPECT_EXCEPTION(jlnsme);
916 
917   // Check that GetStaticMethodID for java.lang.Object.equals(Object) fails as
918   // the method is not static
919   method = env_->GetStaticMethodID(jlobject, "equals", "(Ljava/lang/Object;)Z");
920   EXPECT_EQ(static_cast<jmethodID>(NULL), method);
921   EXPECT_EXCEPTION(jlnsme);
922 
923   // Check that java.lang.String.valueOf(int) does exist
924   jclass jlstring = env_->FindClass("java/lang/String");
925   method = env_->GetStaticMethodID(jlstring, "valueOf",
926                                    "(I)Ljava/lang/String;");
927   EXPECT_NE(static_cast<jmethodID>(NULL), method);
928   EXPECT_FALSE(env_->ExceptionCheck());
929 }
930 
TEST_F(JniInternalTest,FromReflectedField_ToReflectedField)931 TEST_F(JniInternalTest, FromReflectedField_ToReflectedField) {
932   jclass jlrField = env_->FindClass("java/lang/reflect/Field");
933   jclass c = env_->FindClass("java/lang/String");
934   ASSERT_TRUE(c != NULL);
935   jfieldID fid = env_->GetFieldID(c, "count", "I");
936   ASSERT_TRUE(fid != NULL);
937   // Turn the fid into a java.lang.reflect.Field...
938   jobject field = env_->ToReflectedField(c, fid, JNI_FALSE);
939   ASSERT_TRUE(c != NULL);
940   ASSERT_TRUE(env_->IsInstanceOf(field, jlrField));
941   // ...and back again.
942   jfieldID fid2 = env_->FromReflectedField(field);
943   ASSERT_TRUE(fid2 != NULL);
944   // Make sure we can actually use it.
945   jstring s = env_->NewStringUTF("poop");
946   ASSERT_EQ(4, env_->GetIntField(s, fid2));
947 }
948 
TEST_F(JniInternalTest,FromReflectedMethod_ToReflectedMethod)949 TEST_F(JniInternalTest, FromReflectedMethod_ToReflectedMethod) {
950   jclass jlrMethod = env_->FindClass("java/lang/reflect/Method");
951   jclass c = env_->FindClass("java/lang/String");
952   ASSERT_TRUE(c != NULL);
953   jmethodID mid = env_->GetMethodID(c, "length", "()I");
954   ASSERT_TRUE(mid != NULL);
955   // Turn the mid into a java.lang.reflect.Method...
956   jobject method = env_->ToReflectedMethod(c, mid, JNI_FALSE);
957   ASSERT_TRUE(c != NULL);
958   ASSERT_TRUE(env_->IsInstanceOf(method, jlrMethod));
959   // ...and back again.
960   jmethodID mid2 = env_->FromReflectedMethod(method);
961   ASSERT_TRUE(mid2 != NULL);
962   // Make sure we can actually use it.
963   jstring s = env_->NewStringUTF("poop");
964   // TODO: this should return 4, but the runtime skips the method
965   // invoke because the runtime isn't started. In the future it would
966   // be nice to use interpretter for things like this. This still does
967   // validate that we have a sane jmethodID value.
968   ASSERT_EQ(0, env_->CallIntMethod(s, mid2));
969 }
970 
BogusMethod()971 void BogusMethod() {
972   // You can't pass NULL function pointers to RegisterNatives.
973 }
974 
TEST_F(JniInternalTest,RegisterNatives)975 TEST_F(JniInternalTest, RegisterNatives) {
976   jclass jlobject = env_->FindClass("java/lang/Object");
977   jclass jlnsme = env_->FindClass("java/lang/NoSuchMethodError");
978 
979   // Sanity check that no exceptions are pending
980   ASSERT_FALSE(env_->ExceptionCheck());
981 
982   // Check that registering to a non-existent java.lang.Object.foo() causes a
983   // NoSuchMethodError
984   {
985     JNINativeMethod methods[] = { { "foo", "()V", NULL } };
986     env_->RegisterNatives(jlobject, methods, 1);
987   }
988   EXPECT_EXCEPTION(jlnsme);
989 
990   // Check that registering non-native methods causes a NoSuchMethodError
991   {
992     JNINativeMethod methods[] = { { "equals", "(Ljava/lang/Object;)Z", NULL } };
993     env_->RegisterNatives(jlobject, methods, 1);
994   }
995   EXPECT_EXCEPTION(jlnsme);
996 
997   // Check that registering native methods is successful
998   {
999     JNINativeMethod methods[] = { { "notify", "()V", reinterpret_cast<void*>(BogusMethod) } };
1000     env_->RegisterNatives(jlobject, methods, 1);
1001   }
1002   EXPECT_FALSE(env_->ExceptionCheck());
1003 
1004   env_->UnregisterNatives(jlobject);
1005 }
1006 
1007 #define EXPECT_PRIMITIVE_ARRAY(new_fn, \
1008                                get_region_fn, \
1009                                set_region_fn, \
1010                                get_elements_fn, \
1011                                release_elements_fn, \
1012                                scalar_type, \
1013                                expected_class_descriptor) \
1014   jsize size = 4; \
1015   /* Allocate an array and check it has the right type and length. */ \
1016   scalar_type ## Array a = env_->new_fn(size); \
1017   EXPECT_TRUE(a != NULL); \
1018   EXPECT_TRUE(env_->IsInstanceOf(a, env_->FindClass(expected_class_descriptor))); \
1019   EXPECT_EQ(size, env_->GetArrayLength(a)); \
1020   /* AIOOBE for negative start offset. */ \
1021   env_->get_region_fn(a, -1, 1, NULL); \
1022   EXPECT_EXCEPTION(aioobe_); \
1023   env_->set_region_fn(a, -1, 1, NULL); \
1024   EXPECT_EXCEPTION(aioobe_); \
1025   /* AIOOBE for negative length. */ \
1026   env_->get_region_fn(a, 0, -1, NULL); \
1027   EXPECT_EXCEPTION(aioobe_); \
1028   env_->set_region_fn(a, 0, -1, NULL); \
1029   EXPECT_EXCEPTION(aioobe_); \
1030   /* AIOOBE for buffer overrun. */ \
1031   env_->get_region_fn(a, size - 1, size, NULL); \
1032   EXPECT_EXCEPTION(aioobe_); \
1033   env_->set_region_fn(a, size - 1, size, NULL); \
1034   EXPECT_EXCEPTION(aioobe_); \
1035   /* Prepare a couple of buffers. */ \
1036   UniquePtr<scalar_type[]> src_buf(new scalar_type[size]); \
1037   UniquePtr<scalar_type[]> dst_buf(new scalar_type[size]); \
1038   for (jsize i = 0; i < size; ++i) { src_buf[i] = scalar_type(i); } \
1039   for (jsize i = 0; i < size; ++i) { dst_buf[i] = scalar_type(-1); } \
1040   /* Copy all of src_buf onto the heap. */ \
1041   env_->set_region_fn(a, 0, size, &src_buf[0]); \
1042   /* Copy back only part. */ \
1043   env_->get_region_fn(a, 1, size - 2, &dst_buf[1]); \
1044   EXPECT_NE(memcmp(&src_buf[0], &dst_buf[0], size * sizeof(scalar_type)), 0) \
1045     << "short copy equal"; \
1046   /* Copy the missing pieces. */ \
1047   env_->get_region_fn(a, 0, 1, &dst_buf[0]); \
1048   env_->get_region_fn(a, size - 1, 1, &dst_buf[size - 1]); \
1049   EXPECT_EQ(memcmp(&src_buf[0], &dst_buf[0], size * sizeof(scalar_type)), 0) \
1050     << "fixed copy not equal"; \
1051   /* Copy back the whole array. */ \
1052   env_->get_region_fn(a, 0, size, &dst_buf[0]); \
1053   EXPECT_EQ(memcmp(&src_buf[0], &dst_buf[0], size * sizeof(scalar_type)), 0) \
1054     << "full copy not equal"; \
1055   /* GetPrimitiveArrayCritical */ \
1056   void* v = env_->GetPrimitiveArrayCritical(a, NULL); \
1057   EXPECT_EQ(memcmp(&src_buf[0], v, size * sizeof(scalar_type)), 0) \
1058     << "GetPrimitiveArrayCritical not equal"; \
1059   env_->ReleasePrimitiveArrayCritical(a, v, 0); \
1060   /* GetXArrayElements */ \
1061   scalar_type* xs = env_->get_elements_fn(a, NULL); \
1062   EXPECT_EQ(memcmp(&src_buf[0], xs, size * sizeof(scalar_type)), 0) \
1063     << # get_elements_fn " not equal"; \
1064   env_->release_elements_fn(a, xs, 0); \
1065   EXPECT_EQ(reinterpret_cast<uintptr_t>(v), reinterpret_cast<uintptr_t>(xs))
1066 
TEST_F(JniInternalTest,BooleanArrays)1067 TEST_F(JniInternalTest, BooleanArrays) {
1068   EXPECT_PRIMITIVE_ARRAY(NewBooleanArray, GetBooleanArrayRegion, SetBooleanArrayRegion,
1069                          GetBooleanArrayElements, ReleaseBooleanArrayElements, jboolean, "[Z");
1070 }
TEST_F(JniInternalTest,ByteArrays)1071 TEST_F(JniInternalTest, ByteArrays) {
1072   EXPECT_PRIMITIVE_ARRAY(NewByteArray, GetByteArrayRegion, SetByteArrayRegion,
1073                          GetByteArrayElements, ReleaseByteArrayElements, jbyte, "[B");
1074 }
TEST_F(JniInternalTest,CharArrays)1075 TEST_F(JniInternalTest, CharArrays) {
1076   EXPECT_PRIMITIVE_ARRAY(NewCharArray, GetCharArrayRegion, SetCharArrayRegion,
1077                          GetCharArrayElements, ReleaseCharArrayElements, jchar, "[C");
1078 }
TEST_F(JniInternalTest,DoubleArrays)1079 TEST_F(JniInternalTest, DoubleArrays) {
1080   EXPECT_PRIMITIVE_ARRAY(NewDoubleArray, GetDoubleArrayRegion, SetDoubleArrayRegion,
1081                          GetDoubleArrayElements, ReleaseDoubleArrayElements, jdouble, "[D");
1082 }
TEST_F(JniInternalTest,FloatArrays)1083 TEST_F(JniInternalTest, FloatArrays) {
1084   EXPECT_PRIMITIVE_ARRAY(NewFloatArray, GetFloatArrayRegion, SetFloatArrayRegion,
1085                          GetFloatArrayElements, ReleaseFloatArrayElements, jfloat, "[F");
1086 }
TEST_F(JniInternalTest,IntArrays)1087 TEST_F(JniInternalTest, IntArrays) {
1088   EXPECT_PRIMITIVE_ARRAY(NewIntArray, GetIntArrayRegion, SetIntArrayRegion,
1089                          GetIntArrayElements, ReleaseIntArrayElements, jint, "[I");
1090 }
TEST_F(JniInternalTest,LongArrays)1091 TEST_F(JniInternalTest, LongArrays) {
1092   EXPECT_PRIMITIVE_ARRAY(NewLongArray, GetLongArrayRegion, SetLongArrayRegion,
1093                          GetLongArrayElements, ReleaseLongArrayElements, jlong, "[J");
1094 }
TEST_F(JniInternalTest,ShortArrays)1095 TEST_F(JniInternalTest, ShortArrays) {
1096   EXPECT_PRIMITIVE_ARRAY(NewShortArray, GetShortArrayRegion, SetShortArrayRegion,
1097                          GetShortArrayElements, ReleaseShortArrayElements, jshort, "[S");
1098 }
1099 
TEST_F(JniInternalTest,NewObjectArray)1100 TEST_F(JniInternalTest, NewObjectArray) {
1101   // TODO: death tests for negative array sizes.
1102 
1103   // TODO: check non-NULL initial elements.
1104 
1105   jclass element_class = env_->FindClass("java/lang/String");
1106   ASSERT_TRUE(element_class != NULL);
1107   jclass array_class = env_->FindClass("[Ljava/lang/String;");
1108   ASSERT_TRUE(array_class != NULL);
1109 
1110   jobjectArray a;
1111 
1112   a = env_->NewObjectArray(0, element_class, NULL);
1113   EXPECT_TRUE(a != NULL);
1114   EXPECT_TRUE(env_->IsInstanceOf(a, array_class));
1115   EXPECT_EQ(0, env_->GetArrayLength(a));
1116 
1117   a = env_->NewObjectArray(1, element_class, NULL);
1118   EXPECT_TRUE(a != NULL);
1119   EXPECT_TRUE(env_->IsInstanceOf(a, array_class));
1120   EXPECT_EQ(1, env_->GetArrayLength(a));
1121   EXPECT_TRUE(env_->IsSameObject(env_->GetObjectArrayElement(a, 0), NULL));
1122 
1123   jstring s = env_->NewStringUTF("poop");
1124   a = env_->NewObjectArray(2, element_class, s);
1125   EXPECT_TRUE(a != NULL);
1126   EXPECT_TRUE(env_->IsInstanceOf(a, array_class));
1127   EXPECT_EQ(2, env_->GetArrayLength(a));
1128   EXPECT_TRUE(env_->IsSameObject(env_->GetObjectArrayElement(a, 0), s));
1129   EXPECT_TRUE(env_->IsSameObject(env_->GetObjectArrayElement(a, 1), s));
1130 }
1131 
TEST_F(JniInternalTest,GetArrayLength)1132 TEST_F(JniInternalTest, GetArrayLength) {
1133   // Already tested in NewObjectArray/NewPrimitiveArray.
1134 }
1135 
TEST_F(JniInternalTest,GetObjectClass)1136 TEST_F(JniInternalTest, GetObjectClass) {
1137   jclass string_class = env_->FindClass("java/lang/String");
1138   ASSERT_TRUE(string_class != NULL);
1139   jclass class_class = env_->FindClass("java/lang/Class");
1140   ASSERT_TRUE(class_class != NULL);
1141 
1142   jstring s = env_->NewStringUTF("poop");
1143   jclass c = env_->GetObjectClass(s);
1144   ASSERT_TRUE(env_->IsSameObject(string_class, c));
1145 
1146   jclass c2 = env_->GetObjectClass(c);
1147   ASSERT_TRUE(env_->IsSameObject(class_class, env_->GetObjectClass(c2)));
1148 }
1149 
TEST_F(JniInternalTest,GetSuperclass)1150 TEST_F(JniInternalTest, GetSuperclass) {
1151   jclass object_class = env_->FindClass("java/lang/Object");
1152   ASSERT_TRUE(object_class != NULL);
1153   jclass string_class = env_->FindClass("java/lang/String");
1154   ASSERT_TRUE(string_class != NULL);
1155   jclass runnable_interface = env_->FindClass("java/lang/Runnable");
1156   ASSERT_TRUE(runnable_interface != NULL);
1157   ASSERT_TRUE(env_->IsSameObject(object_class, env_->GetSuperclass(string_class)));
1158   ASSERT_TRUE(env_->GetSuperclass(object_class) == NULL);
1159   ASSERT_TRUE(env_->IsSameObject(object_class, env_->GetSuperclass(runnable_interface)));
1160 }
1161 
TEST_F(JniInternalTest,IsAssignableFrom)1162 TEST_F(JniInternalTest, IsAssignableFrom) {
1163   jclass object_class = env_->FindClass("java/lang/Object");
1164   ASSERT_TRUE(object_class != NULL);
1165   jclass string_class = env_->FindClass("java/lang/String");
1166   ASSERT_TRUE(string_class != NULL);
1167 
1168   ASSERT_TRUE(env_->IsAssignableFrom(object_class, string_class));
1169   ASSERT_FALSE(env_->IsAssignableFrom(string_class, object_class));
1170 }
1171 
TEST_F(JniInternalTest,GetObjectRefType)1172 TEST_F(JniInternalTest, GetObjectRefType) {
1173   jclass local = env_->FindClass("java/lang/Object");
1174   ASSERT_TRUE(local != NULL);
1175   EXPECT_EQ(JNILocalRefType, env_->GetObjectRefType(local));
1176 
1177   jobject global = env_->NewGlobalRef(local);
1178   EXPECT_EQ(JNIGlobalRefType, env_->GetObjectRefType(global));
1179 
1180   jweak weak_global = env_->NewWeakGlobalRef(local);
1181   EXPECT_EQ(JNIWeakGlobalRefType, env_->GetObjectRefType(weak_global));
1182 
1183   jobject invalid = reinterpret_cast<jobject>(this);
1184   EXPECT_EQ(JNIInvalidRefType, env_->GetObjectRefType(invalid));
1185 
1186   // TODO: invoke a native method and test that its arguments are considered local references.
1187 }
1188 
TEST_F(JniInternalTest,NewStringUTF)1189 TEST_F(JniInternalTest, NewStringUTF) {
1190   EXPECT_TRUE(env_->NewStringUTF(NULL) == NULL);
1191   jstring s;
1192 
1193   s = env_->NewStringUTF("");
1194   EXPECT_TRUE(s != NULL);
1195   EXPECT_EQ(0, env_->GetStringLength(s));
1196   EXPECT_EQ(0, env_->GetStringUTFLength(s));
1197   s = env_->NewStringUTF("hello");
1198   EXPECT_TRUE(s != NULL);
1199   EXPECT_EQ(5, env_->GetStringLength(s));
1200   EXPECT_EQ(5, env_->GetStringUTFLength(s));
1201 
1202   // TODO: check some non-ASCII strings.
1203 }
1204 
TEST_F(JniInternalTest,NewString)1205 TEST_F(JniInternalTest, NewString) {
1206   jchar chars[] = { 'h', 'i' };
1207   jstring s;
1208   s = env_->NewString(chars, 0);
1209   EXPECT_TRUE(s != NULL);
1210   EXPECT_EQ(0, env_->GetStringLength(s));
1211   EXPECT_EQ(0, env_->GetStringUTFLength(s));
1212   s = env_->NewString(chars, 2);
1213   EXPECT_TRUE(s != NULL);
1214   EXPECT_EQ(2, env_->GetStringLength(s));
1215   EXPECT_EQ(2, env_->GetStringUTFLength(s));
1216 
1217   // TODO: check some non-ASCII strings.
1218 }
1219 
TEST_F(JniInternalTest,NewStringNullCharsZeroLength)1220 TEST_F(JniInternalTest, NewStringNullCharsZeroLength) {
1221   jstring s = env_->NewString(NULL, 0);
1222   EXPECT_TRUE(s != NULL);
1223   EXPECT_EQ(0, env_->GetStringLength(s));
1224 }
1225 
1226 // TODO: fix gtest death tests on host http://b/5690440 (and target)
TEST_F(JniInternalTest,DISABLED_NewStringNullCharsNonzeroLength)1227 TEST_F(JniInternalTest, DISABLED_NewStringNullCharsNonzeroLength) {
1228   ASSERT_DEATH(env_->NewString(NULL, 1), "");
1229 }
1230 
TEST_F(JniInternalTest,GetStringLength_GetStringUTFLength)1231 TEST_F(JniInternalTest, GetStringLength_GetStringUTFLength) {
1232   // Already tested in the NewString/NewStringUTF tests.
1233 }
1234 
TEST_F(JniInternalTest,GetStringRegion_GetStringUTFRegion)1235 TEST_F(JniInternalTest, GetStringRegion_GetStringUTFRegion) {
1236   jstring s = env_->NewStringUTF("hello");
1237   ASSERT_TRUE(s != NULL);
1238 
1239   env_->GetStringRegion(s, -1, 0, NULL);
1240   EXPECT_EXCEPTION(sioobe_);
1241   env_->GetStringRegion(s, 0, -1, NULL);
1242   EXPECT_EXCEPTION(sioobe_);
1243   env_->GetStringRegion(s, 0, 10, NULL);
1244   EXPECT_EXCEPTION(sioobe_);
1245   env_->GetStringRegion(s, 10, 1, NULL);
1246   EXPECT_EXCEPTION(sioobe_);
1247 
1248   jchar chars[4] = { 'x', 'x', 'x', 'x' };
1249   env_->GetStringRegion(s, 1, 2, &chars[1]);
1250   EXPECT_EQ('x', chars[0]);
1251   EXPECT_EQ('e', chars[1]);
1252   EXPECT_EQ('l', chars[2]);
1253   EXPECT_EQ('x', chars[3]);
1254 
1255   env_->GetStringUTFRegion(s, -1, 0, NULL);
1256   EXPECT_EXCEPTION(sioobe_);
1257   env_->GetStringUTFRegion(s, 0, -1, NULL);
1258   EXPECT_EXCEPTION(sioobe_);
1259   env_->GetStringUTFRegion(s, 0, 10, NULL);
1260   EXPECT_EXCEPTION(sioobe_);
1261   env_->GetStringUTFRegion(s, 10, 1, NULL);
1262   EXPECT_EXCEPTION(sioobe_);
1263 
1264   char bytes[4] = { 'x', 'x', 'x', 'x' };
1265   env_->GetStringUTFRegion(s, 1, 2, &bytes[1]);
1266   EXPECT_EQ('x', bytes[0]);
1267   EXPECT_EQ('e', bytes[1]);
1268   EXPECT_EQ('l', bytes[2]);
1269   EXPECT_EQ('x', bytes[3]);
1270 }
1271 
TEST_F(JniInternalTest,GetStringUTFChars_ReleaseStringUTFChars)1272 TEST_F(JniInternalTest, GetStringUTFChars_ReleaseStringUTFChars) {
1273   // Passing in a NULL jstring is ignored normally, but caught by -Xcheck:jni.
1274   {
1275     CheckJniAbortCatcher check_jni_abort_catcher;
1276     EXPECT_TRUE(env_->GetStringUTFChars(NULL, NULL) == NULL);
1277     check_jni_abort_catcher.Check("GetStringUTFChars received null jstring");
1278   }
1279 
1280   jstring s = env_->NewStringUTF("hello");
1281   ASSERT_TRUE(s != NULL);
1282 
1283   const char* utf = env_->GetStringUTFChars(s, NULL);
1284   EXPECT_STREQ("hello", utf);
1285   env_->ReleaseStringUTFChars(s, utf);
1286 
1287   jboolean is_copy = JNI_FALSE;
1288   utf = env_->GetStringUTFChars(s, &is_copy);
1289   EXPECT_EQ(JNI_TRUE, is_copy);
1290   EXPECT_STREQ("hello", utf);
1291   env_->ReleaseStringUTFChars(s, utf);
1292 }
1293 
TEST_F(JniInternalTest,GetStringChars_ReleaseStringChars)1294 TEST_F(JniInternalTest, GetStringChars_ReleaseStringChars) {
1295   jstring s = env_->NewStringUTF("hello");
1296   ASSERT_TRUE(s != NULL);
1297 
1298   jchar expected[] = { 'h', 'e', 'l', 'l', 'o' };
1299   const jchar* chars = env_->GetStringChars(s, NULL);
1300   EXPECT_EQ(expected[0], chars[0]);
1301   EXPECT_EQ(expected[1], chars[1]);
1302   EXPECT_EQ(expected[2], chars[2]);
1303   EXPECT_EQ(expected[3], chars[3]);
1304   EXPECT_EQ(expected[4], chars[4]);
1305   env_->ReleaseStringChars(s, chars);
1306 
1307   jboolean is_copy = JNI_FALSE;
1308   chars = env_->GetStringChars(s, &is_copy);
1309   EXPECT_EQ(JNI_FALSE, is_copy);
1310   EXPECT_EQ(expected[0], chars[0]);
1311   EXPECT_EQ(expected[1], chars[1]);
1312   EXPECT_EQ(expected[2], chars[2]);
1313   EXPECT_EQ(expected[3], chars[3]);
1314   EXPECT_EQ(expected[4], chars[4]);
1315   env_->ReleaseStringChars(s, chars);
1316 }
1317 
TEST_F(JniInternalTest,GetStringCritical_ReleaseStringCritical)1318 TEST_F(JniInternalTest, GetStringCritical_ReleaseStringCritical) {
1319   jstring s = env_->NewStringUTF("hello");
1320   ASSERT_TRUE(s != NULL);
1321 
1322   jchar expected[] = { 'h', 'e', 'l', 'l', 'o' };
1323   const jchar* chars = env_->GetStringCritical(s, NULL);
1324   EXPECT_EQ(expected[0], chars[0]);
1325   EXPECT_EQ(expected[1], chars[1]);
1326   EXPECT_EQ(expected[2], chars[2]);
1327   EXPECT_EQ(expected[3], chars[3]);
1328   EXPECT_EQ(expected[4], chars[4]);
1329   env_->ReleaseStringCritical(s, chars);
1330 
1331   jboolean is_copy = JNI_FALSE;
1332   chars = env_->GetStringCritical(s, &is_copy);
1333   EXPECT_EQ(JNI_FALSE, is_copy);
1334   EXPECT_EQ(expected[0], chars[0]);
1335   EXPECT_EQ(expected[1], chars[1]);
1336   EXPECT_EQ(expected[2], chars[2]);
1337   EXPECT_EQ(expected[3], chars[3]);
1338   EXPECT_EQ(expected[4], chars[4]);
1339   env_->ReleaseStringCritical(s, chars);
1340 }
1341 
TEST_F(JniInternalTest,GetObjectArrayElement_SetObjectArrayElement)1342 TEST_F(JniInternalTest, GetObjectArrayElement_SetObjectArrayElement) {
1343   jclass java_lang_Class = env_->FindClass("java/lang/Class");
1344   ASSERT_TRUE(java_lang_Class != NULL);
1345 
1346   jobjectArray array = env_->NewObjectArray(1, java_lang_Class, NULL);
1347   EXPECT_TRUE(array != NULL);
1348   EXPECT_TRUE(env_->GetObjectArrayElement(array, 0) == NULL);
1349   env_->SetObjectArrayElement(array, 0, java_lang_Class);
1350   EXPECT_TRUE(env_->IsSameObject(env_->GetObjectArrayElement(array, 0), java_lang_Class));
1351 
1352   // ArrayIndexOutOfBounds for negative index.
1353   env_->SetObjectArrayElement(array, -1, java_lang_Class);
1354   EXPECT_EXCEPTION(aioobe_);
1355 
1356   // ArrayIndexOutOfBounds for too-large index.
1357   env_->SetObjectArrayElement(array, 1, java_lang_Class);
1358   EXPECT_EXCEPTION(aioobe_);
1359 
1360   // ArrayStoreException thrown for bad types.
1361   env_->SetObjectArrayElement(array, 0, env_->NewStringUTF("not a jclass!"));
1362   EXPECT_EXCEPTION(ase_);
1363 }
1364 
1365 #define EXPECT_STATIC_PRIMITIVE_FIELD(type, field_name, sig, value1, value2) \
1366   do { \
1367     jfieldID fid = env_->GetStaticFieldID(c, field_name, sig); \
1368     EXPECT_TRUE(fid != NULL); \
1369     env_->SetStatic ## type ## Field(c, fid, value1); \
1370     EXPECT_TRUE(value1 == env_->GetStatic ## type ## Field(c, fid)); \
1371     env_->SetStatic ## type ## Field(c, fid, value2); \
1372     EXPECT_TRUE(value2 == env_->GetStatic ## type ## Field(c, fid)); \
1373   } while (false)
1374 
1375 #define EXPECT_PRIMITIVE_FIELD(instance, type, field_name, sig, value1, value2) \
1376   do { \
1377     jfieldID fid = env_->GetFieldID(c, field_name, sig); \
1378     EXPECT_TRUE(fid != NULL); \
1379     env_->Set ## type ## Field(instance, fid, value1); \
1380     EXPECT_TRUE(value1 == env_->Get ## type ## Field(instance, fid)); \
1381     env_->Set ## type ## Field(instance, fid, value2); \
1382     EXPECT_TRUE(value2 == env_->Get ## type ## Field(instance, fid)); \
1383   } while (false)
1384 
1385 
1386 #if !defined(ART_USE_PORTABLE_COMPILER)
TEST_F(JniInternalTest,GetPrimitiveField_SetPrimitiveField)1387 TEST_F(JniInternalTest, GetPrimitiveField_SetPrimitiveField) {
1388   Thread::Current()->TransitionFromSuspendedToRunnable();
1389   LoadDex("AllFields");
1390   bool started = runtime_->Start();
1391   CHECK(started);
1392 
1393   jclass c = env_->FindClass("AllFields");
1394   ASSERT_TRUE(c != NULL);
1395   jobject o = env_->AllocObject(c);
1396   ASSERT_TRUE(o != NULL);
1397 
1398   EXPECT_STATIC_PRIMITIVE_FIELD(Boolean, "sZ", "Z", true, false);
1399   EXPECT_STATIC_PRIMITIVE_FIELD(Byte, "sB", "B", 1, 2);
1400   EXPECT_STATIC_PRIMITIVE_FIELD(Char, "sC", "C", 'a', 'b');
1401   EXPECT_STATIC_PRIMITIVE_FIELD(Double, "sD", "D", 1.0, 2.0);
1402   EXPECT_STATIC_PRIMITIVE_FIELD(Float, "sF", "F", 1.0, 2.0);
1403   EXPECT_STATIC_PRIMITIVE_FIELD(Int, "sI", "I", 1, 2);
1404   EXPECT_STATIC_PRIMITIVE_FIELD(Long, "sJ", "J", 1, 2);
1405   EXPECT_STATIC_PRIMITIVE_FIELD(Short, "sS", "S", 1, 2);
1406 
1407   EXPECT_PRIMITIVE_FIELD(o, Boolean, "iZ", "Z", true, false);
1408   EXPECT_PRIMITIVE_FIELD(o, Byte, "iB", "B", 1, 2);
1409   EXPECT_PRIMITIVE_FIELD(o, Char, "iC", "C", 'a', 'b');
1410   EXPECT_PRIMITIVE_FIELD(o, Double, "iD", "D", 1.0, 2.0);
1411   EXPECT_PRIMITIVE_FIELD(o, Float, "iF", "F", 1.0, 2.0);
1412   EXPECT_PRIMITIVE_FIELD(o, Int, "iI", "I", 1, 2);
1413   EXPECT_PRIMITIVE_FIELD(o, Long, "iJ", "J", 1, 2);
1414   EXPECT_PRIMITIVE_FIELD(o, Short, "iS", "S", 1, 2);
1415 }
1416 
TEST_F(JniInternalTest,GetObjectField_SetObjectField)1417 TEST_F(JniInternalTest, GetObjectField_SetObjectField) {
1418   Thread::Current()->TransitionFromSuspendedToRunnable();
1419   LoadDex("AllFields");
1420   runtime_->Start();
1421 
1422   jclass c = env_->FindClass("AllFields");
1423   ASSERT_TRUE(c != NULL);
1424   jobject o = env_->AllocObject(c);
1425   ASSERT_TRUE(o != NULL);
1426 
1427   jstring s1 = env_->NewStringUTF("hello");
1428   ASSERT_TRUE(s1 != NULL);
1429   jstring s2 = env_->NewStringUTF("world");
1430   ASSERT_TRUE(s2 != NULL);
1431 
1432   jfieldID s_fid = env_->GetStaticFieldID(c, "sObject", "Ljava/lang/Object;");
1433   ASSERT_TRUE(s_fid != NULL);
1434   jfieldID i_fid = env_->GetFieldID(c, "iObject", "Ljava/lang/Object;");
1435   ASSERT_TRUE(i_fid != NULL);
1436 
1437   env_->SetStaticObjectField(c, s_fid, s1);
1438   ASSERT_TRUE(env_->IsSameObject(s1, env_->GetStaticObjectField(c, s_fid)));
1439   env_->SetStaticObjectField(c, s_fid, s2);
1440   ASSERT_TRUE(env_->IsSameObject(s2, env_->GetStaticObjectField(c, s_fid)));
1441 
1442   env_->SetObjectField(o, i_fid, s1);
1443   ASSERT_TRUE(env_->IsSameObject(s1, env_->GetObjectField(o, i_fid)));
1444   env_->SetObjectField(o, i_fid, s2);
1445   ASSERT_TRUE(env_->IsSameObject(s2, env_->GetObjectField(o, i_fid)));
1446 }
1447 #endif
1448 
TEST_F(JniInternalTest,NewLocalRef_NULL)1449 TEST_F(JniInternalTest, NewLocalRef_NULL) {
1450   EXPECT_TRUE(env_->NewLocalRef(NULL) == NULL);
1451 }
1452 
TEST_F(JniInternalTest,NewLocalRef)1453 TEST_F(JniInternalTest, NewLocalRef) {
1454   jstring s = env_->NewStringUTF("");
1455   ASSERT_TRUE(s != NULL);
1456   jobject o = env_->NewLocalRef(s);
1457   EXPECT_TRUE(o != NULL);
1458   EXPECT_TRUE(o != s);
1459 
1460   EXPECT_EQ(JNILocalRefType, env_->GetObjectRefType(o));
1461 }
1462 
TEST_F(JniInternalTest,DeleteLocalRef_NULL)1463 TEST_F(JniInternalTest, DeleteLocalRef_NULL) {
1464   env_->DeleteLocalRef(NULL);
1465 }
1466 
TEST_F(JniInternalTest,DeleteLocalRef)1467 TEST_F(JniInternalTest, DeleteLocalRef) {
1468   jstring s = env_->NewStringUTF("");
1469   ASSERT_TRUE(s != NULL);
1470   env_->DeleteLocalRef(s);
1471 
1472   // Currently, deleting an already-deleted reference is just a CheckJNI warning.
1473   {
1474     CheckJniAbortCatcher check_jni_abort_catcher;
1475     env_->DeleteLocalRef(s);
1476 
1477     std::string expected(StringPrintf("native code passing in reference to "
1478                                       "invalid local reference: %p", s));
1479     check_jni_abort_catcher.Check(expected.c_str());
1480   }
1481 
1482   s = env_->NewStringUTF("");
1483   ASSERT_TRUE(s != NULL);
1484   jobject o = env_->NewLocalRef(s);
1485   ASSERT_TRUE(o != NULL);
1486 
1487   env_->DeleteLocalRef(s);
1488   env_->DeleteLocalRef(o);
1489 }
1490 
TEST_F(JniInternalTest,PushLocalFrame_10395422)1491 TEST_F(JniInternalTest, PushLocalFrame_10395422) {
1492   // The JNI specification is ambiguous about whether the given capacity is to be interpreted as a
1493   // maximum or as a minimum, but it seems like it's supposed to be a minimum, and that's how
1494   // Android historically treated it, and it's how the RI treats it. It's also the more useful
1495   // interpretation!
1496   ASSERT_EQ(JNI_OK, env_->PushLocalFrame(0));
1497   env_->PopLocalFrame(NULL);
1498 
1499   // Negative capacities are not allowed.
1500   ASSERT_EQ(JNI_ERR, env_->PushLocalFrame(-1));
1501 
1502   // And it's okay to have an upper limit. Ours is currently 512.
1503   ASSERT_EQ(JNI_ERR, env_->PushLocalFrame(8192));
1504 }
1505 
TEST_F(JniInternalTest,PushLocalFrame_PopLocalFrame)1506 TEST_F(JniInternalTest, PushLocalFrame_PopLocalFrame) {
1507   jobject original = env_->NewStringUTF("");
1508   ASSERT_TRUE(original != NULL);
1509 
1510   jobject outer;
1511   jobject inner1, inner2;
1512   ScopedObjectAccess soa(env_);
1513   mirror::Object* inner2_direct_pointer;
1514   {
1515     ASSERT_EQ(JNI_OK, env_->PushLocalFrame(4));
1516     outer = env_->NewLocalRef(original);
1517 
1518     {
1519       ASSERT_EQ(JNI_OK, env_->PushLocalFrame(4));
1520       inner1 = env_->NewLocalRef(outer);
1521       inner2 = env_->NewStringUTF("survivor");
1522       inner2_direct_pointer = soa.Decode<mirror::Object*>(inner2);
1523       env_->PopLocalFrame(inner2);
1524     }
1525 
1526     EXPECT_EQ(JNILocalRefType, env_->GetObjectRefType(original));
1527     EXPECT_EQ(JNILocalRefType, env_->GetObjectRefType(outer));
1528     EXPECT_EQ(JNIInvalidRefType, env_->GetObjectRefType(inner1));
1529 
1530     // Our local reference for the survivor is invalid because the survivor
1531     // gets a new local reference...
1532     EXPECT_EQ(JNIInvalidRefType, env_->GetObjectRefType(inner2));
1533     // ...but the survivor should be in the local reference table.
1534     JNIEnvExt* env = reinterpret_cast<JNIEnvExt*>(env_);
1535     EXPECT_TRUE(env->locals.ContainsDirectPointer(inner2_direct_pointer));
1536 
1537     env_->PopLocalFrame(NULL);
1538   }
1539   EXPECT_EQ(JNILocalRefType, env_->GetObjectRefType(original));
1540   EXPECT_EQ(JNIInvalidRefType, env_->GetObjectRefType(outer));
1541   EXPECT_EQ(JNIInvalidRefType, env_->GetObjectRefType(inner1));
1542   EXPECT_EQ(JNIInvalidRefType, env_->GetObjectRefType(inner2));
1543 }
1544 
TEST_F(JniInternalTest,NewGlobalRef_NULL)1545 TEST_F(JniInternalTest, NewGlobalRef_NULL) {
1546   EXPECT_TRUE(env_->NewGlobalRef(NULL) == NULL);
1547 }
1548 
TEST_F(JniInternalTest,NewGlobalRef)1549 TEST_F(JniInternalTest, NewGlobalRef) {
1550   jstring s = env_->NewStringUTF("");
1551   ASSERT_TRUE(s != NULL);
1552   jobject o = env_->NewGlobalRef(s);
1553   EXPECT_TRUE(o != NULL);
1554   EXPECT_TRUE(o != s);
1555 
1556   // TODO: check that o is a global reference.
1557 }
1558 
TEST_F(JniInternalTest,DeleteGlobalRef_NULL)1559 TEST_F(JniInternalTest, DeleteGlobalRef_NULL) {
1560   env_->DeleteGlobalRef(NULL);
1561 }
1562 
TEST_F(JniInternalTest,DeleteGlobalRef)1563 TEST_F(JniInternalTest, DeleteGlobalRef) {
1564   jstring s = env_->NewStringUTF("");
1565   ASSERT_TRUE(s != NULL);
1566 
1567   jobject o = env_->NewGlobalRef(s);
1568   ASSERT_TRUE(o != NULL);
1569   env_->DeleteGlobalRef(o);
1570 
1571   // Currently, deleting an already-deleted reference is just a CheckJNI warning.
1572   {
1573     CheckJniAbortCatcher check_jni_abort_catcher;
1574     env_->DeleteGlobalRef(o);
1575 
1576     std::string expected(StringPrintf("native code passing in reference to "
1577                                       "invalid global reference: %p", o));
1578     check_jni_abort_catcher.Check(expected.c_str());
1579   }
1580 
1581   jobject o1 = env_->NewGlobalRef(s);
1582   ASSERT_TRUE(o1 != NULL);
1583   jobject o2 = env_->NewGlobalRef(s);
1584   ASSERT_TRUE(o2 != NULL);
1585 
1586   env_->DeleteGlobalRef(o1);
1587   env_->DeleteGlobalRef(o2);
1588 }
1589 
TEST_F(JniInternalTest,NewWeakGlobalRef_NULL)1590 TEST_F(JniInternalTest, NewWeakGlobalRef_NULL) {
1591   EXPECT_TRUE(env_->NewWeakGlobalRef(NULL) == NULL);
1592 }
1593 
TEST_F(JniInternalTest,NewWeakGlobalRef)1594 TEST_F(JniInternalTest, NewWeakGlobalRef) {
1595   jstring s = env_->NewStringUTF("");
1596   ASSERT_TRUE(s != NULL);
1597   jobject o = env_->NewWeakGlobalRef(s);
1598   EXPECT_TRUE(o != NULL);
1599   EXPECT_TRUE(o != s);
1600 
1601   // TODO: check that o is a weak global reference.
1602 }
1603 
TEST_F(JniInternalTest,DeleteWeakGlobalRef_NULL)1604 TEST_F(JniInternalTest, DeleteWeakGlobalRef_NULL) {
1605   env_->DeleteWeakGlobalRef(NULL);
1606 }
1607 
TEST_F(JniInternalTest,DeleteWeakGlobalRef)1608 TEST_F(JniInternalTest, DeleteWeakGlobalRef) {
1609   jstring s = env_->NewStringUTF("");
1610   ASSERT_TRUE(s != NULL);
1611 
1612   jobject o = env_->NewWeakGlobalRef(s);
1613   ASSERT_TRUE(o != NULL);
1614   env_->DeleteWeakGlobalRef(o);
1615 
1616   // Currently, deleting an already-deleted reference is just a CheckJNI warning.
1617   {
1618     CheckJniAbortCatcher check_jni_abort_catcher;
1619     env_->DeleteWeakGlobalRef(o);
1620 
1621     std::string expected(StringPrintf("native code passing in reference to "
1622                                       "invalid weak global reference: %p", o));
1623     check_jni_abort_catcher.Check(expected.c_str());
1624   }
1625 
1626   jobject o1 = env_->NewWeakGlobalRef(s);
1627   ASSERT_TRUE(o1 != NULL);
1628   jobject o2 = env_->NewWeakGlobalRef(s);
1629   ASSERT_TRUE(o2 != NULL);
1630 
1631   env_->DeleteWeakGlobalRef(o1);
1632   env_->DeleteWeakGlobalRef(o2);
1633 }
1634 
TEST_F(JniInternalTest,StaticMainMethod)1635 TEST_F(JniInternalTest, StaticMainMethod) {
1636   TEST_DISABLED_FOR_PORTABLE();
1637   ScopedObjectAccess soa(Thread::Current());
1638   jobject jclass_loader = LoadDex("Main");
1639   SirtRef<mirror::ClassLoader>
1640       class_loader(soa.Self(), soa.Decode<mirror::ClassLoader*>(jclass_loader));
1641   CompileDirectMethod(class_loader.get(), "Main", "main", "([Ljava/lang/String;)V");
1642 
1643   mirror::Class* klass = class_linker_->FindClass("LMain;", class_loader.get());
1644   ASSERT_TRUE(klass != NULL);
1645 
1646   mirror::ArtMethod* method = klass->FindDirectMethod("main", "([Ljava/lang/String;)V");
1647   ASSERT_TRUE(method != NULL);
1648 
1649   ArgArray arg_array(NULL, 0);
1650   arg_array.Append(0);
1651   JValue result;
1652 
1653   // Start runtime.
1654   bool started = runtime_->Start();
1655   CHECK(started);
1656   Thread::Current()->TransitionFromSuspendedToRunnable();
1657 
1658   method->Invoke(Thread::Current(), arg_array.GetArray(), arg_array.GetNumBytes(), &result, 'V');
1659 }
1660 
TEST_F(JniInternalTest,StaticNopMethod)1661 TEST_F(JniInternalTest, StaticNopMethod) {
1662   TEST_DISABLED_FOR_PORTABLE();
1663   ScopedObjectAccess soa(Thread::Current());
1664   InvokeNopMethod(true);
1665 }
1666 
TEST_F(JniInternalTest,NonStaticNopMethod)1667 TEST_F(JniInternalTest, NonStaticNopMethod) {
1668   TEST_DISABLED_FOR_PORTABLE();
1669   ScopedObjectAccess soa(Thread::Current());
1670   InvokeNopMethod(false);
1671 }
1672 
TEST_F(JniInternalTest,StaticIdentityByteMethod)1673 TEST_F(JniInternalTest, StaticIdentityByteMethod) {
1674   TEST_DISABLED_FOR_PORTABLE();
1675   ScopedObjectAccess soa(Thread::Current());
1676   InvokeIdentityByteMethod(true);
1677 }
1678 
TEST_F(JniInternalTest,NonStaticIdentityByteMethod)1679 TEST_F(JniInternalTest, NonStaticIdentityByteMethod) {
1680   TEST_DISABLED_FOR_PORTABLE();
1681   ScopedObjectAccess soa(Thread::Current());
1682   InvokeIdentityByteMethod(false);
1683 }
1684 
TEST_F(JniInternalTest,StaticIdentityIntMethod)1685 TEST_F(JniInternalTest, StaticIdentityIntMethod) {
1686   TEST_DISABLED_FOR_PORTABLE();
1687   ScopedObjectAccess soa(Thread::Current());
1688   InvokeIdentityIntMethod(true);
1689 }
1690 
TEST_F(JniInternalTest,NonStaticIdentityIntMethod)1691 TEST_F(JniInternalTest, NonStaticIdentityIntMethod) {
1692   TEST_DISABLED_FOR_PORTABLE();
1693   ScopedObjectAccess soa(Thread::Current());
1694   InvokeIdentityIntMethod(false);
1695 }
1696 
TEST_F(JniInternalTest,StaticIdentityDoubleMethod)1697 TEST_F(JniInternalTest, StaticIdentityDoubleMethod) {
1698   TEST_DISABLED_FOR_PORTABLE();
1699   ScopedObjectAccess soa(Thread::Current());
1700   InvokeIdentityDoubleMethod(true);
1701 }
1702 
TEST_F(JniInternalTest,NonStaticIdentityDoubleMethod)1703 TEST_F(JniInternalTest, NonStaticIdentityDoubleMethod) {
1704   TEST_DISABLED_FOR_PORTABLE();
1705   ScopedObjectAccess soa(Thread::Current());
1706   InvokeIdentityDoubleMethod(false);
1707 }
1708 
TEST_F(JniInternalTest,StaticSumIntIntMethod)1709 TEST_F(JniInternalTest, StaticSumIntIntMethod) {
1710   TEST_DISABLED_FOR_PORTABLE();
1711   ScopedObjectAccess soa(Thread::Current());
1712   InvokeSumIntIntMethod(true);
1713 }
1714 
TEST_F(JniInternalTest,NonStaticSumIntIntMethod)1715 TEST_F(JniInternalTest, NonStaticSumIntIntMethod) {
1716   TEST_DISABLED_FOR_PORTABLE();
1717   ScopedObjectAccess soa(Thread::Current());
1718   InvokeSumIntIntMethod(false);
1719 }
1720 
TEST_F(JniInternalTest,StaticSumIntIntIntMethod)1721 TEST_F(JniInternalTest, StaticSumIntIntIntMethod) {
1722   TEST_DISABLED_FOR_PORTABLE();
1723   ScopedObjectAccess soa(Thread::Current());
1724   InvokeSumIntIntIntMethod(true);
1725 }
1726 
TEST_F(JniInternalTest,NonStaticSumIntIntIntMethod)1727 TEST_F(JniInternalTest, NonStaticSumIntIntIntMethod) {
1728   TEST_DISABLED_FOR_PORTABLE();
1729   ScopedObjectAccess soa(Thread::Current());
1730   InvokeSumIntIntIntMethod(false);
1731 }
1732 
TEST_F(JniInternalTest,StaticSumIntIntIntIntMethod)1733 TEST_F(JniInternalTest, StaticSumIntIntIntIntMethod) {
1734   TEST_DISABLED_FOR_PORTABLE();
1735   ScopedObjectAccess soa(Thread::Current());
1736   InvokeSumIntIntIntIntMethod(true);
1737 }
1738 
TEST_F(JniInternalTest,NonStaticSumIntIntIntIntMethod)1739 TEST_F(JniInternalTest, NonStaticSumIntIntIntIntMethod) {
1740   TEST_DISABLED_FOR_PORTABLE();
1741   ScopedObjectAccess soa(Thread::Current());
1742   InvokeSumIntIntIntIntMethod(false);
1743 }
1744 
TEST_F(JniInternalTest,StaticSumIntIntIntIntIntMethod)1745 TEST_F(JniInternalTest, StaticSumIntIntIntIntIntMethod) {
1746   TEST_DISABLED_FOR_PORTABLE();
1747   ScopedObjectAccess soa(Thread::Current());
1748   InvokeSumIntIntIntIntIntMethod(true);
1749 }
1750 
TEST_F(JniInternalTest,NonStaticSumIntIntIntIntIntMethod)1751 TEST_F(JniInternalTest, NonStaticSumIntIntIntIntIntMethod) {
1752   TEST_DISABLED_FOR_PORTABLE();
1753   ScopedObjectAccess soa(Thread::Current());
1754   InvokeSumIntIntIntIntIntMethod(false);
1755 }
1756 
TEST_F(JniInternalTest,StaticSumDoubleDoubleMethod)1757 TEST_F(JniInternalTest, StaticSumDoubleDoubleMethod) {
1758   TEST_DISABLED_FOR_PORTABLE();
1759   ScopedObjectAccess soa(Thread::Current());
1760   InvokeSumDoubleDoubleMethod(true);
1761 }
1762 
TEST_F(JniInternalTest,NonStaticSumDoubleDoubleMethod)1763 TEST_F(JniInternalTest, NonStaticSumDoubleDoubleMethod) {
1764   TEST_DISABLED_FOR_PORTABLE();
1765   ScopedObjectAccess soa(Thread::Current());
1766   InvokeSumDoubleDoubleMethod(false);
1767 }
1768 
TEST_F(JniInternalTest,StaticSumDoubleDoubleDoubleMethod)1769 TEST_F(JniInternalTest, StaticSumDoubleDoubleDoubleMethod) {
1770   TEST_DISABLED_FOR_PORTABLE();
1771   ScopedObjectAccess soa(Thread::Current());
1772   InvokeSumDoubleDoubleDoubleMethod(true);
1773 }
1774 
TEST_F(JniInternalTest,NonStaticSumDoubleDoubleDoubleMethod)1775 TEST_F(JniInternalTest, NonStaticSumDoubleDoubleDoubleMethod) {
1776   TEST_DISABLED_FOR_PORTABLE();
1777   ScopedObjectAccess soa(Thread::Current());
1778   InvokeSumDoubleDoubleDoubleMethod(false);
1779 }
1780 
TEST_F(JniInternalTest,StaticSumDoubleDoubleDoubleDoubleMethod)1781 TEST_F(JniInternalTest, StaticSumDoubleDoubleDoubleDoubleMethod) {
1782   TEST_DISABLED_FOR_PORTABLE();
1783   ScopedObjectAccess soa(Thread::Current());
1784   InvokeSumDoubleDoubleDoubleDoubleMethod(true);
1785 }
1786 
TEST_F(JniInternalTest,NonStaticSumDoubleDoubleDoubleDoubleMethod)1787 TEST_F(JniInternalTest, NonStaticSumDoubleDoubleDoubleDoubleMethod) {
1788   TEST_DISABLED_FOR_PORTABLE();
1789   ScopedObjectAccess soa(Thread::Current());
1790   InvokeSumDoubleDoubleDoubleDoubleMethod(false);
1791 }
1792 
TEST_F(JniInternalTest,StaticSumDoubleDoubleDoubleDoubleDoubleMethod)1793 TEST_F(JniInternalTest, StaticSumDoubleDoubleDoubleDoubleDoubleMethod) {
1794   TEST_DISABLED_FOR_PORTABLE();
1795   ScopedObjectAccess soa(Thread::Current());
1796   InvokeSumDoubleDoubleDoubleDoubleDoubleMethod(true);
1797 }
1798 
TEST_F(JniInternalTest,NonStaticSumDoubleDoubleDoubleDoubleDoubleMethod)1799 TEST_F(JniInternalTest, NonStaticSumDoubleDoubleDoubleDoubleDoubleMethod) {
1800   TEST_DISABLED_FOR_PORTABLE();
1801   ScopedObjectAccess soa(Thread::Current());
1802   InvokeSumDoubleDoubleDoubleDoubleDoubleMethod(false);
1803 }
1804 
TEST_F(JniInternalTest,Throw)1805 TEST_F(JniInternalTest, Throw) {
1806   EXPECT_EQ(JNI_ERR, env_->Throw(NULL));
1807 
1808   jclass exception_class = env_->FindClass("java/lang/RuntimeException");
1809   ASSERT_TRUE(exception_class != NULL);
1810   jthrowable exception = reinterpret_cast<jthrowable>(env_->AllocObject(exception_class));
1811   ASSERT_TRUE(exception != NULL);
1812 
1813   EXPECT_EQ(JNI_OK, env_->Throw(exception));
1814   EXPECT_TRUE(env_->ExceptionCheck());
1815   jthrowable thrown_exception = env_->ExceptionOccurred();
1816   env_->ExceptionClear();
1817   EXPECT_TRUE(env_->IsSameObject(exception, thrown_exception));
1818 }
1819 
TEST_F(JniInternalTest,ThrowNew)1820 TEST_F(JniInternalTest, ThrowNew) {
1821   EXPECT_EQ(JNI_ERR, env_->Throw(NULL));
1822 
1823   jclass exception_class = env_->FindClass("java/lang/RuntimeException");
1824   ASSERT_TRUE(exception_class != NULL);
1825 
1826   jthrowable thrown_exception;
1827 
1828   EXPECT_EQ(JNI_OK, env_->ThrowNew(exception_class, "hello world"));
1829   EXPECT_TRUE(env_->ExceptionCheck());
1830   thrown_exception = env_->ExceptionOccurred();
1831   env_->ExceptionClear();
1832   EXPECT_TRUE(env_->IsInstanceOf(thrown_exception, exception_class));
1833 
1834   EXPECT_EQ(JNI_OK, env_->ThrowNew(exception_class, NULL));
1835   EXPECT_TRUE(env_->ExceptionCheck());
1836   thrown_exception = env_->ExceptionOccurred();
1837   env_->ExceptionClear();
1838   EXPECT_TRUE(env_->IsInstanceOf(thrown_exception, exception_class));
1839 }
1840 
1841 // TODO: this test is DISABLED until we can actually run java.nio.Buffer's <init>.
TEST_F(JniInternalTest,DISABLED_NewDirectBuffer_GetDirectBufferAddress_GetDirectBufferCapacity)1842 TEST_F(JniInternalTest, DISABLED_NewDirectBuffer_GetDirectBufferAddress_GetDirectBufferCapacity) {
1843   jclass buffer_class = env_->FindClass("java/nio/Buffer");
1844   ASSERT_TRUE(buffer_class != NULL);
1845 
1846   char bytes[1024];
1847   jobject buffer = env_->NewDirectByteBuffer(bytes, sizeof(bytes));
1848   ASSERT_TRUE(buffer != NULL);
1849   ASSERT_TRUE(env_->IsInstanceOf(buffer, buffer_class));
1850   ASSERT_TRUE(env_->GetDirectBufferAddress(buffer) == bytes);
1851   ASSERT_TRUE(env_->GetDirectBufferCapacity(buffer) == sizeof(bytes));
1852 }
1853 
TEST_F(JniInternalTest,MonitorEnterExit)1854 TEST_F(JniInternalTest, MonitorEnterExit) {
1855   // Create an object to torture
1856   jclass object_class = env_->FindClass("java/lang/Object");
1857   ASSERT_TRUE(object_class != NULL);
1858   jobject object = env_->AllocObject(object_class);
1859   ASSERT_TRUE(object != NULL);
1860 
1861   // Expected class of exceptions
1862   jclass imse_class = env_->FindClass("java/lang/IllegalMonitorStateException");
1863   ASSERT_TRUE(imse_class != NULL);
1864 
1865   jthrowable thrown_exception;
1866 
1867   // Unlock of unowned monitor
1868   env_->MonitorExit(object);
1869   EXPECT_TRUE(env_->ExceptionCheck());
1870   thrown_exception = env_->ExceptionOccurred();
1871   env_->ExceptionClear();
1872   EXPECT_TRUE(env_->IsInstanceOf(thrown_exception, imse_class));
1873 
1874   // Lock of unowned monitor
1875   env_->MonitorEnter(object);
1876   EXPECT_FALSE(env_->ExceptionCheck());
1877   // Regular unlock
1878   env_->MonitorExit(object);
1879   EXPECT_FALSE(env_->ExceptionCheck());
1880 
1881   // Recursively lock a lot
1882   size_t max_recursive_lock = 1024;
1883   for (size_t i = 0; i < max_recursive_lock; i++) {
1884     env_->MonitorEnter(object);
1885     EXPECT_FALSE(env_->ExceptionCheck());
1886   }
1887   // Recursively unlock a lot
1888   for (size_t i = 0; i < max_recursive_lock; i++) {
1889     env_->MonitorExit(object);
1890     EXPECT_FALSE(env_->ExceptionCheck());
1891   }
1892 
1893   // Unlock of unowned monitor
1894   env_->MonitorExit(object);
1895   EXPECT_TRUE(env_->ExceptionCheck());
1896   thrown_exception = env_->ExceptionOccurred();
1897   env_->ExceptionClear();
1898   EXPECT_TRUE(env_->IsInstanceOf(thrown_exception, imse_class));
1899 
1900   // It's an error to call MonitorEnter or MonitorExit on NULL.
1901   {
1902     CheckJniAbortCatcher check_jni_abort_catcher;
1903     env_->MonitorEnter(NULL);
1904     check_jni_abort_catcher.Check("in call to MonitorEnter");
1905 
1906     env_->MonitorExit(NULL);
1907     check_jni_abort_catcher.Check("in call to MonitorExit");
1908   }
1909 }
1910 
TEST_F(JniInternalTest,DetachCurrentThread)1911 TEST_F(JniInternalTest, DetachCurrentThread) {
1912   CleanUpJniEnv();  // cleanup now so TearDown won't have junk from wrong JNIEnv
1913   jint ok = vm_->DetachCurrentThread();
1914   EXPECT_EQ(JNI_OK, ok);
1915 
1916   jint err = vm_->DetachCurrentThread();
1917   EXPECT_EQ(JNI_ERR, err);
1918   vm_->AttachCurrentThread(&env_, NULL);  // need attached thread for CommonTest::TearDown
1919 }
1920 
1921 }  // namespace art
1922