Add hooks for implementing bulk-memory-operations (#1258)

This commit is contained in:
Ryan Hunt
2019-12-06 09:13:53 -06:00
committed by Benjamin Bouvier
parent 81782f8efa
commit aabf6559a0
3 changed files with 262 additions and 12 deletions

View File

@@ -987,18 +987,104 @@ pub fn translate_operator<FE: FuncEnvironment + ?Sized>(
| Operator::Fence { .. } => {
return Err(wasm_unsupported!("proposed thread operator {:?}", op));
}
Operator::MemoryInit { .. }
| Operator::DataDrop { .. }
| Operator::MemoryCopy
| Operator::MemoryFill
| Operator::TableInit { .. }
| Operator::ElemDrop { .. }
| Operator::TableCopy
| Operator::TableGet { .. }
| Operator::TableSet { .. }
| Operator::TableGrow { .. }
| Operator::TableSize { .. } => {
return Err(wasm_unsupported!("proposed bulk memory operator {:?}", op));
Operator::MemoryCopy => {
// The WebAssembly MVP only supports one linear memory and
// wasmparser will ensure that the memory indices specified are
// zero.
let heap_index = MemoryIndex::from_u32(0);
let heap = state.get_heap(builder.func, 0, environ)?;
let len = state.pop1();
let src = state.pop1();
let dest = state.pop1();
environ.translate_memory_copy(builder.cursor(), heap_index, heap, dest, src, len)?;
}
Operator::MemoryFill => {
// The WebAssembly MVP only supports one linear memory and
// wasmparser will ensure that the memory index specified is
// zero.
let heap_index = MemoryIndex::from_u32(0);
let heap = state.get_heap(builder.func, 0, environ)?;
let len = state.pop1();
let val = state.pop1();
let dest = state.pop1();
environ.translate_memory_fill(builder.cursor(), heap_index, heap, dest, val, len)?;
}
Operator::MemoryInit { segment } => {
// The WebAssembly MVP only supports one linear memory and
// wasmparser will ensure that the memory index specified is
// zero.
let heap_index = MemoryIndex::from_u32(0);
let heap = state.get_heap(builder.func, 0, environ)?;
let len = state.pop1();
let src = state.pop1();
let dest = state.pop1();
environ.translate_memory_init(
builder.cursor(),
heap_index,
heap,
*segment,
dest,
src,
len,
)?;
}
Operator::DataDrop { segment } => {
environ.translate_data_drop(builder.cursor(), *segment)?;
}
Operator::TableSize { table: index } => {
let table = state.get_table(builder.func, *index, environ)?;
state.push1(environ.translate_table_size(
builder.cursor(),
TableIndex::from_u32(*index),
table,
)?);
}
Operator::TableCopy => {
// The WebAssembly MVP only supports one table and wasmparser will
// ensure that the table index specified is zero.
let dst_table_index = 0;
let dst_table = state.get_table(builder.func, dst_table_index, environ)?;
let src_table_index = 0;
let src_table = state.get_table(builder.func, src_table_index, environ)?;
let len = state.pop1();
let src = state.pop1();
let dest = state.pop1();
environ.translate_table_copy(
builder.cursor(),
TableIndex::from_u32(dst_table_index),
dst_table,
TableIndex::from_u32(src_table_index),
src_table,
dest,
src,
len,
)?;
}
Operator::TableInit { segment } => {
// The WebAssembly MVP only supports one table and we assume it here.
let table_index = 0;
let table = state.get_table(builder.func, table_index, environ)?;
let len = state.pop1();
let src = state.pop1();
let dest = state.pop1();
environ.translate_table_init(
builder.cursor(),
*segment,
TableIndex::from_u32(table_index),
table,
dest,
src,
len,
)?;
}
Operator::ElemDrop { segment } => {
environ.translate_elem_drop(builder.cursor(), *segment)?;
}
Operator::TableGet { .. } | Operator::TableSet { .. } | Operator::TableGrow { .. } => {
return Err(wasm_unsupported!(
"proposed reference types operator {:?}",
op
));
}
Operator::V128Const { value } => {
let data = value.bytes().to_vec().into();