예제 #1
0
bool VerificationType::resolve_and_check_assignability(instanceKlassHandle klass, Symbol* name,
         Symbol* from_name, bool from_field_is_protected, bool from_is_array, bool from_is_object, TRAPS) {
  Klass* obj = SystemDictionary::resolve_or_fail(
      name, Handle(THREAD, klass->class_loader()),
      Handle(THREAD, klass->protection_domain()), true, CHECK_false);
  if (log_is_enabled(Debug, class, resolve)) {
    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, for arrays, we only allow assignability
    // to interfaces java.lang.Cloneable and java.io.Serializable.
    // Otherwise, we treat interfaces as java.lang.Object.
    return !from_is_array ||
      this_class == SystemDictionary::Cloneable_klass() ||
      this_class == SystemDictionary::Serializable_klass();
  } 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 (log_is_enabled(Debug, class, resolve)) {
      Verifier::trace_class_resolution(from_class, klass());
    }
    return InstanceKlass::cast(from_class)->is_subclass_of(this_class());
  }

  return false;
}
예제 #2
0
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;
}