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

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

Issue 2637483002: Implement switch statement, without the "complex switch statement" (aka switch statement with conti… (Closed)
Patch Set: . Created 3 years, 11 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: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
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
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
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 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698