コード例 #1
0
            public override MethodIL EmitIL()
            {
                // Generate the unboxing stub. This loosely corresponds to following C#:
                // return BoxedValue.InstanceMethod([rest of parameters])

                ILEmitter    emit       = new ILEmitter();
                ILCodeStream codeStream = emit.NewCodeStream();

                FieldDesc boxedValueField = _owningType.BoxedValue.InstantiateAsOpen();

                // unbox to get a pointer to the value type
                codeStream.EmitLdArg(0);
                codeStream.Emit(ILOpcode.ldflda, emit.NewToken(boxedValueField));

                // Load rest of the arguments
                for (int i = 0; i < _targetMethod.Signature.Length; i++)
                {
                    codeStream.EmitLdArg(i + 1);
                }

                // Call an instance method on the target valuetype
                codeStream.Emit(ILOpcode.call, emit.NewToken(_targetMethod.InstantiateAsOpen()));
                codeStream.Emit(ILOpcode.ret);

                return(emit.Link(this));
            }
コード例 #2
0
            public override MethodIL EmitIL()
            {
                // Generate the unboxing stub. This loosely corresponds to following C#:
                // return BoxedValue.InstanceMethod(this.m_pEEType, [rest of parameters])

                ILEmitter    emit       = new ILEmitter();
                ILCodeStream codeStream = emit.NewCodeStream();

                FieldDesc eeTypeField     = Context.GetWellKnownType(WellKnownType.Object).GetKnownField("m_pEEType");
                FieldDesc boxedValueField = _owningType.BoxedValue.InstantiateAsOpen();

                // Load ByRef to the field with the value of the boxed valuetype
                codeStream.EmitLdArg(0);
                codeStream.Emit(ILOpcode.ldflda, emit.NewToken(boxedValueField));

                // Load the EEType of the boxed valuetype (this is the hidden generic context parameter expected
                // by the (canonical) instance method, but normally not part of the signature in IL).
                codeStream.EmitLdArg(0);
                codeStream.Emit(ILOpcode.ldfld, emit.NewToken(eeTypeField));

                // Load rest of the arguments
                for (int i = 0; i < _targetMethod.Signature.Length; i++)
                {
                    codeStream.EmitLdArg(i + 1);
                }

                // Call an instance method on the target valuetype that has a fake instantiation parameter
                // in it's signature. This will be swapped by the actual instance method after codegen is done.
                codeStream.Emit(ILOpcode.call, emit.NewToken(_nakedTargetMethod.InstantiateAsOpen()));
                codeStream.Emit(ILOpcode.ret);

                return(emit.Link(this));
            }
コード例 #3
0
            public override MethodIL EmitIL()
            {
                if (_owningType.BoxedValue == null)
                {
                    // If this is the fake unboxing thunk for ByRef-like types, just make a method that throws.
                    return(new ILStubMethodIL(this,
                                              new byte[] { (byte)ILOpcode.ldnull, (byte)ILOpcode.throw_ },
                                              Array.Empty <LocalVariableDefinition>(),
                                              Array.Empty <object>()));
                }

                // Generate the unboxing stub. This loosely corresponds to following C#:
                // return BoxedValue.InstanceMethod([rest of parameters])

                ILEmitter    emit       = new ILEmitter();
                ILCodeStream codeStream = emit.NewCodeStream();

                FieldDesc boxedValueField = _owningType.BoxedValue.InstantiateAsOpen();

                // unbox to get a pointer to the value type
                codeStream.EmitLdArg(0);
                codeStream.Emit(ILOpcode.ldflda, emit.NewToken(boxedValueField));

                // Load rest of the arguments
                for (int i = 0; i < _targetMethod.Signature.Length; i++)
                {
                    codeStream.EmitLdArg(i + 1);
                }

                // Call an instance method on the target valuetype
                codeStream.Emit(ILOpcode.call, emit.NewToken(_targetMethod.InstantiateAsOpen()));
                codeStream.Emit(ILOpcode.ret);

                return(emit.Link(this));
            }
コード例 #4
0
ファイル: Marshaller.Aot.cs プロジェクト: z77ma/runtime
        protected override void EmitMarshalFieldManagedToNative()
        {
            ILEmitter    emitter    = _ilCodeStreams.Emitter;
            ILCodeStream codeStream = _ilCodeStreams.MarshallingCodeStream;

            var nativeArrayType = NativeType as InlineArrayType;

            Debug.Assert(nativeArrayType != null);

            codeStream.EmitLdArg(0);
            codeStream.Emit(ILOpcode.ldfld, emitter.NewToken(_managedField));

            codeStream.EmitLdArg(1);
            codeStream.Emit(ILOpcode.ldflda, emitter.NewToken(_nativeField));
            codeStream.Emit(ILOpcode.conv_u);

            EmitElementCount(codeStream, MarshalDirection.Forward);

            if (IsAnsi)
            {
                codeStream.Emit(PInvokeFlags.BestFitMapping ? ILOpcode.ldc_i4_1 : ILOpcode.ldc_i4_0);
                codeStream.Emit(PInvokeFlags.ThrowOnUnmappableChar ? ILOpcode.ldc_i4_1 : ILOpcode.ldc_i4_0);
            }

            codeStream.Emit(ILOpcode.call, emitter.NewToken(GetManagedToNativeHelper()));
        }
コード例 #5
0
ファイル: Marshaller.Aot.cs プロジェクト: z77ma/runtime
        protected override void EmitElementCount(ILCodeStream codeStream, MarshalDirection direction)
        {
            ILEmitter emitter = _ilCodeStreams.Emitter;

            if (MarshalAsDescriptor == null || !MarshalAsDescriptor.SizeConst.HasValue)
            {
                throw new InvalidProgramException("SizeConst is required for ByValArray.");
            }

            if (direction == MarshalDirection.Forward)
            {
                // In forward direction ElementCount = Min(managed.length, SizeConst);

                var vLength  = emitter.NewLocal(Context.GetWellKnownType(WellKnownType.Int32));
                var lSmaller = emitter.NewCodeLabel();
                var lDone    = emitter.NewCodeLabel();

                codeStream.EmitLdArg(0);
                codeStream.Emit(ILOpcode.ldfld, emitter.NewToken(_managedField));

                var lNullCheck = emitter.NewCodeLabel();
                codeStream.Emit(ILOpcode.brfalse, lNullCheck);

                codeStream.EmitLdArg(0);
                codeStream.Emit(ILOpcode.ldfld, emitter.NewToken(_managedField));

                codeStream.Emit(ILOpcode.ldlen);
                codeStream.Emit(ILOpcode.conv_i4);
                codeStream.EmitStLoc(vLength);

                codeStream.EmitLabel(lNullCheck);

                Debug.Assert(MarshalAsDescriptor.SizeConst.HasValue);
                int sizeConst = (int)MarshalAsDescriptor.SizeConst.Value;

                codeStream.EmitLdc(sizeConst);
                codeStream.EmitLdLoc(vLength);
                codeStream.Emit(ILOpcode.blt, lSmaller);

                codeStream.EmitLdLoc(vLength);
                codeStream.Emit(ILOpcode.br, lDone);

                codeStream.EmitLabel(lSmaller);
                codeStream.EmitLdc(sizeConst);

                codeStream.EmitLabel(lDone);
            }
            else
            {
                // In reverse direction ElementCount = SizeConst;
                Debug.Assert(MarshalAsDescriptor.SizeConst.HasValue);
                int sizeConst = (int)MarshalAsDescriptor.SizeConst.Value;

                codeStream.EmitLdc(sizeConst);
            }
        }
            public override MethodIL EmitIL()
            {
                if (_owningType.BoxedValue == null)
                {
                    // If this is the fake unboxing thunk for ByRef-like types, just make a method that throws.
                    return(new ILStubMethodIL(this,
                                              new byte[] { (byte)ILOpcode.ldnull, (byte)ILOpcode.throw_ },
                                              Array.Empty <LocalVariableDefinition>(),
                                              Array.Empty <object>()));
                }

                // Generate the unboxing stub. This loosely corresponds to following C#:
                // return BoxedValue.InstanceMethod([rest of parameters])

                ILEmitter    emit       = new ILEmitter();
                ILCodeStream codeStream = emit.NewCodeStream();

                FieldDesc boxedValueField = _owningType.BoxedValue.InstantiateAsOpen();

                // unbox to get a pointer to the value type
                codeStream.EmitLdArg(0);
                codeStream.Emit(ILOpcode.ldflda, emit.NewToken(boxedValueField));

                // Load rest of the arguments
                for (int i = 0; i < _targetMethod.Signature.Length; i++)
                {
                    codeStream.EmitLdArg(i + 1);
                }

                TypeDesc   owner = _targetMethod.OwningType;
                MethodDesc methodToInstantiate = _targetMethod;

                if (owner.HasInstantiation)
                {
                    MetadataType instantiatedOwner = (MetadataType)owner.InstantiateAsOpen();
                    methodToInstantiate = _targetMethod.Context.GetMethodForInstantiatedType(_targetMethod, (InstantiatedType)instantiatedOwner);
                }
                if (methodToInstantiate.HasInstantiation)
                {
                    TypeSystemContext context = methodToInstantiate.Context;

                    var inst = new TypeDesc[methodToInstantiate.Instantiation.Length];
                    for (int i = 0; i < inst.Length; i++)
                    {
                        inst[i] = context.GetSignatureVariable(i, true);
                    }

                    methodToInstantiate = context.GetInstantiatedMethod(methodToInstantiate, new Instantiation(inst));
                }

                codeStream.Emit(ILOpcode.call, emit.NewToken(methodToInstantiate));
                codeStream.Emit(ILOpcode.ret);

                return(emit.Link(this));
            }
コード例 #7
0
        public override MethodIL EmitIL()
        {
            var          emitter    = new ILEmitter();
            ILCodeStream codeStream = emitter.NewCodeStream();

            codeStream.EmitLdArg(0);
            codeStream.EmitLdArg(1);
            codeStream.Emit(ILOpcode.call, emitter.NewToken(
                                InteropTypes.GetNativeFunctionPointerWrapper(Context).GetMethod(".ctor", Signature)));
            codeStream.Emit(ILOpcode.ret);
            return(emitter.Link(this));
        }
コード例 #8
0
            public override MethodIL EmitIL()
            {
                ILEmitter    emit       = new ILEmitter();
                ILCodeStream codeStream = emit.NewCodeStream();

                if (Context.Target.IsWindows)
                {
                    codeStream.MarkDebuggerStepThroughPoint();
                }

                for (int i = 0; i < Signature.Length; i++)
                {
                    codeStream.EmitLdArg(i);
                }

                if (Context.Target.IsWindows)
                {
                    codeStream.MarkDebuggerStepInPoint();
                }

                codeStream.Emit(ILOpcode.call, emit.NewToken(WrappedMethod));

                codeStream.Emit(ILOpcode.ret);

                return(emit.Link(this));
            }
コード例 #9
0
ファイル: Marshaller.Aot.cs プロジェクト: z77ma/runtime
        protected override void EmitMarshalFieldNativeToManaged()
        {
            ILEmitter    emitter    = _ilCodeStreams.Emitter;
            ILCodeStream codeStream = _ilCodeStreams.UnmarshallingCodestream;

            codeStream.EmitLdArg(1);

            codeStream.EmitLdArg(0);
            codeStream.Emit(ILOpcode.ldflda, emitter.NewToken(_nativeField));
            codeStream.Emit(ILOpcode.conv_u);

            EmitElementCount(codeStream, MarshalDirection.Reverse);

            codeStream.Emit(ILOpcode.call, emitter.NewToken(GetNativeToManagedHelper()));

            codeStream.Emit(ILOpcode.stfld, emitter.NewToken(_managedField));
        }
コード例 #10
0
    public static MethodIL EmitIL(MethodDesc method)
    {
        Debug.Assert(method.OwningType.IsDelegate);
        Debug.Assert(method.IsRuntimeImplemented);

        if (method.Name == "BeginInvoke" || method.Name == "EndInvoke")
        {
            // BeginInvoke and EndInvoke are not supported on .NET Core
            ILEmitter    emit       = new ILEmitter();
            ILCodeStream codeStream = emit.NewCodeStream();
            MethodDesc   notSupportedExceptionHelper = method.Context.GetHelperEntryPoint("ThrowHelpers", "ThrowPlatformNotSupportedException");
            codeStream.EmitCallThrowHelper(emit, notSupportedExceptionHelper);
            return(emit.Link());
        }

        if (method.Name == ".ctor")
        {
            TypeSystemContext context = method.Context;

            ILEmitter emit = new ILEmitter();

            TypeDesc   delegateType         = context.GetWellKnownType(WellKnownType.MulticastDelegate).BaseType;
            MethodDesc objectCtorMethod     = context.GetWellKnownType(WellKnownType.Object).GetDefaultConstructor();
            FieldDesc  functionPointerField = delegateType.GetKnownField("m_functionPointer");
            FieldDesc  firstParameterField  = delegateType.GetKnownField("m_firstParameter");

            ILCodeStream codeStream = emit.NewCodeStream();
            codeStream.EmitLdArg(0);
            codeStream.Emit(ILOpcode.call, emit.NewToken(objectCtorMethod));
            codeStream.EmitLdArg(0);
            codeStream.EmitLdArg(1);
            codeStream.Emit(ILOpcode.stfld, emit.NewToken(firstParameterField));
            codeStream.EmitLdArg(0);
            codeStream.EmitLdArg(2);
            codeStream.Emit(ILOpcode.stfld, emit.NewToken(functionPointerField));
            codeStream.Emit(ILOpcode.ret);

            return(emit.Link());
        }

        return(null);
    }
コード例 #11
0
            public override MethodIL EmitIL()
            {
                if (_owningType.ValueTypeRepresented.IsByRefLike)
                {
                    // If this is the fake unboxing thunk for ByRef-like types, just make a method that throws.
                    return(new ILStubMethodIL(this,
                                              new byte[] { (byte)ILOpcode.ldnull, (byte)ILOpcode.throw_ },
                                              Array.Empty <LocalVariableDefinition>(),
                                              Array.Empty <object>()));
                }

                // Generate the unboxing stub. This loosely corresponds to following C#:
                // return BoxedValue.InstanceMethod(this.m_pEEType, [rest of parameters])

                ILEmitter    emit       = new ILEmitter();
                ILCodeStream codeStream = emit.NewCodeStream();

                FieldDesc eeTypeField = Context.GetWellKnownType(WellKnownType.Object).GetKnownField("m_pEEType");

                // Load ByRef to the field with the value of the boxed valuetype
                codeStream.EmitLdArg(0);
                codeStream.Emit(ILOpcode.ldflda, emit.NewToken(Context.SystemModule.GetKnownType("System.Runtime.CompilerServices", "RawData").GetField("Data")));

                // Load the MethodTable of the boxed valuetype (this is the hidden generic context parameter expected
                // by the (canonical) instance method, but normally not part of the signature in IL).
                codeStream.EmitLdArg(0);
                codeStream.Emit(ILOpcode.ldfld, emit.NewToken(eeTypeField));

                // Load rest of the arguments
                for (int i = 0; i < _targetMethod.Signature.Length; i++)
                {
                    codeStream.EmitLdArg(i + 1);
                }

                // Call an instance method on the target valuetype that has a fake instantiation parameter
                // in it's signature. This will be swapped by the actual instance method after codegen is done.
                codeStream.Emit(ILOpcode.call, emit.NewToken(_nakedTargetMethod.InstantiateAsOpen()));
                codeStream.Emit(ILOpcode.ret);

                return(emit.Link(this));
            }
コード例 #12
0
            public override MethodIL EmitIL()
            {
                // Generate the instantiating stub. This loosely corresponds to following C#:
                // return Interface.Method(this, GetOrdinalInterface(this.m_pEEType, Index), [rest of parameters])

                ILEmitter    emit       = new ILEmitter();
                ILCodeStream codeStream = emit.NewCodeStream();

                FieldDesc  eeTypeField = Context.GetWellKnownType(WellKnownType.Object).GetKnownField("m_pEEType");
                MethodDesc getOrdinalInterfaceMethod = Context.GetHelperEntryPoint("SharedCodeHelpers", "GetOrdinalInterface");
                MethodDesc getCurrentContext         = Context.GetHelperEntryPoint("SharedCodeHelpers", "GetCurrentSharedThunkContext");

                // Load "this"
                codeStream.EmitLdArg(0);

                // Load the instantiating argument.
                if (_interfaceIndex == UseContextFromRuntime)
                {
                    codeStream.Emit(ILOpcode.call, emit.NewToken(getCurrentContext));
                }
                else
                {
                    codeStream.EmitLdArg(0);
                    codeStream.Emit(ILOpcode.ldfld, emit.NewToken(eeTypeField));
                    codeStream.EmitLdc(_interfaceIndex);
                    codeStream.Emit(ILOpcode.call, emit.NewToken(getOrdinalInterfaceMethod));
                }

                // Load rest of the arguments
                for (int i = 0; i < _targetMethod.Signature.Length; i++)
                {
                    codeStream.EmitLdArg(i + 1);
                }

                // Call an instance method on the target interface that has a fake instantiation parameter
                // in it's signature. This will be swapped by the actual instance method after codegen is done.
                codeStream.Emit(ILOpcode.call, emit.NewToken(_nakedTargetMethod));
                codeStream.Emit(ILOpcode.ret);

                return(emit.Link(this));
            }
コード例 #13
0
 public void EmitMarshallingIL(ILEmitter emitter, ILCodeStream marshallingCodeStream, ILCodeStream callsiteSetupCodeStream, ILCodeStream unmarshallingCodeStream, ILCodeStream returnValueCodeStream)
 {
     if (!PInvokeParameterMetadata.Return)
     {
         marshallingCodeStream.EmitLdArg(PInvokeParameterMetadata.Index - 1);
         NativeType = MarshalArgument(ManagedType, emitter, marshallingCodeStream, unmarshallingCodeStream);
         IL.Stubs.ILLocalVariable vMarshalledTypeTemp = emitter.NewLocal(NativeType);
         marshallingCodeStream.EmitStLoc(vMarshalledTypeTemp);
         callsiteSetupCodeStream.EmitLdLoc(vMarshalledTypeTemp);
     }
     else
     {
         NativeType = MarshalReturn(ManagedType, emitter, marshallingCodeStream, returnValueCodeStream);
     }
 }
コード例 #14
0
            public override MethodIL EmitIL()
            {
                ILEmitter    emit       = new ILEmitter();
                ILCodeStream codeStream = emit.NewCodeStream();

                for (int i = 0; i < Signature.Length; i++)
                {
                    codeStream.EmitLdArg(i);
                }

                codeStream.Emit(ILOpcode.call, emit.NewToken(_mainMethod));

                codeStream.Emit(ILOpcode.ret);

                return(emit.Link(this));
            }
コード例 #15
0
ファイル: StartupCodeMainMethod.cs プロジェクト: tedd/corert
            public override MethodIL EmitIL()
            {
                ILEmitter    emit       = new ILEmitter();
                ILCodeStream codeStream = emit.NewCodeStream();

                // We only need the initial step over sequence point if there's any instructions before the call.
                if (Signature.Length > 0)
                {
                    codeStream.MarkDebuggerStepThroughPoint();
                }

                for (int i = 0; i < Signature.Length; i++)
                {
                    codeStream.EmitLdArg(i);
                }

                codeStream.MarkDebuggerStepInPoint();

                codeStream.Emit(ILOpcode.call, emit.NewToken(WrappedMethod));

                codeStream.Emit(ILOpcode.ret);

                return(emit.Link(this));
            }
コード例 #16
0
ファイル: Marshaller.Aot.cs プロジェクト: z77ma/runtime
        protected override void EmitMarshalFieldManagedToNative()
        {
            // It generates the following code
            //if (ManagedArg.Field != null)
            //{
            //
            //  fixed (InlineArray* pUnsafe = &NativeArg.Field)
            //  {
            //        uint index = 0u;
            //        while ((ulong)index < (ulong)((long)ManagedArg.Field.Length))
            //        {
            //            NativeArg.s[index] = ManagedArg.Field[(int)index];
            //            index += 1u;
            //        }
            //  }
            //}

            ILEmitter    emitter         = _ilCodeStreams.Emitter;
            ILCodeStream codeStream      = _ilCodeStreams.MarshallingCodeStream;
            var          nativeArrayType = NativeType as InlineArrayType;

            Debug.Assert(nativeArrayType != null);
            Debug.Assert(ManagedType is ArrayType);

            var managedElementType = ((ArrayType)ManagedType).ElementType;

            ILCodeLabel lDone       = emitter.NewCodeLabel();
            ILCodeLabel lRangeCheck = emitter.NewCodeLabel();
            ILCodeLabel lLoopHeader = emitter.NewCodeLabel();

            ILLocalVariable vIndex  = emitter.NewLocal(Context.GetWellKnownType(WellKnownType.Int32));
            ILLocalVariable vLength = emitter.NewLocal(Context.GetWellKnownType(WellKnownType.Int32));
            ILLocalVariable vNative = emitter.NewLocal(NativeType.MakeByRefType(), isPinned: true);

            // check if ManagedType == null, then return
            codeStream.EmitLdArg(0);
            codeStream.Emit(ILOpcode.ldfld, emitter.NewToken(_managedField));
            codeStream.Emit(ILOpcode.brfalse, lDone);

            codeStream.EmitLdArg(1);
            codeStream.Emit(ILOpcode.ldflda, emitter.NewToken(_nativeField));
            codeStream.EmitStLoc(vNative);

            EmitElementCount(codeStream, MarshalDirection.Forward);
            codeStream.EmitStLoc(vLength);

            codeStream.EmitLdc(0);
            codeStream.EmitStLoc(vIndex);
            codeStream.Emit(ILOpcode.br, lRangeCheck);

            codeStream.EmitLabel(lLoopHeader);
            codeStream.EmitLdArg(1);
            codeStream.Emit(ILOpcode.ldflda, emitter.NewToken(_nativeField));
            codeStream.EmitLdLoc(vIndex);

            codeStream.EmitLdArg(0);
            codeStream.Emit(ILOpcode.ldfld, emitter.NewToken(_managedField));
            codeStream.EmitLdLoc(vIndex);

            codeStream.EmitLdElem(managedElementType);

            // generate marshalling IL for the element
            GetElementMarshaller(MarshalDirection.Forward)
            .EmitMarshallingIL(new PInvokeILCodeStreams(_ilCodeStreams.Emitter, codeStream));

            codeStream.Emit(ILOpcode.call, emitter.NewToken(
                                nativeArrayType.GetInlineArrayMethod(InlineArrayMethodKind.Setter)));

            codeStream.EmitLdLoc(vIndex);
            codeStream.EmitLdc(1);
            codeStream.Emit(ILOpcode.add);
            codeStream.EmitStLoc(vIndex);

            codeStream.EmitLabel(lRangeCheck);
            codeStream.EmitLdLoc(vIndex);

            codeStream.EmitLdLoc(vLength);
            codeStream.Emit(ILOpcode.blt, lLoopHeader);

            codeStream.EmitLabel(lDone);
        }
コード例 #17
0
ファイル: Marshaller.Aot.cs プロジェクト: z77ma/runtime
        protected override void EmitMarshalFieldNativeToManaged()
        {
            ILEmitter    emitter    = _ilCodeStreams.Emitter;
            ILCodeStream codeStream = _ilCodeStreams.UnmarshallingCodestream;

            // It generates the following IL:
            //  ManagedArg.s = new ElementType[Length];
            //
            //    for (uint index = 0u; index < Length; index += 1u)
            //    {
            //        ManagedArg.s[index] = NativeArg.s[index];
            //    }
            //

            ILCodeLabel lRangeCheck = emitter.NewCodeLabel();
            ILCodeLabel lLoopHeader = emitter.NewCodeLabel();

            Debug.Assert(ManagedType is ArrayType);

            var nativeArrayType = NativeType as InlineArrayType;

            Debug.Assert(nativeArrayType != null);

            var managedElementType = ((ArrayType)ManagedType).ElementType;

            ILLocalVariable vLength = emitter.NewLocal(Context.GetWellKnownType(WellKnownType.Int32));

            codeStream.EmitLdArg(1);
            // load the length
            EmitElementCount(codeStream, MarshalDirection.Reverse);
            codeStream.EmitStLoc(vLength);

            codeStream.EmitLdLoc(vLength);
            codeStream.Emit(ILOpcode.newarr, emitter.NewToken(managedElementType));
            codeStream.Emit(ILOpcode.stfld, emitter.NewToken(_managedField));


            var vIndex = emitter.NewLocal(Context.GetWellKnownType(WellKnownType.Int32));

            // index = 0
            codeStream.EmitLdc(0);
            codeStream.EmitStLoc(vIndex);
            codeStream.Emit(ILOpcode.br, lRangeCheck);

            codeStream.EmitLabel(lLoopHeader);

            // load managed type
            codeStream.EmitLdArg(1);
            codeStream.Emit(ILOpcode.ldfld, emitter.NewToken(_managedField));

            codeStream.EmitLdLoc(vIndex);

            // load native type
            codeStream.EmitLdArg(0);
            codeStream.Emit(ILOpcode.ldflda, emitter.NewToken(_nativeField));
            codeStream.EmitLdLoc(vIndex);

            codeStream.Emit(ILOpcode.call, emitter.NewToken(
                                nativeArrayType.GetInlineArrayMethod(InlineArrayMethodKind.Getter)));

            // generate marshalling IL for the element
            GetElementMarshaller(MarshalDirection.Reverse)
            .EmitMarshallingIL(new PInvokeILCodeStreams(_ilCodeStreams.Emitter, codeStream));

            codeStream.EmitStElem(managedElementType);

            codeStream.EmitLdLoc(vIndex);
            codeStream.EmitLdc(1);
            codeStream.Emit(ILOpcode.add);
            codeStream.EmitStLoc(vIndex);

            codeStream.EmitLabel(lRangeCheck);

            codeStream.EmitLdLoc(vIndex);
            codeStream.EmitLdLoc(vLength);
            codeStream.Emit(ILOpcode.blt, lLoopHeader);
        }