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

Unified Diff: pkg/compiler/lib/src/tree_ir/tree_ir_builder.dart

Issue 1761903002: dart2js cps: Keep interceptors in a separate field. (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Rebase Created 4 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/js_backend/codegen/unsugar.dart ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: pkg/compiler/lib/src/tree_ir/tree_ir_builder.dart
diff --git a/pkg/compiler/lib/src/tree_ir/tree_ir_builder.dart b/pkg/compiler/lib/src/tree_ir/tree_ir_builder.dart
index 324f45f2b3fde2cb330595186fed02b34b229ed7..a9d3c200940609d347f2526ded374a1d2abc698f 100644
--- a/pkg/compiler/lib/src/tree_ir/tree_ir_builder.dart
+++ b/pkg/compiler/lib/src/tree_ir/tree_ir_builder.dart
@@ -9,6 +9,7 @@ import '../constants/values.dart';
import '../cps_ir/cps_ir_nodes.dart' as cps_ir;
import '../elements/elements.dart';
import 'package:js_ast/js_ast.dart' as js;
+import '../js_backend/codegen/glue.dart';
import 'tree_ir_nodes.dart';
@@ -48,6 +49,7 @@ typedef Statement NodeCallback(Statement next);
*/
class Builder implements cps_ir.Visitor/*<NodeCallback|Node>*/ {
final InternalErrorFunction internalError;
+ final Glue glue;
final Map<cps_ir.Primitive, Variable> primitive2variable =
<cps_ir.Primitive, Variable>{};
@@ -60,17 +62,12 @@ class Builder implements cps_ir.Visitor/*<NodeCallback|Node>*/ {
final Map<cps_ir.Continuation, Label> labels = <cps_ir.Continuation, Label>{};
ExecutableElement currentElement;
- /// The 'this' Parameter for currentElement or the enclosing method.
+ /// The parameter to be translated to 'this'. This can either be the receiver
+ /// parameter, the interceptor parameter, or null if the method has neither.
cps_ir.Parameter thisParameter;
cps_ir.Continuation returnContinuation;
- Builder parent;
-
- Builder(this.internalError, [this.parent]);
-
- Builder createInnerBuilder() {
- return new Builder(internalError, this);
- }
+ Builder(this.internalError, this.glue);
/// Variable used in [buildPhiAssignments] as a temporary when swapping
/// variables.
@@ -84,9 +81,6 @@ class Builder implements cps_ir.Visitor/*<NodeCallback|Node>*/ {
}
Variable getMutableVariable(cps_ir.MutableVariable mutableVariable) {
- if (!mutable2variable.containsKey(mutableVariable)) {
- return parent.getMutableVariable(mutableVariable)..isCaptured = true;
- }
return mutable2variable[mutableVariable];
}
@@ -128,20 +122,17 @@ class Builder implements cps_ir.Visitor/*<NodeCallback|Node>*/ {
return labels.putIfAbsent(cont, () => new Label());
}
- Variable addFunctionParameter(cps_ir.Parameter parameter) {
- return getVariable(parameter);
- }
-
FunctionDefinition buildFunction(cps_ir.FunctionDefinition node) {
currentElement = node.element;
- if (parent != null) {
- // Local function's 'this' refers to enclosing method's 'this'
- thisParameter = parent.thisParameter;
+ List<Variable> parameters = node.parameters.map(getVariable).toList();
+ if (node.interceptorParameter != null) {
+ parameters.insert(0, getVariable(node.receiverParameter));
+ thisParameter = glue.methodUsesReceiverArgument(node.element)
+ ? node.interceptorParameter
+ : node.receiverParameter;
} else {
- thisParameter = node.thisParameter;
+ thisParameter = node.receiverParameter;
}
- List<Variable> parameters =
- node.parameters.map(addFunctionParameter).toList();
returnContinuation = node.returnContinuation;
phiTempVar = new Variable(node.element, null);
Statement body = translateExpression(node.body);
@@ -621,38 +612,86 @@ class Builder implements cps_ir.Visitor/*<NodeCallback|Node>*/ {
node.sourceInformation);
}
+ List<Expression> insertReceiverArgument(Expression receiver,
+ List<Expression> arguments) {
+ return new List<Expression>.generate(arguments.length + 1,
+ (n) => n == 0 ? receiver : arguments[n - 1],
+ growable: false);
+ }
+
Expression visitInvokeMethod(cps_ir.InvokeMethod node) {
- if (node.callingConvention == cps_ir.CallingConvention.OneShotIntercepted) {
- List<Expression> arguments = new List.generate(
- 1 + node.argumentRefs.length,
- (n) => getVariableUse(n == 0 ? node.receiverRef : node.argumentRefs[n - 1]),
- growable: false);
- return new OneShotInterceptor(node.selector, node.mask, arguments,
- node.sourceInformation);
+ switch (node.callingConvention) {
+ case cps_ir.CallingConvention.Normal:
+ InvokeMethod invoke = new InvokeMethod(
+ getVariableUse(node.receiverRef),
+ node.selector,
+ node.mask,
+ translateArguments(node.argumentRefs),
+ node.sourceInformation);
+ invoke.receiverIsNotNull = !node.receiver.type.isNullable;
+ return invoke;
+
+ case cps_ir.CallingConvention.Intercepted:
+ List<Expression> arguments = insertReceiverArgument(
+ getVariableUse(node.receiverRef),
+ translateArguments(node.argumentRefs));
+ InvokeMethod invoke = new InvokeMethod(
+ getVariableUse(node.interceptorRef),
+ node.selector,
+ node.mask,
+ arguments,
+ node.sourceInformation);
+ // Sometimes we know the Dart receiver is non-null because it has been
+ // refined, which implies that the JS receiver also can not be null at
+ // the use-site. Interceptors are not refined, so this information is
+ // not always available on the JS receiver.
+ // Also check the JS receiver's type, however, because sometimes we know
+ // an interceptor is non-null because it intercepts JSNull.
+ invoke.receiverIsNotNull =
+ !node.receiver.type.isNullable ||
+ !node.interceptor.type.isNullable;
+ return invoke;
+
+ case cps_ir.CallingConvention.DummyIntercepted:
+ List<Expression> arguments = insertReceiverArgument(
+ new Constant(new IntConstantValue(0)),
+ translateArguments(node.argumentRefs));
+ InvokeMethod invoke = new InvokeMethod(
+ getVariableUse(node.receiverRef),
+ node.selector,
+ node.mask,
+ arguments,
+ node.sourceInformation);
+ invoke.receiverIsNotNull = !node.receiver.type.isNullable;
+ return invoke;
+
+ case cps_ir.CallingConvention.OneShotIntercepted:
+ List<Expression> arguments = insertReceiverArgument(
+ getVariableUse(node.receiverRef),
+ translateArguments(node.argumentRefs));
+ return new OneShotInterceptor(
+ node.selector,
+ node.mask,
+ arguments,
+ node.sourceInformation);
}
- InvokeMethod invoke = new InvokeMethod(
- getVariableUse(node.receiverRef),
- node.selector,
- node.mask,
- translateArguments(node.argumentRefs),
- node.sourceInformation);
- // Sometimes we know the Dart receiver is non-null because it has been
- // refined, which implies that the JS receiver also can not be null at the
- // use-site. Interceptors are not refined, so this information is not
- // always available on the JS receiver.
- // Also check the JS receiver's type, however, because sometimes we know an
- // interceptor is non-null because it intercepts JSNull.
- invoke.receiverIsNotNull =
- !node.dartReceiver.type.isNullable ||
- !node.receiver.type.isNullable;
- return invoke;
}
Expression visitInvokeMethodDirectly(cps_ir.InvokeMethodDirectly node) {
- Expression receiver = getVariableUse(node.receiverRef);
- List<Expression> arguments = translateArguments(node.argumentRefs);
- return new InvokeMethodDirectly(receiver, node.target,
- node.selector, arguments, node.sourceInformation);
+ if (node.interceptorRef != null) {
+ return new InvokeMethodDirectly(getVariableUse(node.interceptorRef),
+ node.target,
+ node.selector,
+ insertReceiverArgument(getVariableUse(node.receiverRef),
+ translateArguments(node.argumentRefs)),
+ node.sourceInformation);
+ } else {
+ return new InvokeMethodDirectly(getVariableUse(node.receiverRef),
+ node.target,
+ node.selector,
+ translateArguments(node.argumentRefs),
+ node.sourceInformation);
+ }
}
Expression visitTypeCast(cps_ir.TypeCast node) {
« no previous file with comments | « pkg/compiler/lib/src/js_backend/codegen/unsugar.dart ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698