Skip to content

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

@cston

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();
    }

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions