private static Hasher BuildDynamicHasher(Type declaringType, IReadOnlyCollection <FieldInfo> fieldInfos) { return(DynamicMethod <Hasher> .New(il => { // Declare the local variable to store the target instance il.DeclareLocal(declaringType); // Load the argument (the object instance) il.Emit(OpCodes.Ldarg_1); il.Emit(OpCodes.Castclass, declaringType); il.Emit(OpCodes.Stloc_0); // Unroll the member access MethodInfo validateDelegateInfo = typeof(ShaderHashCodeProvider).GetMethod(nameof(ValidateDelegate), BindingFlags.NonPublic | BindingFlags.Static), getMethodInfo = typeof(Delegate).GetProperty(nameof(Delegate.Method)).GetMethod, getHashCodeInfo = typeof(object).GetMethod(nameof(GetHashCode)); foreach (FieldInfo fieldInfo in fieldInfos) { Label label = il.DefineLabel(); // if (fieldInfo.GetValue(obj) != null) { il.Emit(OpCodes.Ldloc_0); il.Emit(OpCodes.Ldfld, fieldInfo); il.Emit(OpCodes.Brfalse_S, label); // if (ValidateDelegate(field)) { il.Emit(OpCodes.Ldloc_0); il.Emit(OpCodes.Ldfld, fieldInfo); il.EmitCall(OpCodes.Call, validateDelegateInfo, null); il.Emit(OpCodes.Brfalse_S, label); // hash = hash * 17 + field.Method.GetHashCode(); il.Emit(OpCodes.Ldarg_0); il.Emit(OpCodes.Ldc_I4_S, (byte)17); il.Emit(OpCodes.Mul); il.Emit(OpCodes.Ldloc_0); il.Emit(OpCodes.Ldfld, fieldInfo); il.EmitCall(OpCodes.Callvirt, getMethodInfo, null); il.EmitCall(OpCodes.Callvirt, getHashCodeInfo, null); il.Emit(OpCodes.Add); il.Emit(OpCodes.Starg_S, (byte)0); il.MarkLabel(label); } // Return the computed hash il.Emit(OpCodes.Ldarg_0); il.Emit(OpCodes.Ret); })); }
public void TestSquare() { Square square = DynamicMethod <Square> .New(il => { il.Emit(OpCodes.Ldarg_0); il.Emit(OpCodes.Dup); il.Emit(OpCodes.Mul); il.Emit(OpCodes.Ret); }); int result = square(2); // result = 2 * 2 Assert.IsTrue(result == 4); }