dotnet / dotnet/runtime

[API Proposal]: DynamicILInfo-like API for dynamic assemblies

Open
#124,733 1 comment 0 reactions 0 assignees View on GitHub
api-suggestion area-System.Reflection.Emit
Dominant language
C#
Stars
18.3k
Forks
5.6k
PR merge metrics
PR metrics pending

Description

### Background and motivation

At the moment, `DynamicILInfo` is only available for `DynamicMethod`s as an alternative to `ILGenerator`, which offers more flexibility by emitting raw IL and exception metadata. `MethodBuilder` only offers the `ILGenerator` API.

My main issue with `ILGenerator` is that it expects exception blocks to be defined in a way that is not easy and in some cases impossible to infer from the metadata parsed from an existing method. It also implicitly emits a `leave` instruction when ending an exception block which may be unnecessary and makes it impossible to properly re-emit an existing method as a (modified) dynamic one.

### API Proposal

The name of the method is up for debate since I am unsure if the same class could be used for the ILInfo API due to differences between dynamic methods and assemblies.
```csharp
namespace System.Reflection.Emit;

public abstract class MethodBuilder : MethodInfo
{
public DynamicILInfo GetDynamicILInfo();
}
```

### API Usage

```csharp
AssemblyName an = new("MyAssembly");
var assembly = AssemblyBuilder.DefineDynamicAssembly(an, AssemblyBuilderAccess.RunAndCollect);
var module = assembly.DefineDynamicModule("MyModule.dll");
var type = module.DefineType("MyMethod");
const MethodAttributes ATTRS = MethodAttributes.Static | MethodAttributes.Public;
var method = module.DefineGlobalMethod(name, ATTRS, typeof(void), []);

var info = method.GetDynamicILInfo();

info.SetLocalSignature(EncodeMySignature());
var (code, stackSize) = CompileMyMethod();
info.SetCode(code, stackSize);

var action = method.CreateDelegate();
action();
```

### Alternative Designs

The alternative I know about would be using the `System.Reflection.Metadata.Ecma335` API to write a whole DLL first and then load it like any other assembly. In addition to generating IL, this would involve manually generating all metadata tokens, which ILGenerator and DynamicILInfo both do for you.

### Risks

_No response_

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.