Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(825)

Side by Side Diff: pkg/compiler/lib/src/native/behavior.dart

Issue 1457383003: Alternative fix for the js-interop crash. (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Created 5 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2014, 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 part of native; 5 part of native;
6 6
7 /// This class is a temporary work-around until we get a more powerful DartType. 7 /// This class is a temporary work-around until we get a more powerful DartType.
8 class SpecialType { 8 class SpecialType {
9 final String name; 9 final String name;
10 const SpecialType._(this.name); 10 const SpecialType._(this.name);
(...skipping 627 matching lines...) Expand 10 before | Expand all | Expand 10 after
638 resolver, 638 resolver,
639 isBuiltin: false, 639 isBuiltin: false,
640 validTags: const ['returns', 'creates']); 640 validTags: const ['returns', 'creates']);
641 641
642 return behavior; 642 return behavior;
643 } 643 }
644 644
645 static NativeBehavior ofMethod(FunctionElement method, Compiler compiler) { 645 static NativeBehavior ofMethod(FunctionElement method, Compiler compiler) {
646 FunctionType type = method.computeType(compiler.resolution); 646 FunctionType type = method.computeType(compiler.resolution);
647 var behavior = new NativeBehavior(); 647 var behavior = new NativeBehavior();
648 behavior.typesReturned.add(type.returnType); 648 var returnType = type.returnType;
649 bool isInterop = compiler.backend.isJsInterop(method);
650 // Note: For dart:html and other internal libraries we maintain, we can
651 // trust the return type and use it to limit what we enqueue. We have to
652 // be more conservative about JS interop types and assume they can return
653 // anything (unless the user provides the experimental flag to trust the
654 // type of js-interop APIs). We do restrict the allocation effects and say
655 // that interop calls create only interop types (which may be unsound if
656 // an interop call returns a DOM type and declares a dynamic return type,
657 // but otherwise we would include a lot of code by default).
658 // TODO(sigmund,sra): consider doing something better for numeric types.
659 behavior.typesReturned.add(
660 !isInterop || compiler.trustJSInteropTypeAnnotations ? returnType
661 : const DynamicType());
649 if (!type.returnType.isVoid) { 662 if (!type.returnType.isVoid) {
650 // Declared types are nullable. 663 // Declared types are nullable.
651 behavior.typesReturned.add(compiler.coreTypes.nullType); 664 behavior.typesReturned.add(compiler.coreTypes.nullType);
652 } 665 }
653 behavior._capture(type, compiler.resolution); 666 behavior._capture(type, compiler.resolution,
667 isInterop: isInterop, compiler: compiler);
654 668
655 // TODO(sra): Optional arguments are currently missing from the 669 // TODO(sra): Optional arguments are currently missing from the
656 // DartType. This should be fixed so the following work-around can be 670 // DartType. This should be fixed so the following work-around can be
657 // removed. 671 // removed.
658 method.functionSignature.forEachOptionalParameter( 672 method.functionSignature.forEachOptionalParameter(
659 (ParameterElement parameter) { 673 (ParameterElement parameter) {
660 behavior._escape(parameter.type, compiler.resolution); 674 behavior._escape(parameter.type, compiler.resolution);
661 }); 675 });
662 676
663 behavior._overrideWithAnnotations(method, compiler); 677 behavior._overrideWithAnnotations(method, compiler);
664 return behavior; 678 return behavior;
665 } 679 }
666 680
667 static NativeBehavior ofFieldLoad(MemberElement field, Compiler compiler) { 681 static NativeBehavior ofFieldLoad(MemberElement field, Compiler compiler) {
668 Resolution resolution = compiler.resolution; 682 Resolution resolution = compiler.resolution;
669 DartType type = field.computeType(resolution); 683 DartType type = field.computeType(resolution);
670 var behavior = new NativeBehavior(); 684 var behavior = new NativeBehavior();
671 behavior.typesReturned.add(type); 685 bool isInterop = compiler.backend.isJsInterop(field);
686 // TODO(sigmund,sra): consider doing something better for numeric types.
687 behavior.typesReturned.add(
688 !isInterop || compiler.trustJSInteropTypeAnnotations ? type
689 : const DynamicType());
672 // Declared types are nullable. 690 // Declared types are nullable.
673 behavior.typesReturned.add(resolution.coreTypes.nullType); 691 behavior.typesReturned.add(resolution.coreTypes.nullType);
674 behavior._capture(type, resolution); 692 behavior._capture(type, resolution,
693 isInterop: isInterop, compiler: compiler);
675 behavior._overrideWithAnnotations(field, compiler); 694 behavior._overrideWithAnnotations(field, compiler);
676 return behavior; 695 return behavior;
677 } 696 }
678 697
679 static NativeBehavior ofFieldStore(MemberElement field, Compiler compiler) { 698 static NativeBehavior ofFieldStore(MemberElement field, Compiler compiler) {
680 Resolution resolution = compiler.resolution; 699 Resolution resolution = compiler.resolution;
681 DartType type = field.computeType(resolution); 700 DartType type = field.computeType(resolution);
682 var behavior = new NativeBehavior(); 701 var behavior = new NativeBehavior();
683 behavior._escape(type, resolution); 702 behavior._escape(type, resolution);
684 // We don't override the default behaviour - the annotations apply to 703 // We don't override the default behaviour - the annotations apply to
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after
758 _escape(functionType.returnType, resolution); 777 _escape(functionType.returnType, resolution);
759 for (DartType parameter in functionType.parameterTypes) { 778 for (DartType parameter in functionType.parameterTypes) {
760 _capture(parameter, resolution); 779 _capture(parameter, resolution);
761 } 780 }
762 } 781 }
763 } 782 }
764 783
765 /// Models the behavior of Dart code receiving instances and methods of [type] 784 /// Models the behavior of Dart code receiving instances and methods of [type]
766 /// from native code. We usually start the analysis by capturing a native 785 /// from native code. We usually start the analysis by capturing a native
767 /// method that has been used. 786 /// method that has been used.
768 void _capture(DartType type, Resolution resolution) { 787 ///
788 /// We assume that JS-interop APIs cannot instantiate Dart types or
789 /// non-JSInterop native types.
790 void _capture(DartType type, Resolution resolution,
791 {bool isInterop: false, Compiler compiler}) {
769 type.computeUnaliased(resolution); 792 type.computeUnaliased(resolution);
770 type = type.unaliased; 793 type = type.unaliased;
771 if (type is FunctionType) { 794 if (type is FunctionType) {
772 FunctionType functionType = type; 795 FunctionType functionType = type;
773 _capture(functionType.returnType, resolution); 796 _capture(functionType.returnType, resolution,
797 isInterop: isInterop, compiler: compiler);
774 for (DartType parameter in functionType.parameterTypes) { 798 for (DartType parameter in functionType.parameterTypes) {
775 _escape(parameter, resolution); 799 _escape(parameter, resolution);
776 } 800 }
777 } else { 801 } else {
778 typesInstantiated.add(type); 802 DartType instantiated = null;
803 JavaScriptBackend backend = compiler?.backend;
804 if (!isInterop) {
805 typesInstantiated.add(type);
806 } else {
807 if (type.element != null && backend.isNative(type.element)) {
808 // Any declared native or interop type (isNative implies isJsInterop)
809 // is assumed to be allocated.
810 typesInstantiated.add(type);
811 }
812
813 if (!compiler.trustJSInteropTypeAnnotations ||
814 type.isDynamic || type.isObject) {
815 // By saying that only JS-interop types can be created, we prevent
816 // pulling in every other native type (e.g. all of dart:html) when a
817 // JS interop API returns dynamic or when we don't trust the type
818 // annotations. This means that to some degree we still use the return
819 // type to decide whether to include native types, even if we don't
820 // trust the type annotation.
821 typesInstantiated.add(
822 backend.helpers.jsJavaScriptObjectClass.thisType);
823 } else {
824 // Otherwise, when the declared type is a Dart type, we do not
825 // register an allocation because we assume it cannot be instantiated
826 // from within the JS-interop code. It must have escaped from another
827 // API.
828 }
829 }
779 } 830 }
780 } 831 }
781 832
782 static dynamic _parseType( 833 static dynamic _parseType(
783 String typeString, 834 String typeString,
784 Parsing parsing, 835 Parsing parsing,
785 lookup(name), 836 lookup(name),
786 locationNodeOrElement) { 837 locationNodeOrElement) {
787 DiagnosticReporter reporter = parsing.reporter; 838 DiagnosticReporter reporter = parsing.reporter;
788 if (typeString == '=Object') return SpecialType.JsObject; 839 if (typeString == '=Object') return SpecialType.JsObject;
(...skipping 21 matching lines...) Expand all
810 MessageKind.GENERIC, 861 MessageKind.GENERIC,
811 {'text': "Type '$typeString' not found."}); 862 {'text': "Type '$typeString' not found."});
812 return const DynamicType(); 863 return const DynamicType();
813 } 864 }
814 865
815 static _errorNode(locationNodeOrElement, Parsing parsing) { 866 static _errorNode(locationNodeOrElement, Parsing parsing) {
816 if (locationNodeOrElement is Node) return locationNodeOrElement; 867 if (locationNodeOrElement is Node) return locationNodeOrElement;
817 return locationNodeOrElement.parseNode(parsing); 868 return locationNodeOrElement.parseNode(parsing);
818 } 869 }
819 } 870 }
OLDNEW
« no previous file with comments | « pkg/compiler/lib/src/js_backend/js_interop_analysis.dart ('k') | pkg/compiler/lib/src/ssa/builder.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698