Method* Class::_resolve_method(Global_Env* env, unsigned cp_index) { lock(); if(m_const_pool.is_entry_in_error(cp_index)) { TRACE2("resolve.testing", "Constant pool entry " << cp_index << " already contains error."); unlock(); return NULL; } #ifdef ORDER if(m_const_pool.is_entry_resolved(cp_index, this)) {//ORDER unlock(); return m_const_pool.get_ref_method(cp_index); } #else if(m_const_pool.is_entry_resolved(cp_index)) {//ORDER unlock(); return m_const_pool.get_ref_method(cp_index); } #endif // // constant pool entry hasn't been resolved yet // unsigned other_index; other_index = m_const_pool.get_ref_class_index(cp_index); unlock(); // // check error condition from resolve class // Class* other_clss = _resolve_class(env, other_index); if(!other_clss) { if(m_const_pool.is_entry_in_error(other_index)) { class_report_failure(this, cp_index, m_const_pool.get_error_cause(other_index)); } else { assert(exn_raised()); } return NULL; } uint16 name_and_type_index = m_const_pool.get_ref_name_and_type_index(cp_index); String* name = m_const_pool.get_name_and_type_name(name_and_type_index); String* desc = m_const_pool.get_name_and_type_descriptor(name_and_type_index); // CONSTANT_Methodref must refer to a class, not an interface, and // CONSTANT_InterfaceMethodref must refer to an interface (vm spec 4.4.2) if(m_const_pool.is_methodref(cp_index) && other_clss->is_interface()) { CLASS_REPORT_FAILURE(this, cp_index, "java/lang/IncompatibleClassChangeError", other_clss->get_name()->bytes << " while resolving constant pool entry " << cp_index << " in class " << m_name->bytes); return NULL; } if(m_const_pool.is_interfacemethodref(cp_index) && !other_clss->is_interface()) { CLASS_REPORT_FAILURE(this, cp_index, "java/lang/IncompatibleClassChangeError", other_clss->get_name()->bytes << " while resolving constant pool entry " << cp_index << " in class " << m_name->bytes); return NULL; } Method* method = class_lookup_method_recursive(other_clss, name, desc); if(method == NULL) { // NoSuchMethodError CLASS_REPORT_FAILURE(this, cp_index, "java/lang/NoSuchMethodError", other_clss->get_name()->bytes << "." << name->bytes << desc->bytes << " while resolving constant pool entry at index " << cp_index << " in class " << m_name->bytes); return NULL; } if(method->is_abstract() && !other_clss->is_abstract()) { // AbstractMethodError CLASS_REPORT_FAILURE(this, cp_index, "java/lang/AbstractMethodError", other_clss->get_name()->bytes << "." << name->bytes << desc->bytes << " while resolving constant pool entry at index " << cp_index << " in class " << m_name->bytes); return NULL; } // // check access permissions // if(!can_access_member(method)) { // IllegalAccessError CLASS_REPORT_FAILURE(this, cp_index, "java/lang/IllegalAccessError", other_clss->get_name()->bytes << "." << name->bytes << desc->bytes << " while resolving constant pool entry at index " << cp_index << " in class " << m_name->bytes); return NULL; } lock(); m_const_pool.resolve_entry(cp_index, method); unlock(); return method; } //_resolve_method
Class* Class::resolve_declaring_class(Global_Env* env) { if(m_declaring_class_index == 0) return NULL; return _resolve_class(env, m_declaring_class_index); }
Field* Class::_resolve_field(Global_Env *env, unsigned cp_index) { lock(); if(m_const_pool.is_entry_in_error(cp_index)) { TRACE2("resolve.testing", "Constant pool entry " << cp_index << " already contains error."); unlock(); return NULL; } #ifdef ORDER if(m_const_pool.is_entry_resolved(cp_index, this)) {//ORDER unlock(); return m_const_pool.get_ref_field(cp_index); } #else if(m_const_pool.is_entry_resolved(cp_index)) { unlock(); return m_const_pool.get_ref_field(cp_index); } #endif // // constant pool entry hasn't been resolved yet // unsigned other_index = m_const_pool.get_ref_class_index(cp_index); unlock(); // // check error condition from resolve class // Class* other_clss = _resolve_class(env, other_index); if(!other_clss) { if(m_const_pool.is_entry_in_error(other_index)) { class_report_failure(this, cp_index, m_const_pool.get_error_cause(other_index)); } else { assert(exn_raised()); } return NULL; } uint16 name_and_type_index = m_const_pool.get_ref_name_and_type_index(cp_index); String* name = m_const_pool.get_name_and_type_name(name_and_type_index); String* desc = m_const_pool.get_name_and_type_descriptor(name_and_type_index); Field* field = other_clss->lookup_field_recursive(name, desc); if(field == NULL) { // // NoSuchFieldError // CLASS_REPORT_FAILURE(this, cp_index, "java/lang/NoSuchFieldError", other_clss->get_name()->bytes << "." << name->bytes << " of type " << desc->bytes << " while resolving constant pool entry at index " << cp_index << " in class " << get_name()->bytes); return NULL; } // // check access permissions // if(!can_access_member(field)) { // // IllegalAccessError // CLASS_REPORT_FAILURE(this, cp_index, "java/lang/IllegalAccessError", other_clss->get_name()->bytes << "." << name->bytes << " of type " << desc->bytes << " while resolving constant pool entry at index " << cp_index << " in class " << get_name()->bytes); return NULL; } lock(); m_const_pool.resolve_entry(cp_index, field); unlock(); return field; } // Class::_resolve_field