| 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 '../constants/expressions.dart'; | 7 import '../constants/expressions.dart'; |
| 8 import '../constants/values.dart' show PrimitiveConstantValue; | 8 import '../constants/values.dart' show PrimitiveConstantValue; |
| 9 import '../dart_types.dart'; | 9 import '../dart_types.dart'; |
| 10 import '../dart2jslib.dart'; | 10 import '../dart2jslib.dart'; |
| 11 import '../elements/elements.dart'; | 11 import '../elements/elements.dart'; |
| 12 import '../io/source_file.dart'; | |
| 13 import '../io/source_information.dart'; | 12 import '../io/source_information.dart'; |
| 14 import '../tree/tree.dart' as ast; | 13 import '../tree/tree.dart' as ast; |
| 15 import '../scanner/scannerlib.dart' show Token, isUserDefinableOperator; | 14 import '../closure.dart' hide ClosureScope; |
| 16 import '../universe/universe.dart' show SelectorKind; | |
| 17 import 'cps_ir_nodes.dart' as ir; | 15 import 'cps_ir_nodes.dart' as ir; |
| 18 import '../elements/modelx.dart' show SynthesizedConstructorElementX, | 16 import 'cps_ir_builder_task.dart' show DartCapturedVariables; |
| 19 ConstructorBodyElementX, FunctionSignatureX; | |
| 20 import '../closure.dart' hide ClosureScope; | |
| 21 import '../closure.dart' as closurelib; | |
| 22 import '../js_backend/js_backend.dart' show JavaScriptBackend; | |
| 23 import '../util/util.dart' show Link; | |
| 24 | |
| 25 part 'cps_ir_builder_visitor.dart'; | |
| 26 | 17 |
| 27 /// A mapping from variable elements to their compile-time values. | 18 /// A mapping from variable elements to their compile-time values. |
| 28 /// | 19 /// |
| 29 /// Map elements denoted by parameters and local variables to the | 20 /// Map elements denoted by parameters and local variables to the |
| 30 /// [ir.Primitive] that is their value. Parameters and locals are | 21 /// [ir.Primitive] that is their value. Parameters and locals are |
| 31 /// assigned indexes which can be used to refer to them. | 22 /// assigned indexes which can be used to refer to them. |
| 32 class Environment { | 23 class Environment { |
| 33 /// A map from locals to their environment index. | 24 /// A map from locals to their environment index. |
| 34 final Map<Local, int> variable2index; | 25 final Map<Local, int> variable2index; |
| 35 | 26 |
| (...skipping 1441 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1477 // TODO(johnniwinther): Type [nodes] as `Iterable` when `NodeList` uses | 1468 // TODO(johnniwinther): Type [nodes] as `Iterable` when `NodeList` uses |
| 1478 // `List` instead of `Link`. | 1469 // `List` instead of `Link`. |
| 1479 void buildSequence(var nodes, BuildFunction build) { | 1470 void buildSequence(var nodes, BuildFunction build) { |
| 1480 for (var node in nodes) { | 1471 for (var node in nodes) { |
| 1481 if (!isOpen) return; | 1472 if (!isOpen) return; |
| 1482 build(node); | 1473 build(node); |
| 1483 } | 1474 } |
| 1484 } | 1475 } |
| 1485 | 1476 |
| 1486 | 1477 |
| 1478 /// Creates a labeled statement |
| 1479 void buildLabeledStatement({SubbuildFunction buildBody, |
| 1480 JumpTarget target}) { |
| 1481 JumpCollector jumps = new JumpCollector(target); |
| 1482 state.breakCollectors.add(jumps); |
| 1483 IrBuilder innerBuilder = makeDelimitedBuilder(); |
| 1484 buildBody(innerBuilder); |
| 1485 state.breakCollectors.removeLast(); |
| 1486 bool hasBreaks = !jumps.isEmpty; |
| 1487 ir.Continuation joinContinuation; |
| 1488 if (hasBreaks) { |
| 1489 if (innerBuilder.isOpen) { |
| 1490 jumps.addJump(innerBuilder); |
| 1491 } |
| 1492 |
| 1493 // All jumps to the break continuation must be in the scope of the |
| 1494 // continuation's binding. The continuation is bound just outside the |
| 1495 // body to satisfy this property without extra analysis. |
| 1496 // As a consequence, the break continuation needs parameters for all |
| 1497 // local variables in scope at the exit from the body. |
| 1498 List<ir.Parameter> parameters = |
| 1499 new List<ir.Parameter>.generate(environment.length, (i) { |
| 1500 return new ir.Parameter(environment.index2variable[i]); |
| 1501 }); |
| 1502 joinContinuation = new ir.Continuation(parameters); |
| 1503 invokeFullJoin(joinContinuation, jumps, recursive: false); |
| 1504 add(new ir.LetCont(joinContinuation, innerBuilder._root)); |
| 1505 for (int i = 0; i < environment.length; ++i) { |
| 1506 environment.index2value[i] = parameters[i]; |
| 1507 } |
| 1508 } else { |
| 1509 if (innerBuilder._root != null) { |
| 1510 add(innerBuilder._root); |
| 1511 _current = innerBuilder._current; |
| 1512 environment = innerBuilder.environment; |
| 1513 } |
| 1514 } |
| 1515 return null; |
| 1516 } |
| 1517 |
| 1518 |
| 1487 // Build(BreakStatement L, C) = C[InvokeContinuation(...)] | 1519 // Build(BreakStatement L, C) = C[InvokeContinuation(...)] |
| 1488 // | 1520 // |
| 1489 // The continuation and arguments are filled in later after translating | 1521 // The continuation and arguments are filled in later after translating |
| 1490 // the body containing the break. | 1522 // the body containing the break. |
| 1491 bool buildBreak(JumpTarget target) { | 1523 bool buildBreak(JumpTarget target) { |
| 1492 return buildJumpInternal(target, state.breakCollectors); | 1524 return buildJumpInternal(target, state.breakCollectors); |
| 1493 } | 1525 } |
| 1494 | 1526 |
| 1495 // Build(ContinueStatement L, C) = C[InvokeContinuation(...)] | 1527 // Build(ContinueStatement L, C) = C[InvokeContinuation(...)] |
| 1496 // | 1528 // |
| (...skipping 255 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1752 return join; | 1784 return join; |
| 1753 } | 1785 } |
| 1754 } | 1786 } |
| 1755 | 1787 |
| 1756 /// Shared state between DartIrBuilders within the same method. | 1788 /// Shared state between DartIrBuilders within the same method. |
| 1757 class DartIrBuilderSharedState { | 1789 class DartIrBuilderSharedState { |
| 1758 /// Maps local variables to their corresponding [MutableVariable] object. | 1790 /// Maps local variables to their corresponding [MutableVariable] object. |
| 1759 final Map<Local, ir.MutableVariable> local2mutable = | 1791 final Map<Local, ir.MutableVariable> local2mutable = |
| 1760 <Local, ir.MutableVariable>{}; | 1792 <Local, ir.MutableVariable>{}; |
| 1761 | 1793 |
| 1794 // Move this to the IrBuilderVisitor. |
| 1762 final DartCapturedVariables capturedVariables; | 1795 final DartCapturedVariables capturedVariables; |
| 1763 | 1796 |
| 1764 /// Creates a [MutableVariable] for the given local. | 1797 /// Creates a [MutableVariable] for the given local. |
| 1765 void makeMutableVariable(Local local) { | 1798 void makeMutableVariable(Local local) { |
| 1766 ir.MutableVariable variable = | 1799 ir.MutableVariable variable = |
| 1767 new ir.MutableVariable(local.executableContext, local); | 1800 new ir.MutableVariable(local.executableContext, local); |
| 1768 local2mutable[local] = variable; | 1801 local2mutable[local] = variable; |
| 1769 } | 1802 } |
| 1770 | 1803 |
| 1771 /// [MutableVariable]s that should temporarily be treated as registers. | 1804 /// [MutableVariable]s that should temporarily be treated as registers. |
| (...skipping 250 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2022 if (env.thisLocal != null && env.freeVariables.containsKey(env.thisLocal)) { | 2055 if (env.thisLocal != null && env.freeVariables.containsKey(env.thisLocal)) { |
| 2023 jsState.receiver = environment.lookup(env.thisLocal); | 2056 jsState.receiver = environment.lookup(env.thisLocal); |
| 2024 } | 2057 } |
| 2025 | 2058 |
| 2026 // If the function has a self-reference, use the value of `this`. | 2059 // If the function has a self-reference, use the value of `this`. |
| 2027 if (env.selfReference != null) { | 2060 if (env.selfReference != null) { |
| 2028 environment.extend(env.selfReference, thisPrim); | 2061 environment.extend(env.selfReference, thisPrim); |
| 2029 } | 2062 } |
| 2030 } | 2063 } |
| 2031 | 2064 |
| 2065 /// Creates a box for [scope.box] and binds the captured variables to |
| 2066 /// that box. |
| 2067 /// |
| 2068 /// The captured variables can subsequently be manipulated with |
| 2069 /// [declareLocalVariable], [buildLocalGet], and [buildLocalSet]. |
| 2070 void enterScope(ClosureScope scope) => _enterScope(scope); |
| 2071 |
| 2032 void _enterScope(ClosureScope scope) { | 2072 void _enterScope(ClosureScope scope) { |
| 2033 if (scope == null) return; | 2073 if (scope == null) return; |
| 2034 ir.CreateBox boxPrim = new ir.CreateBox(); | 2074 ir.CreateBox boxPrim = new ir.CreateBox(); |
| 2035 add(new ir.LetPrim(boxPrim)); | 2075 add(new ir.LetPrim(boxPrim)); |
| 2036 environment.extend(scope.box, boxPrim); | 2076 environment.extend(scope.box, boxPrim); |
| 2037 boxPrim.useElementAsHint(scope.box); | 2077 boxPrim.useElementAsHint(scope.box); |
| 2038 scope.capturedVariables.forEach((Local local, ClosureLocation location) { | 2078 scope.capturedVariables.forEach((Local local, ClosureLocation location) { |
| 2039 assert(!jsState.boxedVariables.containsKey(local)); | 2079 assert(!jsState.boxedVariables.containsKey(local)); |
| 2040 if (location.isBox) { | 2080 if (location.isBox) { |
| 2041 jsState.boxedVariables[local] = location; | 2081 jsState.boxedVariables[local] = location; |
| (...skipping 241 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2283 // TODO(johnniwinther): Support passing of [DartType] for the exception. | 2323 // TODO(johnniwinther): Support passing of [DartType] for the exception. |
| 2284 class CatchClauseInfo { | 2324 class CatchClauseInfo { |
| 2285 final LocalVariableElement exceptionVariable; | 2325 final LocalVariableElement exceptionVariable; |
| 2286 final LocalVariableElement stackTraceVariable; | 2326 final LocalVariableElement stackTraceVariable; |
| 2287 final SubbuildFunction buildCatchBlock; | 2327 final SubbuildFunction buildCatchBlock; |
| 2288 | 2328 |
| 2289 CatchClauseInfo({this.exceptionVariable, | 2329 CatchClauseInfo({this.exceptionVariable, |
| 2290 this.stackTraceVariable, | 2330 this.stackTraceVariable, |
| 2291 this.buildCatchBlock}); | 2331 this.buildCatchBlock}); |
| 2292 } | 2332 } |
| OLD | NEW |