From b8ab6af20338559d457fadb401812fa8aa07148e Mon Sep 17 00:00:00 2001 From: Brian Carroll Date: Sat, 8 Jan 2022 15:29:13 +0000 Subject: [PATCH] Wasm: move WasmModule definition to mod.rs --- compiler/gen_wasm/src/backend.rs | 4 +- compiler/gen_wasm/src/wasm_module/mod.rs | 101 +++++++++++++++++- compiler/gen_wasm/src/wasm_module/sections.rs | 96 +---------------- 3 files changed, 104 insertions(+), 97 deletions(-) diff --git a/compiler/gen_wasm/src/backend.rs b/compiler/gen_wasm/src/backend.rs index 1c8dbdf1c4..af21fd770b 100644 --- a/compiler/gen_wasm/src/backend.rs +++ b/compiler/gen_wasm/src/backend.rs @@ -23,11 +23,11 @@ use crate::wasm_module::linking::{ }; use crate::wasm_module::sections::{ CodeSection, DataMode, DataSection, DataSegment, ExportSection, FunctionSection, GlobalSection, - Import, ImportDesc, ImportSection, MemorySection, OpaqueSection, TypeSection, WasmModule, + Import, ImportDesc, ImportSection, MemorySection, OpaqueSection, TypeSection, }; use crate::wasm_module::{ code_builder, CodeBuilder, ConstExpr, Export, ExportType, Global, GlobalType, LocalId, - Signature, SymInfo, ValueType, + Signature, SymInfo, ValueType, WasmModule, }; use crate::{ copy_memory, round_up_to_alignment, CopyMemoryConfig, Env, BUILTINS_IMPORT_MODULE_NAME, diff --git a/compiler/gen_wasm/src/wasm_module/mod.rs b/compiler/gen_wasm/src/wasm_module/mod.rs index 7c643f97b3..8b61947ff1 100644 --- a/compiler/gen_wasm/src/wasm_module/mod.rs +++ b/compiler/gen_wasm/src/wasm_module/mod.rs @@ -6,4 +6,103 @@ pub mod serialize; pub use code_builder::{Align, CodeBuilder, LocalId, ValueType, VmSymbolState}; pub use linking::SymInfo; -pub use sections::{ConstExpr, Export, ExportType, Global, GlobalType, Signature, WasmModule}; +pub use sections::{ConstExpr, Export, ExportType, Global, GlobalType, Signature}; + +use self::linking::{LinkingSection, RelocationSection}; +use self::sections::{ + CodeSection, DataSection, ExportSection, FunctionSection, GlobalSection, ImportSection, + MemorySection, OpaqueSection, TypeSection, +}; +use self::serialize::{SerialBuffer, Serialize}; + +#[derive(Debug)] +pub struct WasmModule<'a> { + pub types: TypeSection<'a>, + pub import: ImportSection<'a>, + pub function: FunctionSection<'a>, + pub table: OpaqueSection<'a>, + pub memory: MemorySection, + pub global: GlobalSection<'a>, + pub export: ExportSection<'a>, + pub start: OpaqueSection<'a>, + pub element: OpaqueSection<'a>, + pub code: CodeSection<'a>, + pub data: DataSection<'a>, + pub linking: LinkingSection<'a>, + pub relocations: RelocationSection<'a>, +} + +impl<'a> WasmModule<'a> { + pub const WASM_VERSION: u32 = 1; + + /// Create entries in the Type and Function sections for a function signature + pub fn add_function_signature(&mut self, signature: Signature<'a>) { + let index = self.types.insert(signature); + self.function.add_sig(index); + } + + /// Serialize the module to bytes + /// (Mutates some data related to linking) + pub fn serialize_mut(&mut self, buffer: &mut T) { + buffer.append_u8(0); + buffer.append_slice("asm".as_bytes()); + buffer.write_unencoded_u32(Self::WASM_VERSION); + + // Keep track of (non-empty) section indices for linking + let mut counter = SectionCounter { + buffer_size: buffer.size(), + section_index: 0, + }; + + counter.serialize_and_count(buffer, &self.types); + counter.serialize_and_count(buffer, &self.import); + counter.serialize_and_count(buffer, &self.function); + counter.serialize_and_count(buffer, &self.table); + counter.serialize_and_count(buffer, &self.memory); + counter.serialize_and_count(buffer, &self.global); + counter.serialize_and_count(buffer, &self.export); + counter.serialize_and_count(buffer, &self.start); + counter.serialize_and_count(buffer, &self.element); + + // Code section is the only one with relocations so we can stop counting + let code_section_index = counter.section_index; + self.code + .serialize_with_relocs(buffer, &mut self.relocations.entries); + + self.data.serialize(buffer); + + self.linking.serialize(buffer); + + self.relocations.target_section_index = Some(code_section_index); + self.relocations.serialize(buffer); + } +} + +/// Helper struct to count non-empty sections. +/// Needed to generate linking data, which refers to target sections by index. +struct SectionCounter { + buffer_size: usize, + section_index: u32, +} + +impl SectionCounter { + /// Update the section counter if buffer size increased since last call + #[inline] + fn update(&mut self, buffer: &mut SB) { + let new_size = buffer.size(); + if new_size > self.buffer_size { + self.section_index += 1; + self.buffer_size = new_size; + } + } + + #[inline] + fn serialize_and_count( + &mut self, + buffer: &mut SB, + section: &S, + ) { + section.serialize(buffer); + self.update(buffer); + } +} diff --git a/compiler/gen_wasm/src/wasm_module/sections.rs b/compiler/gen_wasm/src/wasm_module/sections.rs index d47fff12e0..254ccbc904 100644 --- a/compiler/gen_wasm/src/wasm_module/sections.rs +++ b/compiler/gen_wasm/src/wasm_module/sections.rs @@ -1,7 +1,7 @@ use bumpalo::collections::vec::Vec; use bumpalo::Bump; -use super::linking::{LinkingSection, RelocationEntry, RelocationSection}; +use super::linking::RelocationEntry; use super::opcodes::OpCode; use super::serialize::{decode_u32_or_panic, SerialBuffer, Serialize}; use super::{CodeBuilder, ValueType}; @@ -328,7 +328,7 @@ impl<'a> FunctionSection<'a> { } } - fn add_sig(&mut self, sig_id: u32) { + pub(super) fn add_sig(&mut self, sig_id: u32) { self.bytes.encode_u32(sig_id); self.count += 1; } @@ -639,35 +639,6 @@ impl Serialize for DataSection<'_> { * *******************************************************************/ -/// Helper struct to count non-empty sections. -/// Needed to generate linking data, which refers to target sections by index. -struct SectionCounter { - buffer_size: usize, - section_index: u32, -} - -impl SectionCounter { - /// Update the section counter if buffer size increased since last call - #[inline] - fn update(&mut self, buffer: &mut SB) { - let new_size = buffer.size(); - if new_size > self.buffer_size { - self.section_index += 1; - self.buffer_size = new_size; - } - } - - #[inline] - fn serialize_and_count( - &mut self, - buffer: &mut SB, - section: &S, - ) { - section.serialize(buffer); - self.update(buffer); - } -} - /// A Wasm module section that we don't use for Roc code, /// but may be present in a preloaded binary #[derive(Debug, Default)] @@ -689,69 +660,6 @@ impl Serialize for OpaqueSection<'_> { } } -#[derive(Debug)] -pub struct WasmModule<'a> { - pub types: TypeSection<'a>, - pub import: ImportSection<'a>, - pub function: FunctionSection<'a>, - pub table: OpaqueSection<'a>, - pub memory: MemorySection, - pub global: GlobalSection<'a>, - pub export: ExportSection<'a>, - pub start: OpaqueSection<'a>, - pub element: OpaqueSection<'a>, - pub code: CodeSection<'a>, - pub data: DataSection<'a>, - pub linking: LinkingSection<'a>, - pub relocations: RelocationSection<'a>, -} - -impl<'a> WasmModule<'a> { - pub const WASM_VERSION: u32 = 1; - - /// Create entries in the Type and Function sections for a function signature - pub fn add_function_signature(&mut self, signature: Signature<'a>) { - let index = self.types.insert(signature); - self.function.add_sig(index); - } - - /// Serialize the module to bytes - /// (Mutates some data related to linking) - pub fn serialize_mut(&mut self, buffer: &mut T) { - buffer.append_u8(0); - buffer.append_slice("asm".as_bytes()); - buffer.write_unencoded_u32(Self::WASM_VERSION); - - // Keep track of (non-empty) section indices for linking - let mut counter = SectionCounter { - buffer_size: buffer.size(), - section_index: 0, - }; - - counter.serialize_and_count(buffer, &self.types); - counter.serialize_and_count(buffer, &self.import); - counter.serialize_and_count(buffer, &self.function); - counter.serialize_and_count(buffer, &self.table); - counter.serialize_and_count(buffer, &self.memory); - counter.serialize_and_count(buffer, &self.global); - counter.serialize_and_count(buffer, &self.export); - counter.serialize_and_count(buffer, &self.start); - counter.serialize_and_count(buffer, &self.element); - - // Code section is the only one with relocations so we can stop counting - let code_section_index = counter.section_index; - self.code - .serialize_with_relocs(buffer, &mut self.relocations.entries); - - self.data.serialize(buffer); - - self.linking.serialize(buffer); - - self.relocations.target_section_index = Some(code_section_index); - self.relocations.serialize(buffer); - } -} - #[cfg(test)] mod tests { use super::*;