Skip to content

ReadOperand throws exception when reading type reference to an open generic #25

@llebron

Description

@llebron

This example throws an exception reliably.

        class TestGeneric<T> { }

        class OpenGenericRef
        {
            public void Foo()
            {
                System.Type type = typeof(TestGeneric<>);
            }
        }

        class ReflectionRunner
        {
            public static void RunReflection()
            {
                MethodInfo methodInfo = typeof(OpenGenericRef).GetMethod("Foo");
                try
                {
                    List<Instruction> instructions = MethodBodyReader.GetInstructions(methodInfo);
                }
                catch (Exception e)
                {
                    string exceptionMessage = e.Message;
                    string exceptionStackTrace = e.StackTrace;
                }
            }
        }

Exception message:
VAR 0 (T) cannot be expanded in this context with 0 instantiations

Exception stack trace:

"  at (wrapper managed-to-native) System.Reflection.RuntimeModule.ResolveMemberToken(intptr,int,intptr[],intptr[],System.Reflection.ResolveTokenError&)  
at System.Reflection.RuntimeModule.ResolveMember (System.Reflection.Module module, System.IntPtr monoModule, System.Int32 metadataToken, System.Type[] genericTypeArguments, System.Type[] genericMethodArguments) [0x0000f] in <dcf6bec1c5764d29a37432d4b047f650>:0 \n  
at System.Reflection.RuntimeModule.ResolveMember (System.Int32 metadataToken, System.Type[] genericTypeArguments, System.Type[] genericMethodArguments) [0x00000] in <dcf6bec1c5764d29a37432d4b047f650>:0 \n  at
Mono.Reflection.MethodBodyReader.ReadOperand (Mono.Reflection.Instruction instruction) [0x00216] in Mono.Reflection/MethodBodyReader.cs:194 \n  at Mono.Reflection.MethodBodyReader.ReadInstructions (System.Int32 metadataToken) [0x00021]

I have traced it to this line, in MethodBodyReader, as the instruction's operand type is InlineTok:

				case OperandType.InlineTok:
				case OperandType.InlineType:
				case OperandType.InlineMethod:
				case OperandType.InlineField:
					instruction.Operand = module.ResolveMember(il.ReadInt32(), type_arguments, method_arguments);
					break;

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions