OLD | NEW |
---|---|
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/entities.dart' show MemberEntity; | 15 import '../elements/entities.dart'; |
16 import '../elements/modelx.dart'; | 16 import '../elements/modelx.dart'; |
17 import '../elements/types.dart'; | |
17 import '../js/js.dart' as js; | 18 import '../js/js.dart' as js; |
18 import '../js_backend/backend_helpers.dart'; | 19 import '../js_backend/backend_helpers.dart'; |
19 import '../js_backend/js_backend.dart'; | 20 import '../js_backend/js_backend.dart'; |
20 import '../kernel/kernel.dart'; | 21 import '../kernel/kernel.dart'; |
21 import '../kernel/kernel_debug.dart'; | 22 import '../kernel/kernel_debug.dart'; |
22 import '../native/native.dart' as native; | 23 import '../native/native.dart' as native; |
23 import '../resolution/tree_elements.dart'; | 24 import '../resolution/tree_elements.dart'; |
24 import '../tree/tree.dart' as ast; | 25 import '../tree/tree.dart' as ast; |
25 import '../types/masks.dart'; | 26 import '../types/masks.dart'; |
26 import '../types/types.dart'; | 27 import '../types/types.dart'; |
27 import '../universe/call_structure.dart'; | 28 import '../universe/call_structure.dart'; |
28 import '../universe/selector.dart'; | 29 import '../universe/selector.dart'; |
29 import '../universe/side_effects.dart'; | 30 import '../universe/side_effects.dart'; |
30 import '../world.dart'; | 31 import '../world.dart'; |
31 import 'graph_builder.dart'; | 32 import 'graph_builder.dart'; |
32 import 'jump_handler.dart' show SwitchCaseJumpHandler; | 33 import 'jump_handler.dart' show SwitchCaseJumpHandler; |
33 import 'locals_handler.dart'; | 34 import 'locals_handler.dart'; |
34 import 'types.dart'; | 35 import 'types.dart'; |
35 | 36 |
37 /// Interface that translates between Kernel IR nodes and entities. | |
Siggi Cherem (dart-lang)
2017/01/24 21:16:21
is the idea that this will be used to actually bui
Johnni Winther
2017/01/25 09:08:56
In time the implementation of this interface will
| |
38 abstract class KernelWorldBuilder { | |
39 /// Returns the [DartType] corresponding to [type]. | |
40 DartType getDartType(ir.DartType type); | |
41 | |
42 /// Returns the list of [DartType]s corresponding to [types]. | |
43 List<DartType> getDartTypes(List<ir.DartType> types); | |
44 | |
45 /// Returns the [InterfaceType] corresponding to [type]. | |
46 InterfaceType getInterfaceType(ir.InterfaceType type); | |
47 | |
48 /// Return the [InterfaceType] corresponding to the [cls] with the given | |
49 /// [typeArguments]. | |
50 InterfaceType createInterfaceType( | |
51 ir.Class cls, List<ir.DartType> typeArguments); | |
52 | |
53 /// Returns the [CallStructure] corresponding to the [arguments]. | |
54 CallStructure getCallStructure(ir.Arguments arguments); | |
55 | |
56 /// Returns the [Selector] corresponding to the invocation or getter/setter | |
57 /// access of [node]. | |
58 Selector getSelector(ir.Expression node); | |
59 | |
60 /// Returns the [FunctionEntity] corresponding to the generative or factory | |
61 /// constructor [node]. | |
62 FunctionEntity getConstructor(ir.Member node); | |
63 | |
64 /// Returns the [MemberEntity] corresponding to the member [node]. | |
65 MemberEntity getMember(ir.Member node); | |
66 | |
67 /// Returns the [FunctionEntity] corresponding to the procedure [node]. | |
68 FunctionEntity getMethod(ir.Procedure node); | |
69 | |
70 /// Returns the [FieldEntity] corresponding to the field [node]. | |
71 FieldEntity getField(ir.Field node); | |
72 | |
73 /// Returns the [ClassEntity] corresponding to the class [node]. | |
74 ClassEntity getClass(ir.Class node); | |
75 | |
76 /// Returns the [Local] corresponding to the [node]. The node must be either | |
77 /// a [ir.FunctionDeclaration] or [ir.FunctionExpression]. | |
78 Local getLocalFunction(ir.Node node); | |
79 | |
80 /// Returns the [Name] corresponding to [name]. | |
81 Name getName(ir.Name name); | |
82 | |
83 /// Returns `true` is [node] has a `@Native(...)` annotation. | |
84 bool isNativeClass(ir.Class node); | |
85 | |
86 /// Return `true` if [node] is the `dart:_foreign_helper` library. | |
87 bool isForeignLibrary(ir.Library node); | |
88 | |
89 /// Computes the native behavior for reading the native [field]. | |
90 native.NativeBehavior getNativeBehaviorForFieldLoad(ir.Field field); | |
91 | |
92 /// Computes the native behavior for writing to the native [field]. | |
93 native.NativeBehavior getNativeBehaviorForFieldStore(ir.Field field); | |
94 | |
95 /// Computes the native behavior for calling [procedure]. | |
96 native.NativeBehavior getNativeBehaviorForMethod(ir.Procedure procedure); | |
97 | |
98 /// Computes the [native.NativeBehavior] for a call to the [JS] function. | |
99 native.NativeBehavior getNativeBehaviorForJsCall(ir.StaticInvocation node); | |
100 | |
101 /// Computes the [native.NativeBehavior] for a call to the [JS_BUILTIN] | |
102 /// function. | |
103 native.NativeBehavior getNativeBehaviorForJsBuiltinCall( | |
104 ir.StaticInvocation node); | |
105 | |
106 /// Computes the [native.NativeBehavior] for a call to the | |
107 /// [JS_EMBEDDED_GLOBAL] function. | |
108 native.NativeBehavior getNativeBehaviorForJsEmbeddedGlobalCall( | |
109 ir.StaticInvocation node); | |
110 | |
111 /// Compute the kind of foreign helper function called by [node], if any. | |
112 ForeignKind getForeignKind(ir.StaticInvocation node); | |
113 | |
114 /// Computes the [InterfaceType] referenced by a call to the | |
115 /// [JS_INTERCEPTOR_CONSTANT] function, if any. | |
116 InterfaceType getInterfaceTypeForJsInterceptorCall(ir.StaticInvocation node); | |
117 } | |
118 | |
36 /// A helper class that abstracts all accesses of the AST from Kernel nodes. | 119 /// A helper class that abstracts all accesses of the AST from Kernel nodes. |
37 /// | 120 /// |
38 /// The goal is to remove all need for the AST from the Kernel SSA builder. | 121 /// The goal is to remove all need for the AST from the Kernel SSA builder. |
39 class KernelAstAdapter { | 122 class KernelAstAdapter implements KernelWorldBuilder { |
40 final Kernel kernel; | 123 final Kernel kernel; |
41 final JavaScriptBackend _backend; | 124 final JavaScriptBackend _backend; |
42 final Map<ir.Node, ast.Node> _nodeToAst; | 125 final Map<ir.Node, ast.Node> _nodeToAst; |
43 final Map<ir.Node, Element> _nodeToElement; | 126 final Map<ir.Node, Element> _nodeToElement; |
44 final Map<ir.VariableDeclaration, SyntheticLocal> _syntheticLocals = | 127 final Map<ir.VariableDeclaration, SyntheticLocal> _syntheticLocals = |
45 <ir.VariableDeclaration, SyntheticLocal>{}; | 128 <ir.VariableDeclaration, SyntheticLocal>{}; |
46 // TODO(efortuna): In an ideal world the TreeNodes should be some common | 129 // TODO(efortuna): In an ideal world the TreeNodes should be some common |
47 // interface we create for both ir.Statements and ir.SwitchCase (the | 130 // interface we create for both ir.Statements and ir.SwitchCase (the |
48 // ContinueSwitchStatement's target is a SwitchCase) rather than general | 131 // ContinueSwitchStatement's target is a SwitchCase) rather than general |
49 // TreeNode. Talking to Asger about this. | 132 // TreeNode. Talking to Asger about this. |
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
120 } | 203 } |
121 | 204 |
122 // TODO(johnniwinther): Use the more precise functions below. | 205 // TODO(johnniwinther): Use the more precise functions below. |
123 Element getElement(ir.Node node) { | 206 Element getElement(ir.Node node) { |
124 Element result = _nodeToElement[node]; | 207 Element result = _nodeToElement[node]; |
125 assert(invariant(CURRENT_ELEMENT_SPANNABLE, result != null, | 208 assert(invariant(CURRENT_ELEMENT_SPANNABLE, result != null, |
126 message: "No element found for $node.")); | 209 message: "No element found for $node.")); |
127 return result; | 210 return result; |
128 } | 211 } |
129 | 212 |
130 ConstructorElement getConstructor(ir.Node node) => | 213 ConstructorElement getConstructor(ir.Member node) => |
131 getElement(node).declaration; | 214 getElement(node).declaration; |
132 | 215 |
133 MemberElement getMember(ir.Node node) => getElement(node).declaration; | 216 MemberElement getMember(ir.Member node) => getElement(node).declaration; |
134 | 217 |
135 MethodElement getMethod(ir.Node node) => getElement(node).declaration; | 218 MethodElement getMethod(ir.Procedure node) => getElement(node).declaration; |
136 | 219 |
137 FieldElement getField(ir.Node node) => getElement(node).declaration; | 220 FieldElement getField(ir.Field node) => getElement(node).declaration; |
138 | 221 |
139 ClassElement getClass(ir.Node node) => getElement(node).declaration; | 222 ClassElement getClass(ir.Class node) => getElement(node).declaration; |
223 | |
224 LocalFunctionElement getLocalFunction(ir.Node node) => getElement(node); | |
140 | 225 |
141 ast.Node getNode(ir.Node node) { | 226 ast.Node getNode(ir.Node node) { |
142 ast.Node result = _nodeToAst[node]; | 227 ast.Node result = _nodeToAst[node]; |
143 assert(invariant(CURRENT_ELEMENT_SPANNABLE, result != null, | 228 assert(invariant(CURRENT_ELEMENT_SPANNABLE, result != null, |
144 message: "No node found for $node")); | 229 message: "No node found for $node")); |
145 return result; | 230 return result; |
146 } | 231 } |
147 | 232 |
148 ast.Node getNodeOrNull(ir.Node node) { | 233 ast.Node getNodeOrNull(ir.Node node) { |
149 return _nodeToAst[node]; | 234 return _nodeToAst[node]; |
(...skipping 440 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
590 List<ir.VariableDeclaration> sortedNamedParameters = | 675 List<ir.VariableDeclaration> sortedNamedParameters = |
591 node.namedParameters.toList()..sort((a, b) => a.name.compareTo(b.name)); | 676 node.namedParameters.toList()..sort((a, b) => a.name.compareTo(b.name)); |
592 for (ir.VariableDeclaration variable in sortedNamedParameters) { | 677 for (ir.VariableDeclaration variable in sortedNamedParameters) { |
593 namedParameters.add(variable.name); | 678 namedParameters.add(variable.name); |
594 namedParameterTypes.add(getDartType(variable.type)); | 679 namedParameterTypes.add(getDartType(variable.type)); |
595 } | 680 } |
596 return new ResolutionFunctionType.synthesized(returnType, parameterTypes, | 681 return new ResolutionFunctionType.synthesized(returnType, parameterTypes, |
597 optionalParameterTypes, namedParameters, namedParameterTypes); | 682 optionalParameterTypes, namedParameters, namedParameterTypes); |
598 } | 683 } |
599 | 684 |
600 ResolutionInterfaceType getInterfaceType(ir.DartType type) => | 685 ResolutionInterfaceType getInterfaceType(ir.InterfaceType type) => |
601 getDartType(type); | 686 getDartType(type); |
602 | 687 |
603 ResolutionInterfaceType createInterfaceType( | 688 ResolutionInterfaceType createInterfaceType( |
604 ClassElement cls, List<ResolutionDartType> typeArguments) { | 689 ir.Class cls, List<ir.DartType> typeArguments) { |
605 return new ResolutionInterfaceType(cls, typeArguments); | 690 return new ResolutionInterfaceType( |
691 getClass(cls), getDartTypes(typeArguments)); | |
606 } | 692 } |
607 | 693 |
608 /// Converts [annotations] into a list of [ConstantExpression]s. | 694 /// Converts [annotations] into a list of [ConstantExpression]s. |
609 List<ConstantExpression> getMetadata(List<ir.Expression> annotations) { | 695 List<ConstantExpression> getMetadata(List<ir.Expression> annotations) { |
610 List<ConstantExpression> metadata = <ConstantExpression>[]; | 696 List<ConstantExpression> metadata = <ConstantExpression>[]; |
611 annotations.forEach((ir.Expression node) { | 697 annotations.forEach((ir.Expression node) { |
612 ConstantExpression constant = node.accept(new Constantifier(this)); | 698 ConstantExpression constant = node.accept(new Constantifier(this)); |
613 if (constant == null) { | 699 if (constant == null) { |
614 throw new UnsupportedError( | 700 throw new UnsupportedError( |
615 'No constant for ${DebugPrinter.prettyPrint(node)}'); | 701 'No constant for ${DebugPrinter.prettyPrint(node)}'); |
(...skipping 150 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
766 return new native.NativeBehavior(); | 852 return new native.NativeBehavior(); |
767 } | 853 } |
768 return native.NativeBehavior.ofJsEmbeddedGlobalCall( | 854 return native.NativeBehavior.ofJsEmbeddedGlobalCall( |
769 specString, | 855 specString, |
770 _typeLookup(resolveAsRaw: true), | 856 _typeLookup(resolveAsRaw: true), |
771 CURRENT_ELEMENT_SPANNABLE, | 857 CURRENT_ELEMENT_SPANNABLE, |
772 reporter, | 858 reporter, |
773 _compiler.commonElements); | 859 _compiler.commonElements); |
774 } | 860 } |
775 | 861 |
862 /// Computes the [InterfaceType] referenced by a call to the | |
863 /// [JS_INTERCEPTOR_CONSTANT] function, if any. | |
864 InterfaceType getInterfaceTypeForJsInterceptorCall(ir.StaticInvocation node) { | |
865 if (node.arguments.positional.length != 1 || | |
866 node.arguments.named.isNotEmpty) { | |
867 reporter.reportErrorMessage(CURRENT_ELEMENT_SPANNABLE, | |
868 MessageKind.WRONG_ARGUMENT_FOR_JS_INTERCEPTOR_CONSTANT); | |
869 } | |
870 ir.Node argument = node.arguments.positional.first; | |
871 if (argument is ir.TypeLiteral && argument.type is ir.InterfaceType) { | |
872 return getInterfaceType(argument.type); | |
873 } | |
874 return null; | |
875 } | |
876 | |
776 /// Returns `true` is [node] has a `@Native(...)` annotation. | 877 /// Returns `true` is [node] has a `@Native(...)` annotation. |
777 // TODO(johnniwinther): Cache this for later use. | 878 // TODO(johnniwinther): Cache this for later use. |
778 bool isNative(ir.Class node) { | 879 bool isNativeClass(ir.Class node) { |
779 for (ir.Expression annotation in node.annotations) { | 880 for (ir.Expression annotation in node.annotations) { |
780 if (annotation is ir.ConstructorInvocation) { | 881 if (annotation is ir.ConstructorInvocation) { |
781 ConstructorElement target = getElement(annotation.target).declaration; | 882 ConstructorElement target = getElement(annotation.target).declaration; |
782 if (target.enclosingClass == | 883 if (target.enclosingClass == |
783 _compiler.commonElements.nativeAnnotationClass) { | 884 _compiler.commonElements.nativeAnnotationClass) { |
784 return true; | 885 return true; |
785 } | 886 } |
786 } | 887 } |
787 } | 888 } |
788 return false; | 889 return false; |
(...skipping 309 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1098 JumpTarget continueTarget = | 1199 JumpTarget continueTarget = |
1099 astAdapter.getJumpTarget(switchCase, isContinueTarget: true); | 1200 astAdapter.getJumpTarget(switchCase, isContinueTarget: true); |
1100 assert(continueTarget is KernelJumpTarget); | 1201 assert(continueTarget is KernelJumpTarget); |
1101 targetIndexMap[continueTarget] = switchIndex; | 1202 targetIndexMap[continueTarget] = switchIndex; |
1102 assert(builder.jumpTargets[continueTarget] == null); | 1203 assert(builder.jumpTargets[continueTarget] == null); |
1103 builder.jumpTargets[continueTarget] = this; | 1204 builder.jumpTargets[continueTarget] = this; |
1104 switchIndex++; | 1205 switchIndex++; |
1105 } | 1206 } |
1106 } | 1207 } |
1107 } | 1208 } |
OLD | NEW |