| //===- ClasspathReflect.cpp - Internal representation of core system classes -// |
| // |
| // 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 "JavaClass.h" |
| #include "JavaConstantPool.h" |
| #include "JavaObject.h" |
| #include "JavaThread.h" |
| #include "JavaTypes.h" |
| #include "JavaUpcalls.h" |
| #include "Jnjvm.h" |
| #include "Reader.h" |
| |
| #include "Reflect.inc" |
| |
| namespace j3 { |
| |
| JavaMethod* JavaObjectConstructor::getInternalMethod(JavaObjectConstructor* self) { |
| llvm_gcroot(self, 0); |
| UserCommonClass* cls = JavaObjectClass::getClass(self->clazz); |
| return &(cls->asClass()->virtualMethods[self->slot]); |
| } |
| |
| JavaMethod* JavaObjectMethod::getInternalMethod(JavaObjectMethod* self) { |
| llvm_gcroot(self, 0); |
| UserCommonClass* cls = JavaObjectClass::getClass(self->clazz); |
| return &(cls->asClass()->virtualMethods[self->slot]); |
| } |
| |
| |
| int JavaObjectThrowable::getStackTraceBase(JavaObjectThrowable * self) { |
| JavaObject * stack = NULL; |
| llvm_gcroot(self, 0); |
| llvm_gcroot(stack, 0); |
| |
| if (!self->backtrace) return 0; |
| |
| Jnjvm* vm = JavaThread::get()->getJVM(); |
| |
| stack = self->backtrace; |
| sint32 index = 2;; |
| while (index != JavaArray::getSize(stack)) { |
| vmkit::FrameInfo* FI = vm->IPToFrameInfo(ArrayPtr::getElement((ArrayPtr*)stack, index)); |
| if (FI->Metadata == NULL) ++index; |
| else { |
| JavaMethod* meth = (JavaMethod*)FI->Metadata; |
| assert(meth && "Wrong stack trace"); |
| if (meth->classDef->isSubclassOf(vm->upcalls->newThrowable)) { |
| ++index; |
| } else return index; |
| } |
| } |
| |
| assert(0 && "Invalid stack trace!"); |
| return 0; |
| } |
| |
| int JavaObjectThrowable::getStackTraceDepth(JavaObjectThrowable * self) { |
| JavaObject * stack = NULL; |
| llvm_gcroot(self, 0); |
| llvm_gcroot(stack, 0); |
| |
| if (!self->backtrace) return 0; |
| |
| Jnjvm* vm = JavaThread::get()->getJVM(); |
| |
| stack = self->backtrace; |
| sint32 index = getStackTraceBase(self); |
| |
| sint32 size = 0; |
| sint32 cur = index; |
| while (cur < JavaArray::getSize(stack)) { |
| vmkit::FrameInfo* FI = vm->IPToFrameInfo(ArrayPtr::getElement((ArrayPtr*)stack, cur)); |
| ++cur; |
| if (FI->Metadata != NULL) ++size; |
| } |
| |
| return size; |
| } |
| |
| JavaObjectConstructor* JavaObjectConstructor::createFromInternalConstructor(JavaMethod * cons, int i) { |
| JavaObjectConstructor* ret = 0; |
| JavaObject* pArr = 0; |
| JavaObject* eArr = 0; |
| ArraySInt8* ann = 0; |
| ArraySInt8* pmAnn = 0; |
| llvm_gcroot(ret, 0); |
| llvm_gcroot(pArr, 0); |
| llvm_gcroot(eArr, 0); |
| llvm_gcroot(ann, 0); |
| llvm_gcroot(pmAnn, 0); |
| |
| Jnjvm* vm = JavaThread::get()->getJVM(); |
| JnjvmClassLoader * classLoader = cons->classDef->classLoader; |
| |
| UserClass* Cons = vm->upcalls->newConstructor; |
| pArr = cons->getParameterTypes(classLoader); |
| eArr = cons->getExceptionTypes(classLoader); |
| ret = (JavaObjectConstructor*)Cons->doNew(vm); |
| JavaObject* const* Cl = cons->classDef->getDelegateePtr(); |
| |
| JavaString ** sig = getSignature(cons); |
| ann = getAnnotations(cons); |
| pmAnn = getParamAnnotations(cons); |
| |
| vm->upcalls->initConstructor->invokeIntSpecial(vm, Cons, ret, |
| Cl, /* declaringClass */ |
| &pArr, /* parameterTypes */ |
| &eArr, /* checkedExceptions */ |
| cons->access, /* modifiers */ |
| i, /* slot */ |
| sig, /* String signature */ |
| &ann, /* annotations */ |
| &pmAnn /* parameterAnnotations */ |
| ); |
| |
| return ret; |
| } |
| |
| JavaObjectMethod* JavaObjectMethod::createFromInternalMethod(JavaMethod* meth, int i) { |
| JavaObjectMethod* ret = 0; |
| JavaString* str = 0; |
| JavaObject* pArr = 0; |
| JavaObject* eArr = 0; |
| JavaObject* retTy = 0; |
| ArraySInt8* ann = 0; |
| ArraySInt8* pmAnn = 0; |
| ArraySInt8* defAnn = 0; |
| llvm_gcroot(ret, 0); |
| llvm_gcroot(str, 0); |
| llvm_gcroot(pArr, 0); |
| llvm_gcroot(eArr, 0); |
| llvm_gcroot(retTy, 0); |
| llvm_gcroot(ann, 0); |
| llvm_gcroot(pmAnn, 0); |
| llvm_gcroot(defAnn, 0); |
| |
| // TODO: check parameter types |
| Jnjvm* vm = JavaThread::get()->getJVM(); |
| JnjvmClassLoader * classLoader = meth->classDef->classLoader; |
| |
| UserClass* Meth = vm->upcalls->newMethod; |
| ret = (JavaObjectMethod*)Meth->doNew(vm); |
| str = vm->internalUTF8ToStr(meth->name); |
| pArr = meth->getParameterTypes(classLoader); |
| eArr = meth->getExceptionTypes(classLoader); |
| retTy = meth->getReturnType(classLoader); |
| JavaString ** sig = getSignature(meth); |
| ann = getAnnotations(meth); |
| pmAnn = getParamAnnotations(meth); |
| defAnn = getAnnotationDefault(meth); |
| |
| JavaObject* const* Cl = meth->classDef->getClassDelegateePtr(vm); |
| vm->upcalls->initMethod->invokeIntSpecial(vm, Meth, ret, |
| Cl, /* declaring class */ |
| &str, /* name */ |
| &pArr, /* parameter types */ |
| &retTy, /* return type */ |
| &eArr, /* exceptions */ |
| meth->access, /* modifiers */ |
| i, /* slot */ |
| sig, /* signature */ |
| &ann, /* annotations */ |
| &pmAnn, /* parameter annotations */ |
| &defAnn); /* default annotations */ |
| |
| return ret; |
| } |
| |
| JavaObjectField* JavaObjectField::createFromInternalField(JavaField* field, int i) { |
| JavaObjectField* ret = 0; |
| JavaString* name = 0; |
| ArraySInt8* ann = 0; |
| llvm_gcroot(ret, 0); |
| llvm_gcroot(name, 0); |
| llvm_gcroot(ann, 0); |
| |
| // TODO: check parameter types |
| Jnjvm* vm = JavaThread::get()->getJVM(); |
| UserClass* Field = vm->upcalls->newField; |
| ret = (JavaObjectField*)Field->doNew(vm); |
| name = vm->internalUTF8ToStr(field->name); |
| |
| //type->Class |
| JnjvmClassLoader* loader = field->classDef->classLoader; |
| UserCommonClass * fieldCl = field->getSignature()->assocClass(loader); |
| assert(fieldCl); |
| JavaObject* const* type = fieldCl->getClassDelegateePtr(vm); |
| JavaObject* const* Cl = field->classDef->getClassDelegateePtr(vm); |
| |
| JavaString** sig = getSignature(field); |
| ann = getAnnotations(field); |
| |
| /* java.reflect.Field( |
| * Class declaringClass, |
| * String name, |
| * Class type, |
| * int modifiers, |
| * int slot, |
| * String signature, |
| * byte[] annotations) |
| */ |
| vm->upcalls->initField->invokeIntSpecial(vm, Field, ret, |
| Cl, |
| &name, |
| type, |
| field->access, |
| i, |
| sig, |
| &ann); |
| |
| return ret; |
| } |
| |
| static inline JavaString** getSignatureString(JavaAttribute* sigAtt, Class* cl) { |
| if (!sigAtt) return 0; |
| |
| Reader reader(sigAtt, cl->bytes); |
| uint16 index = reader.readU2(); |
| |
| return cl->classLoader->UTF8ToStr(cl->getConstantPool()->UTF8At(index)); |
| |
| } |
| |
| JavaString** JavaObjectClass::getSignature(Class *cl) { |
| JavaAttribute* sigAtt = cl->lookupAttribute(JavaAttribute::signatureAttribute); |
| return getSignatureString(sigAtt, cl); |
| } |
| |
| JavaString** JavaObjectField::getSignature(JavaField* field) { |
| JavaAttribute* sigAtt = field->lookupAttribute(JavaAttribute::signatureAttribute); |
| return getSignatureString(sigAtt, field->classDef); |
| } |
| |
| JavaString** JavaObjectMethod::getSignature(JavaMethod* meth) { |
| JavaAttribute* sigAtt = meth->lookupAttribute(JavaAttribute::signatureAttribute); |
| return getSignatureString(sigAtt, meth->classDef); |
| } |
| |
| JavaString** JavaObjectConstructor::getSignature(JavaMethod* cons) { |
| JavaAttribute* sigAtt = cons->lookupAttribute(JavaAttribute::signatureAttribute); |
| return getSignatureString(sigAtt, cons->classDef); |
| } |
| |
| inline ArraySInt8* getAttrBytes(JavaAttribute* annotationsAtt, Class* cl) { |
| ArraySInt8* ret = 0; |
| llvm_gcroot(ret, 0); |
| |
| if (!annotationsAtt) return 0; |
| |
| JavaThread* th = JavaThread::get(); |
| Jnjvm* vm = th->getJVM(); |
| |
| uint32 len = annotationsAtt->nbb; |
| ret = (ArraySInt8*)vm->upcalls->ArrayOfByte->doNew(len, vm); |
| |
| Reader reader(annotationsAtt, cl->bytes); |
| for(uint32 i = 0; i < len; ++i) { |
| ArraySInt8::setElement(ret, reader.readS1(), i); |
| } |
| |
| return ret; |
| } |
| |
| ArraySInt8* JavaObjectClass::getAnnotations(Class *cl) { |
| JavaAttribute* attr = |
| cl->lookupAttribute(JavaAttribute::annotationsAttribute); |
| |
| return getAttrBytes(attr, cl); |
| } |
| |
| ArraySInt8* JavaObjectField::getAnnotations(JavaField *field) { |
| JavaAttribute* attr = |
| field->lookupAttribute(JavaAttribute::annotationsAttribute); |
| |
| return getAttrBytes(attr, field->classDef); |
| } |
| |
| ArraySInt8* JavaObjectMethod::getAnnotations(JavaMethod *meth) { |
| JavaAttribute* attr = |
| meth->lookupAttribute(JavaAttribute::annotationsAttribute); |
| |
| return getAttrBytes(attr, meth->classDef); |
| } |
| ArraySInt8* JavaObjectMethod::getParamAnnotations(JavaMethod *meth) { |
| JavaAttribute* attr = |
| meth->lookupAttribute(JavaAttribute::paramAnnotationsAttribute); |
| |
| return getAttrBytes(attr, meth->classDef); |
| } |
| ArraySInt8* JavaObjectMethod::getAnnotationDefault(JavaMethod *meth) { |
| JavaAttribute* attr = |
| meth->lookupAttribute(JavaAttribute::annotationDefaultAttribute); |
| |
| return getAttrBytes(attr, meth->classDef); |
| } |
| |
| ArraySInt8* JavaObjectConstructor::getAnnotations(JavaMethod *cons) { |
| JavaAttribute* attr = |
| cons->lookupAttribute(JavaAttribute::annotationsAttribute); |
| |
| return getAttrBytes(attr, cons->classDef); |
| } |
| ArraySInt8* JavaObjectConstructor::getParamAnnotations(JavaMethod *cons) { |
| JavaAttribute* attr = |
| cons->lookupAttribute(JavaAttribute::paramAnnotationsAttribute); |
| |
| return getAttrBytes(attr, cons->classDef); |
| } |
| |
| } // end namespace j3 |