Mercurial > hg > truffle
comparison src/share/vm/classfile/verifier.cpp @ 13401:22eaa15b7960
8026065: InterfaceMethodref for invokespecial must name a direct superinterface
Summary: Add verification to check that invokespecial of an InterfaceMethodref names a method in a direct superinterface of the current class or interface in accordance with JSR 335, JVMS 4.9.2 Structural Constraints.
Reviewed-by: acorn, hseigel, coleenp
Contributed-by: lois.foltan@oracle.com
author | hseigel |
---|---|
date | Tue, 26 Nov 2013 09:52:22 -0500 |
parents | cdf20166ec45 |
children | ad431bf0de07 aff11567504c 386dd1c71858 |
comparison
equal
deleted
inserted
replaced
13400:86e6d691f2e1 | 13401:22eaa15b7960 |
---|---|
2300 "Bad operand type when invoking <init>"); | 2300 "Bad operand type when invoking <init>"); |
2301 return; | 2301 return; |
2302 } | 2302 } |
2303 } | 2303 } |
2304 | 2304 |
2305 bool ClassVerifier::is_same_or_direct_interface( | |
2306 instanceKlassHandle klass, | |
2307 VerificationType klass_type, | |
2308 VerificationType ref_class_type) { | |
2309 if (ref_class_type.equals(klass_type)) return true; | |
2310 Array<Klass*>* local_interfaces = klass->local_interfaces(); | |
2311 if (local_interfaces != NULL) { | |
2312 for (int x = 0; x < local_interfaces->length(); x++) { | |
2313 Klass* k = local_interfaces->at(x); | |
2314 assert (k != NULL && k->is_interface(), "invalid interface"); | |
2315 if (ref_class_type.equals(VerificationType::reference_type(k->name()))) { | |
2316 return true; | |
2317 } | |
2318 } | |
2319 } | |
2320 return false; | |
2321 } | |
2322 | |
2305 void ClassVerifier::verify_invoke_instructions( | 2323 void ClassVerifier::verify_invoke_instructions( |
2306 RawBytecodeStream* bcs, u4 code_length, StackMapFrame* current_frame, | 2324 RawBytecodeStream* bcs, u4 code_length, StackMapFrame* current_frame, |
2307 bool *this_uninit, VerificationType return_type, | 2325 bool *this_uninit, VerificationType return_type, |
2308 constantPoolHandle cp, TRAPS) { | 2326 constantPoolHandle cp, TRAPS) { |
2309 // Make sure the constant pool item is the right type | 2327 // Make sure the constant pool item is the right type |
2430 verify_error(ErrorContext::bad_code(bci), | 2448 verify_error(ErrorContext::bad_code(bci), |
2431 "Illegal call to internal method"); | 2449 "Illegal call to internal method"); |
2432 return; | 2450 return; |
2433 } | 2451 } |
2434 } else if (opcode == Bytecodes::_invokespecial | 2452 } else if (opcode == Bytecodes::_invokespecial |
2435 && !ref_class_type.equals(current_type()) | 2453 && !is_same_or_direct_interface(current_class(), current_type(), ref_class_type) |
2436 && !ref_class_type.equals(VerificationType::reference_type( | 2454 && !ref_class_type.equals(VerificationType::reference_type( |
2437 current_class()->super()->name()))) { | 2455 current_class()->super()->name()))) { |
2438 bool subtype = false; | 2456 bool subtype = false; |
2457 bool have_imr_indirect = cp->tag_at(index).value() == JVM_CONSTANT_InterfaceMethodref; | |
2439 if (!current_class()->is_anonymous()) { | 2458 if (!current_class()->is_anonymous()) { |
2440 subtype = ref_class_type.is_assignable_from( | 2459 subtype = ref_class_type.is_assignable_from( |
2441 current_type(), this, CHECK_VERIFY(this)); | 2460 current_type(), this, CHECK_VERIFY(this)); |
2442 } else { | 2461 } else { |
2443 subtype = ref_class_type.is_assignable_from(VerificationType::reference_type( | 2462 VerificationType host_klass_type = |
2444 current_class()->host_klass()->name()), this, CHECK_VERIFY(this)); | 2463 VerificationType::reference_type(current_class()->host_klass()->name()); |
2464 subtype = ref_class_type.is_assignable_from(host_klass_type, this, CHECK_VERIFY(this)); | |
2465 | |
2466 // If invokespecial of IMR, need to recheck for same or | |
2467 // direct interface relative to the host class | |
2468 have_imr_indirect = (have_imr_indirect && | |
2469 !is_same_or_direct_interface( | |
2470 InstanceKlass::cast(current_class()->host_klass()), | |
2471 host_klass_type, ref_class_type)); | |
2445 } | 2472 } |
2446 if (!subtype) { | 2473 if (!subtype) { |
2447 verify_error(ErrorContext::bad_code(bci), | 2474 verify_error(ErrorContext::bad_code(bci), |
2448 "Bad invokespecial instruction: " | 2475 "Bad invokespecial instruction: " |
2449 "current class isn't assignable to reference class."); | 2476 "current class isn't assignable to reference class."); |
2450 return; | 2477 return; |
2451 } | 2478 } else if (have_imr_indirect) { |
2479 verify_error(ErrorContext::bad_code(bci), | |
2480 "Bad invokespecial instruction: " | |
2481 "interface method reference is in an indirect superinterface."); | |
2482 return; | |
2483 } | |
2484 | |
2452 } | 2485 } |
2453 // Match method descriptor with operand stack | 2486 // Match method descriptor with operand stack |
2454 for (int i = nargs - 1; i >= 0; i--) { // Run backwards | 2487 for (int i = nargs - 1; i >= 0; i--) { // Run backwards |
2455 current_frame->pop_stack(sig_types[i], CHECK_VERIFY(this)); | 2488 current_frame->pop_stack(sig_types[i], CHECK_VERIFY(this)); |
2456 } | 2489 } |