| 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; | 5 library dart2js.ir_builder; |
| 6 | 6 |
| 7 import '../compile_time_constants.dart' show BackendConstantEnvironment; | 7 import '../compile_time_constants.dart' show BackendConstantEnvironment; |
| 8 import '../constants/constant_system.dart'; | 8 import '../constants/constant_system.dart'; |
| 9 import '../constants/expressions.dart'; | 9 import '../constants/expressions.dart'; |
| 10 import '../constants/values.dart' show ConstantValue, PrimitiveConstantValue; | 10 import '../constants/values.dart' show ConstantValue, PrimitiveConstantValue; |
| (...skipping 1627 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1638 SwitchCaseInfo defaultCase, | 1638 SwitchCaseInfo defaultCase, |
| 1639 Element error, | 1639 Element error, |
| 1640 SourceInformation sourceInformation) { | 1640 SourceInformation sourceInformation) { |
| 1641 assert(isOpen); | 1641 assert(isOpen); |
| 1642 JumpCollector join = new ForwardJumpCollector(environment, target: target); | 1642 JumpCollector join = new ForwardJumpCollector(environment, target: target); |
| 1643 | 1643 |
| 1644 IrBuilder casesBuilder = makeDelimitedBuilder(); | 1644 IrBuilder casesBuilder = makeDelimitedBuilder(); |
| 1645 casesBuilder.state.breakCollectors.add(join); | 1645 casesBuilder.state.breakCollectors.add(join); |
| 1646 for (SwitchCaseInfo caseInfo in cases) { | 1646 for (SwitchCaseInfo caseInfo in cases) { |
| 1647 buildConditionsFrom(int index) => (IrBuilder builder) { | 1647 buildConditionsFrom(int index) => (IrBuilder builder) { |
| 1648 ir.Primitive comparison = builder.addPrimitive( | 1648 ir.Primitive comparison = builder.buildIdentical( |
| 1649 new ir.Identical(value, caseInfo.constants[index])); | 1649 value, caseInfo.constants[index]); |
| 1650 return (index == caseInfo.constants.length - 1) | 1650 return (index == caseInfo.constants.length - 1) |
| 1651 ? comparison | 1651 ? comparison |
| 1652 : builder.buildLogicalOperator( | 1652 : builder.buildLogicalOperator( |
| 1653 comparison, buildConditionsFrom(index + 1), isLazyOr: true); | 1653 comparison, buildConditionsFrom(index + 1), isLazyOr: true); |
| 1654 }; | 1654 }; |
| 1655 | 1655 |
| 1656 ir.Primitive condition = buildConditionsFrom(0)(casesBuilder); | 1656 ir.Primitive condition = buildConditionsFrom(0)(casesBuilder); |
| 1657 IrBuilder thenBuilder = makeDelimitedBuilder(); | 1657 IrBuilder thenBuilder = makeDelimitedBuilder(); |
| 1658 caseInfo.buildBody(thenBuilder); | 1658 caseInfo.buildBody(thenBuilder); |
| 1659 if (thenBuilder.isOpen) { | 1659 if (thenBuilder.isOpen) { |
| (...skipping 424 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2084 leftFalseContinuation], | 2084 leftFalseContinuation], |
| 2085 new ir.Branch(new ir.IsTrue(leftValue), | 2085 new ir.Branch(new ir.IsTrue(leftValue), |
| 2086 leftTrueContinuation, | 2086 leftTrueContinuation, |
| 2087 leftFalseContinuation)))); | 2087 leftFalseContinuation)))); |
| 2088 environment = join.environment; | 2088 environment = join.environment; |
| 2089 environment.discard(1); | 2089 environment.discard(1); |
| 2090 // There is always a join parameter for the result value, because it | 2090 // There is always a join parameter for the result value, because it |
| 2091 // is different on at least two paths. | 2091 // is different on at least two paths. |
| 2092 return join.continuation.parameters.last; | 2092 return join.continuation.parameters.last; |
| 2093 } | 2093 } |
| 2094 |
| 2095 ir.Primitive buildIdentical(ir.Primitive x, ir.Primitive y) { |
| 2096 return addPrimitive(new ir.ApplyBuiltinOperator( |
| 2097 ir.BuiltinOperator.Identical, <ir.Primitive>[x, y])); |
| 2098 } |
| 2094 } | 2099 } |
| 2095 | 2100 |
| 2096 /// State shared between JsIrBuilders within the same function. | 2101 /// State shared between JsIrBuilders within the same function. |
| 2097 /// | 2102 /// |
| 2098 /// Note that this is not shared between builders of nested functions. | 2103 /// Note that this is not shared between builders of nested functions. |
| 2099 class JsIrBuilderSharedState { | 2104 class JsIrBuilderSharedState { |
| 2100 /// Maps boxed locals to their location. These locals are not part of | 2105 /// Maps boxed locals to their location. These locals are not part of |
| 2101 /// the environment. | 2106 /// the environment. |
| 2102 final Map<Local, ClosureLocation> boxedVariables = {}; | 2107 final Map<Local, ClosureLocation> boxedVariables = {}; |
| 2103 | 2108 |
| (...skipping 398 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2502 // For type tests, we must treat specially the rare cases where `null` | 2507 // For type tests, we must treat specially the rare cases where `null` |
| 2503 // satisfies the test (which otherwise never satisfies a type test). | 2508 // satisfies the test (which otherwise never satisfies a type test). |
| 2504 // This is not an optimization: the TypeOperator assumes that `null` | 2509 // This is not an optimization: the TypeOperator assumes that `null` |
| 2505 // cannot satisfy the type test unless the type is a type variable. | 2510 // cannot satisfy the type test unless the type is a type variable. |
| 2506 if (type.isObject || type.isDynamic) { | 2511 if (type.isObject || type.isDynamic) { |
| 2507 // `x is Object` and `x is dynamic` are always true, even if x is null. | 2512 // `x is Object` and `x is dynamic` are always true, even if x is null. |
| 2508 return buildBooleanConstant(true); | 2513 return buildBooleanConstant(true); |
| 2509 } | 2514 } |
| 2510 if (type is InterfaceType && type.element == program.nullClass) { | 2515 if (type is InterfaceType && type.element == program.nullClass) { |
| 2511 // `x is Null` is true if and only if x is null. | 2516 // `x is Null` is true if and only if x is null. |
| 2512 return addPrimitive(new ir.Identical(value, buildNullConstant())); | 2517 return _buildCheckNull(value); |
| 2513 } | 2518 } |
| 2514 return addPrimitive(new ir.TypeTest(value, type, typeArguments)); | 2519 return addPrimitive(new ir.TypeTest(value, type, typeArguments)); |
| 2515 } else { | 2520 } else { |
| 2516 return _continueWithExpression( | 2521 return _continueWithExpression( |
| 2517 (k) => new ir.TypeCast(value, type, typeArguments, k)); | 2522 (k) => new ir.TypeCast(value, type, typeArguments, k)); |
| 2518 } | 2523 } |
| 2519 } | 2524 } |
| 2520 | 2525 |
| 2521 @override | 2526 @override |
| 2522 ir.Primitive buildIfNull(ir.Primitive value, | 2527 ir.Primitive buildIfNull(ir.Primitive value, |
| 2523 ir.Primitive buildRight(IrBuilder builder)) { | 2528 ir.Primitive buildRight(IrBuilder builder)) { |
| 2524 ir.Primitive condition = _buildCheckNull(value); | 2529 ir.Primitive condition = _buildCheckNull(value); |
| 2525 return buildConditional(condition, buildRight, (_) => value); | 2530 return buildConditional(condition, buildRight, (_) => value); |
| 2526 } | 2531 } |
| 2527 | 2532 |
| 2528 @override | 2533 @override |
| 2529 ir.Primitive buildIfNotNullSend(ir.Primitive receiver, | 2534 ir.Primitive buildIfNotNullSend(ir.Primitive receiver, |
| 2530 ir.Primitive buildSend(IrBuilder builder)) { | 2535 ir.Primitive buildSend(IrBuilder builder)) { |
| 2531 ir.Primitive condition = _buildCheckNull(receiver); | 2536 ir.Primitive condition = _buildCheckNull(receiver); |
| 2532 return buildConditional(condition, (_) => receiver, buildSend); | 2537 return buildConditional(condition, (_) => receiver, buildSend); |
| 2533 } | 2538 } |
| 2534 | 2539 |
| 2535 /// Creates a type test checking whether [value] is null. | 2540 /// Creates a type test checking whether [value] is null. |
| 2536 ir.Primitive _buildCheckNull(ir.Primitive value) { | 2541 ir.Primitive _buildCheckNull(ir.Primitive value) { |
| 2537 assert(isOpen); | 2542 assert(isOpen); |
| 2538 ir.Primitive right = buildNullConstant(); | 2543 return buildIdentical(value, buildNullConstant()); |
| 2539 return addPrimitive(new ir.Identical(value, right)); | |
| 2540 } | 2544 } |
| 2541 | 2545 |
| 2542 /// Convert the given value to a string. | 2546 /// Convert the given value to a string. |
| 2543 ir.Primitive buildStringify(ir.Primitive value) { | 2547 ir.Primitive buildStringify(ir.Primitive value) { |
| 2544 return buildStaticFunctionInvocation( | 2548 return buildStaticFunctionInvocation( |
| 2545 program.stringifyFunction, | 2549 program.stringifyFunction, |
| 2546 new CallStructure.unnamed(1), | 2550 new CallStructure.unnamed(1), |
| 2547 <ir.Primitive>[value]); | 2551 <ir.Primitive>[value]); |
| 2548 } | 2552 } |
| 2549 } | 2553 } |
| (...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2620 } | 2624 } |
| 2621 | 2625 |
| 2622 class SwitchCaseInfo { | 2626 class SwitchCaseInfo { |
| 2623 final List<ir.Primitive> constants = <ir.Primitive>[]; | 2627 final List<ir.Primitive> constants = <ir.Primitive>[]; |
| 2624 final SubbuildFunction buildBody; | 2628 final SubbuildFunction buildBody; |
| 2625 | 2629 |
| 2626 SwitchCaseInfo(this.buildBody); | 2630 SwitchCaseInfo(this.buildBody); |
| 2627 | 2631 |
| 2628 void addConstant(ir.Primitive constant) => constants.add(constant); | 2632 void addConstant(ir.Primitive constant) => constants.add(constant); |
| 2629 } | 2633 } |
| OLD | NEW |