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 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 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 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 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 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 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 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 static LocalBuilder GetSharedVariable <T>(this IEmittingContext emittingContext, string name) { return(emittingContext.GetSharedVariable(typeof(T), name)); }