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 |