本文整理汇总了C#中System.Reflection.Emit.ILGenerator.Emit_UnpinArray方法的典型用法代码示例。如果您正苦于以下问题:C# ILGenerator.Emit_UnpinArray方法的具体用法?C# ILGenerator.Emit_UnpinArray怎么用?C# ILGenerator.Emit_UnpinArray使用的例子?那么恭喜您, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类System.Reflection.Emit.ILGenerator
的用法示例。
在下文中一共展示了ILGenerator.Emit_UnpinArray方法的2个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C#代码示例。
示例1: EmitDecode
public void EmitDecode(ILGenerator il, ILocalVariableCollection locals, bool doNotCheckBounds)
{
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.Emit(OpCodes.Ldloc, locals.RemainingBytes); // if (remainingBytes >= sizeof(int))
il.Emit_Ldc_I4(sizeof(int)); // goto enoughBytesForLengthLabel
il.Emit(OpCodes.Bge, enoughBytesForLengthLabel);
// not enough bytes for length
il.Emit_ThrowUnexpectedEndException(); // throw new InvalidDataException(...)
}
// enough bytes for length
il.MarkLabel(enoughBytesForLengthLabel);
var lengthVar = locals.GetOrAdd("length", // var length = *(int*)data
lil => lil.DeclareLocal(typeof(int)));
il.Emit(OpCodes.Ldloc, locals.DataPointer);
il.Emit(OpCodes.Ldind_I4);
il.Emit(OpCodes.Stloc, lengthVar);
il.Emit_IncreasePointer(locals.DataPointer, sizeof(int)); // data += sizeof(int)
il.Emit_DecreaseInteger(locals.RemainingBytes, sizeof(int));// remainingBytes -= sizeof(int)
il.Emit(OpCodes.Ldloc, lengthVar); // switch(length + 1)
il.Emit_Ldc_I4(1); // case 0: goto lengthIsMinusOneLabel
il.Emit(OpCodes.Add); // case 1: goto lengthIsZeroLabel
il.Emit(OpCodes.Switch, labelGroup); // default: goto lengthIsPositiveLabel
il.Emit(OpCodes.Br, lengthIsPositiveLabel);
// length is -1
il.MarkLabel(lengthIsMinusOneLabel);
il.Emit(OpCodes.Ldnull); // stack_0 = null
il.Emit(OpCodes.Br, endOfMethodLabel); // goto endOfMethodLabel
// length is 0
il.MarkLabel(lengthIsZeroLabel);
il.Emit_Ldc_I4(0); // stack_0 = new T[0]
il.Emit(OpCodes.Newarr, typeOfStruct);
il.Emit(OpCodes.Br, endOfMethodLabel); // goto endOfMethodLabel
// length is positive
il.MarkLabel(lengthIsPositiveLabel);
var sizeVar = locals.GetOrAdd("sizeInBytes", // var sizeInBytes = length * sizeOfStruct
lil => lil.DeclareLocal(typeof(int)));
il.Emit(OpCodes.Ldloc, lengthVar);
il.Emit_Ldc_I4(sizeOfStruct);
il.Emit(OpCodes.Mul);
il.Emit(OpCodes.Stloc, sizeVar);
if (!doNotCheckBounds)
{
il.Emit(OpCodes.Ldloc, locals.RemainingBytes); // if (remainingBytes >= sizeInBytes)
il.Emit(OpCodes.Ldloc, sizeVar); // goto enoughBytesForDataLabel
il.Emit(OpCodes.Bge, enoughBytesForDataLabel);
// not enough bytes for data
il.Emit_ThrowUnexpectedEndException(); // throw new InvalidDataException(...)
}
// enough bytes for data
il.MarkLabel(enoughBytesForDataLabel);
var resultVar = locals.GetOrAdd( // var result = new T[length]
"arrayOf" + typeOfStruct.FullName,
lil => lil.DeclareLocal(typeOfStruct.MakeArrayType()));
il.Emit(OpCodes.Ldloc, lengthVar);
il.Emit(OpCodes.Newarr, typeOfStruct);
il.Emit(OpCodes.Stloc, resultVar);
var arrayPointerVar = il.Emit_PinArray( // var pinned arrayPointer = pin(value)
typeOfStruct, locals, resultVar);
il.Emit(OpCodes.Ldloc, arrayPointerVar); // cpblk((byte*)arrayPointer, data, sizeInBytes)
il.Emit(OpCodes.Conv_I);
il.Emit(OpCodes.Ldloc, locals.DataPointer);
il.Emit(OpCodes.Ldloc, sizeVar);
il.Emit(OpCodes.Cpblk);
il.Emit_UnpinArray(arrayPointerVar); // unpin(arrayPointer)
il.Emit_IncreasePointer(locals.DataPointer, sizeVar); // data += size
il.Emit_DecreaseInteger(locals.RemainingBytes, sizeVar); // remainingBytes -= size
il.Emit(OpCodes.Ldloc, resultVar); // stack_0 = result
il.MarkLabel(endOfMethodLabel);
}
示例2: EmitEncode
public void EmitEncode(ILGenerator il, ILocalVariableCollection locals, Action<ILGenerator> emitLoad)
{
var arrayIsNotNullLabel = il.DefineLabel();
var arrayIsNotEmptylabel = il.DefineLabel();
var endOfSubmethodLabel = il.DefineLabel();
emitLoad(il); // if (value)
il.Emit(OpCodes.Brtrue, arrayIsNotNullLabel); // goto arrayIsNotNullLabel
// Array is null branch
il.Emit(OpCodes.Ldloc, locals.DataPointer); // *(int*) data = -1
il.Emit_Ldc_I4(-1);
il.Emit(OpCodes.Stind_I4);
il.Emit_IncreasePointer(locals.DataPointer, sizeof(int));// data += sizeof(int)
il.Emit(OpCodes.Br, endOfSubmethodLabel); // goto endOfSubmethodLabel
il.MarkLabel(arrayIsNotNullLabel);
emitLoad(il); // if (value.Length)
il.Emit(OpCodes.Ldlen); // goto arrayIsNotEmptylabel
il.Emit(OpCodes.Conv_I4);
il.Emit(OpCodes.Brtrue, arrayIsNotEmptylabel);
// Array is empty branch
il.Emit(OpCodes.Ldloc, locals.DataPointer); // *(int*) data = 0
il.Emit_Ldc_I4(0);
il.Emit(OpCodes.Stind_I4);
il.Emit_IncreasePointer(locals.DataPointer, sizeof(int));// data += sizeof(int)
il.Emit(OpCodes.Br, endOfSubmethodLabel); // goto endOfSubmethodLabel
// Array is not empty branch
il.MarkLabel(arrayIsNotEmptylabel);
var lengthVar = locals.GetOrAdd("length", // var length = value.Length
lil => lil.DeclareLocal(typeof(int)));
emitLoad(il);
il.Emit(OpCodes.Ldlen);
il.Emit(OpCodes.Conv_I4);
il.Emit(OpCodes.Stloc, lengthVar);
var sizeVar = locals.GetOrAdd("sizeInBytes", // var sizeInBytes = length * sizeOfStruct
lil => lil.DeclareLocal(typeof(int)));
il.Emit(OpCodes.Ldloc, lengthVar);
il.Emit_Ldc_I4(sizeOfStruct);
il.Emit(OpCodes.Mul);
il.Emit(OpCodes.Stloc, sizeVar);
il.Emit(OpCodes.Ldloc, locals.DataPointer); // *(int*) data = length
il.Emit(OpCodes.Ldloc, lengthVar);
il.Emit(OpCodes.Stind_I4);
il.Emit_IncreasePointer(locals.DataPointer, sizeof(int));// data += sizeof(int)
var arrayPointerVar = il.Emit_PinArray( // var pinned arrayPointer = pin(value)
typeOfStruct, locals, emitLoad);
il.Emit(OpCodes.Ldloc, locals.DataPointer); // cpblk(data, (byte*)arrayPointer, sizeInBytes)
il.Emit(OpCodes.Ldloc, arrayPointerVar);
il.Emit(OpCodes.Conv_I);
il.Emit(OpCodes.Ldloc, sizeVar);
il.Emit(OpCodes.Cpblk);
il.Emit_UnpinArray(arrayPointerVar); // unpin(arrayPointer)
il.Emit_IncreasePointer(locals.DataPointer, sizeVar); // data += sizeInBytes
il.MarkLabel(endOfSubmethodLabel);
}