| OLD | NEW |
| 1 // Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 import '../closure.dart'; | 5 import '../closure.dart'; |
| 6 import '../common.dart'; | 6 import '../common.dart'; |
| 7 import '../elements/elements.dart'; | 7 import '../elements/elements.dart'; |
| 8 import '../elements/entities.dart'; | 8 import '../elements/entities.dart'; |
| 9 import '../elements/types.dart'; | 9 import '../elements/types.dart'; |
| 10 import '../io/source_information.dart'; | 10 import '../io/source_information.dart'; |
| (...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 129 } | 129 } |
| 130 | 130 |
| 131 HInstruction createBox() { | 131 HInstruction createBox() { |
| 132 HInstruction box = new HCreateBox(commonMasks.nonNullType); | 132 HInstruction box = new HCreateBox(commonMasks.nonNullType); |
| 133 builder.add(box); | 133 builder.add(box); |
| 134 return box; | 134 return box; |
| 135 } | 135 } |
| 136 | 136 |
| 137 /// If the scope (function or loop) [node] has captured variables then this | 137 /// If the scope (function or loop) [node] has captured variables then this |
| 138 /// method creates a box and sets up the redirections. | 138 /// method creates a box and sets up the redirections. |
| 139 void enterScope(ClosureScope closureInfo, | 139 void enterScope(CapturedScope closureInfo, |
| 140 {bool forGenerativeConstructorBody: false}) { | 140 {bool forGenerativeConstructorBody: false}) { |
| 141 // See if any variable in the top-scope of the function is captured. If yes | 141 // See if any variable in the top-scope of the function is captured. If yes |
| 142 // we need to create a box-object. | 142 // we need to create a box-object. |
| 143 if (!closureInfo.requiresContextBox) return; | 143 if (!closureInfo.requiresContextBox) return; |
| 144 HInstruction box; | 144 HInstruction box; |
| 145 // The scope has captured variables. | 145 // The scope has captured variables. |
| 146 if (forGenerativeConstructorBody) { | 146 if (forGenerativeConstructorBody) { |
| 147 // The box is passed as a parameter to a generative | 147 // The box is passed as a parameter to a generative |
| 148 // constructor body. | 148 // constructor body. |
| 149 box = builder.addParameter(closureInfo.context, commonMasks.nonNullType); | 149 box = builder.addParameter(closureInfo.context, commonMasks.nonNullType); |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 191 updateLocal(currentBox, newBox); | 191 updateLocal(currentBox, newBox); |
| 192 updateLocal(boxedVariable, oldValue); | 192 updateLocal(boxedVariable, oldValue); |
| 193 } | 193 } |
| 194 updateLocal(currentBox, newBox); | 194 updateLocal(currentBox, newBox); |
| 195 } | 195 } |
| 196 | 196 |
| 197 /// Documentation wanted -- johnniwinther | 197 /// Documentation wanted -- johnniwinther |
| 198 /// | 198 /// |
| 199 /// Invariant: [function] must be an implementation element. | 199 /// Invariant: [function] must be an implementation element. |
| 200 void startFunction(MemberEntity element, ScopeInfo scopeInfo, | 200 void startFunction(MemberEntity element, ScopeInfo scopeInfo, |
| 201 ClosureScope scopeData, Map<Local, TypeMask> parameters, | 201 CapturedScope scopeData, Map<Local, TypeMask> parameters, |
| 202 {bool isGenerativeConstructorBody}) { | 202 {bool isGenerativeConstructorBody}) { |
| 203 assert(!(element is MemberElement && !element.isImplementation), | 203 assert(!(element is MemberElement && !element.isImplementation), |
| 204 failedAt(element)); | 204 failedAt(element)); |
| 205 this.scopeInfo = scopeInfo; | 205 this.scopeInfo = scopeInfo; |
| 206 | 206 |
| 207 parameters.forEach((Local local, TypeMask typeMask) { | 207 parameters.forEach((Local local, TypeMask typeMask) { |
| 208 if (isGenerativeConstructorBody) { | 208 if (isGenerativeConstructorBody) { |
| 209 if (scopeData.isBoxed(local)) { | 209 if (scopeData.isBoxed(local)) { |
| 210 // The parameter will be a field in the box passed as the | 210 // The parameter will be a field in the box passed as the |
| 211 // last parameter. So no need to have it. | 211 // last parameter. So no need to have it. |
| (...skipping 257 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 469 /// We solve this by emitting the following code (only for [ast.For] loops): | 469 /// We solve this by emitting the following code (only for [ast.For] loops): |
| 470 /// <Create box> <== move the first box creation outside the loop. | 470 /// <Create box> <== move the first box creation outside the loop. |
| 471 /// <initializer>; | 471 /// <initializer>; |
| 472 /// loop-entry: | 472 /// loop-entry: |
| 473 /// if (!<condition>) goto loop-exit; | 473 /// if (!<condition>) goto loop-exit; |
| 474 /// <body> | 474 /// <body> |
| 475 /// <update box> // create a new box and copy the captured loop-variables. | 475 /// <update box> // create a new box and copy the captured loop-variables. |
| 476 /// <updates> | 476 /// <updates> |
| 477 /// goto loop-entry; | 477 /// goto loop-entry; |
| 478 /// loop-exit: | 478 /// loop-exit: |
| 479 void startLoop(LoopClosureScope loopInfo) { | 479 void startLoop(CapturedLoopScope loopInfo) { |
| 480 if (loopInfo.hasBoxedLoopVariables) { | 480 if (loopInfo.hasBoxedLoopVariables) { |
| 481 // If there are boxed loop variables then we set up the box and | 481 // If there are boxed loop variables then we set up the box and |
| 482 // redirections already now. This way the initializer can write its | 482 // redirections already now. This way the initializer can write its |
| 483 // values into the box. | 483 // values into the box. |
| 484 // For other loops the box will be created when entering the body. | 484 // For other loops the box will be created when entering the body. |
| 485 enterScope(loopInfo); | 485 enterScope(loopInfo); |
| 486 } | 486 } |
| 487 } | 487 } |
| 488 | 488 |
| 489 /// Create phis at the loop entry for local variables (ready for the values | 489 /// Create phis at the loop entry for local variables (ready for the values |
| (...skipping 12 matching lines...) Expand all Loading... |
| 502 new HPhi.singleInput(local, instruction, commonMasks.dynamicType); | 502 new HPhi.singleInput(local, instruction, commonMasks.dynamicType); |
| 503 loopEntry.addPhi(phi); | 503 loopEntry.addPhi(phi); |
| 504 directLocals[local] = phi; | 504 directLocals[local] = phi; |
| 505 } else { | 505 } else { |
| 506 directLocals[local] = instruction; | 506 directLocals[local] = instruction; |
| 507 } | 507 } |
| 508 } | 508 } |
| 509 }); | 509 }); |
| 510 } | 510 } |
| 511 | 511 |
| 512 void enterLoopBody(LoopClosureScope loopInfo) { | 512 void enterLoopBody(CapturedLoopScope loopInfo) { |
| 513 // If there are no declared boxed loop variables then we did not create the | 513 // If there are no declared boxed loop variables then we did not create the |
| 514 // box before the initializer and we have to create the box now. | 514 // box before the initializer and we have to create the box now. |
| 515 if (!loopInfo.hasBoxedLoopVariables) { | 515 if (!loopInfo.hasBoxedLoopVariables) { |
| 516 enterScope(loopInfo); | 516 enterScope(loopInfo); |
| 517 } | 517 } |
| 518 } | 518 } |
| 519 | 519 |
| 520 void enterLoopUpdates(LoopClosureScope loopInfo) { | 520 void enterLoopUpdates(CapturedLoopScope loopInfo) { |
| 521 // If there are declared boxed loop variables then the updates might have | 521 // If there are declared boxed loop variables then the updates might have |
| 522 // access to the box and we must switch to a new box before executing the | 522 // access to the box and we must switch to a new box before executing the |
| 523 // updates. | 523 // updates. |
| 524 // In all other cases a new box will be created when entering the body of | 524 // In all other cases a new box will be created when entering the body of |
| 525 // the next iteration. | 525 // the next iteration. |
| 526 if (loopInfo.hasBoxedLoopVariables) { | 526 if (loopInfo.hasBoxedLoopVariables) { |
| 527 updateCaptureBox(loopInfo.context, loopInfo.boxedLoopVariables); | 527 updateCaptureBox(loopInfo.context, loopInfo.boxedLoopVariables); |
| 528 } | 528 } |
| 529 } | 529 } |
| 530 | 530 |
| (...skipping 142 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 673 final MemberEntity memberContext; | 673 final MemberEntity memberContext; |
| 674 | 674 |
| 675 // Avoid slow Object.hashCode. | 675 // Avoid slow Object.hashCode. |
| 676 final int hashCode = _nextHashCode = (_nextHashCode + 1).toUnsigned(30); | 676 final int hashCode = _nextHashCode = (_nextHashCode + 1).toUnsigned(30); |
| 677 static int _nextHashCode = 0; | 677 static int _nextHashCode = 0; |
| 678 | 678 |
| 679 SyntheticLocal(this.name, this.executableContext, this.memberContext); | 679 SyntheticLocal(this.name, this.executableContext, this.memberContext); |
| 680 | 680 |
| 681 toString() => 'SyntheticLocal($name)'; | 681 toString() => 'SyntheticLocal($name)'; |
| 682 } | 682 } |
| OLD | NEW |