Skip to content

DMD Generate overrides modified parameters with originals #282

@isolno

Description

@isolno

Description

When generating from DynamicMethodDefinition, if it has a non-null OriginalMethod, it will ignore the parameters of the new method definition, instead using the originals. While there is a work around of setting OriginalMethod to null before generating, that can remove useful information, and requires using reflection to set a compiler generated field. Issue happens when generating with 'dynamicmethod' or 'methodbuilder', but not 'cecil'.

Example

[Fact]
public void DMDGenerateDoesNotOverrideParameters()
{
  using var dmd = new DynamicMethodDefinition(((Delegate)func).Method);
  // modify to func(a, b) => a + b;
  dmd.Definition.Parameters.Add(new(dmd.Module.TypeSystem.Int32));
  using (var il = new ILContext(dmd.Definition))
  {
    var c = new ILCursor(il);
    c.Index += 1;
    c.Emit(OpCodes.Ldarg_1);
    c.Emit(OpCodes.Add);
  }
  
  Assert.Equal(1, func(1));
  Test("cecil");
  Test("dynamicmethod");
#if NETFRAMEWORK
  Test("methodbuilder");
#endif

  static int func(int a) => a;
  void Test(string dmdtype)
  {
    try
    {
      Switches.SetSwitchValue(Switches.DMDType, dmdtype);
      var newfunc = dmd.Generate().CreateDelegate<Func<int, int, int>>();
      Assert.Equal(3, newfunc(1, 2));
    }
    finally
    {
      Switches.ClearSwitchValue(Switches.DMDType);
    }
  }
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions