5
.NET 4.0にテール再帰的なExpression
を構築しようとしています。テールコール再帰的に最適化された式をビルドできますか?
私はそれを構築できますが、これはtailCall = true
と指定されていますが、コンパイルされたメソッドがテールコール最適化ではないため、生成されたILにはtail.
プレフィックス命令がありません。
テールコール最適化再帰的な呼び出しを構築する方法を教えてくださいExpression
?
ビルドの表現は次のとおりです。
using System;
using System.Linq.Expressions;
namespace ConsoleApplication2
{
public delegate int RecursiveFunc(RecursiveFunc function, int acc, int n);
internal class Program
{
private static void Main()
{
var funcParam = Expression.Parameter(typeof (RecursiveFunc));
var accParam = Expression.Parameter(typeof (int));
var nParam = Expression.Parameter(typeof (int));
var constZero = Expression.Constant(0, typeof (int));
var accumExpr = Expression.Add(accParam, nParam);
var decrimentExpr = Expression.Decrement(nParam);
var invokeExpr = Expression.Invoke(funcParam, funcParam,
accumExpr, decrimentExpr);
var testExpr = Expression.Equal(nParam, constZero);
var condExpr = Expression.Condition(testExpr, accParam,
invokeExpr);
var lambda = Expression.Lambda<RecursiveFunc>(condExpr,
"TailCall", true, new[] {funcParam, accParam, nParam});
var sumParam = Expression.Parameter(typeof (RecursiveFunc),
"Sum");
var method = lambda.Compile();
var ans = method(method, 0, 100);
Console.WriteLine(ans);
}
}
}
そして、このラムダexpresionはILは
.method public static int32 EvaluateTarget (
class [ConsoleApplication2]ConsoleApplication2.RecursiveFunc '',
int32 '',
int32 ''
) cil managed
{
// Method begins at RVA 0x2050
// Code size 25 (0x19)
.maxstack 7
IL_0000: ldarg.2
IL_0001: ldc.i4.0
IL_0002: ceq
IL_0004: brfalse IL_000b
IL_0009: ldarg.1
IL_000a: ret
IL_000b: ldarg.0
IL_000c: ldarg.0
IL_000d: ldarg.1
IL_000e: ldarg.2
IL_000f: add
IL_0010: ldarg.2
IL_0011: ldc.i4.1
IL_0012: sub
IL_0013: callvirt instance int32
[ConsoleApplication2]ConsoleApplication2.RecursiveFunc::Invoke(class
[ConsoleApplication2]ConsoleApplication2.RecursiveFunc, int32, int32)
IL_0018: ret
} // end of method AutoGeneratedType::EvaluateTarget
あなたは式を生成するために使用しているいくつかのコードを投稿する必要があります。確かに言うのは難しいです。 – casperOne
あなたのアドバイスありがとうございます。 サンプルコードを追加し、この式でILを生成しました –