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

Unified 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 side-by-side diff with in-line comments
Download patch
Index: sdk/lib/_internal/compiler/implementation/js_backend/emitter.dart
diff --git a/sdk/lib/_internal/compiler/implementation/js_backend/emitter.dart b/sdk/lib/_internal/compiler/implementation/js_backend/emitter.dart
index b70c32c2aaa78bac336c88971e1f1c5153986a08..2afab9f8b7cda1506160a0a3717e027f782800f3 100644
--- a/sdk/lib/_internal/compiler/implementation/js_backend/emitter.dart
+++ b/sdk/lib/_internal/compiler/implementation/js_backend/emitter.dart
@@ -44,6 +44,8 @@ class CodeEmitterTask extends CompilerTask {
well as in the generated code. */
String isolateProperties;
String classesCollector;
+ Set<ClassElement> cachedNeededClasses;
+ Set<ClassElement> cachedInstantiatedClasses;
String get _ => compiler.enableMinification ? "" : " ";
String get n => compiler.enableMinification ? "" : "\n";
@@ -757,6 +759,49 @@ $lazyInitializerLogic
}
}
+ void emitRuntimeClassesAndTests(CodeBuffer buffer) {
+ JavaScriptBackend backend = compiler.backend;
+ RuntimeTypeInformation rti = backend.rti;
+
+ TypeChecks typeChecks = rti.computeRequiredChecks();
+
+ bool needsHolder(ClassElement cls) {
+ return !neededClasses.contains(cls) || cls.isNative() ||
+ rti.isJsNative(cls);
+ }
+
+ void maybeGenerateHolder(ClassElement cls) {
+ if (!needsHolder(cls)) return;
+
+ String holder = namer.isolateAccess(cls);
+ String name = namer.getName(cls);
+ 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
+ for (ClassElement check in typeChecks[cls]) {
+ 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.
+ };
+ buffer.add('}$N');
+ }
+
+ // 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.
+ // definition for (because they are uninstantiated or native).
+ for (ClassElement cls in rti.allArguments) {
+ maybeGenerateHolder(cls);
+ }
+
+ // Add checks to the constructors of instantiated classes.
+ for (ClassElement cls in typeChecks) {
+ if (needsHolder(cls)) {
+ // We already emitted the is-checks in the object definition for this
+ // class.
+ continue;
+ }
+ String holder = namer.isolateAccess(cls);
+ for (ClassElement check in typeChecks[cls]) {
+ 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.
+ };
+ }
+ }
+
/**
* Documentation wanted -- johnniwinther
*
@@ -1177,16 +1222,18 @@ $lazyInitializerLogic
return (ClassElement cls) => !unneededClasses.contains(cls);
}
- void emitClasses(CodeBuffer buffer) {
- // Compute the required type checks to know which classes need a
- // 'is$' method.
- computeRequiredTypeChecks();
-
- Set<ClassElement> instantiatedClasses =
+ 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.
+ if (cachedInstantiatedClasses != null) return cachedInstantiatedClasses;
+ cachedInstantiatedClasses =
compiler.codegenWorld.instantiatedClasses.filter(computeClassFilter());
+ return cachedInstantiatedClasses;
+ }
+
+ /// Get or compute the classes that we need to emit.
+ 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.
+ if (cachedNeededClasses != null) return cachedNeededClasses;
- Set<ClassElement> neededClasses =
- new Set<ClassElement>.from(instantiatedClasses);
+ cachedNeededClasses = new Set<ClassElement>.from(instantiatedClasses);
for (ClassElement element in instantiatedClasses) {
for (ClassElement superclass = element.superclass;
@@ -1196,6 +1243,14 @@ $lazyInitializerLogic
neededClasses.add(superclass);
}
}
+
+ return cachedNeededClasses;
+ }
+
+ void emitClasses(CodeBuffer buffer) {
+ // Compute the required type checks to know which classes need a
+ // 'is$' method.
+ computeRequiredTypeChecks();
List<ClassElement> sortedClasses =
new List<ClassElement>.from(neededClasses);
sortedClasses.sort((ClassElement class1, ClassElement class2) {
@@ -1961,6 +2016,7 @@ if (typeof document !== 'undefined' && document.readyState !== 'complete') {
// We need to finish the classes before we construct compile time
// constants.
emitFinishClassesInvocationIfNecessary(mainBuffer);
+ emitRuntimeClassesAndTests(mainBuffer);
emitCompileTimeConstants(mainBuffer);
// Static field initializations require the classes and compile-time
// constants to be set up.

Powered by Google App Engine
This is Rietveld 408576698