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

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: Rebase 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 // TODO(ngeoffray): remove this field.
49 Set<ClassElement> instantiatedClasses;
47 50
48 String get _ => compiler.enableMinification ? "" : " "; 51 String get _ => compiler.enableMinification ? "" : " ";
49 String get n => compiler.enableMinification ? "" : "\n"; 52 String get n => compiler.enableMinification ? "" : "\n";
50 String get N => compiler.enableMinification ? "\n" : ";\n"; 53 String get N => compiler.enableMinification ? "\n" : ";\n";
51 54
52 /** 55 /**
53 * A cache of closures that are used to closurize instance methods. 56 * A cache of closures that are used to closurize instance methods.
54 * A closure is dynamically bound to the instance used when 57 * A closure is dynamically bound to the instance used when
55 * closurized. 58 * closurized.
56 */ 59 */
(...skipping 693 matching lines...) Expand 10 before | Expand all | Expand 10 after
750 // Emit the noSuchMethod handlers on the Object prototype now, 753 // Emit the noSuchMethod handlers on the Object prototype now,
751 // so that the code in the dynamicFunction helper can find 754 // so that the code in the dynamicFunction helper can find
752 // them. Note that this helper is invoked before analyzing the 755 // them. Note that this helper is invoked before analyzing the
753 // full JS script. 756 // full JS script.
754 if (!nativeEmitter.handleNoSuchMethod) { 757 if (!nativeEmitter.handleNoSuchMethod) {
755 emitNoSuchMethodHandlers(defineInstanceMember); 758 emitNoSuchMethodHandlers(defineInstanceMember);
756 } 759 }
757 } 760 }
758 } 761 }
759 762
763 void emitRuntimeClassesAndTests(CodeBuffer buffer) {
764 JavaScriptBackend backend = compiler.backend;
765 RuntimeTypeInformation rti = backend.rti;
766
767 TypeChecks typeChecks = rti.computeRequiredChecks();
768
769 bool needsHolder(ClassElement cls) {
770 return !neededClasses.contains(cls) || cls.isNative() ||
771 rti.isJsNative(cls);
772 }
773
774 void maybeGenerateHolder(ClassElement cls) {
775 if (!needsHolder(cls)) return;
776
777 String holder = namer.isolateAccess(cls);
778 String name = namer.getName(cls);
779 buffer.add("$holder$_=$_{builtin\$cls:$_'$name'");
780 for (ClassElement check in typeChecks[cls]) {
781 buffer.add(',$_${namer.operatorIs(check)}:${_}true');
782 };
783 buffer.add('}$N');
784 }
785
786 // Create representation objects for classes that we do not have a class
787 // definition for (because they are uninstantiated or native).
788 for (ClassElement cls in rti.allArguments) {
789 maybeGenerateHolder(cls);
790 }
791
792 // Add checks to the constructors of instantiated classes.
793 for (ClassElement cls in typeChecks) {
794 if (needsHolder(cls)) {
795 // We already emitted the is-checks in the object definition for this
796 // class.
797 continue;
798 }
799 String holder = namer.isolateAccess(cls);
800 for (ClassElement check in typeChecks[cls]) {
801 buffer.add('$holder.${namer.operatorIs(check)}$_=${_}true$N');
802 };
803 }
804 }
805
760 /** 806 /**
761 * Documentation wanted -- johnniwinther 807 * Documentation wanted -- johnniwinther
762 * 808 *
763 * Invariant: [classElement] must be a declaration element. 809 * Invariant: [classElement] must be a declaration element.
764 */ 810 */
765 void visitClassFields(ClassElement classElement, 811 void visitClassFields(ClassElement classElement,
766 void addField(Element member, 812 void addField(Element member,
767 String name, 813 String name,
768 String accessorName, 814 String accessorName,
769 bool needsGetter, 815 bool needsGetter,
(...skipping 404 matching lines...) Expand 10 before | Expand all | Expand 10 after
1174 } 1220 }
1175 } 1221 }
1176 1222
1177 return (ClassElement cls) => !unneededClasses.contains(cls); 1223 return (ClassElement cls) => !unneededClasses.contains(cls);
1178 } 1224 }
1179 1225
1180 void emitClasses(CodeBuffer buffer) { 1226 void emitClasses(CodeBuffer buffer) {
1181 // Compute the required type checks to know which classes need a 1227 // Compute the required type checks to know which classes need a
1182 // 'is$' method. 1228 // 'is$' method.
1183 computeRequiredTypeChecks(); 1229 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 = 1230 List<ClassElement> sortedClasses =
1200 new List<ClassElement>.from(neededClasses); 1231 new List<ClassElement>.from(neededClasses);
1201 sortedClasses.sort((ClassElement class1, ClassElement class2) { 1232 sortedClasses.sort((ClassElement class1, ClassElement class2) {
1202 // We sort by the ids of the classes. There is no guarantee that these 1233 // 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 1234 // ids are meaningful (or even deterministic), but in the current
1204 // implementation they are increasing within a source file. 1235 // implementation they are increasing within a source file.
1205 return class1.id - class2.id; 1236 return class1.id - class2.id;
1206 }); 1237 });
1207 1238
1208 // If we need noSuchMethod support, we run through all needed 1239 // 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) { 1963 for (ClassElement cls in classes) {
1933 if (compiler.codegenWorld.instantiatedClasses.contains(cls)) { 1964 if (compiler.codegenWorld.instantiatedClasses.contains(cls)) {
1934 buffer.add('\n$_$_'); 1965 buffer.add('\n$_$_');
1935 emitInterceptorCheck(cls, buffer); 1966 emitInterceptorCheck(cls, buffer);
1936 } 1967 }
1937 } 1968 }
1938 buffer.add('\n$_${_}return $objectName.prototype;$n}$N'); 1969 buffer.add('\n$_${_}return $objectName.prototype;$n}$N');
1939 }); 1970 });
1940 } 1971 }
1941 1972
1973 void computeNeededClasses() {
1974 instantiatedClasses =
1975 compiler.codegenWorld.instantiatedClasses.filter(computeClassFilter());
1976 neededClasses = new Set<ClassElement>.from(instantiatedClasses);
1977 for (ClassElement element in instantiatedClasses) {
1978 for (ClassElement superclass = element.superclass;
1979 superclass != null;
1980 superclass = superclass.superclass) {
1981 if (neededClasses.contains(superclass)) break;
1982 neededClasses.add(superclass);
1983 }
1984 }
1985 }
1986
1942 String assembleProgram() { 1987 String assembleProgram() {
1943 measure(() { 1988 measure(() {
1989 computeNeededClasses();
1990
1944 mainBuffer.add(GENERATED_BY); 1991 mainBuffer.add(GENERATED_BY);
1945 if (!compiler.enableMinification) mainBuffer.add(HOOKS_API_USAGE); 1992 if (!compiler.enableMinification) mainBuffer.add(HOOKS_API_USAGE);
1946 mainBuffer.add('function ${namer.isolateName}()$_{}\n'); 1993 mainBuffer.add('function ${namer.isolateName}()$_{}\n');
1947 mainBuffer.add('init()$N$n'); 1994 mainBuffer.add('init()$N$n');
1948 // Shorten the code by using "$$" as temporary. 1995 // Shorten the code by using "$$" as temporary.
1949 classesCollector = r"$$"; 1996 classesCollector = r"$$";
1950 mainBuffer.add('var $classesCollector$_=$_{}$N'); 1997 mainBuffer.add('var $classesCollector$_=$_{}$N');
1951 // Shorten the code by using [namer.CURRENT_ISOLATE] as temporary. 1998 // Shorten the code by using [namer.CURRENT_ISOLATE] as temporary.
1952 isolateProperties = namer.CURRENT_ISOLATE; 1999 isolateProperties = namer.CURRENT_ISOLATE;
1953 mainBuffer.add( 2000 mainBuffer.add(
1954 'var $isolateProperties$_=$_$isolatePropertiesName$N'); 2001 'var $isolateProperties$_=$_$isolatePropertiesName$N');
1955 emitClasses(mainBuffer); 2002 emitClasses(mainBuffer);
1956 mainBuffer.add(boundClosureBuffer); 2003 mainBuffer.add(boundClosureBuffer);
1957 // Clear the buffer, so that we can reuse it for the native classes. 2004 // Clear the buffer, so that we can reuse it for the native classes.
1958 boundClosureBuffer.clear(); 2005 boundClosureBuffer.clear();
1959 emitStaticFunctions(mainBuffer); 2006 emitStaticFunctions(mainBuffer);
1960 emitStaticFunctionGetters(mainBuffer); 2007 emitStaticFunctionGetters(mainBuffer);
1961 // We need to finish the classes before we construct compile time 2008 // We need to finish the classes before we construct compile time
1962 // constants. 2009 // constants.
1963 emitFinishClassesInvocationIfNecessary(mainBuffer); 2010 emitFinishClassesInvocationIfNecessary(mainBuffer);
2011 emitRuntimeClassesAndTests(mainBuffer);
1964 emitCompileTimeConstants(mainBuffer); 2012 emitCompileTimeConstants(mainBuffer);
1965 // Static field initializations require the classes and compile-time 2013 // Static field initializations require the classes and compile-time
1966 // constants to be set up. 2014 // constants to be set up.
1967 emitStaticNonFinalFieldInitializations(mainBuffer); 2015 emitStaticNonFinalFieldInitializations(mainBuffer);
1968 emitGetInterceptorMethods(mainBuffer); 2016 emitGetInterceptorMethods(mainBuffer);
1969 emitLazilyInitializedStaticFields(mainBuffer); 2017 emitLazilyInitializedStaticFields(mainBuffer);
1970 2018
1971 isolateProperties = isolatePropertiesName; 2019 isolateProperties = isolatePropertiesName;
1972 // The following code should not use the short-hand for the 2020 // The following code should not use the short-hand for the
1973 // initialStatics. 2021 // initialStatics.
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
2019 """; 2067 """;
2020 const String HOOKS_API_USAGE = """ 2068 const String HOOKS_API_USAGE = """
2021 // The code supports the following hooks: 2069 // The code supports the following hooks:
2022 // dartPrint(message) - if this function is defined it is called 2070 // dartPrint(message) - if this function is defined it is called
2023 // instead of the Dart [print] method. 2071 // instead of the Dart [print] method.
2024 // dartMainRunner(main) - if this function is defined, the Dart [main] 2072 // dartMainRunner(main) - if this function is defined, the Dart [main]
2025 // method will not be invoked directly. 2073 // method will not be invoked directly.
2026 // Instead, a closure that will invoke [main] is 2074 // Instead, a closure that will invoke [main] is
2027 // passed to [dartMainRunner]. 2075 // passed to [dartMainRunner].
2028 """; 2076 """;
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