I tried to generate IL for recursive method using following strategy, Firstly I defined type using following code snippet
private void InitializeAssembly(string outputFileName)
        {
            AppDomain appDomain = AppDomain.CurrentDomain;
            AssemblyName assemblyName = new AssemblyName(outputFileName);
            assemblyBuilder = appDomain.DefineDynamicAssembly(assemblyName,
                                                              AssemblyBuilderAccess.Save);
            moduleBuilder = assemblyBuilder.DefineDynamicModule(outputFileName, outputFileName + ".exe");
            typeBuilder = moduleBuilder.DefineType(typeName, TypeAttributes.Public);
            methodBuilder = typeBuilder.DefineMethod("Main",
                                    MethodAttributes.Static | MethodAttributes.Public,
                                    typeof(void),
                                    System.Type.EmptyTypes);
            ilGen = methodBuilder.GetILGenerator();
        }
Next I started to generate IL for recursive method as given below.
MethodBuilder method = typeBuilder.DefineMethod(
                   “MethodName”,
                   MethodAttributes.Static | MethodAttributes.Public,
                   NodeTypeToDotNetType(func.RetType),
                   parameters);
                ILGenerator ilOfMethod = method.GetILGenerator();
method.DefineParameter();
For calling method itself inside the method body I used following construct,
ilOfMethod.Emit(OpCodes.Call, typeBuilder.GetMethod("MethodName", new System.Type[] {typeof(arg1),typeof(arg2),etc}));
Finally save generated assembly using following method.
private void SaveAssembly(string outputFileName)
        {
            ilGen.Emit(OpCodes.Ret);
            typeBuilder.CreateType();
            moduleBuilder.CreateGlobalFunctions();
            assemblyBuilder.SetEntryPoint(methodBuilder);
            assemblyBuilder.Save(outputFileName + ".exe");
        }
Unfortunately this is not working since recursive method calling construct, inside the method returns null. Issue here is that recursive call inside the method ( i.e. ilOfMethod.Emit(OpCodes.Call, typeBuilder.GetMethod("MethodName", new System.Type[] {typeof(arg1),typeof(arg2),etc}));
) returns null. Since we actually create the type inside the SaveAssembly() method, this is acceptable. So my question is that: is it possible to generate IL for recursive methods using above construct? If it is not possible, Please let me know that alternative constructs for generating IL for recursive methods.
I haven't tested it, but if I remember correctly you should be able to simply use the result of DefineMethod to emit the Call instruction:
MethodBuilder method = typeBuilder.DefineMethod("MethodName", ...);
...
ILGenerator ilOfMethod = method.GetILGenerator();
...
ilOfMethod.Emit(OpCodes.Call, method);
                        If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With