if (res && errors != ec.Report.Errors)
return null;
+ if (block.IsAsync && block.Original.ParametersBlock.HasCapturedThis && ec.CurrentAnonymousMethod != null && ec.CurrentAnonymousMethod.block.IsAsync) {
+ //
+ // We'll do ldftn to load the fabricated m_X method but
+ // because we are inside struct the method can be hoisted
+ // anywhere in the parent scope
+ //
+ ec.CurrentBlock.ParametersBlock.HasReferenceToStoreyForInstanceLambdas = true;
+ }
+
return res ? this : null;
}
parent = storey = sm;
}
}
+ } else if (src_block.ParametersBlock.HasReferenceToStoreyForInstanceLambdas) {
+ src_block.ParametersBlock.StateMachine.AddParentStoreyReference (ec, storey);
}
modifiers = storey != null ? Modifiers.INTERNAL : Modifiers.PRIVATE;
AwaitBlock = 1 << 13,
FinallyBlock = 1 << 14,
CatchBlock = 1 << 15,
+ HasReferenceToStoreyForInstanceLambdas = 1 << 16,
Iterator = 1 << 20,
NoFlowAnalysis = 1 << 21,
InitializationEmitted = 1 << 22
break;
}
}
-
+
//
// We are the first storey on path and 'this' has to be hoisted
//
//
// If we are state machine with no parent. We can hook into parent without additional
- // reference and capture this directly
+ // reference and capture this directly
//
ExplicitBlock parent_storey_block = pb;
while (parent_storey_block.Parent != null) {
#region Properties
+ public bool HasReferenceToStoreyForInstanceLambdas {
+ get {
+ return (flags & Flags.HasReferenceToStoreyForInstanceLambdas) != 0;
+ }
+ set {
+ flags = value ? flags | Flags.HasReferenceToStoreyForInstanceLambdas : flags & ~Flags.HasReferenceToStoreyForInstanceLambdas;
+ }
+ }
+
public bool IsAsync {
get {
return (flags & Flags.HasAsyncModifier) != 0;
--- /dev/null
+using System;
+using System.Threading.Tasks;
+
+class X
+{
+ public static void Main ()
+ {
+ new X ().Test ();
+ }
+
+ void Test ()
+ {
+ object v1 = null;
+
+ Action a = () =>
+ {
+ if (v1 == null)
+ {
+ object v2 = null;
+
+ Action a2 = () =>
+ {
+ Console.WriteLine (v2);
+ };
+
+ Action a3 = async () =>
+ {
+ // This scope needs to access to Scope which can do ldftn on instance method
+ {
+ Func<Task> a4 = async () =>
+ {
+ await Foo ();
+ };
+ }
+
+ await Task.Yield ();
+ };
+
+ a3 ();
+ }
+ };
+
+ a ();
+ }
+
+ async Task Foo ()
+ {
+ await Task.FromResult (1);
+ }
+
+}
\ No newline at end of file
</method>
</type>
</test>
+ <test name="test-async-89.cs">
+ <type name="X">
+ <method name="Void Main()" attrs="150">
+ <size>12</size>
+ </method>
+ <method name="Void Test()" attrs="129">
+ <size>41</size>
+ </method>
+ <method name="System.Threading.Tasks.Task Foo()" attrs="129">
+ <size>33</size>
+ </method>
+ <method name="Void .ctor()" attrs="6278">
+ <size>7</size>
+ </method>
+ </type>
+ <type name="X+<Test>c__AnonStorey1">
+ <method name="Void <>m__0()" attrs="131">
+ <size>67</size>
+ </method>
+ <method name="Void .ctor()" attrs="6278">
+ <size>7</size>
+ </method>
+ </type>
+ <type name="X+<Foo>c__async0">
+ <method name="Void MoveNext()" attrs="486">
+ <size>158</size>
+ </method>
+ <method name="Void SetStateMachine(System.Runtime.CompilerServices.IAsyncStateMachine)" attrs="486">
+ <size>13</size>
+ </method>
+ </type>
+ <type name="X+<Test>c__AnonStorey1+<Test>c__AnonStorey2">
+ <method name="Void <>m__0()" attrs="131">
+ <size>13</size>
+ </method>
+ <method name="Void <>m__1()" attrs="131">
+ <size>48</size>
+ </method>
+ <method name="System.Threading.Tasks.Task <>m__2()" attrs="131">
+ <size>46</size>
+ </method>
+ <method name="Void .ctor()" attrs="6278">
+ <size>7</size>
+ </method>
+ </type>
+ <type name="X+<Test>c__AnonStorey1+<Test>c__AnonStorey2+<Test>c__async3">
+ <method name="Void MoveNext()" attrs="486">
+ <size>179</size>
+ </method>
+ <method name="Void SetStateMachine(System.Runtime.CompilerServices.IAsyncStateMachine)" attrs="486">
+ <size>13</size>
+ </method>
+ </type>
+ <type name="X+<Test>c__AnonStorey1+<Test>c__AnonStorey2+<Test>c__async4">
+ <method name="Void MoveNext()" attrs="486">
+ <size>167</size>
+ </method>
+ <method name="Void SetStateMachine(System.Runtime.CompilerServices.IAsyncStateMachine)" attrs="486">
+ <size>13</size>
+ </method>
+ </type>
+ </test>
<test name="test-cls-00.cs">
<type name="CLSCLass_6">
<method name="Void add_Disposed(Delegate)" attrs="2182">