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

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
Index: sdk/lib/_internal/compiler/implementation/ssa/builder.dart
===================================================================
--- sdk/lib/_internal/compiler/implementation/ssa/builder.dart (revision 19425)
+++ sdk/lib/_internal/compiler/implementation/ssa/builder.dart (working copy)
@@ -3046,17 +3046,26 @@
}
}
- 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.
+ if (selector.isGetter()) {
kasperl 2013/03/05 07:32:36 Could this logic be moved to the enqueuer? If we h
ngeoffray 2013/03/05 08:46:25 Done.
+ compiler.enqueuer.codegen.registerDynamicGetter(name, selector);
+ } else if (selector.isSetter()) {
+ compiler.enqueuer.codegen.registerDynamicSetter(name, selector);
+ } else {
+ compiler.enqueuer.codegen.registerDynamicInvocation(name, selector);
+ }
+ }
HStatic target = new HStatic(element);
add(target);
HInstruction self = localsHandler.readThis();
@@ -3068,11 +3077,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,7 +3121,11 @@
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].
@@ -3589,19 +3597,78 @@
}
Operator op = node.assignmentOperator;
if (node.isSuperCall) {
kasperl 2013/03/05 07:32:36 Think about if some of this could be shared with t
+ HInstruction toPush;
kasperl 2013/03/05 07:32:36 I'd call this the value/result or something like t
ngeoffray 2013/03/05 08:46:25 Done.
+ List<HInstruction> setterInputs = <HInstruction>[];
+ HInstruction context = localsHandler.readThis();
+ if (!Elements.isUnresolved(element)) {
+ HInstruction target = new HStatic(element);
kasperl 2013/03/05 07:32:36 Is any of this refactorable? The resolved target/g
ngeoffray 2013/03/05 08:46:25 Done.
+ add(target);
+ setterInputs.add(target);
+ setterInputs.add(context);
+ if (backend.isInterceptedMethod(element)) {
+ setterInputs.add(context);
+ }
+ }
+ if (identical(node.assignmentOperator.source.stringValue, '=')) {
+ addDynamicSendArgumentsToList(node, setterInputs);
+ toPush = setterInputs.last;
+ } else {
+ Element getter = elements[node.selector];
+ List<HInstruction> getterInputs = <HInstruction>[];
+ if (!Elements.isUnresolved(getter)) {
+ HInstruction getterTarget = new HStatic(getter);
+ add(getterTarget);
+ getterInputs.add(getterTarget);
+ getterInputs.add(context);
+ if (backend.isInterceptedMethod(getter)) {
+ getterInputs.add(context);
+ }
+ }
+ Link<Node> arguments = node.arguments;
kasperl 2013/03/05 07:32:36 Add a comment that explains what you're dealing wi
ngeoffray 2013/03/05 08:46:25 Done.
+ if (node.isIndex) {
+ visit(arguments.head);
+ arguments = arguments.tail;
+ HInstruction index = pop();
+ getterInputs.add(index);
+ setterInputs.add(index);
+ }
+ HInstruction getterInstruction;
kasperl 2013/03/05 07:32:36 Could this (the computation of the getterInstructi
ngeoffray 2013/03/05 08:46:25 Done.
+ if (Elements.isUnresolved(getter)) {
+ generateSuperNoSuchMethodSend(
+ node,
+ elements.getGetterSelectorInComplexSendSet(node),
+ getterInputs);
+ getterInstruction = pop();
+ } else {
+ getterInstruction = new HInvokeSuper(getterInputs);
+ add(getterInstruction);
+ }
+ HInstruction rhs;
kasperl 2013/03/05 07:32:36 Do we have code like this elsewhere in the builder
ngeoffray 2013/03/05 08:46:25 Yes, refactored.
+ if (node.isPrefix || node.isPostfix) {
+ rhs = graph.addConstantInt(1, constantSystem);
+ } else {
+ visit(arguments.head);
+ assert(arguments.tail.isEmpty);
+ rhs = pop();
+ }
+ visitBinary(getterInstruction, op, rhs,
+ elements.getOperatorSelectorInComplexSendSet(node), node);
+ setterInputs.add(pop());
+
+ if (node.isPostfix) {
+ toPush = getterInstruction;
+ } else {
+ toPush = 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(toPush);
} else if (node.isIndex) {
if (const SourceString("=") == op.source) {
// TODO(kasperl): We temporarily disable inlining because the

Powered by Google App Engine
This is Rietveld 408576698