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

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
« no previous file with comments | « pkg/compiler/lib/src/ssa/graph_builder.dart ('k') | pkg/compiler/lib/src/ssa/loop_handler.dart » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 // TODO(efortuna): In an ideal world the TreeNodes should be some common
44 <ir.LabeledStatement, KernelJumpTarget>{}; 45 // interface we create for both ir.Statements and ir.SwitchCase (the
46 // ContinueSwitchStatement's target is a SwitchCase) rather than general
47 // TreeNode. Talking to Asger about this.
48 final Map<ir.TreeNode, KernelJumpTarget> _jumpTargets =
49 <ir.TreeNode, KernelJumpTarget>{};
45 DartTypeConverter _typeConverter; 50 DartTypeConverter _typeConverter;
46 ResolvedAst _resolvedAst; 51 ResolvedAst _resolvedAst;
47 52
48 /// Sometimes for resolution the resolved AST element needs to change (for 53 /// 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 54 /// 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. 55 /// constructing the field values). We keep track of this with a stack.
51 final List<ResolvedAst> _resolvedAstStack = <ResolvedAst>[]; 56 final List<ResolvedAst> _resolvedAstStack = <ResolvedAst>[];
52 57
53 KernelAstAdapter(this.kernel, this._backend, this._resolvedAst, 58 KernelAstAdapter(this.kernel, this._backend, this._resolvedAst,
54 this._nodeToAst, this._nodeToElement) { 59 this._nodeToAst, this._nodeToElement) {
60 KernelJumpTarget.index = 0;
55 // TODO(het): Maybe just use all of the kernel maps directly? 61 // TODO(het): Maybe just use all of the kernel maps directly?
56 for (FieldElement fieldElement in kernel.fields.keys) { 62 for (FieldElement fieldElement in kernel.fields.keys) {
57 _nodeToElement[kernel.fields[fieldElement]] = fieldElement; 63 _nodeToElement[kernel.fields[fieldElement]] = fieldElement;
58 } 64 }
59 for (FunctionElement functionElement in kernel.functions.keys) { 65 for (FunctionElement functionElement in kernel.functions.keys) {
60 _nodeToElement[kernel.functions[functionElement]] = functionElement; 66 _nodeToElement[kernel.functions[functionElement]] = functionElement;
61 } 67 }
62 for (ClassElement classElement in kernel.classes.keys) { 68 for (ClassElement classElement in kernel.classes.keys) {
63 _nodeToElement[kernel.classes[classElement]] = classElement; 69 _nodeToElement[kernel.classes[classElement]] = classElement;
64 } 70 }
(...skipping 294 matching lines...) Expand 10 before | Expand all | Expand 10 after
359 bool isLazyStatic(ir.Member member) { 365 bool isLazyStatic(ir.Member member) {
360 if (member is ir.Field) { 366 if (member is ir.Field) {
361 FieldElement field = _nodeToElement[member]; 367 FieldElement field = _nodeToElement[member];
362 return field.constant == null; 368 return field.constant == null;
363 } 369 }
364 return false; 370 return false;
365 } 371 }
366 372
367 LibraryElement get jsHelperLibrary => _backend.helpers.jsHelperLibrary; 373 LibraryElement get jsHelperLibrary => _backend.helpers.jsHelperLibrary;
368 374
369 JumpTarget getTargetDefinition(ir.Node node) => 375 KernelJumpTarget getJumpTarget(ir.TreeNode node) =>
370 elements.getTargetDefinition(getNode(node)); 376 _jumpTargets.putIfAbsent(node, () {
371 377 if (node is ir.LabeledStatement &&
372 JumpTarget getTargetOf(ir.Node node) => elements.getTargetOf(getNode(node)); 378 _jumpTargets.containsKey((node as ir.LabeledStatement).body)) {
373 379 return _jumpTargets[(node as ir.LabeledStatement).body];
374 KernelJumpTarget getJumpTarget(ir.LabeledStatement labeledStatement) => 380 }
375 _jumpTargets.putIfAbsent(labeledStatement, () { 381 return new KernelJumpTarget(node);
376 return new KernelJumpTarget();
377 }); 382 });
378 383
379 LabelDefinition getTargetLabel(ir.Node node) => 384 LabelDefinition getTargetLabel(ir.Node node) =>
380 elements.getTargetLabel(getNode(node)); 385 elements.getTargetLabel(getNode(node));
381 386
382 ir.Class get mapLiteralClass => 387 ir.Class get mapLiteralClass =>
383 kernel.classes[_backend.helpers.mapLiteralClass]; 388 kernel.classes[_backend.helpers.mapLiteralClass];
384 389
385 ir.Procedure get mapLiteralConstructor => 390 ir.Procedure get mapLiteralConstructor =>
386 kernel.functions[_backend.helpers.mapLiteralConstructor]; 391 kernel.functions[_backend.helpers.mapLiteralConstructor];
(...skipping 17 matching lines...) Expand all
404 TypeMask get traceFromExceptionType => 409 TypeMask get traceFromExceptionType =>
405 TypeMaskFactory.inferredReturnTypeForElement( 410 TypeMaskFactory.inferredReturnTypeForElement(
406 _backend.helpers.traceFromException, _globalInferenceResults); 411 _backend.helpers.traceFromException, _globalInferenceResults);
407 412
408 ir.Procedure get streamIteratorConstructor => 413 ir.Procedure get streamIteratorConstructor =>
409 kernel.functions[_backend.helpers.streamIteratorConstructor]; 414 kernel.functions[_backend.helpers.streamIteratorConstructor];
410 415
411 TypeMask get streamIteratorConstructorType => 416 TypeMask get streamIteratorConstructorType =>
412 TypeMaskFactory.inferredReturnTypeForElement( 417 TypeMaskFactory.inferredReturnTypeForElement(
413 _backend.helpers.streamIteratorConstructor, _globalInferenceResults); 418 _backend.helpers.streamIteratorConstructor, _globalInferenceResults);
419 ir.Procedure get fallThroughError =>
420 kernel.functions[_backend.helpers.fallThroughError];
421
422 TypeMask get fallThroughErrorType =>
423 TypeMaskFactory.inferredReturnTypeForElement(
424 _backend.helpers.fallThroughError, _globalInferenceResults);
414 425
415 ir.Procedure get mapLiteralUntypedMaker => 426 ir.Procedure get mapLiteralUntypedMaker =>
416 kernel.functions[_backend.helpers.mapLiteralUntypedMaker]; 427 kernel.functions[_backend.helpers.mapLiteralUntypedMaker];
417 428
418 MemberElement get jsIndexableLength => _backend.helpers.jsIndexableLength; 429 MemberElement get jsIndexableLength => _backend.helpers.jsIndexableLength;
419 430
420 ir.Procedure get checkConcurrentModificationError => 431 ir.Procedure get checkConcurrentModificationError =>
421 kernel.functions[_backend.helpers.checkConcurrentModificationError]; 432 kernel.functions[_backend.helpers.checkConcurrentModificationError];
422 433
423 TypeMask get checkConcurrentModificationErrorReturnType => 434 TypeMask get checkConcurrentModificationErrorReturnType =>
(...skipping 530 matching lines...) Expand 10 before | Expand all | Expand 10 after
954 965
955 @override 966 @override
956 ConstantExpression visitStringLiteral(ir.StringLiteral node) { 967 ConstantExpression visitStringLiteral(ir.StringLiteral node) {
957 return new StringConstantExpression(node.value); 968 return new StringConstantExpression(node.value);
958 } 969 }
959 } 970 }
960 971
961 class KernelJumpTarget extends JumpTarget { 972 class KernelJumpTarget extends JumpTarget {
962 static int index = 0; 973 static int index = 0;
963 974
964 KernelJumpTarget() { 975 /// Pointer to the actual executable statements that a jump target refers to.
965 labels = <LabelDefinition>[ 976 /// If this jump target was not initially constructed with a LabeledStatement,
966 new LabelDefinitionX(null, 'l${index++}', this)..setBreakTarget() 977 /// this value is identical to originalStatement.
967 ]; 978 // TODO(efortuna): In an ideal world the Node should be some common
979 // interface we create for both ir.Statements and ir.SwitchCase (the
980 // ContinueSwitchStatement's target is a SwitchCase) rather than general
981 // Node. Talking to Asger about this.
982 ir.Node targetStatement;
983
984 /// The original statement used to construct this jump target.
985 /// If this jump target was not initially constructed with a LabeledStatement,
986 /// this value is identical to targetStatement.
987 ir.Node originalStatement;
988
989 @override
990 bool isBreakTarget = false;
991
992 @override
993 bool isContinueTarget = false;
994
995 KernelJumpTarget(this.targetStatement) {
996 labels = <LabelDefinition>[];
997 originalStatement = targetStatement;
998 if (targetStatement is ir.LabeledStatement) {
999 targetStatement = (targetStatement as ir.LabeledStatement).body;
1000 labels.add(
1001 new LabelDefinitionX(null, 'L${index++}', this)..setBreakTarget());
1002 isBreakTarget = true;
1003 }
968 } 1004 }
969 1005
970 @override 1006 @override
971 bool get isBreakTarget => true;
972
973 set isBreakTarget(bool x) {
974 // do nothing, these are always break targets
975 }
976
977 @override
978 bool get isContinueTarget => false;
979
980 set isContinueTarget(bool x) {
981 // do nothing, these are always break targets
982 }
983
984 @override
985 LabelDefinition addLabel(ast.Label label, String labelName) { 1007 LabelDefinition addLabel(ast.Label label, String labelName) {
986 LabelDefinition result = new LabelDefinitionX(label, labelName, this); 1008 LabelDefinition result = new LabelDefinitionX(label, labelName, this);
987 labels.add(result); 1009 labels.add(result);
988 return result; 1010 return result;
989 } 1011 }
990 1012
991 @override 1013 @override
992 ExecutableElement get executableContext => null; 1014 ExecutableElement get executableContext => null;
993 1015
994 @override 1016 @override
995 bool get isSwitch => false; 1017 bool get isSwitch => targetStatement is ir.SwitchStatement;
996 1018
997 @override 1019 @override
998 bool get isTarget => true; 1020 bool get isTarget => isBreakTarget || isContinueTarget;
999 1021
1000 @override 1022 @override
1001 List<LabelDefinition> labels; 1023 List<LabelDefinition> labels;
1002 1024
1003 @override 1025 @override
1004 String get name => null; 1026 String get name => null;
1005 1027
1006 @override 1028 @override
1007 int get nestingLevel => 1; 1029 int get nestingLevel => 1;
1008 1030
1009 @override 1031 @override
1010 ast.Node get statement => null; 1032 ast.Node get statement => null;
1033
1034 String toString() => 'Target:$targetStatement';
1011 } 1035 }
OLDNEW
« no previous file with comments | « pkg/compiler/lib/src/ssa/graph_builder.dart ('k') | pkg/compiler/lib/src/ssa/loop_handler.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698