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: 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 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 76 virtual void TearDown() { 77 CleanUpJniEnv(); 78 CommonTest::TearDown(); 79 } 80 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 971 void BogusMethod() { 972 // You can't pass NULL function pointers to RegisterNatives. 973 } 974 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 1067 TEST_F(JniInternalTest, BooleanArrays) { 1068 EXPECT_PRIMITIVE_ARRAY(NewBooleanArray, GetBooleanArrayRegion, SetBooleanArrayRegion, 1069 GetBooleanArrayElements, ReleaseBooleanArrayElements, jboolean, "[Z"); 1070 } 1071 TEST_F(JniInternalTest, ByteArrays) { 1072 EXPECT_PRIMITIVE_ARRAY(NewByteArray, GetByteArrayRegion, SetByteArrayRegion, 1073 GetByteArrayElements, ReleaseByteArrayElements, jbyte, "[B"); 1074 } 1075 TEST_F(JniInternalTest, CharArrays) { 1076 EXPECT_PRIMITIVE_ARRAY(NewCharArray, GetCharArrayRegion, SetCharArrayRegion, 1077 GetCharArrayElements, ReleaseCharArrayElements, jchar, "[C"); 1078 } 1079 TEST_F(JniInternalTest, DoubleArrays) { 1080 EXPECT_PRIMITIVE_ARRAY(NewDoubleArray, GetDoubleArrayRegion, SetDoubleArrayRegion, 1081 GetDoubleArrayElements, ReleaseDoubleArrayElements, jdouble, "[D"); 1082 } 1083 TEST_F(JniInternalTest, FloatArrays) { 1084 EXPECT_PRIMITIVE_ARRAY(NewFloatArray, GetFloatArrayRegion, SetFloatArrayRegion, 1085 GetFloatArrayElements, ReleaseFloatArrayElements, jfloat, "[F"); 1086 } 1087 TEST_F(JniInternalTest, IntArrays) { 1088 EXPECT_PRIMITIVE_ARRAY(NewIntArray, GetIntArrayRegion, SetIntArrayRegion, 1089 GetIntArrayElements, ReleaseIntArrayElements, jint, "[I"); 1090 } 1091 TEST_F(JniInternalTest, LongArrays) { 1092 EXPECT_PRIMITIVE_ARRAY(NewLongArray, GetLongArrayRegion, SetLongArrayRegion, 1093 GetLongArrayElements, ReleaseLongArrayElements, jlong, "[J"); 1094 } 1095 TEST_F(JniInternalTest, ShortArrays) { 1096 EXPECT_PRIMITIVE_ARRAY(NewShortArray, GetShortArrayRegion, SetShortArrayRegion, 1097 GetShortArrayElements, ReleaseShortArrayElements, jshort, "[S"); 1098 } 1099 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 1132 TEST_F(JniInternalTest, GetArrayLength) { 1133 // Already tested in NewObjectArray/NewPrimitiveArray. 1134 } 1135 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 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 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 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 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 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 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) 1227 TEST_F(JniInternalTest, DISABLED_NewStringNullCharsNonzeroLength) { 1228 ASSERT_DEATH(env_->NewString(NULL, 1), ""); 1229 } 1230 1231 TEST_F(JniInternalTest, GetStringLength_GetStringUTFLength) { 1232 // Already tested in the NewString/NewStringUTF tests. 1233 } 1234 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 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 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 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 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) 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 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 1449 TEST_F(JniInternalTest, NewLocalRef_NULL) { 1450 EXPECT_TRUE(env_->NewLocalRef(NULL) == NULL); 1451 } 1452 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 1463 TEST_F(JniInternalTest, DeleteLocalRef_NULL) { 1464 env_->DeleteLocalRef(NULL); 1465 } 1466 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 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 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 1545 TEST_F(JniInternalTest, NewGlobalRef_NULL) { 1546 EXPECT_TRUE(env_->NewGlobalRef(NULL) == NULL); 1547 } 1548 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 1559 TEST_F(JniInternalTest, DeleteGlobalRef_NULL) { 1560 env_->DeleteGlobalRef(NULL); 1561 } 1562 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 1590 TEST_F(JniInternalTest, NewWeakGlobalRef_NULL) { 1591 EXPECT_TRUE(env_->NewWeakGlobalRef(NULL) == NULL); 1592 } 1593 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 1604 TEST_F(JniInternalTest, DeleteWeakGlobalRef_NULL) { 1605 env_->DeleteWeakGlobalRef(NULL); 1606 } 1607 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 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 1661 TEST_F(JniInternalTest, StaticNopMethod) { 1662 TEST_DISABLED_FOR_PORTABLE(); 1663 ScopedObjectAccess soa(Thread::Current()); 1664 InvokeNopMethod(true); 1665 } 1666 1667 TEST_F(JniInternalTest, NonStaticNopMethod) { 1668 TEST_DISABLED_FOR_PORTABLE(); 1669 ScopedObjectAccess soa(Thread::Current()); 1670 InvokeNopMethod(false); 1671 } 1672 1673 TEST_F(JniInternalTest, StaticIdentityByteMethod) { 1674 TEST_DISABLED_FOR_PORTABLE(); 1675 ScopedObjectAccess soa(Thread::Current()); 1676 InvokeIdentityByteMethod(true); 1677 } 1678 1679 TEST_F(JniInternalTest, NonStaticIdentityByteMethod) { 1680 TEST_DISABLED_FOR_PORTABLE(); 1681 ScopedObjectAccess soa(Thread::Current()); 1682 InvokeIdentityByteMethod(false); 1683 } 1684 1685 TEST_F(JniInternalTest, StaticIdentityIntMethod) { 1686 TEST_DISABLED_FOR_PORTABLE(); 1687 ScopedObjectAccess soa(Thread::Current()); 1688 InvokeIdentityIntMethod(true); 1689 } 1690 1691 TEST_F(JniInternalTest, NonStaticIdentityIntMethod) { 1692 TEST_DISABLED_FOR_PORTABLE(); 1693 ScopedObjectAccess soa(Thread::Current()); 1694 InvokeIdentityIntMethod(false); 1695 } 1696 1697 TEST_F(JniInternalTest, StaticIdentityDoubleMethod) { 1698 TEST_DISABLED_FOR_PORTABLE(); 1699 ScopedObjectAccess soa(Thread::Current()); 1700 InvokeIdentityDoubleMethod(true); 1701 } 1702 1703 TEST_F(JniInternalTest, NonStaticIdentityDoubleMethod) { 1704 TEST_DISABLED_FOR_PORTABLE(); 1705 ScopedObjectAccess soa(Thread::Current()); 1706 InvokeIdentityDoubleMethod(false); 1707 } 1708 1709 TEST_F(JniInternalTest, StaticSumIntIntMethod) { 1710 TEST_DISABLED_FOR_PORTABLE(); 1711 ScopedObjectAccess soa(Thread::Current()); 1712 InvokeSumIntIntMethod(true); 1713 } 1714 1715 TEST_F(JniInternalTest, NonStaticSumIntIntMethod) { 1716 TEST_DISABLED_FOR_PORTABLE(); 1717 ScopedObjectAccess soa(Thread::Current()); 1718 InvokeSumIntIntMethod(false); 1719 } 1720 1721 TEST_F(JniInternalTest, StaticSumIntIntIntMethod) { 1722 TEST_DISABLED_FOR_PORTABLE(); 1723 ScopedObjectAccess soa(Thread::Current()); 1724 InvokeSumIntIntIntMethod(true); 1725 } 1726 1727 TEST_F(JniInternalTest, NonStaticSumIntIntIntMethod) { 1728 TEST_DISABLED_FOR_PORTABLE(); 1729 ScopedObjectAccess soa(Thread::Current()); 1730 InvokeSumIntIntIntMethod(false); 1731 } 1732 1733 TEST_F(JniInternalTest, StaticSumIntIntIntIntMethod) { 1734 TEST_DISABLED_FOR_PORTABLE(); 1735 ScopedObjectAccess soa(Thread::Current()); 1736 InvokeSumIntIntIntIntMethod(true); 1737 } 1738 1739 TEST_F(JniInternalTest, NonStaticSumIntIntIntIntMethod) { 1740 TEST_DISABLED_FOR_PORTABLE(); 1741 ScopedObjectAccess soa(Thread::Current()); 1742 InvokeSumIntIntIntIntMethod(false); 1743 } 1744 1745 TEST_F(JniInternalTest, StaticSumIntIntIntIntIntMethod) { 1746 TEST_DISABLED_FOR_PORTABLE(); 1747 ScopedObjectAccess soa(Thread::Current()); 1748 InvokeSumIntIntIntIntIntMethod(true); 1749 } 1750 1751 TEST_F(JniInternalTest, NonStaticSumIntIntIntIntIntMethod) { 1752 TEST_DISABLED_FOR_PORTABLE(); 1753 ScopedObjectAccess soa(Thread::Current()); 1754 InvokeSumIntIntIntIntIntMethod(false); 1755 } 1756 1757 TEST_F(JniInternalTest, StaticSumDoubleDoubleMethod) { 1758 TEST_DISABLED_FOR_PORTABLE(); 1759 ScopedObjectAccess soa(Thread::Current()); 1760 InvokeSumDoubleDoubleMethod(true); 1761 } 1762 1763 TEST_F(JniInternalTest, NonStaticSumDoubleDoubleMethod) { 1764 TEST_DISABLED_FOR_PORTABLE(); 1765 ScopedObjectAccess soa(Thread::Current()); 1766 InvokeSumDoubleDoubleMethod(false); 1767 } 1768 1769 TEST_F(JniInternalTest, StaticSumDoubleDoubleDoubleMethod) { 1770 TEST_DISABLED_FOR_PORTABLE(); 1771 ScopedObjectAccess soa(Thread::Current()); 1772 InvokeSumDoubleDoubleDoubleMethod(true); 1773 } 1774 1775 TEST_F(JniInternalTest, NonStaticSumDoubleDoubleDoubleMethod) { 1776 TEST_DISABLED_FOR_PORTABLE(); 1777 ScopedObjectAccess soa(Thread::Current()); 1778 InvokeSumDoubleDoubleDoubleMethod(false); 1779 } 1780 1781 TEST_F(JniInternalTest, StaticSumDoubleDoubleDoubleDoubleMethod) { 1782 TEST_DISABLED_FOR_PORTABLE(); 1783 ScopedObjectAccess soa(Thread::Current()); 1784 InvokeSumDoubleDoubleDoubleDoubleMethod(true); 1785 } 1786 1787 TEST_F(JniInternalTest, NonStaticSumDoubleDoubleDoubleDoubleMethod) { 1788 TEST_DISABLED_FOR_PORTABLE(); 1789 ScopedObjectAccess soa(Thread::Current()); 1790 InvokeSumDoubleDoubleDoubleDoubleMethod(false); 1791 } 1792 1793 TEST_F(JniInternalTest, StaticSumDoubleDoubleDoubleDoubleDoubleMethod) { 1794 TEST_DISABLED_FOR_PORTABLE(); 1795 ScopedObjectAccess soa(Thread::Current()); 1796 InvokeSumDoubleDoubleDoubleDoubleDoubleMethod(true); 1797 } 1798 1799 TEST_F(JniInternalTest, NonStaticSumDoubleDoubleDoubleDoubleDoubleMethod) { 1800 TEST_DISABLED_FOR_PORTABLE(); 1801 ScopedObjectAccess soa(Thread::Current()); 1802 InvokeSumDoubleDoubleDoubleDoubleDoubleMethod(false); 1803 } 1804 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 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>. 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 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 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