| 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 414 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 425 | 425 |
| 426 PatchResolverTask patchResolverTask; | 426 PatchResolverTask patchResolverTask; |
| 427 | 427 |
| 428 /// The strategy used for collecting and emitting source information. | 428 /// The strategy used for collecting and emitting source information. |
| 429 SourceInformationStrategy sourceInformationStrategy; | 429 SourceInformationStrategy sourceInformationStrategy; |
| 430 | 430 |
| 431 /// Interface for serialization of backend specific data. | 431 /// Interface for serialization of backend specific data. |
| 432 JavaScriptBackendSerialization serialization; | 432 JavaScriptBackendSerialization serialization; |
| 433 | 433 |
| 434 final NativeDataImpl _nativeData = new NativeDataImpl(); | 434 final NativeDataImpl _nativeData = new NativeDataImpl(); |
| 435 NativeClassData get nativeClassData => _nativeData; |
| 435 NativeData get nativeData => _nativeData; | 436 NativeData get nativeData => _nativeData; |
| 437 NativeClassDataBuilder get nativeClassDataBuilder => _nativeData; |
| 436 NativeDataBuilder get nativeDataBuilder => _nativeData; | 438 NativeDataBuilder get nativeDataBuilder => _nativeData; |
| 437 InterceptorDataBuilder _interceptorDataBuilder; | 439 InterceptorDataBuilder _interceptorDataBuilder; |
| 438 InterceptorData _interceptorData; | 440 InterceptorData _interceptorData; |
| 439 OneShotInterceptorData _oneShotInterceptorData; | 441 OneShotInterceptorData _oneShotInterceptorData; |
| 440 BackendUsage _backendUsage; | 442 BackendUsage _backendUsage; |
| 441 BackendUsageBuilder _backendUsageBuilder; | 443 BackendUsageBuilder _backendUsageBuilder; |
| 442 MirrorsData mirrorsData; | 444 MirrorsData mirrorsData; |
| 443 CheckedModeHelpers _checkedModeHelpers; | 445 CheckedModeHelpers _checkedModeHelpers; |
| 444 | 446 |
| 445 ResolutionEnqueuerListener _resolutionEnqueuerListener; | 447 ResolutionEnqueuerListener _resolutionEnqueuerListener; |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 496 generateSourceMap: generateSourceMap, | 498 generateSourceMap: generateSourceMap, |
| 497 useMultiSourceInfo: useMultiSourceInfo, | 499 useMultiSourceInfo: useMultiSourceInfo, |
| 498 useNewSourceInfo: useNewSourceInfo), | 500 useNewSourceInfo: useNewSourceInfo), |
| 499 frontend = new JSFrontendAccess(compiler), | 501 frontend = new JSFrontendAccess(compiler), |
| 500 constantCompilerTask = new JavaScriptConstantTask(compiler), | 502 constantCompilerTask = new JavaScriptConstantTask(compiler), |
| 501 this.compiler = compiler { | 503 this.compiler = compiler { |
| 502 _target = new JavaScriptBackendTarget(this); | 504 _target = new JavaScriptBackendTarget(this); |
| 503 helpers = new BackendHelpers(compiler.elementEnvironment, commonElements); | 505 helpers = new BackendHelpers(compiler.elementEnvironment, commonElements); |
| 504 impacts = new BackendImpacts(compiler.options, commonElements, helpers); | 506 impacts = new BackendImpacts(compiler.options, commonElements, helpers); |
| 505 backendClasses = new JavaScriptBackendClasses( | 507 backendClasses = new JavaScriptBackendClasses( |
| 506 compiler.elementEnvironment, helpers, nativeData); | 508 compiler.elementEnvironment, helpers, nativeClassData); |
| 507 mirrorsData = new MirrorsData( | 509 mirrorsData = new MirrorsData( |
| 508 compiler, compiler.options, commonElements, helpers, constants); | 510 compiler, compiler.options, commonElements, helpers, constants); |
| 509 _backendUsageBuilder = new BackendUsageBuilderImpl( | 511 _backendUsageBuilder = new BackendUsageBuilderImpl( |
| 510 compiler.elementEnvironment, commonElements, helpers); | 512 compiler.elementEnvironment, commonElements, helpers); |
| 511 _checkedModeHelpers = new CheckedModeHelpers(commonElements, helpers); | 513 _checkedModeHelpers = new CheckedModeHelpers(commonElements, helpers); |
| 512 emitter = | 514 emitter = |
| 513 new CodeEmitterTask(compiler, generateSourceMap, useStartupEmitter); | 515 new CodeEmitterTask(compiler, generateSourceMap, useStartupEmitter); |
| 514 _nativeResolutionEnqueuer = new native.NativeResolutionEnqueuer(compiler); | 516 _nativeResolutionEnqueuer = new native.NativeResolutionEnqueuer(compiler); |
| 515 _nativeCodegenEnqueuer = new native.NativeCodegenEnqueuer( | 517 _nativeCodegenEnqueuer = new native.NativeCodegenEnqueuer( |
| 516 compiler, emitter, _nativeResolutionEnqueuer); | 518 compiler, emitter, _nativeResolutionEnqueuer); |
| 517 | 519 |
| 518 typeVariableAnalysis = new TypeVariableAnalysis( | 520 typeVariableAnalysis = new TypeVariableAnalysis( |
| 519 compiler.elementEnvironment, impacts, backendUsageBuilder); | 521 compiler.elementEnvironment, impacts, backendUsageBuilder); |
| 520 typeVariableHandler = new TypeVariableHandler(this, helpers, mirrorsData); | 522 typeVariableHandler = new TypeVariableHandler(this, helpers, mirrorsData); |
| 521 customElementsResolutionAnalysis = new CustomElementsResolutionAnalysis( | 523 customElementsResolutionAnalysis = new CustomElementsResolutionAnalysis( |
| 522 this, | 524 this, |
| 523 compiler.resolution, | 525 compiler.resolution, |
| 524 commonElements, | 526 commonElements, |
| 525 backendClasses, | 527 backendClasses, |
| 526 helpers, | 528 helpers, |
| 527 nativeData, | 529 nativeClassData, |
| 528 backendUsageBuilder); | 530 backendUsageBuilder); |
| 529 customElementsCodegenAnalysis = new CustomElementsCodegenAnalysis( | 531 customElementsCodegenAnalysis = new CustomElementsCodegenAnalysis( |
| 530 this, | 532 this, |
| 531 compiler.resolution, | 533 compiler.resolution, |
| 532 commonElements, | 534 commonElements, |
| 533 backendClasses, | 535 backendClasses, |
| 534 helpers, | 536 helpers, |
| 535 nativeData); | 537 nativeClassData); |
| 536 jsInteropAnalysis = new JsInteropAnalysis(this); | 538 jsInteropAnalysis = new JsInteropAnalysis(this); |
| 537 mirrorsAnalysis = new MirrorsAnalysis(this, compiler.resolution); | 539 mirrorsAnalysis = new MirrorsAnalysis(this, compiler.resolution); |
| 538 lookupMapLibraryAccess = | 540 lookupMapLibraryAccess = |
| 539 new LookupMapLibraryAccess(reporter, compiler.elementEnvironment); | 541 new LookupMapLibraryAccess(reporter, compiler.elementEnvironment); |
| 540 lookupMapAnalysis = new LookupMapAnalysis(this, compiler.options, reporter, | 542 lookupMapAnalysis = new LookupMapAnalysis(this, compiler.options, reporter, |
| 541 compiler.elementEnvironment, commonElements, backendClasses); | 543 compiler.elementEnvironment, commonElements, backendClasses); |
| 542 | 544 |
| 543 noSuchMethodRegistry = new NoSuchMethodRegistry(this); | 545 noSuchMethodRegistry = new NoSuchMethodRegistry(this); |
| 544 kernelTask = new KernelTask(compiler); | 546 kernelTask = new KernelTask(compiler); |
| 545 impactTransformer = new JavaScriptImpactTransformer(this); | 547 impactTransformer = new JavaScriptImpactTransformer(this); |
| 546 patchResolverTask = new PatchResolverTask(compiler); | 548 patchResolverTask = new PatchResolverTask(compiler); |
| 547 functionCompiler = | 549 functionCompiler = |
| 548 new SsaFunctionCompiler(this, sourceInformationStrategy, useKernel); | 550 new SsaFunctionCompiler(this, sourceInformationStrategy, useKernel); |
| 549 serialization = new JavaScriptBackendSerialization(nativeData); | 551 serialization = new JavaScriptBackendSerialization(nativeData); |
| 550 _interceptorDataBuilder = new InterceptorDataBuilderImpl( | 552 _interceptorDataBuilder = new InterceptorDataBuilderImpl( |
| 551 nativeData, helpers, commonElements, compiler.resolution); | 553 nativeClassData, helpers, commonElements, compiler.resolution); |
| 552 _resolutionEnqueuerListener = new ResolutionEnqueuerListener( | 554 _resolutionEnqueuerListener = new ResolutionEnqueuerListener( |
| 553 kernelTask, | 555 kernelTask, |
| 554 compiler.options, | 556 compiler.options, |
| 555 compiler.elementEnvironment, | 557 compiler.elementEnvironment, |
| 556 commonElements, | 558 commonElements, |
| 557 helpers, | 559 helpers, |
| 558 impacts, | 560 impacts, |
| 559 nativeData, | 561 nativeClassData, |
| 560 _interceptorDataBuilder, | 562 _interceptorDataBuilder, |
| 561 _backendUsageBuilder, | 563 _backendUsageBuilder, |
| 562 _rtiNeedBuilder, | 564 _rtiNeedBuilder, |
| 563 mirrorsData, | 565 mirrorsData, |
| 564 noSuchMethodRegistry, | 566 noSuchMethodRegistry, |
| 565 customElementsResolutionAnalysis, | 567 customElementsResolutionAnalysis, |
| 566 lookupMapLibraryAccess, | 568 lookupMapLibraryAccess, |
| 567 mirrorsAnalysis, | 569 mirrorsAnalysis, |
| 568 typeVariableAnalysis, | 570 typeVariableAnalysis, |
| 569 _nativeResolutionEnqueuer); | 571 _nativeResolutionEnqueuer); |
| (...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 679 | 681 |
| 680 bool isBackendLibrary(LibraryElement library) { | 682 bool isBackendLibrary(LibraryElement library) { |
| 681 return library == helpers.interceptorsLibrary || | 683 return library == helpers.interceptorsLibrary || |
| 682 library == helpers.jsHelperLibrary; | 684 library == helpers.jsHelperLibrary; |
| 683 } | 685 } |
| 684 | 686 |
| 685 Namer determineNamer( | 687 Namer determineNamer( |
| 686 ClosedWorld closedWorld, CodegenWorldBuilder codegenWorldBuilder) { | 688 ClosedWorld closedWorld, CodegenWorldBuilder codegenWorldBuilder) { |
| 687 return compiler.options.enableMinification | 689 return compiler.options.enableMinification |
| 688 ? compiler.options.useFrequencyNamer | 690 ? compiler.options.useFrequencyNamer |
| 689 ? new FrequencyBasedNamer(this, closedWorld, codegenWorldBuilder) | 691 ? new FrequencyBasedNamer( |
| 690 : new MinifyNamer(this, closedWorld, codegenWorldBuilder) | 692 helpers, nativeData, closedWorld, codegenWorldBuilder) |
| 691 : new Namer(this, closedWorld, codegenWorldBuilder); | 693 : new MinifyNamer( |
| 694 helpers, nativeData, closedWorld, codegenWorldBuilder) |
| 695 : new Namer(helpers, nativeData, closedWorld, codegenWorldBuilder); |
| 692 } | 696 } |
| 693 | 697 |
| 694 /// Returns true if global optimizations such as type inferencing can apply to | 698 /// Returns true if global optimizations such as type inferencing can apply to |
| 695 /// the field [element]. | 699 /// the field [element]. |
| 696 /// | 700 /// |
| 697 /// One category of elements that do not apply is runtime helpers that the | 701 /// One category of elements that do not apply is runtime helpers that the |
| 698 /// backend calls, but the optimizations don't see those calls. | 702 /// backend calls, but the optimizations don't see those calls. |
| 699 bool canFieldBeUsedForGlobalOptimizations(FieldElement element) { | 703 bool canFieldBeUsedForGlobalOptimizations(FieldElement element) { |
| 700 return !backendUsage.isFieldUsedByBackend(element) && | 704 return !backendUsage.isFieldUsedByBackend(element) && |
| 701 !mirrorsData.invokedReflectively(element); | 705 !mirrorsData.invokedReflectively(element); |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 738 bool isAliasedSuperMember(FunctionElement member) { | 742 bool isAliasedSuperMember(FunctionElement member) { |
| 739 return aliasedSuperMembers.contains(member); | 743 return aliasedSuperMembers.contains(member); |
| 740 } | 744 } |
| 741 | 745 |
| 742 void resolveNativeElement(MemberElement element, NativeRegistry registry) { | 746 void resolveNativeElement(MemberElement element, NativeRegistry registry) { |
| 743 if (element.isFunction || | 747 if (element.isFunction || |
| 744 element.isConstructor || | 748 element.isConstructor || |
| 745 element.isGetter || | 749 element.isGetter || |
| 746 element.isSetter) { | 750 element.isSetter) { |
| 747 _nativeResolutionEnqueuer.handleMethodAnnotations(element); | 751 _nativeResolutionEnqueuer.handleMethodAnnotations(element); |
| 748 if (nativeData.isNativeMember(element)) { | 752 if (nativeClassData.isNativeMember(element)) { |
| 749 native.NativeBehavior behavior = | 753 native.NativeBehavior behavior = |
| 750 native.NativeBehavior.ofMethodElement(element, compiler); | 754 native.NativeBehavior.ofMethodElement(element, compiler); |
| 751 nativeDataBuilder.setNativeMethodBehavior(element, behavior); | 755 nativeDataBuilder.setNativeMethodBehavior(element, behavior); |
| 752 registry.registerNativeData(behavior); | 756 registry.registerNativeData(behavior); |
| 753 } | 757 } |
| 754 } else if (element.isField) { | 758 } else if (element.isField) { |
| 755 _nativeResolutionEnqueuer.handleFieldAnnotations(element); | 759 _nativeResolutionEnqueuer.handleFieldAnnotations(element); |
| 756 if (nativeData.isNativeMember(element)) { | 760 if (nativeClassData.isNativeMember(element)) { |
| 757 native.NativeBehavior fieldLoadBehavior = | 761 native.NativeBehavior fieldLoadBehavior = |
| 758 native.NativeBehavior.ofFieldElementLoad(element, compiler); | 762 native.NativeBehavior.ofFieldElementLoad(element, compiler); |
| 759 native.NativeBehavior fieldStoreBehavior = | 763 native.NativeBehavior fieldStoreBehavior = |
| 760 native.NativeBehavior.ofFieldElementStore(element, compiler); | 764 native.NativeBehavior.ofFieldElementStore(element, compiler); |
| 761 nativeDataBuilder.setNativeFieldLoadBehavior( | 765 nativeDataBuilder.setNativeFieldLoadBehavior( |
| 762 element, fieldLoadBehavior); | 766 element, fieldLoadBehavior); |
| 763 nativeDataBuilder.setNativeFieldStoreBehavior( | 767 nativeDataBuilder.setNativeFieldStoreBehavior( |
| 764 element, fieldStoreBehavior); | 768 element, fieldStoreBehavior); |
| 765 | 769 |
| 766 // TODO(sra): Process fields for storing separately. | 770 // TODO(sra): Process fields for storing separately. |
| (...skipping 193 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 960 noSuchMethodRegistry.isComplex(element); | 964 noSuchMethodRegistry.isComplex(element); |
| 961 | 965 |
| 962 /// Creates an [Enqueuer] for code generation specific to this backend. | 966 /// Creates an [Enqueuer] for code generation specific to this backend. |
| 963 CodegenEnqueuer createCodegenEnqueuer( | 967 CodegenEnqueuer createCodegenEnqueuer( |
| 964 CompilerTask task, Compiler compiler, ClosedWorld closedWorld) { | 968 CompilerTask task, Compiler compiler, ClosedWorld closedWorld) { |
| 965 return new CodegenEnqueuer( | 969 return new CodegenEnqueuer( |
| 966 task, | 970 task, |
| 967 compiler.options, | 971 compiler.options, |
| 968 const TreeShakingEnqueuerStrategy(), | 972 const TreeShakingEnqueuerStrategy(), |
| 969 new CodegenWorldBuilderImpl( | 973 new CodegenWorldBuilderImpl( |
| 970 this, closedWorld, const TypeMaskStrategy()), | 974 nativeClassData, closedWorld, const TypeMaskStrategy()), |
| 971 new CodegenWorkItemBuilder(this, compiler.options), | 975 new CodegenWorkItemBuilder(this, compiler.options), |
| 972 new CodegenEnqueuerListener( | 976 new CodegenEnqueuerListener( |
| 973 compiler.dumpInfoTask, | 977 compiler.dumpInfoTask, |
| 974 compiler.elementEnvironment, | 978 compiler.elementEnvironment, |
| 975 commonElements, | 979 commonElements, |
| 976 helpers, | 980 helpers, |
| 977 impacts, | 981 impacts, |
| 978 backendUsage, | 982 backendUsage, |
| 979 rtiNeed, | 983 rtiNeed, |
| 980 mirrorsData, | 984 mirrorsData, |
| (...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1056 compiler.dumpInfoTask.registerImpact(element, worldImpact); | 1060 compiler.dumpInfoTask.registerImpact(element, worldImpact); |
| 1057 return worldImpact; | 1061 return worldImpact; |
| 1058 } | 1062 } |
| 1059 | 1063 |
| 1060 native.NativeEnqueuer get nativeResolutionEnqueuer => | 1064 native.NativeEnqueuer get nativeResolutionEnqueuer => |
| 1061 _nativeResolutionEnqueuer; | 1065 _nativeResolutionEnqueuer; |
| 1062 | 1066 |
| 1063 native.NativeEnqueuer get nativeCodegenEnqueuer => _nativeCodegenEnqueuer; | 1067 native.NativeEnqueuer get nativeCodegenEnqueuer => _nativeCodegenEnqueuer; |
| 1064 | 1068 |
| 1065 ClassElement defaultSuperclass(ClassElement element) { | 1069 ClassElement defaultSuperclass(ClassElement element) { |
| 1066 if (nativeData.isJsInterop(element)) { | 1070 if (nativeClassData.isJsInteropClass(element)) { |
| 1067 return helpers.jsJavaScriptObjectClass; | 1071 return helpers.jsJavaScriptObjectClass; |
| 1068 } | 1072 } |
| 1069 // Native classes inherit from Interceptor. | 1073 // Native classes inherit from Interceptor. |
| 1070 return nativeData.isNativeClass(element) | 1074 return nativeClassData.isNativeClass(element) |
| 1071 ? helpers.jsInterceptorClass | 1075 ? helpers.jsInterceptorClass |
| 1072 : commonElements.objectClass; | 1076 : commonElements.objectClass; |
| 1073 } | 1077 } |
| 1074 | 1078 |
| 1075 /** | 1079 /** |
| 1076 * Unit test hook that returns code of an element as a String. | 1080 * Unit test hook that returns code of an element as a String. |
| 1077 * | 1081 * |
| 1078 * Invariant: [element] must be a declaration element. | 1082 * Invariant: [element] must be a declaration element. |
| 1079 */ | 1083 */ |
| 1080 String getGeneratedCode(Element element) { | 1084 String getGeneratedCode(Element element) { |
| (...skipping 458 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1539 // TODO(johnniwinther): Allow emptying when serialization has been | 1543 // TODO(johnniwinther): Allow emptying when serialization has been |
| 1540 // performed. | 1544 // performed. |
| 1541 resolution.emptyCache(); | 1545 resolution.emptyCache(); |
| 1542 } | 1546 } |
| 1543 } | 1547 } |
| 1544 } | 1548 } |
| 1545 | 1549 |
| 1546 class JavaScriptBackendClasses implements BackendClasses { | 1550 class JavaScriptBackendClasses implements BackendClasses { |
| 1547 final ElementEnvironment _env; | 1551 final ElementEnvironment _env; |
| 1548 final BackendHelpers helpers; | 1552 final BackendHelpers helpers; |
| 1549 final NativeData _nativeData; | 1553 final NativeClassData _nativeData; |
| 1550 | 1554 |
| 1551 JavaScriptBackendClasses(this._env, this.helpers, this._nativeData); | 1555 JavaScriptBackendClasses(this._env, this.helpers, this._nativeData); |
| 1552 | 1556 |
| 1553 ClassElement get intClass => helpers.jsIntClass; | 1557 ClassElement get intClass => helpers.jsIntClass; |
| 1554 ClassElement get uint32Class => helpers.jsUInt32Class; | 1558 ClassElement get uint32Class => helpers.jsUInt32Class; |
| 1555 ClassElement get uint31Class => helpers.jsUInt31Class; | 1559 ClassElement get uint31Class => helpers.jsUInt31Class; |
| 1556 ClassElement get positiveIntClass => helpers.jsPositiveIntClass; | 1560 ClassElement get positiveIntClass => helpers.jsPositiveIntClass; |
| 1557 ClassElement get doubleClass => helpers.jsDoubleClass; | 1561 ClassElement get doubleClass => helpers.jsDoubleClass; |
| 1558 ClassElement get numClass => helpers.jsNumberClass; | 1562 ClassElement get numClass => helpers.jsNumberClass; |
| 1559 ClassElement get stringClass => helpers.jsStringClass; | 1563 ClassElement get stringClass => helpers.jsStringClass; |
| (...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1651 return _backend.isDefaultNoSuchMethod(element); | 1655 return _backend.isDefaultNoSuchMethod(element); |
| 1652 } | 1656 } |
| 1653 | 1657 |
| 1654 @override | 1658 @override |
| 1655 ClassElement defaultSuperclass(ClassElement element) { | 1659 ClassElement defaultSuperclass(ClassElement element) { |
| 1656 return _backend.defaultSuperclass(element); | 1660 return _backend.defaultSuperclass(element); |
| 1657 } | 1661 } |
| 1658 | 1662 |
| 1659 @override | 1663 @override |
| 1660 bool isNativeClass(ClassEntity element) => | 1664 bool isNativeClass(ClassEntity element) => |
| 1661 _backend.nativeData.isNativeClass(element); | 1665 _backend.nativeClassData.isNativeClass(element); |
| 1662 | 1666 |
| 1663 @override | 1667 @override |
| 1664 bool isForeign(Element element) => _backend.isForeign(element); | 1668 bool isForeign(Element element) => _backend.isForeign(element); |
| 1665 } | 1669 } |
| OLD | NEW |