Skip to content

[API Proposal]: Support ref fields in System.Reflection.Metadata.Ecma335.BlobEncoder #68309

Closed

Description

@cston

Background and motivation

Provide methods in System.Reflection.Metadata.Ecma335.BlobEncoder to more directly support emitting ref fields, consistent with the corresponding APIs provided for emitting ref parameters and ref locals.

API Proposal

Provide a FieldTypeEncoder type similar to ParameterTypeEncoder and LocalVariableTypeEncoder.

namespace System.Reflection.Metadata.Ecma335
{
    public readonly struct BlobEncoder
    {
        public FieldTypeEncoder FieldTypeEncoder();
    }

    public readonly struct FieldTypeEncoder
    {
        public BlobBuilder Builder { get; }

        public FieldTypeEncoder(BlobBuilder builder);

        public CustomModifiersEncoder CustomModifiers();

        public SignatureTypeEncoder Type(bool isByRef = false);

        public void TypedReference();
    }
}

API Usage

var blobBuilder = new BlobBuilder();
var encoder = new BlobEncoder(blobBuilder);

var fieldEncoder = encoder.FieldTypeEncoder();

// Ref custom modifiers: modopt(object)
var customModifiersEncoder = fieldEncoder.CustomModifiers();
customModifiersEncoder.AddModifier(MetadataTokens.TypeReferenceHandle(2), isOptional: true);

// Type: int&
var typeEncoder = fieldEncoder.Type(isByRef: true);
typeEncoder.PrimitiveType(PrimitiveTypeCode.Int32);

Alternative Designs

The alternative is the existing API which requires emitting SignatureTypeCode.ByReference and creating a CustomModifierEncoder explicitly. The existing API is sufficient, but inconsistent with the support for ref parameters and ref locals.

Using the existing API:

var blobBuilder = new BlobBuilder();
var encoder = new BlobEncoder(blobBuilder);

var typeEncoder = encoder.FieldSignature();

// Ref custom modifiers: modopt(object)
var customModifiersEncoder = new CustomModifiersEncoder(blobBuilder);
customModifiersEncoder.AddModifier(MetadataTokens.TypeReferenceHandle(2), isOptional: true);

// Type: int&
typeEncoder.Builder.WriteByte((byte)SignatureTypeCode.ByReference);
typeEncoder.PrimitiveType(PrimitiveTypeCode.Int32);

Risks

BlobEncoder already includes a FieldSignature method that returns an encoder for a field type, so having two distinct field encoder methods may be confusing.

    public readonly struct BlobEncoder
    {
        public SignatureTypeEncoder FieldSignature();
        public FieldTypeEncoder FieldTypeEncoder();
    }

Activity

  1. added
    api-suggestionEarly API idea and discussion, it is NOT ready for implementation
    on Apr 21, 2022
  2. ghost added
    untriagedNew issue has not been triaged by the area owner
    on Apr 21, 2022
  3. cston commented on Apr 21, 2022

    @cston
    ContributorAuthor
  4. jaredpar commented on Apr 21, 2022

    @jaredpar
    Member
  5. AaronRobinsonMSFT commented on Apr 21, 2022

    @AaronRobinsonMSFT
    Member

    @cston Will the following be needed with this new API. It is in the usage example but is also noted in the Alternative design in a manner that implies it wouldn't be needed if this new API was adopted.

    // Ref custom modifiers: modopt(object)
    var customModifiersEncoder = fieldEncoder.CustomModifiers();
    customModifiersEncoder.AddModifier(MetadataTokens.TypeReferenceHandle(2), isOptional: true);

    Edit Nevermind. A new instance is being created rather than using the existing one in the fieldEncoder instance.

  6. cston commented on Apr 21, 2022

    @cston
    ContributorAuthor

    A new instance is being created rather than using the existing one in the fieldEncoder instance.

    Actually, in both examples an instance of CustomModifiersEncoder is created. The only difference is that the proposed FieldTypeEncoder type includes a CustomModifiers() method that makes it slightly more obvious how to obtain a CustomModifiersEncoder.

    The overall difference between use of the existing API and the proposed API is small. It's perhaps just a question of whether the API for emitting fields should be aligned with the existing APIs for locals and parameters.

  7. added
    blockingMarks issues that we want to fast track in order to unblock other important work
    and removed
    untriagedNew issue has not been triaged by the area owner
    on Apr 27, 2022
  8. added this to the 7.0.0 milestone on Apr 27, 2022
  9. added
    api-ready-for-reviewAPI is ready for review, it is NOT ready for implementation
    and removed
    api-suggestionEarly API idea and discussion, it is NOT ready for implementation
    on Apr 27, 2022
  10. terrajobst commented on May 5, 2022

    @terrajobst
    Contributor

    Video

    • Let's call the method BlobEncoder just Field
    namespace System.Reflection.Metadata.Ecma335;
    
    public partial readonly struct BlobEncoder
    {
        public FieldTypeEncoder Field();
    }
    
    public readonly struct FieldTypeEncoder
    {
        public BlobBuilder Builder { get; }
    
        public FieldTypeEncoder(BlobBuilder builder);
        public CustomModifiersEncoder CustomModifiers();
        public SignatureTypeEncoder Type(bool isByRef = false);
        public void TypedReference();
    }
  11. added
    api-approvedAPI was approved in API review, it can be implemented
    and removed
    api-ready-for-reviewAPI is ready for review, it is NOT ready for implementation
    on May 5, 2022
  12. teo-tsirpanis commented on May 15, 2022

    @teo-tsirpanis
    Contributor

    I'm working on this.

  13. AaronRobinsonMSFT commented on May 15, 2022

    @AaronRobinsonMSFT
    Member

    @teo-tsirpanis Please wait for @cston to confirm he doesn't already have an implementation. Work to support ref fields is close to complete and it is possible the work has been done just not posted yet.

  14. removed
    blockingMarks issues that we want to fast track in order to unblock other important work
    on May 15, 2022
  15. cston commented on May 15, 2022

    @cston
    ContributorAuthor

    Please wait for @cston to confirm he doesn't already have an implementation.

    I have not implemented this. The compiler is currently using the existing API.

  16. AaronRobinsonMSFT commented on May 15, 2022

    @AaronRobinsonMSFT
    Member

    Thanks @cston. @teo-tsirpanis Looking forward to the PR.

  17. added a commit that references this issue on May 15, 2022
    7059a9f
  18. ghost added
    in-prThere is an active PR which will close this issue when it is merged
    on May 15, 2022
  19. ghost removed
    in-prThere is an active PR which will close this issue when it is merged
    on May 17, 2022
  20. ghost added
    in-prThere is an active PR which will close this issue when it is merged
    on May 17, 2022
  21. added a commit that references this issue on May 17, 2022
    eead8e3
  22. ghost removed
    in-prThere is an active PR which will close this issue when it is merged
    on May 17, 2022
  23. ghost locked as resolved and limited conversation to collaborators on Jun 16, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions