Skip to content

[API Proposal]: Add protected factory method for creating Label in ILGenerator, abstract out LocalBuilder #93497

Closed
@buyaa-n

Description

@buyaa-n

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 the LocalBuilder class and make it abstract, make the internal constructor protected, also add a public getter that exposes the method 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. Parent LocalVariableInfo has public virtual properties like LocalType, LocalIndex, IsPinned.

  • For Label struct we need a protected factory method in the abstract ILGenerator 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

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions