private static void EmitProcessAndEncodeDirect(IEmittingContext emittingContext, HandlerParameterCodec[] responseParameterCodecs, Type retvalType) { var il = emittingContext.IL; EmitEncodeDirect(emittingContext, responseParameterCodecs, retvalType); il.Call(TaskMethods.FromResult(typeof(byte[]))); }
private static void EmitEncodeDirect(IEmittingContext emittingContext, HandlerParameterCodec[] responseParameterCodecs, Type retvalType) { var il = emittingContext.IL; bool hasRetval = retvalType != typeof(void); if (hasRetval || responseParameterCodecs.Any()) { HandlerRetvalCodec retvalCodec = null; if (hasRetval) { retvalCodec = new HandlerRetvalCodec(emittingContext, retvalType); retvalCodec.EmitStore(); // var ret = stack_0 retvalCodec.EmitCalculateSize(); // stack_0 = calculateSize(ret) } bool hasSizeOnStack = hasRetval; foreach (var codec in responseParameterCodecs) { codec.EmitCalculateSize(); // stack_0 += calculateSize(param_i) EmitAddIf(il, ref hasSizeOnStack); } var dataArrayVar = il.DeclareLocal(typeof(byte[])); // var dataArray = new byte[size of retval] il.Newarr(typeof(byte)); il.Stloc(dataArrayVar); var pinnedVar = il.PinArray(typeof(byte), dataArrayVar); // var pinned dataPointer = pin(dataArrayVar) il.Ldloc(pinnedVar); // data = dataPointer il.Stloc(emittingContext.DataPointerVar); foreach (var codec in responseParameterCodecs) codec.EmitEncode(); // encode(data, param_i) if (hasRetval) retvalCodec.EmitEncode(); // encode(data, ret) il.Ldloc(dataArrayVar); // stack_0 = dataArray } else { il.Ldc_I4(0); // stack_0 = new byte[0] il.Newarr(typeof(byte)); } }