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 |