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 |