From 5fb0bf5894a6484c1594628b1bd919adf2137ce4 Mon Sep 17 00:00:00 2001 From: Theodore Tsirpanis Date: Tue, 14 Dec 2021 23:15:14 +0200 Subject: [PATCH 1/2] Make `ControlFlowBuilder.Clear` public. --- .../ref/System.Reflection.Metadata.cs | 1 + .../Ecma335/Encoding/ControlFlowBuilder.cs | 5 +++- .../Encoding/ControlFlowBuilderTests.cs | 29 +++++++++++++++++++ 3 files changed, 34 insertions(+), 1 deletion(-) diff --git a/src/libraries/System.Reflection.Metadata/ref/System.Reflection.Metadata.cs b/src/libraries/System.Reflection.Metadata/ref/System.Reflection.Metadata.cs index 27bf37ab916fd0..fee9b78b71fa02 100644 --- a/src/libraries/System.Reflection.Metadata/ref/System.Reflection.Metadata.cs +++ b/src/libraries/System.Reflection.Metadata/ref/System.Reflection.Metadata.cs @@ -2533,6 +2533,7 @@ public void AddCatchRegion(System.Reflection.Metadata.Ecma335.LabelHandle trySta public void AddFaultRegion(System.Reflection.Metadata.Ecma335.LabelHandle tryStart, System.Reflection.Metadata.Ecma335.LabelHandle tryEnd, System.Reflection.Metadata.Ecma335.LabelHandle handlerStart, System.Reflection.Metadata.Ecma335.LabelHandle handlerEnd) { } public void AddFilterRegion(System.Reflection.Metadata.Ecma335.LabelHandle tryStart, System.Reflection.Metadata.Ecma335.LabelHandle tryEnd, System.Reflection.Metadata.Ecma335.LabelHandle handlerStart, System.Reflection.Metadata.Ecma335.LabelHandle handlerEnd, System.Reflection.Metadata.Ecma335.LabelHandle filterStart) { } public void AddFinallyRegion(System.Reflection.Metadata.Ecma335.LabelHandle tryStart, System.Reflection.Metadata.Ecma335.LabelHandle tryEnd, System.Reflection.Metadata.Ecma335.LabelHandle handlerStart, System.Reflection.Metadata.Ecma335.LabelHandle handlerEnd) { } + public void Clear() { } } public readonly partial struct CustomAttributeArrayTypeEncoder { diff --git a/src/libraries/System.Reflection.Metadata/src/System/Reflection/Metadata/Ecma335/Encoding/ControlFlowBuilder.cs b/src/libraries/System.Reflection.Metadata/src/System/Reflection/Metadata/Ecma335/Encoding/ControlFlowBuilder.cs index bbe2809461b800..037ddf639c963c 100644 --- a/src/libraries/System.Reflection.Metadata/src/System/Reflection/Metadata/Ecma335/Encoding/ControlFlowBuilder.cs +++ b/src/libraries/System.Reflection.Metadata/src/System/Reflection/Metadata/Ecma335/Encoding/ControlFlowBuilder.cs @@ -85,7 +85,10 @@ public ControlFlowBuilder() _labels = ImmutableArray.CreateBuilder(); } - internal void Clear() + /// + /// Clears the object's internal state, allowing the same instance to be reused. + /// + public void Clear() { _branches.Clear(); _labels.Clear(); diff --git a/src/libraries/System.Reflection.Metadata/tests/Metadata/Ecma335/Encoding/ControlFlowBuilderTests.cs b/src/libraries/System.Reflection.Metadata/tests/Metadata/Ecma335/Encoding/ControlFlowBuilderTests.cs index d97701818feddd..d51b4f53824c8e 100644 --- a/src/libraries/System.Reflection.Metadata/tests/Metadata/Ecma335/Encoding/ControlFlowBuilderTests.cs +++ b/src/libraries/System.Reflection.Metadata/tests/Metadata/Ecma335/Encoding/ControlFlowBuilderTests.cs @@ -418,5 +418,34 @@ public void Branch_LongInstruction_LongDistance() (byte)ILOpCode.Ret }, builder.ToArray()); } + + [Fact] + public void Clear() + { + var cfb = new ControlFlowBuilder(); + + var il1 = GenerateSampleIL(cfb); + cfb.Clear(); + var il2 = GenerateSampleIL(cfb); + + AssertEx.Equal(il1, il2); + + static byte[] GenerateSampleIL(ControlFlowBuilder cfb) + { + var code = new BlobBuilder(); + var il = new InstructionEncoder(code, cfb); + + var label = il.DefineLabel(); + + il.MarkLabel(label); + il.OpCode(ILOpCode.Nop); + il.Branch(ILOpCode.Br_s, label); + + var builder = new BlobBuilder(); + new MethodBodyStreamEncoder(builder).AddMethodBody(il); + + return builder.ToArray(); + } + } } } From 303bdaa69c8a734a0cb73b5da2915c9cf0ab0d87 Mon Sep 17 00:00:00 2001 From: Theodore Tsirpanis Date: Wed, 15 Dec 2021 00:41:46 +0200 Subject: [PATCH 2/2] Test that exception handlers are cleared as well. --- .../Ecma335/Encoding/ControlFlowBuilderTests.cs | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/src/libraries/System.Reflection.Metadata/tests/Metadata/Ecma335/Encoding/ControlFlowBuilderTests.cs b/src/libraries/System.Reflection.Metadata/tests/Metadata/Ecma335/Encoding/ControlFlowBuilderTests.cs index d51b4f53824c8e..93e3ab418286c9 100644 --- a/src/libraries/System.Reflection.Metadata/tests/Metadata/Ecma335/Encoding/ControlFlowBuilderTests.cs +++ b/src/libraries/System.Reflection.Metadata/tests/Metadata/Ecma335/Encoding/ControlFlowBuilderTests.cs @@ -435,11 +435,21 @@ static byte[] GenerateSampleIL(ControlFlowBuilder cfb) var code = new BlobBuilder(); var il = new InstructionEncoder(code, cfb); - var label = il.DefineLabel(); + var l1 = il.DefineLabel(); + var l2 = il.DefineLabel(); + var l3 = il.DefineLabel(); + var l4 = il.DefineLabel(); - il.MarkLabel(label); + il.MarkLabel(l1); il.OpCode(ILOpCode.Nop); - il.Branch(ILOpCode.Br_s, label); + il.Branch(ILOpCode.Br_s, l1); + il.MarkLabel(l2); + il.OpCode(ILOpCode.Nop); + il.MarkLabel(l3); + il.OpCode(ILOpCode.Nop); + il.MarkLabel(l4); + + cfb.AddCatchRegion(l1, l2, l3, l4, MetadataTokens.TypeDefinitionHandle(1)); var builder = new BlobBuilder(); new MethodBodyStreamEncoder(builder).AddMethodBody(il);