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:js_runtime/shared/embedded_names.dart'; | 5 import 'package:js_runtime/shared/embedded_names.dart'; |
| 6 import 'package:kernel/ast.dart' as ir; | 6 import 'package:kernel/ast.dart' as ir; |
| 7 | 7 |
| 8 import '../closure.dart'; | 8 import '../closure.dart'; |
| 9 import '../common.dart'; | 9 import '../common.dart'; |
| 10 import '../compiler.dart'; | 10 import '../compiler.dart'; |
| (...skipping 16 matching lines...) Expand all Loading... | |
| 27 import '../universe/selector.dart'; | 27 import '../universe/selector.dart'; |
| 28 import '../world.dart'; | 28 import '../world.dart'; |
| 29 import 'graph_builder.dart'; | 29 import 'graph_builder.dart'; |
| 30 import 'jump_handler.dart' show SwitchCaseJumpHandler; | 30 import 'jump_handler.dart' show SwitchCaseJumpHandler; |
| 31 import 'locals_handler.dart'; | 31 import 'locals_handler.dart'; |
| 32 import 'types.dart'; | 32 import 'types.dart'; |
| 33 | 33 |
| 34 /// A helper class that abstracts all accesses of the AST from Kernel nodes. | 34 /// A helper class that abstracts all accesses of the AST from Kernel nodes. |
| 35 /// | 35 /// |
| 36 /// The goal is to remove all need for the AST from the Kernel SSA builder. | 36 /// The goal is to remove all need for the AST from the Kernel SSA builder. |
| 37 class KernelAstAdapter extends KernelToElementMapMixin { | 37 class KernelAstAdapter extends KernelToElementMapMixin { |
|
Siggi Cherem (dart-lang)
2017/06/01 22:08:48
one possiblity here is to subdivide this class in
Johnni Winther
2017/06/02 09:25:04
They are tied together through TreeElements!
| |
| 38 final Kernel kernel; | 38 final Kernel kernel; |
| 39 final JavaScriptBackend _backend; | 39 final JavaScriptBackend _backend; |
| 40 final Map<ir.Node, ast.Node> _nodeToAst; | 40 final Map<ir.Node, ast.Node> _nodeToAst; |
| 41 final Map<ir.Node, Element> _nodeToElement; | 41 final Map<ir.Node, Element> _nodeToElement; |
| 42 final Map<ir.VariableDeclaration, SyntheticLocal> _syntheticLocals = | 42 final Map<ir.VariableDeclaration, SyntheticLocal> _syntheticLocals = |
| 43 <ir.VariableDeclaration, SyntheticLocal>{}; | 43 <ir.VariableDeclaration, SyntheticLocal>{}; |
| 44 // TODO(efortuna): In an ideal world the TreeNodes should be some common | 44 // TODO(efortuna): In an ideal world the TreeNodes should be some common |
| 45 // interface we create for both ir.Statements and ir.SwitchCase (the | 45 // interface we create for both ir.Statements and ir.SwitchCase (the |
| 46 // ContinueSwitchStatement's target is a SwitchCase) rather than general | 46 // ContinueSwitchStatement's target is a SwitchCase) rather than general |
| 47 // TreeNode. Talking to Asger about this. | 47 // TreeNode. Talking to Asger about this. |
| (...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 119 } | 119 } |
| 120 | 120 |
| 121 @override | 121 @override |
| 122 CommonElements get commonElements => _compiler.commonElements; | 122 CommonElements get commonElements => _compiler.commonElements; |
| 123 | 123 |
| 124 @override | 124 @override |
| 125 ElementEnvironment get elementEnvironment => _compiler.elementEnvironment; | 125 ElementEnvironment get elementEnvironment => _compiler.elementEnvironment; |
| 126 | 126 |
| 127 /// Push the existing resolved AST on the stack and shift the current resolved | 127 /// Push the existing resolved AST on the stack and shift the current resolved |
| 128 /// AST to the AST that this kernel node points to. | 128 /// AST to the AST that this kernel node points to. |
| 129 void pushResolvedAst(ir.Node node) { | 129 void enterInlinedMember(MemberElement member) { |
| 130 _resolvedAstStack.add(_resolvedAst); | 130 _resolvedAstStack.add(_resolvedAst); |
| 131 _resolvedAst = (getElement(node) as AstElement).resolvedAst; | 131 _resolvedAst = member.resolvedAst; |
| 132 } | 132 } |
| 133 | 133 |
| 134 /// Pop the resolved AST stack to reset it to the previous resolved AST node. | 134 /// Pop the resolved AST stack to reset it to the previous resolved AST node. |
| 135 void popResolvedAstStack() { | 135 void leaveInlinedMember(MemberElement member) { |
| 136 assert(_resolvedAstStack.isNotEmpty); | 136 assert(_resolvedAstStack.isNotEmpty); |
| 137 assert(_resolvedAst.element == member); | |
| 137 _resolvedAst = _resolvedAstStack.removeLast(); | 138 _resolvedAst = _resolvedAstStack.removeLast(); |
| 138 } | 139 } |
| 139 | 140 |
| 140 void assertAtResolvedAstFor(ir.Node node) { | 141 void assertAtResolvedAstFor(ir.Node node) { |
| 141 assert(invariant(getElement(node), | 142 assert(invariant(getElement(node), |
| 142 _resolvedAst.element == getElement(node).declaration)); | 143 _resolvedAst.element == getElement(node).declaration)); |
| 143 } | 144 } |
| 144 | 145 |
| 145 Compiler get _compiler => _backend.compiler; | 146 Compiler get _compiler => _backend.compiler; |
| 146 TreeElements get elements => _resolvedAst.elements; | 147 TreeElements get elements => _resolvedAst.elements; |
| (...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 219 return _syntheticLocals.putIfAbsent( | 220 return _syntheticLocals.putIfAbsent( |
| 220 variable, () => new SyntheticLocal("x", null, null)); | 221 variable, () => new SyntheticLocal("x", null, null)); |
| 221 } | 222 } |
| 222 return getElement(variable) as LocalElement; | 223 return getElement(variable) as LocalElement; |
| 223 } | 224 } |
| 224 | 225 |
| 225 FunctionSignature getFunctionSignature(ir.FunctionNode function) { | 226 FunctionSignature getFunctionSignature(ir.FunctionNode function) { |
| 226 return getElement(function).asFunctionElement().functionSignature; | 227 return getElement(function).asFunctionElement().functionSignature; |
| 227 } | 228 } |
| 228 | 229 |
| 229 ir.Field getFieldFromElement(FieldElement field) { | |
| 230 return kernel.fields[field]; | |
| 231 } | |
| 232 | |
| 233 bool isFixedLength(TypeMask mask, ClosedWorld closedWorld) { | |
| 234 if (mask.isContainer && (mask as ContainerTypeMask).length != null) { | |
| 235 // A container on which we have inferred the length. | |
| 236 return true; | |
| 237 } | |
| 238 // TODO(sra): Recognize any combination of fixed length indexables. | |
| 239 if (mask.containsOnly(closedWorld.commonElements.jsFixedArrayClass) || | |
| 240 mask.containsOnly( | |
| 241 closedWorld.commonElements.jsUnmodifiableArrayClass) || | |
| 242 mask.containsOnlyString(closedWorld) || | |
| 243 closedWorld.commonMasks.isTypedArray(mask)) { | |
| 244 return true; | |
| 245 } | |
| 246 return false; | |
| 247 } | |
| 248 | |
| 249 ConstantValue getConstantFor(ir.Node node) { | 230 ConstantValue getConstantFor(ir.Node node) { |
| 250 // Some `null`s are not mapped when they correspond to errors, e.g. missing | 231 // Some `null`s are not mapped when they correspond to errors, e.g. missing |
| 251 // `const` initializers. | 232 // `const` initializers. |
| 252 if (node is ir.NullLiteral) return new NullConstantValue(); | 233 if (node is ir.NullLiteral) return new NullConstantValue(); |
| 253 | 234 |
| 254 ConstantValue constantValue = | 235 ConstantValue constantValue = |
| 255 _backend.constants.getConstantValueForNode(getNode(node), elements); | 236 _backend.constants.getConstantValueForNode(getNode(node), elements); |
| 256 assert(invariant(getNode(node), constantValue != null, | 237 assert(invariant(getNode(node), constantValue != null, |
| 257 message: 'No constant computed for $node')); | 238 message: 'No constant computed for $node')); |
| 258 return constantValue; | 239 return constantValue; |
| (...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 333 } | 314 } |
| 334 } | 315 } |
| 335 } | 316 } |
| 336 return null; | 317 return null; |
| 337 } | 318 } |
| 338 | 319 |
| 339 ResolutionDartType getDartType(ir.DartType type) { | 320 ResolutionDartType getDartType(ir.DartType type) { |
| 340 return _typeConverter.convert(type); | 321 return _typeConverter.convert(type); |
| 341 } | 322 } |
| 342 | 323 |
| 343 ResolutionDartType getDartTypeIfValid(ir.DartType type) { | |
| 344 if (type is ir.InvalidType) return null; | |
| 345 return _typeConverter.convert(type); | |
| 346 } | |
| 347 | |
| 348 List<ResolutionDartType> getDartTypes(List<ir.DartType> types) { | 324 List<ResolutionDartType> getDartTypes(List<ir.DartType> types) { |
| 349 return types.map(getDartType).toList(); | 325 return types.map(getDartType).toList(); |
| 350 } | 326 } |
| 351 | 327 |
| 352 ResolutionInterfaceType getDartTypeOfListLiteral(ir.ListLiteral list) { | 328 ResolutionInterfaceType getDartTypeOfListLiteral(ir.ListLiteral list) { |
| 353 ast.Node node = getNodeOrNull(list); | 329 ast.Node node = getNodeOrNull(list); |
| 354 if (node != null) return elements.getType(node); | 330 if (node != null) return elements.getType(node); |
| 355 assertNodeIsSynthetic(list); | 331 assertNodeIsSynthetic(list); |
| 356 return _compiler.commonElements.listType(getDartType(list.typeArgument)); | 332 return _compiler.commonElements.listType(getDartType(list.typeArgument)); |
| 357 } | 333 } |
| (...skipping 323 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 681 bool isJsIndexableIterator( | 657 bool isJsIndexableIterator( |
| 682 ir.ForInStatement forInStatement, ClosedWorld closedWorld) { | 658 ir.ForInStatement forInStatement, ClosedWorld closedWorld) { |
| 683 TypeMask mask = typeOfIterator(forInStatement); | 659 TypeMask mask = typeOfIterator(forInStatement); |
| 684 return mask != null && | 660 return mask != null && |
| 685 mask.satisfies( | 661 mask.satisfies( |
| 686 closedWorld.commonElements.jsIndexableClass, closedWorld) && | 662 closedWorld.commonElements.jsIndexableClass, closedWorld) && |
| 687 // String is indexable but not iterable. | 663 // String is indexable but not iterable. |
| 688 !mask.satisfies(closedWorld.commonElements.jsStringClass, closedWorld); | 664 !mask.satisfies(closedWorld.commonElements.jsStringClass, closedWorld); |
| 689 } | 665 } |
| 690 | 666 |
| 667 bool isFixedLength(TypeMask mask, ClosedWorld closedWorld) { | |
| 668 if (mask.isContainer && (mask as ContainerTypeMask).length != null) { | |
| 669 // A container on which we have inferred the length. | |
| 670 return true; | |
| 671 } | |
| 672 // TODO(sra): Recognize any combination of fixed length indexables. | |
| 673 if (mask.containsOnly(closedWorld.commonElements.jsFixedArrayClass) || | |
| 674 mask.containsOnly( | |
| 675 closedWorld.commonElements.jsUnmodifiableArrayClass) || | |
| 676 mask.containsOnlyString(closedWorld) || | |
| 677 closedWorld.commonMasks.isTypedArray(mask)) { | |
| 678 return true; | |
| 679 } | |
| 680 return false; | |
| 681 } | |
| 682 | |
| 691 TypeMask inferredIndexType(ir.ForInStatement forInStatement) { | 683 TypeMask inferredIndexType(ir.ForInStatement forInStatement) { |
| 692 return TypeMaskFactory.inferredTypeForSelector(new Selector.index(), | 684 return TypeMaskFactory.inferredTypeForSelector(new Selector.index(), |
| 693 typeOfIterator(forInStatement), _globalInferenceResults); | 685 typeOfIterator(forInStatement), _globalInferenceResults); |
| 694 } | 686 } |
| 695 | 687 |
| 696 TypeMask getInferredTypeOf(MemberEntity member) { | 688 TypeMask getInferredTypeOf(MemberEntity member) { |
| 697 return TypeMaskFactory.inferredTypeForMember( | 689 return TypeMaskFactory.inferredTypeForMember( |
| 698 member, _globalInferenceResults); | 690 member, _globalInferenceResults); |
| 699 } | 691 } |
| 700 | 692 |
| 701 TypeMask selectorTypeOf(Selector selector, TypeMask mask) { | 693 TypeMask selectorTypeOf(Selector selector, TypeMask mask) { |
| 702 return TypeMaskFactory.inferredTypeForSelector( | 694 return TypeMaskFactory.inferredTypeForSelector( |
| 703 selector, mask, _globalInferenceResults); | 695 selector, mask, _globalInferenceResults); |
| 704 } | 696 } |
| 705 | 697 |
| 706 TypeMask typeFromNativeBehavior( | 698 TypeMask typeFromNativeBehavior( |
| 707 native.NativeBehavior nativeBehavior, ClosedWorld closedWorld) { | 699 native.NativeBehavior nativeBehavior, ClosedWorld closedWorld) { |
| 708 return TypeMaskFactory.fromNativeBehavior(nativeBehavior, closedWorld); | 700 return TypeMaskFactory.fromNativeBehavior(nativeBehavior, closedWorld); |
| 709 } | 701 } |
| 710 } | 702 } |
| OLD | NEW |