Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(505)

Side by Side Diff: pkg/compiler/lib/src/ssa/builder_kernel.dart

Issue 2932023003: Refactor LoopHandler to avoid calling KernelAstAdapter.getNode (Closed)
Patch Set: Created 3 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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:kernel/ast.dart' as ir; 5 import 'package:kernel/ast.dart' as ir;
6 6
7 import '../closure.dart'; 7 import '../closure.dart';
8 import '../common.dart'; 8 import '../common.dart';
9 import '../common/codegen.dart' show CodegenRegistry; 9 import '../common/codegen.dart' show CodegenRegistry;
10 import '../common/names.dart'; 10 import '../common/names.dart';
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after
79 79
80 @override 80 @override
81 JavaScriptBackend get backend => compiler.backend; 81 JavaScriptBackend get backend => compiler.backend;
82 82
83 @override 83 @override
84 TreeElements get elements => astAdapter.elements; 84 TreeElements get elements => astAdapter.elements;
85 85
86 SourceInformationBuilder sourceInformationBuilder; 86 SourceInformationBuilder sourceInformationBuilder;
87 final KernelToElementMap _elementMap; 87 final KernelToElementMap _elementMap;
88 final KernelToTypeInferenceMap _typeInferenceMap; 88 final KernelToTypeInferenceMap _typeInferenceMap;
89 final KernelToLocalsMap _localsMap; 89 final KernelToLocalsMap localsMap;
90 LoopHandler<ir.Node> loopHandler; 90 LoopHandler<ir.Node> loopHandler;
91 TypeBuilder typeBuilder; 91 TypeBuilder typeBuilder;
92 92
93 final Map<ir.VariableDeclaration, HInstruction> letBindings = 93 final Map<ir.VariableDeclaration, HInstruction> letBindings =
94 <ir.VariableDeclaration, HInstruction>{}; 94 <ir.VariableDeclaration, HInstruction>{};
95 95
96 /// True if we are visiting the expression of a throw statement; we assume 96 /// True if we are visiting the expression of a throw statement; we assume
97 /// this is a slow path. 97 /// this is a slow path.
98 bool _inExpressionOfThrow = false; 98 bool _inExpressionOfThrow = false;
99 99
100 KernelSsaBuilder( 100 KernelSsaBuilder(
101 this.targetElement, 101 this.targetElement,
102 ClassEntity contextClass, 102 ClassEntity contextClass,
103 this.target, 103 this.target,
104 this.compiler, 104 this.compiler,
105 this._elementMap, 105 this._elementMap,
106 this._typeInferenceMap, 106 this._typeInferenceMap,
107 this._localsMap, 107 this.localsMap,
108 this.closedWorld, 108 this.closedWorld,
109 this._worldBuilder, 109 this._worldBuilder,
110 this.registry, 110 this.registry,
111 this.closureToClassMapper, 111 this.closureToClassMapper,
112 // TODO(het): Should sourceInformationBuilder be in GraphBuilder? 112 // TODO(het): Should sourceInformationBuilder be in GraphBuilder?
113 this.sourceInformationBuilder, 113 this.sourceInformationBuilder,
114 this.functionNode, 114 this.functionNode,
115 {bool targetIsConstructorBody: false}) 115 {bool targetIsConstructorBody: false})
116 : this._targetIsConstructorBody = targetIsConstructorBody { 116 : this._targetIsConstructorBody = targetIsConstructorBody {
117 this.loopHandler = new KernelLoopHandler(this); 117 this.loopHandler = new KernelLoopHandler(this);
118 typeBuilder = new TypeBuilder(this); 118 typeBuilder = new TypeBuilder(this);
119 graph.element = targetElement; 119 graph.element = targetElement;
120 graph.sourceInformation = 120 graph.sourceInformation =
121 sourceInformationBuilder.buildVariableDeclaration(); 121 sourceInformationBuilder.buildVariableDeclaration();
122 this.localsHandler = new LocalsHandler(this, targetElement, targetElement, 122 this.localsHandler = new LocalsHandler(this, targetElement, targetElement,
123 contextClass, null, nativeData, interceptorData); 123 contextClass, null, nativeData, interceptorData);
124 _targetStack.add(targetElement); 124 _targetStack.add(targetElement);
125 } 125 }
126 126
127 @deprecated // Use [_elementMap] instead. 127 @deprecated // Use [_elementMap] instead.
128 KernelAstAdapter get astAdapter => _elementMap; 128 KernelAstAdapter get astAdapter => _elementMap;
129 129
130 CommonElements get _commonElements => _elementMap.commonElements; 130 CommonElements get _commonElements => _elementMap.commonElements;
131 131
132 HGraph build() { 132 HGraph build() {
133 return reporter.withCurrentElement(_localsMap.currentMember, () { 133 return reporter.withCurrentElement(localsMap.currentMember, () {
134 // TODO(het): no reason to do this here... 134 // TODO(het): no reason to do this here...
135 HInstruction.idCounter = 0; 135 HInstruction.idCounter = 0;
136 if (target is ir.Procedure) { 136 if (target is ir.Procedure) {
137 _targetFunction = (target as ir.Procedure).function; 137 _targetFunction = (target as ir.Procedure).function;
138 buildFunctionNode(_targetFunction); 138 buildFunctionNode(_targetFunction);
139 } else if (target is ir.Field) { 139 } else if (target is ir.Field) {
140 buildField(target); 140 buildField(target);
141 } else if (target is ir.Constructor) { 141 } else if (target is ir.Constructor) {
142 if (_targetIsConstructorBody) { 142 if (_targetIsConstructorBody) {
143 buildConstructorBody(target); 143 buildConstructorBody(target);
(...skipping 173 matching lines...) Expand 10 before | Expand all | Expand 10 after
317 bodyCallInputs.add(newObject); 317 bodyCallInputs.add(newObject);
318 318
319 // Pass uncaptured arguments first, captured arguments in a box, then type 319 // Pass uncaptured arguments first, captured arguments in a box, then type
320 // arguments. 320 // arguments.
321 321
322 ConstructorElement constructorElement = _elementMap.getConstructor(body); 322 ConstructorElement constructorElement = _elementMap.getConstructor(body);
323 ClosureClassMap parameterClosureData = 323 ClosureClassMap parameterClosureData =
324 closureToClassMapper.getMemberMap(constructorElement); 324 closureToClassMapper.getMemberMap(constructorElement);
325 325
326 void handleParameter(ir.VariableDeclaration node) { 326 void handleParameter(ir.VariableDeclaration node) {
327 Local parameter = _localsMap.getLocal(node); 327 Local parameter = localsMap.getLocal(node);
328 // If [parameter] is boxed, it will be a field in the box passed as the 328 // If [parameter] is boxed, it will be a field in the box passed as the
329 // last parameter. So no need to directly pass it. 329 // last parameter. So no need to directly pass it.
330 if (!localsHandler.isBoxed(parameter)) { 330 if (!localsHandler.isBoxed(parameter)) {
331 bodyCallInputs.add(localsHandler.readLocal(parameter)); 331 bodyCallInputs.add(localsHandler.readLocal(parameter));
332 } 332 }
333 } 333 }
334 334
335 // Provide the parameters to the generative constructor body. 335 // Provide the parameters to the generative constructor body.
336 body.function.positionalParameters.forEach(handleParameter); 336 body.function.positionalParameters.forEach(handleParameter);
337 body.function.namedParameters.toList() 337 body.function.namedParameters.toList()
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
383 /// Sets context for generating code that is the result of inlining 383 /// Sets context for generating code that is the result of inlining
384 /// [inlinedTarget]. 384 /// [inlinedTarget].
385 inlinedFrom(MemberEntity inlinedTarget, f()) { 385 inlinedFrom(MemberEntity inlinedTarget, f()) {
386 reporter.withCurrentElement(inlinedTarget, () { 386 reporter.withCurrentElement(inlinedTarget, () {
387 SourceInformationBuilder oldSourceInformationBuilder = 387 SourceInformationBuilder oldSourceInformationBuilder =
388 sourceInformationBuilder; 388 sourceInformationBuilder;
389 // TODO(sra): Update sourceInformationBuilder to Kernel. 389 // TODO(sra): Update sourceInformationBuilder to Kernel.
390 // sourceInformationBuilder = 390 // sourceInformationBuilder =
391 // sourceInformationBuilder.forContext(resolvedAst); 391 // sourceInformationBuilder.forContext(resolvedAst);
392 392
393 _localsMap.enterInlinedMember(inlinedTarget); 393 localsMap.enterInlinedMember(inlinedTarget);
394 _targetStack.add(inlinedTarget); 394 _targetStack.add(inlinedTarget);
395 var result = f(); 395 var result = f();
396 sourceInformationBuilder = oldSourceInformationBuilder; 396 sourceInformationBuilder = oldSourceInformationBuilder;
397 _targetStack.removeLast(); 397 _targetStack.removeLast();
398 _localsMap.leaveInlinedMember(inlinedTarget); 398 localsMap.leaveInlinedMember(inlinedTarget);
399 return result; 399 return result;
400 }); 400 });
401 } 401 }
402 402
403 /// Maps the instance fields of a class to their SSA values. 403 /// Maps the instance fields of a class to their SSA values.
404 Map<FieldEntity, HInstruction> _collectFieldValues(ir.Class clazz) { 404 Map<FieldEntity, HInstruction> _collectFieldValues(ir.Class clazz) {
405 Map<FieldEntity, HInstruction> fieldValues = <FieldEntity, HInstruction>{}; 405 Map<FieldEntity, HInstruction> fieldValues = <FieldEntity, HInstruction>{};
406 406
407 for (ir.Field node in clazz.fields) { 407 for (ir.Field node in clazz.fields) {
408 if (node.isInstanceMember) { 408 if (node.isInstanceMember) {
(...skipping 12 matching lines...) Expand all
421 } 421 }
422 422
423 return fieldValues; 423 return fieldValues;
424 } 424 }
425 425
426 /// Collects field initializers all the way up the inheritance chain. 426 /// Collects field initializers all the way up the inheritance chain.
427 void _buildInitializers( 427 void _buildInitializers(
428 ir.Constructor constructor, 428 ir.Constructor constructor,
429 List<ir.Constructor> constructorChain, 429 List<ir.Constructor> constructorChain,
430 Map<FieldEntity, HInstruction> fieldValues) { 430 Map<FieldEntity, HInstruction> fieldValues) {
431 assert(_elementMap.getConstructor(constructor) == _localsMap.currentMember); 431 assert(_elementMap.getConstructor(constructor) == localsMap.currentMember);
432 constructorChain.add(constructor); 432 constructorChain.add(constructor);
433 433
434 var foundSuperOrRedirectCall = false; 434 var foundSuperOrRedirectCall = false;
435 for (var initializer in constructor.initializers) { 435 for (var initializer in constructor.initializers) {
436 if (initializer is ir.FieldInitializer) { 436 if (initializer is ir.FieldInitializer) {
437 initializer.value.accept(this); 437 initializer.value.accept(this);
438 fieldValues[_elementMap.getField(initializer.field)] = pop(); 438 fieldValues[_elementMap.getField(initializer.field)] = pop();
439 } else if (initializer is ir.SuperInitializer) { 439 } else if (initializer is ir.SuperInitializer) {
440 assert(!foundSuperOrRedirectCall); 440 assert(!foundSuperOrRedirectCall);
441 foundSuperOrRedirectCall = true; 441 foundSuperOrRedirectCall = true;
(...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after
573 573
574 void _inlineSuperOrRedirectCommon( 574 void _inlineSuperOrRedirectCommon(
575 ir.Initializer initializer, 575 ir.Initializer initializer,
576 ir.Constructor constructor, 576 ir.Constructor constructor,
577 List<HInstruction> arguments, 577 List<HInstruction> arguments,
578 List<ir.Constructor> constructorChain, 578 List<ir.Constructor> constructorChain,
579 Map<FieldEntity, HInstruction> fieldValues, 579 Map<FieldEntity, HInstruction> fieldValues,
580 ir.Constructor caller) { 580 ir.Constructor caller) {
581 var index = 0; 581 var index = 0;
582 void handleParameter(ir.VariableDeclaration node) { 582 void handleParameter(ir.VariableDeclaration node) {
583 Local parameter = _localsMap.getLocal(node); 583 Local parameter = localsMap.getLocal(node);
584 HInstruction argument = arguments[index++]; 584 HInstruction argument = arguments[index++];
585 // Because we are inlining the initializer, we must update 585 // Because we are inlining the initializer, we must update
586 // what was given as parameter. This will be used in case 586 // what was given as parameter. This will be used in case
587 // there is a parameter check expression in the initializer. 587 // there is a parameter check expression in the initializer.
588 parameters[parameter] = argument; 588 parameters[parameter] = argument;
589 localsHandler.updateLocal(parameter, argument); 589 localsHandler.updateLocal(parameter, argument);
590 } 590 }
591 591
592 constructor.function.positionalParameters.forEach(handleParameter); 592 constructor.function.positionalParameters.forEach(handleParameter);
593 constructor.function.namedParameters.toList() 593 constructor.function.namedParameters.toList()
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after
673 void removeImplicitInstantiation(DartType type) { 673 void removeImplicitInstantiation(DartType type) {
674 if (type != null) { 674 if (type != null) {
675 currentImplicitInstantiations.removeLast(); 675 currentImplicitInstantiations.removeLast();
676 } 676 }
677 } 677 }
678 678
679 void openFunction([ir.FunctionNode function]) { 679 void openFunction([ir.FunctionNode function]) {
680 Map<Local, TypeMask> parameterMap = <Local, TypeMask>{}; 680 Map<Local, TypeMask> parameterMap = <Local, TypeMask>{};
681 if (function != null) { 681 if (function != null) {
682 void handleParameter(ir.VariableDeclaration node) { 682 void handleParameter(ir.VariableDeclaration node) {
683 Local local = _localsMap.getLocal(node); 683 Local local = localsMap.getLocal(node);
684 parameterMap[local] = 684 parameterMap[local] =
685 _typeInferenceMap.getInferredTypeOfParameter(local); 685 _typeInferenceMap.getInferredTypeOfParameter(local);
686 } 686 }
687 687
688 function.positionalParameters.forEach(handleParameter); 688 function.positionalParameters.forEach(handleParameter);
689 function.namedParameters.toList() 689 function.namedParameters.toList()
690 ..sort(namedOrdering) 690 ..sort(namedOrdering)
691 ..forEach(handleParameter); 691 ..forEach(handleParameter);
692 } 692 }
693 693
(...skipping 293 matching lines...) Expand 10 before | Expand all | Expand 10 after
987 // Find a type for the element. Use the element type of the indexer of the 987 // Find a type for the element. Use the element type of the indexer of the
988 // array, as this is stronger than the iterator's `get current` type, for 988 // array, as this is stronger than the iterator's `get current` type, for
989 // example, `get current` includes null. 989 // example, `get current` includes null.
990 // TODO(sra): The element type of a container type mask might be better. 990 // TODO(sra): The element type of a container type mask might be better.
991 TypeMask type = _typeInferenceMap.inferredIndexType(forInStatement); 991 TypeMask type = _typeInferenceMap.inferredIndexType(forInStatement);
992 992
993 HInstruction index = localsHandler.readLocal(indexVariable); 993 HInstruction index = localsHandler.readLocal(indexVariable);
994 HInstruction value = new HIndex(array, index, null, type); 994 HInstruction value = new HIndex(array, index, null, type);
995 add(value); 995 add(value);
996 996
997 Local loopVariableLocal = _localsMap.getLocal(forInStatement.variable); 997 Local loopVariableLocal = localsMap.getLocal(forInStatement.variable);
998 localsHandler.updateLocal(loopVariableLocal, value); 998 localsHandler.updateLocal(loopVariableLocal, value);
999 // Hint to name loop value after name of loop variable. 999 // Hint to name loop value after name of loop variable.
1000 if (loopVariableLocal is! SyntheticLocal) { 1000 if (loopVariableLocal is! SyntheticLocal) {
1001 value.sourceElement ??= loopVariableLocal; 1001 value.sourceElement ??= loopVariableLocal;
1002 } 1002 }
1003 1003
1004 forInStatement.body.accept(this); 1004 forInStatement.body.accept(this);
1005 } 1005 }
1006 1006
1007 void buildUpdate() { 1007 void buildUpdate() {
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
1048 TypeMask mask = _typeInferenceMap.typeOfIteratorMoveNext(forInStatement); 1048 TypeMask mask = _typeInferenceMap.typeOfIteratorMoveNext(forInStatement);
1049 _pushDynamicInvocation(forInStatement, mask, <HInstruction>[iterator], 1049 _pushDynamicInvocation(forInStatement, mask, <HInstruction>[iterator],
1050 selector: Selectors.moveNext); 1050 selector: Selectors.moveNext);
1051 return popBoolified(); 1051 return popBoolified();
1052 } 1052 }
1053 1053
1054 void buildBody() { 1054 void buildBody() {
1055 TypeMask mask = _typeInferenceMap.typeOfIteratorCurrent(forInStatement); 1055 TypeMask mask = _typeInferenceMap.typeOfIteratorCurrent(forInStatement);
1056 _pushDynamicInvocation(forInStatement, mask, [iterator], 1056 _pushDynamicInvocation(forInStatement, mask, [iterator],
1057 selector: Selectors.current); 1057 selector: Selectors.current);
1058 Local loopVariableLocal = _localsMap.getLocal(forInStatement.variable); 1058 Local loopVariableLocal = localsMap.getLocal(forInStatement.variable);
1059 HInstruction value = pop(); 1059 HInstruction value = pop();
1060 localsHandler.updateLocal(loopVariableLocal, value); 1060 localsHandler.updateLocal(loopVariableLocal, value);
1061 // Hint to name loop value after name of loop variable. 1061 // Hint to name loop value after name of loop variable.
1062 if (loopVariableLocal is! SyntheticLocal) { 1062 if (loopVariableLocal is! SyntheticLocal) {
1063 value.sourceElement ??= loopVariableLocal; 1063 value.sourceElement ??= loopVariableLocal;
1064 } 1064 }
1065 forInStatement.body.accept(this); 1065 forInStatement.body.accept(this);
1066 } 1066 }
1067 1067
1068 loopHandler.handleLoop( 1068 loopHandler.handleLoop(
(...skipping 21 matching lines...) Expand all
1090 HInstruction future = pop(); 1090 HInstruction future = pop();
1091 push(new HAwait(future, closedWorld.commonMasks.dynamicType)); 1091 push(new HAwait(future, closedWorld.commonMasks.dynamicType));
1092 return popBoolified(); 1092 return popBoolified();
1093 } 1093 }
1094 1094
1095 void buildBody() { 1095 void buildBody() {
1096 TypeMask mask = _typeInferenceMap.typeOfIteratorCurrent(forInStatement); 1096 TypeMask mask = _typeInferenceMap.typeOfIteratorCurrent(forInStatement);
1097 _pushDynamicInvocation(forInStatement, mask, [streamIterator], 1097 _pushDynamicInvocation(forInStatement, mask, [streamIterator],
1098 selector: Selectors.current); 1098 selector: Selectors.current);
1099 localsHandler.updateLocal( 1099 localsHandler.updateLocal(
1100 _localsMap.getLocal(forInStatement.variable), pop()); 1100 localsMap.getLocal(forInStatement.variable), pop());
1101 forInStatement.body.accept(this); 1101 forInStatement.body.accept(this);
1102 } 1102 }
1103 1103
1104 void buildUpdate() {} 1104 void buildUpdate() {}
1105 1105
1106 // Creates a synthetic try/finally block in case anything async goes amiss. 1106 // Creates a synthetic try/finally block in case anything async goes amiss.
1107 TryCatchFinallyBuilder tryBuilder = new TryCatchFinallyBuilder(this); 1107 TryCatchFinallyBuilder tryBuilder = new TryCatchFinallyBuilder(this);
1108 // Build fake try body: 1108 // Build fake try body:
1109 loopHandler.handleLoop(forInStatement, buildInitializer, buildCondition, 1109 loopHandler.handleLoop(forInStatement, buildInitializer, buildCondition,
1110 buildUpdate, buildBody); 1110 buildUpdate, buildBody);
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
1154 loopHandler.handleLoop(whileStatement, () {}, buildCondition, () {}, () { 1154 loopHandler.handleLoop(whileStatement, () {}, buildCondition, () {}, () {
1155 whileStatement.body.accept(this); 1155 whileStatement.body.accept(this);
1156 }); 1156 });
1157 } 1157 }
1158 1158
1159 @override 1159 @override
1160 visitDoStatement(ir.DoStatement doStatement) { 1160 visitDoStatement(ir.DoStatement doStatement) {
1161 // TODO(efortuna): I think this can be rewritten using 1161 // TODO(efortuna): I think this can be rewritten using
1162 // LoopHandler.handleLoop with some tricks about when the "update" happens. 1162 // LoopHandler.handleLoop with some tricks about when the "update" happens.
1163 LocalsHandler savedLocals = new LocalsHandler.from(localsHandler); 1163 LocalsHandler savedLocals = new LocalsHandler.from(localsHandler);
1164 localsHandler.startLoop(astAdapter.getNode(doStatement)); 1164 ClosureScope scopeData = localsMap.getClosureScopeForLoop(
1165 localsHandler.closureData, doStatement);
1166 localsHandler.startLoop(scopeData);
1165 JumpHandler jumpHandler = loopHandler.beginLoopHeader(doStatement); 1167 JumpHandler jumpHandler = loopHandler.beginLoopHeader(doStatement);
1166 HLoopInformation loopInfo = current.loopInformation; 1168 HLoopInformation loopInfo = current.loopInformation;
1167 HBasicBlock loopEntryBlock = current; 1169 HBasicBlock loopEntryBlock = current;
1168 HBasicBlock bodyEntryBlock = current; 1170 HBasicBlock bodyEntryBlock = current;
1169 JumpTarget target = _localsMap.getJumpTarget(doStatement); 1171 JumpTarget target = localsMap.getJumpTarget(doStatement);
1170 bool hasContinues = target != null && target.isContinueTarget; 1172 bool hasContinues = target != null && target.isContinueTarget;
1171 if (hasContinues) { 1173 if (hasContinues) {
1172 // Add extra block to hang labels on. 1174 // Add extra block to hang labels on.
1173 // It doesn't currently work if they are on the same block as the 1175 // It doesn't currently work if they are on the same block as the
1174 // HLoopInfo. The handling of HLabeledBlockInformation will visit a 1176 // HLoopInfo. The handling of HLabeledBlockInformation will visit a
1175 // SubGraph that starts at the same block again, so the HLoopInfo is 1177 // SubGraph that starts at the same block again, so the HLoopInfo is
1176 // either handled twice, or it's handled after the labeled block info, 1178 // either handled twice, or it's handled after the labeled block info,
1177 // both of which generate the wrong code. 1179 // both of which generate the wrong code.
1178 // Using a separate block is just a simple workaround. 1180 // Using a separate block is just a simple workaround.
1179 bodyEntryBlock = openNewBlock(); 1181 bodyEntryBlock = openNewBlock();
1180 } 1182 }
1181 localsHandler.enterLoopBody(astAdapter.getNode(doStatement)); 1183 localsHandler.enterLoopBody(scopeData);
1182 doStatement.body.accept(this); 1184 doStatement.body.accept(this);
1183 1185
1184 // If there are no continues we could avoid the creation of the condition 1186 // If there are no continues we could avoid the creation of the condition
1185 // block. This could also lead to a block having multiple entries and exits. 1187 // block. This could also lead to a block having multiple entries and exits.
1186 HBasicBlock bodyExitBlock; 1188 HBasicBlock bodyExitBlock;
1187 bool isAbortingBody = false; 1189 bool isAbortingBody = false;
1188 if (current != null) { 1190 if (current != null) {
1189 bodyExitBlock = close(new HGoto()); 1191 bodyExitBlock = close(new HGoto());
1190 } else { 1192 } else {
1191 isAbortingBody = true; 1193 isAbortingBody = true;
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after
1271 loopEntryBlock.loopInformation = null; 1273 loopEntryBlock.loopInformation = null;
1272 1274
1273 if (jumpHandler.hasAnyBreak()) { 1275 if (jumpHandler.hasAnyBreak()) {
1274 // Null branchBlock because the body of the do-while loop always aborts, 1276 // Null branchBlock because the body of the do-while loop always aborts,
1275 // so we never get to the condition. 1277 // so we never get to the condition.
1276 loopHandler.endLoop(loopEntryBlock, null, jumpHandler, localsHandler); 1278 loopHandler.endLoop(loopEntryBlock, null, jumpHandler, localsHandler);
1277 1279
1278 // Since the body of the loop has a break, we attach a synthesized label 1280 // Since the body of the loop has a break, we attach a synthesized label
1279 // to the body. 1281 // to the body.
1280 SubGraph bodyGraph = new SubGraph(bodyEntryBlock, bodyExitBlock); 1282 SubGraph bodyGraph = new SubGraph(bodyEntryBlock, bodyExitBlock);
1281 JumpTarget target = _localsMap.getJumpTarget(doStatement); 1283 JumpTarget target = localsMap.getJumpTarget(doStatement);
1282 LabelDefinition label = target.addLabel(null, 'loop'); 1284 LabelDefinition label = target.addLabel(null, 'loop');
1283 label.setBreakTarget(); 1285 label.setBreakTarget();
1284 HLabeledBlockInformation info = new HLabeledBlockInformation( 1286 HLabeledBlockInformation info = new HLabeledBlockInformation(
1285 new HSubGraphBlockInformation(bodyGraph), <LabelDefinition>[label]); 1287 new HSubGraphBlockInformation(bodyGraph), <LabelDefinition>[label]);
1286 loopEntryBlock.setBlockFlow(info, current); 1288 loopEntryBlock.setBlockFlow(info, current);
1287 jumpHandler.forEachBreak((HBreak breakInstruction, _) { 1289 jumpHandler.forEachBreak((HBreak breakInstruction, _) {
1288 HBasicBlock block = breakInstruction.block; 1290 HBasicBlock block = breakInstruction.block;
1289 block.addAtExit(new HBreak.toLabel(label)); 1291 block.addAtExit(new HBreak.toLabel(label));
1290 block.remove(breakInstruction); 1292 block.remove(breakInstruction);
1291 }); 1293 });
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after
1396 } 1398 }
1397 1399
1398 /// Creates a [JumpHandler] for a statement. The node must be a jump 1400 /// Creates a [JumpHandler] for a statement. The node must be a jump
1399 /// target. If there are no breaks or continues targeting the statement, 1401 /// target. If there are no breaks or continues targeting the statement,
1400 /// a special "null handler" is returned. 1402 /// a special "null handler" is returned.
1401 /// 1403 ///
1402 /// [isLoopJump] is true when the jump handler is for a loop. This is used 1404 /// [isLoopJump] is true when the jump handler is for a loop. This is used
1403 /// to distinguish the synthesized loop created for a switch statement with 1405 /// to distinguish the synthesized loop created for a switch statement with
1404 /// continue statements from simple switch statements. 1406 /// continue statements from simple switch statements.
1405 JumpHandler createJumpHandler(ir.TreeNode node, {bool isLoopJump: false}) { 1407 JumpHandler createJumpHandler(ir.TreeNode node, {bool isLoopJump: false}) {
1406 JumpTarget target = _localsMap.getJumpTarget(node); 1408 JumpTarget target = localsMap.getJumpTarget(node);
1407 assert(target is KernelJumpTarget); 1409 assert(target is KernelJumpTarget);
1408 if (target == null) { 1410 if (target == null) {
1409 // No breaks or continues to this node. 1411 // No breaks or continues to this node.
1410 return new NullJumpHandler(reporter); 1412 return new NullJumpHandler(reporter);
1411 } 1413 }
1412 if (isLoopJump && node is ir.SwitchStatement) { 1414 if (isLoopJump && node is ir.SwitchStatement) {
1413 return new KernelSwitchCaseJumpHandler(this, target, node, _localsMap); 1415 return new KernelSwitchCaseJumpHandler(this, target, node, localsMap);
1414 } 1416 }
1415 1417
1416 return new JumpHandler(this, target); 1418 return new JumpHandler(this, target);
1417 } 1419 }
1418 1420
1419 @override 1421 @override
1420 void visitBreakStatement(ir.BreakStatement breakStatement) { 1422 void visitBreakStatement(ir.BreakStatement breakStatement) {
1421 assert(!isAborted()); 1423 assert(!isAborted());
1422 handleInTryStatement(); 1424 handleInTryStatement();
1423 JumpTarget target = _localsMap.getJumpTarget(breakStatement.target); 1425 JumpTarget target = localsMap.getJumpTarget(breakStatement.target);
1424 assert(target != null); 1426 assert(target != null);
1425 JumpHandler handler = jumpTargets[target]; 1427 JumpHandler handler = jumpTargets[target];
1426 assert(handler != null); 1428 assert(handler != null);
1427 if (handler.labels.isNotEmpty) { 1429 if (handler.labels.isNotEmpty) {
1428 handler.generateBreak(handler.labels.first); 1430 handler.generateBreak(handler.labels.first);
1429 } else { 1431 } else {
1430 handler.generateBreak(); 1432 handler.generateBreak();
1431 } 1433 }
1432 } 1434 }
1433 1435
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
1486 constants[caseExpression] = constant; 1488 constants[caseExpression] = constant;
1487 } 1489 }
1488 } 1490 }
1489 return constants; 1491 return constants;
1490 } 1492 }
1491 1493
1492 @override 1494 @override
1493 void visitContinueSwitchStatement( 1495 void visitContinueSwitchStatement(
1494 ir.ContinueSwitchStatement switchStatement) { 1496 ir.ContinueSwitchStatement switchStatement) {
1495 handleInTryStatement(); 1497 handleInTryStatement();
1496 JumpTarget target = _localsMap.getJumpTarget(switchStatement.target); 1498 JumpTarget target = localsMap.getJumpTarget(switchStatement.target);
1497 assert(target != null); 1499 assert(target != null);
1498 JumpHandler handler = jumpTargets[target]; 1500 JumpHandler handler = jumpTargets[target];
1499 assert(handler != null); 1501 assert(handler != null);
1500 assert(target.labels.isNotEmpty); 1502 assert(target.labels.isNotEmpty);
1501 handler.generateContinue(target.labels.first); 1503 handler.generateContinue(target.labels.first);
1502 } 1504 }
1503 1505
1504 @override 1506 @override
1505 void visitSwitchStatement(ir.SwitchStatement switchStatement) { 1507 void visitSwitchStatement(ir.SwitchStatement switchStatement) {
1506 // The switch case indices must match those computed in 1508 // The switch case indices must match those computed in
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after
1606 // case 1: s_1; break l; 1608 // case 1: s_1; break l;
1607 // case 2: s_2; target = i; continue l; 1609 // case 2: s_2; target = i; continue l;
1608 // ... 1610 // ...
1609 // case n: s_n; target = j; continue l; 1611 // case n: s_n; target = j; continue l;
1610 // } 1612 // }
1611 // } 1613 // }
1612 // 1614 //
1613 // This is because JS does not have this same "continue label" semantics so 1615 // This is because JS does not have this same "continue label" semantics so
1614 // we encode it in the form of a state machine. 1616 // we encode it in the form of a state machine.
1615 1617
1616 JumpTarget switchTarget = _localsMap.getJumpTarget(switchStatement); 1618 JumpTarget switchTarget = localsMap.getJumpTarget(switchStatement);
1617 localsHandler.updateLocal(switchTarget, graph.addConstantNull(closedWorld)); 1619 localsHandler.updateLocal(switchTarget, graph.addConstantNull(closedWorld));
1618 1620
1619 var switchCases = switchStatement.cases; 1621 var switchCases = switchStatement.cases;
1620 if (!hasDefault) { 1622 if (!hasDefault) {
1621 // Use null as the marker for a synthetic default clause. 1623 // Use null as the marker for a synthetic default clause.
1622 // The synthetic default is added because otherwise there would be no 1624 // The synthetic default is added because otherwise there would be no
1623 // good place to give a default value to the local. 1625 // good place to give a default value to the local.
1624 switchCases = new List<ir.SwitchCase>.from(switchCases); 1626 switchCases = new List<ir.SwitchCase>.from(switchCases);
1625 switchCases.add(null); 1627 switchCases.add(null);
1626 } 1628 }
(...skipping 451 matching lines...) Expand 10 before | Expand all | Expand 10 after
2078 2080
2079 @override 2081 @override
2080 void visitVariableGet(ir.VariableGet variableGet) { 2082 void visitVariableGet(ir.VariableGet variableGet) {
2081 ir.VariableDeclaration variable = variableGet.variable; 2083 ir.VariableDeclaration variable = variableGet.variable;
2082 HInstruction letBinding = letBindings[variable]; 2084 HInstruction letBinding = letBindings[variable];
2083 if (letBinding != null) { 2085 if (letBinding != null) {
2084 stack.add(letBinding); 2086 stack.add(letBinding);
2085 return; 2087 return;
2086 } 2088 }
2087 2089
2088 Local local = _localsMap.getLocal(variableGet.variable); 2090 Local local = localsMap.getLocal(variableGet.variable);
2089 stack.add(localsHandler.readLocal(local)); 2091 stack.add(localsHandler.readLocal(local));
2090 } 2092 }
2091 2093
2092 @override 2094 @override
2093 void visitPropertySet(ir.PropertySet propertySet) { 2095 void visitPropertySet(ir.PropertySet propertySet) {
2094 propertySet.receiver.accept(this); 2096 propertySet.receiver.accept(this);
2095 HInstruction receiver = pop(); 2097 HInstruction receiver = pop();
2096 propertySet.value.accept(this); 2098 propertySet.value.accept(this);
2097 HInstruction value = pop(); 2099 HInstruction value = pop();
2098 2100
(...skipping 27 matching lines...) Expand all
2126 2128
2127 @override 2129 @override
2128 void visitVariableSet(ir.VariableSet variableSet) { 2130 void visitVariableSet(ir.VariableSet variableSet) {
2129 variableSet.value.accept(this); 2131 variableSet.value.accept(this);
2130 HInstruction value = pop(); 2132 HInstruction value = pop();
2131 _visitLocalSetter(variableSet.variable, value); 2133 _visitLocalSetter(variableSet.variable, value);
2132 } 2134 }
2133 2135
2134 @override 2136 @override
2135 void visitVariableDeclaration(ir.VariableDeclaration declaration) { 2137 void visitVariableDeclaration(ir.VariableDeclaration declaration) {
2136 Local local = _localsMap.getLocal(declaration); 2138 Local local = localsMap.getLocal(declaration);
2137 if (declaration.initializer == null) { 2139 if (declaration.initializer == null) {
2138 HInstruction initialValue = graph.addConstantNull(closedWorld); 2140 HInstruction initialValue = graph.addConstantNull(closedWorld);
2139 localsHandler.updateLocal(local, initialValue); 2141 localsHandler.updateLocal(local, initialValue);
2140 } else { 2142 } else {
2141 declaration.initializer.accept(this); 2143 declaration.initializer.accept(this);
2142 HInstruction initialValue = pop(); 2144 HInstruction initialValue = pop();
2143 2145
2144 _visitLocalSetter(declaration, initialValue); 2146 _visitLocalSetter(declaration, initialValue);
2145 2147
2146 // Ignore value 2148 // Ignore value
2147 pop(); 2149 pop();
2148 } 2150 }
2149 } 2151 }
2150 2152
2151 void _visitLocalSetter(ir.VariableDeclaration variable, HInstruction value) { 2153 void _visitLocalSetter(ir.VariableDeclaration variable, HInstruction value) {
2152 Local local = _localsMap.getLocal(variable); 2154 Local local = localsMap.getLocal(variable);
2153 2155
2154 // Give the value a name if it doesn't have one already. 2156 // Give the value a name if it doesn't have one already.
2155 if (value.sourceElement == null) { 2157 if (value.sourceElement == null) {
2156 value.sourceElement = local; 2158 value.sourceElement = local;
2157 } 2159 }
2158 2160
2159 stack.add(value); 2161 stack.add(value);
2160 localsHandler.updateLocal( 2162 localsHandler.updateLocal(
2161 local, 2163 local,
2162 typeBuilder.potentiallyCheckOrTrustType( 2164 typeBuilder.potentiallyCheckOrTrustType(
(...skipping 1204 matching lines...) Expand 10 before | Expand all | Expand 10 after
3367 // `guard` is often `dynamic`, which generates `true`. 3369 // `guard` is often `dynamic`, which generates `true`.
3368 kernelBuilder.pushIsTest( 3370 kernelBuilder.pushIsTest(
3369 catchBlock.exception, catchBlock.guard, unwrappedException); 3371 catchBlock.exception, catchBlock.guard, unwrappedException);
3370 } 3372 }
3371 3373
3372 void visitThen() { 3374 void visitThen() {
3373 ir.Catch catchBlock = tryCatch.catches[catchesIndex]; 3375 ir.Catch catchBlock = tryCatch.catches[catchesIndex];
3374 catchesIndex++; 3376 catchesIndex++;
3375 if (catchBlock.exception != null) { 3377 if (catchBlock.exception != null) {
3376 LocalVariableElement exceptionVariable = 3378 LocalVariableElement exceptionVariable =
3377 kernelBuilder._localsMap.getLocal(catchBlock.exception); 3379 kernelBuilder.localsMap.getLocal(catchBlock.exception);
3378 kernelBuilder.localsHandler 3380 kernelBuilder.localsHandler
3379 .updateLocal(exceptionVariable, unwrappedException); 3381 .updateLocal(exceptionVariable, unwrappedException);
3380 } 3382 }
3381 if (catchBlock.stackTrace != null) { 3383 if (catchBlock.stackTrace != null) {
3382 kernelBuilder._pushStaticInvocation( 3384 kernelBuilder._pushStaticInvocation(
3383 kernelBuilder._commonElements.traceFromException, 3385 kernelBuilder._commonElements.traceFromException,
3384 [exception], 3386 [exception],
3385 kernelBuilder._typeInferenceMap.getReturnTypeOf( 3387 kernelBuilder._typeInferenceMap.getReturnTypeOf(
3386 kernelBuilder._commonElements.traceFromException)); 3388 kernelBuilder._commonElements.traceFromException));
3387 HInstruction traceInstruction = kernelBuilder.pop(); 3389 HInstruction traceInstruction = kernelBuilder.pop();
3388 LocalVariableElement traceVariable = 3390 LocalVariableElement traceVariable =
3389 kernelBuilder._localsMap.getLocal(catchBlock.stackTrace); 3391 kernelBuilder.localsMap.getLocal(catchBlock.stackTrace);
3390 kernelBuilder.localsHandler 3392 kernelBuilder.localsHandler
3391 .updateLocal(traceVariable, traceInstruction); 3393 .updateLocal(traceVariable, traceInstruction);
3392 } 3394 }
3393 catchBlock.body.accept(kernelBuilder); 3395 catchBlock.body.accept(kernelBuilder);
3394 } 3396 }
3395 3397
3396 void visitElse() { 3398 void visitElse() {
3397 if (catchesIndex >= tryCatch.catches.length) { 3399 if (catchesIndex >= tryCatch.catches.length) {
3398 kernelBuilder.closeAndGotoExit(new HThrow( 3400 kernelBuilder.closeAndGotoExit(new HThrow(
3399 exception, exception.sourceInformation, 3401 exception, exception.sourceInformation,
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
3439 enterBlock.setBlockFlow( 3441 enterBlock.setBlockFlow(
3440 new HTryBlockInformation( 3442 new HTryBlockInformation(
3441 kernelBuilder.wrapStatementGraph(bodyGraph), 3443 kernelBuilder.wrapStatementGraph(bodyGraph),
3442 exception, 3444 exception,
3443 kernelBuilder.wrapStatementGraph(catchGraph), 3445 kernelBuilder.wrapStatementGraph(catchGraph),
3444 kernelBuilder.wrapStatementGraph(finallyGraph)), 3446 kernelBuilder.wrapStatementGraph(finallyGraph)),
3445 exitBlock); 3447 exitBlock);
3446 kernelBuilder.inTryStatement = previouslyInTryStatement; 3448 kernelBuilder.inTryStatement = previouslyInTryStatement;
3447 } 3449 }
3448 } 3450 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698