Skip to content

Commit 0332c70

Browse files
joshualittCommit Queue
authored and
Commit Queue
committed
[wasm_builder] Lift import / definition restrictions.
Change-Id: Id0651e8e2ad270be5cc3788d361257769088faa6 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/316627 Reviewed-by: Ömer Ağacan <[email protected]> Commit-Queue: Joshua Litt <[email protected]>
1 parent 4e6ed30 commit 0332c70

18 files changed

+224
-109
lines changed

pkg/wasm_builder/lib/src/builder/builder.dart

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22
// for details. All rights reserved. Use of this source code is governed by a
33
// BSD-style license that can be found in the LICENSE file.
44

5+
import '../ir/ir.dart' as ir;
6+
57
export 'data_segments.dart' show DataSegmentBuilder, DataSegmentsBuilder;
68
export 'exports.dart' show ExportsBuilder;
79
export 'globals.dart' show GlobalsBuilder, GlobalBuilder;
@@ -20,3 +22,15 @@ mixin Builder<T> {
2022

2123
T forceBuild();
2224
}
25+
26+
// TODO(joshualitt): Share code when we have mixin composition.
27+
mixin IndexableBuilder<T> implements Builder<T>, ir.Indexable {
28+
@override
29+
T? _built;
30+
31+
@override
32+
T build() => _built ??= forceBuild();
33+
34+
@override
35+
T forceBuild();
36+
}

pkg/wasm_builder/lib/src/builder/function.dart

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,8 @@
55
part of 'functions.dart';
66

77
/// A function defined in a module.
8-
class FunctionBuilder extends ir.BaseFunction with Builder<ir.DefinedFunction> {
8+
class FunctionBuilder extends ir.BaseFunction
9+
with IndexableBuilder<ir.DefinedFunction> {
910
/// All local variables defined in the function, including its inputs.
1011
List<ir.Local> get locals => body.locals;
1112

@@ -26,8 +27,8 @@ class FunctionBuilder extends ir.BaseFunction with Builder<ir.DefinedFunction> {
2627

2728
@override
2829
ir.DefinedFunction forceBuild() =>
29-
ir.DefinedFunction(body.build(), index, type, functionName);
30+
ir.DefinedFunction(body.build(), finalizableIndex, type, functionName);
3031

3132
@override
32-
String toString() => exportedName ?? "#$index";
33+
String toString() => exportedName ?? "#$finalizableIndex";
3334
}

pkg/wasm_builder/lib/src/builder/functions.dart

Lines changed: 11 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
import '../ir/ir.dart' as ir;
66
import 'builder.dart';
7+
import 'util.dart';
78

89
part 'function.dart';
910

@@ -14,14 +15,10 @@ class FunctionsBuilder with Builder<ir.Functions> {
1415
final _functionBuilders = <FunctionBuilder>[];
1516
final _importedFunctions = <ir.Import>[];
1617
int _nameCount = 0;
17-
bool _anyFunctionsDefined = false;
1818
ir.BaseFunction? _start;
1919

2020
FunctionsBuilder(this._module);
2121

22-
/// This is guarded by [_anyFunctionsDefined].
23-
int get _index => _importedFunctions.length + _functionBuilders.length;
24-
2522
set start(ir.BaseFunction init) {
2623
assert(_start == null);
2724
_start = init;
@@ -39,8 +36,8 @@ class FunctionsBuilder with Builder<ir.Functions> {
3936
/// The [DefinedFunction.body] must be completed (including the terminating
4037
/// `end`) before the module can be serialized.
4138
FunctionBuilder define(ir.FunctionType type, [String? name]) {
42-
_anyFunctionsDefined = true;
43-
final function = FunctionBuilder(_module, _index, type, name);
39+
final function =
40+
FunctionBuilder(_module, ir.FinalizableIndex(), type, name);
4441
_functionBuilders.add(function);
4542
_addName(name, function);
4643
return function;
@@ -52,17 +49,18 @@ class FunctionsBuilder with Builder<ir.Functions> {
5249
/// using [FunctionsBuilder.define].
5350
ir.ImportedFunction import(String module, String name, ir.FunctionType type,
5451
[String? functionName]) {
55-
if (_anyFunctionsDefined) {
56-
throw "All function imports must be specified before any definitions.";
57-
}
58-
final function =
59-
ir.ImportedFunction(module, name, _index, type, functionName);
52+
final function = ir.ImportedFunction(
53+
module, name, ir.FinalizableIndex(), type, functionName);
6054
_importedFunctions.add(function);
6155
_addName(functionName, function);
6256
return function;
6357
}
6458

6559
@override
66-
ir.Functions forceBuild() => ir.Functions(_start, _importedFunctions,
67-
_functionBuilders.map((f) => f.build()).toList(), _functions, _nameCount);
60+
ir.Functions forceBuild() {
61+
final built = finalizeImportsAndBuilders<ir.DefinedFunction>(
62+
_importedFunctions, _functionBuilders);
63+
return ir.Functions(
64+
_start, _importedFunctions, built, _functions, _nameCount);
65+
}
6866
}

pkg/wasm_builder/lib/src/builder/global.dart

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
part of 'globals.dart';
66

77
/// A global variable defined in a module.
8-
class GlobalBuilder extends ir.Global with Builder<ir.DefinedGlobal> {
8+
class GlobalBuilder extends ir.Global with IndexableBuilder<ir.DefinedGlobal> {
99
final InstructionsBuilder initializer;
1010

1111
GlobalBuilder(ModuleBuilder module, super.index, super.type)
@@ -14,5 +14,5 @@ class GlobalBuilder extends ir.Global with Builder<ir.DefinedGlobal> {
1414

1515
@override
1616
ir.DefinedGlobal forceBuild() =>
17-
ir.DefinedGlobal(initializer.build(), index, type);
17+
ir.DefinedGlobal(initializer.build(), finalizableIndex, type);
1818
}

pkg/wasm_builder/lib/src/builder/globals.dart

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

55
import '../ir/ir.dart' as ir;
66
import 'builder.dart';
7+
import 'util.dart';
78

89
part 'global.dart';
910

1011
class GlobalsBuilder with Builder<ir.Globals> {
1112
final ModuleBuilder _module;
1213
final _importedGlobals = <ir.Import>[];
1314
final _globalBuilders = <GlobalBuilder>[];
14-
bool _anyGlobalsDefined = false;
1515

1616
GlobalsBuilder(this._module);
1717

18-
/// This is guarded by [_anyGlobalsDefined].
19-
int get _index => _importedGlobals.length + _globalBuilders.length;
20-
2118
/// Defines a new global variable in this module.
2219
GlobalBuilder define(ir.GlobalType type) {
23-
_anyGlobalsDefined = true;
24-
final global = GlobalBuilder(_module, _index, type);
20+
final global = GlobalBuilder(_module, ir.FinalizableIndex(), type);
2521
_globalBuilders.add(global);
2622
return global;
2723
}
@@ -31,15 +27,15 @@ class GlobalsBuilder with Builder<ir.Globals> {
3127
/// All imported globals must be specified before any globals are declared
3228
/// using [Globals.define].
3329
ir.ImportedGlobal import(String module, String name, ir.GlobalType type) {
34-
if (_anyGlobalsDefined) {
35-
throw "All global imports must be specified before any definitions.";
36-
}
37-
final global = ir.ImportedGlobal(module, name, _index, type);
30+
final global = ir.ImportedGlobal(module, name, ir.FinalizableIndex(), type);
3831
_importedGlobals.add(global);
3932
return global;
4033
}
4134

4235
@override
43-
ir.Globals forceBuild() => ir.Globals(
44-
_importedGlobals, _globalBuilders.map((g) => g.build()).toList());
36+
ir.Globals forceBuild() {
37+
final built = finalizeImportsAndBuilders<ir.DefinedGlobal>(
38+
_importedGlobals, _globalBuilders);
39+
return ir.Globals(_importedGlobals, built);
40+
}
4541
}

0 commit comments

Comments
 (0)