Managed CodeGen

This blog is to introduce some new features about Managed CodeGen in Whidbey. We provided a new way of doing LightWeight CodeGen, added support for emitting Generics in Reflection.Emit and there is some new exciting token handle stories in Reflection going on.

Token APIs on Module Builder

We have some token APIs on Module Builder that can be used to as an optional approach as to regular Refelction.Emit APIs.

They are:

public TypeToken GetTypeToken(Type type)

public TypeToken GetTypeToken(String name) // this looks just like ModuleBuilder.GetType(string).

public MethodToken GetMethodToken(MethodInfo method)

public MethodToken GetArrayMethodToken(Type arrayClass, String methodName, CallingConventions callingConvention, Type returnType, Type[] parameterTypes)

public MethodToken GetConstructorToken(ConstructorInfo con)

public FieldToken GetFieldToken(FieldInfo field)

public StringToken GetStringConstant(String str)

public SignatureToken GetSignatureToken(SignatureHelper sigHelper)

public SignatureToken GetSignatureToken(byte[] sigBytes, int sigLength)

Here is a code sample showing you the useage as GetArrayMethod for referenced Generic Methods:

using System.Reflection;
using System.Reflection.Emit;
using System;

public class Test
{
    public static void Main()
    {
        AssemblyBuilder asmb = AppDomain.CurrentDomain.DefineDynamicAssembly(new AssemblyName("C"), AssemblyBuilderAccess.RunAndSave);
        ModuleBuilder modb = asmb.DefineDynamicModule("C.dll");
        TypeBuilder A = modb.DefineType("A", TypeAttributes.Public);
        MethodBuilder AM = A.DefineMethod("M", MethodAttributes.Public | MethodAttributes.Static, typeof(int), new Type[]{});
        ILGenerator ilgen = AM.GetILGenerator();
        MethodToken mtToken = modb.GetMethodToken(typeof(G<int>).GetMethod("Foo"));
        LocalBuilder loc = ilgen.DeclareLocal(typeof(G<int>));
        ilgen.Emit(OpCodes.Ldnull);
        ilgen.Emit(OpCodes.Call, mtToken.Token);
        ilgen.Emit(OpCodes.Ldc_I4, 0);
        ilgen.Emit(OpCodes.Ret);
        A.CreateType();
        asmb.Save("C.dll");
    }
}
public class G<T>
{

    public static void Foo(G<T> foo)
    {
    }
}

The code we emitted look like this:

.method public static int32  M() cil managed
{
  // Code size       12 (0xc)
  .maxstack  2
  .locals init (class [repro]G`1<int32> V_0)
  IL_0000:  ldnull
  IL_0001:  call       void class [repro]G`1<int32>::Foo(class [repro]G`1<!0>)
  IL_0006:  ldc.i4     0x0
  IL_000b:  ret
} // end of method A::M

Due to some bugs in Reflection in Beta2, a similiar emitting using normal TypeBuilder.GetMethod won't work in this case. But by using the token APIs, we work directly on module builders and don't need to go through Reflection and thus can correctly emit the signature. It could be also memeory saving for you as well if you just cache the token instead of caching the method info during emitting, you can probably make your GC heap smaller.

 

Published Friday, April 29, 2005 2:27 PM by yirutang

Comment Notification

If you would like to receive an email when updates are made to this post, please register here

Subscribe to this post's comments using RSS

Comments

No Comments

Leave a Comment

(required) 
(optional)
(required) 

  
Enter Code Here: Required
Submit

© 2009 Microsoft Corporation. All rights reserved. Terms of Use  |  Trademarks  |  Privacy Statement
Microsoft
Page view tracker