Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[wasm] Webcil-in-WebAssembly (#85932)
Define a WebAssembly module wrapper for Webcil assemblies. Contributes to #80807 ### Why In some settings serving `application/octet-stream` data, or files with weird extensions will trigger firewalls or AV tools. But let's assume that if you're interested in deploying a .NET WebAssembly app, you're in an environment that can at least serve WebAssembly modules. ### How Essentially we serve this WebAssembly module: ```wat (module (data "\0f\00\00\00") ;; data segment 0: payload size (data "webcil Payload\cc") ;; data segment 1: webcil payload (memory (import "webcil" "memory") 1) (global (export "webcilVersion") i32 (i32.const 0)) (func (export "getWebcilSize") (param $destPtr i32) (result) local.get $destPtr i32.const 0 i32.const 4 memory.init 0) (func (export "getWebcilPayload") (param $d i32) (param $n i32) (result) local.get $d i32.const 0 local.get $n memory.init 1)) ``` The module exports two WebAssembly functions `getWebcilSize` and `getWebcilPayload` that write some bytes (being the size or payload of the webcil assembly) to the linear memory at a given offset. The module also exports the constant `webcilVersion` to version the wrapper format. So a runtime or tool that wants to consume the webcil module can do something like: ```js const wasmModule = new WebAssembly.Module (...); const wasmMemory = new WebAssembly.Memory ({initial: 1}); const wasmInstance = new WebAssembly.Instance(wasmModule, {webcil: {memory: wasmMemory}}); const { getWebcilPayload, webcilVersion, getWebcilSize } = wasmInstance.exports; console.log (`Version ${webcilVersion.value}`); getWebcilSize(0); const size = new Int32Array (wasmMemory.buffer)[0] console.log (`Size ${size}`); console.log (new Uint8Array(wasmMemory.buffer).subarray(0, 20)); getWebcilPayload(4, size); console.log (new Uint8Array(wasmMemory.buffer).subarray(0, 20)); ``` ### How (Part 2) But actually, we will define the wrapper to consist of exactly 2 data segments in the WebAssembly data section: segment 0 is 4 bytes and encodes the webcil payload size; and segment 1 is of variable size and contains the webcil payload. So to load a webcil-in-wasm module, the runtime gets the _raw bytes_ of the WebAssembly module (ie: without instantiating it), and parses it to find the data section, assert that there are 2 segments, ensure they're both passive, and get the data directly from segment 1. --- * Add option to emit webcil inside a wasm module wrapper * [mono][loader] implement a webcil-in-wasm reader * reword WebcilWasmWrapper summary comment * update the Webcil spec to include the WebAssembly wrapper module * Adjust RVA map offsets to account for wasm prefix MonoImage:raw_data is used as a base when applying the RVA map to map virtual addresses to physical offsets in the assembly. With webcil-in-wasm there's an extra wasm prefix before the webcil payload starts, so we need to account for this extra data when creating the mapping. An alternative is to compute the correct offsets as part of generating the webcil, but that would entangle the wasm module and the webcil payload. The current (somewhat hacky approach) keeps them logically separate. * Add a note about the rva mapping to the spec * Serve webcil-in-wasm as .wasm * remove old .webcil support from Sdk Pack Tasks * Implement support for webcil in wasm in the managed WebcilReader * align webcil payload to a 4-byte boundary within the wasm module Add padding to data segment 0 to ensure that data segment 1's payload (ie the webcil content itself) is 4-byte aligned * assert that webcil raw data is 4-byte aligned * add 4-byte alignment requirement to the webcil spec * Don't modify MonoImageStorage:raw_data instead just keep track of the webcil offset in the MonoImageStorage. This introduces a situation where MonoImage:raw_data is different from MonoImageStorage:raw_data. The one to use for accessing IL and metadata is MonoImage:raw_data. The storage pointer is just used by the image loading machinery --------- Co-authored-by: Larry Ewing <[email protected]>
- Loading branch information