Пример #1
0
void* _bcLookupInterfaceMethodImpl(Env* env, ClassInfoHeader* header, Object* thiz, uint32_t index) {
    TypeInfo* typeInfo = header->typeInfo;
    ITables* itables = thiz->clazz->itables;
    ITable* itable = itables->cache;
    if (itable->typeInfo == typeInfo) {
        return itable->table.table[index];
    }
    uint32_t i;
    for (i = 0; i < itables->count; i++) {
        itable = itables->table[i];
        if (itable->typeInfo == typeInfo) {
            itables->cache = itable;
            return itable->table.table[index];
        }
    }

    ENTER;
    initializeClass(env, header);
    Class* ownerInterface = header->clazz;
    char message[256];
    snprintf(message, 256, "Class %s does not implement the requested interface %s", 
        rvmToBinaryClassName(env, thiz->clazz->name), rvmToBinaryClassName(env, ownerInterface->name));
    rvmThrowIncompatibleClassChangeError(env, message);
    LEAVE(NULL);
}
Пример #2
0
void* lookupInterfaceMethod(Env* env, ClassInfoHeader* header, Object* thiz, char* name, char* desc) {
    initializeClass(env, header);
    if (rvmExceptionCheck(env)) return NULL;
    Class* ownerInterface = header->clazz;
    if (!rvmIsInstanceOf(env, thiz, ownerInterface)) {
        char message[256];
        snprintf(message, 256, "Class %s does not implement the requested interface %s", 
            rvmToBinaryClassName(env, thiz->clazz->name), rvmToBinaryClassName(env, ownerInterface->name));
        rvmThrowIncompatibleClassChangeError(env, message);
        return NULL;
    }
    Method* method = rvmGetInstanceMethod(env, thiz->clazz, name, desc);
    Object* throwable = rvmExceptionClear(env);
    if (!method && throwable->clazz != java_lang_NoSuchMethodError) { 
        rvmThrow(env, throwable);
        return NULL;
    }
    if (!method || METHOD_IS_ABSTRACT(method)) {
        rvmThrowAbstractMethodError(env, ""); // TODO: Message
        return NULL;
    }
    if (!METHOD_IS_PUBLIC(method)) {
        rvmThrowIllegalAccessError(env, ""); // TODO: Message
        return NULL;
    }
    return method->synchronizedImpl ? method->synchronizedImpl : method->impl;
}
Пример #3
0
Class* rvmFindClassUsingLoader(Env* env, const char* className, ClassLoader* classLoader) {
    if (!classLoader || classLoader->parent == NULL) {
        // This is the bootstrap classloader. No need to call ClassLoader.loadClass()
        return findBootClass(env, className);
    }
    char* binaryClassName = rvmToBinaryClassName(env, className);
    if (!binaryClassName) return NULL;
    Object* binaryClassNameString = rvmNewInternedStringUTF(env, binaryClassName, -1);
    if (!binaryClassNameString) return NULL;
    Method* loadClassMethod = rvmGetInstanceMethod(env, java_lang_ClassLoader, "loadClass", "(Ljava/lang/String;)Ljava/lang/Class;");
    if (!loadClassMethod) return NULL;
    Object* clazz = rvmCallObjectInstanceMethod(env, (Object*) classLoader, loadClassMethod, binaryClassNameString);
    if (rvmExceptionOccurred(env)) return NULL;
    return (Class*) clazz;
}
Пример #4
0
void* rvmResolveNativeMethodImpl(Env* env, NativeMethod* method, const char* shortMangledName, const char* longMangledName, ClassLoader* classLoader, void** ptr) {
    void* f = method->nativeImpl;
    if (!f) {
        DynamicLib* nativeLibs = NULL;
        if (!classLoader || classLoader->parent == NULL) {
            // This is the bootstrap classloader
            nativeLibs = bootNativeLibs;
        } else if (classLoader->parent->parent == NULL && classLoader->object.clazz->classLoader == NULL) {
            // This is the system classloader
            nativeLibs = mainNativeLibs;
        } else {
            // Unknown classloader
            rvmThrowUnsatisfiedLinkError(env, "Unknown classloader");
            return NULL;
        }

        obtainNativeLibsLock();

        TRACEF("Searching for native method using short name: %s", shortMangledName);
        f = rvmFindDynamicLibSymbol(env, nativeLibs, shortMangledName, TRUE);
        if (f) {
            TRACEF("Found native method using short name: %s", shortMangledName);
        } else if (strcmp(shortMangledName, longMangledName)) {
            TRACEF("Searching for native method using long name: %s", longMangledName);
            f = rvmFindDynamicLibSymbol(env, nativeLibs, longMangledName, TRUE);
            if (f) {
                TRACEF("Found native method using long name: %s", longMangledName);
            }
        }

        method->nativeImpl = f;

        releaseNativeLibsLock();
    }

    if (!f) {
        char* className = rvmToBinaryClassName(env, method->method.clazz->name);
        if (className) {
            rvmThrowNewf(env, java_lang_UnsatisfiedLinkError, "%s.%s%s", className, method->method.name, method->method.desc);
        }
        return NULL;
    }
    // TODO: Remember ptr to allow it to be reset when the JNI RegisterNatives/UnregisterNatives functions are called
    *ptr = f;
    return f;
}
Пример #5
0
jboolean rvmThrowClassNotFoundException(Env* env, const char* className) {
    char* msg = rvmToBinaryClassName(env, className);
    if (!msg) return FALSE;
    return rvmThrowNew(env, java_lang_ClassNotFoundException, msg);
}