This project is read-only.

Size Of Operations

Topics: PE Writer
Apr 23, 2009 at 6:22 PM
I was wondering if there's a way to get the size of a particular operation and its associated value. For example, OperationCode.Br is 4 bytes in size, but OperationCode.Br_S is 1 byte. Basically I'm looking for a method that takes an OperationCode and tells you how many bytes it'll take up on the stack.

I can easily do this myself (basically copy the code form SerializeMethodBodyIL(), create a OperationCodeExtensions class with method Size() and translate all the work from that method to simple integer values) but I'm wondering if that's already somewhere in the API.

Thanks,
Jason
Apr 24, 2009 at 2:13 AM
If you are going to write out IL, you should be using the ILGenerator class, which already knows all about operation sizes and does all sorts of nice things such as calculating the maximum stack size and fixing up Br instructions to Br_S instructions if possible.

Since ILGenerator deals with abstractions such as Labels, whereas the operations produced by the reader has only offsets, just round tripping IL via the ILGenerator is not completely straight forward.

We have some code that does this sort of thing, but this still needs to be packaged up and made available via a sample. I'll see what I can do about in the next week or so. Unfortunately, Mike Barnett, the creator of this code is on vacation, out of town, and away from e-mail, so I can't just dump this on him. :-(
Apr 24, 2009 at 2:22 PM
I would LOVE to see an example of this. Right now I'm using the Operation list from method.Body and I have to do all the fixups myself. It's not hard - I created a LabelOperation, fixup the list before I do my modifications, and then remove the "labels" with the right offsets once I'm done - but it would be nicer if this was all taken care of already. I saw the ILGenerator class in the API but I didn't see where it's ever being created and/or used or how it would be helpful in modifying the contents of an existing assembly. The thing is, though, I'm not emitting new IL; I'm changing IL in an existing method, so I'm not sure if ILGenerator would help out in my case.

Incidentally I did create a Size() extension method for OperationCode :).

Again, if an example like this gets posted, please let me know - I'd love to peruse it.

Thanks,
Jason
Jan 26, 2010 at 6:05 PM

What ever happened with this?  I'm in this same situation. I have some IL I want to rewrite and optimize. However, going from a already defined IOperation -> IlGen.Emit(OpCode, arg) isn't very straight forward since doing something like IlGen.Emit(IOperation.OpCode, IOperation.Value) doesn't have type information available. Is there an easier way to do this then trying to get runtime type information and dynamically calling the appropriate emit?

 

 

Jan 26, 2010 at 6:35 PM

Look at the ILMutator sample.

Jan 26, 2010 at 7:47 PM

Thanks!

It looks it's not going to be as easy as I was hoping for, lol. There is a lot going on in that process method. But some of it looks like it could be abstracted out... Thanks again.