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

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

Issue 15026006: Support for extending native classes (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 7 years, 4 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 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 32d3ab8e05ae37f41f8813b6101e0916f4cbd6be..d0669b331870bb7927aaa425df4c238801d20f99 100644
--- a/sdk/lib/_internal/compiler/implementation/js_backend/emitter.dart
+++ b/sdk/lib/_internal/compiler/implementation/js_backend/emitter.dart
@@ -2631,6 +2631,8 @@ class CodeEmitterTask extends CompilerTask {
for (Element element in Elements.sortedByPosition(staticNonFinalFields)) {
// [:interceptedNames:] is handled in [emitInterceptedNames].
if (element == backend.interceptedNames) continue;
+ // `mapTypeToInterceptor` is handled in [emitMapTypeToInterceptor].
+ if (element == backend.mapTypeToInterceptor) continue;
compiler.withCurrentElement(element, () {
Constant initialValue = handler.getInitialValueFor(element);
jsAst.Expression init =
@@ -3056,6 +3058,9 @@ class CodeEmitterTask extends CompilerTask {
bool hasNumber = false;
bool hasString = false;
bool hasNative = false;
+ bool anyNativeClasses = compiler.enqueuer.codegen.nativeEnqueuer
+ .hasInstantiatedNativeClasses();
+
for (ClassElement cls in classes) {
if (cls == backend.jsArrayClass ||
cls == backend.jsMutableArrayClass ||
@@ -3068,10 +3073,18 @@ class CodeEmitterTask extends CompilerTask {
else if (cls == backend.jsNumberClass) hasNumber = true;
else if (cls == backend.jsStringClass) hasString = true;
else {
- // TODO(sra): The set of classes includes classes mixed-in to
- // interceptor classes.
- // assert(cls == compiler.objectClass || cls.isNative());
- if (cls.isNative()) hasNative = true;
+ // The set of classes includes classes mixed-in to interceptor classes
+ // and user extensions of native classes.
+ //
+ // The set of classes also includes the 'primitive' interceptor
+ // PlainJavaScriptObject even when it has not been resolved, since it is
+ // only resolved through the reference in getNativeInterceptor when
+ // getNativeInterceptor is marked as used. Guard against probing
+ // unresolved PlainJavaScriptObject by testing for anyNativeClasses.
+
+ if (anyNativeClasses) {
+ if (Elements.isNativeOrExtendsNative(cls)) hasNative = true;
+ }
}
}
if (hasDouble) {
@@ -3081,8 +3094,7 @@ class CodeEmitterTask extends CompilerTask {
if (classes == backend.interceptedClasses) {
// I.e. this is the general interceptor.
- hasNative = compiler.enqueuer.codegen.nativeEnqueuer
- .hasInstantiatedNativeClasses();
+ hasNative = anyNativeClasses;
}
jsAst.Block block = new jsAst.Block.empty();
@@ -3245,9 +3257,13 @@ class CodeEmitterTask extends CompilerTask {
for (ClassElement element in sortedClasses) {
if (rtiNeededClasses.contains(element)) {
regularClasses.add(element);
- } else if (element.isNative()) {
- // For now, native classes cannot be deferred.
+ } else if (Elements.isNativeOrExtendsNative(element)) {
+ // For now, native classes and related classes cannot be deferred.
nativeClasses.add(element);
+ if (!element.isNative()) {
+ assert(invariant(element, !isDeferred(element)));
+ regularClasses.add(element);
+ }
} else if (isDeferred(element)) {
deferredClasses.add(element);
} else {
@@ -3511,6 +3527,37 @@ class CodeEmitterTask extends CompilerTask {
buffer.write(N);
}
+ /**
+ * Emit initializer for [mapTypeToInterceptor] data structure used by
+ * [findInterceptorForType]. See declaration of [mapTypeToInterceptor] in
+ * `interceptors.dart`.
+ */
+ void emitMapTypeToInterceptor(CodeBuffer buffer) {
+ // TODO(sra): Perhaps inject a constant instead?
+ // TODO(sra): Filter by subclasses of native types.
+ List<jsAst.Expression> elements = <jsAst.Expression>[];
+ ConstantHandler handler = compiler.constantHandler;
+ List<Constant> constants = handler.getConstantsForEmission();
+ for (Constant constant in constants) {
+ if (constant is TypeConstant) {
+ TypeConstant typeConstant = constant;
+ Element element = typeConstant.representedType.element;
+ if (element is ClassElement) {
+ ClassElement classElement = element;
+ elements.add(backend.emitter.constantReference(constant));
+ elements.add(js(namer.isolateAccess(classElement)));
+ }
+ }
+ }
+
+ jsAst.ArrayInitializer array = new jsAst.ArrayInitializer.from(elements);
+ String name = backend.namer.getName(backend.mapTypeToInterceptor);
+ jsAst.Expression assignment = js('$isolateProperties.$name = #', array);
+
+ buffer.write(jsAst.prettyPrint(assignment, compiler));
+ buffer.write(N);
+ }
+
void emitInitFunction(CodeBuffer buffer) {
jsAst.Fun fun = js.fun([], [
js('$isolateProperties = {}'),
@@ -3843,6 +3890,7 @@ class CodeEmitterTask extends CompilerTask {
emitStaticNonFinalFieldInitializations(mainBuffer);
emitOneShotInterceptors(mainBuffer);
emitInterceptedNames(mainBuffer);
+ emitMapTypeToInterceptor(mainBuffer);
emitLazilyInitializedStaticFields(mainBuffer);
mainBuffer.add(nativeBuffer);

Powered by Google App Engine
This is Rietveld 408576698