Ejemplo n.º 1
0
/**
 * Implements all abstract methods in {@code proxyClass}. This should be called after
 * {@link #addProxyMethods()} which will override all methods defined by the proxy's
 * ancestor classes (abstract or concrete).
 */
static jboolean implementAbstractInterfaceMethods(Env* env, Class* proxyClass, Interface* interface, ProxyClassData* proxyClassData) {
    if (!interface) return TRUE;

    Method* method = rvmGetMethods(env, interface->interface);
    if (rvmExceptionOccurred(env)) return FALSE;
    for (; method != NULL; method = method->next) {
        if (!METHOD_IS_CLASS_INITIALIZER(method)) {
            ProxyMethod* proxyMethod = hasMethod(env, proxyClass, method->name, method->desc);
            if (rvmExceptionOccurred(env)) return FALSE;
            if (!proxyMethod) { 
                jint access = (method->access & (~ACC_ABSTRACT)) | ACC_FINAL;
                proxyMethod = addProxyMethod(env, proxyClass, method, access, _proxy0);
                if (!proxyMethod) return FALSE;
            }
            // Record the lookup function in proxyClassData
            LookupEntry* entry = rvmAllocateMemory(env, sizeof(LookupEntry));
            if (!entry) return FALSE;
            entry->key.name = method->name;
            entry->key.desc = method->desc;
            entry->method = proxyMethod;
            HASH_ADD(hh, proxyClassData->lookupsHash, key, sizeof(LookupKey), entry);
        }
    }

    if (!implementAbstractInterfaceMethods(env, proxyClass, interface->next, proxyClassData)) return FALSE;
    Interface* interfaceInterfaces = rvmGetInterfaces(env, interface->interface);
    if (rvmExceptionCheck(env)) return FALSE;
    if (!implementAbstractInterfaceMethods(env, proxyClass, interfaceInterfaces, proxyClassData)) return FALSE;

    return TRUE;
}
Ejemplo n.º 2
0
ObjectArray* Java_java_lang_Class_getDeclaredMethods0(Env* env, Class* clazz, jboolean publicOnly) {
    if (CLASS_IS_PRIMITIVE(clazz) || CLASS_IS_ARRAY(clazz)) return NULL;

    Method* methods = rvmGetMethods(env, clazz);
    if (rvmExceptionCheck(env)) return NULL;

    Method* method;
    jint length = 0;
    for (method = methods; method != NULL; method = method->next) {
        if (!METHOD_IS_CONSTRUCTOR(method) && !METHOD_IS_CLASS_INITIALIZER(method)) {
            if (!publicOnly || METHOD_IS_PUBLIC(method)) {
                length++;
            }
        }
    }

    ObjectArray* result = NULL;
    jint i = 0;
    for (method = methods; method != NULL; method = method->next) {
        if (!METHOD_IS_CONSTRUCTOR(method) && !METHOD_IS_CLASS_INITIALIZER(method)) {
            if (!publicOnly || METHOD_IS_PUBLIC(method)) {
                Object* c = createMethodObject(env, method);
                if (!c) return NULL;
                if (!result) {
                    result = rvmNewObjectArray(env, length, c->clazz, NULL, NULL);
                    if (!result) return NULL;
                }
                result->values[i++] = c;
            }
        }
    }

    return result;
}
Ejemplo n.º 3
0
static Method* getAnnotationValueMethod(Env* env, Class* clazz, char* name) {
    Method* method = rvmGetMethods(env, clazz);
    for (; method != NULL; method = method->next) {
        if (!strcmp(method->name, name)) {
            return method;
        }
    }
    return NULL;
}
Ejemplo n.º 4
0
static Method* findMethod(Env* env, Class* clazz, const char* name, const char* desc) {
    Method* method = rvmGetMethods(env, clazz);
    if (rvmExceptionCheck(env)) return NULL;
    for (; method != NULL; method = method->next) {
        if (!strcmp(method->name, name) && !strcmp(method->desc, desc)) {
            return method;
        }
    }
    return NULL;
}
Ejemplo n.º 5
0
Method* rvmFindMethodAtAddress(Env* env, void* address) {
    Class* clazz = env->vm->options->findClassAt(env, address);
    if (!clazz) return NULL;
    Method* method = rvmGetMethods(env, clazz);
    if (rvmExceptionCheck(env)) return NULL;
    for (; method != NULL; method = method->next) {
        void* start = method->impl;
        void* end = start + method->size;
        if (start && address >= start && address < end) {
            return method;
        }
    }
    // TODO: We should never end up here
    return NULL;
}
Ejemplo n.º 6
0
static jboolean addProxyMethods(Env* env, Class* proxyClass, Class* clazz, ProxyClassData* proxyClassData) {
    // Add constructors from the super class and override all overridable methods. Constructors will use 
    // the same impl as the superclass. Overridden methods will have _rvmProxy0 as its impl.

    if (clazz->superclass) {
        if (!addProxyMethods(env, proxyClass, clazz->superclass, proxyClassData)) return FALSE;
    }

    Method* method = rvmGetMethods(env, clazz);
    if (rvmExceptionOccurred(env)) return FALSE;
    for (; method != NULL; method = method->next) {
        if (!METHOD_IS_STATIC(method) && !METHOD_IS_PRIVATE(method) && !METHOD_IS_FINAL(method)
                && (!METHOD_IS_CONSTRUCTOR(method) || clazz == proxyClass->superclass)) {

            void* impl = NULL;
            jint access = (method->access & (~ACC_ABSTRACT & ~ACC_NATIVE)) | ACC_FINAL;
            if (METHOD_IS_CONSTRUCTOR(method)) {
                impl = method->impl;
                // TODO: For now we make all constructors public to satisfy java.lang.reflect.Proxy. 
                access = ACC_PUBLIC;
                if (!addProxyMethod(env, proxyClass, method, access, impl)) return FALSE;
            } else {
                impl = _proxy0;
                if (METHOD_IS_PUBLIC(method)) { 
                    ProxyMethod* proxyMethod = hasMethod(env, proxyClass, method->name, method->desc);
                    if (rvmExceptionOccurred(env)) return FALSE;
                    if (!proxyMethod) {
                        proxyMethod = addProxyMethod(env, proxyClass, method, access, impl);
                        if (!proxyMethod) return FALSE;
                    }
                    // Record the lookup function in proxyClassData
                    LookupEntry* entry = rvmAllocateMemory(env, sizeof(LookupEntry));
                    if (!entry) return FALSE;
                    entry->key.name = method->name;
                    entry->key.desc = method->desc;
                    entry->method = proxyMethod;
                    HASH_ADD(hh, proxyClassData->lookupsHash, key, sizeof(LookupKey), entry);
                }
            }
        }
    }

    return TRUE;
}