private MethodInfo EmitFunctionMethod(TypeBuilder dcType, string methName, SchemaObject funcInfo, string objectPrefix, MethodAttributes accessibility) { FunctionGenerator generator = new FunctionGenerator(this, dcType, funcInfo, methName, accessibility); if (generator.Method == null) { return null; } generator.AddAttributes(objectPrefix); ILGenerator iLGenerator = generator.Method.GetILGenerator(); LocalBuilder local = iLGenerator.DeclareLocal(typeof(object[])); iLGenerator.Emit(OpCodes.Ldarg_0); iLGenerator.Emit(OpCodes.Ldarg_0); iLGenerator.Emit(OpCodes.Call, typeof(MethodBase).GetMethod("GetCurrentMethod", BindingFlags.Public | BindingFlags.Static, null, Type.EmptyTypes, null)); iLGenerator.Emit(OpCodes.Castclass, typeof(MethodInfo)); iLGenerator.Emit(OpCodes.Ldc_I4, funcInfo.Parameters.Count); iLGenerator.Emit(OpCodes.Newarr, typeof(object)); iLGenerator.Emit(OpCodes.Stloc, local); int arg = 0; foreach (Parameter parameter in funcInfo.Parameters) { iLGenerator.Emit(OpCodes.Ldloc, local); iLGenerator.Emit(OpCodes.Ldc_I4, arg); iLGenerator.Emit(OpCodes.Ldarg, (int) (arg + 1)); if (parameter.ClrType.IsValueType) { iLGenerator.Emit(OpCodes.Box, parameter.ClrType); } iLGenerator.Emit(OpCodes.Stelem_Ref); arg++; } iLGenerator.Emit(OpCodes.Ldloc, local); MethodInfo meth = typeof(DataContext).GetMethod((funcInfo is TableFunction) ? "CreateMethodCallQuery" : "ExecuteMethodCall", BindingFlags.NonPublic | BindingFlags.Instance, null, new Type[] { typeof(object), typeof(MethodInfo), typeof(object[]) }, null); if (funcInfo is TableFunction) { meth = meth.MakeGenericMethod(new Type[] { generator.ResultType }); } iLGenerator.Emit(OpCodes.Call, meth); if (funcInfo is ScalarFunction) { iLGenerator.Emit(OpCodes.Callvirt, typeof(IExecuteResult).GetProperty("ReturnValue").GetGetMethod()); iLGenerator.Emit(generator.ResultType.IsValueType ? OpCodes.Unbox_Any : OpCodes.Castclass, generator.ResultType); } iLGenerator.Emit(OpCodes.Ret); return generator.Method; }