void _bcThrowUnsatisfiedLinkErrorOptionalBridgeNotBound(Env* env, const char* className, const char* methodName, const char* methodDesc) { ENTER; rvmThrowNewf(env, java_lang_UnsatisfiedLinkError, "Optional @Bridge method %s.%s%s not bound", className, methodName, methodDesc); LEAVEV; }
jboolean rvmThrowArrayStoreException(Env* env, JClass* elemType, JClass* arrayType) { const char* elemTypeName = rvmGetHumanReadableClassName(env, elemType); if (!elemTypeName) return FALSE; const char* arrayTypeName = rvmGetHumanReadableClassName(env, arrayType); if (!arrayTypeName) return FALSE; return rvmThrowNewf(env, java_lang_ArrayStoreException, "%s cannot be stored in an array of type %s", elemTypeName, arrayTypeName); }
jvalue* validateAndUnwrapArgs(Env* env, ObjectArray* parameterTypes, ObjectArray* args) { jint length = args->length; jvalue* jvalueArgs = length > 0 ? (jvalue*) rvmAllocateMemory(env, sizeof(jvalue) * length) : emptyJValueArgs; if (!jvalueArgs) return NULL; jint i; for (i = 0; i < length; i++) { Object* arg = args->values[i]; Class* type = (Class*) parameterTypes->values[i]; if (CLASS_IS_PRIMITIVE(type)) { if (arg == NULL) { const char* typeName = rvmGetHumanReadableClassName(env, type); if (typeName) { rvmThrowNewf(env, java_lang_IllegalArgumentException, "argument %d should have type %s, got null", i + 1, typeName); } return NULL; } if (!rvmUnbox(env, arg, type, &jvalueArgs[i])) { if (rvmExceptionOccurred(env)->clazz == java_lang_ClassCastException) { rvmExceptionClear(env); const char* argTypeName = rvmGetHumanReadableClassName(env, arg->clazz); const char* typeName = argTypeName ? rvmGetHumanReadableClassName(env, type) : NULL; if (argTypeName && typeName) { rvmThrowNewf(env, java_lang_IllegalArgumentException, "argument %d should have type %s, got %s", i + 1, typeName, argTypeName); } } return NULL; } } else { if (arg && !rvmIsInstanceOf(env, arg, type)) { const char* argTypeName = rvmGetHumanReadableClassName(env, arg->clazz); const char* typeName = argTypeName ? rvmGetHumanReadableClassName(env, type) : NULL; if (argTypeName && typeName) { rvmThrowNewf(env, java_lang_IllegalArgumentException, "argument %d should have type %s, got %s", i + 1, typeName, argTypeName); } return NULL; } jvalueArgs[i].l = (jobject) arg; } } return jvalueArgs; }
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; }
jboolean rvmThrowArrayIndexOutOfBoundsException(Env* env, jint length, jint index) { return rvmThrowNewf(env, java_lang_ArrayIndexOutOfBoundsException, "length=%d; index=%d", length, index); }