views:

175

answers:

2

The .NET Framework 4.0 introduces several items to the Reflection API that range from extremely useful to vital for my work. Among these are protected constructors for Assembly, Module, MethodBody, and LocalVariableInfo and the new CustomAttributeData class. There are a couple items I still need that are quite troublesome to work around. I believe they easily apply to the same [small] group of people would need to extend the types I just listed.

This time: I'm looking for a way to construct an instance of the System.Reflection.Emit.OpCode struct with my own parameters. I currently invoke the internal constructor to create the instances. It's not detrimental to performance because I expose the constructed items as public static readonly members of a class for reuse, but as you can imagine this is an extremely sub-optimal scenario.

Is there any reason it is not possible to make the current internal OpCode constructor public with documentation that states user-constructed OpCodes cannot be used with ILGenerator.

Edit: Here's an example. By creating the following custom opcode, I'm able to use it in byte code transformations between some intermediate lists of instructions without resorting to creating temporary local variables. If I were emitting IL, I'd convert the remaining swap instructions to a valid IL representation, but in my case the next step is a JIT that understands the custom swap instruction. I'm using the Prefix2 prefix 0xFD, which is reserved and unused by any valid IL opcodes.

/// <summary>
/// Swaps adjacent elements on the evaluation stack. The supplied inline int32 argument gives the
/// index of the topmost item in the pair.
/// </summary>
public static readonly OpCode Swap;

I'll also be using this for JIT intrinsics that don't have a simple/common managed code representation but have a simple platform-dependent representation available in the various native code generators. One of these is ldthread (loads a reference to the current managed thread's RuntimeThread representation).

A: 

I don't think it is possible to create custom OpCode instance, as OpCode instances are strictly derived from the Common Language Infrastructure (CLI) documentation. So even if your case makes sense, OpCode does not seems to be the way to go.

Laurent Etiemble
The predefined OpCode instances are based on the documentation, but the struct itself is not part of TR/84. Part of the reason my code in this application is *so* clean is I used reflection to invoke the OpCode constructor to make the new instances. For anyone doing IL transforms themselves before sending the result to ILGenerator, the ability to embed "special" opcodes in the intermediate results can be extremely helpful, and given the narrow, technical userbase that actually uses OpCode, it doesn't seem harmful to open this case. Just make ILGenerator throw if invalid codes make it that far.
280Z28
I understand the need. Maybe you can lobby (with the help of a MVP) Microsoft to make the constructor public.
Laurent Etiemble
A: 

Why don't you use our own IL-Opcodes for the intermediate results and then convert them to real opcodes in the last step.

codymanix