Chromium Code Reviews| 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'; |
| (...skipping 931 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 942 // the entry to the body, the loop exit, and the loop successor (break). | 942 // the entry to the body, the loop exit, and the loop successor (break). |
| 943 // The CPS translation of | 943 // The CPS translation of |
| 944 // [[for (initializer; condition; update) body; successor]] is: | 944 // [[for (initializer; condition; update) body; successor]] is: |
| 945 // | 945 // |
| 946 // [[initializer]]; | 946 // [[initializer]]; |
| 947 // let cont loop(x, ...) = | 947 // let cont loop(x, ...) = |
| 948 // let prim cond = [[condition]] in | 948 // let prim cond = [[condition]] in |
| 949 // let cont break() = [[successor]] in | 949 // let cont break() = [[successor]] in |
| 950 // let cont exit() = break(v, ...) in | 950 // let cont exit() = break(v, ...) in |
| 951 // let cont body() = | 951 // let cont body() = |
| 952 // [[enterBody]]; | |
|
Kevin Millikin (Google)
2015/03/04 10:51:05
Maybe we should spell this _enterForLoopBody (to m
asgerf
2015/03/04 13:34:08
Done.
Kevin Millikin (Google)
2015/03/04 13:36:12
Excellent.
| |
| 952 // let cont continue(x, ...) = [[update]]; loop(v, ...) in | 953 // let cont continue(x, ...) = [[update]]; loop(v, ...) in |
| 953 // [[body]]; continue(v, ...) in | 954 // [[body]]; continue(v, ...) in |
| 954 // branch cond (body, exit) in | 955 // branch cond (body, exit) in |
| 955 // loop(v, ...) | 956 // loop(v, ...) |
| 956 // | 957 // |
| 957 // If there are no breaks in the body, the break continuation is inlined | 958 // If there are no breaks in the body, the break continuation is inlined |
| 958 // in the exit continuation (i.e., the translation of the successor | 959 // in the exit continuation (i.e., the translation of the successor |
| 959 // statement occurs in the exit continuation). If there is only one | 960 // statement occurs in the exit continuation). If there is only one |
| 960 // invocation of the continue continuation (i.e., no continues in the | 961 // invocation of the continue continuation (i.e., no continues in the |
| 961 // body), the continue continuation is inlined in the body. | 962 // body), the continue continuation is inlined in the body. |
| 962 | 963 |
| 963 _enterForLoopInitializer(closureScope, loopVariables); | 964 _enterForLoopInitializer(closureScope, loopVariables); |
| 964 | 965 |
| 965 buildInitializer(this); | 966 buildInitializer(this); |
| 966 | 967 |
| 967 IrBuilder condBuilder = makeRecursiveBuilder(); | 968 IrBuilder condBuilder = makeRecursiveBuilder(); |
| 968 ir.Primitive condition = buildCondition(condBuilder); | 969 ir.Primitive condition = buildCondition(condBuilder); |
| 969 if (condition == null) { | 970 if (condition == null) { |
| 970 // If the condition is empty then the body is entered unconditionally. | 971 // If the condition is empty then the body is entered unconditionally. |
| 971 condition = condBuilder.buildBooleanLiteral(true); | 972 condition = condBuilder.buildBooleanLiteral(true); |
| 972 } | 973 } |
| 973 | 974 |
| 974 JumpCollector breakCollector = new JumpCollector(target); | 975 JumpCollector breakCollector = new JumpCollector(target); |
| 975 JumpCollector continueCollector = new JumpCollector(target); | 976 JumpCollector continueCollector = new JumpCollector(target); |
| 976 state.breakCollectors.add(breakCollector); | 977 state.breakCollectors.add(breakCollector); |
| 977 state.continueCollectors.add(continueCollector); | 978 state.continueCollectors.add(continueCollector); |
| 978 | 979 |
| 979 IrBuilder bodyBuilder = condBuilder.makeDelimitedBuilder(); | 980 IrBuilder outerBodyBuilder = condBuilder.makeDelimitedBuilder(); |
|
Kevin Millikin (Google)
2015/03/04 10:51:05
I wish we weren't out of good names to use in this
| |
| 981 outerBodyBuilder._enterForLoopBody(closureScope, loopVariables); | |
| 980 | 982 |
| 981 bodyBuilder._enterForLoopBody(closureScope, loopVariables); | 983 IrBuilder innerBodyBuilder = outerBodyBuilder.makeDelimitedBuilder(); |
| 982 | 984 |
| 983 buildBody(bodyBuilder); | 985 buildBody(innerBodyBuilder); |
| 984 assert(state.breakCollectors.last == breakCollector); | 986 assert(state.breakCollectors.last == breakCollector); |
| 985 assert(state.continueCollectors.last == continueCollector); | 987 assert(state.continueCollectors.last == continueCollector); |
| 986 state.breakCollectors.removeLast(); | 988 state.breakCollectors.removeLast(); |
| 987 state.continueCollectors.removeLast(); | 989 state.continueCollectors.removeLast(); |
| 988 | 990 |
| 989 // The binding of the continue continuation should occur as late as | 991 // The binding of the continue continuation should occur as late as |
| 990 // possible, that is, at the nearest common ancestor of all the continue | 992 // possible, that is, at the nearest common ancestor of all the continue |
| 991 // sites in the body. However, that is difficult to compute here, so it | 993 // sites in the body. However, that is difficult to compute here, so it |
| 992 // is instead placed just outside the body of the body continuation. | 994 // is instead placed just outside the body of the body continuation. |
| 993 bool hasContinues = !continueCollector.isEmpty; | 995 bool hasContinues = !continueCollector.isEmpty; |
| 994 IrBuilder updateBuilder = hasContinues | 996 IrBuilder updateBuilder = hasContinues |
| 995 ? condBuilder.makeRecursiveBuilder() | 997 ? outerBodyBuilder.makeRecursiveBuilder() |
| 996 : bodyBuilder; | 998 : innerBodyBuilder; |
| 997 updateBuilder._enterForLoopUpdate(closureScope, loopVariables); | 999 updateBuilder._enterForLoopUpdate(closureScope, loopVariables); |
| 998 buildUpdate(updateBuilder); | 1000 buildUpdate(updateBuilder); |
| 999 | 1001 |
| 1000 // Create body entry and loop exit continuations and a branch to them. | 1002 // Create body entry and loop exit continuations and a branch to them. |
| 1001 ir.Continuation bodyContinuation = new ir.Continuation([]); | 1003 ir.Continuation bodyContinuation = new ir.Continuation([]); |
| 1002 ir.Continuation exitContinuation = new ir.Continuation([]); | 1004 ir.Continuation exitContinuation = new ir.Continuation([]); |
| 1003 // Note the order of continuations: the first one is the one that will | 1005 // Note the order of continuations: the first one is the one that will |
| 1004 // be filled by LetCont.plug. | 1006 // be filled by LetCont.plug. |
| 1005 ir.LetCont branch = | 1007 ir.LetCont branch = |
| 1006 new ir.LetCont.many(<ir.Continuation>[exitContinuation, | 1008 new ir.LetCont.many(<ir.Continuation>[exitContinuation, |
| (...skipping 10 matching lines...) Expand all Loading... | |
| 1017 condBuilder.add(letJoin); | 1019 condBuilder.add(letJoin); |
| 1018 condBuilder._current = branch; | 1020 condBuilder._current = branch; |
| 1019 } else { | 1021 } else { |
| 1020 condBuilder.add(branch); | 1022 condBuilder.add(branch); |
| 1021 } | 1023 } |
| 1022 ir.Continuation continueContinuation; | 1024 ir.Continuation continueContinuation; |
| 1023 if (hasContinues) { | 1025 if (hasContinues) { |
| 1024 // If there are continues in the body, we need a named continue | 1026 // If there are continues in the body, we need a named continue |
| 1025 // continuation as a join point. | 1027 // continuation as a join point. |
| 1026 continueContinuation = new ir.Continuation(updateBuilder._parameters); | 1028 continueContinuation = new ir.Continuation(updateBuilder._parameters); |
| 1027 if (bodyBuilder.isOpen) continueCollector.addJump(bodyBuilder); | 1029 if (innerBodyBuilder.isOpen) continueCollector.addJump(innerBodyBuilder); |
| 1028 invokeFullJoin(continueContinuation, continueCollector); | 1030 invokeFullJoin(continueContinuation, continueCollector); |
| 1029 } | 1031 } |
| 1030 ir.Continuation loopContinuation = | 1032 ir.Continuation loopContinuation = |
| 1031 new ir.Continuation(condBuilder._parameters); | 1033 new ir.Continuation(condBuilder._parameters); |
| 1032 if (updateBuilder.isOpen) { | 1034 if (updateBuilder.isOpen) { |
| 1033 JumpCollector backEdges = new JumpCollector(null); | 1035 JumpCollector backEdges = new JumpCollector(null); |
| 1034 backEdges.addJump(updateBuilder); | 1036 backEdges.addJump(updateBuilder); |
| 1035 invokeFullJoin(loopContinuation, backEdges, recursive: true); | 1037 invokeFullJoin(loopContinuation, backEdges, recursive: true); |
| 1036 } | 1038 } |
| 1037 | 1039 |
| 1038 // Fill in the body and possible continue continuation bodies. Do this | 1040 // Fill in the body and possible continue continuation bodies. Do this |
| 1039 // only after it is guaranteed that they are not empty. | 1041 // only after it is guaranteed that they are not empty. |
| 1040 if (hasContinues) { | 1042 if (hasContinues) { |
| 1041 continueContinuation.body = updateBuilder._root; | 1043 continueContinuation.body = updateBuilder._root; |
| 1042 bodyContinuation.body = | 1044 outerBodyBuilder.add(new ir.LetCont(continueContinuation, |
| 1043 new ir.LetCont(continueContinuation, | 1045 innerBodyBuilder._root)); |
| 1044 bodyBuilder._root); | |
| 1045 } else { | 1046 } else { |
| 1046 bodyContinuation.body = bodyBuilder._root; | 1047 outerBodyBuilder.add(innerBodyBuilder._root); |
| 1047 } | 1048 } |
| 1049 bodyContinuation.body = outerBodyBuilder._root; | |
| 1048 | 1050 |
| 1049 loopContinuation.body = condBuilder._root; | 1051 loopContinuation.body = condBuilder._root; |
| 1050 add(new ir.LetCont(loopContinuation, | 1052 add(new ir.LetCont(loopContinuation, |
| 1051 new ir.InvokeContinuation(loopContinuation, | 1053 new ir.InvokeContinuation(loopContinuation, |
| 1052 environment.index2value))); | 1054 environment.index2value))); |
| 1053 if (hasBreaks) { | 1055 if (hasBreaks) { |
| 1054 _current = branch; | 1056 _current = branch; |
| 1055 environment = condBuilder.environment; | 1057 environment = condBuilder.environment; |
| 1056 breakCollector.addJump(this); | 1058 breakCollector.addJump(this); |
| 1057 letJoin.continuations = | 1059 letJoin.continuations = |
| (...skipping 1053 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2111 final Map<Local, ClosureLocation> freeVariables; | 2113 final Map<Local, ClosureLocation> freeVariables; |
| 2112 | 2114 |
| 2113 ClosureEnvironment(this.selfReference, this.thisLocal, this.freeVariables); | 2115 ClosureEnvironment(this.selfReference, this.thisLocal, this.freeVariables); |
| 2114 } | 2116 } |
| 2115 | 2117 |
| 2116 class TryStatementInfo { | 2118 class TryStatementInfo { |
| 2117 final Set<LocalVariableElement> declared = new Set<LocalVariableElement>(); | 2119 final Set<LocalVariableElement> declared = new Set<LocalVariableElement>(); |
| 2118 final Set<LocalVariableElement> boxedOnEntry = | 2120 final Set<LocalVariableElement> boxedOnEntry = |
| 2119 new Set<LocalVariableElement>(); | 2121 new Set<LocalVariableElement>(); |
| 2120 } | 2122 } |
| OLD | NEW |