Skip to content

Commit 52da6a0

Browse files
natebiggsCommit Queue
authored andcommitted
[dart2wasm] Add support for overrideable function dispatch to handle signature changing param count.
We compare the signatures from the main module and the dynamic module. If the dynamic module has more parameters these must be from an override with extra optional paramters so we can provide the default value. Change-Id: I818187fde3e38812dcdae0a14bbeefec4ee91e51 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/416460 Reviewed-by: Martin Kustermann <[email protected]> Commit-Queue: Nate Biggs <[email protected]>
1 parent 697e8ce commit 52da6a0

File tree

5 files changed

+96
-16
lines changed

5 files changed

+96
-16
lines changed

pkg/dart2wasm/lib/dynamic_modules.dart

Lines changed: 75 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -572,9 +572,10 @@ class DynamicModuleInfo {
572572
final mainSelector = translator.dynamicMainModuleDispatchTable!
573573
.selectorForTarget(reference);
574574
signature = _getGeneralizedSignature(mainSelector);
575-
buildMain = buildSelectorBranch(reference, useUncheckedEntry, signature);
575+
buildMain =
576+
buildSelectorBranch(reference, useUncheckedEntry, mainSelector);
576577
buildDynamic =
577-
buildSelectorBranch(reference, useUncheckedEntry, signature);
578+
buildSelectorBranch(reference, useUncheckedEntry, mainSelector);
578579

579580
_createUpdateableFunction(
580581
mainSelector.id + BuiltinUpdatableFunctions.values.length,
@@ -690,8 +691,6 @@ class DynamicModuleInfo {
690691

691692
// The shared entry point to this selector has to use 'any' because the
692693
// selector's signature may change between compilations.
693-
// TODO(natebiggs): This doesn't account for overrides with extra
694-
// parameters.
695694
final generalizedSignature = translator.typesBuilder.defineFunction([
696695
...signature.inputs.map((e) => const w.RefType.any(nullable: true)),
697696
w.NumType.i32
@@ -701,26 +700,86 @@ class DynamicModuleInfo {
701700
return generalizedSignature;
702701
}
703702

704-
void Function(w.FunctionBuilder) buildSelectorBranch(Reference target,
705-
bool useUncheckedEntry, w.FunctionType generalizedSignature) {
703+
void Function(w.FunctionBuilder) buildSelectorBranch(
704+
Reference target, bool useUncheckedEntry, SelectorInfo mainSelector) {
706705
return (w.FunctionBuilder function) {
707-
final selector = translator.dispatchTable.selectorForTarget(target);
708-
final localSignature = selector.signature;
706+
final localSelector = translator.dispatchTable.selectorForTarget(target);
707+
final localSignature = localSelector.signature;
709708
final ib = function.body;
710709

711-
final offset = selector.targets(unchecked: useUncheckedEntry).offset;
710+
final offset = localSelector.targets(unchecked: useUncheckedEntry).offset;
712711

713712
if (offset == null) {
714713
ib.unreachable();
715714
ib.end();
716715
return;
717716
}
718717

719-
for (int i = 0; i < ib.locals.length - 1; i++) {
720-
ib.local_get(ib.locals[i]);
721-
translator.convertType(
722-
ib, generalizedSignature.inputs[i], localSignature.inputs[i]);
718+
final generalizedMainSignature = _getGeneralizedSignature(mainSelector);
719+
720+
final mainParamInfo = mainSelector.paramInfo;
721+
final localParamInfo = localSelector.paramInfo;
722+
723+
assert(mainParamInfo.takesContextOrReceiver ==
724+
localParamInfo.takesContextOrReceiver);
725+
726+
int localsIndex = 0;
727+
final takesContextOrReceiver = localParamInfo.takesContextOrReceiver;
728+
if (takesContextOrReceiver) {
729+
ib.local_get(ib.locals[localsIndex]);
730+
translator.convertType(ib, generalizedMainSignature.inputs[localsIndex],
731+
localSignature.inputs[localsIndex]);
732+
localsIndex++;
733+
}
734+
735+
final mainTypeParamCount = mainParamInfo.typeParamCount;
736+
assert(mainTypeParamCount == localParamInfo.typeParamCount);
737+
for (int i = 0; i < mainTypeParamCount; i++, localsIndex++) {
738+
ib.local_get(ib.locals[localsIndex]);
739+
translator.convertType(ib, generalizedMainSignature.inputs[localsIndex],
740+
localSignature.inputs[localsIndex]);
741+
}
742+
743+
final localPositionalCount = localParamInfo.positional.length;
744+
final mainPositionalCount = mainParamInfo.positional.length;
745+
assert(localPositionalCount >= mainPositionalCount);
746+
747+
for (int i = 0; i < localPositionalCount; i++, localsIndex++) {
748+
if (i < mainPositionalCount) {
749+
ib.local_get(ib.locals[localsIndex]);
750+
translator.convertType(
751+
ib,
752+
generalizedMainSignature.inputs[localsIndex],
753+
localSignature.inputs[localsIndex]);
754+
continue;
755+
}
756+
final constant = localParamInfo.positional[i]!;
757+
translator.constants.instantiateConstant(
758+
ib, constant, localSignature.inputs[localsIndex]);
759+
}
760+
761+
final localNamedCount = localParamInfo.named.length;
762+
final mainNamedCount = mainParamInfo.named.length;
763+
assert(localNamedCount >= mainNamedCount);
764+
765+
for (int i = 0; i < localNamedCount; i++, localsIndex++) {
766+
final name = localParamInfo.names[i];
767+
final mainIndex = mainParamInfo.nameIndex[name];
768+
if (mainIndex != null) {
769+
final mainLocalIndex =
770+
(takesContextOrReceiver ? 1 : 0) + mainTypeParamCount + mainIndex;
771+
ib.local_get(ib.locals[mainLocalIndex]);
772+
translator.convertType(
773+
ib,
774+
generalizedMainSignature.inputs[mainLocalIndex],
775+
localSignature.inputs[localsIndex]);
776+
continue;
777+
}
778+
final constant = localParamInfo.named[name]!;
779+
translator.constants.instantiateConstant(
780+
ib, constant, localSignature.inputs[localsIndex]);
723781
}
782+
724783
ib.local_get(ib.locals.last);
725784
if (isDynamicModule) {
726785
translator.callReference(translator.scopeClassId.reference, ib);
@@ -732,7 +791,7 @@ class DynamicModuleInfo {
732791
final table = translator.dispatchTable.getWasmTable(ib.module);
733792
ib.call_indirect(localSignature, table);
734793
translator.convertType(ib, localSignature.outputs.single,
735-
generalizedSignature.outputs.single);
794+
generalizedMainSignature.outputs.single);
736795
ib.end();
737796
};
738797
}
@@ -778,9 +837,9 @@ class DynamicModuleInfo {
778837
_callClassIdBranch(key, useUncheckedEntry, b, generalizedSignature,
779838
name: '#s${mainModuleSelector.id}_${mainModuleSelector.name}',
780839
buildMainMatch: buildSelectorBranch(
781-
interfaceTarget, useUncheckedEntry, generalizedSignature),
840+
interfaceTarget, useUncheckedEntry, mainModuleSelector),
782841
buildDynamicMatch: buildSelectorBranch(
783-
interfaceTarget, useUncheckedEntry, generalizedSignature),
842+
interfaceTarget, useUncheckedEntry, mainModuleSelector),
784843
skipDynamic: translator.isDynamicModule &&
785844
selector
786845
.targets(unchecked: useUncheckedEntry)

pkg/dynamic_modules/test/data/override_extra_params/dynamic_interface.yaml

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,12 @@ can-be-overridden:
99
- library: 'shared/shared.dart'
1010
class: 'Base'
1111
member: 'method1'
12+
- library: 'shared/shared.dart'
13+
class: 'Base'
14+
member: 'method2'
15+
- library: 'shared/shared.dart'
16+
class: 'Base'
17+
member: 'method3'
1218

1319
# TODO(sigmund): consider implying this for all extendable types.
1420
callable:
@@ -27,3 +33,6 @@ callable:
2733
member: 'override'
2834
- library: 'dart:core'
2935
class: 'num'
36+
- library: 'dart:core'
37+
class: 'String'
38+
member: 'get:length'

pkg/dynamic_modules/test/data/override_extra_params/main.dart

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,5 +12,7 @@ import 'shared/shared.dart' show Base;
1212
void main() async {
1313
final o = (await helper.load('entry1.dart')) as Base;
1414
Expect.equals(1, o.method1(1));
15+
Expect.equals(5, o.method2(2, j: 3));
16+
Expect.equals(5, o.method3<num>(2, j: 3));
1517
helper.done();
1618
}

pkg/dynamic_modules/test/data/override_extra_params/modules/entry1.dart

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,12 @@ import '../shared/shared.dart';
77
class Child extends Base {
88
@override
99
int method1(int i, [int? j]) => i + (j ?? 0);
10+
11+
@override
12+
int method2(int i, {int? j, String? a}) => i + (j ?? 0) + (a?.length ?? 0);
13+
14+
@override
15+
int method3<T>(int i, {int? j, T? a}) => i + (j ?? 0);
1016
}
1117

1218
@pragma('dyn-module:entry-point')

pkg/dynamic_modules/test/data/override_extra_params/shared/shared.dart

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,4 +4,8 @@
44

55
abstract class Base {
66
int method1(int i) => i;
7+
8+
int method2(int i, {int? j}) => i;
9+
10+
int method3<T>(int i, {int? j}) => i;
711
}

0 commit comments

Comments
 (0)