mirror of
https://github.com/roc-lang/roc.git
synced 2025-09-27 05:49:08 +00:00
wasm_interp: tests for memory allocation instructions
This commit is contained in:
parent
06f3726e35
commit
2bd67a3292
3 changed files with 59 additions and 7 deletions
|
@ -36,7 +36,7 @@ impl<'a> ExecutionState<'a> {
|
|||
{
|
||||
let mem_bytes = memory_pages * MemorySection::PAGE_SIZE;
|
||||
ExecutionState {
|
||||
memory: Vec::with_capacity_in(mem_bytes as usize, arena),
|
||||
memory: Vec::from_iter_in(iter::repeat(0).take(mem_bytes as usize), arena),
|
||||
call_stack: CallStack::new(arena),
|
||||
value_stack: ValueStack::new(arena),
|
||||
globals: Vec::from_iter_in(globals, arena),
|
||||
|
@ -435,9 +435,23 @@ impl<'a> ExecutionState<'a> {
|
|||
self.value_stack.push(Value::I32(size));
|
||||
}
|
||||
GROWMEMORY => {
|
||||
let old_bytes = self.memory.len() as u32;
|
||||
let old_pages = old_bytes / MemorySection::PAGE_SIZE as u32;
|
||||
let grow_pages = self.value_stack.pop_u32();
|
||||
let grow_bytes = grow_pages as usize * MemorySection::PAGE_SIZE as usize;
|
||||
self.memory.extend(iter::repeat(0).take(grow_bytes));
|
||||
let grow_bytes = grow_pages * MemorySection::PAGE_SIZE;
|
||||
let new_bytes = old_bytes + grow_bytes;
|
||||
|
||||
let success = match module.memory.max_bytes().unwrap() {
|
||||
Some(max_bytes) => new_bytes <= max_bytes,
|
||||
None => true,
|
||||
};
|
||||
if success {
|
||||
self.memory
|
||||
.extend(iter::repeat(0).take(grow_bytes as usize));
|
||||
self.value_stack.push(Value::I32(old_pages as i32));
|
||||
} else {
|
||||
self.value_stack.push(Value::I32(-1));
|
||||
}
|
||||
}
|
||||
I32CONST => {
|
||||
let value = i32::parse((), &module.code.bytes, &mut self.program_counter).unwrap();
|
||||
|
|
|
@ -662,11 +662,39 @@ fn test_i64store32() {
|
|||
);
|
||||
}
|
||||
|
||||
// #[test]
|
||||
// fn test_currentmemory() {}
|
||||
#[test]
|
||||
fn test_currentmemory() {
|
||||
let arena = Bump::new();
|
||||
let mut module = WasmModule::new(&arena);
|
||||
|
||||
// #[test]
|
||||
// fn test_growmemory() {}
|
||||
let pages = 3;
|
||||
let pc = 0;
|
||||
module.memory = MemorySection::new(&arena, pages * MemorySection::PAGE_SIZE);
|
||||
module.code.bytes.push(OpCode::CURRENTMEMORY as u8);
|
||||
|
||||
let mut state = ExecutionState::new(&arena, pages, pc, []);
|
||||
state.execute_next_instruction(&module);
|
||||
assert_eq!(state.value_stack.pop(), Value::I32(3))
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_growmemory() {
|
||||
let arena = Bump::new();
|
||||
let mut module = WasmModule::new(&arena);
|
||||
|
||||
let existing_pages = 3;
|
||||
let grow_pages = 2;
|
||||
let pc = 0;
|
||||
module.memory = MemorySection::new(&arena, existing_pages * MemorySection::PAGE_SIZE);
|
||||
module.code.bytes.push(OpCode::I32CONST as u8);
|
||||
module.code.bytes.encode_i32(grow_pages);
|
||||
module.code.bytes.push(OpCode::GROWMEMORY as u8);
|
||||
|
||||
let mut state = ExecutionState::new(&arena, existing_pages, pc, []);
|
||||
state.execute_next_instruction(&module);
|
||||
state.execute_next_instruction(&module);
|
||||
assert_eq!(state.memory.len(), 5 * MemorySection::PAGE_SIZE as usize);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_i32const() {
|
||||
|
|
|
@ -790,6 +790,16 @@ impl<'a> MemorySection<'a> {
|
|||
};
|
||||
Ok(min_pages * MemorySection::PAGE_SIZE)
|
||||
}
|
||||
|
||||
pub fn max_bytes(&self) -> Result<Option<u32>, ParseError> {
|
||||
let mut cursor = 0;
|
||||
let memory_limits = Limits::parse((), &self.bytes, &mut cursor)?;
|
||||
let bytes = match memory_limits {
|
||||
Limits::Min(_) => None,
|
||||
Limits::MinMax(_, pages) => Some(pages * MemorySection::PAGE_SIZE),
|
||||
};
|
||||
Ok(bytes)
|
||||
}
|
||||
}
|
||||
|
||||
section_impl!(MemorySection, SectionId::Memory);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue