static DynamicMethod GenerateDynamicDeserializerStub(Type type) { var dm = new DynamicMethod("Deserialize", null, new Type[] { typeof(Stream), type.MakeByRefType() }, typeof(Serializer), true); dm.DefineParameter(1, ParameterAttributes.None, "stream"); dm.DefineParameter(2, ParameterAttributes.Out, "value"); return dm; }
private static void CreateDynamicAssembly() { new SecurityPermission(SecurityPermissionFlag.ControlEvidence).Assert(); Type[] types = new Type[] { typeof(Type), typeof(Type), typeof(string) }; MethodInfo methodInfo = typeof(Delegate).GetMethod("CreateDelegate", types); DynamicMethod method = new DynamicMethod("CreateDelegate", typeof(Delegate), types); method.DefineParameter(1, ParameterAttributes.In, "delegateType"); method.DefineParameter(2, ParameterAttributes.In, "targetType"); method.DefineParameter(3, ParameterAttributes.In, "methodName"); ILGenerator iLGenerator = method.GetILGenerator(5); iLGenerator.Emit(OpCodes.Ldarg_0); iLGenerator.Emit(OpCodes.Ldarg_1); iLGenerator.Emit(OpCodes.Ldarg_2); iLGenerator.EmitCall(OpCodes.Call, methodInfo, null); iLGenerator.Emit(OpCodes.Ret); s_CreateDelegate1 = (CreateDelegate1Delegate) method.CreateDelegate(typeof(CreateDelegate1Delegate)); types = new Type[] { typeof(Type), typeof(object), typeof(string) }; methodInfo = typeof(Delegate).GetMethod("CreateDelegate", types); method = new DynamicMethod("CreateDelegate", typeof(Delegate), types); method.DefineParameter(1, ParameterAttributes.In, "delegateType"); method.DefineParameter(2, ParameterAttributes.In, "target"); method.DefineParameter(3, ParameterAttributes.In, "methodName"); iLGenerator = method.GetILGenerator(5); iLGenerator.Emit(OpCodes.Ldarg_0); iLGenerator.Emit(OpCodes.Ldarg_1); iLGenerator.Emit(OpCodes.Ldarg_2); iLGenerator.EmitCall(OpCodes.Call, methodInfo, null); iLGenerator.Emit(OpCodes.Ret); s_CreateDelegate2 = (CreateDelegate2Delegate) method.CreateDelegate(typeof(CreateDelegate2Delegate)); types = new Type[] { typeof(Type), typeof(object[]) }; methodInfo = typeof(Activator).GetMethod("CreateInstance", types); method = new DynamicMethod("CreateInstance", typeof(object), types); method.DefineParameter(1, ParameterAttributes.In, "type"); method.DefineParameter(2, ParameterAttributes.In, "arguments"); iLGenerator = method.GetILGenerator(4); iLGenerator.Emit(OpCodes.Ldarg_0); iLGenerator.Emit(OpCodes.Ldarg_1); iLGenerator.EmitCall(OpCodes.Call, methodInfo, null); iLGenerator.Emit(OpCodes.Ret); s_CreateInstance = (CreateInstanceDelegate) method.CreateDelegate(typeof(CreateInstanceDelegate)); types = new Type[] { typeof(object), typeof(object[]) }; Type[] parameterTypes = new Type[] { typeof(MethodInfo), typeof(object), typeof(object[]) }; methodInfo = typeof(MethodInfo).GetMethod("Invoke", types); method = new DynamicMethod("InvokeMethod", typeof(object), parameterTypes); method.DefineParameter(1, ParameterAttributes.In, "method"); method.DefineParameter(2, ParameterAttributes.In, "instance"); method.DefineParameter(3, ParameterAttributes.In, "args"); iLGenerator = method.GetILGenerator(5); iLGenerator.Emit(OpCodes.Ldarg_0); iLGenerator.Emit(OpCodes.Ldarg_1); iLGenerator.Emit(OpCodes.Ldarg_2); iLGenerator.EmitCall(OpCodes.Callvirt, methodInfo, null); iLGenerator.Emit(OpCodes.Ret); s_InvokeMethod = (InvokeMethodDelegate) method.CreateDelegate(typeof(InvokeMethodDelegate)); }
public static DynamicMethod GenerateDynamicSerializerStub(Type type) { var dm = new DynamicMethod("Serialize", null, new Type[] { typeof(IoBuffer), type }, typeof(Serializer), true); dm.DefineParameter(1, ParameterAttributes.None, "stream"); dm.DefineParameter(2, ParameterAttributes.None, "value"); return dm; }
public static DynamicMethod GenerateDynamicDeserializeInvokerStub() { var dm = new DynamicMethod(string.Empty, null, new Type[] { typeof(Stream), typeof(object).MakeByRefType(), typeof(ObjectList) }, typeof(Serializer), true); dm.DefineParameter(1, ParameterAttributes.None, "stream"); dm.DefineParameter(2, ParameterAttributes.Out, "value"); dm.DefineParameter(3, ParameterAttributes.None, "objList"); return dm; }
private Delegate CreateCompatibleListener(EventInfo eventInfo) { string methodName = eventInfo.Name + "_handler_"; var delegateType = eventInfo.EventHandlerType; var invokeMethod = delegateType.GetMethod("Invoke"); if (invokeMethod.ReturnType != typeof(void)) throw new NotSupportedException(); var delegateParameters = invokeMethod.GetParameters(); var args = new List<Type> {typeof (EventListener)}; args.AddRange(delegateParameters.Select(p=>p.ParameterType)); var dm = new DynamicMethod(methodName, typeof (void), args.ToArray(), typeof(EventListener)); var generator = dm.GetILGenerator(256); generator.DeclareLocal(typeof (Dictionary<string, object>)); generator.Emit(OpCodes.Newobj, _dictionaryCto); generator.Emit(OpCodes.Stloc_0); var savedArgsField = GetType().GetField("_savedArgs", BindingFlags.Instance | BindingFlags.NonPublic); Debug.Assert(savedArgsField != null); // add the arguments received to the dictionary for (var idx = 0; idx < delegateParameters.Length; idx++) { var parameter = delegateParameters[idx]; dm.DefineParameter(idx + 2, ParameterAttributes.In, parameter.Name); generator.Emit(OpCodes.Ldloc_0); generator.Emit(OpCodes.Ldstr, parameter.Name); generator.Emit(OpCodes.Ldarg, idx + 1); if (parameter.ParameterType.IsValueType) { generator.Emit(OpCodes.Box, parameter.ParameterType); } generator.Emit(OpCodes.Callvirt, _dictionarySetItemMethod); } // add the dictionary to the list generator.Emit(OpCodes.Ldarg_0); generator.Emit(OpCodes.Ldfld, savedArgsField); generator.Emit(OpCodes.Ldloc_0); generator.Emit(OpCodes.Callvirt, _listAddMethod); generator.Emit(OpCodes.Ret); return dm.CreateDelegate(delegateType, this); }
/// <summary> /// Creates an ITile instance using the defaul Terraria.Tile constructor. /// /// This cannot be performed at compile time using the OTAPI solution as /// Terraria.Tile does not implement ITile at compile time. /// </summary> /// <returns>ITile instance</returns> private static Func<OTAPI.Tile.ITile, OTAPI.Tile.ITile> GetNewTileFromMethod() { var dm = new DynamicMethod("GetTileFromCollection", typeof(OTAPI.Tile.ITile), new[] { typeof(OTAPI.Tile.ITile) }); dm.DefineParameter(0, System.Reflection.ParameterAttributes.In, "copy"); var processor = dm.GetILGenerator(); processor.Emit(OpCodes.Ldarg_0); processor.Emit(OpCodes.Newobj, typeof(global::Terraria.Tile).GetConstructors().Single(x => x.GetParameters().Length == 1)); processor.Emit(OpCodes.Ret); return (Func<OTAPI.Tile.ITile, OTAPI.Tile.ITile>)dm.CreateDelegate(typeof(Func<OTAPI.Tile.ITile, OTAPI.Tile.ITile>)); }
/// <summary> /// Wrap the parsed the function into a delegate of the specified type. The delegate must accept /// the parameters defined in the parameters collection. The order of parameters is respected as defined /// in parameters collection. /// <br/> /// The function must accept a dictionary of strings and doubles as input. The values passed to the /// wrapping function will be passed to the function using the dictionary. The keys in the dictionary /// are the names of the parameters of the wrapping function. /// </summary> /// <param name="parameters">The required parameters of the wrapping function delegate.</param> /// <param name="function">The function that must be wrapped.</param> /// <returns>A delegate instance of the required type.</returns> public Delegate Wrap(IEnumerable<Jace.Execution.ParameterInfo> parameters, Func<Dictionary<string, double>, double> function) { Jace.Execution.ParameterInfo[] parameterArray = parameters.ToArray(); Type[] parameterTypes = GetParameterTypes(parameterArray); Type delegateType = GetDelegateType(parameterArray); DynamicMethod method = new DynamicMethod("FuncWrapperMethod", typeof(double), parameterTypes, typeof(FuncAdapterArguments)); ILGenerator generator = method.GetILGenerator(); GenerateMethodBody(generator, parameterArray, function); for (int i = 0; i < parameterArray.Length; i++) { Jace.Execution.ParameterInfo parameter = parameterArray[i]; method.DefineParameter((i + 1), ParameterAttributes.In, parameter.Name); } return method.CreateDelegate(delegateType, new FuncAdapterArguments(function)); }
static void DynamicCreateMethod() { // Create an array that specifies the types of the parameters // of the dynamic method. This dynamic method has a String // parameter and an Integer parameter. Type[] helloArgs = { typeof(string), typeof(int) }; // Create a dynamic method with the name "Hello", a return type // of Integer, and two parameters whose types are specified by // the array helloArgs. Create the method in the module that // defines the String class. DynamicMethod hello = new DynamicMethod("Hello", typeof(int), helloArgs, typeof(string).Module); // Create an array that specifies the parameter types of the // overload of Console.WriteLine to be used in Hello. Type[] writeStringArgs = { typeof(string) }; // Get the overload of Console.WriteLine that has one String parameter. MethodInfo writeString = typeof(Console).GetMethod("WriteLine", writeStringArgs); // Get an ILGenerator and emit a body for the dynamic method, // using a stream size larger than the IL that will be emitted. ILGenerator il = hello.GetILGenerator(256); // Load the first argument, which is a string, onto the stack. il.Emit(OpCodes.Ldarg_0); // Call the overload of Console.WriteLine that prints a string. il.EmitCall(OpCodes.Call, writeString, null); // The Hello method returns the value of the second argument; // to do this, load the onto the stack and return. il.Emit(OpCodes.Ldarg_1); il.Emit(OpCodes.Ret); // Display MethodAttributes for the dynamic method, set when // the dynamic method was created. Console.WriteLine("\r\nMethod Attributes: {0}", hello.Attributes); // Display the calling convention of the dynamic method, set when the dynamic method was created. Console.WriteLine("\r\nCalling convention: {0}", hello.CallingConvention); // Display the declaring type, which is always null for dynamic methods. if (hello.DeclaringType == null) Console.WriteLine("\r\nDeclaringType is always null for dynamic methods."); else Console.WriteLine("DeclaringType: {0}", hello.DeclaringType); // Display the default value for InitLocals. if (hello.InitLocals) Console.Write("\r\nThis method contains verifiable code."); else Console.Write("\r\nThis method contains unverifiable code."); Console.WriteLine(" (InitLocals = {0})", hello.InitLocals); // Display the module specified when the dynamic method was created. Console.WriteLine("\r\nModule: {0}", hello.Module); // Display the name specified when the dynamic method was created. // Note that the name can be blank. Console.WriteLine("\r\nName: {0}", hello.Name); // For dynamic methods, the reflected type is always null. if (hello.ReflectedType == null) Console.WriteLine("\r\nReflectedType is null."); else Console.WriteLine("\r\nReflectedType: {0}", hello.ReflectedType); if (hello.ReturnParameter == null) Console.WriteLine("\r\nMethod has no return parameter."); else Console.WriteLine("\r\nReturn parameter: {0}", hello.ReturnParameter); // If the method has no return type, ReturnType is System.Void. Console.WriteLine("\r\nReturn type: {0}", hello.ReturnType); // ReturnTypeCustomAttributes returns an ICustomeAttributeProvider // that can be used to enumerate the custom attributes of the // return value. At present, there is no way to set such custom // attributes, so the list is empty. if (hello.ReturnType == typeof(void)) Console.WriteLine("The method has no return type."); else { ICustomAttributeProvider caProvider = hello.ReturnTypeCustomAttributes; object[] returnAttributes = caProvider.GetCustomAttributes(true); if (returnAttributes.Length == 0) Console.WriteLine("\r\nThe return type has no custom attributes."); else { Console.WriteLine("\r\nThe return type has the following custom attributes:"); foreach (object attr in returnAttributes) { Console.WriteLine("\t{0}", attr.ToString()); } } } Console.WriteLine("\r\nToString: {0}", hello.ToString()); // Add parameter information to the dynamic method. (This is not // necessary, but can be useful for debugging.) For each parameter, // identified by position, supply the parameter attributes and a // parameter name. ParameterBuilder parameter1 = hello.DefineParameter(1,ParameterAttributes.In,"message"); ParameterBuilder parameter2 = hello.DefineParameter(2,ParameterAttributes.In,"valueToReturn"); // Display parameter information. ParameterInfo[] parameters = hello.GetParameters(); Console.WriteLine("\r\nParameters: name, type, ParameterAttributes"); foreach (ParameterInfo p in parameters) { Console.WriteLine("\t{0}, {1}, {2}", p.Name, p.ParameterType, p.Attributes); } // Create a delegate that represents the dynamic method. //This action completes the method, and any further attempts to change the method will cause an exception. HelloDelegate hi = (HelloDelegate)hello.CreateDelegate(typeof(HelloDelegate)); // Use the delegate to execute the dynamic method. Console.WriteLine("\r\nUse the delegate to execute the dynamic method:"); int retval = hi("\r\nHello, World!", 42); Console.WriteLine("Invoking delegate hi(\"Hello, World!\", 42) returned: " + retval); // Execute it again, with different arguments. retval = hi("\r\nHi, Mom!", 5280); Console.WriteLine("Invoking delegate hi(\"Hi, Mom!\", 5280) returned: " + retval); Console.WriteLine("\r\nUse the Invoke method to execute the dynamic method:"); // Create an array of arguments to use with the Invoke method. object[] invokeArgs = { "\r\nHello, World!", 42 }; // Invoke the dynamic method using the arguments. This is much // slower than using the delegate, because you must create an // array to contain the arguments, and value-type arguments // must be boxed. object objRet = hello.Invoke(null, BindingFlags.ExactBinding, null, invokeArgs, new System.Globalization.CultureInfo("en-us")); Console.WriteLine("hello.Invoke returned: " + objRet); }
private static CommandInvocationDelegate CreateInvokeDelegate(MethodInfo targetMethod) { var method = new DynamicMethod("CommandCache.Invoke", typeof(void), new [] { typeof(object), typeof(object) }, true); method.DefineParameter(1, ParameterAttributes.None, "target"); method.DefineParameter(2, ParameterAttributes.None, "sender"); var ilGenerator = method.GetILGenerator(); ilGenerator.Emit(OpCodes.Ldarg_0); ilGenerator.Emit(OpCodes.Isinst, targetMethod.DeclaringType); ilGenerator.Emit(OpCodes.Ldarg_1); ilGenerator.Emit(OpCodes.Tailcall); ilGenerator.Emit(OpCodes.Callvirt, targetMethod); // callvirt will check for null references ilGenerator.Emit(OpCodes.Ret); return method.CreateDelegate(typeof(CommandInvocationDelegate)) as CommandInvocationDelegate; }
static Dictionary<Type, TypeData> GenerateDynamic(Type[] types, Dictionary<Type, TypeData> typeMap) { Dictionary<Type, TypeData> _map = GenerateTypeData(types); Dictionary<Type, TypeData> map = typeMap.Concat(_map).ToDictionary(kvp => kvp.Key, kvp => kvp.Value); var nonStaticTypes = map.Where(kvp => kvp.Value.IsDynamic).Select(kvp => kvp.Key); /* generate stubs */ foreach (var type in nonStaticTypes) { var s_dm = SerializerCodegen.GenerateDynamicSerializerStub(type); var typeData = map[type]; typeData.WriterMethodInfo = s_dm; typeData.WriterILGen = s_dm.GetILGenerator(); var d_dm = DeserializerCodegen.GenerateDynamicDeserializerStub(type); typeData.ReaderMethodInfo = d_dm; typeData.ReaderILGen = d_dm.GetILGenerator(); } #if GENERATE_SWITCH var serializerSwitchMethod = new DynamicMethod("SerializerSwitch", null, new Type[] { typeof(Stream), typeof(object), typeof(ObjectList) }, typeof(Serializer), true); serializerSwitchMethod.DefineParameter(1, ParameterAttributes.None, "stream"); serializerSwitchMethod.DefineParameter(2, ParameterAttributes.None, "value"); serializerSwitchMethod.DefineParameter(3, ParameterAttributes.None, "objList"); var serializerSwitchMethodInfo = serializerSwitchMethod; var deserializerSwitchMethod = new DynamicMethod("DeserializerSwitch", null, new Type[] { typeof(Stream), typeof(object).MakeByRefType(), typeof(ObjectList) }, typeof(Serializer), true); deserializerSwitchMethod.DefineParameter(1, ParameterAttributes.None, "stream"); deserializerSwitchMethod.DefineParameter(2, ParameterAttributes.Out, "value"); deserializerSwitchMethod.DefineParameter(3, ParameterAttributes.Out, "objList"); var deserializerSwitchMethodInfo = deserializerSwitchMethod; var ctx = new CodeGenContext(map, serializerSwitchMethodInfo, deserializerSwitchMethodInfo); #else var ctx = new CodeGenContext(map); #endif /* generate bodies */ foreach (var type in nonStaticTypes) { SerializerCodegen.GenerateSerializerBody(ctx, type, map[type].WriterILGen); DeserializerCodegen.GenerateDeserializerBody(ctx, type, map[type].ReaderILGen); } #if GENERATE_SWITCH var ilGen = serializerSwitchMethod.GetILGenerator(); SerializerCodegen.GenerateSerializerSwitch(ctx, ilGen, map); s_serializerSwitch = (SerializerSwitch)serializerSwitchMethod.CreateDelegate(typeof(SerializerSwitch)); ilGen = deserializerSwitchMethod.GetILGenerator(); DeserializerCodegen.GenerateDeserializerSwitch(ctx, ilGen, map); s_deserializerSwitch = (DeserializerSwitch)deserializerSwitchMethod.CreateDelegate(typeof(DeserializerSwitch)); #else foreach (var kvp in map) { kvp.Value.serializer = GetSerializationInvoker(null, kvp.Value.WriterMethodInfo, kvp.Key, (int)kvp.Value.TypeID); kvp.Value.deserializer = GetDeserializationInvoker(null, kvp.Value.ReaderMethodInfo, kvp.Key, (int)kvp.Value.TypeID); } #endif return map; }
static void GenerateDynamic(Dictionary<Type, TypeData> map) { /* generate stubs */ foreach (var kvp in map) { var type = kvp.Key; var td = kvp.Value; if (!td.IsGenerated) continue; var writerDm = SerializerCodegen.GenerateDynamicSerializerStub(type); td.WriterMethodInfo = writerDm; td.WriterILGen = writerDm.GetILGenerator(); var readerDm = DeserializerCodegen.GenerateDynamicDeserializerStub(type); td.ReaderMethodInfo = readerDm; td.ReaderILGen = readerDm.GetILGenerator(); } var serializerSwitchMethod = new DynamicMethod("SerializerSwitch", null, new Type[] { typeof(Stream), typeof(object) }, typeof(Serializer), true); serializerSwitchMethod.DefineParameter(1, ParameterAttributes.None, "stream"); serializerSwitchMethod.DefineParameter(2, ParameterAttributes.None, "value"); var serializerSwitchMethodInfo = serializerSwitchMethod; var deserializerSwitchMethod = new DynamicMethod("DeserializerSwitch", null, new Type[] { typeof(Stream), typeof(object).MakeByRefType() }, typeof(Serializer), true); deserializerSwitchMethod.DefineParameter(1, ParameterAttributes.None, "stream"); deserializerSwitchMethod.DefineParameter(2, ParameterAttributes.Out, "value"); var deserializerSwitchMethodInfo = deserializerSwitchMethod; var ctx = new CodeGenContext(map, serializerSwitchMethodInfo, deserializerSwitchMethodInfo); /* generate bodies */ foreach (var kvp in map) { var type = kvp.Key; var td = kvp.Value; if (!td.IsGenerated) continue; td.TypeSerializer.GenerateWriterMethod(type, ctx, td.WriterILGen); td.TypeSerializer.GenerateReaderMethod(type, ctx, td.ReaderILGen); } var ilGen = serializerSwitchMethod.GetILGenerator(); SerializerCodegen.GenerateSerializerSwitch(ctx, ilGen, map); s_serializerSwitch = (SerializerSwitch)serializerSwitchMethod.CreateDelegate(typeof(SerializerSwitch)); ilGen = deserializerSwitchMethod.GetILGenerator(); DeserializerCodegen.GenerateDeserializerSwitch(ctx, ilGen, map); s_deserializerSwitch = (DeserializerSwitch)deserializerSwitchMethod.CreateDelegate(typeof(DeserializerSwitch)); }
private Action<object, object> CreateSetAction() { if (null == this.SetMethod) { throw new InvalidOperationException( string.Format("Cannot find a writable \"{0}\" from the type \"{1}\".", this.PropertyName, this.TargetType.FullName)); } DynamicMethod method = new DynamicMethod("SetValue", null, new Type[] { typeof(object), typeof(object) }); ILGenerator ilGenerator = method.GetILGenerator(); Type paramType = this.SetMethod.GetParameters()[0].ParameterType; ilGenerator.DeclareLocal(paramType); ilGenerator.Emit(OpCodes.Ldarg_0); ilGenerator.Emit(OpCodes.Castclass, this.TargetType); ilGenerator.Emit(OpCodes.Ldarg_1); if (paramType.IsValueType) { ilGenerator.Emit(OpCodes.Unbox, paramType); if (valueTpyeOpCodes.ContainsKey(paramType)) { OpCode load = (OpCode)valueTpyeOpCodes[paramType]; ilGenerator.Emit(load); } else { ilGenerator.Emit(OpCodes.Ldobj, paramType); } } else { ilGenerator.Emit(OpCodes.Castclass, paramType); } ilGenerator.EmitCall(OpCodes.Callvirt, this.SetMethod, null); ilGenerator.Emit(OpCodes.Ret); method.DefineParameter(1, ParameterAttributes.In, "obj"); method.DefineParameter(2, ParameterAttributes.In, "value"); return (Action<object, object>)method.CreateDelegate(typeof(Action<object, object>)); }
/// <summary> /// Creates a dynamic method for testing units. All units take the same parameters. /// </summary> /// <param name="runner">The runner.</param> /// <returns></returns> public static DynamicUnitTiming CreateTestMethod(MethodRunner runner) { // Create the basic signature. var signature = new[] { typeof(object), typeof(int) }; var method = new DynamicMethod("DynamicUnitTest" + (counter++), typeof(void), signature, typeof(MethodRunnerCompiler)); // Create an IL generator for the method body. ILGenerator il = method.GetILGenerator(256); // We determine what type of IL code we generate based on the singleton type. if (runner.TimingAttribute.Singleton) { // Create a single call version. CreateSingleton(runner, il); } else { // Create the local variables. il.DeclareLocal(typeof(int)); il.DeclareLocal(typeof(bool)); // Declare the labels. Label loopLabel = il.DefineLabel(); Label topLabel = il.DefineLabel(); // Assign zero to the count variable. il.Emit(OpCodes.Ldc_I4_0); il.Emit(OpCodes.Stloc_0); il.Emit(OpCodes.Br_S, loopLabel); // Build up the actual execution. il.MarkLabel(topLabel); // Figure out how to call this method. il.Emit(OpCodes.Ldarg_0); switch (runner.MethodSignature) { case MethodSignature.CountInt32: il.Emit(OpCodes.Ldloc_0); break; case MethodSignature.CountIterationInt32: il.Emit(OpCodes.Ldloc_0); il.Emit(OpCodes.Ldarg_1); break; } il.EmitCall(OpCodes.Call, runner.Method, null); // Increment the counter. il.Emit(OpCodes.Ldloc_0); il.Emit(OpCodes.Ldc_I4_1); il.Emit(OpCodes.Add); il.Emit(OpCodes.Stloc_0); // Create the loop test. This loads the count variable and compares // it to the second argument (iterations). il.MarkLabel(loopLabel); il.Emit(OpCodes.Ldloc_0); il.Emit(OpCodes.Ldarg_1); il.Emit(OpCodes.Clt); il.Emit(OpCodes.Stloc_1); il.Emit(OpCodes.Ldloc_1); il.Emit(OpCodes.Brtrue_S, topLabel); } // Finish up with a return IL. il.Emit(OpCodes.Ret); // Create the paramters. method.DefineParameter(0, ParameterAttributes.In, "target"); method.DefineParameter(1, ParameterAttributes.In, "iteration"); // Create the delegate and return it. return (DynamicUnitTiming) method.CreateDelegate(typeof(DynamicUnitTiming)); }
/// <summary> /// Create DynamicMethod that configures capabilities using System.Web.Configuration.BrowserCapabilitiesFactory (or similar) type. /// </summary> /// <param name="BrowserCapabilitiesFactoryType">Type with ConfigureBrowserCapabilities and ConfigureCustomCapabilities methods.</param> /// <remarks> /// Generated method performs following code: /// { /// var capsFactory = new System.Web.Configuration.BrowserCapabilitiesFactory(); /// capsFactory.ConfigureBrowserCapabilities(headers, browserCaps); /// capsFactory.ConfigureCustomCapabilities(headers, browserCaps); /// } /// </remarks> private static Action<NameValueCollection, HttpBrowserCapabilities> BuildConfigureCapsMethod(Type/*!*/BrowserCapabilitiesFactoryType) { Debug.Assert(BrowserCapabilitiesFactoryType != null); var method_ctor = BrowserCapabilitiesFactoryType.GetConstructor(Type.EmptyTypes); var method_ConfigureBrowserCapabilities = BrowserCapabilitiesFactoryType.GetMethod("ConfigureBrowserCapabilities"); var method_ConfigureCustomCapabilities = BrowserCapabilitiesFactoryType.GetMethod("ConfigureCustomCapabilities"); if (method_ctor == null) throw new InvalidOperationException(string.Format("{0} does not implement .ctor.", BrowserCapabilitiesFactoryType.ToString())); if (method_ConfigureBrowserCapabilities == null) throw new InvalidOperationException(string.Format("{0} does not implement {1}.", BrowserCapabilitiesFactoryType.ToString(), "ConfigureBrowserCapabilities")); if (method_ConfigureCustomCapabilities == null) throw new InvalidOperationException(string.Format("{0} does not implement {1}.", BrowserCapabilitiesFactoryType.ToString(), "ConfigureCustomCapabilities")); var method = new DynamicMethod("<dynamic>.BrowserCapabilitiesFactory", typeof(void), new Type[] { typeof(NameValueCollection), typeof(HttpBrowserCapabilities) }); var il = new PHP.Core.Emit.ILEmitter(method); method.DefineParameter(1, System.Reflection.ParameterAttributes.None, "headers"); method.DefineParameter(2, System.Reflection.ParameterAttributes.None, "browserCaps"); // var capsFactory = new System.Web.Configuration.BrowserCapabilitiesFactory(); var loc_factory = il.DeclareLocal(BrowserCapabilitiesFactoryType); il.Emit(OpCodes.Newobj, method_ctor); il.Stloc(loc_factory); // capsFactory.ConfigureBrowserCapabilities(headers, browserCaps); il.Ldloc(loc_factory); il.Ldarg(0); il.Ldarg(1); il.Emit(OpCodes.Callvirt, method_ConfigureBrowserCapabilities); // capsFactory.ConfigureCustomCapabilities(headers, browserCaps); il.Ldloc(loc_factory); il.Ldarg(0); il.Ldarg(1); il.Emit(OpCodes.Callvirt, method_ConfigureCustomCapabilities); // ret il.Emit(OpCodes.Ret); // done return (Action<NameValueCollection, HttpBrowserCapabilities>)method.CreateDelegate(typeof(Action<NameValueCollection, HttpBrowserCapabilities>)); }
/// <summary> /// Method CreateGetFunction. /// </summary> /// <param name="getMethod">MethodInfo of get method.</param> /// <returns>GetFunction delegate.</returns> private GetFunction<object, object> CreateGetFunction(MethodInfo getMethod) { DynamicMethod method = new DynamicMethod("GetValue", typeof(object), new Type[] { typeof(object) }); ILGenerator ilGenerator = method.GetILGenerator(); ilGenerator.DeclareLocal(typeof(object)); ilGenerator.Emit(OpCodes.Ldarg_0); ilGenerator.Emit(OpCodes.Castclass, this.TargetType); ilGenerator.EmitCall(OpCodes.Call, getMethod, null); if (getMethod.ReturnType.IsValueType) { ilGenerator.Emit(OpCodes.Box, getMethod.ReturnType); } ilGenerator.Emit(OpCodes.Stloc_0); ilGenerator.Emit(OpCodes.Ldloc_0); ilGenerator.Emit(OpCodes.Ret); method.DefineParameter(1, ParameterAttributes.In, "value"); return (GetFunction<object, object>)method.CreateDelegate(typeof(GetFunction<object, object>)); }
public MethodInfo DefineImplementationMethod(string id) { if (id == null) throw new ArgumentNullException("id"); var parameterTypes = new[] { typeof (PFunction), typeof (StackContext), typeof (PValue[]), typeof (PVariable[]), typeof (PValue).MakeByRefType(), typeof (ReturnMode).MakeByRefType(), }; if (MakeAvailableForLinking) { //Create method stub var dm = TargetType.DefineMethod ( id, MethodAttributes.Static | MethodAttributes.Public, typeof (void), parameterTypes); dm.DefineParameter(1, ParameterAttributes.In, "source"); dm.DefineParameter(2, ParameterAttributes.In, "sctx"); dm.DefineParameter(3, ParameterAttributes.In, "args"); dm.DefineParameter(4, ParameterAttributes.In, "sharedVariables"); dm.DefineParameter(5, ParameterAttributes.Out, "result"); dm.DefineParameter(6, ParameterAttributes.Out, "returnMode"); Implementations.Add(id, dm); //Create function field var fb = TargetType.DefineField (_mkFieldName(id), typeof (PFunction), FieldAttributes.Public | FieldAttributes.Static); FunctionFields.Add(id, fb); return dm; } var cilm = new DynamicMethod ( id, typeof (void), parameterTypes, typeof (Runtime)); cilm.DefineParameter(1, ParameterAttributes.In, "source"); cilm.DefineParameter(2, ParameterAttributes.In, "sctx"); cilm.DefineParameter(3, ParameterAttributes.In, "args"); cilm.DefineParameter(4, ParameterAttributes.In, "sharedVariables"); cilm.DefineParameter(5, ParameterAttributes.Out, "result"); Implementations.Add(id, cilm); return cilm; }
/// <summary> /// Compiles the addition from data /// </summary> /// <param name="handlers">Lookup table with functions</param> /// <param name="functions">Table of functions</param> /// <param name="values">Values associated with the functions</param> /// <returns>Addition info</returns> internal static Info From(Dictionary<uint, MethodInfo> handlers, uint[] functions, int[] values) { try { MethodInfo methodInfo; //DynamicMethod method = new DynamicMethod(string.Empty, typeof(void), new Type[] { typeof(AdditionValue).MakeByRefType() }); DynamicMethod method = new DynamicMethod(string.Empty, MethodAttributes.Public | MethodAttributes.Static, CallingConventions.Standard, typeof(void), new Type[] { typeof(AdditionValue).MakeByRefType() }, typeof(Additions).Module, false); method.DefineParameter(1, ParameterAttributes.Out, "test"); ILGenerator ilgen = method.GetILGenerator(); for (int i = 0; i < functions.Length; i++) { if (functions[i] > 0) { if (handlers.TryGetValue(functions[i], out methodInfo) && methodInfo != null) { //Parse additionValue by reference ilgen.Emit(OpCodes.Ldarg_0, 0); //Hardcode integer ilgen.Emit(OpCodes.Ldc_I4, values[i]); //Call method ilgen.Emit(OpCodes.Call, methodInfo); } } } //No values on the stack and return ilgen.Emit(OpCodes.Ret); return new Info(method); } catch (Exception e) { HostContext.Current.AddUnhandeldException(e); return null; } }
/// <summary> /// Method CreateSetAction. /// </summary> /// <param name="setMethod">MethodInfo of set method.</param> /// <returns>SetAction delegate.</returns> private SetAction<object, object> CreateSetAction(MethodInfo setMethod) { Type paramType = setMethod.GetParameters()[0].ParameterType; DynamicMethod method = new DynamicMethod("SetValue", null, new Type[] { typeof(object), typeof(object) }); ILGenerator ilGenerator = method.GetILGenerator(); ilGenerator.DeclareLocal(paramType); ilGenerator.Emit(OpCodes.Ldarg_0); ilGenerator.Emit(OpCodes.Castclass, this.TargetType); ilGenerator.Emit(OpCodes.Ldarg_1); if (paramType.IsValueType) { ilGenerator.Emit(OpCodes.Unbox, paramType); if (ValueTypeOpCodeDictionary.ContainsKey(paramType)) { OpCode load = (OpCode)ValueTypeOpCodeDictionary[paramType]; ilGenerator.Emit(load); } else { ilGenerator.Emit(OpCodes.Ldobj, paramType); } } else { ilGenerator.Emit(OpCodes.Castclass, paramType); } ilGenerator.EmitCall(OpCodes.Callvirt, setMethod, null); ilGenerator.Emit(OpCodes.Ret); method.DefineParameter(1, ParameterAttributes.In, "obj"); method.DefineParameter(2, ParameterAttributes.In, "value"); return (SetAction<object, object>)method.CreateDelegate(typeof(SetAction<object, object>)); }
private static MethodInfo WrapMethod(MethodInfo method) { Type returnValueType; bool needsWrapper; if (LP64) return method; // Do not wrap the method in 64 bits mode. needsWrapper = (returnValueType = GetCompatibleType(method.ReturnType)) != method.ReturnType; // Prospection only. Do not create a new parameter array now… var originalParameters = method.GetParameters(); // We can't avoid this memory loss anyway for (int i = 0; i < originalParameters.Length; i++) needsWrapper = GetCompatibleType(originalParameters[i].ParameterType) != originalParameters[i].ParameterType || needsWrapper; // In most cases, we won't need a wrapper, and everything will stop there. if (!needsWrapper) return method; // Create the new parameter type array var newParameterTypes = new Type[originalParameters.Length]; for (int i = 0; i < originalParameters.Length; i++) newParameterTypes[i] = GetCompatibleType(originalParameters[i].ParameterType); // Create the new method var dynamicMethod = new DynamicMethod("Wrapper." + method.Name, returnValueType, newParameterTypes, method.DeclaringType, false); var ilGenerator = dynamicMethod.GetILGenerator(); dynamicMethod.DefineParameter(0, method.ReturnParameter.Attributes, method.ReturnParameter.Name); for (int i = 0; i < originalParameters.Length; i++) { var originalParameter = originalParameters[i]; var newType = newParameterTypes[i]; dynamicMethod.DefineParameter(i + 1, originalParameter.Attributes, originalParameter.Name); switch (i) { case 0: ilGenerator.Emit(OpCodes.Ldarg_0); break; case 1: ilGenerator.Emit(OpCodes.Ldarg_1); break; case 2: ilGenerator.Emit(OpCodes.Ldarg_2); break; case 3: ilGenerator.Emit(OpCodes.Ldarg_3); break; default: if (i < 256) ilGenerator.Emit(OpCodes.Ldarg_S, (byte)i); else ilGenerator.Emit(OpCodes.Ldarg, unchecked((short)i)); break; } if (newType == originalParameter.ParameterType) continue; else if (newType == typeof(float)) ilGenerator.Emit(OpCodes.Conv_R8); else if (newType == typeof(RectangleF)) ilGenerator.Emit(OpCodes.Call, rectangle32To64); else if (newType == typeof(PointF)) ilGenerator.Emit(OpCodes.Call, point32To64); else if (newType == typeof(SizeF)) ilGenerator.Emit(OpCodes.Call, size32To64); else throw new InvalidOperationException(); } ilGenerator.Emit(OpCodes.Call, method); if (returnValueType != method.ReturnType) { if (returnValueType == typeof(float)) ilGenerator.Emit(OpCodes.Conv_R4); else if (returnValueType == typeof(RectangleF)) ilGenerator.Emit(OpCodes.Call, rectangle64To32); else if (returnValueType == typeof(PointF)) ilGenerator.Emit(OpCodes.Call, point64To32); else if (returnValueType == typeof(SizeF)) ilGenerator.Emit(OpCodes.Call, size64To32); } ilGenerator.Emit(OpCodes.Ret); wrapperMethods.Add(dynamicMethod); return dynamicMethod; }
/// <summary> /// Define a method in this module with the specified name and parameters. /// </summary> public MethodInfo DefineMethod(string name, Type returnType, Type[] paramTypes, string[] paramNames, XmlILMethodAttributes xmlAttrs) { MethodInfo methResult; int uniqueId = 1; string nameOrig = name; Type[] paramTypesNew; bool isRaw = (xmlAttrs & XmlILMethodAttributes.Raw) != 0; // Ensure that name is unique while (this.methods[name] != null) { // Add unique id to end of name in order to make it unique within this module uniqueId++; name = nameOrig + " (" + uniqueId + ")"; } if (!isRaw) { // XmlQueryRuntime is always 0th parameter paramTypesNew = new Type[paramTypes.Length + 1]; paramTypesNew[0] = typeof(XmlQueryRuntime); Array.Copy(paramTypes, 0, paramTypesNew, 1, paramTypes.Length); paramTypes = paramTypesNew; } if (!this.useLRE) { MethodBuilder methBldr; methBldr = this.typeBldr.DefineMethod( name, MethodAttributes.Private | MethodAttributes.Static, returnType, paramTypes); if (emitSymbols && (xmlAttrs & XmlILMethodAttributes.NonUser) != 0) { // Add DebuggerStepThroughAttribute and DebuggerNonUserCodeAttribute to non-user methods so that debugging is a better experience methBldr.SetCustomAttribute(new CustomAttributeBuilder(XmlILConstructors.StepThrough, new object[] {})); methBldr.SetCustomAttribute(new CustomAttributeBuilder(XmlILConstructors.NonUserCode, new object[] {})); } if (!isRaw) methBldr.DefineParameter(1, ParameterAttributes.None, RuntimeName); for (int i = 0; i < paramNames.Length; i++) { if (paramNames[i] != null && paramNames[i].Length != 0) methBldr.DefineParameter(i + (isRaw ? 1 : 2), ParameterAttributes.None, paramNames[i]); } methResult = methBldr; } else { DynamicMethod methDyn = new DynamicMethod(name, returnType, paramTypes, LREModule); methDyn.InitLocals = true; if (!isRaw) methDyn.DefineParameter(1, ParameterAttributes.None, RuntimeName); for (int i = 0; i < paramNames.Length; i++) { if (paramNames[i] != null && paramNames[i].Length != 0) methDyn.DefineParameter(i + (isRaw ? 1 : 2), ParameterAttributes.None, paramNames[i]); } methResult = methDyn; } // Index method by name this.methods[name] = methResult; return methResult; }
/// <summary> /// Coerces a source delegate to a target delegate type by casting the source delegate's /// parameters individually to the target delegate type's parameter types. /// </summary> /// <param name="targetDelegateType">The target delegate type.</param> /// <param name="sourceDelegate">The source delegate, or null.</param> /// <returns>The target delegate, or null if the source delegate was null.</returns> /// <exception cref="ArgumentNullException">Thrown if <paramref name="targetDelegateType"/> /// is null.</exception> /// <exception cref="ArgumentException">Thrown if <paramref name="targetDelegateType"/> /// is not a delegate type.</exception> /// <exception cref="InvalidOperationException">Thrown if the source and target delegate types are /// incompatible such as if they have different numbers of parameters or a different /// composition of out/ref parameters.</exception> public static Delegate CoerceDelegate(Type targetDelegateType, Delegate sourceDelegate) { if (targetDelegateType == null) throw new ArgumentNullException("targetDelegateType"); if (sourceDelegate == null) return null; if (!typeof(Delegate).IsAssignableFrom(targetDelegateType)) throw new ArgumentException("Target type must be a Delegate type.", "targetDelegateType"); Type sourceDelegateType = sourceDelegate.GetType(); if (targetDelegateType.IsAssignableFrom(sourceDelegateType)) return sourceDelegate; MethodInfo targetInvokeMethod, sourceInvokeMethod; Type targetReturnType, sourceReturnType; ParameterInfo[] targetParameters, sourceParameters; GetDelegateTypeInfo(targetDelegateType, out targetInvokeMethod, out targetReturnType, out targetParameters); GetDelegateTypeInfo(sourceDelegateType, out sourceInvokeMethod, out sourceReturnType, out sourceParameters); if (!IsDelegateReturnTypeCompatible(targetReturnType, sourceReturnType)) throw new InvalidOperationException("The delegate signatures cannot be coerced because they have incompatible return types."); if (!IsDelegateParameterListCompatible(targetParameters, sourceParameters)) throw new InvalidOperationException("The delegate signatures cannot be coerced because they have incompatible parameters."); // Recreating the method each time is not very efficient but this function is not intended // to be used very often. // TODO: Determine whether it would really be worth caching the method. Type[] invokerParameterTypes = new Type[targetParameters.Length + 1]; invokerParameterTypes[0] = sourceDelegateType; for (int i = 0; i < targetParameters.Length; i++) invokerParameterTypes[i + 1] = targetParameters[i].ParameterType; DynamicMethod method = new DynamicMethod("DelegateInvoker", targetReturnType, invokerParameterTypes, true); method.DefineParameter(0, ParameterAttributes.None, "__sourceDelegate"); for (int i = 0; i < targetParameters.Length; i++) method.DefineParameter(i + 1, targetParameters[i].Attributes, targetParameters[i].Name); ILGenerator gen = method.GetILGenerator(); // Load the source delegate onto the top of the evaluation stack. gen.Emit(OpCodes.Ldarg_0); // Load the arguments onto the evaluation stack. LocalBuilder[] locals = null; for (int i = 0; i < targetParameters.Length; i++) { if (IsOutputParameter(sourceParameters[i])) { if (locals == null) locals = new LocalBuilder[targetParameters.Length]; locals[i] = gen.DeclareLocal(sourceParameters[i].ParameterType.GetElementType()); if (IsInputParameter(sourceParameters[i])) { gen.Emit(OpCodes.Ldarg, i + 1); EmitLoadIndirect(gen, targetParameters[i].ParameterType.GetElementType()); EmitConversion(gen, sourceParameters[i].ParameterType.GetElementType(), targetParameters[i].ParameterType.GetElementType()); gen.Emit(OpCodes.Stloc, locals[i].LocalIndex); } gen.Emit(OpCodes.Ldloca, locals[i].LocalIndex); } else { gen.Emit(OpCodes.Ldarg, i + 1); EmitConversion(gen, sourceParameters[i].ParameterType, targetParameters[i].ParameterType); } } // Call the source delegate's Invoke method. gen.EmitCall(OpCodes.Callvirt, sourceInvokeMethod, null); // Store the resulting output parameters. for (int i = 0; i < targetParameters.Length; i++) { if (IsOutputParameter(sourceParameters[i])) { gen.Emit(OpCodes.Ldarg, i + 1); gen.Emit(OpCodes.Ldloc, locals[i].LocalIndex); EmitConversion(gen, targetParameters[i].ParameterType.GetElementType(), sourceParameters[i].ParameterType.GetElementType()); EmitStoreIndirect(gen, targetParameters[i].ParameterType.GetElementType()); } } // Return the result, if any. if (targetReturnType != null) EmitConversion(gen, targetReturnType, sourceReturnType); gen.Emit(OpCodes.Ret); return method.CreateDelegate(targetDelegateType, sourceDelegate); }
static Dictionary<Type, ushort> GenerateDynamic(Type[] types) { Dictionary<Type, TypeData> map = GenerateTypeData(types); var nonStaticTypes = map.Where(kvp => kvp.Value.IsDynamic).Select(kvp => kvp.Key); /* generate stubs */ foreach (var type in nonStaticTypes) { var dm = GenerateDynamicSerializerStub(type); map[type].WriterMethodInfo = dm; map[type].WriterILGen = dm.GetILGenerator(); } foreach (var type in nonStaticTypes) { var dm = GenerateDynamicDeserializerStub(type); map[type].ReaderMethodInfo = dm; map[type].ReaderILGen = dm.GetILGenerator(); } var serializerSwitchMethod = new DynamicMethod("SerializerSwitch", null, new Type[] { typeof(Stream), typeof(object) }, typeof(Serializer), true); serializerSwitchMethod.DefineParameter(1, ParameterAttributes.None, "stream"); serializerSwitchMethod.DefineParameter(2, ParameterAttributes.None, "value"); var serializerSwitchMethodInfo = serializerSwitchMethod; var deserializerSwitchMethod = new DynamicMethod("DeserializerSwitch", null, new Type[] { typeof(Stream), typeof(object).MakeByRefType() }, typeof(Serializer), true); deserializerSwitchMethod.DefineParameter(1, ParameterAttributes.None, "stream"); deserializerSwitchMethod.DefineParameter(2, ParameterAttributes.Out, "value"); var deserializerSwitchMethodInfo = deserializerSwitchMethod; var ctx = new CodeGenContext(map, serializerSwitchMethodInfo, deserializerSwitchMethodInfo); /* generate bodies */ foreach (var type in nonStaticTypes) GenerateSerializerBody(ctx, type, map[type].WriterILGen); foreach (var type in nonStaticTypes) GenerateDeserializerBody(ctx, type, map[type].ReaderILGen); var ilGen = serializerSwitchMethod.GetILGenerator(); GenerateSerializerSwitch(ctx, ilGen, map); s_serializerSwitch = (SerializerSwitch)serializerSwitchMethod.CreateDelegate(typeof(SerializerSwitch)); ilGen = deserializerSwitchMethod.GetILGenerator(); GenerateDeserializerSwitch(ctx, ilGen, map); s_deserializerSwitch = (DeserializerSwitch)deserializerSwitchMethod.CreateDelegate(typeof(DeserializerSwitch)); return map.ToDictionary(kvp => kvp.Key, kvp => kvp.Value.TypeID); }
private Func<object, object> CreateGetFunction() { if (null == this.GetMethod) { throw new InvalidOperationException( string.Format("Cannot find a readable \"{0}\" from the type \"{1}\".", this.PropertyName, this.TargetType.FullName)); } DynamicMethod method = new DynamicMethod("GetValue", typeof(object), new Type[] { typeof(object) }); ILGenerator ilGenerator = method.GetILGenerator(); ilGenerator.DeclareLocal(typeof(object)); ilGenerator.Emit(OpCodes.Ldarg_0); ilGenerator.Emit(OpCodes.Castclass, this.TargetType); ilGenerator.EmitCall(OpCodes.Call, this.GetMethod, null); if (this.GetMethod.ReturnType.IsValueType) { ilGenerator.Emit(OpCodes.Box, this.GetMethod.ReturnType); } ilGenerator.Emit(OpCodes.Stloc_0); ilGenerator.Emit(OpCodes.Ldloc_0); ilGenerator.Emit(OpCodes.Ret); method.DefineParameter(1, ParameterAttributes.In, "value"); return (Func<object, object>)method.CreateDelegate(typeof(Func<object, object>)); }