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 472 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
483 // | 483 // |
484 // Return without a subexpression is translated as if it were return null. | 484 // Return without a subexpression is translated as if it were return null. |
485 ir.Primitive visitReturn(ast.Return node) { | 485 ir.Primitive visitReturn(ast.Return node) { |
486 assert(irBuilder.isOpen); | 486 assert(irBuilder.isOpen); |
487 assert(invariant(node, node.beginToken.value != 'native')); | 487 assert(invariant(node, node.beginToken.value != 'native')); |
488 irBuilder.buildReturn(build(node.expression)); | 488 irBuilder.buildReturn(build(node.expression)); |
489 return null; | 489 return null; |
490 } | 490 } |
491 | 491 |
492 visitTryStatement(ast.TryStatement node) { | 492 visitTryStatement(ast.TryStatement node) { |
493 // Try/catch is not yet implemented in the JS backend. | |
494 if (tryStatements == null) { | |
495 return giveup(node, 'try/catch in the JS backend'); | |
496 } | |
497 // Multiple catch blocks are not yet implemented. | 493 // Multiple catch blocks are not yet implemented. |
498 if (node.catchBlocks.isEmpty || | 494 if (node.catchBlocks.isEmpty || |
499 node.catchBlocks.nodes.tail == null) { | 495 node.catchBlocks.nodes.tail == null) { |
500 return giveup(node, 'not exactly one catch block'); | 496 return giveup(node, 'not exactly one catch block'); |
501 } | 497 } |
502 // 'on T' catch blocks are not yet implemented. | 498 // 'on T' catch blocks are not yet implemented. |
503 if ((node.catchBlocks.nodes.head as ast.CatchBlock).onKeyword != null) { | 499 if ((node.catchBlocks.nodes.head as ast.CatchBlock).onKeyword != null) { |
504 return giveup(node, '"on T" catch block'); | 500 return giveup(node, '"on T" catch block'); |
505 } | 501 } |
506 // Finally blocks are not yet implemented. | 502 // Finally blocks are not yet implemented. |
(...skipping 2073 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2580 body.functionSignature.orderedForEachParameter((ParameterElement param) { | 2576 body.functionSignature.orderedForEachParameter((ParameterElement param) { |
2581 if (scope != null && scope.capturedVariables.containsKey(param)) { | 2577 if (scope != null && scope.capturedVariables.containsKey(param)) { |
2582 // Do not pass this parameter; the box will carry its value. | 2578 // Do not pass this parameter; the box will carry its value. |
2583 } else { | 2579 } else { |
2584 parameters.add(param); | 2580 parameters.add(param); |
2585 } | 2581 } |
2586 }); | 2582 }); |
2587 return parameters; | 2583 return parameters; |
2588 } | 2584 } |
2589 | 2585 |
| 2586 DartCapturedVariables _analyzeCapturedVariables(ast.Node node) { |
| 2587 DartCapturedVariables variables = new DartCapturedVariables(elements); |
| 2588 try { |
| 2589 variables.analyze(node); |
| 2590 } catch (e) { |
| 2591 bailoutMessage = variables.bailoutMessage; |
| 2592 rethrow; |
| 2593 } |
| 2594 return variables; |
| 2595 } |
| 2596 |
2590 /// Builds the IR for the body of a constructor. | 2597 /// Builds the IR for the body of a constructor. |
2591 /// | 2598 /// |
2592 /// This function is invoked from one or more "factory" constructors built by | 2599 /// This function is invoked from one or more "factory" constructors built by |
2593 /// [buildConstructor]. | 2600 /// [buildConstructor]. |
2594 ir.FunctionDefinition buildConstructorBody(ConstructorBodyElement body) { | 2601 ir.FunctionDefinition buildConstructorBody(ConstructorBodyElement body) { |
2595 ConstructorElement constructor = body.constructor; | 2602 ConstructorElement constructor = body.constructor; |
2596 ast.FunctionExpression node = constructor.node; | 2603 ast.FunctionExpression node = constructor.node; |
2597 closureMap = compiler.closureToClassMapper.computeClosureToClassMapping( | 2604 closureMap = compiler.closureToClassMapper.computeClosureToClassMapping( |
2598 constructor, | 2605 constructor, |
2599 node, | 2606 node, |
2600 elements); | 2607 elements); |
2601 | 2608 |
| 2609 // We compute variables boxed in mutable variables on entry to each try |
| 2610 // block, not including variables captured by a closure (which are boxed |
| 2611 // in the heap). This duplicates some of the work of closure conversion |
| 2612 // without directly using the results. This duplication is wasteful and |
| 2613 // error-prone. |
| 2614 // TODO(kmillikin): We should combine closure conversion and try/catch |
| 2615 // variable analysis in some way. |
| 2616 DartCapturedVariables variables = _analyzeCapturedVariables(node); |
| 2617 tryStatements = variables.tryStatements; |
2602 JsIrBuilder builder = getBuilderFor(body); | 2618 JsIrBuilder builder = getBuilderFor(body); |
2603 | 2619 |
2604 return withBuilder(builder, () { | 2620 return withBuilder(builder, () { |
2605 irBuilder.buildConstructorBodyHeader(getConstructorBodyParameters(body), | 2621 irBuilder.buildConstructorBodyHeader(getConstructorBodyParameters(body), |
2606 getClosureScopeForNode(node)); | 2622 getClosureScopeForNode(node)); |
2607 visit(node.body); | 2623 visit(node.body); |
2608 return irBuilder.makeFunctionDefinition([]); | 2624 return irBuilder.makeFunctionDefinition([]); |
2609 }); | 2625 }); |
2610 } | 2626 } |
2611 | 2627 |
2612 ir.FunctionDefinition buildFunction(FunctionElement element) { | 2628 ir.FunctionDefinition buildFunction(FunctionElement element) { |
2613 assert(invariant(element, element.isImplementation)); | 2629 assert(invariant(element, element.isImplementation)); |
2614 ast.FunctionExpression node = element.node; | 2630 ast.FunctionExpression node = element.node; |
2615 | 2631 |
2616 assert(!element.isSynthesized); | 2632 assert(!element.isSynthesized); |
2617 assert(node != null); | 2633 assert(node != null); |
2618 assert(elements[node] != null); | 2634 assert(elements[node] != null); |
2619 | 2635 |
2620 closureMap = compiler.closureToClassMapper.computeClosureToClassMapping( | 2636 closureMap = compiler.closureToClassMapper.computeClosureToClassMapping( |
2621 element, | 2637 element, |
2622 node, | 2638 node, |
2623 elements); | 2639 elements); |
| 2640 DartCapturedVariables variables = _analyzeCapturedVariables(node); |
| 2641 tryStatements = variables.tryStatements; |
2624 IrBuilder builder = getBuilderFor(element); | 2642 IrBuilder builder = getBuilderFor(element); |
2625 return withBuilder(builder, () => _makeFunctionBody(element, node)); | 2643 return withBuilder(builder, () => _makeFunctionBody(element, node)); |
2626 } | 2644 } |
2627 | 2645 |
2628 /// Creates a primitive for the default value of [parameter]. | 2646 /// Creates a primitive for the default value of [parameter]. |
2629 ir.Primitive translateDefaultValue(ParameterElement parameter) { | 2647 ir.Primitive translateDefaultValue(ParameterElement parameter) { |
2630 if (parameter.initializer == null) { | 2648 if (parameter.initializer == null) { |
2631 return irBuilder.buildNullLiteral(); | 2649 return irBuilder.buildNullLiteral(); |
2632 } else { | 2650 } else { |
2633 return inlineConstant(parameter.executableContext, parameter.initializer); | 2651 return inlineConstant(parameter.executableContext, parameter.initializer); |
(...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2764 SourceInformation buildCall(ast.Node node) { | 2782 SourceInformation buildCall(ast.Node node) { |
2765 return new PositionSourceInformation( | 2783 return new PositionSourceInformation( |
2766 new TokenSourceLocation(sourceFile, node.getBeginToken(), name)); | 2784 new TokenSourceLocation(sourceFile, node.getBeginToken(), name)); |
2767 } | 2785 } |
2768 | 2786 |
2769 @override | 2787 @override |
2770 SourceInformationBuilder forContext(AstElement element) { | 2788 SourceInformationBuilder forContext(AstElement element) { |
2771 return new PositionSourceInformationBuilder(element); | 2789 return new PositionSourceInformationBuilder(element); |
2772 } | 2790 } |
2773 } | 2791 } |
OLD | NEW |