I do not know why anyone ever need this :) but few readers did ask me similar questions before. Solving this problem also demonstrates one more ILReader usage.
To build a DynamicMethod, we can choose either DynamicILGenerator or DynamicILInfo. My first impression of using DynamicILGenerator to emit code is slow: you need make calls to emit ILs instruction by instruction. Actually this approach is more difficult, a topic for future post. I already wrote a post about DynamicILInfo. I do not know the motivation behind the DynamicILInfo class (at that time I was not in the CLR team), but I heard this was a feature request from SQL.
To turn a MethodInfo to DynamicMethod, we can not simply call SetCode with the byte array returned by the static method body's GetILAsByteArray. Those tokens (if any) are metadata tokens, meaningful only in the scope of the module where that static method lives. The DynamicILInfo.GetTokenFor overloads are designed to build the relationship between an integer number (the new "token") and the runtime member (type, method, field, string, or signature...) in the scope of the dynamic method. We can first make a copy of the static method's IL byte array, and overwrite the old metadata token with the new token from GetTokenFor for each applicable IL instruction. So here comes ILInfoGetTokenVisitor. As you see, we override 6 visit methods in ILInfoGetTokenVisitor, doing the token replacements; the top-level code to prepare new code array looks simple.
JAY was asking how to set exceptions. Reflection does not provide API to return the exception blob directly, instead the exception information is exposed through the MethodBody.ExceptionHandlingClauses property. With this ExceptionHandlingClause list, we can follow the format described by Ecma 335 (Part 2, 25.4.5 and 25.4.6) and build the exception blob from scratch. To avoid worrying about the restriction of the small version of exception handling clauses, the exception array generated below is with the fat form layout. See some comments inside the code.
If you are interested in the details, you may download the attachment and read the whole source code closely.
A related question is how to build a dynamic method from other sources. DynamicMethod is not Serializable, .NET framework built-in serializing/deserializing support will not work. One approach I can think of is to preserve the code array, the members/strings/... (in order to call GetTokenFor to get new tokens) used and their matching offsets (with one scan of the ILs). MethodInfo, FieldInfo, Type are marked "Serializable", but not sure whether this is the right way to save/restore those members. If the method handles exception, we can save the pre-calculated exception blob, and remember where we need replace token for what exception type.
Finally, let us play with the turn-static-method-to-dynamic-method call, and show off some IronPython code. The first 3 lines bring in the DynamicMethodHelper class. Then we use Reflection to get DateTime.get_Now's MethodInfo (sGetNow), and convert it to DynamicMethod (dGetNow) with "DynamicMethodHelper.ConvertFrom". The last part of the code is interesting: it converts the method "DynamicMethodHelper.ConvertFrom" to DynamicMethod (dConvert), and use that dynamic method (dConvert) to convert sGetNow to another dynamic method (dGetNow2). Just fyi: DateTime.get_Now has 5 instructions, DynamicMethodHelper.ConvertFrom has ~80 instructions and exception handlings clauses.