Index: sdk/lib/_internal/compiler/implementation/js_backend/emitter.dart |
=================================================================== |
--- sdk/lib/_internal/compiler/implementation/js_backend/emitter.dart (revision 15381) |
+++ sdk/lib/_internal/compiler/implementation/js_backend/emitter.dart (working copy) |
@@ -1681,6 +1681,51 @@ |
"""); |
} |
+ /** |
+ * Emit the code for doing a type check on [cls]. [cls] must |
+ * be an interceptor class. |
+ */ |
+ void emitInterceptorCheck(ClassElement cls, CodeBuffer buffer) { |
+ JavaScriptBackend backend = compiler.backend; |
+ assert(backend.isInterceptorClass(cls)); |
+ if (cls == backend.jsBoolClass) { |
+ buffer.add("if (typeof receiver == 'boolean')"); |
+ } else if (cls == backend.jsIntClass) { |
+ buffer.add("if (typeof receiver == 'number' " |
+ "&& Math.floor(receiver) == receiver)"); |
+ } else if (cls == backend.jsDoubleClass || cls == backend.jsNumberClass) { |
+ buffer.add("if (typeof receiver == 'number')"); |
+ } else if (cls == backend.jsArrayClass) { |
+ buffer.add("if (receiver != null && receiver.constructor == Array)"); |
+ } else if (cls == backend.jsStringClass) { |
+ buffer.add("if (typeof receiver == 'string')"); |
+ } else if (cls == backend.jsNullClass) { |
+ buffer.add("if (receiver == null)"); |
+ } else if (cls == backend.jsFunctionClass) { |
+ buffer.add("if (typeof receiver == 'function')"); |
+ } |
+ buffer.add(' return ${namer.isolateAccess(cls)}.prototype;'); |
+ } |
+ |
+ /** |
+ * Emit all versions of the [:getInterceptor:] method. |
+ */ |
+ void emitGetInterceptorMethods(CodeBuffer buffer) { |
+ JavaScriptBackend backend = compiler.backend; |
+ String objectName = namer.isolateAccess(backend.objectInterceptorClass); |
+ backend.specializedGetInterceptors.forEach( |
+ (String key, Collection<ClassElement> classes) { |
+ buffer.add('$isolateProperties.$key = function(receiver) {'); |
+ for (ClassElement cls in classes) { |
+ if (compiler.codegenWorld.instantiatedClasses.contains(cls)) { |
+ buffer.add('\n '); |
+ emitInterceptorCheck(cls, buffer); |
+ } |
+ } |
+ buffer.add('\n return $objectName.prototype;\n};\n'); |
+ }); |
+ } |
+ |
String assembleProgram() { |
measure(() { |
mainBuffer.add(HOOKS_API_USAGE); |
@@ -1705,6 +1750,7 @@ |
// Static field initializations require the classes and compile-time |
// constants to be set up. |
emitStaticNonFinalFieldInitializations(mainBuffer); |
+ emitGetInterceptorMethods(mainBuffer); |
emitLazilyInitializedStaticFields(mainBuffer); |
isolateProperties = isolatePropertiesName; |