mirror of
https://github.com/fluencelabs/parity-wasm
synced 2025-06-21 02:31:51 +00:00
create memory buffer with initial capacity
This commit is contained in:
@ -39,21 +39,23 @@ impl MemoryInstance {
|
|||||||
pub fn new(memory_type: &MemoryType) -> Result<Arc<Self>, Error> {
|
pub fn new(memory_type: &MemoryType) -> Result<Arc<Self>, Error> {
|
||||||
check_limits(memory_type.limits())?;
|
check_limits(memory_type.limits())?;
|
||||||
|
|
||||||
if let Some(maximum_pages) = memory_type.limits().maximum() {
|
let maximum_size = match memory_type.limits().maximum() {
|
||||||
if maximum_pages > LINEAR_MEMORY_MAX_PAGES {
|
Some(maximum_pages) if maximum_pages > LINEAR_MEMORY_MAX_PAGES =>
|
||||||
return Err(Error::Memory(format!("memory size must be at most 65536 pages")));
|
return Err(Error::Memory(format!("maximum memory size must be at most {} pages", LINEAR_MEMORY_MAX_PAGES))),
|
||||||
}
|
Some(maximum_pages) => maximum_pages.saturating_mul(LINEAR_MEMORY_PAGE_SIZE),
|
||||||
}
|
None => u32::MAX,
|
||||||
|
};
|
||||||
|
let initial_size = calculate_memory_size(0, memory_type.limits().initial(), maximum_size)
|
||||||
|
.ok_or(Error::Memory(format!("initial memory size must be at most {} pages", LINEAR_MEMORY_MAX_PAGES)))?;
|
||||||
|
|
||||||
let memory = MemoryInstance {
|
let memory = MemoryInstance {
|
||||||
buffer: RwLock::new(Vec::new()), // TODO: with_capacity
|
buffer: RwLock::new(Vec::with_capacity(initial_size as usize)),
|
||||||
maximum_size: memory_type.limits().maximum()
|
maximum_size: maximum_size,
|
||||||
.map(|s| s.saturating_mul(LINEAR_MEMORY_PAGE_SIZE))
|
|
||||||
.unwrap_or(u32::MAX),
|
|
||||||
};
|
};
|
||||||
if memory.grow(memory_type.limits().initial())? == u32::MAX {
|
if memory.grow(memory_type.limits().initial())? == u32::MAX {
|
||||||
return Err(Error::Memory(format!("error initializing {}-pages linear memory region", memory_type.limits().initial())));
|
return Err(Error::Memory(format!("error initializing {}-bytes linear memory region", initial_size)));
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(Arc::new(memory))
|
Ok(Arc::new(memory))
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -85,9 +87,8 @@ impl MemoryInstance {
|
|||||||
pub fn grow(&self, pages: u32) -> Result<u32, Error> {
|
pub fn grow(&self, pages: u32) -> Result<u32, Error> {
|
||||||
let mut buffer = self.buffer.write();
|
let mut buffer = self.buffer.write();
|
||||||
let old_size = buffer.len() as u32;
|
let old_size = buffer.len() as u32;
|
||||||
match pages.checked_mul(LINEAR_MEMORY_PAGE_SIZE).and_then(|bytes| old_size.checked_add(bytes)) {
|
match calculate_memory_size(old_size, pages, self.maximum_size) {
|
||||||
None => Ok(u32::MAX),
|
None => Ok(u32::MAX),
|
||||||
Some(new_size) if new_size > self.maximum_size => Ok(u32::MAX),
|
|
||||||
Some(new_size) => {
|
Some(new_size) => {
|
||||||
buffer.extend(vec![0; (new_size - old_size) as usize]);
|
buffer.extend(vec![0; (new_size - old_size) as usize]);
|
||||||
Ok(old_size / LINEAR_MEMORY_PAGE_SIZE)
|
Ok(old_size / LINEAR_MEMORY_PAGE_SIZE)
|
||||||
@ -137,3 +138,14 @@ impl MemoryInstance {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn calculate_memory_size(old_size: u32, additional_pages: u32, maximum_size: u32) -> Option<u32> {
|
||||||
|
additional_pages
|
||||||
|
.checked_mul(LINEAR_MEMORY_PAGE_SIZE)
|
||||||
|
.and_then(|size| size.checked_add(old_size))
|
||||||
|
.and_then(|size| if size > maximum_size {
|
||||||
|
None
|
||||||
|
} else {
|
||||||
|
Some(size)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
Reference in New Issue
Block a user