diff --git a/compiler/gen_wasm/src/module_builder.rs b/compiler/gen_wasm/src/module_builder.rs index 8051298300..5b892d4466 100644 --- a/compiler/gen_wasm/src/module_builder.rs +++ b/compiler/gen_wasm/src/module_builder.rs @@ -2,6 +2,7 @@ use bumpalo::collections::vec::Vec; use bumpalo::Bump; use crate::code_builder::{Align, ValueType}; +use crate::opcodes; use crate::serialize::{SerialBuffer, Serialize}; /******************************************************************* @@ -58,7 +59,7 @@ fn write_custom_section_header( buffer: &mut T, name: &str, ) -> SectionHeaderIndices { - buffer.append_u8(SectionId::Custom as u8); + // buffer.append_u8(SectionId::Custom as u8); let size_index = buffer.reserve_padded_u32(); let body_index = buffer.size(); name.serialize(buffer); @@ -289,28 +290,43 @@ enum Limits { impl Serialize for Limits { fn serialize(&self, buffer: &mut T) { - todo!(); + match self { + Self::Min(min) => { + buffer.append_u8(0); + buffer.encode_u32(*min); + } + Self::MinMax(min, max) => { + buffer.append_u8(1); + buffer.encode_u32(*min); + buffer.encode_u32(*max); + } + } } } -pub struct MemorySection { - /// number of 64kB pages - num_pages: Limits, -} +pub struct MemorySection(Option); impl MemorySection { - const PAGE_SIZE_KB: u32 = 64; + pub const PAGE_SIZE: u32 = 64 * 1024; - pub fn new(kb: u32) -> Self { - MemorySection { - num_pages: Limits::Min(kb / Self::PAGE_SIZE_KB), + pub fn new(bytes: u32) -> Self { + if bytes == 0 { + MemorySection(None) + } else { + let pages = (bytes + Self::PAGE_SIZE - 1) / Self::PAGE_SIZE; + MemorySection(Some(Limits::Min(pages))) } } } impl Serialize for MemorySection { fn serialize(&self, buffer: &mut T) { - todo!(); + if let Some(limits) = &self.0 { + let header_indices = write_section_header(buffer, SectionId::Memory); + buffer.append_u8(1); + limits.serialize(buffer); + update_section_size(buffer, header_indices); + } } } @@ -346,7 +362,25 @@ struct Global { impl Serialize for Global { fn serialize(&self, buffer: &mut T) { - todo!(); + self.ty.serialize(buffer); + match self.init_value { + GlobalInitValue::I32(x) => { + buffer.append_u8(opcodes::I32CONST); + buffer.encode_i32(x); + } + GlobalInitValue::I64(x) => { + buffer.append_u8(opcodes::I64CONST); + buffer.encode_i64(x); + } + GlobalInitValue::F32(x) => { + buffer.append_u8(opcodes::F32CONST); + buffer.encode_f32(x); + } + GlobalInitValue::F64(x) => { + buffer.append_u8(opcodes::F64CONST); + buffer.encode_f64(x); + } + } } } diff --git a/compiler/gen_wasm/src/serialize.rs b/compiler/gen_wasm/src/serialize.rs index 2e8777b1b8..f4430332e8 100644 --- a/compiler/gen_wasm/src/serialize.rs +++ b/compiler/gen_wasm/src/serialize.rs @@ -120,6 +120,30 @@ impl Serialize for u32 { } } +impl Serialize for [S] { + fn serialize(&self, buffer: &mut T) { + buffer.encode_u32(self.len() as u32); + for item in self.iter() { + item.serialize(buffer); + } + } +} + +impl Serialize for Option { + /// serialize Option as a vector of length 1 or 0 + fn serialize(&self, buffer: &mut T) { + match self { + Some(x) => { + buffer.append_u8(1); + x.serialize(buffer); + } + None => { + buffer.append_u8(0); + } + } + } +} + fn overwrite_padded_u32_help(buffer: &mut [u8], value: u32) { let mut x = value; for byte in buffer.iter_mut().take(4) {