public static Delegate CreateDynamicMethod(Type delegateType, Action <ILGenerator> ilGen) { var invokeMethod = delegateType.GetMethod("Invoke"); var returnType = invokeMethod.ReturnType; var parameterTypes = invokeMethod.GetParameters().Select(p => p.ParameterType).ToArray(); #if SILVERLIGHT var method = CreateDynamicMethodWithVisibilityChecks(returnType, parameterTypes, ilGen); return(Delegate.CreateDelegate(delegateType, method)); #else // If you try to call the DynamicMethod constructor specifying a ByRef type // as the return value it throws NotSupportedException with the following message: // "The return Type contains some invalid type(i.e. null, ByRef)". In order to make // it working we are applying the following simple workaround: // 1. Pass a non-ref type to constructor and create dynamic method instance // 2. Using reflection change the value of private field 'm_returnType' of the // newly created dynamic method to be ByRef type Type dynamicReturnType = (returnType.IsByRef) ? returnType.GetElementType() : returnType; var method = new DynamicMethod("DynamicMethod_" + Guid.NewGuid().ToString("N"), dynamicReturnType, parameterTypes, true); if (returnType.IsByRef) { method.GetType().GetField("m_returnType", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly) .SetValue(method, returnType); } ilGen(method.GetILGenerator()); return(method.CreateDelegate(delegateType)); #endif }
public static RefGetter <T, U> create_refgetter <T, U>(string s_field, BindingFlags bindingFlags = BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly) { const BindingFlags bf = BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly; var fi = typeof(T).GetField(s_field, bindingFlags); if (fi == null) { throw new MissingFieldException(typeof(T).Name, s_field); } var s_name = "__refget_" + typeof(T).Name + "_fi_" + fi.Name; // workaround for using ref-return with DynamicMethod: // a.) initialize with dummy return value var dm = new DynamicMethod(s_name, typeof(U), new[] { typeof(T) }, typeof(T), true); // b.) replace with desired 'ByRef' return value dm.GetType().GetField("m_returnType", bf).SetValue(dm, typeof(U).MakeByRefType()); var il = dm.GetILGenerator(); il.Emit(OpCodes.Ldarg_0); il.Emit(OpCodes.Ldflda, fi); il.Emit(OpCodes.Ret); return((RefGetter <T, U>)dm.CreateDelegate(typeof(RefGetter <T, U>))); }
public static IntPtr PrepareMethod(this DynamicMethod meth) { Type t = meth.GetType(); RuntimeMethodHandle handle = t.GetMethod("GetMethodDescriptor", mflag0) is MethodInfo getmd ? (RuntimeMethodHandle)getmd.Invoke(meth, null) : t.GetField("m_method", mflag0) is FieldInfo mm ? (RuntimeMethodHandle)mm.GetValue(meth) : (RuntimeMethodHandle)t.GetField("mhandle", mflag0).GetValue(meth); Type ht = handle.GetType(); object result = ht.GetField("m_value", mflag0) is FieldInfo fd ? fd.GetValue(handle) : ht.GetMethod("GetMethodInfo", mflag0) is MethodInfo mi ? mi.Invoke(handle, null) : null; if (result != null) { try { // 2020 01 30 // dynamicmethod 코드에 전혀 문제가 없는 경우에 // 여기서 오류가 발생하지 않는다 m_compileMeth.Invoke(null, new object[1] { result }); return(handle.GetFunctionPointer()); } }
/// <summary> /// Create a pointer for static field <paramref name="s_field"/> /// </summary> /// <typeparam name="U"></typeparam> /// <param name="s_field"></param> /// <returns> Pointer to <paramref name="s_field"/></returns> /// <remarks> Source: https://stackoverflow.com/a/45046664/13073994 </remarks> public static RefGetter <U> CreateStaticFieldRef <U>(Type type, String s_field) { const BindingFlags bf = BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.DeclaredOnly; var fi = type.GetField(s_field, bf); if (fi == null) { throw new MissingFieldException(type.Name, s_field); } var s_name = "__refget_" + type.Name + "_fi_" + fi.Name; // workaround for using ref-return with DynamicMethod: // a.) initialize with dummy return value var dm = new DynamicMethod(s_name, typeof(U), null, type, true); // b.) replace with desired 'ByRef' return value dm.GetType().GetField("returnType", AccessTools.all).SetValue(dm, typeof(U).MakeByRefType()); var il = dm.GetILGenerator(); il.Emit(OpCodes.Ldsflda, fi); il.Emit(OpCodes.Ret); return((RefGetter <U>)dm.CreateDelegate(typeof(RefGetter <U>))); }
public void RtDynamicMethod() { var module = ModuleDefinition.FromFile(typeof(TDynamicMethod).Assembly.Location); DynamicMethod generateDynamicMethod = TDynamicMethod.GenerateDynamicMethod(); var rtDynamicMethod = generateDynamicMethod.GetType().GetField("m_dynMethod", (BindingFlags)(-1))?.GetValue(generateDynamicMethod); var dynamicMethodDefinition = new DynamicMethodDefinition(module, rtDynamicMethod); Assert.NotNull(dynamicMethodDefinition); Assert.NotEmpty(dynamicMethodDefinition.CilMethodBody.Instructions); Assert.Equal(dynamicMethodDefinition.CilMethodBody.Instructions.Select(q => q.OpCode), new [] { CilOpCodes.Ldarg_0, CilOpCodes.Call, CilOpCodes.Ldarg_1, CilOpCodes.Ret }); Assert.Equal(dynamicMethodDefinition.Parameters.Select(q => q.ParameterType), new TypeSignature[] { module.CorLibTypeFactory.String, module.CorLibTypeFactory.Int32 }); }
private static IntPtr GetDynamicMethodAddress(DynamicMethod dynamicMethod) { var type = dynamicMethod.GetType(); var fieldInfo = type.GetField("m_method", BindingFlags.Instance | BindingFlags.NonPublic); if (fieldInfo == null) { fieldInfo = type.GetField("m_methodHandle", BindingFlags.Instance | BindingFlags.NonPublic); } var runtimeMethodInfoStub = fieldInfo?.GetValue(dynamicMethod); if (runtimeMethodInfoStub == null) { return(IntPtr.Zero); } var runtimeMethodHandleInternal = runtimeMethodInfoStub.GetType().GetField("m_value", BindingFlags.Instance | BindingFlags.Public).GetValue(runtimeMethodInfoStub); var getFunctionPointer = typeof(RuntimeMethodHandle).GetMethod(nameof(RuntimeMethodHandle.GetFunctionPointer), BindingFlags.Static | BindingFlags.NonPublic); var ptr = (IntPtr)getFunctionPointer.Invoke(null, new[] { runtimeMethodHandleInternal }); return(ptr); }
public static IntPtr PrepareMethod(this DynamicMethod meth) { Type t = meth.GetType(); // mono only MethodInfo mi = t.GetMethod("CreateDynMethod", mflag0); if (mi != null) { mi.Invoke(meth, null); return(((RuntimeMethodHandle)t.GetField("mhandle", mflag0).GetValue(meth)).GetFunctionPointer()); } RuntimeMethodHandle handle; FieldInfo fi; mi = t.GetMethod("GetMethodDescriptor", mflag0); if (mi != null) { handle = (RuntimeMethodHandle)mi.Invoke(meth, null); } else { fi = t.GetField("m_method", mflag0); handle = fi != null ? (RuntimeMethodHandle)fi.GetValue(meth) : default; } t = handle.GetType(); object result; fi = t.GetField("m_value", mflag0); if (fi != null) { result = fi.GetValue(handle); } else { fi = t.GetField("Value", mflag0); if (fi != null) { result = fi.GetValue(handle); } else { mi = t.GetMethod("GetMethodInfo", mflag0); if (mi != null) { result = mi.Invoke(handle, null); } else { result = null; } } } if (result != null) { try { // 2020 01 30 // dynamicmethod 코드에 전혀 문제가 없는 경우에 // 여기서 오류가 발생하지 않는다 m_compileMeth.Invoke(null, new object[1] { result }); return(handle.GetFunctionPointer()); } }
internal static void PrepareDynamicMethod(DynamicMethod method) { var nonPublicInstance = BindingFlags.NonPublic | BindingFlags.Instance; var nonPublicStatic = BindingFlags.NonPublic | BindingFlags.Static; // on mono, just call 'CreateDynMethod' // var m_CreateDynMethod = method.GetType().GetMethod("CreateDynMethod", nonPublicInstance); if (m_CreateDynMethod != null) { var h_CreateDynMethod = MethodInvoker.GetHandler(m_CreateDynMethod); h_CreateDynMethod(method, new object[0]); return; } // on all .NET Core versions, call 'RuntimeHelpers._CompileMethod' but with a different parameter: // var m__CompileMethod = typeof(RuntimeHelpers).GetMethod("_CompileMethod", nonPublicStatic); var h__CompileMethod = MethodInvoker.GetHandler(m__CompileMethod); var m_GetMethodDescriptor = method.GetType().GetMethod("GetMethodDescriptor", nonPublicInstance); var h_GetMethodDescriptor = MethodInvoker.GetHandler(m_GetMethodDescriptor); var handle = (RuntimeMethodHandle)h_GetMethodDescriptor(method, new object[0]); // 1) RuntimeHelpers._CompileMethod(handle.GetMethodInfo()) // object runtimeMethodInfo = null; var f_m_value = handle.GetType().GetField("m_value", nonPublicInstance); if (f_m_value != null) { runtimeMethodInfo = f_m_value.GetValue(handle); } else { var m_GetMethodInfo = handle.GetType().GetMethod("GetMethodInfo", nonPublicInstance); if (m_GetMethodInfo != null) { var h_GetMethodInfo = MethodInvoker.GetHandler(m_GetMethodInfo); runtimeMethodInfo = h_GetMethodInfo(handle, new object[0]); } } if (runtimeMethodInfo != null) { try { // this can throw BadImageFormatException "An attempt was made to load a program with an incorrect format" h__CompileMethod(null, new object[] { runtimeMethodInfo }); return; } #pragma warning disable RECS0022 catch #pragma warning restore RECS0022 { } } // 2) RuntimeHelpers._CompileMethod(handle.Value) // if (m__CompileMethod.GetParameters()[0].ParameterType.IsAssignableFrom(handle.Value.GetType())) { h__CompileMethod(null, new object[] { handle.Value }); return; } // 3) RuntimeHelpers._CompileMethod(handle) // if (m__CompileMethod.GetParameters()[0].ParameterType.IsAssignableFrom(handle.GetType())) { h__CompileMethod(null, new object[] { handle }); return; } }