private static AccessTools.FieldRef <F>?StaticFieldRefAccessInternal <F>(FieldInfo fieldInfo) { if (!Helper.IsValid()) { return(null); } if (!fieldInfo.IsStatic) { Trace.TraceError($"AccessTools2.StaticFieldRefAccessInternal<{typeof(F).FullName}>: Field must be static"); return(null); } if (!ValidateFieldType <F>(fieldInfo)) { return(null); } var dm = DynamicMethodDefinitionHandle.Create( $"__refget_{fieldInfo.DeclaringType?.Name ?? "null"}_static_fi_{fieldInfo.Name}", typeof(F).MakeByRefType(), new Type[0]); if (dm?.GetILGenerator() is not { } il) { return(null); } il.Emit(OpCodes.Ldsflda, fieldInfo); il.Emit(OpCodes.Ret); //return dm?.Generate() is { } methodInfo ? GetDelegate<AccessTools.FieldRef<F>>(methodInfo) : null; return(dm?.Generate()?.CreateDelegate(typeof(AccessTools.FieldRef <F>)) as AccessTools.FieldRef <F>); }
private static AccessTools.StructFieldRef <T, F>?StructFieldRefAccessInternal <T, F>(FieldInfo fieldInfo) where T : struct { if (!ValidateFieldType <F>(fieldInfo)) { return(null); } var dm = DynamicMethodDefinitionHandle.Create( $"__refget_{typeof(T).Name}_struct_fi_{fieldInfo.Name}", typeof(F).MakeByRefType(), new[] { typeof(T).MakeByRefType() }); if (dm?.GetILGenerator() is not { } il) { return(null); } il.Emit(OpCodes.Ldarg_0); il.Emit(OpCodes.Ldflda, fieldInfo); il.Emit(OpCodes.Ret); //return dm?.Generate() is { } methodInfo ? GetDelegate<AccessTools.StructFieldRef<T, F>>(methodInfo) : null; return(dm?.Generate()?.CreateDelegate(typeof(AccessTools.StructFieldRef <T, F>)) as AccessTools.StructFieldRef <T, F>); }
private static AccessTools.FieldRef <T, F>?FieldRefAccessInternal <T, F>(FieldInfo fieldInfo, bool needCastclass) where T : class { if (!Helper.IsValid()) { return(null); } if (fieldInfo.IsStatic) { Trace.TraceError($"AccessTools2.FieldRefAccessInternal<{typeof(T).FullName}, {typeof(F).FullName}>: Field must not be static"); return(null); } if (!ValidateFieldType <F>(fieldInfo)) { return(null); } var delegateInstanceType = typeof(T); var declaringType = fieldInfo.DeclaringType; var dm = DynamicMethodDefinitionHandle.Create( $"__refget_{delegateInstanceType.Name}_fi_{fieldInfo.Name}", typeof(F).MakeByRefType(), new[] { delegateInstanceType }); if (dm?.GetILGenerator() is not { } il) { return(null); } il.Emit(OpCodes.Ldarg_0); // The castclass is needed when T is a parent class or interface of declaring type (e.g. if T is object), // since there's no guarantee the instance passed to the delegate is actually of the declaring type. // In such a situation, the castclass will throw an InvalidCastException and thus prevent undefined behavior. if (needCastclass) { il.Emit(OpCodes.Castclass, declaringType); } il.Emit(OpCodes.Ldflda, fieldInfo); il.Emit(OpCodes.Ret); //return dm?.Generate() is { } methodInfo ? GetDelegate<AccessTools.FieldRef<T, F>>(methodInfo) : null; return(dm?.Generate()?.CreateDelegate(typeof(AccessTools.FieldRef <T, F>)) as AccessTools.FieldRef <T, F>); }