blob: f5f5b66620652492ff468e37c686b91eb9fd3b9b [file] [log] [blame]
//===---- Reflect.inc - Shared reflecation code ---------------------------===//
//
// The VMKit project
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#include "ClasspathReflect.h"
#include "JavaArray.h"
#include "JavaUpcalls.h"
#include "Jnjvm.h"
namespace j3 {
ArrayObject* JavaObjectClass::getDeclaredConstructors(JavaObjectClass* Cl, bool publicOnly) {
ArrayObject* ret = 0;
JavaObject* tmp = 0;
llvm_gcroot(Cl, 0);
llvm_gcroot(ret, 0);
llvm_gcroot(tmp, 0);
Jnjvm* vm = JavaThread::get()->getJVM();
UserCommonClass* cl = UserCommonClass::resolvedImplClass(vm, Cl, false);
if (cl->isArray() || cl->isInterface() || cl->isPrimitive()) {
ret = (ArrayObject*)vm->upcalls->constructorArrayClass->doNew(0, vm);
} else {
UserClass* realCl = cl->asClass();;
JnjvmClassLoader* classLoader = cl->classLoader;
uint32 size = 0;
for (uint32 i = 0; i < realCl->nbVirtualMethods; ++i) {
JavaMethod* meth = &realCl->virtualMethods[i];
bool pub = isPublic(meth->access);
if (meth->name->equals(classLoader->bootstrapLoader->initName) &&
(!publicOnly || pub)) {
++size;
}
}
ret = (ArrayObject*)vm->upcalls->constructorArrayClass->doNew(size, vm);
sint32 index = 0;
for (uint32 i = 0; i < realCl->nbVirtualMethods; ++i) {
JavaMethod* meth = &realCl->virtualMethods[i];
bool pub = isPublic(meth->access);
if (meth->name->equals(classLoader->bootstrapLoader->initName) &&
(!publicOnly || pub)) {
tmp = JavaObjectConstructor::createFromInternalConstructor(meth, i);
ArrayObject::setElement(ret, tmp, index);
index++;
}
}
}
return ret;
}
ArrayObject* JavaObjectClass::getDeclaredMethods(JavaObjectClass* Cl, bool publicOnly) {
ArrayObject* ret = 0;
JavaObject* tmp = 0;
JavaString* str = 0;
llvm_gcroot(Cl, 0);
llvm_gcroot(ret, 0);
llvm_gcroot(tmp, 0);
llvm_gcroot(str, 0);
Jnjvm* vm = JavaThread::get()->getJVM();
UserCommonClass* cl = UserCommonClass::resolvedImplClass(vm, Cl, false);
Classpath* upcalls = vm->upcalls;
if (cl->isArray() || cl->isPrimitive()) {
ret = (ArrayObject*)upcalls->methodArrayClass->doNew(0, vm);
} else {
UserClass* realCl = cl->asClass();
JnjvmClassLoader* classLoader = cl->classLoader;
uint32 size = 0;
// Ugly hack : we don't want this method to return annotationType()
// method for annotations. For that, we start the counter to 1 instead
// of 0.
for (uint32 i = 0 ; i < realCl->nbVirtualMethods + realCl->nbStaticMethods;
++i) {
JavaMethod* meth = &realCl->virtualMethods[i];
bool pub = isPublic(meth->access);
if (!(meth->name->equals(classLoader->bootstrapLoader->initName)) &&
!(meth->name->equals(classLoader->bootstrapLoader->clinitName)) &&
(!publicOnly || pub)) {
++size;
}
}
ret = (ArrayObject*)upcalls->methodArrayClass->doNew(size, vm);
sint32 index = 0;
for (uint32 i = 0; i < realCl->nbVirtualMethods + realCl->nbStaticMethods;
++i) {
JavaMethod* meth = &realCl->virtualMethods[i];
bool pub = isPublic(meth->access);
if (!(meth->name->equals(classLoader->bootstrapLoader->initName)) &&
!(meth->name->equals(classLoader->bootstrapLoader->clinitName)) &&
(!publicOnly || pub)) {
tmp = JavaObjectMethod::createFromInternalMethod(meth, i);
ArrayObject::setElement(ret, tmp, index);
index++;
}
}
}
return ret;
}
JavaObject* JavaObjectClass::getDeclaringClass(JavaObjectClass* Cl) {
JavaObject* res = 0;
llvm_gcroot(Cl, 0);
llvm_gcroot(res, 0);
Jnjvm* vm = JavaThread::get()->getJVM();
UserClass* cl = UserCommonClass::resolvedImplClass(vm, Cl, false)->asClass();
if (cl) {
cl->resolveInnerOuterClasses();
UserClass* outer = cl->getOuterClass();
if (outer) {
res = outer->getClassDelegatee(vm);
}
}
return res;
}
ArrayObject* JavaObjectClass::getDeclaredClasses(JavaObjectClass* Cl, bool publicOnly) {
JavaObject* obj = 0;
ArrayObject* result = 0;
llvm_gcroot(result, 0);
llvm_gcroot(Cl, 0);
llvm_gcroot(obj, 0);
Jnjvm* vm = JavaThread::get()->getJVM();
UserClass* cl = UserCommonClass::resolvedImplClass(vm, Cl, false)->asClass();
if (cl) {
cl->resolveInnerOuterClasses();
UserClassArray* array = vm->upcalls->constructorArrayClass;
uint16 sizeArray = 0;
if (publicOnly) {
for (uint16 i = 0; i < cl->nbInnerClasses; ++i) {
UserClass* klass = cl->innerClasses[i];
if (isPublic(klass->innerAccess)) ++sizeArray;
}
} else {
sizeArray = cl->nbInnerClasses;
}
result = (ArrayObject*)array->doNew(sizeArray, vm);
int index = 0;
for (uint16 i = 0; i < cl->nbInnerClasses; ++i) {
UserClass* klass = cl->innerClasses[i];
obj = klass->getClassDelegatee(vm);
if (!publicOnly || isPublic(klass->innerAccess))
ArrayObject::setElement(result, obj, index++);
}
assert(index == sizeArray);
}
return result;
}
ArrayObject* JavaObjectClass::getDeclaredFields(JavaObjectClass* Cl, bool publicOnly) {
ArrayObject* ret = 0;
JavaObject* tmp = 0;
JavaString* name = 0;
llvm_gcroot(Cl, 0);
llvm_gcroot(ret, 0);
llvm_gcroot(tmp, 0);
llvm_gcroot(name, 0);
Jnjvm* vm = JavaThread::get()->getJVM();
UserCommonClass* cl = UserCommonClass::resolvedImplClass(vm, Cl, false);
if (!cl->isClass()) {
ret = (ArrayObject*)vm->upcalls->fieldArrayClass->doNew(0, vm);
} else {
UserClass* realCl = cl->asClass();
uint32 size = 0;
for (uint32 i = 0; i < realCl->nbVirtualFields + realCl->nbStaticFields;
++i) {
JavaField* field = &realCl->virtualFields[i];
if (!publicOnly || isPublic(field->access)) {
++size;
}
}
ret = (ArrayObject*)vm->upcalls->fieldArrayClass->doNew(size, vm);
sint32 index = 0;
for (uint32 i = 0; i < realCl->nbVirtualFields + realCl->nbStaticFields;
++i) {
JavaField* field = &realCl->virtualFields[i];
if (!publicOnly || isPublic(field->access)) {
tmp = JavaObjectField::createFromInternalField(field, i);
ArrayObject::setElement(ret, tmp, index);
index++;
}
}
}
return ret;
}
ArrayObject* JavaObjectClass::getInterfaces(JavaObjectClass* Cl) {
JavaObject* obj = 0;
ArrayObject* res = 0;
llvm_gcroot(Cl, 0);
llvm_gcroot(res, 0);
llvm_gcroot(obj, 0);
Jnjvm* vm = JavaThread::get()->getJVM();
UserCommonClass* cl = UserCommonClass::resolvedImplClass(vm, Cl, false);
res = (ArrayObject*)vm->upcalls->classArrayClass->doNew(cl->nbInterfaces, vm);
for (uint16 i = 0; i < cl->nbInterfaces; ++i) {
UserClass* klass = cl->interfaces[i];
obj = klass->getClassDelegatee(vm);
ArrayObject::setElement(res, obj, i);
}
return res;
}
int32_t JavaObjectClass::getModifiers(JavaObjectClass* Cl) {
llvm_gcroot(Cl, 0);
int32_t res;
Jnjvm* vm = JavaThread::get()->getJVM();
UserCommonClass* cl = UserCommonClass::resolvedImplClass(vm, Cl, false);
res = cl->getAccess();
if (isEnum(res) && cl->getSuper() != vm->upcalls->EnumClass) {
// javac may put that flag to inner classes of enum classes.
res &= ~ACC_ENUM;
}
return res;
}
JavaObject* JavaObjectClass::getEnclosingClass(JavaObjectClass* Cl)
{
JavaObject* res = 0;
llvm_gcroot(Cl, 0);
llvm_gcroot(res, 0);
Jnjvm* vm = JavaThread::get()->getJVM();
UserCommonClass* ccl = UserCommonClass::resolvedImplClass(vm, Cl, false);
if (ccl->isClass()) {
UserClass *cl = ccl->asClass();
cl->resolveInnerOuterClasses();
UserClass *outerCl = cl->getOuterClass();
if (outerCl != NULL)
res = outerCl->getClassDelegatee(vm, NULL);
}
return res;
}
bool JavaObjectClass::isAnonymousClass(JavaObjectClass* Cl)
{
llvm_gcroot(Cl, 0);
Jnjvm* vm = JavaThread::get()->getJVM();
UserCommonClass* ccl = UserCommonClass::resolvedImplClass(vm, Cl, false);
if (!ccl->isClass()) return false;
UserClass *cl = ccl->asClass();
cl->resolveInnerOuterClasses();
return cl->isAnonymous;
}
} // end namespace j3