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

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: Forgot a change to a comment. 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
« no previous file with comments | « no previous file | sdk/lib/_internal/compiler/implementation/js_backend/runtime_types.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 /** 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> neededClasses;
48 Set<ClassElement> instantiatedClasses;
ngeoffray 2012/12/13 14:52:12 Please add a TODO(ngeoffray): to remove this field
karlklose 2012/12/13 14:56:45 Done.
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'");
779 for (ClassElement check in typeChecks[cls]) {
780 buffer.add(',$_${namer.operatorIs(check)}:${_}true');
781 };
782 buffer.add('}$N');
783 }
784
785 // Create representation objects for classes that we do not have a class
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.${namer.operatorIs(check)}$_=${_}true$N');
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 404 matching lines...) Expand 10 before | Expand all | Expand 10 after
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 void emitClasses(CodeBuffer buffer) {
1181 // Compute the required type checks to know which classes need a 1226 // Compute the required type checks to know which classes need a
1182 // 'is$' method. 1227 // 'is$' method.
1183 computeRequiredTypeChecks(); 1228 computeRequiredTypeChecks();
1184
1185 Set<ClassElement> instantiatedClasses =
1186 compiler.codegenWorld.instantiatedClasses.filter(computeClassFilter());
1187
1188 Set<ClassElement> neededClasses =
1189 new Set<ClassElement>.from(instantiatedClasses);
1190
1191 for (ClassElement element in instantiatedClasses) {
1192 for (ClassElement superclass = element.superclass;
1193 superclass != null;
1194 superclass = superclass.superclass) {
1195 if (neededClasses.contains(superclass)) break;
1196 neededClasses.add(superclass);
1197 }
1198 }
1199 List<ClassElement> sortedClasses = 1229 List<ClassElement> sortedClasses =
1200 new List<ClassElement>.from(neededClasses); 1230 new List<ClassElement>.from(neededClasses);
1201 sortedClasses.sort((ClassElement class1, ClassElement class2) { 1231 sortedClasses.sort((ClassElement class1, ClassElement class2) {
1202 // We sort by the ids of the classes. There is no guarantee that these 1232 // 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 1233 // ids are meaningful (or even deterministic), but in the current
1204 // implementation they are increasing within a source file. 1234 // implementation they are increasing within a source file.
1205 return class1.id - class2.id; 1235 return class1.id - class2.id;
1206 }); 1236 });
1207 1237
1208 // If we need noSuchMethod support, we run through all needed 1238 // If we need noSuchMethod support, we run through all needed
(...skipping 723 matching lines...) Expand 10 before | Expand all | Expand 10 after
1932 for (ClassElement cls in classes) { 1962 for (ClassElement cls in classes) {
1933 if (compiler.codegenWorld.instantiatedClasses.contains(cls)) { 1963 if (compiler.codegenWorld.instantiatedClasses.contains(cls)) {
1934 buffer.add('\n$_$_'); 1964 buffer.add('\n$_$_');
1935 emitInterceptorCheck(cls, buffer); 1965 emitInterceptorCheck(cls, buffer);
1936 } 1966 }
1937 } 1967 }
1938 buffer.add('\n$_${_}return $objectName.prototype;$n}$N'); 1968 buffer.add('\n$_${_}return $objectName.prototype;$n}$N');
1939 }); 1969 });
1940 } 1970 }
1941 1971
1972 void computeNeededClasses() {
1973 instantiatedClasses =
1974 compiler.codegenWorld.instantiatedClasses.filter(computeClassFilter());
1975 neededClasses = new Set<ClassElement>.from(instantiatedClasses);
1976 for (ClassElement element in instantiatedClasses) {
1977 for (ClassElement superclass = element.superclass;
1978 superclass != null;
1979 superclass = superclass.superclass) {
1980 if (neededClasses.contains(superclass)) break;
1981 neededClasses.add(superclass);
1982 }
1983 }
1984 }
1985
1942 String assembleProgram() { 1986 String assembleProgram() {
1943 measure(() { 1987 measure(() {
1988 computeNeededClasses();
1989
1944 mainBuffer.add(GENERATED_BY); 1990 mainBuffer.add(GENERATED_BY);
1945 if (!compiler.enableMinification) mainBuffer.add(HOOKS_API_USAGE); 1991 if (!compiler.enableMinification) mainBuffer.add(HOOKS_API_USAGE);
1946 mainBuffer.add('function ${namer.isolateName}()$_{}\n'); 1992 mainBuffer.add('function ${namer.isolateName}()$_{}\n');
1947 mainBuffer.add('init()$N$n'); 1993 mainBuffer.add('init()$N$n');
1948 // Shorten the code by using "$$" as temporary. 1994 // Shorten the code by using "$$" as temporary.
1949 classesCollector = r"$$"; 1995 classesCollector = r"$$";
1950 mainBuffer.add('var $classesCollector$_=$_{}$N'); 1996 mainBuffer.add('var $classesCollector$_=$_{}$N');
1951 // Shorten the code by using [namer.CURRENT_ISOLATE] as temporary. 1997 // Shorten the code by using [namer.CURRENT_ISOLATE] as temporary.
1952 isolateProperties = namer.CURRENT_ISOLATE; 1998 isolateProperties = namer.CURRENT_ISOLATE;
1953 mainBuffer.add( 1999 mainBuffer.add(
1954 'var $isolateProperties$_=$_$isolatePropertiesName$N'); 2000 'var $isolateProperties$_=$_$isolatePropertiesName$N');
1955 emitClasses(mainBuffer); 2001 emitClasses(mainBuffer);
1956 mainBuffer.add(boundClosureBuffer); 2002 mainBuffer.add(boundClosureBuffer);
1957 // Clear the buffer, so that we can reuse it for the native classes. 2003 // Clear the buffer, so that we can reuse it for the native classes.
1958 boundClosureBuffer.clear(); 2004 boundClosureBuffer.clear();
1959 emitStaticFunctions(mainBuffer); 2005 emitStaticFunctions(mainBuffer);
1960 emitStaticFunctionGetters(mainBuffer); 2006 emitStaticFunctionGetters(mainBuffer);
1961 // We need to finish the classes before we construct compile time 2007 // We need to finish the classes before we construct compile time
1962 // constants. 2008 // constants.
1963 emitFinishClassesInvocationIfNecessary(mainBuffer); 2009 emitFinishClassesInvocationIfNecessary(mainBuffer);
2010 emitRuntimeClassesAndTests(mainBuffer);
1964 emitCompileTimeConstants(mainBuffer); 2011 emitCompileTimeConstants(mainBuffer);
1965 // Static field initializations require the classes and compile-time 2012 // Static field initializations require the classes and compile-time
1966 // constants to be set up. 2013 // constants to be set up.
1967 emitStaticNonFinalFieldInitializations(mainBuffer); 2014 emitStaticNonFinalFieldInitializations(mainBuffer);
1968 emitGetInterceptorMethods(mainBuffer); 2015 emitGetInterceptorMethods(mainBuffer);
1969 emitLazilyInitializedStaticFields(mainBuffer); 2016 emitLazilyInitializedStaticFields(mainBuffer);
1970 2017
1971 isolateProperties = isolatePropertiesName; 2018 isolateProperties = isolatePropertiesName;
1972 // The following code should not use the short-hand for the 2019 // The following code should not use the short-hand for the
1973 // initialStatics. 2020 // initialStatics.
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
2019 """; 2066 """;
2020 const String HOOKS_API_USAGE = """ 2067 const String HOOKS_API_USAGE = """
2021 // The code supports the following hooks: 2068 // The code supports the following hooks:
2022 // dartPrint(message) - if this function is defined it is called 2069 // dartPrint(message) - if this function is defined it is called
2023 // instead of the Dart [print] method. 2070 // instead of the Dart [print] method.
2024 // dartMainRunner(main) - if this function is defined, the Dart [main] 2071 // dartMainRunner(main) - if this function is defined, the Dart [main]
2025 // method will not be invoked directly. 2072 // method will not be invoked directly.
2026 // Instead, a closure that will invoke [main] is 2073 // Instead, a closure that will invoke [main] is
2027 // passed to [dartMainRunner]. 2074 // passed to [dartMainRunner].
2028 """; 2075 """;
OLDNEW
« no previous file with comments | « no previous file | sdk/lib/_internal/compiler/implementation/js_backend/runtime_types.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698