//===---- 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