OLD | NEW |
1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, 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 library dart2js.ir_builder_task; | 5 library dart2js.ir_builder_task; |
6 | 6 |
7 import '../closure.dart' as closure; | 7 import '../closure.dart' as closure; |
8 import '../common.dart'; | 8 import '../common.dart'; |
9 import '../common/names.dart' show Identifiers, Names, Selectors; | 9 import '../common/names.dart' show Identifiers, Names, Selectors; |
10 import '../common/tasks.dart' show CompilerTask; | 10 import '../common/tasks.dart' show CompilerTask; |
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
72 [this.builderCallback]) | 72 [this.builderCallback]) |
73 : super(compiler); | 73 : super(compiler); |
74 | 74 |
75 String get name => 'CPS builder'; | 75 String get name => 'CPS builder'; |
76 | 76 |
77 ir.FunctionDefinition buildNode( | 77 ir.FunctionDefinition buildNode( |
78 AstElement element, TypeMaskSystem typeMaskSystem) { | 78 AstElement element, TypeMaskSystem typeMaskSystem) { |
79 return measure(() { | 79 return measure(() { |
80 bailoutMessage = null; | 80 bailoutMessage = null; |
81 | 81 |
82 TreeElements elementsMapping = element.resolvedAst.elements; | 82 ResolvedAst resolvedAst = element.resolvedAst; |
83 element = element.implementation; | 83 element = element.implementation; |
84 return reporter.withCurrentElement(element, () { | 84 return reporter.withCurrentElement(element, () { |
85 SourceInformationBuilder sourceInformationBuilder = | 85 SourceInformationBuilder sourceInformationBuilder = |
86 sourceInformationStrategy.createBuilderForContext(element); | 86 sourceInformationStrategy.createBuilderForContext(element); |
87 | 87 |
88 IrBuilderVisitor builder = new IrBuilderVisitor(elementsMapping, | 88 IrBuilderVisitor builder = new IrBuilderVisitor( |
89 compiler, sourceInformationBuilder, typeMaskSystem); | 89 resolvedAst, compiler, sourceInformationBuilder, typeMaskSystem); |
90 ir.FunctionDefinition irNode = builder.buildExecutable(element); | 90 ir.FunctionDefinition irNode = builder.buildExecutable(element); |
91 if (irNode == null) { | 91 if (irNode == null) { |
92 bailoutMessage = builder.bailoutMessage; | 92 bailoutMessage = builder.bailoutMessage; |
93 } else if (builderCallback != null) { | 93 } else if (builderCallback != null) { |
94 builderCallback(element, irNode); | 94 builderCallback(element, irNode); |
95 } | 95 } |
96 return irNode; | 96 return irNode; |
97 }); | 97 }); |
98 }); | 98 }); |
99 } | 99 } |
(...skipping 16 matching lines...) Expand all Loading... |
116 BaseImplementationOfStaticsMixin<ir.Primitive, dynamic>, | 116 BaseImplementationOfStaticsMixin<ir.Primitive, dynamic>, |
117 BaseImplementationOfLocalsMixin<ir.Primitive, dynamic>, | 117 BaseImplementationOfLocalsMixin<ir.Primitive, dynamic>, |
118 BaseImplementationOfDynamicsMixin<ir.Primitive, dynamic>, | 118 BaseImplementationOfDynamicsMixin<ir.Primitive, dynamic>, |
119 BaseImplementationOfConstantsMixin<ir.Primitive, dynamic>, | 119 BaseImplementationOfConstantsMixin<ir.Primitive, dynamic>, |
120 BaseImplementationOfNewMixin<ir.Primitive, dynamic>, | 120 BaseImplementationOfNewMixin<ir.Primitive, dynamic>, |
121 BaseImplementationOfCompoundsMixin<ir.Primitive, dynamic>, | 121 BaseImplementationOfCompoundsMixin<ir.Primitive, dynamic>, |
122 BaseImplementationOfSetIfNullsMixin<ir.Primitive, dynamic>, | 122 BaseImplementationOfSetIfNullsMixin<ir.Primitive, dynamic>, |
123 BaseImplementationOfIndexCompoundsMixin<ir.Primitive, dynamic>, | 123 BaseImplementationOfIndexCompoundsMixin<ir.Primitive, dynamic>, |
124 BaseImplementationOfSuperIndexSetIfNullMixin<ir.Primitive, dynamic> | 124 BaseImplementationOfSuperIndexSetIfNullMixin<ir.Primitive, dynamic> |
125 implements SemanticSendVisitor<ir.Primitive, dynamic> { | 125 implements SemanticSendVisitor<ir.Primitive, dynamic> { |
126 final TreeElements elements; | 126 final ResolvedAst resolvedAst; |
127 final Compiler compiler; | 127 final Compiler compiler; |
128 final SourceInformationBuilder sourceInformationBuilder; | 128 final SourceInformationBuilder sourceInformationBuilder; |
129 final TypeMaskSystem typeMaskSystem; | 129 final TypeMaskSystem typeMaskSystem; |
130 | 130 |
131 /// A map from try statements in the source to analysis information about | 131 /// A map from try statements in the source to analysis information about |
132 /// them. | 132 /// them. |
133 /// | 133 /// |
134 /// The analysis information includes the set of variables that must be | 134 /// The analysis information includes the set of variables that must be |
135 /// copied into [ir.MutableVariable]s on entry to the try and copied out on | 135 /// copied into [ir.MutableVariable]s on entry to the try and copied out on |
136 /// exit. | 136 /// exit. |
(...skipping 11 matching lines...) Expand all Loading... |
148 // surrounding context, the free occurrences can be captured or become free | 148 // surrounding context, the free occurrences can be captured or become free |
149 // occurrences in the next outer delimited subexpression. | 149 // occurrences in the next outer delimited subexpression. |
150 // | 150 // |
151 // Each nested visitor maintains a list that maps indexes of variables | 151 // Each nested visitor maintains a list that maps indexes of variables |
152 // assigned in the delimited subexpression to their reaching definition --- | 152 // assigned in the delimited subexpression to their reaching definition --- |
153 // that is, the definition in effect at the hole in 'current'. These are | 153 // that is, the definition in effect at the hole in 'current'. These are |
154 // used to determine if a join-point continuation needs to be passed | 154 // used to determine if a join-point continuation needs to be passed |
155 // arguments, and what the arguments are. | 155 // arguments, and what the arguments are. |
156 | 156 |
157 /// Construct a top-level visitor. | 157 /// Construct a top-level visitor. |
158 IrBuilderVisitor(this.elements, this.compiler, this.sourceInformationBuilder, | 158 IrBuilderVisitor(this.resolvedAst, this.compiler, |
159 this.typeMaskSystem); | 159 this.sourceInformationBuilder, this.typeMaskSystem); |
| 160 |
| 161 TreeElements get elements => resolvedAst.elements; |
160 | 162 |
161 JavaScriptBackend get backend => compiler.backend; | 163 JavaScriptBackend get backend => compiler.backend; |
162 BackendHelpers get helpers => backend.helpers; | 164 BackendHelpers get helpers => backend.helpers; |
163 DiagnosticReporter get reporter => compiler.reporter; | 165 DiagnosticReporter get reporter => compiler.reporter; |
164 | 166 |
165 String bailoutMessage = null; | 167 String bailoutMessage = null; |
166 | 168 |
167 ir.Primitive visit(ast.Node node) => node.accept(this); | 169 ir.Primitive visit(ast.Node node) => node.accept(this); |
168 | 170 |
169 @override | 171 @override |
(...skipping 16 matching lines...) Expand all Loading... |
186 // We translate a ClosureScope from closure.dart into IR builder's variant | 188 // We translate a ClosureScope from closure.dart into IR builder's variant |
187 // because the IR builder should not depend on the synthetic elements | 189 // because the IR builder should not depend on the synthetic elements |
188 // created in closure.dart. | 190 // created in closure.dart. |
189 return new ClosureScope(closureClassMap.capturingScopes[node]); | 191 return new ClosureScope(closureClassMap.capturingScopes[node]); |
190 } | 192 } |
191 | 193 |
192 /// Returns the [ClosureScope] for any function, possibly different from the | 194 /// Returns the [ClosureScope] for any function, possibly different from the |
193 /// one currently being built. | 195 /// one currently being built. |
194 ClosureScope getClosureScopeForFunction(FunctionElement function) { | 196 ClosureScope getClosureScopeForFunction(FunctionElement function) { |
195 closure.ClosureClassMap map = compiler.closureToClassMapper | 197 closure.ClosureClassMap map = compiler.closureToClassMapper |
196 .computeClosureToClassMapping(function, function.node, elements); | 198 .computeClosureToClassMapping(function.resolvedAst); |
197 return new ClosureScope(map.capturingScopes[function.node]); | 199 return new ClosureScope(map.capturingScopes[function.node]); |
198 } | 200 } |
199 | 201 |
200 /// If the current function is a nested function with free variables (or a | 202 /// If the current function is a nested function with free variables (or a |
201 /// captured reference to `this`), returns a [ClosureEnvironment] | 203 /// captured reference to `this`), returns a [ClosureEnvironment] |
202 /// indicating how to access these. | 204 /// indicating how to access these. |
203 ClosureEnvironment getClosureEnvironment() { | 205 ClosureEnvironment getClosureEnvironment() { |
204 return new ClosureEnvironment(closureClassMap); | 206 return new ClosureEnvironment(closureClassMap); |
205 } | 207 } |
206 | 208 |
(...skipping 291 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
498 return irBuilder.makeFunctionDefinition( | 500 return irBuilder.makeFunctionDefinition( |
499 sourceInformationBuilder.buildVariableDeclaration()); | 501 sourceInformationBuilder.buildVariableDeclaration()); |
500 }); | 502 }); |
501 } | 503 } |
502 | 504 |
503 /// Make a visitor suitable for translating ASTs taken from [context]. | 505 /// Make a visitor suitable for translating ASTs taken from [context]. |
504 /// | 506 /// |
505 /// Every visitor can only be applied to nodes in one context, because | 507 /// Every visitor can only be applied to nodes in one context, because |
506 /// the [elements] field is specific to that context. | 508 /// the [elements] field is specific to that context. |
507 IrBuilderVisitor makeVisitorForContext(AstElement context) { | 509 IrBuilderVisitor makeVisitorForContext(AstElement context) { |
508 return new IrBuilderVisitor(context.resolvedAst.elements, compiler, | 510 return new IrBuilderVisitor(context.resolvedAst, compiler, |
509 sourceInformationBuilder.forContext(context), typeMaskSystem); | 511 sourceInformationBuilder.forContext(context), typeMaskSystem); |
510 } | 512 } |
511 | 513 |
512 /// Builds the IR for an [expression] taken from a different [context]. | 514 /// Builds the IR for an [expression] taken from a different [context]. |
513 /// | 515 /// |
514 /// Such expressions need to be compiled with a different [sourceFile] and | 516 /// Such expressions need to be compiled with a different [sourceFile] and |
515 /// [elements] mapping. | 517 /// [elements] mapping. |
516 ir.Primitive inlineExpression(AstElement context, ast.Expression expression) { | 518 ir.Primitive inlineExpression(AstElement context, ast.Expression expression) { |
517 IrBuilderVisitor visitor = makeVisitorForContext(context); | 519 IrBuilderVisitor visitor = makeVisitorForContext(context); |
518 return visitor.withBuilder(irBuilder, () => visitor.visit(expression)); | 520 return visitor.withBuilder(irBuilder, () => visitor.visit(expression)); |
(...skipping 19 matching lines...) Expand all Loading... |
538 } | 540 } |
539 | 541 |
540 /// In preparation of inlining (part of) [target], the [arguments] are moved | 542 /// In preparation of inlining (part of) [target], the [arguments] are moved |
541 /// into the environment bindings for the corresponding parameters. | 543 /// into the environment bindings for the corresponding parameters. |
542 /// | 544 /// |
543 /// Defaults for optional arguments are evaluated in order to ensure | 545 /// Defaults for optional arguments are evaluated in order to ensure |
544 /// all parameters are available in the environment. | 546 /// all parameters are available in the environment. |
545 void loadArguments(ConstructorElement target, CallStructure call, | 547 void loadArguments(ConstructorElement target, CallStructure call, |
546 List<ir.Primitive> arguments) { | 548 List<ir.Primitive> arguments) { |
547 assert(target.isImplementation); | 549 assert(target.isImplementation); |
548 assert(target == elements.analyzedElement); | 550 assert(target.declaration == resolvedAst.element); |
549 FunctionSignature signature = target.functionSignature; | 551 FunctionSignature signature = target.functionSignature; |
550 | 552 |
551 // Establish a scope in case parameters are captured. | 553 // Establish a scope in case parameters are captured. |
552 ClosureScope scope = getClosureScopeForFunction(target); | 554 ClosureScope scope = getClosureScopeForFunction(target); |
553 irBuilder.enterScope(scope); | 555 irBuilder.enterScope(scope); |
554 | 556 |
555 // Load required parameters | 557 // Load required parameters |
556 int index = 0; | 558 int index = 0; |
557 signature.forEachRequiredParameter((ParameterElement param) { | 559 signature.forEachRequiredParameter((ParameterElement param) { |
558 irBuilder.declareLocalVariable(param, initialValue: arguments[index]); | 560 irBuilder.declareLocalVariable(param, initialValue: arguments[index]); |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
613 /// | 615 /// |
614 /// The parameters to superconstructors are, however, assumed *not* to be in | 616 /// The parameters to superconstructors are, however, assumed *not* to be in |
615 /// the environment, but will be put there by this procedure. | 617 /// the environment, but will be put there by this procedure. |
616 /// | 618 /// |
617 /// All constructors will be added to [supers], with superconstructors first. | 619 /// All constructors will be added to [supers], with superconstructors first. |
618 void evaluateConstructorFieldInitializers( | 620 void evaluateConstructorFieldInitializers( |
619 ConstructorElement constructor, | 621 ConstructorElement constructor, |
620 List<ConstructorElement> supers, | 622 List<ConstructorElement> supers, |
621 Map<FieldElement, ir.Primitive> fieldValues) { | 623 Map<FieldElement, ir.Primitive> fieldValues) { |
622 assert(constructor.isImplementation); | 624 assert(constructor.isImplementation); |
623 assert(constructor == elements.analyzedElement); | 625 assert(constructor.declaration == resolvedAst.element); |
624 ClassElement enclosingClass = constructor.enclosingClass.implementation; | 626 ClassElement enclosingClass = constructor.enclosingClass.implementation; |
625 // Evaluate declaration-site field initializers, unless this constructor | 627 // Evaluate declaration-site field initializers, unless this constructor |
626 // redirects to another using a `this()` initializer. In that case, these | 628 // redirects to another using a `this()` initializer. In that case, these |
627 // will be initialized by the effective target constructor. | 629 // will be initialized by the effective target constructor. |
628 if (!constructor.isRedirectingGenerative) { | 630 if (!constructor.isRedirectingGenerative) { |
629 enclosingClass.forEachInstanceField((ClassElement c, FieldElement field) { | 631 enclosingClass.forEachInstanceField((ClassElement c, FieldElement field) { |
630 if (field.initializer != null) { | 632 if (field.initializer != null) { |
631 fieldValues[field] = inlineExpression(field, field.initializer); | 633 fieldValues[field] = inlineExpression(field, field.initializer); |
632 } else { | 634 } else { |
633 if (backend.isNativeOrExtendsNative(c)) { | 635 if (backend.isNativeOrExtendsNative(c)) { |
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
707 } | 709 } |
708 | 710 |
709 /// Builds the IR for the body of a constructor. | 711 /// Builds the IR for the body of a constructor. |
710 /// | 712 /// |
711 /// This function is invoked from one or more "factory" constructors built by | 713 /// This function is invoked from one or more "factory" constructors built by |
712 /// [buildConstructor]. | 714 /// [buildConstructor]. |
713 ir.FunctionDefinition buildConstructorBody(ConstructorBodyElement body) { | 715 ir.FunctionDefinition buildConstructorBody(ConstructorBodyElement body) { |
714 ConstructorElement constructor = body.constructor; | 716 ConstructorElement constructor = body.constructor; |
715 ast.FunctionExpression node = constructor.node; | 717 ast.FunctionExpression node = constructor.node; |
716 closureClassMap = compiler.closureToClassMapper | 718 closureClassMap = compiler.closureToClassMapper |
717 .computeClosureToClassMapping(constructor, node, elements); | 719 .computeClosureToClassMapping(constructor.resolvedAst); |
718 | 720 |
719 // We compute variables boxed in mutable variables on entry to each try | 721 // We compute variables boxed in mutable variables on entry to each try |
720 // block, not including variables captured by a closure (which are boxed | 722 // block, not including variables captured by a closure (which are boxed |
721 // in the heap). This duplicates some of the work of closure conversion | 723 // in the heap). This duplicates some of the work of closure conversion |
722 // without directly using the results. This duplication is wasteful and | 724 // without directly using the results. This duplication is wasteful and |
723 // error-prone. | 725 // error-prone. |
724 // TODO(kmillikin): We should combine closure conversion and try/catch | 726 // TODO(kmillikin): We should combine closure conversion and try/catch |
725 // variable analysis in some way. | 727 // variable analysis in some way. |
726 TryBoxedVariables variables = _analyzeTryBoxedVariables(node); | 728 TryBoxedVariables variables = _analyzeTryBoxedVariables(node); |
727 tryStatements = variables.tryStatements; | 729 tryStatements = variables.tryStatements; |
(...skipping 10 matching lines...) Expand all Loading... |
738 | 740 |
739 ir.FunctionDefinition buildFunction(FunctionElement element) { | 741 ir.FunctionDefinition buildFunction(FunctionElement element) { |
740 assert(invariant(element, element.isImplementation)); | 742 assert(invariant(element, element.isImplementation)); |
741 ast.FunctionExpression node = element.node; | 743 ast.FunctionExpression node = element.node; |
742 | 744 |
743 assert(!element.isSynthesized); | 745 assert(!element.isSynthesized); |
744 assert(node != null); | 746 assert(node != null); |
745 assert(elements[node] != null); | 747 assert(elements[node] != null); |
746 | 748 |
747 closureClassMap = compiler.closureToClassMapper | 749 closureClassMap = compiler.closureToClassMapper |
748 .computeClosureToClassMapping(element, node, elements); | 750 .computeClosureToClassMapping(element.resolvedAst); |
749 TryBoxedVariables variables = _analyzeTryBoxedVariables(node); | 751 TryBoxedVariables variables = _analyzeTryBoxedVariables(node); |
750 tryStatements = variables.tryStatements; | 752 tryStatements = variables.tryStatements; |
751 IrBuilder builder = getBuilderFor(element); | 753 IrBuilder builder = getBuilderFor(element); |
752 return withBuilder( | 754 return withBuilder( |
753 builder, () => _makeFunctionBody(builder, element, node)); | 755 builder, () => _makeFunctionBody(builder, element, node)); |
754 } | 756 } |
755 | 757 |
756 ir.FunctionDefinition buildStaticFieldInitializer(FieldElement element) { | 758 ir.FunctionDefinition buildStaticFieldInitializer(FieldElement element) { |
757 if (!backend.constants.lazyStatics.contains(element)) { | 759 if (!backend.constants.lazyStatics.contains(element)) { |
758 return null; // Nothing to do. | 760 return null; // Nothing to do. |
759 } | 761 } |
760 closureClassMap = compiler.closureToClassMapper | 762 closureClassMap = compiler.closureToClassMapper |
761 .computeClosureToClassMapping(element, element.node, elements); | 763 .computeClosureToClassMapping(element.resolvedAst); |
762 IrBuilder builder = getBuilderFor(element); | 764 IrBuilder builder = getBuilderFor(element); |
763 return withBuilder(builder, () { | 765 return withBuilder(builder, () { |
764 irBuilder.buildFunctionHeader(<Local>[]); | 766 irBuilder.buildFunctionHeader(<Local>[]); |
765 ir.Primitive initialValue = visit(element.initializer); | 767 ir.Primitive initialValue = visit(element.initializer); |
766 ast.VariableDefinitions node = element.node; | 768 ast.VariableDefinitions node = element.node; |
767 ast.SendSet sendSet = node.definitions.nodes.head; | 769 ast.SendSet sendSet = node.definitions.nodes.head; |
768 irBuilder.buildReturn( | 770 irBuilder.buildReturn( |
769 value: initialValue, | 771 value: initialValue, |
770 sourceInformation: | 772 sourceInformation: |
771 sourceInformationBuilder.buildReturn(sendSet.assignmentOperator)); | 773 sourceInformationBuilder.buildReturn(sendSet.assignmentOperator)); |
(...skipping 3247 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4019 _backend.jsInteropAnalysis.hasAnonymousAnnotation(element.contextClass); | 4021 _backend.jsInteropAnalysis.hasAnonymousAnnotation(element.contextClass); |
4020 | 4022 |
4021 String getJsInteropTargetPath(FunctionElement element) { | 4023 String getJsInteropTargetPath(FunctionElement element) { |
4022 return '${_backend.namer.fixedBackendPath(element)}.' | 4024 return '${_backend.namer.fixedBackendPath(element)}.' |
4023 '${_backend.nativeData.getFixedBackendName(element)}'; | 4025 '${_backend.nativeData.getFixedBackendName(element)}'; |
4024 } | 4026 } |
4025 | 4027 |
4026 DartType get jsJavascriptObjectType => | 4028 DartType get jsJavascriptObjectType => |
4027 _backend.helpers.jsJavaScriptObjectClass.thisType; | 4029 _backend.helpers.jsJavaScriptObjectClass.thisType; |
4028 } | 4030 } |
OLD | NEW |