Chromium Code Reviews| 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 'package:kernel/ast.dart' as ir; | 5 import 'package:kernel/ast.dart' as ir; |
| 6 | 6 |
| 7 import '../closure.dart'; | 7 import '../closure.dart'; |
| 8 import '../common.dart'; | 8 import '../common.dart'; |
| 9 import '../common/codegen.dart' show CodegenRegistry; | 9 import '../common/codegen.dart' show CodegenRegistry; |
| 10 import '../common/names.dart'; | 10 import '../common/names.dart'; |
| (...skipping 298 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 309 for (ir.Constructor body in constructorChain.reversed) { | 309 for (ir.Constructor body in constructorChain.reversed) { |
| 310 if (_isEmptyStatement(body.function.body)) continue; | 310 if (_isEmptyStatement(body.function.body)) continue; |
| 311 | 311 |
| 312 List<HInstruction> bodyCallInputs = <HInstruction>[]; | 312 List<HInstruction> bodyCallInputs = <HInstruction>[]; |
| 313 bodyCallInputs.add(newObject); | 313 bodyCallInputs.add(newObject); |
| 314 | 314 |
| 315 // Pass uncaptured arguments first, captured arguments in a box, then type | 315 // Pass uncaptured arguments first, captured arguments in a box, then type |
| 316 // arguments. | 316 // arguments. |
| 317 | 317 |
| 318 ConstructorElement constructorElement = astAdapter.getElement(body); | 318 ConstructorElement constructorElement = astAdapter.getElement(body); |
| 319 ClosureClassMap parameterClosureData = | |
| 320 closureToClassMapper.getMemberMap(constructorElement); | |
| 321 | 319 |
| 322 var functionSignature = astAdapter.getFunctionSignature(body.function); | 320 var functionSignature = astAdapter.getFunctionSignature(body.function); |
| 323 // Provide the parameters to the generative constructor body. | 321 // Provide the parameters to the generative constructor body. |
| 324 functionSignature.orderedForEachParameter((ParameterElement parameter) { | 322 functionSignature.orderedForEachParameter((ParameterElement parameter) { |
| 325 // If [parameter] is boxed, it will be a field in the box passed as the | 323 // If [parameter] is boxed, it will be a field in the box passed as the |
| 326 // last parameter. So no need to directly pass it. | 324 // last parameter. So no need to directly pass it. |
| 327 if (!localsHandler.isBoxed(parameter)) { | 325 if (!localsHandler.isBoxed(parameter)) { |
| 328 bodyCallInputs.add(localsHandler.readLocal(parameter)); | 326 bodyCallInputs.add(localsHandler.readLocal(parameter)); |
| 329 } | 327 } |
| 330 }); | 328 }); |
| 331 | 329 |
| 332 // If there are locals that escape (i.e. mutated in closures), we pass the | 330 // If there are locals that escape (i.e. mutated in closures), we pass the |
| 333 // box to the constructor. | 331 // box to the constructor. |
| 334 ClosureScope scopeData = parameterClosureData | 332 CapturedVariableInfo scopeData = closureToClassMapper |
| 335 .capturingScopes[constructorElement.resolvedAst.node]; | 333 .getCapturedVariableInfo(constructorElement.resolvedAst.node); |
|
Johnni Winther
2017/05/31 12:39:51
The uses of `constructorElement.resolvedAst.node`
Siggi Cherem (dart-lang)
2017/05/31 20:44:39
Another idea:
I noticed that we have 2 kinds of ca
| |
| 336 if (scopeData != null) { | 334 if (scopeData.hasCapturedVariables()) { |
| 337 bodyCallInputs.add(localsHandler.readLocal(scopeData.boxElement)); | 335 bodyCallInputs.add(localsHandler.readLocal(closureToClassMapper |
| 336 .getExecutableContext(constructorElement.resolvedAst.node))); | |
| 338 } | 337 } |
| 339 | 338 |
| 340 // Pass type arguments. | 339 // Pass type arguments. |
| 341 ir.Class currentClass = body.enclosingClass; | 340 ir.Class currentClass = body.enclosingClass; |
| 342 if (backend.rtiNeed.classNeedsRti(_elementMap.getClass(currentClass))) { | 341 if (backend.rtiNeed.classNeedsRti(_elementMap.getClass(currentClass))) { |
| 343 for (ir.DartType typeParameter in currentClass.thisType.typeArguments) { | 342 for (ir.DartType typeParameter in currentClass.thisType.typeArguments) { |
| 344 HInstruction argument = localsHandler.readLocal(localsHandler | 343 HInstruction argument = localsHandler.readLocal(localsHandler |
| 345 .getTypeVariableAsLocal(_elementMap.getDartType(typeParameter) | 344 .getTypeVariableAsLocal(_elementMap.getDartType(typeParameter) |
| 346 as ResolutionTypeVariableType)); | 345 as ResolutionTypeVariableType)); |
| 347 bodyCallInputs.add(argument); | 346 bodyCallInputs.add(argument); |
| (...skipping 232 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 580 // what was given as parameter. This will be used in case | 579 // what was given as parameter. This will be used in case |
| 581 // there is a parameter check expression in the initializer. | 580 // there is a parameter check expression in the initializer. |
| 582 parameters[parameter] = argument; | 581 parameters[parameter] = argument; |
| 583 localsHandler.updateLocal(parameter, argument); | 582 localsHandler.updateLocal(parameter, argument); |
| 584 }); | 583 }); |
| 585 | 584 |
| 586 // Set the locals handler state as if we were inlining the constructor. | 585 // Set the locals handler state as if we were inlining the constructor. |
| 587 astAdapter.pushResolvedAst(constructor); | 586 astAdapter.pushResolvedAst(constructor); |
| 588 ConstructorElement astElement = astAdapter.getElement(constructor); | 587 ConstructorElement astElement = astAdapter.getElement(constructor); |
| 589 ResolvedAst resolvedAst = astElement.resolvedAst; | 588 ResolvedAst resolvedAst = astElement.resolvedAst; |
| 589 // TODO(efortuna): Remove reference to ClosureClassMap. | |
| 590 ClosureClassMap oldClosureData = localsHandler.closureData; | 590 ClosureClassMap oldClosureData = localsHandler.closureData; |
| 591 ClosureClassMap newClosureData = | 591 ClosureClassMap newClosureData = |
| 592 closureToClassMapper.getMemberMap(astElement); | 592 closureToClassMapper.getMemberMap(astElement); |
| 593 localsHandler.closureData = newClosureData; | 593 localsHandler.closureData = newClosureData; |
| 594 if (resolvedAst.kind == ResolvedAstKind.PARSED) { | 594 if (resolvedAst.kind == ResolvedAstKind.PARSED) { |
| 595 localsHandler.enterScope(resolvedAst.node, | 595 localsHandler.enterScope(resolvedAst.node, |
| 596 forGenerativeConstructorBody: astElement.isGenerativeConstructorBody); | 596 forGenerativeConstructorBody: astElement.isGenerativeConstructorBody); |
| 597 } | 597 } |
| 598 inlinedFrom(constructor, () { | 598 inlinedFrom(constructor, () { |
| 599 _buildInitializers(constructor, constructorChain, fieldValues); | 599 _buildInitializers(constructor, constructorChain, fieldValues); |
| (...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 713 // TODO(sra): Re-implement type builder using Kernel types and the | 713 // TODO(sra): Re-implement type builder using Kernel types and the |
| 714 // `target` for context. | 714 // `target` for context. |
| 715 @override | 715 @override |
| 716 Element get sourceElement => _sourceElementForTarget(_targetStack.last); | 716 Element get sourceElement => _sourceElementForTarget(_targetStack.last); |
| 717 | 717 |
| 718 List<ir.Node> _targetStack = <ir.Node>[]; | 718 List<ir.Node> _targetStack = <ir.Node>[]; |
| 719 | 719 |
| 720 Element _sourceElementForTarget(ir.Node target) { | 720 Element _sourceElementForTarget(ir.Node target) { |
| 721 // For closure-converted (i.e. local functions) the source element is the | 721 // For closure-converted (i.e. local functions) the source element is the |
| 722 // 'call' method of the class that represents the closure. | 722 // 'call' method of the class that represents the closure. |
| 723 Element callMethodOfClosureClass() { | 723 FunctionEntity callMethodOfClosureClass() { |
| 724 LocalFunctionElement element = astAdapter.getElement(target); | 724 LocalFunctionElement element = astAdapter.getElement(target); |
| 725 ClosureClassMap classMap = | 725 return closureToClassMapper.getCallEntity(element); |
| 726 closureToClassMapper.getLocalFunctionMap(element); | |
| 727 return classMap.callElement; | |
| 728 } | 726 } |
| 729 | 727 |
| 730 if (target is ir.FunctionExpression) { | 728 if (target is ir.FunctionExpression) { |
| 731 return callMethodOfClosureClass(); | 729 return callMethodOfClosureClass(); |
| 732 } | 730 } |
| 733 if (target is ir.FunctionDeclaration) { | 731 if (target is ir.FunctionDeclaration) { |
| 734 return callMethodOfClosureClass(); | 732 return callMethodOfClosureClass(); |
| 735 } | 733 } |
| 736 Element element = astAdapter.getElement(target); | 734 Element element = astAdapter.getElement(target); |
| 737 return element; | 735 return element; |
| (...skipping 2036 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2774 push(new HInvokeDynamicSetter(selector, mask, null, inputs, type)); | 2772 push(new HInvokeDynamicSetter(selector, mask, null, inputs, type)); |
| 2775 } else { | 2773 } else { |
| 2776 push(new HInvokeDynamicMethod( | 2774 push(new HInvokeDynamicMethod( |
| 2777 selector, mask, inputs, type, isIntercepted)); | 2775 selector, mask, inputs, type, isIntercepted)); |
| 2778 } | 2776 } |
| 2779 } | 2777 } |
| 2780 | 2778 |
| 2781 @override | 2779 @override |
| 2782 visitFunctionNode(ir.FunctionNode node) { | 2780 visitFunctionNode(ir.FunctionNode node) { |
| 2783 LocalFunctionElement methodElement = astAdapter.getElement(node); | 2781 LocalFunctionElement methodElement = astAdapter.getElement(node); |
| 2784 ClosureClassMap nestedClosureData = | 2782 ClassEntity closureClassEntity = |
| 2785 closureToClassMapper.getLocalFunctionMap(methodElement); | 2783 closureToClassMapper.getClosureClassEntity(methodElement); |
| 2786 assert(nestedClosureData != null); | |
| 2787 assert(nestedClosureData.closureClassElement != null); | |
| 2788 ClosureClassElement closureClassElement = | |
| 2789 nestedClosureData.closureClassElement; | |
| 2790 MethodElement callElement = nestedClosureData.callElement; | |
| 2791 | 2784 |
| 2792 List<HInstruction> capturedVariables = <HInstruction>[]; | 2785 List<HInstruction> capturedVariables = <HInstruction>[]; |
| 2793 closureClassElement.closureFields.forEach((ClosureFieldElement field) { | 2786 closureToClassMapper.forEachClosureClassFieldEntity(methodElement, |
| 2787 (ClosureFieldElement field) { | |
| 2794 Local capturedLocal = | 2788 Local capturedLocal = |
| 2795 nestedClosureData.getLocalVariableForClosureField(field); | 2789 closureToClassMapper.getLocalVarForClosureField(methodElement, field); |
| 2796 assert(capturedLocal != null); | 2790 assert(capturedLocal != null); |
| 2797 capturedVariables.add(localsHandler.readLocal(capturedLocal)); | 2791 capturedVariables.add(localsHandler.readLocal(capturedLocal)); |
| 2798 }); | 2792 }); |
| 2799 | 2793 |
| 2800 TypeMask type = new TypeMask.nonNullExact(closureClassElement, closedWorld); | 2794 TypeMask type = new TypeMask.nonNullExact(closureClassEntity, closedWorld); |
| 2801 // TODO(efortuna): Add source information here. | 2795 // TODO(efortuna): Add source information here. |
| 2802 push(new HCreate(closureClassElement, capturedVariables, type, | 2796 push(new HCreate(closureClassEntity, capturedVariables, type, |
| 2803 callMethod: callElement, localFunction: methodElement)); | 2797 callMethod: closureToClassMapper.getCallEntity(methodElement), |
| 2798 localFunction: methodElement)); | |
| 2804 } | 2799 } |
| 2805 | 2800 |
| 2806 @override | 2801 @override |
| 2807 visitFunctionDeclaration(ir.FunctionDeclaration declaration) { | 2802 visitFunctionDeclaration(ir.FunctionDeclaration declaration) { |
| 2808 assert(isReachable); | 2803 assert(isReachable); |
| 2809 declaration.function.accept(this); | 2804 declaration.function.accept(this); |
| 2810 LocalFunctionElement localFunction = | 2805 LocalFunctionElement localFunction = |
| 2811 astAdapter.getElement(declaration.function); | 2806 astAdapter.getElement(declaration.function); |
| 2812 localsHandler.updateLocal(localFunction, pop()); | 2807 localsHandler.updateLocal(localFunction, pop()); |
| 2813 } | 2808 } |
| (...skipping 611 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3425 enterBlock.setBlockFlow( | 3420 enterBlock.setBlockFlow( |
| 3426 new HTryBlockInformation( | 3421 new HTryBlockInformation( |
| 3427 kernelBuilder.wrapStatementGraph(bodyGraph), | 3422 kernelBuilder.wrapStatementGraph(bodyGraph), |
| 3428 exception, | 3423 exception, |
| 3429 kernelBuilder.wrapStatementGraph(catchGraph), | 3424 kernelBuilder.wrapStatementGraph(catchGraph), |
| 3430 kernelBuilder.wrapStatementGraph(finallyGraph)), | 3425 kernelBuilder.wrapStatementGraph(finallyGraph)), |
| 3431 exitBlock); | 3426 exitBlock); |
| 3432 kernelBuilder.inTryStatement = previouslyInTryStatement; | 3427 kernelBuilder.inTryStatement = previouslyInTryStatement; |
| 3433 } | 3428 } |
| 3434 } | 3429 } |
| OLD | NEW |