📄 field.c
字号:
bits. */ switch (toType) { case CVM_T_BOOLEAN: CVMfbStaticField(ee, declaringClassFb).i = v.z; break; case CVM_T_CHAR: CVMfbStaticField(ee, declaringClassFb).i = v.c; break; case CVM_T_FLOAT: CVMfbStaticField(ee, declaringClassFb).f = v.f; break; case CVM_T_DOUBLE: CVMdouble2Jvm(&CVMfbStaticField(ee, declaringClassFb).raw, v.d); break; case CVM_T_BYTE: CVMfbStaticField(ee, declaringClassFb).i = v.b; break; case CVM_T_SHORT: CVMfbStaticField(ee, declaringClassFb).i = v.s; break; case CVM_T_INT: CVMfbStaticField(ee, declaringClassFb).i = v.i; break; case CVM_T_LONG: CVMlong2Jvm(&CVMfbStaticField(ee, declaringClassFb).raw, v.j); break; default: CVMthrowInternalError(ee, "illegal primitive type"); return CNI_EXCEPTION; } } } else { /* Check argument object against field's type */ CVMBool retVal; /* NOTE this works for null objects as well */ retVal = CVMgcUnsafeIsInstanceOf(ee, argObj, fieldTypeCb); if (retVal == CVM_TRUE) { if (!CVMfbIs(declaringClassFb, STATIC)) { CVMD_fieldWriteRef(obj, CVMfbOffset(declaringClassFb), argObj); } else { CVMID_icellSetDirect(ee, &(CVMfbStaticField(ee, declaringClassFb).r), argObj); } } else { CVMthrowIllegalArgumentException(ee, "java.lang.reflect.Field.set(): " "argument object is of " "wrong type"); return CNI_EXCEPTION; } } return CNI_VOID;fail: CVMthrowIllegalArgumentException(ee, "java.lang.reflect.Field.set():" "widening primitive value"); return CNI_EXCEPTION;#else /* CVM_REFLECT */ CVMthrowUnsupportedOperationException(ee, NULL); return CNI_EXCEPTION;#endif /* CVM_REFLECT */}#ifdef CVM_REFLECTCNIResultCodeCVMsetPrimitiveField(CVMExecEnv* ee, CVMStackVal32 *arguments, CVMMethodBlock **p_mb, CVMBasicType argType){ CVMObject* fieldObj; CVMObject* obj = NULL; CVMObject* fieldTypeObj; CVMFieldBlock* declaringClassFb; CVMClassBlock* declaringClassCb; /* * fieldTypeCbAddr holds a native pointer as an int value * therefore change the type to CVMAddr which is 4 byte on * 32 bit platforms and 8 byte on 64 bit platforms */ CVMAddr fieldTypeCbAddr; CVMClassBlock* fieldTypeCb; CVMClassBlock* objectCb; CVMInt32 override; CVMJavaVal32 val32; CVMJavaVal64 val64; /* kept in "stack" order, not native order */ CVMBasicType toType; jvalue v; CVMBool argIs64Bit; CVMBool fieldIs64Bit; /* CNI policy: offer a gc-safe checkpoint */ CVMD_gcSafeCheckPoint(ee, {}, {}); fieldObj = CVMID_icellDirect(ee, &arguments[0].j.r); /* Can this happen? */ if (fieldObj == NULL) { CVMthrowNullPointerException(ee, "java.lang.reflect.Field." "setPrimitiveField(): " "null Field object"); return CNI_EXCEPTION; } /* Get the declaring class's fieldblock corresponding to the Field object. */ declaringClassFb = CVMreflectGCUnsafeGetFieldBlock(fieldObj); CVMassert(declaringClassFb != NULL); /* Get the declaring class of this field (note that the "class" field in java.lang.reflect.Field is redundant) */ declaringClassCb = CVMfbClassBlock(declaringClassFb); CVMassert(declaringClassCb != NULL); /* See whether the field is static. If so, we ignore the object argument. */ if (CVMfbIs(declaringClassFb, STATIC)) { /* According to Field.set() API spec, if the underlying field is static and the class that declares the field is uninitialized, we need to initializ the class. */ if (!CVMcbInitializationDoneFlag(ee, declaringClassCb)) { if (!CVMreflectEnsureInitialized(ee, declaringClassCb)) { return CNI_EXCEPTION; } } objectCb = declaringClassCb; } else { /* Check whether the object is a non-null instance of the declaring class. */ obj = CVMID_icellDirect(ee, &arguments[1].j.r); if (obj == NULL) { CVMthrowNullPointerException(ee, "java.lang.reflect.Field.set(): " "null argument object for non-static " "field reference"); return CNI_EXCEPTION; } objectCb = CVMobjectGetClass(obj); if (!(objectCb == declaringClassCb || CVMgcUnsafeIsInstanceOf(ee, obj, declaringClassCb))) { CVMthrowIllegalArgumentException(ee, "java.lang.reflect.Field.set(): " "argument object is of the wrong type"); return CNI_EXCEPTION; } } /* * Access checking (unless overridden by Field) */ CVMD_fieldReadInt(fieldObj, CVMoffsetOfjava_lang_reflect_AccessibleObject_override, override); if (!override) { if (!(CVMcbIs(declaringClassCb, PUBLIC) && CVMfbIs(declaringClassFb, PUBLIC))) { /* NOTE: we pass in CVM_TRUE for "forInvoke" because we used the CNI calling convention to enter this code, which doesn't push an intermediary frame which we would need to skip. See documentation for CVMreflectCheckAccess. */ if (!CVMreflectCheckAccess(ee, declaringClassCb, CVMfbAccessFlags(declaringClassFb), objectCb, CVM_TRUE, NULL)) return CNI_EXCEPTION; /* exception */ } } if (CVMfbIs(declaringClassFb, FINAL)) { CVMthrowIllegalAccessException(ee, "field is final"); return CNI_EXCEPTION; /* exception */ } CVMD_fieldReadRef(fieldObj, CVMoffsetOfjava_lang_reflect_Field_type, fieldTypeObj); /* Now get the classblock of the type of the field. */ /* * Access member variable of type 'int' * and cast it to a native pointer. The java type 'int' only garanties * 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 * are catched which set/get this member. */ CVMD_fieldReadAddr(fieldTypeObj, CVMoffsetOfjava_lang_Class_classBlockPointer, fieldTypeCbAddr); fieldTypeCb = (CVMClassBlock*) fieldTypeCbAddr; CVMassert(fieldTypeCb != NULL); if (!CVMcbIs(fieldTypeCb, PRIMITIVE)) { /* Wording in the spec may lead the unwary to believe * that this should work. Unfortunately. */ CVMthrowIllegalArgumentException(ee, "java.lang.reflect.Field." "setPrimitiveField(): " "attempt to set object field " "as primitive" ); return CNI_EXCEPTION; } /* Read the argument off the stack. How we do so depends on whether we're expecting a 64-bit argument or not. */ argIs64Bit = (argType == CVM_T_LONG || argType == CVM_T_DOUBLE); if (argIs64Bit) { CVMmemCopy64(val64.v, &arguments[2].j.raw); val32.i = 0; /* fix compiler warning */ } else { val32 = arguments[2].j; val64.l = CVMlongConstZero(); /* fix compiler warning */ } toType = CVMcbBasicTypeCode(fieldTypeCb); fieldIs64Bit = (toType == CVM_T_LONG || toType == CVM_T_DOUBLE); if (argType != toType) { /* Put it in the appropriate slot of jvalue so we can use the REFLECT_WIDEN macro */ switch (argType) { case CVM_T_BOOLEAN: v.z = val32.i; break; case CVM_T_CHAR: v.c = val32.i; break; case CVM_T_FLOAT: v.f = val32.f; break; case CVM_T_DOUBLE: /* "stack" order to native order */ v.d = CVMjvm2Double(val64.v); break; case CVM_T_BYTE: v.b = val32.i; break; case CVM_T_SHORT: v.s = val32.i; break; case CVM_T_INT: v.i = val32.i; break; case CVM_T_LONG: /* "stack" order to native order */ v.j = CVMjvm2Long(val64.v); break; default: CVMthrowInternalError(ee, "illegal primitive type"); return CNI_EXCEPTION; } REFLECT_WIDEN(v, argType, toType, fail); /* Put it back in the appropriate CVMJavaVal */ switch (toType) { case CVM_T_BOOLEAN: val32.i = v.z; break; case CVM_T_CHAR: val32.i = v.c; break; case CVM_T_FLOAT: val32.f = v.f; break; case CVM_T_DOUBLE: /* native order to "stack" order */ CVMdouble2Jvm(val64.v, v.d); break; case CVM_T_BYTE: val32.i = v.b; break; case CVM_T_SHORT: val32.i = v.s; break; case CVM_T_INT: val32.i = v.i; break; case CVM_T_LONG: /* native order to "stack" order */ CVMlong2Jvm(val64.v, v.j); break; default: CVMthrowInternalError(ee, "illegal primitive type"); return CNI_EXCEPTION; } } if (!CVMfbIs(declaringClassFb, STATIC)) { if (fieldIs64Bit) { CVMD_fieldWrite64(obj, CVMfbOffset(declaringClassFb), (CVMJavaVal32*) val64.v); } else { CVMD_fieldWrite32(obj, CVMfbOffset(declaringClassFb), val32); } } else { if (fieldIs64Bit) { CVMmemCopy64(&CVMfbStaticField(ee, declaringClassFb).raw, val64.v); } else { CVMfbStaticField(ee, declaringClassFb) = val32; } } /* Note we leave frame->topOfStack untouched, because it is decached by the interpreter when we return, but it is very important that we don't offer a GC-safe point after mutating the stack slot(s) corresponding to the return value because of possible changes of refness, which would make the stackmap incorrect. */ return CNI_VOID;fail: CVMthrowIllegalArgumentException(ee, "java.lang.reflect.Field.set():" "widening primitive value"); return CNI_EXCEPTION;}#endifCNIEXPORT CNIResultCodeCNIjava_lang_reflect_Field_setBoolean(CVMExecEnv* ee, CVMStackVal32 *arguments, CVMMethodBlock **p_mb){ /* CNI policy: offer a gc-safe checkpoint */ CVMD_gcSafeCheckPoint(ee, {}, {});#ifdef CVM_REFLECT return CVMsetPrimitiveField(ee, arguments, p_mb, CVM_T_BOOLEAN);#else /* CVM_REFLECT */ CVMthrowUnsupportedOperationException(ee, NULL); return CNI_EXCEPTION;#endif /* CVM_REFLECT */}CNIEXPORT CNIResultCodeCNIjava_lang_reflect_Field_setByte(CVMExecEnv* ee, CVMStackVal32 *arguments, CVMMethodBlock **p_mb){ /* CNI policy: offer a gc-safe checkpoint */ CVMD_gcSafeCheckPoint(ee, {}, {});#ifdef CVM_REFLECT return CVMsetPrimitiveField(ee, arguments, p_mb, CVM_T_BYTE);#else /* CVM_REFLECT */ CVMthrowUnsupportedOperationException(ee, NULL); return CNI_EXCEPTION;#endif /* CVM_REFLECT */}CNIEXPORT CNIResultCodeCNIjava_lang_reflect_Field_setChar(CVMExecEnv* ee, CVMStackVal32 *arguments, CVMMethodBlock **p_mb){ /* CNI policy: offer a gc-safe checkpoint */ CVMD_gcSafeCheckPoint(ee, {}, {});#ifdef CVM_REFLECT return CVMsetPrimitiveField(ee, arguments, p_mb, CVM_T_CHAR);#else /* CVM_REFLECT */ CVMthrowUnsupportedOperationException(ee, NULL); return CNI_EXCEPTION;#endif /* CVM_REFLECT */}CNIEXPORT CNIResultCodeCNIjava_lang_reflect_Field_setShort(CVMExecEnv* ee, CVMStackVal32 *arguments, CVMMethodBlock **p_mb){ /* CNI policy: offer a gc-safe checkpoint */ CVMD_gcSafeCheckPoint(ee, {}, {});#ifdef CVM_REFLECT return CVMsetPrimitiveField(ee, arguments, p_mb, CVM_T_SHORT);#else /* CVM_REFLECT */ CVMthrowUnsupportedOperationException(ee, NULL); return CNI_EXCEPTION;#endif /* CVM_REFLECT */}CNIEXPORT CNIResultCodeCNIjava_lang_reflect_Field_setInt(CVMExecEnv* ee, CVMStackVal32 *arguments, CVMMethodBlock **p_mb){ /* CNI policy: offer a gc-safe checkpoint */ CVMD_gcSafeCheckPoint(ee, {}, {});#ifdef CVM_REFLECT return CVMsetPrimitiveField(ee, arguments, p_mb, CVM_T_INT);#else /* CVM_REFLECT */ CVMthrowUnsupportedOperationException(ee, NULL); return CNI_EXCEPTION;#endif /* CVM_REFLECT */}CNIEXPORT CNIResultCodeCNIjava_lang_reflect_Field_setLong(CVMExecEnv* ee, CVMStackVal32 *arguments, CVMMethodBlock **p_mb){ /* CNI policy: offer a gc-safe checkpoint */ CVMD_gcSafeCheckPoint(ee, {}, {});#ifdef CVM_REFLECT return CVMsetPrimitiveField(ee, arguments, p_mb, CVM_T_LONG);#else /* CVM_REFLECT */ CVMthrowUnsupportedOperationException(ee, NULL); return CNI_EXCEPTION;#endif /* CVM_REFLECT */}CNIEXPORT CNIResultCodeCNIjava_lang_reflect_Field_setFloat(CVMExecEnv* ee, CVMStackVal32 *arguments, CVMMethodBlock **p_mb){ /* CNI policy: offer a gc-safe checkpoint */ CVMD_gcSafeCheckPoint(ee, {}, {});#ifdef CVM_REFLECT return CVMsetPrimitiveField(ee, arguments, p_mb, CVM_T_FLOAT);#else /* CVM_REFLECT */ CVMthrowUnsupportedOperationException(ee, NULL); return CNI_EXCEPTION;#endif /* CVM_REFLECT */}CNIEXPORT CNIResultCodeCNIjava_lang_reflect_Field_setDouble(CVMExecEnv* ee, CVMStackVal32 *arguments, CVMMethodBlock **p_mb){ /* CNI policy: offer a gc-safe checkpoint */ CVMD_gcSafeCheckPoint(ee, {}, {});#ifdef CVM_REFLECT return CVMsetPrimitiveField(ee, arguments, p_mb, CVM_T_DOUBLE);#else /* CVM_REFLECT */ CVMthrowUnsupportedOperationException(ee, NULL); return CNI_EXCEPTION;#endif /* CVM_REFLECT */}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -