[dart2wasm] Allow giving names to globals in the module globals section

Currently no globals are named, so the subsection will be empty. Three
extra bytes will be generated in the names section for the empty
subsection.

When debugging we can now name globals with the optional positional
argument:

    // "my global" is new:
    m.globals.define(w.GlobalType(type), "my global")

wasm-opt and v8 (d8, wami) support the subsection, so the global will
now appear as "my global" in the debugger and Wast outputs.

Change-Id: I5988ab792209c5c82593b85c48fead65ad536031
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/355120
Reviewed-by: Martin Kustermann <kustermann@google.com>
Commit-Queue: Ömer Ağacan <omersa@google.com>
This commit is contained in:
Ömer Sinan Ağacan 2024-03-07 11:51:57 +00:00 committed by Commit Queue
parent a85689758e
commit 511bffedca
7 changed files with 51 additions and 14 deletions

View file

@ -8,11 +8,12 @@ part of 'globals.dart';
class GlobalBuilder extends ir.Global with IndexableBuilder<ir.DefinedGlobal> {
final InstructionsBuilder initializer;
GlobalBuilder(ModuleBuilder module, super.index, super.type)
GlobalBuilder(ModuleBuilder module, super.index, super.type,
[super.globalName])
: initializer =
InstructionsBuilder(module, [type.type], isGlobalInitializer: true);
@override
ir.DefinedGlobal forceBuild() =>
ir.DefinedGlobal(initializer.build(), finalizableIndex, type);
ir.DefinedGlobal(initializer.build(), finalizableIndex, type, globalName);
}

View file

@ -13,12 +13,18 @@ class GlobalsBuilder with Builder<ir.Globals> {
final _importedGlobals = <ir.Import>[];
final _globalBuilders = <GlobalBuilder>[];
/// Number of named globals.
int _namedCount = 0;
GlobalsBuilder(this._module);
/// Defines a new global variable in this module.
GlobalBuilder define(ir.GlobalType type) {
final global = GlobalBuilder(_module, ir.FinalizableIndex(), type);
GlobalBuilder define(ir.GlobalType type, [String? name]) {
final global = GlobalBuilder(_module, ir.FinalizableIndex(), type, name);
_globalBuilders.add(global);
if (name != null) {
_namedCount += 1;
}
return global;
}
@ -36,6 +42,6 @@ class GlobalsBuilder with Builder<ir.Globals> {
ir.Globals forceBuild() {
final built = finalizeImportsAndBuilders<ir.DefinedGlobal>(
_importedGlobals, _globalBuilders);
return ir.Globals(_importedGlobals, built);
return ir.Globals(_importedGlobals, built, _namedCount);
}
}

View file

@ -10,10 +10,13 @@ abstract class Global with Indexable implements Exportable {
final FinalizableIndex finalizableIndex;
final GlobalType type;
Global(this.finalizableIndex, this.type);
/// Name of the global in the names section.
final String? globalName;
Global(this.finalizableIndex, this.type, this.globalName);
@override
String toString() => "$finalizableIndex";
String toString() => globalName ?? "$finalizableIndex";
@override
Export export(String name) => GlobalExport(name, this);
@ -23,7 +26,8 @@ abstract class Global with Indexable implements Exportable {
class DefinedGlobal extends Global implements Serializable {
final Instructions initializer;
DefinedGlobal(this.initializer, super.finalizableIndex, super.type);
DefinedGlobal(this.initializer, super.finalizableIndex, super.type,
[super.globalName]);
@override
void serialize(Serializer s) {
@ -36,10 +40,12 @@ class DefinedGlobal extends Global implements Serializable {
class ImportedGlobal extends Global implements Import {
@override
final String module;
@override
final String name;
ImportedGlobal(this.module, this.name, super.finalizableIndex, super.type);
ImportedGlobal(this.module, this.name, super.finalizableIndex, super.type,
[super.globalName]);
@override
void serialize(Serializer s) {

View file

@ -14,5 +14,8 @@ class Globals {
/// Defined globals.
final List<DefinedGlobal> defined;
Globals(this.imported, this.defined);
/// Number of named globals.
final int namedCount;
Globals(this.imported, this.defined, this.namedCount);
}

View file

@ -8,6 +8,7 @@ import 'ir.dart';
/// Any import (function, table, memory or global).
abstract class Import implements Indexable, Serializable {
String get module;
@override
String get name;
}

View file

@ -59,9 +59,10 @@ class Module implements Serializable {
CodeSection(functions.defined, watchPoints).serialize(s);
DataSection(dataSegments.defined, watchPoints).serialize(s);
if (functions.namedCount > 0 || types.namedCount > 0) {
NameSection(functions.all, types.defined, watchPoints,
NameSection(functions.all, types.defined, globals.defined, watchPoints,
functionNameCount: functions.namedCount,
typeNameCount: types.namedCount)
typeNameCount: types.namedCount,
globalNameCount: globals.namedCount)
.serialize(s);
}
}

View file

@ -330,11 +330,15 @@ abstract class CustomSection extends Section {
class NameSection extends CustomSection {
final List<ir.BaseFunction> functions;
final List<ir.DefType> types;
final List<ir.Global> globals;
final int functionNameCount;
final int typeNameCount;
final int globalNameCount;
NameSection(this.functions, this.types, super.watchPoints,
{required this.functionNameCount, required this.typeNameCount});
NameSection(this.functions, this.types, this.globals, super.watchPoints,
{required this.functionNameCount,
required this.typeNameCount,
required this.globalNameCount});
@override
bool get isNotEmpty => functionNameCount > 0 || typeNameCount > 0;
@ -363,11 +367,26 @@ class NameSection extends CustomSection {
}
}
final globalNameSubsection = Serializer();
globalNameSubsection.writeUnsigned(globalNameCount);
for (int i = 0; i < globals.length; i++) {
final globalName = globals[i].globalName;
if (globalName != null) {
globalNameSubsection.writeUnsigned(i);
globalNameSubsection.writeName(globalName);
}
}
s.writeByte(1); // Function names subsection
s.writeUnsigned(functionNameSubsection.data.length);
s.writeData(functionNameSubsection);
s.writeByte(4); // Type names subsection
s.writeUnsigned(typeNameSubsection.data.length);
s.writeData(typeNameSubsection);
s.writeByte(7); // Global names subsection
s.writeUnsigned(globalNameSubsection.data.length);
s.writeData(globalNameSubsection);
}
}