Skip to content

AssemblyBuilderImpl.DefinePersistedAssembly has trouble with ReadOnlySpan methods #96469

@stephentoub

Description

@stephentoub

Repro (add this somewhere in the System.Reflection.Emit tests):

[Fact]
public void Repro()
{
    using (TempFile file = TempFile.Create())
    {
        AssemblyBuilder ab = AssemblySaveTools.PopulateAssemblyBuilderTypeBuilderAndSaveMethod(out TypeBuilder type, out MethodInfo saveMethod);
        MethodBuilder method = type.DefineMethod("M1", MethodAttributes.Public, null, null);

        ILGenerator ilGenerator = method.GetILGenerator();
        LocalBuilder span = ilGenerator.DeclareLocal(typeof(ReadOnlySpan<char>));
        LocalBuilder str = ilGenerator.DeclareLocal(typeof(string));

        ilGenerator.Emit(OpCodes.Ldstr, "hello");
        ilGenerator.Emit(OpCodes.Call, typeof(MemoryExtensions).GetMethod("AsSpan", [typeof(string)])!);
        ilGenerator.Emit(OpCodes.Stloc, span);
        ilGenerator.Emit(OpCodes.Ldloca_S, span);
        ilGenerator.Emit(OpCodes.Ldc_I4_1);
        ilGenerator.Emit(OpCodes.Call, typeof(ReadOnlySpan<char>).GetMethod("Slice", [typeof(int)])!);
        ilGenerator.Emit(OpCodes.Stloc, span);
        ilGenerator.Emit(OpCodes.Ldloca_S, span);
        ilGenerator.Emit(OpCodes.Constrained, typeof(ReadOnlySpan<char>));
        ilGenerator.Emit(OpCodes.Callvirt, typeof(object).GetMethod("ToString"));
        ilGenerator.Emit(OpCodes.Stloc, str);
        ilGenerator.EmitWriteLine(str);
        ilGenerator.Emit(OpCodes.Ret);

        type.CreateType();
        saveMethod.Invoke(ab, [file.Path]);

        Type typeFromDisk = Assembly.LoadFile(file.Path).GetType("MyType");
        typeFromDisk.GetMethod("M1").Invoke(Activator.CreateInstance(typeFromDisk), null);
    }
}

That fails with:

    Discovering: System.Reflection.Emit.Tests (method display = ClassAndMethod, method display options = None)
    Discovered:  System.Reflection.Emit.Tests (found 632 of 633 test cases)
    Starting:    System.Reflection.Emit.Tests (parallel test collections = on, max threads = 12)
      System.Reflection.Emit.Tests.AssemblySaveMethodBuilderTests.Repro [FAIL]
        System.MissingMethodException : Method not found: 'System.ReadOnlySpan`1<Char> System.ReadOnlySpan`1.Slice(Int32)'.
        Stack Trace:
             at MyType.M1()
             at System.RuntimeMethodHandle.InvokeMethod(Object target, Void** arguments, Signature sig, Boolean isConstructor)
          D:\repos\runtime\src\coreclr\System.Private.CoreLib\src\System\Reflection\MethodBaseInvoker.CoreCLR.cs(36,0): at System.Reflection.MethodBaseInvoker.InterpretedInvoke_Method(Object obj, IntPtr* args)
          D:\repos\runtime\src\libraries\System.Private.CoreLib\src\System\Reflection\MethodBaseInvoker.cs(57,0): at System.Reflection.MethodBaseInvoker.InvokeWithNoArgs(Object obj, BindingFlags invokeAttr)
    Finished:    System.Reflection.Emit.Tests

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions