Beispiel #1
0
 protected override void TransformNativeToManaged(ILCodeStream codeStream)
 {
     LoadNativeAddr(codeStream);
     LoadManagedAddr(codeStream);
     codeStream.Emit(ILOpcode.call, _ilCodeStreams.Emitter.NewToken(
                         InteropStateManager.GetStructMarshallingNativeToManagedThunk(ManagedType)));
 }
Beispiel #2
0
        private MethodDesc GetStructMarshallingNativeToManagedStub(TypeDesc structType)
        {
            MethodDesc stub = InteropStateManager.GetStructMarshallingNativeToManagedThunk(structType);

            Debug.Assert(stub != null);

            _structMarshallingTypes.Add(structType);
            return(stub);
        }
Beispiel #3
0
 internal IEnumerable <StructMarshallingThunks> GetStructMarshallingTypes()
 {
     foreach (var structType in _structMarshallingTypes)
     {
         yield return
             (new StructMarshallingThunks()
         {
             StructType = structType,
             NativeStructType = InteropStateManager.GetStructMarshallingNativeType(structType),
             MarshallingThunk = InteropStateManager.GetStructMarshallingManagedToNativeThunk(structType),
             UnmarshallingThunk = InteropStateManager.GetStructMarshallingNativeToManagedThunk(structType),
             CleanupThunk = InteropStateManager.GetStructMarshallingCleanupThunk(structType)
         });
     }
 }
Beispiel #4
0
        protected override void TransformNativeToManaged(ILCodeStream codeStream)
        {
            ILEmitter   emitter = _ilCodeStreams.Emitter;
            ILCodeLabel lNull   = emitter.NewCodeLabel();

            LoadManagedValue(codeStream);
            codeStream.Emit(ILOpcode.brfalse, lNull);

            LoadNativeValue(codeStream);
            LoadManagedValue(codeStream);
            codeStream.Emit(ILOpcode.call, _ilCodeStreams.Emitter.NewToken(
                                InteropStateManager.GetStructMarshallingNativeToManagedThunk(ManagedType)));

            codeStream.EmitLabel(lNull);
        }
Beispiel #5
0
        public override IEnumerable <DependencyListEntry> GetStaticDependencies(NodeFactory factory)
        {
            InteropStateManager stateManager = ((CompilerGeneratedInteropStubManager)factory.InteropStubManager)._interopStateManager;

            yield return(new DependencyListEntry(factory.NecessaryTypeSymbol(_type), "Struct Marshalling Stub"));

            // Not all StructMarshalingDataNodes require marshalling - some are only present because we want to
            // generate field offset information for Marshal.OffsetOf.
            if (MarshalHelpers.IsStructMarshallingRequired(_type))
            {
                yield return(new DependencyListEntry(factory.MethodEntrypoint(stateManager.GetStructMarshallingManagedToNativeThunk(_type)), "Struct Marshalling stub"));

                yield return(new DependencyListEntry(factory.MethodEntrypoint(stateManager.GetStructMarshallingNativeToManagedThunk(_type)), "Struct Marshalling stub"));

                yield return(new DependencyListEntry(factory.MethodEntrypoint(stateManager.GetStructMarshallingCleanupThunk(_type)), "Struct Marshalling stub"));
            }
        }
Beispiel #6
0
        protected override void TransformNativeToManaged(ILCodeStream codeStream)
        {
            ILEmitter   emitter  = _ilCodeStreams.Emitter;
            ILCodeLabel lNonNull = emitter.NewCodeLabel();

            LoadManagedValue(codeStream);
            codeStream.Emit(ILOpcode.brtrue, lNonNull);

            MethodDesc ctor = ManagedType.GetParameterlessConstructor();

            if (ctor == null)
            {
                throw new InvalidProgramException();
            }

            codeStream.Emit(ILOpcode.newobj, emitter.NewToken(ctor));
            StoreManagedValue(codeStream);

            codeStream.EmitLabel(lNonNull);
            LoadNativeAddr(codeStream);
            LoadManagedValue(codeStream);
            codeStream.Emit(ILOpcode.call, _ilCodeStreams.Emitter.NewToken(
                                InteropStateManager.GetStructMarshallingNativeToManagedThunk(ManagedType)));
        }
        public override ObjectData GetData(NodeFactory factory, bool relocsOnly = false)
        {
            // This node does not trigger generation of other nodes.
            if (relocsOnly)
            {
                return(new ObjectData(Array.Empty <byte>(), Array.Empty <Relocation>(), 1, new ISymbolDefinitionNode[] { this }));
            }

            var writer           = new NativeWriter();
            var typeMapHashTable = new VertexHashtable();

            Section hashTableSection = writer.NewSection();

            hashTableSection.Place(typeMapHashTable);

            foreach (var structType in factory.MetadataManager.GetTypesWithStructMarshalling())
            {
                // the order of data written is as follows:
                //  managed struct type
                //  NumFields<< 2 | (HasInvalidLayout ? (2:0)) | (MarshallingRequired ? (1:0))
                //  If MarshallingRequired:
                //    size
                //    struct marshalling thunk
                //    struct unmarshalling thunk
                //    struct cleanup thunk
                //  For each field field:
                //     name
                //     offset

                var nativeType = _interopStateManager.GetStructMarshallingNativeType(structType);

                Vertex marshallingData = null;
                if (MarshalHelpers.IsStructMarshallingRequired(structType))
                {
                    Vertex thunks = writer.GetTuple(
                        writer.GetUnsignedConstant(_externalReferences.GetIndex(factory.MethodEntrypoint(_interopStateManager.GetStructMarshallingManagedToNativeThunk(structType)))),
                        writer.GetUnsignedConstant(_externalReferences.GetIndex(factory.MethodEntrypoint(_interopStateManager.GetStructMarshallingNativeToManagedThunk(structType)))),
                        writer.GetUnsignedConstant(_externalReferences.GetIndex(factory.MethodEntrypoint(_interopStateManager.GetStructMarshallingCleanupThunk(structType)))));

                    uint size = (uint)nativeType.InstanceFieldSize.AsInt;
                    marshallingData = writer.GetTuple(writer.GetUnsignedConstant(size), thunks);
                }

                Vertex fieldOffsetData = null;
                for (int i = 0; i < nativeType.Fields.Length; i++)
                {
                    var row = writer.GetTuple(
                        writer.GetStringConstant(nativeType.Fields[i].Name),
                        writer.GetUnsignedConstant((uint)nativeType.Fields[i].Offset.AsInt)
                        );

                    fieldOffsetData = (fieldOffsetData != null) ? writer.GetTuple(fieldOffsetData, row) : row;
                }

                uint mask = (uint)((marshallingData != null) ? InteropDataConstants.HasMarshallers : 0) |
                            (uint)(nativeType.HasInvalidLayout ? InteropDataConstants.HasInvalidLayout : 0) |
                            (uint)(nativeType.Fields.Length << InteropDataConstants.FieldCountShift);

                Vertex data = writer.GetUnsignedConstant(mask);
                if (marshallingData != null)
                {
                    data = writer.GetTuple(data, marshallingData);
                }

                if (fieldOffsetData != null)
                {
                    data = writer.GetTuple(data, fieldOffsetData);
                }

                Vertex vertex = writer.GetTuple(
                    writer.GetUnsignedConstant(_externalReferences.GetIndex(factory.NecessaryTypeSymbol(structType))),
                    data
                    );

                int hashCode = structType.GetHashCode();
                typeMapHashTable.Append((uint)hashCode, hashTableSection.Place(vertex));
            }

            byte[] hashTableBytes = writer.Save();

            _endSymbol.SetSymbolOffset(hashTableBytes.Length);

            return(new ObjectData(hashTableBytes, Array.Empty <Relocation>(), 1, new ISymbolDefinitionNode[] { this, _endSymbol }));
        }