[RyuJIT Wasm] WasmObjectWriter Webcil Envelope Support#125468
[RyuJIT Wasm] WasmObjectWriter Webcil Envelope Support#125468adamperlin wants to merge 33 commits intodotnet:mainfrom
Conversation
…-object-writer-webcil
Stemming from incorrect start address calculation for first data section, and passing in wrong section start pointer Enable emitting AssemblyStubNode's and SymbolRangeNodes on Wasm into data section (contents still not correct)
…gs and add associated asserts
Move WasmFunction type definition to a more suitable spot (and fix ilc compilation)
…-object-writer-webcil
There was a problem hiding this comment.
Pull request overview
Adds initial WebCIL “envelope” emission support to the CoreCLR AOT Wasm object writer so the runtime can locate PE/CLI header data and debug directory data inside a WebAssembly binary.
Changes:
- Introduces
WebcilHeader/WebcilSectionHeaderencoders and wiresWebcil.csinto ILCompiler projects. - Extends
WasmObjectWriterto build a flat WebCIL segment, resolve PE-style relocations into it, and emit it as passive Wasm data segments (with DataCount + exported helpers/globals). - Adjusts dependency tracking so Wasm methods get explicit signature nodes, and updates some Wasm-specific section placement logic.
Reviewed changes
Copilot reviewed 10 out of 11 changed files in this pull request and generated 12 comments.
Show a summary per file
| File | Description |
|---|---|
| src/coreclr/tools/aot/ILCompiler.ReadyToRun/ILCompiler.ReadyToRun.csproj | Adds Webcil.cs to the ReadyToRun tool build. |
| src/coreclr/tools/aot/ILCompiler.ReadyToRun/Compiler/DependencyAnalysis/ReadyToRun/MethodWithGCInfo.cs | Adds a Wasm32-only dependency on WasmTypeNode for explicit signatures. |
| src/coreclr/tools/aot/ILCompiler.Compiler/ILCompiler.Compiler.csproj | Adds Webcil.cs to the compiler tool build. |
| src/coreclr/tools/Common/Compiler/ObjectWriter/Webcil.cs | New: encodes WebCIL header + section headers. |
| src/coreclr/tools/Common/Compiler/ObjectWriter/WasmObjectWriter.cs | Major: builds/emits WebCIL payload as Wasm data segments; adds DataCount/Global handling and relocation resolution changes. |
| src/coreclr/tools/Common/Compiler/ObjectWriter/WasmNative.cs | Adds WasmGlobal encoding support. |
| src/coreclr/tools/Common/Compiler/ObjectWriter/WasmInstructions.cs | Adds instruction helpers needed for emitted Wasm stubs (locals + memory.init). |
| src/coreclr/tools/Common/Compiler/ObjectWriter/ObjectWriter.cs | Adds Wasm-related adjustments and several debug Console.WriteLine statements during emission/relocation. |
| src/coreclr/tools/Common/Compiler/DependencyAnalysis/Target_Wasm/WasmTypes.cs | Formatting tweak in WasmValueType. |
| src/coreclr/tools/Common/Compiler/DependencyAnalysis/Relocation.cs | Exposes WASM_PADDED_RELOC_SIZE_32 publicly for reuse. |
| src/coreclr/tools/Common/Compiler/DependencyAnalysis/AssemblyStubNode.cs | Places AssemblyStubNode into read-only data for Wasm targets. |
You can also share your feedback on Copilot code review. Take the survey.
src/coreclr/tools/Common/Compiler/ObjectWriter/WasmObjectWriter.cs
Outdated
Show resolved
Hide resolved
src/coreclr/tools/Common/Compiler/ObjectWriter/WasmObjectWriter.cs
Outdated
Show resolved
Hide resolved
src/coreclr/tools/Common/Compiler/ObjectWriter/WasmObjectWriter.cs
Outdated
Show resolved
Hide resolved
src/coreclr/tools/Common/Compiler/ObjectWriter/WasmObjectWriter.cs
Outdated
Show resolved
Hide resolved
src/coreclr/tools/Common/Compiler/ObjectWriter/WasmObjectWriter.cs
Outdated
Show resolved
Hide resolved
…or webcil sections and check alignment constraints in BuildWebcilDataSegment()
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 13 out of 14 changed files in this pull request and generated 5 comments.
You can also share your feedback on Copilot code review. Take the survey.
src/coreclr/tools/Common/Compiler/ObjectWriter/WasmObjectWriter.cs
Outdated
Show resolved
Hide resolved
src/coreclr/tools/Common/Compiler/ObjectWriter/WasmObjectWriter.cs
Outdated
Show resolved
Hide resolved
...Microsoft.NET.WebAssembly.Webcil.Validator/Microsoft.NET.WebAssembly.Webcil.Validator.csproj
Outdated
Show resolved
Hide resolved
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 13 out of 14 changed files in this pull request and generated 7 comments.
Comments suppressed due to low confidence (1)
src/coreclr/tools/Common/Compiler/ObjectWriter/ObjectWriter.cs:389
- This change makes all
ISymbolRangeNodehandling unconditional (previously gated byLayoutMode == CodeDataLayout.Unified). If the original condition was important for non-Wasm backends or for separate-layout scenarios, this risks changing behavior beyond Wasm. Consider restricting this to the Wasm path (or otherwise documenting why it is now correct for all targets/layout modes).
// TODO-WASM: emit symbol ranges properly when code and data are separated
// Right now we still need to determine placements for some traditionally text-placed nodes,
// such as DebugDirectoryEntryNode and AssemblyStubNode
if (depNode is ISymbolRangeNode symbolRange)
{
symbolRangeNodes.Add(symbolRange);
continue;
}
You can also share your feedback on Copilot code review. Take the survey.
src/coreclr/tools/Common/Compiler/ObjectWriter/WasmObjectWriter.cs
Outdated
Show resolved
Hide resolved
src/coreclr/tools/Common/Compiler/ObjectWriter/WasmObjectWriter.cs
Outdated
Show resolved
Hide resolved
src/coreclr/tools/Common/Compiler/ObjectWriter/WasmObjectWriter.cs
Outdated
Show resolved
Hide resolved
src/coreclr/tools/Common/Compiler/ObjectWriter/WasmObjectWriter.cs
Outdated
Show resolved
Hide resolved
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
…m/Webcil.cs and unify type definition with WasmObjectWriter
…-object-writer-webcil
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 18 out of 18 changed files in this pull request and generated 7 comments.
Comments suppressed due to low confidence (1)
src/coreclr/tools/Common/Compiler/ObjectWriter/ObjectWriter.cs:456
AssemblyStubNodeis no longer skipped for Wasm during object emission, but the Wasm implementations of severalAssemblyStubNodederivatives still throwNotImplementedException(e.g.Target_Wasm/WasmReadyToRunHelperNode.cs). If any of these nodes are present (they’re created byNodeFactory.CreateReadyToRunHelperNode), this change will cause the Wasm/R2R build to fail at emit time. Consider restoring the WasmAssemblyStubNodeskip until the Wasm stub emitters are implemented, or implement the required Wasm emitters before allowing these nodes to be emitted.
if (node is INodeWithTypeSignature codeNode && _nodeFactory.Target.IsWasm)
{
Debug.Assert(codeNode.Signature != null, $"Wasm code node {codeNode.GetType()} has null signature");
// TODO: eventually this should check IMethodCodeNodeWithTypeSignature
// Once we have signatures implemented for all code-carrying nodes
if (node is IMethodBodyNode methodNode)
{
// Record only information we can get from the MethodDesc here. The actual
// body will be emitted by the call to EmitData() at the end
// of this loop iteration.
RecordMethodDeclaration(codeNode, methodNode.Method);
}
}
You can also share your feedback on Copilot code review. Take the survey.
src/coreclr/tools/Common/Compiler/ObjectWriter/WasmObjectWriter.cs
Outdated
Show resolved
Hide resolved
src/coreclr/tools/aot/ILCompiler.ReadyToRun/ILCompiler.ReadyToRun.csproj
Outdated
Show resolved
Hide resolved
src/tasks/Microsoft.NET.WebAssembly.Webcil.Validator/Program.cs
Outdated
Show resolved
Hide resolved
...Microsoft.NET.WebAssembly.Webcil.Validator/Microsoft.NET.WebAssembly.Webcil.Validator.csproj
Outdated
Show resolved
Hide resolved
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 18 out of 18 changed files in this pull request and generated 4 comments.
You can also share your feedback on Copilot code review. Take the survey.
src/coreclr/tools/aot/ILCompiler.ReadyToRun/ILCompiler.ReadyToRun.csproj
Outdated
Show resolved
Hide resolved
| Relocation.WriteValue(reloc.Type, pData, virtualSymbolImageOffset - (virtualRelocOffset + relocLength) + addend); | ||
| break; | ||
| case RelocType.IMAGE_REL_FILE_ABSOLUTE: | ||
| // Debug.Assert(betweenWebcilSections && symbolWebcilSection != null); | ||
| Debug.Assert(symbolWebcilSection != null); | ||
| long fileOffset = symbolWebcilSection.Header.PointerToRawData + definedSymbol.Value; | ||
| Relocation.WriteValue(reloc.Type, pData, fileOffset + addend); | ||
| break; |
| // TODO-WASM: Consider alignment needs for data sections | ||
| public static readonly ObjectNodeSection DataSection = new ObjectNodeSection("wasm.data", SectionType.Writeable, needsAlign: false); | ||
| public static readonly ObjectNodeSection DataCountSection = new ObjectNodeSection("wasm.datacount", SectionType.ReadOnly, needsAlign: false); | ||
| public static readonly ObjectNodeSection CombinedDataSection = new ObjectNodeSection("wasm.alldata", SectionType.Writeable, needsAlign: false); |
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 16 out of 16 changed files in this pull request and generated 2 comments.
You can also share your feedback on Copilot code review. Take the survey.
| protected internal override void UpdateSectionAlignment(int sectionIndex, int alignment) | ||
| { | ||
| // This is a no-op for now under Wasm | ||
| WebcilSection section = _sections[sectionIndex] as WebcilSection; | ||
| // We should only be updating the alignment of Webcil sections; Wasm-native sections should | ||
| // not have alignment constraints. | ||
| Debug.Assert(section != null, $"Section: {sectionIndex} is not a WebcilSection"); | ||
| if (section == null) | ||
| { | ||
| return; | ||
| } | ||
|
|
||
| section.MinAlignment = Math.Max(section.MinAlignment, alignment); | ||
| } |
| @@ -468,19 +842,22 @@ private void WriteImports() | |||
| if (import.Index.HasValue) | |||
| { | |||
| int assigned = assignedImportIndices[(int)import.Kind]; | |||
pavelsavara
left a comment
There was a problem hiding this comment.
LGTM.
I wonder if we can add smoke test.
Produce trivial IL-only webcil with the object writer and test it with coreCLR loader.
Even manual/unmerged test doing this would be nice.
I have validated that the basic structure is correct for a simple example using the existing Microsoft.NET.WebAssembly.WebcilReader (and a simple driver program that calls the reader), but I'd definitely like to have a smoke test! What would it take to use the CoreCLR loader at the moment? |
| foreach (var symbolicRelocation in relocationList) | ||
| { | ||
| if (!_definedSymbols.ContainsKey(symbolicRelocation.SymbolName)) | ||
| foreach (var symbolicRelocation in relocationList) |
There was a problem hiding this comment.
Add another set of curly braces here for clarity.
|
|
||
| uint rawSectionSize = (uint)webcilSection.Stream.Length; | ||
| uint alignedSectionSize = (uint)AlignmentHelper.AlignUp((int)rawSectionSize, (int)WebcilSectionAlignment); | ||
| uint virtualSize = alignedSectionSize; |
There was a problem hiding this comment.
Needs a comment that virtualSize needs to be the same as alignedSectionSize so that RVA's can be constant, and that loading the Webcil image doesn't require interesting layout in memory.
Just produce valid WebCIL 1 IL-only assembly (no R2R). I think you are close to it, right ? |
…mperlin/runtime into adamperlin/wasm-object-writer-webcil
This PR implements WebCIL envelope support for the WasmObjectWriter. It builds up the data segment and assigns RVAs/Raw data addresses to each Webcil section as a first pass. As a second pass, it emits the proper headers and sections, and and also implements relocation resolution for
IMAGE_BASE*type relocs that may appear in Webcil data sections using the pre-assigned section addresses.The
WebcilDataSegmentis emitted as two Wasm data segments according to the Webcil spec like so:The PR also adds a simple validator program which uses
Microsoft.NET.Webcil.Validator. I am fine if we don't want to include this or want this refactored, I just included it in case it would be useful to have as I used it for testing purposes.