bool VerificationType::is_reference_assignable_from( const VerificationType& from, ClassVerifier* context, bool from_field_is_protected, TRAPS) const { instanceKlassHandle klass = context->current_class(); if (from.is_null()) { // null is assignable to any reference return true; } else if (is_null()) { return false; } else if (name() == from.name()) { return true; } else if (is_object()) { // We need check the class hierarchy to check assignability if (name() == vmSymbols::java_lang_Object()) { // any object or array is assignable to java.lang.Object return true; } Klass* obj = SystemDictionary::resolve_or_fail( name(), Handle(THREAD, klass->class_loader()), Handle(THREAD, klass->protection_domain()), true, CHECK_false); if (TraceClassResolution) { Verifier::trace_class_resolution(obj, klass()); } KlassHandle this_class(THREAD, obj); if (this_class->is_interface() && (!from_field_is_protected || from.name() != vmSymbols::java_lang_Object())) { // If we are not trying to access a protected field or method in // java.lang.Object then we treat interfaces as java.lang.Object, // including java.lang.Cloneable and java.io.Serializable. return true; } else if (from.is_object()) { Klass* from_class = SystemDictionary::resolve_or_fail( from.name(), Handle(THREAD, klass->class_loader()), Handle(THREAD, klass->protection_domain()), true, CHECK_false); if (TraceClassResolution) { Verifier::trace_class_resolution(from_class, klass()); } return InstanceKlass::cast(from_class)->is_subclass_of(this_class()); } } else if (is_array() && from.is_array()) { VerificationType comp_this = get_component(context, CHECK_false); VerificationType comp_from = from.get_component(context, CHECK_false); if (!comp_this.is_bogus() && !comp_from.is_bogus()) { return comp_this.is_component_assignable_from(comp_from, context, from_field_is_protected, CHECK_false); } } return false; }
VerificationType StackMapFrame::set_locals_from_arg( const methodHandle m, VerificationType thisKlass, TRAPS) { SignatureStream ss(m->signature()); int init_local_num = 0; if (!m->is_static()) { init_local_num++; // add one extra argument for instance method if (m->name() == vmSymbols::object_initializer_name() && thisKlass.name() != vmSymbols::java_lang_Object()) { _locals[0] = VerificationType::uninitialized_this_type(); _flags |= FLAG_THIS_UNINIT; } else { _locals[0] = thisKlass; } } // local num may be greater than size of parameters because long/double occupies two slots while(!ss.at_return_type()) { init_local_num += _verifier->change_sig_to_verificationType( &ss, &_locals[init_local_num], CHECK_VERIFY_(verifier(), VerificationType::bogus_type())); ss.next(); } _locals_size = init_local_num; switch (ss.type()) { case T_OBJECT: case T_ARRAY: { Symbol* sig = ss.as_symbol(CHECK_(VerificationType::bogus_type())); // Create another symbol to save as signature stream unreferences // this symbol. Symbol* sig_copy = verifier()->create_temporary_symbol(sig, 0, sig->utf8_length(), CHECK_(VerificationType::bogus_type())); assert(sig_copy == sig, "symbols don't match"); return VerificationType::reference_type(sig_copy); } case T_INT: return VerificationType::integer_type(); case T_BYTE: return VerificationType::byte_type(); case T_CHAR: return VerificationType::char_type(); case T_SHORT: return VerificationType::short_type(); case T_BOOLEAN: return VerificationType::boolean_type(); case T_FLOAT: return VerificationType::float_type(); case T_DOUBLE: return VerificationType::double_type(); case T_LONG: return VerificationType::long_type(); case T_VOID: return VerificationType::bogus_type(); default: ShouldNotReachHere(); } return VerificationType::bogus_type(); }
bool VerificationType::is_reference_assignable_from( const VerificationType& from, ClassVerifier* context, bool from_field_is_protected, TRAPS) const { instanceKlassHandle klass = context->current_class(); if (from.is_null()) { // null is assignable to any reference return true; } else if (is_null()) { return false; } else if (name() == from.name()) { return true; } else if (is_object()) { // We need check the class hierarchy to check assignability if (name() == vmSymbols::java_lang_Object()) { // any object or array is assignable to java.lang.Object return true; } if (DumpSharedSpaces && SystemDictionaryShared::add_verification_constraint(klass(), name(), from.name(), from_field_is_protected, from.is_array(), from.is_object())) { // If add_verification_constraint() returns true, the resolution/check should be // delayed until runtime. return true; } return resolve_and_check_assignability(klass(), name(), from.name(), from_field_is_protected, from.is_array(), from.is_object(), THREAD); } else if (is_array() && from.is_array()) { VerificationType comp_this = get_component(context, CHECK_false); VerificationType comp_from = from.get_component(context, CHECK_false); if (!comp_this.is_bogus() && !comp_from.is_bogus()) { return comp_this.is_component_assignable_from(comp_from, context, from_field_is_protected, CHECK_false); } } return false; }