| 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 '../common.dart'; | 9 import '../common.dart'; |
| 10 import '../common/names.dart' show | 10 import '../common/names.dart' show |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 46 NativeBehavior; | 46 NativeBehavior; |
| 47 | 47 |
| 48 // TODO(karlklose): remove. | 48 // TODO(karlklose): remove. |
| 49 import '../js/js.dart' as js show js, Template, Expression, Name; | 49 import '../js/js.dart' as js show js, Template, Expression, Name; |
| 50 import '../ssa/ssa.dart' show TypeMaskFactory; | 50 import '../ssa/ssa.dart' show TypeMaskFactory; |
| 51 import '../util/util.dart'; | 51 import '../util/util.dart'; |
| 52 | 52 |
| 53 import 'package:js_runtime/shared/embedded_names.dart' | 53 import 'package:js_runtime/shared/embedded_names.dart' |
| 54 show JsBuiltin, JsGetName; | 54 show JsBuiltin, JsGetName; |
| 55 import '../constants/values.dart'; | 55 import '../constants/values.dart'; |
| 56 import 'type_mask_system.dart' show |
| 57 TypeMaskSystem; |
| 56 | 58 |
| 57 typedef void IrBuilderCallback(Element element, ir.FunctionDefinition irNode); | 59 typedef void IrBuilderCallback(Element element, ir.FunctionDefinition irNode); |
| 58 | 60 |
| 59 /// This task provides the interface to build IR nodes from [ast.Node]s, which | 61 /// This task provides the interface to build IR nodes from [ast.Node]s, which |
| 60 /// is used from the [CpsFunctionCompiler] to generate code. | 62 /// is used from the [CpsFunctionCompiler] to generate code. |
| 61 /// | 63 /// |
| 62 /// This class is mainly there to correctly measure how long building the IR | 64 /// This class is mainly there to correctly measure how long building the IR |
| 63 /// takes. | 65 /// takes. |
| 64 class IrBuilderTask extends CompilerTask { | 66 class IrBuilderTask extends CompilerTask { |
| 65 final SourceInformationStrategy sourceInformationStrategy; | 67 final SourceInformationStrategy sourceInformationStrategy; |
| 66 | 68 |
| 67 String bailoutMessage = null; | 69 String bailoutMessage = null; |
| 68 | 70 |
| 69 /// If not null, this function will be called with for each | 71 /// If not null, this function will be called with for each |
| 70 /// [ir.FunctionDefinition] node that has been built. | 72 /// [ir.FunctionDefinition] node that has been built. |
| 71 IrBuilderCallback builderCallback; | 73 IrBuilderCallback builderCallback; |
| 72 | 74 |
| 73 IrBuilderTask(Compiler compiler, this.sourceInformationStrategy, | 75 IrBuilderTask(Compiler compiler, this.sourceInformationStrategy, |
| 74 [this.builderCallback]) | 76 [this.builderCallback]) |
| 75 : super(compiler); | 77 : super(compiler); |
| 76 | 78 |
| 77 String get name => 'CPS builder'; | 79 String get name => 'CPS builder'; |
| 78 | 80 |
| 79 ir.FunctionDefinition buildNode(AstElement element) { | 81 ir.FunctionDefinition buildNode(AstElement element, |
| 82 TypeMaskSystem typeMaskSystem) { |
| 80 return measure(() { | 83 return measure(() { |
| 81 bailoutMessage = null; | 84 bailoutMessage = null; |
| 82 | 85 |
| 83 TreeElements elementsMapping = element.resolvedAst.elements; | 86 TreeElements elementsMapping = element.resolvedAst.elements; |
| 84 element = element.implementation; | 87 element = element.implementation; |
| 85 return reporter.withCurrentElement(element, () { | 88 return reporter.withCurrentElement(element, () { |
| 86 SourceInformationBuilder sourceInformationBuilder = | 89 SourceInformationBuilder sourceInformationBuilder = |
| 87 sourceInformationStrategy.createBuilderForContext(element); | 90 sourceInformationStrategy.createBuilderForContext(element); |
| 88 | 91 |
| 89 IrBuilderVisitor builder = | 92 IrBuilderVisitor builder = |
| 90 new JsIrBuilderVisitor( | 93 new JsIrBuilderVisitor( |
| 91 elementsMapping, compiler, sourceInformationBuilder); | 94 elementsMapping, compiler, sourceInformationBuilder, |
| 95 typeMaskSystem); |
| 92 ir.FunctionDefinition irNode = builder.buildExecutable(element); | 96 ir.FunctionDefinition irNode = builder.buildExecutable(element); |
| 93 if (irNode == null) { | 97 if (irNode == null) { |
| 94 bailoutMessage = builder.bailoutMessage; | 98 bailoutMessage = builder.bailoutMessage; |
| 95 } else if (builderCallback != null) { | 99 } else if (builderCallback != null) { |
| 96 builderCallback(element, irNode); | 100 builderCallback(element, irNode); |
| 97 } | 101 } |
| 98 return irNode; | 102 return irNode; |
| 99 }); | 103 }); |
| 100 }); | 104 }); |
| 101 } | 105 } |
| (...skipping 18 matching lines...) Expand all Loading... |
| 120 BaseImplementationOfDynamicsMixin<ir.Primitive, dynamic>, | 124 BaseImplementationOfDynamicsMixin<ir.Primitive, dynamic>, |
| 121 BaseImplementationOfConstantsMixin<ir.Primitive, dynamic>, | 125 BaseImplementationOfConstantsMixin<ir.Primitive, dynamic>, |
| 122 BaseImplementationOfNewMixin<ir.Primitive, dynamic>, | 126 BaseImplementationOfNewMixin<ir.Primitive, dynamic>, |
| 123 BaseImplementationOfCompoundsMixin<ir.Primitive, dynamic>, | 127 BaseImplementationOfCompoundsMixin<ir.Primitive, dynamic>, |
| 124 BaseImplementationOfSetIfNullsMixin<ir.Primitive, dynamic>, | 128 BaseImplementationOfSetIfNullsMixin<ir.Primitive, dynamic>, |
| 125 BaseImplementationOfIndexCompoundsMixin<ir.Primitive, dynamic> | 129 BaseImplementationOfIndexCompoundsMixin<ir.Primitive, dynamic> |
| 126 implements SemanticSendVisitor<ir.Primitive, dynamic> { | 130 implements SemanticSendVisitor<ir.Primitive, dynamic> { |
| 127 final TreeElements elements; | 131 final TreeElements elements; |
| 128 final Compiler compiler; | 132 final Compiler compiler; |
| 129 final SourceInformationBuilder sourceInformationBuilder; | 133 final SourceInformationBuilder sourceInformationBuilder; |
| 134 final TypeMaskSystem typeMaskSystem; |
| 130 | 135 |
| 131 /// A map from try statements in the source to analysis information about | 136 /// A map from try statements in the source to analysis information about |
| 132 /// them. | 137 /// them. |
| 133 /// | 138 /// |
| 134 /// The analysis information includes the set of variables that must be | 139 /// 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 | 140 /// copied into [ir.MutableVariable]s on entry to the try and copied out on |
| 136 /// exit. | 141 /// exit. |
| 137 Map<ast.Node, TryStatementInfo> tryStatements = null; | 142 Map<ast.Node, TryStatementInfo> tryStatements = null; |
| 138 | 143 |
| 139 // In SSA terms, join-point continuation parameters are the phis and the | 144 // In SSA terms, join-point continuation parameters are the phis and the |
| (...skipping 10 matching lines...) Expand all Loading... |
| 150 // | 155 // |
| 151 // Each nested visitor maintains a list that maps indexes of variables | 156 // Each nested visitor maintains a list that maps indexes of variables |
| 152 // assigned in the delimited subexpression to their reaching definition --- | 157 // assigned in the delimited subexpression to their reaching definition --- |
| 153 // that is, the definition in effect at the hole in 'current'. These are | 158 // 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 | 159 // used to determine if a join-point continuation needs to be passed |
| 155 // arguments, and what the arguments are. | 160 // arguments, and what the arguments are. |
| 156 | 161 |
| 157 /// Construct a top-level visitor. | 162 /// Construct a top-level visitor. |
| 158 IrBuilderVisitor(this.elements, | 163 IrBuilderVisitor(this.elements, |
| 159 this.compiler, | 164 this.compiler, |
| 160 this.sourceInformationBuilder); | 165 this.sourceInformationBuilder, |
| 166 this.typeMaskSystem); |
| 161 | 167 |
| 162 DiagnosticReporter get reporter => compiler.reporter; | 168 DiagnosticReporter get reporter => compiler.reporter; |
| 163 | 169 |
| 164 String bailoutMessage = null; | 170 String bailoutMessage = null; |
| 165 | 171 |
| 166 @override | 172 @override |
| 167 ir.Primitive apply(ast.Node node, _) => node.accept(this); | 173 ir.Primitive apply(ast.Node node, _) => node.accept(this); |
| 168 | 174 |
| 169 @override | 175 @override |
| 170 SemanticSendVisitor get sendVisitor => this; | 176 SemanticSendVisitor get sendVisitor => this; |
| (...skipping 231 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 402 variableSelector: selector, | 408 variableSelector: selector, |
| 403 variableMask: elements.getTypeMask(identifier), | 409 variableMask: elements.getTypeMask(identifier), |
| 404 currentMask: elements.getCurrentTypeMask(node), | 410 currentMask: elements.getCurrentTypeMask(node), |
| 405 moveNextMask: elements.getMoveNextTypeMask(node), | 411 moveNextMask: elements.getMoveNextTypeMask(node), |
| 406 iteratorMask: elements.getIteratorTypeMask(node), | 412 iteratorMask: elements.getIteratorTypeMask(node), |
| 407 buildBody: subbuild(node.body), | 413 buildBody: subbuild(node.body), |
| 408 target: elements.getTargetDefinition(node), | 414 target: elements.getTargetDefinition(node), |
| 409 closureScope: getClosureScopeForNode(node)); | 415 closureScope: getClosureScopeForNode(node)); |
| 410 } | 416 } |
| 411 | 417 |
| 418 /// If compiling with trusted type annotations, assumes that [value] is |
| 419 /// now known to be `null` or an instance of [type]. |
| 420 /// |
| 421 /// This is also where we should add type checks in checked mode, but this |
| 422 /// is not supported yet. |
| 423 ir.Primitive checkType(ir.Primitive value, DartType dartType) { |
| 424 if (!compiler.trustTypeAnnotations) return value; |
| 425 TypeMask type = typeMaskSystem.subtypesOf(dartType).nullable(); |
| 426 return irBuilder.buildRefinement(value, type); |
| 427 } |
| 428 |
| 429 ir.Primitive checkTypeVsElement(ir.Primitive value, TypedElement element) { |
| 430 return checkType(value, element.type); |
| 431 } |
| 432 |
| 412 ir.Primitive visitVariableDefinitions(ast.VariableDefinitions node) { | 433 ir.Primitive visitVariableDefinitions(ast.VariableDefinitions node) { |
| 413 assert(irBuilder.isOpen); | 434 assert(irBuilder.isOpen); |
| 414 for (ast.Node definition in node.definitions.nodes) { | 435 for (ast.Node definition in node.definitions.nodes) { |
| 415 Element element = elements[definition]; | 436 Element element = elements[definition]; |
| 416 ir.Primitive initialValue; | 437 ir.Primitive initialValue; |
| 417 // Definitions are either SendSets if there is an initializer, or | 438 // Definitions are either SendSets if there is an initializer, or |
| 418 // Identifiers if there is no initializer. | 439 // Identifiers if there is no initializer. |
| 419 if (definition is ast.SendSet) { | 440 if (definition is ast.SendSet) { |
| 420 assert(!definition.arguments.isEmpty); | 441 assert(!definition.arguments.isEmpty); |
| 421 assert(definition.arguments.tail.isEmpty); | 442 assert(definition.arguments.tail.isEmpty); |
| 422 initialValue = visit(definition.arguments.head); | 443 initialValue = visit(definition.arguments.head); |
| 444 initialValue = checkTypeVsElement(initialValue, element); |
| 423 } else { | 445 } else { |
| 424 assert(definition is ast.Identifier); | 446 assert(definition is ast.Identifier); |
| 425 } | 447 } |
| 426 irBuilder.declareLocalVariable(element, initialValue: initialValue); | 448 irBuilder.declareLocalVariable(element, initialValue: initialValue); |
| 427 } | 449 } |
| 428 return null; | 450 return null; |
| 429 } | 451 } |
| 430 | 452 |
| 431 static final RegExp nativeRedirectionRegExp = | 453 static final RegExp nativeRedirectionRegExp = |
| 432 new RegExp(r'^[a-zA-Z][a-zA-Z_$0-9]*$'); | 454 new RegExp(r'^[a-zA-Z][a-zA-Z_$0-9]*$'); |
| (...skipping 962 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1395 elements.getTypeMask(node), | 1417 elements.getTypeMask(node), |
| 1396 visit(rhs)))); | 1418 visit(rhs)))); |
| 1397 } | 1419 } |
| 1398 | 1420 |
| 1399 @override | 1421 @override |
| 1400 ir.Primitive handleLocalSet( | 1422 ir.Primitive handleLocalSet( |
| 1401 ast.SendSet node, | 1423 ast.SendSet node, |
| 1402 LocalElement element, | 1424 LocalElement element, |
| 1403 ast.Node rhs, | 1425 ast.Node rhs, |
| 1404 _) { | 1426 _) { |
| 1405 return irBuilder.buildLocalVariableSet(element, visit(rhs)); | 1427 ir.Primitive value = visit(rhs); |
| 1428 value = checkTypeVsElement(value, element); |
| 1429 return irBuilder.buildLocalVariableSet(element, value); |
| 1406 } | 1430 } |
| 1407 | 1431 |
| 1408 @override | 1432 @override |
| 1409 ir.Primitive handleStaticFieldSet( | 1433 ir.Primitive handleStaticFieldSet( |
| 1410 ast.SendSet node, | 1434 ast.SendSet node, |
| 1411 FieldElement field, | 1435 FieldElement field, |
| 1412 ast.Node rhs, | 1436 ast.Node rhs, |
| 1413 _) { | 1437 _) { |
| 1414 return irBuilder.buildStaticFieldSet(field, visit(rhs)); | 1438 return irBuilder.buildStaticFieldSet(field, visit(rhs)); |
| 1415 } | 1439 } |
| (...skipping 1107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2523 JavaScriptBackend get backend => compiler.backend; | 2547 JavaScriptBackend get backend => compiler.backend; |
| 2524 | 2548 |
| 2525 /// Result of closure conversion for the current body of code. | 2549 /// Result of closure conversion for the current body of code. |
| 2526 /// | 2550 /// |
| 2527 /// Will be initialized upon entering the body of a function. | 2551 /// Will be initialized upon entering the body of a function. |
| 2528 /// It is computed by the [ClosureTranslator]. | 2552 /// It is computed by the [ClosureTranslator]. |
| 2529 ClosureClassMap closureClassMap; | 2553 ClosureClassMap closureClassMap; |
| 2530 | 2554 |
| 2531 JsIrBuilderVisitor(TreeElements elements, | 2555 JsIrBuilderVisitor(TreeElements elements, |
| 2532 Compiler compiler, | 2556 Compiler compiler, |
| 2533 SourceInformationBuilder sourceInformationBuilder) | 2557 SourceInformationBuilder sourceInformationBuilder, |
| 2534 : super(elements, compiler, sourceInformationBuilder); | 2558 TypeMaskSystem typeMaskSystem) |
| 2559 : super(elements, compiler, sourceInformationBuilder, typeMaskSystem); |
| 2535 | 2560 |
| 2536 | 2561 |
| 2537 /// Builds the IR for creating an instance of the closure class corresponding | 2562 /// Builds the IR for creating an instance of the closure class corresponding |
| 2538 /// to the given nested function. | 2563 /// to the given nested function. |
| 2539 ClosureClassElement makeSubFunction(ast.FunctionExpression node) { | 2564 ClosureClassElement makeSubFunction(ast.FunctionExpression node) { |
| 2540 ClosureClassMap innerMap = | 2565 ClosureClassMap innerMap = |
| 2541 compiler.closureToClassMapper.getMappingForNestedFunction(node); | 2566 compiler.closureToClassMapper.getMappingForNestedFunction(node); |
| 2542 ClosureClassElement closureClass = innerMap.closureClassElement; | 2567 ClosureClassElement closureClass = innerMap.closureClassElement; |
| 2543 return closureClass; | 2568 return closureClass; |
| 2544 } | 2569 } |
| (...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2677 } | 2702 } |
| 2678 | 2703 |
| 2679 /// Make a visitor suitable for translating ASTs taken from [context]. | 2704 /// Make a visitor suitable for translating ASTs taken from [context]. |
| 2680 /// | 2705 /// |
| 2681 /// Every visitor can only be applied to nodes in one context, because | 2706 /// Every visitor can only be applied to nodes in one context, because |
| 2682 /// the [elements] field is specific to that context. | 2707 /// the [elements] field is specific to that context. |
| 2683 JsIrBuilderVisitor makeVisitorForContext(AstElement context) { | 2708 JsIrBuilderVisitor makeVisitorForContext(AstElement context) { |
| 2684 return new JsIrBuilderVisitor( | 2709 return new JsIrBuilderVisitor( |
| 2685 context.resolvedAst.elements, | 2710 context.resolvedAst.elements, |
| 2686 compiler, | 2711 compiler, |
| 2687 sourceInformationBuilder.forContext(context)); | 2712 sourceInformationBuilder.forContext(context), |
| 2713 typeMaskSystem); |
| 2688 } | 2714 } |
| 2689 | 2715 |
| 2690 /// Builds the IR for an [expression] taken from a different [context]. | 2716 /// Builds the IR for an [expression] taken from a different [context]. |
| 2691 /// | 2717 /// |
| 2692 /// Such expressions need to be compiled with a different [sourceFile] and | 2718 /// Such expressions need to be compiled with a different [sourceFile] and |
| 2693 /// [elements] mapping. | 2719 /// [elements] mapping. |
| 2694 ir.Primitive inlineExpression(AstElement context, ast.Expression expression) { | 2720 ir.Primitive inlineExpression(AstElement context, ast.Expression expression) { |
| 2695 JsIrBuilderVisitor visitor = makeVisitorForContext(context); | 2721 JsIrBuilderVisitor visitor = makeVisitorForContext(context); |
| 2696 return visitor.withBuilder(irBuilder, () => visitor.visit(expression)); | 2722 return visitor.withBuilder(irBuilder, () => visitor.visit(expression)); |
| 2697 } | 2723 } |
| (...skipping 878 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3576 if (compiler.backend.isForeign(function)) { | 3602 if (compiler.backend.isForeign(function)) { |
| 3577 return handleForeignCode(node, function, argumentList, callStructure); | 3603 return handleForeignCode(node, function, argumentList, callStructure); |
| 3578 } else { | 3604 } else { |
| 3579 return irBuilder.buildStaticFunctionInvocation(function, callStructure, | 3605 return irBuilder.buildStaticFunctionInvocation(function, callStructure, |
| 3580 translateStaticArguments(argumentList, function, callStructure), | 3606 translateStaticArguments(argumentList, function, callStructure), |
| 3581 sourceInformation: | 3607 sourceInformation: |
| 3582 sourceInformationBuilder.buildCall(node, node.selector)); | 3608 sourceInformationBuilder.buildCall(node, node.selector)); |
| 3583 } | 3609 } |
| 3584 } | 3610 } |
| 3585 } | 3611 } |
| OLD | NEW |