Skip to content

Commit

Permalink
Merge pull request #10833 from tmat/MetadataWriter-3SF
Browse files Browse the repository at this point in the history
Metadata writer refactoring (4F)
  • Loading branch information
tmat committed Apr 28, 2016
2 parents bd54434 + 38db50e commit 710e0fc
Show file tree
Hide file tree
Showing 122 changed files with 8,678 additions and 6,418 deletions.
11 changes: 4 additions & 7 deletions src/Compilers/CSharp/Portable/CodeGen/EmitArrayInitializer.cs
@@ -1,19 +1,16 @@
// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.

using System;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Diagnostics;
using System.Linq;
using System.Reflection.Metadata;
using Microsoft.CodeAnalysis.CodeGen;
using Microsoft.CodeAnalysis.CSharp.Symbols;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using Microsoft.CodeAnalysis.Text;
using ILOpCode = Microsoft.CodeAnalysis.CodeGen.ILOpCode;

namespace Microsoft.CodeAnalysis.CSharp.CodeGen
{
using Roslyn.Reflection;

internal partial class CodeGenerator
{
private enum ArrayInitializerStyle
Expand Down Expand Up @@ -312,14 +309,14 @@ private ImmutableArray<byte> GetRawData(ImmutableArray<BoundExpression> initiali
// the initial size is a guess.
// there is no point to be precise here as MemoryStream always has N + 1 storage
// and will need to be trimmed regardless
var writer = new Cci.BlobBuilder(initializers.Length * 4);
var writer = new BlobBuilder(initializers.Length * 4);

SerializeArrayRecursive(writer, initializers);

return writer.ToImmutableArray();
}

private void SerializeArrayRecursive(Cci.BlobBuilder bw, ImmutableArray<BoundExpression> inits)
private void SerializeArrayRecursive(BlobBuilder bw, ImmutableArray<BoundExpression> inits)
{
if (inits.Length != 0)
{
Expand Down
@@ -1,7 +1,7 @@
// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.

using System.Collections.Generic;
using System.Linq;
using System.Collections.Immutable;
using System.Reflection.Metadata;
using Microsoft.CodeAnalysis.CSharp.Emit;
using Microsoft.CodeAnalysis.Emit;
Expand Down Expand Up @@ -36,51 +36,9 @@ bool Cci.IArrayTypeReference.IsSZArray
}
}

IEnumerable<int> Cci.IArrayTypeReference.LowerBounds
{
get
{
var lowerBounds = this.LowerBounds;

if (lowerBounds.IsDefault)
{
return Enumerable.Repeat(0, Rank);
}
else
{
return lowerBounds;
}
}
}

uint Cci.IArrayTypeReference.Rank
{
get
{
return (uint)this.Rank;
}
}

IEnumerable<ulong> Cci.IArrayTypeReference.Sizes
{
get
{
if (this.Sizes.IsEmpty)
{
return SpecializedCollections.EmptyEnumerable<ulong>();
}

return GetSizes();
}
}

private IEnumerable<ulong> GetSizes()
{
foreach (var size in this.Sizes)
{
yield return (ulong)size;
}
}
ImmutableArray<int> Cci.IArrayTypeReference.LowerBounds => LowerBounds;
int Cci.IArrayTypeReference.Rank => Rank;
ImmutableArray<int> Cci.IArrayTypeReference.Sizes => Sizes;

void Cci.IReference.Dispatch(Cci.MetadataVisitor visitor)
{
Expand Down
Expand Up @@ -263,13 +263,12 @@ internal virtual ImmutableArray<byte> MarshallingDescriptor
}
}

uint Cci.IFieldDefinition.Offset
int Cci.IFieldDefinition.Offset
{
get
{
CheckDefinitionInvariant();
var offset = this.TypeLayoutOffset;
return (uint)(offset ?? 0);
return TypeLayoutOffset ?? 0;
}
}

Expand Down
10 changes: 6 additions & 4 deletions src/Compilers/CSharp/Portable/Emitter/Model/PEAssemblyBuilder.cs
Expand Up @@ -104,16 +104,18 @@ IEnumerable<Cci.IFileReference> Cci.IAssembly.GetFiles(EmitContext context)
return _lazyFiles;
}

uint Cci.IAssembly.Flags
AssemblyFlags Cci.IAssembly.Flags
{
get
{
AssemblyNameFlags result = _sourceAssembly.Flags & ~AssemblyNameFlags.PublicKey;
AssemblyFlags result = _sourceAssembly.Flags & ~AssemblyFlags.PublicKey;

if (!_sourceAssembly.PublicKey.IsDefaultOrEmpty)
result |= AssemblyNameFlags.PublicKey;
{
result |= AssemblyFlags.PublicKey;
}

return (uint)result;
return result;
}
}

Expand Down
Expand Up @@ -424,11 +424,11 @@ internal AssemblyHashAlgorithm AssemblyHashAlgorithm
/// This represents what the user claimed in source through the AssemblyFlagsAttribute.
/// It may be modified as emitted due to presence or absence of the public key.
/// </summary>
internal AssemblyNameFlags Flags
internal AssemblyFlags Flags
{
get
{
var defaultValue = default(AssemblyNameFlags);
var defaultValue = default(AssemblyFlags);
var fieldValue = defaultValue;

var data = GetSourceDecodedWellKnownAttributeData();
Expand Down Expand Up @@ -2202,15 +2202,15 @@ private void DecodeWellKnownAttribute(ref DecodeWellKnownAttributeArguments<Attr
else if ((signature = attribute.GetTargetAttributeSignatureIndex(this, AttributeDescription.AssemblyFlagsAttribute)) != -1)
{
object value = attribute.CommonConstructorArguments[0].Value;
System.Reflection.AssemblyNameFlags nameFlags;
AssemblyFlags nameFlags;

if (signature == 0 || signature == 1)
{
nameFlags = (System.Reflection.AssemblyNameFlags)value;
nameFlags = (AssemblyFlags)(AssemblyNameFlags)value;
}
else
{
nameFlags = (System.Reflection.AssemblyNameFlags)(uint)value;
nameFlags = (AssemblyFlags)(uint)value;
}

arguments.GetOrCreateData<CommonAssemblyWellKnownAttributeData>().AssemblyFlagsAttributeSetting = nameFlags;
Expand Down
Expand Up @@ -2207,12 +2207,12 @@ public class C
Assert.Equal(true, info.ThrowOnUnmappableCharacter);
Assert.Equal(
Cci.PInvokeAttributes.NoMangle |
Cci.PInvokeAttributes.CharSetUnicode |
Cci.PInvokeAttributes.SupportsLastError |
Cci.PInvokeAttributes.CallConvCdecl |
Cci.PInvokeAttributes.BestFitEnabled |
Cci.PInvokeAttributes.ThrowOnUnmappableCharEnabled, ((Cci.IPlatformInvokeInformation)info).Flags);
MethodImportAttributes.ExactSpelling |
MethodImportAttributes.CharSetUnicode |
MethodImportAttributes.SetLastError |
MethodImportAttributes.CallingConventionCDecl |
MethodImportAttributes.BestFitMappingEnable |
MethodImportAttributes.ThrowOnUnmappableCharEnable, ((Cci.IPlatformInvokeInformation)info).Flags);
});
}

Expand Down
10 changes: 6 additions & 4 deletions src/Compilers/CSharp/Test/Emit/Emit/CompilationEmitTests.cs
Expand Up @@ -2559,6 +2559,7 @@ public interface ITestPlatform
var refCompilation = CreateCompilation(refSource, options: TestOptions.ReleaseModule.WithPlatform(Platform.Itanium), assemblyName: "PlatformMismatch");

refCompilation.VerifyEmitDiagnostics(emitOptions);

var imageRef = refCompilation.EmitToImageReference();

string useSource = @"
Expand Down Expand Up @@ -2698,16 +2699,17 @@ public void BrokenOutStream()
var compilation = CreateCompilationWithMscorlib(source);

var output = new BrokenStream();

output.BreakHow = BrokenStream.BreakHowType.ThrowOnWrite;
var result = compilation.Emit(output);
result.Diagnostics.Verify(
// error CS8104: An error occurred while writing the Portable Executable file.
Diagnostic(ErrorCode.ERR_PeWritingFailure).WithArguments(output.ThrownException.ToString()).WithLocation(1, 1));


// Stream.Position is not called:
output.BreakHow = BrokenStream.BreakHowType.ThrowOnSetPosition;
result = compilation.Emit(output);
result.Diagnostics.Verify(
// error CS8104: An error occurred while writing the Portable Executable file.
Diagnostic(ErrorCode.ERR_PeWritingFailure).WithArguments(output.ThrownException.ToString()).WithLocation(1, 1));
result.Diagnostics.Verify();

// disposed stream is not writable
var outReal = new MemoryStream();
Expand Down
2 changes: 1 addition & 1 deletion src/Compilers/CSharp/Test/Emit/Emit/EmitMetadata.cs
Expand Up @@ -2172,7 +2172,7 @@ private void VerifyEmitWithNoResources(CSharpCompilation comp, Platform platform
[Fact]
public unsafe void PEHeaders1()
{
var options = EmitOptions.Default.WithFileAlignment(8192);
var options = EmitOptions.Default.WithFileAlignment(0x2000);
var syntax = SyntaxFactory.ParseSyntaxTree(@"class C {}", TestOptions.Regular);

var peStream = CreateCompilationWithMscorlib(
Expand Down
4 changes: 4 additions & 0 deletions src/Compilers/Core/CodeAnalysisTest/CodeAnalysisTest.csproj
Expand Up @@ -45,6 +45,10 @@
<Compile Include="MetadataReferences\AssemblyIdentityMapTests.cs" />
<Compile Include="PEWriter\BlobUtilitiesTests.cs" />
<Compile Include="PEWriter\BlobTests.cs" />
<Compile Include="PEWriter\LabelHandleTests.cs" />
<Compile Include="PEWriter\MethodBodyEncoderTests.cs" />
<Compile Include="PEWriter\MetadataBuilderTests.cs" />
<Compile Include="PEWriter\PEBuilderTests.cs" />
<Compile Include="PEWriter\UsedNamespaceOrTypeTests.cs" />
<Compile Include="RealParserTests.cs" />
<Compile Include="SimpleAnalyzerAssemblyLoaderTests.cs" />
Expand Down
13 changes: 8 additions & 5 deletions src/Compilers/Core/CodeAnalysisTest/Emit/CustomDebugInfoTests.cs
@@ -1,11 +1,12 @@
// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
extern alias PDB;


using System;
using System.Collections.Immutable;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Reflection.Metadata.Ecma335;
using Microsoft.CodeAnalysis.CodeGen;
using Microsoft.CodeAnalysis.Emit;
using PDB::Microsoft.CodeAnalysis;
Expand All @@ -14,6 +15,8 @@

namespace Microsoft.CodeAnalysis.UnitTests.Emit
{
using Roslyn.Reflection;

public class CustomDebugInfoTests
{
[Fact]
Expand Down Expand Up @@ -196,7 +199,7 @@ public void EditAndContinueLocalSlotMap_NegativeSyntaxOffsets()
var closures = ImmutableArray<ClosureDebugInfo>.Empty;
var lambdas = ImmutableArray<LambdaDebugInfo>.Empty;

var cmw = new Cci.BlobBuilder();
var cmw = new BlobBuilder();

new EditAndContinueMethodDebugInformation(123, slots, closures, lambdas).SerializeLocalSlots(cmw);

Expand All @@ -223,7 +226,7 @@ public void EditAndContinueLambdaAndClosureMap_NegativeSyntaxOffsets()
new LambdaDebugInfo(-50, new DebugId(1, 0), 0),
new LambdaDebugInfo(-180, new DebugId(2, 0), LambdaDebugInfo.StaticClosureOrdinal));

var cmw = new Cci.BlobBuilder();
var cmw = new BlobBuilder();

new EditAndContinueMethodDebugInformation(0x7b, slots, closures, lambdas).SerializeLambdaMap(cmw);

Expand All @@ -245,7 +248,7 @@ public void EditAndContinueLambdaAndClosureMap_NoClosures()
var closures = ImmutableArray<ClosureDebugInfo>.Empty;
var lambdas = ImmutableArray.Create(new LambdaDebugInfo(20, new DebugId(0, 0), LambdaDebugInfo.StaticClosureOrdinal));

var cmw = new Cci.BlobBuilder();
var cmw = new BlobBuilder();

new EditAndContinueMethodDebugInformation(-1, slots, closures, lambdas).SerializeLambdaMap(cmw);

Expand All @@ -268,7 +271,7 @@ public void EditAndContinueLambdaAndClosureMap_NoLambdas()
var closures = ImmutableArray<ClosureDebugInfo>.Empty;
var lambdas = ImmutableArray<LambdaDebugInfo>.Empty;

var cmw = new Cci.BlobBuilder();
var cmw = new BlobBuilder();

new EditAndContinueMethodDebugInformation(10, slots, closures, lambdas).SerializeLambdaMap(cmw);

Expand Down
26 changes: 15 additions & 11 deletions src/Compilers/Core/CodeAnalysisTest/PEWriter/BlobTests.cs
Expand Up @@ -5,6 +5,8 @@
using System.Collections.Immutable;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Reflection.Metadata.Ecma335;
using System.Text;
using Microsoft.Cci;
using Microsoft.CodeAnalysis.Collections;
Expand All @@ -13,6 +15,8 @@

namespace Microsoft.CodeAnalysis.UnitTests.PEWriter
{
using Roslyn.Reflection;

public class BlobTests
{
[Fact]
Expand Down Expand Up @@ -136,11 +140,11 @@ public void GetBlobs()
blobs = builder.GetBlobs().ToArray();
Assert.Equal(3, blobs.Length);
Assert.Equal(16, blobs[0].Length);
Assert.Equal(16, blobs[0].GetUnderlyingBuffer().Array.Length);
Assert.Equal(16, blobs[0].GetBytes().Array.Length);
Assert.Equal(100 - 16, blobs[1].Length);
Assert.Equal(100 - 16, blobs[1].GetUnderlyingBuffer().Array.Length);
Assert.Equal(100 - 16, blobs[1].GetBytes().Array.Length);
Assert.Equal(1, blobs[2].Length);
Assert.Equal(100 - 16, blobs[2].GetUnderlyingBuffer().Array.Length);
Assert.Equal(100 - 16, blobs[2].GetBytes().Array.Length);

builder.Clear();

Expand All @@ -149,7 +153,7 @@ public void GetBlobs()
Assert.Equal(0, blobs[0].Length);

// Clear uses the first buffer:
Assert.Equal(16, blobs[0].GetUnderlyingBuffer().Array.Length);
Assert.Equal(16, blobs[0].GetBytes().Array.Length);
}

[Fact]
Expand Down Expand Up @@ -485,9 +489,9 @@ public unsafe void Write_Errors()
public void ReserveBytes1()
{
var builder = new BlobBuilder(16);
var writer0 = builder.ReserveBytes(0);
var writer1 = builder.ReserveBytes(1);
var writer2 = builder.ReserveBytes(2);
var writer0 = new BlobWriter(builder.ReserveBytes(0));
var writer1 = new BlobWriter(builder.ReserveBytes(1));
var writer2 = new BlobWriter(builder.ReserveBytes(2));
Assert.Equal(3, builder.Count);
AssertEx.Equal(new byte[] { 0, 0, 0 }, builder.ToArray());

Expand All @@ -507,7 +511,7 @@ public void ReserveBytes1()
public void ReserveBytes2()
{
var builder = new BlobBuilder(16);
var writer = builder.ReserveBytes(17);
var writer = new BlobWriter(builder.ReserveBytes(17));
writer.WriteBytes(1, 17);

var blobs = builder.GetBlobs().ToArray();
Expand All @@ -517,7 +521,7 @@ public void ReserveBytes2()
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01
}, blobs[0].GetUnderlyingBuffer().ToArray());
}, blobs[0].GetBytes().ToArray());
}

// TODO:
Expand All @@ -530,11 +534,11 @@ public void ReserveBytes2()
private static void TestCompressedUnsignedInteger(byte[] expected, int value)
{
var writer = new BlobWriter(4);
writer.WriteCompressedInteger((uint)value);
writer.WriteCompressedInteger(value);
AssertEx.Equal(expected, writer.ToArray());

var builder = new BlobBuilder();
builder.WriteCompressedInteger((uint)value);
builder.WriteCompressedInteger(value);
AssertEx.Equal(expected, builder.ToArray());
}

Expand Down
@@ -1,6 +1,7 @@
// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.

using Microsoft.Cci;
using System.Reflection;
using Roslyn.Reflection;
using Xunit;

namespace Microsoft.CodeAnalysis.UnitTests.PEWriter
Expand Down

0 comments on commit 710e0fc

Please sign in to comment.