mirror of
https://github.com/dart-lang/sdk
synced 2024-11-02 12:24:24 +00:00
[dart2wasm] Improve cases where we use cid-based range checks for is/as
This removes an expensive type check for `is GlobalKey` in flutter code where the `GlobalKey` has non-trivial bound. abstract class GlobalKey<T extends State<StatefulWidget>> { ... } Change-Id: Ia685c0b528fdfe93d7a50685d2ba38b216277e15 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/353740 Reviewed-by: Ömer Ağacan <omersa@google.com> Commit-Queue: Martin Kustermann <kustermann@google.com>
This commit is contained in:
parent
19d11a70af
commit
a21fec815a
1 changed files with 17 additions and 7 deletions
|
@ -631,8 +631,8 @@ class Types {
|
|||
if (_canUseAsCheckHelper(codeGen, type, operandType)) return true;
|
||||
|
||||
if (type is! InterfaceType) return false;
|
||||
if (type.typeArguments.any((t) => t is! DynamicType)) {
|
||||
// Type has at least one type argument that is not `dynamic`.
|
||||
if (_hasNonDefaultTypeArguments(type)) {
|
||||
// Type has at least one type argument that is not default.
|
||||
//
|
||||
// In cases like `x is List<T>` where `x : Iterable<T>` (tested-against
|
||||
// type is a subtype of the operand's static type and the types have same
|
||||
|
@ -658,9 +658,19 @@ class Types {
|
|||
bool _canUseAsCheckHelper(
|
||||
CodeGenerator codeGen, DartType type, DartType operandType) {
|
||||
if (type is! InterfaceType) return false;
|
||||
// TODO: Should be rather defaults to bounds instead of `dynamic`.
|
||||
// (assuming omitting bound will make it dynamic rather than void/Object?)
|
||||
return type.typeArguments.every((t) => t is DynamicType);
|
||||
return !_hasNonDefaultTypeArguments(type);
|
||||
}
|
||||
|
||||
bool _hasNonDefaultTypeArguments(InterfaceType type) {
|
||||
if (type.typeArguments.isEmpty) return false;
|
||||
|
||||
final parameters = type.classNode.typeParameters;
|
||||
final arguments = type.typeArguments;
|
||||
assert(parameters.length == arguments.length);
|
||||
for (int i = 0; i < arguments.length; ++i) {
|
||||
if (arguments[i] != parameters[i].defaultType) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
final Map<DartType, w.BaseFunction> _nullableIsCheckers = {};
|
||||
|
@ -682,7 +692,7 @@ class Types {
|
|||
[argumentType],
|
||||
[w.NumType.i32],
|
||||
),
|
||||
'<obj> is <$type>');
|
||||
'<obj> is ${type.classNode}');
|
||||
|
||||
final b = function.body;
|
||||
b.local_get(b.locals[0]);
|
||||
|
@ -744,7 +754,7 @@ class Types {
|
|||
[argumentType],
|
||||
[returnType],
|
||||
),
|
||||
'<obj> as <$type>');
|
||||
'<obj> as ${type.classNode}');
|
||||
|
||||
final b = function.body;
|
||||
w.Label asCheckBlock = b.block();
|
||||
|
|
Loading…
Reference in a new issue