0889fdd883
Not all instance members are necessarily called via dispatch table
calls.
If we know an instance member isn't a target of any dispatch table call
we can choose the representation for that member on its own (instead of
using the selector representation - which is a upper-bounding of all
implementations of that selector).
This CL requires all call sites to obtain target signature & parameter
information via one of
* `Translator.{signature,paramInfo}ForDirectCall`
* `Translator.{signature,paramInfo}ForDispatchTableCall`
=> Those methods handle the case of calling a method
a) via dispatch table call
b) via direct call where
b.1) target can also be called via dispatch table
b.2) target cannot be called via dispatch table
In a follow up CL we're going to reland [0] which will shrink the set of
instance methods that are callable via dispatch table calls (e.g.
members that are only called via `super.*()` can use their own
representation selection instead of clustering it with methods of same
name that can be called via dispatch table).
The regression test added in this CL is a test that will fail with [0]
without this CL.
[0] https://dart-review.googlesource.com/c/sdk/+/374320
Change-Id: I5184cf6e712f33a894fd1463a5903128f87be92f
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/375280
Commit-Queue: Martin Kustermann <kustermann@google.com>
Reviewed-by: Slava Egorov <vegorov@google.com>
54 lines
904 B
Dart
54 lines
904 B
Dart
// Copyright (c) 2024, the Dart project authors. Please see the AUTHORS file
|
|
// for details. All rights reserved. Use of this source code is governed by a
|
|
// BSD-style license that can be found in the LICENSE file.
|
|
|
|
import 'package:expect/expect.dart';
|
|
|
|
abstract class I {
|
|
Base foo();
|
|
Base get bar;
|
|
}
|
|
|
|
abstract class A extends I {
|
|
Base foo() => Sub1();
|
|
Base get bar => Sub1();
|
|
}
|
|
|
|
class B1 extends A {
|
|
Base foo() {
|
|
print(super.foo());
|
|
return Sub2();
|
|
}
|
|
|
|
Base get bar {
|
|
print(super.bar);
|
|
return Sub2();
|
|
}
|
|
}
|
|
|
|
class B2 extends A {
|
|
Base foo() {
|
|
print(super.foo());
|
|
return Sub3();
|
|
}
|
|
|
|
Base get bar {
|
|
print(super.bar);
|
|
return Sub3();
|
|
}
|
|
}
|
|
|
|
abstract class Base {}
|
|
|
|
class Sub1 extends Base {}
|
|
|
|
class Sub2 extends Base {}
|
|
|
|
class Sub3 extends Base {}
|
|
|
|
main() {
|
|
final l = [B1(), B2()];
|
|
Expect.isTrue(l[0].foo() is Sub2);
|
|
Expect.isTrue(l[0].bar is Sub2);
|
|
}
|