- 18 7月, 2017 1 次提交
-
-
由 Andy Gocke 提交于
Swaps out all uses of CapturedVariablesByLambda for functions on the Scope tree. The reason the baseline changed is that the order of enumerating closures changed. I briefly looked into matching the behavior, but the problem is that the closure order in the old visitors is determined by the visitation of captured variables, not visitation of the closures themselves. More specifically, an item is only added to the CapturedVariablesByLambda dictionary when ReferenceVariable encounters a captured variable. In contrast, the visitation of the Scope tree looks at closures in an in-order traversal of the tree, stopping at the first introduced closure, not necessarily the closure which first captured a variable. One obvious consequence of this changing is that the old ordering for a series of nested lambdas was effectively post-order -- the interior closures would be added to the visitation first, since they would be added from the perspective of the captured variable looking up, instead of the visitor looking down. This particular case is responsible for all the baseline changes that I have seen. When I looked into replicating this traversal order I found it complicated and pretty counter-intuitive. Since the baseline change was so low in emitted IL, I thought it better to keep a very natural in-order tree traversal and just rebaseline a few tests. Fixes https://github.com/dotnet/roslyn/projects/26#card-3753318
-
- 30 6月, 2017 1 次提交
-
-
由 Andy Gocke 提交于
When lowering local functions that capture struct frames, the frames are added as ref parameters to the lowered method. Normally, when the local function captures variables from multiple levels up the intermediate closures are also rewritten to take the ref parameters. However, if one of the intermediate closures captures no variables, the closure conversion code can skip adding ref environments to that closure. This can cause the inner-most closure to no longer have access to all of the ref structs it expects, which crashes the compiler. Fixes #18814, #18918
-
- 17 6月, 2017 1 次提交
-
-
由 Tomas Matousek 提交于
-
- 17 5月, 2017 1 次提交
-
-
由 Charles Stoner 提交于
-
- 13 5月, 2017 2 次提交
- 29 4月, 2017 1 次提交
-
-
由 vsadov 提交于
-
- 05 4月, 2017 1 次提交
-
-
由 Julien Couvreur 提交于
-
- 20 3月, 2017 1 次提交
-
-
由 Andy Gocke 提交于
Lambda rewriting currently allows frames to be structs in the instance where The variables in the frame are not captured by any closures converted to delegates. A closure nested inside the struct closure captures a separate variable that does require a class frame. This poses a problem when the "outer" closure is in the same frame as the variable that requires a class closure. The problem is that we treat scopes and frames as essentially the same thing -- if any scope is perceived to require a particular environment type, all captured variables in that scope will be captured on that frame and all closures will be lowered onto that frame. This creates a conflict between class-based environment capturing, where we want to capture the frame pointer as a field, and struct-based frame capturing, where we want to add arguments as ref parameters. Doing both results in breaking the delegate contract (no signature rewriting) or losing required struct arguments to intermediate closures. To elaborate on the problem here, let's consider the example: ```csharp using System; class C { public void M() { int x = 0; { int y= 0; void Local() { if (x == 0) { Action a = () => y++; a(); } } Local(); } } } ``` The current problem in the compiler is in the code now in GetStructClosures. The previous implementation only built struct closure if the closure was being lowered onto a struct frame. However, in the example, y is being captured by a lambda, meaning that y must be in a class frame. Since Local lives in the same scope it also lives in the same frame and contains the lambda capturing y, meaning that it must live in a class frame as well. Of course, it is not converted to a delegate, nor does it capture any variables that are captured by closures converted to delegates, so its signature is free to be rewritten to take variables which are not captured by closures converted to delegates as struct environment parameters. Here is the expected lowering for the previous example: ```csharp void M() { var env1 = new Env1(); env1.x = 0; var env2 = new Env2(); env2.y = 0; env2.<>_L(ref env1); } struct Env1 { public int x; } class Env2 { public int y; public void <>_L(ref Env1 env1) { if (env1.x == 0) { var env3 = new Env3(); env3.env2 = this; Action a = env3.<>_anon; a(); } } } class Env3 { Env2 env2; public void <>_anon() => this.env2.y++; } ``` The problem comes when calculating the struct frames needed to be passed to Local. In the current implementation, unless the "container" is a struct, no struct frames are added. If we fix that to check for struct frames that are required as parent frames, regardless of the type of container we run into another problem. In this case, the lambda also includes struct frames in its parent "context", but adding any struct frames to a closure that is converted to a delegate is incorrect. The previous problem can be solved by a check to see if the closure can take new ref parameters. This is true for all closures except for ones marked async or iterators or ones converted to delegates. This works because of something we already know from the analysis: if we assume that struct environments are only created when the their capturing closure can take ref parameters, we can assume that any struct environments in scope are "safe" to use, even if those frames are in the "parent context" of the closure. Fixes #16895
-
- 17 3月, 2017 1 次提交
-
-
由 Manish Vasani 提交于
Fixes #17802
-
- 11 3月, 2017 1 次提交
-
-
由 Julien Couvreur 提交于
Conflicts: src/Compilers/CSharp/Portable/Binder/Binder_Expressions.cs src/Compilers/CSharp/Portable/Binder/Binder_Query.cs src/Compilers/CSharp/Portable/Compiler/MethodCompiler.cs src/Compilers/CSharp/Portable/Errors/ErrorCode.cs
-
- 24 2月, 2017 1 次提交
-
-
由 Neal Gafter 提交于
Fixes #14882 Fixes #13840 Fixes #13915
-
- 19 1月, 2017 1 次提交
-
-
由 AlekseyTs 提交于
Expand the lifetime of locals declared within CasePatternSwitchLabelSyntax to the entire switch body. Fixes #15536. Fixes #16066.
-
- 06 1月, 2017 1 次提交
-
-
由 Andy Gocke 提交于
Fixes #16038
-
- 18 12月, 2016 1 次提交
-
-
由 Andy Gocke 提交于
Local functions have already implemented their own frame management, including frame pointer "capturing" (which is implemented by passing a list of frames to the local function by-ref, rather than traditional lambda capturing which is implemented by keeping a linked list of frame pointers to parent frames). PR #14736 wired up local function lowering to the lambda frame pointer machinery, which is necessary for when a local function is captured by a lambda or converted to a delegate, but in the process it diverted control flow for pure local function capturing to the frame pointer machinery, which can't handle the structure of local function struct frame pointers. This PR resolves the issue by restoring the control flow for local functions capturing other local functions with by-ref struct frames. Fixes #15599
-
- 09 11月, 2016 1 次提交
-
-
由 Julien Couvreur 提交于
-
- 29 10月, 2016 1 次提交
-
-
由 Andy Gocke 提交于
Currently, when a local function is captured inside another local function or lambda it can capture 'this' without generating a frame. This is useful, but when that lambda is itself captured then the capturing closure must also capture the frame pointer, namely 'this'. Currently, local function frame pointers are not correctly captured when the captured local function itself captures something from a "higher" scope than the capturing local function. This change solves this problem by: 1) Considering a local function's captured variables when deciding its scope. If the local function captures variables from a higher scope, that local function will be analyzed as belonging to the "higher" scope, causing that local function to register for frame capturing. 2) Since the proxies for capturing frames are not available at the time of local function reference rewriting, the proxies must be saved. There is a new temporary bound node for this purpose, PartiallyLoweredLocalFunctionReference, that stores the proxies and the underlying node for later use during the rewriting phase. This node should never make it past LocalFunctionReferenceRewriting. When these steps are completed, local functions should act very similarly to all other captured variables with different frames, where the frame pointers are captured and walked in a linked list in order to access the target with the proper receiver/frame pointer.
-
- 31 8月, 2016 1 次提交
-
-
由 Ty Overby 提交于
-
- 26 8月, 2016 1 次提交
-
-
由 Andy Gocke 提交于
This PR addresses changes to local functions described in #10391. Specifically, it has been decided that it should be legal to reference local functions defined lexically after the point of reference, i.e. call a local function defined at the end of a method: ``` public void Main() { Local(); void Local() {} } ``` This PR completes the lowering work necessary to correctly emit this code, although it doesn't modify definite assignment to handle the new cases created by this change. That work will be completed in a subsequent PR.
-
- 16 8月, 2016 2 次提交
-
-
由 John Hamby 提交于
-
由 John Hamby 提交于
Try a third strategy for determining when closing over a local is permissible in a synthesized constructor.
-
- 15 8月, 2016 1 次提交
-
-
由 CyrusNajmabadi 提交于
-
- 13 8月, 2016 1 次提交
-
-
由 John Hamby 提交于
-
- 12 8月, 2016 1 次提交
-
-
由 John Hamby 提交于
Add instrumentForDynamicAnalysis parameter to MethodSymbol.CalculateLocalSyntaxOffset, so that an error test can be retained when not instrumenting.
-
- 06 8月, 2016 1 次提交
-
-
由 Neal Gafter 提交于
Similarly for TupleDeconstructionVariableDesignation. Also found many places to handle both kinds of foreach statements.
-
- 01 7月, 2016 3 次提交
- 28 3月, 2016 1 次提交
-
-
由 AlekseyTs 提交于
Related to #8817, #8814.
-
- 18 2月, 2016 1 次提交
-
-
由 VSadov 提交于
-
- 12 11月, 2015 1 次提交
-
-
由 Neal Gafter 提交于
Fixes #6726 in strict mode only
-
- 04 11月, 2015 1 次提交
-
-
由 Neal Gafter 提交于
-
- 22 10月, 2015 1 次提交
-
-
由 Charles Stoner 提交于
-
- 16 10月, 2015 1 次提交
-
-
由 Paul Harrington 提交于
-
- 01 10月, 2015 1 次提交
-
-
由 AlekseyTs 提交于
Fixes #5395. Adjusted Binder, Optimizer, Flow Analysis, code generator and majority of bound tree visitors to not use recursion to handle binary expressions nested on the left side of another binary expression. Adjusted majority of bound tree visitors to detect that stack overflow is about to happen while an expression is being traversed and report a diagnostic pointing to the expression at fault instead of crashing compiler.
-
- 10 9月, 2015 2 次提交
-
-
由 Neal Gafter 提交于
-
由 Tomas Matousek 提交于
-
- 22 8月, 2015 1 次提交
-
-
由 AlekseyTs 提交于
Fixes #4163.
-
- 21 7月, 2015 1 次提交
-
-
由 Evan Hauck 提交于
-
- 17 7月, 2015 1 次提交
-
-
由 Evan Hauck 提交于
-