OLD | NEW |
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, 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 _js_helper; | 5 part of _js_helper; |
6 | 6 |
7 String typeNameInChrome(obj) { | 7 String typeNameInChrome(obj) { |
8 String name = JS('String', "#.constructor.name", obj); | 8 String name = JS('String', "#.constructor.name", obj); |
9 return typeNameInWebKitCommon(name); | 9 return typeNameInWebKitCommon(name); |
10 } | 10 } |
(...skipping 267 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
278 if (interceptorClass == null) { | 278 if (interceptorClass == null) { |
279 // This object is not known to Dart. There could be several | 279 // This object is not known to Dart. There could be several |
280 // reasons for that, including (but not limited to): | 280 // reasons for that, including (but not limited to): |
281 // * A bug in native code (hopefully this is caught during development). | 281 // * A bug in native code (hopefully this is caught during development). |
282 // * An unknown DOM object encountered. | 282 // * An unknown DOM object encountered. |
283 // * JavaScript code running in an unexpected context. For | 283 // * JavaScript code running in an unexpected context. For |
284 // example, on node.js. | 284 // example, on node.js. |
285 return null; | 285 return null; |
286 } | 286 } |
287 var interceptor = JS('', '#.prototype', interceptorClass); | 287 var interceptor = JS('', '#.prototype', interceptorClass); |
288 var isLeaf = | 288 var isLeaf = JS('bool', '(#[#]) === true', leafTags, tag); |
289 (leafTags != null) && JS('bool', '(#[#]) === true', leafTags, tag); | |
290 if (isLeaf) { | 289 if (isLeaf) { |
291 return makeLeafDispatchRecord(interceptor); | 290 return makeLeafDispatchRecord(interceptor); |
292 } else { | 291 } else { |
293 var proto = JS('', 'Object.getPrototypeOf(#)', obj); | 292 var proto = JS('', 'Object.getPrototypeOf(#)', obj); |
294 return makeDispatchRecord(interceptor, proto, null, null); | 293 return makeDispatchRecord(interceptor, proto, null, null); |
295 } | 294 } |
296 } | 295 } |
297 | 296 |
298 makeLeafDispatchRecord(interceptor) { | 297 makeLeafDispatchRecord(interceptor) { |
299 var fieldName = JS_IS_INDEXABLE_FIELD_NAME(); | 298 var fieldName = JS_IS_INDEXABLE_FIELD_NAME(); |
300 bool indexability = JS('bool', r'!!#[#]', interceptor, fieldName); | 299 bool indexability = JS('bool', r'!!#[#]', interceptor, fieldName); |
301 return makeDispatchRecord(interceptor, false, null, indexability); | 300 return makeDispatchRecord(interceptor, false, null, indexability); |
302 } | 301 } |
303 | 302 |
| 303 makeDefaultDispatchRecord(tag, interceptorClass, proto) { |
| 304 var interceptor = JS('', '#.prototype', interceptorClass); |
| 305 var isLeaf = JS('bool', '(#[#]) === true', leafTags, tag); |
| 306 if (isLeaf) { |
| 307 return makeLeafDispatchRecord(interceptor); |
| 308 } else { |
| 309 return makeDispatchRecord(interceptor, proto, null, null); |
| 310 } |
| 311 } |
| 312 |
| 313 var initNativeDispatchFlag; // null or true |
| 314 |
| 315 void initNativeDispatch() { |
| 316 initNativeDispatchFlag = true; |
| 317 |
| 318 // Try to pro-actively patch prototypes of DOM objects. For each of our known |
| 319 // tags `TAG`, if `window.TAG` is a (constructor) function, set the dispatch |
| 320 // property if the function's prototype to a dispatch record. |
| 321 if (JS('bool', 'typeof window != "undefined"')) { |
| 322 var context = JS('=Object', 'window'); |
| 323 var map = interceptorsByTag; |
| 324 var tags = JS('JSMutableArray', 'Object.getOwnPropertyNames(#)', map); |
| 325 for (int i = 0; i < tags.length; i++) { |
| 326 var tag = tags[i]; |
| 327 if (JS('bool', 'typeof (#[#]) == "function"', context, tag)) { |
| 328 var constructor = JS('', '#[#]', context, tag); |
| 329 var proto = JS('', '#.prototype', constructor); |
| 330 var interceptorClass = JS('', '#[#]', map, tag); |
| 331 var record = makeDefaultDispatchRecord(tag, interceptorClass, proto); |
| 332 if (record != null) { |
| 333 setDispatchProperty(proto, record); |
| 334 } |
| 335 } |
| 336 } |
| 337 } |
| 338 } |
| 339 |
| 340 |
304 /** | 341 /** |
305 * [proto] should have no shadowing prototypes that are not also assigned a | 342 * [proto] should have no shadowing prototypes that are not also assigned a |
306 * dispatch rescord. | 343 * dispatch rescord. |
307 */ | 344 */ |
308 setNativeSubclassDispatchRecord(proto, interceptor) { | 345 setNativeSubclassDispatchRecord(proto, interceptor) { |
309 setDispatchProperty(proto, makeLeafDispatchRecord(interceptor)); | 346 setDispatchProperty(proto, makeLeafDispatchRecord(interceptor)); |
310 } | 347 } |
OLD | NEW |