Split memory, table creation. Mark unsafe functions unsafe

This commit is contained in:
Mark McCaskey
2020-10-15 15:42:54 -07:00
parent 33c32da5d0
commit 9fdbb0886c
6 changed files with 114 additions and 32 deletions

View File

@@ -37,7 +37,7 @@ impl Memory {
pub fn new(store: &Store, ty: MemoryType) -> Result<Self, MemoryError> { pub fn new(store: &Store, ty: MemoryType) -> Result<Self, MemoryError> {
let tunables = store.tunables(); let tunables = store.tunables();
let style = tunables.memory_style(&ty); let style = tunables.memory_style(&ty);
let memory = tunables.create_memory(&ty, &style, None)?; let memory = tunables.create_host_memory(&ty, &style)?;
Ok(Self { Ok(Self {
store: store.clone(), store: store.clone(),

View File

@@ -43,7 +43,7 @@ impl Table {
let tunables = store.tunables(); let tunables = store.tunables();
let style = tunables.table_style(&ty); let style = tunables.table_style(&ty);
let table = tunables let table = tunables
.create_table(&ty, &style, None) .create_host_table(&ty, &style)
.map_err(RuntimeError::new)?; .map_err(RuntimeError::new)?;
let num_elements = table.size(); let num_elements = table.size();

View File

@@ -88,28 +88,52 @@ impl BaseTunables for Tunables {
TableStyle::CallerChecksSignature TableStyle::CallerChecksSignature
} }
/// Create a memory given a [`MemoryType`] and a [`MemoryStyle`]. /// Create a memory owned by the host given a [`MemoryType`] and a [`MemoryStyle`].
fn create_memory( fn create_host_memory(
&self, &self,
ty: &MemoryType, ty: &MemoryType,
style: &MemoryStyle, style: &MemoryStyle,
vm_definition_location: Option<NonNull<VMMemoryDefinition>>,
) -> Result<Arc<dyn Memory>, MemoryError> { ) -> Result<Arc<dyn Memory>, MemoryError> {
Ok(Arc::new(LinearMemory::new( 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 location in VM memory.
unsafe fn create_vm_memory(
&self,
ty: &MemoryType,
style: &MemoryStyle,
vm_definition_location: NonNull<VMMemoryDefinition>,
) -> Result<Arc<dyn Memory>, MemoryError> {
Ok(Arc::new(LinearMemory::from_definition(
&ty, &ty,
&style, &style,
vm_definition_location, vm_definition_location,
)?)) )?))
} }
/// Create a table given a [`TableType`] and a [`TableStyle`]. /// Create a table owned by the host given a [`TableType`] and a [`TableStyle`].
fn create_table( fn create_host_table(
&self, &self,
ty: &TableType, ty: &TableType,
style: &TableStyle, style: &TableStyle,
vm_definition_location: Option<NonNull<VMTableDefinition>>,
) -> Result<Arc<dyn Table>, String> { ) -> Result<Arc<dyn Table>, String> {
Ok(Arc::new(LinearTable::new( 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 location in VM memory.
unsafe fn create_vm_table(
&self,
ty: &TableType,
style: &TableStyle,
vm_definition_location: NonNull<VMTableDefinition>,
) -> Result<Arc<dyn Table>, String> {
Ok(Arc::new(LinearTable::from_definition(
&ty, &ty,
&style, &style,
vm_definition_location, vm_definition_location,

View File

@@ -20,28 +20,40 @@ pub trait Tunables {
/// Construct a `TableStyle` for the provided `TableType` /// Construct a `TableStyle` for the provided `TableType`
fn table_style(&self, table: &TableType) -> TableStyle; fn table_style(&self, table: &TableType) -> TableStyle;
/// Create a memory given a memory type /// Create a memory owned by the host given a [`MemoryType`] and a [`MemoryStyle`].
/// fn create_host_memory(
/// `vm_definition_location` should either point to a valid memory location
/// in VM memory or be `None` to indicate that the metadata for the memory
/// should be owned by the host.
fn create_memory(
&self, &self,
ty: &MemoryType, ty: &MemoryType,
style: &MemoryStyle, style: &MemoryStyle,
vm_definition_location: Option<NonNull<VMMemoryDefinition>>,
) -> Result<Arc<dyn Memory>, MemoryError>; ) -> Result<Arc<dyn Memory>, MemoryError>;
/// Create a memory given a memory type. /// Create a memory owned by the VM given a [`MemoryType`] and a [`MemoryStyle`].
/// ///
/// `vm_definition_location` should either point to a valid memory location /// # Safety
/// in VM memory or be `None` to indicate that the metadata for the table /// - `vm_definition_location` must point to a valid location in VM memory.
/// should be owned by the host. unsafe fn create_vm_memory(
fn create_table( &self,
ty: &MemoryType,
style: &MemoryStyle,
vm_definition_location: NonNull<VMMemoryDefinition>,
) -> Result<Arc<dyn Memory>, MemoryError>;
/// Create a table owned by the host given a [`TableType`] and a [`TableStyle`].
fn create_host_table(
&self, &self,
ty: &TableType, ty: &TableType,
style: &TableStyle, style: &TableStyle,
vm_definition_location: Option<NonNull<VMTableDefinition>>, ) -> Result<Arc<dyn Table>, String>;
/// Create a table owned by the VM given a [`TableType`] and a [`TableStyle`].
///
/// # Safety
/// - `vm_definition_location` must point to a valid location in VM memory.
unsafe fn create_vm_table(
&self,
ty: &TableType,
style: &TableStyle,
vm_definition_location: NonNull<VMTableDefinition>,
) -> Result<Arc<dyn Table>, String>; ) -> Result<Arc<dyn Table>, String>;
/// Create a global with an unset value. /// Create a global with an unset value.
@@ -50,7 +62,7 @@ pub trait Tunables {
} }
/// Allocate memory for just the memories of the current module. /// Allocate memory for just the memories of the current module.
fn create_memories( unsafe fn create_memories(
&self, &self,
module: &ModuleInfo, module: &ModuleInfo,
memory_styles: &PrimaryMap<MemoryIndex, MemoryStyle>, memory_styles: &PrimaryMap<MemoryIndex, MemoryStyle>,
@@ -66,7 +78,7 @@ pub trait Tunables {
// TODO: error handling // TODO: error handling
let mdl = memory_definition_locations[index]; let mdl = memory_definition_locations[index];
memories.push( memories.push(
self.create_memory(ty, style, Some(mdl)) self.create_vm_memory(ty, style, mdl)
.map_err(|e| LinkError::Resource(format!("Failed to create memory: {}", e)))?, .map_err(|e| LinkError::Resource(format!("Failed to create memory: {}", e)))?,
); );
} }
@@ -74,7 +86,7 @@ pub trait Tunables {
} }
/// Allocate memory for just the tables of the current module. /// Allocate memory for just the tables of the current module.
fn create_tables( unsafe fn create_tables(
&self, &self,
module: &ModuleInfo, module: &ModuleInfo,
table_styles: &PrimaryMap<TableIndex, TableStyle>, table_styles: &PrimaryMap<TableIndex, TableStyle>,
@@ -90,7 +102,7 @@ pub trait Tunables {
let style = &table_styles[ti]; let style = &table_styles[ti];
let tdl = table_definition_locations[index]; let tdl = table_definition_locations[index];
tables.push( tables.push(
self.create_table(ty, style, Some(tdl)) self.create_vm_table(ty, style, tdl)
.map_err(LinkError::Resource)?, .map_err(LinkError::Resource)?,
); );
} }

View File

@@ -177,7 +177,30 @@ struct WasmMmap {
impl LinearMemory { impl LinearMemory {
/// Create a new linear memory instance with specified minimum and maximum number of wasm pages. /// Create a new linear memory instance with specified minimum and maximum number of wasm pages.
pub fn new( ///
/// This creates a `LinearMemory` with owned metadata: this can be used to create a memory
/// that will be imported into Wasm modules.
pub fn new(memory: &MemoryType, style: &MemoryStyle) -> Result<Self, MemoryError> {
unsafe { Self::new_internal(memory, style, None) }
}
/// Create a new linear memory instance with specified minimum and maximum number of wasm pages.
///
/// This creates a `LinearMemory` with metadata owned by a VM, pointed to by
/// `vm_memory_location`: this can be used to create a local memory.
///
/// # Safety
/// - `vm_memory_location` must point to a valid location in VM memory.
pub unsafe fn from_definition(
memory: &MemoryType,
style: &MemoryStyle,
vm_memory_location: NonNull<VMMemoryDefinition>,
) -> Result<Self, MemoryError> {
Self::new_internal(memory, style, Some(vm_memory_location))
}
/// Build a `LinearMemory` with either self-owned or VM owned metadata.
unsafe fn new_internal(
memory: &MemoryType, memory: &MemoryType,
style: &MemoryStyle, style: &MemoryStyle,
vm_memory_location: Option<NonNull<VMMemoryDefinition>>, vm_memory_location: Option<NonNull<VMMemoryDefinition>>,
@@ -243,7 +266,7 @@ impl LinearMemory {
offset_guard_size: offset_guard_bytes, offset_guard_size: offset_guard_bytes,
needs_signal_handlers, needs_signal_handlers,
vm_memory_definition: if let Some(mem_loc) = vm_memory_location { vm_memory_definition: if let Some(mem_loc) = vm_memory_location {
unsafe { {
let mut ptr = mem_loc.clone(); let mut ptr = mem_loc.clone();
let md = ptr.as_mut(); let md = ptr.as_mut();
md.base = base_ptr; md.base = base_ptr;

View File

@@ -134,8 +134,31 @@ unsafe impl Send for LinearTable {}
unsafe impl Sync for LinearTable {} unsafe impl Sync for LinearTable {}
impl LinearTable { impl LinearTable {
/// Create a new table instance with specified minimum and maximum number of elements. /// Create a new linear table instance with specified minimum and maximum number of elements.
pub fn new( ///
/// This creates a `LinearTable` with metadata owned by a VM, pointed to by
/// `vm_table_location`: this can be used to create a local table.
pub fn new(table: &TableType, style: &TableStyle) -> Result<Self, String> {
unsafe { Self::new_inner(table, style, None) }
}
/// Create a new linear table instance with specified minimum and maximum number of elements.
///
/// This creates a `LinearTable` with metadata owned by a VM, pointed to by
/// `vm_table_location`: this can be used to create a local table.
///
/// # Safety
/// - `vm_table_location` must point to a valid location in VM memory.
pub unsafe fn from_definition(
table: &TableType,
style: &TableStyle,
vm_table_location: NonNull<VMTableDefinition>,
) -> Result<Self, String> {
Self::new_inner(table, style, Some(vm_table_location))
}
/// Create a new `LinearTable` with either self-owned or VM owned metadata.
unsafe fn new_inner(
table: &TableType, table: &TableType,
style: &TableStyle, style: &TableStyle,
vm_table_location: Option<NonNull<VMTableDefinition>>, vm_table_location: Option<NonNull<VMTableDefinition>>,
@@ -163,7 +186,7 @@ impl LinearTable {
table: *table, table: *table,
style: style.clone(), style: style.clone(),
vm_table_definition: if let Some(table_loc) = vm_table_location { vm_table_definition: if let Some(table_loc) = vm_table_location {
unsafe { {
let mut ptr = table_loc.clone(); let mut ptr = table_loc.clone();
let td = ptr.as_mut(); let td = ptr.as_mut();
td.base = base as _; td.base = base as _;