Пример #1
0
/*
 * Get Method Modifiers
 *
 * For the method indicated by method, return the access flags
 * via modifiers_ptr.
 *
 * REQUIRED Functionality.
 */
jvmtiError JNICALL
jvmtiGetMethodModifiers(jvmtiEnv* env,
                        jmethodID method,
                        jint* modifiers_ptr)
{
    TRACE("GetMethodModifiers called");
    SuspendEnabledChecker sec;
    /*
     * Check given env & current phase.
     */
    jvmtiPhase phases[] = {JVMTI_PHASE_START, JVMTI_PHASE_LIVE};

    CHECK_EVERYTHING();

    if( !method ) return JVMTI_ERROR_NULL_POINTER;
    if( !modifiers_ptr ) return JVMTI_ERROR_NULL_POINTER;

    *modifiers_ptr = 0;
    Method* mtd = reinterpret_cast<Method*>(method);
    if( mtd->is_public() ) *modifiers_ptr |= ACC_PUBLIC;
    if( mtd->is_private() ) *modifiers_ptr |= ACC_PRIVATE;
    if( mtd->is_protected() ) *modifiers_ptr |= ACC_PROTECTED;
    if( mtd->is_static() ) *modifiers_ptr |= ACC_STATIC;
    if( mtd->is_final() ) *modifiers_ptr |= ACC_FINAL;
    if( mtd->is_synchronized() ) *modifiers_ptr |= ACC_SYNCHRONIZED;
    if( mtd->is_native() ) *modifiers_ptr |= ACC_NATIVE;
    if( mtd->is_abstract() ) *modifiers_ptr |= ACC_ABSTRACT;

    return JVMTI_ERROR_NONE;
}
Пример #2
0
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