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 library js_backend.backend; | 5 library js_backend.backend; |
| 6 | 6 |
| 7 import 'dart:async' show Future; | 7 import 'dart:async' show Future; |
| 8 | 8 |
| 9 import 'package:js_runtime/shared/embedded_names.dart' as embeddedNames; | 9 import 'package:js_runtime/shared/embedded_names.dart' as embeddedNames; |
| 10 | 10 |
| (...skipping 29 matching lines...) Expand all Loading... | |
| 40 import '../io/start_end_information.dart' | 40 import '../io/start_end_information.dart' |
| 41 show StartEndSourceInformationStrategy; | 41 show StartEndSourceInformationStrategy; |
| 42 import '../js/js.dart' as jsAst; | 42 import '../js/js.dart' as jsAst; |
| 43 import '../js/js.dart' show js; | 43 import '../js/js.dart' show js; |
| 44 import '../js/js_source_mapping.dart' show JavaScriptSourceInformationStrategy; | 44 import '../js/js_source_mapping.dart' show JavaScriptSourceInformationStrategy; |
| 45 import '../js/rewrite_async.dart'; | 45 import '../js/rewrite_async.dart'; |
| 46 import '../js_emitter/js_emitter.dart' show CodeEmitterTask; | 46 import '../js_emitter/js_emitter.dart' show CodeEmitterTask; |
| 47 import '../kernel/task.dart'; | 47 import '../kernel/task.dart'; |
| 48 import '../library_loader.dart' show LibraryLoader, LoadedLibraries; | 48 import '../library_loader.dart' show LibraryLoader, LoadedLibraries; |
| 49 import '../native/native.dart' as native; | 49 import '../native/native.dart' as native; |
| 50 import '../patch_parser.dart' | 50 import '../native/resolver.dart'; |
| 51 show checkNativeAnnotation, checkJsInteropAnnotation; | |
| 52 import '../ssa/ssa.dart' show SsaFunctionCompiler; | 51 import '../ssa/ssa.dart' show SsaFunctionCompiler; |
| 53 import '../tracer.dart'; | 52 import '../tracer.dart'; |
| 54 import '../tree/tree.dart'; | 53 import '../tree/tree.dart'; |
| 55 import '../types/types.dart'; | 54 import '../types/types.dart'; |
| 56 import '../universe/call_structure.dart' show CallStructure; | 55 import '../universe/call_structure.dart' show CallStructure; |
| 57 import '../universe/selector.dart' show Selector; | 56 import '../universe/selector.dart' show Selector; |
| 58 import '../universe/world_builder.dart'; | 57 import '../universe/world_builder.dart'; |
| 59 import '../universe/use.dart' show StaticUse, TypeUse; | 58 import '../universe/use.dart' show StaticUse, TypeUse; |
| 60 import '../universe/world_impact.dart' | 59 import '../universe/world_impact.dart' |
| 61 show | 60 show |
| (...skipping 367 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 429 SourceInformationStrategy sourceInformationStrategy; | 428 SourceInformationStrategy sourceInformationStrategy; |
| 430 | 429 |
| 431 /// Interface for serialization of backend specific data. | 430 /// Interface for serialization of backend specific data. |
| 432 JavaScriptBackendSerialization serialization; | 431 JavaScriptBackendSerialization serialization; |
| 433 | 432 |
| 434 final NativeDataImpl _nativeData = new NativeDataImpl(); | 433 final NativeDataImpl _nativeData = new NativeDataImpl(); |
| 435 NativeClassData get nativeClassData => _nativeData; | 434 NativeClassData get nativeClassData => _nativeData; |
| 436 NativeData get nativeData => _nativeData; | 435 NativeData get nativeData => _nativeData; |
| 437 NativeClassDataBuilder get nativeClassDataBuilder => _nativeData; | 436 NativeClassDataBuilder get nativeClassDataBuilder => _nativeData; |
| 438 NativeDataBuilder get nativeDataBuilder => _nativeData; | 437 NativeDataBuilder get nativeDataBuilder => _nativeData; |
| 438 final NativeDataResolver _nativeDataResolver; | |
| 439 InterceptorDataBuilder _interceptorDataBuilder; | 439 InterceptorDataBuilder _interceptorDataBuilder; |
| 440 InterceptorData _interceptorData; | 440 InterceptorData _interceptorData; |
| 441 OneShotInterceptorData _oneShotInterceptorData; | 441 OneShotInterceptorData _oneShotInterceptorData; |
| 442 BackendUsage _backendUsage; | 442 BackendUsage _backendUsage; |
| 443 BackendUsageBuilder _backendUsageBuilder; | 443 BackendUsageBuilder _backendUsageBuilder; |
| 444 MirrorsData mirrorsData; | 444 MirrorsData mirrorsData; |
| 445 CheckedModeHelpers _checkedModeHelpers; | 445 CheckedModeHelpers _checkedModeHelpers; |
| 446 | 446 |
| 447 ResolutionEnqueuerListener _resolutionEnqueuerListener; | 447 ResolutionEnqueuerListener _resolutionEnqueuerListener; |
| 448 | 448 |
| (...skipping 30 matching lines...) Expand all Loading... | |
| 479 const PositionSourceInformationStrategy() | 479 const PositionSourceInformationStrategy() |
| 480 ]); | 480 ]); |
| 481 } | 481 } |
| 482 } else if (useNewSourceInfo) { | 482 } else if (useNewSourceInfo) { |
| 483 return const PositionSourceInformationStrategy(); | 483 return const PositionSourceInformationStrategy(); |
| 484 } else { | 484 } else { |
| 485 return const StartEndSourceInformationStrategy(); | 485 return const StartEndSourceInformationStrategy(); |
| 486 } | 486 } |
| 487 } | 487 } |
| 488 | 488 |
| 489 JavaScriptBackend(Compiler compiler, | 489 JavaScriptBackend(this.compiler, |
| 490 {bool generateSourceMap: true, | 490 {bool generateSourceMap: true, |
| 491 bool useStartupEmitter: false, | 491 bool useStartupEmitter: false, |
| 492 bool useMultiSourceInfo: false, | 492 bool useMultiSourceInfo: false, |
| 493 bool useNewSourceInfo: false, | 493 bool useNewSourceInfo: false, |
| 494 bool useKernel: false}) | 494 bool useKernel: false}) |
| 495 : _rti = new _RuntimeTypes(compiler), | 495 : _rti = new _RuntimeTypes(compiler), |
| 496 annotations = new Annotations(compiler), | 496 annotations = new Annotations(compiler), |
| 497 this.sourceInformationStrategy = createSourceInformationStrategy( | 497 this.sourceInformationStrategy = createSourceInformationStrategy( |
| 498 generateSourceMap: generateSourceMap, | 498 generateSourceMap: generateSourceMap, |
| 499 useMultiSourceInfo: useMultiSourceInfo, | 499 useMultiSourceInfo: useMultiSourceInfo, |
| 500 useNewSourceInfo: useNewSourceInfo), | 500 useNewSourceInfo: useNewSourceInfo), |
| 501 frontend = new JSFrontendAccess(compiler), | 501 frontend = new JSFrontendAccess(compiler), |
| 502 constantCompilerTask = new JavaScriptConstantTask(compiler), | 502 constantCompilerTask = new JavaScriptConstantTask(compiler), |
| 503 this.compiler = compiler { | 503 _nativeDataResolver = new NativeDataResolverImpl(compiler) { |
| 504 _target = new JavaScriptBackendTarget(this); | 504 _target = new JavaScriptBackendTarget(this); |
| 505 helpers = new BackendHelpers(compiler.elementEnvironment, commonElements); | 505 helpers = new BackendHelpers(compiler.elementEnvironment, commonElements); |
| 506 impacts = new BackendImpacts(compiler.options, commonElements, helpers); | 506 impacts = new BackendImpacts(compiler.options, commonElements, helpers); |
| 507 backendClasses = new JavaScriptBackendClasses( | 507 backendClasses = new JavaScriptBackendClasses( |
| 508 compiler.elementEnvironment, helpers, nativeClassData); | 508 compiler.elementEnvironment, helpers, nativeClassData); |
| 509 mirrorsData = new MirrorsData( | 509 mirrorsData = new MirrorsData( |
| 510 compiler, compiler.options, commonElements, helpers, constants); | 510 compiler, compiler.options, commonElements, helpers, constants); |
| 511 _backendUsageBuilder = new BackendUsageBuilderImpl( | 511 _backendUsageBuilder = new BackendUsageBuilderImpl( |
| 512 compiler.elementEnvironment, commonElements, helpers); | 512 compiler.elementEnvironment, commonElements, helpers); |
| 513 _checkedModeHelpers = new CheckedModeHelpers(commonElements, helpers); | 513 _checkedModeHelpers = new CheckedModeHelpers(commonElements, helpers); |
| (...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 657 } | 657 } |
| 658 | 658 |
| 659 bool isDefaultNoSuchMethod(MethodElement element) { | 659 bool isDefaultNoSuchMethod(MethodElement element) { |
| 660 return noSuchMethodRegistry.isDefaultNoSuchMethodImplementation(element); | 660 return noSuchMethodRegistry.isDefaultNoSuchMethodImplementation(element); |
| 661 } | 661 } |
| 662 | 662 |
| 663 MethodElement resolveExternalFunction(MethodElement element) { | 663 MethodElement resolveExternalFunction(MethodElement element) { |
| 664 if (isForeign(element)) { | 664 if (isForeign(element)) { |
| 665 return element; | 665 return element; |
| 666 } | 666 } |
| 667 if (nativeData.isJsInterop(element)) { | 667 if (_nativeDataResolver.isJsInteropMember(element)) { |
|
Siggi Cherem (dart-lang)
2017/03/14 04:09:15
was the jsinterop check within patchResolver.resol
Johnni Winther
2017/03/15 10:55:13
Yes.
| |
| 668 if (element.memberName == const PublicName('[]') || | 668 if (element.memberName == const PublicName('[]') || |
| 669 element.memberName == const PublicName('[]=')) { | 669 element.memberName == const PublicName('[]=')) { |
| 670 reporter.reportErrorMessage( | 670 reporter.reportErrorMessage( |
| 671 element, MessageKind.JS_INTEROP_INDEX_NOT_SUPPORTED); | 671 element, MessageKind.JS_INTEROP_INDEX_NOT_SUPPORTED); |
| 672 } | 672 } |
| 673 return element; | 673 return element; |
| 674 } | 674 } |
| 675 return patchResolverTask.measure(() { | 675 return patchResolverTask.measure(() { |
| 676 return patchResolverTask.resolveExternalFunction(element); | 676 return patchResolverTask.resolveExternalFunction(element); |
| 677 }); | 677 }); |
| (...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 736 return !selector.isGetter; | 736 return !selector.isGetter; |
| 737 } | 737 } |
| 738 | 738 |
| 739 /** | 739 /** |
| 740 * Returns `true` if [member] is called from a subclass via `super`. | 740 * Returns `true` if [member] is called from a subclass via `super`. |
| 741 */ | 741 */ |
| 742 bool isAliasedSuperMember(FunctionElement member) { | 742 bool isAliasedSuperMember(FunctionElement member) { |
| 743 return aliasedSuperMembers.contains(member); | 743 return aliasedSuperMembers.contains(member); |
| 744 } | 744 } |
| 745 | 745 |
| 746 void resolveNativeElement(MemberElement element, NativeRegistry registry) { | |
| 747 if (element.isFunction || | |
| 748 element.isConstructor || | |
| 749 element.isGetter || | |
| 750 element.isSetter) { | |
| 751 _nativeResolutionEnqueuer.handleMethodAnnotations(element); | |
| 752 if (nativeClassData.isNativeMember(element)) { | |
| 753 native.NativeBehavior behavior = | |
| 754 native.NativeBehavior.ofMethodElement(element, compiler); | |
| 755 nativeDataBuilder.setNativeMethodBehavior(element, behavior); | |
| 756 registry.registerNativeData(behavior); | |
| 757 } | |
| 758 } else if (element.isField) { | |
| 759 _nativeResolutionEnqueuer.handleFieldAnnotations(element); | |
| 760 if (nativeClassData.isNativeMember(element)) { | |
| 761 native.NativeBehavior fieldLoadBehavior = | |
| 762 native.NativeBehavior.ofFieldElementLoad(element, compiler); | |
| 763 native.NativeBehavior fieldStoreBehavior = | |
| 764 native.NativeBehavior.ofFieldElementStore(element, compiler); | |
| 765 nativeDataBuilder.setNativeFieldLoadBehavior( | |
| 766 element, fieldLoadBehavior); | |
| 767 nativeDataBuilder.setNativeFieldStoreBehavior( | |
| 768 element, fieldStoreBehavior); | |
| 769 | |
| 770 // TODO(sra): Process fields for storing separately. | |
| 771 // We have to handle both loading and storing to the field because we | |
| 772 // only get one look at each member and there might be a load or store | |
| 773 // we have not seen yet. | |
| 774 registry.registerNativeData(fieldLoadBehavior); | |
| 775 registry.registerNativeData(fieldStoreBehavior); | |
| 776 } | |
| 777 } | |
| 778 } | |
| 779 | |
| 780 /// Maps compile-time classes to their runtime class. The runtime class is | 746 /// Maps compile-time classes to their runtime class. The runtime class is |
| 781 /// always a superclass or the class itself. | 747 /// always a superclass or the class itself. |
| 782 ClassElement getRuntimeClass(ClassElement class_) { | 748 ClassElement getRuntimeClass(ClassElement class_) { |
| 783 if (class_.isSubclassOf(helpers.jsIntClass)) return helpers.jsIntClass; | 749 if (class_.isSubclassOf(helpers.jsIntClass)) return helpers.jsIntClass; |
| 784 if (class_.isSubclassOf(helpers.jsArrayClass)) return helpers.jsArrayClass; | 750 if (class_.isSubclassOf(helpers.jsArrayClass)) return helpers.jsArrayClass; |
| 785 return class_; | 751 return class_; |
| 786 } | 752 } |
| 787 | 753 |
| 788 bool operatorEqHandlesNullArgument(FunctionElement operatorEqfunction) { | 754 bool operatorEqHandlesNullArgument(FunctionElement operatorEqfunction) { |
| 789 return specialOperatorEqClasses.contains(operatorEqfunction.enclosingClass); | 755 return specialOperatorEqClasses.contains(operatorEqfunction.enclosingClass); |
| (...skipping 356 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1146 element == helpers.jsUnmodifiableArrayClass; | 1112 element == helpers.jsUnmodifiableArrayClass; |
| 1147 } | 1113 } |
| 1148 | 1114 |
| 1149 /// This method is called immediately after the [library] and its parts have | 1115 /// This method is called immediately after the [library] and its parts have |
| 1150 /// been scanned. | 1116 /// been scanned. |
| 1151 Future onLibraryScanned(LibraryElement library, LibraryLoader loader) { | 1117 Future onLibraryScanned(LibraryElement library, LibraryLoader loader) { |
| 1152 if (!compiler.serialization.isDeserialized(library)) { | 1118 if (!compiler.serialization.isDeserialized(library)) { |
| 1153 if (canLibraryUseNative(library)) { | 1119 if (canLibraryUseNative(library)) { |
| 1154 library.forEachLocalMember((Element element) { | 1120 library.forEachLocalMember((Element element) { |
| 1155 if (element.isClass) { | 1121 if (element.isClass) { |
| 1156 checkNativeAnnotation(compiler, element); | 1122 checkNativeAnnotation(compiler, element, nativeClassDataBuilder); |
| 1157 } | 1123 } |
| 1158 }); | 1124 }); |
| 1159 } | 1125 } |
| 1160 checkJsInteropAnnotation(compiler, library); | 1126 checkJsInteropClassAnnotations(compiler, library, nativeClassDataBuilder); |
| 1161 library.forEachLocalMember((Element element) { | |
| 1162 checkJsInteropAnnotation(compiler, element); | |
| 1163 if (element.isClass && nativeData.isJsInterop(element)) { | |
| 1164 ClassElement classElement = element; | |
| 1165 classElement.forEachMember((_, memberElement) { | |
| 1166 checkJsInteropAnnotation(compiler, memberElement); | |
| 1167 }); | |
| 1168 } | |
| 1169 }); | |
| 1170 } | 1127 } |
| 1171 if (library.isPlatformLibrary && | 1128 if (library.isPlatformLibrary && |
| 1172 // Don't patch library currently disallowed. | 1129 // Don't patch library currently disallowed. |
| 1173 !library.isSynthesized && | 1130 !library.isSynthesized && |
| 1174 !library.isPatched && | 1131 !library.isPatched && |
| 1175 // Don't patch deserialized libraries. | 1132 // Don't patch deserialized libraries. |
| 1176 !compiler.serialization.isDeserialized(library)) { | 1133 !compiler.serialization.isDeserialized(library)) { |
| 1177 // Apply patch, if any. | 1134 // Apply patch, if any. |
| 1178 Uri patchUri = compiler.resolvePatchUri(library.canonicalUri.path); | 1135 Uri patchUri = compiler.resolvePatchUri(library.canonicalUri.path); |
| 1179 if (patchUri != null) { | 1136 if (patchUri != null) { |
| (...skipping 408 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1588 return classElement == helpers.commonElements.objectClass || | 1545 return classElement == helpers.commonElements.objectClass || |
| 1589 classElement == helpers.jsInterceptorClass || | 1546 classElement == helpers.jsInterceptorClass || |
| 1590 classElement == helpers.jsNullClass; | 1547 classElement == helpers.jsNullClass; |
| 1591 } | 1548 } |
| 1592 | 1549 |
| 1593 @override | 1550 @override |
| 1594 bool isNativeClass(ClassEntity element) { | 1551 bool isNativeClass(ClassEntity element) { |
| 1595 return _nativeData.isNativeClass(element); | 1552 return _nativeData.isNativeClass(element); |
| 1596 } | 1553 } |
| 1597 | 1554 |
| 1598 @override | |
| 1599 bool isNativeMember(MemberEntity element) { | |
| 1600 return _nativeData.isNativeMember(element); | |
| 1601 } | |
| 1602 | |
| 1603 InterfaceType getConstantMapTypeFor(InterfaceType sourceType, | 1555 InterfaceType getConstantMapTypeFor(InterfaceType sourceType, |
| 1604 {bool hasProtoKey: false, bool onlyStringKeys: false}) { | 1556 {bool hasProtoKey: false, bool onlyStringKeys: false}) { |
| 1605 ClassElement classElement = onlyStringKeys | 1557 ClassElement classElement = onlyStringKeys |
| 1606 ? (hasProtoKey | 1558 ? (hasProtoKey |
| 1607 ? helpers.constantProtoMapClass | 1559 ? helpers.constantProtoMapClass |
| 1608 : helpers.constantStringMapClass) | 1560 : helpers.constantStringMapClass) |
| 1609 : helpers.generalConstantMapClass; | 1561 : helpers.generalConstantMapClass; |
| 1610 List<DartType> typeArgument = sourceType.typeArguments; | 1562 List<DartType> typeArgument = sourceType.typeArguments; |
| 1611 if (sourceType.treatAsRaw) { | 1563 if (sourceType.treatAsRaw) { |
| 1612 return _env.getRawType(classElement); | 1564 return _env.getRawType(classElement); |
| (...skipping 15 matching lines...) Expand all Loading... | |
| 1628 final JavaScriptBackend _backend; | 1580 final JavaScriptBackend _backend; |
| 1629 | 1581 |
| 1630 JavaScriptBackendTarget(this._backend); | 1582 JavaScriptBackendTarget(this._backend); |
| 1631 | 1583 |
| 1632 @override | 1584 @override |
| 1633 bool isTargetSpecificLibrary(LibraryElement element) { | 1585 bool isTargetSpecificLibrary(LibraryElement element) { |
| 1634 return _backend.isTargetSpecificLibrary(element); | 1586 return _backend.isTargetSpecificLibrary(element); |
| 1635 } | 1587 } |
| 1636 | 1588 |
| 1637 @override | 1589 @override |
| 1638 void resolveNativeElement(MemberElement element, NativeRegistry registry) { | 1590 void resolveNativeMember(MemberElement element, NativeRegistry registry) { |
| 1639 return _backend.resolveNativeElement(element, registry); | 1591 return _backend._nativeDataResolver.resolveNativeMember(element, registry); |
| 1640 } | 1592 } |
| 1641 | 1593 |
| 1642 @override | 1594 @override |
| 1643 MethodElement resolveExternalFunction(MethodElement element) { | 1595 MethodElement resolveExternalFunction(MethodElement element) { |
| 1644 return _backend.resolveExternalFunction(element); | 1596 return _backend.resolveExternalFunction(element); |
| 1645 } | 1597 } |
| 1646 | 1598 |
| 1647 @override | 1599 @override |
| 1648 dynamic resolveForeignCall(Send node, Element element, | 1600 dynamic resolveForeignCall(Send node, Element element, |
| 1649 CallStructure callStructure, ForeignResolver resolver) { | 1601 CallStructure callStructure, ForeignResolver resolver) { |
| (...skipping 10 matching lines...) Expand all Loading... | |
| 1660 return _backend.defaultSuperclass(element); | 1612 return _backend.defaultSuperclass(element); |
| 1661 } | 1613 } |
| 1662 | 1614 |
| 1663 @override | 1615 @override |
| 1664 bool isNativeClass(ClassEntity element) => | 1616 bool isNativeClass(ClassEntity element) => |
| 1665 _backend.nativeClassData.isNativeClass(element); | 1617 _backend.nativeClassData.isNativeClass(element); |
| 1666 | 1618 |
| 1667 @override | 1619 @override |
| 1668 bool isForeign(Element element) => _backend.isForeign(element); | 1620 bool isForeign(Element element) => _backend.isForeign(element); |
| 1669 } | 1621 } |
| OLD | NEW |