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

Side by Side Diff: sdk/lib/_internal/compiler/implementation/js_backend/backend.dart

Issue 12045019: Fix braino with return types, and make sure the compiler knows we might call noSuchMethod with a JS… (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 7 years, 11 months 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 | Annotate | Revision Log
« no previous file with comments | « no previous file | tests/language/no_such_method2_test.dart » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 part of js_backend; 5 part of js_backend;
6 6
7 typedef void Recompile(Element element); 7 typedef void Recompile(Element element);
8 8
9 class ReturnInfo { 9 class ReturnInfo {
10 HType returnType; 10 HType returnType;
11 List<Element> compiledFunctions; 11 List<Element> compiledFunctions;
12 12
13 ReturnInfo(HType this.returnType) 13 ReturnInfo(HType this.returnType)
14 : compiledFunctions = new List<Element>(); 14 : compiledFunctions = new List<Element>();
15 15
16 ReturnInfo.unknownType() 16 ReturnInfo.unknownType()
17 : this.returnType = null, 17 : this.returnType = HType.UNKNOWN,
18 compiledFunctions = new List<Element>(); 18 compiledFunctions = new List<Element>();
19 19
20 void update(HType type, Recompile recompile, Compiler compiler) { 20 void update(HType type, Recompile recompile, Compiler compiler) {
21 HType newType = 21 HType newType =
22 returnType != null ? returnType.union(type, compiler) : type; 22 returnType != null ? returnType.union(type, compiler) : type;
23 if (newType != returnType) { 23 if (newType != returnType) {
24 if (returnType == null && identical(newType, HType.UNKNOWN)) { 24 if (returnType == null && identical(newType, HType.UNKNOWN)) {
25 // If the first actual piece of information is not providing any type 25 // If the first actual piece of information is not providing any type
26 // information there is no need to recompile callers. 26 // information there is no need to recompile callers.
27 compiledFunctions.clear(); 27 compiledFunctions.clear();
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after
121 } 121 }
122 return result; 122 return result;
123 } 123 }
124 124
125 static const HTypeList ALL_UNKNOWN = const HTypeList.withAllUnknown(); 125 static const HTypeList ALL_UNKNOWN = const HTypeList.withAllUnknown();
126 126
127 bool get allUnknown => types == null; 127 bool get allUnknown => types == null;
128 bool get hasNamedArguments => namedArguments != null; 128 bool get hasNamedArguments => namedArguments != null;
129 int get length => types.length; 129 int get length => types.length;
130 HType operator[](int index) => types[index]; 130 HType operator[](int index) => types[index];
131 void operator[]=(int index, HType type) { types[index] = type; }
131 132
132 HTypeList union(HTypeList other, Compiler compiler) { 133 HTypeList union(HTypeList other, Compiler compiler) {
133 if (allUnknown) return this; 134 if (allUnknown) return this;
134 if (other.allUnknown) return other; 135 if (other.allUnknown) return other;
135 if (length != other.length) return HTypeList.ALL_UNKNOWN; 136 if (length != other.length) return HTypeList.ALL_UNKNOWN;
136 bool onlyUnknown = true; 137 bool onlyUnknown = true;
137 HTypeList result = this; 138 HTypeList result = this;
138 for (int i = 0; i < length; i++) { 139 for (int i = 0; i < length; i++) {
139 HType newType = this[i].union(other[i], compiler); 140 HType newType = this[i].union(other[i], compiler);
140 if (result == this && newType != this[i]) { 141 if (result == this && newType != this[i]) {
(...skipping 334 matching lines...) Expand 10 before | Expand all | Expand 10 after
475 // When a static is used for anything else than a call target we cannot 476 // When a static is used for anything else than a call target we cannot
476 // infer anything about its parameter types. 477 // infer anything about its parameter types.
477 Element element = node.element; 478 Element element = node.element;
478 assert(invariant(node, element.isDeclaration)); 479 assert(invariant(node, element.isDeclaration));
479 if (optimizedStaticFunctions.contains(element)) { 480 if (optimizedStaticFunctions.contains(element)) {
480 backend.scheduleForRecompilation(element); 481 backend.scheduleForRecompilation(element);
481 } 482 }
482 staticTypeMap[element] = HTypeList.ALL_UNKNOWN; 483 staticTypeMap[element] = HTypeList.ALL_UNKNOWN;
483 } 484 }
484 485
485 void registerDynamicInvocation(HInvokeDynamic node, 486 void registerDynamicInvocation(HTypeList providedTypes, Selector selector) {
486 Selector selector,
487 HTypeMap types) {
488 if (selector.isClosureCall()) { 487 if (selector.isClosureCall()) {
489 // We cannot use the current framework to do optimizations based 488 // We cannot use the current framework to do optimizations based
490 // on the 'call' selector because we are also generating closure 489 // on the 'call' selector because we are also generating closure
491 // calls during the emitter phase, which at this point, does not 490 // calls during the emitter phase, which at this point, does not
492 // track parameter types, nor invalidates optimized methods. 491 // track parameter types, nor invalidates optimized methods.
493 return; 492 return;
494 } 493 }
495 HTypeList providedTypes =
496 new HTypeList.fromDynamicInvocation(node, selector, types);
497 if (!selectorTypeMap.containsKey(selector)) { 494 if (!selectorTypeMap.containsKey(selector)) {
498 selectorTypeMap[selector] = providedTypes; 495 selectorTypeMap[selector] = providedTypes;
499 } else { 496 } else {
500 HTypeList oldTypes = selectorTypeMap[selector]; 497 HTypeList oldTypes = selectorTypeMap[selector];
501 updateTypes(oldTypes, providedTypes, selector, selectorTypeMap); 498 updateTypes(oldTypes, providedTypes, selector, selectorTypeMap);
502 } 499 }
503 500
504 // If we're not compiling, we don't have to do anything. 501 // If we're not compiling, we don't have to do anything.
505 if (compiler.phase != Compiler.PHASE_COMPILING) return; 502 if (compiler.phase != Compiler.PHASE_COMPILING) return;
506 503
(...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after
636 ClassElement jsBoolClass; 633 ClassElement jsBoolClass;
637 ClassElement objectInterceptorClass; 634 ClassElement objectInterceptorClass;
638 Element jsArrayLength; 635 Element jsArrayLength;
639 Element jsStringLength; 636 Element jsStringLength;
640 Element jsArrayRemoveLast; 637 Element jsArrayRemoveLast;
641 Element jsArrayAdd; 638 Element jsArrayAdd;
642 Element jsStringSplit; 639 Element jsStringSplit;
643 Element jsStringConcat; 640 Element jsStringConcat;
644 Element getInterceptorMethod; 641 Element getInterceptorMethod;
645 Element fixedLengthListConstructor; 642 Element fixedLengthListConstructor;
646 bool _interceptorsAreInitialized = false; 643 bool oneClassSeen = false;
kasperl 2013/01/22 13:16:01 firstClassSeen?
ngeoffray 2013/01/22 13:19:42 Senamed to seenAnyClass.
647 644
648 final Namer namer; 645 final Namer namer;
649 646
650 /** 647 /**
651 * Interface used to determine if an object has the JavaScript 648 * Interface used to determine if an object has the JavaScript
652 * indexing behavior. The interface is only visible to specific 649 * indexing behavior. The interface is only visible to specific
653 * libraries. 650 * libraries.
654 */ 651 */
655 ClassElement jsIndexingBehaviorInterface; 652 ClassElement jsIndexingBehaviorInterface;
656 653
(...skipping 179 matching lines...) Expand 10 before | Expand all | Expand 10 after
836 return keys; 833 return keys;
837 }); 834 });
838 return namer.isolateAccess(getInterceptorMethod); 835 return namer.isolateAccess(getInterceptorMethod);
839 } else { 836 } else {
840 String name = namer.getSpecializedName(getInterceptorMethod, classes); 837 String name = namer.getSpecializedName(getInterceptorMethod, classes);
841 specializedGetInterceptors[name] = classes; 838 specializedGetInterceptors[name] = classes;
842 return '${namer.CURRENT_ISOLATE}.$name'; 839 return '${namer.CURRENT_ISOLATE}.$name';
843 } 840 }
844 } 841 }
845 842
843 void initializeNoSuchMethod() {
844 // In case the emitter generates noSuchMethod calls, we need to
845 // make sure all [noSuchMethod] methods know they might take a
846 // [JsInvocationMirror] as parameter.
847 HTypeList types = new HTypeList(1);
848 types[0] = new HType.fromBoundedType(
849 compiler.jsInvocationMirrorClass.computeType(compiler),
850 compiler,
851 false);
852 argumentTypes.registerDynamicInvocation(types, new Selector.noSuchMethod());
853 }
854
846 void registerInstantiatedClass(ClassElement cls, Enqueuer enqueuer) { 855 void registerInstantiatedClass(ClassElement cls, Enqueuer enqueuer) {
856 if (!oneClassSeen) {
857 initializeInterceptorElements();
858 initializeNoSuchMethod();
859 oneClassSeen = true;
860 }
847 ClassElement result = null; 861 ClassElement result = null;
848 if (!_interceptorsAreInitialized) {
849 initializeInterceptorElements();
850 _interceptorsAreInitialized = true;
851 }
852 if (cls == compiler.stringClass) { 862 if (cls == compiler.stringClass) {
853 addInterceptors(jsStringClass, enqueuer); 863 addInterceptors(jsStringClass, enqueuer);
854 } else if (cls == compiler.listClass) { 864 } else if (cls == compiler.listClass) {
855 addInterceptors(jsArrayClass, enqueuer); 865 addInterceptors(jsArrayClass, enqueuer);
856 // The backend will try to optimize array access and use the 866 // The backend will try to optimize array access and use the
857 // `ioore` and `iae` helpers directly. 867 // `ioore` and `iae` helpers directly.
858 enqueuer.registerStaticUse( 868 enqueuer.registerStaticUse(
859 compiler.findHelper(const SourceString('ioore'))); 869 compiler.findHelper(const SourceString('ioore')));
860 enqueuer.registerStaticUse( 870 enqueuer.registerStaticUse(
861 compiler.findHelper(const SourceString('iae'))); 871 compiler.findHelper(const SourceString('iae')));
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after
957 } 967 }
958 } 968 }
959 969
960 /** 970 /**
961 * Register a dynamic invocation and collect the provided types for the 971 * Register a dynamic invocation and collect the provided types for the
962 * named selector. 972 * named selector.
963 */ 973 */
964 void registerDynamicInvocation(HInvokeDynamic node, 974 void registerDynamicInvocation(HInvokeDynamic node,
965 Selector selector, 975 Selector selector,
966 HTypeMap types) { 976 HTypeMap types) {
967 argumentTypes.registerDynamicInvocation(node, selector, types); 977 HTypeList providedTypes =
978 new HTypeList.fromDynamicInvocation(node, selector, types);
979 argumentTypes.registerDynamicInvocation(providedTypes, selector);
968 } 980 }
969 981
970 /** 982 /**
971 * Register a static invocation and collect the provided types for the 983 * Register a static invocation and collect the provided types for the
972 * named selector. 984 * named selector.
973 */ 985 */
974 void registerStaticInvocation(HInvokeStatic node, HTypeMap types) { 986 void registerStaticInvocation(HInvokeStatic node, HTypeMap types) {
975 argumentTypes.registerStaticInvocation(node, types); 987 argumentTypes.registerStaticInvocation(node, types);
976 } 988 }
977 989
(...skipping 164 matching lines...) Expand 10 before | Expand all | Expand 10 after
1142 print("Inferred return types:"); 1154 print("Inferred return types:");
1143 print("----------------------"); 1155 print("----------------------");
1144 dumpReturnTypes(); 1156 dumpReturnTypes();
1145 print(""); 1157 print("");
1146 print("Inferred field types:"); 1158 print("Inferred field types:");
1147 print("------------------------"); 1159 print("------------------------");
1148 fieldTypes.dump(); 1160 fieldTypes.dump();
1149 print(""); 1161 print("");
1150 } 1162 }
1151 } 1163 }
OLDNEW
« no previous file with comments | « no previous file | tests/language/no_such_method2_test.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698