Wasm: Serialize WasmModule without linking info

This commit is contained in:
Brian Carroll 2022-01-08 16:12:48 +00:00
parent b8ab6af203
commit 5a39002e8b
6 changed files with 75 additions and 5 deletions

View file

@ -156,6 +156,12 @@ pub struct CodeBuilder<'a> {
relocations: Vec<'a, RelocationEntry>,
}
impl<'a> Serialize for CodeBuilder<'a> {
fn serialize<T: SerialBuffer>(&self, buffer: &mut T) {
self.serialize_without_relocs(buffer);
}
}
#[allow(clippy::new_without_default)]
impl<'a> CodeBuilder<'a> {
pub fn new(arena: &'a Bump) -> Self {
@ -470,6 +476,35 @@ impl<'a> CodeBuilder<'a> {
***********************************************************/
/// Serialize all byte vectors in the right order
/// Also update relocation offsets relative to the base offset (code section body start)
pub fn serialize_without_relocs<T: SerialBuffer>(&self, buffer: &mut T) {
buffer.append_slice(&self.inner_length);
buffer.append_slice(&self.preamble);
let mut code_pos = 0;
let mut insert_iter = self.insertions.iter();
loop {
let next_insert = insert_iter.next();
let next_pos = match next_insert {
Some(Insertion { at, .. }) => *at,
None => self.code.len(),
};
buffer.append_slice(&self.code[code_pos..next_pos]);
match next_insert {
Some(Insertion { at, start, end }) => {
buffer.append_slice(&self.insert_bytes[*start..*end]);
code_pos = *at;
}
None => {
break;
}
}
}
}
/// Serialize all byte vectors in the right order
/// Also update relocation offsets relative to the base offset (code section body start)
pub fn serialize_with_relocs<T: SerialBuffer>(

View file

@ -41,9 +41,29 @@ impl<'a> WasmModule<'a> {
self.function.add_sig(index);
}
/// Serialize the module to bytes
/// (not using Serialize trait because it's just one more thing to export)
pub fn serialize<T: SerialBuffer>(&self, buffer: &mut T) {
buffer.append_u8(0);
buffer.append_slice("asm".as_bytes());
buffer.write_unencoded_u32(Self::WASM_VERSION);
self.types.serialize(buffer);
self.import.serialize(buffer);
self.function.serialize(buffer);
self.table.serialize(buffer);
self.memory.serialize(buffer);
self.global.serialize(buffer);
self.export.serialize(buffer);
self.start.serialize(buffer);
self.element.serialize(buffer);
self.code.serialize(buffer);
self.data.serialize(buffer);
}
/// Serialize the module to bytes
/// (Mutates some data related to linking)
pub fn serialize_mut<T: SerialBuffer>(&mut self, buffer: &mut T) {
pub fn serialize_with_linker_data_mut<T: SerialBuffer>(&mut self, buffer: &mut T) {
buffer.append_u8(0);
buffer.append_slice("asm".as_bytes());
buffer.write_unencoded_u32(Self::WASM_VERSION);

View file

@ -557,6 +557,21 @@ impl<'a> CodeSection<'a> {
}
}
impl<'a> Serialize for CodeSection<'a> {
fn serialize<T: SerialBuffer>(&self, buffer: &mut T) {
let header_indices = write_section_header(buffer, SectionId::Code);
buffer.encode_u32(self.preloaded_count + self.code_builders.len() as u32);
buffer.append_slice(&self.preloaded_bytes);
for code_builder in self.code_builders.iter() {
code_builder.serialize(buffer);
}
update_section_size(buffer, header_indices);
}
}
/*******************************************************************
*
* Data section

View file

@ -3,7 +3,7 @@ use std::{fmt::Debug, iter::FromIterator};
use bumpalo::collections::vec::Vec;
use roc_reporting::internal_error;
pub trait Serialize {
pub(super) trait Serialize {
fn serialize<T: SerialBuffer>(&self, buffer: &mut T);
}