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 part of dart2js.js_emitter; | 5 part of dart2js.js_emitter; |
6 | 6 |
7 class InterceptorStubGenerator { | 7 class InterceptorStubGenerator { |
8 final Compiler compiler; | 8 final Compiler compiler; |
9 final Namer namer; | 9 final Namer namer; |
10 final JavaScriptBackend backend; | 10 final JavaScriptBackend backend; |
(...skipping 199 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
210 } else { | 210 } else { |
211 assert(name == '~'); | 211 assert(name == '~'); |
212 return js.statement(''' | 212 return js.statement(''' |
213 if (typeof receiver == "number" && Math.floor(receiver) == receiver) | 213 if (typeof receiver == "number" && Math.floor(receiver) == receiver) |
214 return (~receiver) >>> 0; | 214 return (~receiver) >>> 0; |
215 '''); | 215 '''); |
216 } | 216 } |
217 } else if (selector.isIndex || selector.isIndexSet) { | 217 } else if (selector.isIndex || selector.isIndexSet) { |
218 // For an index operation, this code generates: | 218 // For an index operation, this code generates: |
219 // | 219 // |
220 // if (receiver.constructor == Array || typeof receiver == "string") { | 220 // if (typeof a0 === "number") { |
221 // if (a0 >>> 0 === a0 && a0 < receiver.length) { | 221 // if (receiver.constructor == Array || |
222 // return receiver[a0]; | 222 // typeof receiver == "string") { |
| 223 // if (a0 >>> 0 === a0 && a0 < receiver.length) { |
| 224 // return receiver[a0]; |
| 225 // } |
223 // } | 226 // } |
224 // } | 227 // } |
225 // | 228 // |
226 // For an index set operation, this code generates: | 229 // For an index set operation, this code generates: |
227 // | 230 // |
228 // if (receiver.constructor == Array && !receiver.immutable$list) { | 231 // if (typeof a0 === "number") { |
229 // if (a0 >>> 0 === a0 && a0 < receiver.length) { | 232 // if (receiver.constructor == Array && !receiver.immutable$list) { |
230 // return receiver[a0] = a1; | 233 // if (a0 >>> 0 === a0 && a0 < receiver.length) { |
| 234 // return receiver[a0] = a1; |
| 235 // } |
231 // } | 236 // } |
232 // } | 237 // } |
233 bool containsArray = classes.contains(helpers.jsArrayClass); | 238 bool containsArray = classes.contains(helpers.jsArrayClass); |
234 bool containsString = classes.contains(helpers.jsStringClass); | 239 bool containsString = classes.contains(helpers.jsStringClass); |
235 bool containsJsIndexable = | 240 bool containsJsIndexable = |
236 helpers.jsIndexingBehaviorInterface.isResolved && classes.any((cls) { | 241 helpers.jsIndexingBehaviorInterface.isResolved && classes.any((cls) { |
237 return compiler.world.isSubtypeOf(cls, | 242 return compiler.world.isSubtypeOf(cls, |
238 helpers.jsIndexingBehaviorInterface); | 243 helpers.jsIndexingBehaviorInterface); |
239 }); | 244 }); |
240 // The index set operator requires a check on its set value in | 245 // The index set operator requires a check on its set value in |
(...skipping 22 matching lines...) Expand all Loading... |
263 | 268 |
264 if (containsString) { | 269 if (containsString) { |
265 typeCheck = orExp(typeCheck, js('typeof receiver == "string"')); | 270 typeCheck = orExp(typeCheck, js('typeof receiver == "string"')); |
266 } | 271 } |
267 | 272 |
268 if (containsJsIndexable) { | 273 if (containsJsIndexable) { |
269 typeCheck = orExp(typeCheck, indexableCheck); | 274 typeCheck = orExp(typeCheck, indexableCheck); |
270 } | 275 } |
271 | 276 |
272 return js.statement(''' | 277 return js.statement(''' |
273 if (#) | 278 if (typeof a0 === "number") |
274 if ((a0 >>> 0) === a0 && a0 < receiver.length) | 279 if (#) |
275 return receiver[a0]; | 280 if ((a0 >>> 0) === a0 && a0 < receiver.length) |
| 281 return receiver[a0]; |
276 ''', typeCheck); | 282 ''', typeCheck); |
277 } else { | 283 } else { |
278 jsAst.Expression typeCheck; | 284 jsAst.Expression typeCheck; |
279 if (containsArray) { | 285 if (containsArray) { |
280 typeCheck = arrayCheck; | 286 typeCheck = arrayCheck; |
281 } | 287 } |
282 | 288 |
283 if (containsJsIndexable) { | 289 if (containsJsIndexable) { |
284 typeCheck = orExp(typeCheck, indexableCheck); | 290 typeCheck = orExp(typeCheck, indexableCheck); |
285 } | 291 } |
286 | 292 |
287 return js.statement(r''' | 293 return js.statement(r''' |
288 if (# && !receiver.immutable$list && | 294 if (typeof a0 === "number") |
289 (a0 >>> 0) === a0 && a0 < receiver.length) | 295 if (# && !receiver.immutable$list && |
290 return receiver[a0] = a1; | 296 (a0 >>> 0) === a0 && a0 < receiver.length) |
| 297 return receiver[a0] = a1; |
291 ''', typeCheck); | 298 ''', typeCheck); |
292 } | 299 } |
293 } | 300 } |
294 return null; | 301 return null; |
295 } | 302 } |
296 | 303 |
297 jsAst.Expression generateOneShotInterceptor(jsAst.Name name) { | 304 jsAst.Expression generateOneShotInterceptor(jsAst.Name name) { |
298 Selector selector = backend.oneShotInterceptors[name]; | 305 Selector selector = backend.oneShotInterceptors[name]; |
299 Set<ClassElement> classes = | 306 Set<ClassElement> classes = |
300 backend.getInterceptedClassesOn(selector.name); | 307 backend.getInterceptedClassesOn(selector.name); |
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
370 | 377 |
371 var map = new jsAst.ObjectInitializer(properties); | 378 var map = new jsAst.ObjectInitializer(properties); |
372 elements.add(map); | 379 elements.add(map); |
373 } | 380 } |
374 } | 381 } |
375 } | 382 } |
376 | 383 |
377 return new jsAst.ArrayInitializer(elements); | 384 return new jsAst.ArrayInitializer(elements); |
378 } | 385 } |
379 } | 386 } |
OLD | NEW |