| 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 library dart2js.js_emitter.interceptor_stub_generator; | 5 library dart2js.js_emitter.interceptor_stub_generator; |
| 6 | 6 |
| 7 import 'package:js_runtime/shared/embedded_names.dart' as embeddedNames; | 7 import 'package:js_runtime/shared/embedded_names.dart' as embeddedNames; |
| 8 | 8 |
| 9 import '../common_elements.dart'; | 9 import '../common_elements.dart'; |
| 10 import '../constants/values.dart'; | 10 import '../constants/values.dart'; |
| (...skipping 135 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 146 | 146 |
| 147 /// Note: there are two number classes in play: Dart's [num], | 147 /// Note: there are two number classes in play: Dart's [num], |
| 148 /// and JavaScript's Number (typeof receiver == 'number'). This | 148 /// and JavaScript's Number (typeof receiver == 'number'). This |
| 149 /// is the fallback used when we have determined that receiver | 149 /// is the fallback used when we have determined that receiver |
| 150 /// is a JavaScript Number. | 150 /// is a JavaScript Number. |
| 151 jsAst.Expression interceptorForNumber = interceptorFor(hasDouble | 151 jsAst.Expression interceptorForNumber = interceptorFor(hasDouble |
| 152 ? _commonElements.jsDoubleClass | 152 ? _commonElements.jsDoubleClass |
| 153 : _commonElements.jsNumberClass); | 153 : _commonElements.jsNumberClass); |
| 154 | 154 |
| 155 if (hasInt) { | 155 if (hasInt) { |
| 156 whenNumber = js.statement( | 156 whenNumber = js.statement('''{ |
| 157 '''{ | |
| 158 if (Math.floor(receiver) == receiver) return #; | 157 if (Math.floor(receiver) == receiver) return #; |
| 159 return #; | 158 return #; |
| 160 }''', | 159 }''', |
| 161 [interceptorFor(_commonElements.jsIntClass), interceptorForNumber]); | 160 [interceptorFor(_commonElements.jsIntClass), interceptorForNumber]); |
| 162 } else { | 161 } else { |
| 163 whenNumber = js.statement('return #', interceptorForNumber); | 162 whenNumber = js.statement('return #', interceptorForNumber); |
| 164 } | 163 } |
| 165 statements | 164 statements |
| 166 .add(js.statement('if (typeof receiver == "number") #;', whenNumber)); | 165 .add(js.statement('if (typeof receiver == "number") #;', whenNumber)); |
| 167 } | 166 } |
| (...skipping 12 matching lines...) Expand all Loading... |
| 180 if (hasBool) { | 179 if (hasBool) { |
| 181 statements.add(buildInterceptorCheck(_commonElements.jsBoolClass)); | 180 statements.add(buildInterceptorCheck(_commonElements.jsBoolClass)); |
| 182 } | 181 } |
| 183 // TODO(ahe): It might be faster to check for Array before | 182 // TODO(ahe): It might be faster to check for Array before |
| 184 // function and bool. | 183 // function and bool. |
| 185 if (hasArray) { | 184 if (hasArray) { |
| 186 statements.add(buildInterceptorCheck(_commonElements.jsArrayClass)); | 185 statements.add(buildInterceptorCheck(_commonElements.jsArrayClass)); |
| 187 } | 186 } |
| 188 | 187 |
| 189 if (hasNative) { | 188 if (hasNative) { |
| 190 statements.add(js.statement( | 189 statements.add(js.statement(r'''{ |
| 191 r'''{ | |
| 192 if (typeof receiver != "object") { | 190 if (typeof receiver != "object") { |
| 193 if (typeof receiver == "function" ) return #; | 191 if (typeof receiver == "function" ) return #; |
| 194 return receiver; | 192 return receiver; |
| 195 } | 193 } |
| 196 if (receiver instanceof #) return receiver; | 194 if (receiver instanceof #) return receiver; |
| 197 return #(receiver); | 195 return #(receiver); |
| 198 }''', | 196 }''', [ |
| 199 [ | 197 interceptorFor(_commonElements.jsJavaScriptFunctionClass), |
| 200 interceptorFor(_commonElements.jsJavaScriptFunctionClass), | 198 _emitter.constructorAccess(_commonElements.objectClass), |
| 201 _emitter.constructorAccess(_commonElements.objectClass), | 199 _emitter |
| 202 _emitter.staticFunctionAccess( | 200 .staticFunctionAccess(_commonElements.getNativeInterceptorMethod) |
| 203 _commonElements.getNativeInterceptorMethod) | 201 ])); |
| 204 ])); | |
| 205 } else { | 202 } else { |
| 206 ClassEntity jsUnknown = _commonElements.jsUnknownJavaScriptObjectClass; | 203 ClassEntity jsUnknown = _commonElements.jsUnknownJavaScriptObjectClass; |
| 207 if (_codegenWorldBuilder.directlyInstantiatedClasses | 204 if (_codegenWorldBuilder.directlyInstantiatedClasses |
| 208 .contains(jsUnknown)) { | 205 .contains(jsUnknown)) { |
| 209 statements.add(js.statement('if (!(receiver instanceof #)) return #;', [ | 206 statements.add(js.statement('if (!(receiver instanceof #)) return #;', [ |
| 210 _emitter.constructorAccess(_commonElements.objectClass), | 207 _emitter.constructorAccess(_commonElements.objectClass), |
| 211 interceptorFor(jsUnknown) | 208 interceptorFor(jsUnknown) |
| 212 ])); | 209 ])); |
| 213 } | 210 } |
| 214 | 211 |
| (...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 332 } | 329 } |
| 333 | 330 |
| 334 if (containsString) { | 331 if (containsString) { |
| 335 typeCheck = orExp(typeCheck, js('typeof receiver == "string"')); | 332 typeCheck = orExp(typeCheck, js('typeof receiver == "string"')); |
| 336 } | 333 } |
| 337 | 334 |
| 338 if (containsJsIndexable) { | 335 if (containsJsIndexable) { |
| 339 typeCheck = orExp(typeCheck, indexableCheck); | 336 typeCheck = orExp(typeCheck, indexableCheck); |
| 340 } | 337 } |
| 341 | 338 |
| 342 return js.statement( | 339 return js.statement(''' |
| 343 ''' | |
| 344 if (typeof a0 === "number") | 340 if (typeof a0 === "number") |
| 345 if (#) | 341 if (#) |
| 346 if ((a0 >>> 0) === a0 && a0 < receiver.length) | 342 if ((a0 >>> 0) === a0 && a0 < receiver.length) |
| 347 return receiver[a0]; | 343 return receiver[a0]; |
| 348 ''', | 344 ''', typeCheck); |
| 349 typeCheck); | |
| 350 } else { | 345 } else { |
| 351 jsAst.Expression typeCheck; | 346 jsAst.Expression typeCheck; |
| 352 if (containsArray) { | 347 if (containsArray) { |
| 353 typeCheck = arrayCheck; | 348 typeCheck = arrayCheck; |
| 354 } | 349 } |
| 355 | 350 |
| 356 if (containsJsIndexable) { | 351 if (containsJsIndexable) { |
| 357 typeCheck = orExp(typeCheck, indexableCheck); | 352 typeCheck = orExp(typeCheck, indexableCheck); |
| 358 } | 353 } |
| 359 | 354 |
| 360 return js.statement( | 355 return js.statement(r''' |
| 361 r''' | |
| 362 if (typeof a0 === "number") | 356 if (typeof a0 === "number") |
| 363 if (# && !receiver.immutable$list && | 357 if (# && !receiver.immutable$list && |
| 364 (a0 >>> 0) === a0 && a0 < receiver.length) | 358 (a0 >>> 0) === a0 && a0 < receiver.length) |
| 365 return receiver[a0] = a1; | 359 return receiver[a0] = a1; |
| 366 ''', | 360 ''', typeCheck); |
| 367 typeCheck); | |
| 368 } | 361 } |
| 369 } | 362 } |
| 370 return null; | 363 return null; |
| 371 } | 364 } |
| 372 | 365 |
| 373 jsAst.Expression generateOneShotInterceptor(jsAst.Name name) { | 366 jsAst.Expression generateOneShotInterceptor(jsAst.Name name) { |
| 374 Selector selector = | 367 Selector selector = |
| 375 _oneShotInterceptorData.getOneShotInterceptorSelector(name); | 368 _oneShotInterceptorData.getOneShotInterceptorSelector(name); |
| 376 Set<ClassEntity> classes = | 369 Set<ClassEntity> classes = |
| 377 _interceptorData.getInterceptedClassesOn(selector.name, _closedWorld); | 370 _interceptorData.getInterceptedClassesOn(selector.name, _closedWorld); |
| (...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 446 } | 439 } |
| 447 | 440 |
| 448 var map = new jsAst.ObjectInitializer(properties); | 441 var map = new jsAst.ObjectInitializer(properties); |
| 449 elements.add(map); | 442 elements.add(map); |
| 450 } | 443 } |
| 451 } | 444 } |
| 452 | 445 |
| 453 return new jsAst.ArrayInitializer(elements); | 446 return new jsAst.ArrayInitializer(elements); |
| 454 } | 447 } |
| 455 } | 448 } |
| OLD | NEW |