| Index: pkg/compiler/lib/src/js_emitter/interceptor_stub_generator.dart
|
| diff --git a/pkg/compiler/lib/src/js_emitter/interceptor_stub_generator.dart b/pkg/compiler/lib/src/js_emitter/interceptor_stub_generator.dart
|
| index 73eeeb74b7917fba7b716820b0f270efaefe152a..1ccb101b904f8af0d0fb0fdfec36493a2792e4df 100644
|
| --- a/pkg/compiler/lib/src/js_emitter/interceptor_stub_generator.dart
|
| +++ b/pkg/compiler/lib/src/js_emitter/interceptor_stub_generator.dart
|
| @@ -30,13 +30,13 @@ class InterceptorStubGenerator {
|
| if (cls == helpers.jsBoolClass) {
|
| condition = js('(typeof receiver) == "boolean"');
|
| } else if (cls == helpers.jsIntClass ||
|
| - cls == helpers.jsDoubleClass ||
|
| - cls == helpers.jsNumberClass) {
|
| + cls == helpers.jsDoubleClass ||
|
| + cls == helpers.jsNumberClass) {
|
| throw 'internal error';
|
| } else if (cls == helpers.jsArrayClass ||
|
| - cls == helpers.jsMutableArrayClass ||
|
| - cls == helpers.jsFixedArrayClass ||
|
| - cls == helpers.jsExtendableArrayClass) {
|
| + cls == helpers.jsMutableArrayClass ||
|
| + cls == helpers.jsFixedArrayClass ||
|
| + cls == helpers.jsExtendableArrayClass) {
|
| condition = js('receiver.constructor == Array');
|
| } else if (cls == helpers.jsStringClass) {
|
| condition = js('(typeof receiver) == "string"');
|
| @@ -56,20 +56,27 @@ class InterceptorStubGenerator {
|
| bool hasNumber = false;
|
| bool hasString = false;
|
| bool hasNative = false;
|
| - bool anyNativeClasses = compiler.enqueuer.codegen.nativeEnqueuer
|
| - .hasInstantiatedNativeClasses();
|
| + bool anyNativeClasses =
|
| + compiler.enqueuer.codegen.nativeEnqueuer.hasInstantiatedNativeClasses();
|
|
|
| for (ClassElement cls in classes) {
|
| if (cls == helpers.jsArrayClass ||
|
| cls == helpers.jsMutableArrayClass ||
|
| cls == helpers.jsFixedArrayClass ||
|
| - cls == helpers.jsExtendableArrayClass) hasArray = true;
|
| - else if (cls == helpers.jsBoolClass) hasBool = true;
|
| - else if (cls == helpers.jsDoubleClass) hasDouble = true;
|
| - else if (cls == helpers.jsIntClass) hasInt = true;
|
| - else if (cls == helpers.jsNullClass) hasNull = true;
|
| - else if (cls == helpers.jsNumberClass) hasNumber = true;
|
| - else if (cls == helpers.jsStringClass) hasString = true;
|
| + cls == helpers.jsExtendableArrayClass)
|
| + hasArray = true;
|
| + else if (cls == helpers.jsBoolClass)
|
| + hasBool = true;
|
| + else if (cls == helpers.jsDoubleClass)
|
| + hasDouble = true;
|
| + else if (cls == helpers.jsIntClass)
|
| + hasInt = true;
|
| + else if (cls == helpers.jsNullClass)
|
| + hasNull = true;
|
| + else if (cls == helpers.jsNumberClass)
|
| + hasNumber = true;
|
| + else if (cls == helpers.jsStringClass)
|
| + hasString = true;
|
| else {
|
| // The set of classes includes classes mixed-in to interceptor classes
|
| // and user extensions of native classes.
|
| @@ -108,15 +115,17 @@ class InterceptorStubGenerator {
|
| hasDouble ? helpers.jsDoubleClass : helpers.jsNumberClass);
|
|
|
| if (hasInt) {
|
| - whenNumber = js.statement('''{
|
| + whenNumber = js.statement(
|
| + '''{
|
| if (Math.floor(receiver) == receiver) return #;
|
| return #;
|
| - }''', [interceptorFor(helpers.jsIntClass), interceptorForNumber]);
|
| + }''',
|
| + [interceptorFor(helpers.jsIntClass), interceptorForNumber]);
|
| } else {
|
| whenNumber = js.statement('return #', interceptorForNumber);
|
| }
|
| - statements.add(
|
| - js.statement('if (typeof receiver == "number") #;', whenNumber));
|
| + statements
|
| + .add(js.statement('if (typeof receiver == "number") #;', whenNumber));
|
| }
|
|
|
| if (hasString) {
|
| @@ -128,8 +137,7 @@ class InterceptorStubGenerator {
|
| // Returning "undefined" or "null" here will provoke a JavaScript
|
| // TypeError which is later identified as a null-error by
|
| // [unwrapException] in js_helper.dart.
|
| - statements.add(
|
| - js.statement('if (receiver == null) return receiver'));
|
| + statements.add(js.statement('if (receiver == null) return receiver'));
|
| }
|
| if (hasBool) {
|
| statements.add(buildInterceptorCheck(helpers.jsBoolClass));
|
| @@ -141,28 +149,29 @@ class InterceptorStubGenerator {
|
| }
|
|
|
| if (hasNative) {
|
| - statements.add(js.statement(r'''{
|
| + statements.add(js.statement(
|
| + r'''{
|
| if (typeof receiver != "object") {
|
| if (typeof receiver == "function" ) return #;
|
| return receiver;
|
| }
|
| if (receiver instanceof #) return receiver;
|
| return #(receiver);
|
| - }''', [
|
| - interceptorFor(helpers.jsJavaScriptFunctionClass),
|
| - backend.emitter.constructorAccess(compiler.coreClasses.objectClass),
|
| - backend.emitter
|
| - .staticFunctionAccess(helpers.getNativeInterceptorMethod)]));
|
| -
|
| + }''',
|
| + [
|
| + interceptorFor(helpers.jsJavaScriptFunctionClass),
|
| + backend.emitter.constructorAccess(compiler.coreClasses.objectClass),
|
| + backend.emitter
|
| + .staticFunctionAccess(helpers.getNativeInterceptorMethod)
|
| + ]));
|
| } else {
|
| ClassElement jsUnknown = helpers.jsUnknownJavaScriptObjectClass;
|
| - if (compiler.codegenWorld
|
| - .directlyInstantiatedClasses.contains(jsUnknown)) {
|
| - statements.add(
|
| - js.statement('if (!(receiver instanceof #)) return #;',
|
| - [backend.emitter.constructorAccess(
|
| - compiler.coreClasses.objectClass),
|
| - interceptorFor(jsUnknown)]));
|
| + if (compiler.codegenWorld.directlyInstantiatedClasses
|
| + .contains(jsUnknown)) {
|
| + statements.add(js.statement('if (!(receiver instanceof #)) return #;', [
|
| + backend.emitter.constructorAccess(compiler.coreClasses.objectClass),
|
| + interceptorFor(jsUnknown)
|
| + ]));
|
| }
|
|
|
| statements.add(js.statement('return receiver'));
|
| @@ -174,9 +183,8 @@ class InterceptorStubGenerator {
|
| // Returns a statement that takes care of performance critical
|
| // common case for a one-shot interceptor, or null if there is no
|
| // fast path.
|
| - jsAst.Statement _fastPathForOneShotInterceptor(Selector selector,
|
| - Set<ClassElement> classes) {
|
| -
|
| + jsAst.Statement _fastPathForOneShotInterceptor(
|
| + Selector selector, Set<ClassElement> classes) {
|
| if (selector.isOperator) {
|
| String name = selector.name;
|
| if (name == '==') {
|
| @@ -186,9 +194,9 @@ class InterceptorStubGenerator {
|
| return a0 != null && receiver === a0;
|
| }''');
|
| }
|
| - if (!classes.contains(helpers.jsIntClass)
|
| - && !classes.contains(helpers.jsNumberClass)
|
| - && !classes.contains(helpers.jsDoubleClass)) {
|
| + if (!classes.contains(helpers.jsIntClass) &&
|
| + !classes.contains(helpers.jsNumberClass) &&
|
| + !classes.contains(helpers.jsDoubleClass)) {
|
| return null;
|
| }
|
| if (selector.argumentCount == 1) {
|
| @@ -205,8 +213,8 @@ class InterceptorStubGenerator {
|
| ' return #;',
|
| result);
|
| } else if (name == 'unary-') {
|
| - return js.statement(
|
| - 'if (typeof receiver == "number") return -receiver');
|
| + return js
|
| + .statement('if (typeof receiver == "number") return -receiver');
|
| } else {
|
| assert(name == '~');
|
| return js.statement('''
|
| @@ -238,15 +246,16 @@ class InterceptorStubGenerator {
|
| bool containsArray = classes.contains(helpers.jsArrayClass);
|
| bool containsString = classes.contains(helpers.jsStringClass);
|
| bool containsJsIndexable =
|
| - helpers.jsIndexingBehaviorInterface.isResolved && classes.any((cls) {
|
| - return compiler.world.isSubtypeOf(cls,
|
| - helpers.jsIndexingBehaviorInterface);
|
| - });
|
| + helpers.jsIndexingBehaviorInterface.isResolved &&
|
| + classes.any((cls) {
|
| + return compiler.world
|
| + .isSubtypeOf(cls, helpers.jsIndexingBehaviorInterface);
|
| + });
|
| // The index set operator requires a check on its set value in
|
| // checked mode, so we don't optimize the interceptor if the
|
| // compiler has type assertions enabled.
|
| - if (selector.isIndexSet
|
| - && (compiler.options.enableTypeAssertions || !containsArray)) {
|
| + if (selector.isIndexSet &&
|
| + (compiler.options.enableTypeAssertions || !containsArray)) {
|
| return null;
|
| }
|
| if (!containsArray && !containsString) {
|
| @@ -274,12 +283,14 @@ class InterceptorStubGenerator {
|
| typeCheck = orExp(typeCheck, indexableCheck);
|
| }
|
|
|
| - return js.statement('''
|
| + return js.statement(
|
| + '''
|
| if (typeof a0 === "number")
|
| if (#)
|
| if ((a0 >>> 0) === a0 && a0 < receiver.length)
|
| return receiver[a0];
|
| - ''', typeCheck);
|
| + ''',
|
| + typeCheck);
|
| } else {
|
| jsAst.Expression typeCheck;
|
| if (containsArray) {
|
| @@ -290,12 +301,14 @@ class InterceptorStubGenerator {
|
| typeCheck = orExp(typeCheck, indexableCheck);
|
| }
|
|
|
| - return js.statement(r'''
|
| + return js.statement(
|
| + r'''
|
| if (typeof a0 === "number")
|
| if (# && !receiver.immutable$list &&
|
| (a0 >>> 0) === a0 && a0 < receiver.length)
|
| return receiver[a0] = a1;
|
| - ''', typeCheck);
|
| + ''',
|
| + typeCheck);
|
| }
|
| }
|
| return null;
|
| @@ -303,8 +316,7 @@ class InterceptorStubGenerator {
|
|
|
| jsAst.Expression generateOneShotInterceptor(jsAst.Name name) {
|
| Selector selector = backend.oneShotInterceptors[name];
|
| - Set<ClassElement> classes =
|
| - backend.getInterceptedClassesOn(selector.name);
|
| + Set<ClassElement> classes = backend.getInterceptedClassesOn(selector.name);
|
| jsAst.Name getInterceptorName = namer.nameForGetInterceptor(classes);
|
|
|
| List<String> parameterNames = <String>[];
|
| @@ -325,11 +337,14 @@ class InterceptorStubGenerator {
|
| _fastPathForOneShotInterceptor(selector, classes);
|
| if (optimizedPath == null) optimizedPath = js.statement(';');
|
|
|
| - return js(
|
| - 'function(#) { #; return #.#(receiver).#(#) }',
|
| - [parameterNames,
|
| - optimizedPath,
|
| - globalObject, getInterceptorName, invocationName, parameterNames]);
|
| + return js('function(#) { #; return #.#(receiver).#(#) }', [
|
| + parameterNames,
|
| + optimizedPath,
|
| + globalObject,
|
| + getInterceptorName,
|
| + invocationName,
|
| + parameterNames
|
| + ]);
|
| }
|
|
|
| jsAst.ArrayInitializer generateTypeToInterceptorMap() {
|
| @@ -369,10 +384,8 @@ class InterceptorStubGenerator {
|
| // We expect most of the time the map will be a singleton.
|
| var properties = [];
|
| for (Element member in analysis.constructors(classElement)) {
|
| - properties.add(
|
| - new jsAst.Property(
|
| - js.string(member.name),
|
| - backend.emitter.staticFunctionAccess(member)));
|
| + properties.add(new jsAst.Property(js.string(member.name),
|
| + backend.emitter.staticFunctionAccess(member)));
|
| }
|
|
|
| var map = new jsAst.ObjectInitializer(properties);
|
|
|