我尝试使用以下策略为递归方法生成IL,
首先,我使用以下代码片段定义了类型
首先,我使用以下代码片段定义了类型
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(); }
MethodBuilder method = typeBuilder.DefineMethod( “MethodName”,NodeTypeToDotNetType(func.RetType),parameters); ILGenerator ilOfMethod = method.GetILGenerator(); method.DefineParameter();
ilOfMethod.Emit(OpCodes.Call,typeBuilder.GetMethod("MethodName",new System.Type[] {typeof(arg1),typeof(arg2),etc}));
private void SaveAssembly(string outputFileName) { ilGen.Emit(OpCodes.Ret); typeBuilder.CreateType(); moduleBuilder.CreateGlobalFunctions(); assemblyBuilder.SetEntryPoint(methodBuilder); assemblyBuilder.Save(outputFileName + ".exe"); }
不幸的是,由于递归方法调用构造,在方法内部返回null,因此无效.这里的问题是在方法内部的递归调用(即ilOfMethod.Emit(OpCodes.Call,typeBuilder.GetMethod(“MethodName”,new System.Type [] {typeof(arg1),etc}));
)返回null.因为我们实际上在SaveAssembly()方法中创建了类型,所以这是可以接受的.所以我的问题是:是否有可能使用上述构造为递归方法生成IL?如果不可能,请让我知道用于为递归方法生成IL的替代构造.
解决方法
我还没有测试过,但是如果我没记错的话,你应该能够简单地使用DefineMethod的结果来发出Call指令:
MethodBuilder method = typeBuilder.DefineMethod("MethodName",...); ... ILGenerator ilOfMethod = method.GetILGenerator(); ... ilOfMethod.Emit(OpCodes.Call,method);