Cool, thank you so much. There are a lot of details to know about! Why didn't the disassembled IL call the virtual ToString and simply performs a regular call instead? And why can't I see variables in the IL for the get_Now and get_Ticks calls? Are V_0 and V_1 in the IL constants that reference some kind of variable storage inside the runtime?
Again, thanks a lot for your help! When I'm done with this, I'll try to help you out and write something for your FAQ! Louis On May 7, 11:48 pm, Jb Evain <[email protected]> wrote: > Hey, > > On Sat, May 8, 2010 at 6:16 AM, Louis Salin <[email protected]> wrote: > > Thanks for the quick reply. > > I've upgraded my code to 0.9.2. > > Cool! > > > I'm not sure how to use a > > VariableDefinition to hold the values of get_Now and get_Ticks in the > > code I've posted earlier. Maybe I shouldn't try to write what the > > disassembler is giving me... > > Actually, it's usually a very good strategy. > > In ildasm, you can see that DateTime.get_Now returns a > System.DateTime, and that System.DateTime.get_Ticks returns a long (a > System.Int64). > > stloc/ldloc work on variables, so you need to create appropriate variables. > > > var processor = init.Body.GetILProcessor(); > > Here you would add: > > var date_now = new VariableDefinition (module.Import (typeof (DateTime))); > var date_ticks = new VariableDefinition (module.Import (typeof (long))); > > init.Body.Variables.Add (date_now); > init.Body.Variables.Add (date_ticks); > init.Body.InitLocals = true; > > Also note that Append(Create()) can be simplified with Emit. > > > processor.Append(processor.Create(OpCodes.Ldstr, "start time:{0}\n")); > > met = > > assembly.MainModule.Import(typeof(DateTime).GetMethod("get_Now")); > > processor.Append(processor.Create(OpCodes.Call, met)); > > processor.Append(processor.Create(OpCodes.Stloc_0)); > > Change to: > > processor.Emit (OpCodes.Stloc, date_now); > > > processor.Append(processor.Create(OpCodes.Ldloca_S, 0)); > > processor.Emit (OpCodes.Ldloca_S, date_now); > > > met = > > assembly.MainModule.Import(typeof(DateTime).GetMethod("get_Ticks")); > > processor.Append(processor.Create(OpCodes.Call, met)); > > processor.Append(processor.Create(OpCodes.Stloc_1)); > > processor.Emit (OpCodes.Stloc, date_ticks); > > > processor.Append(processor.Create(OpCodes.Ldloca_S, 1)); > > processor.Emit (OpCodes.Ldloca_S, date_ticks); > > > met = assembly.MainModule.Import(typeof(int).GetMethod("ToString")); > > You want to call typeof (long).GetMethod ("ToString"), not int.ToString. > > > processor.Append(processor.Create(OpCodes.Call, met)); > > You need to use Callvirt for ToString, it's a virtual method > > > met = assembly.MainModule.Import(typeof(string).GetMethod("Format", > > new [] {typeof(string), typeof(object)})); > > processor.Append(processor.Create(OpCodes.Call, met)); > > And you should > > -- > Jb Evain <[email protected]> > > -- > -- > mono-cecil -- -- mono-cecil
