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 |