Earlz
Earlz

Reputation: 63835

Is it possible to use Reflection.Emit for the opcodes stelem.any and ldelem.any?

So, I recently did some experimenting and discovered that it appears that Reflection.Emit doesn't support all of the opcodes in the ECMA spec. There are 3 opcodes missing:

Are these opcodes just not supported in the Reflection API, or is there some way to generate them or something?

Upvotes: 8

Views: 773

Answers (2)

Michael B
Michael B

Reputation: 7567

I placed a comment about this but the OpCode.Stelem instruction at least in .net 4 translate sto a stelem.any

See it use to be the case that you had to encode the type you were storing in the array and for the primitives there was the various stelem.* opcodes. If you were storing a reference type (something which declared as a delegate or a class) you would use stelem.Ref and you would use Stelem (myType) for value types (something which is declared as a struct or an enum).

However, with the advent of generics there came the type parameter and it could be anything it wanted. T could be a reference type or it could be a value type. So stelem.any is born to handle this unusual case. But you might say, I can only store an unboxed T into a T array so its entirely pointless, can't we just rely on the type of the array?

Well the array's type might also be generic, which would make things rather difficult. But more importantly its converse operation also helps verify the next operation.

ldarg.0
ldc.i4.0
ldelem.any !!T

Tells the verifier that the next instruction after this stack transition should be operated upon an unboxed T which is the generic methods parameter.

Upvotes: 0

René Wolferink
René Wolferink

Reputation: 3548

Actually, you can.

There is a wonderful walkthrough at http://msdn.microsoft.com/en-us/library/4xxf1410.aspx

Two essential parts are:

Create the generic parameters:

string[] typeParamNames = {"TFirst", "TSecond"};
GenericTypeParameterBuilder[] typeParams = 
    myType.DefineGenericParameters(typeParamNames);

GenericTypeParameterBuilder TFirst = typeParams[0];
GenericTypeParameterBuilder TSecond = typeParams[1];

Then create the method:

Type listOf = typeof(List<>);
Type listOfTFirst = listOf.MakeGenericType(TFirst);
Type[] mParamTypes = {TFirst.MakeArrayType()};

MethodBuilder exMethod = 
    myType.DefineMethod("ExampleMethod", 
        MethodAttributes.Public | MethodAttributes.Static, 
        listOfTFirst, 
        mParamTypes);

However, you should go through it entirely, as the generic parameters are used in so many different ways and sections (on the method, on the parameters, as result types, when invoking, ...).

-update- and if you want the .NET 2 specific version: http://msdn.microsoft.com/en-us/library/4xxf1410%28v=vs.80%29.aspx

The dropdown on the page lets you select many versions of the framework in which you can do it.

Upvotes: 1

Related Questions