当前位置: 首页>>代码示例>>C#>>正文


C# ILGenerator.Emit_PinArray方法代码示例

本文整理汇总了C#中System.Reflection.Emit.ILGenerator.Emit_PinArray方法的典型用法代码示例。如果您正苦于以下问题:C# ILGenerator.Emit_PinArray方法的具体用法?C# ILGenerator.Emit_PinArray怎么用?C# ILGenerator.Emit_PinArray使用的例子?那么恭喜您, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在System.Reflection.Emit.ILGenerator的用法示例。


在下文中一共展示了ILGenerator.Emit_PinArray方法的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);
        }
开发者ID:Eisenstein,项目名称:SharpRPC,代码行数:86,代码来源:NativeStructArrayCodec.cs

示例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);
        }
开发者ID:Eisenstein,项目名称:SharpRPC,代码行数:58,代码来源:NativeStructArrayCodec.cs


注:本文中的System.Reflection.Emit.ILGenerator.Emit_PinArray方法示例由纯净天空整理自Github/MSDocs等开源代码及文档管理平台,相关代码片段筛选自各路编程大神贡献的开源项目,源码版权归原作者所有,传播和使用请参考对应项目的License;未经允许,请勿转载。