| 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/values.dart' show ConstantValue, PrimitiveConstantValue; | 9 import '../constants/values.dart' show ConstantValue, PrimitiveConstantValue; |
| 10 import '../dart_types.dart'; | 10 import '../dart_types.dart'; |
| (...skipping 175 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 186 for (Iterable<LocalVariableElement> boxedOnEntry in _boxedTryVariables) { | 186 for (Iterable<LocalVariableElement> boxedOnEntry in _boxedTryVariables) { |
| 187 for (LocalVariableElement variable in boxedOnEntry) { | 187 for (LocalVariableElement variable in boxedOnEntry) { |
| 188 assert(builder.isInMutableVariable(variable)); | 188 assert(builder.isInMutableVariable(variable)); |
| 189 ir.Primitive value = builder.buildLocalVariableGet(variable); | 189 ir.Primitive value = builder.buildLocalVariableGet(variable); |
| 190 builder.environment.update(variable, value); | 190 builder.environment.update(variable, value); |
| 191 } | 191 } |
| 192 } | 192 } |
| 193 } | 193 } |
| 194 | 194 |
| 195 /// True if a jump inserted now will escape from a try block. | 195 /// True if a jump inserted now will escape from a try block. |
| 196 /// | 196 /// |
| 197 /// Concretely, this is true when [enterTry] has been called without | 197 /// Concretely, this is true when [enterTry] has been called without |
| 198 /// its corresponding [leaveTry] call. | 198 /// its corresponding [leaveTry] call. |
| 199 bool get isEscapingTry => _boxedTryVariables.isNotEmpty; | 199 bool get isEscapingTry => _boxedTryVariables.isNotEmpty; |
| 200 } | 200 } |
| 201 | 201 |
| 202 /// A class to collect 'forward' jumps. | 202 /// A class to collect 'forward' jumps. |
| 203 /// | 203 /// |
| 204 /// A forward jump to a continuation in the sense of the CPS translation is | 204 /// A forward jump to a continuation in the sense of the CPS translation is |
| 205 /// a jump where the jump is emitted before any code in the body of the | 205 /// a jump where the jump is emitted before any code in the body of the |
| 206 /// continuation is translated. They have the property that continuation | 206 /// continuation is translated. They have the property that continuation |
| (...skipping 332 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 539 mutableVariables); | 539 mutableVariables); |
| 540 } | 540 } |
| 541 | 541 |
| 542 /// True if [local] should currently be accessed from a [ir.MutableVariable]. | 542 /// True if [local] should currently be accessed from a [ir.MutableVariable]. |
| 543 bool isInMutableVariable(Local local) { | 543 bool isInMutableVariable(Local local) { |
| 544 return mutableVariables.containsKey(local); | 544 return mutableVariables.containsKey(local); |
| 545 } | 545 } |
| 546 | 546 |
| 547 /// Creates a [ir.MutableVariable] for the given local. | 547 /// Creates a [ir.MutableVariable] for the given local. |
| 548 void makeMutableVariable(Local local) { | 548 void makeMutableVariable(Local local) { |
| 549 mutableVariables[local] = new ir.MutableVariable(local); | 549 mutableVariables[local] = |
| 550 new ir.MutableVariable(local); |
| 550 } | 551 } |
| 551 | 552 |
| 552 /// Remove an [ir.MutableVariable] for a local. | 553 /// Remove an [ir.MutableVariable] for a local. |
| 553 /// | 554 /// |
| 554 /// Subsequent access to the local will be direct rather than through the | 555 /// Subsequent access to the local will be direct rather than through the |
| 555 /// mutable variable. | 556 /// mutable variable. |
| 556 void removeMutableVariable(Local local) { | 557 void removeMutableVariable(Local local) { |
| 557 mutableVariables.remove(local); | 558 mutableVariables.remove(local); |
| 558 } | 559 } |
| 559 | 560 |
| (...skipping 1872 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2432 ir.Primitive buildThis() { | 2433 ir.Primitive buildThis() { |
| 2433 if (state.enclosingThis != null) return state.enclosingThis; | 2434 if (state.enclosingThis != null) return state.enclosingThis; |
| 2434 assert(state.thisParameter != null); | 2435 assert(state.thisParameter != null); |
| 2435 return state.thisParameter; | 2436 return state.thisParameter; |
| 2436 } | 2437 } |
| 2437 | 2438 |
| 2438 ir.Primitive buildFieldGet(ir.Primitive receiver, FieldElement target) { | 2439 ir.Primitive buildFieldGet(ir.Primitive receiver, FieldElement target) { |
| 2439 return addPrimitive(new ir.GetField(receiver, target)); | 2440 return addPrimitive(new ir.GetField(receiver, target)); |
| 2440 } | 2441 } |
| 2441 | 2442 |
| 2442 void buildFieldSet(ir.Primitive receiver, | 2443 void buildFieldSet(ir.Primitive receiver, |
| 2443 FieldElement target, | 2444 FieldElement target, |
| 2444 ir.Primitive value) { | 2445 ir.Primitive value) { |
| 2445 add(new ir.SetField(receiver, target, value)); | 2446 add(new ir.SetField(receiver, target, value)); |
| 2446 } | 2447 } |
| 2447 | 2448 |
| 2448 ir.Primitive buildSuperFieldGet(FieldElement target) { | 2449 ir.Primitive buildSuperFieldGet(FieldElement target) { |
| 2449 return addPrimitive(new ir.GetField(buildThis(), target)); | 2450 return addPrimitive(new ir.GetField(buildThis(), target)); |
| 2450 } | 2451 } |
| 2451 | 2452 |
| 2452 ir.Primitive buildSuperFieldSet(FieldElement target, ir.Primitive value) { | 2453 ir.Primitive buildSuperFieldSet(FieldElement target, ir.Primitive value) { |
| 2453 add(new ir.SetField(buildThis(), target, value)); | 2454 add(new ir.SetField(buildThis(), target, value)); |
| (...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2574 ir.Primitive buildInvocationMirror(Selector selector, | 2575 ir.Primitive buildInvocationMirror(Selector selector, |
| 2575 List<ir.Primitive> arguments) { | 2576 List<ir.Primitive> arguments) { |
| 2576 return addPrimitive(new ir.CreateInvocationMirror(selector, arguments)); | 2577 return addPrimitive(new ir.CreateInvocationMirror(selector, arguments)); |
| 2577 } | 2578 } |
| 2578 | 2579 |
| 2579 ir.Primitive buildForeignCode(js.Template codeTemplate, | 2580 ir.Primitive buildForeignCode(js.Template codeTemplate, |
| 2580 List<ir.Primitive> arguments, | 2581 List<ir.Primitive> arguments, |
| 2581 NativeBehavior behavior, | 2582 NativeBehavior behavior, |
| 2582 {Element dependency}) { | 2583 {Element dependency}) { |
| 2583 types.TypeMask type = program.getTypeMaskForForeign(behavior); | 2584 types.TypeMask type = program.getTypeMaskForForeign(behavior); |
| 2584 if (codeTemplate.isExpression) { | 2585 ir.Primitive result = _continueWithExpression((k) => new ir.ForeignCode( |
| 2585 return _continueWithExpression((k) => new ir.ForeignCode( | |
| 2586 codeTemplate, | 2586 codeTemplate, |
| 2587 type, | 2587 type, |
| 2588 arguments, | 2588 arguments, |
| 2589 behavior, | 2589 behavior, |
| 2590 continuation: k, | 2590 k, |
| 2591 dependency: dependency)); | 2591 dependency: dependency)); |
| 2592 } else { | 2592 if (!codeTemplate.isExpression) { |
| 2593 assert(isOpen); | 2593 // Close the term if this is a "throw" expression. |
| 2594 add(new ir.ForeignCode(codeTemplate, type, arguments, behavior, | 2594 add(new ir.Unreachable()); |
| 2595 dependency: dependency)); | |
| 2596 _current = null; | 2595 _current = null; |
| 2597 return null; | |
| 2598 } | 2596 } |
| 2597 return result; |
| 2599 } | 2598 } |
| 2600 | 2599 |
| 2601 /// Creates a type test or type cast of [value] against [type]. | 2600 /// Creates a type test or type cast of [value] against [type]. |
| 2602 ir.Primitive buildTypeOperator(ir.Primitive value, | 2601 ir.Primitive buildTypeOperator(ir.Primitive value, |
| 2603 DartType type, | 2602 DartType type, |
| 2604 {bool isTypeTest}) { | 2603 {bool isTypeTest}) { |
| 2605 assert(isOpen); | 2604 assert(isOpen); |
| 2606 assert(isTypeTest != null); | 2605 assert(isTypeTest != null); |
| 2607 | 2606 |
| 2608 type = program.unaliasType(type); | 2607 type = program.unaliasType(type); |
| (...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2756 } | 2755 } |
| 2757 | 2756 |
| 2758 class SwitchCaseInfo { | 2757 class SwitchCaseInfo { |
| 2759 final List<ir.Primitive> constants = <ir.Primitive>[]; | 2758 final List<ir.Primitive> constants = <ir.Primitive>[]; |
| 2760 final SubbuildFunction buildBody; | 2759 final SubbuildFunction buildBody; |
| 2761 | 2760 |
| 2762 SwitchCaseInfo(this.buildBody); | 2761 SwitchCaseInfo(this.buildBody); |
| 2763 | 2762 |
| 2764 void addConstant(ir.Primitive constant) => constants.add(constant); | 2763 void addConstant(ir.Primitive constant) => constants.add(constant); |
| 2765 } | 2764 } |
| OLD | NEW |