private MethodInfo CreateDecodeDeferredMethod(ProxyClassBuildingContext classContext, string parentMethodName, IReadOnlyList <Type> genericTypeArguments, Type pureRetvalType) { var methodBuilder = classContext.Builder.DefineMethod("__rpc_decode_deferred_" + parentMethodName, MethodAttributes.Private | MethodAttributes.HideBySig); var genericTypeParameterBuilders = genericTypeArguments.Any() ? methodBuilder.DefineGenericParameters(genericTypeArguments.Select(x => x.Name).ToArray()) : new GenericTypeParameterBuilder[0]; var genericArgumentMap = genericTypeParameterBuilders.ToDictionary(x => x.Name, x => (Type)x); var retvalType = pureRetvalType.DeepSubstituteGenerics(genericArgumentMap); methodBuilder.SetParameters(DecodeDeferredParameterTypes); methodBuilder.SetReturnType(retvalType); methodBuilder.SetImplementationFlags(MethodImplAttributes.Managed); var il = new MyILGenerator(methodBuilder.GetILGenerator()); var emittingContext = new ProxyMethodEmittingContext(il, classContext.Fields); il.Ldarg(1); il.Call(TaskMethods.GetResult(typeof(byte[]))); EmitPrepareToDecode(emittingContext); var retvalCodec = new ProxyMethodRetvalCodec(retvalType); retvalCodec.EmitDecode(emittingContext); il.Ret(); return(methodBuilder); }
private void EmitProcessDirect(IEmittingContext emittingContext, ProxyMethodParameterCodec[] responseParameterCodecs, Type retvalType) { bool hasRetval = retvalType != typeof(void); var il = emittingContext.IL; il.Callvirt(OutgoingRequestProcessorMethods.Process); // stack_0 = stack_0.Process(stack_1, stack_2, stack_3, stack_4, stack_5) if (responseParameterCodecs.Any() || hasRetval) { EmitPrepareToDecode(emittingContext); foreach (var codec in responseParameterCodecs) { codec.EmitDecodeAndStore(emittingContext); // arg_i = Decode(data, remainingBytes, false) } if (hasRetval) { var retvalCodec = new ProxyMethodRetvalCodec(retvalType); retvalCodec.EmitDecode(emittingContext); // stack_0 = Decode(data, remainingBytes, false) } } else { il.Pop(); // pop(stack_0) } }