public void EmitEncode(IEmittingContext context, Action <MyILGenerator> emitLoad) { var il = context.IL; var arrayIsNotNullLabel = il.DefineLabel(); var arrayIsNotEmptylabel = il.DefineLabel(); var endOfSubmethodLabel = il.DefineLabel(); emitLoad(il); // if (value) il.Brtrue(arrayIsNotNullLabel); // goto arrayIsNotNullLabel // Array is null branch il.Ldloc(context.DataPointerVar); // *(int*) data = -1 il.Ldc_I4(-1); il.Stind_I4(); il.IncreasePointer(context.DataPointerVar, sizeof(int)); // data += sizeof(int) il.Br(endOfSubmethodLabel); // goto endOfSubmethodLabel il.MarkLabel(arrayIsNotNullLabel); emitLoad(il); // if (value.Length) il.Ldlen(); // goto arrayIsNotEmptylabel il.Conv_I4(); il.Brtrue(arrayIsNotEmptylabel); // Array is empty branch il.Ldloc(context.DataPointerVar); // *(int*) data = 0 il.Ldc_I4(0); il.Stind_I4(); il.IncreasePointer(context.DataPointerVar, sizeof(int)); // data += sizeof(int) il.Br(endOfSubmethodLabel); // goto endOfSubmethodLabel // Array is not empty branch il.MarkLabel(arrayIsNotEmptylabel); var lengthVar = context.GetSharedVariable <int>("length"); // var length = value.Length emitLoad(il); il.Ldlen(); il.Conv_I4(); il.Stloc(lengthVar); var sizeVar = context.GetSharedVariable <int>("sizeInBytes");// var sizeInBytes = length * sizeOfStruct il.Ldloc(lengthVar); il.Ldc_I4(sizeOfStruct); il.Mul(); il.Stloc(sizeVar); il.Ldloc(context.DataPointerVar); // *(int*) data = length il.Ldloc(lengthVar); il.Stind_I4(); il.IncreasePointer(context.DataPointerVar, sizeof(int)); // data += sizeof(int) var pointerVar = il.PinArray(typeOfStruct, emitLoad); // var pinned arrayPointer = pin(value) il.Ldloc(context.DataPointerVar); // cpblk(data, (byte*)arrayPointer, sizeInBytes) il.Ldloc(pointerVar); il.Conv_I(); il.Ldloc(sizeVar); il.Cpblk(); il.UnpinArray(pointerVar); // unpin(arrayPointer) il.IncreasePointer(context.DataPointerVar, sizeVar); // data += sizeInBytes il.MarkLabel(endOfSubmethodLabel); }
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) } }
public void EmitCalculateSize(IEmittingContext context, Action <MyILGenerator> emitLoad) { var il = context.IL; var contractIsNotNullLabel = il.DefineLabel(); var endOfSubmethodLabel = il.DefineLabel(); if (CanBeNull) { emitLoad(il); // if (value) il.Brtrue(contractIsNotNullLabel); // goto contractIsNotNullLabel il.Ldc_I4(sizeof(int)); // stack_0 = sizeof(int) il.Br(endOfSubmethodLabel); // goto endOfSubmethodLabel il.MarkLabel(contractIsNotNullLabel); // label contractIsNotNullLabel } il.Ldc_I4(fixedPartOfSize); // stack_0 = fixedPartOfSize foreach (var memberInfo in memberInfos.Skip(numFixedProperties)) // foreach (member) { var memberVar = il.DeclareLocal( // stack_0 += sizeof member GetMemberType(memberInfo.Member)); EmitLoadMember(il, emitLoad, memberInfo.Member); il.Stloc(memberVar); memberInfo.Codec.EmitCalculateSize(context, memberVar); il.Add(); } il.MarkLabel(endOfSubmethodLabel); // label endOfSubmethodLabel }
public void EmitCalculateSize(IEmittingContext context, Action<MyILGenerator> emitLoad) { var il = context.IL; context.EmitLoadManualCodecFor(type); emitLoad(il); il.Callvirt(ManualCodecMethods.CalculateSize(type)); }
public void EmitEncode(IEmittingContext context, Action <MyILGenerator> emitLoad) { var il = context.IL; var valueIsNotNullLabel = il.DefineLabel(); var endOfMethodLabel = il.DefineLabel(); var elemVar = il.DeclareLocal(elementType); // TElement elem emitLoad(il); // if (value) il.Brtrue(valueIsNotNullLabel); // goto valueIsNotNullLabel // value is null branch il.Ldloc(context.DataPointerVar); // *(int*) data = -1 il.Ldc_I4(-1); il.Stind_I4(); il.IncreasePointer(context.DataPointerVar, sizeof(int)); // data += sizeof(int) il.Br(endOfMethodLabel); // goto endOfMethodLabel // value is not null branch il.MarkLabel(valueIsNotNullLabel); // label valueIsNotNullLabel il.Ldloc(context.DataPointerVar); // *(int*) data = (int)value.Count EmitLoadCount(il, emitLoad); il.Stind_I4(); il.IncreasePointer(context.DataPointerVar, sizeof(int)); // data += sizeof(int) using (var loop = il.EmitForeachLoop(elementType, emitLoad)) // foreach (current in value) { loop.LoadCurrent(); // elem = current il.Stloc(elemVar); elementCodec.EmitEncode(context, elemVar); // encode(data, elem) } il.MarkLabel(endOfMethodLabel); // label endOfMethodLabel }
public void EmitEncode(IEmittingContext context, Action <MyILGenerator> emitLoad) { var il = context.IL; var valueIsNotNullLabel = il.DefineLabel(); var endOfSubmethodLabel = il.DefineLabel(); if (CanBeNull) { emitLoad(il); // if (value) il.Brtrue(valueIsNotNullLabel); // goto valueIsNotNullLabel il.Ldloc(context.DataPointerVar); // *(int*) data = 0 il.Ldc_I4(0); il.Stind_I4(); il.IncreasePointer(context.DataPointerVar, sizeof(int)); // data += sizeof(int) il.Br(endOfSubmethodLabel); // goto endOfSubmethodLabel il.MarkLabel(valueIsNotNullLabel); // goto valueIsNotNullLabel il.Ldloc(context.DataPointerVar); // *(int*) data = 1 il.Ldc_I4(1); il.Stind_I4(); il.IncreasePointer(context.DataPointerVar, sizeof(int)); // data += sizeof(int) } foreach (var memberInfo in memberInfos) // foreach (member) { var memberVar = il.DeclareLocal( // encode(value.member) GetMemberType(memberInfo.Member)); EmitLoadMember(il, emitLoad, memberInfo.Member); il.Stloc(memberVar); memberInfo.Codec.EmitEncode(context, memberVar); } il.MarkLabel(endOfSubmethodLabel); // label endOfSubmethodLabel }
private static void EmitProcessAndEncodeDirect(IEmittingContext emittingContext, HandlerParameterCodec[] responseParameterCodecs, Type retvalType) { var il = emittingContext.IL; EmitEncodeDirect(emittingContext, responseParameterCodecs, retvalType); il.Call(TaskMethods.FromResult(typeof(byte[]))); }
public void EmitCalculateSize(IEmittingContext context, Action<MyILGenerator> emitLoad) { var il = context.IL; var arrayIsNotNullLabel = il.DefineLabel(); var endOfSubmethodLabel = il.DefineLabel(); emitLoad(il); // if (value) il.Brtrue(arrayIsNotNullLabel); // goto arrayIsNotNullLabel // Array is null branch il.Ldc_I4(sizeof(int)); // stack_0 = sizeof(int) il.Br(endOfSubmethodLabel); // goto endOfSubmethodLabel // String is not null branch il.MarkLabel(arrayIsNotNullLabel); emitLoad(il); // stack_0 = value.Length * sizeOfStruct + sizeof(int) il.Ldlen(); il.Conv_I4(); il.Ldc_I4(sizeOfStruct); il.Mul(); il.Ldc_I4(sizeof(int)); il.Add(); il.MarkLabel(endOfSubmethodLabel); }
protected override void EmitDecodeAndStore(IEmittingContext context, LocalBuilder collectionVar, Action emitLoadIndex, bool doNotCheckBounds) { var il = context.IL; il.Ldloc(collectionVar); ElementCodec.EmitDecode(context, doNotCheckBounds); il.Callvirt(addMethod); }
public void EmitCalculateSize(IEmittingContext context, Action <MyILGenerator> emitLoad) { var il = context.IL; var arrayIsNotNullLabel = il.DefineLabel(); var endOfSubmethodLabel = il.DefineLabel(); emitLoad(il); // if (value) il.Brtrue(arrayIsNotNullLabel); // goto arrayIsNotNullLabel // Array is null branch il.Ldc_I4(sizeof(int)); // stack_0 = sizeof(int) il.Br(endOfSubmethodLabel); // goto endOfSubmethodLabel // String is not null branch il.MarkLabel(arrayIsNotNullLabel); emitLoad(il); // stack_0 = value.Length * sizeOfStruct + sizeof(int) il.Ldlen(); il.Conv_I4(); il.Ldc_I4(sizeOfStruct); il.Mul(); il.Ldc_I4(sizeof(int)); il.Add(); il.MarkLabel(endOfSubmethodLabel); }
public void EmitCalculateSize(IEmittingContext context, Action <MyILGenerator> emitLoad) { var il = context.IL; var endOfSubmethodLabel = il.DefineLabel(); if (canBeNull) { var stringIsNotNullLabel = il.DefineLabel(); emitLoad(il); // if (value) il.Brtrue(stringIsNotNullLabel); // goto stringIsNotNullLabel // String is null branch il.Ldc_I4(sizeof(int)); // stack_0 = sizeof(int) il.Br(endOfSubmethodLabel); // goto endOfSubmethodLabel // String is not null branch il.MarkLabel(stringIsNotNullLabel); // label stringIsNotNullLabel } EmitLoadAsString(il, emitLoad); // stack_0 = (FormatToString(value).Length << 1) + sizeof(int) il.Call(GetLength); il.Ldc_I4(1); il.Shl(); il.Ldc_I4(sizeof(int)); il.Add(); il.MarkLabel(endOfSubmethodLabel); // label endOfSubmethodLabel }
public void EmitCalculateSize(IEmittingContext context, Action <MyILGenerator> emitLoad) { var il = context.IL; var valueIsNullOrEmptyLabel = il.DefineLabel(); var valueHasElementsLabel = il.DefineLabel(); var endOfMethodLabel = il.DefineLabel(); var elemVar = il.DeclareLocal(elementType); // T elem emitLoad(il); // if (!value) il.Brfalse(valueIsNullOrEmptyLabel); // goto valueIsNullOrEmptyLabel EmitLoadCount(il, emitLoad); // if ((int)value.Length) il.Brtrue(valueHasElementsLabel); // goto valueHasElementsLabel il.MarkLabel(valueIsNullOrEmptyLabel); // label valueIsNullOrEmptyLabel il.Ldc_I4(sizeof(int)); // stack_0 = sizeof(int) il.Br(endOfMethodLabel); // goto endOfMethodLabel il.MarkLabel(valueHasElementsLabel); // label valueHasElementsLabel il.Ldc_I4(sizeof(int)); // sum = sizeof(int) using (var loop = il.EmitForeachLoop(elementType, emitLoad)) // foreach (current in value) { loop.LoadCurrent(); // elem = current il.Stloc(elemVar); elementCodec.EmitCalculateSize(context, elemVar); // stack_1 = CalculateSize(elem) il.Add(); // stack_0 = stack_0 + stack_1 } il.MarkLabel(endOfMethodLabel); // label endOfMethodLabel }
public void EmitDecode(IEmittingContext context, bool doNotCheckBounds) { var il = context.IL; var endOfSubmethodLabel = il.DefineLabel(); if (!doNotCheckBounds) { var canReadSizeLabel = il.DefineLabel(); il.Ldloc(context.RemainingBytesVar); // if (remainingBytes >= sizeof(int)) il.Ldc_I4(sizeof(int)); // goto canReadSizeLabel il.Bge(canReadSizeLabel); il.ThrowUnexpectedEndException(); // throw new InvalidDataException("...") il.MarkLabel(canReadSizeLabel); // label canReadSizeLabel } il.Ldloc(context.DataPointerVar); // stack_0 = *(int*) data il.Ldind_I4(); var tempInteger = context.GetSharedVariable <int>("tempInteger"); // var tempInteger = stack_0 il.Stloc(tempInteger); il.IncreasePointer(context.DataPointerVar, sizeof(int)); // data += sizeof(int) il.DecreaseInteger(context.RemainingBytesVar, sizeof(int)); // remainingBytes -= sizeof(int) if (canBeNull) { var strIsNotNullLabel = il.DefineLabel(); il.Ldloc(tempInteger); // if (tempInteger != -1) il.Ldc_I4(-1); // goto strIsNotNullLabel il.Bne_Un(strIsNotNullLabel); // String is null branch il.Ldnull(); // stack_0 = null il.Br(endOfSubmethodLabel); // goto endOfSubmethodLabel // String is not null branch il.MarkLabel(strIsNotNullLabel); // label strIsNotNullLabel } if (!doNotCheckBounds) { var canReadDataLabel = il.DefineLabel(); il.Ldloc(context.RemainingBytesVar); // if (remainingBytes >= tempInteger) il.Ldloc(tempInteger); // goto canReadDataLabel il.Bge(canReadDataLabel); il.ThrowUnexpectedEndException(); // throw new InvalidDataException("...") il.MarkLabel(canReadDataLabel); // label canReadDataLabel } il.Ldloc(context.DataPointerVar); // stack_0 = data il.Ldc_I4(0); // stack_1 = 0 il.Ldloc(tempInteger); // stack_2 = tempInteger >> 1 il.Ldc_I4(1); il.Shr(); il.Newobj(NewString); // stack_0 = new string(stack_0, stack_1, stack_2) EmitParseFromString(il); // stack_0 = Parse(stack_0) il.IncreasePointer(context.DataPointerVar, tempInteger); // data += tempInteger il.DecreaseInteger(context.RemainingBytesVar, tempInteger); // remainingBytes -= tempInteger il.MarkLabel(endOfSubmethodLabel); // label endOfSubmethodLabel }
public void EmitEncode(IEmittingContext context, Action <MyILGenerator> emitLoad) { var il = context.IL; var strIsNotNullLabel = il.DefineLabel(); var endOfSubmethodLabel = il.DefineLabel(); if (canBeNull) { emitLoad(il); // if (val) goto strIsNotNullLabel il.Brtrue(strIsNotNullLabel); // String is null branch il.Ldloc(context.DataPointerVar); // *(int*) data = -1 il.Ldc_I4(-1); il.Stind_I4(); il.IncreasePointer(context.DataPointerVar, sizeof(int)); // data += sizeof(int) il.Br(endOfSubmethodLabel); // goto endOfEncodeLabel // String is not null branch il.MarkLabel(strIsNotNullLabel); // label strIsNotNullLabel } var stringValueVar = context.GetSharedVariable <string>("stringValue"); // var stringValue = FormatToString(value) EmitLoadAsString(il, emitLoad); il.Stloc(stringValueVar); var tempIntegerVar = context.GetSharedVariable <int>("tempInteger"); // var tempInteger = stringValue.Length << 1 il.Ldloc(stringValueVar); il.Call(GetLength); il.Ldc_I4(1); il.Shl(); il.Stloc(tempIntegerVar); il.Ldloc(context.DataPointerVar); // *(int*)data = tempInteger il.Ldloc(tempIntegerVar); il.Stind_I4(); il.IncreasePointer(context.DataPointerVar, sizeof(int)); // data += sizeof(int) var pinnedString = il.DeclareLocal(typeof(string), true); // var pinned pinnedString = stringValue il.Ldloc(stringValueVar); il.Stloc(pinnedString); il.Ldloc(pinnedString); // stack_0 = (byte*)pinnedString il.Conv_I(); il.Call(GetOffsetToStringData); // stack_0 = stack_0 + il.Add(); // RuntimeHelpers.OffsetToStringData var charPointer = context.GetSharedVariable(typeof(char *), "charPointer"); // charPointer = stack_0 il.Stloc(charPointer); il.Ldloc(context.DataPointerVar); // cpblk(data, charPointer, tempInteger) il.Ldloc(charPointer); il.Ldloc(tempIntegerVar); il.Cpblk(); il.Ldnull(); // pinnedString = null il.Stloc(pinnedString); il.IncreasePointer(context.DataPointerVar, tempIntegerVar); // data += tempInteger il.MarkLabel(endOfSubmethodLabel); // label endOfSubmethodLabel }
public void EmitCalculateSize(IEmittingContext context, Action <MyILGenerator> emitLoad) { var il = context.IL; context.EmitLoadManualCodecFor(type); emitLoad(il); il.Callvirt(ManualCodecMethods.CalculateSize(type)); }
public void EmitEncode(IEmittingContext context, Action <MyILGenerator> emitLoad) { var il = context.IL; context.EmitLoadManualCodecFor(type); il.Ldloca(context.DataPointerVar); emitLoad(il); il.Callvirt(ManualCodecMethods.Encode(type)); }
public HandlerParameterCodec(IEmittingContext emittingContext, MethodParameterDescription description) { this.emittingContext = emittingContext; type = description.Type; way = description.Way; codec = new IndirectCodec(type); if (IsResponseParameter) local = emittingContext.IL.DeclareLocal(type); }
protected override void EmitDecodeAndStore(IEmittingContext context, LocalBuilder collectionVar, Action emitLoadIndex, bool doNotCheckBounds) { var il = context.IL; il.Ldloc(collectionVar); emitLoadIndex(); il.Ldelema(ElementType); ElementCodec.EmitDecode(context, doNotCheckBounds); il.Stobj(ElementType); }
public void EmitEncode(IEmittingContext context, Action <MyILGenerator> emitLoad) { var il = context.IL; il.Ldloc(context.DataPointerVar); // *(T*) data = val emitLoad(il); il.Stobj(type); il.IncreasePointer(context.DataPointerVar, sizeInBytes); // data += sizeInBytes }
public void EmitDecodeAndStore(IEmittingContext emittingContext) { var il = emittingContext.IL; il.Ldarg(argIndex); codec.EmitDecode(emittingContext, false); if (type.IsValueType) il.Stobj(type); else il.Stind_Ref(); }
public void EmitDecode(IEmittingContext context, bool doNotCheckBounds) { var il = context.IL; context.EmitLoadManualCodecFor(type); il.Ldloca(context.DataPointerVar); il.Ldloca(context.RemainingBytesVar); il.Ldc_I4(0); il.Callvirt(ManualCodecMethods.Decode(type)); }
public HandlerParameterCodec(IEmittingContext emittingContext, MethodParameterDescription description) { this.emittingContext = emittingContext; type = description.Type; way = description.Way; codec = new IndirectCodec(type); if (IsResponseParameter) { local = emittingContext.IL.DeclareLocal(type); } }
private static void EmitPrepareToDecode(IEmittingContext emittingContext) { var il = emittingContext.IL; var responseDataArrayVar = il.DeclareLocal(typeof(byte[])); il.Stloc(responseDataArrayVar); // dataArray = stack_0 il.Ldloc(responseDataArrayVar); // remainingBytes = dataArray.Length il.Ldlen(); il.Stloc(emittingContext.RemainingBytesVar); var pinnedVar = il.PinArray(typeof(byte), responseDataArrayVar); // var pinned dataPointer = pin(dataArray) il.Ldloc(pinnedVar); // data = dataPointer il.Stloc(emittingContext.DataPointerVar); }
public void EmitDecodeAndStore(IEmittingContext emittingContext) { var il = emittingContext.IL; il.Ldarg(argIndex); codec.EmitDecode(emittingContext, false); if (type.IsValueType) { il.Stobj(type); } else { il.Stind_Ref(); } }
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)); } }
public void EmitDecode(IEmittingContext context, bool doNotCheckBounds) { var il = context.IL; var valueIsNotNullLabel = il.DefineLabel(); var endOfMethodLabel = il.DefineLabel(); var resultVar = il.DeclareLocal(type); // TCollection result if (!doNotCheckBounds) { var canReadLengthLabel = il.DefineLabel(); il.Ldloc(context.RemainingBytesVar); // if (remainingBytes >= sizeof(int)) il.Ldc_I4(sizeof(int)); // goto canReadLengthLabel il.Bge(canReadLengthLabel); il.ThrowUnexpectedEndException(); // throw new InvalidDataException("...") il.MarkLabel(canReadLengthLabel); // label canReadLengthLabel } var lengthVar = il.DeclareLocal(typeof(int)); // var length = *(int*) data il.Ldloc(context.DataPointerVar); il.Ldind_I4(); il.Stloc(lengthVar); il.IncreasePointer(context.DataPointerVar, sizeof(int)); // data += sizeof(int) il.DecreaseInteger(context.RemainingBytesVar, sizeof(int)); // remainingBytes -= sizeof(int) il.Ldloc(lengthVar); // if (length != -1) il.Ldc_I4(-1); // goto valueIsNotNullLabel il.Bne_Un(valueIsNotNullLabel); il.Ldnull(); // stack_0 = null il.Br(endOfMethodLabel); // goto endOfMethodLabel il.MarkLabel(valueIsNotNullLabel); // label valueIsNotNullLabel EmitCreateCollection(il, lengthVar); // result = new TCollection() il.Stloc(resultVar); using (var loop = il.EmitForLoop(lengthVar)) // for (int i = 0; i < length; i++) { // result.Add(decode(data, remainingBytes)) EmitDecodeAndStore(context, resultVar, loop.LoadIndex, doNotCheckBounds); } il.Ldloc(resultVar); // stack_0 = result il.MarkLabel(endOfMethodLabel); // label endOfMethodLabel }
public void EmitDecode(IEmittingContext context, bool doNotCheckBounds) { var il = context.IL; if (!doNotCheckBounds) { var everythingsAllrightLabel = il.DefineLabel(); il.Ldloc(context.RemainingBytesVar); // if (remainingBytes >= sizeInBytes) il.Ldc_I4(sizeInBytes); // goto everythingsAllrightLabel il.Bge(everythingsAllrightLabel); il.ThrowUnexpectedEndException(); // throw new InvalidDataException("...") il.MarkLabel(everythingsAllrightLabel); // label everythingsAllrightLabel } il.Ldloc(context.DataPointerVar); // stack_0 = *(T*) data il.Ldobj(type); il.IncreasePointer(context.DataPointerVar, sizeInBytes); // data += sizeInBytes il.DecreaseInteger(context.RemainingBytesVar, sizeInBytes); // remainingBytes -= sizeInBytes }
public void EmitDecode(IEmittingContext emittingContext) { codec.EmitDecode(emittingContext, false); }
public void EmitCalculateSize(IEmittingContext emittingContext) { typeCodec.EmitCalculateSize(emittingContext, Loaders.TypeOf(type)); }
protected abstract void EmitDecodeAndStore(IEmittingContext context, LocalBuilder collectionVar, Action emitLoadIndex, bool doNotCheckBounds);
public void EmitEncode(IEmittingContext context, Action<MyILGenerator> emitLoad) { var il = context.IL; var arrayIsNotNullLabel = il.DefineLabel(); var arrayIsNotEmptylabel = il.DefineLabel(); var endOfSubmethodLabel = il.DefineLabel(); emitLoad(il); // if (value) il.Brtrue(arrayIsNotNullLabel); // goto arrayIsNotNullLabel // Array is null branch il.Ldloc(context.DataPointerVar); // *(int*) data = -1 il.Ldc_I4(-1); il.Stind_I4(); il.IncreasePointer(context.DataPointerVar, sizeof(int)); // data += sizeof(int) il.Br(endOfSubmethodLabel); // goto endOfSubmethodLabel il.MarkLabel(arrayIsNotNullLabel); emitLoad(il); // if (value.Length) il.Ldlen(); // goto arrayIsNotEmptylabel il.Conv_I4(); il.Brtrue(arrayIsNotEmptylabel); // Array is empty branch il.Ldloc(context.DataPointerVar); // *(int*) data = 0 il.Ldc_I4(0); il.Stind_I4(); il.IncreasePointer(context.DataPointerVar, sizeof(int)); // data += sizeof(int) il.Br(endOfSubmethodLabel); // goto endOfSubmethodLabel // Array is not empty branch il.MarkLabel(arrayIsNotEmptylabel); var lengthVar = context.GetSharedVariable<int>("length"); // var length = value.Length emitLoad(il); il.Ldlen(); il.Conv_I4(); il.Stloc(lengthVar); var sizeVar = context.GetSharedVariable<int>("sizeInBytes");// var sizeInBytes = length * sizeOfStruct il.Ldloc(lengthVar); il.Ldc_I4(sizeOfStruct); il.Mul(); il.Stloc(sizeVar); il.Ldloc(context.DataPointerVar); // *(int*) data = length il.Ldloc(lengthVar); il.Stind_I4(); il.IncreasePointer(context.DataPointerVar, sizeof(int)); // data += sizeof(int) var pointerVar = il.PinArray(typeOfStruct, emitLoad); // var pinned arrayPointer = pin(value) il.Ldloc(context.DataPointerVar); // cpblk(data, (byte*)arrayPointer, sizeInBytes) il.Ldloc(pointerVar); il.Conv_I(); il.Ldloc(sizeVar); il.Cpblk(); il.UnpinArray(pointerVar); // unpin(arrayPointer) il.IncreasePointer(context.DataPointerVar, sizeVar); // data += sizeInBytes il.MarkLabel(endOfSubmethodLabel); }
public static void EmitEncode(this IEmittingCodec codec, IEmittingContext context, Action<MyILGenerator> emitLoadParent, MethodInfo propertyGetter) { codec.EmitEncode(context, il => { emitLoadParent(il); il.Call(propertyGetter); }); }
private static void EmitProcessAndEncodeAsyncVoid(IEmittingContext emittingContext) { var il = emittingContext.IL; il.Call(ToEmptyByteArrayTaskMethod); }
public static void EmitEncode(this IEmittingCodec codec, IEmittingContext context, int argIndex) { codec.EmitEncode(context, il => il.Ldarg(argIndex)); }
public static void EmitEncode(this IEmittingCodec codec, IEmittingContext context, LocalBuilder localVar) { codec.EmitEncode(context, il => il.Ldloc(localVar)); }
private static void EmitProcessAndEncodeAsyncWithRetval(HandlerClassBuildingContext classContext, IEmittingContext emittingContext, Type pureRetvalType) { var encodeDeferredMethod = CreateEncodeDeferredMethod(classContext, pureRetvalType); var continueWithMethod = TaskMethods.ContinueWith(pureRetvalType, typeof(byte[])); var il = emittingContext.IL; il.Ldarg(0); il.Ldftn(encodeDeferredMethod); il.Newobj(FuncMethods.Constructor(typeof(Task<>).MakeGenericType(pureRetvalType), typeof(byte[]))); il.Callvirt(continueWithMethod); }
public void EmitCalculateSize(IEmittingContext context, Action<MyILGenerator> emitLoad) { var il = context.IL; var endOfSubmethodLabel = il.DefineLabel(); if (canBeNull) { var stringIsNotNullLabel = il.DefineLabel(); emitLoad(il); // if (value) il.Brtrue(stringIsNotNullLabel); // goto stringIsNotNullLabel // String is null branch il.Ldc_I4(sizeof(int)); // stack_0 = sizeof(int) il.Br(endOfSubmethodLabel); // goto endOfSubmethodLabel // String is not null branch il.MarkLabel(stringIsNotNullLabel); // label stringIsNotNullLabel } EmitLoadAsString(il, emitLoad); // stack_0 = (FormatToString(value).Length << 1) + sizeof(int) il.Call(GetLength); il.Ldc_I4(1); il.Shl(); il.Ldc_I4(sizeof(int)); il.Add(); il.MarkLabel(endOfSubmethodLabel); // label endOfSubmethodLabel }
public void EmitEncode(IEmittingContext emittingContext) { typeCodec.EmitEncode(emittingContext, Loaders.TypeOf(type)); }
public static void EmitEncodeIndirect(this IEmittingCodec codec, IEmittingContext context, int argIndex, Type type) { codec.EmitEncode(context, il => { il.Ldarg(argIndex); il.Ldobj(type); }); }
public HandlerRetvalCodec(IEmittingContext emittingContext, Type type) { this.emittingContext = emittingContext; codec = new IndirectCodec(type); local = emittingContext.IL.DeclareLocal(type); }
public void EmitEncode(IEmittingContext context, Action<MyILGenerator> emitLoad) { var il = context.IL; var strIsNotNullLabel = il.DefineLabel(); var endOfSubmethodLabel = il.DefineLabel(); if (canBeNull) { emitLoad(il); // if (val) goto strIsNotNullLabel il.Brtrue(strIsNotNullLabel); // String is null branch il.Ldloc(context.DataPointerVar); // *(int*) data = -1 il.Ldc_I4(-1); il.Stind_I4(); il.IncreasePointer(context.DataPointerVar, sizeof(int)); // data += sizeof(int) il.Br(endOfSubmethodLabel); // goto endOfEncodeLabel // String is not null branch il.MarkLabel(strIsNotNullLabel); // label strIsNotNullLabel } var stringValueVar = context.GetSharedVariable<string>("stringValue"); // var stringValue = FormatToString(value) EmitLoadAsString(il, emitLoad); il.Stloc(stringValueVar); var tempIntegerVar = context.GetSharedVariable<int>("tempInteger"); // var tempInteger = stringValue.Length << 1 il.Ldloc(stringValueVar); il.Call(GetLength); il.Ldc_I4(1); il.Shl(); il.Stloc(tempIntegerVar); il.Ldloc(context.DataPointerVar); // *(int*)data = tempInteger il.Ldloc(tempIntegerVar); il.Stind_I4(); il.IncreasePointer(context.DataPointerVar, sizeof(int)); // data += sizeof(int) var pinnedString = il.DeclareLocal(typeof(string), true); // var pinned pinnedString = stringValue il.Ldloc(stringValueVar); il.Stloc(pinnedString); il.Ldloc(pinnedString); // stack_0 = (byte*)pinnedString il.Conv_I(); il.Call(GetOffsetToStringData); // stack_0 = stack_0 + il.Add(); // RuntimeHelpers.OffsetToStringData var charPointer = context.GetSharedVariable(typeof(char*), "charPointer");// charPointer = stack_0 il.Stloc(charPointer); il.Ldloc(context.DataPointerVar); // cpblk(data, charPointer, tempInteger) il.Ldloc(charPointer); il.Ldloc(tempIntegerVar); il.Cpblk(); il.Ldnull(); // pinnedString = null il.Stloc(pinnedString); il.IncreasePointer(context.DataPointerVar, tempIntegerVar); // data += tempInteger il.MarkLabel(endOfSubmethodLabel); // label endOfSubmethodLabel }
private static void EmitProcessAndEncodeAsyncWithRetval(HandlerClassBuildingContext classContext, IEmittingContext emittingContext, Type pureRetvalType) { var encodeDeferredMethod = CreateEncodeDeferredMethod(classContext, pureRetvalType); var continueWithMethod = TaskMethods.ContinueWith(pureRetvalType, typeof(byte[])); var il = emittingContext.IL; il.Ldarg(0); il.Ldftn(encodeDeferredMethod); il.Newobj(FuncMethods.Constructor(typeof(Task <>).MakeGenericType(pureRetvalType), typeof(byte[]))); il.Callvirt(continueWithMethod); }
public void EmitCalculateSize(IEmittingContext emittingContext) { codec.EmitCalculateSize(emittingContext, emitLoad); }
public void EmitDecode(IEmittingContext context, bool doNotCheckBounds) { var il = context.IL; var enoughBytesForLengthLabel = il.DefineLabel(); var enoughBytesForDataLabel = il.DefineLabel(); var lengthIsMinusOneLabel = il.DefineLabel(); var lengthIsZeroLabel = il.DefineLabel(); var labelGroup = new[] {lengthIsMinusOneLabel, lengthIsZeroLabel}; var lengthIsPositiveLabel = il.DefineLabel(); var endOfMethodLabel = il.DefineLabel(); if (!doNotCheckBounds) { il.Ldloc(context.RemainingBytesVar); // if (remainingBytes >= sizeof(int)) il.Ldc_I4(sizeof(int)); // goto enoughBytesForLengthLabel il.Bge(enoughBytesForLengthLabel); // not enough bytes for length il.ThrowUnexpectedEndException(); // throw new InvalidDataException(...) } // enough bytes for length il.MarkLabel(enoughBytesForLengthLabel); var lengthVar = context.GetSharedVariable<int>("length"); // var length = *(int*)data il.Ldloc(context.DataPointerVar); il.Ldind_I4(); il.Stloc(lengthVar); il.IncreasePointer(context.DataPointerVar, sizeof(int)); // data += sizeof(int) il.DecreaseInteger(context.RemainingBytesVar, sizeof(int)); // remainingBytes -= sizeof(int) il.Ldloc(lengthVar); // switch(length + 1) il.Ldc_I4(1); // case 0: goto lengthIsMinusOneLabel il.Add(); // case 1: goto lengthIsZeroLabel il.Switch(labelGroup); // default: goto lengthIsPositiveLabel il.Br(lengthIsPositiveLabel); // length is -1 il.MarkLabel(lengthIsMinusOneLabel); il.Ldnull(); // stack_0 = null il.Br(endOfMethodLabel); // goto endOfMethodLabel // length is 0 il.MarkLabel(lengthIsZeroLabel); il.Ldc_I4(0); // stack_0 = new T[0] il.Newarr(typeOfStruct); il.Br(endOfMethodLabel); // goto endOfMethodLabel // length is positive il.MarkLabel(lengthIsPositiveLabel); var sizeVar = context.GetSharedVariable<int>("sizeInBytes");// var sizeInBytes = length * sizeOfStruct il.Ldloc(lengthVar); il.Ldc_I4(sizeOfStruct); il.Mul(); il.Stloc(sizeVar); if (!doNotCheckBounds) { il.Ldloc(context.RemainingBytesVar); // if (remainingBytes >= sizeInBytes) il.Ldloc(sizeVar); // goto enoughBytesForDataLabel il.Bge(enoughBytesForDataLabel); // not enough bytes for data il.ThrowUnexpectedEndException(); // throw new InvalidDataException(...) } // enough bytes for data il.MarkLabel(enoughBytesForDataLabel); var resultVar = context.GetSharedVariable( // var result = new T[length] typeOfStruct.MakeArrayType(), "arrayOf"); il.Ldloc(lengthVar); il.Newarr(typeOfStruct); il.Stloc(resultVar); var pointerVar = il.PinArray(typeOfStruct, resultVar); // var pinned arrayPointer = pin(value) il.Ldloc(pointerVar); // cpblk((byte*)arrayPointer, data, sizeInBytes) il.Conv_I(); il.Ldloc(context.DataPointerVar); il.Ldloc(sizeVar); il.Cpblk(); il.UnpinArray(pointerVar); // unpin(arrayPointer) il.IncreasePointer(context.DataPointerVar, sizeVar); // data += size il.DecreaseInteger(context.RemainingBytesVar, sizeVar); // remainingBytes -= size il.Ldloc(resultVar); // stack_0 = result il.MarkLabel(endOfMethodLabel); }
public void EmitDecode(IEmittingContext context, bool doNotCheckBounds) { var il = context.IL; var resultIsNotNullLabel = il.DefineLabel(); var endOfSubmethodLabel = il.DefineLabel(); if (CanBeNull) { if (!doNotCheckBounds) { var canReadFlagLabel = il.DefineLabel(); il.Ldloc(context.RemainingBytesVar); // if (remainingBytes >= sizeof(int)) il.Ldc_I4(sizeof(int)); // goto canReadFlagLabel il.Bge(canReadFlagLabel); il.ThrowUnexpectedEndException(); // throw new InvalidDataException("...") il.MarkLabel(canReadFlagLabel); // label canReadFlagLabel } var flagVar = il.DeclareLocal(typeof(int)); il.Ldloc(context.DataPointerVar); // flag = *(int*) data il.Ldind_I4(); il.Stloc(flagVar); il.IncreasePointer(context.DataPointerVar, sizeof(int)); // data += sizeof(int) il.DecreaseInteger(context.RemainingBytesVar, sizeof(int)); // remainingBytes -= sizeof(int) il.Ldloc(flagVar); // if (flag) il.Brtrue(resultIsNotNullLabel); // goto resultIsNotNullLabel il.Ldnull(); // stack_0 = null il.Br(endOfSubmethodLabel); // goto endOfSubmethodLabel il.MarkLabel(resultIsNotNullLabel); // label resultIsNotNullLabel } var thisVar = il.DeclareLocal(type); if (CanBeNull) { il.Ldtoken(type); // stack_0 = (T)FormatterServices.GetUninitializedObject(typeof(T)) il.Call(GetTypeFromHandleMethod); il.Call(GetUninitializedObject); il.Castclass(type); il.Stloc(thisVar); } else { il.Ldloca(thisVar); il.Initobj(type); } foreach (var memberInfo in memberInfos) // foreach (member) { if (CanBeNull) // stack_0.member = decode() { il.Ldloc(thisVar); } else { il.Ldloca(thisVar); } memberInfo.Codec.EmitDecode(context, doNotCheckBounds); EmitSetMember(il, memberInfo.Member); } il.Ldloc(thisVar); il.MarkLabel(endOfSubmethodLabel); // label endOfSubmethodLabel }
public void EmitEncode(IEmittingContext context, Action<MyILGenerator> emitLoad) { var il = context.IL; var valueIsNotNullLabel = il.DefineLabel(); var endOfMethodLabel = il.DefineLabel(); var elemVar = il.DeclareLocal(elementType); // TElement elem emitLoad(il); // if (value) il.Brtrue(valueIsNotNullLabel); // goto valueIsNotNullLabel // value is null branch il.Ldloc(context.DataPointerVar); // *(int*) data = -1 il.Ldc_I4(-1); il.Stind_I4(); il.IncreasePointer(context.DataPointerVar, sizeof(int)); // data += sizeof(int) il.Br(endOfMethodLabel); // goto endOfMethodLabel // value is not null branch il.MarkLabel(valueIsNotNullLabel); // label valueIsNotNullLabel il.Ldloc(context.DataPointerVar); // *(int*) data = (int)value.Count EmitLoadCount(il, emitLoad); il.Stind_I4(); il.IncreasePointer(context.DataPointerVar, sizeof(int)); // data += sizeof(int) using (var loop = il.EmitForeachLoop(elementType, emitLoad)) // foreach (current in value) { loop.LoadCurrent(); // elem = current il.Stloc(elemVar); elementCodec.EmitEncode(context, elemVar); // encode(data, elem) } il.MarkLabel(endOfMethodLabel); // label endOfMethodLabel }
public void EmitEncode(IEmittingContext context, Action<MyILGenerator> emitLoad) { var il = context.IL; context.EmitLoadManualCodecFor(type); il.Ldloca(context.DataPointerVar); emitLoad(il); il.Callvirt(ManualCodecMethods.Encode(type)); }
public void EmitCalculateSize(IEmittingContext context, Action<MyILGenerator> emitLoad) { var il = context.IL; var valueIsNullOrEmptyLabel = il.DefineLabel(); var valueHasElementsLabel = il.DefineLabel(); var endOfMethodLabel = il.DefineLabel(); var elemVar = il.DeclareLocal(elementType); // T elem emitLoad(il); // if (!value) il.Brfalse(valueIsNullOrEmptyLabel); // goto valueIsNullOrEmptyLabel EmitLoadCount(il, emitLoad); // if ((int)value.Length) il.Brtrue(valueHasElementsLabel); // goto valueHasElementsLabel il.MarkLabel(valueIsNullOrEmptyLabel); // label valueIsNullOrEmptyLabel il.Ldc_I4(sizeof(int)); // stack_0 = sizeof(int) il.Br(endOfMethodLabel); // goto endOfMethodLabel il.MarkLabel(valueHasElementsLabel); // label valueHasElementsLabel il.Ldc_I4(sizeof(int)); // sum = sizeof(int) using (var loop = il.EmitForeachLoop(elementType, emitLoad)) // foreach (current in value) { loop.LoadCurrent(); // elem = current il.Stloc(elemVar); elementCodec.EmitCalculateSize(context, elemVar); // stack_1 = CalculateSize(elem) il.Add(); // stack_0 = stack_0 + stack_1 } il.MarkLabel(endOfMethodLabel); // label endOfMethodLabel }
public void EmitDecode(IEmittingContext context, bool doNotCheckBounds) { var il = context.IL; var endOfSubmethodLabel = il.DefineLabel(); if (!doNotCheckBounds) { var canReadSizeLabel = il.DefineLabel(); il.Ldloc(context.RemainingBytesVar); // if (remainingBytes >= sizeof(int)) il.Ldc_I4(sizeof(int)); // goto canReadSizeLabel il.Bge(canReadSizeLabel); il.ThrowUnexpectedEndException(); // throw new InvalidDataException("...") il.MarkLabel(canReadSizeLabel); // label canReadSizeLabel } il.Ldloc(context.DataPointerVar); // stack_0 = *(int*) data il.Ldind_I4(); var tempInteger = context.GetSharedVariable<int>("tempInteger");// var tempInteger = stack_0 il.Stloc(tempInteger); il.IncreasePointer(context.DataPointerVar, sizeof(int)); // data += sizeof(int) il.DecreaseInteger(context.RemainingBytesVar, sizeof(int)); // remainingBytes -= sizeof(int) if (canBeNull) { var strIsNotNullLabel = il.DefineLabel(); il.Ldloc(tempInteger); // if (tempInteger != -1) il.Ldc_I4(-1); // goto strIsNotNullLabel il.Bne_Un(strIsNotNullLabel); // String is null branch il.Ldnull(); // stack_0 = null il.Br(endOfSubmethodLabel); // goto endOfSubmethodLabel // String is not null branch il.MarkLabel(strIsNotNullLabel); // label strIsNotNullLabel } if (!doNotCheckBounds) { var canReadDataLabel = il.DefineLabel(); il.Ldloc(context.RemainingBytesVar); // if (remainingBytes >= tempInteger) il.Ldloc(tempInteger); // goto canReadDataLabel il.Bge(canReadDataLabel); il.ThrowUnexpectedEndException(); // throw new InvalidDataException("...") il.MarkLabel(canReadDataLabel); // label canReadDataLabel } il.Ldloc(context.DataPointerVar); // stack_0 = data il.Ldc_I4(0); // stack_1 = 0 il.Ldloc(tempInteger); // stack_2 = tempInteger >> 1 il.Ldc_I4(1); il.Shr(); il.Newobj(NewString); // stack_0 = new string(stack_0, stack_1, stack_2) EmitParseFromString(il); // stack_0 = Parse(stack_0) il.IncreasePointer(context.DataPointerVar, tempInteger); // data += tempInteger il.DecreaseInteger(context.RemainingBytesVar, tempInteger); // remainingBytes -= tempInteger il.MarkLabel(endOfSubmethodLabel); // label endOfSubmethodLabel }
public void EmitEncode(IEmittingContext emittingContext) { codec.EmitEncode(emittingContext, emitLoad); }
public void EmitDecode(IEmittingContext context, bool doNotCheckBounds) { var il = context.IL; var enoughBytesForLengthLabel = il.DefineLabel(); var enoughBytesForDataLabel = il.DefineLabel(); var lengthIsMinusOneLabel = il.DefineLabel(); var lengthIsZeroLabel = il.DefineLabel(); var labelGroup = new[] { lengthIsMinusOneLabel, lengthIsZeroLabel }; var lengthIsPositiveLabel = il.DefineLabel(); var endOfMethodLabel = il.DefineLabel(); if (!doNotCheckBounds) { il.Ldloc(context.RemainingBytesVar); // if (remainingBytes >= sizeof(int)) il.Ldc_I4(sizeof(int)); // goto enoughBytesForLengthLabel il.Bge(enoughBytesForLengthLabel); // not enough bytes for length il.ThrowUnexpectedEndException(); // throw new InvalidDataException(...) } // enough bytes for length il.MarkLabel(enoughBytesForLengthLabel); var lengthVar = context.GetSharedVariable <int>("length"); // var length = *(int*)data il.Ldloc(context.DataPointerVar); il.Ldind_I4(); il.Stloc(lengthVar); il.IncreasePointer(context.DataPointerVar, sizeof(int)); // data += sizeof(int) il.DecreaseInteger(context.RemainingBytesVar, sizeof(int)); // remainingBytes -= sizeof(int) il.Ldloc(lengthVar); // switch(length + 1) il.Ldc_I4(1); // case 0: goto lengthIsMinusOneLabel il.Add(); // case 1: goto lengthIsZeroLabel il.Switch(labelGroup); // default: goto lengthIsPositiveLabel il.Br(lengthIsPositiveLabel); // length is -1 il.MarkLabel(lengthIsMinusOneLabel); il.Ldnull(); // stack_0 = null il.Br(endOfMethodLabel); // goto endOfMethodLabel // length is 0 il.MarkLabel(lengthIsZeroLabel); il.Ldc_I4(0); // stack_0 = new T[0] il.Newarr(typeOfStruct); il.Br(endOfMethodLabel); // goto endOfMethodLabel // length is positive il.MarkLabel(lengthIsPositiveLabel); var sizeVar = context.GetSharedVariable <int>("sizeInBytes");// var sizeInBytes = length * sizeOfStruct il.Ldloc(lengthVar); il.Ldc_I4(sizeOfStruct); il.Mul(); il.Stloc(sizeVar); if (!doNotCheckBounds) { il.Ldloc(context.RemainingBytesVar); // if (remainingBytes >= sizeInBytes) il.Ldloc(sizeVar); // goto enoughBytesForDataLabel il.Bge(enoughBytesForDataLabel); // not enough bytes for data il.ThrowUnexpectedEndException(); // throw new InvalidDataException(...) } // enough bytes for data il.MarkLabel(enoughBytesForDataLabel); var resultVar = context.GetSharedVariable( // var result = new T[length] typeOfStruct.MakeArrayType(), "arrayOf"); il.Ldloc(lengthVar); il.Newarr(typeOfStruct); il.Stloc(resultVar); var pointerVar = il.PinArray(typeOfStruct, resultVar); // var pinned arrayPointer = pin(value) il.Ldloc(pointerVar); // cpblk((byte*)arrayPointer, data, sizeInBytes) il.Conv_I(); il.Ldloc(context.DataPointerVar); il.Ldloc(sizeVar); il.Cpblk(); il.UnpinArray(pointerVar); // unpin(arrayPointer) il.IncreasePointer(context.DataPointerVar, sizeVar); // data += size il.DecreaseInteger(context.RemainingBytesVar, sizeVar); // remainingBytes -= size il.Ldloc(resultVar); // stack_0 = result il.MarkLabel(endOfMethodLabel); }
public static void EmitEncode(this IEmittingCodec codec, IEmittingContext context, Action <MyILGenerator> emitLoadParent, MethodInfo propertyGetter) { codec.EmitEncode(context, il => { emitLoadParent(il); il.Call(propertyGetter); }); }
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)); } }