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 '../common.dart'; | 8 import '../common.dart'; |
| 9 import '../common/names.dart'; | 9 import '../common/names.dart'; |
| 10 import '../compiler.dart'; | 10 import '../compiler.dart'; |
| 11 import '../constants/expressions.dart'; | 11 import '../constants/expressions.dart'; |
| 12 import '../constants/values.dart'; | 12 import '../constants/values.dart'; |
| 13 import '../elements/resolution_types.dart'; | 13 import '../elements/resolution_types.dart'; |
| 14 import '../elements/elements.dart'; | 14 import '../elements/elements.dart'; |
| 15 import '../elements/modelx.dart'; | 15 import '../elements/modelx.dart'; |
| 16 import '../js/js.dart' as js; | 16 import '../js/js.dart' as js; |
| 17 import '../js_backend/backend_helpers.dart'; | 17 import '../js_backend/backend_helpers.dart'; |
| 18 import '../js_backend/js_backend.dart'; | 18 import '../js_backend/js_backend.dart'; |
| 19 import '../kernel/kernel.dart'; | 19 import '../kernel/kernel.dart'; |
| 20 import '../kernel/kernel_debug.dart'; | 20 import '../kernel/kernel_debug.dart'; |
| 21 import '../native/native.dart' as native; | 21 import '../native/native.dart' as native; |
| 22 import '../resolution/tree_elements.dart'; | 22 import '../resolution/tree_elements.dart'; |
| 23 import '../tree/tree.dart' as ast; | 23 import '../tree/tree.dart' as ast; |
| 24 import '../types/masks.dart'; | 24 import '../types/masks.dart'; |
| 25 import '../types/types.dart'; | 25 import '../types/types.dart'; |
| 26 import '../universe/call_structure.dart'; | 26 import '../universe/call_structure.dart'; |
| 27 import '../universe/selector.dart'; | 27 import '../universe/selector.dart'; |
| 28 import '../universe/side_effects.dart'; | 28 import '../universe/side_effects.dart'; |
| 29 import '../world.dart'; | 29 import '../world.dart'; |
| 30 import 'jump_handler.dart' show SwitchCaseJumpHandler; | |
| 30 import 'locals_handler.dart'; | 31 import 'locals_handler.dart'; |
| 31 import 'types.dart'; | 32 import 'types.dart'; |
| 32 | 33 |
| 33 /// 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. |
| 34 /// | 35 /// |
| 35 /// 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. |
| 36 class KernelAstAdapter { | 37 class KernelAstAdapter { |
| 37 final Kernel kernel; | 38 final Kernel kernel; |
| 38 final JavaScriptBackend _backend; | 39 final JavaScriptBackend _backend; |
| 39 final Map<ir.Node, ast.Node> _nodeToAst; | 40 final Map<ir.Node, ast.Node> _nodeToAst; |
| 40 final Map<ir.Node, Element> _nodeToElement; | 41 final Map<ir.Node, Element> _nodeToElement; |
| 41 final Map<ir.VariableDeclaration, SyntheticLocal> _syntheticLocals = | 42 final Map<ir.VariableDeclaration, SyntheticLocal> _syntheticLocals = |
| 42 <ir.VariableDeclaration, SyntheticLocal>{}; | 43 <ir.VariableDeclaration, SyntheticLocal>{}; |
| 43 final Map<ir.LabeledStatement, KernelJumpTarget> _jumpTargets = | 44 final Map<ir.TreeNode, KernelJumpTarget> _jumpTargets = |
|
sra1
2017/01/18 23:31:28
Consider adding an interface type in the Kernel (o
Emily Fortuna
2017/01/19 00:21:22
Done.
| |
| 44 <ir.LabeledStatement, KernelJumpTarget>{}; | 45 <ir.TreeNode, KernelJumpTarget>{}; |
| 45 DartTypeConverter _typeConverter; | 46 DartTypeConverter _typeConverter; |
| 46 ResolvedAst _resolvedAst; | 47 ResolvedAst _resolvedAst; |
| 47 | 48 |
| 48 /// Sometimes for resolution the resolved AST element needs to change (for | 49 /// Sometimes for resolution the resolved AST element needs to change (for |
| 49 /// example, if we're inlining, or if we're in a constructor, but then also | 50 /// example, if we're inlining, or if we're in a constructor, but then also |
| 50 /// constructing the field values). We keep track of this with a stack. | 51 /// constructing the field values). We keep track of this with a stack. |
| 51 final List<ResolvedAst> _resolvedAstStack = <ResolvedAst>[]; | 52 final List<ResolvedAst> _resolvedAstStack = <ResolvedAst>[]; |
| 52 | 53 |
| 53 KernelAstAdapter(this.kernel, this._backend, this._resolvedAst, | 54 KernelAstAdapter(this.kernel, this._backend, this._resolvedAst, |
| 54 this._nodeToAst, this._nodeToElement) { | 55 this._nodeToAst, this._nodeToElement) { |
| (...skipping 304 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 359 bool isLazyStatic(ir.Member member) { | 360 bool isLazyStatic(ir.Member member) { |
| 360 if (member is ir.Field) { | 361 if (member is ir.Field) { |
| 361 FieldElement field = _nodeToElement[member]; | 362 FieldElement field = _nodeToElement[member]; |
| 362 return field.constant == null; | 363 return field.constant == null; |
| 363 } | 364 } |
| 364 return false; | 365 return false; |
| 365 } | 366 } |
| 366 | 367 |
| 367 LibraryElement get jsHelperLibrary => _backend.helpers.jsHelperLibrary; | 368 LibraryElement get jsHelperLibrary => _backend.helpers.jsHelperLibrary; |
| 368 | 369 |
| 369 JumpTarget getTargetDefinition(ir.Node node) => | 370 KernelJumpTarget getJumpTarget(ir.TreeNode node) => |
| 370 elements.getTargetDefinition(getNode(node)); | 371 _jumpTargets.putIfAbsent(node, () { |
| 371 | 372 if (node is ir.LabeledStatement && |
| 372 JumpTarget getTargetOf(ir.Node node) => elements.getTargetOf(getNode(node)); | 373 _jumpTargets.containsKey((node as ir.LabeledStatement).body)) { |
| 373 | 374 return _jumpTargets[(node as ir.LabeledStatement).body]; |
| 374 KernelJumpTarget getJumpTarget(ir.LabeledStatement labeledStatement) => | 375 } |
| 375 _jumpTargets.putIfAbsent(labeledStatement, () { | 376 return new KernelJumpTarget(node); |
| 376 return new KernelJumpTarget(); | |
| 377 }); | 377 }); |
| 378 | 378 |
| 379 LabelDefinition getTargetLabel(ir.Node node) => | 379 LabelDefinition getTargetLabel(ir.Node node) => |
| 380 elements.getTargetLabel(getNode(node)); | 380 elements.getTargetLabel(getNode(node)); |
| 381 | 381 |
| 382 ir.Class get mapLiteralClass => | 382 ir.Class get mapLiteralClass => |
| 383 kernel.classes[_backend.helpers.mapLiteralClass]; | 383 kernel.classes[_backend.helpers.mapLiteralClass]; |
| 384 | 384 |
| 385 ir.Procedure get mapLiteralConstructor => | 385 ir.Procedure get mapLiteralConstructor => |
| 386 kernel.functions[_backend.helpers.mapLiteralConstructor]; | 386 kernel.functions[_backend.helpers.mapLiteralConstructor]; |
| (...skipping 11 matching lines...) Expand all Loading... | |
| 398 TypeMaskFactory.inferredReturnTypeForElement( | 398 TypeMaskFactory.inferredReturnTypeForElement( |
| 399 _backend.helpers.exceptionUnwrapper, _globalInferenceResults); | 399 _backend.helpers.exceptionUnwrapper, _globalInferenceResults); |
| 400 | 400 |
| 401 ir.Procedure get traceFromException => | 401 ir.Procedure get traceFromException => |
| 402 kernel.functions[_backend.helpers.traceFromException]; | 402 kernel.functions[_backend.helpers.traceFromException]; |
| 403 | 403 |
| 404 TypeMask get traceFromExceptionType => | 404 TypeMask get traceFromExceptionType => |
| 405 TypeMaskFactory.inferredReturnTypeForElement( | 405 TypeMaskFactory.inferredReturnTypeForElement( |
| 406 _backend.helpers.traceFromException, _globalInferenceResults); | 406 _backend.helpers.traceFromException, _globalInferenceResults); |
| 407 | 407 |
| 408 ir.Procedure get fallThroughError => | |
| 409 kernel.functions[_backend.helpers.fallThroughError]; | |
| 410 | |
| 411 TypeMask get fallThroughErrorType => | |
| 412 TypeMaskFactory.inferredReturnTypeForElement( | |
| 413 _backend.helpers.fallThroughError, _globalInferenceResults); | |
| 414 | |
| 408 ir.Procedure get mapLiteralUntypedMaker => | 415 ir.Procedure get mapLiteralUntypedMaker => |
| 409 kernel.functions[_backend.helpers.mapLiteralUntypedMaker]; | 416 kernel.functions[_backend.helpers.mapLiteralUntypedMaker]; |
| 410 | 417 |
| 411 MemberElement get jsIndexableLength => _backend.helpers.jsIndexableLength; | 418 MemberElement get jsIndexableLength => _backend.helpers.jsIndexableLength; |
| 412 | 419 |
| 413 ir.Procedure get checkConcurrentModificationError => | 420 ir.Procedure get checkConcurrentModificationError => |
| 414 kernel.functions[_backend.helpers.checkConcurrentModificationError]; | 421 kernel.functions[_backend.helpers.checkConcurrentModificationError]; |
| 415 | 422 |
| 416 TypeMask get checkConcurrentModificationErrorReturnType => | 423 TypeMask get checkConcurrentModificationErrorReturnType => |
| 417 TypeMaskFactory.inferredReturnTypeForElement( | 424 TypeMaskFactory.inferredReturnTypeForElement( |
| (...skipping 523 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 941 | 948 |
| 942 @override | 949 @override |
| 943 ConstantExpression visitStringLiteral(ir.StringLiteral node) { | 950 ConstantExpression visitStringLiteral(ir.StringLiteral node) { |
| 944 return new StringConstantExpression(node.value); | 951 return new StringConstantExpression(node.value); |
| 945 } | 952 } |
| 946 } | 953 } |
| 947 | 954 |
| 948 class KernelJumpTarget extends JumpTarget { | 955 class KernelJumpTarget extends JumpTarget { |
| 949 static int index = 0; | 956 static int index = 0; |
| 950 | 957 |
| 951 KernelJumpTarget() { | 958 /// Pointer to the actual executable statements that a jump target refers to. |
| 952 labels = <LabelDefinition>[ | 959 /// If this jump target was not initially constructed with a LabeledStatement, |
| 953 new LabelDefinitionX(null, 'l${index++}', this)..setBreakTarget() | 960 /// this value is identical to originalStatement. |
| 954 ]; | 961 ir.Node targetStatement; |
| 962 | |
| 963 /// The original statement used to construct this jump target. | |
| 964 /// If this jump target was not initially constructed with a LabeledStatement, | |
| 965 /// this value is identical to targetStatement. | |
| 966 ir.Node originalStatement; | |
| 967 | |
| 968 @override | |
| 969 bool isBreakTarget = false; | |
| 970 | |
| 971 @override | |
| 972 bool isContinueTarget = false; | |
| 973 | |
| 974 KernelJumpTarget(this.targetStatement) { | |
| 975 labels = <LabelDefinition>[]; | |
| 976 originalStatement = targetStatement; | |
| 977 if (targetStatement is ir.LabeledStatement) { | |
| 978 targetStatement = (targetStatement as ir.LabeledStatement).body; | |
| 979 labels.add( | |
| 980 new LabelDefinitionX(null, 'L${index++}', this)..setBreakTarget()); | |
| 981 isBreakTarget = true; | |
| 982 } | |
| 955 } | 983 } |
| 956 | 984 |
| 957 @override | 985 @override |
| 958 bool get isBreakTarget => true; | |
| 959 | |
| 960 set isBreakTarget(bool x) { | |
| 961 // do nothing, these are always break targets | |
| 962 } | |
| 963 | |
| 964 @override | |
| 965 bool get isContinueTarget => false; | |
| 966 | |
| 967 set isContinueTarget(bool x) { | |
| 968 // do nothing, these are always break targets | |
| 969 } | |
| 970 | |
| 971 @override | |
| 972 LabelDefinition addLabel(ast.Label label, String labelName) { | 986 LabelDefinition addLabel(ast.Label label, String labelName) { |
| 973 LabelDefinition result = new LabelDefinitionX(label, labelName, this); | 987 LabelDefinition result = new LabelDefinitionX(label, labelName, this); |
| 974 labels.add(result); | 988 labels.add(result); |
| 975 return result; | 989 return result; |
| 976 } | 990 } |
| 977 | 991 |
| 978 @override | 992 @override |
| 979 ExecutableElement get executableContext => null; | 993 ExecutableElement get executableContext => null; |
| 980 | 994 |
| 981 @override | 995 @override |
| 982 bool get isSwitch => false; | 996 bool get isSwitch => targetStatement is ir.SwitchStatement; |
| 983 | 997 |
| 984 @override | 998 @override |
| 985 bool get isTarget => true; | 999 bool get isTarget => isBreakTarget || isContinueTarget; |
| 986 | 1000 |
| 987 @override | 1001 @override |
| 988 List<LabelDefinition> labels; | 1002 List<LabelDefinition> labels; |
| 989 | 1003 |
| 990 @override | 1004 @override |
| 991 String get name => null; | 1005 String get name => null; |
| 992 | 1006 |
| 993 @override | 1007 @override |
| 994 int get nestingLevel => 1; | 1008 int get nestingLevel => 1; |
| 995 | 1009 |
| 996 @override | 1010 @override |
| 997 ast.Node get statement => null; | 1011 ast.Node get statement => null; |
| 1012 | |
| 1013 String toString() => 'Target:$targetStatement'; | |
| 998 } | 1014 } |
| OLD | NEW |