diff --git a/src/libraries/System.Reflection.Emit/ref/System.Reflection.Emit.cs b/src/libraries/System.Reflection.Emit/ref/System.Reflection.Emit.cs index 71a79c36dc91b3..2847b868711dec 100644 --- a/src/libraries/System.Reflection.Emit/ref/System.Reflection.Emit.cs +++ b/src/libraries/System.Reflection.Emit/ref/System.Reflection.Emit.cs @@ -479,7 +479,6 @@ public sealed class PersistedAssemblyBuilder : System.Reflection.Emit.AssemblyBu { public PersistedAssemblyBuilder(System.Reflection.AssemblyName name, System.Reflection.Assembly coreAssembly, System.Collections.Generic.IEnumerable? assemblyAttributes = null) { } public override string? FullName { get { throw null; } } - public override bool IsDynamic { get { throw null; } } public override System.Reflection.Module ManifestModule { get { throw null; } } [System.Diagnostics.CodeAnalysis.RequiresDynamicCode("Defining a dynamic assembly requires dynamic code.")] protected override System.Reflection.Emit.ModuleBuilder DefineDynamicModuleCore(string name) { throw null; } diff --git a/src/libraries/System.Reflection.Emit/src/System/Reflection/Emit/ILGeneratorImpl.cs b/src/libraries/System.Reflection.Emit/src/System/Reflection/Emit/ILGeneratorImpl.cs index ef186a685a397c..1ac507c16ee8b8 100644 --- a/src/libraries/System.Reflection.Emit/src/System/Reflection/Emit/ILGeneratorImpl.cs +++ b/src/libraries/System.Reflection.Emit/src/System/Reflection/Emit/ILGeneratorImpl.cs @@ -30,7 +30,8 @@ internal sealed class ILGeneratorImpl : ILGenerator private int _localCount; private Dictionary _labelTable = new(2); private List> _memberReferences = new(); - private List _exceptionStack = new(); + private List _exceptionStack = new(); // tracks the exception nesting + private List _exceptionBlocks = new(); // keeps all ExceptionHandler blocks private Dictionary> _documentToSequencePoints = new(); internal ILGeneratorImpl(MethodBuilderImpl methodBuilder, int size) @@ -54,6 +55,32 @@ internal ILGeneratorImpl(MethodBuilderImpl methodBuilder, int size) internal Scope Scope => _scope; internal Dictionary> DocumentToSequencePoints => _documentToSequencePoints; + internal void AddExceptionBlocks() + { + foreach(ExceptionHandlerInfo eb in _exceptionBlocks) + { + switch (eb.Kind) + { + case ExceptionRegionKind.Catch: + _cfBuilder.AddCatchRegion(GetMetaLabel(eb.TryStart), GetMetaLabel(eb.TryEnd), + GetMetaLabel(eb.HandlerStart), GetMetaLabel(eb.HandlerEnd), _moduleBuilder.GetTypeHandle(eb.ExceptionType!)); + break; + case ExceptionRegionKind.Filter: + _cfBuilder.AddFilterRegion(GetMetaLabel(eb.TryStart), GetMetaLabel(eb.TryEnd), + GetMetaLabel(eb.HandlerStart), GetMetaLabel(eb.HandlerEnd), GetMetaLabel(eb.FilterStart)); + break; + case ExceptionRegionKind.Fault: + _cfBuilder.AddFaultRegion(GetMetaLabel(eb.TryStart), GetMetaLabel(eb.TryEnd), + GetMetaLabel(eb.HandlerStart), GetMetaLabel(eb.HandlerEnd)); + break; + case ExceptionRegionKind.Finally: + _cfBuilder.AddFinallyRegion(GetMetaLabel(eb.TryStart), GetMetaLabel(eb.TryEnd), + GetMetaLabel(eb.HandlerStart), GetMetaLabel(eb.HandlerEnd)); + break; + } + } + } + public override int ILOffset => _il.Offset; public override void BeginCatchBlock(Type? exceptionType) @@ -91,8 +118,8 @@ public override void BeginCatchBlock(Type? exceptionType) currentExBlock.HandleStart = DefineLabel(); currentExBlock.HandleEnd = DefineLabel(); - _cfBuilder.AddCatchRegion(GetMetaLabel(currentExBlock.TryStart), GetMetaLabel(currentExBlock.TryEnd), - GetMetaLabel(currentExBlock.HandleStart), GetMetaLabel(currentExBlock.HandleEnd), _moduleBuilder.GetTypeHandle(exceptionType)); + _exceptionBlocks.Add(new ExceptionHandlerInfo(ExceptionRegionKind.Catch, currentExBlock.TryStart, + currentExBlock.TryEnd, currentExBlock.HandleStart, currentExBlock.HandleEnd, default, exceptionType)); MarkLabel(currentExBlock.HandleStart); } @@ -124,9 +151,9 @@ public override void BeginExceptFilterBlock() currentExBlock.FilterStart = DefineLabel(); currentExBlock.HandleStart = DefineLabel(); currentExBlock.HandleEnd = DefineLabel(); - _cfBuilder.AddFilterRegion(GetMetaLabel(currentExBlock.TryStart), GetMetaLabel(currentExBlock.TryEnd), - GetMetaLabel(currentExBlock.HandleStart), GetMetaLabel(currentExBlock.HandleEnd), GetMetaLabel(currentExBlock.FilterStart)); currentExBlock.State = ExceptionState.Filter; + _exceptionBlocks.Add(new ExceptionHandlerInfo(ExceptionRegionKind.Filter, currentExBlock.TryStart, + currentExBlock.TryEnd, currentExBlock.HandleStart, currentExBlock.HandleEnd, currentExBlock.FilterStart)); MarkLabel(currentExBlock.FilterStart); // Stack depth for "filter" starts at one. _currentStackDepth = 1; @@ -166,8 +193,8 @@ public override void BeginFaultBlock() currentExBlock.HandleStart = DefineLabel(); currentExBlock.HandleEnd = DefineLabel(); - _cfBuilder.AddFaultRegion(GetMetaLabel(currentExBlock.TryStart), GetMetaLabel(currentExBlock.TryEnd), - GetMetaLabel(currentExBlock.HandleStart), GetMetaLabel(currentExBlock.HandleEnd)); + _exceptionBlocks.Add(new ExceptionHandlerInfo(ExceptionRegionKind.Fault, currentExBlock.TryStart, + currentExBlock.TryEnd, currentExBlock.HandleStart, currentExBlock.HandleEnd)); currentExBlock.State = ExceptionState.Fault; MarkLabel(currentExBlock.HandleStart); // Stack depth for "fault" starts at zero. @@ -197,8 +224,8 @@ public override void BeginFinallyBlock() MarkLabel(currentExBlock.TryEnd); currentExBlock.HandleStart = DefineLabel(); currentExBlock.HandleEnd = finallyEndLabel; - _cfBuilder.AddFinallyRegion(GetMetaLabel(currentExBlock.TryStart), GetMetaLabel(currentExBlock.TryEnd), - GetMetaLabel(currentExBlock.HandleStart), GetMetaLabel(currentExBlock.HandleEnd)); + _exceptionBlocks.Add(new ExceptionHandlerInfo(ExceptionRegionKind.Finally, currentExBlock.TryStart, + currentExBlock.TryEnd, currentExBlock.HandleStart, currentExBlock.HandleEnd)); currentExBlock.State = ExceptionState.Finally; MarkLabel(currentExBlock.HandleStart); // Stack depth for "finally" starts at zero. @@ -835,6 +862,31 @@ internal sealed class ExceptionBlock public ExceptionState State; } + internal struct ExceptionHandlerInfo + { + public readonly ExceptionRegionKind Kind; + public readonly Label TryStart, TryEnd, HandlerStart, HandlerEnd, FilterStart; + public Type? ExceptionType; + + public ExceptionHandlerInfo( + ExceptionRegionKind kind, + Label tryStart, + Label tryEnd, + Label handlerStart, + Label handlerEnd, + Label filterStart = default, + Type? catchType = null) + { + Kind = kind; + TryStart = tryStart; + TryEnd = tryEnd; + HandlerStart = handlerStart; + HandlerEnd = handlerEnd; + FilterStart = filterStart; + ExceptionType = catchType; + } + } + internal enum ExceptionState { Undefined, diff --git a/src/libraries/System.Reflection.Emit/src/System/Reflection/Emit/ModuleBuilderImpl.cs b/src/libraries/System.Reflection.Emit/src/System/Reflection/Emit/ModuleBuilderImpl.cs index a8685230ad4949..513df134b75a50 100644 --- a/src/libraries/System.Reflection.Emit/src/System/Reflection/Emit/ModuleBuilderImpl.cs +++ b/src/libraries/System.Reflection.Emit/src/System/Reflection/Emit/ModuleBuilderImpl.cs @@ -357,6 +357,7 @@ private void WriteMethods(List methods, List