Skip to content
Open
Show file tree
Hide file tree
Changes from all 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 @@ -840,6 +840,12 @@ internal override void ResolveToken(int token, out IntPtr typeHandle, out IntPtr
#endregion
}

/// <summary>
/// Provides support for alternative ways to generate the Microsoft intermediate language (MSIL) and metadata for a dynamic method, including methods for creating tokens and for inserting the code, exception handling, and local variable signature blobs.
/// </summary>
/// <remarks>
/// For more information about this API, see <see href="https://github.com/dotnet/docs/raw/main/docs/fundamentals/runtime-libraries/system-reflection-emit-dynamicilinfo.md">Supplemental API remarks for DynamicILInfo</see>.
/// </remarks>
public class DynamicILInfo
{
#region Private Data Members
Expand Down Expand Up @@ -878,15 +884,45 @@ internal void GetCallableMethod(RuntimeModule module, DynamicMethod dm)
#endregion

#region Public ILGenerator Methods
/// <summary>
/// Gets the dynamic method whose body is generated by the current instance.
/// </summary>
/// <value>A <see cref="DynamicMethod" /> object representing the dynamic method for which the current <see cref="DynamicILInfo" /> object is generating code.</value>
/// <remarks>
/// A <see cref="DynamicILInfo" /> object is always associated with a dynamic method. The purpose of the <see cref="DynamicILInfo" /> class is to provide another way of inserting the MSIL stream, exception handling, and local variable signature into a dynamic method, for developers who want to generate MSIL without using the <see cref="ILGenerator" /> class.
/// </remarks>
public DynamicMethod DynamicMethod => m_method;
internal DynamicScope DynamicScope => m_scope;

/// <summary>
/// Sets the code body of the associated dynamic method.
/// </summary>
/// <param name="code">An array that contains the MSIL stream.</param>
/// <param name="maxStackSize">The maximum number of items on the operand stack when the method is executing.</param>
/// <remarks>
/// No validity checks are performed on the MSIL stream.
/// <para>Calling this method a second time replaces the first MSIL stream with the second.</para>
/// <para>Generating your own metadata and MSIL requires familiarity with the Common Language Infrastructure (CLI) documentation, especially "Partition II: Metadata Definition and Semantics" and "Partition III: CIL Instruction Set". For more information, see <see href="https://www.ecma-international.org/publications-and-standards/standards/ecma-335/">ECMA 335 Common Language Infrastructure (CLI)</see>.</para>
/// </remarks>
public void SetCode(byte[]? code, int maxStackSize)
{
m_code = (code != null) ? (byte[])code.Clone() : [];
m_maxStackSize = maxStackSize;
}

/// <summary>
/// Sets the code body of the associated dynamic method.
/// </summary>
/// <param name="code">A pointer to a byte array containing the MSIL stream.</param>
/// <param name="codeSize">The number of bytes in the MSIL stream.</param>
/// <param name="maxStackSize">The maximum number of items on the operand stack when the method is executing.</param>
/// <remarks>
/// No validity checks are performed on the MSIL stream.
/// <para>Calling this method a second time replaces the first MSIL stream with the second.</para>
/// <para>Generating your own metadata and MSIL requires familiarity with the Common Language Infrastructure (CLI) documentation, especially "Partition II: Metadata Definition and Semantics" and "Partition III: CIL Instruction Set." For more information, see <see href="https://www.ecma-international.org/publications-and-standards/standards/ecma-335/">ECMA 335 Common Language Infrastructure (CLI)</see>.</para>
/// </remarks>
/// <exception cref="ArgumentNullException"><paramref name="code" /> is <see langword="null" /> and <paramref name="codeSize" /> is greater than 0.</exception>
/// <exception cref="ArgumentOutOfRangeException"><paramref name="codeSize" /> is less than 0.</exception>
[CLSCompliant(false)]
public unsafe void SetCode(byte* code, int codeSize, int maxStackSize)
{
Expand All @@ -898,11 +934,28 @@ public unsafe void SetCode(byte* code, int codeSize, int maxStackSize)
m_maxStackSize = maxStackSize;
}

/// <summary>
/// Sets the exception metadata for the associated dynamic method.
/// </summary>
/// <param name="exceptions">An array that contains the exception metadata.</param>
/// <remarks>
/// The exception metadata for a method defines the location and size of all <c>try</c>, <c>catch</c>, <c>finally</c>, filter, and fault blocks. For information on the layout of this metadata, see the Common Language Infrastructure (CLI) documentation, especially "Partition II: Metadata Definition and Semantics". For more information, see <see href="https://www.ecma-international.org/publications-and-standards/standards/ecma-335/">ECMA 335 Common Language Infrastructure (CLI)</see>.
/// </remarks>
public void SetExceptions(byte[]? exceptions)
{
m_exceptions = (exceptions != null) ? (byte[])exceptions.Clone() : [];
}

/// <summary>
/// Sets the exception metadata for the associated dynamic method.
/// </summary>
/// <param name="exceptions">A pointer to a byte array containing the exception metadata.</param>
/// <param name="exceptionsSize">The number of bytes of exception metadata.</param>
/// <remarks>
/// The exception metadata for a method defines the location and size of all <c>try</c>, <c>catch</c>, <c>finally</c>, filter, and fault blocks. For information on the layout of this metadata, see the Common Language Infrastructure (CLI) documentation, especially "Partition II: Metadata Definition and Semantics" and "Partition III: CIL Instruction Set". For more information, see <see href="https://www.ecma-international.org/publications-and-standards/standards/ecma-335/">ECMA 335 Common Language Infrastructure (CLI)</see>.
/// </remarks>
/// <exception cref="ArgumentNullException"><paramref name="exceptions" /> is <see langword="null" /> and <paramref name="exceptionsSize" /> is greater than 0.</exception>
/// <exception cref="ArgumentOutOfRangeException"><paramref name="exceptionsSize" /> is less than 0.</exception>
[CLSCompliant(false)]
public unsafe void SetExceptions(byte* exceptions, int exceptionsSize)
{
Expand All @@ -914,11 +967,30 @@ public unsafe void SetExceptions(byte* exceptions, int exceptionsSize)
m_exceptions = new Span<byte>(exceptions, exceptionsSize).ToArray();
}

/// <summary>
/// Sets the local variable signature that describes the layout of local variables for the associated dynamic method.
/// </summary>
/// <param name="localSignature">An array that contains the layout of local variables for the associated <see cref="DynamicMethod" />.</param>
/// <remarks>
/// The local variable signature describes the layout of a method's local variables. To simplify construction of the local variable signature, use the <see langword="static" /> (<see langword="Shared" /> in Visual Basic) <see cref="SignatureHelper.GetLocalVarSigHelper()">SignatureHelper.GetLocalVarSigHelper</see> method to get a <see cref="SignatureHelper" /> for the local signature.
/// <para>For information on local variable signatures, see the Common Language Infrastructure (CLI) documentation, especially "Partition II: Metadata Definition and Semantics". For more information, see <see href="https://www.ecma-international.org/publications-and-standards/standards/ecma-335/">ECMA 335 Common Language Infrastructure (CLI)</see>.</para>
/// </remarks>
public void SetLocalSignature(byte[]? localSignature)
{
m_localSignature = (localSignature != null) ? (byte[])localSignature.Clone() : [];
}

/// <summary>
/// Sets the local variable signature that describes the layout of local variables for the associated dynamic method.
/// </summary>
/// <param name="localSignature">An array that contains the layout of local variables for the associated <see cref="DynamicMethod" />.</param>
/// <param name="signatureSize">The number of bytes in the signature.</param>
/// <remarks>
/// The local variable signature describes the layout of a method's local variables. To simplify construction of the local variable signature, use the <see langword="static" /> (<see langword="Shared" /> in Visual Basic) <see cref="SignatureHelper.GetLocalVarSigHelper()">SignatureHelper.GetLocalVarSigHelper</see> method to get a <see cref="SignatureHelper" /> for the local signature.
/// <para>For information on local variable signatures, see the Common Language Infrastructure (CLI) documentation, especially "Partition II: Metadata Definition and Semantics". For more information, see <see href="https://www.ecma-international.org/publications-and-standards/standards/ecma-335/">ECMA 335 Common Language Infrastructure (CLI)</see>.</para>
/// </remarks>
/// <exception cref="ArgumentNullException"><paramref name="localSignature" /> is <see langword="null" /> and <paramref name="signatureSize" /> is greater than 0.</exception>
/// <exception cref="ArgumentOutOfRangeException"><paramref name="signatureSize" /> is less than 0.</exception>
[CLSCompliant(false)]
public unsafe void SetLocalSignature(byte* localSignature, int signatureSize)
{
Expand All @@ -931,34 +1003,99 @@ public unsafe void SetLocalSignature(byte* localSignature, int signatureSize)
#endregion

#region Public Scope Methods
/// <summary>
/// Gets a token, valid in the scope of the current <see cref="DynamicILInfo" />, representing a method to be accessed from the associated dynamic method.
/// </summary>
/// <param name="method">The method to be accessed.</param>
/// <returns>A token that can be used as the operand of an MSIL instruction that accesses methods, such as <see cref="OpCodes.Call" /> or <see cref="OpCodes.Ldtoken" />, in the scope of the current <see cref="DynamicILInfo" /> object.</returns>
/// <remarks>
/// You must obtain a token for any method that will be accessed by the dynamic method associated with the current <see cref="DynamicILInfo" /> object. Use the <see cref="Type.GetMethod(string)">Type.GetMethod</see> method to get a <see cref="MethodInfo" /> for the method you want to access, and then use the <see cref="MethodBase.MethodHandle" /> property to get the <see cref="RuntimeMethodHandle" />.
/// <note type="note">For a method that belongs to a generic type, use the <see cref="GetTokenFor(RuntimeMethodHandle, RuntimeTypeHandle)" /> method overload and specify a <see cref="RuntimeTypeHandle" /> for the generic type.</note>
/// </remarks>
public int GetTokenFor(RuntimeMethodHandle method)
{
return DynamicScope.GetTokenFor(method);
}
/// <summary>
/// Gets a token, valid in the scope of the current <see cref="DynamicILInfo" />, representing a dynamic method to be called from the associated method.
/// </summary>
/// <param name="method">The dynamic method to call.</param>
/// <returns>A token that can be embedded in the MSIL stream for the associated dynamic method, as the target of an MSIL instruction.</returns>
/// <remarks>
/// The token returned by this method overload allows you to call a dynamic method from the dynamic method associated with the current <see cref="DynamicILInfo" /> object. To call the associated dynamic method recursively, pass the value of the <see cref="DynamicMethod" /> property.
/// </remarks>
public int GetTokenFor(DynamicMethod method)
{
return DynamicScope.GetTokenFor(method);
}
/// <summary>
/// Gets a token, valid in the scope of the current <see cref="DynamicILInfo" />, representing a method on a generic type.
/// </summary>
/// <param name="method">The method.</param>
/// <param name="contextType">The generic type the method belongs to.</param>
/// <returns>A token that can be used as the operand of an MSIL instruction that accesses methods, such as <see cref="OpCodes.Call" /> or <see cref="OpCodes.Ldtoken" />, in the scope of the current <see cref="DynamicILInfo" /> object.</returns>
/// <remarks>
/// You must obtain a token for any method that will be called by the dynamic method associated with the current <see cref="DynamicILInfo" /> object. Use the <see cref="Type.GetMethod(string)">Type.GetMethod</see> method to get a <see cref="MethodInfo" /> for the method you want to call, and then use the <see cref="MethodBase.MethodHandle" /> property to get the <see cref="RuntimeMethodHandle" />.
/// </remarks>
public int GetTokenFor(RuntimeMethodHandle method, RuntimeTypeHandle contextType)
{
return DynamicScope.GetTokenFor(method, contextType);
}
/// <summary>
/// Gets a token, valid in the scope of the current <see cref="DynamicILInfo" />, representing a field to be accessed from the associated dynamic method.
/// </summary>
/// <param name="field">The field to be accessed.</param>
/// <returns>A token that can be used as the operand of an MSIL instruction that accesses fields, in the scope of the current <see cref="DynamicILInfo" /> object.</returns>
/// <remarks>
/// You must obtain a token for any field that will be accessed by the dynamic method associated with the current <see cref="DynamicILInfo" /> object. Use the <see cref="Type.GetField(string)">Type.GetField</see> method to get a <see cref="FieldInfo" /> for the field you want to access, then use the <see cref="FieldInfo.FieldHandle" /> property to get the <see cref="RuntimeFieldHandle" />.
/// </remarks>
public int GetTokenFor(RuntimeFieldHandle field)
{
return DynamicScope.GetTokenFor(field);
}
/// <summary>
/// Gets a token, valid in the scope of the current <see cref="DynamicILInfo" />, representing a field to be accessed from the associated dynamic method; the field is on the specified generic type.
/// </summary>
/// <param name="field">The field to be accessed.</param>
/// <param name="contextType">The generic type the field belongs to.</param>
/// <returns>A token that can be used as the operand of an MSIL instruction that accesses fields in the scope of the current <see cref="DynamicILInfo" /> object.</returns>
/// <remarks>
/// You must obtain a token for any field that will be accessed by the dynamic method associated with the current <see cref="DynamicILInfo" /> object. Use the <see cref="Type.GetField(string)">Type.GetField</see> method to get a <see cref="FieldInfo" /> for the field you want to access, and then use the <see cref="FieldInfo.FieldHandle" /> property to get the <see cref="RuntimeFieldHandle" />.
/// </remarks>
public int GetTokenFor(RuntimeFieldHandle field, RuntimeTypeHandle contextType)
{
return DynamicScope.GetTokenFor(field, contextType);
}
/// <summary>
/// Gets a token, valid in the scope of the current <see cref="DynamicILInfo" />, representing a type to be used in the associated dynamic method.
/// </summary>
/// <param name="type">The type to be used.</param>
/// <returns>A token that can be used as the operand of an MSIL instruction that requires a type, in the scope of the current <see cref="DynamicILInfo" /> object.</returns>
/// <remarks>
/// The token returned by this method overload allows you to define a local variable type, and emit MSIL to create an instance of a type in the dynamic method associated with the current <see cref="DynamicILInfo" /> object.
/// <para>To get a <see cref="RuntimeTypeHandle" /> representing a type, use the <see cref="Type.TypeHandle" /> property.</para>
/// </remarks>
public int GetTokenFor(RuntimeTypeHandle type)
{
return DynamicScope.GetTokenFor(type);
}
/// <summary>
/// Gets a token, valid in the scope of the current <see cref="DynamicILInfo" />, representing a string literal to be used in the associated dynamic method.
/// </summary>
/// <param name="literal">The string to be used.</param>
/// <returns>A token that can be used as the operand of an MSIL instruction that requires a string, in the scope of the current <see cref="DynamicILInfo" /> object.</returns>
public int GetTokenFor(string literal)
{
return DynamicScope.GetTokenFor(literal);
}
/// <summary>
/// Gets a token, valid in the scope of the current <see cref="DynamicILInfo" />, representing the signature for the associated dynamic method.
/// </summary>
/// <param name="signature">An array that contains the signature.</param>
/// <returns>A token that can be embedded in the metadata and the MSIL stream for the associated dynamic method.</returns>
/// <remarks>
/// For information on signature blobs, see the Common Language Infrastructure (CLI) documentation, especially "Partition II: Metadata Definition and Semantics". For more information, see <see href="https://www.ecma-international.org/publications-and-standards/standards/ecma-335/">ECMA 335 Common Language Infrastructure (CLI)</see>.
/// </remarks>
public int GetTokenFor(byte[] signature)
{
return DynamicScope.GetTokenFor(signature);
Expand Down
Loading
Loading