2 To fix this, use a range check in the call and dynamically
3 decide tailcall or not.
5 Apply that to not just the `this` parameter, but all ref valuetypes.
7 Note that a small valuetype is no easier because it still has
8 reference semantics and is always passed by address.
11 using System.Runtime.CompilerServices;
12 using static System.Runtime.CompilerServices.MethodImplOptions;
15 // change to class and it works
21 [MethodImpl (NoInlining)]
22 static void check (long stack1, long stack2)
24 // NOTE: This is wierd in order to be later hand edited (removed) in the IL.
29 Console.WriteLine ("tailcall failure {0} {1}", stack1, stack2);
33 [MethodImpl (NoInlining)]
34 public void Method1 (long depth = 100, long stack = 0)
38 Method2 (depth - 1, (long)&local);
41 check ((long)&local, stack);
44 [MethodImpl (NoInlining)]
45 void Method2 (long depth = 100, long stack = 0)
49 Method1 (depth - 1, (long)&local);
52 check ((long)&local, stack);
58 [MethodImpl (NoInlining)]
59 public static void Main (string[] args)
61 new ValueType ().Method1 (999999);
66 .assembly extern mscorlib { }
68 .assembly 'tailcall-member-function-in-valuetype' { }
70 .class public ValueType
71 extends [mscorlib]System.ValueType
75 .method static void check (int64 stack1, int64 stack2) noinlining
90 ldstr "tailcall failure {0} {1}"
92 box [mscorlib]System.Int64
94 box [mscorlib]System.Int64
95 call void class [mscorlib]System.Console::WriteLine(string, object, object)
98 call void class [mscorlib]System.Environment::Exit(int32)
102 .method public instance void Method1 (int64 depth, int64 stack) noinlining
104 .locals init ( int32 V_0)
117 call instance void valuetype ValueType::Method2(int64, int64)
125 call void valuetype ValueType::check(int64, int64)
129 .method instance void Method2 (int64 depth, int64 stack) noinlining
131 .locals init ( int32 V_0)
144 call instance void valuetype ValueType::Method1(int64, int64)
152 call void valuetype ValueType::check(int64, int64)
157 extends [mscorlib]System.Object
160 .method public static void Main (string[] args) noinlining
163 .locals init ( valuetype ValueType V_0)
173 call instance void valuetype ValueType::Method1(int64, int64)
177 .method public instance default void '.ctor' ()
181 call instance void object::'.ctor'()