blob: 8f7884d956e273d0ebc6b4484d9c2f3a3254ca17 [file] [log] [blame]
Elliott Hughes2faa5f12012-01-30 14:42:07 -08001/*
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 */
Elliott Hughes0c9cd562011-08-12 10:59:29 -070016
Carl Shapiro9b9ba282011-08-14 15:30:39 -070017#include "jni_internal.h"
Elliott Hughes0c9cd562011-08-12 10:59:29 -070018
Carl Shapiro9b9ba282011-08-14 15:30:39 -070019#include <sys/mman.h>
20
Ian Rogers0cfe1fb2011-08-26 03:29:44 -070021#include <cmath>
22
Carl Shapiro9b9ba282011-08-14 15:30:39 -070023#include "common_test.h"
Elliott Hughes726079d2011-10-07 18:43:44 -070024#include "ScopedLocalRef.h"
Elliott Hughes0c9cd562011-08-12 10:59:29 -070025
26namespace art {
27
Brian Carlstromf734cf52011-08-17 16:28:14 -070028class JniInternalTest : public CommonTest {
Elliott Hughesc7ac37f2011-08-12 12:21:58 -070029 protected:
30 virtual void SetUp() {
Brian Carlstromf734cf52011-08-17 16:28:14 -070031 CommonTest::SetUp();
Elliott Hughes5174fe62011-08-23 15:12:35 -070032
Elliott Hughesa2501992011-08-26 19:39:54 -070033 vm_ = Runtime::Current()->GetJavaVM();
34
Elliott Hughes5174fe62011-08-23 15:12:35 -070035 // Turn on -verbose:jni for the JNI tests.
Elliott Hughes4dd9b4d2011-12-12 18:29:24 -080036 gLogVerbosity.jni = true;
Elliott Hughes5174fe62011-08-23 15:12:35 -070037
Elliott Hughesc7ac37f2011-08-12 12:21:58 -070038 env_ = Thread::Current()->GetJniEnv();
Elliott Hughesb465ab02011-08-24 11:21:21 -070039
Elliott Hughes726079d2011-10-07 18:43:44 -070040 ScopedLocalRef<jclass> aioobe(env_, env_->FindClass("java/lang/ArrayIndexOutOfBoundsException"));
41 CHECK(aioobe.get() != NULL);
42 aioobe_ = reinterpret_cast<jclass>(env_->NewGlobalRef(aioobe.get()));
Elliott Hughesb465ab02011-08-24 11:21:21 -070043
Elliott Hughesb264f082012-04-06 17:10:10 -070044 ScopedLocalRef<jclass> ase(env_, env_->FindClass("java/lang/ArrayStoreException"));
45 CHECK(ase.get() != NULL);
46 ase_ = reinterpret_cast<jclass>(env_->NewGlobalRef(ase.get()));
47
Elliott Hughes726079d2011-10-07 18:43:44 -070048 ScopedLocalRef<jclass> sioobe(env_, env_->FindClass("java/lang/StringIndexOutOfBoundsException"));
49 CHECK(sioobe.get() != NULL);
50 sioobe_ = reinterpret_cast<jclass>(env_->NewGlobalRef(sioobe.get()));
51 }
52
53 virtual void TearDown() {
54 env_->DeleteGlobalRef(aioobe_);
Elliott Hughesb264f082012-04-06 17:10:10 -070055 env_->DeleteGlobalRef(ase_);
Elliott Hughes726079d2011-10-07 18:43:44 -070056 env_->DeleteGlobalRef(sioobe_);
57 CommonTest::TearDown();
Elliott Hughesc7ac37f2011-08-12 12:21:58 -070058 }
Elliott Hughesb465ab02011-08-24 11:21:21 -070059
Elliott Hughes77405792012-03-15 15:22:12 -070060 Method::InvokeStub* DoCompile(Method*& method, Object*& receiver, bool is_static, const char* method_name, const char* method_signature) {
61 const char* class_name = is_static ? "StaticLeafMethods" : "NonStaticLeafMethods";
62 SirtRef<ClassLoader> class_loader(LoadDex(class_name));
63 if (is_static) {
64 CompileDirectMethod(class_loader.get(), class_name, method_name, method_signature);
65 } else {
66 CompileVirtualMethod(NULL, "java.lang.Class", "isFinalizable", "()Z");
67 CompileDirectMethod(NULL, "java.lang.Object", "<init>", "()V");
68 CompileVirtualMethod(class_loader.get(), class_name, method_name, method_signature);
69 }
70
71 Class* c = class_linker_->FindClass(DotToDescriptor(class_name).c_str(), class_loader.get());
72 CHECK(c != NULL);
73
74 method = is_static ? c->FindDirectMethod(method_name, method_signature) : c->FindVirtualMethod(method_name, method_signature);
75 CHECK(method != NULL);
76
77 receiver = (is_static ? NULL : c->AllocObject());
78
79 Method::InvokeStub* stub = method->GetInvokeStub();
80 CHECK(stub != NULL);
81
82 return stub;
83 }
84
85 void InvokeNopMethod(bool is_static) {
Elliott Hughes77405792012-03-15 15:22:12 -070086 Method* method;
87 Object* receiver;
88 Method::InvokeStub* stub = DoCompile(method, receiver, is_static, "nop", "()V");
89 (*stub)(method, receiver, Thread::Current(), NULL, NULL);
90 }
91
92 void InvokeIdentityByteMethod(bool is_static) {
Elliott Hughes77405792012-03-15 15:22:12 -070093 Method* method;
94 Object* receiver;
95 Method::InvokeStub* stub = DoCompile(method, receiver, is_static, "identity", "(B)B");
96
97 JValue args[1];
98 JValue result;
99
100 args[0].i = 0;
101 result.b = -1;
102 (*stub)(method, receiver, Thread::Current(), args, &result);
103 EXPECT_EQ(0, result.b);
104
105 args[0].i = -1;
106 result.b = 0;
107 (*stub)(method, receiver, Thread::Current(), args, &result);
108 EXPECT_EQ(-1, result.b);
109
110 args[0].i = SCHAR_MAX;
111 result.b = 0;
112 (*stub)(method, receiver, Thread::Current(), args, &result);
113 EXPECT_EQ(SCHAR_MAX, result.b);
114
115 args[0].i = SCHAR_MIN;
116 result.b = 0;
117 (*stub)(method, receiver, Thread::Current(), args, &result);
118 EXPECT_EQ(SCHAR_MIN, result.b);
119 }
120
121 void InvokeIdentityIntMethod(bool is_static) {
Elliott Hughes77405792012-03-15 15:22:12 -0700122 Method* method;
123 Object* receiver;
124 Method::InvokeStub* stub = DoCompile(method, receiver, is_static, "identity", "(I)I");
125
126 JValue args[1];
127 JValue result;
128
129 args[0].i = 0;
130 result.i = -1;
131 (*stub)(method, receiver, Thread::Current(), args, &result);
132 EXPECT_EQ(0, result.i);
133
134 args[0].i = -1;
135 result.i = 0;
136 (*stub)(method, receiver, Thread::Current(), args, &result);
137 EXPECT_EQ(-1, result.i);
138
139 args[0].i = INT_MAX;
140 result.i = 0;
141 (*stub)(method, receiver, Thread::Current(), args, &result);
142 EXPECT_EQ(INT_MAX, result.i);
143
144 args[0].i = INT_MIN;
145 result.i = 0;
146 (*stub)(method, receiver, Thread::Current(), args, &result);
147 EXPECT_EQ(INT_MIN, result.i);
148 }
149
150 void InvokeIdentityDoubleMethod(bool is_static) {
Elliott Hughes77405792012-03-15 15:22:12 -0700151 Method* method;
152 Object* receiver;
153 Method::InvokeStub* stub = DoCompile(method, receiver, is_static, "identity", "(D)D");
154
155 JValue args[1];
156 JValue result;
157
158 args[0].d = 0.0;
159 result.d = -1.0;
160 (*stub)(method, receiver, Thread::Current(), args, &result);
161 EXPECT_EQ(0.0, result.d);
162
163 args[0].d = -1.0;
164 result.d = 0.0;
165 (*stub)(method, receiver, Thread::Current(), args, &result);
166 EXPECT_EQ(-1.0, result.d);
167
168 args[0].d = DBL_MAX;
169 result.d = 0.0;
170 (*stub)(method, receiver, Thread::Current(), args, &result);
171 EXPECT_EQ(DBL_MAX, result.d);
172
173 args[0].d = DBL_MIN;
174 result.d = 0.0;
175 (*stub)(method, receiver, Thread::Current(), args, &result);
176 EXPECT_EQ(DBL_MIN, result.d);
177 }
178
179 void InvokeSumIntIntMethod(bool is_static) {
Elliott Hughes77405792012-03-15 15:22:12 -0700180 Method* method;
181 Object* receiver;
182 Method::InvokeStub* stub = DoCompile(method, receiver, is_static, "sum", "(II)I");
183
184 JValue result;
185 result.i = -1;
186 JValue args[2];
187 args[0].i = 0;
188 args[1].i = 0;
189 (*stub)(method, NULL, Thread::Current(), args, &result);
190 EXPECT_EQ(0, result.i);
191
192 result.i = 0;
193 args[0].i = 1;
194 args[1].i = 2;
195 (*stub)(method, NULL, Thread::Current(), args, &result);
196 EXPECT_EQ(3, result.i);
197
198 result.i = 0;
199 args[0].i = -2;
200 args[1].i = 5;
201 (*stub)(method, NULL, Thread::Current(), args, &result);
202 EXPECT_EQ(3, result.i);
203
204 result.i = 1234;
205 args[0].i = INT_MAX;
206 args[1].i = INT_MIN;
207 (*stub)(method, NULL, Thread::Current(), args, &result);
208 EXPECT_EQ(-1, result.i);
209
210 result.i = INT_MIN;
211 args[0].i = INT_MAX;
212 args[1].i = INT_MAX;
213 (*stub)(method, NULL, Thread::Current(), args, &result);
214 EXPECT_EQ(-2, result.i);
215 }
216
217 void InvokeSumIntIntIntMethod(bool is_static) {
Elliott Hughes77405792012-03-15 15:22:12 -0700218 Method* method;
219 Object* receiver;
220 Method::InvokeStub* stub = DoCompile(method, receiver, is_static, "sum", "(III)I");
221
222 JValue result;
223 result.i = -1;
224 JValue args[3];
225 args[0].i = 0;
226 args[1].i = 0;
227 args[2].i = 0;
228 (*stub)(method, NULL, Thread::Current(), args, &result);
229 EXPECT_EQ(0, result.i);
230
231 result.i = 0;
232 args[0].i = 1;
233 args[1].i = 2;
234 args[2].i = 3;
235 (*stub)(method, NULL, Thread::Current(), args, &result);
236 EXPECT_EQ(6, result.i);
237
238 result.i = 0;
239 args[0].i = -1;
240 args[1].i = 2;
241 args[2].i = -3;
242 (*stub)(method, NULL, Thread::Current(), args, &result);
243 EXPECT_EQ(-2, result.i);
244
245 result.i = 1234;
246 args[0].i = INT_MAX;
247 args[1].i = INT_MIN;
248 args[2].i = INT_MAX;
249 (*stub)(method, NULL, Thread::Current(), args, &result);
250 EXPECT_EQ(2147483646, result.i);
251
252 result.i = INT_MIN;
253 args[0].i = INT_MAX;
254 args[1].i = INT_MAX;
255 args[2].i = INT_MAX;
256 (*stub)(method, NULL, Thread::Current(), args, &result);
257 EXPECT_EQ(2147483645, result.i);
258 }
259
260 void InvokeSumIntIntIntIntMethod(bool is_static) {
Elliott Hughes77405792012-03-15 15:22:12 -0700261 Method* method;
262 Object* receiver;
263 Method::InvokeStub* stub = DoCompile(method, receiver, is_static, "sum", "(IIII)I");
264
265 JValue result;
266 result.i = -1;
267 JValue args[4];
268 args[0].i = 0;
269 args[1].i = 0;
270 args[2].i = 0;
271 args[3].i = 0;
272 (*stub)(method, NULL, Thread::Current(), args, &result);
273 EXPECT_EQ(0, result.i);
274
275 result.i = 0;
276 args[0].i = 1;
277 args[1].i = 2;
278 args[2].i = 3;
279 args[3].i = 4;
280 (*stub)(method, NULL, Thread::Current(), args, &result);
281 EXPECT_EQ(10, result.i);
282
283 result.i = 0;
284 args[0].i = -1;
285 args[1].i = 2;
286 args[2].i = -3;
287 args[3].i = 4;
288 (*stub)(method, NULL, Thread::Current(), args, &result);
289 EXPECT_EQ(2, result.i);
290
291 result.i = 1234;
292 args[0].i = INT_MAX;
293 args[1].i = INT_MIN;
294 args[2].i = INT_MAX;
295 args[3].i = INT_MIN;
296 (*stub)(method, NULL, Thread::Current(), args, &result);
297 EXPECT_EQ(-2, result.i);
298
299 result.i = INT_MIN;
300 args[0].i = INT_MAX;
301 args[1].i = INT_MAX;
302 args[2].i = INT_MAX;
303 args[3].i = INT_MAX;
304 (*stub)(method, NULL, Thread::Current(), args, &result);
305 EXPECT_EQ(-4, result.i);
306 }
307
308 void InvokeSumIntIntIntIntIntMethod(bool is_static) {
Elliott Hughes77405792012-03-15 15:22:12 -0700309 Method* method;
310 Object* receiver;
311 Method::InvokeStub* stub = DoCompile(method, receiver, is_static, "sum", "(IIIII)I");
312
313 JValue result;
314 result.i = -1.0;
315 JValue args[5];
316 args[0].i = 0;
317 args[1].i = 0;
318 args[2].i = 0;
319 args[3].i = 0;
320 args[4].i = 0;
321 (*stub)(method, NULL, Thread::Current(), args, &result);
322 EXPECT_EQ(0, result.i);
323
324 result.i = 0;
325 args[0].i = 1;
326 args[1].i = 2;
327 args[2].i = 3;
328 args[3].i = 4;
329 args[4].i = 5;
330 (*stub)(method, NULL, Thread::Current(), args, &result);
331 EXPECT_EQ(15, result.i);
332
333 result.i = 0;
334 args[0].i = -1;
335 args[1].i = 2;
336 args[2].i = -3;
337 args[3].i = 4;
338 args[4].i = -5;
339 (*stub)(method, NULL, Thread::Current(), args, &result);
340 EXPECT_EQ(-3, result.i);
341
342 result.i = 1234;
343 args[0].i = INT_MAX;
344 args[1].i = INT_MIN;
345 args[2].i = INT_MAX;
346 args[3].i = INT_MIN;
347 args[4].i = INT_MAX;
348 (*stub)(method, NULL, Thread::Current(), args, &result);
349 EXPECT_EQ(2147483645, result.i);
350
351 result.i = INT_MIN;
352 args[0].i = INT_MAX;
353 args[1].i = INT_MAX;
354 args[2].i = INT_MAX;
355 args[3].i = INT_MAX;
356 args[4].i = INT_MAX;
357 (*stub)(method, NULL, Thread::Current(), args, &result);
358 EXPECT_EQ(2147483643, result.i);
359 }
360
361 void InvokeSumDoubleDoubleMethod(bool is_static) {
Elliott Hughes77405792012-03-15 15:22:12 -0700362 Method* method;
363 Object* receiver;
364 Method::InvokeStub* stub = DoCompile(method, receiver, is_static, "sum", "(DD)D");
365
366 JValue args[2];
367 JValue result;
368
369 args[0].d = 0.0;
370 args[1].d = 0.0;
371 result.d = -1.0;
372 (*stub)(method, NULL, Thread::Current(), args, &result);
373 EXPECT_EQ(0.0, result.d);
374
375 args[0].d = 1.0;
376 args[1].d = 2.0;
377 result.d = 0.0;
378 (*stub)(method, NULL, Thread::Current(), args, &result);
379 EXPECT_EQ(3.0, result.d);
380
381 args[0].d = 1.0;
382 args[1].d = -2.0;
383 result.d = 0.0;
384 (*stub)(method, NULL, Thread::Current(), args, &result);
385 EXPECT_EQ(-1.0, result.d);
386
387 args[0].d = DBL_MAX;
388 args[1].d = DBL_MIN;
389 result.d = 0.0;
390 (*stub)(method, NULL, Thread::Current(), args, &result);
391 EXPECT_EQ(1.7976931348623157e308, result.d);
392
393 args[0].d = DBL_MAX;
394 args[1].d = DBL_MAX;
395 result.d = 0.0;
396 (*stub)(method, NULL, Thread::Current(), args, &result);
397 EXPECT_EQ(INFINITY, result.d);
398 }
399
400 void InvokeSumDoubleDoubleDoubleMethod(bool is_static) {
Elliott Hughes77405792012-03-15 15:22:12 -0700401 Method* method;
402 Object* receiver;
403 Method::InvokeStub* stub = DoCompile(method, receiver, is_static, "sum", "(DDD)D");
404
405 JValue args[3];
406 JValue result;
407
408 args[0].d = 0.0;
409 args[1].d = 0.0;
410 args[2].d = 0.0;
411 result.d = -1.0;
412 (*stub)(method, NULL, Thread::Current(), args, &result);
413 EXPECT_EQ(0.0, result.d);
414
415 args[0].d = 1.0;
416 args[1].d = 2.0;
417 args[2].d = 3.0;
418 result.d = 0.0;
419 (*stub)(method, NULL, Thread::Current(), args, &result);
420 EXPECT_EQ(6.0, result.d);
421
422 args[0].d = 1.0;
423 args[1].d = -2.0;
424 args[2].d = 3.0;
425 result.d = 0.0;
426 (*stub)(method, NULL, Thread::Current(), args, &result);
427 EXPECT_EQ(2.0, result.d);
428 }
429
430 void InvokeSumDoubleDoubleDoubleDoubleMethod(bool is_static) {
Elliott Hughes77405792012-03-15 15:22:12 -0700431 Method* method;
432 Object* receiver;
433 Method::InvokeStub* stub = DoCompile(method, receiver, is_static, "sum", "(DDDD)D");
434
435 JValue args[4];
436 JValue result;
437
438 args[0].d = 0.0;
439 args[1].d = 0.0;
440 args[2].d = 0.0;
441 args[3].d = 0.0;
442 result.d = -1.0;
443 (*stub)(method, NULL, Thread::Current(), args, &result);
444 EXPECT_EQ(0.0, result.d);
445
446 args[0].d = 1.0;
447 args[1].d = 2.0;
448 args[2].d = 3.0;
449 args[3].d = 4.0;
450 result.d = 0.0;
451 (*stub)(method, NULL, Thread::Current(), args, &result);
452 EXPECT_EQ(10.0, result.d);
453
454 args[0].d = 1.0;
455 args[1].d = -2.0;
456 args[2].d = 3.0;
457 args[3].d = -4.0;
458 result.d = 0.0;
459 (*stub)(method, NULL, Thread::Current(), args, &result);
460 EXPECT_EQ(-2.0, result.d);
461 }
462
463 void InvokeSumDoubleDoubleDoubleDoubleDoubleMethod(bool is_static) {
Elliott Hughes77405792012-03-15 15:22:12 -0700464 Method* method;
465 Object* receiver;
466 Method::InvokeStub* stub = DoCompile(method, receiver, is_static, "sum", "(DDDDD)D");
467
468 JValue args[5];
469 JValue result;
470
471 args[0].d = 0.0;
472 args[1].d = 0.0;
473 args[2].d = 0.0;
474 args[3].d = 0.0;
475 args[4].d = 0.0;
476 result.d = -1.0;
477 (*stub)(method, NULL, Thread::Current(), args, &result);
478 EXPECT_EQ(0.0, result.d);
479
480 args[0].d = 1.0;
481 args[1].d = 2.0;
482 args[2].d = 3.0;
483 args[3].d = 4.0;
484 args[4].d = 5.0;
485 result.d = 0.0;
486 (*stub)(method, NULL, Thread::Current(), args, &result);
487 EXPECT_EQ(15.0, result.d);
488
489 args[0].d = 1.0;
490 args[1].d = -2.0;
491 args[2].d = 3.0;
492 args[3].d = -4.0;
493 args[4].d = 5.0;
494 result.d = 0.0;
495 (*stub)(method, NULL, Thread::Current(), args, &result);
496 EXPECT_EQ(3.0, result.d);
497 }
498
Elliott Hughesa2501992011-08-26 19:39:54 -0700499 JavaVMExt* vm_;
500 JNIEnvExt* env_;
Elliott Hughes814e4032011-08-23 12:07:56 -0700501 jclass aioobe_;
Elliott Hughesb264f082012-04-06 17:10:10 -0700502 jclass ase_;
Elliott Hughesb465ab02011-08-24 11:21:21 -0700503 jclass sioobe_;
Elliott Hughes0c9cd562011-08-12 10:59:29 -0700504};
505
Elliott Hughes885c3bd2011-08-22 16:59:20 -0700506TEST_F(JniInternalTest, AllocObject) {
507 jclass c = env_->FindClass("java/lang/String");
508 ASSERT_TRUE(c != NULL);
509 jobject o = env_->AllocObject(c);
510 ASSERT_TRUE(o != NULL);
511
512 // We have an instance of the class we asked for...
513 ASSERT_TRUE(env_->IsInstanceOf(o, c));
514 // ...whose fields haven't been initialized because
515 // we didn't call a constructor.
516 ASSERT_EQ(0, env_->GetIntField(o, env_->GetFieldID(c, "count", "I")));
517 ASSERT_EQ(0, env_->GetIntField(o, env_->GetFieldID(c, "offset", "I")));
518 ASSERT_TRUE(env_->GetObjectField(o, env_->GetFieldID(c, "value", "[C")) == NULL);
519}
520
Elliott Hughesc7ac37f2011-08-12 12:21:58 -0700521TEST_F(JniInternalTest, GetVersion) {
522 ASSERT_EQ(JNI_VERSION_1_6, env_->GetVersion());
523}
524
Elliott Hughes0c9cd562011-08-12 10:59:29 -0700525#define EXPECT_CLASS_FOUND(NAME) \
Elliott Hughesbd935992011-08-22 11:59:34 -0700526 EXPECT_TRUE(env_->FindClass(NAME) != NULL); \
527 EXPECT_FALSE(env_->ExceptionCheck())
Elliott Hughes0c9cd562011-08-12 10:59:29 -0700528
529#define EXPECT_CLASS_NOT_FOUND(NAME) \
Elliott Hughesbd935992011-08-22 11:59:34 -0700530 EXPECT_TRUE(env_->FindClass(NAME) == NULL); \
531 EXPECT_TRUE(env_->ExceptionCheck()); \
532 env_->ExceptionClear()
Elliott Hughes0c9cd562011-08-12 10:59:29 -0700533
534TEST_F(JniInternalTest, FindClass) {
Elliott Hughes0c9cd562011-08-12 10:59:29 -0700535 // Reference types...
Elliott Hughes0c9cd562011-08-12 10:59:29 -0700536 EXPECT_CLASS_FOUND("java/lang/String");
Elliott Hughes0c9cd562011-08-12 10:59:29 -0700537 // ...for arrays too, where you must include "L;".
538 EXPECT_CLASS_FOUND("[Ljava/lang/String;");
Elliott Hughesa2501992011-08-26 19:39:54 -0700539
Elliott Hughesb264f082012-04-06 17:10:10 -0700540 {
541 CheckJniAbortCatcher check_jni_abort_catcher;
Elliott Hughes0c9cd562011-08-12 10:59:29 -0700542
Elliott Hughesb264f082012-04-06 17:10:10 -0700543 // We support . as well as / for compatibility, if -Xcheck:jni is off.
544 EXPECT_CLASS_FOUND("java.lang.String");
545 EXPECT_CLASS_NOT_FOUND("Ljava.lang.String;");
546 EXPECT_CLASS_FOUND("[Ljava.lang.String;");
547 EXPECT_CLASS_NOT_FOUND("[java.lang.String");
548
549 // You can't include the "L;" in a JNI class descriptor.
550 EXPECT_CLASS_NOT_FOUND("Ljava/lang/String;");
551 // But you must include it for an array of any reference type.
552 EXPECT_CLASS_NOT_FOUND("[java/lang/String");
553 }
Elliott Hughesa2501992011-08-26 19:39:54 -0700554
Elliott Hughes0c9cd562011-08-12 10:59:29 -0700555 // Primitive arrays are okay (if the primitive type is valid)...
556 EXPECT_CLASS_FOUND("[C");
Elliott Hughesb264f082012-04-06 17:10:10 -0700557 {
558 CheckJniAbortCatcher check_jni_abort_catcher;
559 EXPECT_CLASS_NOT_FOUND("[K");
560 }
Elliott Hughes0c9cd562011-08-12 10:59:29 -0700561 // But primitive types aren't allowed...
562 EXPECT_CLASS_NOT_FOUND("C");
563 EXPECT_CLASS_NOT_FOUND("K");
564}
565
Elliott Hughescdf53122011-08-19 15:46:09 -0700566#define EXPECT_EXCEPTION(exception_class) \
567 do { \
568 EXPECT_TRUE(env_->ExceptionCheck()); \
569 jthrowable exception = env_->ExceptionOccurred(); \
570 EXPECT_NE(static_cast<jthrowable>(NULL), exception); \
Elliott Hughescdf53122011-08-19 15:46:09 -0700571 env_->ExceptionClear(); \
Elliott Hughesa2501992011-08-26 19:39:54 -0700572 EXPECT_TRUE(env_->IsInstanceOf(exception, exception_class)); \
Elliott Hughescdf53122011-08-19 15:46:09 -0700573 } while (false)
574
575TEST_F(JniInternalTest, GetFieldID) {
576 jclass jlnsfe = env_->FindClass("java/lang/NoSuchFieldError");
577 ASSERT_TRUE(jlnsfe != NULL);
578 jclass c = env_->FindClass("java/lang/String");
579 ASSERT_TRUE(c != NULL);
580
581 // Wrong type.
582 jfieldID fid = env_->GetFieldID(c, "count", "J");
583 EXPECT_EQ(static_cast<jfieldID>(NULL), fid);
584 EXPECT_EXCEPTION(jlnsfe);
585
Ian Rogersb17d08b2011-09-02 16:16:49 -0700586 // Wrong type where type doesn't exist.
587 fid = env_->GetFieldID(c, "count", "Lrod/jane/freddy;");
588 EXPECT_EQ(static_cast<jfieldID>(NULL), fid);
589 EXPECT_EXCEPTION(jlnsfe);
590
Elliott Hughescdf53122011-08-19 15:46:09 -0700591 // Wrong name.
592 fid = env_->GetFieldID(c, "Count", "I");
593 EXPECT_EQ(static_cast<jfieldID>(NULL), fid);
594 EXPECT_EXCEPTION(jlnsfe);
595
596 // Good declared field lookup.
597 fid = env_->GetFieldID(c, "count", "I");
598 EXPECT_NE(static_cast<jfieldID>(NULL), fid);
599 EXPECT_TRUE(fid != NULL);
600 EXPECT_FALSE(env_->ExceptionCheck());
601
602 // Good superclass field lookup.
603 c = env_->FindClass("java/lang/StringBuilder");
604 fid = env_->GetFieldID(c, "count", "I");
605 EXPECT_NE(static_cast<jfieldID>(NULL), fid);
606 EXPECT_TRUE(fid != NULL);
607 EXPECT_FALSE(env_->ExceptionCheck());
608
609 // Not instance.
610 fid = env_->GetFieldID(c, "CASE_INSENSITIVE_ORDER", "Ljava/util/Comparator;");
611 EXPECT_EQ(static_cast<jfieldID>(NULL), fid);
612 EXPECT_EXCEPTION(jlnsfe);
613}
614
615TEST_F(JniInternalTest, GetStaticFieldID) {
616 jclass jlnsfe = env_->FindClass("java/lang/NoSuchFieldError");
617 ASSERT_TRUE(jlnsfe != NULL);
618 jclass c = env_->FindClass("java/lang/String");
619 ASSERT_TRUE(c != NULL);
620
621 // Wrong type.
622 jfieldID fid = env_->GetStaticFieldID(c, "CASE_INSENSITIVE_ORDER", "J");
623 EXPECT_EQ(static_cast<jfieldID>(NULL), fid);
624 EXPECT_EXCEPTION(jlnsfe);
625
Ian Rogersb17d08b2011-09-02 16:16:49 -0700626 // Wrong type where type doesn't exist.
627 fid = env_->GetStaticFieldID(c, "CASE_INSENSITIVE_ORDER", "Lrod/jane/freddy;");
628 EXPECT_EQ(static_cast<jfieldID>(NULL), fid);
629 EXPECT_EXCEPTION(jlnsfe);
630
Elliott Hughescdf53122011-08-19 15:46:09 -0700631 // Wrong name.
632 fid = env_->GetStaticFieldID(c, "cASE_INSENSITIVE_ORDER", "Ljava/util/Comparator;");
633 EXPECT_EQ(static_cast<jfieldID>(NULL), fid);
634 EXPECT_EXCEPTION(jlnsfe);
635
636 // Good declared field lookup.
637 fid = env_->GetStaticFieldID(c, "CASE_INSENSITIVE_ORDER", "Ljava/util/Comparator;");
638 EXPECT_NE(static_cast<jfieldID>(NULL), fid);
639 EXPECT_TRUE(fid != NULL);
640 EXPECT_FALSE(env_->ExceptionCheck());
641
642 // Not static.
643 fid = env_->GetStaticFieldID(c, "count", "I");
644 EXPECT_EQ(static_cast<jfieldID>(NULL), fid);
645 EXPECT_EXCEPTION(jlnsfe);
646}
647
Ian Rogers4dd71f12011-08-16 14:16:02 -0700648TEST_F(JniInternalTest, GetMethodID) {
649 jclass jlobject = env_->FindClass("java/lang/Object");
650 jclass jlstring = env_->FindClass("java/lang/String");
651 jclass jlnsme = env_->FindClass("java/lang/NoSuchMethodError");
652
653 // Sanity check that no exceptions are pending
Elliott Hughescdf53122011-08-19 15:46:09 -0700654 ASSERT_FALSE(env_->ExceptionCheck());
Ian Rogers4dd71f12011-08-16 14:16:02 -0700655
656 // Check that java.lang.Object.foo() doesn't exist and NoSuchMethodError is
657 // a pending exception
658 jmethodID method = env_->GetMethodID(jlobject, "foo", "()V");
659 EXPECT_EQ(static_cast<jmethodID>(NULL), method);
Elliott Hughescdf53122011-08-19 15:46:09 -0700660 EXPECT_EXCEPTION(jlnsme);
Ian Rogers4dd71f12011-08-16 14:16:02 -0700661
662 // Check that java.lang.Object.equals() does exist
Ian Rogers4dd71f12011-08-16 14:16:02 -0700663 method = env_->GetMethodID(jlobject, "equals", "(Ljava/lang/Object;)Z");
664 EXPECT_NE(static_cast<jmethodID>(NULL), method);
665 EXPECT_FALSE(env_->ExceptionCheck());
Ian Rogers4dd71f12011-08-16 14:16:02 -0700666
667 // Check that GetMethodID for java.lang.String.valueOf(int) fails as the
668 // method is static
669 method = env_->GetMethodID(jlstring, "valueOf", "(I)Ljava/lang/String;");
670 EXPECT_EQ(static_cast<jmethodID>(NULL), method);
Elliott Hughescdf53122011-08-19 15:46:09 -0700671 EXPECT_EXCEPTION(jlnsme);
Ian Rogers4dd71f12011-08-16 14:16:02 -0700672}
673
674TEST_F(JniInternalTest, GetStaticMethodID) {
675 jclass jlobject = env_->FindClass("java/lang/Object");
676 jclass jlnsme = env_->FindClass("java/lang/NoSuchMethodError");
677
678 // Sanity check that no exceptions are pending
Elliott Hughescdf53122011-08-19 15:46:09 -0700679 ASSERT_FALSE(env_->ExceptionCheck());
Ian Rogers4dd71f12011-08-16 14:16:02 -0700680
681 // Check that java.lang.Object.foo() doesn't exist and NoSuchMethodError is
682 // a pending exception
683 jmethodID method = env_->GetStaticMethodID(jlobject, "foo", "()V");
684 EXPECT_EQ(static_cast<jmethodID>(NULL), method);
Elliott Hughescdf53122011-08-19 15:46:09 -0700685 EXPECT_EXCEPTION(jlnsme);
Ian Rogers4dd71f12011-08-16 14:16:02 -0700686
687 // Check that GetStaticMethodID for java.lang.Object.equals(Object) fails as
688 // the method is not static
689 method = env_->GetStaticMethodID(jlobject, "equals", "(Ljava/lang/Object;)Z");
690 EXPECT_EQ(static_cast<jmethodID>(NULL), method);
Elliott Hughescdf53122011-08-19 15:46:09 -0700691 EXPECT_EXCEPTION(jlnsme);
Ian Rogers4dd71f12011-08-16 14:16:02 -0700692
693 // Check that java.lang.String.valueOf(int) does exist
Ian Rogers4dd71f12011-08-16 14:16:02 -0700694 jclass jlstring = env_->FindClass("java/lang/String");
695 method = env_->GetStaticMethodID(jlstring, "valueOf",
696 "(I)Ljava/lang/String;");
697 EXPECT_NE(static_cast<jmethodID>(NULL), method);
698 EXPECT_FALSE(env_->ExceptionCheck());
Ian Rogers4dd71f12011-08-16 14:16:02 -0700699}
700
Elliott Hughescdf53122011-08-19 15:46:09 -0700701TEST_F(JniInternalTest, FromReflectedField_ToReflectedField) {
702 jclass jlrField = env_->FindClass("java/lang/reflect/Field");
703 jclass c = env_->FindClass("java/lang/String");
704 ASSERT_TRUE(c != NULL);
705 jfieldID fid = env_->GetFieldID(c, "count", "I");
706 ASSERT_TRUE(fid != NULL);
707 // Turn the fid into a java.lang.reflect.Field...
708 jobject field = env_->ToReflectedField(c, fid, JNI_FALSE);
709 ASSERT_TRUE(c != NULL);
710 ASSERT_TRUE(env_->IsInstanceOf(field, jlrField));
711 // ...and back again.
712 jfieldID fid2 = env_->FromReflectedField(field);
713 ASSERT_TRUE(fid2 != NULL);
714}
715
716TEST_F(JniInternalTest, FromReflectedMethod_ToReflectedMethod) {
717 jclass jlrMethod = env_->FindClass("java/lang/reflect/Method");
718 jclass c = env_->FindClass("java/lang/String");
719 ASSERT_TRUE(c != NULL);
720 jmethodID mid = env_->GetMethodID(c, "length", "()I");
721 ASSERT_TRUE(mid != NULL);
722 // Turn the mid into a java.lang.reflect.Method...
723 jobject method = env_->ToReflectedMethod(c, mid, JNI_FALSE);
724 ASSERT_TRUE(c != NULL);
725 ASSERT_TRUE(env_->IsInstanceOf(method, jlrMethod));
726 // ...and back again.
727 jmethodID mid2 = env_->FromReflectedMethod(method);
728 ASSERT_TRUE(mid2 != NULL);
729}
730
Elliott Hughes5174fe62011-08-23 15:12:35 -0700731void BogusMethod() {
732 // You can't pass NULL function pointers to RegisterNatives.
733}
734
Ian Rogers4dd71f12011-08-16 14:16:02 -0700735TEST_F(JniInternalTest, RegisterNatives) {
736 jclass jlobject = env_->FindClass("java/lang/Object");
737 jclass jlnsme = env_->FindClass("java/lang/NoSuchMethodError");
738
739 // Sanity check that no exceptions are pending
Elliott Hughescdf53122011-08-19 15:46:09 -0700740 ASSERT_FALSE(env_->ExceptionCheck());
Ian Rogers4dd71f12011-08-16 14:16:02 -0700741
742 // Check that registering to a non-existent java.lang.Object.foo() causes a
743 // NoSuchMethodError
744 {
Elliott Hughesb25c3f62012-03-26 16:35:06 -0700745 JNINativeMethod methods[] = { { "foo", "()V", NULL } };
Ian Rogers4dd71f12011-08-16 14:16:02 -0700746 env_->RegisterNatives(jlobject, methods, 1);
747 }
Elliott Hughescdf53122011-08-19 15:46:09 -0700748 EXPECT_EXCEPTION(jlnsme);
Ian Rogers4dd71f12011-08-16 14:16:02 -0700749
750 // Check that registering non-native methods causes a NoSuchMethodError
751 {
Elliott Hughesb25c3f62012-03-26 16:35:06 -0700752 JNINativeMethod methods[] = { { "equals", "(Ljava/lang/Object;)Z", NULL } };
Ian Rogers4dd71f12011-08-16 14:16:02 -0700753 env_->RegisterNatives(jlobject, methods, 1);
754 }
Elliott Hughescdf53122011-08-19 15:46:09 -0700755 EXPECT_EXCEPTION(jlnsme);
Ian Rogers4dd71f12011-08-16 14:16:02 -0700756
757 // Check that registering native methods is successful
758 {
Elliott Hughesb25c3f62012-03-26 16:35:06 -0700759 JNINativeMethod methods[] = { { "notify", "()V", reinterpret_cast<void*>(BogusMethod) } };
Ian Rogers4dd71f12011-08-16 14:16:02 -0700760 env_->RegisterNatives(jlobject, methods, 1);
761 }
762 EXPECT_FALSE(env_->ExceptionCheck());
Elliott Hughes5174fe62011-08-23 15:12:35 -0700763
764 env_->UnregisterNatives(jlobject);
Ian Rogers4dd71f12011-08-16 14:16:02 -0700765}
766
Elliott Hughes75770752011-08-24 17:52:38 -0700767#define EXPECT_PRIMITIVE_ARRAY(new_fn, get_region_fn, set_region_fn, get_elements_fn, release_elements_fn, scalar_type, expected_class_descriptor) \
Elliott Hughes814e4032011-08-23 12:07:56 -0700768 jsize size = 4; \
769 /* Allocate an array and check it has the right type and length. */ \
770 scalar_type ## Array a = env_->new_fn(size); \
771 EXPECT_TRUE(a != NULL); \
772 EXPECT_TRUE(env_->IsInstanceOf(a, env_->FindClass(expected_class_descriptor))); \
773 EXPECT_EQ(size, env_->GetArrayLength(a)); \
774 /* AIOOBE for negative start offset. */ \
775 env_->get_region_fn(a, -1, 1, NULL); \
776 EXPECT_EXCEPTION(aioobe_); \
777 env_->set_region_fn(a, -1, 1, NULL); \
778 EXPECT_EXCEPTION(aioobe_); \
779 /* AIOOBE for negative length. */ \
780 env_->get_region_fn(a, 0, -1, NULL); \
781 EXPECT_EXCEPTION(aioobe_); \
782 env_->set_region_fn(a, 0, -1, NULL); \
783 EXPECT_EXCEPTION(aioobe_); \
784 /* AIOOBE for buffer overrun. */ \
785 env_->get_region_fn(a, size - 1, size, NULL); \
786 EXPECT_EXCEPTION(aioobe_); \
787 env_->set_region_fn(a, size - 1, size, NULL); \
788 EXPECT_EXCEPTION(aioobe_); \
789 /* Prepare a couple of buffers. */ \
Elliott Hughesee0fa762012-03-26 17:12:41 -0700790 UniquePtr<scalar_type[]> src_buf(new scalar_type[size]); \
791 UniquePtr<scalar_type[]> dst_buf(new scalar_type[size]); \
Elliott Hughes814e4032011-08-23 12:07:56 -0700792 for (jsize i = 0; i < size; ++i) { src_buf[i] = scalar_type(i); } \
793 for (jsize i = 0; i < size; ++i) { dst_buf[i] = scalar_type(-1); } \
794 /* Copy all of src_buf onto the heap. */ \
Elliott Hughesee0fa762012-03-26 17:12:41 -0700795 env_->set_region_fn(a, 0, size, &src_buf[0]); \
Elliott Hughes814e4032011-08-23 12:07:56 -0700796 /* Copy back only part. */ \
797 env_->get_region_fn(a, 1, size - 2, &dst_buf[1]); \
Elliott Hughesee0fa762012-03-26 17:12:41 -0700798 EXPECT_NE(memcmp(&src_buf[0], &dst_buf[0], size * sizeof(scalar_type)), 0) << "short copy equal"; \
Elliott Hughes814e4032011-08-23 12:07:56 -0700799 /* Copy the missing pieces. */ \
Elliott Hughesee0fa762012-03-26 17:12:41 -0700800 env_->get_region_fn(a, 0, 1, &dst_buf[0]); \
Elliott Hughes814e4032011-08-23 12:07:56 -0700801 env_->get_region_fn(a, size - 1, 1, &dst_buf[size - 1]); \
Elliott Hughesee0fa762012-03-26 17:12:41 -0700802 EXPECT_EQ(memcmp(&src_buf[0], &dst_buf[0], size * sizeof(scalar_type)), 0) << "fixed copy not equal"; \
Elliott Hughes814e4032011-08-23 12:07:56 -0700803 /* Copy back the whole array. */ \
Elliott Hughesee0fa762012-03-26 17:12:41 -0700804 env_->get_region_fn(a, 0, size, &dst_buf[0]); \
805 EXPECT_EQ(memcmp(&src_buf[0], &dst_buf[0], size * sizeof(scalar_type)), 0) << "full copy not equal"; \
Elliott Hughes75770752011-08-24 17:52:38 -0700806 /* GetPrimitiveArrayCritical */ \
807 void* v = env_->GetPrimitiveArrayCritical(a, NULL); \
Elliott Hughesee0fa762012-03-26 17:12:41 -0700808 EXPECT_EQ(memcmp(&src_buf[0], v, size * sizeof(scalar_type)), 0) << "GetPrimitiveArrayCritical not equal"; \
Elliott Hughes75770752011-08-24 17:52:38 -0700809 env_->ReleasePrimitiveArrayCritical(a, v, 0); \
810 /* GetXArrayElements */ \
811 scalar_type* xs = env_->get_elements_fn(a, NULL); \
Elliott Hughesee0fa762012-03-26 17:12:41 -0700812 EXPECT_EQ(memcmp(&src_buf[0], xs, size * sizeof(scalar_type)), 0) << # get_elements_fn " not equal"; \
Elliott Hughes75770752011-08-24 17:52:38 -0700813 env_->release_elements_fn(a, xs, 0); \
814 EXPECT_EQ(reinterpret_cast<uintptr_t>(v), reinterpret_cast<uintptr_t>(xs))
Elliott Hughesbd935992011-08-22 11:59:34 -0700815
Elliott Hughes814e4032011-08-23 12:07:56 -0700816TEST_F(JniInternalTest, BooleanArrays) {
Elliott Hughes75770752011-08-24 17:52:38 -0700817 EXPECT_PRIMITIVE_ARRAY(NewBooleanArray, GetBooleanArrayRegion, SetBooleanArrayRegion, GetBooleanArrayElements, ReleaseBooleanArrayElements, jboolean, "[Z");
Elliott Hughes814e4032011-08-23 12:07:56 -0700818}
819TEST_F(JniInternalTest, ByteArrays) {
Elliott Hughes75770752011-08-24 17:52:38 -0700820 EXPECT_PRIMITIVE_ARRAY(NewByteArray, GetByteArrayRegion, SetByteArrayRegion, GetByteArrayElements, ReleaseByteArrayElements, jbyte, "[B");
Elliott Hughes814e4032011-08-23 12:07:56 -0700821}
822TEST_F(JniInternalTest, CharArrays) {
Elliott Hughes75770752011-08-24 17:52:38 -0700823 EXPECT_PRIMITIVE_ARRAY(NewCharArray, GetCharArrayRegion, SetCharArrayRegion, GetCharArrayElements, ReleaseCharArrayElements, jchar, "[C");
Elliott Hughes814e4032011-08-23 12:07:56 -0700824}
825TEST_F(JniInternalTest, DoubleArrays) {
Elliott Hughes75770752011-08-24 17:52:38 -0700826 EXPECT_PRIMITIVE_ARRAY(NewDoubleArray, GetDoubleArrayRegion, SetDoubleArrayRegion, GetDoubleArrayElements, ReleaseDoubleArrayElements, jdouble, "[D");
Elliott Hughes814e4032011-08-23 12:07:56 -0700827}
828TEST_F(JniInternalTest, FloatArrays) {
Elliott Hughes75770752011-08-24 17:52:38 -0700829 EXPECT_PRIMITIVE_ARRAY(NewFloatArray, GetFloatArrayRegion, SetFloatArrayRegion, GetFloatArrayElements, ReleaseFloatArrayElements, jfloat, "[F");
Elliott Hughes814e4032011-08-23 12:07:56 -0700830}
831TEST_F(JniInternalTest, IntArrays) {
Elliott Hughes75770752011-08-24 17:52:38 -0700832 EXPECT_PRIMITIVE_ARRAY(NewIntArray, GetIntArrayRegion, SetIntArrayRegion, GetIntArrayElements, ReleaseIntArrayElements, jint, "[I");
Elliott Hughes814e4032011-08-23 12:07:56 -0700833}
834TEST_F(JniInternalTest, LongArrays) {
Elliott Hughes75770752011-08-24 17:52:38 -0700835 EXPECT_PRIMITIVE_ARRAY(NewLongArray, GetLongArrayRegion, SetLongArrayRegion, GetLongArrayElements, ReleaseLongArrayElements, jlong, "[J");
Elliott Hughes814e4032011-08-23 12:07:56 -0700836}
837TEST_F(JniInternalTest, ShortArrays) {
Elliott Hughes75770752011-08-24 17:52:38 -0700838 EXPECT_PRIMITIVE_ARRAY(NewShortArray, GetShortArrayRegion, SetShortArrayRegion, GetShortArrayElements, ReleaseShortArrayElements, jshort, "[S");
Elliott Hughesd8ddfd52011-08-15 14:32:53 -0700839}
840
Elliott Hughesf2682d52011-08-15 16:37:04 -0700841TEST_F(JniInternalTest, NewObjectArray) {
842 // TODO: death tests for negative array sizes.
843
Elliott Hughesf2682d52011-08-15 16:37:04 -0700844 // TODO: check non-NULL initial elements.
845
Elliott Hughesbd935992011-08-22 11:59:34 -0700846 jclass element_class = env_->FindClass("java/lang/String");
847 ASSERT_TRUE(element_class != NULL);
848 jclass array_class = env_->FindClass("[Ljava/lang/String;");
849 ASSERT_TRUE(array_class != NULL);
Elliott Hughesf2682d52011-08-15 16:37:04 -0700850
Elliott Hughesbd935992011-08-22 11:59:34 -0700851 jobjectArray a;
Elliott Hughesf2682d52011-08-15 16:37:04 -0700852
Elliott Hughesbd935992011-08-22 11:59:34 -0700853 a = env_->NewObjectArray(0, element_class, NULL);
854 EXPECT_TRUE(a != NULL);
855 EXPECT_TRUE(env_->IsInstanceOf(a, array_class));
856 EXPECT_EQ(0, env_->GetArrayLength(a));
857
858 a = env_->NewObjectArray(1, element_class, NULL);
859 EXPECT_TRUE(a != NULL);
860 EXPECT_TRUE(env_->IsInstanceOf(a, array_class));
861 EXPECT_EQ(1, env_->GetArrayLength(a));
Elliott Hughes75770752011-08-24 17:52:38 -0700862 EXPECT_TRUE(env_->IsSameObject(env_->GetObjectArrayElement(a, 0), NULL));
863
864 jstring s = env_->NewStringUTF("poop");
865 a = env_->NewObjectArray(2, element_class, s);
866 EXPECT_TRUE(a != NULL);
867 EXPECT_TRUE(env_->IsInstanceOf(a, array_class));
868 EXPECT_EQ(2, env_->GetArrayLength(a));
869 EXPECT_TRUE(env_->IsSameObject(env_->GetObjectArrayElement(a, 0), s));
870 EXPECT_TRUE(env_->IsSameObject(env_->GetObjectArrayElement(a, 1), s));
Elliott Hughesbd935992011-08-22 11:59:34 -0700871}
872
873TEST_F(JniInternalTest, GetArrayLength) {
874 // Already tested in NewObjectArray/NewPrimitiveArray.
Elliott Hughes8a26c5c2011-08-15 18:35:43 -0700875}
876
Elliott Hughes37f7a402011-08-22 18:56:01 -0700877TEST_F(JniInternalTest, GetObjectClass) {
878 jclass string_class = env_->FindClass("java/lang/String");
879 ASSERT_TRUE(string_class != NULL);
880 jclass class_class = env_->FindClass("java/lang/Class");
881 ASSERT_TRUE(class_class != NULL);
882
883 jstring s = env_->NewStringUTF("poop");
884 jclass c = env_->GetObjectClass(s);
885 ASSERT_TRUE(env_->IsSameObject(string_class, c));
886
887 jclass c2 = env_->GetObjectClass(c);
888 ASSERT_TRUE(env_->IsSameObject(class_class, env_->GetObjectClass(c2)));
889}
890
Elliott Hughes885c3bd2011-08-22 16:59:20 -0700891TEST_F(JniInternalTest, GetSuperclass) {
892 jclass object_class = env_->FindClass("java/lang/Object");
893 ASSERT_TRUE(object_class != NULL);
894 jclass string_class = env_->FindClass("java/lang/String");
895 ASSERT_TRUE(string_class != NULL);
Ian Rogersdc180202012-01-29 14:47:29 -0800896 jclass runnable_interface = env_->FindClass("java/lang/Runnable");
897 ASSERT_TRUE(runnable_interface != NULL);
Elliott Hughes885c3bd2011-08-22 16:59:20 -0700898 ASSERT_TRUE(env_->IsSameObject(object_class, env_->GetSuperclass(string_class)));
899 ASSERT_TRUE(env_->GetSuperclass(object_class) == NULL);
Ian Rogersdc180202012-01-29 14:47:29 -0800900 ASSERT_TRUE(env_->IsSameObject(object_class, env_->GetSuperclass(runnable_interface)));
Elliott Hughes885c3bd2011-08-22 16:59:20 -0700901}
902
Elliott Hughes37f7a402011-08-22 18:56:01 -0700903TEST_F(JniInternalTest, IsAssignableFrom) {
904 jclass object_class = env_->FindClass("java/lang/Object");
905 ASSERT_TRUE(object_class != NULL);
906 jclass string_class = env_->FindClass("java/lang/String");
907 ASSERT_TRUE(string_class != NULL);
908
909 ASSERT_TRUE(env_->IsAssignableFrom(object_class, string_class));
910 ASSERT_FALSE(env_->IsAssignableFrom(string_class, object_class));
911}
912
Elliott Hughesb465ab02011-08-24 11:21:21 -0700913TEST_F(JniInternalTest, GetObjectRefType) {
914 jclass local = env_->FindClass("java/lang/Object");
915 ASSERT_TRUE(local != NULL);
916 EXPECT_EQ(JNILocalRefType, env_->GetObjectRefType(local));
917
918 jobject global = env_->NewGlobalRef(local);
919 EXPECT_EQ(JNIGlobalRefType, env_->GetObjectRefType(global));
920
921 jweak weak_global = env_->NewWeakGlobalRef(local);
922 EXPECT_EQ(JNIWeakGlobalRefType, env_->GetObjectRefType(weak_global));
923
924 jobject invalid = reinterpret_cast<jobject>(this);
925 EXPECT_EQ(JNIInvalidRefType, env_->GetObjectRefType(invalid));
926
927 // TODO: invoke a native method and test that its arguments are considered local references.
928}
929
Elliott Hughes8a26c5c2011-08-15 18:35:43 -0700930TEST_F(JniInternalTest, NewStringUTF) {
931 EXPECT_TRUE(env_->NewStringUTF(NULL) == NULL);
Elliott Hughes814e4032011-08-23 12:07:56 -0700932 jstring s;
933
934 s = env_->NewStringUTF("");
935 EXPECT_TRUE(s != NULL);
936 EXPECT_EQ(0, env_->GetStringLength(s));
937 EXPECT_EQ(0, env_->GetStringUTFLength(s));
938 s = env_->NewStringUTF("hello");
939 EXPECT_TRUE(s != NULL);
940 EXPECT_EQ(5, env_->GetStringLength(s));
941 EXPECT_EQ(5, env_->GetStringUTFLength(s));
942
Elliott Hughes8a26c5c2011-08-15 18:35:43 -0700943 // TODO: check some non-ASCII strings.
Elliott Hughesf2682d52011-08-15 16:37:04 -0700944}
945
Elliott Hughes814e4032011-08-23 12:07:56 -0700946TEST_F(JniInternalTest, NewString) {
Elliott Hughes814e4032011-08-23 12:07:56 -0700947 jchar chars[] = { 'h', 'i' };
948 jstring s;
949 s = env_->NewString(chars, 0);
950 EXPECT_TRUE(s != NULL);
951 EXPECT_EQ(0, env_->GetStringLength(s));
952 EXPECT_EQ(0, env_->GetStringUTFLength(s));
953 s = env_->NewString(chars, 2);
954 EXPECT_TRUE(s != NULL);
955 EXPECT_EQ(2, env_->GetStringLength(s));
956 EXPECT_EQ(2, env_->GetStringUTFLength(s));
957
958 // TODO: check some non-ASCII strings.
959}
960
Jesse Wilson25e79a52011-11-18 15:31:58 -0500961TEST_F(JniInternalTest, NewStringNullCharsZeroLength) {
962 jstring s = env_->NewString(NULL, 0);
963 EXPECT_TRUE(s != NULL);
964 EXPECT_EQ(0, env_->GetStringLength(s));
965}
966
Brian Carlstrom36258122011-12-09 12:55:51 -0800967// TODO: fix gtest death tests on host http://b/5690440 (and target)
968TEST_F(JniInternalTest, DISABLED_NewStringNullCharsNonzeroLength) {
Jesse Wilson25e79a52011-11-18 15:31:58 -0500969 ASSERT_DEATH(env_->NewString(NULL, 1), "");
970}
971
Elliott Hughesb465ab02011-08-24 11:21:21 -0700972TEST_F(JniInternalTest, GetStringLength_GetStringUTFLength) {
973 // Already tested in the NewString/NewStringUTF tests.
974}
975
976TEST_F(JniInternalTest, GetStringRegion_GetStringUTFRegion) {
977 jstring s = env_->NewStringUTF("hello");
978 ASSERT_TRUE(s != NULL);
979
980 env_->GetStringRegion(s, -1, 0, NULL);
981 EXPECT_EXCEPTION(sioobe_);
982 env_->GetStringRegion(s, 0, -1, NULL);
983 EXPECT_EXCEPTION(sioobe_);
984 env_->GetStringRegion(s, 0, 10, NULL);
985 EXPECT_EXCEPTION(sioobe_);
986 env_->GetStringRegion(s, 10, 1, NULL);
987 EXPECT_EXCEPTION(sioobe_);
988
989 jchar chars[4] = { 'x', 'x', 'x', 'x' };
990 env_->GetStringRegion(s, 1, 2, &chars[1]);
991 EXPECT_EQ('x', chars[0]);
992 EXPECT_EQ('e', chars[1]);
993 EXPECT_EQ('l', chars[2]);
994 EXPECT_EQ('x', chars[3]);
995
996 env_->GetStringUTFRegion(s, -1, 0, NULL);
997 EXPECT_EXCEPTION(sioobe_);
998 env_->GetStringUTFRegion(s, 0, -1, NULL);
999 EXPECT_EXCEPTION(sioobe_);
1000 env_->GetStringUTFRegion(s, 0, 10, NULL);
1001 EXPECT_EXCEPTION(sioobe_);
1002 env_->GetStringUTFRegion(s, 10, 1, NULL);
1003 EXPECT_EXCEPTION(sioobe_);
1004
1005 char bytes[4] = { 'x', 'x', 'x', 'x' };
1006 env_->GetStringUTFRegion(s, 1, 2, &bytes[1]);
1007 EXPECT_EQ('x', bytes[0]);
1008 EXPECT_EQ('e', bytes[1]);
1009 EXPECT_EQ('l', bytes[2]);
1010 EXPECT_EQ('x', bytes[3]);
1011}
1012
Elliott Hughes75770752011-08-24 17:52:38 -07001013TEST_F(JniInternalTest, GetStringUTFChars_ReleaseStringUTFChars) {
Elliott Hughesb264f082012-04-06 17:10:10 -07001014 {
1015 // Passing in a NULL jstring is ignored normally, but caught by -Xcheck:jni.
1016 CheckJniAbortCatcher check_jni_abort_catcher;
1017 EXPECT_TRUE(env_->GetStringUTFChars(NULL, NULL) == NULL);
1018 }
Elliott Hughes75770752011-08-24 17:52:38 -07001019
1020 jstring s = env_->NewStringUTF("hello");
1021 ASSERT_TRUE(s != NULL);
1022
1023 const char* utf = env_->GetStringUTFChars(s, NULL);
1024 EXPECT_STREQ("hello", utf);
1025 env_->ReleaseStringUTFChars(s, utf);
1026
1027 jboolean is_copy = JNI_FALSE;
1028 utf = env_->GetStringUTFChars(s, &is_copy);
1029 EXPECT_EQ(JNI_TRUE, is_copy);
1030 EXPECT_STREQ("hello", utf);
1031 env_->ReleaseStringUTFChars(s, utf);
1032}
1033
1034TEST_F(JniInternalTest, GetStringChars_ReleaseStringChars) {
1035 jstring s = env_->NewStringUTF("hello");
1036 ASSERT_TRUE(s != NULL);
1037
1038 jchar expected[] = { 'h', 'e', 'l', 'l', 'o' };
1039 const jchar* chars = env_->GetStringChars(s, NULL);
1040 EXPECT_EQ(expected[0], chars[0]);
1041 EXPECT_EQ(expected[1], chars[1]);
1042 EXPECT_EQ(expected[2], chars[2]);
1043 EXPECT_EQ(expected[3], chars[3]);
1044 EXPECT_EQ(expected[4], chars[4]);
1045 env_->ReleaseStringChars(s, chars);
1046
1047 jboolean is_copy = JNI_FALSE;
1048 chars = env_->GetStringChars(s, &is_copy);
1049 EXPECT_EQ(JNI_FALSE, is_copy);
1050 EXPECT_EQ(expected[0], chars[0]);
1051 EXPECT_EQ(expected[1], chars[1]);
1052 EXPECT_EQ(expected[2], chars[2]);
1053 EXPECT_EQ(expected[3], chars[3]);
1054 EXPECT_EQ(expected[4], chars[4]);
1055 env_->ReleaseStringChars(s, chars);
1056}
1057
1058TEST_F(JniInternalTest, GetStringCritical_ReleaseStringCritical) {
1059 jstring s = env_->NewStringUTF("hello");
1060 ASSERT_TRUE(s != NULL);
1061
1062 jchar expected[] = { 'h', 'e', 'l', 'l', 'o' };
1063 const jchar* chars = env_->GetStringCritical(s, NULL);
1064 EXPECT_EQ(expected[0], chars[0]);
1065 EXPECT_EQ(expected[1], chars[1]);
1066 EXPECT_EQ(expected[2], chars[2]);
1067 EXPECT_EQ(expected[3], chars[3]);
1068 EXPECT_EQ(expected[4], chars[4]);
1069 env_->ReleaseStringCritical(s, chars);
1070
1071 jboolean is_copy = JNI_FALSE;
1072 chars = env_->GetStringCritical(s, &is_copy);
1073 EXPECT_EQ(JNI_FALSE, is_copy);
1074 EXPECT_EQ(expected[0], chars[0]);
1075 EXPECT_EQ(expected[1], chars[1]);
1076 EXPECT_EQ(expected[2], chars[2]);
1077 EXPECT_EQ(expected[3], chars[3]);
1078 EXPECT_EQ(expected[4], chars[4]);
1079 env_->ReleaseStringCritical(s, chars);
1080}
1081
Elliott Hughes814e4032011-08-23 12:07:56 -07001082TEST_F(JniInternalTest, GetObjectArrayElement_SetObjectArrayElement) {
Elliott Hughesb264f082012-04-06 17:10:10 -07001083 jclass java_lang_Class = env_->FindClass("java/lang/Class");
1084 ASSERT_TRUE(java_lang_Class != NULL);
Elliott Hughes289da822011-08-16 10:11:20 -07001085
Elliott Hughesb264f082012-04-06 17:10:10 -07001086 jobjectArray array = env_->NewObjectArray(1, java_lang_Class, NULL);
Elliott Hughes289da822011-08-16 10:11:20 -07001087 EXPECT_TRUE(array != NULL);
Elliott Hughes814e4032011-08-23 12:07:56 -07001088 EXPECT_TRUE(env_->GetObjectArrayElement(array, 0) == NULL);
Elliott Hughesb264f082012-04-06 17:10:10 -07001089 env_->SetObjectArrayElement(array, 0, java_lang_Class);
1090 EXPECT_TRUE(env_->IsSameObject(env_->GetObjectArrayElement(array, 0), java_lang_Class));
Elliott Hughesa5b897e2011-08-16 11:33:06 -07001091
1092 // ArrayIndexOutOfBounds for negative index.
Elliott Hughesb264f082012-04-06 17:10:10 -07001093 env_->SetObjectArrayElement(array, -1, java_lang_Class);
Elliott Hughes814e4032011-08-23 12:07:56 -07001094 EXPECT_EXCEPTION(aioobe_);
Elliott Hughesa5b897e2011-08-16 11:33:06 -07001095
1096 // ArrayIndexOutOfBounds for too-large index.
Elliott Hughesb264f082012-04-06 17:10:10 -07001097 env_->SetObjectArrayElement(array, 1, java_lang_Class);
Elliott Hughes814e4032011-08-23 12:07:56 -07001098 EXPECT_EXCEPTION(aioobe_);
Elliott Hughesa5b897e2011-08-16 11:33:06 -07001099
Elliott Hughesb264f082012-04-06 17:10:10 -07001100 // ArrayStoreException thrown for bad types.
1101 env_->SetObjectArrayElement(array, 0, env_->NewStringUTF("not a jclass!"));
1102 EXPECT_EXCEPTION(ase_);
Elliott Hughes289da822011-08-16 10:11:20 -07001103}
1104
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001105#define EXPECT_STATIC_PRIMITIVE_FIELD(type, field_name, sig, value1, value2) \
1106 do { \
1107 jfieldID fid = env_->GetStaticFieldID(c, field_name, sig); \
1108 EXPECT_TRUE(fid != NULL); \
1109 env_->SetStatic ## type ## Field(c, fid, value1); \
Brian Carlstrom2e3d1b22012-01-09 18:01:56 -08001110 EXPECT_TRUE(value1 == env_->GetStatic ## type ## Field(c, fid)); \
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001111 env_->SetStatic ## type ## Field(c, fid, value2); \
Brian Carlstrom2e3d1b22012-01-09 18:01:56 -08001112 EXPECT_TRUE(value2 == env_->GetStatic ## type ## Field(c, fid)); \
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001113 } while (false)
1114
1115#define EXPECT_PRIMITIVE_FIELD(instance, type, field_name, sig, value1, value2) \
1116 do { \
1117 jfieldID fid = env_->GetFieldID(c, field_name, sig); \
1118 EXPECT_TRUE(fid != NULL); \
1119 env_->Set ## type ## Field(instance, fid, value1); \
Brian Carlstrom2e3d1b22012-01-09 18:01:56 -08001120 EXPECT_TRUE(value1 == env_->Get ## type ## Field(instance, fid)); \
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001121 env_->Set ## type ## Field(instance, fid, value2); \
Brian Carlstrom2e3d1b22012-01-09 18:01:56 -08001122 EXPECT_TRUE(value2 == env_->Get ## type ## Field(instance, fid)); \
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001123 } while (false)
1124
1125
Shih-wei Liao5b8b1ed2012-02-23 23:48:21 -08001126#if !defined(ART_USE_LLVM_COMPILER)
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001127TEST_F(JniInternalTest, GetPrimitiveField_SetPrimitiveField) {
Brian Carlstrom40381fb2011-10-19 14:13:40 -07001128 SirtRef<ClassLoader> class_loader(LoadDex("AllFields"));
Brian Carlstrom25c33252011-09-18 15:58:35 -07001129 runtime_->Start();
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001130
1131 jclass c = env_->FindClass("AllFields");
1132 ASSERT_TRUE(c != NULL);
1133 jobject o = env_->AllocObject(c);
1134 ASSERT_TRUE(o != NULL);
1135
1136 EXPECT_STATIC_PRIMITIVE_FIELD(Boolean, "sZ", "Z", true, false);
1137 EXPECT_STATIC_PRIMITIVE_FIELD(Byte, "sB", "B", 1, 2);
1138 EXPECT_STATIC_PRIMITIVE_FIELD(Char, "sC", "C", 'a', 'b');
1139 EXPECT_STATIC_PRIMITIVE_FIELD(Double, "sD", "D", 1.0, 2.0);
1140 EXPECT_STATIC_PRIMITIVE_FIELD(Float, "sF", "F", 1.0, 2.0);
1141 EXPECT_STATIC_PRIMITIVE_FIELD(Int, "sI", "I", 1, 2);
1142 EXPECT_STATIC_PRIMITIVE_FIELD(Long, "sJ", "J", 1, 2);
1143 EXPECT_STATIC_PRIMITIVE_FIELD(Short, "sS", "S", 1, 2);
1144
1145 EXPECT_PRIMITIVE_FIELD(o, Boolean, "iZ", "Z", true, false);
1146 EXPECT_PRIMITIVE_FIELD(o, Byte, "iB", "B", 1, 2);
1147 EXPECT_PRIMITIVE_FIELD(o, Char, "iC", "C", 'a', 'b');
1148 EXPECT_PRIMITIVE_FIELD(o, Double, "iD", "D", 1.0, 2.0);
1149 EXPECT_PRIMITIVE_FIELD(o, Float, "iF", "F", 1.0, 2.0);
1150 EXPECT_PRIMITIVE_FIELD(o, Int, "iI", "I", 1, 2);
1151 EXPECT_PRIMITIVE_FIELD(o, Long, "iJ", "J", 1, 2);
1152 EXPECT_PRIMITIVE_FIELD(o, Short, "iS", "S", 1, 2);
1153}
1154
1155TEST_F(JniInternalTest, GetObjectField_SetObjectField) {
Brian Carlstrom40381fb2011-10-19 14:13:40 -07001156 SirtRef<ClassLoader> class_loader(LoadDex("AllFields"));
Brian Carlstrom25c33252011-09-18 15:58:35 -07001157 runtime_->Start();
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001158
1159 jclass c = env_->FindClass("AllFields");
1160 ASSERT_TRUE(c != NULL);
1161 jobject o = env_->AllocObject(c);
1162 ASSERT_TRUE(o != NULL);
1163
1164 jstring s1 = env_->NewStringUTF("hello");
1165 ASSERT_TRUE(s1 != NULL);
1166 jstring s2 = env_->NewStringUTF("world");
1167 ASSERT_TRUE(s2 != NULL);
1168
1169 jfieldID s_fid = env_->GetStaticFieldID(c, "sObject", "Ljava/lang/Object;");
1170 ASSERT_TRUE(s_fid != NULL);
1171 jfieldID i_fid = env_->GetFieldID(c, "iObject", "Ljava/lang/Object;");
1172 ASSERT_TRUE(i_fid != NULL);
1173
1174 env_->SetStaticObjectField(c, s_fid, s1);
1175 ASSERT_TRUE(env_->IsSameObject(s1, env_->GetStaticObjectField(c, s_fid)));
1176 env_->SetStaticObjectField(c, s_fid, s2);
1177 ASSERT_TRUE(env_->IsSameObject(s2, env_->GetStaticObjectField(c, s_fid)));
1178
1179 env_->SetObjectField(o, i_fid, s1);
1180 ASSERT_TRUE(env_->IsSameObject(s1, env_->GetObjectField(o, i_fid)));
1181 env_->SetObjectField(o, i_fid, s2);
1182 ASSERT_TRUE(env_->IsSameObject(s2, env_->GetObjectField(o, i_fid)));
1183}
Shih-wei Liao5b8b1ed2012-02-23 23:48:21 -08001184#endif
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001185
Elliott Hughes18c07532011-08-18 15:50:51 -07001186TEST_F(JniInternalTest, NewLocalRef_NULL) {
1187 EXPECT_TRUE(env_->NewLocalRef(NULL) == NULL);
1188}
1189
1190TEST_F(JniInternalTest, NewLocalRef) {
1191 jstring s = env_->NewStringUTF("");
1192 ASSERT_TRUE(s != NULL);
1193 jobject o = env_->NewLocalRef(s);
1194 EXPECT_TRUE(o != NULL);
1195 EXPECT_TRUE(o != s);
1196
Elliott Hughes2ced6a52011-10-16 18:44:48 -07001197 EXPECT_EQ(JNILocalRefType, env_->GetObjectRefType(o));
Elliott Hughes18c07532011-08-18 15:50:51 -07001198}
1199
1200TEST_F(JniInternalTest, DeleteLocalRef_NULL) {
1201 env_->DeleteLocalRef(NULL);
1202}
1203
1204TEST_F(JniInternalTest, DeleteLocalRef) {
1205 jstring s = env_->NewStringUTF("");
1206 ASSERT_TRUE(s != NULL);
1207 env_->DeleteLocalRef(s);
1208
Elliott Hughesb264f082012-04-06 17:10:10 -07001209 {
1210 // Currently, deleting an already-deleted reference is just a CheckJNI warning.
1211 CheckJniAbortCatcher check_jni_abort_catcher;
1212 env_->DeleteLocalRef(s);
1213 }
Elliott Hughes18c07532011-08-18 15:50:51 -07001214
1215 s = env_->NewStringUTF("");
1216 ASSERT_TRUE(s != NULL);
1217 jobject o = env_->NewLocalRef(s);
1218 ASSERT_TRUE(o != NULL);
1219
1220 env_->DeleteLocalRef(s);
1221 env_->DeleteLocalRef(o);
1222}
1223
Elliott Hughes2ced6a52011-10-16 18:44:48 -07001224TEST_F(JniInternalTest, PushLocalFrame_PopLocalFrame) {
1225 jobject original = env_->NewStringUTF("");
1226 ASSERT_TRUE(original != NULL);
1227
1228 jobject outer;
1229 jobject inner1, inner2;
1230 Object* inner2_direct_pointer;
1231 {
1232 env_->PushLocalFrame(4);
1233 outer = env_->NewLocalRef(original);
1234
1235 {
1236 env_->PushLocalFrame(4);
1237 inner1 = env_->NewLocalRef(outer);
1238 inner2 = env_->NewStringUTF("survivor");
1239 inner2_direct_pointer = Decode<Object*>(env_, inner2);
1240 env_->PopLocalFrame(inner2);
1241 }
1242
1243 EXPECT_EQ(JNILocalRefType, env_->GetObjectRefType(original));
1244 EXPECT_EQ(JNILocalRefType, env_->GetObjectRefType(outer));
1245 EXPECT_EQ(JNIInvalidRefType, env_->GetObjectRefType(inner1));
1246
1247 // Our local reference for the survivor is invalid because the survivor
1248 // gets a new local reference...
1249 EXPECT_EQ(JNIInvalidRefType, env_->GetObjectRefType(inner2));
1250 // ...but the survivor should be in the local reference table.
1251 EXPECT_TRUE(env_->locals.ContainsDirectPointer(inner2_direct_pointer));
1252
1253 env_->PopLocalFrame(NULL);
1254 }
1255 EXPECT_EQ(JNILocalRefType, env_->GetObjectRefType(original));
1256 EXPECT_EQ(JNIInvalidRefType, env_->GetObjectRefType(outer));
1257 EXPECT_EQ(JNIInvalidRefType, env_->GetObjectRefType(inner1));
1258 EXPECT_EQ(JNIInvalidRefType, env_->GetObjectRefType(inner2));
1259}
1260
Elliott Hughes18c07532011-08-18 15:50:51 -07001261TEST_F(JniInternalTest, NewGlobalRef_NULL) {
1262 EXPECT_TRUE(env_->NewGlobalRef(NULL) == NULL);
1263}
1264
1265TEST_F(JniInternalTest, NewGlobalRef) {
1266 jstring s = env_->NewStringUTF("");
1267 ASSERT_TRUE(s != NULL);
1268 jobject o = env_->NewGlobalRef(s);
1269 EXPECT_TRUE(o != NULL);
1270 EXPECT_TRUE(o != s);
1271
1272 // TODO: check that o is a global reference.
1273}
1274
1275TEST_F(JniInternalTest, DeleteGlobalRef_NULL) {
1276 env_->DeleteGlobalRef(NULL);
1277}
1278
1279TEST_F(JniInternalTest, DeleteGlobalRef) {
1280 jstring s = env_->NewStringUTF("");
1281 ASSERT_TRUE(s != NULL);
1282
1283 jobject o = env_->NewGlobalRef(s);
1284 ASSERT_TRUE(o != NULL);
1285 env_->DeleteGlobalRef(o);
1286
Elliott Hughesb264f082012-04-06 17:10:10 -07001287 {
1288 // Currently, deleting an already-deleted reference is just a CheckJNI warning.
1289 CheckJniAbortCatcher check_jni_abort_catcher;
1290 env_->DeleteGlobalRef(o);
1291 }
Elliott Hughes18c07532011-08-18 15:50:51 -07001292
1293 jobject o1 = env_->NewGlobalRef(s);
1294 ASSERT_TRUE(o1 != NULL);
1295 jobject o2 = env_->NewGlobalRef(s);
1296 ASSERT_TRUE(o2 != NULL);
1297
1298 env_->DeleteGlobalRef(o1);
1299 env_->DeleteGlobalRef(o2);
1300}
1301
1302TEST_F(JniInternalTest, NewWeakGlobalRef_NULL) {
1303 EXPECT_TRUE(env_->NewWeakGlobalRef(NULL) == NULL);
1304}
1305
1306TEST_F(JniInternalTest, NewWeakGlobalRef) {
1307 jstring s = env_->NewStringUTF("");
1308 ASSERT_TRUE(s != NULL);
1309 jobject o = env_->NewWeakGlobalRef(s);
1310 EXPECT_TRUE(o != NULL);
1311 EXPECT_TRUE(o != s);
1312
1313 // TODO: check that o is a weak global reference.
1314}
1315
1316TEST_F(JniInternalTest, DeleteWeakGlobalRef_NULL) {
1317 env_->DeleteWeakGlobalRef(NULL);
1318}
1319
1320TEST_F(JniInternalTest, DeleteWeakGlobalRef) {
1321 jstring s = env_->NewStringUTF("");
1322 ASSERT_TRUE(s != NULL);
1323
1324 jobject o = env_->NewWeakGlobalRef(s);
1325 ASSERT_TRUE(o != NULL);
1326 env_->DeleteWeakGlobalRef(o);
1327
Elliott Hughesb264f082012-04-06 17:10:10 -07001328 {
1329 // Currently, deleting an already-deleted reference is just a CheckJNI warning.
1330 CheckJniAbortCatcher check_jni_abort_catcher;
1331 env_->DeleteWeakGlobalRef(o);
1332 }
Elliott Hughes18c07532011-08-18 15:50:51 -07001333
1334 jobject o1 = env_->NewWeakGlobalRef(s);
1335 ASSERT_TRUE(o1 != NULL);
1336 jobject o2 = env_->NewWeakGlobalRef(s);
1337 ASSERT_TRUE(o2 != NULL);
1338
1339 env_->DeleteWeakGlobalRef(o1);
1340 env_->DeleteWeakGlobalRef(o2);
1341}
1342
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001343TEST_F(JniInternalTest, StaticMainMethod) {
Brian Carlstrom40381fb2011-10-19 14:13:40 -07001344 SirtRef<ClassLoader> class_loader(LoadDex("Main"));
1345 CompileDirectMethod(class_loader.get(), "Main", "main", "([Ljava/lang/String;)V");
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001346
Brian Carlstrom40381fb2011-10-19 14:13:40 -07001347 Class* klass = class_linker_->FindClass("LMain;", class_loader.get());
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001348 ASSERT_TRUE(klass != NULL);
1349
1350 Method* method = klass->FindDirectMethod("main", "([Ljava/lang/String;)V");
1351 ASSERT_TRUE(method != NULL);
1352
Brian Carlstrom9baa4ae2011-09-01 21:14:14 -07001353 Method::InvokeStub* stub = method->GetInvokeStub();
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001354
Elliott Hughes77405792012-03-15 15:22:12 -07001355 JValue args[1];
1356 args[0].l = NULL;
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001357
Elliott Hughes77405792012-03-15 15:22:12 -07001358 (*stub)(method, NULL, Thread::Current(), args, NULL);
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001359}
1360
1361TEST_F(JniInternalTest, StaticNopMethod) {
Elliott Hughes77405792012-03-15 15:22:12 -07001362 InvokeNopMethod(true);
1363}
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001364
Elliott Hughes77405792012-03-15 15:22:12 -07001365TEST_F(JniInternalTest, NonStaticNopMethod) {
1366 InvokeNopMethod(false);
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001367}
1368
1369TEST_F(JniInternalTest, StaticIdentityByteMethod) {
Elliott Hughes77405792012-03-15 15:22:12 -07001370 InvokeIdentityByteMethod(true);
1371}
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001372
Elliott Hughes77405792012-03-15 15:22:12 -07001373TEST_F(JniInternalTest, NonStaticIdentityByteMethod) {
1374 InvokeIdentityByteMethod(false);
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001375}
1376
1377TEST_F(JniInternalTest, StaticIdentityIntMethod) {
Elliott Hughes77405792012-03-15 15:22:12 -07001378 InvokeIdentityIntMethod(true);
1379}
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001380
Elliott Hughes77405792012-03-15 15:22:12 -07001381TEST_F(JniInternalTest, NonStaticIdentityIntMethod) {
1382 InvokeIdentityIntMethod(false);
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001383}
1384
1385TEST_F(JniInternalTest, StaticIdentityDoubleMethod) {
Elliott Hughes77405792012-03-15 15:22:12 -07001386 InvokeIdentityDoubleMethod(true);
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001387}
1388
Elliott Hughes77405792012-03-15 15:22:12 -07001389TEST_F(JniInternalTest, NonStaticIdentityDoubleMethod) {
1390 InvokeIdentityDoubleMethod(false);
Shih-wei Liao5b8b1ed2012-02-23 23:48:21 -08001391}
1392
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001393TEST_F(JniInternalTest, StaticSumIntIntMethod) {
Elliott Hughes77405792012-03-15 15:22:12 -07001394 InvokeSumIntIntMethod(true);
1395}
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001396
Elliott Hughes77405792012-03-15 15:22:12 -07001397TEST_F(JniInternalTest, NonStaticSumIntIntMethod) {
1398 InvokeSumIntIntMethod(false);
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001399}
1400
1401TEST_F(JniInternalTest, StaticSumIntIntIntMethod) {
Elliott Hughes77405792012-03-15 15:22:12 -07001402 InvokeSumIntIntIntMethod(true);
1403}
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001404
Elliott Hughes77405792012-03-15 15:22:12 -07001405TEST_F(JniInternalTest, NonStaticSumIntIntIntMethod) {
1406 InvokeSumIntIntIntMethod(false);
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001407}
1408
1409TEST_F(JniInternalTest, StaticSumIntIntIntIntMethod) {
Elliott Hughes77405792012-03-15 15:22:12 -07001410 InvokeSumIntIntIntIntMethod(true);
1411}
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001412
Elliott Hughes77405792012-03-15 15:22:12 -07001413TEST_F(JniInternalTest, NonStaticSumIntIntIntIntMethod) {
1414 InvokeSumIntIntIntIntMethod(false);
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001415}
1416
1417TEST_F(JniInternalTest, StaticSumIntIntIntIntIntMethod) {
Elliott Hughes77405792012-03-15 15:22:12 -07001418 InvokeSumIntIntIntIntIntMethod(true);
1419}
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001420
Elliott Hughes77405792012-03-15 15:22:12 -07001421TEST_F(JniInternalTest, NonStaticSumIntIntIntIntIntMethod) {
1422 InvokeSumIntIntIntIntIntMethod(false);
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001423}
1424
1425TEST_F(JniInternalTest, StaticSumDoubleDoubleMethod) {
Elliott Hughes77405792012-03-15 15:22:12 -07001426 InvokeSumDoubleDoubleMethod(true);
1427}
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001428
Elliott Hughes77405792012-03-15 15:22:12 -07001429TEST_F(JniInternalTest, NonStaticSumDoubleDoubleMethod) {
1430 InvokeSumDoubleDoubleMethod(false);
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001431}
1432
1433TEST_F(JniInternalTest, StaticSumDoubleDoubleDoubleMethod) {
Elliott Hughes77405792012-03-15 15:22:12 -07001434 InvokeSumDoubleDoubleDoubleMethod(true);
1435}
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001436
Elliott Hughes77405792012-03-15 15:22:12 -07001437TEST_F(JniInternalTest, NonStaticSumDoubleDoubleDoubleMethod) {
1438 InvokeSumDoubleDoubleDoubleMethod(false);
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001439}
1440
1441TEST_F(JniInternalTest, StaticSumDoubleDoubleDoubleDoubleMethod) {
Elliott Hughes77405792012-03-15 15:22:12 -07001442 InvokeSumDoubleDoubleDoubleDoubleMethod(true);
1443}
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001444
Elliott Hughes77405792012-03-15 15:22:12 -07001445TEST_F(JniInternalTest, NonStaticSumDoubleDoubleDoubleDoubleMethod) {
1446 InvokeSumDoubleDoubleDoubleDoubleMethod(false);
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001447}
1448
1449TEST_F(JniInternalTest, StaticSumDoubleDoubleDoubleDoubleDoubleMethod) {
Elliott Hughes77405792012-03-15 15:22:12 -07001450 InvokeSumDoubleDoubleDoubleDoubleDoubleMethod(true);
1451}
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001452
Elliott Hughes77405792012-03-15 15:22:12 -07001453TEST_F(JniInternalTest, NonStaticSumDoubleDoubleDoubleDoubleDoubleMethod) {
1454 InvokeSumDoubleDoubleDoubleDoubleDoubleMethod(false);
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001455}
Carl Shapiro9b9ba282011-08-14 15:30:39 -07001456
Elliott Hughes37f7a402011-08-22 18:56:01 -07001457TEST_F(JniInternalTest, Throw) {
1458 EXPECT_EQ(JNI_ERR, env_->Throw(NULL));
1459
1460 jclass exception_class = env_->FindClass("java/lang/RuntimeException");
1461 ASSERT_TRUE(exception_class != NULL);
1462 jthrowable exception = reinterpret_cast<jthrowable>(env_->AllocObject(exception_class));
1463 ASSERT_TRUE(exception != NULL);
1464
1465 EXPECT_EQ(JNI_OK, env_->Throw(exception));
1466 EXPECT_TRUE(env_->ExceptionCheck());
Elliott Hughesa2501992011-08-26 19:39:54 -07001467 jthrowable thrown_exception = env_->ExceptionOccurred();
Elliott Hughes37f7a402011-08-22 18:56:01 -07001468 env_->ExceptionClear();
Elliott Hughesa2501992011-08-26 19:39:54 -07001469 EXPECT_TRUE(env_->IsSameObject(exception, thrown_exception));
Elliott Hughes37f7a402011-08-22 18:56:01 -07001470}
1471
1472TEST_F(JniInternalTest, ThrowNew) {
1473 EXPECT_EQ(JNI_ERR, env_->Throw(NULL));
1474
1475 jclass exception_class = env_->FindClass("java/lang/RuntimeException");
1476 ASSERT_TRUE(exception_class != NULL);
1477
Elliott Hughes5cb5ad22011-10-02 12:13:39 -07001478 jthrowable thrown_exception;
1479
Elliott Hughes37f7a402011-08-22 18:56:01 -07001480 EXPECT_EQ(JNI_OK, env_->ThrowNew(exception_class, "hello world"));
1481 EXPECT_TRUE(env_->ExceptionCheck());
Elliott Hughes5cb5ad22011-10-02 12:13:39 -07001482 thrown_exception = env_->ExceptionOccurred();
1483 env_->ExceptionClear();
1484 EXPECT_TRUE(env_->IsInstanceOf(thrown_exception, exception_class));
1485
1486 EXPECT_EQ(JNI_OK, env_->ThrowNew(exception_class, NULL));
1487 EXPECT_TRUE(env_->ExceptionCheck());
1488 thrown_exception = env_->ExceptionOccurred();
Elliott Hughes37f7a402011-08-22 18:56:01 -07001489 env_->ExceptionClear();
Elliott Hughesa2501992011-08-26 19:39:54 -07001490 EXPECT_TRUE(env_->IsInstanceOf(thrown_exception, exception_class));
Elliott Hughes37f7a402011-08-22 18:56:01 -07001491}
1492
Elliott Hughesb465ab02011-08-24 11:21:21 -07001493// TODO: this test is DISABLED until we can actually run java.nio.Buffer's <init>.
1494TEST_F(JniInternalTest, DISABLED_NewDirectBuffer_GetDirectBufferAddress_GetDirectBufferCapacity) {
1495 jclass buffer_class = env_->FindClass("java/nio/Buffer");
1496 ASSERT_TRUE(buffer_class != NULL);
1497
1498 char bytes[1024];
1499 jobject buffer = env_->NewDirectByteBuffer(bytes, sizeof(bytes));
1500 ASSERT_TRUE(buffer != NULL);
1501 ASSERT_TRUE(env_->IsInstanceOf(buffer, buffer_class));
1502 ASSERT_TRUE(env_->GetDirectBufferAddress(buffer) == bytes);
1503 ASSERT_TRUE(env_->GetDirectBufferCapacity(buffer) == sizeof(bytes));
1504}
1505
Ian Rogers6d0b13e2012-02-07 09:25:29 -08001506TEST_F(JniInternalTest, MonitorEnterExit) {
1507 // Create an object to torture
1508 jclass object_class = env_->FindClass("java/lang/Object");
1509 ASSERT_TRUE(object_class != NULL);
1510 jobject object = env_->AllocObject(object_class);
1511 ASSERT_TRUE(object != NULL);
1512
1513 // Expected class of exceptions
1514 jclass imse_class = env_->FindClass("java/lang/IllegalMonitorStateException");
1515 ASSERT_TRUE(imse_class != NULL);
1516
1517 jthrowable thrown_exception;
1518
1519 // Unlock of unowned monitor
1520 env_->MonitorExit(object);
1521 EXPECT_TRUE(env_->ExceptionCheck());
1522 thrown_exception = env_->ExceptionOccurred();
1523 env_->ExceptionClear();
1524 EXPECT_TRUE(env_->IsInstanceOf(thrown_exception, imse_class));
1525
1526 // Lock of unowned monitor
1527 env_->MonitorEnter(object);
1528 EXPECT_FALSE(env_->ExceptionCheck());
1529 // Regular unlock
1530 env_->MonitorExit(object);
1531 EXPECT_FALSE(env_->ExceptionCheck());
1532
1533 // Recursively lock a lot
1534 size_t max_recursive_lock = 1024;
1535 for (size_t i = 0; i < max_recursive_lock; i++) {
1536 env_->MonitorEnter(object);
1537 EXPECT_FALSE(env_->ExceptionCheck());
1538 }
1539 // Recursively unlock a lot
1540 for (size_t i = 0; i < max_recursive_lock; i++) {
1541 env_->MonitorExit(object);
1542 EXPECT_FALSE(env_->ExceptionCheck());
1543 }
1544
1545 // Unlock of unowned monitor
1546 env_->MonitorExit(object);
1547 EXPECT_TRUE(env_->ExceptionCheck());
1548 thrown_exception = env_->ExceptionOccurred();
1549 env_->ExceptionClear();
1550 EXPECT_TRUE(env_->IsInstanceOf(thrown_exception, imse_class));
Elliott Hughesa92853e2012-02-07 16:09:27 -08001551
1552 // It's an error to call MonitorEnter or MonitorExit on NULL.
Elliott Hughesb264f082012-04-06 17:10:10 -07001553 {
1554 CheckJniAbortCatcher check_jni_abort_catcher;
1555 env_->MonitorEnter(NULL);
1556 check_jni_abort_catcher.Check("in call to MonitorEnter");
1557 }
1558
1559 {
1560 CheckJniAbortCatcher check_jni_abort_catcher;
1561 env_->MonitorExit(NULL);
1562 check_jni_abort_catcher.Check("in call to MonitorExit");
1563 }
Ian Rogers6d0b13e2012-02-07 09:25:29 -08001564}
1565
Ian Rogers0cfe1fb2011-08-26 03:29:44 -07001566} // namespace art