| 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;
|
|
|
|
|