Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(118)

Side by Side Diff: pkg/compiler/lib/src/native/js.dart

Issue 1074043003: Compute default throws behavior from JavaScript. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 5 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « pkg/compiler/lib/src/native/behavior.dart ('k') | pkg/compiler/lib/src/ssa/builder.dart » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 part of native; 5 part of native;
6 6
7 class SideEffectsVisitor extends js.BaseVisitor { 7 class SideEffectsVisitor extends js.BaseVisitor {
8 final SideEffects sideEffects; 8 final SideEffects sideEffects;
9 SideEffectsVisitor(this.sideEffects); 9 SideEffectsVisitor(this.sideEffects);
10 10
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
74 node.visitChildren(this); 74 node.visitChildren(this);
75 } 75 }
76 76
77 void visitAccess(js.PropertyAccess node) { 77 void visitAccess(js.PropertyAccess node) {
78 sideEffects.setDependsOnIndexStore(); 78 sideEffects.setDependsOnIndexStore();
79 sideEffects.setDependsOnInstancePropertyStore(); 79 sideEffects.setDependsOnInstancePropertyStore();
80 sideEffects.setDependsOnStaticPropertyStore(); 80 sideEffects.setDependsOnStaticPropertyStore();
81 node.visitChildren(this); 81 node.visitChildren(this);
82 } 82 }
83 } 83 }
84
85
86 /// ThrowBehaviorVisitor generates a NativeThrowBehavior describing the
87 /// exception behavior of a JavaScript expression.
88 ///
89 /// The result is semi-conservative, giving reasonable results for many simple
90 /// JS fragments. The non-conservative part is the assumption that binary
91 /// operators are used on 'good' operands thatdo not force arbirary code to be
floitsch 2015/04/10 13:34:16 that do
sra1 2015/04/10 15:57:48 Done.
92 /// executed via conversions (valueOf() and toString() methods).
93 ///
94 /// In many cases a JS fragment has more precise behavior. In these cases the
95 /// behavior should be described as a property of the JS fragment.
96 ///
97 class ThrowBehaviorVisitor extends js.BaseVisitor<NativeThrowBehavior> {
98
99 ThrowBehaviorVisitor();
100
101 NativeThrowBehavior analyze(js.Node node) {
102 return visit(node);
103 }
104
105 // TODO(sra): Add [sequence] functionality to NativeThrowBehavior.
106 static NativeThrowBehavior sequence(NativeThrowBehavior first,
floitsch 2015/04/10 13:34:16 Add comment explaining what this is. (probably my
sra1 2015/04/10 15:57:48 Done.
107 NativeThrowBehavior second) {
108 if (first == NativeThrowBehavior.MUST) return first;
109 if (second == NativeThrowBehavior.MUST) return second;
110 if (second == NativeThrowBehavior.NEVER) return first;
111 if (first == NativeThrowBehavior.NEVER) return second;
112 // Both are one of MAY or MAY_THROW_ONLY_ON_FIRST_ARGUMENT_ACCESS.
113 return NativeThrowBehavior.MAY;
114 }
115
116 // TODO(sra): Add [choice] functionality to NativeThrowBehavior.
117 static NativeThrowBehavior choice(NativeThrowBehavior first,
118 NativeThrowBehavior second) {
119 if (first == second) return first; // Both paths have same behaviour.
120 return NativeThrowBehavior.MAY;
121 }
122
123 NativeThrowBehavior visit(js.Node node) {
124 return node.accept(this);
125 }
126
127 NativeThrowBehavior visitNode(js.Node node) {
128 return NativeThrowBehavior.MAY;
129 }
130
131 NativeThrowBehavior visitLiteral(js.Literal node) {
132 return NativeThrowBehavior.NEVER;
133 }
134
135 NativeThrowBehavior visitInterpolatedExpression(js.InterpolatedNode node) {
136 return NativeThrowBehavior.NEVER;
137 }
138
139 NativeThrowBehavior visitInterpolatedSelector(js.InterpolatedNode node) {
140 return NativeThrowBehavior.NEVER;
141 }
142
143 NativeThrowBehavior visitObjectInitializer(js.ObjectInitializer node) {
144 NativeThrowBehavior result = NativeThrowBehavior.NEVER;
145 for (js.Property property in node.properties) {
146 result = sequence(result, visit(property));
147 }
148 return result;
149 }
150
151 NativeThrowBehavior visitProperty(js.Property node) {
152 return sequence(visit(node.name), visit(node.value));
153 }
154
155 NativeThrowBehavior visitAssignment(js.Assignment node) {
156 // TODO(sra): Can we make "#.p = #" be null(1)?
157 return NativeThrowBehavior.MAY;
158 }
159
160 NativeThrowBehavior visitCall(js.Call node) {
161 return NativeThrowBehavior.MAY;
162 }
163
164 NativeThrowBehavior visitNew(js.New node) {
165 // TODO(sra): `new Array(x)` where `x` is is a small number.
floitsch 2015/04/10 13:34:16 -is-
sra1 2015/04/10 15:57:48 Done.
166 return NativeThrowBehavior.MAY;
167 }
168
169 NativeThrowBehavior visitBinary(js.Binary node) {
170 NativeThrowBehavior left = visit(node.left);
171 NativeThrowBehavior right = visit(node.right);
172 switch (node.op) {
173 // We make the non-conservative assumption that these operations are not
174 // used in ways that force calling arbitrary code via valueOf or
175 // toString().
176 case "*":
177 case "/":
178 case "%":
179 case "+":
180 case "-":
181 case "<<":
182 case ">>":
183 case ">>>":
184 case "<":
185 case ">":
186 case "<=":
187 case ">=":
188 case "==":
189 case "===":
190 case "!=":
191 case "!==":
192 case "&":
193 case "^":
194 case "|":
195 return sequence(left, right);
196
197 case ',':
198 return sequence(left, right);
199
200 case "&&":
201 case "||":
202 return choice(left, sequence(left, right));
203
204 case "instanceof":
205 case "in":
206 default:
207 return NativeThrowBehavior.MAY;
208 }
209 }
210
211 NativeThrowBehavior visitThrow(js.Throw node) {
212 return NativeThrowBehavior.MUST;
213 }
214
215 NativeThrowBehavior visitPrefix(js.Prefix node) {
216 NativeThrowBehavior result = visit(node.argument);
217 switch (node.op) {
218 case '!':
219 case '~':
220 case 'void':
221 case 'typeof':
222 return result;
223 default:
224 return NativeThrowBehavior.MAY;
225 }
226 }
227
228 NativeThrowBehavior visitVariableUse(js.VariableUse node) {
229 // We could get a ReferenceError unless the variable is in scope. The AST
230 // could distinguish in-scope and out-of scope references. For JS
231 // fragments, the only use of VariableUse should be for gloabl references.
floitsch 2015/04/10 13:34:16 global
sra1 2015/04/10 15:57:48 Done.
232 // Certain global names are almost certainly not reference errors, e.g
233 // 'Array'.
234 switch (node.name) {
235 case 'Array':
floitsch 2015/04/10 13:34:16 add case 'Object':
sra1 2015/04/10 15:57:49 Done, but it is not really useful, since most uses
236 return NativeThrowBehavior.NEVER;
237 default:
238 return NativeThrowBehavior.MAY;
239 }
240 }
241
242 NativeThrowBehavior visitAccess(js.PropertyAccess node) {
243 // TODO(sra): We need a representation where the nsm guard behaviour is
244 // maintained when combined with other throwing behaviour.
245 js.Node receiver = node.receiver;
246 NativeThrowBehavior first = visit(receiver);
247 NativeThrowBehavior second = visit(node.selector);
248
249 if (receiver is js.InterpolatedExpression &&
250 receiver.isPositional &&
251 receiver.nameOrPosition == 0) {
252 first = NativeThrowBehavior.MAY_THROW_ONLY_ON_FIRST_ARGUMENT_ACCESS;
253 } else {
254 first = NativeThrowBehavior.MAY;
255 }
256
257 return sequence(first, second);
258 }
259 }
OLDNEW
« no previous file with comments | « pkg/compiler/lib/src/native/behavior.dart ('k') | pkg/compiler/lib/src/ssa/builder.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698