Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(241)

Unified Diff: sdk/lib/_internal/compiler/implementation/ssa/builder.dart

Issue 12374094: Implement complex super assignment. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 7 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « sdk/lib/_internal/compiler/implementation/resolution/members.dart ('k') | tests/co19/co19-dart2js.status » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: sdk/lib/_internal/compiler/implementation/ssa/builder.dart
===================================================================
--- sdk/lib/_internal/compiler/implementation/ssa/builder.dart (revision 19450)
+++ sdk/lib/_internal/compiler/implementation/ssa/builder.dart (working copy)
@@ -3046,17 +3046,20 @@
}
}
- generateSuperNoSuchMethodSend(Send node) {
- Selector selector = elements.getSelector(node);
+ generateSuperNoSuchMethodSend(Send node,
+ Selector selector,
+ List<HInstruction> arguments) {
SourceString name = selector.name;
ClassElement cls = currentElement.getEnclosingClass();
Element element = cls.lookupSuperMember(Compiler.NO_SUCH_METHOD);
if (element.enclosingElement.declaration != compiler.objectClass) {
// Register the call as dynamic if [:noSuchMethod:] on the super class
- // is _not_ the default implementation from [:Object:].
- compiler.enqueuer.codegen.registerDynamicInvocation(name, selector);
- }
+ // is _not_ the default implementation from [:Object:], in case
+ // the [:noSuchMethod:] implementation does an [:invokeOn:] on
+ // the invocation mirror.
+ compiler.enqueuer.codegen.registerSelectorUse(selector);
+ }
HStatic target = new HStatic(element);
add(target);
HInstruction self = localsHandler.readThis();
@@ -3068,11 +3071,6 @@
constantSystem.createString(new DartString.literal(internalName), node);
Element createInvocationMirror = backend.getCreateInvocationMirror();
-
- var arguments = new List<HInstruction>();
- if (node.argumentsNode != null) {
- addGenericSendArgumentsToList(node.arguments, arguments);
- }
var argumentsInstruction = new HLiteralList(arguments);
add(argumentsInstruction);
@@ -3117,17 +3115,13 @@
Selector selector = elements.getSelector(node);
Element element = elements[node];
if (Elements.isUnresolved(element)) {
- return generateSuperNoSuchMethodSend(node);
+ List<HInstruction> arguments = <HInstruction>[];
+ if (!node.isPropertyAccess) {
+ addGenericSendArgumentsToList(node.arguments, arguments);
+ }
+ return generateSuperNoSuchMethodSend(node, selector, arguments);
}
- // TODO(5346): Try to avoid the need for calling [declaration] before
- // creating an [HStatic].
- HInstruction target = new HStatic(element.declaration);
- HInstruction context = localsHandler.readThis();
- add(target);
- var inputs = <HInstruction>[target, context];
- if (backend.isInterceptedMethod(element)) {
- inputs.add(context);
- }
+ List<HInstruction> inputs = buildSuperAccessorInputs(element);
if (node.isPropertyAccess) {
push(new HInvokeSuper(inputs));
} else if (element.isFunction() || element.isGenerativeConstructor()) {
@@ -3579,6 +3573,38 @@
return new HInvokeDynamicMethod(selector, inputs, isIntercepted);
}
+ void handleComplexOperatorSend(SendSet node,
+ HInstruction receiver,
+ Link<Node> arguments) {
+ HInstruction rhs;
+ if (node.isPrefix || node.isPostfix) {
+ rhs = graph.addConstantInt(1, constantSystem);
+ } else {
+ visit(arguments.head);
+ assert(arguments.tail.isEmpty);
+ rhs = pop();
+ }
+ visitBinary(receiver, node.assignmentOperator, rhs,
+ elements.getOperatorSelectorInComplexSendSet(node), node);
+ }
+
+ List<HInstruction> buildSuperAccessorInputs(Element element) {
+ List<HInstruction> inputs = <HInstruction>[];
+ if (Elements.isUnresolved(element)) return inputs;
+ // TODO(5346): Try to avoid the need for calling [declaration] before
+ // creating an [HStatic].
+ HInstruction target = new HStatic(element.declaration);
+ add(target);
+ inputs.add(target);
+ HInstruction context = localsHandler.readThis();
+ inputs.add(context);
+ if (backend.isInterceptedMethod(element)) {
+ inputs.add(context);
+ }
+ return inputs;
+ }
+
+
visitSendSet(SendSet node) {
Element element = elements[node];
if (!Elements.isUnresolved(element) && element.impliesType()) {
@@ -3589,19 +3615,54 @@
}
Operator op = node.assignmentOperator;
if (node.isSuperCall) {
+ HInstruction result;
+ List<HInstruction> setterInputs = buildSuperAccessorInputs(element);
+ if (identical(node.assignmentOperator.source.stringValue, '=')) {
+ addDynamicSendArgumentsToList(node, setterInputs);
+ result = setterInputs.last;
+ } else {
+ Element getter = elements[node.selector];
+ List<HInstruction> getterInputs = buildSuperAccessorInputs(getter);
+ Link<Node> arguments = node.arguments;
+ if (node.isIndex) {
+ // If node is of the from [:super.foo[0] += 2:], the send has
+ // two arguments: the index and the left hand side. We get
+ // the index and add it as input of the getter and the
+ // setter.
+ visit(arguments.head);
+ arguments = arguments.tail;
+ HInstruction index = pop();
+ getterInputs.add(index);
+ setterInputs.add(index);
+ }
+ HInstruction getterInstruction;
+ if (Elements.isUnresolved(getter)) {
+ generateSuperNoSuchMethodSend(
+ node,
+ elements.getGetterSelectorInComplexSendSet(node),
+ getterInputs);
+ getterInstruction = pop();
+ } else {
+ getterInstruction = new HInvokeSuper(getterInputs);
+ add(getterInstruction);
+ }
+ handleComplexOperatorSend(node, getterInstruction, arguments);
+ setterInputs.add(pop());
+
+ if (node.isPostfix) {
+ result = getterInstruction;
+ } else {
+ result = setterInputs.last;
+ }
+ }
if (Elements.isUnresolved(element)) {
- return generateSuperNoSuchMethodSend(node);
+ generateSuperNoSuchMethodSend(
+ node, elements.getSelector(node), setterInputs);
+ pop();
+ } else {
+ add(new HInvokeSuper(setterInputs, isSetter: true));
}
- HInstruction target = new HStatic(element);
- HInstruction context = localsHandler.readThis();
- add(target);
- var inputs = <HInstruction>[target, context];
- addDynamicSendArgumentsToList(node, inputs);
- if (!identical(node.assignmentOperator.source.stringValue, '=')) {
- compiler.unimplemented('complex super assignment',
- node: node.assignmentOperator);
- }
- push(new HInvokeSuper(inputs, isSetter: true));
+ stack.add(result);
} else if (node.isIndex) {
if (const SourceString("=") == op.source) {
// TODO(kasperl): We temporarily disable inlining because the
@@ -3613,36 +3674,32 @@
} else {
visit(node.receiver);
HInstruction receiver = pop();
- visit(node.argumentsNode);
- HInstruction value;
+ Link<Node> arguments = node.arguments;
HInstruction index;
- // Compound assignments are considered as being prefix.
- bool isCompoundAssignment = op.source.stringValue.endsWith('=');
- bool isPrefix = !node.isPostfix;
- if (isCompoundAssignment) {
- value = pop();
+ if (node.isIndex) {
+ visit(arguments.head);
+ arguments = arguments.tail;
index = pop();
- } else {
- index = pop();
- value = graph.addConstantInt(1, constantSystem);
}
- HInvokeDynamicMethod left = buildInvokeDynamic(
+ HInvokeDynamicMethod getterInstruction = buildInvokeDynamic(
node,
elements.getGetterSelectorInComplexSendSet(node),
receiver,
<HInstruction>[index]);
- add(left);
- visitBinary(left, op, value,
- elements.getOperatorSelectorInComplexSendSet(node), node);
- value = pop();
+ add(getterInstruction);
+
+ handleComplexOperatorSend(node, getterInstruction, arguments);
+ HInstruction value = pop();
+
HInvokeDynamicMethod assign = buildInvokeDynamic(
node, elements.getSelector(node), receiver, [index, value]);
add(assign);
- if (isPrefix) {
+
+ if (node.isPostfix) {
+ stack.add(getterInstruction);
+ } else {
stack.add(value);
- } else {
- stack.add(left);
}
}
} else if (const SourceString("=") == op.source) {
@@ -3657,8 +3714,6 @@
assert(const SourceString("++") == op.source ||
const SourceString("--") == op.source ||
node.assignmentOperator.source.stringValue.endsWith("="));
- bool isCompoundAssignment = !node.arguments.isEmpty;
- bool isPrefix = !node.isPostfix; // Compound assignments are prefix.
// [receiver] is only used if the node is an instance send.
HInstruction receiver = null;
@@ -3669,28 +3724,20 @@
} else {
generateGetter(node, elements[node.selector]);
}
- HInstruction left = pop();
- HInstruction right;
- if (isCompoundAssignment) {
- visit(node.argumentsNode);
- right = pop();
- } else {
- right = graph.addConstantInt(1, constantSystem);
- }
- visitBinary(left, op, right,
- elements.getOperatorSelectorInComplexSendSet(node), node);
- HInstruction operation = pop();
- assert(operation != null);
+ HInstruction getterInstruction = pop();
+ handleComplexOperatorSend(node, getterInstruction, node.arguments);
+ HInstruction value = pop();
+ assert(value != null);
if (Elements.isInstanceSend(node, elements)) {
assert(receiver != null);
- generateInstanceSetterWithCompiledReceiver(node, receiver, operation);
+ generateInstanceSetterWithCompiledReceiver(node, receiver, value);
} else {
assert(receiver == null);
- generateSetter(node, element, operation);
+ generateSetter(node, element, value);
}
- if (!isPrefix) {
+ if (node.isPostfix) {
pop();
- stack.add(left);
+ stack.add(getterInstruction);
}
}
}
« no previous file with comments | « sdk/lib/_internal/compiler/implementation/resolution/members.dart ('k') | tests/co19/co19-dart2js.status » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698