internal void EndSet(Type stackType) { BuildUtil.Convert(_il, stackType, typeof(T), false); _il.Emit(OpCodes.Stelem_Ref); }
private MethodBuilder AddMethodImpl(MethodInfo mi) { ParameterInfo[] parameters = mi.GetParameters(); Type[] paramTypes = ParamTypes(parameters, false); MethodBuilder mdb = _tb.DefineMethod(mi.Name, MethodAttributes.Public | MethodAttributes.Virtual, mi.ReturnType, paramTypes); if (mi.ContainsGenericParameters) { Type[] ts = mi.GetGenericArguments(); string[] ss = new string[ts.Length]; for (int i = 0; i < ts.Length; i++) { ss[i] = ts[i].Name; } GenericTypeParameterBuilder[] genericParameters = mdb.DefineGenericParameters(ss); for (int i = 0; i < genericParameters.Length; i++) { genericParameters[i].SetGenericParameterAttributes(ts[i].GetTypeInfo().GenericParameterAttributes); } } ILGenerator il = mdb.GetILGenerator(); ParametersArray args = new ParametersArray(il, paramTypes); // object[] args = new object[paramCount]; il.Emit(OpCodes.Nop); GenericArray <object> argsArr = new GenericArray <object>(il, ParamTypes(parameters, true).Length); for (int i = 0; i < parameters.Length; i++) { // args[i] = argi; if (!parameters[i].IsOut) { argsArr.BeginSet(i); args.Get(i); argsArr.EndSet(parameters[i].ParameterType); } } // object[] packed = new object[PackedArgs.PackedTypes.Length]; GenericArray <object> packedArr = new GenericArray <object>(il, PackedArgs.PackedTypes.Length); // packed[PackedArgs.DispatchProxyPosition] = this; packedArr.BeginSet(GlobalConst.DISPATCH_PROXY_POSITION); il.Emit(OpCodes.Ldarg_0); packedArr.EndSet(typeof(DispatchProxyAsync)); // packed[PackedArgs.DeclaringTypePosition] = typeof(iface); MethodInfo Type_GetTypeFromHandle = typeof(Type).GetRuntimeMethod("GetTypeFromHandle", new Type[] { typeof(RuntimeTypeHandle) }); int methodToken; Type declaringType; _assembly.GetTokenForMethod(mi, out declaringType, out methodToken); packedArr.BeginSet(GlobalConst.DECLARING_TYPE_POSITION); il.Emit(OpCodes.Ldtoken, declaringType); il.Emit(OpCodes.Call, Type_GetTypeFromHandle); packedArr.EndSet(typeof(object)); // packed[PackedArgs.MethodTokenPosition] = iface method token; packedArr.BeginSet(GlobalConst.METHOD_TOKEN_POSITION); il.Emit(OpCodes.Ldc_I4, methodToken); packedArr.EndSet(typeof(Int32)); // packed[PackedArgs.ArgsPosition] = args; packedArr.BeginSet(GlobalConst.ARGS_POSITION); argsArr.Load(); packedArr.EndSet(typeof(object[])); // packed[PackedArgs.GenericTypesPosition] = mi.GetGenericArguments(); if (mi.ContainsGenericParameters) { packedArr.BeginSet(GlobalConst.GENERIC_TYPES_POSITION); Type[] genericTypes = mi.GetGenericArguments(); GenericArray <Type> typeArr = new GenericArray <Type>(il, genericTypes.Length); for (int i = 0; i < genericTypes.Length; ++i) { typeArr.BeginSet(i); il.Emit(OpCodes.Ldtoken, genericTypes[i]); il.Emit(OpCodes.Call, Type_GetTypeFromHandle); typeArr.EndSet(typeof(Type)); } typeArr.Load(); packedArr.EndSet(typeof(Type[])); } for (int i = 0; i < parameters.Length; i++) { if (parameters[i].ParameterType.IsByRef) { args.BeginSet(i); argsArr.Get(i); args.EndSet(i, typeof(object)); } } MethodInfo invokeMethod = s_delegateInvoke; if (mi.ReturnType == typeof(Task)) { invokeMethod = s_delegateInvokeAsync; } if (IsGenericTask(mi.ReturnType)) { var returnTypes = mi.ReturnType.GetGenericArguments(); invokeMethod = s_delegateinvokeAsyncT.MakeGenericMethod(returnTypes); } // Call AsyncDispatchProxyGenerator.Invoke(object[]), InvokeAsync or InvokeAsyncT il.Emit(OpCodes.Ldarg_0); il.Emit(OpCodes.Ldfld, _fields[GlobalConst.InvokeActionFieldAndCtorParameterIndex]); packedArr.Load(); il.Emit(OpCodes.Callvirt, invokeMethod); if (mi.ReturnType != typeof(void)) { BuildUtil.Convert(il, typeof(object), mi.ReturnType, false); } else { il.Emit(OpCodes.Pop); } il.Emit(OpCodes.Ret); _tb.DefineMethodOverride(mdb, mi); return(mdb); }