Skip to content

Commit 45b7c47

Browse files
committed
Move WebcilReader reflection to a helper; add lazy initialization
1 parent 6eaee63 commit 45b7c47

File tree

2 files changed

+63
-30
lines changed

2 files changed

+63
-30
lines changed
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
// Licensed to the .NET Foundation under one or more agreements.
2+
// The .NET Foundation licenses this file to you under the MIT license.
3+
4+
using System;
5+
using System.Collections.Immutable;
6+
using System.IO;
7+
using System.Reflection;
8+
using System.Runtime.InteropServices;
9+
10+
using System.Reflection.Metadata;
11+
using System.Reflection.PortableExecutable;
12+
13+
namespace Microsoft.NET.WebAssembly.Webcil;
14+
15+
16+
public sealed partial class WebcilReader
17+
{
18+
19+
// Helpers to call into System.Reflection.Metadata internals
20+
internal static class Reflection
21+
{
22+
private static Lazy<MethodInfo> _readUtf8NullTerminated = new Lazy<MethodInfo>(() =>
23+
{
24+
var mi = typeof(BlobReader).GetMethod("ReadUtf8NullTerminated", BindingFlags.NonPublic | BindingFlags.Instance);
25+
if (mi == null)
26+
{
27+
throw new InvalidOperationException("Could not find BlobReader.ReadUtf8NullTerminated");
28+
}
29+
return mi;
30+
});
31+
32+
internal static string? ReadUtf8NullTerminated(BlobReader reader) => (string?)_readUtf8NullTerminated.Value.Invoke(reader, null);
33+
34+
private static Lazy<ConstructorInfo> _codeViewDebugDirectoryDataCtor = new Lazy<ConstructorInfo>(() =>
35+
{
36+
var types = new Type[] { typeof(Guid), typeof(int), typeof(string) };
37+
var mi = typeof(CodeViewDebugDirectoryData).GetConstructor(BindingFlags.NonPublic | BindingFlags.Instance, null, types, null);
38+
if (mi == null)
39+
{
40+
throw new InvalidOperationException("Could not find CodeViewDebugDirectoryData constructor");
41+
}
42+
return mi;
43+
});
44+
45+
internal static CodeViewDebugDirectoryData MakeCodeViewDebugDirectoryData(Guid guid, int age, string path) => (CodeViewDebugDirectoryData)_codeViewDebugDirectoryDataCtor.Value.Invoke(new object[] { guid, age, path });
46+
47+
private static Lazy<ConstructorInfo> _pdbChecksumDebugDirectoryDataCtor = new Lazy<ConstructorInfo>(() =>
48+
{
49+
var types = new Type[] { typeof(string), typeof(ImmutableArray<byte>) };
50+
var mi = typeof(PdbChecksumDebugDirectoryData).GetConstructor(BindingFlags.NonPublic | BindingFlags.Instance, null, types, null);
51+
if (mi == null)
52+
{
53+
throw new InvalidOperationException("Could not find PdbChecksumDebugDirectoryData constructor");
54+
}
55+
return mi;
56+
});
57+
internal static PdbChecksumDebugDirectoryData MakePdbChecksumDebugDirectoryData(string algorithmName, ImmutableArray<byte> checksum) => (PdbChecksumDebugDirectoryData)_pdbChecksumDebugDirectoryDataCtor.Value.Invoke(new object[] { algorithmName, checksum });
58+
}
59+
}

src/libraries/Microsoft.NET.WebAssembly.Webcil/src/Webcil/WebcilReader.cs

Lines changed: 4 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
namespace Microsoft.NET.WebAssembly.Webcil;
1414

1515

16-
public sealed class WebcilReader : IDisposable
16+
public sealed partial class WebcilReader : IDisposable
1717
{
1818
// WISH:
1919
// This should be implemented in terms of System.Reflection.Internal.MemoryBlockProvider like the PEReader,
@@ -219,37 +219,11 @@ private static CodeViewDebugDirectoryData DecodeCodeViewDebugDirectoryData(BlobR
219219
return MakeCodeViewDebugDirectoryData(guid, age, path);
220220
}
221221

222-
private static string? ReadUtf8NullTerminated(BlobReader reader)
223-
{
224-
var mi = typeof(BlobReader).GetMethod("ReadUtf8NullTerminated", BindingFlags.NonPublic | BindingFlags.Instance);
225-
if (mi == null)
226-
{
227-
throw new InvalidOperationException("Could not find BlobReader.ReadUtf8NullTerminated");
228-
}
229-
return (string?)mi.Invoke(reader, null);
230-
}
222+
private static string? ReadUtf8NullTerminated(BlobReader reader) => Reflection.ReadUtf8NullTerminated(reader);
231223

232-
private static CodeViewDebugDirectoryData MakeCodeViewDebugDirectoryData(Guid guid, int age, string path)
233-
{
234-
var types = new Type[] { typeof(Guid), typeof(int), typeof(string) };
235-
var mi = typeof(CodeViewDebugDirectoryData).GetConstructor(BindingFlags.NonPublic | BindingFlags.Instance, null, types, null);
236-
if (mi == null)
237-
{
238-
throw new InvalidOperationException("Could not find CodeViewDebugDirectoryData constructor");
239-
}
240-
return (CodeViewDebugDirectoryData)mi.Invoke(new object[] { guid, age, path });
241-
}
224+
private static CodeViewDebugDirectoryData MakeCodeViewDebugDirectoryData(Guid guid, int age, string path) => Reflection.MakeCodeViewDebugDirectoryData(guid, age, path);
242225

243-
private static PdbChecksumDebugDirectoryData MakePdbChecksumDebugDirectoryData(string algorithmName, ImmutableArray<byte> checksum)
244-
{
245-
var types = new Type[] { typeof(string), typeof(ImmutableArray<byte>) };
246-
var mi = typeof(PdbChecksumDebugDirectoryData).GetConstructor(BindingFlags.NonPublic | BindingFlags.Instance, null, types, null);
247-
if (mi == null)
248-
{
249-
throw new InvalidOperationException("Could not find PdbChecksumDebugDirectoryData constructor");
250-
}
251-
return (PdbChecksumDebugDirectoryData)mi.Invoke(new object[] { algorithmName, checksum });
252-
}
226+
private static PdbChecksumDebugDirectoryData MakePdbChecksumDebugDirectoryData(string algorithmName, ImmutableArray<byte> checksum) => Reflection.MakePdbChecksumDebugDirectoryData(algorithmName, checksum);
253227

254228
public MetadataReaderProvider ReadEmbeddedPortablePdbDebugDirectoryData(DebugDirectoryEntry entry)
255229
{

0 commit comments

Comments
 (0)