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

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

Issue 12330135: Make instance methods whose names collide with intercepted methods have the interceptor calling con… (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 19306)
+++ sdk/lib/_internal/compiler/implementation/ssa/builder.dart (working copy)
@@ -11,10 +11,8 @@
*/
class InterceptedElement extends ElementX {
final HType ssaType;
- InterceptedElement(this.ssaType, Element enclosing)
- : super(const SourceString('receiver'),
- ElementKind.PARAMETER,
- enclosing);
+ InterceptedElement(this.ssaType, SourceString name, Element enclosing)
+ : super(name, ElementKind.PARAMETER, enclosing);
DartType computeType(Compiler compiler) => ssaType.computeType(compiler);
}
@@ -325,10 +323,12 @@
}
// If this method is an intercepted method, add the extra
- // parameter to it, that is the actual receiver.
+ // parameter to it, that is the actual receiver for intercepted
+ // classes, or the same as [:this:] for non-intercepted classes.
ClassElement cls = element.getEnclosingClass();
- if (builder.backend.isInterceptorClass(cls)) {
+ if (builder.backend.isInterceptedMethod(element)) {
HType type = HType.UNKNOWN;
+ SourceString name = const SourceString('receiver');
if (cls == builder.backend.jsArrayClass) {
type = HType.READABLE_ARRAY;
} else if (cls == builder.backend.jsStringClass) {
@@ -343,12 +343,21 @@
type = HType.NULL;
} else if (cls == builder.backend.jsBoolClass) {
type = HType.BOOLEAN;
+ } else if (cls == builder.backend.jsFunctionClass) {
+ type = HType.UNKNOWN;
+ } else if (cls != compiler.objectClass) {
+ JavaScriptBackend backend = compiler.backend;
+ assert(!backend.isInterceptorClass(cls));
+ name = const SourceString('_');
}
- Element parameter = new InterceptedElement(type, element);
+ Element parameter = new InterceptedElement(type, name, element);
HParameterValue value = new HParameterValue(parameter);
builder.graph.entry.addAfter(
directLocals[closureData.thisElement], value);
- directLocals[closureData.thisElement] = value;
+ if (builder.backend.isInterceptorClass(cls.declaration)) {
+ // Only use the extra parameter in intercepted classes.
+ directLocals[closureData.thisElement] = value;
+ }
value.instructionType = type;
}
}
@@ -895,6 +904,18 @@
// check at the beginning of the method. This is to avoid having
// call sites do the null check.
if (name == const SourceString('==')) {
+ if (functionElement.getEnclosingClass() == compiler.objectClass) {
+ // We special case [Object.operator==] because we know the
+ // receiver is not null and therefore can just do an identity
+ // check on [:this:]. The interceptor classes have their own
+ // synthesized [:operator==:] method.
+ HInstruction parameter = parameters.values.first;
+ HIdentity identity = new HIdentity(graph.thisInstruction, parameter);
+ add(identity);
+ HReturn ret = new HReturn(identity);
+ close(ret).addSuccessor(graph.exit);
+ return closeFunction();
+ }
handleIf(
function,
() {
@@ -2293,20 +2314,17 @@
}
/**
- * Returns a set of interceptor classes that contain a member whose
- * signature matches the given [selector].
+ * Returns a set of interceptor classes that contain the given
+ * [selector].
*/
- Set<ClassElement> getInterceptedClassesOn(Selector selector) {
- return backend.getInterceptedClassesOn(selector);
- }
-
void generateInstanceGetterWithCompiledReceiver(Send send,
Selector selector,
HInstruction receiver) {
assert(Elements.isInstanceSend(send, elements));
assert(selector.isGetter());
SourceString getterName = selector.name;
- Set<ClassElement> interceptedClasses = getInterceptedClassesOn(selector);
+ Set<ClassElement> interceptedClasses =
+ backend.getInterceptedClassesOn(getterName);
bool hasGetter = compiler.world.hasAnyUserDefinedGetter(selector);
HInstruction instruction;
@@ -2382,7 +2400,8 @@
assert(selector.isSetter());
SourceString setterName = selector.name;
bool hasSetter = compiler.world.hasAnyUserDefinedSetter(selector);
- Set<ClassElement> interceptedClasses = getInterceptedClassesOn(selector);
+ Set<ClassElement> interceptedClasses =
+ backend.getInterceptedClassesOn(setterName);
if (interceptedClasses != null) {
// If we're using an interceptor class, emit a call to the
// getInterceptor method and then the actual dynamic call on the
@@ -3044,10 +3063,11 @@
argumentNamesInstruction,
HType.UNKNOWN);
- var inputs = <HInstruction>[
- target,
- self,
- pop()];
+ var inputs = <HInstruction>[target, self];
+ if (backend.isInterceptedMethod(element)) {
+ inputs.add(self);
+ }
+ inputs.add(pop());
push(new HInvokeSuper(inputs));
}
@@ -3071,6 +3091,9 @@
HInstruction context = localsHandler.readThis();
add(target);
var inputs = <HInstruction>[target, context];
+ if (backend.isInterceptedMethod(element)) {
+ inputs.add(context);
+ }
if (node.isPropertyAccess) {
push(new HInvokeSuper(inputs));
} else if (element.isFunction() || element.isGenerativeConstructor()) {
@@ -3510,7 +3533,8 @@
Selector selector,
HInstruction receiver,
List<HInstruction> arguments) {
- Set<ClassElement> interceptedClasses = getInterceptedClassesOn(selector);
+ Set<ClassElement> interceptedClasses =
+ backend.getInterceptedClassesOn(selector.name);
List<HInstruction> inputs = <HInstruction>[];
bool isIntercepted = interceptedClasses != null;
if (isIntercepted) {
@@ -3868,7 +3892,8 @@
HInstruction iterator;
void buildInitializer() {
Selector selector = elements.getIteratorSelector(node);
- Set<ClassElement> interceptedClasses = getInterceptedClassesOn(selector);
+ Set<ClassElement> interceptedClasses =
+ backend.getInterceptedClassesOn(selector.name);
visit(node.expression);
HInstruction receiver = pop();
bool hasGetter = compiler.world.hasAnyUserDefinedGetter(selector);
« no previous file with comments | « sdk/lib/_internal/compiler/implementation/lib/js_helper.dart ('k') | sdk/lib/_internal/compiler/implementation/ssa/nodes.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698