Chromium Code Reviews| Index: pkg/compiler/lib/src/ssa/codegen.dart |
| diff --git a/pkg/compiler/lib/src/ssa/codegen.dart b/pkg/compiler/lib/src/ssa/codegen.dart |
| index ae57bc2c4bf40c79e17def56488cac6cce9c7cbd..ceeace7887c1f8c83d67efbbdd97b580163a6dea 100644 |
| --- a/pkg/compiler/lib/src/ssa/codegen.dart |
| +++ b/pkg/compiler/lib/src/ssa/codegen.dart |
| @@ -2467,97 +2467,43 @@ class SsaCodeGenerator implements HVisitor, HBlockInformationVisitor { |
| attachLocationToLast(node); |
| } |
| - js.Expression generateTest(HInstruction input, TypeMask checkedType) { |
| + js.Expression generateReceiverOrArgumentTypeTest( |
| + HInstruction input, TypeMask checkedType) { |
| ClassWorld classWorld = compiler.world; |
| - TypeMask receiver = input.instructionType; |
| + TypeMask inputType = input.instructionType; |
| // Figure out if it is beneficial to turn this into a null check. |
| // V8 generally prefers 'typeof' checks, but for integers and |
| // indexable primitives we cannot compile this test into a single |
| // typeof check so the null check is cheaper. |
| - bool turnIntoNumCheck = input.isIntegerOrNull(compiler) |
| - && checkedType.containsOnlyInt(classWorld); |
| + bool isIntCheck = checkedType.containsOnlyInt(classWorld); |
| + bool turnIntoNumCheck = isIntCheck && input.isIntegerOrNull(compiler); |
| bool turnIntoNullCheck = !turnIntoNumCheck |
| - && (checkedType.nullable() == receiver) |
| - && (checkedType.containsOnlyInt(classWorld) |
| + && (checkedType.nullable() == inputType) |
| + && (isIntCheck |
| || checkedType.satisfies(backend.jsIndexableClass, classWorld)); |
|
sra1
2014/12/03 01:26:19
If we remove this line, string checks on string-or
|
| - js.Expression test; |
| + |
| if (turnIntoNullCheck) { |
| use(input); |
| - test = new js.Binary("==", pop(), new js.LiteralNull()); |
| - } else if (checkedType.containsOnlyInt(classWorld) && !turnIntoNumCheck) { |
| + return new js.Binary("==", pop(), new js.LiteralNull()); |
| + } else if (isIntCheck && !turnIntoNumCheck) { |
| // input is !int |
| - checkInt(input, '!=='); |
| - test = pop(); |
| - } else if (checkedType.containsOnlyNum(classWorld) || turnIntoNumCheck) { |
| + checkBigInt(input, '!=='); |
| + return pop(); |
| + } else if (turnIntoNumCheck || checkedType.containsOnlyNum(classWorld)) { |
| // input is !num |
| checkNum(input, '!=='); |
| - test = pop(); |
| + return pop(); |
| } else if (checkedType.containsOnlyBool(classWorld)) { |
| // input is !bool |
| checkBool(input, '!=='); |
| - test = pop(); |
| + return pop(); |
| } else if (checkedType.containsOnlyString(classWorld)) { |
| // input is !string |
| checkString(input, '!=='); |
| - test = pop(); |
| - } else if (checkedType.satisfies(backend.jsExtendableArrayClass, |
| - classWorld)) { |
| - // input is !Object || input is !Array || input.isFixed |
| - checkObject(input, '!=='); |
| - js.Expression objectTest = pop(); |
| - checkArray(input, '!=='); |
| - js.Expression arrayTest = pop(); |
| - checkFixedArray(input); |
| - test = new js.Binary('||', objectTest, arrayTest); |
| - test = new js.Binary('||', test, pop()); |
| - } else if (checkedType.satisfies(backend.jsMutableArrayClass, classWorld)) { |
| - // input is !Object |
| - // || ((input is !Array || input.isImmutable) |
| - // && input is !JsIndexingBehavior) |
| - checkObject(input, '!=='); |
| - js.Expression objectTest = pop(); |
| - checkArray(input, '!=='); |
| - js.Expression arrayTest = pop(); |
| - checkImmutableArray(input); |
| - js.Binary notArrayOrImmutable = new js.Binary('||', arrayTest, pop()); |
| - |
| - js.Binary notIndexing = checkIndexingBehavior(input, negative: true) |
| - ? new js.Binary('&&', notArrayOrImmutable, pop()) |
| - : notArrayOrImmutable; |
| - test = new js.Binary('||', objectTest, notIndexing); |
| - } else if (checkedType.satisfies(backend.jsArrayClass, classWorld)) { |
| - // input is !Object |
| - // || (input is !Array && input is !JsIndexingBehavior) |
| - checkObject(input, '!=='); |
| - js.Expression objectTest = pop(); |
| - checkArray(input, '!=='); |
| - js.Expression arrayTest = pop(); |
| - |
| - js.Expression notIndexing = checkIndexingBehavior(input, negative: true) |
| - ? new js.Binary('&&', arrayTest, pop()) |
| - : arrayTest; |
| - test = new js.Binary('||', objectTest, notIndexing); |
| - } else if (checkedType.satisfies(backend.jsIndexableClass, classWorld)) { |
| - // input is !String |
| - // && (input is !Object |
| - // || (input is !Array && input is !JsIndexingBehavior)) |
| - checkString(input, '!=='); |
| - js.Expression stringTest = pop(); |
| - checkObject(input, '!=='); |
| - js.Expression objectTest = pop(); |
| - checkArray(input, '!=='); |
| - js.Expression arrayTest = pop(); |
| - |
| - js.Binary notIndexingTest = checkIndexingBehavior(input, negative: true) |
| - ? new js.Binary('&&', arrayTest, pop()) |
| - : arrayTest; |
| - js.Binary notObjectOrIndexingTest = |
| - new js.Binary('||', objectTest, notIndexingTest); |
| - test = new js.Binary('&&', stringTest, notObjectOrIndexingTest); |
| - } else { |
| - compiler.internalError(input, 'Unexpected check.'); |
| + return pop(); |
| } |
| - return test; |
| + compiler.internalError(input, 'Unexpected check.'); |
| + return null; |
| } |
| void visitTypeConversion(HTypeConversion node) { |
| @@ -2568,7 +2514,8 @@ class SsaCodeGenerator implements HVisitor, HBlockInformationVisitor { |
| assert(compiler.trustTypeAnnotations || |
| !node.checkedType.containsOnlyInt(classWorld) || |
| node.checkedInput.isIntegerOrNull(compiler)); |
| - js.Expression test = generateTest(node.checkedInput, node.checkedType); |
| + js.Expression test = generateReceiverOrArgumentTypeTest( |
| + node.checkedInput, node.checkedType); |
| js.Block oldContainer = currentContainer; |
| js.Statement body = new js.Block.empty(); |
| currentContainer = body; |