Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.

Commit bdf996a

Browse files
osa1Commit Queue
authored and
Commit Queue
committed
[dart2wasm] Refactor function collector:
- Move visitor interface to another class - Make work list and exports private. Add public methods for getting an export and popping the work list. Change-Id: I983337c5e325eb41f5e70526a338a769cf553326 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/268900 Reviewed-by: Aske Simon Christensen <[email protected]> Commit-Queue: Ömer Ağacan <[email protected]>
1 parent 3bcb194 commit bdf996a

File tree

2 files changed

+78
-66
lines changed

2 files changed

+78
-66
lines changed

pkg/dart2wasm/lib/functions.dart

Lines changed: 75 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -13,15 +13,15 @@ import 'package:wasm_builder/wasm_builder.dart' as w;
1313
/// This class is responsible for collecting import and export annotations.
1414
/// It also creates Wasm functions for Dart members and manages the worklist
1515
/// used to achieve tree shaking.
16-
class FunctionCollector extends MemberVisitor1<w.FunctionType, Reference> {
16+
class FunctionCollector {
1717
final Translator translator;
1818

1919
// Wasm function for each Dart function
2020
final Map<Reference, w.BaseFunction> _functions = {};
2121
// Names of exported functions
22-
final Map<Reference, String> exports = {};
22+
final Map<Reference, String> _exports = {};
2323
// Functions for which code has not yet been generated
24-
final List<Reference> worklist = [];
24+
final List<Reference> _worklist = [];
2525
// Class IDs for classes that are allocated somewhere in the program
2626
final Set<int> _allocatedClasses = {};
2727
// For each class ID, which functions should be added to the worklist if an
@@ -53,6 +53,10 @@ class FunctionCollector extends MemberVisitor1<w.FunctionType, Reference> {
5353
}
5454
}
5555

56+
bool isWorkListEmpty() => _worklist.isEmpty;
57+
58+
Reference popWorkList() => _worklist.removeLast();
59+
5660
void _importOrExport(Member member) {
5761
String? importName = translator.getPragma(member, "wasm:import");
5862
if (importName != null) {
@@ -63,7 +67,7 @@ class FunctionCollector extends MemberVisitor1<w.FunctionType, Reference> {
6367
String name = importName.substring(dot + 1);
6468
if (member is Procedure) {
6569
w.FunctionType ftype = _makeFunctionType(
66-
member.reference, member.function.returnType, null,
70+
translator, member.reference, member.function.returnType, null,
6771
isImportOrExport: true);
6872
_functions[member.reference] =
6973
m.importFunction(module, name, ftype, "$importName (import)");
@@ -78,20 +82,22 @@ class FunctionCollector extends MemberVisitor1<w.FunctionType, Reference> {
7882
}
7983

8084
void addExport(Reference target, String exportName) {
81-
exports[target] = exportName;
85+
_exports[target] = exportName;
8286
}
8387

88+
String? getExport(Reference target) => _exports[target];
89+
8490
void initialize() {
8591
// Add exports to the module and add exported functions to the worklist
86-
for (var export in exports.entries) {
92+
for (var export in _exports.entries) {
8793
Reference target = export.key;
8894
Member node = target.asMember;
8995
if (node is Procedure) {
90-
worklist.add(target);
96+
_worklist.add(target);
9197
assert(!node.isInstanceMember);
9298
assert(!node.isGetter);
9399
w.FunctionType ftype = _makeFunctionType(
94-
target, node.function.returnType, null,
100+
translator, target, node.function.returnType, null,
95101
isImportOrExport: true);
96102
w.DefinedFunction function = m.addFunction(ftype, "$node");
97103
_functions[target] = function;
@@ -116,14 +122,14 @@ class FunctionCollector extends MemberVisitor1<w.FunctionType, Reference> {
116122

117123
w.BaseFunction getFunction(Reference target) {
118124
return _functions.putIfAbsent(target, () {
119-
worklist.add(target);
125+
_worklist.add(target);
120126
if (target.isAsyncInnerReference) {
121127
w.BaseFunction outer = getFunction(target.asProcedure.reference);
122128
return addAsyncInnerFunctionFor(outer);
123129
}
124130
w.FunctionType ftype = target.isTearOffReference
125131
? translator.dispatchTable.selectorForTarget(target).signature
126-
: target.asMember.accept1(this, target);
132+
: target.asMember.accept1(_FunctionTypeGenerator(translator), target);
127133
return m.addFunction(ftype, "${target.asMember}");
128134
});
129135
}
@@ -157,6 +163,12 @@ class FunctionCollector extends MemberVisitor1<w.FunctionType, Reference> {
157163
}
158164
}
159165
}
166+
}
167+
168+
class _FunctionTypeGenerator extends MemberVisitor1<w.FunctionType, Reference> {
169+
final Translator translator;
170+
171+
_FunctionTypeGenerator(this.translator);
160172

161173
@override
162174
w.FunctionType defaultMember(Member node, Reference target) {
@@ -168,7 +180,7 @@ class FunctionCollector extends MemberVisitor1<w.FunctionType, Reference> {
168180
if (!node.isInstanceMember) {
169181
if (target == node.fieldReference) {
170182
// Static field initializer function
171-
return _makeFunctionType(target, node.type, null);
183+
return _makeFunctionType(translator, target, node.type, null);
172184
}
173185
String kind = target == node.setterReference ? "setter" : "getter";
174186
throw "No implicit $kind function for static field: $node";
@@ -181,70 +193,70 @@ class FunctionCollector extends MemberVisitor1<w.FunctionType, Reference> {
181193
assert(!node.isAbstract);
182194
return node.isInstanceMember
183195
? translator.dispatchTable.selectorForTarget(node.reference).signature
184-
: _makeFunctionType(target, node.function.returnType, null);
196+
: _makeFunctionType(translator, target, node.function.returnType, null);
185197
}
186198

187199
@override
188200
w.FunctionType visitConstructor(Constructor node, Reference target) {
189-
return _makeFunctionType(target, VoidType(),
201+
return _makeFunctionType(translator, target, VoidType(),
190202
translator.classInfo[node.enclosingClass]!.nonNullableType);
191203
}
204+
}
192205

193-
w.FunctionType _makeFunctionType(
194-
Reference target, DartType returnType, w.ValueType? receiverType,
195-
{bool isImportOrExport = false}) {
196-
Member member = target.asMember;
197-
int typeParamCount = 0;
198-
Iterable<DartType> params;
199-
if (member is Field) {
200-
params = [if (target.isImplicitSetter) member.setterType];
201-
} else {
202-
FunctionNode function = member.function!;
203-
typeParamCount = (member is Constructor
204-
? member.enclosingClass.typeParameters
205-
: function.typeParameters)
206-
.length;
207-
List<String> names = [for (var p in function.namedParameters) p.name!]
208-
..sort();
209-
Map<String, DartType> nameTypes = {
210-
for (var p in function.namedParameters) p.name!: p.type
211-
};
212-
params = [
213-
for (var p in function.positionalParameters) p.type,
214-
for (String name in names) nameTypes[name]!
215-
];
216-
function.positionalParameters.map((p) => p.type);
217-
}
206+
w.FunctionType _makeFunctionType(Translator translator, Reference target,
207+
DartType returnType, w.ValueType? receiverType,
208+
{bool isImportOrExport = false}) {
209+
Member member = target.asMember;
210+
int typeParamCount = 0;
211+
Iterable<DartType> params;
212+
if (member is Field) {
213+
params = [if (target.isImplicitSetter) member.setterType];
214+
} else {
215+
FunctionNode function = member.function!;
216+
typeParamCount = (member is Constructor
217+
? member.enclosingClass.typeParameters
218+
: function.typeParameters)
219+
.length;
220+
List<String> names = [for (var p in function.namedParameters) p.name!]
221+
..sort();
222+
Map<String, DartType> nameTypes = {
223+
for (var p in function.namedParameters) p.name!: p.type
224+
};
225+
params = [
226+
for (var p in function.positionalParameters) p.type,
227+
for (String name in names) nameTypes[name]!
228+
];
229+
function.positionalParameters.map((p) => p.type);
230+
}
218231

219-
List<w.ValueType> typeParameters = List.filled(typeParamCount,
220-
translator.classInfo[translator.typeClass]!.nonNullableType);
232+
List<w.ValueType> typeParameters = List.filled(typeParamCount,
233+
translator.classInfo[translator.typeClass]!.nonNullableType);
221234

222-
// The only reference types allowed as parameters and returns on imported
223-
// or exported functions for JS interop are `externref` and `funcref`.
224-
w.ValueType adjustExternalType(w.ValueType type) {
225-
if (isImportOrExport && type is w.RefType) {
226-
if (type.heapType.isSubtypeOf(w.HeapType.func)) {
227-
return w.RefType.func(nullable: true);
228-
}
229-
return w.RefType.extern(nullable: true);
235+
// The only reference types allowed as parameters and returns on imported or
236+
// exported functions for JS interop are `externref` and `funcref`.
237+
w.ValueType adjustExternalType(w.ValueType type) {
238+
if (isImportOrExport && type is w.RefType) {
239+
if (type.heapType.isSubtypeOf(w.HeapType.func)) {
240+
return w.RefType.func(nullable: true);
230241
}
231-
return type;
242+
return w.RefType.extern(nullable: true);
232243
}
244+
return type;
245+
}
233246

234-
List<w.ValueType> inputs = [];
235-
if (receiverType != null) {
236-
inputs.add(adjustExternalType(receiverType));
237-
}
238-
inputs.addAll(typeParameters.map(adjustExternalType));
239-
inputs.addAll(
240-
params.map((t) => adjustExternalType(translator.translateType(t))));
247+
List<w.ValueType> inputs = [];
248+
if (receiverType != null) {
249+
inputs.add(adjustExternalType(receiverType));
250+
}
251+
inputs.addAll(typeParameters.map(adjustExternalType));
252+
inputs.addAll(
253+
params.map((t) => adjustExternalType(translator.translateType(t))));
241254

242-
List<w.ValueType> outputs = returnType is VoidType
243-
? member.function?.asyncMarker == AsyncMarker.Async
244-
? [adjustExternalType(translator.topInfo.nullableType)]
245-
: const []
246-
: [adjustExternalType(translator.translateType(returnType))];
255+
List<w.ValueType> outputs = returnType is VoidType
256+
? member.function?.asyncMarker == AsyncMarker.Async
257+
? [adjustExternalType(translator.topInfo.nullableType)]
258+
: const []
259+
: [adjustExternalType(translator.translateType(returnType))];
247260

248-
return m.addFunctionType(inputs, outputs);
249-
}
261+
return translator.m.addFunctionType(inputs, outputs);
250262
}

pkg/dart2wasm/lib/translator.dart

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -402,8 +402,8 @@ class Translator {
402402
m.exportFunction("\$getMain", generateGetMain(mainFunction));
403403

404404
functions.initialize();
405-
while (functions.worklist.isNotEmpty) {
406-
Reference reference = functions.worklist.removeLast();
405+
while (!functions.isWorkListEmpty()) {
406+
Reference reference = functions.popWorkList();
407407
Member member = reference.asMember;
408408
var function =
409409
functions.getExistingFunction(reference) as w.DefinedFunction;
@@ -421,7 +421,7 @@ class Translator {
421421
? canonicalName
422422
: "${member.enclosingLibrary.importUri} $canonicalName";
423423

424-
String? exportName = functions.exports[reference];
424+
String? exportName = functions.getExport(reference);
425425

426426
if (options.printKernel || options.printWasm) {
427427
if (exportName != null) {

0 commit comments

Comments
 (0)