Пример #1
0
        public unsafe void ShouldTryAgain_Mixed()
        {
            var comp1 = CreateCompilationWithMscorlib("public class C { }", assemblyName: GetUniqueName());
            var comp2 = CreateCompilationWithMscorlib("public class D { }", assemblyName: GetUniqueName());
            using (PinnedMetadata pinned1 = new PinnedMetadata(GetMetadataBytes(comp1)),
                pinned2 = new PinnedMetadata(GetMetadataBytes(comp2)))
            {
                var assemblyIdentity1 = comp1.Assembly.Identity;
                var assemblyIdentity2 = comp2.Assembly.Identity;
                Assert.NotEqual(assemblyIdentity1, assemblyIdentity2);

                DkmUtilities.GetMetadataBytesPtrFunction gmdbpf = (AssemblyIdentity assemblyIdentity, out uint uSize) =>
                {
                    if (assemblyIdentity == assemblyIdentity1)
                    {
                        uSize = (uint)pinned1.Size;
                        return pinned1.Pointer;
                    }
                    else if (assemblyIdentity == assemblyIdentity2)
                    {
                        uSize = (uint)pinned2.Size;
                        return pinned2.Pointer;
                    }
                    else
                    {
                        Marshal.ThrowExceptionForHR(unchecked((int)MetadataUtilities.CORDBG_E_MISSING_METADATA));
                        throw ExceptionUtilities.Unreachable;
                    }
                };

                var references = ImmutableArray.Create(default(MetadataBlock));
                var unknownAssemblyIdentity = new AssemblyIdentity(GetUniqueName());
                var missingAssemblyIdentities = ImmutableArray.Create(assemblyIdentity1, unknownAssemblyIdentity, assemblyIdentity2);
                Assert.True(ExpressionCompiler.ShouldTryAgainWithMoreMetadataBlocks(gmdbpf, missingAssemblyIdentities, ref references));
                Assert.Equal(3, references.Length);

                Assert.Equal(default(MetadataBlock), references[0]);

                Assert.Equal(pinned1.Pointer, references[1].Pointer);
                Assert.Equal(pinned1.Size, references[1].Size);

                Assert.Equal(pinned2.Pointer, references[2].Pointer);
                Assert.Equal(pinned2.Size, references[2].Size);
            }
        }
Пример #2
0
        public void ImportScopeEquality()
        {
            var sources = new[] { @"
extern alias A;
using System;
using C = System;

namespace N.M 
{
   using System.Collections;

   class C1 { void F() {} }
}

namespace N.M 
{
   using System.Collections;

   class C2 { void F() {} }
}
", @"
extern alias A;
using System;
using C = System;

namespace N.M 
{
   using System.Collections;

   class C3 { void F() {} }
}

namespace N.M 
{
   using System.Collections.Generic;

   class C4 { void F() {} }
}
", @"
extern alias A;
using System;
using D = System;

namespace N.M 
{
   using System.Collections;

   class C5 { void F() {} }
}
", @"
extern alias A;
using System;

class C6 { void F() {} }
" };

            var c = CreateCompilationWithMscorlib(sources, new[] { SystemCoreRef.WithAliases(ImmutableArray.Create("A")) });
            var pdbStream = new MemoryStream();
            c.EmitToArray(EmitOptions.Default.WithDebugInformationFormat(DebugInformationFormat.PortablePdb), pdbStream: pdbStream);
            var pdbImage = pdbStream.ToImmutable();
            using (var metadata = new PinnedMetadata(pdbImage))
            {
                var mdReader = metadata.Reader;
                var writer = new StringWriter();
                var mdVisualizer = new MetadataVisualizer(mdReader, writer);
                mdVisualizer.WriteImportScope();

                AssertEx.AssertEqualToleratingWhitespaceDifferences(@"
ImportScope (index: 0x35, size: 36): 
=============================================================================================
   Parent                    Imports                                                          
=============================================================================================
1: nil (ImportScope)         'A' (#1) = 0x23000002 (AssemblyRef)                              
2: 0x35000001 (ImportScope)  Extern Alias 'A' (#1), 'System' (#7)                             
3: 0x35000001 (ImportScope)  Extern Alias 'A' (#1), 'System' (#7), 'C' (#1d) = 'System' (#7)  
4: 0x35000003 (ImportScope)  nil                                                              
5: 0x35000004 (ImportScope)  'System.Collections' (#27)                                       
6: 0x35000004 (ImportScope)  'System.Collections.Generic' (#4b)                               
7: 0x35000001 (ImportScope)  Extern Alias 'A' (#1), 'System' (#7), 'D' (#69) = 'System' (#7)  
8: 0x35000007 (ImportScope)  nil                                                              
9: 0x35000008 (ImportScope)  'System.Collections' (#27)    
", writer.ToString());
            }
        }
Пример #3
0
        public unsafe void ShouldTryAgain_Success()
        {
            var comp = CreateCompilationWithMscorlib("public class C { }");
            using (var pinned = new PinnedMetadata(GetMetadataBytes(comp)))
            {
                DkmUtilities.GetMetadataBytesPtrFunction gmdbpf = (AssemblyIdentity assemblyIdentity, out uint uSize) =>
                {
                    uSize = (uint)pinned.Size;
                    return pinned.Pointer;
                };

                var references = ImmutableArray<MetadataBlock>.Empty;
                var missingAssemblyIdentity = new AssemblyIdentity("A");
                var missingAssemblyIdentities = ImmutableArray.Create(missingAssemblyIdentity);
                Assert.True(ExpressionCompiler.ShouldTryAgainWithMoreMetadataBlocks(gmdbpf, missingAssemblyIdentities, ref references));

                var newReference = references.Single();
                Assert.Equal(pinned.Pointer, newReference.Pointer);
                Assert.Equal(pinned.Size, newReference.Size);
            }
        }
        public void SequencePointBlob()
        {
            string source = @"
class C
{
    public static void Main()
    {
        if (F())
        {
            System.Console.WriteLine(1);
        }
    }

    public static bool F() => false;
}
";
            var c = CreateCompilationWithMscorlib(source, options: TestOptions.DebugDll);

            var pdbStream = new MemoryStream();
            var peBlob = c.EmitToArray(EmitOptions.Default.WithDebugInformationFormat(DebugInformationFormat.PortablePdb), pdbStream: pdbStream);

            using (var peReader = new PEReader(peBlob))
            using (var pdbMetadata = new PinnedMetadata(pdbStream.ToImmutable()))
            {
                var mdReader = peReader.GetMetadataReader();
                var pdbReader = pdbMetadata.Reader;

                foreach (var methodHandle in mdReader.MethodDefinitions)
                {
                    var method = mdReader.GetMethodDefinition(methodHandle);
                    var methodDebugInfo = pdbReader.GetMethodDebugInformation(methodHandle);

                    var name = mdReader.GetString(method.Name);

                    TextWriter writer = new StringWriter();
                    foreach (var sp in methodDebugInfo.GetSequencePoints())
                    {
                        if (sp.IsHidden)
                        {
                            writer.WriteLine($"{sp.Offset}: <hidden>");
                        }
                        else
                        {
                            writer.WriteLine($"{sp.Offset}: ({sp.StartLine},{sp.StartColumn})-({sp.EndLine},{sp.EndColumn})");
                        }
                    }

                    var spString = writer.ToString();
                    var spBlob = pdbReader.GetBlobBytes(methodDebugInfo.SequencePointsBlob);

                    switch (name)
                    {
                        case "Main":
                            AssertEx.AssertEqualToleratingWhitespaceDifferences(@"
0: (5,5)-(5,6)
1: (6,9)-(6,17)
7: <hidden>
10: (7,9)-(7,10)
11: (8,13)-(8,41)
18: (9,9)-(9,10)
19: (10,5)-(10,6)
", spString);
                            AssertEx.Equal(new byte[] 
                            {
                                0x01, // local signature

                                0x00, // IL offset
                                0x00, // Delta Lines
                                0x01, // Delta Columns
                                0x05, // Start Line
                                0x05, // Start Column

                                0x01, // delta IL offset
                                0x00, // Delta Lines
                                0x08, // Delta Columns
                                0x02, // delta Start Line (signed compressed)
                                0x08, // delta Start Column (signed compressed)

                                0x06, // delta IL offset
                                0x00, // hidden
                                0x00, // hidden

                                0x03, // delta IL offset
                                0x00, // Delta Lines
                                0x01, // Delta Columns
                                0x02, // delta Start Line (signed compressed)
                                0x00, // delta Start Column (signed compressed)

                                0x01, // delta IL offset
                                0x00, // Delta Lines
                                0x1C, // Delta Columns
                                0x02, // delta Start Line (signed compressed)
                                0x08, // delta Start Column (signed compressed)

                                0x07, // delta IL offset
                                0x00, // Delta Lines
                                0x01, // Delta Columns
                                0x02, // delta Start Line (signed compressed)
                                0x79, // delta Start Column (signed compressed)

                                0x01, // delta IL offset
                                0x00, // Delta Lines
                                0x01, // Delta Columns
                                0x02, // delta Start Line (signed compressed)
                                0x79, // delta Start Column (signed compressed)
                            }, spBlob);
                            break;

                        case "F":
                            AssertEx.AssertEqualToleratingWhitespaceDifferences("0: (12,31)-(12,36)", spString);
                            AssertEx.Equal(new byte[] 
                            {
                                0x00, // local signature

                                0x00, // delta IL offset
                                0x00, // Delta Lines
                                0x05, // Delta Columns
                                0x0C, // Start Line
                                0x1F  // Start Column
                            }, spBlob);
                            break;
                    }
                }
            }
        }