Skip to content

Conversation

@adamperlin
Copy link
Contributor

@adamperlin adamperlin commented Jan 5, 2026

This PR implements support for a data section in crossgen emitted wasm r2r output files.
As part of this goal, the WasmObjectWriter class has been adapted to better conform to the base ObjectWriter interface, so that the base class's method can be used to process DependencyNodes.

Each separate data-like is represented as a single data segment, and the segments are then merged into a single data section as is required by the Wasm format.

GetOrCreateSection(ObjectNodeSection.ManagedCodeWindowsContentSection);
}
else
else if (_nodeFactory.Target.OperatingSystem != TargetOS.Browser)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Once #122511 is in, we should remove this OS check and instead handle this with an override of GetEmitSection in WasmObjectWriter.

Comment on lines 85 to 87
// Write the number of functions
writer.WriteULEB128((ulong)methodBodies.Count);
for (int i = 0; i < methodBodies.Count; i++)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For these array-based sections, could we do the following?

  • Skip the "count" header.
  • When a node for such a section is seen, emit the data into the section and record that we emitted a node into the section.
  • When emitting the object file, emit the "count" header before emitting the section data.

With this design, we could avoid having this split between "emit into the section as we process the nodes" and "emit at the end".

Copy link
Contributor Author

@adamperlin adamperlin Jan 10, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is mostly implemented now, but I'm going to change the way we write method bodies according to your other comment below about RecordMethod.

Comment on lines 66 to 72
public static readonly ObjectNodeSection WasmCodeSection = new ObjectNodeSection("wasm.code", SectionType.Executable, needsAlign: false);
// TODO-Wasm: consider alignment of data sections
public static readonly ObjectNodeSection WasmDataSection = new ObjectNodeSection("wasm.data", SectionType.Writeable, needsAlign: false);
public static readonly ObjectNodeSection WasmFunctionSection = new ObjectNodeSection("wasm.function", SectionType.ReadOnly, needsAlign: false);
public static readonly ObjectNodeSection WasmTypeSection = new ObjectNodeSection("wasm.type", SectionType.ReadOnly, needsAlign: false);
public static readonly ObjectNodeSection WasmExportSection = new ObjectNodeSection("wasm.export", SectionType.ReadOnly, needsAlign: false);
public static readonly ObjectNodeSection WasmMemorySection = new ObjectNodeSection("wasm.memory", SectionType.ReadOnly, needsAlign: false);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If these sections won't be returned by ObjectNode.GetSection, then they should be defined in WasmObjectWriter.

Comment on lines +521 to +528
// Write the data if:
// 1. We are in unified code/data layout mode so separating code and data nodes doesn't matter, OR
// 2. We are in separate code data layout mode but are writing data nodes
// Note that this has to be done last as not to advance the section writer position.
if (LayoutMode == CodeDataLayout.Unified || node.GetSection(_nodeFactory) != ObjectNodeSection.TextSection)
{
sectionWriter.EmitData(nodeContents.Data);
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we change RecordMethod to only write the signature into the signature table and the signature index into the function table, we should be able to change this code to just emit the data directly.

I guess we'd need a way to also prepend length here. We could do that with a bool property that wasm sets (and we only do it for when that property is true and we're emitting into the text section).

Or, we could add a feature to the section writer so the writer for the Text section always prepends length.

@adamperlin adamperlin marked this pull request as ready for review January 9, 2026 22:04
Copilot AI review requested due to automatic review settings January 9, 2026 22:04
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR implements support for writing R2R metadata into WebAssembly data sections by extending the WasmObjectWriter class. The changes enable crossgen2 to emit Wasm object files with proper data section support, which is critical for R2R compilation targeting WebAssembly.

Key changes:

  • Introduced a CodeDataLayoutMode enum to distinguish between platforms that require unified vs. separate code/data address spaces (Wasm32 requires separate)
  • Refactored WasmObjectWriter to use the base ObjectWriter class's methods for processing DependencyNodes instead of fully overriding EmitObject
  • Implemented WebAssembly data segment support, where each data section is represented as a segment that gets merged into a single data section per Wasm format requirements

Reviewed changes

Copilot reviewed 12 out of 12 changed files in this pull request and generated 16 comments.

Show a summary per file
File Description
ILCompiler.ReadyToRun.csproj Added reference to CodeDataLayoutMode.cs for R2R compiler
ILCompiler.Compiler.csproj Added reference to CodeDataLayoutMode.cs for AOT compiler
CodeDataLayoutMode.cs New file defining the CodeDataLayout enum (Unified/Separate) for platform-specific code/data layout requirements
WasmObjectWriter.cs Major refactor to support data sections: added RecordMethod, EmitSymbolTable, EmitRelocations, EmitObjectFile overrides; implemented WasmDataSection and WasmDataSegment classes for proper Wasm binary format encoding
WasmNative.cs Added WasmConstExpr and WasmExprKind for encoding constant expressions in data segments (used for memory offset calculations)
SectionWriter.cs Exposed Buffer property to allow direct access to underlying buffer writer for Wasm encoding
ObjectWriter.cs Added CodeDataLayout support, made _insPaddingByte nullable for Wasm, added RecordMethod virtual method, updated EmitRelocations and EmitObjectFile signatures to include Logger parameter
PEObjectWriter.cs Updated method signatures to match base class changes (Logger parameter)
MachObjectWriter.cs Updated method signatures to match base class changes (Logger parameter)
ElfObjectWriter.cs Updated method signatures to match base class changes (Logger parameter)
CoffObjectWriter.cs Updated method signatures to match base class changes (Logger parameter)
ObjectNodeSection.cs Added NeedsAlignment property and new constructor; added Wasm-specific section definitions (WasmCodeSection, WasmDataSection, etc.)

adamperlin and others added 7 commits January 9, 2026 14:35
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
…r.cs

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
…r.cs

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
…erlin/runtime into adamperlin/wasm-object-writer-v0.2
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants