| 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 |
| 38 implements KernelToLocalsMap { |
| 38 final Kernel kernel; | 39 final Kernel kernel; |
| 39 final JavaScriptBackend _backend; | 40 final JavaScriptBackend _backend; |
| 40 final Map<ir.Node, ast.Node> _nodeToAst; | 41 final Map<ir.Node, ast.Node> _nodeToAst; |
| 41 final Map<ir.Node, Element> _nodeToElement; | 42 final Map<ir.Node, Element> _nodeToElement; |
| 42 final Map<ir.VariableDeclaration, SyntheticLocal> _syntheticLocals = | 43 final Map<ir.VariableDeclaration, SyntheticLocal> _syntheticLocals = |
| 43 <ir.VariableDeclaration, SyntheticLocal>{}; | 44 <ir.VariableDeclaration, SyntheticLocal>{}; |
| 44 // TODO(efortuna): In an ideal world the TreeNodes should be some common | 45 // TODO(efortuna): In an ideal world the TreeNodes should be some common |
| 45 // interface we create for both ir.Statements and ir.SwitchCase (the | 46 // interface we create for both ir.Statements and ir.SwitchCase (the |
| 46 // ContinueSwitchStatement's target is a SwitchCase) rather than general | 47 // ContinueSwitchStatement's target is a SwitchCase) rather than general |
| 47 // TreeNode. Talking to Asger about this. | 48 // TreeNode. Talking to Asger about this. |
| (...skipping 159 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 207 ast.Node getNodeOrNull(ir.Node node) { | 208 ast.Node getNodeOrNull(ir.Node node) { |
| 208 return _nodeToAst[node]; | 209 return _nodeToAst[node]; |
| 209 } | 210 } |
| 210 | 211 |
| 211 void assertNodeIsSynthetic(ir.Node node) { | 212 void assertNodeIsSynthetic(ir.Node node) { |
| 212 assert(invariant( | 213 assert(invariant( |
| 213 CURRENT_ELEMENT_SPANNABLE, kernel.syntheticNodes.contains(node), | 214 CURRENT_ELEMENT_SPANNABLE, kernel.syntheticNodes.contains(node), |
| 214 message: "No synthetic marker found for $node")); | 215 message: "No synthetic marker found for $node")); |
| 215 } | 216 } |
| 216 | 217 |
| 218 @override |
| 217 Local getLocal(ir.VariableDeclaration variable) { | 219 Local getLocal(ir.VariableDeclaration variable) { |
| 218 // If this is a synthetic local, return the synthetic local | 220 // If this is a synthetic local, return the synthetic local |
| 219 if (variable.name == null) { | 221 if (variable.name == null) { |
| 220 return _syntheticLocals.putIfAbsent( | 222 return _syntheticLocals.putIfAbsent( |
| 221 variable, () => new SyntheticLocal("x", null, null)); | 223 variable, () => new SyntheticLocal("x", null, null)); |
| 222 } | 224 } |
| 223 return getElement(variable) as LocalElement; | 225 return getElement(variable) as LocalElement; |
| 224 } | 226 } |
| 225 | 227 |
| 226 FunctionSignature getFunctionSignature(ir.FunctionNode function) { | 228 FunctionSignature getFunctionSignature(ir.FunctionNode function) { |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 260 | 262 |
| 261 // Is the member a lazy initialized static or top-level member? | 263 // Is the member a lazy initialized static or top-level member? |
| 262 bool isLazyStatic(ir.Member member) { | 264 bool isLazyStatic(ir.Member member) { |
| 263 if (member is ir.Field) { | 265 if (member is ir.Field) { |
| 264 FieldElement field = _nodeToElement[member]; | 266 FieldElement field = _nodeToElement[member]; |
| 265 return field.constant == null; | 267 return field.constant == null; |
| 266 } | 268 } |
| 267 return false; | 269 return false; |
| 268 } | 270 } |
| 269 | 271 |
| 270 LibraryElement get jsHelperLibrary => | |
| 271 _compiler.commonElements.jsHelperLibrary; | |
| 272 | |
| 273 KernelJumpTarget getJumpTarget(ir.TreeNode node, | 272 KernelJumpTarget getJumpTarget(ir.TreeNode node, |
| 274 {bool isContinueTarget: false}) { | 273 {bool isContinueTarget: false}) { |
| 275 return _jumpTargets.putIfAbsent(node, () { | 274 return _jumpTargets.putIfAbsent(node, () { |
| 276 if (node is ir.LabeledStatement && _jumpTargets.containsKey(node.body)) { | 275 if (node is ir.LabeledStatement && _jumpTargets.containsKey(node.body)) { |
| 277 return _jumpTargets[node.body]; | 276 return _jumpTargets[node.body]; |
| 278 } | 277 } |
| 279 return new KernelJumpTarget(node, this, | 278 return new KernelJumpTarget(node, this, |
| 280 makeContinueLabel: isContinueTarget); | 279 makeContinueLabel: isContinueTarget); |
| 281 }); | 280 }); |
| 282 } | 281 } |
| 283 | 282 |
| 284 bool isInForeignLibrary(ir.Member member) => | |
| 285 _backend.isForeign(getElement(member)); | |
| 286 | |
| 287 native.NativeBehavior getNativeBehavior(ir.Node node) { | 283 native.NativeBehavior getNativeBehavior(ir.Node node) { |
| 288 return elements.getNativeData(getNode(node)); | 284 return elements.getNativeData(getNode(node)); |
| 289 } | 285 } |
| 290 | 286 |
| 291 js.Name getNameForJsGetName(ir.Node argument, ConstantValue constant) { | 287 js.Name getNameForJsGetName(ir.Node argument, ConstantValue constant) { |
| 292 int index = _extractEnumIndexFromConstantValue( | 288 int index = _extractEnumIndexFromConstantValue( |
| 293 constant, _compiler.commonElements.jsGetNameEnum); | 289 constant, _compiler.commonElements.jsGetNameEnum); |
| 294 if (index == null) return null; | 290 if (index == null) return null; |
| 295 return _backend.namer | 291 return _backend.namer |
| 296 .getNameForJsGetName(getNode(argument), JsGetName.values[index]); | 292 .getNameForJsGetName(getNode(argument), JsGetName.values[index]); |
| (...skipping 265 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 562 @override | 558 @override |
| 563 ast.Node get statement => null; | 559 ast.Node get statement => null; |
| 564 | 560 |
| 565 String toString() => 'Target:$targetStatement'; | 561 String toString() => 'Target:$targetStatement'; |
| 566 } | 562 } |
| 567 | 563 |
| 568 /// Special [JumpHandler] implementation used to handle continue statements | 564 /// Special [JumpHandler] implementation used to handle continue statements |
| 569 /// targeting switch cases. | 565 /// targeting switch cases. |
| 570 class KernelSwitchCaseJumpHandler extends SwitchCaseJumpHandler { | 566 class KernelSwitchCaseJumpHandler extends SwitchCaseJumpHandler { |
| 571 KernelSwitchCaseJumpHandler(GraphBuilder builder, JumpTarget target, | 567 KernelSwitchCaseJumpHandler(GraphBuilder builder, JumpTarget target, |
| 572 ir.SwitchStatement switchStatement, KernelAstAdapter astAdapter) | 568 ir.SwitchStatement switchStatement, KernelToLocalsMap localsMap) |
| 573 : super(builder, target) { | 569 : super(builder, target) { |
| 574 // The switch case indices must match those computed in | 570 // The switch case indices must match those computed in |
| 575 // [KernelSsaBuilder.buildSwitchCaseConstants]. | 571 // [KernelSsaBuilder.buildSwitchCaseConstants]. |
| 576 // Switch indices are 1-based so we can bypass the synthetic loop when no | 572 // Switch indices are 1-based so we can bypass the synthetic loop when no |
| 577 // cases match simply by branching on the index (which defaults to null). | 573 // cases match simply by branching on the index (which defaults to null). |
| 578 // TODO | 574 // TODO |
| 579 int switchIndex = 1; | 575 int switchIndex = 1; |
| 580 for (ir.SwitchCase switchCase in switchStatement.cases) { | 576 for (ir.SwitchCase switchCase in switchStatement.cases) { |
| 581 JumpTarget continueTarget = | 577 JumpTarget continueTarget = |
| 582 astAdapter.getJumpTarget(switchCase, isContinueTarget: true); | 578 localsMap.getJumpTarget(switchCase, isContinueTarget: true); |
| 583 assert(continueTarget is KernelJumpTarget); | 579 assert(continueTarget is KernelJumpTarget); |
| 584 targetIndexMap[continueTarget] = switchIndex; | 580 targetIndexMap[continueTarget] = switchIndex; |
| 585 assert(builder.jumpTargets[continueTarget] == null); | 581 assert(builder.jumpTargets[continueTarget] == null); |
| 586 builder.jumpTargets[continueTarget] = this; | 582 builder.jumpTargets[continueTarget] = this; |
| 587 switchIndex++; | 583 switchIndex++; |
| 588 } | 584 } |
| 589 } | 585 } |
| 590 } | 586 } |
| 591 | 587 |
| 592 class KernelAstTypeInferenceMap implements KernelToTypeInferenceMap { | 588 class KernelAstTypeInferenceMap implements KernelToTypeInferenceMap { |
| (...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 693 TypeMask selectorTypeOf(Selector selector, TypeMask mask) { | 689 TypeMask selectorTypeOf(Selector selector, TypeMask mask) { |
| 694 return TypeMaskFactory.inferredTypeForSelector( | 690 return TypeMaskFactory.inferredTypeForSelector( |
| 695 selector, mask, _globalInferenceResults); | 691 selector, mask, _globalInferenceResults); |
| 696 } | 692 } |
| 697 | 693 |
| 698 TypeMask typeFromNativeBehavior( | 694 TypeMask typeFromNativeBehavior( |
| 699 native.NativeBehavior nativeBehavior, ClosedWorld closedWorld) { | 695 native.NativeBehavior nativeBehavior, ClosedWorld closedWorld) { |
| 700 return TypeMaskFactory.fromNativeBehavior(nativeBehavior, closedWorld); | 696 return TypeMaskFactory.fromNativeBehavior(nativeBehavior, closedWorld); |
| 701 } | 697 } |
| 702 } | 698 } |
| OLD | NEW |