Description
Background and motivation
For adding AssemblyBuilder.Save()
equivalent in .NET Core we have abstracted most of the System.Refleciton.Emit types and adding new implementations for them. This abstraction did not cover Label
and LocalBuilder
types and its constructors are internal, so I could not create an instance from the new ILGenerator
implementation.
API Proposal
-
For
LocalBuilder
we need to unseal theLocalBuilder
class and make it abstract, make theinternal
constructorprotected
, also add a public getter that exposes themethod
the local belongs to.namespace System.Reflection.Emit; -public sealed class LocalBuilder : System.Reflection.LocalVariableInfo +public abstract class LocalBuilder : System.Reflection.LocalVariableInfo { - internal LocalBuilder(int localIndex, Type localType, MethodInfo method, bool isPinned) { } + protected LocalBuilder() { } + public abstract MethodInfo LocalMethod { get; } }
Abstract
LocalMethod
property can be used for validation. ParentLocalVariableInfo
has public virtual properties likeLocalType
,LocalIndex
,IsPinned
. -
For
Label
struct we need a protected factory method in the abstractILGenerator
type so that we can create an instance from derived types.namespace System.Reflection.Emit; public abstract class ILGenerator { protected ILGenerator() { } ... public abstract Label DefineLabel(); + protected static Label CreateLabel(int id) { throw null; } } public readonly partial struct Label : System.IEquatable<System.Reflection.Emit.Label> { ... + public int Id { get; } }
API Usage
internal sealed class ILGeneratorImpl : ILGenerator
{
public override Label DefineLabel()
{
LabelHandle metadataLabel = _il.DefineLabel();
Label emitLabel = CreateLabel(metadataLabel.Id);
_labelTable.Add(emitLabel, metadataLabel);
return emitLabel;
}
}
Related to #92975
CC @steveharter