Hoist all long-lived (user-defined and synthesized) variables to state machine...
Hoist all long-lived (user-defined and synthesized) variables to state machine fields in debug builds. In order to provide good debugging experience and enable EnC of async and iterator methods we need to lift locals whose lifetime may span state machine suspension points to fields of the state machine. For example, IEnumerable<int> Enumerate() { int x = 1; F(x); yield return 1; } might be changed to IEnumerable<int> Enumerate() { int x = 1; F(x); yield return 1; G(x); } during debugging (or G(x) might just be evaluated in EE while the program is broken on a breakpoint following the yield statement) and thus x has to be hoisted upfront even though it’s lifetime doesn’t cross suspension point in the initial compilation. In addition to lifting the locals we also need to generate an EnC map for them (syntax offset + debug id + type -> slot index), so that we can reuse the state of existing locals during EnC. The implementation is similar to unhoisted local variable mapping and exploits an existing notion of “slots” used by the EE to encode local scopes of hoisted variables. All hoisted variables are assigned slot indices in a syntax order (just to make it deterministic, the order doesn’t matter). The variables are hoisted to fields with names <>5__N (user-defined – this name pattern is already recognized by both Dev12 and Roslyn EEs) and <>s__N (synthesized). N is a slot number. For these locals we emit EnC custom debug information in the same format as we do for unhoisted locals. We attach this CDI to the iterator/async method. (changeset 1364072)
Showing
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
想要评论请 注册 或 登录