| Index: sdk/lib/_internal/compiler/implementation/ssa/codegen.dart
|
| ===================================================================
|
| --- sdk/lib/_internal/compiler/implementation/ssa/codegen.dart (revision 22664)
|
| +++ sdk/lib/_internal/compiler/implementation/ssa/codegen.dart (working copy)
|
| @@ -527,10 +527,11 @@
|
| /**
|
| * Only visits the arguments starting at inputs[HInvoke.ARGUMENTS_OFFSET].
|
| */
|
| - List<js.Expression> visitArguments(List<HInstruction> inputs) {
|
| - assert(inputs.length >= HInvoke.ARGUMENTS_OFFSET);
|
| + List<js.Expression> visitArguments(List<HInstruction> inputs,
|
| + {int start: HInvoke.ARGUMENTS_OFFSET}) {
|
| + assert(inputs.length >= start);
|
| List<js.Expression> result = <js.Expression>[];
|
| - for (int i = HInvoke.ARGUMENTS_OFFSET; i < inputs.length; i++) {
|
| + for (int i = start; i < inputs.length; i++) {
|
| use(inputs[i]);
|
| result.add(pop());
|
| }
|
| @@ -1612,18 +1613,26 @@
|
| // Register this invocation to collect the types used at all call sites.
|
| backend.registerStaticInvocation(node);
|
| }
|
| - use(node.target);
|
| - push(new js.Call(pop(), visitArguments(node.inputs)), node);
|
| + Element element = node.element;
|
| + world.registerStaticUse(element);
|
| + ClassElement cls = element.getEnclosingClass();
|
| + if (element.isGenerativeConstructor()
|
| + || (element.isFactoryConstructor() && cls == compiler.listClass)) {
|
| + world.registerInstantiatedClass(cls, work.resolutionTree);
|
| + }
|
| + push(new js.VariableUse(backend.namer.isolateAccess(node.element)));
|
| + push(new js.Call(pop(), visitArguments(node.inputs, start: 0)), node);
|
| }
|
|
|
| visitInvokeSuper(HInvokeSuper node) {
|
| Element superMethod = node.element;
|
| + world.registerStaticUse(superMethod);
|
| Element superClass = superMethod.getEnclosingClass();
|
| if (superMethod.kind == ElementKind.FIELD) {
|
| String fieldName = node.caller.isShadowedByField(superMethod)
|
| ? backend.namer.shadowedFieldName(superMethod)
|
| : backend.namer.instanceFieldName(superMethod);
|
| - use(node.inputs[1]);
|
| + use(node.inputs[0]);
|
| js.PropertyAccess access =
|
| new js.PropertyAccess.field(pop(), fieldName);
|
| if (node.isSetter) {
|
| @@ -1640,7 +1649,8 @@
|
| new js.PropertyAccess.field(classReference, "prototype");
|
| js.PropertyAccess method =
|
| new js.PropertyAccess.field(prototype, methodName);
|
| - push(jsPropertyCall(method, "call", visitArguments(node.inputs)), node);
|
| + push(jsPropertyCall(
|
| + method, "call", visitArguments(node.inputs, start: 0)), node);
|
| }
|
| world.registerStaticUse(superMethod);
|
| }
|
| @@ -1988,27 +1998,17 @@
|
| }
|
|
|
| void visitStatic(HStatic node) {
|
| - // Check whether this static is used for anything else than as a target in
|
| - // a static call.
|
| - node.usedBy.forEach((HInstruction instr) {
|
| - if (instr is !HInvokeStatic) {
|
| - backend.registerNonCallStaticUse(node);
|
| - if (node.element.isFunction()) {
|
| - world.registerInstantiatedClass(
|
| - compiler.functionClass, work.resolutionTree);
|
| - }
|
| - } else if (instr.target != node) {
|
| - backend.registerNonCallStaticUse(node);
|
| - }
|
| - });
|
| Element element = node.element;
|
| - world.registerStaticUse(element);
|
| - ClassElement cls = element.getEnclosingClass();
|
| - if (element.isGenerativeConstructor()
|
| - || (element.isFactoryConstructor() && cls == compiler.listClass)) {
|
| - world.registerInstantiatedClass(cls, work.resolutionTree);
|
| + if (element.isFunction()) {
|
| + backend.registerNonCallStaticUse(node);
|
| + world.registerInstantiatedClass(
|
| + compiler.functionClass, work.resolutionTree);
|
| + push(new js.VariableUse(
|
| + backend.namer.isolateStaticClosureAccess(node.element)));
|
| + } else {
|
| + push(new js.VariableUse(backend.namer.isolateAccess(node.element)));
|
| }
|
| - push(new js.VariableUse(backend.namer.isolateAccess(node.element)));
|
| + world.registerStaticUse(element);
|
| }
|
|
|
| void visitLazyStatic(HLazyStatic node) {
|
| @@ -2182,21 +2182,6 @@
|
| push(new js.Binary('!=', pop(), new js.LiteralNull()));
|
| }
|
|
|
| - void checkFunction(HInstruction input,
|
| - DartType type,
|
| - { bool negative: false}) {
|
| - String relation = negative ? '!==' : '===';
|
| - checkTypeOf(input, relation, 'function');
|
| - js.Expression functionTest = pop();
|
| - checkObject(input, relation);
|
| - js.Expression objectTest = pop();
|
| - checkType(input, type, negative: negative);
|
| - String combiner = negative ? '||' : '&&';
|
| - push(new js.Binary(negative ? '&&' : '||',
|
| - functionTest,
|
| - new js.Binary(combiner, objectTest, pop())));
|
| - }
|
| -
|
| void checkType(HInstruction input, DartType type, {bool negative: false}) {
|
| assert(invariant(input, !type.isMalformed,
|
| message: 'Attempt to check malformed type $type'));
|
| @@ -2338,9 +2323,6 @@
|
| } else if (element == compiler.boolClass) {
|
| checkBool(input, relation);
|
| attachLocationToLast(node);
|
| - } else if (element == compiler.functionClass) {
|
| - checkFunction(input, type, negative: negative);
|
| - attachLocationToLast(node);
|
| } else if (element == compiler.intClass) {
|
| // The is check in the code tells us that it might not be an
|
| // int. So we do a typeof first to avoid possible
|
| @@ -2488,6 +2470,12 @@
|
|
|
| assert(node.isCheckedModeCheck || node.isCastTypeCheck);
|
| DartType type = node.typeExpression;
|
| + if (type.kind == TypeKind.FUNCTION) {
|
| + // TODO(5022): We currently generate $isFunction checks for
|
| + // function types.
|
| + world.registerIsCheck(
|
| + compiler.functionClass.computeType(compiler), work.resolutionTree);
|
| + }
|
| world.registerIsCheck(type, work.resolutionTree);
|
|
|
| // TODO(kasperl): For now, we ignore type checks against type
|
|
|