void Expander::expand_class_representation(const string & name){ if(logger.is_info()) logger.log_info() << indent << name << " : expanding..." << endl; jvm_class.name = get_class_name(); if(jvm_class.name != name){ ostringstream os; os << "name mismatch - expected to expand " << name << " but class file representation contains " << jvm_class.name << endl; throw JvmException (os.str()); } jvm_class.access_flags = class_file_representation.access_flags; if(logger.is_info()) logger.log_info() << indent << jvm_class.name << " : access specifiers [" << jvm_class.get_access_string() << "]" << endl; if(jvm_class.name == "java/lang/Object"){ if(logger.is_debug()) logger.log_debug() << indent << jvm_class.name << " : has no super class" << endl; }else{ string super_class_name = get_super_class_name(); if(logger.is_debug()) logger.log_debug() << indent << jvm_class.name << " : super class name : " << super_class_name << endl; jvm_class.super_class = &class_loader.get_class(super_class_name, depth + 1); } expand_interfaces(); expand_members(); if(logger.is_info()) logger.log_info() << indent << name << " : ...expanded" << endl; }
bool Class::load_ancestors(Global_Env* env) { m_state = ST_LoadingAncestors; const String* superName = get_super_class_name(); if(superName == NULL) { if(env->InBootstrap() || get_name() != env->JavaLangClass_String) { // This class better be java.lang.Object if(get_name() != env->JavaLangObject_String) { // ClassFormatError std::stringstream ss; ss << get_name()->bytes << ": class does not have superclass " << "but the class is not java.lang.Object"; REPORT_FAILED_CLASS_CLASS(m_class_loader, this, "java/lang/ClassFormatError", ss.str().c_str()); return false; } } } else { // Load super class Class* superClass; m_super_class.name = NULL; superClass = m_class_loader->LoadVerifyAndPrepareClass(env, superName); if(superClass == NULL) { assert(exn_raised()); return false; } if(superClass->is_interface()) { REPORT_FAILED_CLASS_CLASS(m_class_loader, this, "java/lang/IncompatibleClassChangeError", "class " << m_name->bytes << " has interface " << superClass->get_name()->bytes << " as super class"); return false; } if(superClass->is_final()) { REPORT_FAILED_CLASS_CLASS(m_class_loader, this, "java/lang/VerifyError", m_name->bytes << " cannot inherit from final class " << superClass->get_name()->bytes); return false; } // super class was successfully loaded m_super_class.clss = superClass; if(m_super_class.cp_index) { m_const_pool.resolve_entry(m_super_class.cp_index, superClass); } // if it's an interface, its superclass must be java/lang/Object if(is_interface()) { if((env->JavaLangObject_Class != NULL) && (superClass != env->JavaLangObject_Class)) { std::stringstream ss; ss << get_name()->bytes << ": interface superclass is not java.lang.Object"; REPORT_FAILED_CLASS_CLASS(m_class_loader, this, "java/lang/ClassFormatError", ss.str().c_str()); return false; } } // Update the cha_first_child and cha_next_sibling fields. m_cha_first_child = NULL; if(has_super_class()) { m_cha_next_sibling = get_super_class()->m_cha_first_child; get_super_class()->m_cha_first_child = this; } } // // load in super interfaces // for(unsigned i = 0; i < m_num_superinterfaces; i++ ) { const String* intfc_name = m_superinterfaces[i].name; Class* intfc = m_class_loader->LoadVerifyAndPrepareClass(env, intfc_name); if(intfc == NULL) { assert(exn_raised()); return false; } if(!intfc->is_interface()) { REPORT_FAILED_CLASS_CLASS(m_class_loader, this, "java/lang/IncompatibleClassChangeError", get_name()->bytes << ": " << intfc->get_name()->bytes << " is not an interface"); return false; } // superinterface was successfully loaded m_superinterfaces[i].clss = intfc; if(m_superinterfaces[i].cp_index != 0) { // there are no constant pool entries for array classes m_const_pool.resolve_entry(m_superinterfaces[i].cp_index, intfc); } } // class, superclass, and superinterfaces successfully loaded m_state = ST_Loaded; if(!is_array()) m_package = m_class_loader->ProvidePackage(env, m_name, NULL); return true; }