Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support encoding TypedReferences in signatures. #85360

Merged
merged 4 commits into from
May 1, 2023
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -3064,6 +3064,7 @@ public void Single() { }
public void String() { }
public System.Reflection.Metadata.Ecma335.SignatureTypeEncoder SZArray() { throw null; }
public void Type(System.Reflection.Metadata.EntityHandle type, bool isValueType) { }
public void TypedReference() { }
public void UInt16() { }
public void UInt32() { }
public void UInt64() { }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -885,10 +885,20 @@ public void Enum(string enumTypeName)
}
}

/// <summary>
/// Encodes a type in a signature.
/// </summary>
public readonly struct SignatureTypeEncoder
{
/// <summary>
/// The <see cref="BlobBuilder"/> where the signature is written to.
/// </summary>
public BlobBuilder Builder { get; }

/// <summary>
/// Creates a <see cref="SignatureTypeEncoder"/>.
/// </summary>
/// <param name="builder">The <see cref="BlobBuilder"/> where the signature will be wwritten.</param>
teo-tsirpanis marked this conversation as resolved.
Show resolved Hide resolved
public SignatureTypeEncoder(BlobBuilder builder)
{
Builder = builder;
Expand All @@ -904,27 +914,79 @@ private void ClassOrValue(bool isValueType)
Builder.WriteByte(isValueType ? (byte)SignatureTypeKind.ValueType : (byte)SignatureTypeKind.Class);
}

/// <summary>
/// Encodes <see cref="bool"/>.
/// </summary>
public void Boolean() => WriteTypeCode(SignatureTypeCode.Boolean);
/// <summary>
/// Encodes <see cref="char"/>.
/// </summary>
public void Char() => WriteTypeCode(SignatureTypeCode.Char);
/// <summary>
/// Encodes <see cref="sbyte"/>.
/// </summary>
public void SByte() => WriteTypeCode(SignatureTypeCode.SByte);
/// <summary>
/// Encodes <see cref="byte"/>.
/// </summary>
public void Byte() => WriteTypeCode(SignatureTypeCode.Byte);
/// <summary>
/// Encodes <see cref="short"/>.
/// </summary>
public void Int16() => WriteTypeCode(SignatureTypeCode.Int16);
/// <summary>
/// Encodes <see cref="ushort"/>.
/// </summary>
public void UInt16() => WriteTypeCode(SignatureTypeCode.UInt16);
/// <summary>
/// Encodes <see cref="int"/>.
/// </summary>
public void Int32() => WriteTypeCode(SignatureTypeCode.Int32);
/// <summary>
/// Encodes <see cref="uint"/>.
/// </summary>
public void UInt32() => WriteTypeCode(SignatureTypeCode.UInt32);
/// <summary>
/// Encodes <see cref="long"/>.
/// </summary>
public void Int64() => WriteTypeCode(SignatureTypeCode.Int64);
/// <summary>
/// Encodes <see cref="ulong"/>.
/// </summary>
public void UInt64() => WriteTypeCode(SignatureTypeCode.UInt64);
/// <summary>
/// Encodes <see cref="float"/>.
/// </summary>
public void Single() => WriteTypeCode(SignatureTypeCode.Single);
/// <summary>
/// Encodes <see cref="double"/>.
/// </summary>
public void Double() => WriteTypeCode(SignatureTypeCode.Double);
/// <summary>
/// Encodes <see cref="string"/>.
/// </summary>
public void String() => WriteTypeCode(SignatureTypeCode.String);
/// <summary>
/// Encodes <see cref="System.TypedReference"/>.
/// </summary>
public void TypedReference() => WriteTypeCode(SignatureTypeCode.TypedReference);
/// <summary>
/// Encodes <see cref="System.IntPtr"/>.
/// </summary>
public void IntPtr() => WriteTypeCode(SignatureTypeCode.IntPtr);
/// <summary>
/// Encodes <see cref="System.UIntPtr"/>.
/// </summary>
public void UIntPtr() => WriteTypeCode(SignatureTypeCode.UIntPtr);
/// <summary>
/// Encodes <see cref="object"/>.
/// </summary>
public void Object() => WriteTypeCode(SignatureTypeCode.Object);

/// <summary>
/// Writes primitive type code.
/// Encodes a primitive type.
/// </summary>
/// <param name="type">Any primitive type code except for <see cref="PrimitiveTypeCode.TypedReference"/> and <see cref="PrimitiveTypeCode.Void"/>.</param>
/// <param name="type">Any primitive type code except for <see cref="PrimitiveTypeCode.Void"/>.</param>
/// <exception cref="ArgumentOutOfRangeException"><paramref name="type"/> is not valid in this context.</exception>
public void PrimitiveType(PrimitiveTypeCode type)
{
Expand All @@ -942,14 +1004,14 @@ public void PrimitiveType(PrimitiveTypeCode type)
case PrimitiveTypeCode.UInt64:
case PrimitiveTypeCode.Single:
case PrimitiveTypeCode.Double:
case PrimitiveTypeCode.TypedReference:
case PrimitiveTypeCode.IntPtr:
case PrimitiveTypeCode.UIntPtr:
case PrimitiveTypeCode.String:
case PrimitiveTypeCode.Object:
Builder.WriteByte((byte)type);
return;

case PrimitiveTypeCode.TypedReference:
case PrimitiveTypeCode.Void:
default:
Throw.ArgumentOutOfRange(nameof(type));
Expand All @@ -958,7 +1020,7 @@ public void PrimitiveType(PrimitiveTypeCode type)
}

/// <summary>
/// Encodes an array type.
/// Starts encoding an array type.
/// Returns a pair of encoders that must be used in the order they appear in the parameter list.
/// </summary>
/// <param name="elementType">Use first, to encode the type of the element.</param>
Expand Down Expand Up @@ -1011,7 +1073,7 @@ public void Type(EntityHandle type, bool isValueType)
}

/// <summary>
/// Starts a function pointer signature.
/// Starts encoding a function pointer signature.
/// </summary>
/// <param name="convention">Calling convention.</param>
/// <param name="attributes">Function pointer attributes.</param>
Expand Down Expand Up @@ -1051,7 +1113,7 @@ public MethodSignatureEncoder FunctionPointer(
}

/// <summary>
/// Starts a generic instantiation signature.
/// Starts encoding a generic instantiation signature.
/// </summary>
/// <param name="genericType"><see cref="TypeDefinitionHandle"/> or <see cref="TypeReferenceHandle"/>.</param>
/// <param name="genericArgumentCount">Generic argument count.</param>
Expand Down Expand Up @@ -1109,7 +1171,7 @@ public void GenericTypeParameter(int parameterIndex)
}

/// <summary>
/// Starts pointer signature.
/// Starts encoding a pointer signature.
/// </summary>
public SignatureTypeEncoder Pointer()
{
Expand All @@ -1127,7 +1189,7 @@ public void VoidPointer()
}

/// <summary>
/// Starts SZ array (vector) signature.
/// Starts encoding an SZ array (vector) signature.
/// </summary>
public SignatureTypeEncoder SZArray()
{
Expand All @@ -1136,7 +1198,7 @@ public SignatureTypeEncoder SZArray()
}

/// <summary>
/// Starts a signature of a type with custom modifiers.
/// Starts encoding a signature of a type with custom modifiers.
/// </summary>
public CustomModifiersEncoder CustomModifiers()
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -972,6 +972,10 @@ public void SignatureTypeEncoder_Primitives()
AssertEx.Equal(new byte[] { 0x0E }, b.ToArray());
b.Clear();

e.TypedReference();
AssertEx.Equal(new byte[] { 0x16 }, b.ToArray());
b.Clear();

e.IntPtr();
AssertEx.Equal(new byte[] { 0x18 }, b.ToArray());
b.Clear();
Expand Down Expand Up @@ -1044,6 +1048,10 @@ public void SignatureTypeEncoder_PrimitiveType()
AssertEx.Equal(new byte[] { 0x0E }, b.ToArray());
b.Clear();

e.PrimitiveType(PrimitiveTypeCode.TypedReference);
AssertEx.Equal(new byte[] { 0x16 }, b.ToArray());
b.Clear();

e.PrimitiveType(PrimitiveTypeCode.IntPtr);
AssertEx.Equal(new byte[] { 0x18 }, b.ToArray());
b.Clear();
Expand All @@ -1057,7 +1065,6 @@ public void SignatureTypeEncoder_PrimitiveType()
b.Clear();

Assert.Throws<ArgumentOutOfRangeException>(() => e.PrimitiveType(PrimitiveTypeCode.Void));
Assert.Throws<ArgumentOutOfRangeException>(() => e.PrimitiveType(PrimitiveTypeCode.TypedReference));
Assert.Throws<ArgumentOutOfRangeException>(() => e.PrimitiveType((PrimitiveTypeCode)255));
}

Expand Down