| 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 '../common.dart'; | 7 import '../common.dart'; |
| 8 import '../common/backend_api.dart' | 8 import '../common/backend_api.dart' |
| 9 show ForeignResolver, NativeRegistry, ImpactTransformer; | 9 show ForeignResolver, NativeRegistry, ImpactTransformer; |
| 10 import '../common/codegen.dart' show CodegenWorkItem; | 10 import '../common/codegen.dart' show CodegenWorkItem; |
| (...skipping 335 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 346 /// called. When TRACE_METHOD is 'console' this will be logged | 346 /// called. When TRACE_METHOD is 'console' this will be logged |
| 347 /// directly in the JavaScript console. When TRACE_METHOD is 'post' the | 347 /// directly in the JavaScript console. When TRACE_METHOD is 'post' the |
| 348 /// information will be sent to a server via a POST request. | 348 /// information will be sent to a server via a POST request. |
| 349 static const String TRACE_METHOD = const String.fromEnvironment('traceCalls'); | 349 static const String TRACE_METHOD = const String.fromEnvironment('traceCalls'); |
| 350 static const bool TRACE_CALLS = | 350 static const bool TRACE_CALLS = |
| 351 TRACE_METHOD == 'post' || TRACE_METHOD == 'console'; | 351 TRACE_METHOD == 'post' || TRACE_METHOD == 'console'; |
| 352 | 352 |
| 353 Namer _namer; | 353 Namer _namer; |
| 354 | 354 |
| 355 Namer get namer { | 355 Namer get namer { |
| 356 assert(invariant(NO_LOCATION_SPANNABLE, _namer != null, | 356 assert(_namer != null, |
| 357 message: "Namer has not been created yet.")); | 357 failedAt(NO_LOCATION_SPANNABLE, "Namer has not been created yet.")); |
| 358 return _namer; | 358 return _namer; |
| 359 } | 359 } |
| 360 | 360 |
| 361 /** | 361 /** |
| 362 * Set of classes whose `operator ==` methods handle `null` themselves. | 362 * Set of classes whose `operator ==` methods handle `null` themselves. |
| 363 */ | 363 */ |
| 364 final Set<ClassEntity> specialOperatorEqClasses = new Set<ClassEntity>(); | 364 final Set<ClassEntity> specialOperatorEqClasses = new Set<ClassEntity>(); |
| 365 | 365 |
| 366 List<CompilerTask> get tasks { | 366 List<CompilerTask> get tasks { |
| 367 List<CompilerTask> result = functionCompiler.tasks; | 367 List<CompilerTask> result = functionCompiler.tasks; |
| (...skipping 161 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 529 | 529 |
| 530 CommonElements get commonElements => compiler.commonElements; | 530 CommonElements get commonElements => compiler.commonElements; |
| 531 | 531 |
| 532 Resolution get resolution => compiler.resolution; | 532 Resolution get resolution => compiler.resolution; |
| 533 | 533 |
| 534 Target get target => _target; | 534 Target get target => _target; |
| 535 | 535 |
| 536 /// Resolution support for generating table of interceptors and | 536 /// Resolution support for generating table of interceptors and |
| 537 /// constructors for custom elements. | 537 /// constructors for custom elements. |
| 538 CustomElementsResolutionAnalysis get customElementsResolutionAnalysis { | 538 CustomElementsResolutionAnalysis get customElementsResolutionAnalysis { |
| 539 assert(invariant( | 539 assert( |
| 540 NO_LOCATION_SPANNABLE, _customElementsResolutionAnalysis != null, | 540 _customElementsResolutionAnalysis != null, |
| 541 message: "CustomElementsResolutionAnalysis has not been created yet.")); | 541 failedAt(NO_LOCATION_SPANNABLE, |
| 542 "CustomElementsResolutionAnalysis has not been created yet.")); |
| 542 return _customElementsResolutionAnalysis; | 543 return _customElementsResolutionAnalysis; |
| 543 } | 544 } |
| 544 | 545 |
| 545 /// Codegen support for generating table of interceptors and | 546 /// Codegen support for generating table of interceptors and |
| 546 /// constructors for custom elements. | 547 /// constructors for custom elements. |
| 547 CustomElementsCodegenAnalysis get customElementsCodegenAnalysis { | 548 CustomElementsCodegenAnalysis get customElementsCodegenAnalysis { |
| 548 assert(invariant( | 549 assert( |
| 549 NO_LOCATION_SPANNABLE, _customElementsCodegenAnalysis != null, | 550 _customElementsCodegenAnalysis != null, |
| 550 message: "CustomElementsCodegenAnalysis has not been created yet.")); | 551 failedAt(NO_LOCATION_SPANNABLE, |
| 552 "CustomElementsCodegenAnalysis has not been created yet.")); |
| 551 return _customElementsCodegenAnalysis; | 553 return _customElementsCodegenAnalysis; |
| 552 } | 554 } |
| 553 | 555 |
| 554 NativeBasicData get nativeBasicData { | 556 NativeBasicData get nativeBasicData { |
| 555 assert(invariant(NO_LOCATION_SPANNABLE, _nativeBasicData != null, | 557 assert( |
| 556 message: "NativeBasicData has not been computed yet.")); | 558 _nativeBasicData != null, |
| 559 failedAt(NO_LOCATION_SPANNABLE, |
| 560 "NativeBasicData has not been computed yet.")); |
| 557 return _nativeBasicData; | 561 return _nativeBasicData; |
| 558 } | 562 } |
| 559 | 563 |
| 560 NativeBasicDataBuilder get nativeBasicDataBuilder => _nativeBasicDataBuilder; | 564 NativeBasicDataBuilder get nativeBasicDataBuilder => _nativeBasicDataBuilder; |
| 561 | 565 |
| 562 /// Resolution analysis for tracking reflective access to type variables. | 566 /// Resolution analysis for tracking reflective access to type variables. |
| 563 TypeVariableResolutionAnalysis get typeVariableResolutionAnalysis { | 567 TypeVariableResolutionAnalysis get typeVariableResolutionAnalysis { |
| 564 assert(invariant( | 568 assert( |
| 565 NO_LOCATION_SPANNABLE, _typeVariableCodegenAnalysis == null, | 569 _typeVariableCodegenAnalysis == null, |
| 566 message: "TypeVariableHandler has already been created.")); | 570 failedAt(NO_LOCATION_SPANNABLE, |
| 571 "TypeVariableHandler has already been created.")); |
| 567 return _typeVariableResolutionAnalysis; | 572 return _typeVariableResolutionAnalysis; |
| 568 } | 573 } |
| 569 | 574 |
| 570 /// Codegen handler for reflective access to type variables. | 575 /// Codegen handler for reflective access to type variables. |
| 571 TypeVariableCodegenAnalysis get typeVariableCodegenAnalysis { | 576 TypeVariableCodegenAnalysis get typeVariableCodegenAnalysis { |
| 572 assert(invariant( | 577 assert( |
| 573 NO_LOCATION_SPANNABLE, _typeVariableCodegenAnalysis != null, | 578 _typeVariableCodegenAnalysis != null, |
| 574 message: "TypeVariableHandler has not been created yet.")); | 579 failedAt(NO_LOCATION_SPANNABLE, |
| 580 "TypeVariableHandler has not been created yet.")); |
| 575 return _typeVariableCodegenAnalysis; | 581 return _typeVariableCodegenAnalysis; |
| 576 } | 582 } |
| 577 | 583 |
| 578 MirrorsData get mirrorsData => _mirrorsData; | 584 MirrorsData get mirrorsData => _mirrorsData; |
| 579 | 585 |
| 580 MirrorsDataBuilder get mirrorsDataBuilder => _mirrorsData; | 586 MirrorsDataBuilder get mirrorsDataBuilder => _mirrorsData; |
| 581 | 587 |
| 582 /// Resolution support for computing reflectable elements. | 588 /// Resolution support for computing reflectable elements. |
| 583 MirrorsResolutionAnalysis get mirrorsResolutionAnalysis => | 589 MirrorsResolutionAnalysis get mirrorsResolutionAnalysis => |
| 584 _mirrorsResolutionAnalysis; | 590 _mirrorsResolutionAnalysis; |
| 585 | 591 |
| 586 /// Codegen support for computing reflectable elements. | 592 /// Codegen support for computing reflectable elements. |
| 587 MirrorsCodegenAnalysis get mirrorsCodegenAnalysis { | 593 MirrorsCodegenAnalysis get mirrorsCodegenAnalysis { |
| 588 assert(invariant(NO_LOCATION_SPANNABLE, _mirrorsCodegenAnalysis != null, | 594 assert( |
| 589 message: "MirrorsCodegenAnalysis has not been created yet.")); | 595 _mirrorsCodegenAnalysis != null, |
| 596 failedAt(NO_LOCATION_SPANNABLE, |
| 597 "MirrorsCodegenAnalysis has not been created yet.")); |
| 590 return _mirrorsCodegenAnalysis; | 598 return _mirrorsCodegenAnalysis; |
| 591 } | 599 } |
| 592 | 600 |
| 593 /// Codegen support for tree-shaking entries of `LookupMap`. | 601 /// Codegen support for tree-shaking entries of `LookupMap`. |
| 594 LookupMapAnalysis get lookupMapAnalysis { | 602 LookupMapAnalysis get lookupMapAnalysis { |
| 595 assert(invariant(NO_LOCATION_SPANNABLE, _lookupMapAnalysis != null, | 603 assert( |
| 596 message: "LookupMapAnalysis has not been created yet.")); | 604 _lookupMapAnalysis != null, |
| 605 failedAt(NO_LOCATION_SPANNABLE, |
| 606 "LookupMapAnalysis has not been created yet.")); |
| 597 return _lookupMapAnalysis; | 607 return _lookupMapAnalysis; |
| 598 } | 608 } |
| 599 | 609 |
| 600 OneShotInterceptorData get oneShotInterceptorData { | 610 OneShotInterceptorData get oneShotInterceptorData { |
| 601 assert(invariant(NO_LOCATION_SPANNABLE, _oneShotInterceptorData != null, | 611 assert( |
| 602 message: "OneShotInterceptorData has not been prepared yet.")); | 612 _oneShotInterceptorData != null, |
| 613 failedAt(NO_LOCATION_SPANNABLE, |
| 614 "OneShotInterceptorData has not been prepared yet.")); |
| 603 return _oneShotInterceptorData; | 615 return _oneShotInterceptorData; |
| 604 } | 616 } |
| 605 | 617 |
| 606 RuntimeTypesNeed get rtiNeed { | 618 RuntimeTypesNeed get rtiNeed { |
| 607 assert(invariant(NO_LOCATION_SPANNABLE, _rtiNeed != null, | 619 assert( |
| 608 message: "RuntimeTypesNeed has not been computed yet.")); | 620 _rtiNeed != null, |
| 621 failedAt(NO_LOCATION_SPANNABLE, |
| 622 "RuntimeTypesNeed has not been computed yet.")); |
| 609 return _rtiNeed; | 623 return _rtiNeed; |
| 610 } | 624 } |
| 611 | 625 |
| 612 RuntimeTypesNeedBuilder get rtiNeedBuilder { | 626 RuntimeTypesNeedBuilder get rtiNeedBuilder { |
| 613 assert(invariant(NO_LOCATION_SPANNABLE, _rtiNeed == null, | 627 assert( |
| 614 message: "RuntimeTypesNeed has already been computed.")); | 628 _rtiNeed == null, |
| 629 failedAt(NO_LOCATION_SPANNABLE, |
| 630 "RuntimeTypesNeed has already been computed.")); |
| 615 return _rtiNeedBuilder; | 631 return _rtiNeedBuilder; |
| 616 } | 632 } |
| 617 | 633 |
| 618 RuntimeTypesChecksBuilder get rtiChecksBuilder { | 634 RuntimeTypesChecksBuilder get rtiChecksBuilder { |
| 619 assert(invariant(NO_LOCATION_SPANNABLE, !_rti.rtiChecksBuilderClosed, | 635 assert( |
| 620 message: "RuntimeTypesChecks has already been computed.")); | 636 !_rti.rtiChecksBuilderClosed, |
| 637 failedAt(NO_LOCATION_SPANNABLE, |
| 638 "RuntimeTypesChecks has already been computed.")); |
| 621 return _rti; | 639 return _rti; |
| 622 } | 640 } |
| 623 | 641 |
| 624 RuntimeTypesSubstitutions get rtiSubstitutions => _rti; | 642 RuntimeTypesSubstitutions get rtiSubstitutions => _rti; |
| 625 | 643 |
| 626 RuntimeTypesEncoder get rtiEncoder { | 644 RuntimeTypesEncoder get rtiEncoder { |
| 627 assert(invariant(NO_LOCATION_SPANNABLE, _rtiEncoder != null, | 645 assert( |
| 628 message: "RuntimeTypesEncoder has not been created.")); | 646 _rtiEncoder != null, |
| 647 failedAt(NO_LOCATION_SPANNABLE, |
| 648 "RuntimeTypesEncoder has not been created.")); |
| 629 return _rtiEncoder; | 649 return _rtiEncoder; |
| 630 } | 650 } |
| 631 | 651 |
| 632 CheckedModeHelpers get checkedModeHelpers => _checkedModeHelpers; | 652 CheckedModeHelpers get checkedModeHelpers => _checkedModeHelpers; |
| 633 | 653 |
| 634 /// Returns constant environment for the JavaScript interpretation of the | 654 /// Returns constant environment for the JavaScript interpretation of the |
| 635 /// constants. | 655 /// constants. |
| 636 JavaScriptConstantCompiler get constants { | 656 JavaScriptConstantCompiler get constants { |
| 637 return constantCompilerTask.jsConstantCompiler; | 657 return constantCompilerTask.jsConstantCompiler; |
| 638 } | 658 } |
| (...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 713 ClassEntity interceptorClass) { | 733 ClassEntity interceptorClass) { |
| 714 if (interceptorClass == null) return; | 734 if (interceptorClass == null) return; |
| 715 ClassEntity objectClass = commonElements.objectClass; | 735 ClassEntity objectClass = commonElements.objectClass; |
| 716 compiler.elementEnvironment.forEachClassMember(objectClass, | 736 compiler.elementEnvironment.forEachClassMember(objectClass, |
| 717 (_, MemberEntity member) { | 737 (_, MemberEntity member) { |
| 718 if (member.isConstructor) return; | 738 if (member.isConstructor) return; |
| 719 MemberEntity interceptorMember = compiler.elementEnvironment | 739 MemberEntity interceptorMember = compiler.elementEnvironment |
| 720 .lookupClassMember(interceptorClass, member.name); | 740 .lookupClassMember(interceptorClass, member.name); |
| 721 // Interceptors must override all Object methods due to calling convention | 741 // Interceptors must override all Object methods due to calling convention |
| 722 // differences. | 742 // differences. |
| 723 assert(invariant(interceptorMember, | 743 assert( |
| 724 interceptorMember.enclosingClass == interceptorClass, | 744 interceptorMember.enclosingClass == interceptorClass, |
| 725 message: | 745 failedAt( |
| 746 interceptorMember, |
| 726 "Member ${member.name} not overridden in ${interceptorClass}. " | 747 "Member ${member.name} not overridden in ${interceptorClass}. " |
| 727 "Found $interceptorMember from " | 748 "Found $interceptorMember from " |
| 728 "${interceptorMember.enclosingClass}.")); | 749 "${interceptorMember.enclosingClass}.")); |
| 729 }); | 750 }); |
| 730 } | 751 } |
| 731 | 752 |
| 732 /// Called before processing of the resolution queue is started. | 753 /// Called before processing of the resolution queue is started. |
| 733 void onResolutionStart(ResolutionEnqueuer enqueuer) { | 754 void onResolutionStart(ResolutionEnqueuer enqueuer) { |
| 734 // TODO(johnniwinther): Avoid the compiler.elementEnvironment.getThisType | 755 // TODO(johnniwinther): Avoid the compiler.elementEnvironment.getThisType |
| 735 // calls. Currently needed to ensure resolution of the classes for various | 756 // calls. Currently needed to ensure resolution of the classes for various |
| (...skipping 221 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 957 ? commonElements.jsInterceptorClass | 978 ? commonElements.jsInterceptorClass |
| 958 : commonElements.objectClass; | 979 : commonElements.objectClass; |
| 959 } | 980 } |
| 960 | 981 |
| 961 /** | 982 /** |
| 962 * Unit test hook that returns code of an element as a String. | 983 * Unit test hook that returns code of an element as a String. |
| 963 * | 984 * |
| 964 * Invariant: [element] must be a declaration element. | 985 * Invariant: [element] must be a declaration element. |
| 965 */ | 986 */ |
| 966 String getGeneratedCode(Element element) { | 987 String getGeneratedCode(Element element) { |
| 967 assert(invariant(element, element.isDeclaration)); | 988 assert(element.isDeclaration, failedAt(element)); |
| 968 return jsAst.prettyPrint(generatedCode[element], compiler.options); | 989 return jsAst.prettyPrint(generatedCode[element], compiler.options); |
| 969 } | 990 } |
| 970 | 991 |
| 971 /// Generates the output and returns the total size of the generated code. | 992 /// Generates the output and returns the total size of the generated code. |
| 972 int assembleProgram(ClosedWorld closedWorld) { | 993 int assembleProgram(ClosedWorld closedWorld) { |
| 973 int programSize = emitter.assembleProgram(namer, closedWorld); | 994 int programSize = emitter.assembleProgram(namer, closedWorld); |
| 974 noSuchMethodRegistry.emitDiagnostic(reporter); | 995 noSuchMethodRegistry.emitDiagnostic(reporter); |
| 975 int totalMethodCount = generatedCode.length; | 996 int totalMethodCount = generatedCode.length; |
| 976 if (totalMethodCount != mirrorsCodegenAnalysis.preMirrorsMethodCount) { | 997 if (totalMethodCount != mirrorsCodegenAnalysis.preMirrorsMethodCount) { |
| 977 int mirrorCount = | 998 int mirrorCount = |
| (...skipping 418 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1396 | 1417 |
| 1397 bool canUseAliasedSuperMember(MemberEntity member, Selector selector) { | 1418 bool canUseAliasedSuperMember(MemberEntity member, Selector selector) { |
| 1398 return !selector.isGetter; | 1419 return !selector.isGetter; |
| 1399 } | 1420 } |
| 1400 | 1421 |
| 1401 /// Returns `true` if [member] is called from a subclass via `super`. | 1422 /// Returns `true` if [member] is called from a subclass via `super`. |
| 1402 bool isAliasedSuperMember(MemberEntity member) { | 1423 bool isAliasedSuperMember(MemberEntity member) { |
| 1403 return _aliasedSuperMembers.contains(member); | 1424 return _aliasedSuperMembers.contains(member); |
| 1404 } | 1425 } |
| 1405 } | 1426 } |
| OLD | NEW |