📄 reflect.c
字号:
/* * Modify the member variable slot of type 'int' and cast * it to CVMClassBlock*. The java type 'int' only * guarantees 32 bit, but because one slot is used as * storage space and a slot is 64 bit on 64 bit platforms, * it is possible to store a native pointer without * modification of java source code. This assumes that all * places in the C-code which set/get this member are * caught. */ CVMID_fieldReadAddr(ee, classICell, CVMoffsetOfjava_lang_Class_classBlockPointer, cbAsInt); cbFromArray = (CVMClassBlock*) cbAsInt; if (cbFromSig != cbFromArray) { /* Must execute CVMID_localrootEnd() */ mustAbort = CVM_TRUE; goto abort; } } }abort: CVMID_localrootEnd(); if (mustAbort) return CVM_FALSE; return CVM_TRUE;}voidCVMreflectMethod(CVMExecEnv* ee, CVMClassBlock* cb, const char* name, CVMArrayOfRefICell* types, int which, CVMObjectICell* result){ CVMInt32 tcnt, pcnt; CVMMethodTypeID nameCookie; GET_ARRAY_LENGTH(ee, types, tcnt); /* handles NULL */ if (CVMcbIs(cb, PRIMITIVE)) { nameCookie = CVM_TYPEID_ERROR; goto nosuchmethod; } CVMreflectEnsureLinked(ee, cb); /* * We need to use the "new" function, because the "lookup" function * is only valid when we know that the type already exists. */ nameCookie = CVMtypeidNewMembername(ee, name); if (nameCookie == CVM_TYPEID_ERROR) { /* Clear the exception. */ CVMclearLocalException(ee); goto nosuchmethod; } switch (which) { case REFLECT_MEMBER_PUBLIC: { if (CVMcbIs(cb, INTERFACE)) { WALK_INTERFACE_METHODS(cb, mb, { CVMMethodTypeID nameAndTypeID = CVMmbNameAndTypeID(mb); if ((CVMtypeidIsSameName(nameCookie, nameAndTypeID)) && (tcnt == (pcnt = CVMreflectGetParameterCount(nameAndTypeID))) && (pcnt == 0 || CVMreflectMatchParameterTypes(ee, mb, types, pcnt))) { CVMreflectNewJavaLangReflectMethod(ee, mb, result); goto finish; } /* CVMreflectMatchParameterTypes can throw an exception */ if (CVMexceptionOccurred(ee)) { goto finish; } }); goto nosuchmethod; } WALK_INSTANCE_METHODS(cb, mb, { CVMMethodTypeID nameAndTypeID = CVMmbNameAndTypeID(mb); if (CVMmbIs(mb, PUBLIC) && !CVMmbIsSpecial(mb) && (CVMtypeidIsSameName(nameCookie, nameAndTypeID)) && (tcnt == (pcnt = CVMreflectGetParameterCount(nameAndTypeID))) && (pcnt == 0 || CVMreflectMatchParameterTypes(ee, mb, types, pcnt))) { CVMreflectNewJavaLangReflectMethod(ee, mb, result); goto finish; } /* CVMreflectMatchParameterTypes can throw an exception */ if (CVMexceptionOccurred(ee)) { goto finish; } }); WALK_SUPER_METHODS(cb, mb, { CVMMethodTypeID nameAndTypeID = CVMmbNameAndTypeID(mb); if (CVMmbIs(mb, PUBLIC) && CVMmbIs(mb, STATIC) && !CVMmbIsSpecial(mb) && (CVMtypeidIsSameName(nameCookie, nameAndTypeID )) && (tcnt == (pcnt = CVMreflectGetParameterCount(nameAndTypeID))) && (pcnt == 0 || CVMreflectMatchParameterTypes(ee, mb, types, pcnt))) { CVMreflectNewJavaLangReflectMethod(ee, mb, result); goto finish; } /* CVMreflectMatchParameterTypes can throw an exception */ if (CVMexceptionOccurred(ee)) { goto finish; } }); break; } case REFLECT_MEMBER_DECLARED: { CVMMethodBlock *foundMB = NULL; int foundMBClassDepth = 0; WALK_DECLARED_METHODS(cb, mb, { CVMMethodTypeID nameAndTypeID = CVMmbNameAndTypeID(mb); if (!CVMmbIsSpecial(mb) && (CVMtypeidIsSameName(nameCookie, nameAndTypeID )) && (tcnt == (pcnt = CVMreflectGetParameterCount(nameAndTypeID))) && (pcnt == 0 || CVMreflectMatchParameterTypes(ee, mb, types, pcnt))) { /* In case of ambiguous method overloading, we need to walk all the methods and look for the most "specific" method: */ CVMSigIterator signature; CVMClassTypeID returnTypeID; CVMtypeidGetSignatureIterator(nameAndTypeID, &signature); returnTypeID = CVM_SIGNATURE_ITER_RETURNTYPE(signature); if (CVMtypeidIsPrimitive(returnTypeID)) { /* If the first method we encounter is a primitive type, then its as "specific" as it gets. We need not compare primitive types with class types even if some exists. The 2 are considered equally "specific". */ if (foundMB == NULL) { foundMB = mb; goto found; } } else { CVMClassBlock *returnTypeCB; CVMClassBlock *superCB; int classDepth = 0; /* Get the return type CB: */ returnTypeCB = CVMclassLookupByTypeFromClass(ee, returnTypeID, CVM_FALSE, CVMmbClassBlock(mb)); if (CVMexceptionOccurred(ee)) { goto finish; } /* Scan the superclass tree and count the inheritance depth: */ superCB = returnTypeCB; while (superCB != NULL) { superCB = CVMcbSuperclass(superCB); classDepth++; } if (foundMB == NULL || (classDepth > foundMBClassDepth)) { foundMB = mb; foundMBClassDepth = classDepth; } } } /* CVMreflectMatchParameterTypes can throw an exception */ if (CVMexceptionOccurred(ee)) { goto finish; } }); found: if (foundMB != NULL) { CVMreflectNewJavaLangReflectMethod(ee, foundMB, result); goto finish; } break; } default: CVMassert(CVM_FALSE); } nosuchmethod: CVMthrowNoSuchMethodException(ee, "%s", name); finish: if (nameCookie != CVM_TYPEID_ERROR) { CVMtypeidDisposeMembername(ee, nameCookie); }}/* * */voidCVMreflectNewJavaLangReflectConstructor(CVMExecEnv* ee, CVMMethodBlock* mb, CVMObjectICell* result){ CVMClassBlock *cb; const CVMClassBlock* classJavaLangReflectConstructor = CVMsystemClass(java_lang_reflect_Constructor); /* * Modify the member variable slot of type 'int' * and cast it to CVMMethodBlock*. The java type 'int' only guarantees * 32 bit, but because one slot is used as storage space and * a slot is 64 bit on 64 bit platforms, it is possible * to store a native pointer without modification of * java source code. This assumes that all places in the C-code * which set/get this member are caught. */ CVMAddr mbPtr; CVMMethodTypeID nameAndTypeID; CVMSigIterator parameters; CVMUint32 modifiers; /* Casting away const is safe here (see classes.h, runtime flags) */ CVMID_allocNewInstance(ee, (CVMClassBlock*) classJavaLangReflectConstructor, result); if (CVMID_icellIsNull(result)) { CVMthrowOutOfMemoryError(ee, "out of memory allocating Constructor object"); return; } CVMID_localrootBegin(ee); { CVMID_localrootDeclare(CVMArrayOfRefICell, parameterTypes); CVMID_localrootDeclare(CVMArrayOfRefICell, exceptionTypes); /* declaring class */ cb = CVMmbClassBlock(mb); CVMID_fieldWriteRef(ee, result, CVMoffsetOfjava_lang_reflect_Constructor_clazz, CVMcbJavaInstance(cb)); /* Store raw methodblock pointer as int (NOTE: not 64-bit clean) */ /* * Modify the member variable slot of type 'int' * and cast it to CVMMethodBlock*. The java type 'int' only guarantees * 32 bit, but because one slot is used as storage space and * a slot is 64 bit on 64 bit platforms, it is possible * to store a native pointer without modification of * java source code. This assumes that all places in the C-code * which set/get this member are caught. */ mbPtr = (CVMAddr) mb; CVMID_fieldWriteAddr(ee, result, CVMoffsetOfjava_lang_reflect_Constructor_slot, mbPtr); /* parameter types from signature */ nameAndTypeID = CVMmbNameAndTypeID(mb); CVMtypeidGetSignatureIterator( nameAndTypeID, ¶meters ); CVMreflectGetParameterTypes(ee, ¶meters, cb, parameterTypes); if (CVMID_icellIsNull(parameterTypes)) { CVMID_icellSetNull(result); /* Must execute CVMID_localrootEnd() */ goto abort; /* exception */ } CVMID_fieldWriteRef(ee, result, CVMoffsetOfjava_lang_reflect_Constructor_parameterTypes, (CVMObjectICell*) parameterTypes); CVMreflectGetExceptionTypes(ee, cb, mb, exceptionTypes); if (CVMID_icellIsNull(exceptionTypes)) { CVMID_icellSetNull(result); /* Must execute CVMID_localrootEnd() */ goto abort; /* exception */ } CVMID_fieldWriteRef(ee, result, CVMoffsetOfjava_lang_reflect_Constructor_exceptionTypes, (CVMObjectICell*) exceptionTypes); /* Modifiers */ /* Make sure we use the constants defined by the JVM spec as opposed to any renumbered ones in the VM. We get these from java.lang.reflect.Modifier via JavaCodeCompact. */ modifiers = 0; if (CVMmbIs(mb, PUBLIC)) modifiers |= java_lang_reflect_Modifier_PUBLIC; if (CVMmbIs(mb, PRIVATE)) modifiers |= java_lang_reflect_Modifier_PRIVATE; if (CVMmbIs(mb, PROTECTED)) modifiers |= java_lang_reflect_Modifier_PROTECTED; if (CVMmbIs(mb, STATIC)) modifiers |= java_lang_reflect_Modifier_STATIC; if (CVMmbIs(mb, FINAL)) modifiers |= java_lang_reflect_Modifier_FINAL; if (CVMmbIs(mb, SYNCHRONIZED)) modifiers |= java_lang_reflect_Modifier_SYNCHRONIZED; if (CVMmbIs(mb, NATIVE)) modifiers |= java_lang_reflect_Modifier_NATIVE; if (CVMmbIs(mb, ABSTRACT)) modifiers |= java_lang_reflect_Modifier_ABSTRACT; if (CVMmbIsJava(mb) && CVMjmdIs(CVMmbJmd(mb), STRICT)) modifiers |= java_lang_reflect_Modifier_STRICT; CVMID_fieldWriteInt(ee, result, CVMoffsetOfjava_lang_reflect_Constructor_modifiers, modifiers); CVMID_fieldWriteInt(ee, result, CVMoffsetOfjava_lang_reflect_AccessibleObject_override, CVM_FALSE); }abort: CVMID_localrootEnd();}voidCVMreflectConstructors(CVMExecEnv* ee, CVMClassBlock* cb, int which, CVMArrayOfRefICell* result){ CVMBool mustAbort = CVM_FALSE; CVMBool pub = (which == REFLECT_MEMBER_PUBLIC); CVMInt32 cnt = 0, j; const CVMClassBlock* classJavaLangReflectConstructor = CVMsystemClass(java_lang_reflect_Constructor); /* Exclude primitive, interface and array types */ if (CVMcbIs(cb, PRIMITIVE) || CVMcbIs(cb, INTERFACE) || CVMisArrayClass(cb)) { /* Allocate zero-length array of java.lang.reflect.Constructor objects */ /* Casting away const is safe here (see classes.h, runtime flags) */ CVMreflectNewArray(ee, (CVMClassBlock*) classJavaLangReflectConstructor, 0, (CVMArrayOfAnyTypeICell*) result); return; } CVMreflectEnsureLinked(ee, cb); WALK_DECLARED_METHODS(cb, mb, { if (CVMmbIsSpecial(mb) && (!pub || CVMmbIs(mb, PUBLIC)) && (CVMtypeidIsConstructor(CVMmbNameAndTypeID(mb)))) { cnt++; } }); /* Allocate result array */ /* Casting away const is safe here (see classes.h, runtime flags) */ CVMreflectNewArray(ee, (CVMClassBlock*) classJavaLangReflectConstructor, cnt, (CVMArrayOfAnyTypeICell*) result); if (CVMID_icellIsNull(result)) /* exception occurred */ return; /* Fill in declared order */ j = cnt; CVMID_localrootBegin(ee); { CVMID_localrootDeclare(CVMObjectICell, constructorICell); WALK_DECLARED_METHODS(cb, mb, { if (CVMmbIsSpecial(mb) && (!pub || CVMmbIs(mb, PUBLIC)) && (CVMtypeidIsConstructor(CVMmbNameAndTypeID(mb)))) { CVMreflectNewJavaLangReflectConstructor(ee, mb, constructorICell); if (CVMID_icellIsNull(constructorICell)) { /* exception occurred */ CVMID_icellSetNull(result); /* Must execute CVMID_localrootEnd() */ mustAbort = CVM_TRUE; goto abort; } j--; CVMID_arrayWriteRef(ee, result, j, constructorICell); } }); }abort: CVMID_localrootEnd(); if (mustAbort) return; CVMassert(j == 0);}voidCVMreflectConstructor(CVMExecEnv* ee, CVMClassBlock* cb, CVMArrayOfRefICell* types, int which, CVMObjectICell* result){ CVMInt32 tcnt, pcnt; CVMBool pub = (which == REFLECT_MEMBER_PUBLIC); /* Exclude primitive, interface and array types */ if (CVMcbIs(cb, PRIMITIVE) || CVMcbIs(cb, INTERFACE) || CVMisArrayClass(cb)) goto nosuchmethod; CVMreflectEnsureLinked(ee, cb); GET_ARRAY_LENGTH(ee, types, tcnt); /* handles NULL */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -