From 8f035d8a07a16d725d4299c1453fcc117a8d09a1 Mon Sep 17 00:00:00 2001 From: ptitSeb Date: Mon, 8 Nov 2021 15:41:20 +0100 Subject: [PATCH 1/4] fix(windows) Fix slow memory grow handling (fix #2260) --- lib/api/src/sys/tunables.rs | 394 ++++++++++++++++++------------------ 1 file changed, 193 insertions(+), 201 deletions(-) diff --git a/lib/api/src/sys/tunables.rs b/lib/api/src/sys/tunables.rs index 5dbf39722f7..92e8dc8056f 100644 --- a/lib/api/src/sys/tunables.rs +++ b/lib/api/src/sys/tunables.rs @@ -1,201 +1,193 @@ -use crate::sys::{MemoryType, Pages, TableType}; -use loupe::MemoryUsage; -use std::cmp::min; -use std::ptr::NonNull; -use std::sync::Arc; -use target_lexicon::{OperatingSystem, PointerWidth}; -use wasmer_compiler::Target; -use wasmer_engine::Tunables; -use wasmer_vm::MemoryError; -use wasmer_vm::{ - LinearMemory, LinearTable, Memory, MemoryStyle, Table, TableStyle, VMMemoryDefinition, - VMTableDefinition, -}; - -/// Tunable parameters for WebAssembly compilation. -/// This is the reference implementation of the `Tunables` trait, -/// used by default. -/// -/// You can use this as a template for creating a custom Tunables -/// implementation or use composition to wrap your Tunables around -/// this one. The later approach is demonstrated in the -/// tunables-limit-memory example. -#[derive(Clone, MemoryUsage)] -pub struct BaseTunables { - /// For static heaps, the size in wasm pages of the heap protected by bounds checking. - pub static_memory_bound: Pages, - - /// The size in bytes of the offset guard for static heaps. - pub static_memory_offset_guard_size: u64, - - /// The size in bytes of the offset guard for dynamic heaps. - pub dynamic_memory_offset_guard_size: u64, -} - -impl BaseTunables { - /// Get the `BaseTunables` for a specific Target - pub fn for_target(target: &Target) -> Self { - let triple = target.triple(); - let pointer_width: PointerWidth = triple.pointer_width().unwrap(); - let (mut static_memory_bound, mut static_memory_offset_guard_size): (Pages, u64) = - match pointer_width { - PointerWidth::U16 => (0x400.into(), 0x1000), - PointerWidth::U32 => (0x4000.into(), 0x1_0000), - // Static Memory Bound: - // Allocating 4 GiB of address space let us avoid the - // need for explicit bounds checks. - // Static Memory Guard size: - // Allocating 2 GiB of address space lets us translate wasm - // offsets into x86 offsets as aggressively as we can. - PointerWidth::U64 => (0x1_0000.into(), 0x8000_0000), - }; - - // Allocate a small guard to optimize common cases but without - // wasting too much memory. - // The Windows memory manager seems more laxed than the other ones - // And a guard of just 1 page may not be enough is some borderline cases - // So using 2 pages for guard on this platform - #[cfg(target_os = "windows")] - let dynamic_memory_offset_guard_size: u64 = 0x2_0000; - #[cfg(not(target_os = "windows"))] - let dynamic_memory_offset_guard_size: u64 = 0x1_0000; - - if let OperatingSystem::Windows = triple.operating_system { - // For now, use a smaller footprint on Windows so that we don't - // outstrip the paging file. - static_memory_bound = min(static_memory_bound, 0x100.into()); - static_memory_offset_guard_size = min(static_memory_offset_guard_size, 0x20000); - } - - Self { - static_memory_bound, - static_memory_offset_guard_size, - dynamic_memory_offset_guard_size, - } - } -} - -impl Tunables for BaseTunables { - /// Get a `MemoryStyle` for the provided `MemoryType` - fn memory_style(&self, memory: &MemoryType) -> MemoryStyle { - // A heap with a maximum that doesn't exceed the static memory bound specified by the - // tunables make it static. - // - // If the module doesn't declare an explicit maximum treat it as 4GiB. - let maximum = memory.maximum.unwrap_or_else(Pages::max_value); - if maximum <= self.static_memory_bound { - MemoryStyle::Static { - // Bound can be larger than the maximum for performance reasons - bound: self.static_memory_bound, - offset_guard_size: self.static_memory_offset_guard_size, - } - } else { - MemoryStyle::Dynamic { - offset_guard_size: self.dynamic_memory_offset_guard_size, - } - } - } - - /// Get a [`TableStyle`] for the provided [`TableType`]. - fn table_style(&self, _table: &TableType) -> TableStyle { - TableStyle::CallerChecksSignature - } - - /// Create a memory owned by the host given a [`MemoryType`] and a [`MemoryStyle`]. - fn create_host_memory( - &self, - ty: &MemoryType, - style: &MemoryStyle, - ) -> Result, MemoryError> { - Ok(Arc::new(LinearMemory::new(&ty, &style)?)) - } - - /// Create a memory owned by the VM given a [`MemoryType`] and a [`MemoryStyle`]. - /// - /// # Safety - /// - `vm_definition_location` must point to a valid, owned `VMMemoryDefinition`, - /// for example in `VMContext`. - unsafe fn create_vm_memory( - &self, - ty: &MemoryType, - style: &MemoryStyle, - vm_definition_location: NonNull, - ) -> Result, MemoryError> { - Ok(Arc::new(LinearMemory::from_definition( - &ty, - &style, - vm_definition_location, - )?)) - } - - /// Create a table owned by the host given a [`TableType`] and a [`TableStyle`]. - fn create_host_table( - &self, - ty: &TableType, - style: &TableStyle, - ) -> Result, String> { - Ok(Arc::new(LinearTable::new(&ty, &style)?)) - } - - /// Create a table owned by the VM given a [`TableType`] and a [`TableStyle`]. - /// - /// # Safety - /// - `vm_definition_location` must point to a valid, owned `VMTableDefinition`, - /// for example in `VMContext`. - unsafe fn create_vm_table( - &self, - ty: &TableType, - style: &TableStyle, - vm_definition_location: NonNull, - ) -> Result, String> { - Ok(Arc::new(LinearTable::from_definition( - &ty, - &style, - vm_definition_location, - )?)) - } -} - -#[cfg(test)] -mod tests { - use super::*; - - #[test] - fn memory_style() { - let tunables = BaseTunables { - static_memory_bound: Pages(2048), - static_memory_offset_guard_size: 128, - dynamic_memory_offset_guard_size: 256, - }; - - // No maximum - let requested = MemoryType::new(3, None, true); - let style = tunables.memory_style(&requested); - match style { - MemoryStyle::Dynamic { offset_guard_size } => assert_eq!(offset_guard_size, 256), - s => panic!("Unexpected memory style: {:?}", s), - } - - // Large maximum - let requested = MemoryType::new(3, Some(5_000_000), true); - let style = tunables.memory_style(&requested); - match style { - MemoryStyle::Dynamic { offset_guard_size } => assert_eq!(offset_guard_size, 256), - s => panic!("Unexpected memory style: {:?}", s), - } - - // Small maximum - let requested = MemoryType::new(3, Some(16), true); - let style = tunables.memory_style(&requested); - match style { - MemoryStyle::Static { - bound, - offset_guard_size, - } => { - assert_eq!(bound, Pages(2048)); - assert_eq!(offset_guard_size, 128); - } - s => panic!("Unexpected memory style: {:?}", s), - } - } -} +use crate::sys::{MemoryType, Pages, TableType}; +use loupe::MemoryUsage; +use std::ptr::NonNull; +use std::sync::Arc; +use target_lexicon::PointerWidth; +use wasmer_compiler::Target; +use wasmer_engine::Tunables; +use wasmer_vm::MemoryError; +use wasmer_vm::{ + LinearMemory, LinearTable, Memory, MemoryStyle, Table, TableStyle, VMMemoryDefinition, + VMTableDefinition, +}; + +/// Tunable parameters for WebAssembly compilation. +/// This is the reference implementation of the `Tunables` trait, +/// used by default. +/// +/// You can use this as a template for creating a custom Tunables +/// implementation or use composition to wrap your Tunables around +/// this one. The later approach is demonstrated in the +/// tunables-limit-memory example. +#[derive(Clone, MemoryUsage)] +pub struct BaseTunables { + /// For static heaps, the size in wasm pages of the heap protected by bounds checking. + pub static_memory_bound: Pages, + + /// The size in bytes of the offset guard for static heaps. + pub static_memory_offset_guard_size: u64, + + /// The size in bytes of the offset guard for dynamic heaps. + pub dynamic_memory_offset_guard_size: u64, +} + +impl BaseTunables { + /// Get the `BaseTunables` for a specific Target + pub fn for_target(target: &Target) -> Self { + let triple = target.triple(); + let pointer_width: PointerWidth = triple.pointer_width().unwrap(); + let (static_memory_bound, static_memory_offset_guard_size): (Pages, u64) = + match pointer_width { + PointerWidth::U16 => (0x400.into(), 0x1000), + PointerWidth::U32 => (0x4000.into(), 0x1_0000), + // Static Memory Bound: + // Allocating 4 GiB of address space let us avoid the + // need for explicit bounds checks. + // Static Memory Guard size: + // Allocating 2 GiB of address space lets us translate wasm + // offsets into x86 offsets as aggressively as we can. + PointerWidth::U64 => (0x1_0000.into(), 0x8000_0000), + }; + + // Allocate a small guard to optimize common cases but without + // wasting too much memory. + // The Windows memory manager seems more laxed than the other ones + // And a guard of just 1 page may not be enough is some borderline cases + // So using 2 pages for guard on this platform + #[cfg(target_os = "windows")] + let dynamic_memory_offset_guard_size: u64 = 0x2_0000; + #[cfg(not(target_os = "windows"))] + let dynamic_memory_offset_guard_size: u64 = 0x1_0000; + + Self { + static_memory_bound, + static_memory_offset_guard_size, + dynamic_memory_offset_guard_size, + } + } +} + +impl Tunables for BaseTunables { + /// Get a `MemoryStyle` for the provided `MemoryType` + fn memory_style(&self, memory: &MemoryType) -> MemoryStyle { + // A heap with a maximum that doesn't exceed the static memory bound specified by the + // tunables make it static. + // + // If the module doesn't declare an explicit maximum treat it as 4GiB. + let maximum = memory.maximum.unwrap_or_else(Pages::max_value); + if maximum <= self.static_memory_bound { + MemoryStyle::Static { + // Bound can be larger than the maximum for performance reasons + bound: self.static_memory_bound, + offset_guard_size: self.static_memory_offset_guard_size, + } + } else { + MemoryStyle::Dynamic { + offset_guard_size: self.dynamic_memory_offset_guard_size, + } + } + } + + /// Get a [`TableStyle`] for the provided [`TableType`]. + fn table_style(&self, _table: &TableType) -> TableStyle { + TableStyle::CallerChecksSignature + } + + /// Create a memory owned by the host given a [`MemoryType`] and a [`MemoryStyle`]. + fn create_host_memory( + &self, + ty: &MemoryType, + style: &MemoryStyle, + ) -> Result, MemoryError> { + Ok(Arc::new(LinearMemory::new(&ty, &style)?)) + } + + /// Create a memory owned by the VM given a [`MemoryType`] and a [`MemoryStyle`]. + /// + /// # Safety + /// - `vm_definition_location` must point to a valid, owned `VMMemoryDefinition`, + /// for example in `VMContext`. + unsafe fn create_vm_memory( + &self, + ty: &MemoryType, + style: &MemoryStyle, + vm_definition_location: NonNull, + ) -> Result, MemoryError> { + Ok(Arc::new(LinearMemory::from_definition( + &ty, + &style, + vm_definition_location, + )?)) + } + + /// Create a table owned by the host given a [`TableType`] and a [`TableStyle`]. + fn create_host_table( + &self, + ty: &TableType, + style: &TableStyle, + ) -> Result, String> { + Ok(Arc::new(LinearTable::new(&ty, &style)?)) + } + + /// Create a table owned by the VM given a [`TableType`] and a [`TableStyle`]. + /// + /// # Safety + /// - `vm_definition_location` must point to a valid, owned `VMTableDefinition`, + /// for example in `VMContext`. + unsafe fn create_vm_table( + &self, + ty: &TableType, + style: &TableStyle, + vm_definition_location: NonNull, + ) -> Result, String> { + Ok(Arc::new(LinearTable::from_definition( + &ty, + &style, + vm_definition_location, + )?)) + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn memory_style() { + let tunables = BaseTunables { + static_memory_bound: Pages(2048), + static_memory_offset_guard_size: 128, + dynamic_memory_offset_guard_size: 256, + }; + + // No maximum + let requested = MemoryType::new(3, None, true); + let style = tunables.memory_style(&requested); + match style { + MemoryStyle::Dynamic { offset_guard_size } => assert_eq!(offset_guard_size, 256), + s => panic!("Unexpected memory style: {:?}", s), + } + + // Large maximum + let requested = MemoryType::new(3, Some(5_000_000), true); + let style = tunables.memory_style(&requested); + match style { + MemoryStyle::Dynamic { offset_guard_size } => assert_eq!(offset_guard_size, 256), + s => panic!("Unexpected memory style: {:?}", s), + } + + // Small maximum + let requested = MemoryType::new(3, Some(16), true); + let style = tunables.memory_style(&requested); + match style { + MemoryStyle::Static { + bound, + offset_guard_size, + } => { + assert_eq!(bound, Pages(2048)); + assert_eq!(offset_guard_size, 128); + } + s => panic!("Unexpected memory style: {:?}", s), + } + } +} From 8b6c07eaa79dc58761a3a0b7773e905a64a33d60 Mon Sep 17 00:00:00 2001 From: ptitSeb Date: Mon, 8 Nov 2021 15:57:36 +0100 Subject: [PATCH 2/4] feat(windows) Only exclude test file from the line ending conversion --- .gitattributes | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitattributes b/.gitattributes index cc596aeaaef..dc6e07495a3 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1,4 +1,4 @@ CHANGELOG.md merge=union *.wast linguist-vendored *.wat linguist-vendored -* -text +tests/wasi-wast/wasi/test_fs -text From 3af8b1215271e1351c55587be9170b6353a7cd9f Mon Sep 17 00:00:00 2001 From: ptitSeb Date: Mon, 8 Nov 2021 16:08:01 +0100 Subject: [PATCH 3/4] fix(windows) Fix slow memory grow handling (fix #2260) --- lib/api/src/sys/tunables.rs | 386 ++++++++++++++++++------------------ 1 file changed, 193 insertions(+), 193 deletions(-) diff --git a/lib/api/src/sys/tunables.rs b/lib/api/src/sys/tunables.rs index 92e8dc8056f..4bdb6572408 100644 --- a/lib/api/src/sys/tunables.rs +++ b/lib/api/src/sys/tunables.rs @@ -1,193 +1,193 @@ -use crate::sys::{MemoryType, Pages, TableType}; -use loupe::MemoryUsage; -use std::ptr::NonNull; -use std::sync::Arc; -use target_lexicon::PointerWidth; -use wasmer_compiler::Target; -use wasmer_engine::Tunables; -use wasmer_vm::MemoryError; -use wasmer_vm::{ - LinearMemory, LinearTable, Memory, MemoryStyle, Table, TableStyle, VMMemoryDefinition, - VMTableDefinition, -}; - -/// Tunable parameters for WebAssembly compilation. -/// This is the reference implementation of the `Tunables` trait, -/// used by default. -/// -/// You can use this as a template for creating a custom Tunables -/// implementation or use composition to wrap your Tunables around -/// this one. The later approach is demonstrated in the -/// tunables-limit-memory example. -#[derive(Clone, MemoryUsage)] -pub struct BaseTunables { - /// For static heaps, the size in wasm pages of the heap protected by bounds checking. - pub static_memory_bound: Pages, - - /// The size in bytes of the offset guard for static heaps. - pub static_memory_offset_guard_size: u64, - - /// The size in bytes of the offset guard for dynamic heaps. - pub dynamic_memory_offset_guard_size: u64, -} - -impl BaseTunables { - /// Get the `BaseTunables` for a specific Target - pub fn for_target(target: &Target) -> Self { - let triple = target.triple(); - let pointer_width: PointerWidth = triple.pointer_width().unwrap(); - let (static_memory_bound, static_memory_offset_guard_size): (Pages, u64) = - match pointer_width { - PointerWidth::U16 => (0x400.into(), 0x1000), - PointerWidth::U32 => (0x4000.into(), 0x1_0000), - // Static Memory Bound: - // Allocating 4 GiB of address space let us avoid the - // need for explicit bounds checks. - // Static Memory Guard size: - // Allocating 2 GiB of address space lets us translate wasm - // offsets into x86 offsets as aggressively as we can. - PointerWidth::U64 => (0x1_0000.into(), 0x8000_0000), - }; - - // Allocate a small guard to optimize common cases but without - // wasting too much memory. - // The Windows memory manager seems more laxed than the other ones - // And a guard of just 1 page may not be enough is some borderline cases - // So using 2 pages for guard on this platform - #[cfg(target_os = "windows")] - let dynamic_memory_offset_guard_size: u64 = 0x2_0000; - #[cfg(not(target_os = "windows"))] - let dynamic_memory_offset_guard_size: u64 = 0x1_0000; - - Self { - static_memory_bound, - static_memory_offset_guard_size, - dynamic_memory_offset_guard_size, - } - } -} - -impl Tunables for BaseTunables { - /// Get a `MemoryStyle` for the provided `MemoryType` - fn memory_style(&self, memory: &MemoryType) -> MemoryStyle { - // A heap with a maximum that doesn't exceed the static memory bound specified by the - // tunables make it static. - // - // If the module doesn't declare an explicit maximum treat it as 4GiB. - let maximum = memory.maximum.unwrap_or_else(Pages::max_value); - if maximum <= self.static_memory_bound { - MemoryStyle::Static { - // Bound can be larger than the maximum for performance reasons - bound: self.static_memory_bound, - offset_guard_size: self.static_memory_offset_guard_size, - } - } else { - MemoryStyle::Dynamic { - offset_guard_size: self.dynamic_memory_offset_guard_size, - } - } - } - - /// Get a [`TableStyle`] for the provided [`TableType`]. - fn table_style(&self, _table: &TableType) -> TableStyle { - TableStyle::CallerChecksSignature - } - - /// Create a memory owned by the host given a [`MemoryType`] and a [`MemoryStyle`]. - fn create_host_memory( - &self, - ty: &MemoryType, - style: &MemoryStyle, - ) -> Result, MemoryError> { - Ok(Arc::new(LinearMemory::new(&ty, &style)?)) - } - - /// Create a memory owned by the VM given a [`MemoryType`] and a [`MemoryStyle`]. - /// - /// # Safety - /// - `vm_definition_location` must point to a valid, owned `VMMemoryDefinition`, - /// for example in `VMContext`. - unsafe fn create_vm_memory( - &self, - ty: &MemoryType, - style: &MemoryStyle, - vm_definition_location: NonNull, - ) -> Result, MemoryError> { - Ok(Arc::new(LinearMemory::from_definition( - &ty, - &style, - vm_definition_location, - )?)) - } - - /// Create a table owned by the host given a [`TableType`] and a [`TableStyle`]. - fn create_host_table( - &self, - ty: &TableType, - style: &TableStyle, - ) -> Result, String> { - Ok(Arc::new(LinearTable::new(&ty, &style)?)) - } - - /// Create a table owned by the VM given a [`TableType`] and a [`TableStyle`]. - /// - /// # Safety - /// - `vm_definition_location` must point to a valid, owned `VMTableDefinition`, - /// for example in `VMContext`. - unsafe fn create_vm_table( - &self, - ty: &TableType, - style: &TableStyle, - vm_definition_location: NonNull, - ) -> Result, String> { - Ok(Arc::new(LinearTable::from_definition( - &ty, - &style, - vm_definition_location, - )?)) - } -} - -#[cfg(test)] -mod tests { - use super::*; - - #[test] - fn memory_style() { - let tunables = BaseTunables { - static_memory_bound: Pages(2048), - static_memory_offset_guard_size: 128, - dynamic_memory_offset_guard_size: 256, - }; - - // No maximum - let requested = MemoryType::new(3, None, true); - let style = tunables.memory_style(&requested); - match style { - MemoryStyle::Dynamic { offset_guard_size } => assert_eq!(offset_guard_size, 256), - s => panic!("Unexpected memory style: {:?}", s), - } - - // Large maximum - let requested = MemoryType::new(3, Some(5_000_000), true); - let style = tunables.memory_style(&requested); - match style { - MemoryStyle::Dynamic { offset_guard_size } => assert_eq!(offset_guard_size, 256), - s => panic!("Unexpected memory style: {:?}", s), - } - - // Small maximum - let requested = MemoryType::new(3, Some(16), true); - let style = tunables.memory_style(&requested); - match style { - MemoryStyle::Static { - bound, - offset_guard_size, - } => { - assert_eq!(bound, Pages(2048)); - assert_eq!(offset_guard_size, 128); - } - s => panic!("Unexpected memory style: {:?}", s), - } - } -} +use crate::sys::{MemoryType, Pages, TableType}; +use loupe::MemoryUsage; +use std::ptr::NonNull; +use std::sync::Arc; +use target_lexicon::PointerWidth; +use wasmer_compiler::Target; +use wasmer_engine::Tunables; +use wasmer_vm::MemoryError; +use wasmer_vm::{ + LinearMemory, LinearTable, Memory, MemoryStyle, Table, TableStyle, VMMemoryDefinition, + VMTableDefinition, +}; + +/// Tunable parameters for WebAssembly compilation. +/// This is the reference implementation of the `Tunables` trait, +/// used by default. +/// +/// You can use this as a template for creating a custom Tunables +/// implementation or use composition to wrap your Tunables around +/// this one. The later approach is demonstrated in the +/// tunables-limit-memory example. +#[derive(Clone, MemoryUsage)] +pub struct BaseTunables { + /// For static heaps, the size in wasm pages of the heap protected by bounds checking. + pub static_memory_bound: Pages, + + /// The size in bytes of the offset guard for static heaps. + pub static_memory_offset_guard_size: u64, + + /// The size in bytes of the offset guard for dynamic heaps. + pub dynamic_memory_offset_guard_size: u64, +} + +impl BaseTunables { + /// Get the `BaseTunables` for a specific Target + pub fn for_target(target: &Target) -> Self { + let triple = target.triple(); + let pointer_width: PointerWidth = triple.pointer_width().unwrap(); + let (static_memory_bound, static_memory_offset_guard_size): (Pages, u64) = + match pointer_width { + PointerWidth::U16 => (0x400.into(), 0x1000), + PointerWidth::U32 => (0x4000.into(), 0x1_0000), + // Static Memory Bound: + // Allocating 4 GiB of address space let us avoid the + // need for explicit bounds checks. + // Static Memory Guard size: + // Allocating 2 GiB of address space lets us translate wasm + // offsets into x86 offsets as aggressively as we can. + PointerWidth::U64 => (0x1_0000.into(), 0x8000_0000), + }; + + // Allocate a small guard to optimize common cases but without + // wasting too much memory. + // The Windows memory manager seems more laxed than the other ones + // And a guard of just 1 page may not be enough is some borderline cases + // So using 2 pages for guard on this platform + #[cfg(target_os = "windows")] + let dynamic_memory_offset_guard_size: u64 = 0x2_0000; + #[cfg(not(target_os = "windows"))] + let dynamic_memory_offset_guard_size: u64 = 0x1_0000; + + Self { + static_memory_bound, + static_memory_offset_guard_size, + dynamic_memory_offset_guard_size, + } + } +} + +impl Tunables for BaseTunables { + /// Get a `MemoryStyle` for the provided `MemoryType` + fn memory_style(&self, memory: &MemoryType) -> MemoryStyle { + // A heap with a maximum that doesn't exceed the static memory bound specified by the + // tunables make it static. + // + // If the module doesn't declare an explicit maximum treat it as 4GiB. + let maximum = memory.maximum.unwrap_or_else(Pages::max_value); + if maximum <= self.static_memory_bound { + MemoryStyle::Static { + // Bound can be larger than the maximum for performance reasons + bound: self.static_memory_bound, + offset_guard_size: self.static_memory_offset_guard_size, + } + } else { + MemoryStyle::Dynamic { + offset_guard_size: self.dynamic_memory_offset_guard_size, + } + } + } + + /// Get a [`TableStyle`] for the provided [`TableType`]. + fn table_style(&self, _table: &TableType) -> TableStyle { + TableStyle::CallerChecksSignature + } + + /// Create a memory owned by the host given a [`MemoryType`] and a [`MemoryStyle`]. + fn create_host_memory( + &self, + ty: &MemoryType, + style: &MemoryStyle, + ) -> Result, MemoryError> { + Ok(Arc::new(LinearMemory::new(&ty, &style)?)) + } + + /// Create a memory owned by the VM given a [`MemoryType`] and a [`MemoryStyle`]. + /// + /// # Safety + /// - `vm_definition_location` must point to a valid, owned `VMMemoryDefinition`, + /// for example in `VMContext`. + unsafe fn create_vm_memory( + &self, + ty: &MemoryType, + style: &MemoryStyle, + vm_definition_location: NonNull, + ) -> Result, MemoryError> { + Ok(Arc::new(LinearMemory::from_definition( + &ty, + &style, + vm_definition_location, + )?)) + } + + /// Create a table owned by the host given a [`TableType`] and a [`TableStyle`]. + fn create_host_table( + &self, + ty: &TableType, + style: &TableStyle, + ) -> Result, String> { + Ok(Arc::new(LinearTable::new(&ty, &style)?)) + } + + /// Create a table owned by the VM given a [`TableType`] and a [`TableStyle`]. + /// + /// # Safety + /// - `vm_definition_location` must point to a valid, owned `VMTableDefinition`, + /// for example in `VMContext`. + unsafe fn create_vm_table( + &self, + ty: &TableType, + style: &TableStyle, + vm_definition_location: NonNull, + ) -> Result, String> { + Ok(Arc::new(LinearTable::from_definition( + &ty, + &style, + vm_definition_location, + )?)) + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn memory_style() { + let tunables = BaseTunables { + static_memory_bound: Pages(2048), + static_memory_offset_guard_size: 128, + dynamic_memory_offset_guard_size: 256, + }; + + // No maximum + let requested = MemoryType::new(3, None, true); + let style = tunables.memory_style(&requested); + match style { + MemoryStyle::Dynamic { offset_guard_size } => assert_eq!(offset_guard_size, 256), + s => panic!("Unexpected memory style: {:?}", s), + } + + // Large maximum + let requested = MemoryType::new(3, Some(5_000_000), true); + let style = tunables.memory_style(&requested); + match style { + MemoryStyle::Dynamic { offset_guard_size } => assert_eq!(offset_guard_size, 256), + s => panic!("Unexpected memory style: {:?}", s), + } + + // Small maximum + let requested = MemoryType::new(3, Some(16), true); + let style = tunables.memory_style(&requested); + match style { + MemoryStyle::Static { + bound, + offset_guard_size, + } => { + assert_eq!(bound, Pages(2048)); + assert_eq!(offset_guard_size, 128); + } + s => panic!("Unexpected memory style: {:?}", s), + } + } +} From 686c36a96e8b841aac03c225fdac350a7b3bc42c Mon Sep 17 00:00:00 2001 From: ptitSeb Date: Mon, 8 Nov 2021 16:28:55 +0100 Subject: [PATCH 4/4] windows(test) Refined .gitattributes --- .gitattributes | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitattributes b/.gitattributes index dc6e07495a3..6486387fd29 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1,4 +1,4 @@ CHANGELOG.md merge=union *.wast linguist-vendored *.wat linguist-vendored -tests/wasi-wast/wasi/test_fs -text +scene*.txt -text