Генерация IL для рекурсивных методов
Я попытался сгенерировать 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();
}
Затем я начал генерировать IL для рекурсивного метода, как указано ниже.
MethodBuilder method = typeBuilder.DefineMethod(
“MethodName”,
MethodAttributes.Static | MethodAttributes.Public,
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),typeof(arg2),etc}));
) возвращает ноль. Так как мы на самом деле создаем тип внутри SaveAssembly()
метод, это приемлемо. Поэтому мой вопрос таков: возможно ли сгенерировать IL для рекурсивных методов, используя приведенную выше конструкцию? Если это невозможно, пожалуйста, дайте мне знать, что альтернативные конструкции для генерации IL для рекурсивных методов.
1 ответ
Я не проверял это, но если я правильно помню, вы сможете просто использовать результат DefineMethod
испускать Call
инструкция:
MethodBuilder method = typeBuilder.DefineMethod("MethodName", ...);
...
ILGenerator ilOfMethod = method.GetILGenerator();
...
ilOfMethod.Emit(OpCodes.Call, method);