| 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 closurelib; | 7 import '../closure.dart' as closurelib; |
| 8 import '../closure.dart' hide ClosureScope; | 8 import '../closure.dart' hide ClosureScope; |
| 9 import '../constants/expressions.dart'; | 9 import '../constants/expressions.dart'; |
| 10 import '../dart_types.dart'; | 10 import '../dart_types.dart'; |
| (...skipping 180 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 191 @override | 191 @override |
| 192 SemanticSendVisitor get sendVisitor => this; | 192 SemanticSendVisitor get sendVisitor => this; |
| 193 | 193 |
| 194 /** | 194 /** |
| 195 * Builds the [ir.RootNode] for an executable element. In case the | 195 * Builds the [ir.RootNode] for an executable element. In case the |
| 196 * function uses features that cannot be expressed in the IR, this element | 196 * function uses features that cannot be expressed in the IR, this element |
| 197 * returns `null`. | 197 * returns `null`. |
| 198 */ | 198 */ |
| 199 ir.RootNode buildExecutable(ExecutableElement element); | 199 ir.RootNode buildExecutable(ExecutableElement element); |
| 200 | 200 |
| 201 ClosureClassMap get closureClassMap; |
| 201 ClosureScope getClosureScopeForNode(ast.Node node); | 202 ClosureScope getClosureScopeForNode(ast.Node node); |
| 202 ClosureEnvironment getClosureEnvironment(); | 203 ClosureEnvironment getClosureEnvironment(); |
| 203 | 204 |
| 204 /// Normalizes the argument list to a static invocation (i.e. where the target | 205 /// Normalizes the argument list to a static invocation (i.e. where the target |
| 205 /// element is known). | 206 /// element is known). |
| 206 /// | 207 /// |
| 207 /// For the JS backend, inserts default arguments and normalizes order of | 208 /// For the JS backend, inserts default arguments and normalizes order of |
| 208 /// named arguments. | 209 /// named arguments. |
| 209 /// | 210 /// |
| 210 /// For the Dart backend, returns [arguments]. | 211 /// For the Dart backend, returns [arguments]. |
| (...skipping 316 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 527 } | 528 } |
| 528 catchClauseInfos.add(new CatchClauseInfo( | 529 catchClauseInfos.add(new CatchClauseInfo( |
| 529 exceptionVariable: exceptionVariable, | 530 exceptionVariable: exceptionVariable, |
| 530 stackTraceVariable: stackTraceVariable, | 531 stackTraceVariable: stackTraceVariable, |
| 531 buildCatchBlock: subbuild(catchClause.block))); | 532 buildCatchBlock: subbuild(catchClause.block))); |
| 532 } | 533 } |
| 533 | 534 |
| 534 irBuilder.buildTry( | 535 irBuilder.buildTry( |
| 535 tryStatementInfo: tryStatements[node], | 536 tryStatementInfo: tryStatements[node], |
| 536 buildTryBlock: subbuild(node.tryBlock), | 537 buildTryBlock: subbuild(node.tryBlock), |
| 537 catchClauseInfos: catchClauseInfos); | 538 catchClauseInfos: catchClauseInfos, |
| 539 closureClassMap: closureClassMap); |
| 538 } | 540 } |
| 539 | 541 |
| 540 // ## Expressions ## | 542 // ## Expressions ## |
| 541 ir.Primitive visitConditional(ast.Conditional node) { | 543 ir.Primitive visitConditional(ast.Conditional node) { |
| 542 return irBuilder.buildConditional( | 544 return irBuilder.buildConditional( |
| 543 build(node.condition), | 545 build(node.condition), |
| 544 subbuild(node.thenExpression), | 546 subbuild(node.thenExpression), |
| 545 subbuild(node.elseExpression)); | 547 subbuild(node.elseExpression)); |
| 546 } | 548 } |
| 547 | 549 |
| (...skipping 1466 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2014 ir.Primitive visitFunctionExpression(ast.FunctionExpression node) { | 2016 ir.Primitive visitFunctionExpression(ast.FunctionExpression node) { |
| 2015 return irBuilder.buildFunctionExpression(makeSubFunction(node)); | 2017 return irBuilder.buildFunctionExpression(makeSubFunction(node)); |
| 2016 } | 2018 } |
| 2017 | 2019 |
| 2018 visitFunctionDeclaration(ast.FunctionDeclaration node) { | 2020 visitFunctionDeclaration(ast.FunctionDeclaration node) { |
| 2019 LocalFunctionElement element = elements[node.function]; | 2021 LocalFunctionElement element = elements[node.function]; |
| 2020 Object inner = makeSubFunction(node.function); | 2022 Object inner = makeSubFunction(node.function); |
| 2021 irBuilder.declareLocalFunction(element, inner); | 2023 irBuilder.declareLocalFunction(element, inner); |
| 2022 } | 2024 } |
| 2023 | 2025 |
| 2026 ClosureClassMap get closureClassMap => null; |
| 2024 ClosureScope getClosureScopeForNode(ast.Node node) => null; | 2027 ClosureScope getClosureScopeForNode(ast.Node node) => null; |
| 2025 ClosureEnvironment getClosureEnvironment() => null; | 2028 ClosureEnvironment getClosureEnvironment() => null; |
| 2026 | 2029 |
| 2027 ir.RootNode buildExecutable(ExecutableElement element) { | 2030 ir.RootNode buildExecutable(ExecutableElement element) { |
| 2028 return nullIfGiveup(() { | 2031 return nullIfGiveup(() { |
| 2029 ir.RootNode root; | 2032 ir.RootNode root; |
| 2030 if (element is FieldElement) { | 2033 if (element is FieldElement) { |
| 2031 root = buildField(element); | 2034 root = buildField(element); |
| 2032 } else if (element is FunctionElement || element is ConstructorElement) { | 2035 } else if (element is FunctionElement || element is ConstructorElement) { |
| 2033 root = buildFunction(element); | 2036 root = buildFunction(element); |
| (...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2148 | 2151 |
| 2149 /// IR builder specific to the JavaScript backend, coupled to the [JsIrBuilder]. | 2152 /// IR builder specific to the JavaScript backend, coupled to the [JsIrBuilder]. |
| 2150 class JsIrBuilderVisitor extends IrBuilderVisitor { | 2153 class JsIrBuilderVisitor extends IrBuilderVisitor { |
| 2151 /// Promote the type of [irBuilder] to [JsIrBuilder]. | 2154 /// Promote the type of [irBuilder] to [JsIrBuilder]. |
| 2152 JsIrBuilder get irBuilder => super.irBuilder; | 2155 JsIrBuilder get irBuilder => super.irBuilder; |
| 2153 | 2156 |
| 2154 /// Result of closure conversion for the current body of code. | 2157 /// Result of closure conversion for the current body of code. |
| 2155 /// | 2158 /// |
| 2156 /// Will be initialized upon entering the body of a function. | 2159 /// Will be initialized upon entering the body of a function. |
| 2157 /// It is computed by the [ClosureTranslator]. | 2160 /// It is computed by the [ClosureTranslator]. |
| 2158 ClosureClassMap closureMap; | 2161 ClosureClassMap closureClassMap; |
| 2159 | 2162 |
| 2160 /// During construction of a constructor factory, [fieldValues] maps fields | 2163 /// During construction of a constructor factory, [fieldValues] maps fields |
| 2161 /// to the primitive containing their initial value. | 2164 /// to the primitive containing their initial value. |
| 2162 Map<FieldElement, ir.Primitive> fieldValues = <FieldElement, ir.Primitive>{}; | 2165 Map<FieldElement, ir.Primitive> fieldValues = <FieldElement, ir.Primitive>{}; |
| 2163 | 2166 |
| 2164 JsIrBuilderVisitor(TreeElements elements, | 2167 JsIrBuilderVisitor(TreeElements elements, |
| 2165 Compiler compiler, | 2168 Compiler compiler, |
| 2166 SourceInformationBuilder sourceInformationBuilder) | 2169 SourceInformationBuilder sourceInformationBuilder) |
| 2167 : super(elements, compiler, sourceInformationBuilder); | 2170 : super(elements, compiler, sourceInformationBuilder); |
| 2168 | 2171 |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2202 } else { | 2205 } else { |
| 2203 ClosureFieldElement field = v; | 2206 ClosureFieldElement field = v; |
| 2204 return new ClosureLocation(null, field); | 2207 return new ClosureLocation(null, field); |
| 2205 } | 2208 } |
| 2206 } | 2209 } |
| 2207 | 2210 |
| 2208 /// If the current function is a nested function with free variables (or a | 2211 /// If the current function is a nested function with free variables (or a |
| 2209 /// captured reference to `this`), returns a [ClosureEnvironment] | 2212 /// captured reference to `this`), returns a [ClosureEnvironment] |
| 2210 /// indicating how to access these. | 2213 /// indicating how to access these. |
| 2211 ClosureEnvironment getClosureEnvironment() { | 2214 ClosureEnvironment getClosureEnvironment() { |
| 2212 if (closureMap.closureElement == null) return null; | 2215 if (closureClassMap.closureElement == null) return null; |
| 2213 return new ClosureEnvironment( | 2216 return new ClosureEnvironment( |
| 2214 closureMap.closureElement, | 2217 closureClassMap.closureElement, |
| 2215 closureMap.thisLocal, | 2218 closureClassMap.thisLocal, |
| 2216 mapValues(closureMap.freeVariableMap, getLocation)); | 2219 mapValues(closureClassMap.freeVariableMap, getLocation)); |
| 2217 } | 2220 } |
| 2218 | 2221 |
| 2219 /// If [node] has declarations for variables that should be boxed, | 2222 /// If [node] has declarations for variables that should be boxed, |
| 2220 /// returns a [ClosureScope] naming a box to create, and enumerating the | 2223 /// returns a [ClosureScope] naming a box to create, and enumerating the |
| 2221 /// variables that should be stored in the box. | 2224 /// variables that should be stored in the box. |
| 2222 /// | 2225 /// |
| 2223 /// Also see [ClosureScope]. | 2226 /// Also see [ClosureScope]. |
| 2224 ClosureScope getClosureScopeForNode(ast.Node node) { | 2227 ClosureScope getClosureScopeForNode(ast.Node node) { |
| 2225 closurelib.ClosureScope scope = closureMap.capturingScopes[node]; | 2228 closurelib.ClosureScope scope = closureClassMap.capturingScopes[node]; |
| 2226 if (scope == null) return null; | 2229 if (scope == null) return null; |
| 2227 // We translate a ClosureScope from closure.dart into IR builder's variant | 2230 // We translate a ClosureScope from closure.dart into IR builder's variant |
| 2228 // because the IR builder should not depend on the synthetic elements | 2231 // because the IR builder should not depend on the synthetic elements |
| 2229 // created in closure.dart. | 2232 // created in closure.dart. |
| 2230 return new ClosureScope(scope.boxElement, | 2233 return new ClosureScope(scope.boxElement, |
| 2231 mapValues(scope.capturedVariables, getLocation), | 2234 mapValues(scope.capturedVariables, getLocation), |
| 2232 scope.boxedLoopVariables); | 2235 scope.boxedLoopVariables); |
| 2233 } | 2236 } |
| 2234 | 2237 |
| 2235 /// Returns the [ClosureScope] for any function, possibly different from the | 2238 /// Returns the [ClosureScope] for any function, possibly different from the |
| (...skipping 372 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2608 return variables; | 2611 return variables; |
| 2609 } | 2612 } |
| 2610 | 2613 |
| 2611 /// Builds the IR for the body of a constructor. | 2614 /// Builds the IR for the body of a constructor. |
| 2612 /// | 2615 /// |
| 2613 /// This function is invoked from one or more "factory" constructors built by | 2616 /// This function is invoked from one or more "factory" constructors built by |
| 2614 /// [buildConstructor]. | 2617 /// [buildConstructor]. |
| 2615 ir.FunctionDefinition buildConstructorBody(ConstructorBodyElement body) { | 2618 ir.FunctionDefinition buildConstructorBody(ConstructorBodyElement body) { |
| 2616 ConstructorElement constructor = body.constructor; | 2619 ConstructorElement constructor = body.constructor; |
| 2617 ast.FunctionExpression node = constructor.node; | 2620 ast.FunctionExpression node = constructor.node; |
| 2618 closureMap = compiler.closureToClassMapper.computeClosureToClassMapping( | 2621 closureClassMap = |
| 2619 constructor, | 2622 compiler.closureToClassMapper.computeClosureToClassMapping( |
| 2620 node, | 2623 constructor, |
| 2621 elements); | 2624 node, |
| 2625 elements); |
| 2622 | 2626 |
| 2623 // We compute variables boxed in mutable variables on entry to each try | 2627 // We compute variables boxed in mutable variables on entry to each try |
| 2624 // block, not including variables captured by a closure (which are boxed | 2628 // block, not including variables captured by a closure (which are boxed |
| 2625 // in the heap). This duplicates some of the work of closure conversion | 2629 // in the heap). This duplicates some of the work of closure conversion |
| 2626 // without directly using the results. This duplication is wasteful and | 2630 // without directly using the results. This duplication is wasteful and |
| 2627 // error-prone. | 2631 // error-prone. |
| 2628 // TODO(kmillikin): We should combine closure conversion and try/catch | 2632 // TODO(kmillikin): We should combine closure conversion and try/catch |
| 2629 // variable analysis in some way. | 2633 // variable analysis in some way. |
| 2630 DartCapturedVariables variables = _analyzeCapturedVariables(node); | 2634 DartCapturedVariables variables = _analyzeCapturedVariables(node); |
| 2631 tryStatements = variables.tryStatements; | 2635 tryStatements = variables.tryStatements; |
| 2632 JsIrBuilder builder = getBuilderFor(body); | 2636 JsIrBuilder builder = getBuilderFor(body); |
| 2633 | 2637 |
| 2634 return withBuilder(builder, () { | 2638 return withBuilder(builder, () { |
| 2635 irBuilder.buildConstructorBodyHeader(getConstructorBodyParameters(body), | 2639 irBuilder.buildConstructorBodyHeader(getConstructorBodyParameters(body), |
| 2636 getClosureScopeForNode(node)); | 2640 getClosureScopeForNode(node)); |
| 2637 visit(node.body); | 2641 visit(node.body); |
| 2638 return irBuilder.makeFunctionDefinition([]); | 2642 return irBuilder.makeFunctionDefinition([]); |
| 2639 }); | 2643 }); |
| 2640 } | 2644 } |
| 2641 | 2645 |
| 2642 ir.FunctionDefinition buildFunction(FunctionElement element) { | 2646 ir.FunctionDefinition buildFunction(FunctionElement element) { |
| 2643 assert(invariant(element, element.isImplementation)); | 2647 assert(invariant(element, element.isImplementation)); |
| 2644 ast.FunctionExpression node = element.node; | 2648 ast.FunctionExpression node = element.node; |
| 2645 | 2649 |
| 2646 assert(!element.isSynthesized); | 2650 assert(!element.isSynthesized); |
| 2647 assert(node != null); | 2651 assert(node != null); |
| 2648 assert(elements[node] != null); | 2652 assert(elements[node] != null); |
| 2649 | 2653 |
| 2650 closureMap = compiler.closureToClassMapper.computeClosureToClassMapping( | 2654 closureClassMap = |
| 2651 element, | 2655 compiler.closureToClassMapper.computeClosureToClassMapping( |
| 2652 node, | 2656 element, |
| 2653 elements); | 2657 node, |
| 2658 elements); |
| 2654 DartCapturedVariables variables = _analyzeCapturedVariables(node); | 2659 DartCapturedVariables variables = _analyzeCapturedVariables(node); |
| 2655 tryStatements = variables.tryStatements; | 2660 tryStatements = variables.tryStatements; |
| 2656 IrBuilder builder = getBuilderFor(element); | 2661 IrBuilder builder = getBuilderFor(element); |
| 2657 return withBuilder(builder, () => _makeFunctionBody(element, node)); | 2662 return withBuilder(builder, () => _makeFunctionBody(element, node)); |
| 2658 } | 2663 } |
| 2659 | 2664 |
| 2660 /// Creates a primitive for the default value of [parameter]. | 2665 /// Creates a primitive for the default value of [parameter]. |
| 2661 ir.Primitive translateDefaultValue(ParameterElement parameter) { | 2666 ir.Primitive translateDefaultValue(ParameterElement parameter) { |
| 2662 if (parameter.initializer == null) { | 2667 if (parameter.initializer == null) { |
| 2663 return irBuilder.buildNullConstant(); | 2668 return irBuilder.buildNullConstant(); |
| (...skipping 158 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2822 node.body = replacementFor(node.body); | 2827 node.body = replacementFor(node.body); |
| 2823 } | 2828 } |
| 2824 } | 2829 } |
| 2825 | 2830 |
| 2826 /// Visit a just-deleted subterm and unlink all [Reference]s in it. | 2831 /// Visit a just-deleted subterm and unlink all [Reference]s in it. |
| 2827 class RemovalVisitor extends ir.RecursiveVisitor { | 2832 class RemovalVisitor extends ir.RecursiveVisitor { |
| 2828 processReference(ir.Reference reference) { | 2833 processReference(ir.Reference reference) { |
| 2829 reference.unlink(); | 2834 reference.unlink(); |
| 2830 } | 2835 } |
| 2831 } | 2836 } |
| OLD | NEW |