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

Unified Diff: pkg/compiler/lib/src/ssa/builder_kernel.dart

Issue 2672063003: Implement SuperPropertySet and SuperNoSuchMethod. (Closed)
Patch Set: merged with master Created 3 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 | « pkg/compiler/lib/src/kernel/element_adapter.dart ('k') | pkg/compiler/lib/src/ssa/kernel_ast_adapter.dart » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: pkg/compiler/lib/src/ssa/builder_kernel.dart
diff --git a/pkg/compiler/lib/src/ssa/builder_kernel.dart b/pkg/compiler/lib/src/ssa/builder_kernel.dart
index 551be940de95cc5fc71ebac2af93ba7facf3ba05..62e293efba6ff07d671e74dd9e2e80e035398a7a 100644
--- a/pkg/compiler/lib/src/ssa/builder_kernel.dart
+++ b/pkg/compiler/lib/src/ssa/builder_kernel.dart
@@ -31,7 +31,7 @@ import '../types/masks.dart';
import '../universe/call_structure.dart' show CallStructure;
import '../universe/selector.dart';
import '../universe/side_effects.dart' show SideEffects;
-import '../universe/use.dart' show StaticUse;
+import '../universe/use.dart' show DynamicUse, StaticUse;
import '../world.dart';
import 'graph_builder.dart';
import 'jump_handler.dart';
@@ -1899,6 +1899,25 @@ class KernelSsaBuilder extends ir.Visitor with GraphBuilder {
}
@override
+ void visitSuperPropertySet(ir.SuperPropertySet propertySet) {
+ propertySet.value.accept(this);
+ HInstruction value = pop();
+
+ if (propertySet.interfaceTarget == null) {
+ _generateSuperNoSuchMethod(
+ propertySet,
+ astAdapter.getSelector(propertySet).name + "=",
+ <HInstruction>[value]);
+ } else {
+ _buildInvokeSuper(
+ astAdapter.getSelector(propertySet),
+ _containingClass(propertySet),
+ propertySet.interfaceTarget,
+ <HInstruction>[value]);
+ }
+ }
+
+ @override
void visitVariableSet(ir.VariableSet variableSet) {
variableSet.value.accept(this);
HInstruction value = pop();
@@ -2625,29 +2644,104 @@ class KernelSsaBuilder extends ir.Visitor with GraphBuilder {
return null;
}
- HInstruction _buildInvokeSuper(
- ir.Expression invocation, List<HInstruction> arguments) {
- // Invocation is either a method invocation or a property get/set.
- // TODO(efortuna): Common interface?
- // TODO(efortuna): Add source information.
+ /// Find the applicable NoSuchMethod method for an object of this particular
+ /// class.
+ ir.Procedure _findNoSuchMethodInClass(ir.Class cls) {
sra1 2017/02/03 21:07:41 Can closedWorld.locateSingleElement be used to do
Emily Fortuna 2017/02/03 21:53:06 Per offline discussion we decided to keep this sin
+ ir.Procedure noSuchMethod = null;
+ while (cls != null && cls != astAdapter.objectClass) {
+ for (ir.Procedure procedure in cls.procedures) {
+ // TODO(efortuna): Do we need to check mixin classes as well?
+ if (procedure.name.name == Identifiers.noSuchMethod_ &&
+ Selectors.noSuchMethod_
+ .signatureApplies(astAdapter.getElement(procedure))) {
+ noSuchMethod = procedure;
+ }
+ }
+ cls = cls.superclass;
+ }
+
+ if (noSuchMethod == null) {
+ // There is no matching overloaded NoSuchMethod function in the containing
+ // class. Look on the Object class itself.
+ for (ir.Procedure procedure in astAdapter.objectClass.procedures) {
+ if (procedure.name.name == Identifiers.noSuchMethod_) {
+ noSuchMethod = procedure;
+ }
+ }
+ }
+ assert(noSuchMethod != null);
+ return noSuchMethod;
+ }
+
+ void _generateSuperNoSuchMethod(ir.Expression invocation, String publicName,
+ List<HInstruction> arguments) {
Selector selector = astAdapter.getSelector(invocation);
+ ir.Class cls = _containingClass(invocation).superclass;
+ assert(cls != null);
+ ir.Procedure noSuchMethod = _findNoSuchMethodInClass(cls);
+ if (backend.hasInvokeOnSupport &&
+ _containingClass(noSuchMethod) != astAdapter.objectClass) {
+ // Register the call as dynamic if [noSuchMethod] on the super
+ // class is _not_ the default implementation from [Object] (it might be
+ // overridden in the super class, but it might have a different number of
+ // arguments), in case the [noSuchMethod] implementation calls
+ // [JSInvocationMirror._invokeOn].
+ // TODO(johnniwinther): Register this more precisely.
+ registry?.registerDynamicUse(new DynamicUse(selector, null));
+ }
+
+ ConstantValue nameConstant =
+ backend.constantSystem.createString(new DartString.literal(publicName));
sra1 2017/02/03 21:07:41 Check that we generate the same code under --minif
Emily Fortuna 2017/02/03 21:53:06 looks good!
+
+ js.Name internalName = backend.namer.invocationName(selector);
+
+ var argumentsInstruction =
+ new HLiteralList(arguments, commonMasks.extendableArrayType);
+ add(argumentsInstruction);
+
+ var argumentNames = new List<HInstruction>();
+ for (String argumentName in selector.namedArguments) {
+ ConstantValue argumentNameConstant = backend.constantSystem
+ .createString(new DartString.literal(argumentName));
+ argumentNames.add(graph.addConstant(argumentNameConstant, closedWorld));
+ }
+ var argumentNamesInstruction =
+ new HLiteralList(argumentNames, commonMasks.extendableArrayType);
+ add(argumentNamesInstruction);
+
+ ConstantValue kindConstant =
+ backend.constantSystem.createInt(selector.invocationMirrorKind);
+
+ _pushStaticInvocation(
+ astAdapter.createInvocationMirror,
+ [
+ graph.addConstant(nameConstant, closedWorld),
+ graph.addConstantStringFromName(internalName, closedWorld),
+ graph.addConstant(kindConstant, closedWorld),
+ argumentsInstruction,
+ argumentNamesInstruction
+ ],
+ commonMasks.dynamicType);
+
+ _buildInvokeSuper(Selectors.noSuchMethod_, _containingClass(invocation),
+ noSuchMethod, <HInstruction>[pop()]);
+ }
+
+ HInstruction _buildInvokeSuper(Selector selector, ir.Class containingClass,
+ ir.Member interfaceTarget, List<HInstruction> arguments) {
+ // TODO(efortuna): Add source information.
HInstruction receiver = localsHandler.readThis();
- ir.Class surroundingClass = _containingClass(invocation);
List<HInstruction> inputs = <HInstruction>[];
- if (astAdapter.isIntercepted(invocation)) {
+ if (astAdapter.isInterceptedSelector(selector)) {
inputs.add(_interceptorFor(receiver));
}
inputs.add(receiver);
inputs.addAll(arguments);
- ir.Member interfaceTarget = invocation is ir.SuperMethodInvocation
- ? (invocation as ir.SuperMethodInvocation).interfaceTarget
- : (invocation as ir.SuperPropertyGet).interfaceTarget;
-
HInstruction instruction = new HInvokeSuper(
astAdapter.getMember(interfaceTarget),
- astAdapter.getClass(surroundingClass),
+ astAdapter.getClass(containingClass),
selector,
inputs,
astAdapter.returnTypeOf(interfaceTarget),
@@ -2661,14 +2755,23 @@ class KernelSsaBuilder extends ir.Visitor with GraphBuilder {
@override
void visitSuperPropertyGet(ir.SuperPropertyGet propertyGet) {
- _buildInvokeSuper(propertyGet, const <HInstruction>[]);
+ if (propertyGet.interfaceTarget == null) {
+ _generateSuperNoSuchMethod(propertyGet,
+ astAdapter.getSelector(propertyGet).name, const <HInstruction>[]);
+ } else {
+ _buildInvokeSuper(
+ astAdapter.getSelector(propertyGet),
+ _containingClass(propertyGet),
+ propertyGet.interfaceTarget, const <HInstruction>[]);
+ }
}
@override
void visitSuperMethodInvocation(ir.SuperMethodInvocation invocation) {
List<HInstruction> arguments = _visitArgumentsForStaticTarget(
invocation.interfaceTarget.function, invocation.arguments);
- _buildInvokeSuper(invocation, arguments);
+ _buildInvokeSuper(astAdapter.getSelector(invocation),
+ _containingClass(invocation), invocation.interfaceTarget, arguments);
}
@override
« no previous file with comments | « pkg/compiler/lib/src/kernel/element_adapter.dart ('k') | pkg/compiler/lib/src/ssa/kernel_ast_adapter.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698