| Index: sdk/lib/_internal/compiler/implementation/ssa/codegen.dart
|
| diff --git a/sdk/lib/_internal/compiler/implementation/ssa/codegen.dart b/sdk/lib/_internal/compiler/implementation/ssa/codegen.dart
|
| index f5499468c8c294afb26d625abef9159b426bdecb..b1eb8f2f7f59b3ef335005e7c9cdff6a1fff4127 100644
|
| --- a/sdk/lib/_internal/compiler/implementation/ssa/codegen.dart
|
| +++ b/sdk/lib/_internal/compiler/implementation/ssa/codegen.dart
|
| @@ -2216,8 +2216,7 @@ abstract class SsaCodeGenerator implements HVisitor, HBlockInformationVisitor {
|
| if (negative) push(new js.Prefix('!', pop()));
|
| }
|
|
|
| - void checkType(HInstruction input, HInstruction interceptor,
|
| - DartType type, {bool negative: false}) {
|
| + void checkType(HInstruction input, DartType type, {bool negative: false}) {
|
| Element element = type.element;
|
| if (element == backend.jsArrayClass) {
|
| checkArray(input, negative ? '!==': '===');
|
| @@ -2244,8 +2243,20 @@ abstract class SsaCodeGenerator implements HVisitor, HBlockInformationVisitor {
|
| }
|
| return;
|
| }
|
| - use(interceptor);
|
| + use(input);
|
| +
|
| + // Hack in interceptor. Ideally the interceptor would occur at the
|
| + // instruction level to allow optimizations, and checks would be broken into
|
| + // several smaller tests.
|
| + // This code is a slice of visitInterceptor for the univeral interceptor.
|
| + String interceptorName = backend.namer.getInterceptorName(
|
| + backend.getInterceptorMethod, backend.interceptedClasses);
|
| + backend.registerSpecializedGetInterceptor(backend.interceptedClasses);
|
| + backend.registerUseInterceptor(world);
|
|
|
| + var isolate = new js.VariableUse(backend.namer.CURRENT_ISOLATE);
|
| + List<js.Expression> arguments = <js.Expression>[pop()];
|
| + push(jsPropertyCall(isolate, interceptorName, arguments));
|
| world.registerIsCheck(type, work.resolutionTree);
|
|
|
| js.PropertyAccess field =
|
| @@ -2257,7 +2268,6 @@ abstract class SsaCodeGenerator implements HVisitor, HBlockInformationVisitor {
|
| }
|
|
|
| void handleNumberOrStringSupertypeCheck(HInstruction input,
|
| - HInstruction interceptor,
|
| DartType type,
|
| { bool negative: false }) {
|
| assert(!identical(type.element, compiler.listClass)
|
| @@ -2270,7 +2280,7 @@ abstract class SsaCodeGenerator implements HVisitor, HBlockInformationVisitor {
|
| js.Expression stringTest = pop();
|
| checkObject(input, relation);
|
| js.Expression objectTest = pop();
|
| - checkType(input, interceptor, type, negative: negative);
|
| + checkType(input, type, negative: negative);
|
| String combiner = negative ? '&&' : '||';
|
| String combiner2 = negative ? '||' : '&&';
|
| push(new js.Binary(combiner,
|
| @@ -2279,7 +2289,6 @@ abstract class SsaCodeGenerator implements HVisitor, HBlockInformationVisitor {
|
| }
|
|
|
| void handleStringSupertypeCheck(HInstruction input,
|
| - HInstruction interceptor,
|
| DartType type,
|
| { bool negative: false }) {
|
| assert(!identical(type.element, compiler.listClass)
|
| @@ -2290,7 +2299,7 @@ abstract class SsaCodeGenerator implements HVisitor, HBlockInformationVisitor {
|
| js.Expression stringTest = pop();
|
| checkObject(input, relation);
|
| js.Expression objectTest = pop();
|
| - checkType(input, interceptor, type, negative: negative);
|
| + checkType(input, type, negative: negative);
|
| String combiner = negative ? '||' : '&&';
|
| push(new js.Binary(negative ? '&&' : '||',
|
| stringTest,
|
| @@ -2298,7 +2307,6 @@ abstract class SsaCodeGenerator implements HVisitor, HBlockInformationVisitor {
|
| }
|
|
|
| void handleListOrSupertypeCheck(HInstruction input,
|
| - HInstruction interceptor,
|
| DartType type,
|
| { bool negative: false }) {
|
| assert(!identical(type.element, compiler.stringClass)
|
| @@ -2309,7 +2317,7 @@ abstract class SsaCodeGenerator implements HVisitor, HBlockInformationVisitor {
|
| js.Expression objectTest = pop();
|
| checkArray(input, relation);
|
| js.Expression arrayTest = pop();
|
| - checkType(input, interceptor, type, negative: negative);
|
| + checkType(input, type, negative: negative);
|
| String combiner = negative ? '&&' : '||';
|
| push(new js.Binary(negative ? '||' : '&&',
|
| objectTest,
|
| @@ -2335,7 +2343,6 @@ abstract class SsaCodeGenerator implements HVisitor, HBlockInformationVisitor {
|
| if (negative) push(new js.Prefix('!', pop()));
|
| } else {
|
| assert(node.isRawCheck);
|
| - HInstruction interceptor = node.interceptor;
|
| LibraryElement coreLibrary = compiler.coreLibrary;
|
| ClassElement objectClass = compiler.objectClass;
|
| Element element = type.element;
|
| @@ -2370,33 +2377,46 @@ abstract class SsaCodeGenerator implements HVisitor, HBlockInformationVisitor {
|
| checkBigInt(input, relation);
|
| push(new js.Binary(negative ? '||' : '&&', numTest, pop()), node);
|
| } else if (Elements.isNumberOrStringSupertype(element, compiler)) {
|
| - handleNumberOrStringSupertypeCheck(
|
| - input, interceptor, type, negative: negative);
|
| + handleNumberOrStringSupertypeCheck(input, type, negative: negative);
|
| attachLocationToLast(node);
|
| } else if (Elements.isStringOnlySupertype(element, compiler)) {
|
| - handleStringSupertypeCheck(
|
| - input, interceptor, type, negative: negative);
|
| + handleStringSupertypeCheck(input, type, negative: negative);
|
| attachLocationToLast(node);
|
| } else if (identical(element, compiler.listClass)
|
| || Elements.isListSupertype(element, compiler)) {
|
| - handleListOrSupertypeCheck(
|
| - input, interceptor, type, negative: negative);
|
| + handleListOrSupertypeCheck(input, type, negative: negative);
|
| attachLocationToLast(node);
|
| - } else if (type.kind == TypeKind.FUNCTION) {
|
| - checkType(input, interceptor, type, negative: negative);
|
| + } else if (element.isTypedef()) {
|
| + if (negative) {
|
| + checkNull(input);
|
| + } else {
|
| + checkNonNull(input);
|
| + }
|
| + js.Expression nullTest = pop();
|
| + checkType(input, type, negative: negative);
|
| + push(new js.Binary(negative ? '||' : '&&', nullTest, pop()));
|
| attachLocationToLast(node);
|
| } else if ((input.canBePrimitive(compiler)
|
| && !input.canBePrimitiveArray(compiler))
|
| || input.canBeNull()) {
|
| checkObject(input, relation);
|
| js.Expression objectTest = pop();
|
| - checkType(input, interceptor, type, negative: negative);
|
| + checkType(input, type, negative: negative);
|
| push(new js.Binary(negative ? '||' : '&&', objectTest, pop()), node);
|
| } else {
|
| - checkType(input, interceptor, type, negative: negative);
|
| + checkType(input, type, negative: negative);
|
| attachLocationToLast(node);
|
| }
|
| }
|
| + if (node.nullOk) {
|
| + if (negative) {
|
| + checkNonNull(input);
|
| + push(new js.Binary('&&', pop(), pop()), node);
|
| + } else {
|
| + checkNull(input);
|
| + push(new js.Binary('||', pop(), pop()), node);
|
| + }
|
| + }
|
| }
|
|
|
| js.Expression generateTest(HCheck node) {
|
|
|