mod data;
mod ty;
pub use self::{
data::{DataSegment, DataSegmentEntity},
ty::{MemoryType, MemoryTypeBuilder},
};
use crate::{
AsContext,
AsContextMut,
Error,
StoreContext,
StoreContextMut,
core::CoreMemory,
errors::MemoryError,
store::Stored,
};
define_handle! {
/// A Wasm linear memory reference.
struct Memory(u32, Stored) => CoreMemory;
}
impl Memory {
/// Creates a new linear memory to the store.
///
/// # Errors
///
/// If more than [`u32::MAX`] much linear memory is allocated.
pub fn new(mut ctx: impl AsContextMut, ty: MemoryType) -> Result<Self, Error> {
let (inner, mut resource_limiter) = ctx
.as_context_mut()
.store
.store_inner_and_resource_limiter_ref();
let entity = CoreMemory::new(ty.core, &mut resource_limiter)?;
let memory = inner.alloc_memory(entity);
Ok(memory)
}
/// Creates a new linear memory to the store.
///
/// # Errors
///
/// If more than [`u32::MAX`] much linear memory is allocated.
/// - If static buffer is invalid
pub fn new_static(
mut ctx: impl AsContextMut,
ty: MemoryType,
buf: &'static mut [u8],
) -> Result<Self, Error> {
let (inner, mut resource_limiter) = ctx
.as_context_mut()
.store
.store_inner_and_resource_limiter_ref();
let entity = CoreMemory::new_static(ty.core, &mut resource_limiter, buf)?;
let memory = inner.alloc_memory(entity);
Ok(memory)
}
/// Returns the memory type of the linear memory.
///
/// # Panics
///
/// Panics if `ctx` does not own this [`Memory`].
pub fn ty(&self, ctx: impl AsContext) -> MemoryType {
let core = ctx.as_context().store.inner.resolve_memory(self).ty();
MemoryType { core }
}
/// Returns the dynamic [`MemoryType`] of the [`Memory`].
///
/// # Note
///
/// This respects the current size of the [`Memory`] as
/// its minimum size and is useful for import subtyping checks.
///
/// # Panics
///
/// Panics if `ctx` does not own this [`Memory`].
pub(crate) fn dynamic_ty(&self, ctx: impl AsContext) -> MemoryType {
let core = ctx
.as_context()
.store
.inner
.resolve_memory(self)
.dynamic_ty();
MemoryType { core }
}
/// Returns the size, in WebAssembly pages, of this Wasm linear memory.
///
/// # Panics
///
/// Panics if `ctx` does not own this [`Memory`].
pub fn size(&self, ctx: impl AsContext) -> u64 {
ctx.as_context().store.inner.resolve_memory(self).size()
}
/// Grows the linear memory by the given amount of new pages.
///
/// Returns the amount of pages before the operation upon success.
///
/// # Errors
///
/// If the linear memory would grow beyond its maximum limit after
/// the grow operation.
///
/// # Panics
///
/// Panics if `ctx` does not own this [`Memory`].
pub fn grow(&self, mut ctx: impl AsContextMut, additional: u64) -> Result<u64, MemoryError> {
let (inner, mut limiter) = ctx
.as_context_mut()
.store
.store_inner_and_resource_limiter_ref();
inner
.resolve_memory_mut(self)
.grow(additional, None, &mut limiter)
.map_err(|_| MemoryError::OutOfBoundsGrowth)
}
/// Returns a shared slice to the bytes underlying the [`Memory`].
///
/// # Panics
///
/// Panics if `ctx` does not own this [`Memory`].
pub fn data<'a, T: 'a>(&self, ctx: impl Into<StoreContext<'a, T>>) -> &'a [u8] {
ctx.into().store.inner.resolve_memory(self).data()
}
/// Returns an exclusive slice to the bytes underlying the [`Memory`].
///
/// # Panics
///
/// Panics if `ctx` does not own this [`Memory`].
pub fn data_mut<'a, T: 'a>(&self, ctx: impl Into<StoreContextMut<'a, T>>) -> &'a mut [u8] {
ctx.into().store.inner.resolve_memory_mut(self).data_mut()
}
/// Returns an exclusive slice to the bytes underlying the [`Memory`], and an exclusive
/// reference to the user provided state.
///
/// # Panics
///
/// Panics if `ctx` does not own this [`Memory`].
pub fn data_and_store_mut<'a, T: 'a>(
&self,
ctx: impl Into<StoreContextMut<'a, T>>,
) -> (&'a mut [u8], &'a mut T) {
let (memory, store) = ctx.into().store.resolve_memory_and_state_mut(self);
(memory.data_mut(), store)
}
/// Returns the base pointer, in the hostβs address space, that the [`Memory`] is located at.
///
/// # Panics
///
/// Panics if `ctx` does not own this [`Memory`].
pub fn data_ptr(&self, ctx: impl AsContext) -> *mut u8 {
ctx.as_context().store.inner.resolve_memory(self).data_ptr()
}
/// Returns the byte length of this [`Memory`].
///
/// The returned value will be a multiple of the wasm page size, 64k.
///
/// # Panics
///
/// Panics if `ctx` does not own this [`Memory`].
pub fn data_size(&self, ctx: impl AsContext) -> usize {
ctx.as_context()
.store
.inner
.resolve_memory(self)
.data_size()
}
/// Reads `n` bytes from `memory[offset..offset+n]` into `buffer`
/// where `n` is the length of `buffer`.
///
/// # Errors
///
/// If this operation accesses out of bounds linear memory.
///
/// # Panics
///
/// Panics if `ctx` does not own this [`Memory`].
pub fn read(
&self,
ctx: impl AsContext,
offset: usize,
buffer: &mut [u8],
) -> Result<(), MemoryError> {
ctx.as_context()
.store
.inner
.resolve_memory(self)
.read(offset, buffer)
}
/// Writes `n` bytes to `memory[offset..offset+n]` from `buffer`
/// where `n` if the length of `buffer`.
///
/// # Errors
///
/// If this operation accesses out of bounds linear memory.
///
/// # Panics
///
/// Panics if `ctx` does not own this [`Memory`].
pub fn write(
&self,
mut ctx: impl AsContextMut,
offset: usize,
buffer: &[u8],
) -> Result<(), MemoryError> {
ctx.as_context_mut()
.store
.inner
.resolve_memory_mut(self)
.write(offset, buffer)
}
}
pub use ;
use crate::;
define_handle!
Homonyms
cyb/evy/forks/naga/src/back/hlsl/mod.rs
struct Baz { m: mat3x2, } struct Baz { float2 m_0; float2 m_1; float2 m_2; }; float3x2 GetMatmOnBaz(Baz obj) { return float3x2(obj.m_0, obj.m_1, obj.m_2); }