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

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

Issue 11557010: Implement subtype checks on type arguments. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Address Kasper's comments. Created 8 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 | Annotate | Revision Log
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 /** 7 /**
8 * A function element that represents a closure call. The signature is copied 8 * A function element that represents a closure call. The signature is copied
9 * from the given element. 9 * from the given element.
10 */ 10 */
(...skipping 26 matching lines...) Expand all
37 bool needsLazyInitializer = false; 37 bool needsLazyInitializer = false;
38 final Namer namer; 38 final Namer namer;
39 ConstantEmitter constantEmitter; 39 ConstantEmitter constantEmitter;
40 NativeEmitter nativeEmitter; 40 NativeEmitter nativeEmitter;
41 CodeBuffer boundClosureBuffer; 41 CodeBuffer boundClosureBuffer;
42 CodeBuffer mainBuffer; 42 CodeBuffer mainBuffer;
43 /** Shorter access to [isolatePropertiesName]. Both here in the code, as 43 /** Shorter access to [isolatePropertiesName]. Both here in the code, as
44 well as in the generated code. */ 44 well as in the generated code. */
45 String isolateProperties; 45 String isolateProperties;
46 String classesCollector; 46 String classesCollector;
47 Set<ClassElement> cachedNeededClasses;
48 Set<ClassElement> cachedInstantiatedClasses;
47 49
48 String get _ => compiler.enableMinification ? "" : " "; 50 String get _ => compiler.enableMinification ? "" : " ";
49 String get n => compiler.enableMinification ? "" : "\n"; 51 String get n => compiler.enableMinification ? "" : "\n";
50 String get N => compiler.enableMinification ? "\n" : ";\n"; 52 String get N => compiler.enableMinification ? "\n" : ";\n";
51 53
52 /** 54 /**
53 * A cache of closures that are used to closurize instance methods. 55 * A cache of closures that are used to closurize instance methods.
54 * A closure is dynamically bound to the instance used when 56 * A closure is dynamically bound to the instance used when
55 * closurized. 57 * closurized.
56 */ 58 */
(...skipping 693 matching lines...) Expand 10 before | Expand all | Expand 10 after
750 // Emit the noSuchMethod handlers on the Object prototype now, 752 // Emit the noSuchMethod handlers on the Object prototype now,
751 // so that the code in the dynamicFunction helper can find 753 // so that the code in the dynamicFunction helper can find
752 // them. Note that this helper is invoked before analyzing the 754 // them. Note that this helper is invoked before analyzing the
753 // full JS script. 755 // full JS script.
754 if (!nativeEmitter.handleNoSuchMethod) { 756 if (!nativeEmitter.handleNoSuchMethod) {
755 emitNoSuchMethodHandlers(defineInstanceMember); 757 emitNoSuchMethodHandlers(defineInstanceMember);
756 } 758 }
757 } 759 }
758 } 760 }
759 761
762 void emitRuntimeClassesAndTests(CodeBuffer buffer) {
763 JavaScriptBackend backend = compiler.backend;
764 RuntimeTypeInformation rti = backend.rti;
765
766 TypeChecks typeChecks = rti.computeRequiredChecks();
767
768 bool needsHolder(ClassElement cls) {
769 return !neededClasses.contains(cls) || cls.isNative() ||
770 rti.isJsNative(cls);
771 }
772
773 void maybeGenerateHolder(ClassElement cls) {
774 if (!needsHolder(cls)) return;
775
776 String holder = namer.isolateAccess(cls);
777 String name = namer.getName(cls);
778 buffer.add("$holder$_=$_{builtin\$cls:$_'$name'");
ngeoffray 2012/12/13 13:34:58 I think you can share the following code with the
karlklose 2012/12/13 14:37:34 I want to generate the checks for the synthetic ho
779 for (ClassElement check in typeChecks[cls]) {
780 buffer.add(',${_}is\$${namer.getName(check)}:${_}true');
ngeoffray 2012/12/13 13:34:58 Please use namer.operatorIs.
karlklose 2012/12/13 14:37:34 Done.
781 };
782 buffer.add('}$N');
783 }
784
785 // Create representation objects for classes that we do not need a class
ngeoffray 2012/12/13 13:34:58 do not need -> do not have
karlklose 2012/12/13 14:37:34 Done.
786 // definition for (because they are uninstantiated or native).
787 for (ClassElement cls in rti.allArguments) {
788 maybeGenerateHolder(cls);
789 }
790
791 // Add checks to the constructors of instantiated classes.
792 for (ClassElement cls in typeChecks) {
793 if (needsHolder(cls)) {
794 // We already emitted the is-checks in the object definition for this
795 // class.
796 continue;
797 }
798 String holder = namer.isolateAccess(cls);
799 for (ClassElement check in typeChecks[cls]) {
800 buffer.add('$holder.is\$${namer.getName(check)} = true;\n');
ngeoffray 2012/12/13 13:34:58 namer.operatorIs.
karlklose 2012/12/13 14:37:34 Done.
801 };
802 }
803 }
804
760 /** 805 /**
761 * Documentation wanted -- johnniwinther 806 * Documentation wanted -- johnniwinther
762 * 807 *
763 * Invariant: [classElement] must be a declaration element. 808 * Invariant: [classElement] must be a declaration element.
764 */ 809 */
765 void visitClassFields(ClassElement classElement, 810 void visitClassFields(ClassElement classElement,
766 void addField(Element member, 811 void addField(Element member,
767 String name, 812 String name,
768 String accessorName, 813 String accessorName,
769 bool needsGetter, 814 bool needsGetter,
(...skipping 400 matching lines...) Expand 10 before | Expand all | Expand 10 after
1170 // Add unneeded interceptors to the [unneededClasses] set. 1215 // Add unneeded interceptors to the [unneededClasses] set.
1171 for (ClassElement interceptor in backend.interceptedClasses.keys) { 1216 for (ClassElement interceptor in backend.interceptedClasses.keys) {
1172 if (!needed.contains(interceptor)) { 1217 if (!needed.contains(interceptor)) {
1173 unneededClasses.add(interceptor); 1218 unneededClasses.add(interceptor);
1174 } 1219 }
1175 } 1220 }
1176 1221
1177 return (ClassElement cls) => !unneededClasses.contains(cls); 1222 return (ClassElement cls) => !unneededClasses.contains(cls);
1178 } 1223 }
1179 1224
1180 void emitClasses(CodeBuffer buffer) { 1225 Set<ClassElement> get instantiatedClasses {
ngeoffray 2012/12/13 13:34:58 Do you need this? If it's only used by the neededC
karlklose 2012/12/13 14:37:34 It is also needed in emitClasses.
1181 // Compute the required type checks to know which classes need a 1226 if (cachedInstantiatedClasses != null) return cachedInstantiatedClasses;
1182 // 'is$' method. 1227 cachedInstantiatedClasses =
1183 computeRequiredTypeChecks(); 1228 compiler.codegenWorld.instantiatedClasses.filter(computeClassFilter());
1229 return cachedInstantiatedClasses;
1230 }
1184 1231
1185 Set<ClassElement> instantiatedClasses = 1232 /// Get or compute the classes that we need to emit.
1186 compiler.codegenWorld.instantiatedClasses.filter(computeClassFilter()); 1233 Set<ClassElement> get neededClasses {
ngeoffray 2012/12/13 13:34:58 Instead of doing this lazily I would definitely pr
karlklose 2012/12/13 14:37:34 Done.
1234 if (cachedNeededClasses != null) return cachedNeededClasses;
1187 1235
1188 Set<ClassElement> neededClasses = 1236 cachedNeededClasses = new Set<ClassElement>.from(instantiatedClasses);
1189 new Set<ClassElement>.from(instantiatedClasses);
1190 1237
1191 for (ClassElement element in instantiatedClasses) { 1238 for (ClassElement element in instantiatedClasses) {
1192 for (ClassElement superclass = element.superclass; 1239 for (ClassElement superclass = element.superclass;
1193 superclass != null; 1240 superclass != null;
1194 superclass = superclass.superclass) { 1241 superclass = superclass.superclass) {
1195 if (neededClasses.contains(superclass)) break; 1242 if (neededClasses.contains(superclass)) break;
1196 neededClasses.add(superclass); 1243 neededClasses.add(superclass);
1197 } 1244 }
1198 } 1245 }
1246
1247 return cachedNeededClasses;
1248 }
1249
1250 void emitClasses(CodeBuffer buffer) {
1251 // Compute the required type checks to know which classes need a
1252 // 'is$' method.
1253 computeRequiredTypeChecks();
1199 List<ClassElement> sortedClasses = 1254 List<ClassElement> sortedClasses =
1200 new List<ClassElement>.from(neededClasses); 1255 new List<ClassElement>.from(neededClasses);
1201 sortedClasses.sort((ClassElement class1, ClassElement class2) { 1256 sortedClasses.sort((ClassElement class1, ClassElement class2) {
1202 // We sort by the ids of the classes. There is no guarantee that these 1257 // We sort by the ids of the classes. There is no guarantee that these
1203 // ids are meaningful (or even deterministic), but in the current 1258 // ids are meaningful (or even deterministic), but in the current
1204 // implementation they are increasing within a source file. 1259 // implementation they are increasing within a source file.
1205 return class1.id - class2.id; 1260 return class1.id - class2.id;
1206 }); 1261 });
1207 1262
1208 // If we need noSuchMethod support, we run through all needed 1263 // If we need noSuchMethod support, we run through all needed
(...skipping 745 matching lines...) Expand 10 before | Expand all | Expand 10 after
1954 'var $isolateProperties$_=$_$isolatePropertiesName$N'); 2009 'var $isolateProperties$_=$_$isolatePropertiesName$N');
1955 emitClasses(mainBuffer); 2010 emitClasses(mainBuffer);
1956 mainBuffer.add(boundClosureBuffer); 2011 mainBuffer.add(boundClosureBuffer);
1957 // Clear the buffer, so that we can reuse it for the native classes. 2012 // Clear the buffer, so that we can reuse it for the native classes.
1958 boundClosureBuffer.clear(); 2013 boundClosureBuffer.clear();
1959 emitStaticFunctions(mainBuffer); 2014 emitStaticFunctions(mainBuffer);
1960 emitStaticFunctionGetters(mainBuffer); 2015 emitStaticFunctionGetters(mainBuffer);
1961 // We need to finish the classes before we construct compile time 2016 // We need to finish the classes before we construct compile time
1962 // constants. 2017 // constants.
1963 emitFinishClassesInvocationIfNecessary(mainBuffer); 2018 emitFinishClassesInvocationIfNecessary(mainBuffer);
2019 emitRuntimeClassesAndTests(mainBuffer);
1964 emitCompileTimeConstants(mainBuffer); 2020 emitCompileTimeConstants(mainBuffer);
1965 // Static field initializations require the classes and compile-time 2021 // Static field initializations require the classes and compile-time
1966 // constants to be set up. 2022 // constants to be set up.
1967 emitStaticNonFinalFieldInitializations(mainBuffer); 2023 emitStaticNonFinalFieldInitializations(mainBuffer);
1968 emitGetInterceptorMethods(mainBuffer); 2024 emitGetInterceptorMethods(mainBuffer);
1969 emitLazilyInitializedStaticFields(mainBuffer); 2025 emitLazilyInitializedStaticFields(mainBuffer);
1970 2026
1971 isolateProperties = isolatePropertiesName; 2027 isolateProperties = isolatePropertiesName;
1972 // The following code should not use the short-hand for the 2028 // The following code should not use the short-hand for the
1973 // initialStatics. 2029 // initialStatics.
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
2019 """; 2075 """;
2020 const String HOOKS_API_USAGE = """ 2076 const String HOOKS_API_USAGE = """
2021 // The code supports the following hooks: 2077 // The code supports the following hooks:
2022 // dartPrint(message) - if this function is defined it is called 2078 // dartPrint(message) - if this function is defined it is called
2023 // instead of the Dart [print] method. 2079 // instead of the Dart [print] method.
2024 // dartMainRunner(main) - if this function is defined, the Dart [main] 2080 // dartMainRunner(main) - if this function is defined, the Dart [main]
2025 // method will not be invoked directly. 2081 // method will not be invoked directly.
2026 // Instead, a closure that will invoke [main] is 2082 // Instead, a closure that will invoke [main] is
2027 // passed to [dartMainRunner]. 2083 // passed to [dartMainRunner].
2028 """; 2084 """;
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698