diff options
Diffstat (limited to 'third_party/rust/wasm-encoder/src/core')
-rw-r--r-- | third_party/rust/wasm-encoder/src/core/code.rs | 60 | ||||
-rw-r--r-- | third_party/rust/wasm-encoder/src/core/data.rs | 1 | ||||
-rw-r--r-- | third_party/rust/wasm-encoder/src/core/globals.rs | 13 | ||||
-rw-r--r-- | third_party/rust/wasm-encoder/src/core/imports.rs | 1 | ||||
-rw-r--r-- | third_party/rust/wasm-encoder/src/core/memories.rs | 25 | ||||
-rw-r--r-- | third_party/rust/wasm-encoder/src/core/types.rs | 15 |
6 files changed, 104 insertions, 11 deletions
diff --git a/third_party/rust/wasm-encoder/src/core/code.rs b/third_party/rust/wasm-encoder/src/core/code.rs index 76bfd7afde..4b04b0b72b 100644 --- a/third_party/rust/wasm-encoder/src/core/code.rs +++ b/third_party/rust/wasm-encoder/src/core/code.rs @@ -274,6 +274,34 @@ impl Encode for MemArg { } } +/// The memory ordering for atomic instructions. +/// +/// For an in-depth explanation of memory orderings, see the C++ documentation +/// for [`memory_order`] or the Rust documentation for [`atomic::Ordering`]. +/// +/// [`memory_order`]: https://en.cppreference.com/w/cpp/atomic/memory_order +/// [`atomic::Ordering`]: https://doc.rust-lang.org/std/sync/atomic/enum.Ordering.html +#[derive(Clone, Copy, Debug)] +pub enum Ordering { + /// For a load, it acquires; this orders all operations before the last + /// "releasing" store. For a store, it releases; this orders all operations + /// before it at the next "acquiring" load. + AcqRel, + /// Like `AcqRel` but all threads see all sequentially consistent operations + /// in the same order. + SeqCst, +} + +impl Encode for Ordering { + fn encode(&self, sink: &mut Vec<u8>) { + let flag: u8 = match self { + Ordering::SeqCst => 0, + Ordering::AcqRel => 1, + }; + sink.push(flag); + } +} + /// Describe an unchecked SIMD lane index. pub type Lane = u8; @@ -980,6 +1008,16 @@ pub enum Instruction<'a> { I64AtomicRmw8CmpxchgU(MemArg), I64AtomicRmw16CmpxchgU(MemArg), I64AtomicRmw32CmpxchgU(MemArg), + + // More atomic instructions (the shared-everything-threads proposal) + GlobalAtomicGet { + ordering: Ordering, + global_index: u32, + }, + GlobalAtomicSet { + ordering: Ordering, + global_index: u32, + }, } impl Encode for Instruction<'_> { @@ -2787,7 +2825,7 @@ impl Encode for Instruction<'_> { 0x113u32.encode(sink); } - // Atmoic instructions from the thread proposal + // Atomic instructions from the thread proposal Instruction::MemoryAtomicNotify(memarg) => { sink.push(0xFE); sink.push(0x00); @@ -3123,6 +3161,26 @@ impl Encode for Instruction<'_> { sink.push(0x4E); memarg.encode(sink); } + + // Atomic instructions from the shared-everything-threads proposal + Instruction::GlobalAtomicGet { + ordering, + global_index, + } => { + sink.push(0xFE); + sink.push(0x4F); + ordering.encode(sink); + global_index.encode(sink); + } + Instruction::GlobalAtomicSet { + ordering, + global_index, + } => { + sink.push(0xFE); + sink.push(0x50); + ordering.encode(sink); + global_index.encode(sink); + } } } } diff --git a/third_party/rust/wasm-encoder/src/core/data.rs b/third_party/rust/wasm-encoder/src/core/data.rs index 6439b66e2e..6f408befe5 100644 --- a/third_party/rust/wasm-encoder/src/core/data.rs +++ b/third_party/rust/wasm-encoder/src/core/data.rs @@ -18,6 +18,7 @@ use crate::{encode_section, encoding_size, ConstExpr, Encode, Section, SectionId /// maximum: None, /// memory64: false, /// shared: false, +/// page_size_log2: None, /// }); /// /// let mut data = DataSection::new(); diff --git a/third_party/rust/wasm-encoder/src/core/globals.rs b/third_party/rust/wasm-encoder/src/core/globals.rs index 64fec982cd..291ca80472 100644 --- a/third_party/rust/wasm-encoder/src/core/globals.rs +++ b/third_party/rust/wasm-encoder/src/core/globals.rs @@ -14,6 +14,7 @@ use crate::{encode_section, ConstExpr, Encode, Section, SectionId, ValType}; /// GlobalType { /// val_type: ValType::I32, /// mutable: false, +/// shared: false, /// }, /// &ConstExpr::i32_const(42), /// ); @@ -80,12 +81,21 @@ pub struct GlobalType { pub val_type: ValType, /// Whether this global is mutable or not. pub mutable: bool, + /// Whether this global is shared or not. + pub shared: bool, } impl Encode for GlobalType { fn encode(&self, sink: &mut Vec<u8>) { self.val_type.encode(sink); - sink.push(self.mutable as u8); + let mut flag = 0; + if self.mutable { + flag |= 0b01; + } + if self.shared { + flag |= 0b10; + } + sink.push(flag); } } @@ -96,6 +106,7 @@ impl TryFrom<wasmparser::GlobalType> for GlobalType { Ok(GlobalType { val_type: global_ty.content_type.try_into()?, mutable: global_ty.mutable, + shared: global_ty.shared, }) } } diff --git a/third_party/rust/wasm-encoder/src/core/imports.rs b/third_party/rust/wasm-encoder/src/core/imports.rs index 0030d640e6..d4db2e65c5 100644 --- a/third_party/rust/wasm-encoder/src/core/imports.rs +++ b/third_party/rust/wasm-encoder/src/core/imports.rs @@ -103,6 +103,7 @@ impl TryFrom<wasmparser::TypeRef> for EntityType { /// maximum: None, /// memory64: false, /// shared: false, +/// page_size_log2: None, /// } /// ); /// diff --git a/third_party/rust/wasm-encoder/src/core/memories.rs b/third_party/rust/wasm-encoder/src/core/memories.rs index 892545eb98..d64ef01210 100644 --- a/third_party/rust/wasm-encoder/src/core/memories.rs +++ b/third_party/rust/wasm-encoder/src/core/memories.rs @@ -15,6 +15,7 @@ use crate::{encode_section, Encode, Section, SectionId}; /// maximum: None, /// memory64: false, /// shared: false, +/// page_size_log2: None, /// }); /// /// let mut module = Module::new(); @@ -75,26 +76,41 @@ pub struct MemoryType { pub memory64: bool, /// Whether or not this memory is shared. pub shared: bool, + /// The log base 2 of a custom page size for this memory. + /// + /// The default page size for Wasm memories is 64KiB, i.e. 2<sup>16</sup> or + /// `65536`. + /// + /// After the introduction of [the custom-page-sizes + /// proposal](https://github.com/WebAssembly/custom-page-sizes), Wasm can + /// customize the page size. It must be a power of two that is less than or + /// equal to 64KiB. Attempting to encode an invalid page size may panic. + pub page_size_log2: Option<u32>, } impl Encode for MemoryType { fn encode(&self, sink: &mut Vec<u8>) { let mut flags = 0; if self.maximum.is_some() { - flags |= 0b001; + flags |= 0b0001; } if self.shared { - flags |= 0b010; + flags |= 0b0010; } if self.memory64 { - flags |= 0b100; + flags |= 0b0100; + } + if self.page_size_log2.is_some() { + flags |= 0b1000; } - sink.push(flags); self.minimum.encode(sink); if let Some(max) = self.maximum { max.encode(sink); } + if let Some(p) = self.page_size_log2 { + p.encode(sink); + } } } @@ -106,6 +122,7 @@ impl From<wasmparser::MemoryType> for MemoryType { maximum: memory_ty.maximum, memory64: memory_ty.memory64, shared: memory_ty.shared, + page_size_log2: memory_ty.page_size_log2, } } } diff --git a/third_party/rust/wasm-encoder/src/core/types.rs b/third_party/rust/wasm-encoder/src/core/types.rs index bfc54ae1e3..8b5f340bb6 100644 --- a/third_party/rust/wasm-encoder/src/core/types.rs +++ b/third_party/rust/wasm-encoder/src/core/types.rs @@ -450,9 +450,12 @@ pub enum HeapType { /// The unboxed `i31` heap type. I31, - /// The abstract` exception` heap type. + /// The abstract `exception` heap type. Exn, + /// The abstract `noexn` heap type. + NoExn, + /// A concrete Wasm-defined type at the given index. Concrete(u32), } @@ -471,6 +474,7 @@ impl Encode for HeapType { HeapType::Array => sink.push(0x6A), HeapType::I31 => sink.push(0x6C), HeapType::Exn => sink.push(0x69), + HeapType::NoExn => sink.push(0x74), // Note that this is encoded as a signed type rather than unsigned // as it's decoded as an s33 HeapType::Concrete(i) => i64::from(*i).encode(sink), @@ -496,6 +500,7 @@ impl TryFrom<wasmparser::HeapType> for HeapType { wasmparser::HeapType::Array => HeapType::Array, wasmparser::HeapType::I31 => HeapType::I31, wasmparser::HeapType::Exn => HeapType::Exn, + wasmparser::HeapType::NoExn => HeapType::NoExn, }) } } @@ -645,6 +650,8 @@ impl Section for TypeSection { #[cfg(test)] mod tests { + use wasmparser::WasmFeatures; + use super::*; use crate::Module; @@ -661,10 +668,8 @@ mod tests { module.section(&types); let wasm_bytes = module.finish(); - let mut validator = wasmparser::Validator::new_with_features(wasmparser::WasmFeatures { - gc: false, - ..Default::default() - }); + let mut validator = + wasmparser::Validator::new_with_features(WasmFeatures::default() & !WasmFeatures::GC); validator.validate_all(&wasm_bytes).expect( "Encoding pre Wasm GC type should not accidentally use Wasm GC specific encoding", |