Пример #1
0
        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));
 }
Пример #3
0
        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;
        }
Пример #4
0
        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;
        }
Пример #5
0
        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);
        }
Пример #6
0
		/// <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>));
		}
Пример #7
0
        /// <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));
        }
Пример #8
0
        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);
        }
Пример #9
0
        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;
        }
Пример #10
0
        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;
        }
Пример #11
0
		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));
		}
Пример #12
0
        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));
        }
Пример #14
0
        /// <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>));
        }
Пример #15
0
        /// <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>));
        }
Пример #16
0
        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;
        }
Пример #17
0
            /// <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;
                }
            }
Пример #18
0
        /// <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>));
        }
Пример #19
0
        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;
        }
Пример #20
0
        /// <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;
        }
Пример #21
0
        /// <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);
        }
Пример #22
0
        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);
        }
Пример #23
0
        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>));
        }