Chromium Code Reviews| 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_backend; | 5 part of js_backend; |
| 6 | 6 |
| 7 class JavaScriptItemCompilationContext extends ItemCompilationContext { | 7 class JavaScriptItemCompilationContext extends ItemCompilationContext { |
| 8 final Set<HInstruction> boundsChecked; | 8 final Set<HInstruction> boundsChecked; |
| 9 | 9 |
| 10 JavaScriptItemCompilationContext() | 10 JavaScriptItemCompilationContext() |
| (...skipping 250 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 261 * always specializing it based on the incoming type. The keys in | 261 * always specializing it based on the incoming type. The keys in |
| 262 * the map are the names of these specialized versions. Note that | 262 * the map are the names of these specialized versions. Note that |
| 263 * the generic version that contains all possible type checks is | 263 * the generic version that contains all possible type checks is |
| 264 * also stored in this map. | 264 * also stored in this map. |
| 265 */ | 265 */ |
| 266 final Map<String, Set<ClassElement>> specializedGetInterceptors; | 266 final Map<String, Set<ClassElement>> specializedGetInterceptors; |
| 267 | 267 |
| 268 /** | 268 /** |
| 269 * Set of classes whose methods are intercepted. | 269 * Set of classes whose methods are intercepted. |
| 270 */ | 270 */ |
| 271 final Set<ClassElement> interceptedClasses = new Set<ClassElement>(); | 271 final Set<ClassElement> _interceptedClasses = new Set<ClassElement>(); |
| 272 | 272 |
| 273 /** | 273 /** |
| 274 * Set of classes used as mixins on native classes. Methods on these classes | 274 * Set of classes used as mixins on native classes. Methods on these classes |
| 275 * might also be mixed in to non-native classes. | 275 * might also be mixed in to non-native classes. |
| 276 */ | 276 */ |
| 277 final Set<ClassElement> classesMixedIntoNativeClasses = | 277 final Set<ClassElement> classesMixedIntoNativeClasses = |
| 278 new Set<ClassElement>(); | 278 new Set<ClassElement>(); |
| 279 | 279 |
| 280 /** | 280 /** |
| 281 * Set of classes whose `operator ==` methods handle `null` themselves. | 281 * Set of classes whose `operator ==` methods handle `null` themselves. |
| (...skipping 268 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 550 jsArrayClass, const SourceString('add')); | 550 jsArrayClass, const SourceString('add')); |
| 551 | 551 |
| 552 jsStringClass.ensureResolved(compiler); | 552 jsStringClass.ensureResolved(compiler); |
| 553 jsStringSplit = compiler.lookupElementIn( | 553 jsStringSplit = compiler.lookupElementIn( |
| 554 jsStringClass, const SourceString('split')); | 554 jsStringClass, const SourceString('split')); |
| 555 jsStringConcat = compiler.lookupElementIn( | 555 jsStringConcat = compiler.lookupElementIn( |
| 556 jsStringClass, const SourceString('concat')); | 556 jsStringClass, const SourceString('concat')); |
| 557 jsStringToString = compiler.lookupElementIn( | 557 jsStringToString = compiler.lookupElementIn( |
| 558 jsStringClass, const SourceString('toString')); | 558 jsStringClass, const SourceString('toString')); |
| 559 | 559 |
| 560 for (ClassElement cls in classes) { | |
| 561 if (cls != null) interceptedClasses.add(cls); | |
| 562 } | |
| 563 | |
| 564 typeLiteralClass = compiler.findHelper(const SourceString('TypeImpl')); | 560 typeLiteralClass = compiler.findHelper(const SourceString('TypeImpl')); |
| 565 mapLiteralClass = | 561 mapLiteralClass = |
| 566 compiler.coreLibrary.find(const SourceString('LinkedHashMap')); | 562 compiler.coreLibrary.find(const SourceString('LinkedHashMap')); |
| 567 constMapLiteralClass = | 563 constMapLiteralClass = |
| 568 compiler.findHelper(const SourceString('ConstantMap')); | 564 compiler.findHelper(const SourceString('ConstantMap')); |
| 569 | 565 |
| 570 objectEquals = compiler.lookupElementIn( | 566 objectEquals = compiler.lookupElementIn( |
| 571 compiler.objectClass, const SourceString('==')); | 567 compiler.objectClass, const SourceString('==')); |
| 572 | 568 |
| 573 specialOperatorEqClasses | 569 specialOperatorEqClasses |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 623 } | 619 } |
| 624 }, | 620 }, |
| 625 includeSuperAndInjectedMembers: true); | 621 includeSuperAndInjectedMembers: true); |
| 626 } | 622 } |
| 627 } | 623 } |
| 628 | 624 |
| 629 void addInterceptors(ClassElement cls, | 625 void addInterceptors(ClassElement cls, |
| 630 Enqueuer enqueuer, | 626 Enqueuer enqueuer, |
| 631 TreeElements elements) { | 627 TreeElements elements) { |
| 632 if (enqueuer.isResolutionQueue) { | 628 if (enqueuer.isResolutionQueue) { |
| 629 _interceptedClasses.add(cls); | |
| 633 cls.ensureResolved(compiler); | 630 cls.ensureResolved(compiler); |
| 634 cls.forEachMember((ClassElement classElement, Element member) { | 631 cls.forEachMember((ClassElement classElement, Element member) { |
| 635 // All methods on [Object] are shadowed by [Interceptor]. | 632 // All methods on [Object] are shadowed by [Interceptor]. |
| 636 if (classElement == compiler.objectClass) return; | 633 if (classElement == compiler.objectClass) return; |
| 637 Set<Element> set = interceptedElements.putIfAbsent( | 634 Set<Element> set = interceptedElements.putIfAbsent( |
| 638 member.name, () => new Set<Element>()); | 635 member.name, () => new Set<Element>()); |
| 639 set.add(member); | 636 set.add(member); |
| 640 }, | 637 }, |
| 641 includeSuperAndInjectedMembers: true); | 638 includeSuperAndInjectedMembers: true); |
| 642 } | 639 } |
| 643 enqueueClass(enqueuer, cls, elements); | 640 enqueueClass(enqueuer, cls, elements); |
| 644 } | 641 } |
| 645 | 642 |
| 643 Set<ClassElement> get interceptedClasses { | |
| 644 assert(compiler.enqueuer.resolution.queueIsClosed); | |
| 645 return _interceptedClasses; | |
| 646 } | |
| 647 | |
| 646 void registerSpecializedGetInterceptor(Set<ClassElement> classes) { | 648 void registerSpecializedGetInterceptor(Set<ClassElement> classes) { |
| 647 String name = namer.getInterceptorName(getInterceptorMethod, classes); | 649 String name = namer.getInterceptorName(getInterceptorMethod, classes); |
| 648 if (classes.contains(jsInterceptorClass)) { | 650 if (classes.contains(jsInterceptorClass)) { |
| 649 // We can't use a specialized [getInterceptorMethod], so we make | 651 // We can't use a specialized [getInterceptorMethod], so we make |
| 650 // sure we emit the one with all checks. | 652 // sure we emit the one with all checks. |
| 651 specializedGetInterceptors[name] = interceptedClasses; | 653 specializedGetInterceptors[name] = interceptedClasses; |
| 652 } else { | 654 } else { |
| 653 specializedGetInterceptors[name] = classes; | 655 specializedGetInterceptors[name] = classes; |
| 654 } | 656 } |
| 655 } | 657 } |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 698 enqueueClass(enqueuer, mapLiteralClass, elements); | 700 enqueueClass(enqueuer, mapLiteralClass, elements); |
| 699 enqueueInResolution(getMapMaker(), elements); | 701 enqueueInResolution(getMapMaker(), elements); |
| 700 } else if (cls == compiler.boundClosureClass) { | 702 } else if (cls == compiler.boundClosureClass) { |
| 701 // TODO(ngeoffray): Move the bound closure class in the | 703 // TODO(ngeoffray): Move the bound closure class in the |
| 702 // backend. | 704 // backend. |
| 703 enqueueClass(enqueuer, compiler.boundClosureClass, elements); | 705 enqueueClass(enqueuer, compiler.boundClosureClass, elements); |
| 704 } | 706 } |
| 705 } | 707 } |
| 706 ClassElement result = null; | 708 ClassElement result = null; |
| 707 if (cls == compiler.stringClass || cls == jsStringClass) { | 709 if (cls == compiler.stringClass || cls == jsStringClass) { |
| 710 addInterceptors(jsInterceptorClass, enqueuer, elements); | |
|
ngeoffray
2013/08/27 08:55:02
Maybe move the registration of the super class in
Johnni Winther
2013/08/27 10:20:10
Done.
| |
| 708 addInterceptors(jsStringClass, enqueuer, elements); | 711 addInterceptors(jsStringClass, enqueuer, elements); |
| 709 } else if (cls == compiler.listClass | 712 } else if (cls == compiler.listClass |
| 710 || cls == jsArrayClass | 713 || cls == jsArrayClass |
| 711 || cls == jsFixedArrayClass | 714 || cls == jsFixedArrayClass |
| 712 || cls == jsExtendableArrayClass) { | 715 || cls == jsExtendableArrayClass) { |
| 716 addInterceptors(jsInterceptorClass, enqueuer, elements); | |
| 713 addInterceptors(jsArrayClass, enqueuer, elements); | 717 addInterceptors(jsArrayClass, enqueuer, elements); |
| 714 enqueueClass(enqueuer, jsFixedArrayClass, elements); | 718 addInterceptors(jsMutableArrayClass, enqueuer, elements); |
| 715 enqueueClass(enqueuer, jsExtendableArrayClass, elements); | 719 addInterceptors(jsFixedArrayClass, enqueuer, elements); |
| 720 addInterceptors(jsExtendableArrayClass, enqueuer, elements); | |
| 716 } else if (cls == compiler.intClass || cls == jsIntClass) { | 721 } else if (cls == compiler.intClass || cls == jsIntClass) { |
| 722 addInterceptors(jsInterceptorClass, enqueuer, elements); | |
| 717 addInterceptors(jsIntClass, enqueuer, elements); | 723 addInterceptors(jsIntClass, enqueuer, elements); |
| 718 addInterceptors(jsNumberClass, enqueuer, elements); | 724 addInterceptors(jsNumberClass, enqueuer, elements); |
| 719 } else if (cls == compiler.doubleClass || cls == jsDoubleClass) { | 725 } else if (cls == compiler.doubleClass || cls == jsDoubleClass) { |
| 726 addInterceptors(jsInterceptorClass, enqueuer, elements); | |
| 720 addInterceptors(jsDoubleClass, enqueuer, elements); | 727 addInterceptors(jsDoubleClass, enqueuer, elements); |
| 721 addInterceptors(jsNumberClass, enqueuer, elements); | 728 addInterceptors(jsNumberClass, enqueuer, elements); |
| 722 } else if (cls == compiler.boolClass || cls == jsBoolClass) { | 729 } else if (cls == compiler.boolClass || cls == jsBoolClass) { |
| 730 addInterceptors(jsInterceptorClass, enqueuer, elements); | |
| 723 addInterceptors(jsBoolClass, enqueuer, elements); | 731 addInterceptors(jsBoolClass, enqueuer, elements); |
| 724 } else if (cls == compiler.nullClass || cls == jsNullClass) { | 732 } else if (cls == compiler.nullClass || cls == jsNullClass) { |
| 733 addInterceptors(jsInterceptorClass, enqueuer, elements); | |
| 725 addInterceptors(jsNullClass, enqueuer, elements); | 734 addInterceptors(jsNullClass, enqueuer, elements); |
| 726 } else if (cls == compiler.numClass || cls == jsNumberClass) { | 735 } else if (cls == compiler.numClass || cls == jsNumberClass) { |
| 736 addInterceptors(jsInterceptorClass, enqueuer, elements); | |
| 727 addInterceptors(jsIntClass, enqueuer, elements); | 737 addInterceptors(jsIntClass, enqueuer, elements); |
| 728 addInterceptors(jsDoubleClass, enqueuer, elements); | 738 addInterceptors(jsDoubleClass, enqueuer, elements); |
| 729 addInterceptors(jsNumberClass, enqueuer, elements); | 739 addInterceptors(jsNumberClass, enqueuer, elements); |
| 730 } else if (cls == jsPlainJavaScriptObjectClass) { | 740 } else if (cls == jsPlainJavaScriptObjectClass) { |
| 741 addInterceptors(jsInterceptorClass, enqueuer, elements); | |
| 731 addInterceptors(jsPlainJavaScriptObjectClass, enqueuer, elements); | 742 addInterceptors(jsPlainJavaScriptObjectClass, enqueuer, elements); |
| 732 } else if (cls == jsUnknownJavaScriptObjectClass) { | 743 } else if (cls == jsUnknownJavaScriptObjectClass) { |
| 744 addInterceptors(jsInterceptorClass, enqueuer, elements); | |
| 733 addInterceptors(jsUnknownJavaScriptObjectClass, enqueuer, elements); | 745 addInterceptors(jsUnknownJavaScriptObjectClass, enqueuer, elements); |
| 734 } else if (Elements.isNativeOrExtendsNative(cls)) { | 746 } else if (Elements.isNativeOrExtendsNative(cls)) { |
| 735 addInterceptorsForNativeClassMembers(cls, enqueuer); | 747 addInterceptorsForNativeClassMembers(cls, enqueuer); |
| 736 } | 748 } |
| 737 } | 749 } |
| 738 | 750 |
| 739 void registerUseInterceptor(Enqueuer enqueuer) { | 751 void registerUseInterceptor(Enqueuer enqueuer) { |
| 740 assert(!enqueuer.isResolutionQueue); | 752 assert(!enqueuer.isResolutionQueue); |
| 741 if (!enqueuer.nativeEnqueuer.hasInstantiatedNativeClasses()) return; | 753 if (!enqueuer.nativeEnqueuer.hasInstantiatedNativeClasses()) return; |
| 742 TreeElements elements = compiler.globalDependencies; | 754 TreeElements elements = compiler.globalDependencies; |
| (...skipping 534 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1277 ? const PropertyCheckedModeHelper( | 1289 ? const PropertyCheckedModeHelper( |
| 1278 const SourceString('propertyTypeCast')) | 1290 const SourceString('propertyTypeCast')) |
| 1279 : const PropertyCheckedModeHelper( | 1291 : const PropertyCheckedModeHelper( |
| 1280 const SourceString('propertyTypeCheck')); | 1292 const SourceString('propertyTypeCheck')); |
| 1281 } | 1293 } |
| 1282 } | 1294 } |
| 1283 } | 1295 } |
| 1284 } | 1296 } |
| 1285 } | 1297 } |
| 1286 | 1298 |
| 1299 /** | |
| 1300 * Returns [:true:] if the checking of [type] is performed directly on the | |
| 1301 * object and not on an interceptor. | |
| 1302 */ | |
| 1303 bool hasDirectCheckFor(DartType type) { | |
| 1304 Element element = type.element; | |
| 1305 return element == compiler.stringClass || | |
| 1306 element == compiler.boolClass || | |
| 1307 element == compiler.numClass || | |
| 1308 element == compiler.intClass || | |
| 1309 element == compiler.doubleClass || | |
| 1310 element == jsArrayClass || | |
| 1311 element == jsMutableArrayClass || | |
| 1312 element == jsExtendableArrayClass || | |
| 1313 element == jsFixedArrayClass; | |
| 1314 } | |
| 1315 | |
| 1287 Element getExceptionUnwrapper() { | 1316 Element getExceptionUnwrapper() { |
| 1288 return compiler.findHelper(const SourceString('unwrapException')); | 1317 return compiler.findHelper(const SourceString('unwrapException')); |
| 1289 } | 1318 } |
| 1290 | 1319 |
| 1291 Element getThrowRuntimeError() { | 1320 Element getThrowRuntimeError() { |
| 1292 return compiler.findHelper(const SourceString('throwRuntimeError')); | 1321 return compiler.findHelper(const SourceString('throwRuntimeError')); |
| 1293 } | 1322 } |
| 1294 | 1323 |
| 1295 Element getThrowAbstractClassInstantiationError() { | 1324 Element getThrowAbstractClassInstantiationError() { |
| 1296 return compiler.findHelper( | 1325 return compiler.findHelper( |
| (...skipping 324 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1621 copy(constant.values); | 1650 copy(constant.values); |
| 1622 copy(constant.protoValue); | 1651 copy(constant.protoValue); |
| 1623 copy(constant); | 1652 copy(constant); |
| 1624 } | 1653 } |
| 1625 | 1654 |
| 1626 void visitConstructed(ConstructedConstant constant) { | 1655 void visitConstructed(ConstructedConstant constant) { |
| 1627 copy(constant.fields); | 1656 copy(constant.fields); |
| 1628 copy(constant); | 1657 copy(constant); |
| 1629 } | 1658 } |
| 1630 } | 1659 } |
| OLD | NEW |