blob: b3c87735c2ca207d2f6f61f30aeeda6db012fcce [file] [log] [blame]
//===---- ClasspathVMClass.cpp - GNU classpath java/lang/VMClass ----------===//
//
// The VMKit project
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#include "types.h"
#include "Classpath.h"
#include "ClasspathReflect.h"
#include "JavaAccess.h"
#include "JavaArray.h"
#include "JavaClass.h"
#include "JavaObject.h"
#include "JavaString.h"
#include "JavaTypes.h"
#include "JavaThread.h"
#include "JavaUpcalls.h"
#include "Jnjvm.h"
using namespace j3;
extern "C" {
// Never throws
JNIEXPORT jboolean JNICALL Java_java_lang_VMClass_isArray(
#ifdef NATIVE_JNI
JNIEnv *env,
jclass clazz,
#endif
JavaObjectClass* klass) {
llvm_gcroot(klass, 0);
UserCommonClass* cl = JavaObjectClass::getClass(klass);
return cl->isArray();
}
JNIEXPORT JavaObject* JNICALL Java_java_lang_VMClass_forName(
#ifdef NATIVE_JNI
JNIEnv *env,
jclass clazz,
#endif
JavaString* str,
jboolean clinit,
JavaObject* loader) {
JavaObject* res = 0;
llvm_gcroot(loader, 0);
llvm_gcroot(str, 0);
llvm_gcroot(res, 0);
BEGIN_NATIVE_EXCEPTION(0)
verifyNull(str);
Jnjvm* vm = JavaThread::get()->getJVM();
JnjvmClassLoader* JCL =
JnjvmClassLoader::getJnjvmLoaderFromJavaObject(loader, vm);
UserCommonClass* cl = JCL->loadClassFromJavaString(str, true, false);
if (cl != NULL && !cl->isPrimitive()) {
if (clinit && cl->asClass()) {
cl->asClass()->initialiseClass(vm);
}
res = cl->getClassDelegatee(vm);
} else {
vm->classNotFoundException(str);
}
END_NATIVE_EXCEPTION
return res;
}
JNIEXPORT JavaObject* JNICALL Java_java_lang_VMClass_getDeclaredConstructors(
#ifdef NATIVE_JNI
JNIEnv *env,
jclass clazz,
#endif
JavaObject* Cl,
jboolean publicOnly) {
JavaObjectClass* jcl = 0;
ArrayObject* ret = 0;
llvm_gcroot(Cl, 0);
llvm_gcroot(ret, 0);
llvm_gcroot(jcl, 0);
BEGIN_NATIVE_EXCEPTION(0)
ret = JavaObjectClass::getDeclaredConstructors(jcl = (JavaObjectClass*)Cl, publicOnly);
END_NATIVE_EXCEPTION
return ret;
}
JNIEXPORT JavaObject* JNICALL Java_java_lang_VMClass_getDeclaredMethods(
#ifdef NATIVE_JNI
JNIEnv *env,
jclass clazz,
#endif
JavaObject* Cl,
jboolean publicOnly) {
JavaObjectClass* jcl = 0;
ArrayObject* ret = 0;
llvm_gcroot(Cl, 0);
llvm_gcroot(ret, 0);
llvm_gcroot(jcl, 0);
BEGIN_NATIVE_EXCEPTION(0)
ret = JavaObjectClass::getDeclaredMethods(jcl = (JavaObjectClass*)Cl, publicOnly);
END_NATIVE_EXCEPTION
return ret;
}
JNIEXPORT jint JNICALL Java_java_lang_VMClass_getModifiers(
#ifdef NATIVE_JNI
JNIEnv *env,
jclass clazz,
#endif
JavaObject* Cl,
jboolean ignore) {
JavaObjectClass* jcl = 0;
jint res = 0;
llvm_gcroot(Cl, 0);
llvm_gcroot(jcl, 0);
BEGIN_NATIVE_EXCEPTION(0)
res = JavaObjectClass::getModifiers(jcl = (JavaObjectClass*)Cl);
END_NATIVE_EXCEPTION
return res;
}
JNIEXPORT JavaObject* JNICALL Java_java_lang_VMClass_getName(
#ifdef NATIVE_JNI
JNIEnv *env,
jclass clazz,
#endif
JavaObject* Cl) {
JavaObject* result = 0;
llvm_gcroot(Cl, 0);
llvm_gcroot(result, 0);
BEGIN_NATIVE_EXCEPTION(0)
Jnjvm* vm = JavaThread::get()->getJVM();
UserCommonClass* cl = UserCommonClass::resolvedImplClass(vm, Cl, false);
const UTF8* iname = cl->getName();
result = JavaString::internalToJava(iname, vm);
END_NATIVE_EXCEPTION
return result;
}
JNIEXPORT jboolean JNICALL Java_java_lang_VMClass_isPrimitive(
#ifdef NATIVE_JNI
JNIEnv *env,
jclass clazz,
#endif
JavaObject* Cl) {
jboolean res = 0;
llvm_gcroot(Cl, 0);
BEGIN_NATIVE_EXCEPTION(0)
Jnjvm* vm = JavaThread::get()->getJVM();
UserCommonClass* cl = UserCommonClass::resolvedImplClass(vm, Cl, false);
res = cl->isPrimitive();
END_NATIVE_EXCEPTION
return res;
}
JNIEXPORT jboolean JNICALL Java_java_lang_VMClass_isInterface(
#ifdef NATIVE_JNI
JNIEnv *env,
jclass clazz,
#endif
JavaObject* Cl) {
jboolean res = 0;
llvm_gcroot(Cl, 0);
BEGIN_NATIVE_EXCEPTION(0)
Jnjvm* vm = JavaThread::get()->getJVM();
UserCommonClass* cl = UserCommonClass::resolvedImplClass(vm, Cl, false);
res = cl->isInterface();
END_NATIVE_EXCEPTION
return res;
}
JNIEXPORT JavaObject* JNICALL Java_java_lang_VMClass_getComponentType(
#ifdef NATIVE_JNI
JNIEnv *env,
jclass clazz,
#endif
JavaObject* Cl) {
JavaObject* res = 0;
llvm_gcroot(res, 0);
llvm_gcroot(Cl, 0);
BEGIN_NATIVE_EXCEPTION(0)
Jnjvm* vm = JavaThread::get()->getJVM();
UserCommonClass* cl = UserCommonClass::resolvedImplClass(vm, Cl, false);
if (cl->isArray()) {
UserCommonClass* bc = cl->asArrayClass()->baseClass();
res = bc->getClassDelegatee(vm);
} else {
res = 0;
}
END_NATIVE_EXCEPTION
return res;
}
JNIEXPORT JavaObject* JNICALL Java_java_lang_VMClass_getClassLoader(
#ifdef NATIVE_JNI
JNIEnv *env,
jclass clazz,
#endif
JavaObject* Cl) {
JavaObject* res = 0;
llvm_gcroot(res, 0);
llvm_gcroot(Cl, 0);
BEGIN_NATIVE_EXCEPTION(0)
Jnjvm* vm = JavaThread::get()->getJVM();
UserCommonClass* cl = UserCommonClass::resolvedImplClass(vm, Cl, false);
res = cl->classLoader->getJavaClassLoader();
END_NATIVE_EXCEPTION
return res;
}
JNIEXPORT jboolean JNICALL Java_java_lang_VMClass_isAssignableFrom(
#ifdef NATIVE_JNI
JNIEnv *env,
jclass clazz,
#endif
JavaObject* Cl1, JavaObject* Cl2) {
jboolean res = 0;
llvm_gcroot(Cl1, 0);
llvm_gcroot(Cl2, 0);
BEGIN_NATIVE_EXCEPTION(0)
Jnjvm* vm = JavaThread::get()->getJVM();
if (!Cl2) vm->nullPointerException();
UserCommonClass* cl1 = UserCommonClass::resolvedImplClass(vm, Cl1, false);
UserCommonClass* cl2 = UserCommonClass::resolvedImplClass(vm, Cl2, false);
res = cl2->isSubclassOf(cl1);
END_NATIVE_EXCEPTION
return res;
}
JNIEXPORT JavaObject* JNICALL Java_java_lang_VMClass_getSuperclass(
#ifdef NATIVE_JNI
JNIEnv *env,
jclass clazz,
#endif
JavaObject* Cl) {
JavaObject* res = 0;
llvm_gcroot(Cl, 0);
llvm_gcroot(res, 0);
BEGIN_NATIVE_EXCEPTION(0)
Jnjvm* vm = JavaThread::get()->getJVM();
UserCommonClass* cl = UserCommonClass::resolvedImplClass(vm, Cl, false);
if (cl->isInterface()) res = 0;
else {
if (cl->getSuper()) res = cl->getSuper()->getClassDelegatee(vm);
else res = 0;
}
END_NATIVE_EXCEPTION
return res;
}
JNIEXPORT bool JNICALL Java_java_lang_VMClass_isInstance(
#ifdef NATIVE_JNI
JNIEnv *env,
jclass clazz,
#endif
JavaObject* Cl, JavaObject* obj) {
bool res = false;
llvm_gcroot(Cl, 0);
llvm_gcroot(obj, 0);
BEGIN_NATIVE_EXCEPTION(0)
Jnjvm* vm = JavaThread::get()->getJVM();
UserCommonClass* cl = UserCommonClass::resolvedImplClass(vm, Cl, false);
res = JavaObject::instanceOf(obj, cl);
END_NATIVE_EXCEPTION
return res;
}
JNIEXPORT JavaObject* JNICALL Java_java_lang_VMClass_getDeclaredFields(
#ifdef NATIVE_JNI
JNIEnv *env,
jclass clazz,
#endif
JavaObject* Cl, jboolean publicOnly) {
JavaObjectClass* jcl = 0;
ArrayObject* ret = 0;
llvm_gcroot(Cl, 0);
llvm_gcroot(ret, 0);
llvm_gcroot(jcl, 0);
BEGIN_NATIVE_EXCEPTION(0)
ret = JavaObjectClass::getDeclaredFields(jcl = (JavaObjectClass*)Cl, publicOnly);
END_NATIVE_EXCEPTION
return ret;
}
JNIEXPORT JavaObject* JNICALL Java_java_lang_VMClass_getInterfaces(
#ifdef NATIVE_JNI
JNIEnv *env,
jclass clazz,
#endif
JavaObject* Cl) {
JavaObjectClass* jcl = 0;
ArrayObject* res = 0;
llvm_gcroot(res, 0);
llvm_gcroot(Cl, 0);
llvm_gcroot(jcl, 0);
BEGIN_NATIVE_EXCEPTION(0)
res = JavaObjectClass::getInterfaces(jcl = (JavaObjectClass*)Cl);
END_NATIVE_EXCEPTION
return res;
}
JNIEXPORT JavaObject* JNICALL Java_java_lang_VMClass_getDeclaringClass(
#ifdef NATIVE_JNI
JNIEnv *env,
jclass clazz,
#endif
JavaObject* Cl) {
JavaObjectClass* jcl = 0;
JavaObject* res = 0;
llvm_gcroot(res, 0);
llvm_gcroot(Cl, 0);
llvm_gcroot(jcl, 0);
BEGIN_NATIVE_EXCEPTION(0)
res = JavaObjectClass::getDeclaringClass(jcl = (JavaObjectClass*)Cl);
END_NATIVE_EXCEPTION
return res;
}
JNIEXPORT JavaObject* JNICALL Java_java_lang_VMClass_getDeclaredClasses(
#ifdef NATIVE_JNI
JNIEnv *env,
jclass clazz,
#endif
JavaObject* Cl, bool publicOnly) {
JavaObjectClass* jcl = 0;
ArrayObject* result = 0;
llvm_gcroot(result, 0);
llvm_gcroot(Cl, 0);
llvm_gcroot(jcl, 0);
BEGIN_NATIVE_EXCEPTION(0)
result = JavaObjectClass::getDeclaredClasses(jcl = (JavaObjectClass*)Cl, publicOnly);
END_NATIVE_EXCEPTION
return result;
}
// Only throws.
JNIEXPORT void JNICALL Java_java_lang_VMClass_throwException(
#ifdef NATIVE_JNI
JNIEnv *env,
jclass clazz,
#endif
JavaObject* throwable) {
llvm_gcroot(throwable, 0);
assert(throwable && "Using internal VM throw exception without exception");
JavaThread::get()->throwException(throwable);
}
JNIEXPORT ArrayObject* Java_java_lang_VMClass_getDeclaredAnnotations(
#ifdef NATIVE_JNI
JNIEnv *env,
jclass clazz,
#endif
JavaObject* Cl) {
ArrayObject* arrayRes = 0;
JavaObject* res = 0;
JavaObject* annon = 0;
JavaObject* newHashMap = 0;
JavaObject* annotationClass = 0;
llvm_gcroot(res, 0);
llvm_gcroot(annon, 0);
llvm_gcroot(newHashMap, 0);
llvm_gcroot(Cl, 0);
llvm_gcroot(annotationClass, 0);
llvm_gcroot(arrayRes, 0);
BEGIN_NATIVE_EXCEPTION(0)
Jnjvm* vm = JavaThread::get()->getJVM();
Classpath* upcalls = vm->upcalls;
UserClass* cl = UserCommonClass::resolvedImplClass(vm, Cl, false)->asClass();
//JavaField* field = JavaObjectVMField::getInternalField(VMField);
JavaAttribute* annotationsAtt =
cl->lookupAttribute(JavaAttribute::annotationsAttribute);
JnjvmClassLoader* loader = cl->classLoader;
if (annotationsAtt) {
Reader reader(annotationsAtt, cl->bytes);
AnnotationReader AR(reader, cl);
uint16 numAnnotations = reader.readU2();
UserClassArray* array = upcalls->constructorArrayAnnotation;
arrayRes = (ArrayObject *)(res = array->doNew(numAnnotations, vm));
for (uint16 i = 0; i < numAnnotations; ++i) {
uint16 typeIndex = reader.readU2();
const UTF8* annoType = cl->ctpInfo->UTF8At(typeIndex);
annoType = annoType->extract(loader->hashUTF8, 1,annoType->size-1);
dprintf("Annotation type : %s\n", UTF8Buffer(annoType).cString());
UserClass* AnnonClass = 0;
UserCommonClass* commClass = loader->lookupClass(annoType);
if (commClass)
AnnonClass = commClass -> asClass();
else
AnnonClass = loader->loadName(annoType, true, true, NULL);
assert(AnnonClass && "Panic, imposible conditions");
dprintf("Loaded class : %s \n", UTF8Buffer(AnnonClass->name).cString());
annotationClass = AnnonClass->getClassDelegatee(vm);
newHashMap = AR.createAnnotationMapValues(annotationClass);
annon = upcalls->createAnnotation->invokeJavaObjectStatic(vm, upcalls->newAnnotationHandler, &annotationClass, &newHashMap);
ArrayObject::setElement(arrayRes, annon, i);
} // end for
}
else {
UserClassArray* array = upcalls->constructorArrayAnnotation;
res = array->doNew(0, vm);
}
END_NATIVE_EXCEPTION
return (ArrayObject*)res;
}
JNIEXPORT jboolean Java_java_lang_VMClass_isAnonymousClass(
#ifdef NATIVE_JNI
JNIEnv *env,
jclass clazz,
#endif
JavaObjectClass* Cl) {
jboolean res = false;
llvm_gcroot(Cl, 0);
BEGIN_NATIVE_EXCEPTION(0)
res = JavaObjectClass::isAnonymousClass(Cl);
END_NATIVE_EXCEPTION
return res;
}
// Returns the class which immediately encloses the specified class.
// If the class is a top-level class, this method returns null.
JNIEXPORT JavaObject* JNICALL Java_java_lang_VMClass_getEnclosingClass(
#ifdef NATIVE_JNI
JNIEnv *env,
jclass clazz,
#endif
JavaObjectClass* Cl) {
JavaObject* res = 0;
llvm_gcroot(Cl, 0);
llvm_gcroot(res, 0);
BEGIN_NATIVE_EXCEPTION(0)
res = JavaObjectClass::getEnclosingClass(Cl);
END_NATIVE_EXCEPTION
return res;
}
}