[dart2wasm] Dart format pkg/wasm_builder
The change in [0] increased the language version of pkg/dart2wasm. That in return changes how the package is formatted by the autoformatter. This CL runs now the formatter to re-format the code. Unfortunately this makes blame lists worse. But not doing it will make us have to disable auto-formatting before saving files which is very annoying. [0] https://dart-review.googlesource.com/c/sdk/+/487944 Change-Id: Ie3cbdc58bbd7f5aba187470554b7c958719fa795 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/496940 Reviewed-by: Slava Egorov <vegorov@google.com> Commit-Queue: Martin Kustermann <kustermann@google.com>
This commit is contained in:
committed by
dart-scoped@luci-project-accounts.iam.gserviceaccount.com
parent
0b7c68fad4
commit
4201b2677e
@@ -18,8 +18,12 @@ class SourceMapping {
|
||||
SourceMapping._(this.instructionOffset, this.sourceInfo);
|
||||
|
||||
SourceMapping(
|
||||
this.instructionOffset, Uri fileUri, int line, int col, String? name)
|
||||
: sourceInfo = SourceInfo(fileUri, line, col, name);
|
||||
this.instructionOffset,
|
||||
Uri fileUri,
|
||||
int line,
|
||||
int col,
|
||||
String? name,
|
||||
) : sourceInfo = SourceInfo(fileUri, line, col, name);
|
||||
|
||||
SourceMapping.unmapped(this.instructionOffset) : sourceInfo = null;
|
||||
|
||||
@@ -81,10 +85,9 @@ class SourceMapSerializer {
|
||||
|
||||
void copyMappings(SourceMapSerializer other, int offset) {
|
||||
for (final mapping in other.mappings) {
|
||||
mappings.add(SourceMapping._(
|
||||
mapping.instructionOffset + offset,
|
||||
mapping.sourceInfo,
|
||||
));
|
||||
mappings.add(
|
||||
SourceMapping._(mapping.instructionOffset + offset, mapping.sourceInfo),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -148,16 +151,22 @@ Map<String, Object?> _sourceMapToJson(List<SourceMapping> mappings) {
|
||||
|
||||
first = false;
|
||||
|
||||
lastTargetColumn =
|
||||
_encodeVLQ(mappingsStr, mapping.instructionOffset, lastTargetColumn);
|
||||
lastTargetColumn = _encodeVLQ(
|
||||
mappingsStr,
|
||||
mapping.instructionOffset,
|
||||
lastTargetColumn,
|
||||
);
|
||||
|
||||
if (sourceInfo != null) {
|
||||
final sourceIndex = sourceIndices[sourceInfo.fileUri]!;
|
||||
|
||||
lastSourceIndex = _encodeVLQ(mappingsStr, sourceIndex, lastSourceIndex);
|
||||
lastSourceLine = _encodeVLQ(mappingsStr, sourceInfo.line, lastSourceLine);
|
||||
lastSourceColumn =
|
||||
_encodeVLQ(mappingsStr, sourceInfo.col, lastSourceColumn);
|
||||
lastSourceColumn = _encodeVLQ(
|
||||
mappingsStr,
|
||||
sourceInfo.col,
|
||||
lastSourceColumn,
|
||||
);
|
||||
|
||||
if (sourceInfo.name != null) {
|
||||
final nameIndex = nameIndices[sourceInfo.name!]!;
|
||||
@@ -202,5 +211,6 @@ int _encodeVLQ(StringSink output, int value, int offset) {
|
||||
const int _vlqBaseShift = 5;
|
||||
const int _vlqBaseMask = (1 << 5) - 1;
|
||||
const int _vlqContinuationBit = 1 << 5;
|
||||
const String _base64Digits = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmn'
|
||||
const String _base64Digits =
|
||||
'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmn'
|
||||
'opqrstuvwxyz0123456789+/';
|
||||
|
||||
@@ -13,8 +13,11 @@ class DataSegmentBuilder extends ir.BaseDataSegment
|
||||
final BytesBuilder content;
|
||||
|
||||
DataSegmentBuilder(
|
||||
super.index, Uint8List initialContent, super.memory, super.offset)
|
||||
: content = BytesBuilder()..add(initialContent);
|
||||
super.index,
|
||||
Uint8List initialContent,
|
||||
super.memory,
|
||||
super.offset,
|
||||
) : content = BytesBuilder()..add(initialContent);
|
||||
|
||||
bool get isActive => memory != null;
|
||||
bool get isPassive => memory == null;
|
||||
@@ -24,8 +27,9 @@ class DataSegmentBuilder extends ir.BaseDataSegment
|
||||
/// Append content to the data segment.
|
||||
void append(Uint8List data) {
|
||||
content.add(data);
|
||||
assert(isPassive ||
|
||||
offset! >= 0 && offset! + content.length <= memory!.minSize);
|
||||
assert(
|
||||
isPassive || offset! >= 0 && offset! + content.length <= memory!.minSize,
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
|
||||
@@ -21,15 +21,25 @@ class DataSegmentsBuilder with Builder<ir.DataSegments> {
|
||||
///
|
||||
/// If [initialContent] is specified, it defines the initial content of the
|
||||
/// segment. The content can be extended later.
|
||||
DataSegmentBuilder define(
|
||||
[Uint8List? initialContent, ir.Memory? memory, int? offset]) {
|
||||
DataSegmentBuilder define([
|
||||
Uint8List? initialContent,
|
||||
ir.Memory? memory,
|
||||
int? offset,
|
||||
]) {
|
||||
initialContent ??= Uint8List(0);
|
||||
assert((memory != null) == (offset != null));
|
||||
assert(memory == null ||
|
||||
offset! >= 0 &&
|
||||
offset + initialContent.length <= memory.minSize * memoryBlockSize);
|
||||
assert(
|
||||
memory == null ||
|
||||
offset! >= 0 &&
|
||||
offset + initialContent.length <=
|
||||
memory.minSize * memoryBlockSize,
|
||||
);
|
||||
final builder = DataSegmentBuilder(
|
||||
_dataSegmentBuilders.length, initialContent, memory, offset);
|
||||
_dataSegmentBuilders.length,
|
||||
initialContent,
|
||||
memory,
|
||||
offset,
|
||||
);
|
||||
_dataSegmentBuilders.add(builder);
|
||||
return builder;
|
||||
}
|
||||
|
||||
@@ -13,8 +13,9 @@ class ElementsBuilder with Builder<ir.Elements> {
|
||||
final _functionTableBuilders = <ir.Table, ActiveFunctionSegmentBuilder>{};
|
||||
final _expressionTableBuilders = <ir.Table, ActiveExpressionSegmentBuilder>{};
|
||||
|
||||
late final declarativeSegmentBuilder =
|
||||
DeclarativeSegmentBuilder(_moduleBuilder);
|
||||
late final declarativeSegmentBuilder = DeclarativeSegmentBuilder(
|
||||
_moduleBuilder,
|
||||
);
|
||||
|
||||
ElementsBuilder(this._moduleBuilder);
|
||||
|
||||
@@ -25,14 +26,19 @@ class ElementsBuilder with Builder<ir.Elements> {
|
||||
assert(table.type.isSubtypeOf(ir.RefType.func(nullable: true)));
|
||||
assert(table.enclosingModule == _moduleBuilder.module);
|
||||
return _functionTableBuilders.putIfAbsent(
|
||||
table, () => ActiveFunctionSegmentBuilder(table));
|
||||
table,
|
||||
() => ActiveFunctionSegmentBuilder(table),
|
||||
);
|
||||
}
|
||||
|
||||
ActiveExpressionSegmentBuilder activeExpressionSegmentBuilderFor(
|
||||
ir.Table table) {
|
||||
ir.Table table,
|
||||
) {
|
||||
assert(table.enclosingModule == _moduleBuilder.module);
|
||||
return _expressionTableBuilders.putIfAbsent(
|
||||
table, () => ActiveExpressionSegmentBuilder(table));
|
||||
table,
|
||||
() => ActiveExpressionSegmentBuilder(table),
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
@@ -77,8 +83,10 @@ class ActiveFunctionSegmentBuilder with Builder<List<ir.ActiveElementSegment>> {
|
||||
|
||||
void setFunctionAt(int index, ir.BaseFunction function) {
|
||||
assert(function.enclosingModule == table.enclosingModule);
|
||||
assert(table.maxSize == null || index < table.maxSize!,
|
||||
'Index $index greater than max table size ${table.maxSize}');
|
||||
assert(
|
||||
table.maxSize == null || index < table.maxSize!,
|
||||
'Index $index greater than max table size ${table.maxSize}',
|
||||
);
|
||||
_functions[index] = function;
|
||||
table.minSize = math.max(table.minSize, index + 1);
|
||||
}
|
||||
@@ -129,8 +137,10 @@ class ActiveExpressionSegmentBuilder
|
||||
|
||||
void setExpressionAt(int index, InstructionsBuilder init) {
|
||||
assert(init.moduleBuilder.module == table.enclosingModule);
|
||||
assert(table.maxSize == null || index < table.maxSize!,
|
||||
'Index $index greater than max table size ${table.maxSize}');
|
||||
assert(
|
||||
table.maxSize == null || index < table.maxSize!,
|
||||
'Index $index greater than max table size ${table.maxSize}',
|
||||
);
|
||||
_expressions[index] = init;
|
||||
table.minSize = math.max(table.minSize, index + 1);
|
||||
}
|
||||
|
||||
@@ -17,9 +17,11 @@ class FunctionBuilder extends ir.BaseFunction
|
||||
late InstructionsBuilder _body;
|
||||
|
||||
FunctionBuilder(
|
||||
this.moduleBuilder, ir.FinalizableIndex index, ir.FunctionType type,
|
||||
[String? functionName])
|
||||
: super(moduleBuilder.module, index, type, functionName) {
|
||||
this.moduleBuilder,
|
||||
ir.FinalizableIndex index,
|
||||
ir.FunctionType type, [
|
||||
String? functionName,
|
||||
]) : super(moduleBuilder.module, index, type, functionName) {
|
||||
_body = InstructionsBuilder(moduleBuilder, type.inputs, type.outputs);
|
||||
}
|
||||
|
||||
@@ -31,8 +33,12 @@ class FunctionBuilder extends ir.BaseFunction
|
||||
|
||||
@override
|
||||
ir.DefinedFunction forceBuild() => ir.DefinedFunction(
|
||||
enclosingModule, body.build(), finalizableIndex, type, functionName)
|
||||
..isPure = isPure;
|
||||
enclosingModule,
|
||||
body.build(),
|
||||
finalizableIndex,
|
||||
type,
|
||||
functionName,
|
||||
)..isPure = isPure;
|
||||
|
||||
@override
|
||||
String toString() => functionName ?? "#$finalizableIndex";
|
||||
|
||||
@@ -29,17 +29,31 @@ class FunctionsBuilder with Builder<ir.Functions> {
|
||||
/// The [ir.DefinedFunction.body] must be completed (including the terminating
|
||||
/// `end`) before the module can be serialized.
|
||||
FunctionBuilder define(ir.FunctionType type, [String? name]) {
|
||||
final function =
|
||||
FunctionBuilder(_moduleBuilder, ir.FinalizableIndex(), type, name);
|
||||
final function = FunctionBuilder(
|
||||
_moduleBuilder,
|
||||
ir.FinalizableIndex(),
|
||||
type,
|
||||
name,
|
||||
);
|
||||
_functionBuilders.add(function);
|
||||
return function;
|
||||
}
|
||||
|
||||
/// Import a function into the module.
|
||||
ir.ImportedFunction import(String module, String name, ir.FunctionType type,
|
||||
[String? functionName]) {
|
||||
final function = ir.ImportedFunction(_moduleBuilder.module, module, name,
|
||||
ir.FinalizableIndex(), type, functionName);
|
||||
ir.ImportedFunction import(
|
||||
String module,
|
||||
String name,
|
||||
ir.FunctionType type, [
|
||||
String? functionName,
|
||||
]) {
|
||||
final function = ir.ImportedFunction(
|
||||
_moduleBuilder.module,
|
||||
module,
|
||||
name,
|
||||
ir.FinalizableIndex(),
|
||||
type,
|
||||
functionName,
|
||||
);
|
||||
_importedFunctions.add(function);
|
||||
return function;
|
||||
}
|
||||
@@ -47,7 +61,9 @@ class FunctionsBuilder with Builder<ir.Functions> {
|
||||
@override
|
||||
ir.Functions forceBuild() {
|
||||
final built = finalizeImportsAndBuilders<ir.DefinedFunction>(
|
||||
_importedFunctions, _functionBuilders);
|
||||
_importedFunctions,
|
||||
_functionBuilders,
|
||||
);
|
||||
return ir.Functions(_importedFunctions, built);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,13 +11,21 @@ class GlobalBuilder extends ir.Global with IndexableBuilder<ir.DefinedGlobal> {
|
||||
final InstructionsBuilder initializer;
|
||||
|
||||
GlobalBuilder(
|
||||
this.moduleBuilder, ir.FinalizableIndex index, ir.GlobalType type,
|
||||
[String? globalName])
|
||||
: initializer = InstructionsBuilder(moduleBuilder, [], [type.type],
|
||||
constantExpression: true),
|
||||
super(moduleBuilder.module, index, type, globalName);
|
||||
this.moduleBuilder,
|
||||
ir.FinalizableIndex index,
|
||||
ir.GlobalType type, [
|
||||
String? globalName,
|
||||
]) : initializer = InstructionsBuilder(moduleBuilder, [], [
|
||||
type.type,
|
||||
], constantExpression: true),
|
||||
super(moduleBuilder.module, index, type, globalName);
|
||||
|
||||
@override
|
||||
ir.DefinedGlobal forceBuild() => ir.DefinedGlobal(
|
||||
enclosingModule, initializer.build(), finalizableIndex, type, globalName);
|
||||
enclosingModule,
|
||||
initializer.build(),
|
||||
finalizableIndex,
|
||||
type,
|
||||
globalName,
|
||||
);
|
||||
}
|
||||
|
||||
@@ -27,8 +27,12 @@ class GlobalsBuilder with Builder<ir.Globals> {
|
||||
|
||||
/// Defines a new global variable in this module.
|
||||
GlobalBuilder define(ir.GlobalType type, [String? name]) {
|
||||
final global =
|
||||
GlobalBuilder(_moduleBuilder, ir.FinalizableIndex(), type, name);
|
||||
final global = GlobalBuilder(
|
||||
_moduleBuilder,
|
||||
ir.FinalizableIndex(),
|
||||
type,
|
||||
name,
|
||||
);
|
||||
_globalBuilders.add(global);
|
||||
return global;
|
||||
}
|
||||
@@ -36,7 +40,12 @@ class GlobalsBuilder with Builder<ir.Globals> {
|
||||
/// Imports a global variable into this module.
|
||||
ir.ImportedGlobal import(String module, String name, ir.GlobalType type) {
|
||||
final global = ir.ImportedGlobal(
|
||||
_moduleBuilder.module, module, name, ir.FinalizableIndex(), type);
|
||||
_moduleBuilder.module,
|
||||
module,
|
||||
name,
|
||||
ir.FinalizableIndex(),
|
||||
type,
|
||||
);
|
||||
_importedGlobals.add(global);
|
||||
return global;
|
||||
}
|
||||
@@ -62,8 +71,10 @@ class GlobalsBuilder with Builder<ir.Globals> {
|
||||
dfs(g);
|
||||
}
|
||||
|
||||
final built =
|
||||
finalizeImportsAndBuilders<ir.DefinedGlobal>(_importedGlobals, order);
|
||||
final built = finalizeImportsAndBuilders<ir.DefinedGlobal>(
|
||||
_importedGlobals,
|
||||
order,
|
||||
);
|
||||
return ir.Globals(_importedGlobals, built);
|
||||
}
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -17,16 +17,33 @@ class MemoriesBuilder with Builder<ir.Memories> {
|
||||
/// Add a new memory to the module.
|
||||
ir.DefinedMemory define(bool shared, int minSize, [int? maxSize]) {
|
||||
final memory = ir.DefinedMemory(
|
||||
_module, ir.FinalizableIndex(), shared, minSize, maxSize);
|
||||
_module,
|
||||
ir.FinalizableIndex(),
|
||||
shared,
|
||||
minSize,
|
||||
maxSize,
|
||||
);
|
||||
_definedMemories.add(memory);
|
||||
return memory;
|
||||
}
|
||||
|
||||
/// Imports a memory into this module.
|
||||
ir.ImportedMemory import(String module, String name, bool shared, int minSize,
|
||||
[int? maxSize]) {
|
||||
ir.ImportedMemory import(
|
||||
String module,
|
||||
String name,
|
||||
bool shared,
|
||||
int minSize, [
|
||||
int? maxSize,
|
||||
]) {
|
||||
final memory = ir.ImportedMemory(
|
||||
_module, module, name, ir.FinalizableIndex(), shared, minSize, maxSize);
|
||||
_module,
|
||||
module,
|
||||
name,
|
||||
ir.FinalizableIndex(),
|
||||
shared,
|
||||
minSize,
|
||||
maxSize,
|
||||
);
|
||||
_importedMemories.add(memory);
|
||||
return memory;
|
||||
}
|
||||
|
||||
@@ -41,8 +41,12 @@ class ModuleBuilder with Builder<ir.Module> {
|
||||
/// bytes to watch. When the module is serialized, the stack traces leading
|
||||
/// to the production of all watched bytes are printed. This can be used to
|
||||
/// debug runtime errors happening at specific offsets within the module.
|
||||
ModuleBuilder(this.moduleName, this.sourceMapUrl,
|
||||
{ModuleBuilder? parent, this.watchPoints = const []}) {
|
||||
ModuleBuilder(
|
||||
this.moduleName,
|
||||
this.sourceMapUrl, {
|
||||
ModuleBuilder? parent,
|
||||
this.watchPoints = const [],
|
||||
}) {
|
||||
types = TypesBuilder(this, parent: parent?.types);
|
||||
}
|
||||
|
||||
@@ -64,8 +68,10 @@ class ModuleBuilder with Builder<ir.Module> {
|
||||
return true;
|
||||
}
|
||||
|
||||
FunctionBuilder get startFunction => _startFunction ??=
|
||||
functions.define(types.defineFunction(const [], const []), "#init");
|
||||
FunctionBuilder get startFunction => _startFunction ??= functions.define(
|
||||
types.defineFunction(const [], const []),
|
||||
"#init",
|
||||
);
|
||||
|
||||
@override
|
||||
ir.Module forceBuild() {
|
||||
@@ -85,21 +91,21 @@ class ModuleBuilder with Builder<ir.Module> {
|
||||
finalTables.imported,
|
||||
finalMemories.imported,
|
||||
);
|
||||
return module
|
||||
..initialize(
|
||||
moduleName,
|
||||
finalFunctions,
|
||||
_startFunction,
|
||||
finalTables,
|
||||
finalElements,
|
||||
finalTags,
|
||||
finalMemories,
|
||||
exports.build(),
|
||||
finalGlobals,
|
||||
types.build(),
|
||||
dataSegments.build(),
|
||||
imports,
|
||||
watchPoints,
|
||||
sourceMapUrl);
|
||||
return module..initialize(
|
||||
moduleName,
|
||||
finalFunctions,
|
||||
_startFunction,
|
||||
finalTables,
|
||||
finalElements,
|
||||
finalTags,
|
||||
finalMemories,
|
||||
exports.build(),
|
||||
finalGlobals,
|
||||
types.build(),
|
||||
dataSegments.build(),
|
||||
imports,
|
||||
watchPoints,
|
||||
sourceMapUrl,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,11 +9,20 @@ import 'builder.dart';
|
||||
class TableBuilder extends ir.Table with IndexableBuilder<ir.DefinedTable> {
|
||||
final ModuleBuilder moduleBuilder;
|
||||
|
||||
TableBuilder(this.moduleBuilder, ir.FinalizableIndex index, ir.RefType type,
|
||||
int minSize, int? maxSize)
|
||||
: super(moduleBuilder.module, index, type, minSize, maxSize);
|
||||
TableBuilder(
|
||||
this.moduleBuilder,
|
||||
ir.FinalizableIndex index,
|
||||
ir.RefType type,
|
||||
int minSize,
|
||||
int? maxSize,
|
||||
) : super(moduleBuilder.module, index, type, minSize, maxSize);
|
||||
|
||||
@override
|
||||
ir.DefinedTable forceBuild() => ir.DefinedTable(
|
||||
enclosingModule, finalizableIndex, type, minSize, maxSize);
|
||||
enclosingModule,
|
||||
finalizableIndex,
|
||||
type,
|
||||
minSize,
|
||||
maxSize,
|
||||
);
|
||||
}
|
||||
|
||||
@@ -17,17 +17,33 @@ class TablesBuilder with Builder<ir.Tables> {
|
||||
/// Defines a new table in this module.
|
||||
TableBuilder define(ir.RefType type, int minSize, [int? maxSize]) {
|
||||
final table = TableBuilder(
|
||||
_moduleBuilder, ir.FinalizableIndex(), type, minSize, maxSize);
|
||||
_moduleBuilder,
|
||||
ir.FinalizableIndex(),
|
||||
type,
|
||||
minSize,
|
||||
maxSize,
|
||||
);
|
||||
_tableBuilders.add(table);
|
||||
return table;
|
||||
}
|
||||
|
||||
/// Imports a table into this module.
|
||||
ir.ImportedTable import(
|
||||
String module, String name, ir.RefType type, int minSize,
|
||||
[int? maxSize]) {
|
||||
final table = ir.ImportedTable(_moduleBuilder.module, module, name,
|
||||
ir.FinalizableIndex(), type, minSize, maxSize);
|
||||
String module,
|
||||
String name,
|
||||
ir.RefType type,
|
||||
int minSize, [
|
||||
int? maxSize,
|
||||
]) {
|
||||
final table = ir.ImportedTable(
|
||||
_moduleBuilder.module,
|
||||
module,
|
||||
name,
|
||||
ir.FinalizableIndex(),
|
||||
type,
|
||||
minSize,
|
||||
maxSize,
|
||||
);
|
||||
_importedTables.add(table);
|
||||
return table;
|
||||
}
|
||||
@@ -35,7 +51,9 @@ class TablesBuilder with Builder<ir.Tables> {
|
||||
@override
|
||||
ir.Tables forceBuild() {
|
||||
final built = finalizeImportsAndBuilders<ir.DefinedTable>(
|
||||
_importedTables, _tableBuilders);
|
||||
_importedTables,
|
||||
_tableBuilders,
|
||||
);
|
||||
return ir.Tables(_importedTables, built);
|
||||
}
|
||||
|
||||
|
||||
@@ -32,8 +32,13 @@ class TagsBuilder with Builder<ir.Tags> {
|
||||
|
||||
/// Defines a new tag in the module.
|
||||
ir.Tag import(String module, String name, ir.FunctionType type) {
|
||||
final tag =
|
||||
ir.ImportedTag(_module, module, name, ir.FinalizableIndex(), type);
|
||||
final tag = ir.ImportedTag(
|
||||
_module,
|
||||
module,
|
||||
name,
|
||||
ir.FinalizableIndex(),
|
||||
type,
|
||||
);
|
||||
_imported.add(tag);
|
||||
return tag;
|
||||
}
|
||||
|
||||
@@ -49,7 +49,8 @@ ir.StructType _getBrandType(int index) {
|
||||
final useMutable = index & 1 == 1;
|
||||
final digitIndex = (index >> 1) % numDigits;
|
||||
fields.add(
|
||||
ir.FieldType(_brandTypeFieldValues[digitIndex], mutable: useMutable));
|
||||
ir.FieldType(_brandTypeFieldValues[digitIndex], mutable: useMutable),
|
||||
);
|
||||
index = index ~/ (numDigits * 2);
|
||||
}
|
||||
return ir.StructType(brandName, fields: fields);
|
||||
@@ -103,7 +104,9 @@ class _RecGroupBuilder {
|
||||
///
|
||||
/// Assumes both groups are the same size.
|
||||
static bool _areGroupsStructurallyEqual(
|
||||
List<ir.DefType> group1, List<ir.DefType> group2) {
|
||||
List<ir.DefType> group1,
|
||||
List<ir.DefType> group2,
|
||||
) {
|
||||
for (int i = 0; i < group1.length; i++) {
|
||||
final type1 = group1[i];
|
||||
final type2 = group2[i];
|
||||
@@ -135,8 +138,11 @@ class _RecGroupBuilder {
|
||||
// Skip groups with no struct types.
|
||||
if (structIndex == -1) continue;
|
||||
final structType = group[structIndex] as ir.StructType;
|
||||
final key =
|
||||
_RecursionGroupKey(group.length, structType.fields.length, group);
|
||||
final key = _RecursionGroupKey(
|
||||
group.length,
|
||||
structType.fields.length,
|
||||
group,
|
||||
);
|
||||
equivalenceGroups.putIfAbsent(key, () => []).add(group);
|
||||
}
|
||||
|
||||
@@ -208,7 +214,8 @@ class _RecGroupBuilder {
|
||||
/// The returned list includes all rec groups that contain a directly or
|
||||
/// indirectly used type.
|
||||
List<List<ir.DefType>> createGroupsForModule(
|
||||
Set<ir.DefType> directlyUsedTypes) {
|
||||
Set<ir.DefType> directlyUsedTypes,
|
||||
) {
|
||||
final allUsedTypes = {...directlyUsedTypes};
|
||||
|
||||
void addUsedType(ir.DefType type) {
|
||||
@@ -240,7 +247,7 @@ class TypesBuilder with Builder<ir.Types> {
|
||||
final _RecGroupBuilder _recGroupBuilder;
|
||||
|
||||
TypesBuilder(this._module, {TypesBuilder? parent})
|
||||
: _recGroupBuilder = parent?._recGroupBuilder ?? _RecGroupBuilder();
|
||||
: _recGroupBuilder = parent?._recGroupBuilder ?? _RecGroupBuilder();
|
||||
|
||||
Map<ir.DefType, int> get brandTypeAssignments =>
|
||||
_recGroupBuilder._brandTypeAssignments;
|
||||
@@ -258,8 +265,10 @@ class TypesBuilder with Builder<ir.Types> {
|
||||
/// This means that recursive function types (without any non-function types
|
||||
/// on the recursion path) are not supported.
|
||||
ir.FunctionType defineFunction(
|
||||
Iterable<ir.ValueType> inputs, Iterable<ir.ValueType> outputs,
|
||||
{ir.DefType? superType}) {
|
||||
Iterable<ir.ValueType> inputs,
|
||||
Iterable<ir.ValueType> outputs, {
|
||||
ir.DefType? superType,
|
||||
}) {
|
||||
final List<ir.ValueType> inputList = List.unmodifiable(inputs);
|
||||
final List<ir.ValueType> outputList = List.unmodifiable(outputs);
|
||||
final _FunctionTypeKey key = _FunctionTypeKey(inputList, outputList);
|
||||
@@ -274,8 +283,11 @@ class TypesBuilder with Builder<ir.Types> {
|
||||
///
|
||||
/// Fields can be added later, by adding to the [fields] list. This enables
|
||||
/// struct types to be recursive.
|
||||
ir.StructType defineStruct(String name,
|
||||
{Iterable<ir.FieldType>? fields, ir.DefType? superType}) {
|
||||
ir.StructType defineStruct(
|
||||
String name, {
|
||||
Iterable<ir.FieldType>? fields,
|
||||
ir.DefType? superType,
|
||||
}) {
|
||||
final type = ir.StructType(name, fields: fields, superType: superType);
|
||||
_recGroupBuilder.addDefinedType(type);
|
||||
return type;
|
||||
@@ -285,10 +297,16 @@ class TypesBuilder with Builder<ir.Types> {
|
||||
///
|
||||
/// The element type can be specified later. This enables array types to be
|
||||
/// recursive.
|
||||
ir.ArrayType defineArray(String name,
|
||||
{ir.FieldType? elementType, ir.DefType? superType}) {
|
||||
final type =
|
||||
ir.ArrayType(name, elementType: elementType, superType: superType);
|
||||
ir.ArrayType defineArray(
|
||||
String name, {
|
||||
ir.FieldType? elementType,
|
||||
ir.DefType? superType,
|
||||
}) {
|
||||
final type = ir.ArrayType(
|
||||
name,
|
||||
elementType: elementType,
|
||||
superType: superType,
|
||||
);
|
||||
_recGroupBuilder.addDefinedType(type);
|
||||
return type;
|
||||
}
|
||||
|
||||
@@ -13,7 +13,9 @@ int _finalizeIndexables(int index, Iterable<ir.Indexable> indexables) {
|
||||
}
|
||||
|
||||
List<T> _finalizeIndexablesAndBuild<T>(
|
||||
int index, Iterable<IndexableBuilder<T>> indexableBuilders) {
|
||||
int index,
|
||||
Iterable<IndexableBuilder<T>> indexableBuilders,
|
||||
) {
|
||||
final built = <T>[];
|
||||
for (final f in indexableBuilders) {
|
||||
f.finalizableIndex.finalize(index++);
|
||||
@@ -24,14 +26,18 @@ List<T> _finalizeIndexablesAndBuild<T>(
|
||||
|
||||
/// Finalizes imports before iterating through a list of builders and building.
|
||||
List<T> finalizeImportsAndBuilders<T>(
|
||||
Iterable<ir.Indexable> imported, Iterable<IndexableBuilder<T>> builders) {
|
||||
Iterable<ir.Indexable> imported,
|
||||
Iterable<IndexableBuilder<T>> builders,
|
||||
) {
|
||||
int index = _finalizeIndexables(0, imported);
|
||||
return _finalizeIndexablesAndBuild<T>(index, builders);
|
||||
}
|
||||
|
||||
/// Finalizes imports and definitions.
|
||||
void finalizeImportsAndDefinitions(
|
||||
Iterable<ir.Indexable> imported, Iterable<ir.Indexable> defined) {
|
||||
Iterable<ir.Indexable> imported,
|
||||
Iterable<ir.Indexable> defined,
|
||||
) {
|
||||
int index = _finalizeIndexables(0, imported);
|
||||
_finalizeIndexables(index, defined);
|
||||
}
|
||||
|
||||
@@ -20,9 +20,11 @@ sealed class ActiveElementSegment extends ElementSegment {
|
||||
final class ActiveFunctionElementSegment extends ActiveElementSegment {
|
||||
final List<BaseFunction> entries;
|
||||
|
||||
ActiveFunctionElementSegment(super.table, super.startIndex,
|
||||
[List<BaseFunction>? entries])
|
||||
: entries = entries ?? [];
|
||||
ActiveFunctionElementSegment(
|
||||
super.table,
|
||||
super.startIndex, [
|
||||
List<BaseFunction>? entries,
|
||||
]) : entries = entries ?? [];
|
||||
|
||||
@override
|
||||
void serialize(Serializer s) {
|
||||
@@ -131,8 +133,12 @@ final class ActiveExpressionElementSegment extends ActiveElementSegment {
|
||||
for (int i = 0; i < count; i++) {
|
||||
final instructions = <Instruction>[];
|
||||
while (true) {
|
||||
final instruction =
|
||||
Instruction.deserializeConst(d, types, functions, globals);
|
||||
final instruction = Instruction.deserializeConst(
|
||||
d,
|
||||
types,
|
||||
functions,
|
||||
globals,
|
||||
);
|
||||
instructions.add(instruction);
|
||||
if (instruction is End) break;
|
||||
}
|
||||
@@ -160,7 +166,9 @@ final class DeclarativeElementSegment implements ElementSegment {
|
||||
}
|
||||
|
||||
static DeclarativeElementSegment deserialize(
|
||||
Deserializer d, Functions functions) {
|
||||
Deserializer d,
|
||||
Functions functions,
|
||||
) {
|
||||
if (d.readByte() != 0x03) {
|
||||
throw StateError('Expected declarative segment to start with 0x03.');
|
||||
}
|
||||
@@ -188,13 +196,18 @@ extension on Serializer {
|
||||
|
||||
extension on Deserializer {
|
||||
int deserializeTableOffset(
|
||||
Types types, Functions functions, Globals globals) {
|
||||
Types types,
|
||||
Functions functions,
|
||||
Globals globals,
|
||||
) {
|
||||
final i0 = Instruction.deserializeConst(this, types, functions, globals);
|
||||
final i1 = Instruction.deserializeConst(this, types, functions, globals);
|
||||
if (i0 is! I32Const || i1 is! End) {
|
||||
throw StateError('Expected offset to be encoded as '
|
||||
'`(i32.const <value>) (end)`. '
|
||||
'Got instead: (${i0.name}) (${i1.name})');
|
||||
throw StateError(
|
||||
'Expected offset to be encoded as '
|
||||
'`(i32.const <value>) (end)`. '
|
||||
'Got instead: (${i0.name}) (${i1.name})',
|
||||
);
|
||||
}
|
||||
return i0.value;
|
||||
}
|
||||
|
||||
@@ -13,8 +13,11 @@ class Local {
|
||||
|
||||
Local(this.index, this.type);
|
||||
|
||||
void printTo(IrPrinter p, Map<int, String> localNames,
|
||||
{bool isParam = false}) {
|
||||
void printTo(
|
||||
IrPrinter p,
|
||||
Map<int, String> localNames, {
|
||||
bool isParam = false,
|
||||
}) {
|
||||
p.write(isParam ? 'param' : 'local');
|
||||
p.write(' ');
|
||||
p.writeLocalIndexReference(index);
|
||||
@@ -41,8 +44,12 @@ abstract class BaseFunction with Indexable, Exportable {
|
||||
/// `binaryen.removable.if.unused` custom section.
|
||||
bool isPure = false;
|
||||
|
||||
BaseFunction(this.enclosingModule, this.finalizableIndex, this.type,
|
||||
[this.functionName]);
|
||||
BaseFunction(
|
||||
this.enclosingModule,
|
||||
this.finalizableIndex,
|
||||
this.type, [
|
||||
this.functionName,
|
||||
]);
|
||||
|
||||
@override
|
||||
String get name => functionName ?? super.name;
|
||||
@@ -64,12 +71,19 @@ class DefinedFunction extends BaseFunction implements Serializable {
|
||||
Map<int, String> get localNames => body.localNames;
|
||||
|
||||
DefinedFunction(
|
||||
super.enclosingModule, this.body, super.finalizableIndex, super.type,
|
||||
[super.functionName]);
|
||||
super.enclosingModule,
|
||||
this.body,
|
||||
super.finalizableIndex,
|
||||
super.type, [
|
||||
super.functionName,
|
||||
]);
|
||||
|
||||
DefinedFunction.withoutBody(
|
||||
super.enclosingModule, super.finalizableIndex, super.type,
|
||||
[super.functionName]);
|
||||
super.enclosingModule,
|
||||
super.finalizableIndex,
|
||||
super.type, [
|
||||
super.functionName,
|
||||
]);
|
||||
|
||||
@override
|
||||
void serialize(Serializer s) {
|
||||
@@ -154,9 +168,14 @@ class ImportedFunction extends BaseFunction implements Import {
|
||||
@override
|
||||
final String name;
|
||||
|
||||
ImportedFunction(super.enclosingModule, this.module, this.name,
|
||||
super.finalizableIndex, super.type,
|
||||
[super.functionName]);
|
||||
ImportedFunction(
|
||||
super.enclosingModule,
|
||||
this.module,
|
||||
this.name,
|
||||
super.finalizableIndex,
|
||||
super.type, [
|
||||
super.functionName,
|
||||
]);
|
||||
|
||||
@override
|
||||
void serialize(Serializer s) {
|
||||
|
||||
@@ -17,8 +17,12 @@ abstract class Global with Indexable, Exportable {
|
||||
/// Name of the global in the names section.
|
||||
String? globalName;
|
||||
|
||||
Global(this.enclosingModule, this.finalizableIndex, this.type,
|
||||
[this.globalName]);
|
||||
Global(
|
||||
this.enclosingModule,
|
||||
this.finalizableIndex,
|
||||
this.type, [
|
||||
this.globalName,
|
||||
]);
|
||||
|
||||
@override
|
||||
String toString() => globalName ?? "$finalizableIndex";
|
||||
@@ -36,9 +40,13 @@ abstract class Global with Indexable, Exportable {
|
||||
class DefinedGlobal extends Global implements Serializable {
|
||||
final Instructions initializer;
|
||||
|
||||
DefinedGlobal(super.enclosingModule, this.initializer, super.finalizableIndex,
|
||||
super.type,
|
||||
[super.globalName]);
|
||||
DefinedGlobal(
|
||||
super.enclosingModule,
|
||||
this.initializer,
|
||||
super.finalizableIndex,
|
||||
super.type, [
|
||||
super.globalName,
|
||||
]);
|
||||
|
||||
@override
|
||||
void serialize(Serializer s) {
|
||||
@@ -84,9 +92,14 @@ class ImportedGlobal extends Global implements Import {
|
||||
@override
|
||||
final String name;
|
||||
|
||||
ImportedGlobal(super.enclosingModule, this.module, this.name,
|
||||
super.finalizableIndex, super.type,
|
||||
[super.globalName]);
|
||||
ImportedGlobal(
|
||||
super.enclosingModule,
|
||||
this.module,
|
||||
this.name,
|
||||
super.finalizableIndex,
|
||||
super.type, [
|
||||
super.globalName,
|
||||
]);
|
||||
|
||||
@override
|
||||
void serialize(Serializer s) {
|
||||
|
||||
@@ -15,23 +15,24 @@ class Imports {
|
||||
final List<ImportedMemory> memories;
|
||||
|
||||
Imports(this.functions, this.tags, this.globals, this.tables, this.memories) {
|
||||
all = [
|
||||
...functions,
|
||||
...tags,
|
||||
...globals,
|
||||
...tables,
|
||||
...memories,
|
||||
];
|
||||
all = [...functions, ...tags, ...globals, ...tables, ...memories];
|
||||
}
|
||||
|
||||
Imports.deserialized(this.all, this.functions, this.tags, this.globals,
|
||||
this.tables, this.memories)
|
||||
: assert(all.length ==
|
||||
Imports.deserialized(
|
||||
this.all,
|
||||
this.functions,
|
||||
this.tags,
|
||||
this.globals,
|
||||
this.tables,
|
||||
this.memories,
|
||||
) : assert(
|
||||
all.length ==
|
||||
(functions.length +
|
||||
tags.length +
|
||||
globals.length +
|
||||
tables.length +
|
||||
memories.length));
|
||||
memories.length),
|
||||
);
|
||||
}
|
||||
|
||||
/// Any import (function, table, memory or global).
|
||||
|
||||
@@ -37,8 +37,12 @@ abstract mixin class Instruction implements Serializable {
|
||||
}
|
||||
|
||||
static Instruction deserializeConst(
|
||||
Deserializer d, Types types, Functions functions, Globals globals,
|
||||
{bool isConstOnlyUse = true}) {
|
||||
Deserializer d,
|
||||
Types types,
|
||||
Functions functions,
|
||||
Globals globals, {
|
||||
bool isConstOnlyUse = true,
|
||||
}) {
|
||||
final byte = d.readByte();
|
||||
switch (byte) {
|
||||
case 0x0B:
|
||||
@@ -70,7 +74,7 @@ abstract mixin class Instruction implements Serializable {
|
||||
0x1B => ExternExternalize.deserialize(d),
|
||||
0x1C => I31New.deserialize(d),
|
||||
_ =>
|
||||
throw "Invalid ${isConstOnlyUse ? 'const ' : ''}instruction byte: $byte $byte2"
|
||||
throw "Invalid ${isConstOnlyUse ? 'const ' : ''}instruction byte: $byte $byte2",
|
||||
};
|
||||
}
|
||||
default:
|
||||
@@ -96,19 +100,39 @@ abstract mixin class Instruction implements Serializable {
|
||||
case 0x01:
|
||||
return Nop.deserialize(d);
|
||||
case 0x02:
|
||||
return d.deserializeBlock(types, tags, BeginNoEffectBlock.deserialize,
|
||||
BeginOneOutputBlock.deserialize, BeginFunctionBlock.deserialize);
|
||||
return d.deserializeBlock(
|
||||
types,
|
||||
tags,
|
||||
BeginNoEffectBlock.deserialize,
|
||||
BeginOneOutputBlock.deserialize,
|
||||
BeginFunctionBlock.deserialize,
|
||||
);
|
||||
case 0x03:
|
||||
return d.deserializeBlock(types, tags, BeginNoEffectLoop.deserialize,
|
||||
BeginOneOutputLoop.deserialize, BeginFunctionLoop.deserialize);
|
||||
return d.deserializeBlock(
|
||||
types,
|
||||
tags,
|
||||
BeginNoEffectLoop.deserialize,
|
||||
BeginOneOutputLoop.deserialize,
|
||||
BeginFunctionLoop.deserialize,
|
||||
);
|
||||
case 0x04:
|
||||
return d.deserializeBlock(types, tags, BeginNoEffectIf.deserialize,
|
||||
BeginOneOutputIf.deserialize, BeginFunctionIf.deserialize);
|
||||
return d.deserializeBlock(
|
||||
types,
|
||||
tags,
|
||||
BeginNoEffectIf.deserialize,
|
||||
BeginOneOutputIf.deserialize,
|
||||
BeginFunctionIf.deserialize,
|
||||
);
|
||||
case 0x05:
|
||||
return Else.deserialize(d);
|
||||
case 0x06:
|
||||
return d.deserializeBlock(types, tags, BeginNoEffectTry.deserialize,
|
||||
BeginOneOutputTry.deserialize, BeginFunctionTry.deserialize);
|
||||
return d.deserializeBlock(
|
||||
types,
|
||||
tags,
|
||||
BeginNoEffectTry.deserialize,
|
||||
BeginOneOutputTry.deserialize,
|
||||
BeginFunctionTry.deserialize,
|
||||
);
|
||||
case 0x07:
|
||||
return CatchLegacy.deserialize(d, tags);
|
||||
case 0x08:
|
||||
@@ -141,11 +165,12 @@ abstract mixin class Instruction implements Serializable {
|
||||
return SelectWithType.deserialize(d, types);
|
||||
case 0x1F:
|
||||
return d.deserializeBlock(
|
||||
types,
|
||||
tags,
|
||||
BeginNoEffectTryTable.deserialize,
|
||||
BeginOneOutputTryTable.deserialize,
|
||||
BeginFunctionTryTable.deserialize);
|
||||
types,
|
||||
tags,
|
||||
BeginNoEffectTryTable.deserialize,
|
||||
BeginOneOutputTryTable.deserialize,
|
||||
BeginFunctionTryTable.deserialize,
|
||||
);
|
||||
case 0x20:
|
||||
return LocalGet.deserialize(d);
|
||||
case 0x21:
|
||||
@@ -520,8 +545,13 @@ abstract mixin class Instruction implements Serializable {
|
||||
return I31GetU.deserialize(d);
|
||||
default:
|
||||
d.offset = instructionStart;
|
||||
return deserializeConst(d, types, functions, globals,
|
||||
isConstOnlyUse: false);
|
||||
return deserializeConst(
|
||||
d,
|
||||
types,
|
||||
functions,
|
||||
globals,
|
||||
isConstOnlyUse: false,
|
||||
);
|
||||
}
|
||||
}
|
||||
case 0xFC:
|
||||
@@ -539,7 +569,7 @@ abstract mixin class Instruction implements Serializable {
|
||||
0x0B => MemoryFill.deserialize(d, memories),
|
||||
0x10 => TableSize.deserialize(d, tables),
|
||||
0x11 => TableFill.deserialize(d, tables),
|
||||
_ => throw "Invalid instruction byte: 0xFC $opcode"
|
||||
_ => throw "Invalid instruction byte: 0xFC $opcode",
|
||||
};
|
||||
}
|
||||
case 0xFD:
|
||||
@@ -563,13 +593,18 @@ abstract mixin class Instruction implements Serializable {
|
||||
0x20 => F32x4ReplaceLane.deserialize(d),
|
||||
0x21 => F64x2ExtractLane.deserialize(d),
|
||||
0x22 => F64x2ReplaceLane.deserialize(d),
|
||||
_ => throw "Invalid instruction byte: 0xFD $opcode"
|
||||
_ => throw "Invalid instruction byte: 0xFD $opcode",
|
||||
};
|
||||
}
|
||||
default:
|
||||
d.offset = instructionStart;
|
||||
return deserializeConst(d, types, functions, globals,
|
||||
isConstOnlyUse: false);
|
||||
return deserializeConst(
|
||||
d,
|
||||
types,
|
||||
functions,
|
||||
globals,
|
||||
isConstOnlyUse: false,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1568,8 +1603,11 @@ class MemoryOffsetAlign implements Serializable {
|
||||
final align = alignAndMemory & 0x3F;
|
||||
final offset = d.readUnsigned();
|
||||
final memoryIndex = (alignAndMemory & 0x40) != 0 ? d.readUnsigned() : 0;
|
||||
return MemoryOffsetAlign(memories[memoryIndex],
|
||||
offset: offset, align: align);
|
||||
return MemoryOffsetAlign(
|
||||
memories[memoryIndex],
|
||||
offset: offset,
|
||||
align: align,
|
||||
);
|
||||
}
|
||||
|
||||
void printTo(IrPrinter p) {
|
||||
@@ -2220,7 +2258,9 @@ class StructGet extends Instruction {
|
||||
|
||||
static StructGet deserialize(Deserializer d, Types types) {
|
||||
return StructGet(
|
||||
types.defined[d.readTypeIndex()] as StructType, d.readUnsigned());
|
||||
types.defined[d.readTypeIndex()] as StructType,
|
||||
d.readUnsigned(),
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
@@ -2253,7 +2293,9 @@ class StructGetS extends Instruction {
|
||||
|
||||
static StructGetS deserialize(Deserializer d, Types types) {
|
||||
return StructGetS(
|
||||
types.defined[d.readTypeIndex()] as StructType, d.readUnsigned());
|
||||
types.defined[d.readTypeIndex()] as StructType,
|
||||
d.readUnsigned(),
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
@@ -2286,7 +2328,9 @@ class StructGetU extends Instruction {
|
||||
|
||||
static StructGetU deserialize(Deserializer d, Types types) {
|
||||
return StructGetU(
|
||||
types.defined[d.readTypeIndex()] as StructType, d.readUnsigned());
|
||||
types.defined[d.readTypeIndex()] as StructType,
|
||||
d.readUnsigned(),
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
@@ -2319,7 +2363,9 @@ class StructSet extends Instruction {
|
||||
|
||||
static StructSet deserialize(Deserializer d, Types types) {
|
||||
return StructSet(
|
||||
types.defined[d.readTypeIndex()] as StructType, d.readUnsigned());
|
||||
types.defined[d.readTypeIndex()] as StructType,
|
||||
d.readUnsigned(),
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
@@ -2553,7 +2599,9 @@ class ArrayNewFixed extends Instruction {
|
||||
|
||||
static ArrayNewFixed deserialize(Deserializer d, Types types) {
|
||||
return ArrayNewFixed(
|
||||
types.defined[d.readTypeIndex()] as ArrayType, d.readUnsigned());
|
||||
types.defined[d.readTypeIndex()] as ArrayType,
|
||||
d.readUnsigned(),
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
@@ -2655,9 +2703,14 @@ class ArrayNewData extends Instruction {
|
||||
ArrayNewData(this.arrayType, this.data);
|
||||
|
||||
static ArrayNewData deserialize(
|
||||
Deserializer d, Types types, DataSegments dataSegments) {
|
||||
return ArrayNewData(types.defined[d.readTypeIndex()] as ArrayType,
|
||||
dataSegments.defined[d.readUnsigned()]);
|
||||
Deserializer d,
|
||||
Types types,
|
||||
DataSegments dataSegments,
|
||||
) {
|
||||
return ArrayNewData(
|
||||
types.defined[d.readTypeIndex()] as ArrayType,
|
||||
dataSegments.defined[d.readUnsigned()],
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
@@ -2691,8 +2744,9 @@ class ArrayCopy extends Instruction {
|
||||
|
||||
static ArrayCopy deserialize(Deserializer d, Types types) {
|
||||
return ArrayCopy(
|
||||
destArrayType: types.defined[d.readTypeIndex()] as ArrayType,
|
||||
sourceArrayType: types.defined[d.readTypeIndex()] as ArrayType);
|
||||
destArrayType: types.defined[d.readTypeIndex()] as ArrayType,
|
||||
sourceArrayType: types.defined[d.readTypeIndex()] as ArrayType,
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
@@ -2801,7 +2855,8 @@ class RefTest extends Instruction {
|
||||
|
||||
static RefTest deserialize(Deserializer d, Types types, bool nullable) {
|
||||
return RefTest(
|
||||
RefType(HeapType.deserialize(d, types.defined), nullable: nullable));
|
||||
RefType(HeapType.deserialize(d, types.defined), nullable: nullable),
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
@@ -2832,7 +2887,8 @@ class RefCast extends Instruction {
|
||||
|
||||
static RefCast deserialize(Deserializer d, Types types, bool nullable) {
|
||||
return RefCast(
|
||||
RefType(HeapType.deserialize(d, types.defined), nullable: nullable));
|
||||
RefType(HeapType.deserialize(d, types.defined), nullable: nullable),
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
@@ -2875,7 +2931,8 @@ class BrOnCast extends Instruction {
|
||||
|
||||
@override
|
||||
void serialize(Serializer s) {
|
||||
int flags = (inputType.nullable ? 0x01 : 0x00) |
|
||||
int flags =
|
||||
(inputType.nullable ? 0x01 : 0x00) |
|
||||
(targetType.nullable ? 0x02 : 0x00);
|
||||
s.writeByte(0xFB);
|
||||
s.writeByte(0x18);
|
||||
@@ -2924,7 +2981,8 @@ class BrOnCastFail extends Instruction {
|
||||
|
||||
@override
|
||||
void serialize(Serializer s) {
|
||||
int flags = (inputType.nullable ? 0x01 : 0x00) |
|
||||
int flags =
|
||||
(inputType.nullable ? 0x01 : 0x00) |
|
||||
(targetType.nullable ? 0x02 : 0x00);
|
||||
s.writeByte(0xFB);
|
||||
s.writeByte(0x19);
|
||||
@@ -4782,7 +4840,10 @@ class BeginOneOutputTryTable extends Instruction {
|
||||
BeginOneOutputTryTable(this.type, this.catches);
|
||||
|
||||
static BeginOneOutputTryTable deserialize(
|
||||
Deserializer d, Tags tags, Types types) {
|
||||
Deserializer d,
|
||||
Tags tags,
|
||||
Types types,
|
||||
) {
|
||||
final type = ValueType.deserialize(d, types.defined);
|
||||
final catches = d.readList((d) => TryTableCatch.deserialize(d, tags));
|
||||
return BeginOneOutputTryTable(type, catches);
|
||||
@@ -4809,7 +4870,10 @@ class BeginFunctionTryTable extends Instruction {
|
||||
BeginFunctionTryTable(this.type, this.catches);
|
||||
|
||||
static BeginFunctionTryTable deserialize(
|
||||
Deserializer d, Tags tags, Types types) {
|
||||
Deserializer d,
|
||||
Tags tags,
|
||||
Types types,
|
||||
) {
|
||||
final type = types.defined[d.readSigned()] as FunctionType;
|
||||
final catches = d.readList((d) => TryTableCatch.deserialize(d, tags));
|
||||
return BeginFunctionTryTable(type, catches);
|
||||
@@ -4916,11 +4980,12 @@ extension on Deserializer {
|
||||
int readTypeIndex() => readUnsigned();
|
||||
|
||||
Instruction deserializeBlock(
|
||||
Types types,
|
||||
Tags tags,
|
||||
Instruction Function(Deserializer, Tags) deserializeNoInputNoOutput,
|
||||
Instruction Function(Deserializer, Tags, Types) deserializeOneOutput,
|
||||
Instruction Function(Deserializer, Tags, Types) deserializeGeneral) {
|
||||
Types types,
|
||||
Tags tags,
|
||||
Instruction Function(Deserializer, Tags) deserializeNoInputNoOutput,
|
||||
Instruction Function(Deserializer, Tags, Types) deserializeOneOutput,
|
||||
Instruction Function(Deserializer, Tags, Types) deserializeGeneral,
|
||||
) {
|
||||
if (peekByte() == 0x40) {
|
||||
// 0x40 means empty type, the block has neither inputs nor outputs.
|
||||
return deserializeNoInputNoOutput(this, tags);
|
||||
|
||||
@@ -34,16 +34,24 @@ class Instructions implements Serializable {
|
||||
final List<SourceMapping>? _sourceMappings;
|
||||
|
||||
/// Create a new instruction sequence.
|
||||
Instructions(this.locals, this.localNames, this.instructions,
|
||||
this._stackTraces, this._traceLines, this._sourceMappings);
|
||||
Instructions(
|
||||
this.locals,
|
||||
this.localNames,
|
||||
this.instructions,
|
||||
this._stackTraces,
|
||||
this._traceLines,
|
||||
this._sourceMappings,
|
||||
);
|
||||
|
||||
@override
|
||||
void serialize(Serializer s) {
|
||||
final sourceMappings = _sourceMappings;
|
||||
int sourceMappingIdx = 0;
|
||||
for (int instructionIdx = 0;
|
||||
instructionIdx < instructions.length;
|
||||
instructionIdx += 1) {
|
||||
for (
|
||||
int instructionIdx = 0;
|
||||
instructionIdx < instructions.length;
|
||||
instructionIdx += 1
|
||||
) {
|
||||
final i = instructions[instructionIdx];
|
||||
if (_stackTraces != null) s.debugTrace(_stackTraces[i]!);
|
||||
|
||||
@@ -91,18 +99,22 @@ class Instructions implements Serializable {
|
||||
for (int k = 0; k < instructions.length; ++k) {
|
||||
final i = instructions[k];
|
||||
|
||||
final isTry = i is BeginNoEffectTry ||
|
||||
final isTry =
|
||||
i is BeginNoEffectTry ||
|
||||
i is BeginOneOutputTry ||
|
||||
i is BeginFunctionTry;
|
||||
final isTryTable = i is BeginNoEffectTryTable ||
|
||||
final isTryTable =
|
||||
i is BeginNoEffectTryTable ||
|
||||
i is BeginOneOutputTryTable ||
|
||||
i is BeginFunctionTryTable;
|
||||
final isIf =
|
||||
i is BeginNoEffectIf || i is BeginOneOutputIf || i is BeginFunctionIf;
|
||||
final isBlock = i is BeginNoEffectBlock ||
|
||||
final isBlock =
|
||||
i is BeginNoEffectBlock ||
|
||||
i is BeginOneOutputBlock ||
|
||||
i is BeginFunctionBlock;
|
||||
final isLoop = i is BeginNoEffectLoop ||
|
||||
final isLoop =
|
||||
i is BeginNoEffectLoop ||
|
||||
i is BeginOneOutputLoop ||
|
||||
i is BeginFunctionLoop;
|
||||
if (isTry || isIf || isBlock || isTryTable || isLoop) {
|
||||
@@ -157,8 +169,12 @@ class Instructions implements Serializable {
|
||||
) {
|
||||
final instructions = <Instruction>[];
|
||||
while (true) {
|
||||
final instruction =
|
||||
Instruction.deserializeConst(d, types, functions, globals);
|
||||
final instruction = Instruction.deserializeConst(
|
||||
d,
|
||||
types,
|
||||
functions,
|
||||
globals,
|
||||
);
|
||||
instructions.add(instruction);
|
||||
if (instruction is End) break;
|
||||
}
|
||||
@@ -179,7 +195,15 @@ class Instructions implements Serializable {
|
||||
final instructions = <Instruction>[];
|
||||
while (true) {
|
||||
final instruction = Instruction.deserialize(
|
||||
d, types, tables, tags, globals, dataSegments, memories, functions);
|
||||
d,
|
||||
types,
|
||||
tables,
|
||||
tags,
|
||||
globals,
|
||||
dataSegments,
|
||||
memories,
|
||||
functions,
|
||||
);
|
||||
instructions.add(instruction);
|
||||
if (instruction is End) break;
|
||||
}
|
||||
|
||||
@@ -16,8 +16,13 @@ abstract class Memory with Indexable, Exportable {
|
||||
@override
|
||||
final Module enclosingModule;
|
||||
|
||||
Memory(this.enclosingModule, this.finalizableIndex, this.shared, this.minSize,
|
||||
[this.maxSize]) {
|
||||
Memory(
|
||||
this.enclosingModule,
|
||||
this.finalizableIndex,
|
||||
this.shared,
|
||||
this.minSize, [
|
||||
this.maxSize,
|
||||
]) {
|
||||
if (shared && maxSize == null) {
|
||||
throw "Shared memory must specify a maximum size.";
|
||||
}
|
||||
@@ -58,8 +63,13 @@ abstract class Memory with Indexable, Exportable {
|
||||
|
||||
/// A memory defined in a module.
|
||||
class DefinedMemory extends Memory implements Serializable {
|
||||
DefinedMemory(super.enclosingModule, super.finalizableIndex, super.shared,
|
||||
super.minSize, super.maxSize);
|
||||
DefinedMemory(
|
||||
super.enclosingModule,
|
||||
super.finalizableIndex,
|
||||
super.shared,
|
||||
super.minSize,
|
||||
super.maxSize,
|
||||
);
|
||||
|
||||
@override
|
||||
void serialize(Serializer s) => _serializeLimits(s);
|
||||
@@ -93,8 +103,15 @@ class ImportedMemory extends Memory implements Import {
|
||||
@override
|
||||
final String name;
|
||||
|
||||
ImportedMemory(super.enclosingModule, this.module, this.name,
|
||||
super.finalizableIndex, super.shared, super.minSize, super.maxSize);
|
||||
ImportedMemory(
|
||||
super.enclosingModule,
|
||||
this.module,
|
||||
this.name,
|
||||
super.finalizableIndex,
|
||||
super.shared,
|
||||
super.minSize,
|
||||
super.maxSize,
|
||||
);
|
||||
|
||||
@override
|
||||
void serialize(Serializer s) {
|
||||
|
||||
@@ -96,8 +96,18 @@ class Module implements Serializable {
|
||||
Serializer.traceEnabled = true;
|
||||
}
|
||||
// Wasm module preamble: magic number, version 1.
|
||||
s.writeBytes(Uint8List.fromList(
|
||||
const [0x00, 0x61, 0x73, 0x6D, 0x01, 0x00, 0x00, 0x00]));
|
||||
s.writeBytes(
|
||||
Uint8List.fromList(const [
|
||||
0x00,
|
||||
0x61,
|
||||
0x73,
|
||||
0x6D,
|
||||
0x01,
|
||||
0x00,
|
||||
0x00,
|
||||
0x00,
|
||||
]),
|
||||
);
|
||||
TypeSection(types, watchPoints).serialize(s);
|
||||
ImportSection(imports, watchPoints).serialize(s);
|
||||
FunctionSection(functions.defined, watchPoints).serialize(s);
|
||||
@@ -112,14 +122,18 @@ class Module implements Serializable {
|
||||
CodeSection(functions.defined, watchPoints).serialize(s);
|
||||
DataSection(dataSegments.defined, watchPoints).serialize(s);
|
||||
NameSection(
|
||||
moduleName, functions, types.recursionGroups, globals, watchPoints)
|
||||
.serialize(s);
|
||||
moduleName,
|
||||
functions,
|
||||
types.recursionGroups,
|
||||
globals,
|
||||
watchPoints,
|
||||
).serialize(s);
|
||||
RemovableIfUnusedSection(functions).serialize(s);
|
||||
SourceMapSection(sourceMapUrl).serialize(s);
|
||||
}
|
||||
|
||||
static (Map<int, List<Deserializer>>, Map<String, List<Deserializer>>)
|
||||
_deserializeTopLevel(Deserializer d) {
|
||||
_deserializeTopLevel(Deserializer d) {
|
||||
final preamble = d.readBytes(8);
|
||||
if (preamble[0] != 0x00 ||
|
||||
preamble[1] != 0x61 ||
|
||||
@@ -165,118 +179,180 @@ class Module implements Serializable {
|
||||
final types = TypeSection.deserialize(typeSections?.single);
|
||||
|
||||
final importSections = sections[ImportSection.sectionId];
|
||||
final imports =
|
||||
ImportSection.deserialize(importSections?.single, module, types);
|
||||
final imports = ImportSection.deserialize(
|
||||
importSections?.single,
|
||||
module,
|
||||
types,
|
||||
);
|
||||
|
||||
final functionSections = sections[FunctionSection.sectionId];
|
||||
final functions = FunctionSection.deserialize(
|
||||
functionSections?.single, module, types, imports.functions);
|
||||
functionSections?.single,
|
||||
module,
|
||||
types,
|
||||
imports.functions,
|
||||
);
|
||||
|
||||
final tablesSections = sections[TableSection.sectionId];
|
||||
final tables = TableSection.deserialize(
|
||||
tablesSections?.single, module, types, imports.tables);
|
||||
tablesSections?.single,
|
||||
module,
|
||||
types,
|
||||
imports.tables,
|
||||
);
|
||||
|
||||
final memorySections = sections[MemorySection.sectionId];
|
||||
final memories = MemorySection.deserialize(
|
||||
memorySections?.single, module, imports.memories);
|
||||
memorySections?.single,
|
||||
module,
|
||||
imports.memories,
|
||||
);
|
||||
|
||||
final tagSections = sections[TagSection.sectionId];
|
||||
final tags = TagSection.deserialize(
|
||||
tagSections?.single, module, types, imports.tags);
|
||||
tagSections?.single,
|
||||
module,
|
||||
types,
|
||||
imports.tags,
|
||||
);
|
||||
|
||||
final globalSections = sections[GlobalSection.sectionId];
|
||||
final globals = GlobalSection.deserialize(
|
||||
globalSections?.single, module, types, functions, imports.globals);
|
||||
globalSections?.single,
|
||||
module,
|
||||
types,
|
||||
functions,
|
||||
imports.globals,
|
||||
);
|
||||
|
||||
final exportSections = sections[ExportSection.sectionId];
|
||||
final exports = ExportSection.deserialize(
|
||||
exportSections?.single, functions, tables, memories, globals, tags);
|
||||
exportSections?.single,
|
||||
functions,
|
||||
tables,
|
||||
memories,
|
||||
globals,
|
||||
tags,
|
||||
);
|
||||
|
||||
final startFunctionSections = sections[StartSection.sectionId];
|
||||
final start =
|
||||
StartSection.deserialize(startFunctionSections?.single, functions);
|
||||
final start = StartSection.deserialize(
|
||||
startFunctionSections?.single,
|
||||
functions,
|
||||
);
|
||||
|
||||
final elementSections = sections[ElementSection.sectionId];
|
||||
final elements = ElementSection.deserialize(
|
||||
elementSections?.single, module, types, functions, tables, globals);
|
||||
elementSections?.single,
|
||||
module,
|
||||
types,
|
||||
functions,
|
||||
tables,
|
||||
globals,
|
||||
);
|
||||
|
||||
final dataCountSections = sections[DataCountSection.sectionId];
|
||||
final dataSegments =
|
||||
DataCountSection.deserialize(dataCountSections?.single);
|
||||
final dataSegments = DataCountSection.deserialize(
|
||||
dataCountSections?.single,
|
||||
);
|
||||
|
||||
final codeSections = sections[CodeSection.sectionId];
|
||||
CodeSection.deserialize(codeSections?.single, functions.defined, module,
|
||||
types, functions, tables, memories, tags, globals, dataSegments);
|
||||
CodeSection.deserialize(
|
||||
codeSections?.single,
|
||||
functions.defined,
|
||||
module,
|
||||
types,
|
||||
functions,
|
||||
tables,
|
||||
memories,
|
||||
tags,
|
||||
globals,
|
||||
dataSegments,
|
||||
);
|
||||
|
||||
final dataSections = sections[DataSection.sectionId];
|
||||
// As side-effect initializes [dataSegments.defined]
|
||||
DataSection.deserialize(dataSections?.single, dataSegments, memories);
|
||||
|
||||
final moduleName = NameSection.deserialize(
|
||||
customSections[NameSection.customSectionName]?.single,
|
||||
functions,
|
||||
types,
|
||||
globals);
|
||||
customSections[NameSection.customSectionName]?.single,
|
||||
functions,
|
||||
types,
|
||||
globals,
|
||||
);
|
||||
RemovableIfUnusedSection.deserialize(
|
||||
customSections[RemovableIfUnusedSection.customSectionName]?.single,
|
||||
functions);
|
||||
customSections[RemovableIfUnusedSection.customSectionName]?.single,
|
||||
functions,
|
||||
);
|
||||
final sourceMapUrl = SourceMapSection.deserialize(
|
||||
customSections[SourceMapSection.customSectionName]?.single);
|
||||
customSections[SourceMapSection.customSectionName]?.single,
|
||||
);
|
||||
|
||||
return module
|
||||
..initialize(
|
||||
moduleName ?? '',
|
||||
functions,
|
||||
start,
|
||||
tables,
|
||||
elements,
|
||||
tags,
|
||||
memories,
|
||||
exports,
|
||||
globals,
|
||||
types,
|
||||
dataSegments,
|
||||
imports,
|
||||
[],
|
||||
sourceMapUrl,
|
||||
);
|
||||
return module..initialize(
|
||||
moduleName ?? '',
|
||||
functions,
|
||||
start,
|
||||
tables,
|
||||
elements,
|
||||
tags,
|
||||
memories,
|
||||
exports,
|
||||
globals,
|
||||
types,
|
||||
dataSegments,
|
||||
imports,
|
||||
[],
|
||||
sourceMapUrl,
|
||||
);
|
||||
}
|
||||
|
||||
/// Deserialize just the `sourceMapUrl` section of a module as a [Uri].
|
||||
static Uri? deserializeSourceMapUrl(Deserializer d) {
|
||||
final (sections, customSections) = _deserializeTopLevel(d);
|
||||
final sourceMapUrl = SourceMapSection.deserialize(
|
||||
customSections[SourceMapSection.customSectionName]?.single);
|
||||
customSections[SourceMapSection.customSectionName]?.single,
|
||||
);
|
||||
return sourceMapUrl;
|
||||
}
|
||||
|
||||
String printAsWat(
|
||||
{ModulePrintSettings settings = const ModulePrintSettings()}) {
|
||||
String printAsWat({
|
||||
ModulePrintSettings settings = const ModulePrintSettings(),
|
||||
}) {
|
||||
final mp = ModulePrinter(this, settings: settings);
|
||||
|
||||
if (settings.hasFilters) {
|
||||
// If we have any filters, we treat those as roots.
|
||||
if (settings.typeFilters.isNotEmpty) {
|
||||
for (final type in mp.typeNamer.sort(mp.typeNamer
|
||||
.filter(types.defined, settings.printTypeConstituents))) {
|
||||
for (final type in mp.typeNamer.sort(
|
||||
mp.typeNamer.filter(types.defined, settings.printTypeConstituents),
|
||||
)) {
|
||||
mp.enqueueType(type);
|
||||
}
|
||||
}
|
||||
if (settings.globalFilters.isNotEmpty) {
|
||||
for (final global in mp.globalNamer.sort(mp.globalNamer
|
||||
.filter(globals.defined, settings.printGlobalInitializer))) {
|
||||
for (final global in mp.globalNamer.sort(
|
||||
mp.globalNamer.filter(
|
||||
globals.defined,
|
||||
settings.printGlobalInitializer,
|
||||
),
|
||||
)) {
|
||||
mp.enqueueGlobal(global);
|
||||
}
|
||||
}
|
||||
if (settings.functionFilters.isNotEmpty) {
|
||||
for (final function in mp.functionNamer.sort(mp.functionNamer
|
||||
.filter(functions.defined, settings.printFunctionBody))) {
|
||||
for (final function in mp.functionNamer.sort(
|
||||
mp.functionNamer.filter(
|
||||
functions.defined,
|
||||
settings.printFunctionBody,
|
||||
),
|
||||
)) {
|
||||
mp.enqueueFunction(function);
|
||||
}
|
||||
}
|
||||
if (settings.tableFilters.isNotEmpty) {
|
||||
for (final table in mp.tableNamer.sort(mp.tableNamer
|
||||
.filter(tables.defined, settings.printTableElements))) {
|
||||
for (final table in mp.tableNamer.sort(
|
||||
mp.tableNamer.filter(tables.defined, settings.printTableElements),
|
||||
)) {
|
||||
mp.enqueueTable(table);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,8 +18,13 @@ class Table with Indexable, Exportable implements Serializable {
|
||||
@override
|
||||
final Module enclosingModule;
|
||||
|
||||
Table(this.enclosingModule, this.finalizableIndex, this.type, this.minSize,
|
||||
this.maxSize);
|
||||
Table(
|
||||
this.enclosingModule,
|
||||
this.finalizableIndex,
|
||||
this.type,
|
||||
this.minSize,
|
||||
this.maxSize,
|
||||
);
|
||||
|
||||
@override
|
||||
void serialize(Serializer s) {
|
||||
@@ -41,8 +46,13 @@ class Table with Indexable, Exportable implements Serializable {
|
||||
|
||||
/// A table defined in a module.
|
||||
class DefinedTable extends Table {
|
||||
DefinedTable(super.enclosingModule, super.finalizableIndex, super.type,
|
||||
super.minSize, super.maxSize);
|
||||
DefinedTable(
|
||||
super.enclosingModule,
|
||||
super.finalizableIndex,
|
||||
super.type,
|
||||
super.minSize,
|
||||
super.maxSize,
|
||||
);
|
||||
|
||||
void printTo(IrPrinter p) {
|
||||
p.write('(table ');
|
||||
@@ -72,8 +82,15 @@ class ImportedTable extends Table implements Import {
|
||||
@override
|
||||
final String name;
|
||||
|
||||
ImportedTable(super.enclosingModule, this.module, this.name,
|
||||
super.finalizableIndex, super.type, super.minSize, super.maxSize);
|
||||
ImportedTable(
|
||||
super.enclosingModule,
|
||||
this.module,
|
||||
this.name,
|
||||
super.finalizableIndex,
|
||||
super.type,
|
||||
super.minSize,
|
||||
super.maxSize,
|
||||
);
|
||||
|
||||
@override
|
||||
void serialize(Serializer s) {
|
||||
|
||||
@@ -70,8 +70,13 @@ class ImportedTag extends Tag implements Import {
|
||||
@override
|
||||
final String name;
|
||||
|
||||
ImportedTag(super.enclosingModule, this.module, this.name,
|
||||
super.finalizableIndex, super.type);
|
||||
ImportedTag(
|
||||
super.enclosingModule,
|
||||
this.module,
|
||||
this.name,
|
||||
super.finalizableIndex,
|
||||
super.type,
|
||||
);
|
||||
|
||||
@override
|
||||
void serialize(Serializer s) {
|
||||
|
||||
@@ -113,7 +113,7 @@ class NumType extends ValueType {
|
||||
return switch (kind) {
|
||||
NumTypeKind.i32 || NumTypeKind.f32 => 4,
|
||||
NumTypeKind.i64 || NumTypeKind.f64 => 8,
|
||||
NumTypeKind.v128 => 16
|
||||
NumTypeKind.v128 => 16,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -170,19 +170,20 @@ class RefType extends ValueType {
|
||||
final bool nullable;
|
||||
|
||||
RefType(this.heapType, {bool? nullable})
|
||||
: nullable = nullable ??
|
||||
heapType.nullableByDefault ??
|
||||
(throw "Unspecified nullability");
|
||||
: nullable =
|
||||
nullable ??
|
||||
heapType.nullableByDefault ??
|
||||
(throw "Unspecified nullability");
|
||||
|
||||
const RefType._(this.heapType, this.nullable);
|
||||
|
||||
/// Internal supertype above any, func and extern. Not a real Wasm ref type.
|
||||
const RefType.common({required bool nullable})
|
||||
: this._(HeapType.common, nullable);
|
||||
: this._(HeapType.common, nullable);
|
||||
|
||||
/// A (possibly nullable) reference to the `extern` heap type.
|
||||
const RefType.extern({required bool nullable})
|
||||
: this._(HeapType.extern, nullable);
|
||||
: this._(HeapType.extern, nullable);
|
||||
|
||||
/// A (possibly nullable) reference to the `any` heap type.
|
||||
const RefType.any({required bool nullable}) : this._(HeapType.any, nullable);
|
||||
@@ -192,37 +193,37 @@ class RefType extends ValueType {
|
||||
|
||||
/// A (possibly nullable) reference to the `func` heap type.
|
||||
const RefType.func({required bool nullable})
|
||||
: this._(HeapType.func, nullable);
|
||||
: this._(HeapType.func, nullable);
|
||||
|
||||
/// A (possibly nullable) reference to the `struct` heap type.
|
||||
const RefType.struct({required bool nullable})
|
||||
: this._(HeapType.struct, nullable);
|
||||
: this._(HeapType.struct, nullable);
|
||||
|
||||
/// A (possibly nullable) reference to the `array` heap type.
|
||||
const RefType.array({required bool nullable})
|
||||
: this._(HeapType.array, nullable);
|
||||
: this._(HeapType.array, nullable);
|
||||
|
||||
/// A (possibly nullable) reference to the `i31` heap type.
|
||||
const RefType.i31({required bool nullable}) : this._(HeapType.i31, nullable);
|
||||
|
||||
/// A (possibly nullable) reference to the `none` heap type.
|
||||
const RefType.none({required bool nullable})
|
||||
: this._(HeapType.none, nullable);
|
||||
: this._(HeapType.none, nullable);
|
||||
|
||||
/// A (possibly nullable) reference to the `noextern` heap type.
|
||||
const RefType.noextern({required bool nullable})
|
||||
: this._(HeapType.noextern, nullable);
|
||||
: this._(HeapType.noextern, nullable);
|
||||
|
||||
/// A (possibly nullable) reference to the `nofunc` heap type.
|
||||
const RefType.nofunc({required bool nullable})
|
||||
: this._(HeapType.nofunc, nullable);
|
||||
: this._(HeapType.nofunc, nullable);
|
||||
|
||||
/// A (possibly nullable) reference to the `exn` heap type.
|
||||
const RefType.exn({required bool nullable}) : this._(HeapType.exn, nullable);
|
||||
|
||||
/// A (possibly nullable) reference to a custom heap type.
|
||||
RefType.def(DefType defType, {required bool nullable})
|
||||
: this(defType, nullable: nullable);
|
||||
: this(defType, nullable: nullable);
|
||||
|
||||
@override
|
||||
RefType withNullability(bool nullable) =>
|
||||
@@ -716,7 +717,7 @@ abstract class DefType extends HeapType {
|
||||
bool hasAnySubtypes = false;
|
||||
|
||||
DefType({this.superType})
|
||||
: depth = superType != null ? superType.depth + 1 : 0 {
|
||||
: depth = superType != null ? superType.depth + 1 : 0 {
|
||||
superType?.hasAnySubtypes = true;
|
||||
}
|
||||
|
||||
@@ -1025,7 +1026,10 @@ class FunctionType extends DefType {
|
||||
}
|
||||
|
||||
static FunctionType deserializeAllocate(
|
||||
Deserializer d, DefType? superType, List<DefType> existing) {
|
||||
Deserializer d,
|
||||
DefType? superType,
|
||||
List<DefType> existing,
|
||||
) {
|
||||
d.readList((d) => ValueType.deserialize(d, existing));
|
||||
d.readList((d) => ValueType.deserialize(d, existing));
|
||||
return FunctionType([], [], superType: superType);
|
||||
@@ -1124,8 +1128,9 @@ class StructType extends DataType {
|
||||
HeapType get abstractSuperType => HeapType.struct;
|
||||
|
||||
@override
|
||||
Iterable<StorageType> get constituentTypes =>
|
||||
[for (FieldType f in fields) f.type];
|
||||
Iterable<StorageType> get constituentTypes => [
|
||||
for (FieldType f in fields) f.type,
|
||||
];
|
||||
|
||||
@override
|
||||
bool isStructuralSubtypeOf(HeapType other) {
|
||||
@@ -1165,7 +1170,10 @@ class StructType extends DataType {
|
||||
}
|
||||
|
||||
static StructType deserializeAllocate(
|
||||
Deserializer d, DefType? superType, List<DefType> existing) {
|
||||
Deserializer d,
|
||||
DefType? superType,
|
||||
List<DefType> existing,
|
||||
) {
|
||||
d.readList((d) => FieldType.deserialize(d, existing));
|
||||
return StructType(null, fields: [], superType: superType);
|
||||
}
|
||||
@@ -1250,7 +1258,10 @@ class ArrayType extends DataType {
|
||||
}
|
||||
|
||||
static ArrayType deserializeAllocate(
|
||||
Deserializer d, DefType? superType, List<DefType> existing) {
|
||||
Deserializer d,
|
||||
DefType? superType,
|
||||
List<DefType> existing,
|
||||
) {
|
||||
FieldType.deserialize(d, existing);
|
||||
return ArrayType(null, elementType: null, superType: superType);
|
||||
}
|
||||
@@ -1288,7 +1299,9 @@ class _WithMutability<T extends StorageType> implements Serializable {
|
||||
}
|
||||
|
||||
static (T, bool) deserialize<T extends StorageType>(
|
||||
Deserializer d, T Function(Deserializer) fun) {
|
||||
Deserializer d,
|
||||
T Function(Deserializer) fun,
|
||||
) {
|
||||
final type = fun(d);
|
||||
final mutable = d.readByte() == 0x01;
|
||||
return (type, mutable);
|
||||
@@ -1305,8 +1318,10 @@ class GlobalType extends _WithMutability<ValueType> {
|
||||
GlobalType(super.type, {super.mutable = true});
|
||||
|
||||
static GlobalType deserialize(Deserializer d, List<DefType> types) {
|
||||
final (type, mutable) =
|
||||
_WithMutability.deserialize(d, (d) => ValueType.deserialize(d, types));
|
||||
final (type, mutable) = _WithMutability.deserialize(
|
||||
d,
|
||||
(d) => ValueType.deserialize(d, types),
|
||||
);
|
||||
return GlobalType(type, mutable: mutable);
|
||||
}
|
||||
|
||||
@@ -1342,7 +1357,9 @@ class FieldType extends _WithMutability<StorageType> {
|
||||
|
||||
static FieldType deserialize(Deserializer d, List<DefType> existing) {
|
||||
final (type, mutable) = _WithMutability.deserialize(
|
||||
d, (d) => StorageType.deserialize(d, existing));
|
||||
d,
|
||||
(d) => StorageType.deserialize(d, existing),
|
||||
);
|
||||
return FieldType(type, mutable: mutable);
|
||||
}
|
||||
}
|
||||
@@ -1372,7 +1389,10 @@ class PackedType implements StorageType {
|
||||
|
||||
@override
|
||||
int get byteSize {
|
||||
return switch (kind) { PackedTypeKind.i8 => 1, PackedTypeKind.i16 => 2 };
|
||||
return switch (kind) {
|
||||
PackedTypeKind.i8 => 1,
|
||||
PackedTypeKind.i16 => 2,
|
||||
};
|
||||
}
|
||||
|
||||
@override
|
||||
|
||||
@@ -11,7 +11,7 @@ class Types {
|
||||
late final List<DefType> defined;
|
||||
|
||||
Types(this.recursionGroups)
|
||||
: defined = recursionGroups.expand((g) => g).toList();
|
||||
: defined = recursionGroups.expand((g) => g).toList();
|
||||
|
||||
DefType operator [](int index) => defined[index];
|
||||
|
||||
|
||||
@@ -10,20 +10,41 @@ import '../ir/ir.dart' as ir;
|
||||
class ModulePrinter {
|
||||
final ir.Module _module;
|
||||
|
||||
late final typeNamer =
|
||||
TypeNamer(settings.scrubAbsoluteUris, _module, enqueueType);
|
||||
late final globalNamer =
|
||||
GlobalNamer(settings.scrubAbsoluteUris, _module, enqueueGlobal);
|
||||
late final functionNamer =
|
||||
FunctionNamer(settings.scrubAbsoluteUris, _module, enqueueFunction);
|
||||
late final tagNamer =
|
||||
TagNamer(settings.scrubAbsoluteUris, _module, enqueueTag);
|
||||
late final tableNamer =
|
||||
TableNamer(settings.scrubAbsoluteUris, _module, enqueueTable);
|
||||
late final dataNamer =
|
||||
DataNamer(settings.scrubAbsoluteUris, _module, enqueueDataSegment);
|
||||
late final memoryNamer =
|
||||
MemoryNamer(settings.scrubAbsoluteUris, _module, enqueueMemory);
|
||||
late final typeNamer = TypeNamer(
|
||||
settings.scrubAbsoluteUris,
|
||||
_module,
|
||||
enqueueType,
|
||||
);
|
||||
late final globalNamer = GlobalNamer(
|
||||
settings.scrubAbsoluteUris,
|
||||
_module,
|
||||
enqueueGlobal,
|
||||
);
|
||||
late final functionNamer = FunctionNamer(
|
||||
settings.scrubAbsoluteUris,
|
||||
_module,
|
||||
enqueueFunction,
|
||||
);
|
||||
late final tagNamer = TagNamer(
|
||||
settings.scrubAbsoluteUris,
|
||||
_module,
|
||||
enqueueTag,
|
||||
);
|
||||
late final tableNamer = TableNamer(
|
||||
settings.scrubAbsoluteUris,
|
||||
_module,
|
||||
enqueueTable,
|
||||
);
|
||||
late final dataNamer = DataNamer(
|
||||
settings.scrubAbsoluteUris,
|
||||
_module,
|
||||
enqueueDataSegment,
|
||||
);
|
||||
late final memoryNamer = MemoryNamer(
|
||||
settings.scrubAbsoluteUris,
|
||||
_module,
|
||||
enqueueMemory,
|
||||
);
|
||||
|
||||
final _types = <ir.DefType, String>{};
|
||||
final _tags = <ir.Tag, String>{};
|
||||
@@ -46,31 +67,38 @@ class ModulePrinter {
|
||||
ModulePrinter(this._module, {this.settings = const ModulePrintSettings()});
|
||||
|
||||
IrPrinter newIrPrinter() => IrPrinter._(
|
||||
settings.preferMultiline,
|
||||
_module,
|
||||
typeNamer,
|
||||
globalNamer,
|
||||
functionNamer,
|
||||
tagNamer,
|
||||
tableNamer,
|
||||
dataNamer,
|
||||
memoryNamer);
|
||||
settings.preferMultiline,
|
||||
_module,
|
||||
typeNamer,
|
||||
globalNamer,
|
||||
functionNamer,
|
||||
tagNamer,
|
||||
tableNamer,
|
||||
dataNamer,
|
||||
memoryNamer,
|
||||
);
|
||||
|
||||
void enqueueType(ir.DefType type) {
|
||||
if (!_types.containsKey(type)) {
|
||||
_types[type] = '';
|
||||
_generateDefType(type,
|
||||
includeConstituents: settings.printTypeConstituents(
|
||||
typeNamer.name(type, activateOnReferenceCallback: false)));
|
||||
_generateDefType(
|
||||
type,
|
||||
includeConstituents: settings.printTypeConstituents(
|
||||
typeNamer.name(type, activateOnReferenceCallback: false),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
void enqueueGlobal(ir.Global global) {
|
||||
if (!_globals.containsKey(global)) {
|
||||
_globals[global] = '';
|
||||
_generateGlobal(global,
|
||||
includeInitializer: settings.printGlobalInitializer(
|
||||
globalNamer.name(global, activateOnReferenceCallback: false)));
|
||||
_generateGlobal(
|
||||
global,
|
||||
includeInitializer: settings.printGlobalInitializer(
|
||||
globalNamer.name(global, activateOnReferenceCallback: false),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -116,14 +144,17 @@ class ModulePrinter {
|
||||
if (_elementSegments.add(segment)) {
|
||||
switch (segment) {
|
||||
case ir.ActiveFunctionElementSegment(
|
||||
startIndex: final start,
|
||||
table: final table,
|
||||
entries: final entries
|
||||
):
|
||||
final printedEntries =
|
||||
_activeElementSegments.putIfAbsent(table, () => {});
|
||||
if (settings.printTableElements(tableNamer.name(segment.table,
|
||||
activateOnReferenceCallback: false))) {
|
||||
startIndex: final start,
|
||||
table: final table,
|
||||
entries: final entries,
|
||||
):
|
||||
final printedEntries = _activeElementSegments.putIfAbsent(
|
||||
table,
|
||||
() => {},
|
||||
);
|
||||
if (settings.printTableElements(
|
||||
tableNamer.name(segment.table, activateOnReferenceCallback: false),
|
||||
)) {
|
||||
for (int i = 0; i < entries.length; ++i) {
|
||||
final index = start + i;
|
||||
final ip = newIrPrinter();
|
||||
@@ -136,14 +167,17 @@ class ModulePrinter {
|
||||
|
||||
break;
|
||||
case ir.ActiveExpressionElementSegment(
|
||||
startIndex: final start,
|
||||
table: final table,
|
||||
expressions: final expressions
|
||||
):
|
||||
final printedEntries =
|
||||
_activeElementSegments.putIfAbsent(table, () => {});
|
||||
if (settings.printTableElements(tableNamer.name(segment.table,
|
||||
activateOnReferenceCallback: false))) {
|
||||
startIndex: final start,
|
||||
table: final table,
|
||||
expressions: final expressions,
|
||||
):
|
||||
final printedEntries = _activeElementSegments.putIfAbsent(
|
||||
table,
|
||||
() => {},
|
||||
);
|
||||
if (settings.printTableElements(
|
||||
tableNamer.name(segment.table, activateOnReferenceCallback: false),
|
||||
)) {
|
||||
for (int i = 0; i < expressions.length; ++i) {
|
||||
final index = start + i;
|
||||
final expression = expressions[i];
|
||||
@@ -199,9 +233,12 @@ class ModulePrinter {
|
||||
while (_functionsQueue.isNotEmpty) {
|
||||
final fun = _functionsQueue.removeFirst();
|
||||
|
||||
_generateFunction(fun,
|
||||
includingBody: settings.printFunctionBody(
|
||||
functionNamer.name(fun, activateOnReferenceCallback: false)));
|
||||
_generateFunction(
|
||||
fun,
|
||||
includingBody: settings.printFunctionBody(
|
||||
functionNamer.name(fun, activateOnReferenceCallback: false),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -214,15 +251,21 @@ class ModulePrinter {
|
||||
if (settings.printInSortedOrder) {
|
||||
groups.sort((a, b) {
|
||||
final firstA = typeNamer.name(
|
||||
a.firstWhere((t) => !typeNamer
|
||||
a.firstWhere(
|
||||
(t) => !typeNamer
|
||||
.name(t, activateOnReferenceCallback: false)
|
||||
.startsWith('\$brand')),
|
||||
activateOnReferenceCallback: false);
|
||||
.startsWith('\$brand'),
|
||||
),
|
||||
activateOnReferenceCallback: false,
|
||||
);
|
||||
final firstB = typeNamer.name(
|
||||
b.firstWhere((t) => !typeNamer
|
||||
b.firstWhere(
|
||||
(t) => !typeNamer
|
||||
.name(t, activateOnReferenceCallback: false)
|
||||
.startsWith('\$brand')),
|
||||
activateOnReferenceCallback: false);
|
||||
.startsWith('\$brand'),
|
||||
),
|
||||
activateOnReferenceCallback: false,
|
||||
);
|
||||
return firstA.compareTo(firstB);
|
||||
});
|
||||
}
|
||||
@@ -247,14 +290,18 @@ class ModulePrinter {
|
||||
}
|
||||
|
||||
void printOrdered<T>(
|
||||
List<T> all, Namer<T> namer, Map<T, String> enqueued) {
|
||||
List<T> all,
|
||||
Namer<T> namer,
|
||||
Map<T, String> enqueued,
|
||||
) {
|
||||
/// Either we print the elements in the name order (defined by a
|
||||
/// [Namer]) or we print them in same order as they appear in the wasm
|
||||
/// module.
|
||||
final filtered = all.where((v) => enqueued.containsKey(v)).toList();
|
||||
for (final key in (settings.printInSortedOrder
|
||||
? namer.sort(filtered)
|
||||
: filtered)) {
|
||||
for (final key
|
||||
in (settings.printInSortedOrder
|
||||
? namer.sort(filtered)
|
||||
: filtered)) {
|
||||
mp.write(enqueued[key]!);
|
||||
mp.writeln();
|
||||
}
|
||||
@@ -336,8 +383,10 @@ class ModulePrinter {
|
||||
_functions[fun] = p.getText();
|
||||
}
|
||||
|
||||
void _generateFunction(ir.DefinedFunction fun,
|
||||
{required bool includingBody}) {
|
||||
void _generateFunction(
|
||||
ir.DefinedFunction fun, {
|
||||
required bool includingBody,
|
||||
}) {
|
||||
final p = newIrPrinter();
|
||||
if (includingBody) {
|
||||
fun.printTo(p);
|
||||
@@ -363,14 +412,15 @@ class ModulePrintSettings {
|
||||
final bool scrubAbsoluteUris;
|
||||
final bool printInSortedOrder;
|
||||
|
||||
const ModulePrintSettings(
|
||||
{this.functionFilters = const [],
|
||||
this.tableFilters = const [],
|
||||
this.globalFilters = const [],
|
||||
this.typeFilters = const [],
|
||||
this.preferMultiline = false,
|
||||
this.scrubAbsoluteUris = false,
|
||||
this.printInSortedOrder = false});
|
||||
const ModulePrintSettings({
|
||||
this.functionFilters = const [],
|
||||
this.tableFilters = const [],
|
||||
this.globalFilters = const [],
|
||||
this.typeFilters = const [],
|
||||
this.preferMultiline = false,
|
||||
this.scrubAbsoluteUris = false,
|
||||
this.printInSortedOrder = false,
|
||||
});
|
||||
|
||||
bool printFunctionBody(String name) {
|
||||
if (functionFilters.isEmpty) return true;
|
||||
@@ -488,28 +538,30 @@ class IrPrinter extends IndentPrinter {
|
||||
final _labelNamer = _LabelNamer();
|
||||
|
||||
IrPrinter._(
|
||||
this.preferMultiline,
|
||||
this.module,
|
||||
this._typeNamer,
|
||||
this._globalNamer,
|
||||
this._functionNamer,
|
||||
this._tagNamer,
|
||||
this._tableNamer,
|
||||
this._dataNamer,
|
||||
this._memoryNamer);
|
||||
this.preferMultiline,
|
||||
this.module,
|
||||
this._typeNamer,
|
||||
this._globalNamer,
|
||||
this._functionNamer,
|
||||
this._tagNamer,
|
||||
this._tableNamer,
|
||||
this._dataNamer,
|
||||
this._memoryNamer,
|
||||
);
|
||||
|
||||
/// Returns a new [IrPrinter] with same settings, but empty indentation,
|
||||
/// empty text content and no local namer.
|
||||
IrPrinter dup() => IrPrinter._(
|
||||
preferMultiline,
|
||||
module,
|
||||
_typeNamer,
|
||||
_globalNamer,
|
||||
_functionNamer,
|
||||
_tagNamer,
|
||||
_tableNamer,
|
||||
_dataNamer,
|
||||
_memoryNamer);
|
||||
preferMultiline,
|
||||
module,
|
||||
_typeNamer,
|
||||
_globalNamer,
|
||||
_functionNamer,
|
||||
_tagNamer,
|
||||
_tableNamer,
|
||||
_dataNamer,
|
||||
_memoryNamer,
|
||||
);
|
||||
|
||||
void beginLabeledBlock(ir.Instruction? instruction) {
|
||||
_labelNamer.stack.add(LabelInfo(instruction));
|
||||
@@ -538,8 +590,11 @@ class IrPrinter extends IndentPrinter {
|
||||
}
|
||||
|
||||
void withLocalNames(Map<int, String> names, void Function() fun) {
|
||||
_localNamer =
|
||||
_LocalNamer(_functionNamer._scrubAbsoluteFileUris, module, names);
|
||||
_localNamer = _LocalNamer(
|
||||
_functionNamer._scrubAbsoluteFileUris,
|
||||
module,
|
||||
names,
|
||||
);
|
||||
fun();
|
||||
_localNamer = null;
|
||||
}
|
||||
@@ -675,8 +730,12 @@ abstract class Namer<T> {
|
||||
|
||||
String name(T key, {bool activateOnReferenceCallback = true});
|
||||
|
||||
String _name(T key, String? name, String unnamedPrefix,
|
||||
bool activateOnReferenceCallback) {
|
||||
String _name(
|
||||
T key,
|
||||
String? name,
|
||||
String unnamedPrefix,
|
||||
bool activateOnReferenceCallback,
|
||||
) {
|
||||
final existing = _names[key];
|
||||
if (existing != null) return existing;
|
||||
|
||||
@@ -708,8 +767,10 @@ abstract class Namer<T> {
|
||||
|
||||
List<T> sort(List<T> values) => values.toList()
|
||||
..sort((a, b) {
|
||||
return name(a, activateOnReferenceCallback: false)
|
||||
.compareTo(name(b, activateOnReferenceCallback: false));
|
||||
return name(
|
||||
a,
|
||||
activateOnReferenceCallback: false,
|
||||
).compareTo(name(b, activateOnReferenceCallback: false));
|
||||
});
|
||||
}
|
||||
|
||||
@@ -717,10 +778,16 @@ class FunctionNamer extends Namer<ir.BaseFunction> {
|
||||
FunctionNamer(super.scrubAbsoluteUris, super.module, super.onReference);
|
||||
|
||||
@override
|
||||
String name(ir.BaseFunction function,
|
||||
{bool activateOnReferenceCallback = true}) {
|
||||
String name(
|
||||
ir.BaseFunction function, {
|
||||
bool activateOnReferenceCallback = true,
|
||||
}) {
|
||||
return super._name(
|
||||
function, function.functionName, '', activateOnReferenceCallback);
|
||||
function,
|
||||
function.functionName,
|
||||
'',
|
||||
activateOnReferenceCallback,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -754,8 +821,12 @@ class TypeNamer extends Namer<ir.DefType> {
|
||||
|
||||
@override
|
||||
String name(ir.DefType type, {bool activateOnReferenceCallback = true}) {
|
||||
return super._name(type, type is ir.DataType ? type.name : null, 'type',
|
||||
activateOnReferenceCallback);
|
||||
return super._name(
|
||||
type,
|
||||
type is ir.DataType ? type.name : null,
|
||||
'type',
|
||||
activateOnReferenceCallback,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -763,12 +834,16 @@ class _LocalNamer extends Namer<int> {
|
||||
final Map<int, String> _namedVariables;
|
||||
|
||||
_LocalNamer(bool scrubAbsoluteUris, ir.Module module, this._namedVariables)
|
||||
: super(scrubAbsoluteUris, module, (_) {});
|
||||
: super(scrubAbsoluteUris, module, (_) {});
|
||||
|
||||
@override
|
||||
String name(int index, {bool activateOnReferenceCallback = true}) {
|
||||
return super._name(
|
||||
index, _namedVariables[index], 'var', activateOnReferenceCallback);
|
||||
index,
|
||||
_namedVariables[index],
|
||||
'var',
|
||||
activateOnReferenceCallback,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -789,8 +864,10 @@ class DataNamer extends Namer<ir.BaseDataSegment> {
|
||||
DataNamer(super.scubUris, super.module, super.onReference);
|
||||
|
||||
@override
|
||||
String name(ir.BaseDataSegment data,
|
||||
{bool activateOnReferenceCallback = true}) {
|
||||
String name(
|
||||
ir.BaseDataSegment data, {
|
||||
bool activateOnReferenceCallback = true,
|
||||
}) {
|
||||
return super._name(data, null, 'data', true);
|
||||
}
|
||||
}
|
||||
@@ -801,10 +878,11 @@ class MemoryNamer extends Namer<ir.Memory> {
|
||||
@override
|
||||
String name(ir.Memory memory, {bool activateOnReferenceCallback = true}) {
|
||||
return super._name(
|
||||
memory,
|
||||
memory is ir.ImportedMemory ? '${memory.module}.${memory.name}' : null,
|
||||
'memory',
|
||||
activateOnReferenceCallback);
|
||||
memory,
|
||||
memory is ir.ImportedMemory ? '${memory.module}.${memory.name}' : null,
|
||||
'memory',
|
||||
activateOnReferenceCallback,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -19,8 +19,10 @@ abstract class Section implements Serializable {
|
||||
if (data.isNotEmpty) {
|
||||
s.writeByte(id);
|
||||
s.writeUnsigned(data.length);
|
||||
s.sourceMapSerializer
|
||||
.copyMappings(contents.sourceMapSerializer, s.offset);
|
||||
s.sourceMapSerializer.copyMappings(
|
||||
contents.sourceMapSerializer,
|
||||
s.offset,
|
||||
);
|
||||
s.writeData(contents, watchPoints);
|
||||
}
|
||||
}
|
||||
@@ -65,15 +67,17 @@ class TypeSection extends Section {
|
||||
}
|
||||
for (final type in group) {
|
||||
assert(
|
||||
type.superType == null || type.superType!.index <= group.last.index,
|
||||
"Type '$type' has a supertype in a later recursion group");
|
||||
type.superType == null || type.superType!.index <= group.last.index,
|
||||
"Type '$type' has a supertype in a later recursion group",
|
||||
);
|
||||
assert(
|
||||
type.constituentTypes
|
||||
.whereType<ir.RefType>()
|
||||
.map((t) => t.heapType)
|
||||
.whereType<ir.DefType>()
|
||||
.every((d) => d.index <= group.last.index),
|
||||
"Type '$type' depends on a type in a later recursion group");
|
||||
type.constituentTypes
|
||||
.whereType<ir.RefType>()
|
||||
.map((t) => t.heapType)
|
||||
.whereType<ir.DefType>()
|
||||
.every((d) => d.index <= group.last.index),
|
||||
"Type '$type' depends on a type in a later recursion group",
|
||||
);
|
||||
type.serializeDefinition(s);
|
||||
}
|
||||
}
|
||||
@@ -144,7 +148,10 @@ class ImportSection extends Section {
|
||||
}
|
||||
|
||||
static ir.Imports deserialize(
|
||||
Deserializer? d, ir.Module module, ir.Types types) {
|
||||
Deserializer? d,
|
||||
ir.Module module,
|
||||
ir.Types types,
|
||||
) {
|
||||
final imports = <ir.Import>[];
|
||||
final importedMemories = <ir.ImportedMemory>[];
|
||||
final importedGlobals = <ir.ImportedGlobal>[];
|
||||
@@ -163,7 +170,12 @@ class ImportSection extends Section {
|
||||
final typeIndex = d.readUnsigned();
|
||||
final type = types[typeIndex] as ir.FunctionType;
|
||||
final import = ir.ImportedFunction(
|
||||
module, moduleName, name, ir.FinalizableIndex(), type);
|
||||
module,
|
||||
moduleName,
|
||||
name,
|
||||
ir.FinalizableIndex(),
|
||||
type,
|
||||
);
|
||||
import.finalizableIndex.value = importedFunctions.length;
|
||||
importedFunctions.add(import);
|
||||
imports.add(import);
|
||||
@@ -173,8 +185,15 @@ class ImportSection extends Section {
|
||||
final limits = d.readByte();
|
||||
final minSize = d.readUnsigned();
|
||||
final maxSize = limits == 0x01 ? d.readUnsigned() : null;
|
||||
final import = ir.ImportedTable(module, moduleName, name,
|
||||
ir.FinalizableIndex(), type, minSize, maxSize);
|
||||
final import = ir.ImportedTable(
|
||||
module,
|
||||
moduleName,
|
||||
name,
|
||||
ir.FinalizableIndex(),
|
||||
type,
|
||||
minSize,
|
||||
maxSize,
|
||||
);
|
||||
import.finalizableIndex.value = importedTables.length;
|
||||
importedTables.add(import);
|
||||
imports.add(import);
|
||||
@@ -183,10 +202,18 @@ class ImportSection extends Section {
|
||||
final limits = d.readByte();
|
||||
final shared = limits == 0x03;
|
||||
final minSize = d.readUnsigned();
|
||||
final maxSize =
|
||||
limits == 0x01 || limits == 0x03 ? d.readUnsigned() : null;
|
||||
final import = ir.ImportedMemory(module, moduleName, name,
|
||||
ir.FinalizableIndex(), shared, minSize, maxSize);
|
||||
final maxSize = limits == 0x01 || limits == 0x03
|
||||
? d.readUnsigned()
|
||||
: null;
|
||||
final import = ir.ImportedMemory(
|
||||
module,
|
||||
moduleName,
|
||||
name,
|
||||
ir.FinalizableIndex(),
|
||||
shared,
|
||||
minSize,
|
||||
maxSize,
|
||||
);
|
||||
import.finalizableIndex.value = importedMemories.length;
|
||||
importedMemories.add(import);
|
||||
imports.add(import);
|
||||
@@ -194,7 +221,12 @@ class ImportSection extends Section {
|
||||
case 0x03: // Global
|
||||
final type = ir.GlobalType.deserialize(d, types.defined);
|
||||
final import = ir.ImportedGlobal(
|
||||
module, moduleName, name, ir.FinalizableIndex(), type);
|
||||
module,
|
||||
moduleName,
|
||||
name,
|
||||
ir.FinalizableIndex(),
|
||||
type,
|
||||
);
|
||||
import.finalizableIndex.value = importedGlobals.length;
|
||||
importedGlobals.add(import);
|
||||
imports.add(import);
|
||||
@@ -204,7 +236,12 @@ class ImportSection extends Section {
|
||||
if (exceptionByte != 0x00) throw 'unexpected';
|
||||
final type = types[d.readUnsigned()] as ir.FunctionType;
|
||||
final tag = ir.ImportedTag(
|
||||
module, moduleName, name, ir.FinalizableIndex(), type);
|
||||
module,
|
||||
moduleName,
|
||||
name,
|
||||
ir.FinalizableIndex(),
|
||||
type,
|
||||
);
|
||||
tag.finalizableIndex.value = importedTags.length;
|
||||
importedTags.add(tag);
|
||||
imports.add(tag);
|
||||
@@ -213,8 +250,14 @@ class ImportSection extends Section {
|
||||
}
|
||||
}
|
||||
}
|
||||
return ir.Imports.deserialized(imports, importedFunctions, importedTags,
|
||||
importedGlobals, importedTables, importedMemories);
|
||||
return ir.Imports.deserialized(
|
||||
imports,
|
||||
importedFunctions,
|
||||
importedTags,
|
||||
importedGlobals,
|
||||
importedTables,
|
||||
importedMemories,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -238,8 +281,12 @@ class FunctionSection extends Section {
|
||||
}
|
||||
}
|
||||
|
||||
static ir.Functions deserialize(Deserializer? d, ir.Module module,
|
||||
ir.Types types, List<ir.ImportedFunction> imported) {
|
||||
static ir.Functions deserialize(
|
||||
Deserializer? d,
|
||||
ir.Module module,
|
||||
ir.Types types,
|
||||
List<ir.ImportedFunction> imported,
|
||||
) {
|
||||
if (d == null) {
|
||||
return ir.Functions(imported, []);
|
||||
}
|
||||
@@ -250,7 +297,10 @@ class FunctionSection extends Section {
|
||||
final typeIndex = d.readUnsigned();
|
||||
final type = types[typeIndex] as ir.FunctionType;
|
||||
final function = ir.DefinedFunction.withoutBody(
|
||||
module, ir.FinalizableIndex()..value = imported.length + i, type);
|
||||
module,
|
||||
ir.FinalizableIndex()..value = imported.length + i,
|
||||
type,
|
||||
);
|
||||
defined.add(function);
|
||||
}
|
||||
return ir.Functions(imported, defined);
|
||||
@@ -274,8 +324,12 @@ class TableSection extends Section {
|
||||
}
|
||||
}
|
||||
|
||||
static ir.Tables deserialize(Deserializer? d, ir.Module module,
|
||||
ir.Types types, List<ir.ImportedTable> imported) {
|
||||
static ir.Tables deserialize(
|
||||
Deserializer? d,
|
||||
ir.Module module,
|
||||
ir.Types types,
|
||||
List<ir.ImportedTable> imported,
|
||||
) {
|
||||
if (d == null) return ir.Tables(imported, []);
|
||||
|
||||
final defined = <ir.DefinedTable>[];
|
||||
@@ -286,11 +340,12 @@ class TableSection extends Section {
|
||||
final minSize = d.readUnsigned();
|
||||
final maxSize = limits == 0x01 ? d.readUnsigned() : null;
|
||||
final table = ir.DefinedTable(
|
||||
module,
|
||||
ir.FinalizableIndex()..value = imported.length + i,
|
||||
type,
|
||||
minSize,
|
||||
maxSize);
|
||||
module,
|
||||
ir.FinalizableIndex()..value = imported.length + i,
|
||||
type,
|
||||
minSize,
|
||||
maxSize,
|
||||
);
|
||||
defined.add(table);
|
||||
}
|
||||
return ir.Tables(imported, defined);
|
||||
@@ -315,7 +370,10 @@ class MemorySection extends Section {
|
||||
}
|
||||
|
||||
static ir.Memories deserialize(
|
||||
Deserializer? d, ir.Module module, List<ir.ImportedMemory> imported) {
|
||||
Deserializer? d,
|
||||
ir.Module module,
|
||||
List<ir.ImportedMemory> imported,
|
||||
) {
|
||||
if (d == null) return ir.Memories(imported, []);
|
||||
|
||||
final defined = <ir.DefinedMemory>[];
|
||||
@@ -324,14 +382,16 @@ class MemorySection extends Section {
|
||||
final limits = d.readByte();
|
||||
final shared = limits == 0x03;
|
||||
final minSize = d.readUnsigned();
|
||||
final maxSize =
|
||||
limits == 0x01 || limits == 0x03 ? d.readUnsigned() : null;
|
||||
final maxSize = limits == 0x01 || limits == 0x03
|
||||
? d.readUnsigned()
|
||||
: null;
|
||||
final memory = ir.DefinedMemory(
|
||||
module,
|
||||
ir.FinalizableIndex()..value = imported.length + i,
|
||||
shared,
|
||||
minSize,
|
||||
maxSize);
|
||||
module,
|
||||
ir.FinalizableIndex()..value = imported.length + i,
|
||||
shared,
|
||||
minSize,
|
||||
maxSize,
|
||||
);
|
||||
defined.add(memory);
|
||||
}
|
||||
return ir.Memories(imported, defined);
|
||||
@@ -355,8 +415,12 @@ class TagSection extends Section {
|
||||
}
|
||||
}
|
||||
|
||||
static ir.Tags deserialize(Deserializer? d, ir.Module module, ir.Types types,
|
||||
List<ir.ImportedTag> imported) {
|
||||
static ir.Tags deserialize(
|
||||
Deserializer? d,
|
||||
ir.Module module,
|
||||
ir.Types types,
|
||||
List<ir.ImportedTag> imported,
|
||||
) {
|
||||
if (d == null) return ir.Tags(imported, []);
|
||||
|
||||
final defined = <ir.DefinedTag>[];
|
||||
@@ -368,7 +432,10 @@ class TagSection extends Section {
|
||||
}
|
||||
final type = types[d.readUnsigned()] as ir.FunctionType;
|
||||
final tag = ir.DefinedTag(
|
||||
module, ir.FinalizableIndex()..value = imported.length + i, type);
|
||||
module,
|
||||
ir.FinalizableIndex()..value = imported.length + i,
|
||||
type,
|
||||
);
|
||||
defined.add(tag);
|
||||
}
|
||||
return ir.Tags(imported, defined);
|
||||
@@ -393,11 +460,12 @@ class GlobalSection extends Section {
|
||||
}
|
||||
|
||||
static ir.Globals deserialize(
|
||||
Deserializer? d,
|
||||
ir.Module module,
|
||||
ir.Types types,
|
||||
ir.Functions functions,
|
||||
List<ir.ImportedGlobal> imported) {
|
||||
Deserializer? d,
|
||||
ir.Module module,
|
||||
ir.Types types,
|
||||
ir.Functions functions,
|
||||
List<ir.ImportedGlobal> imported,
|
||||
) {
|
||||
if (d == null) {
|
||||
return ir.Globals(imported, []);
|
||||
}
|
||||
@@ -407,10 +475,18 @@ class GlobalSection extends Section {
|
||||
final count = d.readUnsigned();
|
||||
for (int i = 0; i < count; i++) {
|
||||
final type = ir.GlobalType.deserialize(d, types.defined);
|
||||
final initializer =
|
||||
ir.Instructions.deserializeConst(d, types, functions, globals);
|
||||
final global = ir.DefinedGlobal(module, initializer,
|
||||
ir.FinalizableIndex()..value = globals.length, type);
|
||||
final initializer = ir.Instructions.deserializeConst(
|
||||
d,
|
||||
types,
|
||||
functions,
|
||||
globals,
|
||||
);
|
||||
final global = ir.DefinedGlobal(
|
||||
module,
|
||||
initializer,
|
||||
ir.FinalizableIndex()..value = globals.length,
|
||||
type,
|
||||
);
|
||||
globals.defined.add(global);
|
||||
}
|
||||
return globals;
|
||||
@@ -435,12 +511,13 @@ class ExportSection extends Section {
|
||||
}
|
||||
|
||||
static ir.Exports deserialize(
|
||||
Deserializer? d,
|
||||
ir.Functions functions,
|
||||
ir.Tables tables,
|
||||
ir.Memories memories,
|
||||
ir.Globals globals,
|
||||
ir.Tags tags) {
|
||||
Deserializer? d,
|
||||
ir.Functions functions,
|
||||
ir.Tables tables,
|
||||
ir.Memories memories,
|
||||
ir.Globals globals,
|
||||
ir.Tags tags,
|
||||
) {
|
||||
if (d == null) {
|
||||
return ir.Exports([]);
|
||||
}
|
||||
@@ -532,14 +609,26 @@ class ElementSection extends Section {
|
||||
if (byte == 0x00 || byte == 0x02) {
|
||||
// Active element, table values are function indices.
|
||||
final es = ir.ActiveFunctionElementSegment.deserialize(
|
||||
d, module, types, functions, tables, globals);
|
||||
d,
|
||||
module,
|
||||
types,
|
||||
functions,
|
||||
tables,
|
||||
globals,
|
||||
);
|
||||
segments.add(es);
|
||||
continue;
|
||||
}
|
||||
if (byte == 0x04 || byte == 0x06) {
|
||||
// Active element, table values are expressions.
|
||||
final es = ir.ActiveExpressionElementSegment.deserialize(
|
||||
d, module, types, functions, tables, globals);
|
||||
d,
|
||||
module,
|
||||
types,
|
||||
functions,
|
||||
tables,
|
||||
globals,
|
||||
);
|
||||
segments.add(es);
|
||||
continue;
|
||||
}
|
||||
@@ -572,7 +661,7 @@ class DataCountSection extends Section {
|
||||
}
|
||||
final count = d.readUnsigned();
|
||||
final uninitializedSegments = [
|
||||
for (int i = 0; i < count; ++i) ir.DataSegment.uninitialized()
|
||||
for (int i = 0; i < count; ++i) ir.DataSegment.uninitialized(),
|
||||
];
|
||||
return ir.DataSegments(uninitializedSegments);
|
||||
}
|
||||
@@ -638,8 +727,16 @@ class CodeSection extends Section {
|
||||
}
|
||||
}
|
||||
while (!bodyDeserializer.isAtEnd) {
|
||||
final instruction = ir.Instruction.deserialize(bodyDeserializer, types,
|
||||
tables, tags, globals, dataSegments, memories, functions);
|
||||
final instruction = ir.Instruction.deserialize(
|
||||
bodyDeserializer,
|
||||
types,
|
||||
tables,
|
||||
tags,
|
||||
globals,
|
||||
dataSegments,
|
||||
memories,
|
||||
functions,
|
||||
);
|
||||
instructions.add(instruction);
|
||||
}
|
||||
|
||||
@@ -666,7 +763,10 @@ class DataSection extends Section {
|
||||
}
|
||||
|
||||
static void deserialize(
|
||||
Deserializer? d, ir.DataSegments dataSegments, ir.Memories memories) {
|
||||
Deserializer? d,
|
||||
ir.DataSegments dataSegments,
|
||||
ir.Memories memories,
|
||||
) {
|
||||
final defined = dataSegments.defined;
|
||||
if (d == null) {
|
||||
assert(defined.isEmpty);
|
||||
@@ -830,47 +930,61 @@ class NameSection extends CustomSection {
|
||||
|
||||
if (functionNameCount > 0) {
|
||||
s.writeByte(1); // Function names subsection
|
||||
s.writeUnsigned(functionNames.data.length +
|
||||
Serializer.writeUnsignedByteCount(functionNameCount));
|
||||
s.writeUnsigned(
|
||||
functionNames.data.length +
|
||||
Serializer.writeUnsignedByteCount(functionNameCount),
|
||||
);
|
||||
s.writeUnsigned(functionNameCount);
|
||||
s.writeData(functionNames);
|
||||
}
|
||||
|
||||
if (functionsWithLocalNamesCount > 0) {
|
||||
s.writeByte(2); // Local names substion
|
||||
s.writeUnsigned(localNames.data.length +
|
||||
Serializer.writeUnsignedByteCount(functionsWithLocalNamesCount));
|
||||
s.writeUnsigned(
|
||||
localNames.data.length +
|
||||
Serializer.writeUnsignedByteCount(functionsWithLocalNamesCount),
|
||||
);
|
||||
s.writeUnsigned(functionsWithLocalNamesCount);
|
||||
s.writeData(localNames);
|
||||
}
|
||||
|
||||
if (typeNameCount > 0) {
|
||||
s.writeByte(4); // Type names subsection
|
||||
s.writeUnsigned(typeNames.data.length +
|
||||
Serializer.writeUnsignedByteCount(typeNameCount));
|
||||
s.writeUnsigned(
|
||||
typeNames.data.length +
|
||||
Serializer.writeUnsignedByteCount(typeNameCount),
|
||||
);
|
||||
s.writeUnsigned(typeNameCount);
|
||||
s.writeData(typeNames);
|
||||
}
|
||||
|
||||
if (globalNameCount > 0) {
|
||||
s.writeByte(7); // Global names subsection
|
||||
s.writeUnsigned(globalNames.data.length +
|
||||
Serializer.writeUnsignedByteCount(globalNameCount));
|
||||
s.writeUnsigned(
|
||||
globalNames.data.length +
|
||||
Serializer.writeUnsignedByteCount(globalNameCount),
|
||||
);
|
||||
s.writeUnsigned(globalNameCount);
|
||||
s.writeData(globalNames);
|
||||
}
|
||||
|
||||
if (typesWithNamedFieldsCount > 0) {
|
||||
s.writeByte(10); // Field names subsection
|
||||
s.writeUnsigned(fieldNames.data.length +
|
||||
Serializer.writeUnsignedByteCount(typesWithNamedFieldsCount));
|
||||
s.writeUnsigned(
|
||||
fieldNames.data.length +
|
||||
Serializer.writeUnsignedByteCount(typesWithNamedFieldsCount),
|
||||
);
|
||||
s.writeUnsigned(typesWithNamedFieldsCount);
|
||||
s.writeData(fieldNames);
|
||||
}
|
||||
}
|
||||
|
||||
static String? deserialize(Deserializer? d, ir.Functions functions,
|
||||
ir.Types types, ir.Globals globals) {
|
||||
static String? deserialize(
|
||||
Deserializer? d,
|
||||
ir.Functions functions,
|
||||
ir.Types types,
|
||||
ir.Globals globals,
|
||||
) {
|
||||
String? moduleName;
|
||||
|
||||
if (d == null) {
|
||||
@@ -1016,7 +1130,8 @@ class RemovableIfUnusedSection extends CustomSection {
|
||||
final offset = d.readUnsigned(); // Offset (0 == function-level)
|
||||
if (offset != 0) {
|
||||
throw UnsupportedError(
|
||||
'Only function-level ($customSectionName) annotation supported.');
|
||||
'Only function-level ($customSectionName) annotation supported.',
|
||||
);
|
||||
}
|
||||
final data = d.readUnsigned(); // always 0
|
||||
if (data != 0) {
|
||||
|
||||
Reference in New Issue
Block a user