Revert "[vm/aot/tfa] Analyze function calls"
This reverts commit 66d3eedb33d80273385bcba9aeaf988c07f3ef3f.
Reason for revert: breaks google3 (b/320642692)
Original change's description:
> [vm/aot/tfa] Analyze function calls
>
> This change adds analysis of function calls when closure target
> of a call can be inferred. Local functions are now analyzed separately
> from enclosing members. Inferred result type of function calls is now
> used in the AOT compiler.
>
> Time of AOT compilation step 2 (TFA) on a large Flutter application:
> Before: 59.448s
> After: 61.870s (+4%)
>
> Maintaining hierarchy of function types and analysis of all function
> calls is not feasible as it causes unbearable increase in AOT
> compilation time.
>
> TEST=existing
> Issue: https://github.com/dart-lang/sdk/issues/39692
>
> Change-Id: Ieb4d5dce23868b5ab5c87fa1e77e49b85fd656fe
> Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/345083
> Reviewed-by: Slava Egorov <vegorov@google.com>
> Reviewed-by: Martin Kustermann <kustermann@google.com>
> Commit-Queue: Alexander Markov <alexmarkov@google.com>
Issue: https://github.com/dart-lang/sdk/issues/39692
Change-Id: Ieb9104f4263e19ef9e5bd749e935f6c2dbec3046
No-Presubmit: true
No-Tree-Checks: true
No-Try: true
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/346780
Reviewed-by: Martin Kustermann <kustermann@google.com>
Reviewed-by: Slava Egorov <vegorov@google.com>
Bot-Commit: Rubber Stamper <rubber-stamper@appspot.gserviceaccount.com>
Commit-Queue: Emmanuel Pellereau <emmanuelp@google.com>
diff --git a/pkg/vm/lib/transformations/type_flow/analysis.dart b/pkg/vm/lib/transformations/type_flow/analysis.dart
index 5f10826..e6ad923 100644
--- a/pkg/vm/lib/transformations/type_flow/analysis.dart
+++ b/pkg/vm/lib/transformations/type_flow/analysis.dart
@@ -36,6 +36,7 @@
// === Precision ===
// * Handle '==' with null.
// * Special type inference rules for binary int operators.
+// * Support function types, better handle closures.
// * Support generic types: substitution, passing type arguments. Figure out
// when generic type should be approximated.
//
@@ -185,75 +186,11 @@
return type;
}
-
- // Process [receiver].call(args) for calls via field or getter.
- Type _processCallWithSubstitutedReceiver(
- Type receiver, TypeFlowAnalysis typeFlowAnalysis) {
- if (receiver == emptyType) {
- return emptyType;
- }
- final closure = receiver.closure;
- if (closure != null) {
- final target = typeFlowAnalysis.getClosureCallMethod(closure);
- if (!areArgumentsValidFor(target)) {
- return emptyType;
- }
- return typeFlowAnalysis.applyCall(/* callSite = */ null,
- DirectSelector(target), Args.withReceiver(args, receiver));
- } else {
- typeFlowAnalysis.applyCall(/* callSite = */ null, DynamicSelector.kCall,
- Args.withReceiver(args, receiver),
- isResultUsed: false, processImmediately: false);
- return nullableAnyType;
- }
- }
-
- // Returns true if the argument count and the names
- // of optional arguments are valid for calling [member].
- bool areArgumentsValidFor(Member member) {
- if (member is Field ||
- (member is Procedure && (member.isGetter || member.isSetter)) ||
- selector.callKind == CallKind.PropertyGet) {
- return true;
- }
- final function = member.function!;
- final int positionalArguments = args.positionalCount;
-
- final int firstParamIndex =
- numTypeParams(member) + (hasReceiverArg(member) ? 1 : 0);
- final int requiredParameters =
- firstParamIndex + function.requiredParameterCount;
- if (positionalArguments < requiredParameters) {
- return false;
- }
-
- final int positionalParameters =
- firstParamIndex + function.positionalParameters.length;
- if (positionalArguments > positionalParameters) {
- return false;
- }
-
- if (args.names.isNotEmpty) {
- // TODO(dartbug.com/32292): make sure parameters are sorted in kernel AST
- // and iterate parameters in parallel, without lookup.
- for (var name in args.names) {
- if (findNamedParameter(function, name) == null) {
- return false;
- }
- }
- }
-
- return true;
- }
}
final class _DirectInvocation extends _Invocation {
_DirectInvocation(DirectSelector selector, Args<Type> args)
- : super(selector, args) {
- if (!areArgumentsValidFor(selector.member)) {
- throw 'Creating _DirectInvocation($selector, $args) with invalid args';
- }
- }
+ : super(selector, args);
@override
void init() {
@@ -318,10 +255,17 @@
case CallKind.Method:
// Call via field.
+ // TODO(alexmarkov): support function types and use inferred type
+ // to get more precise return type.
fieldValue.isGetterUsed = true;
final receiver = fieldValue.getValue(
typeFlowAnalysis, field.isStatic ? null : args.values[0]);
- return _processCallWithSubstitutedReceiver(receiver, typeFlowAnalysis);
+ if (receiver != emptyType) {
+ typeFlowAnalysis.applyCall(/* callSite = */ null,
+ DynamicSelector.kCall, new Args.withReceiver(args, receiver),
+ isResultUsed: false, processImmediately: false);
+ }
+ return nullableAnyType;
case CallKind.FieldInitializer:
assert(args.values.length == firstParamIndex);
@@ -349,68 +293,28 @@
}
Type _processFunction(TypeFlowAnalysis typeFlowAnalysis) {
- Member member = selector.member!;
- assert(areArgumentsValidFor(member));
- Args<Type> args = this.args;
+ final Member member = selector.member!;
if (selector.memberAgreesToCallKind(member)) {
- final closure = typeFlowAnalysis._closureByCallMethod[member];
- if (closure != null && closure.function == null) {
- // Calling tear-off.
- //
- // Only factories can take type parameters as arguments in TFA.
- // Invocation of a tear-off (its call method) doesn't take
- // type parameters, but target member may need to receive
- // type parameters if it happens to be a factory of generic class.
- assert(numTypeParams(member) == 0);
- // Get the actual target of the call.
- member = closure.member;
- if (member is Constructor) {
- final receiver =
- typeFlowAnalysis.addAllocatedClass(member.enclosingClass);
- // Generative constructors do not take type parameters as arguments.
- assert(numTypeParams(member) == 0);
- args = Args.withReceiver(args, receiver);
- } else if (member.isInstanceMember) {
- final receiver = typeFlowAnalysis
- .getSharedCapturedThis(member)
- .getValue(typeFlowAnalysis.hierarchyCache, typeFlowAnalysis);
- if (receiver == emptyType) {
- return emptyType;
- }
- // Instance members do not take type parameters as arguments.
- assert(numTypeParams(member) == 0);
- args = Args.withReceiver(args, receiver);
- } else {
- // Drop closure receiver.
- List<Type> argValues = args.values.sublist(1);
- // Prepend type parameters if target member needs them.
- final numTypeParameters = numTypeParams(member);
- if (numTypeParameters != 0) {
- argValues = [
- for (int i = 0; i < numTypeParameters; ++i) unknownType,
- ...argValues
- ];
- }
- args = Args(argValues, names: args.names);
+ if (_argumentsValid()) {
+ final summary = typeFlowAnalysis.getSummary(member);
+ // If result type is known upfront (doesn't depend on the flow),
+ // set it eagerly so recursive invocations are able to use it.
+ final summaryResult = summary.result;
+ if (summaryResult is Type &&
+ !typeFlowAnalysis.workList._isPending(this)) {
+ assert(result == null || result == summaryResult);
+ setResult(typeFlowAnalysis, summaryResult);
}
- final result = typeFlowAnalysis.applyCall(/* callSite = */ null,
- DirectSelector(member, callKind: CallKind.Method), args);
- return (member is Constructor) ? args.receiver : result;
+ return summary.apply(
+ args, typeFlowAnalysis.hierarchyCache, typeFlowAnalysis);
+ } else {
+ assert(selector.callKind == CallKind.Method);
+ return _processNoSuchMethod(args.receiver, typeFlowAnalysis);
}
- final summary = typeFlowAnalysis.getSummary(member);
- // If result type is known upfront (doesn't depend on the flow),
- // set it eagerly so recursive invocations are able to use it.
- final summaryResult = summary.result;
- if (summaryResult is Type &&
- !typeFlowAnalysis.workList._isPending(this)) {
- assert(result == null || result == summaryResult);
- setResult(typeFlowAnalysis, summaryResult);
- }
- return summary.apply(
- args, typeFlowAnalysis.hierarchyCache, typeFlowAnalysis);
} else {
if (selector.callKind == CallKind.PropertyGet) {
- // Taking tear-off.
+ // Tear-off.
+ // TODO(alexmarkov): capture receiver type
assert((member is Procedure) &&
!member.isGetter &&
!member.isSetter &&
@@ -418,10 +322,6 @@
!member.isAbstract);
typeFlowAnalysis.addRawCall(new DirectSelector(member));
typeFlowAnalysis._tearOffTaken.add(member);
- if (member.isInstanceMember) {
- typeFlowAnalysis.getSharedCapturedThis(member).setValue(
- args.receiver, typeFlowAnalysis.hierarchyCache, typeFlowAnalysis);
- }
final Class? concreteClass = typeFlowAnalysis.target
.concreteClosureClass(typeFlowAnalysis.coreTypes);
if (concreteClass != null) {
@@ -441,17 +341,51 @@
return nullableAnyType;
} else {
// Call via getter.
+ // TODO(alexmarkov): capture receiver type
assert((selector.callKind == CallKind.Method) &&
(member is Procedure) &&
member.isGetter);
- final receiver = typeFlowAnalysis.applyCall(
- /* callSite = */ null,
- DirectSelector(member, callKind: CallKind.PropertyGet),
- Args([args.receiver]));
- return _processCallWithSubstitutedReceiver(receiver, typeFlowAnalysis);
+ typeFlowAnalysis.addRawCall(
+ new DirectSelector(member, callKind: CallKind.PropertyGet));
+ typeFlowAnalysis.applyCall(/* callSite = */ null, DynamicSelector.kCall,
+ new Args.withReceiver(args, nullableAnyType),
+ isResultUsed: false, processImmediately: false);
+ return nullableAnyType;
}
}
}
+
+ bool _argumentsValid() {
+ final member = selector.member!;
+ final function = member.function!;
+ final int positionalArguments = args.positionalCount;
+
+ final int firstParamIndex =
+ numTypeParams(member) + (hasReceiverArg(member) ? 1 : 0);
+ final int requiredParameters =
+ firstParamIndex + function.requiredParameterCount;
+ if (positionalArguments < requiredParameters) {
+ return false;
+ }
+
+ final int positionalParameters =
+ firstParamIndex + function.positionalParameters.length;
+ if (positionalArguments > positionalParameters) {
+ return false;
+ }
+
+ if (args.names.isNotEmpty) {
+ // TODO(dartbug.com/32292): make sure parameters are sorted in kernel AST
+ // and iterate parameters in parallel, without lookup.
+ for (var name in args.names) {
+ if (findNamedParameter(function, name) == null) {
+ return false;
+ }
+ }
+ }
+
+ return true;
+ }
}
final class _DispatchableInvocation extends _Invocation {
@@ -486,16 +420,7 @@
// Collect all possible targets for this invocation,
// along with more accurate receiver types for each target.
final targets = <Member, _ReceiverTypeBuilder>{};
- final selector = this.selector;
- if (selector is FunctionSelector) {
- if (!_collectTargetsForFunctionCall(
- args.receiver, targets, typeFlowAnalysis)) {
- // No known closure target, approximate function call with static type.
- return selector.staticResultType;
- }
- } else {
- _collectTargetsForReceiverType(args.receiver, targets, typeFlowAnalysis);
- }
+ _collectTargetsForReceiverType(args.receiver, targets, typeFlowAnalysis);
// Calculate result as a union of results of direct invocations
// corresponding to each target.
@@ -574,6 +499,7 @@
});
}
+ // TODO(alexmarkov): handle closures more precisely
if ((selector is DynamicSelector) && (selector.name.text == "call")) {
tracePrint("Possible closure call, result is dynamic");
result = nullableAnyType;
@@ -594,10 +520,9 @@
assert(receiver is! NullableType);
}
- final selector = this.selector;
if (selector is InterfaceSelector) {
final staticReceiverType = typeFlowAnalysis.hierarchyCache
- .getTFClass(selector.member.enclosingClass!)
+ .getTFClass(selector.member!.enclosingClass!)
.coneType;
receiver = receiver.intersection(
staticReceiverType, typeFlowAnalysis.hierarchyCache);
@@ -639,7 +564,7 @@
TypeFlowAnalysis typeFlowAnalysis) {
final Member? target = typeFlowAnalysis.hierarchyCache._nullTFClass
.getDispatchTarget(selector);
- if (target != null && areArgumentsValidFor(target)) {
+ if (target != null) {
if (kPrintTrace) {
tracePrint("Found $target for null receiver");
}
@@ -656,34 +581,28 @@
Member? target = cls.getDispatchTarget(selector);
if (target != null) {
- if (areArgumentsValidFor(target)) {
- if (kPrintTrace) {
- tracePrint("Found $target for concrete receiver $receiver");
- }
- _getReceiverTypeBuilder(targets, target).addConcreteType(receiver);
- return;
- } else {
- assert(selector is DynamicSelector);
- _recordMismatchedDynamicInvocation(target, typeFlowAnalysis);
- // Fall through to add NSM marker.
- }
- }
- if (typeFlowAnalysis.hierarchyCache.hasNonTrivialNoSuchMethod(cls)) {
if (kPrintTrace) {
- tracePrint("Found non-trivial noSuchMethod for receiver $receiver");
+ tracePrint("Found $target for concrete receiver $receiver");
}
- _getReceiverTypeBuilder(targets, kNoSuchMethodMarker)
- .addConcreteType(receiver);
- } else if (selector is DynamicSelector) {
- if (kPrintTrace) {
- tracePrint(
- "Dynamic selector - adding noSuchMethod for receiver $receiver");
- }
- _getReceiverTypeBuilder(targets, kNoSuchMethodMarker)
- .addConcreteType(receiver);
+ _getReceiverTypeBuilder(targets, target).addConcreteType(receiver);
} else {
- if (kPrintTrace) {
- tracePrint("Target is not found for receiver $receiver");
+ if (typeFlowAnalysis.hierarchyCache.hasNonTrivialNoSuchMethod(cls)) {
+ if (kPrintTrace) {
+ tracePrint("Found non-trivial noSuchMethod for receiver $receiver");
+ }
+ _getReceiverTypeBuilder(targets, kNoSuchMethodMarker)
+ .addConcreteType(receiver);
+ } else if (selector is DynamicSelector) {
+ if (kPrintTrace) {
+ tracePrint(
+ "Dynamic selector - adding noSuchMethod for receiver $receiver");
+ }
+ _getReceiverTypeBuilder(targets, kNoSuchMethodMarker)
+ .addConcreteType(receiver);
+ } else {
+ if (kPrintTrace) {
+ tracePrint("Target is not found for receiver $receiver");
+ }
}
}
}
@@ -691,23 +610,23 @@
void _collectTargetsForSelector(Map<Member, _ReceiverTypeBuilder> targets,
TypeFlowAnalysis typeFlowAnalysis) {
Selector selector = this.selector;
- if (selector is! DynamicSelector) {
- selector = DynamicSelector(selector.callKind, selector.name);
+ if (selector is InterfaceSelector) {
+ // TODO(alexmarkov): support generic types and make sure inferred types
+ // are always same or better than static types.
+// assert(selector.member.enclosingClass ==
+// _typeFlowAnalysis.coreTypes.objectClass);
+ selector = new DynamicSelector(selector.callKind, selector.name);
}
final receiver = args.receiver;
- final _DynamicTargetSet dynamicTargetSet =
- typeFlowAnalysis.hierarchyCache.getDynamicTargetSet(selector);
+ final _DynamicTargetSet dynamicTargetSet = typeFlowAnalysis.hierarchyCache
+ .getDynamicTargetSet(selector as DynamicSelector);
dynamicTargetSet.addDependentInvocation(this);
assert(targets.isEmpty);
for (Member target in dynamicTargetSet.targets) {
- if (areArgumentsValidFor(target)) {
- _getReceiverTypeBuilder(targets, target).addType(receiver);
- } else {
- _recordMismatchedDynamicInvocation(target, typeFlowAnalysis);
- }
+ _getReceiverTypeBuilder(targets, target).addType(receiver);
}
// Conservatively include noSuchMethod if selector is not from Object,
@@ -717,38 +636,6 @@
}
}
- bool _collectTargetsForFunctionCall(
- Type receiver,
- Map<Member, _ReceiverTypeBuilder> targets,
- TypeFlowAnalysis typeFlowAnalysis) {
- final closure = receiver.closure;
- if (closure != null) {
- final target = typeFlowAnalysis.getClosureCallMethod(closure);
- if (areArgumentsValidFor(target)) {
- if (kPrintTrace) {
- tracePrint("Found closure target $closure");
- }
- _getReceiverTypeBuilder(targets, target)
- .addConcreteType(receiver as ConcreteType);
- }
- return true;
- }
- return false;
- }
-
- void _recordMismatchedDynamicInvocation(
- Member target, TypeFlowAnalysis typeFlowAnalysis) {
- // Although target is not going to be called because of
- // the mismatch in the number or names of arguments,
- // it still participates in the dynamic lookup.
- // So mark it as called dynamically so its signature is preserved.
- if (selector.callKind != CallKind.PropertyGet) {
- typeFlowAnalysis._methodsAndSettersCalledDynamically.add(target);
- } else {
- typeFlowAnalysis._gettersCalledDynamically.add(target);
- }
- }
-
_ReceiverTypeBuilder _getReceiverTypeBuilder(
Map<Member, _ReceiverTypeBuilder> targets, Member member) =>
targets[member] ??= new _ReceiverTypeBuilder();
@@ -1121,7 +1008,7 @@
final String name;
Type value = emptyType;
- _SharedVariableImpl(this.name);
+ _SharedVariableImpl(VariableDeclaration decl) : name = decl.name ?? '__tmp';
@override
Type getValue(
@@ -1338,6 +1225,7 @@
// TODO(alexmarkov): Rename to _TypeHierarchyImpl.
class _ClassHierarchyCache extends TypeHierarchy {
final TypeFlowAnalysis _typeFlowAnalysis;
+ final CoreTypes coreTypes;
final GenericInterfacesInfo genericInterfacesInfo;
final Map<Class, _TFClassImpl> classes = <Class, _TFClassImpl>{};
final Set<Class> allocatedClasses = Set<Class>();
@@ -1367,24 +1255,32 @@
getTFClass(coreTypes.deprecatedNullClass);
_ClassHierarchyCache(this._typeFlowAnalysis, this.genericInterfacesInfo,
- super.coreTypes, super.target, super.soundNullSafety)
+ this.coreTypes, bool soundNullSafety)
: objectNoSuchMethod =
- coreTypes.index.getProcedure('dart:core', 'Object', 'noSuchMethod');
+ coreTypes.index.getProcedure('dart:core', 'Object', 'noSuchMethod'),
+ super(coreTypes, soundNullSafety);
@override
_TFClassImpl getTFClass(Class c) {
- return classes[c] ??= _createOrdinaryClass(c);
+ return classes[c] ??= _createTFClass(c, null);
}
- _TFClassImpl _createOrdinaryClass(Class c) {
+ _TFClassImpl _createTFClass(Class c, RecordShape? recordShape) {
final supertypes = Set<TFClass>();
- for (var sup in c.supers) {
- supertypes.addAll(getTFClass(sup.classNode).supertypes);
+ _TFClassImpl? superclass;
+ if (recordShape != null) {
+ // Record class has an ordinary class as its superclass.
+ superclass = getTFClass(c);
+ supertypes.addAll(superclass.supertypes);
+ } else {
+ for (var sup in c.supers) {
+ supertypes.addAll(getTFClass(sup.classNode).supertypes);
+ }
+ Class? superclassNode = c.superclass;
+ superclass = superclassNode != null ? getTFClass(superclassNode) : null;
}
- Class? superclassNode = c.superclass;
- _TFClassImpl? superclass =
- superclassNode != null ? getTFClass(superclassNode) : null;
- return _TFClassImpl(++_classIdCounter, c, superclass, supertypes, null);
+ return _TFClassImpl(
+ ++_classIdCounter, c, superclass, supertypes, recordShape);
}
ConcreteType addAllocatedClass(_TFClassImpl cls) {
@@ -1423,16 +1319,12 @@
recordClasses[shape] ??= _createRecordClass(shape);
_TFClassImpl _createRecordClass(RecordShape shape) {
- final Class c = target.getRecordImplementationClass(
+ final Class c = _typeFlowAnalysis.target.getRecordImplementationClass(
coreTypes, shape.numPositionalFields, shape.namedFields);
if (c.isAbstract) {
throw 'Record class $c should not be abstract';
}
- // Record class has an ordinary class as its superclass.
- _TFClassImpl superclass = getTFClass(c);
- final supertypes = Set<TFClass>();
- supertypes.addAll(superclass.supertypes);
- return _TFClassImpl(++_classIdCounter, c, superclass, supertypes, shape);
+ return _createTFClass(c, shape);
}
Field getRecordField(RecordShape shape, String name) {
@@ -1722,9 +1614,6 @@
final Map<Field, _FieldValue> _fieldValues = <Field, _FieldValue>{};
final Map<VariableDeclaration, _SharedVariableImpl> _sharedCapturedVariables =
{};
- final Map<Member, _SharedVariableImpl> _sharedCapturedThisVariables = {};
- final Map<Member, Closure> _closureByCallMethod = {};
- final Map<Closure, Procedure> _callMethodByClosure = {};
final Set<Member> _tearOffTaken = new Set<Member>();
final Set<Member> _methodsAndSettersCalledDynamically = new Set<Member>();
final Set<Member> _gettersCalledDynamically = new Set<Member>();
@@ -1744,8 +1633,8 @@
: annotationMatcher =
matcher ?? new ConstantPragmaAnnotationParser(coreTypes, target) {
nativeCodeOracle = new NativeCodeOracle(libraryIndex, annotationMatcher);
- hierarchyCache = new _ClassHierarchyCache(this, _genericInterfacesInfo,
- coreTypes, target, target.flags.soundNullSafety);
+ hierarchyCache = new _ClassHierarchyCache(
+ this, _genericInterfacesInfo, coreTypes, target.flags.soundNullSafety);
summaryCollector = new SummaryCollector(
target,
environment,
@@ -1768,14 +1657,7 @@
Summary getSummary(Member member) {
Summary? summary = _summaries[member];
if (summary == null) {
- final closure = _closureByCallMethod[member];
- if (closure != null) {
- summary =
- summaryCollector.createSummary(closure.member, closure.function!);
- } else {
- summary = summaryCollector.createSummary(member, null);
- }
- _summaries[member] = summary;
+ _summaries[member] = summary = summaryCollector.createSummary(member);
if (summary.statements.length >=
_SelectorApproximation.largeSummarySize) {
final DirectSelector selector =
@@ -1791,7 +1673,7 @@
if (fieldValue == null) {
Summary? typeGuardSummary = null;
if (field.isCovariantByClass) {
- typeGuardSummary = summaryCollector.createSummary(field, null,
+ typeGuardSummary = summaryCollector.createSummary(field,
fieldSummaryType: FieldSummaryType.kFieldGuard);
}
fieldValue = _FieldValue(field, typeGuardSummary, hierarchyCache);
@@ -1957,7 +1839,7 @@
if (kPrintDebug) {
debugPrint("ADD RAW CALL: $selector");
}
- assert(selector is! DynamicSelector);
+ assert(selector is! DynamicSelector); // TODO(alexmarkov)
applyCall(null, selector, summaryCollector.rawArguments(selector),
isResultUsed: false, processImmediately: false);
@@ -1994,25 +1876,9 @@
_tearOffTaken.add(target);
}
- @override
- Procedure getClosureCallMethod(Closure closure) =>
- _callMethodByClosure[closure] ??= _createCallMethod(closure);
-
- Procedure _createCallMethod(Closure closure) {
- final callMethod = closure.createCallMethod();
- _closureByCallMethod[callMethod] = closure;
- return callMethod;
- }
-
/// ---- Implementation of [SharedVariableBuilder] interface. ----
@override
SharedVariable getSharedVariable(VariableDeclaration variable) =>
- _sharedCapturedVariables[variable] ??=
- _SharedVariableImpl(variable.name ?? '__tmp');
-
- @override
- SharedVariable getSharedCapturedThis(Member member) =>
- _sharedCapturedThisVariables[member] ??=
- _SharedVariableImpl('${nodeToText(member)}::this');
+ _sharedCapturedVariables[variable] ??= _SharedVariableImpl(variable);
}
diff --git a/pkg/vm/lib/transformations/type_flow/calls.dart b/pkg/vm/lib/transformations/type_flow/calls.dart
index 5c0edf7..035e176 100644
--- a/pkg/vm/lib/transformations/type_flow/calls.dart
+++ b/pkg/vm/lib/transformations/type_flow/calls.dart
@@ -163,7 +163,7 @@
@override
final Name name;
- static final kCall = DynamicSelector(CallKind.Method, Name.callName);
+ static final kCall = new DynamicSelector(CallKind.Method, new Name('call'));
DynamicSelector(CallKind callKind, this.name) : super(callKind);
@@ -182,32 +182,6 @@
String toString() => 'dynamic ${_callKindPrefix}[${nodeToText(name)}]';
}
-/// Function call with known function type.
-class FunctionSelector extends Selector {
- final Type staticResultType;
-
- @override
- Name get name => Name.callName;
-
- FunctionSelector(this.staticResultType) : super(CallKind.Method);
-
- @override
- Member? get member => null;
-
- @override
- int get hashCode => combineHashes(super.hashCode, staticResultType.hashCode);
-
- @override
- bool operator ==(other) =>
- identical(this, other) ||
- other is FunctionSelector &&
- super == (other) &&
- other.staticResultType == staticResultType;
-
- @override
- String toString() => 'function [=> ${staticResultType}]';
-}
-
/// Arguments passed to a call, including implicit receiver argument.
// TODO(alexmarkov): take type arguments into account
class Args<T extends TypeExpr> {
diff --git a/pkg/vm/lib/transformations/type_flow/native_code.dart b/pkg/vm/lib/transformations/type_flow/native_code.dart
index a6d6fb0..d8a8581 100644
--- a/pkg/vm/lib/transformations/type_flow/native_code.dart
+++ b/pkg/vm/lib/transformations/type_flow/native_code.dart
@@ -39,9 +39,6 @@
/// Record the fact that given member is torn off.
void recordTearOff(Member target) {}
-
- /// Artificial call method corresponding to the given [closure].
- Procedure getClosureCallMethod(Closure closure);
}
class PragmaEntryPointsVisitor extends RecursiveVisitor {
diff --git a/pkg/vm/lib/transformations/type_flow/rta.dart b/pkg/vm/lib/transformations/type_flow/rta.dart
index d5d16e4..e0e6f7f 100644
--- a/pkg/vm/lib/transformations/type_flow/rta.dart
+++ b/pkg/vm/lib/transformations/type_flow/rta.dart
@@ -18,7 +18,7 @@
import 'native_code.dart'
show EntryPointsListener, NativeCodeOracle, PragmaEntryPointsVisitor;
import 'protobuf_handler.dart' show ProtobufHandler;
-import 'types.dart' show Closure, ConcreteType, RecordShape, TFClass, Type;
+import 'types.dart' show TFClass, Type, ConcreteType, RecordShape;
import 'utils.dart' show combineHashes;
import '../pragma.dart' show ConstantPragmaAnnotationParser;
@@ -574,8 +574,4 @@
@override
void recordTearOff(Member target) => throw 'Unsupported operation';
-
- @override
- Procedure getClosureCallMethod(Closure closure) =>
- throw 'Unsupported operation';
}
diff --git a/pkg/vm/lib/transformations/type_flow/summary.dart b/pkg/vm/lib/transformations/type_flow/summary.dart
index 77ea809..8ca5d00 100644
--- a/pkg/vm/lib/transformations/type_flow/summary.dart
+++ b/pkg/vm/lib/transformations/type_flow/summary.dart
@@ -318,7 +318,9 @@
Call(this.selector, this.args, this.staticResultType,
bool isInstanceCreation) {
- if (selector is! InterfaceSelector) {
+ // TODO(sjindel/tfa): Support inferring unchecked entry-points for dynamic
+ // and direct calls as well.
+ if (selector is DynamicSelector || selector is DirectSelector) {
setUseCheckedEntry();
}
if (isInstanceCreation) {
@@ -446,13 +448,11 @@
if (receiver is NullableType) {
_flags |= kNullableReceiver;
}
- if (!receiverMayBeInt) {
- final receiverIntIntersect =
- receiver.intersection(typeHierarchy.intType, typeHierarchy);
- if (receiverIntIntersect != emptyType &&
- receiverIntIntersect != nullableEmptyType) {
- _flags |= kReceiverMayBeInt;
- }
+ final receiverIntIntersect =
+ receiver.intersection(typeHierarchy.intType, typeHierarchy);
+ if (receiverIntIntersect != emptyType &&
+ receiverIntIntersect != nullableEmptyType) {
+ _flags |= kReceiverMayBeInt;
}
}
@@ -901,11 +901,8 @@
}
abstract class SharedVariableBuilder {
- /// [SharedVariable] representing captured [variable].
+ /// Returns [SharedVariable] representing captured [variable].
SharedVariable getSharedVariable(VariableDeclaration variable);
-
- /// [SharedVariable] representing captured `this` in [member].
- SharedVariable getSharedCapturedThis(Member member);
}
/// Reads value from [variable].
diff --git a/pkg/vm/lib/transformations/type_flow/summary_collector.dart b/pkg/vm/lib/transformations/type_flow/summary_collector.dart
index 369572a..e6b90d1 100644
--- a/pkg/vm/lib/transformations/type_flow/summary_collector.dart
+++ b/pkg/vm/lib/transformations/type_flow/summary_collector.dart
@@ -296,13 +296,7 @@
/// Number of variables at entry of active statements.
List<int>? numVariablesAtActiveStatements;
- bool isInsideLocalFunction = false;
- bool isReceiverCaptured = false;
-
- LocalFunction? summaryFunction;
- int numVariablesAtSummaryFunctionEntry = 0;
-
- _VariablesInfoCollector(Member member, this.summaryFunction) {
+ _VariablesInfoCollector(Member member) {
member.accept(this);
}
@@ -324,12 +318,6 @@
numVariablesAtActiveStatements = null;
final savedNumVariablesAtFunctionEntry = numVariablesAtFunctionEntry;
numVariablesAtFunctionEntry = numVariables;
- final savedIsInsideLocalFunction = isInsideLocalFunction;
- isInsideLocalFunction = true;
-
- if (node == summaryFunction) {
- numVariablesAtSummaryFunctionEntry = numVariablesAtFunctionEntry;
- }
final function = node.function;
function.accept(this);
@@ -337,7 +325,6 @@
activeStatements = savedActiveStatements;
numVariablesAtActiveStatements = savedNumVariablesAtActiveStatements;
numVariablesAtFunctionEntry = savedNumVariablesAtFunctionEntry;
- isInsideLocalFunction = savedIsInsideLocalFunction;
}
bool _isDeclaredBefore(int variableIndex, int entryDeclarationCounter) =>
@@ -376,12 +363,6 @@
numVariablesAtActiveStatements!.removeLast();
}
- void _useReceiver() {
- if (isInsideLocalFunction) {
- isReceiverCaptured = true;
- }
- }
-
@override
visitConstructor(Constructor node) {
// Need to visit parameters before initializers.
@@ -478,56 +459,6 @@
visitList(node.cases, this);
_endCollectingModifiedVariables();
}
-
- @override
- visitSuperMethodInvocation(SuperMethodInvocation node) {
- _useReceiver();
- super.visitSuperMethodInvocation(node);
- }
-
- @override
- visitSuperPropertyGet(SuperPropertyGet node) {
- _useReceiver();
- super.visitSuperPropertyGet(node);
- }
-
- @override
- visitSuperPropertySet(SuperPropertySet node) {
- _useReceiver();
- super.visitSuperPropertySet(node);
- }
-
- @override
- visitThisExpression(ThisExpression node) {
- _useReceiver();
- super.visitThisExpression(node);
- }
-
- @override
- visitFieldInitializer(FieldInitializer node) {
- assert(!isInsideLocalFunction);
- super.visitFieldInitializer(node);
- }
-
- @override
- visitRedirectingInitializer(RedirectingInitializer node) {
- assert(!isInsideLocalFunction);
- super.visitRedirectingInitializer(node);
- }
-
- @override
- visitSuperInitializer(SuperInitializer node) {
- assert(!isInsideLocalFunction);
- super.visitSuperInitializer(node);
- }
-
- @override
- visitTypeParameterType(TypeParameterType node) {
- if (node.parameter.declaration is Class) {
- _useReceiver();
- }
- super.visitTypeParameterType(node);
- }
}
Iterable<Name> getSelectors(ClassHierarchy hierarchy, Class cls,
@@ -596,11 +527,14 @@
Join? _returnValue;
Member? _enclosingMember;
- TypeExpr? _receiver;
+ Parameter? _receiver;
late ConstantAllocationCollector constantAllocationCollector;
late RuntimeTypeTranslatorImpl _translator;
StaticTypeContext? _staticTypeContext;
+ // Currently only used for factory constructors.
+ Map<TypeParameter, TypeExpr>? _fnTypeVariables;
+
SummaryCollector(
this.target,
this._environment,
@@ -620,48 +554,32 @@
setters: true));
}
- Summary createSummary(Member member, LocalFunction? localFunction,
+ Summary createSummary(Member member,
{fieldSummaryType = FieldSummaryType.kInitializer}) {
- String summaryName = member.toString();
- if (fieldSummaryType == FieldSummaryType.kFieldGuard) {
- summaryName += ' (guard)';
- }
- if (localFunction != null) {
- summaryName += '::${localFunctionName(localFunction)}';
- }
+ final String summaryName =
+ "${member}${fieldSummaryType == FieldSummaryType.kFieldGuard ? " (guard)" : ""}";
debugPrint("===== $summaryName =====");
assert(!member.isAbstract);
_enclosingMember = member;
- if (localFunction == null) {
- _protobufHandler?.beforeSummaryCreation(member);
- }
+ _protobufHandler?.beforeSummaryCreation(member);
- _staticTypeContext = StaticTypeContext(member, _environment);
- _variablesInfo = _VariablesInfoCollector(member, localFunction);
- _variableValues = List<TypeExpr?>.filled(_variablesInfo.numVariables, null);
- _aggregateVariable = List<bool>.filled(_variablesInfo.numVariables, false);
+ _staticTypeContext = new StaticTypeContext(member, _environment);
+ _variablesInfo = new _VariablesInfoCollector(member);
+ _variableValues =
+ new List<TypeExpr?>.filled(_variablesInfo.numVariables, null);
+ _aggregateVariable =
+ new List<bool>.filled(_variablesInfo.numVariables, false);
_capturedVariableReads = null;
- _variableVersions = List<int>.filled(_variablesInfo.numVariables, 0);
+ _variableVersions = new List<int>.filled(_variablesInfo.numVariables, 0);
_jumpHandlers = null;
_returnValue = null;
_receiver = null;
_currentCondition = null;
- // Summary collector doesn't visit outer functions, so
- // captured variables declared in the outer functions should be
- // "pre-declared" and marked as aggregate.
- for (int i = 0;
- i < _variablesInfo.numVariablesAtSummaryFunctionEntry;
- ++i) {
- if (_variablesInfo.isCaptured(_variablesInfo.varDeclarations[i])) {
- _aggregateVariable[i] = true;
- }
- }
-
final hasReceiver = hasReceiverArg(member);
- if (member is Field && localFunction == null) {
+ if (member is Field) {
if (hasReceiver) {
final int numArgs =
fieldSummaryType == FieldSummaryType.kInitializer ? 1 : 2;
@@ -671,18 +589,12 @@
_receiver = _declareParameter("this",
_environment.coreTypes.legacyRawType(member.enclosingClass!), null,
isReceiver: true);
- if (_variablesInfo.isReceiverCaptured) {
- final capturedReceiver =
- _sharedVariableBuilder.getSharedCapturedThis(_enclosingMember!);
- final write = WriteVariable(capturedReceiver, _receiver!);
- _summary.add(write);
- }
} else {
_summary = new Summary(summaryName);
}
- _translator = new RuntimeTypeTranslatorImpl(
- _environment.coreTypes, _summary, this, null, _genericInterfacesInfo);
+ _translator = new RuntimeTypeTranslatorImpl(_environment.coreTypes,
+ _summary, _receiver, null, _genericInterfacesInfo);
if (fieldSummaryType == FieldSummaryType.kInitializer) {
_summary.result = _visit(member.initializer!);
@@ -692,13 +604,10 @@
_summary.result = _typeCheck(valueParam, member.type, member);
}
} else {
- final FunctionNode function =
- localFunction != null ? localFunction.function : member.function!;
+ final FunctionNode function = member.function!;
- final numTypeParameters =
- localFunction == null ? numTypeParams(member) : 0;
- final firstParamIndex =
- ((hasReceiver || localFunction != null) ? 1 : 0) + numTypeParameters;
+ final numTypeParameters = numTypeParams(member);
+ final firstParamIndex = (hasReceiver ? 1 : 0) + numTypeParameters;
_summary = new Summary(summaryName,
parameterCount: firstParamIndex +
@@ -709,32 +618,27 @@
requiredParameterCount:
firstParamIndex + function.requiredParameterCount);
- Map<TypeParameter, TypeExpr>? fnTypeVariables;
if (numTypeParameters > 0) {
- fnTypeVariables = <TypeParameter, TypeExpr>{
+ _fnTypeVariables = <TypeParameter, TypeExpr>{
for (TypeParameter tp in function.typeParameters)
tp: _declareParameter(tp.name!, null, null)
};
}
- if (localFunction != null) {
- _declareParameter('#closure', const DynamicType(), null);
- } else if (hasReceiver) {
+ if (hasReceiver) {
// TODO(alexmarkov): subclass cone
- _receiver = _declareParameter('this',
+ _receiver = _declareParameter("this",
_environment.coreTypes.legacyRawType(member.enclosingClass!), null,
isReceiver: true);
}
_translator = new RuntimeTypeTranslatorImpl(_environment.coreTypes,
- _summary, this, fnTypeVariables, _genericInterfacesInfo);
+ _summary, _receiver, _fnTypeVariables, _genericInterfacesInfo);
// Handle forwarding stubs. We need to check types against the types of
// the forwarding stub's target, [member.concreteForwardingStubTarget].
FunctionNode useTypesFrom = function;
- if (member is Procedure &&
- member.isForwardingStub &&
- localFunction == null) {
+ if (member is Procedure && member.isForwardingStub) {
final target = member.concreteForwardingStubTarget;
if (target != null) {
if (target is Field) {
@@ -767,18 +671,6 @@
decl.initializer);
}
- if (hasReceiver && _variablesInfo.isReceiverCaptured) {
- final capturedReceiver =
- _sharedVariableBuilder.getSharedCapturedThis(_enclosingMember!);
- if (localFunction != null) {
- final read = _receiver = ReadVariable(capturedReceiver);
- _summary.add(read);
- } else {
- final write = WriteVariable(capturedReceiver, _receiver!);
- _summary.add(write);
- }
- }
-
int count = firstParamIndex;
for (int i = 0; i < function.positionalParameters.length; ++i) {
final decl = function.positionalParameters[i];
@@ -803,7 +695,7 @@
_returnValue = new Join("%result", function.returnType);
_summary.add(_returnValue!);
- if (member is Constructor && localFunction == null) {
+ if (member is Constructor) {
// Make sure instance field initializers are visited.
for (var f in member.enclosingClass.members) {
if ((f is Field) &&
@@ -818,7 +710,6 @@
}
if (function.body == null) {
- assert(localFunction == null);
TypeExpr type = _nativeCodeOracle.handleNativeProcedure(
member, _entryPointsListener, _typesBuilder, _translator);
if (type is! ConcreteType && type is! Statement) {
@@ -839,7 +730,7 @@
_currentCondition = null;
- if (member.name.text == '==' && localFunction == null) {
+ if (member.name.text == '==') {
// In addition to what is returned from the function body,
// operator == performs implicit comparison with null
// and returns bool.
@@ -876,11 +767,9 @@
}
}
- if (localFunction == null) {
- member.annotations.forEach(_visit);
- member.enclosingClass?.annotations.forEach(_visit);
- member.enclosingLibrary.annotations.forEach(_visit);
- }
+ member.annotations.forEach(_visit);
+ member.enclosingClass?.annotations.forEach(_visit);
+ member.enclosingLibrary.annotations.forEach(_visit);
_enclosingMember = null;
_staticTypeContext = null;
@@ -889,7 +778,7 @@
debugPrint(_summary);
debugPrint("---------------------------------");
- _SummaryNormalizer(_summary, _typesBuilder).normalize();
+ new _SummaryNormalizer(_summary, _typesBuilder).normalize();
debugPrint("---------- NORM SUMMARY ---------");
debugPrint(_summary);
@@ -915,18 +804,10 @@
}
if (hasReceiverArg(member)) {
- final enclosingClass = member.enclosingClass;
- if (enclosingClass == null) {
- if (isArtificialNode(member) && member.name == Name.callName) {
- // Approximate closure parameter of the artificial call method.
- args.add(nullableAnyType);
- } else {
- throw 'Unexpected $member without enclosing class.';
- }
- } else {
- final receiver = _typesBuilder.getTFClass(enclosingClass).coneType;
- args.add(receiver);
- }
+ assert(member.enclosingClass != null);
+ final receiver =
+ _typesBuilder.getTFClass(member.enclosingClass!).coneType;
+ args.add(receiver);
}
switch (selector.callKind) {
@@ -1068,8 +949,6 @@
}
}
- TypeExpr _readReceiver() => _receiver!;
-
TypeExpr _readVariable(VariableDeclaration variable, TreeNode node) {
if (_variablesInfo.isCaptured(variable)) {
assert(_aggregateVariable[_variablesInfo.varIndex[variable]!]);
@@ -1282,10 +1161,7 @@
if (target is Procedure && node is Expression) {
final returnType = target.function.returnType;
final staticDartType = _staticDartType(node);
- // TODO(dartbug.com/54200): static type cannot be trusted when
- // function type is returned.
- if (returnType is TypeParameterType ||
- (returnType != staticDartType && returnType is! FunctionType)) {
+ if (returnType is TypeParameterType || returnType != staticDartType) {
staticResultType = _typesBuilder.fromStaticType(staticDartType, true);
}
}
@@ -1480,6 +1356,25 @@
return _stringType;
}
+ void _handleNestedFunctionNode(FunctionNode node) {
+ final savedReturn = _returnValue;
+ _returnValue = null;
+ final savedCondition = _currentCondition;
+ final savedVariableValues = _variableValues;
+ _variableValues = _makeEmptyVariableValues();
+
+ // Approximate parameters of nested functions with static types.
+ // TODO(sjindel/tfa): Use TypeCheck for closure parameters.
+ node.positionalParameters.forEach(_declareVariableWithStaticType);
+ node.namedParameters.forEach(_declareVariableWithStaticType);
+
+ _visitWithoutResult(node.body!);
+
+ _currentCondition = savedCondition;
+ _variableValues = savedVariableValues;
+ _returnValue = savedReturn;
+ }
+
TypeExpr _closureType(LocalFunction node) {
final Class? concreteClass =
target.concreteClosureClass(_environment.coreTypes);
@@ -1754,12 +1649,7 @@
@override
TypeExpr visitFunctionExpression(FunctionExpression node) {
- final closure = Closure(_enclosingMember!, node);
- final callMethod = _entryPointsListener.getClosureCallMethod(closure);
- // In order to keep analysis scalable, targets of function calls are
- // not calculated when target closure is not inferred.
- // Raw call is added to account for such approximated function calls.
- _entryPointsListener.addRawCall(DirectSelector(callMethod));
+ _handleNestedFunctionNode(node.function);
return _closureType(node);
}
@@ -1951,19 +1841,17 @@
@override
TypeExpr visitLocalFunctionInvocation(LocalFunctionInvocation node) {
- final closure = Closure(_enclosingMember!, node.localFunction);
- final callMethod = _entryPointsListener.getClosureCallMethod(closure);
- final args = _visitArguments(anyInstanceType, node.arguments);
- return _makeCall(node, DirectSelector(callMethod), args);
+ _visitArguments(null, node.arguments);
+ return _staticType(node);
}
@override
TypeExpr visitFunctionInvocation(FunctionInvocation node) {
final receiverNode = node.receiver;
final receiver = _visit(receiverNode);
- final args = _visitArguments(receiver, node.arguments);
- final result = _makeCall(node, FunctionSelector(_staticType(node)), args);
- _updateReceiverAfterCall(receiverNode, receiver, Name.callName);
+ _visitArguments(receiver, node.arguments);
+ final result = _staticType(node);
+ _updateReceiverAfterCall(receiverNode, receiver, Name('call'));
return result;
}
@@ -2070,7 +1958,8 @@
@override
TypeExpr visitSuperMethodInvocation(SuperMethodInvocation node) {
assert(kPartialMixinResolution);
- final args = _visitArguments(_readReceiver(), node.arguments);
+ assert(_receiver != null, "Should have receiver. Node: $node");
+ final args = _visitArguments(_receiver, node.arguments);
// Re-resolve target due to partial mixin resolution.
final target = _hierarchy.getDispatchTarget(_superclass, node.name);
if (target == null) {
@@ -2085,7 +1974,7 @@
@override
TypeExpr visitSuperPropertyGet(SuperPropertyGet node) {
assert(kPartialMixinResolution);
- final args = new Args<TypeExpr>([_readReceiver()]);
+ final args = new Args<TypeExpr>([_receiver!]);
// Re-resolve target due to partial mixin resolution.
final target = _hierarchy.getDispatchTarget(_superclass, node.name);
if (target == null) {
@@ -2100,7 +1989,7 @@
TypeExpr visitSuperPropertySet(SuperPropertySet node) {
assert(kPartialMixinResolution);
final value = _visit(node.value);
- final args = new Args<TypeExpr>([_readReceiver(), value]);
+ final args = new Args<TypeExpr>([_receiver!, value]);
// Re-resolve target due to partial mixin resolution.
final target =
_hierarchy.getDispatchTarget(_superclass, node.name, setter: true);
@@ -2205,7 +2094,7 @@
@override
TypeExpr visitThisExpression(ThisExpression node) {
- return _readReceiver();
+ return _receiver!;
}
@override
@@ -2360,12 +2249,7 @@
TypeExpr? visitFunctionDeclaration(FunctionDeclaration node) {
node.variable.annotations.forEach(_visit);
_declareVariable(node.variable, _closureType(node));
- final closure = Closure(_enclosingMember!, node);
- final callMethod = _entryPointsListener.getClosureCallMethod(closure);
- // In order to keep analysis scalable, targets of function calls are
- // not calculated when target closure is not inferred.
- // Raw call is added to account for such approximated function calls.
- _entryPointsListener.addRawCall(DirectSelector(callMethod));
+ _handleNestedFunctionNode(node.function);
return null;
}
@@ -2570,7 +2454,7 @@
@override
TypeExpr? visitFieldInitializer(FieldInitializer node) {
final value = _visit(node.value);
- final args = new Args<TypeExpr>([_readReceiver(), value]);
+ final args = new Args<TypeExpr>([_receiver!, value]);
_makeCall(
node,
new DirectSelector(node.field,
@@ -2581,14 +2465,14 @@
@override
TypeExpr? visitRedirectingInitializer(RedirectingInitializer node) {
- final args = _visitArguments(_readReceiver(), node.arguments);
+ final args = _visitArguments(_receiver, node.arguments);
_makeCall(node, new DirectSelector(node.target), args);
return null;
}
@override
TypeExpr? visitSuperInitializer(SuperInitializer node) {
- final args = _visitArguments(_readReceiver(), node.arguments);
+ final args = _visitArguments(_receiver, node.arguments);
Constructor? target = null;
if (kPartialMixinResolution) {
@@ -2641,12 +2525,12 @@
implements RuntimeTypeTranslator, DartTypeVisitor<TypeExpr> {
final CoreTypes coreTypes;
final Summary? summary;
- final SummaryCollector? summaryCollector;
final Map<TypeParameter, TypeExpr>? functionTypeVariables;
final Map<DartType, TypeExpr> typesCache = <DartType, TypeExpr>{};
+ final TypeExpr? receiver;
final GenericInterfacesInfo genericInterfacesInfo;
- RuntimeTypeTranslatorImpl(this.coreTypes, this.summary, this.summaryCollector,
+ RuntimeTypeTranslatorImpl(this.coreTypes, this.summary, this.receiver,
this.functionTypeVariables, this.genericInterfacesInfo) {}
// Create a type translator which can be used only for types with no free type
@@ -2654,8 +2538,8 @@
RuntimeTypeTranslatorImpl.forClosedTypes(
this.coreTypes, this.genericInterfacesInfo)
: summary = null,
- summaryCollector = null,
- functionTypeVariables = null {}
+ functionTypeVariables = null,
+ receiver = null {}
TypeExpr instantiateConcreteType(ConcreteType type, List<DartType> typeArgs) {
if (typeArgs.isEmpty) return type;
@@ -2803,7 +2687,7 @@
if (nullability == Nullability.undetermined) {
nullability = Nullability.nonNullable;
}
- final extract = Extract(summaryCollector!._readReceiver(), interfaceClass,
+ final extract = new Extract(receiver!, interfaceClass,
interfaceClass.typeParameters.indexOf(type.parameter), nullability);
summary!.add(extract);
return extract;
diff --git a/pkg/vm/lib/transformations/type_flow/types.dart b/pkg/vm/lib/transformations/type_flow/types.dart
index 43e0d1f..2230312 100644
--- a/pkg/vm/lib/transformations/type_flow/types.dart
+++ b/pkg/vm/lib/transformations/type_flow/types.dart
@@ -7,10 +7,9 @@
import 'dart:core' hide Type;
-import 'package:kernel/ast.dart' hide Variance;
+import 'package:kernel/ast.dart';
+
import 'package:kernel/core_types.dart';
-import 'package:kernel/type_algebra.dart' show getFreshTypeParameters;
-import 'package:kernel/target/targets.dart' show Target;
import 'utils.dart';
@@ -57,7 +56,7 @@
!member.isStatic &&
!member.isAbstract));
return _concreteTypeWithAttributes(
- TypeAttributes._(null, Closure(member, function)));
+ TypeAttributes._(null, Closure._(member, function)));
}
/// Returns ConeType corresponding to this class.
@@ -66,13 +65,8 @@
bool get isRecord => recordShape != null;
/// Tests if [this] is a subtype of [other].
- bool isSubtypeOf(TFClass other) {
- final result = identical(this, other) || supertypes.contains(other);
- if (kPrintTrace) {
- tracePrint("isSubtype sub $this, sup $other = $result");
- }
- return result;
- }
+ bool isSubtypeOf(TFClass other) =>
+ identical(this, other) || supertypes.contains(other);
@override
int get hashCode => id;
@@ -98,7 +92,7 @@
target.isStatic &&
!target.isGetter &&
!target.isSetter));
- return Closure(target, null);
+ return Closure._(target, null);
} else if (c is TypedefTearOffConstant) {
throw 'Unexpected TypedefTearOffConstant $c';
}
@@ -191,10 +185,9 @@
abstract class TypesBuilder {
final CoreTypes coreTypes;
- final Target target;
final bool soundNullSafety;
- TypesBuilder(this.coreTypes, this.target, this.soundNullSafety);
+ TypesBuilder(this.coreTypes, this.soundNullSafety);
/// Return [TFClass] corresponding to the given [classNode].
TFClass getTFClass(Class classNode);
@@ -230,6 +223,7 @@
} else if (type is NeverType || type is NullType) {
result = emptyType;
} else if (type is FunctionType) {
+ // TODO(alexmarkov): support inference of function types
result = functionType;
} else if (type is RecordType) {
result = getRecordType(RecordShape(type), false);
@@ -275,11 +269,14 @@
/// Abstract interface to type hierarchy information used by types.
abstract class TypeHierarchy extends TypesBuilder
implements GenericInterfacesInfo {
- TypeHierarchy(CoreTypes coreTypes, Target target, bool soundNullSafety)
- : super(coreTypes, target, soundNullSafety);
+ TypeHierarchy(CoreTypes coreTypes, bool soundNullSafety)
+ : super(coreTypes, soundNullSafety);
/// Test if [sub] is a subtype of [sup].
bool isSubtype(Class sub, Class sup) {
+ if (kPrintTrace) {
+ tracePrint("isSubtype for sub = $sub, sup = $sup");
+ }
return identical(sub, sup) || getTFClass(sub).isSubtypeOf(getTFClass(sup));
}
@@ -325,8 +322,6 @@
Class? getConcreteClass(TypeHierarchy typeHierarchy) => null;
- Closure? get closure => null;
-
bool isSubtypeOf(TFClass cls) => false;
// Returns 'true' if this type will definitely pass a runtime type-check
@@ -595,23 +590,6 @@
String toString() => "_T ${types}";
@override
- Class? getConcreteClass(TypeHierarchy typeHierarchy) {
- Class? result;
- for (final t in types) {
- final cls = t.getConcreteClass(typeHierarchy);
- if (cls == null) {
- return null;
- }
- if (result == null) {
- result = cls;
- } else if (result != cls) {
- return null;
- }
- }
- return result;
- }
-
- @override
bool isSubtypeOf(TFClass cls) =>
types.every((ConcreteType t) => t.isSubtypeOf(cls));
@@ -966,22 +944,7 @@
return emptyType;
}
} else if (other is SetType) {
- final list = <ConcreteType>[];
- for (ConcreteType t in other.types) {
- if (t.cls.isSubtypeOf(this.cls)) {
- list.add(t);
- }
- }
- final size = list.length;
- if (size == 0) {
- return emptyType;
- } else if (size == 1) {
- return list.single;
- } else if (size == other.types.length) {
- return other;
- } else {
- return SetType(list);
- }
+ return other;
} else {
throw 'Unexpected type $other';
}
@@ -998,45 +961,7 @@
final Member member;
final LocalFunction? function;
- Closure(this.member, this.function);
-
- // Create a synthetic 'call' method.
- Procedure createCallMethod() {
- final localFunction = this.function;
- final functionNode =
- (localFunction != null) ? localFunction.function : member.function!;
- final typeParameters = (localFunction == null && member is Constructor)
- ? member.enclosingClass!.typeParameters
- : functionNode.typeParameters;
- final freshTypeParameters = getFreshTypeParameters(typeParameters);
- List<VariableDeclaration> convertParameters(
- List<VariableDeclaration> params) =>
- [
- for (final p in params)
- VariableDeclaration(p.name,
- initializer: (p.initializer != null)
- ? ConstantExpression(
- (p.initializer as ConstantExpression).constant)
- : null,
- type: freshTypeParameters.substitute(p.type),
- flags: p.flags)
- ];
- return Procedure(
- Name.callName,
- ProcedureKind.Method,
- FunctionNode(null,
- typeParameters: freshTypeParameters.freshTypeParameters,
- positionalParameters:
- convertParameters(functionNode.positionalParameters),
- namedParameters: convertParameters(functionNode.namedParameters),
- requiredParameterCount: functionNode.requiredParameterCount,
- returnType:
- freshTypeParameters.substitute(functionNode.returnType)),
- isExternal: true,
- isSynthetic: true,
- isStatic: false,
- fileUri: artificialNodeUri);
- }
+ Closure._(this.member, this.function);
@override
int get hashCode => combineHashes(member.hashCode, function.hashCode);
@@ -1054,7 +979,19 @@
if (function == null) {
return 'tear-off ${nodeToText(member)}';
}
- return localFunctionName(function);
+ switch (function) {
+ case FunctionDeclaration():
+ return function.variable.name!;
+ case FunctionExpression():
+ final location = function.location;
+ return '<anonymous closure' +
+ (location != null
+ ? ' at ${location.file.pathSegments.last}:${location.line}'
+ : '') +
+ '>';
+ default:
+ throw 'Unexpected local function ${function.runtimeType} $function';
+ }
}
}
@@ -1139,6 +1076,7 @@
numImmediateTypeArgs =
typeArgs_ != null ? cls.classNode.typeParameters.length : 0,
super._() {
+ // TODO(alexmarkov): support closures
assert(!cls.classNode.isAbstract);
assert(typeArgs == null || cls.classNode.typeParameters.isNotEmpty);
assert(typeArgs == null || typeArgs!.any((t) => t is RuntimeType));
@@ -1154,9 +1092,6 @@
filterArtificialNode(cls.classNode);
@override
- Closure? get closure => attributes?.closure;
-
- @override
bool isSubtypeOf(TFClass other) => cls.isSubtypeOf(other);
bool isSubtypeOfRuntimeType(TypeHierarchy typeHierarchy,
diff --git a/pkg/vm/lib/transformations/type_flow/utils.dart b/pkg/vm/lib/transformations/type_flow/utils.dart
index 23e8dbe..2f04c48 100644
--- a/pkg/vm/lib/transformations/type_flow/utils.dart
+++ b/pkg/vm/lib/transformations/type_flow/utils.dart
@@ -440,19 +440,3 @@
// Returns [node] or null, if node is artificial.
T? filterArtificialNode<T extends TreeNode>(T? node) =>
(node == null || isArtificialNode(node)) ? null : node;
-
-String localFunctionName(LocalFunction function) {
- switch (function) {
- case FunctionDeclaration():
- return function.variable.name!;
- case FunctionExpression():
- final location = function.location;
- return '<anonymous closure' +
- (location != null
- ? ' at ${location.file.pathSegments.last}:${location.line}'
- : '') +
- '>';
- default:
- throw 'Unexpected local function ${function.runtimeType} $function';
- }
-}
diff --git a/pkg/vm/test/transformations/type_flow/summary_collector_test.dart b/pkg/vm/test/transformations/type_flow/summary_collector_test.dart
index 005ba81..c18e5d6 100644
--- a/pkg/vm/test/transformations/type_flow/summary_collector_test.dart
+++ b/pkg/vm/test/transformations/type_flow/summary_collector_test.dart
@@ -21,7 +21,6 @@
import 'package:vm/transformations/type_flow/summary.dart';
import 'package:vm/transformations/type_flow/summary_collector.dart';
import 'package:vm/transformations/type_flow/types.dart';
-import 'package:vm/transformations/type_flow/utils.dart';
import '../../common_test_utils.dart';
@@ -31,8 +30,8 @@
final Map<Class, TFClass> _classes = <Class, TFClass>{};
int _classIdCounter = 0;
- FakeTypesBuilder(CoreTypes coreTypes, Target target)
- : super(coreTypes, target, /*soundNullSafety=*/ true);
+ FakeTypesBuilder(CoreTypes coreTypes)
+ : super(coreTypes, /*soundNullSafety=*/ true);
@override
TFClass getTFClass(Class c) =>
@@ -71,14 +70,11 @@
@override
void recordTearOff(Member target) {}
-
- @override
- Procedure getClosureCallMethod(Closure closure) => closure.createCallMethod();
}
class FakeSharedVariable implements SharedVariable {
- final String name;
- FakeSharedVariable(this.name);
+ final VariableDeclaration decl;
+ FakeSharedVariable(this.decl);
@override
Type getValue(TypeHierarchy typeHierarchy, CallHandler callHandler) =>
@@ -90,31 +86,24 @@
throw 'Not implemented';
@override
- String toString() => name;
+ String toString() => decl.name ?? '__tmp';
}
class FakeSharedVariableBuilder implements SharedVariableBuilder {
final Map<VariableDeclaration, SharedVariable> _sharedVariables = {};
- final Map<Member, SharedVariable> _sharedCapturedThisVariables = {};
@override
SharedVariable getSharedVariable(VariableDeclaration variable) =>
- _sharedVariables[variable] ??=
- FakeSharedVariable(variable.name ?? '__tmp');
- @override
- SharedVariable getSharedCapturedThis(Member member) =>
- _sharedCapturedThisVariables[member] ??=
- FakeSharedVariable('${nodeToText(member)}::this');
+ _sharedVariables[variable] ??= FakeSharedVariable(variable);
}
class PrintSummaries extends RecursiveVisitor {
late SummaryCollector _summaryCollector;
final StringBuffer _buf = new StringBuffer();
- Member? _enclosingMember;
PrintSummaries(Target target, TypeEnvironment environment,
CoreTypes coreTypes, ClosedWorldClassHierarchy hierarchy) {
- final typesBuilder = FakeTypesBuilder(coreTypes, target);
+ final typesBuilder = FakeTypesBuilder(coreTypes);
final annotationParser = ConstantPragmaAnnotationParser(coreTypes, target);
_summaryCollector = SummaryCollector(
target,
@@ -133,39 +122,15 @@
return _buf.toString();
}
- void printSummary(Member member, LocalFunction? localFunction) {
- String name;
- if (localFunction != null) {
- name = localFunctionName(localFunction);
- } else {
- name = qualifiedMemberNameToString(member);
- }
- _buf.writeln('------------ $name ------------');
- _buf.writeln(_summaryCollector.createSummary(member, localFunction));
- }
-
@override
defaultMember(Member member) {
if (!member.isAbstract &&
!((member is Field) && (member.initializer == null))) {
- printSummary(member, null);
- _enclosingMember = member;
- super.defaultMember(member);
- _enclosingMember = null;
+ _buf.writeln(
+ "------------ ${qualifiedMemberNameToString(member)} ------------");
+ _buf.writeln(_summaryCollector.createSummary(member));
}
}
-
- @override
- visitFunctionExpression(FunctionExpression node) {
- printSummary(_enclosingMember!, node);
- super.visitFunctionExpression(node);
- }
-
- @override
- visitFunctionDeclaration(FunctionDeclaration node) {
- printSummary(_enclosingMember!, node);
- super.visitFunctionDeclaration(node);
- }
}
class TestOptions {
diff --git a/pkg/vm/test/transformations/type_flow/types_test.dart b/pkg/vm/test/transformations/type_flow/types_test.dart
index 6c88211..a39a3db 100644
--- a/pkg/vm/test/transformations/type_flow/types_test.dart
+++ b/pkg/vm/test/transformations/type_flow/types_test.dart
@@ -6,10 +6,8 @@
import 'package:kernel/ast.dart';
import 'package:kernel/core_types.dart';
-import 'package:kernel/target/targets.dart' show Target, TargetFlags;
import 'package:kernel/testing/mock_sdk_component.dart';
import 'package:test/test.dart';
-import 'package:vm/target/vm.dart';
import 'package:vm/transformations/type_flow/types.dart';
class TestTypeHierarchy extends TypeHierarchy {
@@ -17,9 +15,8 @@
final Map<Class, Type> specializations;
int classIdCounter = 0;
- TestTypeHierarchy(
- CoreTypes coreTypes, Target target, this.classes, this.specializations)
- : super(coreTypes, target, /*soundNullSafety=*/ true);
+ TestTypeHierarchy(CoreTypes coreTypes, this.classes, this.specializations)
+ : super(coreTypes, /*soundNullSafety=*/ true);
@override
Type specializeTypeCone(TFClass base, {bool allowWideCone = false}) {
@@ -43,18 +40,9 @@
throw "flattenedTypeArgumentsFor is not supported in the types test.";
}
-class TestingTarget extends VmTarget {
- TestingTarget() : super(TargetFlags());
-
- // Mock SDK doesn't have _Closure class, use Function.
- @override
- Class concreteClosureClass(CoreTypes coreTypes) => coreTypes.functionClass;
-}
-
main() {
final Component component = createMockSdkComponent();
- final CoreTypes coreTypes = CoreTypes(component);
- final Target target = TestingTarget();
+ final CoreTypes coreTypes = new CoreTypes(component);
test('types-builder', () {
final Class c1 = new Class(name: 'C1', fileUri: dummyUri);
@@ -63,7 +51,7 @@
typeParameters: [new TypeParameter('E')],
fileUri: dummyUri);
- final TypesBuilder tb = new TestTypeHierarchy(coreTypes, target, {}, {});
+ final TypesBuilder tb = new TestTypeHierarchy(coreTypes, {}, {});
final tfc1 = tb.getTFClass(c1);
final tfc2 = tb.getTFClass(c2);
final tfFunction = tb.getTFClass(coreTypes.functionClass);
@@ -259,7 +247,6 @@
final hierarchy = new TestTypeHierarchy(
coreTypes,
- target,
// classes
{
c1: tfc1,
diff --git a/pkg/vm/testcases/transformations/ffi/as_function.dart.aot.expect b/pkg/vm/testcases/transformations/ffi/as_function.dart.aot.expect
index a45f3d7..233545a 100644
--- a/pkg/vm/testcases/transformations/ffi/as_function.dart.aot.expect
+++ b/pkg/vm/testcases/transformations/ffi/as_function.dart.aot.expect
@@ -15,7 +15,7 @@
return ffi::_ffiCall<void>(#ffiTarget0);
}
} =>#ffiClosure0;
- [@vm.inferred-type.metadata=!? (receiver not int)] function(){() → void};
+ function(){() → void};
}
[@vm.unboxing-info.metadata=()->i]static method testIntInt() → dynamic {
final ffi::Pointer<ffi::NativeFunction<(ffi::Int64) → ffi::Int32>> pointer = [@vm.inferred-type.metadata=dart.ffi::Pointer] ffi::Pointer::fromAddress<ffi::NativeFunction<(ffi::Int64) → ffi::Int32>>(3735928559);
@@ -24,10 +24,10 @@
@#C6
function #ffiClosure1(core::int arg1) → core::int {
_in::_nativeEffect(arg1);
- return [@vm.inferred-type.metadata=int] ffi::_ffiCall<core::int>(#ffiTarget1);
+ return ffi::_ffiCall<core::int>(#ffiTarget1);
}
} =>#ffiClosure1;
- return [@vm.inferred-type.metadata=int (receiver not int)] function(42){(core::int) → core::int};
+ return function(42){(core::int) → core::int};
}
[@vm.unboxing-info.metadata=()->i]static method testLeaf5Args() → dynamic {
final ffi::Pointer<ffi::NativeFunction<(ffi::Int32, ffi::Int32, ffi::Int32, ffi::Int32, ffi::Int32) → ffi::Int32>> pointer = [@vm.inferred-type.metadata=dart.ffi::Pointer] ffi::Pointer::fromAddress<ffi::NativeFunction<(ffi::Int32, ffi::Int32, ffi::Int32, ffi::Int32, ffi::Int32) → ffi::Int32>>(3735928559);
@@ -40,10 +40,10 @@
_in::_nativeEffect(arg3);
_in::_nativeEffect(arg4);
_in::_nativeEffect(arg5);
- return [@vm.inferred-type.metadata=int] ffi::_ffiCall<core::int>(#ffiTarget2);
+ return ffi::_ffiCall<core::int>(#ffiTarget2);
}
} =>#ffiClosure2;
- return [@vm.inferred-type.metadata=int (receiver not int)] function(1, 2, 3, 4, 5){(core::int, core::int, core::int, core::int, core::int) → core::int};
+ return function(1, 2, 3, 4, 5){(core::int, core::int, core::int, core::int, core::int) → core::int};
}
static method main() → void {
self::testVoidNoArg();
diff --git a/pkg/vm/testcases/transformations/ffi/finalizable_late_initializer.dart.aot.expect b/pkg/vm/testcases/transformations/ffi/finalizable_late_initializer.dart.aot.expect
index 29230b8..cc0cd7c 100644
--- a/pkg/vm/testcases/transformations/ffi/finalizable_late_initializer.dart.aot.expect
+++ b/pkg/vm/testcases/transformations/ffi/finalizable_late_initializer.dart.aot.expect
@@ -15,15 +15,15 @@
[@vm.inferred-type.metadata=#lib::Foo?] self::Foo? :foo:finalizableValue;
function #foo#initializer() → self::Foo
return :foo:finalizableValue = new self::Foo::•();
- [@vm.inferred-type.metadata=#lib::Foo] late final self::Foo foo = [@vm.inferred-type.metadata=#lib::Foo (receiver not int)] #foo#initializer(){() → self::Foo};
- [@vm.inferred-type.metadata=!? (receiver not int)](() → Null {
+ [@vm.inferred-type.metadata=#lib::Foo] late final self::Foo foo = #foo#initializer(){() → self::Foo};
+ (() → Null {
core::print(foo);
_in::reachabilityFence(:foo:finalizableValue);
})(){() → Null};
[@vm.inferred-type.metadata=#lib::Foo?] self::Foo? :foo2:finalizableValue;
function #foo2#initializer() → self::Foo
return :foo2:finalizableValue = new self::Foo::•();
- late final self::Foo foo2 = [@vm.inferred-type.metadata=#lib::Foo (receiver not int)] #foo2#initializer(){() → self::Foo};
+ late final self::Foo foo2 = #foo2#initializer(){() → self::Foo};
if([@vm.direct-call.metadata=dart.core::_IntegerImplementation.==] [@vm.inferred-type.metadata=dart.core::bool (skip check)] [@vm.direct-call.metadata=dart.core::_IntegerImplementation.%] [@vm.inferred-type.metadata=int (skip check)] [@vm.direct-call.metadata=dart.core::DateTime.millisecond] [@vm.inferred-type.metadata=int] new core::DateTime::now().{core::DateTime::millisecond}{core::int}.{core::num::%}(2){(core::num) → core::int} =={core::num::==}{(core::Object) → core::bool} 0) {
core::print(foo2);
}
diff --git a/pkg/vm/testcases/transformations/ffi/native_callable.dart.aot.expect b/pkg/vm/testcases/transformations/ffi/native_callable.dart.aot.expect
index 5b401ce..93c9361 100644
--- a/pkg/vm/testcases/transformations/ffi/native_callable.dart.aot.expect
+++ b/pkg/vm/testcases/transformations/ffi/native_callable.dart.aot.expect
@@ -21,7 +21,7 @@
static method testNativeCallableListener() → void {
final ffi::NativeCallable<(ffi::Int32) → ffi::Void> callback = block {
final ffi::NativeCallable<(ffi::Int32) → ffi::Void> #t1 = new ffi::_NativeCallableListener::•<(ffi::Int32) → ffi::Void>((final core::List<dynamic> args) → void
- [@vm.inferred-type.metadata=!? (receiver not int)] #C1(args.{core::List::[]}(0){(core::int) → dynamic}){(ffi::Int32) → ffi::Void};
+ #C1(args.{core::List::[]}(0){(core::int) → dynamic}){(ffi::Int32) → ffi::Void};
, "NativeCallable(ConstantExpression(printInt))");
[@vm.call-site-attributes.metadata=receiverType:dart.ffi::NativeCallable<dart.ffi::Void Function(dart.ffi::Int32)>] [@vm.direct-call.metadata=dart.ffi::_NativeCallableBase._pointer] #t1.{ffi::_NativeCallableBase::_pointer} = [@vm.inferred-type.metadata=dart.ffi::Pointer] ffi::_createNativeCallableListener<ffi::NativeFunction<(ffi::Int32) → ffi::Void>>(ffi::_nativeAsyncCallbackFunction<(ffi::Int32) → ffi::Void>(), [@vm.direct-call.metadata=dart.ffi::_NativeCallableListener._port] [@vm.inferred-type.metadata=dart.isolate::_RawReceivePort] #t1.{ffi::_NativeCallableListener::_port}{iso::RawReceivePort});
} =>#t1;
@@ -31,10 +31,10 @@
[@vm.closure-id=2]static method testNativeCallableListenerClosure() → void {
[@vm.inferred-type.metadata=dart.core::_Smi (value: 123)] core::int j = 123;
[@vm.closure-id=1] function closure(core::int i) → void
- return [@vm.inferred-type.metadata=dart.core::Null? (value: null)] core::print([@vm.direct-call.metadata=dart.core::_IntegerImplementation.+] [@vm.inferred-type.metadata=int (skip check)] i.{core::num::+}(j){(core::num) → core::int});
+ return core::print([@vm.direct-call.metadata=dart.core::_IntegerImplementation.+] [@vm.inferred-type.metadata=int (skip check)] i.{core::num::+}(j){(core::num) → core::int});
final ffi::NativeCallable<(ffi::Int32) → ffi::Void> callback = block {
final ffi::NativeCallable<(ffi::Int32) → ffi::Void> #t2 = new ffi::_NativeCallableListener::•<(ffi::Int32) → ffi::Void>([@vm.closure-id=2](final core::List<dynamic> args) → void
- [@vm.inferred-type.metadata=!? (receiver not int)] closure(args.{core::List::[]}(0){(core::int) → dynamic}){(ffi::Int32) → ffi::Void};
+ closure(args.{core::List::[]}(0){(core::int) → dynamic}){(ffi::Int32) → ffi::Void};
, "NativeCallable(VariableGetImpl(closure))");
[@vm.call-site-attributes.metadata=receiverType:dart.ffi::NativeCallable<dart.ffi::Void Function(dart.ffi::Int32)>] [@vm.direct-call.metadata=dart.ffi::_NativeCallableBase._pointer] #t2.{ffi::_NativeCallableBase::_pointer} = [@vm.inferred-type.metadata=dart.ffi::Pointer] ffi::_createNativeCallableListener<ffi::NativeFunction<(ffi::Int32) → ffi::Void>>(ffi::_nativeAsyncCallbackFunction<(ffi::Int32) → ffi::Void>(), [@vm.direct-call.metadata=dart.ffi::_NativeCallableListener._port] [@vm.inferred-type.metadata=dart.isolate::_RawReceivePort] #t2.{ffi::_NativeCallableListener::_port}{iso::RawReceivePort});
} =>#t2;
@@ -49,7 +49,7 @@
static method testNativeCallableIsolateLocalVoidClosure() → void {
[@vm.inferred-type.metadata=dart.core::_Smi (value: 123)] core::int j = 123;
function closure(core::int i) → void
- return [@vm.inferred-type.metadata=dart.core::Null? (value: null)] core::print([@vm.direct-call.metadata=dart.core::_IntegerImplementation.+] [@vm.inferred-type.metadata=int (skip check)] i.{core::num::+}(j){(core::num) → core::int});
+ return core::print([@vm.direct-call.metadata=dart.core::_IntegerImplementation.+] [@vm.inferred-type.metadata=int (skip check)] i.{core::num::+}(j){(core::num) → core::int});
final ffi::NativeCallable<(ffi::Int32) → ffi::Void> callback = new ffi::_NativeCallableIsolateLocal::•<(ffi::Int32) → ffi::Void>([@vm.inferred-type.metadata=dart.ffi::Pointer] ffi::_createNativeCallableIsolateLocal<ffi::NativeFunction<(ffi::Int32) → ffi::Void>>(ffi::_nativeIsolateLocalCallbackFunction<(ffi::Int32) → ffi::Void>(null), closure, true));
core::print([@vm.direct-call.metadata=dart.ffi::_NativeCallableBase.nativeFunction] [@vm.inferred-type.metadata=dart.ffi::Pointer] callback.{ffi::NativeCallable::nativeFunction}{ffi::Pointer<ffi::NativeFunction<(ffi::Int32) → ffi::Void>>});
[@vm.direct-call.metadata=dart.ffi::_NativeCallableBase.close] [@vm.inferred-type.metadata=!? (skip check)] callback.{ffi::NativeCallable::close}(){() → void};
@@ -64,7 +64,7 @@
static method testNativeCallableIsolateLocalPointerClosure() → void {
[@vm.inferred-type.metadata=dart.core::_Smi (value: 123)] core::int j = 123;
function closure(core::int i) → ffi::Pointer<ffi::NativeType>
- return [@vm.inferred-type.metadata=dart.ffi::Pointer] ffi::Pointer::fromAddress<ffi::NativeType>([@vm.direct-call.metadata=dart.core::_IntegerImplementation.+] [@vm.inferred-type.metadata=int (skip check)] i.{core::num::+}(j){(core::num) → core::int});
+ return ffi::Pointer::fromAddress<ffi::NativeType>([@vm.direct-call.metadata=dart.core::_IntegerImplementation.+] [@vm.inferred-type.metadata=int (skip check)] i.{core::num::+}(j){(core::num) → core::int});
final ffi::NativeCallable<(ffi::Int32) → ffi::Pointer<ffi::NativeType>> callback = new ffi::_NativeCallableIsolateLocal::•<(ffi::Int32) → ffi::Pointer<ffi::NativeType>>([@vm.inferred-type.metadata=dart.ffi::Pointer] ffi::_createNativeCallableIsolateLocal<ffi::NativeFunction<(ffi::Int32) → ffi::Pointer<ffi::NativeType>>>(ffi::_nativeIsolateLocalCallbackFunction<(ffi::Int32) → ffi::Pointer<ffi::NativeType>>(null), closure, true));
core::print([@vm.direct-call.metadata=dart.ffi::_NativeCallableBase.nativeFunction] [@vm.inferred-type.metadata=dart.ffi::Pointer] callback.{ffi::NativeCallable::nativeFunction}{ffi::Pointer<ffi::NativeFunction<(ffi::Int32) → ffi::Pointer<ffi::NativeType>>>});
[@vm.direct-call.metadata=dart.ffi::_NativeCallableBase.close] [@vm.inferred-type.metadata=!? (skip check)] callback.{ffi::NativeCallable::close}(){() → void};
@@ -79,7 +79,7 @@
static method testNativeCallableIsolateLocalIntClosure() → void {
[@vm.inferred-type.metadata=dart.core::_Smi (value: 123)] core::int j = 123;
function closure(core::int i) → core::int
- return [@vm.direct-call.metadata=dart.core::_IntegerImplementation.+] [@vm.inferred-type.metadata=int (skip check)] i.{core::num::+}(j){(core::num) → core::int};
+ return [@vm.direct-call.metadata=dart.core::_IntegerImplementation.+] [@vm.inferred-type.metadata=!? (skip check)] i.{core::num::+}(j){(core::num) → core::int};
final ffi::NativeCallable<(ffi::Int32) → ffi::Int> callback = new ffi::_NativeCallableIsolateLocal::•<(ffi::Int32) → ffi::Int>([@vm.inferred-type.metadata=dart.ffi::Pointer] ffi::_createNativeCallableIsolateLocal<ffi::NativeFunction<(ffi::Int32) → ffi::Int>>(ffi::_nativeIsolateLocalCallbackFunction<(ffi::Int32) → ffi::Int>(123), closure, true));
core::print([@vm.direct-call.metadata=dart.ffi::_NativeCallableBase.nativeFunction] [@vm.inferred-type.metadata=dart.ffi::Pointer] callback.{ffi::NativeCallable::nativeFunction}{ffi::Pointer<ffi::NativeFunction<(ffi::Int32) → ffi::Int>>});
[@vm.direct-call.metadata=dart.ffi::_NativeCallableBase.close] [@vm.inferred-type.metadata=!? (skip check)] callback.{ffi::NativeCallable::close}(){() → void};
diff --git a/pkg/vm/testcases/transformations/type_flow/summary_collector/control_flow.dart.expect b/pkg/vm/testcases/transformations/type_flow/summary_collector/control_flow.dart.expect
index fa61e57..8b1072d 100644
--- a/pkg/vm/testcases/transformations/type_flow/summary_collector/control_flow.dart.expect
+++ b/pkg/vm/testcases/transformations/type_flow/summary_collector/control_flow.dart.expect
@@ -286,27 +286,20 @@
write x = t0
t2 = read x
t3 = _Call direct [#lib::foo] (t2)
-t4 = _Call direct [#lib::foo] (_T (dart.core::_Closure, <anonymous closure at control_flow.dart:268>))
-t5* = _Call direct [#lib::C2.] (_T (#lib::C2))
-write x = t5
-RESULT: _T {}?
------------- <anonymous closure at control_flow.dart:268> ------------
-%#closure = _Parameter #0 [_T ANY?]
-t1 = read x
-t2 = _Call direct [#lib::bar] (t1)
+t4 = _Call direct [#lib::bar] (t2)
+t5 = _Call direct [#lib::foo] (_T (dart.core::_Closure, <anonymous closure at control_flow.dart:268>))
+t6* = _Call direct [#lib::C2.] (_T (#lib::C2))
+write x = t6
RESULT: _T {}?
------------ closure2 ------------
t0* = _Call direct [#lib::C1.] (_T (#lib::C1))
write x = t0
t2 = read x
t3 = _Call direct [#lib::foo] (t2)
-t4 = _Call direct [#lib::foo] (_T (dart.core::_Closure, <anonymous closure at control_flow.dart:277>))
+t4* = _Call direct [#lib::C2.] (_T (#lib::C2))
+write x = t4
+t6 = _Call direct [#lib::foo] (_T (dart.core::_Closure, <anonymous closure at control_flow.dart:277>))
RESULT: t2
------------- <anonymous closure at control_flow.dart:277> ------------
-%#closure = _Parameter #0 [_T ANY?]
-t1* = _Call direct [#lib::C2.] (_T (#lib::C2))
-write x = t1
-RESULT: _T {}?
------------ switch1 ------------
%selector = _Parameter #0 [_T (dart.core::int)+]
t1* = _Call direct [#lib::C1.] (_T (#lib::C1))
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/closures.dart.expect b/pkg/vm/testcases/transformations/type_flow/transformer/closures.dart.expect
index c29fb80..ff0026d 100644
--- a/pkg/vm/testcases/transformations/type_flow/transformer/closures.dart.expect
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/closures.dart.expect
@@ -20,7 +20,7 @@
: self::UseClosure31::func = func, super core::Object::•()
;
[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:4,getterSelectorId:5] method use() → void {
- let final core::int #t1 = 42 in [@vm.inferred-type.metadata=!? (receiver not int)] [@vm.direct-call.metadata=#lib::UseClosure31.func] [@vm.inferred-type.metadata=dart.core::_Closure (closure 1 in #lib::createClosure1)] this.{self::UseClosure31::func}{(dynamic) → void}(#t1){(dynamic) → void};
+ let final core::int #t1 = 42 in [@vm.direct-call.metadata=#lib::UseClosure31.func] this.{self::UseClosure31::func}{(dynamic) → void}(#t1){(dynamic) → void};
}
}
class UseClosure32 extends core::Object {
@@ -29,7 +29,7 @@
: self::UseClosure32::func = func, super core::Object::•()
;
[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:7,getterSelectorId:8] method use() → void {
- let final core::int #t2 = 42 in [@vm.inferred-type.metadata=!? (receiver not int)] [@vm.direct-call.metadata=#lib::UseClosure32.func] [@vm.inferred-type.metadata=dart.core::_Closure (closure 1 in #lib::createClosure2)] this.{self::UseClosure32::func}{(dynamic) → void}(#t2){(dynamic) → void};
+ let final core::int #t2 = 42 in [@vm.direct-call.metadata=#lib::UseClosure32.func] this.{self::UseClosure32::func}{(dynamic) → void}(#t2){(dynamic) → void};
}
}
class UseClosure33 extends core::Object {
@@ -38,7 +38,7 @@
: self::UseClosure33::func = func, super core::Object::•()
;
[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:10,getterSelectorId:11] method use() → void {
- let final core::int #t3 = 42 in [@vm.inferred-type.metadata=!? (receiver not int)] [@vm.direct-call.metadata=#lib::UseClosure33.func] [@vm.inferred-type.metadata=dart.core::_Closure (closure 0 in #lib::C.instanceMethod)] this.{self::UseClosure33::func}{(dynamic) → void}(#t3){(dynamic) → void};
+ let final core::int #t3 = 42 in [@vm.direct-call.metadata=#lib::UseClosure33.func] this.{self::UseClosure33::func}{(dynamic) → void}(#t3){(dynamic) → void};
}
}
class UseClosure34 extends core::Object {
@@ -47,7 +47,7 @@
: self::UseClosure34::func = #C1, super core::Object::•()
;
[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:13,getterSelectorId:14] method use() → void {
- let final core::int #t4 = 42 in [@vm.inferred-type.metadata=!? (receiver not int)] [@vm.direct-call.metadata=#lib::UseClosure34.func] [@vm.inferred-type.metadata=dart.core::_Closure (value: #lib::C.staticMethod) (closure 0 in #lib::C.staticMethod)] this.{self::UseClosure34::func}{(dynamic) → void}(#t4){(dynamic) → void};
+ let final core::int #t4 = 42 in [@vm.direct-call.metadata=#lib::UseClosure34.func] this.{self::UseClosure34::func}{(dynamic) → void}(#t4){(dynamic) → void};
}
}
class UseClosure35 extends core::Object {
@@ -56,11 +56,11 @@
: self::UseClosure35::func = #C2, super core::Object::•()
;
[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:16,getterSelectorId:17] method use() → void {
- let final core::int #t5 = 42 in [@vm.inferred-type.metadata=!? (receiver not int)] [@vm.direct-call.metadata=#lib::UseClosure35.func] [@vm.inferred-type.metadata=dart.core::_Closure (value: #lib::C.) (closure 0 in #lib::C.)] this.{self::UseClosure35::func}{(dynamic) → void}(#t5){(dynamic) → void};
+ let final core::int #t5 = 42 in [@vm.direct-call.metadata=#lib::UseClosure35.func] this.{self::UseClosure35::func}{(dynamic) → void}(#t5){(dynamic) → void};
}
}
[@vm.closure-id=1]static method createClosure1() → dynamic
- return [@vm.closure-id=1](dynamic arg) → void => [@vm.inferred-type.metadata=dart.core::Null? (value: null)] core::print(arg);
+ return [@vm.closure-id=1](dynamic arg) → void => core::print(arg);
[@vm.closure-id=1]static method createClosure2() → dynamic {
[@vm.closure-id=1] function inner(dynamic arg) → void {
core::print(arg);
@@ -74,19 +74,19 @@
static method createClosure5() → dynamic
return #C2;
static method useClosure11([@vm.inferred-arg-type.metadata=dart.core::_Closure (closure 1 in #lib::createClosure1)] (dynamic) → void func) → void {
- [@vm.inferred-type.metadata=!? (receiver not int)] func(42){(dynamic) → void};
+ func(42){(dynamic) → void};
}
static method useClosure12([@vm.inferred-arg-type.metadata=dart.core::_Closure (closure 1 in #lib::createClosure2)] (dynamic) → void func) → void {
- [@vm.inferred-type.metadata=!? (receiver not int)] func(42){(dynamic) → void};
+ func(42){(dynamic) → void};
}
static method useClosure13([@vm.inferred-arg-type.metadata=dart.core::_Closure (closure 0 in #lib::C.instanceMethod)] (dynamic) → void func) → void {
- [@vm.inferred-type.metadata=!? (receiver not int)] func(42){(dynamic) → void};
+ func(42){(dynamic) → void};
}
static method useClosure14() → void {
- [@vm.inferred-type.metadata=!? (receiver not int)] #C1(42){(dynamic) → void};
+ #C1(42){(dynamic) → void};
}
static method useClosure15() → void {
- [@vm.inferred-type.metadata=!? (receiver not int)] #C2(42){(dynamic) → void};
+ #C2(42){(dynamic) → void};
}
static method useClosure21([@vm.inferred-arg-type.metadata=dart.core::_Closure (closure 1 in #lib::createClosure1)] dynamic func) → void {
[@vm.inferred-type.metadata=!? (receiver not int)] func{dynamic}.call(42);
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/extension_type.dart.expect b/pkg/vm/testcases/transformations/type_flow/transformer/extension_type.dart.expect
index be27bcf..4ab2f92 100644
--- a/pkg/vm/testcases/transformations/type_flow/transformer/extension_type.dart.expect
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/extension_type.dart.expect
@@ -43,7 +43,7 @@
return #this;
}
static method testTypeCheckRemoval() → void {
- final core::List<self::SomeExtensionType% /* = core::int */> list = [@vm.inferred-type.metadata=dart.core::_GrowableList<dart.core::int>] core::_GrowableList::generate<self::SomeExtensionType% /* = core::int */>(10, (final core::int a) → self::SomeExtensionType /* = core::int */ => [@vm.inferred-type.metadata=int] self::SomeExtensionType|constructor#(a));
+ final core::List<self::SomeExtensionType% /* = core::int */> list = [@vm.inferred-type.metadata=dart.core::_GrowableList<dart.core::int>] core::_GrowableList::generate<self::SomeExtensionType% /* = core::int */>(10, (final core::int a) → self::SomeExtensionType /* = core::int */ => self::SomeExtensionType|constructor#(a));
final self::Run<self::SomeExtensionType% /* = core::int */> obj = new self::Run::•<self::SomeExtensionType /* = core::int */>();
[@vm.call-site-attributes.metadata=receiverType:#lib::Run<#lib::SomeExtensionType%>] [@vm.direct-call.metadata=#lib::Run.execute] [@vm.inferred-type.metadata=!? (skip check)] obj.{self::Run::execute}(list){(core::List<self::SomeExtensionType% /* = core::int */>) → void};
}
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/ffi_struct_constructors.dart.expect b/pkg/vm/testcases/transformations/type_flow/transformer/ffi_struct_constructors.dart.expect
index 14b6961..3f41441 100644
--- a/pkg/vm/testcases/transformations/type_flow/transformer/ffi_struct_constructors.dart.expect
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/ffi_struct_constructors.dart.expect
@@ -71,10 +71,10 @@
[@vm.inferred-type.metadata=dart.ffi::Pointer] synthesized ffi::Pointer<ffi::NativeFunction<() → self::Struct1>> #ffiTarget0 = [@vm.direct-call.metadata=dart.ffi::DynamicLibrary.lookup] [@vm.inferred-type.metadata=dart.ffi::Pointer (skip check)] dylib.{ffi::DynamicLibrary::lookup}<ffi::NativeFunction<() → self::Struct1>>("function1"){(core::String) → ffi::Pointer<ffi::NativeFunction<() → self::Struct1>>};
@#C22
function #ffiClosure0() → self::Struct1 {
- return [@vm.inferred-type.metadata=#lib::Struct1] ffi::_ffiCall<self::Struct1>(#ffiTarget0);
+ return ffi::_ffiCall<self::Struct1>(#ffiTarget0);
}
} =>#ffiClosure0;
- final self::Struct1 struct1 = [@vm.inferred-type.metadata=#lib::Struct1 (receiver not int)] function1(){() → self::Struct1};
+ final self::Struct1 struct1 = function1(){() → self::Struct1};
core::print(struct1);
}
static method testAsFunctionReturn() → void {
@@ -85,10 +85,10 @@
[@vm.inferred-type.metadata=dart.ffi::Pointer] synthesized ffi::Pointer<ffi::NativeFunction<() → self::Struct2>> #ffiTarget1 = pointer;
@#C24
function #ffiClosure1() → self::Struct2 {
- return [@vm.inferred-type.metadata=#lib::Struct2] ffi::_ffiCall<self::Struct2>(#ffiTarget1);
+ return ffi::_ffiCall<self::Struct2>(#ffiTarget1);
}
} =>#ffiClosure1;
- final self::Struct2 struct2 = [@vm.inferred-type.metadata=#lib::Struct2 (receiver not int)] function2(){() → self::Struct2};
+ final self::Struct2 struct2 = function2(){() → self::Struct2};
core::print(struct2);
}
[@vm.unboxing-info.metadata=(b)->i]static method useStruct3(self::Struct3 struct3) → core::int {
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/future_or.dart.expect b/pkg/vm/testcases/transformations/type_flow/transformer/future_or.dart.expect
index f06d2d5..be538ac 100644
--- a/pkg/vm/testcases/transformations/type_flow/transformer/future_or.dart.expect
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/future_or.dart.expect
@@ -2,7 +2,6 @@
import self as self;
import "dart:core" as core;
import "dart:async" as asy;
-import "dart:_internal" as _in;
import "dart:async";
@@ -18,7 +17,7 @@
}
static field dynamic usedObject;
[@vm.inferred-type.metadata=!]late static field core::Function unknown;
-static method use([@vm.inferred-arg-type.metadata=!] dynamic object) → void {
+static method use(dynamic object) → void {
self::usedObject == null ?{dynamic} self::usedObject = object : null;
}
static method foo1_a1([@vm.inferred-arg-type.metadata=dart.async::_Future<#lib::B>] dynamic x) → void {
@@ -39,16 +38,27 @@
self::foo1_a3(a3);
self::foo1_a4(a4);
}
+static method foo2_a1([@vm.inferred-arg-type.metadata=dart.async::_Future?] dynamic x) → void {
+ self::use(x);
+}
+static method foo2_a2([@vm.inferred-arg-type.metadata=#lib::B?] dynamic x) → void {
+ self::use(x);
+}
+static method foo2_a3(dynamic x) → void {
+ self::use(x);
+}
+static method foo2_a4(dynamic x) → void {
+ self::use(x);
+}
+static method foo2([@vm.inferred-arg-type.metadata=dart.async::_Future?] asy::Future<self::A>? a1, [@vm.inferred-arg-type.metadata=#lib::B?] self::A? a2, FutureOr<self::A>? a3, FutureOr<self::A>? a4) → void {
+ self::foo2_a1(a1);
+ self::foo2_a2(a2);
+ self::foo2_a3(a3);
+ self::foo2_a4(a4);
+}
static method getDynamic() → dynamic
- return block {
- [@vm.inferred-type.metadata=!] self::unknown;
- } =>throw "Attempt to execute code removed by Dart AOT compiler (TFA)";
+ return self::unknown();
static method main(core::List<core::String> args) → dynamic {
self::foo1([@vm.inferred-type.metadata=dart.async::_Future<#lib::B>] asy::Future::value<self::B>(new self::B::•()), new self::B::•(), [@vm.inferred-type.metadata=dart.async::_Future<#lib::B>] asy::Future::value<self::B>(new self::B::•()), new self::B::•());
- block {
- _in::unsafeCast<asy::Future<self::A>?>([@vm.inferred-type.metadata=!] self::getDynamic());
- _in::unsafeCast<self::A?>([@vm.inferred-type.metadata=!] self::getDynamic());
- _in::unsafeCast<FutureOr<self::A>?>([@vm.inferred-type.metadata=!] self::getDynamic());
- _in::unsafeCast<FutureOr<self::A>?>([@vm.inferred-type.metadata=!] self::getDynamic());
- } =>throw "Attempt to execute code removed by Dart AOT compiler (TFA)";
+ self::foo2(self::getDynamic() as{TypeError,ForDynamic} asy::Future<self::A>?, self::getDynamic() as{TypeError,ForDynamic} self::A?, self::getDynamic() as{TypeError,ForDynamic} FutureOr<self::A>?, self::getDynamic() as{TypeError,ForDynamic} FutureOr<self::A>?);
}
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/invalidation_field_initializer.dart.expect b/pkg/vm/testcases/transformations/type_flow/transformer/invalidation_field_initializer.dart.expect
index f69240c..77f3fee 100644
--- a/pkg/vm/testcases/transformations/type_flow/transformer/invalidation_field_initializer.dart.expect
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/invalidation_field_initializer.dart.expect
@@ -1,67 +1,73 @@
library #lib;
import self as self;
import "dart:core" as core;
-import "dart:_internal" as _in;
class T1 extends core::Object {
+ synthetic constructor •() → self::T1
+ : super core::Object::•()
+ ;
}
class T2 extends core::Object {
+ synthetic constructor •() → self::T2
+ : super core::Object::•()
+ ;
}
abstract class A extends core::Object {
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:1,getterSelectorId:2] abstract method foo() → core::Object;
}
class B extends core::Object implements self::A {
synthetic constructor •() → self::B
: super core::Object::•()
;
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:1,getterSelectorId:2] method foo() → core::Object
+ return new self::T1::•();
}
class C extends core::Object implements self::A {
synthetic constructor •() → self::C
: super core::Object::•()
;
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:1,getterSelectorId:2] method foo() → core::Object
+ return new self::T2::•();
}
class DeepCaller1 extends core::Object {
synthetic constructor •() → self::DeepCaller1
: super core::Object::•()
;
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:1,getterSelectorId:2] method barL1() → dynamic
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:3,getterSelectorId:4] method barL1() → dynamic
return [@vm.direct-call.metadata=#lib::DeepCaller1.barL2] [@vm.inferred-type.metadata=! (skip check)] this.{self::DeepCaller1::barL2}(){() → dynamic};
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasNonThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:3,getterSelectorId:4] method barL2() → dynamic
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasNonThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:5,getterSelectorId:6] method barL2() → dynamic
return [@vm.direct-call.metadata=#lib::DeepCaller1.barL3] [@vm.inferred-type.metadata=! (skip check)] this.{self::DeepCaller1::barL3}(){() → dynamic};
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasNonThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:5,getterSelectorId:6] method barL3() → dynamic
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasNonThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:7,getterSelectorId:8] method barL3() → dynamic
return [@vm.direct-call.metadata=#lib::DeepCaller1.barL4] [@vm.inferred-type.metadata=! (skip check)] this.{self::DeepCaller1::barL4}(){() → dynamic};
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasNonThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:7,getterSelectorId:8] method barL4() → dynamic
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasNonThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:9,getterSelectorId:10] method barL4() → dynamic
return [@vm.inferred-type.metadata=!] self::field1;
}
class D extends core::Object {
-[@vm.inferred-type.metadata=!] [@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:9,getterSelectorId:10] field core::Object field2;
+[@vm.inferred-type.metadata=!] [@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:11,getterSelectorId:12] field core::Object field2;
synthetic constructor •() → self::D
- : dynamic #t1 = block {
- [@vm.inferred-type.metadata=!] self::getValue();
- } =>throw "Attempt to execute code removed by Dart AOT compiler (TFA)", super core::Object::•()
+ : self::D::field2 = [@vm.inferred-type.metadata=!] self::getValue(), super core::Object::•()
;
}
class DeepCaller2 extends core::Object {
synthetic constructor •() → self::DeepCaller2
: super core::Object::•()
;
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:11,getterSelectorId:12] method barL1([@vm.inferred-arg-type.metadata=#lib::D] self::D dd) → dynamic
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:13,getterSelectorId:14] method barL1([@vm.inferred-arg-type.metadata=#lib::D] self::D dd) → dynamic
return [@vm.direct-call.metadata=#lib::DeepCaller2.barL2] [@vm.inferred-type.metadata=! (skip check)] this.{self::DeepCaller2::barL2}(dd){(self::D) → dynamic};
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasNonThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:13,getterSelectorId:14] method barL2([@vm.inferred-arg-type.metadata=#lib::D] self::D dd) → dynamic
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasNonThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:15,getterSelectorId:16] method barL2([@vm.inferred-arg-type.metadata=#lib::D] self::D dd) → dynamic
return [@vm.direct-call.metadata=#lib::DeepCaller2.barL3] [@vm.inferred-type.metadata=! (skip check)] this.{self::DeepCaller2::barL3}(dd){(self::D) → dynamic};
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasNonThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:15,getterSelectorId:16] method barL3([@vm.inferred-arg-type.metadata=#lib::D] self::D dd) → dynamic
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasNonThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:17,getterSelectorId:18] method barL3([@vm.inferred-arg-type.metadata=#lib::D] self::D dd) → dynamic
return [@vm.direct-call.metadata=#lib::DeepCaller2.barL4] [@vm.inferred-type.metadata=! (skip check)] this.{self::DeepCaller2::barL4}(dd){(self::D) → dynamic};
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasNonThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:17,getterSelectorId:18] method barL4([@vm.inferred-arg-type.metadata=#lib::D] self::D dd) → dynamic
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasNonThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:19,getterSelectorId:20] method barL4([@vm.inferred-arg-type.metadata=#lib::D] self::D dd) → dynamic
return [@vm.direct-call.metadata=#lib::D.field2] [@vm.inferred-type.metadata=!] dd.{self::D::field2}{core::Object};
}
[@vm.inferred-type.metadata=!]late static field core::Function unknown;
[@vm.inferred-type.metadata=!]static field core::Object field1 = [@vm.inferred-type.metadata=!] self::getValue();
static method getDynamic() → dynamic
- return block {
- [@vm.inferred-type.metadata=!] self::unknown;
- } =>throw "Attempt to execute code removed by Dart AOT compiler (TFA)";
+ return self::unknown();
static method getValue() → core::Object {
- self::A aa = _in::unsafeCast<self::A>([@vm.inferred-type.metadata=!] self::getDynamic());
- return throw "Attempt to execute code removed by Dart AOT compiler (TFA)";
+ self::A aa = self::getDynamic() as{TypeError,ForDynamic} self::A;
+ return [@vm.inferred-type.metadata=!] aa.{self::A::foo}(){() → core::Object};
}
static method use1([@vm.inferred-arg-type.metadata=#lib::DeepCaller1] self::DeepCaller1 x) → dynamic
return [@vm.direct-call.metadata=#lib::DeepCaller1.barL1] [@vm.inferred-type.metadata=! (skip check)] x.{self::DeepCaller1::barL1}(){() → dynamic};
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/invalidation_new_class1.dart.expect b/pkg/vm/testcases/transformations/type_flow/transformer/invalidation_new_class1.dart.expect
index f24f63e..63f534e 100644
--- a/pkg/vm/testcases/transformations/type_flow/transformer/invalidation_new_class1.dart.expect
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/invalidation_new_class1.dart.expect
@@ -1,41 +1,44 @@
library #lib;
import self as self;
import "dart:core" as core;
-import "dart:_internal" as _in;
class T1 extends core::Object {
+ synthetic constructor •() → self::T1
+ : super core::Object::•()
+ ;
}
abstract class A extends core::Object {
synthetic constructor •() → self::A
: super core::Object::•()
;
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:1,getterSelectorId:2] abstract method foo() → dynamic;
}
class B extends self::A {
synthetic constructor •() → self::B
: super self::A::•()
;
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:1,getterSelectorId:2] method foo() → dynamic
+ return new self::T1::•();
}
class Intermediate extends core::Object {
synthetic constructor •() → self::Intermediate
: super core::Object::•()
;
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:3,getterSelectorId:4] method bar([@vm.inferred-arg-type.metadata=#lib::B] self::A aa) → dynamic
+ return [@vm.direct-call.metadata=#lib::B.foo] [@vm.inferred-type.metadata=#lib::T1 (skip check)] aa.{self::A::foo}(){() → dynamic};
}
[@vm.inferred-type.metadata=!]late static field core::Function unknown;
+static method use1([@vm.inferred-arg-type.metadata=#lib::Intermediate] self::Intermediate i, [@vm.inferred-arg-type.metadata=#lib::B] self::A aa) → dynamic
+ return [@vm.direct-call.metadata=#lib::Intermediate.bar] [@vm.inferred-type.metadata=#lib::T1 (skip check)] i.{self::Intermediate::bar}(aa){(self::A) → dynamic};
+static method use2([@vm.inferred-arg-type.metadata=#lib::Intermediate] self::Intermediate i, [@vm.inferred-arg-type.metadata=#lib::B] self::A aa) → dynamic
+ return [@vm.direct-call.metadata=#lib::Intermediate.bar] [@vm.inferred-type.metadata=#lib::T1 (skip check)] i.{self::Intermediate::bar}(aa){(self::A) → dynamic};
static method getDynamic() → dynamic
- return block {
- [@vm.inferred-type.metadata=!] self::unknown;
- } =>throw "Attempt to execute code removed by Dart AOT compiler (TFA)";
+ return self::unknown();
static method allocateB() → dynamic {
new self::B::•();
}
static method main(core::List<core::String> args) → dynamic {
- block {
- new self::Intermediate::•();
- _in::unsafeCast<self::A>([@vm.inferred-type.metadata=!] self::getDynamic());
- } =>throw "Attempt to execute code removed by Dart AOT compiler (TFA)";
+ self::use1(new self::Intermediate::•(), self::getDynamic() as{TypeError,ForDynamic} self::A);
self::allocateB();
- block {
- new self::Intermediate::•();
- _in::unsafeCast<self::A>([@vm.inferred-type.metadata=!] self::getDynamic());
- } =>throw "Attempt to execute code removed by Dart AOT compiler (TFA)";
+ self::use2(new self::Intermediate::•(), self::getDynamic() as{TypeError,ForDynamic} self::A);
}
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/invalidation_new_class2.dart.expect b/pkg/vm/testcases/transformations/type_flow/transformer/invalidation_new_class2.dart.expect
index 00c744c..99934ba 100644
--- a/pkg/vm/testcases/transformations/type_flow/transformer/invalidation_new_class2.dart.expect
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/invalidation_new_class2.dart.expect
@@ -1,21 +1,29 @@
library #lib;
import self as self;
import "dart:core" as core;
-import "dart:_internal" as _in;
class T1 extends core::Object {
+ synthetic constructor •() → self::T1
+ : super core::Object::•()
+ ;
}
class T2 extends core::Object {
+ synthetic constructor •() → self::T2
+ : super core::Object::•()
+ ;
}
abstract class A extends core::Object {
synthetic constructor •() → self::A
: super core::Object::•()
;
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:1,getterSelectorId:2] abstract method foo() → dynamic;
}
class B extends self::A {
synthetic constructor •() → self::B
: super self::A::•()
;
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:1,getterSelectorId:2] method foo() → dynamic
+ return new self::T1::•();
}
abstract class C extends core::Object implements self::B /*isMixinDeclaration*/ {
}
@@ -33,17 +41,25 @@
synthetic constructor •() → self::E
: super self::_E&D&C::•()
;
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:1,getterSelectorId:2] method foo() → dynamic
+ return new self::T2::•();
}
class Intermediate extends core::Object {
synthetic constructor •() → self::Intermediate
: super core::Object::•()
;
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:3,getterSelectorId:4] method bar([@vm.inferred-arg-type.metadata=!] self::A aa) → dynamic
+ return [@vm.inferred-type.metadata=!] aa.{self::A::foo}(){() → dynamic};
}
[@vm.inferred-type.metadata=!]late static field core::Function unknown;
+static method use1([@vm.inferred-arg-type.metadata=#lib::Intermediate] self::Intermediate i, [@vm.inferred-arg-type.metadata=!] self::A aa) → dynamic
+ return [@vm.direct-call.metadata=#lib::Intermediate.bar] [@vm.inferred-type.metadata=! (skip check)] i.{self::Intermediate::bar}(aa){(self::A) → dynamic};
+static method use2([@vm.inferred-arg-type.metadata=#lib::Intermediate] self::Intermediate i, [@vm.inferred-arg-type.metadata=!] self::A aa) → dynamic
+ return [@vm.direct-call.metadata=#lib::Intermediate.bar] [@vm.inferred-type.metadata=! (skip check)] i.{self::Intermediate::bar}(aa){(self::A) → dynamic};
+static method use3([@vm.inferred-arg-type.metadata=#lib::Intermediate] self::Intermediate i, [@vm.inferred-arg-type.metadata=!] self::A aa) → dynamic
+ return [@vm.direct-call.metadata=#lib::Intermediate.bar] [@vm.inferred-type.metadata=! (skip check)] i.{self::Intermediate::bar}(aa){(self::A) → dynamic};
static method getDynamic() → dynamic
- return block {
- [@vm.inferred-type.metadata=!] self::unknown;
- } =>throw "Attempt to execute code removed by Dart AOT compiler (TFA)";
+ return self::unknown();
static method allocateB() → dynamic {
new self::B::•();
}
@@ -51,18 +67,9 @@
new self::E::•();
}
static method main(core::List<core::String> args) → dynamic {
- block {
- new self::Intermediate::•();
- _in::unsafeCast<self::A>([@vm.inferred-type.metadata=!] self::getDynamic());
- } =>throw "Attempt to execute code removed by Dart AOT compiler (TFA)";
+ self::use1(new self::Intermediate::•(), self::getDynamic() as{TypeError,ForDynamic} self::A);
self::allocateB();
- block {
- new self::Intermediate::•();
- _in::unsafeCast<self::A>([@vm.inferred-type.metadata=!] self::getDynamic());
- } =>throw "Attempt to execute code removed by Dart AOT compiler (TFA)";
+ self::use2(new self::Intermediate::•(), self::getDynamic() as{TypeError,ForDynamic} self::A);
self::allocateE();
- block {
- new self::Intermediate::•();
- _in::unsafeCast<self::A>([@vm.inferred-type.metadata=!] self::getDynamic());
- } =>throw "Attempt to execute code removed by Dart AOT compiler (TFA)";
+ self::use3(new self::Intermediate::•(), self::getDynamic() as{TypeError,ForDynamic} self::A);
}
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/invalidation_new_dynamic_target.dart.expect b/pkg/vm/testcases/transformations/type_flow/transformer/invalidation_new_dynamic_target.dart.expect
index 91ba46c..dacc785 100644
--- a/pkg/vm/testcases/transformations/type_flow/transformer/invalidation_new_dynamic_target.dart.expect
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/invalidation_new_dynamic_target.dart.expect
@@ -3,26 +3,53 @@
import "dart:core" as core;
class T1 extends core::Object {
+ synthetic constructor •() → self::T1
+ : super core::Object::•()
+ ;
}
class T2 extends core::Object {
+ synthetic constructor •() → self::T2
+ : super core::Object::•()
+ ;
}
class T3 extends core::Object {
+ synthetic constructor •() → self::T3
+ : super core::Object::•()
+ ;
}
class A extends core::Object {
synthetic constructor •() → self::A
: super core::Object::•()
;
+[@vm.procedure-attributes.metadata=getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:1,getterSelectorId:2] method foo() → dynamic
+ return new self::T1::•();
+[@vm.procedure-attributes.metadata=getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:3,getterSelectorId:4] method bar() → dynamic
+ return new self::T2::•();
+[@vm.procedure-attributes.metadata=getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:5,getterSelectorId:6] method bazz() → dynamic
+ return new self::T3::•();
}
class B extends core::Object {
synthetic constructor •() → self::B
: super core::Object::•()
;
+[@vm.procedure-attributes.metadata=getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:7,getterSelectorId:8] method foo() → dynamic
+ return new self::T1::•();
+[@vm.procedure-attributes.metadata=getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:9,getterSelectorId:10] method bar() → dynamic
+ return new self::T2::•();
+[@vm.procedure-attributes.metadata=getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:11,getterSelectorId:12] method bazz() → dynamic
+ return new self::T3::•();
}
[@vm.inferred-type.metadata=!]late static field core::Function unknown;
+static method use_foo1(dynamic x) → dynamic
+ return [@vm.inferred-type.metadata=#lib::T1] x{dynamic}.foo();
+static method use_foo2(dynamic x) → dynamic
+ return [@vm.inferred-type.metadata=#lib::T1] x{dynamic}.foo();
+static method use_bar(dynamic x) → dynamic
+ return [@vm.inferred-type.metadata=#lib::T2] x{dynamic}.bar();
+static method use_bazz(dynamic x) → dynamic
+ return [@vm.inferred-type.metadata=#lib::T3] x{dynamic}.bazz();
static method getDynamic() → dynamic
- return block {
- [@vm.inferred-type.metadata=!] self::unknown;
- } =>throw "Attempt to execute code removed by Dart AOT compiler (TFA)";
+ return self::unknown();
static method allocateA() → dynamic {
new self::A::•();
}
@@ -30,18 +57,10 @@
new self::B::•();
}
static method main(core::List<core::String> args) → dynamic {
- block {
- [@vm.inferred-type.metadata=!] self::getDynamic();
- } =>throw "Attempt to execute code removed by Dart AOT compiler (TFA)";
+ self::use_foo1(self::getDynamic());
self::allocateA();
- block {
- [@vm.inferred-type.metadata=!] self::getDynamic();
- } =>throw "Attempt to execute code removed by Dart AOT compiler (TFA)";
- block {
- [@vm.inferred-type.metadata=!] self::getDynamic();
- } =>throw "Attempt to execute code removed by Dart AOT compiler (TFA)";
+ self::use_foo2(self::getDynamic());
+ self::use_bar(self::getDynamic());
self::allocateB();
- block {
- [@vm.inferred-type.metadata=!] self::getDynamic();
- } =>throw "Attempt to execute code removed by Dart AOT compiler (TFA)";
+ self::use_bazz(self::getDynamic());
}
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/invalidation_set_field.dart.expect b/pkg/vm/testcases/transformations/type_flow/transformer/invalidation_set_field.dart.expect
index 3f139da..cbce7e6 100644
--- a/pkg/vm/testcases/transformations/type_flow/transformer/invalidation_set_field.dart.expect
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/invalidation_set_field.dart.expect
@@ -1,7 +1,6 @@
library #lib;
import self as self;
import "dart:core" as core;
-import "dart:_internal" as _in;
class T1 extends core::Object {
synthetic constructor •() → self::T1
@@ -14,26 +13,45 @@
;
}
class A extends core::Object {
+[@vm.inferred-type.metadata=#lib::T1] [@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:1,getterSelectorId:2] field dynamic field1;
+[@vm.inferred-type.metadata=!] [@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:3,getterSelectorId:4] field dynamic field2;
synthetic constructor •() → self::A
- : dynamic #t1 = new self::T1::•(), dynamic #t2 = new self::T1::•(), super core::Object::•()
+ : self::A::field1 = new self::T1::•(), self::A::field2 = new self::T1::•(), super core::Object::•()
;
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:1] set /*isLegacy*/ field2(synthesized dynamic value) → void;
}
class DeepCaller1 extends core::Object {
synthetic constructor •() → self::DeepCaller1
: super core::Object::•()
;
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:5,getterSelectorId:6] method barL1([@vm.inferred-arg-type.metadata=#lib::A] self::A aa) → dynamic
+ return [@vm.direct-call.metadata=#lib::DeepCaller1.barL2] [@vm.inferred-type.metadata=#lib::T1 (skip check)] this.{self::DeepCaller1::barL2}(aa){(self::A) → dynamic};
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasNonThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:7,getterSelectorId:8] method barL2([@vm.inferred-arg-type.metadata=#lib::A] self::A aa) → dynamic
+ return [@vm.direct-call.metadata=#lib::DeepCaller1.barL3] [@vm.inferred-type.metadata=#lib::T1 (skip check)] this.{self::DeepCaller1::barL3}(aa){(self::A) → dynamic};
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasNonThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:9,getterSelectorId:10] method barL3([@vm.inferred-arg-type.metadata=#lib::A] self::A aa) → dynamic
+ return [@vm.direct-call.metadata=#lib::DeepCaller1.barL4] [@vm.inferred-type.metadata=#lib::T1 (skip check)] this.{self::DeepCaller1::barL4}(aa){(self::A) → dynamic};
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasNonThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:11,getterSelectorId:12] method barL4([@vm.inferred-arg-type.metadata=#lib::A] self::A aa) → dynamic
+ return [@vm.direct-call.metadata=#lib::A.field1] [@vm.inferred-type.metadata=#lib::T1] aa.{self::A::field1}{dynamic};
}
class DeepCaller2 extends core::Object {
synthetic constructor •() → self::DeepCaller2
: super core::Object::•()
;
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:13,getterSelectorId:14] method barL1([@vm.inferred-arg-type.metadata=#lib::A] self::A aa) → dynamic
+ return [@vm.direct-call.metadata=#lib::DeepCaller2.barL2] [@vm.inferred-type.metadata=! (skip check)] this.{self::DeepCaller2::barL2}(aa){(self::A) → dynamic};
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasNonThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:15,getterSelectorId:16] method barL2([@vm.inferred-arg-type.metadata=#lib::A] self::A aa) → dynamic
+ return [@vm.direct-call.metadata=#lib::DeepCaller2.barL3] [@vm.inferred-type.metadata=! (skip check)] this.{self::DeepCaller2::barL3}(aa){(self::A) → dynamic};
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasNonThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:17,getterSelectorId:18] method barL3([@vm.inferred-arg-type.metadata=#lib::A] self::A aa) → dynamic
+ return [@vm.direct-call.metadata=#lib::DeepCaller2.barL4] [@vm.inferred-type.metadata=! (skip check)] this.{self::DeepCaller2::barL4}(aa){(self::A) → dynamic};
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasNonThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:19,getterSelectorId:20] method barL4([@vm.inferred-arg-type.metadata=#lib::A] self::A aa) → dynamic
+ return [@vm.direct-call.metadata=#lib::A.field2] [@vm.inferred-type.metadata=!] aa.{self::A::field2}{dynamic};
}
[@vm.inferred-type.metadata=!]late static field core::Function unknown;
+static method use1([@vm.inferred-arg-type.metadata=#lib::DeepCaller1] self::DeepCaller1 x, [@vm.inferred-arg-type.metadata=#lib::A] self::A aa) → dynamic
+ return [@vm.direct-call.metadata=#lib::DeepCaller1.barL1] [@vm.inferred-type.metadata=#lib::T1 (skip check)] x.{self::DeepCaller1::barL1}(aa){(self::A) → dynamic};
+static method use2([@vm.inferred-arg-type.metadata=#lib::DeepCaller2] self::DeepCaller2 x, [@vm.inferred-arg-type.metadata=#lib::A] self::A aa) → dynamic
+ return [@vm.direct-call.metadata=#lib::DeepCaller2.barL1] [@vm.inferred-type.metadata=! (skip check)] x.{self::DeepCaller2::barL1}(aa){(self::A) → dynamic};
static method getDynamic() → dynamic
- return block {
- [@vm.inferred-type.metadata=!] self::unknown;
- } =>throw "Attempt to execute code removed by Dart AOT compiler (TFA)";
+ return self::unknown();
static method setField2([@vm.inferred-arg-type.metadata=#lib::A] self::A aa, [@vm.inferred-arg-type.metadata=#lib::T2] dynamic value) → void {
[@vm.direct-call.metadata=#lib::A.field2] [@vm.inferred-type.metadata=!? (skip check)] aa.{self::A::field2} = value;
}
@@ -41,13 +59,7 @@
new self::A::•();
new self::T1::•();
new self::T2::•();
- block {
- new self::DeepCaller1::•();
- _in::unsafeCast<self::A>([@vm.inferred-type.metadata=!] self::getDynamic());
- } =>throw "Attempt to execute code removed by Dart AOT compiler (TFA)";
- block {
- new self::DeepCaller2::•();
- _in::unsafeCast<self::A>([@vm.inferred-type.metadata=!] self::getDynamic());
- } =>throw "Attempt to execute code removed by Dart AOT compiler (TFA)";
+ self::use1(new self::DeepCaller1::•(), self::getDynamic() as{TypeError,ForDynamic} self::A);
+ self::use2(new self::DeepCaller2::•(), self::getDynamic() as{TypeError,ForDynamic} self::A);
self::setField2(new self::A::•(), new self::T2::•());
}
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/lists.dart.expect b/pkg/vm/testcases/transformations/type_flow/transformer/lists.dart.expect
index e4ea918..f7daf42 100644
--- a/pkg/vm/testcases/transformations/type_flow/transformer/lists.dart.expect
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/lists.dart.expect
@@ -26,7 +26,7 @@
[@vm.inferred-type.metadata=dart.core::_GrowableList<dart.core::int>] [@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,getterSelectorId:20] final field core::List<core::int> generateFactory6;
[@vm.inferred-type.metadata=dart.core::_List<dart.core::int>] [@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,getterSelectorId:21] final field core::List<core::int> generateFactory7;
[@vm.closure-id=7] synthetic constructor •() → self::A
- : self::A::literal1 = [@vm.inferred-type.metadata=dart.core::_GrowableList<dart.core::int>] core::_GrowableList::•<core::int>(0), self::A::literal2 = [@vm.inferred-type.metadata=dart.core::_GrowableList<dart.core::int>] core::_GrowableList::_literal3<core::int>(1, 2, 3), self::A::filledFactory1 = [@vm.inferred-type.metadata=dart.core::_List<dart.core::int>] core::_List::filled<core::int>(2, 0), self::A::filledFactory2 = [@vm.inferred-type.metadata=dart.core::_GrowableList<dart.core::int>] core::_GrowableList::filled<core::int>(2, 0), self::A::filledFactory3 = [@vm.inferred-type.metadata=dart.core::_List<dart.core::int>] core::_List::filled<core::int>(2, 0), self::A::filledFactory4 = let final core::bool #t1 = _in::unsafeCast<core::bool>([@vm.inferred-type.metadata=dart.core::bool] self::nonConstant()) in [@vm.inferred-type.metadata=!] core::List::filled<core::int>(2, 0, #t1), self::A::filledFactory5 = [@vm.inferred-type.metadata=dart.core::_List<dart.core::int?>] core::_List::•<core::int?>(2), self::A::filledFactory6 = [@vm.inferred-type.metadata=dart.core::_GrowableList<dart.core::int?>] core::_GrowableList::•<core::int?>(2), self::A::filledFactory7 = [@vm.inferred-type.metadata=dart.core::_List<dart.core::int?>] core::_List::•<core::int?>(2), self::A::filledFactory8 = let final core::bool #t2 = _in::unsafeCast<core::bool>([@vm.inferred-type.metadata=dart.core::bool] self::nonConstant()) in [@vm.inferred-type.metadata=!] core::List::filled<core::int?>(2, null, #t2), self::A::filledFactory9 = let final core::int #t3 = 2 in let final core::bool #t4 = true in [@vm.inferred-type.metadata=dart.core::_GrowableList<dart.core::int?>] core::_GrowableList::•<core::int?>(#t3), self::A::filledFactory10 = let final core::int #t5 = 2 in let final core::bool #t6 = false in [@vm.inferred-type.metadata=dart.core::_List<dart.core::int?>] core::_List::•<core::int?>(#t5), self::A::generateFactory1 = [@vm.inferred-type.metadata=dart.core::_GrowableList<dart.core::int>] core::_GrowableList::generate<core::int>(2, [@vm.closure-id=1](core::int i) → core::int => i), self::A::generateFactory2 = [@vm.inferred-type.metadata=dart.core::_GrowableList<dart.core::int>] core::_GrowableList::generate<core::int>(2, [@vm.closure-id=2](core::int i) → core::int => i), self::A::generateFactory3 = [@vm.inferred-type.metadata=dart.core::_List<dart.core::int>] core::_List::generate<core::int>([@vm.closure-id=3](core::int i) → core::int => i), self::A::generateFactory4 = let final (core::int) → core::int #t7 = [@vm.closure-id=4](core::int i) → core::int => i in let final core::bool #t8 = _in::unsafeCast<core::bool>([@vm.inferred-type.metadata=dart.core::bool] self::nonConstant()) in [@vm.inferred-type.metadata=!] core::List::generate<core::int>(#t7, #t8), self::A::generateFactory5 = [@vm.inferred-type.metadata=dart.core::_GrowableList<dart.core::List<dart.core::int>>] core::_GrowableList::generate<core::List<core::int>>(2, [@vm.closure-id=5](core::int _) → core::List<core::int> => [@vm.inferred-type.metadata=dart.core::_GrowableList<dart.core::int>] core::_GrowableList::•<core::int>(0)), self::A::generateFactory6 = let final core::int #t9 = 2 in let final core::bool #t10 = true in [@vm.inferred-type.metadata=dart.core::_GrowableList<dart.core::int>] core::_GrowableList::generate<core::int>(#t9, [@vm.closure-id=6](core::int i) → core::int => i), self::A::generateFactory7 = let final core::int #t11 = 2 in let final core::bool #t12 = false in [@vm.inferred-type.metadata=dart.core::_List<dart.core::int>] core::_List::generate<core::int>([@vm.closure-id=7](core::int i) → core::int => i), super core::Object::•()
+ : self::A::literal1 = [@vm.inferred-type.metadata=dart.core::_GrowableList<dart.core::int>] core::_GrowableList::•<core::int>(0), self::A::literal2 = [@vm.inferred-type.metadata=dart.core::_GrowableList<dart.core::int>] core::_GrowableList::_literal3<core::int>(1, 2, 3), self::A::filledFactory1 = [@vm.inferred-type.metadata=dart.core::_List<dart.core::int>] core::_List::filled<core::int>(2, 0), self::A::filledFactory2 = [@vm.inferred-type.metadata=dart.core::_GrowableList<dart.core::int>] core::_GrowableList::filled<core::int>(2, 0), self::A::filledFactory3 = [@vm.inferred-type.metadata=dart.core::_List<dart.core::int>] core::_List::filled<core::int>(2, 0), self::A::filledFactory4 = let final core::bool #t1 = _in::unsafeCast<core::bool>([@vm.inferred-type.metadata=dart.core::bool] self::nonConstant()) in [@vm.inferred-type.metadata=!] core::List::filled<core::int>(2, 0, #t1), self::A::filledFactory5 = [@vm.inferred-type.metadata=dart.core::_List<dart.core::int?>] core::_List::•<core::int?>(2), self::A::filledFactory6 = [@vm.inferred-type.metadata=dart.core::_GrowableList<dart.core::int?>] core::_GrowableList::•<core::int?>(2), self::A::filledFactory7 = [@vm.inferred-type.metadata=dart.core::_List<dart.core::int?>] core::_List::•<core::int?>(2), self::A::filledFactory8 = let final core::bool #t2 = _in::unsafeCast<core::bool>([@vm.inferred-type.metadata=dart.core::bool] self::nonConstant()) in [@vm.inferred-type.metadata=!] core::List::filled<core::int?>(2, null, #t2), self::A::filledFactory9 = let final core::int #t3 = 2 in let final core::bool #t4 = true in [@vm.inferred-type.metadata=dart.core::_GrowableList<dart.core::int?>] core::_GrowableList::•<core::int?>(#t3), self::A::filledFactory10 = let final core::int #t5 = 2 in let final core::bool #t6 = false in [@vm.inferred-type.metadata=dart.core::_List<dart.core::int?>] core::_List::•<core::int?>(#t5), self::A::generateFactory1 = [@vm.inferred-type.metadata=dart.core::_GrowableList<dart.core::int>] core::_GrowableList::generate<core::int>(2, [@vm.closure-id=1](core::int i) → core::int => i), self::A::generateFactory2 = [@vm.inferred-type.metadata=dart.core::_GrowableList<dart.core::int>] core::_GrowableList::generate<core::int>(2, [@vm.closure-id=2](core::int i) → core::int => i), self::A::generateFactory3 = [@vm.inferred-type.metadata=dart.core::_List<dart.core::int>] core::_List::generate<core::int>([@vm.closure-id=3](core::int i) → core::int => i), self::A::generateFactory4 = let final (core::int) → core::int #t7 = [@vm.closure-id=4](core::int i) → core::int => i in let final core::bool #t8 = _in::unsafeCast<core::bool>([@vm.inferred-type.metadata=dart.core::bool] self::nonConstant()) in [@vm.inferred-type.metadata=!] core::List::generate<core::int>(#t7, #t8), self::A::generateFactory5 = [@vm.inferred-type.metadata=dart.core::_GrowableList<dart.core::List<dart.core::int>>] core::_GrowableList::generate<core::List<core::int>>(2, [@vm.closure-id=5](core::int _) → core::List<core::int> => core::_GrowableList::•<core::int>(0)), self::A::generateFactory6 = let final core::int #t9 = 2 in let final core::bool #t10 = true in [@vm.inferred-type.metadata=dart.core::_GrowableList<dart.core::int>] core::_GrowableList::generate<core::int>(#t9, [@vm.closure-id=6](core::int i) → core::int => i), self::A::generateFactory7 = let final core::int #t11 = 2 in let final core::bool #t12 = false in [@vm.inferred-type.metadata=dart.core::_List<dart.core::int>] core::_List::generate<core::int>([@vm.closure-id=7](core::int i) → core::int => i), super core::Object::•()
;
}
static method nonConstant() → dynamic
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/mixin_with_field_test.dart.expect b/pkg/vm/testcases/transformations/type_flow/transformer/mixin_with_field_test.dart.expect
index 5df4917..a4de748 100644
--- a/pkg/vm/testcases/transformations/type_flow/transformer/mixin_with_field_test.dart.expect
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/mixin_with_field_test.dart.expect
@@ -5,9 +5,9 @@
abstract class M extends core::Object /*isMixinDeclaration*/ {
}
abstract class _C&Object&M extends core::Object implements self::M /*isAnonymousMixin,isEliminatedMixin*/ {
-[@vm.inferred-type.metadata=dart.core::_Smi (value: 7)] [@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:1,getterSelectorId:2] [@vm.unboxing-info.metadata=(i)->i] field core::int x;
+[@vm.inferred-type.metadata=int] [@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:1,getterSelectorId:2] [@vm.unboxing-info.metadata=(i)->i] field core::int x;
synthetic constructor •() → self::_C&Object&M
- : self::_C&Object&M::x = [@vm.inferred-type.metadata=dart.core::_Smi (value: 7) (receiver not int)](() → core::int => 7)(){() → core::int}, super core::Object::•()
+ : self::_C&Object&M::x = (() → core::int => 7)(){() → core::int}, super core::Object::•()
;
}
class C extends self::_C&Object&M {
@@ -16,5 +16,5 @@
;
}
static method main() → dynamic {
- core::print([@vm.direct-call.metadata=#lib::_C&Object&M.x] [@vm.inferred-type.metadata=dart.core::_Smi (value: 7)] new self::C::•().{self::_C&Object&M::x}{core::int});
+ core::print([@vm.direct-call.metadata=#lib::_C&Object&M.x] [@vm.inferred-type.metadata=int] new self::C::•().{self::_C&Object&M::x}{core::int});
}
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/no_such_method.dart.expect b/pkg/vm/testcases/transformations/type_flow/transformer/no_such_method.dart.expect
index bede843..5c01f13 100644
--- a/pkg/vm/testcases/transformations/type_flow/transformer/no_such_method.dart.expect
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/no_such_method.dart.expect
@@ -80,9 +80,11 @@
synthetic constructor •() → self::E
: super core::Object::•()
;
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:6,getterSelectorId:7] method noSuchMethod(core::Invocation invocation) → dynamic {
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasTearOffUses:false,methodOrSetterSelectorId:6,getterSelectorId:7] method noSuchMethod(core::Invocation invocation) → dynamic {
return new self::T4::•();
}
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,getterSelectorId:3] no-such-method-forwarder get bar() → dynamic
+ return _in::unsafeCast<dynamic>([@vm.direct-call.metadata=#lib::E.noSuchMethod] [@vm.inferred-type.metadata=#lib::T4 (skip check)] this.{self::E::noSuchMethod}(new core::_InvocationMirror::_withType(#C5, 1, #C2, #C3, [@vm.inferred-type.metadata=dart.collection::UnmodifiableMapView<dart.core::Symbol*, dynamic>] core::Map::unmodifiable<core::Symbol*, dynamic>(#C4))){(core::Invocation) → dynamic});
}
class F extends core::Object {
synthetic constructor •() → self::F
@@ -114,9 +116,7 @@
[@vm.inferred-type.metadata=#lib::D]static field self::A dd = new self::D::•();
[@vm.inferred-type.metadata=!]late static field core::Function unknown;
static method getDynamic() → dynamic
- return block {
- [@vm.inferred-type.metadata=!] self::unknown;
- } =>throw "Attempt to execute code removed by Dart AOT compiler (TFA)";
+ return self::unknown();
static method main(core::List<core::String> args) → dynamic {
core::print([@vm.direct-call.metadata=#lib::B.foo] [@vm.inferred-type.metadata=#lib::T1 (skip check)] [@vm.inferred-type.metadata=#lib::B] self::bb.{self::A::foo}(){() → dynamic});
core::print([@vm.direct-call.metadata=#lib::B.bar] [@vm.inferred-type.metadata=#lib::T1] [@vm.inferred-type.metadata=#lib::B] self::bb.{self::A::bar}{dynamic});
@@ -125,10 +125,10 @@
core::print([@vm.direct-call.metadata=#lib::D.bar] [@vm.inferred-type.metadata=#lib::T2] [@vm.inferred-type.metadata=#lib::D] self::dd.{self::A::bar}{dynamic});
core::print([@vm.direct-call.metadata=#lib::D.bazz] [@vm.inferred-type.metadata=#lib::T2 (skip check)] [@vm.inferred-type.metadata=#lib::D] self::dd.{self::A::bazz}(1, 2, 3, 4){(dynamic, dynamic, dynamic, [dynamic, dynamic]) → dynamic});
new self::E::•();
- self::A xx = _in::unsafeCast<self::A>([@vm.inferred-type.metadata=!] self::getDynamic());
- throw "Attempt to execute code removed by Dart AOT compiler (TFA)";
- dynamic yy = [@vm.inferred-type.metadata=!] self::getDynamic();
- throw "Attempt to execute code removed by Dart AOT compiler (TFA)";
+ self::A xx = self::getDynamic() as{TypeError,ForDynamic} self::A;
+ core::print([@vm.inferred-type.metadata=!] xx.{self::A::bar}{dynamic});
+ dynamic yy = self::getDynamic();
+ core::print([@vm.inferred-type.metadata=!] yy{dynamic}.twoArg(1, 2, 3));
new self::F::•();
dynamic gg = new self::G::•();
core::print([@vm.inferred-type.metadata=#lib::T5 (receiver not int)] gg{dynamic}.noSuchMethod(null, null));
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/null_test_elimination2.dart.expect b/pkg/vm/testcases/transformations/type_flow/transformer/null_test_elimination2.dart.expect
index dde262a..fb6ac8e 100644
--- a/pkg/vm/testcases/transformations/type_flow/transformer/null_test_elimination2.dart.expect
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/null_test_elimination2.dart.expect
@@ -6,7 +6,7 @@
static method _defaultCheck([dynamic _ = #C1]) → core::bool
return true;
static method testStaticTypeOfConditional<T extends core::Object? = dynamic>([@vm.inferred-arg-type.metadata=dart.core::_Closure (closure 1 in #lib::main)] (self::testStaticTypeOfConditional::T%) →? core::bool check) → void {
- if(#C2 is self::testStaticTypeOfConditional::T% && _in::unsafeCast<core::bool>([@vm.inferred-type.metadata=dart.core::bool (value: true) (receiver not int)](let final (self::testStaticTypeOfConditional::T%) →? core::bool #t1 = check in _in::unsafeCast<core::Function>(#t1{(self::testStaticTypeOfConditional::T%) → core::bool}))(#C2))) {
+ if(#C2 is self::testStaticTypeOfConditional::T% && (let final (self::testStaticTypeOfConditional::T%) →? core::bool #t1 = check in _in::unsafeCast<core::Function>(#t1{(self::testStaticTypeOfConditional::T%) → core::bool}))(#C2) as{TypeError,ForDynamic} core::bool) {
core::print("ok");
}
}
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/param_types_before_strong_mode_checks.dart.expect b/pkg/vm/testcases/transformations/type_flow/transformer/param_types_before_strong_mode_checks.dart.expect
index 6eff4ab..7bd31a1 100644
--- a/pkg/vm/testcases/transformations/type_flow/transformer/param_types_before_strong_mode_checks.dart.expect
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/param_types_before_strong_mode_checks.dart.expect
@@ -1,7 +1,6 @@
library #lib;
import self as self;
import "dart:core" as core;
-import "dart:_internal" as _in;
abstract class T0 extends core::Object {
synthetic constructor •() → self::T0
@@ -24,45 +23,47 @@
}
}
abstract class B extends core::Object {
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:5,getterSelectorId:6] abstract method method2(covariant-by-declaration dynamic arg) → void;
}
class C extends core::Object implements self::B {
synthetic constructor •() → self::C
: super core::Object::•()
;
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:5,getterSelectorId:6] method method2(covariant-by-declaration self::T0 t0) → void {
+ [@vm.direct-call.metadata=#lib::T2.foo] [@vm.inferred-type.metadata=!? (skip check)] t0.{self::T0::foo}(){() → void};
+ }
}
class D extends core::Object {
synthetic constructor •() → self::D
: super core::Object::•()
;
+[@vm.procedure-attributes.metadata=getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:7,getterSelectorId:8] method method3(self::T0 t0) → void {
+ [@vm.direct-call.metadata=#lib::T2.foo] [@vm.inferred-type.metadata=!? (skip check)] t0.{self::T0::foo}(){() → void};
+ }
}
[@vm.inferred-type.metadata=!]late static field core::Function unknown;
+static method func1([@vm.inferred-arg-type.metadata=#lib::T2] self::T0 t0) → void {
+ [@vm.direct-call.metadata=#lib::T2.foo] [@vm.inferred-type.metadata=!? (skip check)] t0.{self::T0::foo}(){() → void};
+}
static method func2(self::T0 t0) → void {
[@vm.direct-call.metadata=#lib::T2.foo] [@vm.inferred-type.metadata=!? (skip check)] t0.{self::T0::foo}(){() → void};
}
static method getDynamic() → dynamic
- return block {
- [@vm.inferred-type.metadata=!] self::unknown;
- } =>throw "Attempt to execute code removed by Dart AOT compiler (TFA)";
-static method use() → dynamic
- return block {
- [@vm.inferred-type.metadata=!] self::unknown;
- } =>throw "Attempt to execute code removed by Dart AOT compiler (TFA)";
+ return self::unknown();
+static method use([@vm.inferred-arg-type.metadata=dart.core::_Closure] dynamic x) → dynamic
+ return self::unknown(x);
static method main(core::List<core::String> args) → dynamic {
- block {
- _in::unsafeCast<self::T0>([@vm.inferred-type.metadata=!] self::getDynamic());
- } =>throw "Attempt to execute code removed by Dart AOT compiler (TFA)";
- self::use();
- let final (self::T0) → void #t1 = [@vm.inferred-type.metadata=dart.core::_Closure (closure 0 in #lib::A.method1)] new self::A::•().{self::A::method1}{(self::T0) → void} in self::use();
- self::B bb = _in::unsafeCast<self::B>([@vm.inferred-type.metadata=!] self::getDynamic());
- block {
- [@vm.inferred-type.metadata=!] self::getDynamic();
- } =>throw "Attempt to execute code removed by Dart AOT compiler (TFA)";
- block {
- [@vm.inferred-type.metadata=!] self::getDynamic();
- [@vm.inferred-type.metadata=!] self::getDynamic();
- } =>throw "Attempt to execute code removed by Dart AOT compiler (TFA)";
+ self::func1(self::getDynamic() as{TypeError,ForDynamic} self::T0);
+ self::use(#C1);
+ self::use([@vm.inferred-type.metadata=dart.core::_Closure (closure 0 in #lib::A.method1)] new self::A::•().{self::A::method1}{(self::T0) → void});
+ self::B bb = self::getDynamic() as{TypeError,ForDynamic} self::B;
+ [@vm.direct-call.metadata=#lib::C.method2] [@vm.inferred-type.metadata=!? (skip check)] bb.{self::B::method2}(self::getDynamic()){(dynamic) → void};
+ self::getDynamic(){dynamic}.method3(self::getDynamic());
new self::T2::•();
new self::A::•();
new self::C::•();
new self::D::•();
}
+constants {
+ #C1 = static-tearoff self::func2
+}
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/pragmas.dart.expect b/pkg/vm/testcases/transformations/type_flow/transformer/pragmas.dart.expect
index b51a3f0..ca00923 100644
--- a/pkg/vm/testcases/transformations/type_flow/transformer/pragmas.dart.expect
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/pragmas.dart.expect
@@ -20,7 +20,7 @@
method bar() → void {
@#C16
function bazz() → void {}
- [@vm.inferred-type.metadata=!? (receiver not int)] bazz(){() → void};
+ bazz(){() → void};
}
}
static method main() → dynamic {
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/protobuf_handler/lib/freeze_test.dart.expect b/pkg/vm/testcases/transformations/type_flow/transformer/protobuf_handler/lib/freeze_test.dart.expect
index 8fe1a38..49bee5c 100644
--- a/pkg/vm/testcases/transformations/type_flow/transformer/protobuf_handler/lib/freeze_test.dart.expect
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/protobuf_handler/lib/freeze_test.dart.expect
@@ -60,7 +60,7 @@
exp::expect([@vm.direct-call.metadata=library file:pkg/vm/testcases/transformations/type_flow/transformer/protobuf_handler/lib/generated/foo.pb.dart::BarKeep.aKeep] [@vm.inferred-type.metadata=int] [@vm.direct-call.metadata=library package:protobuf/protobuf.dart::PbMap.[]] [@vm.inferred-type.metadata=library file:pkg/vm/testcases/transformations/type_flow/transformer/protobuf_handler/lib/generated/foo.pb.dart::BarKeep? (skip check)] [@vm.direct-call.metadata=library file:pkg/vm/testcases/transformations/type_flow/transformer/protobuf_handler/lib/generated/foo.pb.dart::FooKeep.mapKeep] [@vm.inferred-type.metadata=library package:protobuf/protobuf.dart::PbMap] foo.{pb::FooKeep::mapKeep}{core::Map<core::String, pb::BarKeep>}.{core::Map::[]}("foo"){(core::Object?) → pb::BarKeep?}!.{pb::BarKeep::aKeep}{core::int}, 2);
exp::expect([@vm.direct-call.metadata=library file:pkg/vm/testcases/transformations/type_flow/transformer/protobuf_handler/lib/generated/foo.pb.dart::FooKeep.hasHasKeep] [@vm.inferred-type.metadata=dart.core::bool (skip check)] foo.{pb::FooKeep::hasHasKeep}(){() → core::bool}, false);
exp::expect([@vm.direct-call.metadata=library file:pkg/vm/testcases/transformations/type_flow/transformer/protobuf_handler/lib/generated/foo.pb.dart::FooKeep.aKeep] [@vm.inferred-type.metadata=int] foo.{pb::FooKeep::aKeep}{core::int}, 43);
- exp::expect([@vm.closure-id=2]() → void => [@vm.direct-call.metadata=library file:pkg/vm/testcases/transformations/type_flow/transformer/protobuf_handler/lib/generated/foo.pb.dart::FooKeep.clearClearKeep] [@vm.inferred-type.metadata=dart.core::Null? (skip check) (value: null)] foo.{pb::FooKeep::clearClearKeep}(){() → void}, [@vm.inferred-type.metadata=library package:matcher/src/expect/throws_matcher.dart::Throws] thr::throwsA());
+ exp::expect([@vm.closure-id=2]() → void => [@vm.direct-call.metadata=library file:pkg/vm/testcases/transformations/type_flow/transformer/protobuf_handler/lib/generated/foo.pb.dart::FooKeep.clearClearKeep] [@vm.inferred-type.metadata=!? (skip check)] foo.{pb::FooKeep::clearClearKeep}(){() → void}, [@vm.inferred-type.metadata=library package:matcher/src/expect/throws_matcher.dart::Throws] thr::throwsA());
});
}
library foo.pb.dart;
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/regress_54163.dart.expect b/pkg/vm/testcases/transformations/type_flow/transformer/regress_54163.dart.expect
index 6b39f48..8212007 100644
--- a/pkg/vm/testcases/transformations/type_flow/transformer/regress_54163.dart.expect
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/regress_54163.dart.expect
@@ -28,5 +28,5 @@
self::foo<core::double>(new self::C::•(), new self::C::•());
[@vm.inferred-type.metadata=#lib::B] self::A<core::num> a1 = new self::B::•();
[@vm.inferred-type.metadata=#lib::C] self::A<core::num> a2 = new self::C::•();
- exp::Expect::throws<core::TypeError>([@vm.closure-id=1]() → void => [@vm.inferred-type.metadata=dart.core::Null? (value: null)] self::foo<core::num>(a1, a2));
+ exp::Expect::throws<core::TypeError>([@vm.closure-id=1]() → void => self::foo<core::num>(a1, a2));
}
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/regress_flutter16182.dart.expect b/pkg/vm/testcases/transformations/type_flow/transformer/regress_flutter16182.dart.expect
index 9a4440c..07dffe4 100644
--- a/pkg/vm/testcases/transformations/type_flow/transformer/regress_flutter16182.dart.expect
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/regress_flutter16182.dart.expect
@@ -19,7 +19,7 @@
synthetic constructor •() → self::A1
: super core::Object::•()
;
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:5,getterSelectorId:6] method call([@vm.inferred-arg-type.metadata=#lib::T1] dynamic a5) → void {
+[@vm.procedure-attributes.metadata=getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:5,getterSelectorId:6] method call([[@vm.inferred-arg-type.metadata=dart.core::_Smi (value: 1)] dynamic a1 = #C1, [@vm.inferred-arg-type.metadata=dart.core::_Smi (value: 2)] dynamic a2 = #C1, [@vm.inferred-arg-type.metadata=dart.core::_Smi (value: 3)] dynamic a3 = #C1, [@vm.inferred-arg-type.metadata=dart.core::_Smi (value: 4)] dynamic a4 = #C1, [@vm.inferred-arg-type.metadata=#lib::T1] dynamic a5 = #C1]) → void {
[@vm.direct-call.metadata=#lib::A1.foo] [@vm.inferred-type.metadata=!? (skip check)] this.{self::A1::foo} = _in::unsafeCast<self::T1?>(a5);
}
}
@@ -112,12 +112,12 @@
}
[@vm.inferred-type.metadata=dart.core::bool?]static field core::bool? ok;
[@vm.inferred-type.metadata=#lib::B3?]static field dynamic bb3 = new self::B3::•();
-[@vm.inferred-type.metadata=dart.core::_Closure (closure 1 in #lib::unknown3)] [@vm.closure-id=1]static field core::Function unknown3 = [@vm.closure-id=1]() → dynamic => [@vm.inferred-type.metadata=#lib::B3?] self::bb3;
+[@vm.inferred-type.metadata=dart.core::_Closure (closure 1 in #lib::unknown3)] [@vm.closure-id=1]static field core::Function unknown3 = [@vm.closure-id=1]() → dynamic => self::bb3;
[@vm.inferred-type.metadata=#lib::B4?]static field dynamic bb4 = new self::B4::•();
-[@vm.inferred-type.metadata=dart.core::_Closure (closure 1 in #lib::unknown4)] [@vm.closure-id=1]static field core::Function unknown4 = [@vm.closure-id=1]() → dynamic => [@vm.inferred-type.metadata=#lib::B4?] self::bb4;
+[@vm.inferred-type.metadata=dart.core::_Closure (closure 1 in #lib::unknown4)] [@vm.closure-id=1]static field core::Function unknown4 = [@vm.closure-id=1]() → dynamic => self::bb4;
static method test1() → void {
self::B1 bb = new self::B1::•();
- let final self::B1 #t1 = bb in let final core::int #t2 = 1 in let final core::int #t3 = 2 in let final core::int #t4 = 3 in let final core::int #t5 = 4 in let final self::T1 #t6 = new self::T1::•() in [@vm.direct-call.metadata=#lib::A1.call] [@vm.inferred-type.metadata=!? (skip check)] [@vm.direct-call.metadata=#lib::B1.aa1] [@vm.inferred-type.metadata=#lib::A1] #t1.{self::B1::aa1}{self::A1}.{self::A1::call}(#t6){([dynamic, dynamic, dynamic, dynamic, dynamic]) → void};
+ let final self::B1 #t1 = bb in let final core::int #t2 = 1 in let final core::int #t3 = 2 in let final core::int #t4 = 3 in let final core::int #t5 = 4 in let final self::T1 #t6 = new self::T1::•() in [@vm.direct-call.metadata=#lib::A1.call] [@vm.inferred-type.metadata=!? (skip check)] [@vm.direct-call.metadata=#lib::B1.aa1] [@vm.inferred-type.metadata=#lib::A1] #t1.{self::B1::aa1}{self::A1}.{self::A1::call}(#t2, #t3, #t4, #t5, #t6){([dynamic, dynamic, dynamic, dynamic, dynamic]) → void};
self::ok = false;
[@vm.direct-call.metadata=#lib::T1.doTest1] [@vm.inferred-type.metadata=!? (skip check)] [@vm.direct-call.metadata=#lib::A1.foo] [@vm.inferred-type.metadata=#lib::T1?] [@vm.direct-call.metadata=#lib::B1.aa1] [@vm.inferred-type.metadata=#lib::A1] bb.{self::B1::aa1}{self::A1}.{self::A1::foo}{self::T1?}!.{self::T1::doTest1}(){() → void};
exp::Expect::isTrue([@vm.inferred-type.metadata=dart.core::bool?] self::ok);
@@ -130,19 +130,19 @@
exp::Expect::isTrue([@vm.inferred-type.metadata=dart.core::bool?] self::ok);
}
static method getDynamic3() → dynamic
- return [@vm.inferred-type.metadata=#lib::B3? (receiver not int)] [@vm.inferred-type.metadata=dart.core::_Closure (closure 1 in #lib::unknown3)] self::unknown3();
+ return self::unknown3();
static method test3() → void {
- [@vm.inferred-type.metadata=!? (receiver not int)] [@vm.inferred-type.metadata=#lib::B3?] self::getDynamic3(){dynamic}.aa3(1, 2, 3, 4, 5, 6, new self::T3::•());
+ self::getDynamic3(){dynamic}.aa3(1, 2, 3, 4, 5, 6, new self::T3::•());
self::ok = false;
[@vm.direct-call.metadata=#lib::T3.doTest3??] [@vm.inferred-type.metadata=!? (receiver not int)] [@vm.direct-call.metadata=#lib::A3.foo] [@vm.inferred-type.metadata=#lib::T3? (receiver not int)] [@vm.direct-call.metadata=#lib::B3.aa3??] [@vm.inferred-type.metadata=#lib::A3 (receiver not int)] [@vm.inferred-type.metadata=#lib::B3?] self::bb3{dynamic}.aa3{dynamic}.foo{dynamic}.doTest3();
exp::Expect::isTrue([@vm.inferred-type.metadata=dart.core::bool?] self::ok);
}
static method getDynamic4() → dynamic
- return [@vm.inferred-type.metadata=#lib::B4? (receiver not int)] [@vm.inferred-type.metadata=dart.core::_Closure (closure 1 in #lib::unknown4)] self::unknown4();
+ return self::unknown4();
static method test4() → void {
- [@vm.inferred-type.metadata=!? (receiver not int)] [@vm.inferred-type.metadata=#lib::B4?] self::getDynamic4(){dynamic}.aa4(1, 2, 3, 4, 5, 6, 7, new self::T4::•());
+ self::getDynamic4(){dynamic}.aa4(1, 2, 3, 4, 5, 6, 7, new self::T4::•());
self::ok = false;
- [@vm.direct-call.metadata=#lib::T4.doTest4??] [@vm.inferred-type.metadata=!? (receiver not int)] [@vm.direct-call.metadata=#lib::A4.foo] [@vm.inferred-type.metadata=#lib::T4? (receiver not int)] [@vm.direct-call.metadata=#lib::B4.aa4??] [@vm.inferred-type.metadata=#lib::A4 (receiver not int)] [@vm.inferred-type.metadata=#lib::B4?] self::getDynamic4(){dynamic}.aa4{dynamic}.foo{dynamic}.doTest4();
+ [@vm.direct-call.metadata=#lib::T4.doTest4??] [@vm.inferred-type.metadata=!? (receiver not int)] [@vm.direct-call.metadata=#lib::A4.foo] [@vm.inferred-type.metadata=#lib::T4? (receiver not int)] [@vm.inferred-type.metadata=#lib::A4] self::getDynamic4(){dynamic}.aa4{dynamic}.foo{dynamic}.doTest4();
exp::Expect::isTrue([@vm.inferred-type.metadata=dart.core::bool?] self::ok);
}
static method main() → void {
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/set_map_constructor_concrete.dart.expect b/pkg/vm/testcases/transformations/type_flow/transformer/set_map_constructor_concrete.dart.expect
index 69ff30b..de71ed6 100644
--- a/pkg/vm/testcases/transformations/type_flow/transformer/set_map_constructor_concrete.dart.expect
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/set_map_constructor_concrete.dart.expect
@@ -10,14 +10,14 @@
[@vm.inferred-type.metadata=dart.collection::_CompactLinkedIdentityHashSet<dynamic>]static field core::Set<dynamic> identitySet = [@vm.inferred-type.metadata=dart.collection::_CompactLinkedIdentityHashSet<dynamic>] col::LinkedHashSet::identity<dynamic>();
[@vm.inferred-type.metadata=dart.collection::_Set<dart.core::String>]static field core::Set<core::String> linkedSet = new col::_Set::•<core::String>();
[@vm.inferred-type.metadata=!]static field core::Set<core::String> linkedIdentitySet = [@vm.inferred-type.metadata=!] col::LinkedHashSet::•<core::String>(#C1, #C2);
-[@vm.inferred-type.metadata=dart.collection::_CompactLinkedCustomHashSet<dart.core::String>]static field core::Set<core::String> linkedCustomSet = let final (core::String, core::String) → core::bool #t1 = (core::String a, core::String b) → core::bool => [@vm.inferred-type.metadata=dart.core::bool (receiver not int)] a =={core::String::==}{(core::Object) → core::bool} b in let final (core::String) → core::int #t2 = (core::String o) → core::int => [@vm.inferred-type.metadata=dart.core::_Smi] o.{core::String::hashCode}{core::int} in let final (dynamic) → core::bool #t3 = (dynamic o) → core::bool => true in [@vm.inferred-type.metadata=dart.collection::_CompactLinkedCustomHashSet<dart.core::String>] col::LinkedHashSet::•<core::String>(#t1, #t2, isValidKey: #t3);
+[@vm.inferred-type.metadata=dart.collection::_CompactLinkedCustomHashSet<dart.core::String>]static field core::Set<core::String> linkedCustomSet = let final (core::String, core::String) → core::bool #t1 = (core::String a, core::String b) → core::bool => [@vm.inferred-type.metadata=!? (receiver not int)] a =={core::String::==}{(core::Object) → core::bool} b in let final (core::String) → core::int #t2 = (core::String o) → core::int => o.{core::String::hashCode}{core::int} in let final (dynamic) → core::bool #t3 = (dynamic o) → core::bool => true in [@vm.inferred-type.metadata=dart.collection::_CompactLinkedCustomHashSet<dart.core::String>] col::LinkedHashSet::•<core::String>(#t1, #t2, isValidKey: #t3);
[@vm.inferred-type.metadata=dart.collection::_Map<dynamic, dynamic>]static field core::Map<dynamic, dynamic> globalMap = [@vm.inferred-type.metadata=dart.collection::_Map<dynamic, dynamic>] core::Map::•<dynamic, dynamic>();
[@vm.inferred-type.metadata=dart.collection::_CompactLinkedIdentityHashMap<dynamic, dynamic>]static field core::Map<dynamic, dynamic> identityMap = [@vm.inferred-type.metadata=dart.collection::_CompactLinkedIdentityHashMap<dynamic, dynamic>] col::LinkedHashMap::identity<dynamic, dynamic>();
[@vm.inferred-type.metadata=dart.collection::UnmodifiableMapView<dynamic, dynamic>]static field core::Map<dynamic, dynamic> unmodifiableMap = [@vm.inferred-type.metadata=dart.collection::UnmodifiableMapView<dynamic, dynamic>] core::Map::unmodifiable<dynamic, dynamic>([@vm.inferred-type.metadata=dart.collection::_CompactLinkedIdentityHashMap<dynamic, dynamic>] self::identityMap);
[@vm.inferred-type.metadata=dart.collection::_Map<dynamic, dynamic>]static field core::Map<dynamic, dynamic> globalMapLiteral = <dynamic, dynamic>{};
[@vm.inferred-type.metadata=dart.collection::_Map<dart.core::String, dart.core::String>]static field core::Map<core::String, core::String> linkedMap = new col::_Map::•<core::String, core::String>();
[@vm.inferred-type.metadata=!]static field core::Map<core::String, core::String> linkedIdentityMap = [@vm.inferred-type.metadata=!] col::LinkedHashMap::•<core::String, core::String>(#C1, #C2);
-[@vm.inferred-type.metadata=dart.collection::_CompactLinkedCustomHashMap<dart.core::String, dart.core::String>]static field core::Map<core::String, core::String> linkedCustomMap = let final (core::String, core::String) → core::bool #t4 = (core::String a, core::String b) → core::bool => [@vm.inferred-type.metadata=dart.core::bool (receiver not int)] a =={core::String::==}{(core::Object) → core::bool} b in let final (core::String) → core::int #t5 = (core::String o) → core::int => [@vm.inferred-type.metadata=dart.core::_Smi] o.{core::String::hashCode}{core::int} in let final (dynamic) → core::bool #t6 = (dynamic o) → core::bool => true in [@vm.inferred-type.metadata=dart.collection::_CompactLinkedCustomHashMap<dart.core::String, dart.core::String>] col::LinkedHashMap::•<core::String, core::String>(#t4, #t5, isValidKey: #t6);
+[@vm.inferred-type.metadata=dart.collection::_CompactLinkedCustomHashMap<dart.core::String, dart.core::String>]static field core::Map<core::String, core::String> linkedCustomMap = let final (core::String, core::String) → core::bool #t4 = (core::String a, core::String b) → core::bool => [@vm.inferred-type.metadata=!? (receiver not int)] a =={core::String::==}{(core::Object) → core::bool} b in let final (core::String) → core::int #t5 = (core::String o) → core::int => o.{core::String::hashCode}{core::int} in let final (dynamic) → core::bool #t6 = (dynamic o) → core::bool => true in [@vm.inferred-type.metadata=dart.collection::_CompactLinkedCustomHashMap<dart.core::String, dart.core::String>] col::LinkedHashMap::•<core::String, core::String>(#t4, #t5, isValidKey: #t6);
static method main() → dynamic {
core::print([@vm.inferred-type.metadata=dart.collection::_Set<dynamic>] self::globalSet);
core::print([@vm.inferred-type.metadata=dart.collection::_CompactLinkedIdentityHashSet<dynamic>] self::identitySet);
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/tear_off_dynamic_method.dart.expect b/pkg/vm/testcases/transformations/type_flow/transformer/tear_off_dynamic_method.dart.expect
index 596de28..d1c2fe2 100644
--- a/pkg/vm/testcases/transformations/type_flow/transformer/tear_off_dynamic_method.dart.expect
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/tear_off_dynamic_method.dart.expect
@@ -1,7 +1,6 @@
library #lib;
import self as self;
import "dart:core" as core;
-import "dart:_internal" as _in;
abstract class A extends core::Object {
synthetic constructor •() → self::A
@@ -13,12 +12,12 @@
: super self::A::•()
;
[@vm.procedure-attributes.metadata=hasThisUses:false,methodOrSetterSelectorId:1,getterSelectorId:2] [@vm.unboxing-info.metadata=()->i] method foo() → core::int
- return _in::unsafeCast<core::int>([@vm.direct-call.metadata=dart.core::_IntegerImplementation.+] [@vm.inferred-type.metadata=int (skip check)] 1.{core::num::+}(_in::unsafeCast<core::num>([@vm.direct-call.metadata=#lib::B.foo] [@vm.inferred-type.metadata=int (receiver not int)] [@vm.inferred-type.metadata=#lib::B] self::knownResult(){dynamic}.foo())){(core::num) → core::num});
+ return [@vm.direct-call.metadata=dart.core::_IntegerImplementation.+] [@vm.inferred-type.metadata=! (skip check)] 1.{core::num::+}([@vm.direct-call.metadata=#lib::B.foo] [@vm.inferred-type.metadata=!? (receiver not int)] [@vm.inferred-type.metadata=#lib::B] self::knownResult(){dynamic}.foo() as{TypeError,ForDynamic} core::num){(core::num) → core::num} as core::int;
}
class TearOffDynamicMethod extends core::Object {
[@vm.inferred-type.metadata=dart.core::_Closure (closure 0 in #lib::B.foo)] [@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:3,getterSelectorId:4] field dynamic bazz;
- constructor •([@vm.inferred-arg-type.metadata=#lib::B] dynamic arg) → self::TearOffDynamicMethod
- : self::TearOffDynamicMethod::bazz = [@vm.inferred-type.metadata=dart.core::_Closure (receiver not int) (closure 0 in #lib::B.foo)] arg{dynamic}.foo, super core::Object::•() {
+ constructor •(dynamic arg) → self::TearOffDynamicMethod
+ : self::TearOffDynamicMethod::bazz = [@vm.inferred-type.metadata=dart.core::_Closure (closure 0 in #lib::B.foo)] arg{dynamic}.foo, super core::Object::•() {
[@vm.inferred-type.metadata=!? (receiver not int)] [@vm.direct-call.metadata=#lib::TearOffDynamicMethod.bazz] [@vm.inferred-type.metadata=dart.core::_Closure (closure 0 in #lib::B.foo)] this.{self::TearOffDynamicMethod::bazz}{dynamic}{dynamic}.call();
}
}
@@ -26,5 +25,5 @@
return new self::B::•();
static method main(core::List<core::String> args) → dynamic {
core::Function closure = () → self::B => new self::B::•();
- new self::TearOffDynamicMethod::•([@vm.inferred-type.metadata=#lib::B (receiver not int)] closure());
+ new self::TearOffDynamicMethod::•(closure());
}
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/tear_off_super_method.dart.expect b/pkg/vm/testcases/transformations/type_flow/transformer/tear_off_super_method.dart.expect
index 70b3010..b079063 100644
--- a/pkg/vm/testcases/transformations/type_flow/transformer/tear_off_super_method.dart.expect
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/tear_off_super_method.dart.expect
@@ -14,7 +14,7 @@
: super self::A::•()
;
[@vm.procedure-attributes.metadata=getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:1,getterSelectorId:2] [@vm.unboxing-info.metadata=()->i] method foo() → core::int
- return [@vm.direct-call.metadata=dart.core::_IntegerImplementation.+] [@vm.inferred-type.metadata=! (skip check)] 1.{core::num::+}([@vm.direct-call.metadata=#lib::B.foo] [@vm.inferred-type.metadata=!? (receiver not int)] [@vm.inferred-type.metadata=#lib::B] self::knownResult(){dynamic}.foo() as{TypeError,ForDynamic} core::num){(core::num) → core::num} as core::int;
+ return _in::unsafeCast<core::int>([@vm.direct-call.metadata=dart.core::_IntegerImplementation.+] [@vm.inferred-type.metadata=int (skip check)] 1.{core::num::+}(_in::unsafeCast<core::num>([@vm.direct-call.metadata=#lib::B.foo] [@vm.inferred-type.metadata=int (receiver not int)] [@vm.inferred-type.metadata=#lib::B] self::knownResult(){dynamic}.foo())){(core::num) → core::num});
}
class C extends core::Object implements self::A {
}
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/unboxed_records.dart.expect b/pkg/vm/testcases/transformations/type_flow/transformer/unboxed_records.dart.expect
index fe0af4c..424b4e7 100644
--- a/pkg/vm/testcases/transformations/type_flow/transformer/unboxed_records.dart.expect
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/unboxed_records.dart.expect
@@ -64,8 +64,8 @@
self::A obj = [@vm.inferred-type.metadata=dart.core::bool] self::condition ?{self::A} new self::B::•() : new self::C::•();
core::print([@vm.inferred-type.metadata=dart.core::_Record] obj.{self::A::returnUnboxed1}(){() → dynamic});
core::print([@vm.inferred-type.metadata=dart.core::_Record] obj.{self::A::returnUnboxed2}{dynamic});
- core::print([@vm.inferred-type.metadata=dart.core::_Record] obj.{self::A::returnBoxed1}(){() → dynamic});
- core::print([@vm.inferred-type.metadata=dart.core::_Record] obj.{self::A::returnBoxed2}{dynamic});
+ core::print([@vm.inferred-type.metadata=!] obj.{self::A::returnBoxed1}(){() → dynamic});
+ core::print([@vm.inferred-type.metadata=!] obj.{self::A::returnBoxed2}{dynamic});
}
constants {
#C1 = "vm:entry-point"
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/weak.dart.expect b/pkg/vm/testcases/transformations/type_flow/transformer/weak.dart.expect
index 7e23db5..624fcc0 100644
--- a/pkg/vm/testcases/transformations/type_flow/transformer/weak.dart.expect
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/weak.dart.expect
@@ -26,7 +26,7 @@
return [@vm.direct-call.metadata=dart.core::_Smi.toString] [@vm.inferred-type.metadata=dart.core::_OneByteString (skip check)] 2.{core::int::toString}(){() → core::String};
static method register([@vm.inferred-arg-type.metadata=dart.core::_Closure?] () →? core::String getAccessor) → void {
if(!(getAccessor == null)) {
- core::print([@vm.inferred-type.metadata=! (receiver not int)] getAccessor{() → core::String}(){() → core::String});
+ core::print(getAccessor{() → core::String}(){() → core::String});
}
}
static method main(core::List<core::String> args) → dynamic {
diff --git a/runtime/vm/compiler/backend/type_propagator.cc b/runtime/vm/compiler/backend/type_propagator.cc
index ad1f7fb..c2da713 100644
--- a/runtime/vm/compiler/backend/type_propagator.cc
+++ b/runtime/vm/compiler/backend/type_propagator.cc
@@ -2057,15 +2057,13 @@
CompileType LoadIndexedInstr::ComputeType() const {
switch (class_id_) {
case kArrayCid:
- case kImmutableArrayCid: {
- CompileType elem_type = ComputeArrayElementType(array());
+ case kImmutableArrayCid:
if (result_type_ != nullptr &&
!CompileType::Dynamic().IsEqualTo(result_type_)) {
// The original call knew something.
- return *CompileType::ComputeRefinedType(&elem_type, result_type_);
+ return *result_type_;
}
- return elem_type;
- }
+ return ComputeArrayElementType(array());
case kTypeArgumentsCid:
return CompileType::FromAbstractType(Object::dynamic_type(),
diff --git a/runtime/vm/compiler/frontend/base_flow_graph_builder.cc b/runtime/vm/compiler/frontend/base_flow_graph_builder.cc
index 86134a9..8b78359 100644
--- a/runtime/vm/compiler/frontend/base_flow_graph_builder.cc
+++ b/runtime/vm/compiler/frontend/base_flow_graph_builder.cc
@@ -8,7 +8,6 @@
#include "vm/compiler/backend/range_analysis.h" // For Range.
#include "vm/compiler/frontend/flow_graph_builder.h" // For InlineExitCollector.
-#include "vm/compiler/frontend/kernel_translation_helper.h"
#include "vm/compiler/jit/compiler.h" // For Compiler::IsBackgroundCompilation().
#include "vm/compiler/runtime_api.h"
#include "vm/growable_array.h"
@@ -1134,14 +1133,12 @@
return call_hook;
}
-Fragment BaseFlowGraphBuilder::ClosureCall(
- const Function& target_function,
- TokenPosition position,
- intptr_t type_args_len,
- intptr_t argument_count,
- const Array& argument_names,
- const InferredTypeMetadata* result_type) {
- Fragment instructions = RecordCoverage(position);
+Fragment BaseFlowGraphBuilder::ClosureCall(const Function& target_function,
+ TokenPosition position,
+ intptr_t type_args_len,
+ intptr_t argument_count,
+ const Array& argument_names) {
+ Fragment result = RecordCoverage(position);
const intptr_t total_count =
(type_args_len > 0 ? 1 : 0) + argument_count +
/*closure (bare instructions) or function (otherwise)*/ 1;
@@ -1150,12 +1147,8 @@
target_function, std::move(arguments), type_args_len, argument_names,
InstructionSource(position), GetNextDeoptId());
Push(call);
- instructions <<= call;
- if (result_type != nullptr && result_type->IsConstant()) {
- instructions += Drop();
- instructions += Constant(result_type->constant_value);
- }
- return instructions;
+ result <<= call;
+ return result;
}
void BaseFlowGraphBuilder::reset_context_depth_for_deopt_id(intptr_t deopt_id) {
diff --git a/runtime/vm/compiler/frontend/base_flow_graph_builder.h b/runtime/vm/compiler/frontend/base_flow_graph_builder.h
index 77e47d2..e3df988 100644
--- a/runtime/vm/compiler/frontend/base_flow_graph_builder.h
+++ b/runtime/vm/compiler/frontend/base_flow_graph_builder.h
@@ -22,7 +22,6 @@
namespace kernel {
class BaseFlowGraphBuilder;
-struct InferredTypeMetadata;
class TryCatchBlock;
class Fragment {
@@ -456,8 +455,7 @@
TokenPosition position,
intptr_t type_args_len,
intptr_t argument_count,
- const Array& argument_names,
- const InferredTypeMetadata* result_type = nullptr);
+ const Array& argument_names);
// Pops function type arguments, instantiator type arguments, dst_type, and
// value; and type checks value against the type arguments.
diff --git a/runtime/vm/compiler/frontend/kernel_binary_flowgraph.cc b/runtime/vm/compiler/frontend/kernel_binary_flowgraph.cc
index 4c2f464..fc13c48 100644
--- a/runtime/vm/compiler/frontend/kernel_binary_flowgraph.cc
+++ b/runtime/vm/compiler/frontend/kernel_binary_flowgraph.cc
@@ -2964,13 +2964,8 @@
Fragment StreamingFlowGraphBuilder::BuildLocalFunctionInvocation(
TokenPosition* p) {
- const intptr_t offset = ReaderOffset() - 1; // Include the tag.
const TokenPosition position = ReadPosition();
if (p != nullptr) *p = position;
-
- const InferredTypeMetadata result_type =
- inferred_type_metadata_helper_.GetInferredType(offset);
-
// read variable kernel position.
const intptr_t variable_kernel_position = ReadUInt();
ReadUInt(); // read relative variable index.
@@ -3032,7 +3027,7 @@
instructions += DebugStepCheck(position);
}
instructions += B->ClosureCall(target_function, position, type_args_len,
- argument_count, argument_names, &result_type);
+ argument_count, argument_names);
return instructions;
}
@@ -3095,7 +3090,7 @@
}
instructions +=
B->ClosureCall(Function::null_function(), position, type_args_len,
- argument_count, argument_names, &result_type);
+ argument_count, argument_names);
} else {
instructions += InstanceCall(
position, Symbols::DynamicCall(), Token::kILLEGAL, type_args_len,