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;
|
let mem_bytes = memory_pages * MemorySection::PAGE_SIZE;
|
||||||
ExecutionState {
|
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),
|
call_stack: CallStack::new(arena),
|
||||||
value_stack: ValueStack::new(arena),
|
value_stack: ValueStack::new(arena),
|
||||||
globals: Vec::from_iter_in(globals, arena),
|
globals: Vec::from_iter_in(globals, arena),
|
||||||
|
@ -435,9 +435,23 @@ impl<'a> ExecutionState<'a> {
|
||||||
self.value_stack.push(Value::I32(size));
|
self.value_stack.push(Value::I32(size));
|
||||||
}
|
}
|
||||||
GROWMEMORY => {
|
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_pages = self.value_stack.pop_u32();
|
||||||
let grow_bytes = grow_pages as usize * MemorySection::PAGE_SIZE as usize;
|
let grow_bytes = grow_pages * MemorySection::PAGE_SIZE;
|
||||||
self.memory.extend(iter::repeat(0).take(grow_bytes));
|
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 => {
|
I32CONST => {
|
||||||
let value = i32::parse((), &module.code.bytes, &mut self.program_counter).unwrap();
|
let value = i32::parse((), &module.code.bytes, &mut self.program_counter).unwrap();
|
||||||
|
|
|
@ -662,11 +662,39 @@ fn test_i64store32() {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// #[test]
|
#[test]
|
||||||
// fn test_currentmemory() {}
|
fn test_currentmemory() {
|
||||||
|
let arena = Bump::new();
|
||||||
|
let mut module = WasmModule::new(&arena);
|
||||||
|
|
||||||
// #[test]
|
let pages = 3;
|
||||||
// fn test_growmemory() {}
|
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]
|
#[test]
|
||||||
fn test_i32const() {
|
fn test_i32const() {
|
||||||
|
|
|
@ -790,6 +790,16 @@ impl<'a> MemorySection<'a> {
|
||||||
};
|
};
|
||||||
Ok(min_pages * MemorySection::PAGE_SIZE)
|
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);
|
section_impl!(MemorySection, SectionId::Memory);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue