| Index: pkg/compiler/lib/src/cps_ir/cps_ir_builder_task.dart
|
| diff --git a/pkg/compiler/lib/src/cps_ir/cps_ir_builder_task.dart b/pkg/compiler/lib/src/cps_ir/cps_ir_builder_task.dart
|
| index b7d0985b251e59240065c02a389c84c77ab9699c..516475e2ceff351e037a0f1a607ae90f3658f1d5 100644
|
| --- a/pkg/compiler/lib/src/cps_ir/cps_ir_builder_task.dart
|
| +++ b/pkg/compiler/lib/src/cps_ir/cps_ir_builder_task.dart
|
| @@ -17,6 +17,7 @@ import '../js_backend/js_backend.dart' show JavaScriptBackend;
|
| import '../resolution/semantic_visitor.dart';
|
| import '../resolution/operators.dart' as op;
|
| import '../tree/tree.dart' as ast;
|
| +import '../types/types.dart' show TypeMask;
|
| import '../universe/universe.dart' show SelectorKind, CallStructure;
|
| import 'cps_ir_nodes.dart' as ir;
|
| import 'cps_ir_builder.dart';
|
| @@ -166,28 +167,6 @@ abstract class IrBuilderVisitor extends ast.Visitor<ir.Primitive>
|
| /// Read the value of [field].
|
| ir.Primitive buildStaticFieldGet(FieldElement field, SourceInformation src);
|
|
|
| - /// Creates a [TypedSelector] variant of [newSelector] using the type of
|
| - /// [oldSelector], if available.
|
| - ///
|
| - /// This is needed to preserve inferred receiver types when creating new
|
| - /// selectors.
|
| - Selector useSelectorType(Selector newSelector, Selector oldSelector) {
|
| - // TODO(asgerf,johnniwinther): This works but it is brittle.
|
| - // We should decouple selectors from inferred receiver type masks.
|
| - // TODO(asgerf): Use this whenever we create a selector for a dynamic call.
|
| - if (oldSelector is TypedSelector) {
|
| - return new TypedSelector(oldSelector.mask, newSelector, compiler.world);
|
| - } else {
|
| - return newSelector;
|
| - }
|
| - }
|
| -
|
| - /// Like [useSelectorType], except the original typed selector is obtained
|
| - /// from the [node].
|
| - Selector useSelectorTypeOfNode(Selector newSelector, ast.Send node) {
|
| - return useSelectorType(newSelector, elements.getSelector(node));
|
| - }
|
| -
|
| ir.FunctionDefinition _makeFunctionBody(FunctionElement element,
|
| ast.FunctionExpression node) {
|
| FunctionSignature signature = element.functionSignature;
|
| @@ -334,6 +313,10 @@ abstract class IrBuilderVisitor extends ast.Visitor<ir.Primitive>
|
| buildVariableDeclaration: subbuild(variableDeclaration),
|
| variableElement: variableElement,
|
| variableSelector: selector,
|
| + variableMask: elements.getTypeMask(node),
|
| + currentMask: elements.getCurrentTypeMask(node),
|
| + moveNextMask: elements.getMoveNextTypeMask(node),
|
| + iteratorMask: elements.getIteratorTypeMask(node),
|
| buildBody: subbuild(node.body),
|
| target: elements.getTargetDefinition(node),
|
| closureScope: getClosureScopeForNode(node));
|
| @@ -581,7 +564,8 @@ abstract class IrBuilderVisitor extends ast.Visitor<ir.Primitive>
|
| _) {
|
| return irBuilder.buildDynamicGet(
|
| translateReceiver(receiver),
|
| - selector);
|
| + selector,
|
| + elements.getTypeMask(node));
|
| }
|
|
|
| @override
|
| @@ -593,7 +577,8 @@ abstract class IrBuilderVisitor extends ast.Visitor<ir.Primitive>
|
| ir.Primitive target = visit(receiver);
|
| return irBuilder.buildIfNotNullSend(
|
| target,
|
| - nested(() => irBuilder.buildDynamicGet(target, selector)));
|
| + nested(() => irBuilder.buildDynamicGet(
|
| + target, selector, elements.getTypeMask(node))));
|
| }
|
|
|
| @override
|
| @@ -678,7 +663,8 @@ abstract class IrBuilderVisitor extends ast.Visitor<ir.Primitive>
|
| ir.Primitive visitUnresolvedSuperGet(
|
| ast.Send node,
|
| Element element, _) {
|
| - return buildInstanceNoSuchMethod(elements.getSelector(node), []);
|
| + return buildInstanceNoSuchMethod(
|
| + elements.getSelector(node), elements.getTypeMask(node), []);
|
| }
|
|
|
| @override
|
| @@ -762,14 +748,16 @@ abstract class IrBuilderVisitor extends ast.Visitor<ir.Primitive>
|
| return irBuilder.buildNegation(check);
|
| }
|
|
|
| - ir.Primitive translateBinary(ast.Node left,
|
| + ir.Primitive translateBinary(ast.Send node,
|
| + ast.Node left,
|
| op.BinaryOperator operator,
|
| ast.Node right) {
|
| Selector selector = new Selector.binaryOperator(operator.selectorName);
|
| ir.Primitive receiver = visit(left);
|
| List<ir.Primitive> arguments = <ir.Primitive>[visit(right)];
|
| arguments = normalizeDynamicArguments(selector.callStructure, arguments);
|
| - return irBuilder.buildDynamicInvocation(receiver, selector, arguments);
|
| + return irBuilder.buildDynamicInvocation(
|
| + receiver, selector, elements.getTypeMask(node), arguments);
|
| }
|
|
|
| @override
|
| @@ -777,7 +765,7 @@ abstract class IrBuilderVisitor extends ast.Visitor<ir.Primitive>
|
| ast.Node left,
|
| op.BinaryOperator operator,
|
| ast.Node right, _) {
|
| - return translateBinary(left, operator, right);
|
| + return translateBinary(node, left, operator, right);
|
| }
|
|
|
| @override
|
| @@ -788,7 +776,8 @@ abstract class IrBuilderVisitor extends ast.Visitor<ir.Primitive>
|
| ir.Primitive target = visit(receiver);
|
| List<ir.Primitive> arguments = <ir.Primitive>[visit(index)];
|
| arguments = normalizeDynamicArguments(selector.callStructure, arguments);
|
| - return irBuilder.buildDynamicInvocation(target, selector, arguments);
|
| + return irBuilder.buildDynamicInvocation(
|
| + target, selector, elements.getTypeMask(node), arguments);
|
| }
|
|
|
| ir.Primitive translateSuperBinary(FunctionElement function,
|
| @@ -826,7 +815,7 @@ abstract class IrBuilderVisitor extends ast.Visitor<ir.Primitive>
|
| ast.Node left,
|
| ast.Node right,
|
| _) {
|
| - return translateBinary(left, op.BinaryOperator.EQ, right);
|
| + return translateBinary(node, left, op.BinaryOperator.EQ, right);
|
| }
|
|
|
| @override
|
| @@ -853,7 +842,7 @@ abstract class IrBuilderVisitor extends ast.Visitor<ir.Primitive>
|
| ast.Node right,
|
| _) {
|
| return irBuilder.buildNegation(
|
| - translateBinary(left, op.BinaryOperator.NOT_EQ, right));
|
| + translateBinary(node, left, op.BinaryOperator.NOT_EQ, right));
|
| }
|
|
|
| @override
|
| @@ -872,7 +861,8 @@ abstract class IrBuilderVisitor extends ast.Visitor<ir.Primitive>
|
| // TODO(johnniwinther): Clean up the creation of selectors.
|
| Selector selector = operator.selector;
|
| ir.Primitive receiver = translateReceiver(expression);
|
| - return irBuilder.buildDynamicInvocation(receiver, selector, const []);
|
| + return irBuilder.buildDynamicInvocation(
|
| + receiver, selector, elements.getTypeMask(node), const []);
|
| }
|
|
|
| @override
|
| @@ -929,7 +919,7 @@ abstract class IrBuilderVisitor extends ast.Visitor<ir.Primitive>
|
| Selector selector,
|
| _) {
|
| return irBuilder.buildDynamicInvocation(
|
| - translateReceiver(receiver), selector,
|
| + translateReceiver(receiver), selector, elements.getTypeMask(node),
|
| translateDynamicArguments(arguments, selector.callStructure));
|
| }
|
|
|
| @@ -944,7 +934,7 @@ abstract class IrBuilderVisitor extends ast.Visitor<ir.Primitive>
|
| return irBuilder.buildIfNotNullSend(
|
| target,
|
| nested(() => irBuilder.buildDynamicInvocation(
|
| - target, selector,
|
| + target, selector, elements.getTypeMask(node),
|
| translateDynamicArguments(arguments, selector.callStructure))));
|
| }
|
|
|
| @@ -1076,6 +1066,7 @@ abstract class IrBuilderVisitor extends ast.Visitor<ir.Primitive>
|
| CallStructure callStructure, _) {
|
| return buildInstanceNoSuchMethod(
|
| elements.getSelector(node),
|
| + elements.getTypeMask(node),
|
| translateDynamicArguments(arguments, callStructure));
|
| }
|
|
|
| @@ -1087,6 +1078,7 @@ abstract class IrBuilderVisitor extends ast.Visitor<ir.Primitive>
|
| Selector selector, _) {
|
| return buildInstanceNoSuchMethod(
|
| elements.getSelector(node),
|
| + elements.getTypeMask(node),
|
| translateDynamicArguments(arguments, selector.callStructure));
|
| }
|
|
|
| @@ -1120,7 +1112,7 @@ abstract class IrBuilderVisitor extends ast.Visitor<ir.Primitive>
|
| ast.Node rhs,
|
| _) {
|
| return irBuilder.buildDynamicIndexSet(
|
| - visit(receiver), visit(index), visit(rhs));
|
| + visit(receiver), elements.getTypeMask(node), visit(index), visit(rhs));
|
| }
|
|
|
| @override
|
| @@ -1160,8 +1152,10 @@ abstract class IrBuilderVisitor extends ast.Visitor<ir.Primitive>
|
| List<ir.Primitive> arguments = <ir.Primitive>[rhsValue];
|
| arguments = normalizeDynamicArguments(
|
| operatorSelector.callStructure, arguments);
|
| + // TODO(johnniwinther): Find the type mask for the operation.
|
| ir.Primitive result =
|
| - irBuilder.buildDynamicInvocation(value, operatorSelector, arguments);
|
| + irBuilder.buildDynamicInvocation(
|
| + value, operatorSelector, null, arguments);
|
| setValue(result);
|
| return rhs.kind == CompoundKind.POSTFIX ? value : result;
|
| }
|
| @@ -1176,6 +1170,7 @@ abstract class IrBuilderVisitor extends ast.Visitor<ir.Primitive>
|
| return irBuilder.buildDynamicSet(
|
| translateReceiver(receiver),
|
| selector,
|
| + elements.getTypeMask(node),
|
| visit(rhs));
|
| }
|
|
|
| @@ -1189,7 +1184,8 @@ abstract class IrBuilderVisitor extends ast.Visitor<ir.Primitive>
|
| ir.Primitive target = visit(receiver);
|
| return irBuilder.buildIfNotNullSend(
|
| target,
|
| - nested(() => irBuilder.buildDynamicSet(target, selector, visit(rhs))));
|
| + nested(() => irBuilder.buildDynamicSet(
|
| + target, selector, elements.getTypeMask(node), visit(rhs))));
|
| }
|
|
|
| @override
|
| @@ -1261,7 +1257,7 @@ abstract class IrBuilderVisitor extends ast.Visitor<ir.Primitive>
|
|
|
| @override
|
| ir.Primitive handleDynamicCompounds(
|
| - ast.Send node,
|
| + ast.SendSet node,
|
| ast.Node receiver,
|
| CompoundRhs rhs,
|
| Selector getterSelector,
|
| @@ -1270,10 +1266,14 @@ abstract class IrBuilderVisitor extends ast.Visitor<ir.Primitive>
|
| ir.Primitive target = translateReceiver(receiver);
|
| ir.Primitive helper() {
|
| return translateCompounds(
|
| - getValue: () => irBuilder.buildDynamicGet(target, getterSelector),
|
| + getValue: () => irBuilder.buildDynamicGet(
|
| + target,
|
| + getterSelector,
|
| + elements.getGetterTypeMaskInComplexSendSet(node)),
|
| rhs: rhs,
|
| setValue: (ir.Primitive result) {
|
| - irBuilder.buildDynamicSet(target, setterSelector, result);
|
| + irBuilder.buildDynamicSet(
|
| + target, setterSelector, elements.getTypeMask(node), result);
|
| });
|
| }
|
| return node.isConditional
|
| @@ -1361,15 +1361,19 @@ abstract class IrBuilderVisitor extends ast.Visitor<ir.Primitive>
|
| });
|
| }
|
|
|
| - ir.Primitive buildSuperNoSuchGetter(Element element) {
|
| + ir.Primitive buildSuperNoSuchGetter(Element element, TypeMask mask) {
|
| return buildInstanceNoSuchMethod(
|
| new Selector.getter(element.name, element.library),
|
| + mask,
|
| const <ir.Primitive>[]);
|
| }
|
|
|
| - ir.Primitive buildSuperNoSuchSetter(Element element, ir.Primitive value) {
|
| + ir.Primitive buildSuperNoSuchSetter(Element element,
|
| + TypeMask mask,
|
| + ir.Primitive value) {
|
| return buildInstanceNoSuchMethod(
|
| new Selector.setter(element.name, element.library),
|
| + mask,
|
| <ir.Primitive>[value]);
|
| }
|
|
|
| @@ -1393,7 +1397,9 @@ abstract class IrBuilderVisitor extends ast.Visitor<ir.Primitive>
|
| return irBuilder.buildSuperMethodGet(getter);
|
| case CompoundGetter.UNRESOLVED:
|
| // TODO(johnniwinther): Ensure [getter] is not null.
|
| - return buildSuperNoSuchGetter(getter != null ? getter : setter);
|
| + return buildSuperNoSuchGetter(
|
| + getter != null ? getter : setter,
|
| + elements.getGetterTypeMaskInComplexSendSet(node));
|
| }
|
| },
|
| rhs: rhs,
|
| @@ -1404,7 +1410,7 @@ abstract class IrBuilderVisitor extends ast.Visitor<ir.Primitive>
|
| case CompoundSetter.SETTER:
|
| return irBuilder.buildSuperSetterSet(setter, result);
|
| case CompoundSetter.INVALID:
|
| - return buildSuperNoSuchSetter(setter, result);
|
| + return buildSuperNoSuchSetter(setter, elements.getTypeMask(node), result);
|
| }
|
| });
|
| }
|
| @@ -1436,11 +1442,19 @@ abstract class IrBuilderVisitor extends ast.Visitor<ir.Primitive>
|
| List<ir.Primitive> arguments = <ir.Primitive>[indexValue];
|
| arguments =
|
| normalizeDynamicArguments(selector.callStructure, arguments);
|
| - return irBuilder.buildDynamicInvocation(target, selector, arguments);
|
| + return irBuilder.buildDynamicInvocation(
|
| + target,
|
| + selector,
|
| + elements.getGetterTypeMaskInComplexSendSet(node),
|
| + arguments);
|
| },
|
| rhs: rhs,
|
| setValue: (ir.Primitive result) {
|
| - irBuilder.buildDynamicIndexSet(target, indexValue, result);
|
| + irBuilder.buildDynamicIndexSet(
|
| + target,
|
| + elements.getTypeMask(node),
|
| + indexValue,
|
| + result);
|
| });
|
| }
|
|
|
| @@ -1461,7 +1475,9 @@ abstract class IrBuilderVisitor extends ast.Visitor<ir.Primitive>
|
| return irBuilder.buildSuperIndex(indexFunction, indexValue);
|
| } else {
|
| return buildInstanceNoSuchMethod(
|
| - new Selector.index(), <ir.Primitive>[indexValue]);
|
| + new Selector.index(),
|
| + elements.getGetterTypeMaskInComplexSendSet(node),
|
| + <ir.Primitive>[indexValue]);
|
| }
|
| },
|
| rhs: rhs,
|
| @@ -1470,7 +1486,9 @@ abstract class IrBuilderVisitor extends ast.Visitor<ir.Primitive>
|
| irBuilder.buildSuperIndexSet(indexSetFunction, indexValue, result);
|
| } else {
|
| buildInstanceNoSuchMethod(
|
| - new Selector.indexSet(), <ir.Primitive>[indexValue, result]);
|
| + new Selector.indexSet(),
|
| + elements.getTypeMask(node),
|
| + <ir.Primitive>[indexValue, result]);
|
| }
|
| });
|
| }
|
| @@ -1513,6 +1531,7 @@ abstract class IrBuilderVisitor extends ast.Visitor<ir.Primitive>
|
|
|
| ir.Primitive buildInstanceNoSuchMethod(
|
| Selector selector,
|
| + TypeMask mask,
|
| List<ir.Primitive> arguments);
|
|
|
| ir.Primitive buildRuntimeError(String message);
|
| @@ -1631,8 +1650,8 @@ abstract class IrBuilderVisitor extends ast.Visitor<ir.Primitive>
|
| Element function,
|
| ast.Node index, _) {
|
| // Assume the index getter is missing.
|
| - Selector selector = useSelectorTypeOfNode(new Selector.index(), node);
|
| - return buildInstanceNoSuchMethod(selector, [visit(index)]);
|
| + return buildInstanceNoSuchMethod(
|
| + new Selector.index(), elements.getTypeMask(node), [visit(index)]);
|
| }
|
|
|
| @override
|
| @@ -1643,6 +1662,7 @@ abstract class IrBuilderVisitor extends ast.Visitor<ir.Primitive>
|
| ast.Node argument, _) {
|
| return buildInstanceNoSuchMethod(
|
| elements.getSelector(node),
|
| + elements.getTypeMask(node),
|
| [visit(argument)]);
|
| }
|
|
|
| @@ -1651,7 +1671,8 @@ abstract class IrBuilderVisitor extends ast.Visitor<ir.Primitive>
|
| ast.Send node,
|
| op.UnaryOperator operator,
|
| Element element, _) {
|
| - return buildInstanceNoSuchMethod(elements.getSelector(node), []);
|
| + return buildInstanceNoSuchMethod(
|
| + elements.getSelector(node), elements.getTypeMask(node), []);
|
| }
|
|
|
| @override
|
| @@ -1739,10 +1760,10 @@ abstract class IrBuilderVisitor extends ast.Visitor<ir.Primitive>
|
| ast.SendSet node,
|
| FieldElement field,
|
| ast.Node rhs, _) {
|
| - Selector selector = useSelectorTypeOfNode(
|
| + return buildInstanceNoSuchMethod(
|
| new Selector.setter(field.name, field.library),
|
| - node);
|
| - return buildInstanceNoSuchMethod(selector, [visit(rhs)]);
|
| + elements.getTypeMask(node),
|
| + [visit(rhs)]);
|
| }
|
|
|
| @override
|
| @@ -1807,10 +1828,10 @@ abstract class IrBuilderVisitor extends ast.Visitor<ir.Primitive>
|
| FunctionElement getter,
|
| ast.Node rhs,
|
| _) {
|
| - Selector selector = useSelectorTypeOfNode(
|
| + return buildInstanceNoSuchMethod(
|
| new Selector.setter(getter.name, getter.library),
|
| - node);
|
| - return buildInstanceNoSuchMethod(selector, [visit(rhs)]);
|
| + elements.getTypeMask(node),
|
| + [visit(rhs)]);
|
| }
|
|
|
| @override
|
| @@ -1819,20 +1840,20 @@ abstract class IrBuilderVisitor extends ast.Visitor<ir.Primitive>
|
| MethodElement method,
|
| ast.Node rhs,
|
| _) {
|
| - Selector selector = useSelectorTypeOfNode(
|
| + return buildInstanceNoSuchMethod(
|
| new Selector.setter(method.name, method.library),
|
| - node);
|
| - return buildInstanceNoSuchMethod(selector, [visit(rhs)]);
|
| + elements.getTypeMask(node),
|
| + [visit(rhs)]);
|
| }
|
|
|
| @override
|
| ir.Primitive visitSuperSetterGet(
|
| ast.Send node,
|
| FunctionElement setter, _) {
|
| - Selector selector = useSelectorTypeOfNode(
|
| + return buildInstanceNoSuchMethod(
|
| new Selector.setter(setter.name, setter.library),
|
| - node);
|
| - return buildInstanceNoSuchMethod(selector, []);
|
| + elements.getTypeMask(node),
|
| + []);
|
| }
|
|
|
| @override
|
| @@ -1844,10 +1865,10 @@ abstract class IrBuilderVisitor extends ast.Visitor<ir.Primitive>
|
| List<ir.Primitive> args =
|
| translateDynamicArguments(arguments, callStructure);
|
| Name name = new Name(setter.name, setter.library);
|
| - Selector selector = useSelectorTypeOfNode(
|
| + return buildInstanceNoSuchMethod(
|
| new Selector(SelectorKind.CALL, name, callStructure),
|
| - node);
|
| - return buildInstanceNoSuchMethod(selector, args);
|
| + elements.getTypeMask(node),
|
| + args);
|
| }
|
|
|
| ir.FunctionDefinition nullIfGiveup(ir.FunctionDefinition action()) {
|
| @@ -2765,10 +2786,12 @@ class JsIrBuilderVisitor extends IrBuilderVisitor {
|
|
|
| @override
|
| ir.Primitive buildInstanceNoSuchMethod(Selector selector,
|
| + TypeMask mask,
|
| List<ir.Primitive> arguments) {
|
| return irBuilder.buildDynamicInvocation(
|
| irBuilder.buildThis(),
|
| - useSelectorType(compiler.noSuchMethodSelector, selector),
|
| + compiler.noSuchMethodSelector,
|
| + mask,
|
| [irBuilder.buildInvocationMirror(selector, arguments)]);
|
| }
|
|
|
|
|