Skip to content

Commit fb70292

Browse files
LakshanFMichalStrehovsky
authored andcommitted
Draft PR to get FB (#24)
* Draft PR to get FB * Still not refactored and in draft but incorporate Sven's FB * Partial support for Local var signature * FB
1 parent 14af3ae commit fb70292

3 files changed

Lines changed: 107 additions & 6 deletions

File tree

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
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.Generic;
6+
using System.Linq;
7+
using System.Text;
8+
using System.Threading.Tasks;
9+
using System.Reflection.Metadata.Ecma335;
10+
11+
using System.Reflection.Metadata;
12+
13+
namespace ILTrim.DependencyAnalysis
14+
{
15+
public struct EcmaSignatureParser
16+
{
17+
private MetadataReader _reader;
18+
private BlobBuilder _builder;
19+
private TokenMap _tokenMap;
20+
21+
public EcmaSignatureParser(MetadataReader reader, TokenMap tokenMap)
22+
{
23+
_reader = reader;
24+
_builder = new BlobBuilder();
25+
_tokenMap = tokenMap;
26+
}
27+
28+
public byte[] GetLocalVariableBlob(StandaloneSignatureHandle handle)
29+
{
30+
StandaloneSignature standaloneSig = _reader.GetStandaloneSignature(handle);
31+
BlobReader signatureReader = _reader.GetBlobReader(standaloneSig.Signature);
32+
SignatureHeader header = signatureReader.ReadSignatureHeader();
33+
int varCount = signatureReader.ReadCompressedInteger();
34+
var blobBuilder = new BlobBuilder();
35+
var encoder = new BlobEncoder(blobBuilder);
36+
var localEncoder = encoder.LocalVariableSignature(varCount);
37+
38+
for (int i = 0; i < varCount; i++)
39+
{
40+
SignatureTypeCode typeCode = signatureReader.ReadSignatureTypeCode();
41+
switch (typeCode)
42+
{
43+
case SignatureTypeCode.TypeHandle:
44+
{
45+
var localVarTypeEncoder = localEncoder.AddVariable();
46+
47+
var signatureTypeEncoder = localVarTypeEncoder.Type();
48+
signatureTypeEncoder.Type(_tokenMap.MapToken((TypeDefinitionHandle)signatureReader.ReadTypeHandle()), isValueType: false);
49+
break;
50+
}
51+
52+
case SignatureTypeCode.Int32:
53+
{
54+
var localVarTypeEncoder = localEncoder.AddVariable();
55+
56+
var signatureTypeEncoder = localVarTypeEncoder.Type();
57+
signatureTypeEncoder.Int32();
58+
break;
59+
}
60+
61+
default:
62+
break;
63+
}
64+
}
65+
66+
return blobBuilder.ToArray();
67+
}
68+
69+
}
70+
}

src/coreclr/tools/ILTrim/ILTrim/DependencyAnalysis/TokenBased/StandaloneSignatureNode.cs

Lines changed: 34 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,10 @@
33

44
using System.Collections.Generic;
55
using System.Reflection.Metadata;
6+
using System.Reflection.Metadata.Ecma335;
7+
using System.Linq;
8+
9+
using Internal.TypeSystem;
610

711
namespace ILTrim.DependencyAnalysis
812
{
@@ -20,20 +24,44 @@ public StandaloneSignatureNode(EcmaModule module, StandaloneSignatureHandle hand
2024

2125
public override IEnumerable<DependencyListEntry> GetStaticDependencies(NodeFactory factory)
2226
{
23-
// TODO: the signature might depend on other tokens
27+
// @TODO: These need to go EcmaSignatureParser
28+
// Cannot think of a design that can move this logic to that struct
29+
30+
MetadataReader reader = _module.MetadataReader;
31+
32+
StandaloneSignature standaloneSig = reader.GetStandaloneSignature(Handle);
33+
34+
BlobReader signatureReader = reader.GetBlobReader(standaloneSig.Signature);
35+
36+
if (signatureReader.ReadSignatureHeader().Kind != SignatureKind.LocalVariables)
37+
ThrowHelper.ThrowInvalidProgramException();
38+
39+
int count = signatureReader.ReadCompressedInteger();
40+
41+
for (int i = 0; i < count; i++)
42+
{
43+
SignatureTypeCode typeCode = signatureReader.ReadSignatureTypeCode();
44+
switch (typeCode)
45+
{
46+
case SignatureTypeCode.TypeHandle:
47+
TypeDefinitionHandle typeDefHandle = (TypeDefinitionHandle)signatureReader.ReadTypeHandle();
48+
yield return new DependencyListEntry(factory.TypeDefinition(_module, typeDefHandle), "Local variable type");
49+
break;
50+
}
51+
}
52+
2453
yield break;
2554
}
2655

2756
protected override EntityHandle WriteInternal(ModuleWritingContext writeContext)
2857
{
29-
MetadataReader reader = _module.MetadataReader;
30-
StandaloneSignature standaloneSig = reader.GetStandaloneSignature(Handle);
58+
EcmaSignatureParser signatureParser = new EcmaSignatureParser(_module.MetadataReader, writeContext.TokenMap);
59+
byte[] blobBytes = signatureParser.GetLocalVariableBlob(Handle);
3160

32-
// TODO: the signature might have tokens we need to rewrite
3361
var builder = writeContext.MetadataBuilder;
3462
return builder.AddStandaloneSignature(
35-
builder.GetOrAddBlob(reader.GetBlobBytes(standaloneSig.Signature))
36-
);
63+
builder.GetOrAddBlob(blobBytes));
64+
3765
}
3866

3967
public override string ToString()

src/coreclr/tools/ILTrim/repro/Program.cs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,9 @@ interface IProgram
1313
static int FirstMethod() => 300;
1414
static int Main()
1515
{
16+
#pragma warning disable 0219
17+
IAnotherType mylocal = default;
18+
#pragma warning restore 0219
1619
return 42;
1720
}
1821
static void LastMethod(int someParameter) { }

0 commit comments

Comments
 (0)