I see your problem. That never came up for me, as I mentioned, it's a slightly different situation. What I actually did was creating a map of Instruction -> offset (int), and I went through the method body and adjusted all Instruction pointers.
I think this is possible for all instructions whose OpCode.OperandType is InlineBr or InlineBr_S (i.e. all instructions whose operands are of type Instruction). I'm not sure if the switch instruction can also cause the same problem. Good luck! :) 2011/7/7 Indiefreaks.com <[email protected]> > Thanks Gabor. > > I actually implemented adding my code injection before each > OpCodes.Return instance in the MethodDefinition.Body.Instructions > list. > > I did need to inject the code differently depending if the method was > returning a value or void so that it kept returning it correctly. > > However, I'm now facing an issue with if statements that are on the > end of a method. For instance, imagine the following method: > > public void Foo() > { > this.DoSomething(); > > if(myProperty.IsTrue) > { > this.DoSomethingElse(); > } > } > > If I use the last OpCodes.Ret, it actually injects my code in the if > statement like so: > > public void Foo() > { > this.DoSomething(); > > if(myProperty.IsTrue) > { > this.DoSomethingElse(); > this.MyInjectedCodeMethod(); > } > } > > instead of putting it at the real end of the method. Do I have no > other choice than parsing the method and see if I have a brfalse or > brtrue that points to one of my ret addresses in the IL instructions? > > And if that is the case, is there any other similar case that I should > take care of? > > Thanks > > On 7 juil, 22:34, Gábor Kozár <[email protected]> wrote: > > It means that the exact same values will be on the stack after your > custom > > injected code, than before. Essentially means that your injected code > does > > not push any value to the stack it does not pop later, and also it does > not > > pop any values from the stack that it did not push (unless you save the > > value to, for example, a local variable first and then load it back > later). > > > > My project had a similar problem, when I was writing a method using > > Mono.Cecil to inline (specific) method calls. I solved it by basically > > injecting my custom code before all 'ret' instructions. (It's a bit more > > complicated than that, because most of the 'ret' instructions are removed > > during inlining, but you get the point.) > > > > 2011/7/7 Indiefreaks.com <[email protected]> > > > > > > > > > What do you mean stabilizing the stack? > > > > > On 7 juil, 14:37, Alex <[email protected]> wrote: > > > > Hi, > > > > > > >Well, I tried that method but I get way too many return operations > in > > > > > > some situations like when a switch operation occurs in the method. > > > > Moreover, if I fear that simply injecting my code before the > > > > OpCodes.Ret instruction wouldn't work neither in some cases like when > > > > a value is returned by the method. > > > > > > I don't think that's a problem as long as you correctly stabilize the > > > stack. > > > > > > Regards, > > > > Alex > > > > > > On Thu, Jul 7, 2011 at 2:30 PM, Indiefreaks.com > > > > > > <[email protected]> wrote: > > > > > Well, I tried that method but I get way too many return operations > in > > > > > some situations like when a switch operation occurs in the method. > > > > > Moreover, if I fear that simply injecting my code before the > > > > > OpCodes.Ret instruction wouldn't work neither in some cases like > when > > > > > a value is returned by the method. > > > > > > > I may also go down the route of cloning the current method and > adding > > > > > it (with a different name) to the current class and then clear the > > > > > current method instructions and surround a call to the cached > method > > > > > by my profiling code making sure that I catch the returned value if > > > > > different from "System.Void" to return it back once the original > > > > > method ends... > > > > > > > On 7 juil, 13:44, Alex <[email protected]> wrote: > > > > >> Hi, > > > > > > >> I think what you propose is the best way to achieve this. I'm not > sure > > > > >> if 'ret' is the only opcode that can leave a method normally, > though. > > > > > > >> Regards, > > > > >> Alex > > > > > > >> On Thu, Jul 7, 2011 at 11:47 AM, Indiefreaks.com > > > > > > >> <[email protected]> wrote: > > > > >> > Hi, > > > > > > >> > In my current Xna game profiler tool (learn more athttp:// > > > indiefreaks.com), > > > > >> > I'm wrapping each method that should be profiled with my > profiling > > > > >> > code. > > > > > > >> > Right now, in order to do so, I'm getting the first instruction > from > > > > >> > the MethodDefinition Body as well as the last one and inject my > code > > > > >> > before them. > > > > > > >> > It works perfectly fine on most cases except when a control flow > > > > >> > operation code is set in the body. > > > > > > >> > My profiling code that is injected before the actual method is > > > invoked > > > > >> > works fine but because of the previous statement, the code I > inject > > > at > > > > >> > what I would consider the end of the method never gets called or > > > gets > > > > >> > called inside an if or switch statement which crashes the > resulting > > > > >> > assembly. > > > > > > >> > From what I understand, if I have such control flow operations, > the > > > > >> > last instruction in a method body may not be the end of the > current > > > > >> > Method. > > > > > > >> > I'm now considering parsing the whole method instructions and > look > > > for > > > > >> > each OpCodes.Ret instance to add my custom code there but I > wondered > > > > >> > if there was a better solution to find the end of a method or > hook > > > to > > > > >> > it. > > > > > > >> > Thanks > > > > > > >> > -- > > > > >> > -- > > > > >> > mono-cecil- Masquer le texte des messages précédents - > > > > > > >> - Afficher le texte des messages précédents - > > > > > > > -- > > > > > -- > > > > > mono-cecil- Masquer le texte des messages précédents - > > > > > > - Afficher le texte des messages précédents - > > > > > -- > > > -- > > > mono-cecil- Masquer le texte des messages précédents - > > > > - Afficher le texte des messages précédents - > > -- > -- > mono-cecil > -- -- mono-cecil
