OLD | NEW |
1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2014, 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 import '../js/js.dart' as js; | 5 import '../js/js.dart' as js; |
6 import '../universe/side_effects.dart' show SideEffects; | 6 import '../universe/side_effects.dart' show SideEffects; |
7 | 7 |
8 import 'behavior.dart'; | 8 import 'behavior.dart'; |
9 | 9 |
10 class HasCapturedPlaceholders extends js.BaseVisitor { | 10 class HasCapturedPlaceholders extends js.BaseVisitor { |
11 | |
12 HasCapturedPlaceholders._(); | 11 HasCapturedPlaceholders._(); |
13 | 12 |
14 static bool check(js.Node node) { | 13 static bool check(js.Node node) { |
15 HasCapturedPlaceholders visitor = new HasCapturedPlaceholders._(); | 14 HasCapturedPlaceholders visitor = new HasCapturedPlaceholders._(); |
16 node.accept(visitor); | 15 node.accept(visitor); |
17 return visitor.found; | 16 return visitor.found; |
18 } | 17 } |
19 | 18 |
20 int enclosingFunctions = 0; | 19 int enclosingFunctions = 0; |
21 bool found = false; | 20 bool found = false; |
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
106 } | 105 } |
107 | 106 |
108 void visitAccess(js.PropertyAccess node) { | 107 void visitAccess(js.PropertyAccess node) { |
109 sideEffects.setDependsOnIndexStore(); | 108 sideEffects.setDependsOnIndexStore(); |
110 sideEffects.setDependsOnInstancePropertyStore(); | 109 sideEffects.setDependsOnInstancePropertyStore(); |
111 sideEffects.setDependsOnStaticPropertyStore(); | 110 sideEffects.setDependsOnStaticPropertyStore(); |
112 node.visitChildren(this); | 111 node.visitChildren(this); |
113 } | 112 } |
114 } | 113 } |
115 | 114 |
116 | |
117 /// ThrowBehaviorVisitor generates a NativeThrowBehavior describing the | 115 /// ThrowBehaviorVisitor generates a NativeThrowBehavior describing the |
118 /// exception behavior of a JavaScript expression. | 116 /// exception behavior of a JavaScript expression. |
119 /// | 117 /// |
120 /// The result is semi-conservative, giving reasonable results for many simple | 118 /// The result is semi-conservative, giving reasonable results for many simple |
121 /// JS fragments. The non-conservative part is the assumption that binary | 119 /// JS fragments. The non-conservative part is the assumption that binary |
122 /// operators are used on 'good' operands that do not force arbirary code to be | 120 /// operators are used on 'good' operands that do not force arbirary code to be |
123 /// executed via conversions (valueOf() and toString() methods). | 121 /// executed via conversions (valueOf() and toString() methods). |
124 /// | 122 /// |
125 /// In many cases a JS fragment has more precise behavior. In these cases the | 123 /// In many cases a JS fragment has more precise behavior. In these cases the |
126 /// behavior should be described as a property of the JS fragment. For example, | 124 /// behavior should be described as a property of the JS fragment. For example, |
127 /// Object.keys(#) has a TypeError on null / undefined, which can only be known | 125 /// Object.keys(#) has a TypeError on null / undefined, which can only be known |
128 /// in the calling context. | 126 /// in the calling context. |
129 /// | 127 /// |
130 class ThrowBehaviorVisitor extends js.BaseVisitor<NativeThrowBehavior> { | 128 class ThrowBehaviorVisitor extends js.BaseVisitor<NativeThrowBehavior> { |
131 | |
132 ThrowBehaviorVisitor(); | 129 ThrowBehaviorVisitor(); |
133 | 130 |
134 NativeThrowBehavior analyze(js.Node node) { | 131 NativeThrowBehavior analyze(js.Node node) { |
135 return visit(node); | 132 return visit(node); |
136 } | 133 } |
137 | 134 |
138 // TODO(sra): Add [sequence] functionality to NativeThrowBehavior. | 135 // TODO(sra): Add [sequence] functionality to NativeThrowBehavior. |
139 /// Returns the combined behavior of sequential execution of code having | 136 /// Returns the combined behavior of sequential execution of code having |
140 /// behavior [first] followed by code having behavior [second]. | 137 /// behavior [first] followed by code having behavior [second]. |
141 static NativeThrowBehavior sequence(NativeThrowBehavior first, | 138 static NativeThrowBehavior sequence( |
142 NativeThrowBehavior second) { | 139 NativeThrowBehavior first, NativeThrowBehavior second) { |
143 if (first == NativeThrowBehavior.MUST) return first; | 140 if (first == NativeThrowBehavior.MUST) return first; |
144 if (second == NativeThrowBehavior.MUST) return second; | 141 if (second == NativeThrowBehavior.MUST) return second; |
145 if (second == NativeThrowBehavior.NEVER) return first; | 142 if (second == NativeThrowBehavior.NEVER) return first; |
146 if (first == NativeThrowBehavior.NEVER) return second; | 143 if (first == NativeThrowBehavior.NEVER) return second; |
147 // Both are one of MAY or MAY_THROW_ONLY_ON_FIRST_ARGUMENT_ACCESS. | 144 // Both are one of MAY or MAY_THROW_ONLY_ON_FIRST_ARGUMENT_ACCESS. |
148 return NativeThrowBehavior.MAY; | 145 return NativeThrowBehavior.MAY; |
149 } | 146 } |
150 | 147 |
151 // TODO(sra): Add [choice] functionality to NativeThrowBehavior. | 148 // TODO(sra): Add [choice] functionality to NativeThrowBehavior. |
152 /// Returns the combined behavior of a choice between two paths with behaviors | 149 /// Returns the combined behavior of a choice between two paths with behaviors |
153 /// [first] and [second]. | 150 /// [first] and [second]. |
154 static NativeThrowBehavior choice(NativeThrowBehavior first, | 151 static NativeThrowBehavior choice( |
155 NativeThrowBehavior second) { | 152 NativeThrowBehavior first, NativeThrowBehavior second) { |
156 if (first == second) return first; // Both paths have same behaviour. | 153 if (first == second) return first; // Both paths have same behaviour. |
157 return NativeThrowBehavior.MAY; | 154 return NativeThrowBehavior.MAY; |
158 } | 155 } |
159 | 156 |
160 NativeThrowBehavior visit(js.Node node) { | 157 NativeThrowBehavior visit(js.Node node) { |
161 return node.accept(this); | 158 return node.accept(this); |
162 } | 159 } |
163 | 160 |
164 NativeThrowBehavior visitNode(js.Node node) { | 161 NativeThrowBehavior visitNode(js.Node node) { |
165 return NativeThrowBehavior.MAY; | 162 return NativeThrowBehavior.MAY; |
166 } | 163 } |
(...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
291 receiver.isPositional && | 288 receiver.isPositional && |
292 receiver.nameOrPosition == 0) { | 289 receiver.nameOrPosition == 0) { |
293 first = NativeThrowBehavior.MAY_THROW_ONLY_ON_FIRST_ARGUMENT_ACCESS; | 290 first = NativeThrowBehavior.MAY_THROW_ONLY_ON_FIRST_ARGUMENT_ACCESS; |
294 } else { | 291 } else { |
295 first = NativeThrowBehavior.MAY; | 292 first = NativeThrowBehavior.MAY; |
296 } | 293 } |
297 | 294 |
298 return sequence(first, second); | 295 return sequence(first, second); |
299 } | 296 } |
300 } | 297 } |
OLD | NEW |