Skip to content

Commit 40ffa5a

Browse files
rakudramaCommit Queue
authored andcommitted
[dart2js] Move decision to do static type refinement to dataflow
This is a follow-up to https://dart-review.googlesource.com/c/sdk/+/426660 The "using" of the static type didn't work in loops since the variables used in the loop start out as phis with a top type, so the guard to avoid trusting the static type for legacy js-interop always applied. There are very few code differences with this change, but if we can address the TODOs, especially to partition Dart closures from JavaScriptFunctions, there are some nice changes in loops that call function parameters. Bug: #60327 Change-Id: I76252d99b8047f74547d34ddc10e23d1fa380b2e Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/426820 Reviewed-by: Mayank Patke <[email protected]> Commit-Queue: Stephen Adams <[email protected]>
1 parent 893e37a commit 40ffa5a

File tree

2 files changed

+33
-23
lines changed

2 files changed

+33
-23
lines changed

pkg/compiler/lib/src/ssa/builder.dart

Lines changed: 5 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -7030,17 +7030,11 @@ class KernelSsaGraphBuilder extends ir.VisitorDefault<void>
70307030
final staticType = _abstractValueDomain
70317031
.createFromStaticType(_getStaticType(node as ir.Expression))
70327032
.abstractValue;
7033-
// Narrow to front-end inferred type, but only if `receiverType` is
7034-
// disjoint with LegacyJavaScriptObject. Global type inference does not
7035-
// trust the legacy js-interop methods, so we should not start doing so
7036-
// here.
7037-
if (!_possiblyLegacyJavaScriptObject(selector, receiverType)) {
7038-
invoke.staticType = staticType;
7039-
invoke.instructionType = invoke.computeInstructionType(
7040-
resultType,
7041-
_abstractValueDomain,
7042-
);
7043-
}
7033+
invoke.staticType = staticType;
7034+
invoke.instructionType = invoke.computeInstructionType(
7035+
resultType,
7036+
_abstractValueDomain,
7037+
);
70447038
}
70457039
push(invoke);
70467040
if (element != null &&
@@ -7052,18 +7046,6 @@ class KernelSsaGraphBuilder extends ir.VisitorDefault<void>
70527046
}
70537047
}
70547048

7055-
bool _possiblyLegacyJavaScriptObject(Selector selector, AbstractValue type) {
7056-
// Legacy js-interop cannot override `[]`.
7057-
if (selector.isIndex) return false;
7058-
7059-
if (_abstractValueDomain.isInterceptor(type).isDefinitelyFalse ||
7060-
_abstractValueDomain.isPrimitive(type).isDefinitelyTrue) {
7061-
return false;
7062-
}
7063-
7064-
return true;
7065-
}
7066-
70677049
void _invokeJsInteropFunction(
70687050
FunctionEntity element,
70697051
List<HInstruction?> arguments, {

pkg/compiler/lib/src/ssa/nodes.dart

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1967,6 +1967,18 @@ abstract class HInvokeDynamic extends HInvoke implements InstructionContext {
19671967
AbstractValueDomain abstractValueDomain,
19681968
) {
19691969
if (staticType == null) return value;
1970+
1971+
// When the receiver might be a LegacyJavaScriptObject, we don't trust the
1972+
// static type. Global type inference is conservative for legacy js-interop
1973+
// methods, so we should be conservative here too.
1974+
if (_possiblyLegacyJavaScriptObject(
1975+
selector,
1976+
receiverType,
1977+
abstractValueDomain,
1978+
)) {
1979+
return value;
1980+
}
1981+
19701982
final narrowed = abstractValueDomain.intersection(value, staticType!);
19711983
// Preserve the sentinel in [value] since the static type does not include
19721984
// a sentinel and the intersection would remove it.
@@ -1975,6 +1987,22 @@ abstract class HInvokeDynamic extends HInvoke implements InstructionContext {
19751987
: narrowed;
19761988
}
19771989

1990+
static bool _possiblyLegacyJavaScriptObject(
1991+
Selector selector,
1992+
AbstractValue type,
1993+
AbstractValueDomain domain,
1994+
) {
1995+
// Legacy js-interop cannot override `[]`.
1996+
if (selector.isIndex) return false;
1997+
if (domain.isPrimitiveOrNull(type).isDefinitelyTrue) return false;
1998+
if (domain.isInterceptor(type).isDefinitelyFalse) return false;
1999+
// We get here for typed_data classes.
2000+
// TODO(sra): Test against LegacyJavaScriptObject explicitly.
2001+
// TODO(sra): Ensure that regular closures are not conflated with
2002+
// JavaScriptFunction which also implements `Function`.
2003+
return true;
2004+
}
2005+
19782006
@override
19792007
String toString() => 'invoke dynamic: selector=$selector, mask=$receiverType';
19802008

0 commit comments

Comments
 (0)