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); }
// 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))); }