mirror of
https://github.com/dart-lang/sdk
synced 2024-09-16 01:30:32 +00:00
[vm, kernel] Cleanup support for old invocation nodes from the VM
This change concludes switching to the new invocation nodes in the VM. Support for the old invocation nodes (MethodInvocation, PropertyGet and PropertySet) is removed from the VM and VM-specific kernel transformations. TEST=ci Closes https://github.com/dart-lang/sdk/issues/45340 Change-Id: I0717732feb1b9c6ebdf0f6079ed42a90d00970a5 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/204741 Reviewed-by: Johnni Winther <johnniwinther@google.com> Reviewed-by: Martin Kustermann <kustermann@google.com> Commit-Queue: Alexander Markov <alexmarkov@google.com>
This commit is contained in:
parent
960cc715ee
commit
a9757d177a
|
@ -215,8 +215,6 @@ class ExpressionLifter extends Transformer {
|
|||
@override
|
||||
TreeNode visitVariableSet(VariableSet expr) => unary(expr);
|
||||
@override
|
||||
TreeNode visitPropertyGet(PropertyGet expr) => unary(expr);
|
||||
@override
|
||||
TreeNode visitInstanceGet(InstanceGet expr) => unary(expr);
|
||||
@override
|
||||
TreeNode visitDynamicGet(DynamicGet expr) => unary(expr);
|
||||
|
@ -237,14 +235,6 @@ class ExpressionLifter extends Transformer {
|
|||
@override
|
||||
TreeNode visitThrow(Throw expr) => unary(expr);
|
||||
|
||||
@override
|
||||
TreeNode visitPropertySet(PropertySet expr) {
|
||||
return transformTreeNode(expr, () {
|
||||
expr.value = transform(expr.value)..parent = expr;
|
||||
expr.receiver = transform(expr.receiver)..parent = expr;
|
||||
});
|
||||
}
|
||||
|
||||
@override
|
||||
TreeNode visitInstanceSet(InstanceSet expr) {
|
||||
return transformTreeNode(expr, () {
|
||||
|
@ -274,14 +264,6 @@ class ExpressionLifter extends Transformer {
|
|||
return args;
|
||||
}
|
||||
|
||||
@override
|
||||
TreeNode visitMethodInvocation(MethodInvocation expr) {
|
||||
return transformTreeNode(expr, () {
|
||||
visitArguments(expr.arguments);
|
||||
expr.receiver = transform(expr.receiver)..parent = expr;
|
||||
});
|
||||
}
|
||||
|
||||
@override
|
||||
TreeNode visitInstanceInvocation(InstanceInvocation expr) {
|
||||
return transformTreeNode(expr, () {
|
||||
|
|
|
@ -60,13 +60,16 @@ class AnnotateWithStaticTypes extends RecursiveVisitor {
|
|||
}
|
||||
|
||||
@override
|
||||
visitPropertySet(PropertySet node) {
|
||||
super.visitPropertySet(node);
|
||||
visitPropertyGet(PropertyGet node) =>
|
||||
throw 'Unexpected node ${node.runtimeType}: $node at ${node.location}';
|
||||
|
||||
if (hasGenericCovariantParameters(node.interfaceTarget)) {
|
||||
annotateWithReceiver(node, node.receiver);
|
||||
}
|
||||
}
|
||||
@override
|
||||
visitPropertySet(PropertySet node) =>
|
||||
throw 'Unexpected node ${node.runtimeType}: $node at ${node.location}';
|
||||
|
||||
@override
|
||||
visitMethodInvocation(MethodInvocation node) =>
|
||||
throw 'Unexpected node ${node.runtimeType}: $node at ${node.location}';
|
||||
|
||||
@override
|
||||
visitInstanceSet(InstanceSet node) {
|
||||
|
@ -77,18 +80,6 @@ class AnnotateWithStaticTypes extends RecursiveVisitor {
|
|||
}
|
||||
}
|
||||
|
||||
@override
|
||||
visitMethodInvocation(MethodInvocation node) {
|
||||
super.visitMethodInvocation(node);
|
||||
|
||||
// TODO(34162): We don't need to save the type here for calls, just whether
|
||||
// or not it's a statically-checked call.
|
||||
if (node.name.text == 'call' ||
|
||||
hasGenericCovariantParameters(node.interfaceTarget)) {
|
||||
annotateWithReceiver(node, node.receiver);
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
visitInstanceInvocation(InstanceInvocation node) {
|
||||
super.visitInstanceInvocation(node);
|
||||
|
|
|
@ -119,12 +119,6 @@ abstract class Devirtualization extends RecursiveVisitor {
|
|||
}
|
||||
}
|
||||
|
||||
@override
|
||||
visitMethodInvocation(MethodInvocation node) {
|
||||
super.visitMethodInvocation(node);
|
||||
_handleMethodInvocation(node, node.interfaceTarget, node.arguments);
|
||||
}
|
||||
|
||||
@override
|
||||
visitInstanceInvocation(InstanceInvocation node) {
|
||||
super.visitInstanceInvocation(node);
|
||||
|
@ -162,12 +156,6 @@ abstract class Devirtualization extends RecursiveVisitor {
|
|||
}
|
||||
}
|
||||
|
||||
@override
|
||||
visitPropertyGet(PropertyGet node) {
|
||||
super.visitPropertyGet(node);
|
||||
_handlePropertyGet(node, node.interfaceTarget);
|
||||
}
|
||||
|
||||
@override
|
||||
visitInstanceGet(InstanceGet node) {
|
||||
super.visitInstanceGet(node);
|
||||
|
@ -188,12 +176,6 @@ abstract class Devirtualization extends RecursiveVisitor {
|
|||
}
|
||||
}
|
||||
|
||||
@override
|
||||
visitPropertySet(PropertySet node) {
|
||||
super.visitPropertySet(node);
|
||||
_handlePropertySet(node, node.interfaceTarget);
|
||||
}
|
||||
|
||||
@override
|
||||
visitInstanceSet(InstanceSet node) {
|
||||
super.visitInstanceSet(node);
|
||||
|
|
|
@ -674,44 +674,6 @@ class _FfiUseSiteTransformer extends FfiTransformer {
|
|||
..fileOffset = node.fileOffset);
|
||||
}
|
||||
|
||||
@override
|
||||
visitMethodInvocation(MethodInvocation node) {
|
||||
super.visitMethodInvocation(node);
|
||||
|
||||
final Member target = node.interfaceTarget;
|
||||
try {
|
||||
if (target == elementAtMethod) {
|
||||
final DartType pointerType =
|
||||
node.receiver.getStaticType(_staticTypeContext);
|
||||
final DartType nativeType = _pointerTypeGetTypeArg(pointerType);
|
||||
|
||||
_ensureNativeTypeValid(nativeType, node, allowCompounds: true);
|
||||
|
||||
Expression inlineSizeOf = _inlineSizeOf(nativeType);
|
||||
if (inlineSizeOf != null) {
|
||||
// Generates `receiver.offsetBy(inlineSizeOfExpression)`.
|
||||
return InstanceInvocation(
|
||||
InstanceAccessKind.Instance,
|
||||
node.receiver,
|
||||
offsetByMethod.name,
|
||||
Arguments(
|
||||
[multiply(node.arguments.positional.single, inlineSizeOf)]),
|
||||
interfaceTarget: offsetByMethod,
|
||||
functionType:
|
||||
Substitution.fromInterfaceType(pointerType as InterfaceType)
|
||||
.substituteType(offsetByMethod.getterType)
|
||||
as FunctionType);
|
||||
}
|
||||
}
|
||||
} on _FfiStaticTypeError {
|
||||
// It's OK to swallow the exception because the diagnostics issued will
|
||||
// cause compilation to fail. By continuing, we can report more
|
||||
// diagnostics before compilation ends.
|
||||
}
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
@override
|
||||
visitInstanceInvocation(InstanceInvocation node) {
|
||||
super.visitInstanceInvocation(node);
|
||||
|
|
|
@ -165,12 +165,6 @@ class ReferenceUpdater extends RecursiveVisitor {
|
|||
node.stubTarget = _resolveNewInterfaceTarget(node.stubTarget);
|
||||
}
|
||||
|
||||
@override
|
||||
visitPropertyGet(PropertyGet node) {
|
||||
node.interfaceTarget = _resolveNewInterfaceTarget(node.interfaceTarget);
|
||||
super.visitPropertyGet(node);
|
||||
}
|
||||
|
||||
@override
|
||||
visitInstanceGet(InstanceGet node) {
|
||||
node.interfaceTarget = _resolveNewInterfaceTarget(node.interfaceTarget)!;
|
||||
|
@ -184,24 +178,12 @@ class ReferenceUpdater extends RecursiveVisitor {
|
|||
super.visitInstanceTearOff(node);
|
||||
}
|
||||
|
||||
@override
|
||||
visitPropertySet(PropertySet node) {
|
||||
node.interfaceTarget = _resolveNewInterfaceTarget(node.interfaceTarget);
|
||||
super.visitPropertySet(node);
|
||||
}
|
||||
|
||||
@override
|
||||
visitInstanceSet(InstanceSet node) {
|
||||
node.interfaceTarget = _resolveNewInterfaceTarget(node.interfaceTarget)!;
|
||||
super.visitInstanceSet(node);
|
||||
}
|
||||
|
||||
@override
|
||||
visitMethodInvocation(MethodInvocation node) {
|
||||
node.interfaceTarget = _resolveNewInterfaceTarget(node.interfaceTarget);
|
||||
super.visitMethodInvocation(node);
|
||||
}
|
||||
|
||||
@override
|
||||
visitInstanceInvocation(InstanceInvocation node) {
|
||||
node.interfaceTarget =
|
||||
|
|
|
@ -175,20 +175,6 @@ class DynamicSelectorsCollector extends RecursiveVisitor {
|
|||
return v;
|
||||
}
|
||||
|
||||
@override
|
||||
visitMethodInvocation(MethodInvocation node) {
|
||||
super.visitMethodInvocation(node);
|
||||
|
||||
Selector selector;
|
||||
if (node.interfaceTarget == null) {
|
||||
dynamicSelectors.add(new Selector.doInvoke(node.name));
|
||||
} else {
|
||||
if (node.receiver is! ThisExpression) {
|
||||
nonThisSelectors.add(selector ??= new Selector.doInvoke(node.name));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
visitInstanceInvocation(InstanceInvocation node) {
|
||||
super.visitInstanceInvocation(node);
|
||||
|
@ -211,25 +197,6 @@ class DynamicSelectorsCollector extends RecursiveVisitor {
|
|||
}
|
||||
}
|
||||
|
||||
@override
|
||||
visitPropertyGet(PropertyGet node) {
|
||||
super.visitPropertyGet(node);
|
||||
|
||||
Selector selector;
|
||||
if (node.interfaceTarget == null) {
|
||||
dynamicSelectors.add(selector = new Selector.doGet(node.name));
|
||||
} else {
|
||||
if (node.receiver is! ThisExpression) {
|
||||
nonThisSelectors.add(selector ??= new Selector.doGet(node.name));
|
||||
}
|
||||
|
||||
final target = node.interfaceTarget;
|
||||
if (target is Procedure && target.kind == ProcedureKind.Method) {
|
||||
tearOffSelectors.add(new Selector.doInvoke(node.name));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
visitInstanceGet(InstanceGet node) {
|
||||
super.visitInstanceGet(node);
|
||||
|
@ -253,20 +220,6 @@ class DynamicSelectorsCollector extends RecursiveVisitor {
|
|||
tearOffSelectors.add(new Selector.doInvoke(node.name));
|
||||
}
|
||||
|
||||
@override
|
||||
visitPropertySet(PropertySet node) {
|
||||
super.visitPropertySet(node);
|
||||
|
||||
Selector selector;
|
||||
if (node.interfaceTarget == null) {
|
||||
dynamicSelectors.add(selector = new Selector.doSet(node.name));
|
||||
} else {
|
||||
if (node.receiver is! ThisExpression) {
|
||||
nonThisSelectors.add(selector ??= new Selector.doSet(node.name));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
visitInstanceSet(InstanceSet node) {
|
||||
super.visitInstanceSet(node);
|
||||
|
|
|
@ -155,17 +155,6 @@ class ProtobufHandler {
|
|||
Statistics.protobufMetadataFieldsPruned += cls.numberOfFieldsPruned;
|
||||
}
|
||||
|
||||
bool _isUnusedMetadataMethodInvocation(
|
||||
_MessageClass cls, MethodInvocation node) {
|
||||
if (node.interfaceTarget != null &&
|
||||
node.interfaceTarget.enclosingClass == _builderInfoClass &&
|
||||
fieldAddingMethods.contains(node.name.text)) {
|
||||
final tagNumber = (node.arguments.positional[0] as IntLiteral).value;
|
||||
return !cls._usedTags.contains(tagNumber);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool _isUnusedMetadata(_MessageClass cls, InstanceInvocation node) {
|
||||
if (node.interfaceTarget.enclosingClass == _builderInfoClass &&
|
||||
fieldAddingMethods.contains(node.name.text)) {
|
||||
|
@ -190,38 +179,6 @@ class _MetadataTransformer extends Transformer {
|
|||
|
||||
_MetadataTransformer(this.ph, this.cls);
|
||||
|
||||
@override
|
||||
TreeNode visitMethodInvocation(MethodInvocation node) {
|
||||
if (!ph._isUnusedMetadataMethodInvocation(cls, node)) {
|
||||
super.visitMethodInvocation(node);
|
||||
return node;
|
||||
}
|
||||
// Replace the field metadata method with a dummy call to
|
||||
// `BuilderInfo.add`. This is to preserve the index calculations when
|
||||
// removing a field.
|
||||
// Change the tag-number to 0. Otherwise the decoder will get confused.
|
||||
++numberOfFieldsPruned;
|
||||
return InstanceInvocation(
|
||||
InstanceAccessKind.Instance,
|
||||
node.receiver,
|
||||
ph._builderInfoAddMethod.name,
|
||||
Arguments(
|
||||
<Expression>[
|
||||
IntLiteral(0), // tagNumber
|
||||
NullLiteral(), // name
|
||||
NullLiteral(), // fieldType
|
||||
NullLiteral(), // defaultOrMaker
|
||||
NullLiteral(), // subBuilder
|
||||
NullLiteral(), // valueOf
|
||||
NullLiteral(), // enumValues
|
||||
],
|
||||
types: const <DartType>[NullType()],
|
||||
),
|
||||
interfaceTarget: ph._builderInfoAddMethod,
|
||||
functionType: ph._typeOfBuilderInfoAddOfNull)
|
||||
..fileOffset = node.fileOffset;
|
||||
}
|
||||
|
||||
@override
|
||||
TreeNode visitInstanceInvocation(InstanceInvocation node) {
|
||||
if (!ph._isUnusedMetadata(cls, node)) {
|
||||
|
|
|
@ -296,12 +296,6 @@ class _Collect extends RecursiveVisitor {
|
|||
info.callCount++;
|
||||
}
|
||||
|
||||
@override
|
||||
void visitMethodInvocation(MethodInvocation node) {
|
||||
collectCall(node.interfaceTarget, node.arguments);
|
||||
super.visitMethodInvocation(node);
|
||||
}
|
||||
|
||||
@override
|
||||
void visitInstanceInvocation(InstanceInvocation node) {
|
||||
collectCall(node.interfaceTarget, node.arguments);
|
||||
|
@ -639,12 +633,6 @@ class _Transform extends RecursiveVisitor {
|
|||
args.replaceWith(Arguments(positional, named: named, types: args.types));
|
||||
}
|
||||
|
||||
@override
|
||||
void visitMethodInvocation(MethodInvocation node) {
|
||||
super.visitMethodInvocation(node);
|
||||
transformCall(node.interfaceTarget, node, node.receiver, node.arguments);
|
||||
}
|
||||
|
||||
@override
|
||||
void visitInstanceInvocation(InstanceInvocation node) {
|
||||
super.visitInstanceInvocation(node);
|
||||
|
|
|
@ -1134,9 +1134,7 @@ class SummaryCollector extends RecursiveResultVisitor<TypeExpr> {
|
|||
}
|
||||
|
||||
TypeExpr _makeNarrowNotNull(TreeNode node, TypeExpr arg) {
|
||||
assert(node is NullCheck ||
|
||||
node is MethodInvocation && isComparisonWithNull(node) ||
|
||||
node is EqualsNull);
|
||||
assert(node is NullCheck || node is EqualsNull);
|
||||
if (arg is NarrowNotNull) {
|
||||
nullTests[node] = arg;
|
||||
return arg;
|
||||
|
@ -1355,44 +1353,6 @@ class SummaryCollector extends RecursiveResultVisitor<TypeExpr> {
|
|||
}
|
||||
_variableValues = null;
|
||||
return;
|
||||
} else if (node is MethodInvocation &&
|
||||
node.receiver is VariableGet &&
|
||||
node.name.text == '==') {
|
||||
assert(node.arguments.positional.length == 1 &&
|
||||
node.arguments.types.isEmpty &&
|
||||
node.arguments.named.isEmpty);
|
||||
final lhs = node.receiver as VariableGet;
|
||||
final rhs = node.arguments.positional.single;
|
||||
if (isNullLiteral(rhs)) {
|
||||
// 'x == null', where x is a variable.
|
||||
final expr = _visit(lhs);
|
||||
_makeCall(node, DirectSelector(_environment.coreTypes.objectEquals),
|
||||
Args<TypeExpr>([expr, _nullType]));
|
||||
final narrowedNotNull = _makeNarrowNotNull(node, expr);
|
||||
final int varIndex = _variablesInfo.varIndex[lhs.variable];
|
||||
if (_variableCells[varIndex] == null) {
|
||||
trueState[varIndex] = _nullType;
|
||||
falseState[varIndex] = narrowedNotNull;
|
||||
}
|
||||
_variableValues = null;
|
||||
return;
|
||||
} else if ((rhs is IntLiteral &&
|
||||
_isSubtype(lhs.variable.type,
|
||||
_environment.coreTypes.intLegacyRawType)) ||
|
||||
(rhs is StringLiteral &&
|
||||
_isSubtype(lhs.variable.type,
|
||||
_environment.coreTypes.stringLegacyRawType)) ||
|
||||
(rhs is ConstantExpression &&
|
||||
!_hasOverriddenEquals(lhs.variable.type))) {
|
||||
// 'x == c', where x is a variable and c is a constant.
|
||||
_addUse(_visit(node));
|
||||
final int varIndex = _variablesInfo.varIndex[lhs.variable];
|
||||
if (_variableCells[varIndex] == null) {
|
||||
trueState[varIndex] = _visit(rhs);
|
||||
}
|
||||
_variableValues = null;
|
||||
return;
|
||||
}
|
||||
} else if (node is EqualsCall && node.left is VariableGet) {
|
||||
final lhs = node.left as VariableGet;
|
||||
final rhs = node.right;
|
||||
|
@ -1620,55 +1580,6 @@ class SummaryCollector extends RecursiveResultVisitor<TypeExpr> {
|
|||
return _staticType(node);
|
||||
}
|
||||
|
||||
@override
|
||||
TypeExpr visitMethodInvocation(MethodInvocation node) {
|
||||
if (isComparisonWithNull(node)) {
|
||||
final arg = _visit(getArgumentOfComparisonWithNull(node));
|
||||
_makeNarrowNotNull(node, arg);
|
||||
_makeCall(node, DirectSelector(_environment.coreTypes.objectEquals),
|
||||
Args<TypeExpr>([arg, _nullType]));
|
||||
return _boolType;
|
||||
}
|
||||
final receiverNode = node.receiver;
|
||||
final receiver = _visit(receiverNode);
|
||||
final args = _visitArguments(receiver, node.arguments);
|
||||
final target = node.interfaceTarget;
|
||||
if (receiverNode is ConstantExpression && node.name.text == '[]') {
|
||||
Constant constant = receiverNode.constant;
|
||||
if (constant is ListConstant) {
|
||||
return _handleIndexingIntoListConstant(constant);
|
||||
}
|
||||
}
|
||||
TypeExpr result;
|
||||
if (target == null) {
|
||||
if (node.name.text == '==') {
|
||||
_makeCall(node, new DynamicSelector(CallKind.Method, node.name), args);
|
||||
return new Type.nullable(_boolType);
|
||||
}
|
||||
if (node.name.text == 'call') {
|
||||
final recvType = _staticDartType(node.receiver);
|
||||
if ((recvType is FunctionType) ||
|
||||
(recvType == _environment.functionLegacyRawType)) {
|
||||
// Call to a Function.
|
||||
return _staticType(node);
|
||||
}
|
||||
}
|
||||
result = _makeCall(
|
||||
node, new DynamicSelector(CallKind.Method, node.name), args);
|
||||
} else {
|
||||
assert(target is Procedure && !target.isGetter);
|
||||
// TODO(alexmarkov): overloaded arithmetic operators
|
||||
result = _makeCall(
|
||||
node,
|
||||
(node.receiver is ThisExpression)
|
||||
? new VirtualSelector(target)
|
||||
: new InterfaceSelector(target),
|
||||
args);
|
||||
}
|
||||
_updateReceiverAfterCall(receiverNode, receiver, node.name);
|
||||
return result;
|
||||
}
|
||||
|
||||
@override
|
||||
TypeExpr visitInstanceInvocation(InstanceInvocation node) {
|
||||
final receiverNode = node.receiver;
|
||||
|
@ -1780,12 +1691,6 @@ class SummaryCollector extends RecursiveResultVisitor<TypeExpr> {
|
|||
return result;
|
||||
}
|
||||
|
||||
@override
|
||||
TypeExpr visitPropertyGet(PropertyGet node) {
|
||||
return _handlePropertyGet(
|
||||
node, node.receiver, node.interfaceTarget, node.name);
|
||||
}
|
||||
|
||||
@override
|
||||
TypeExpr visitInstanceGet(InstanceGet node) {
|
||||
return _handlePropertyGet(
|
||||
|
@ -1808,29 +1713,6 @@ class SummaryCollector extends RecursiveResultVisitor<TypeExpr> {
|
|||
return _handlePropertyGet(node, node.receiver, null, node.name);
|
||||
}
|
||||
|
||||
@override
|
||||
TypeExpr visitPropertySet(PropertySet node) {
|
||||
var receiver = _visit(node.receiver);
|
||||
var value = _visit(node.value);
|
||||
var args = new Args<TypeExpr>([receiver, value]);
|
||||
final target = node.interfaceTarget;
|
||||
if (target == null) {
|
||||
_makeCall(
|
||||
node, new DynamicSelector(CallKind.PropertySet, node.name), args);
|
||||
} else {
|
||||
assert((target is Field) || ((target is Procedure) && target.isSetter));
|
||||
_makeCall(
|
||||
node,
|
||||
(node.receiver is ThisExpression)
|
||||
? new VirtualSelector(target, callKind: CallKind.PropertySet)
|
||||
: new InterfaceSelector(target, callKind: CallKind.PropertySet),
|
||||
args);
|
||||
}
|
||||
_updateReceiverAfterCall(node.receiver, receiver, node.name,
|
||||
isSetter: true);
|
||||
return value;
|
||||
}
|
||||
|
||||
@override
|
||||
TypeExpr visitInstanceSet(InstanceSet node) {
|
||||
var receiver = _visit(node.receiver);
|
||||
|
|
|
@ -306,11 +306,9 @@ class AnnotateKernel extends RecursiveVisitor {
|
|||
}
|
||||
|
||||
final bool markSkipCheck = !callSite.useCheckedEntry &&
|
||||
(node is MethodInvocation ||
|
||||
node is InstanceInvocation ||
|
||||
(node is InstanceInvocation ||
|
||||
node is DynamicInvocation ||
|
||||
node is EqualsCall ||
|
||||
node is PropertySet ||
|
||||
node is InstanceSet ||
|
||||
node is DynamicSet);
|
||||
|
||||
|
@ -355,16 +353,12 @@ class AnnotateKernel extends RecursiveVisitor {
|
|||
// Tell the table selector assigner about the callsite.
|
||||
final Selector selector = callSite.selector;
|
||||
if (selector is InterfaceSelector && !_callSiteUsesDirectCall(node)) {
|
||||
if (node is PropertyGet ||
|
||||
node is InstanceGet ||
|
||||
node is InstanceTearOff) {
|
||||
if (node is InstanceGet || node is InstanceTearOff) {
|
||||
_tableSelectorAssigner.registerGetterCall(
|
||||
selector.member, callSite.isNullableReceiver);
|
||||
} else {
|
||||
assert(node is MethodInvocation ||
|
||||
node is InstanceInvocation ||
|
||||
assert(node is InstanceInvocation ||
|
||||
node is EqualsCall ||
|
||||
node is PropertySet ||
|
||||
node is InstanceSet);
|
||||
_tableSelectorAssigner.registerMethodOrSetterCall(
|
||||
selector.member, callSite.isNullableReceiver);
|
||||
|
@ -484,12 +478,6 @@ class AnnotateKernel extends RecursiveVisitor {
|
|||
super.visitField(node);
|
||||
}
|
||||
|
||||
@override
|
||||
visitMethodInvocation(MethodInvocation node) {
|
||||
_annotateCallSite(node, node.interfaceTarget);
|
||||
super.visitMethodInvocation(node);
|
||||
}
|
||||
|
||||
@override
|
||||
visitInstanceInvocation(InstanceInvocation node) {
|
||||
_annotateCallSite(node, node.interfaceTarget);
|
||||
|
@ -520,12 +508,6 @@ class AnnotateKernel extends RecursiveVisitor {
|
|||
super.visitEqualsCall(node);
|
||||
}
|
||||
|
||||
@override
|
||||
visitPropertyGet(PropertyGet node) {
|
||||
_annotateCallSite(node, node.interfaceTarget);
|
||||
super.visitPropertyGet(node);
|
||||
}
|
||||
|
||||
@override
|
||||
visitInstanceGet(InstanceGet node) {
|
||||
_annotateCallSite(node, node.interfaceTarget);
|
||||
|
@ -550,12 +532,6 @@ class AnnotateKernel extends RecursiveVisitor {
|
|||
super.visitDynamicGet(node);
|
||||
}
|
||||
|
||||
@override
|
||||
visitPropertySet(PropertySet node) {
|
||||
_annotateCallSite(node, node.interfaceTarget);
|
||||
super.visitPropertySet(node);
|
||||
}
|
||||
|
||||
@override
|
||||
visitInstanceSet(InstanceSet node) {
|
||||
_annotateCallSite(node, node.interfaceTarget);
|
||||
|
@ -1104,30 +1080,6 @@ class _TreeShakerPass1 extends RemovingTransformer {
|
|||
return node;
|
||||
}
|
||||
|
||||
@override
|
||||
TreeNode visitMethodInvocation(
|
||||
MethodInvocation node, TreeNode removalSentinel) {
|
||||
node.transformOrRemoveChildren(this);
|
||||
if (_isUnreachable(node)) {
|
||||
return _makeUnreachableCall(
|
||||
_flattenArguments(node.arguments, receiver: node.receiver));
|
||||
}
|
||||
if (isComparisonWithNull(node)) {
|
||||
final nullTest = _getNullTest(node);
|
||||
if (nullTest.isAlwaysNull || nullTest.isAlwaysNotNull) {
|
||||
return _evaluateArguments(
|
||||
_flattenArguments(node.arguments, receiver: node.receiver),
|
||||
BoolLiteral(nullTest.isAlwaysNull));
|
||||
}
|
||||
}
|
||||
node.interfaceTarget =
|
||||
fieldMorpher.adjustInstanceCallTarget(node.interfaceTarget);
|
||||
if (node.interfaceTarget != null) {
|
||||
shaker.addUsedMember(node.interfaceTarget);
|
||||
}
|
||||
return node;
|
||||
}
|
||||
|
||||
@override
|
||||
TreeNode visitInstanceInvocation(
|
||||
InstanceInvocation node, TreeNode removalSentinel) {
|
||||
|
@ -1200,21 +1152,6 @@ class _TreeShakerPass1 extends RemovingTransformer {
|
|||
return node;
|
||||
}
|
||||
|
||||
@override
|
||||
TreeNode visitPropertyGet(PropertyGet node, TreeNode removalSentinel) {
|
||||
node.transformOrRemoveChildren(this);
|
||||
if (_isUnreachable(node)) {
|
||||
return _makeUnreachableCall([node.receiver]);
|
||||
} else {
|
||||
node.interfaceTarget =
|
||||
fieldMorpher.adjustInstanceCallTarget(node.interfaceTarget);
|
||||
if (node.interfaceTarget != null) {
|
||||
shaker.addUsedMember(node.interfaceTarget);
|
||||
}
|
||||
return node;
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
TreeNode visitInstanceGet(InstanceGet node, TreeNode removalSentinel) {
|
||||
node.transformOrRemoveChildren(this);
|
||||
|
@ -1263,21 +1200,6 @@ class _TreeShakerPass1 extends RemovingTransformer {
|
|||
}
|
||||
}
|
||||
|
||||
@override
|
||||
TreeNode visitPropertySet(PropertySet node, TreeNode removalSentinel) {
|
||||
node.transformOrRemoveChildren(this);
|
||||
if (_isUnreachable(node)) {
|
||||
return _makeUnreachableCall([node.receiver, node.value]);
|
||||
} else {
|
||||
node.interfaceTarget = fieldMorpher
|
||||
.adjustInstanceCallTarget(node.interfaceTarget, isSetter: true);
|
||||
if (node.interfaceTarget != null) {
|
||||
shaker.addUsedMember(node.interfaceTarget);
|
||||
}
|
||||
return node;
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
TreeNode visitInstanceSet(InstanceSet node, TreeNode removalSentinel) {
|
||||
node.transformOrRemoveChildren(this);
|
||||
|
|
|
@ -377,26 +377,6 @@ extension NullabilitySuffix on Nullability {
|
|||
String get suffix => nullabilitySuffix[this];
|
||||
}
|
||||
|
||||
bool isNullLiteral(Expression expr) =>
|
||||
expr is NullLiteral ||
|
||||
(expr is ConstantExpression && expr.constant is NullConstant);
|
||||
|
||||
Expression getArgumentOfComparisonWithNull(MethodInvocation node) {
|
||||
if (node.name.text == '==') {
|
||||
final lhs = node.receiver;
|
||||
final rhs = node.arguments.positional.single;
|
||||
if (isNullLiteral(lhs)) {
|
||||
return rhs;
|
||||
} else if (isNullLiteral(rhs)) {
|
||||
return lhs;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
bool isComparisonWithNull(MethodInvocation node) =>
|
||||
getArgumentOfComparisonWithNull(node) != null;
|
||||
|
||||
bool mayHaveSideEffects(Expression node) {
|
||||
// Keep this function in sync with mayHaveOrSeeSideEffects:
|
||||
// If new false cases are added here, add the corresponding visibility cases
|
||||
|
|
|
@ -1115,8 +1115,6 @@ Fragment StreamingFlowGraphBuilder::BuildExpression(TokenPosition* position) {
|
|||
return BuildVariableSet(position);
|
||||
case kSpecializedVariableSet:
|
||||
return BuildVariableSet(payload, position);
|
||||
case kPropertyGet:
|
||||
return BuildPropertyGet(position);
|
||||
case kInstanceGet:
|
||||
return BuildInstanceGet(position);
|
||||
case kDynamicGet:
|
||||
|
@ -1125,8 +1123,6 @@ Fragment StreamingFlowGraphBuilder::BuildExpression(TokenPosition* position) {
|
|||
return BuildInstanceTearOff(position);
|
||||
case kFunctionTearOff:
|
||||
return BuildFunctionTearOff(position);
|
||||
case kPropertySet:
|
||||
return BuildPropertySet(position);
|
||||
case kInstanceSet:
|
||||
return BuildInstanceSet(position);
|
||||
case kDynamicSet:
|
||||
|
@ -1139,10 +1135,10 @@ Fragment StreamingFlowGraphBuilder::BuildExpression(TokenPosition* position) {
|
|||
return BuildStaticGet(position);
|
||||
case kStaticSet:
|
||||
return BuildStaticSet(position);
|
||||
case kMethodInvocation:
|
||||
case kInstanceInvocation:
|
||||
return BuildMethodInvocation(position, /*is_dynamic=*/false);
|
||||
case kDynamicInvocation:
|
||||
return BuildMethodInvocation(position, tag);
|
||||
return BuildMethodInvocation(position, /*is_dynamic=*/true);
|
||||
case kLocalFunctionInvocation:
|
||||
return BuildLocalFunctionInvocation(position);
|
||||
case kFunctionInvocation:
|
||||
|
@ -2173,78 +2169,6 @@ Fragment StreamingFlowGraphBuilder::BuildVariableSetImpl(
|
|||
return instructions;
|
||||
}
|
||||
|
||||
Fragment StreamingFlowGraphBuilder::BuildPropertyGet(TokenPosition* p) {
|
||||
const intptr_t offset = ReaderOffset() - 1; // Include the tag.
|
||||
const TokenPosition position = ReadPosition(); // read position.
|
||||
if (p != NULL) *p = position;
|
||||
|
||||
const DirectCallMetadata direct_call =
|
||||
direct_call_metadata_helper_.GetDirectTargetForPropertyGet(offset);
|
||||
const InferredTypeMetadata result_type =
|
||||
inferred_type_metadata_helper_.GetInferredType(offset);
|
||||
|
||||
Fragment instructions = BuildExpression(); // read receiver.
|
||||
|
||||
LocalVariable* receiver = NULL;
|
||||
if (direct_call.check_receiver_for_null_) {
|
||||
// Duplicate receiver for CheckNull before it is consumed by PushArgument.
|
||||
receiver = MakeTemporary();
|
||||
instructions += LoadLocal(receiver);
|
||||
}
|
||||
|
||||
const String& getter_name = ReadNameAsGetterName(); // read name.
|
||||
|
||||
const Function* interface_target = &Function::null_function();
|
||||
const Function* tearoff_interface_target = &Function::null_function();
|
||||
const NameIndex itarget_name =
|
||||
ReadInterfaceMemberNameReference(); // read interface_target_reference.
|
||||
if (!H.IsRoot(itarget_name) && H.IsGetter(itarget_name)) {
|
||||
interface_target = &Function::ZoneHandle(
|
||||
Z,
|
||||
H.LookupMethodByMember(itarget_name, H.DartGetterName(itarget_name)));
|
||||
ASSERT(getter_name.ptr() == interface_target->name());
|
||||
} else if (!H.IsRoot(itarget_name) && H.IsMethod(itarget_name)) {
|
||||
tearoff_interface_target = &Function::ZoneHandle(
|
||||
Z,
|
||||
H.LookupMethodByMember(itarget_name, H.DartMethodName(itarget_name)));
|
||||
}
|
||||
|
||||
if (direct_call.check_receiver_for_null_) {
|
||||
instructions += CheckNull(position, receiver, getter_name);
|
||||
}
|
||||
|
||||
const String* mangled_name = &getter_name;
|
||||
const Function* direct_call_target = &direct_call.target_;
|
||||
if (H.IsRoot(itarget_name)) {
|
||||
mangled_name = &String::ZoneHandle(
|
||||
Z, Function::CreateDynamicInvocationForwarderName(getter_name));
|
||||
if (!direct_call_target->IsNull()) {
|
||||
direct_call_target = &Function::ZoneHandle(
|
||||
direct_call.target_.GetDynamicInvocationForwarder(*mangled_name));
|
||||
}
|
||||
}
|
||||
|
||||
if (!direct_call_target->IsNull()) {
|
||||
ASSERT(CompilerState::Current().is_aot());
|
||||
instructions +=
|
||||
StaticCall(position, *direct_call_target, 1, Array::null_array(),
|
||||
ICData::kNoRebind, &result_type);
|
||||
} else {
|
||||
const intptr_t kTypeArgsLen = 0;
|
||||
const intptr_t kNumArgsChecked = 1;
|
||||
instructions +=
|
||||
InstanceCall(position, *mangled_name, Token::kGET, kTypeArgsLen, 1,
|
||||
Array::null_array(), kNumArgsChecked, *interface_target,
|
||||
*tearoff_interface_target, &result_type);
|
||||
}
|
||||
|
||||
if (direct_call.check_receiver_for_null_) {
|
||||
instructions += DropTempsPreserveTop(1); // Drop receiver, preserve result.
|
||||
}
|
||||
|
||||
return instructions;
|
||||
}
|
||||
|
||||
Fragment StreamingFlowGraphBuilder::BuildInstanceGet(TokenPosition* p) {
|
||||
const intptr_t offset = ReaderOffset() - 1; // Include the tag.
|
||||
ReadByte(); // read kind.
|
||||
|
@ -2451,101 +2375,6 @@ Fragment StreamingFlowGraphBuilder::BuildFunctionTearOff(TokenPosition* p) {
|
|||
return instructions;
|
||||
}
|
||||
|
||||
Fragment StreamingFlowGraphBuilder::BuildPropertySet(TokenPosition* p) {
|
||||
const intptr_t offset = ReaderOffset() - 1; // Include the tag.
|
||||
|
||||
const DirectCallMetadata direct_call =
|
||||
direct_call_metadata_helper_.GetDirectTargetForPropertySet(offset);
|
||||
const CallSiteAttributesMetadata call_site_attributes =
|
||||
call_site_attributes_metadata_helper_.GetCallSiteAttributes(offset);
|
||||
const InferredTypeMetadata inferred_type =
|
||||
inferred_type_metadata_helper_.GetInferredType(offset);
|
||||
|
||||
// True if callee can skip argument type checks.
|
||||
bool is_unchecked_call = inferred_type.IsSkipCheck();
|
||||
if (call_site_attributes.receiver_type != nullptr &&
|
||||
call_site_attributes.receiver_type->HasTypeClass() &&
|
||||
!Class::Handle(call_site_attributes.receiver_type->type_class())
|
||||
.IsGeneric()) {
|
||||
is_unchecked_call = true;
|
||||
}
|
||||
|
||||
Fragment instructions(MakeTemp());
|
||||
LocalVariable* variable = MakeTemporary();
|
||||
|
||||
const TokenPosition position = ReadPosition(); // read position.
|
||||
if (p != nullptr) *p = position;
|
||||
|
||||
if (PeekTag() == kThisExpression) {
|
||||
is_unchecked_call = true;
|
||||
}
|
||||
instructions += BuildExpression(); // read receiver.
|
||||
|
||||
LocalVariable* receiver = nullptr;
|
||||
if (direct_call.check_receiver_for_null_) {
|
||||
// Duplicate receiver for CheckNull before it is consumed by PushArgument.
|
||||
receiver = MakeTemporary();
|
||||
instructions += LoadLocal(receiver);
|
||||
}
|
||||
|
||||
const String& setter_name = ReadNameAsSetterName(); // read name.
|
||||
|
||||
instructions += BuildExpression(); // read value.
|
||||
instructions += StoreLocal(TokenPosition::kNoSource, variable);
|
||||
|
||||
const Function* interface_target = &Function::null_function();
|
||||
const NameIndex itarget_name =
|
||||
ReadInterfaceMemberNameReference(); // read interface_target_reference.
|
||||
if (!H.IsRoot(itarget_name)) {
|
||||
interface_target = &Function::ZoneHandle(
|
||||
Z,
|
||||
H.LookupMethodByMember(itarget_name, H.DartSetterName(itarget_name)));
|
||||
ASSERT(setter_name.ptr() == interface_target->name());
|
||||
}
|
||||
|
||||
if (direct_call.check_receiver_for_null_) {
|
||||
instructions += CheckNull(position, receiver, setter_name);
|
||||
}
|
||||
|
||||
const String* mangled_name = &setter_name;
|
||||
const Function* direct_call_target = &direct_call.target_;
|
||||
if (H.IsRoot(itarget_name)) {
|
||||
mangled_name = &String::ZoneHandle(
|
||||
Z, Function::CreateDynamicInvocationForwarderName(setter_name));
|
||||
if (!direct_call_target->IsNull()) {
|
||||
direct_call_target = &Function::ZoneHandle(
|
||||
direct_call.target_.GetDynamicInvocationForwarder(*mangled_name));
|
||||
}
|
||||
}
|
||||
|
||||
if (!direct_call_target->IsNull()) {
|
||||
ASSERT(CompilerState::Current().is_aot());
|
||||
instructions +=
|
||||
StaticCall(position, *direct_call_target, 2, Array::null_array(),
|
||||
ICData::kNoRebind, /*result_type=*/nullptr,
|
||||
/*type_args_count=*/0,
|
||||
/*use_unchecked_entry=*/is_unchecked_call);
|
||||
} else {
|
||||
const intptr_t kTypeArgsLen = 0;
|
||||
const intptr_t kNumArgsChecked = 1;
|
||||
|
||||
instructions += InstanceCall(
|
||||
position, *mangled_name, Token::kSET, kTypeArgsLen, 2,
|
||||
Array::null_array(), kNumArgsChecked, *interface_target,
|
||||
Function::null_function(),
|
||||
/*result_type=*/nullptr,
|
||||
/*use_unchecked_entry=*/is_unchecked_call, &call_site_attributes);
|
||||
}
|
||||
|
||||
instructions += Drop(); // Drop result of the setter invocation.
|
||||
|
||||
if (direct_call.check_receiver_for_null_) {
|
||||
instructions += Drop(); // Drop receiver.
|
||||
}
|
||||
|
||||
return instructions;
|
||||
}
|
||||
|
||||
Fragment StreamingFlowGraphBuilder::BuildInstanceSet(TokenPosition* p) {
|
||||
const intptr_t offset = ReaderOffset() - 1; // Include the tag.
|
||||
ReadByte(); // read kind.
|
||||
|
@ -3020,19 +2849,12 @@ Fragment StreamingFlowGraphBuilder::BuildStaticSet(TokenPosition* p) {
|
|||
}
|
||||
|
||||
Fragment StreamingFlowGraphBuilder::BuildMethodInvocation(TokenPosition* p,
|
||||
Tag tag) {
|
||||
ASSERT((tag == kMethodInvocation) || (tag == kInstanceInvocation) ||
|
||||
(tag == kDynamicInvocation));
|
||||
bool is_dynamic) {
|
||||
const intptr_t offset = ReaderOffset() - 1; // Include the tag.
|
||||
|
||||
if ((tag == kInstanceInvocation) || (tag == kDynamicInvocation)) {
|
||||
ReadByte(); // read kind.
|
||||
}
|
||||
ReadByte(); // read kind.
|
||||
|
||||
// read flags.
|
||||
const uint8_t flags =
|
||||
((tag == kMethodInvocation) || (tag == kInstanceInvocation)) ? ReadFlags()
|
||||
: 0;
|
||||
const uint8_t flags = is_dynamic ? 0 : ReadFlags();
|
||||
const bool is_invariant = (flags & kMethodInvocationFlagInvariant) != 0;
|
||||
|
||||
const TokenPosition position = ReadPosition(); // read position.
|
||||
|
@ -3047,22 +2869,13 @@ Fragment StreamingFlowGraphBuilder::BuildMethodInvocation(TokenPosition* p,
|
|||
|
||||
const Tag receiver_tag = PeekTag(); // peek tag for receiver.
|
||||
|
||||
bool is_unchecked_closure_call = false;
|
||||
bool is_unchecked_call = is_invariant || result_type.IsSkipCheck();
|
||||
if (call_site_attributes.receiver_type != nullptr) {
|
||||
if ((tag == kMethodInvocation) &&
|
||||
call_site_attributes.receiver_type->IsFunctionType()) {
|
||||
AlternativeReadingScope alt(&reader_);
|
||||
SkipExpression(); // skip receiver
|
||||
is_unchecked_closure_call =
|
||||
ReadNameAsMethodName().Equals(Symbols::Call());
|
||||
} else if ((tag != kDynamicInvocation) &&
|
||||
call_site_attributes.receiver_type->HasTypeClass() &&
|
||||
!call_site_attributes.receiver_type->IsDynamicType() &&
|
||||
!Class::Handle(call_site_attributes.receiver_type->type_class())
|
||||
.IsGeneric()) {
|
||||
is_unchecked_call = true;
|
||||
}
|
||||
if (!is_dynamic && (call_site_attributes.receiver_type != nullptr) &&
|
||||
call_site_attributes.receiver_type->HasTypeClass() &&
|
||||
!call_site_attributes.receiver_type->IsDynamicType() &&
|
||||
!Class::Handle(call_site_attributes.receiver_type->type_class())
|
||||
.IsGeneric()) {
|
||||
is_unchecked_call = true;
|
||||
}
|
||||
|
||||
Fragment instructions;
|
||||
|
@ -3079,7 +2892,7 @@ Fragment StreamingFlowGraphBuilder::BuildMethodInvocation(TokenPosition* p,
|
|||
const TypeArguments& type_arguments =
|
||||
T.BuildTypeArguments(list_length); // read types.
|
||||
instructions += TranslateInstantiatedTypeArguments(type_arguments);
|
||||
if (direct_call.check_receiver_for_null_ || is_unchecked_closure_call) {
|
||||
if (direct_call.check_receiver_for_null_) {
|
||||
// Don't yet push type arguments if we need to check receiver for null.
|
||||
// In this case receiver will be duplicated so instead of pushing
|
||||
// type arguments here we need to push it between receiver_temp
|
||||
|
@ -3092,7 +2905,7 @@ Fragment StreamingFlowGraphBuilder::BuildMethodInvocation(TokenPosition* p,
|
|||
|
||||
// Take note of whether the invocation is against the receiver of the current
|
||||
// function: in this case, we may skip some type checks in the callee.
|
||||
if ((PeekTag() == kThisExpression) && (tag != kDynamicInvocation)) {
|
||||
if ((PeekTag() == kThisExpression) && !is_dynamic) {
|
||||
is_unchecked_call = true;
|
||||
}
|
||||
instructions += BuildExpression(); // read receiver.
|
||||
|
@ -3119,7 +2932,7 @@ Fragment StreamingFlowGraphBuilder::BuildMethodInvocation(TokenPosition* p,
|
|||
}
|
||||
|
||||
LocalVariable* receiver_temp = NULL;
|
||||
if (direct_call.check_receiver_for_null_ || is_unchecked_closure_call) {
|
||||
if (direct_call.check_receiver_for_null_) {
|
||||
// Duplicate receiver for CheckNull before it is consumed by PushArgument.
|
||||
receiver_temp = MakeTemporary();
|
||||
if (type_arguments_temp != NULL) {
|
||||
|
@ -3149,15 +2962,14 @@ Fragment StreamingFlowGraphBuilder::BuildMethodInvocation(TokenPosition* p,
|
|||
checked_argument_count = argument_count;
|
||||
}
|
||||
|
||||
if (tag == kInstanceInvocation) {
|
||||
if (!is_dynamic) {
|
||||
SkipDartType(); // read function_type.
|
||||
}
|
||||
|
||||
const Function* interface_target = &Function::null_function();
|
||||
// read interface_target_reference.
|
||||
const NameIndex itarget_name =
|
||||
((tag == kMethodInvocation) || (tag == kInstanceInvocation))
|
||||
? ReadInterfaceMemberNameReference()
|
||||
: NameIndex(); // read interface_target_reference.
|
||||
is_dynamic ? NameIndex() : ReadInterfaceMemberNameReference();
|
||||
// TODO(dartbug.com/34497): Once front-end desugars calls via
|
||||
// fields/getters, filtering of field and getter interface targets here
|
||||
// can be turned into assertions.
|
||||
|
@ -3169,12 +2981,9 @@ Fragment StreamingFlowGraphBuilder::BuildMethodInvocation(TokenPosition* p,
|
|||
ASSERT(!interface_target->IsGetterFunction());
|
||||
}
|
||||
|
||||
// TODO(sjindel): Avoid the check for null on unchecked closure calls if TFA
|
||||
// allows.
|
||||
if (direct_call.check_receiver_for_null_ || is_unchecked_closure_call) {
|
||||
// Receiver temp is needed to load the function to call from the closure.
|
||||
if (direct_call.check_receiver_for_null_) {
|
||||
instructions += CheckNull(position, receiver_temp, name,
|
||||
/*clear_temp=*/!is_unchecked_closure_call);
|
||||
/*clear_temp=*/true);
|
||||
}
|
||||
|
||||
const String* mangled_name = &name;
|
||||
|
@ -3193,19 +3002,7 @@ Fragment StreamingFlowGraphBuilder::BuildMethodInvocation(TokenPosition* p,
|
|||
}
|
||||
}
|
||||
|
||||
if (is_unchecked_closure_call) {
|
||||
// Lookup the function in the closure.
|
||||
instructions += LoadLocal(receiver_temp);
|
||||
if (!FLAG_precompiled_mode || !FLAG_use_bare_instructions) {
|
||||
instructions += LoadNativeField(Slot::Closure_function());
|
||||
}
|
||||
if (parsed_function()->function().is_debuggable()) {
|
||||
ASSERT(!parsed_function()->function().is_native());
|
||||
instructions += DebugStepCheck(position);
|
||||
}
|
||||
instructions +=
|
||||
B->ClosureCall(position, type_args_len, argument_count, argument_names);
|
||||
} else if (!direct_call_target->IsNull()) {
|
||||
if (!direct_call_target->IsNull()) {
|
||||
// Even if TFA infers a concrete receiver type, the static type of the
|
||||
// call-site may still be dynamic and we need to call the dynamic invocation
|
||||
// forwarder to ensure type-checks are performed.
|
||||
|
|
|
@ -274,12 +274,10 @@ class StreamingFlowGraphBuilder : public KernelReaderHelper {
|
|||
Fragment BuildVariableSet(uint8_t payload, TokenPosition* position);
|
||||
Fragment BuildVariableSetImpl(TokenPosition position,
|
||||
intptr_t variable_kernel_position);
|
||||
Fragment BuildPropertyGet(TokenPosition* position);
|
||||
Fragment BuildInstanceGet(TokenPosition* position);
|
||||
Fragment BuildDynamicGet(TokenPosition* position);
|
||||
Fragment BuildInstanceTearOff(TokenPosition* position);
|
||||
Fragment BuildFunctionTearOff(TokenPosition* position);
|
||||
Fragment BuildPropertySet(TokenPosition* position);
|
||||
Fragment BuildInstanceSet(TokenPosition* position);
|
||||
Fragment BuildDynamicSet(TokenPosition* position);
|
||||
Fragment BuildAllocateInvocationMirrorCall(TokenPosition position,
|
||||
|
@ -293,7 +291,7 @@ class StreamingFlowGraphBuilder : public KernelReaderHelper {
|
|||
Fragment BuildSuperPropertySet(TokenPosition* position);
|
||||
Fragment BuildStaticGet(TokenPosition* position);
|
||||
Fragment BuildStaticSet(TokenPosition* position);
|
||||
Fragment BuildMethodInvocation(TokenPosition* position, Tag tag);
|
||||
Fragment BuildMethodInvocation(TokenPosition* position, bool is_dynamic);
|
||||
Fragment BuildLocalFunctionInvocation(TokenPosition* position);
|
||||
Fragment BuildFunctionInvocation(TokenPosition* position);
|
||||
Fragment BuildEqualsCall(TokenPosition* position);
|
||||
|
|
|
@ -373,12 +373,6 @@ void KernelFingerprintHelper::CalculateExpressionFingerprint() {
|
|||
ReadUInt(); // read kernel position.
|
||||
CalculateExpressionFingerprint(); // read expression.
|
||||
return;
|
||||
case kPropertyGet:
|
||||
ReadPosition(); // read position.
|
||||
CalculateExpressionFingerprint(); // read receiver.
|
||||
BuildHash(ReadNameAsGetterName().Hash()); // read name.
|
||||
CalculateGetterNameFingerprint(); // read interface_target_reference.
|
||||
return;
|
||||
case kInstanceGet:
|
||||
ReadByte(); // read kind.
|
||||
ReadPosition(); // read position.
|
||||
|
@ -405,13 +399,6 @@ void KernelFingerprintHelper::CalculateExpressionFingerprint() {
|
|||
ReadPosition(); // read position.
|
||||
CalculateExpressionFingerprint(); // read receiver.
|
||||
return;
|
||||
case kPropertySet:
|
||||
ReadPosition(); // read position.
|
||||
CalculateExpressionFingerprint(); // read receiver.
|
||||
BuildHash(ReadNameAsSetterName().Hash()); // read name.
|
||||
CalculateExpressionFingerprint(); // read value.
|
||||
CalculateSetterNameFingerprint(); // read interface_target_reference.
|
||||
return;
|
||||
case kInstanceSet:
|
||||
ReadByte(); // read kind.
|
||||
ReadPosition(); // read position.
|
||||
|
@ -447,14 +434,6 @@ void KernelFingerprintHelper::CalculateExpressionFingerprint() {
|
|||
CalculateCanonicalNameFingerprint(); // read target_reference.
|
||||
CalculateExpressionFingerprint(); // read expression.
|
||||
return;
|
||||
case kMethodInvocation:
|
||||
ReadFlags(); // read flags.
|
||||
ReadPosition(); // read position.
|
||||
CalculateExpressionFingerprint(); // read receiver.
|
||||
BuildHash(ReadNameAsMethodName().Hash()); // read name.
|
||||
CalculateArgumentsFingerprint(); // read arguments.
|
||||
CalculateMethodNameFingerprint(); // read interface_target_reference.
|
||||
return;
|
||||
case kInstanceInvocation:
|
||||
ReadByte(); // read kind.
|
||||
ReadFlags(); // read flags.
|
||||
|
|
|
@ -2320,12 +2320,6 @@ void KernelReaderHelper::SkipExpression() {
|
|||
ReadUInt(); // read kernel position.
|
||||
SkipExpression(); // read expression.
|
||||
return;
|
||||
case kPropertyGet:
|
||||
ReadPosition(); // read position.
|
||||
SkipExpression(); // read receiver.
|
||||
SkipName(); // read name.
|
||||
SkipInterfaceMemberNameReference(); // read interface_target_reference.
|
||||
return;
|
||||
case kInstanceGet:
|
||||
ReadByte(); // read kind.
|
||||
ReadPosition(); // read position.
|
||||
|
@ -2352,13 +2346,6 @@ void KernelReaderHelper::SkipExpression() {
|
|||
ReadPosition(); // read position.
|
||||
SkipExpression(); // read receiver.
|
||||
return;
|
||||
case kPropertySet:
|
||||
ReadPosition(); // read position.
|
||||
SkipExpression(); // read receiver.
|
||||
SkipName(); // read name.
|
||||
SkipExpression(); // read value.
|
||||
SkipInterfaceMemberNameReference(); // read interface_target_reference.
|
||||
return;
|
||||
case kInstanceSet:
|
||||
ReadByte(); // read kind.
|
||||
ReadPosition(); // read position.
|
||||
|
@ -2394,14 +2381,6 @@ void KernelReaderHelper::SkipExpression() {
|
|||
SkipCanonicalNameReference(); // read target_reference.
|
||||
SkipExpression(); // read expression.
|
||||
return;
|
||||
case kMethodInvocation:
|
||||
ReadFlags(); // read flags.
|
||||
ReadPosition(); // read position.
|
||||
SkipExpression(); // read receiver.
|
||||
SkipName(); // read name.
|
||||
SkipArguments(); // read arguments.
|
||||
SkipInterfaceMemberNameReference(); // read interface_target_reference.
|
||||
return;
|
||||
case kInstanceInvocation:
|
||||
ReadByte(); // read kind.
|
||||
ReadFlags(); // read flags.
|
||||
|
|
|
@ -686,13 +686,6 @@ void ScopeBuilder::VisitExpression() {
|
|||
VisitExpression(); // read expression.
|
||||
return;
|
||||
}
|
||||
case kPropertyGet:
|
||||
helper_.ReadPosition(); // read position.
|
||||
VisitExpression(); // read receiver.
|
||||
helper_.SkipName(); // read name.
|
||||
// read interface_target_reference.
|
||||
helper_.SkipInterfaceMemberNameReference();
|
||||
return;
|
||||
case kInstanceGet:
|
||||
helper_.ReadByte(); // read kind.
|
||||
helper_.ReadPosition(); // read position.
|
||||
|
@ -721,14 +714,6 @@ void ScopeBuilder::VisitExpression() {
|
|||
helper_.ReadPosition(); // read position.
|
||||
VisitExpression(); // read receiver.
|
||||
return;
|
||||
case kPropertySet:
|
||||
helper_.ReadPosition(); // read position.
|
||||
VisitExpression(); // read receiver.
|
||||
helper_.SkipName(); // read name.
|
||||
VisitExpression(); // read value.
|
||||
// read interface_target_reference.
|
||||
helper_.SkipInterfaceMemberNameReference();
|
||||
return;
|
||||
case kInstanceSet:
|
||||
helper_.ReadByte(); // read kind.
|
||||
helper_.ReadPosition(); // read position.
|
||||
|
@ -767,15 +752,6 @@ void ScopeBuilder::VisitExpression() {
|
|||
helper_.SkipCanonicalNameReference(); // read target_reference.
|
||||
VisitExpression(); // read expression.
|
||||
return;
|
||||
case kMethodInvocation:
|
||||
helper_.ReadFlags(); // read flags.
|
||||
helper_.ReadPosition(); // read position.
|
||||
VisitExpression(); // read receiver.
|
||||
helper_.SkipName(); // read name.
|
||||
VisitArguments(); // read arguments.
|
||||
// read interface_target_reference.
|
||||
helper_.SkipInterfaceMemberNameReference();
|
||||
return;
|
||||
case kInstanceInvocation:
|
||||
helper_.ReadByte(); // read kind.
|
||||
helper_.ReadFlags(); // read flags.
|
||||
|
|
Loading…
Reference in a new issue