Index: pkg/compiler/lib/src/kernel/kernel_backend_strategy.dart |
diff --git a/pkg/compiler/lib/src/kernel/kernel_backend_strategy.dart b/pkg/compiler/lib/src/kernel/kernel_backend_strategy.dart |
index 1ab568f4459928df650fdea4850517d2b597a65f..58be21caf77f6ab1642bea2fbfebff1930d50d9e 100644 |
--- a/pkg/compiler/lib/src/kernel/kernel_backend_strategy.dart |
+++ b/pkg/compiler/lib/src/kernel/kernel_backend_strategy.dart |
@@ -8,19 +8,19 @@ import 'package:kernel/ast.dart' as ir; |
import '../backend_strategy.dart'; |
import '../closure.dart'; |
-import '../common.dart'; |
import '../common/codegen.dart' show CodegenRegistry, CodegenWorkItem; |
import '../common/tasks.dart'; |
import '../compiler.dart'; |
import '../elements/entities.dart'; |
import '../elements/entity_utils.dart' as utils; |
-import '../elements/jumps.dart'; |
import '../enqueue.dart'; |
import '../io/source_information.dart'; |
import '../js/js_source_mapping.dart'; |
import '../js_backend/backend.dart'; |
import '../js_backend/native_data.dart'; |
import '../js_emitter/sorter.dart'; |
+import '../js_model/closure.dart'; |
+import '../js_model/locals.dart'; |
import '../kernel/element_map.dart'; |
import '../kernel/element_map_impl.dart'; |
import '../native/behavior.dart'; |
@@ -34,7 +34,6 @@ import '../universe/selector.dart'; |
import '../universe/world_builder.dart'; |
import '../universe/world_impact.dart'; |
import '../world.dart'; |
-import 'closure.dart'; |
import 'element_map_impl.dart'; |
import 'kernel_strategy.dart'; |
@@ -267,271 +266,6 @@ class KernelToTypeInferenceMapImpl implements KernelToTypeInferenceMap { |
} |
} |
-class GlobalLocalsMap { |
- Map<MemberEntity, KernelToLocalsMap> _localsMaps = |
- <MemberEntity, KernelToLocalsMap>{}; |
- |
- KernelToLocalsMap getLocalsMap(MemberEntity member) { |
- return _localsMaps.putIfAbsent( |
- member, () => new KernelToLocalsMapImpl(member)); |
- } |
-} |
- |
-class KernelToLocalsMapImpl implements KernelToLocalsMap { |
- final List<MemberEntity> _members = <MemberEntity>[]; |
- Map<ir.VariableDeclaration, KLocal> _map = <ir.VariableDeclaration, KLocal>{}; |
- Map<ir.TreeNode, KJumpTarget> _jumpTargetMap; |
- Set<ir.BreakStatement> _breaksAsContinue; |
- |
- MemberEntity get currentMember => _members.last; |
- |
- // TODO(johnniwinther): Compute this eagerly from the root of the member. |
- void _ensureJumpMap(ir.TreeNode node) { |
- if (_jumpTargetMap == null) { |
- JumpVisitor visitor = new JumpVisitor(currentMember); |
- |
- // Find the root node for the current member. |
- while (node is! ir.Member) { |
- node = node.parent; |
- } |
- |
- node.accept(visitor); |
- _jumpTargetMap = visitor.jumpTargetMap; |
- _breaksAsContinue = visitor.breaksAsContinue; |
- } |
- } |
- |
- KernelToLocalsMapImpl(MemberEntity member) { |
- _members.add(member); |
- } |
- |
- @override |
- void enterInlinedMember(MemberEntity member) { |
- _members.add(member); |
- } |
- |
- @override |
- void leaveInlinedMember(MemberEntity member) { |
- assert(member == currentMember); |
- _members.removeLast(); |
- } |
- |
- @override |
- JumpTarget getJumpTargetForBreak(ir.BreakStatement node) { |
- _ensureJumpMap(node.target); |
- JumpTarget target = _jumpTargetMap[node]; |
- assert(target != null, failedAt(currentMember, 'No target for $node.')); |
- return target; |
- } |
- |
- @override |
- bool generateContinueForBreak(ir.BreakStatement node) { |
- return _breaksAsContinue.contains(node); |
- } |
- |
- @override |
- JumpTarget getJumpTargetForContinueSwitch(ir.ContinueSwitchStatement node) { |
- _ensureJumpMap(node.target); |
- throw new UnimplementedError( |
- 'KernelToLocalsMapImpl.getJumpTargetForContinueSwitch'); |
- } |
- |
- @override |
- JumpTarget getJumpTargetForSwitchCase(ir.SwitchCase node) { |
- _ensureJumpMap(node); |
- throw new UnimplementedError( |
- 'KernelToLocalsMapImpl.getJumpTargetForSwitchCase'); |
- } |
- |
- @override |
- JumpTarget getJumpTargetForDo(ir.DoStatement node) { |
- _ensureJumpMap(node); |
- return _jumpTargetMap[node.parent]; |
- } |
- |
- @override |
- JumpTarget getJumpTargetForLabel(ir.LabeledStatement node) { |
- _ensureJumpMap(node); |
- return _jumpTargetMap[node]; |
- } |
- |
- @override |
- JumpTarget getJumpTargetForSwitch(ir.SwitchStatement node) { |
- _ensureJumpMap(node); |
- throw new UnimplementedError( |
- 'KernelToLocalsMapImpl.getJumpTargetForSwitch'); |
- } |
- |
- @override |
- JumpTarget getJumpTargetForFor(ir.ForStatement node) { |
- _ensureJumpMap(node); |
- return _jumpTargetMap[node]; |
- } |
- |
- @override |
- JumpTarget getJumpTargetForForIn(ir.ForInStatement node) { |
- _ensureJumpMap(node); |
- return _jumpTargetMap[node]; |
- } |
- |
- @override |
- JumpTarget getJumpTargetForWhile(ir.WhileStatement node) { |
- _ensureJumpMap(node); |
- return _jumpTargetMap[node]; |
- } |
- |
- @override |
- Local getLocal(ir.VariableDeclaration node) { |
- return _map.putIfAbsent(node, () { |
- return new KLocal(node.name, currentMember); |
- }); |
- } |
- |
- @override |
- LoopClosureScope getLoopClosureScope( |
- ClosureDataLookup closureLookup, ir.TreeNode node) { |
- return closureLookup.getLoopClosureScope(node); |
- } |
-} |
- |
-class JumpVisitor extends ir.Visitor { |
- int index = 0; |
- final MemberEntity member; |
- final Map<ir.TreeNode, KJumpTarget> jumpTargetMap = |
- <ir.TreeNode, KJumpTarget>{}; |
- final Set<ir.BreakStatement> breaksAsContinue = new Set<ir.BreakStatement>(); |
- |
- JumpVisitor(this.member); |
- |
- KJumpTarget _getJumpTarget(ir.TreeNode node) { |
- return jumpTargetMap.putIfAbsent(node, () { |
- return new KJumpTarget(member, index++); |
- }); |
- } |
- |
- @override |
- defaultNode(ir.Node node) => node.visitChildren(this); |
- |
- bool _canBeBreakTarget(ir.TreeNode node) { |
- // TODO(johnniwinther): Add more. |
- return node is ir.ForStatement || |
- node is ir.ForInStatement || |
- node is ir.WhileStatement; |
- } |
- |
- bool _canBeContinueTarget(ir.TreeNode node) { |
- // TODO(johnniwinther): Add more. |
- return node is ir.ForStatement || |
- node is ir.ForInStatement || |
- node is ir.WhileStatement; |
- } |
- |
- @override |
- visitBreakStatement(ir.BreakStatement node) { |
- // TODO(johnniwinther): Add labels if the enclosing loop is not the implicit |
- // break target. |
- KJumpTarget target; |
- ir.TreeNode body = node.target.body; |
- ir.TreeNode parent = node.target.parent; |
- if (_canBeBreakTarget(body)) { |
- // We have code like |
- // |
- // l1: for (int i = 0; i < 10; i++) { |
- // break l1: |
- // } |
- // |
- // and can therefore use the for loop as the break target. |
- target = _getJumpTarget(body); |
- target.isBreakTarget = true; |
- } else if (_canBeContinueTarget(parent)) { |
- // We have code like |
- // |
- // for (int i = 0; i < 10; i++) l1: { |
- // break l1: |
- // } |
- // |
- // and can therefore use the for loop as a continue target. |
- target = _getJumpTarget(parent); |
- target.isContinueTarget = true; |
- breaksAsContinue.add(node); |
- } else { |
- target = _getJumpTarget(node.target); |
- target.isBreakTarget = true; |
- } |
- jumpTargetMap[node] = target; |
- super.visitBreakStatement(node); |
- } |
-} |
- |
-class KJumpTarget extends JumpTarget<ir.Node> { |
- final MemberEntity memberContext; |
- final int nestingLevel; |
- |
- KJumpTarget(this.memberContext, this.nestingLevel); |
- |
- bool isBreakTarget = false; |
- bool isContinueTarget = false; |
- bool isSwitch = false; |
- |
- @override |
- Entity get executableContext => memberContext; |
- |
- @override |
- LabelDefinition<ir.Node> addLabel(ir.Node label, String labelName, |
- {bool isBreakTarget: false}) { |
- throw new UnimplementedError('KJumpTarget.addLabel'); |
- } |
- |
- @override |
- List<LabelDefinition<ir.Node>> get labels { |
- return const <LabelDefinition<ir.Node>>[]; |
- } |
- |
- @override |
- ir.Node get statement { |
- throw new UnimplementedError('KJumpTarget.statement'); |
- } |
- |
- String toString() { |
- StringBuffer sb = new StringBuffer(); |
- sb.write('KJumpTarget['); |
- sb.write('memberContext='); |
- sb.write(memberContext); |
- sb.write(',nestingLevel='); |
- sb.write(nestingLevel); |
- sb.write(',isBreakTarget='); |
- sb.write(isBreakTarget); |
- sb.write(',isContinueTarget='); |
- sb.write(isContinueTarget); |
- sb.write(']'); |
- return sb.toString(); |
- } |
-} |
- |
-class KLocal implements Local { |
- final String name; |
- final MemberEntity memberContext; |
- |
- KLocal(this.name, this.memberContext); |
- |
- @override |
- Entity get executableContext => memberContext; |
- |
- String toString() { |
- StringBuffer sb = new StringBuffer(); |
- sb.write('local('); |
- if (memberContext.enclosingClass != null) { |
- sb.write(memberContext.enclosingClass.name); |
- sb.write('.'); |
- } |
- sb.write(memberContext.name); |
- sb.write('#'); |
- sb.write(name); |
- sb.write(')'); |
- return sb.toString(); |
- } |
-} |
- |
class KernelSorter implements Sorter { |
final KernelToElementMapImpl elementMap; |