示例#1
0
        private void GenerateMethodBody(ILGenerator generator, Jace.Execution.ParameterInfo[] parameters,
                                        Func <Dictionary <string, double>, double> function)
        {
            Type            dictionaryType            = typeof(Dictionary <string, double>);
            ConstructorInfo dictionaryConstructorInfo = dictionaryType.GetConstructor(Type.EmptyTypes);

            FieldInfo functionField = typeof(FuncAdapterArguments).GetField("function",
                                                                            BindingFlags.NonPublic | BindingFlags.Instance);

            generator.DeclareLocal(dictionaryType);
            generator.DeclareLocal(typeof(double));

            generator.Emit(OpCodes.Newobj, dictionaryConstructorInfo);
            generator.Emit(OpCodes.Stloc_0);

            for (int i = 0; i < parameters.Length; i++)
            {
                Jace.Execution.ParameterInfo parameter = parameters[i];

                generator.Emit(OpCodes.Ldloc_0);
                generator.Emit(OpCodes.Ldstr, parameter.Name);

                switch (i)
                {
                case 0:
                    generator.Emit(OpCodes.Ldarg_1);
                    break;

                case 1:
                    generator.Emit(OpCodes.Ldarg_2);
                    break;

                case 2:
                    generator.Emit(OpCodes.Ldarg_3);
                    break;

                default:
                    generator.Emit(OpCodes.Ldarg, i + 1);
                    break;
                }

                if (parameter.DataType != DataType.FloatingPoint)
                {
                    generator.Emit(OpCodes.Conv_R8);
                }

                generator.Emit(OpCodes.Callvirt, dictionaryType.GetMethod("Add", new Type[] { typeof(string), typeof(double) }));
            }

            generator.Emit(OpCodes.Ldarg_0);
            generator.Emit(OpCodes.Ldfld, functionField);
            generator.Emit(OpCodes.Ldloc_0);
            generator.Emit(OpCodes.Callvirt, function.GetType().GetMethod("Invoke"));

            generator.Emit(OpCodes.Ret);
        }
示例#2
0
        // Uncomment for debugging purposes
        //public void CreateDynamicModuleBuilder()
        //{
        //    AssemblyName assemblyName = new AssemblyName("JaceDynamicAssembly");
        //    AppDomain domain = AppDomain.CurrentDomain;
        //    AssemblyBuilder assemblyBuilder = domain.DefineDynamicAssembly(assemblyName,
        //        AssemblyBuilderAccess.RunAndSave);
        //    ModuleBuilder moduleBuilder = assemblyBuilder.DefineDynamicModule(assemblyName.Name, "test.dll");

        //    TypeBuilder typeBuilder = moduleBuilder.DefineType("MyTestClass");

        //    MethodBuilder method = typeBuilder.DefineMethod("MyTestMethod", MethodAttributes.Static, typeof(double),
        //       new Type[] { typeof(FuncAdapterArguments), typeof(int), typeof(double) });

        //    ILGenerator generator = method.GetILGenerator();
        //    GenerateMethodBody(generator, new List<Calculator.Execution.ParameterInfo>() {
        //        new Calculator.Execution.ParameterInfo() { Name = "test1", DataType = DataType.Integer },
        //        new Calculator.Execution.ParameterInfo() { Name = "test2", DataType = DataType.FloatingPoint }},
        //        (a) => 0.0);

        //    typeBuilder.CreateType();

        //    assemblyBuilder.Save(@"test.dll");
        //}

#if !NETFX_CORE
        private Delegate GenerateDelegate(Jace.Execution.ParameterInfo[] parameterArray,
                                          Func <Dictionary <string, double>, double> function)
        {
            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)));
        }