2437 } |
2437 } |
2438 } else if (opcode == Bytecodes::_invokespecial |
2438 } else if (opcode == Bytecodes::_invokespecial |
2439 && !ref_class_type.equals(current_type()) |
2439 && !ref_class_type.equals(current_type()) |
2440 && !ref_class_type.equals(VerificationType::reference_type( |
2440 && !ref_class_type.equals(VerificationType::reference_type( |
2441 current_class()->super()->name()))) { |
2441 current_class()->super()->name()))) { |
2442 bool subtype = ref_class_type.is_assignable_from( |
2442 bool subtype = false; |
2443 current_type(), this, CHECK_VERIFY(this)); |
2443 if (!current_class()->is_anonymous()) { |
|
2444 subtype = ref_class_type.is_assignable_from( |
|
2445 current_type(), this, CHECK_VERIFY(this)); |
|
2446 } else { |
|
2447 subtype = ref_class_type.is_assignable_from(VerificationType::reference_type( |
|
2448 current_class()->host_klass()->name()), this, CHECK_VERIFY(this)); |
|
2449 } |
2444 if (!subtype) { |
2450 if (!subtype) { |
2445 if (current_class()->is_anonymous()) { |
2451 verify_error(ErrorContext::bad_code(bci), |
2446 subtype = ref_class_type.is_assignable_from(VerificationType::reference_type( |
2452 "Bad invokespecial instruction: " |
2447 current_class()->host_klass()->name()), this, CHECK_VERIFY(this)); |
2453 "current class isn't assignable to reference class."); |
2448 } |
2454 return; |
2449 if (!subtype) { |
|
2450 verify_error(ErrorContext::bad_code(bci), |
|
2451 "Bad invokespecial instruction: " |
|
2452 "current class isn't assignable to reference class."); |
|
2453 return; |
|
2454 } |
|
2455 } |
2455 } |
2456 } |
2456 } |
2457 // Match method descriptor with operand stack |
2457 // Match method descriptor with operand stack |
2458 for (int i = nargs - 1; i >= 0; i--) { // Run backwards |
2458 for (int i = nargs - 1; i >= 0; i--) { // Run backwards |
2459 current_frame->pop_stack(sig_types[i], CHECK_VERIFY(this)); |
2459 current_frame->pop_stack(sig_types[i], CHECK_VERIFY(this)); |
2468 // Ensures that target class is assignable to method class. |
2468 // Ensures that target class is assignable to method class. |
2469 if (opcode == Bytecodes::_invokespecial) { |
2469 if (opcode == Bytecodes::_invokespecial) { |
2470 if (!current_class()->is_anonymous()) { |
2470 if (!current_class()->is_anonymous()) { |
2471 current_frame->pop_stack(current_type(), CHECK_VERIFY(this)); |
2471 current_frame->pop_stack(current_type(), CHECK_VERIFY(this)); |
2472 } else { |
2472 } else { |
2473 // anonymous class invokespecial calls: either the |
2473 // anonymous class invokespecial calls: check if the |
2474 // operand stack/objectref is a subtype of the current class OR |
2474 // objectref is a subtype of the host_klass of the current class |
2475 // the objectref is a subtype of the host_klass of the current class |
|
2476 // to allow an anonymous class to reference methods in the host_klass |
2475 // to allow an anonymous class to reference methods in the host_klass |
2477 VerificationType top = current_frame->pop_stack(CHECK_VERIFY(this)); |
2476 VerificationType top = current_frame->pop_stack(CHECK_VERIFY(this)); |
2478 bool subtype = current_type().is_assignable_from(top, this, CHECK_VERIFY(this)); |
2477 VerificationType hosttype = |
2479 if (!subtype) { |
2478 VerificationType::reference_type(current_class()->host_klass()->name()); |
2480 VerificationType hosttype = |
2479 bool subtype = hosttype.is_assignable_from(top, this, CHECK_VERIFY(this)); |
2481 VerificationType::reference_type(current_class()->host_klass()->name()); |
|
2482 subtype = hosttype.is_assignable_from(top, this, CHECK_VERIFY(this)); |
|
2483 } |
|
2484 if (!subtype) { |
2480 if (!subtype) { |
2485 verify_error( ErrorContext::bad_type(current_frame->offset(), |
2481 verify_error( ErrorContext::bad_type(current_frame->offset(), |
2486 current_frame->stack_top_ctx(), |
2482 current_frame->stack_top_ctx(), |
2487 TypeOrigin::implicit(top)), |
2483 TypeOrigin::implicit(top)), |
2488 "Bad type on operand stack"); |
2484 "Bad type on operand stack"); |