wasmtime: Implement table.fill

Part of #929
This commit is contained in:
Nick Fitzgerald
2020-07-02 16:56:02 -07:00
parent d87ada209c
commit 3555f97906
5 changed files with 97 additions and 13 deletions

View File

@@ -265,6 +265,41 @@ pub unsafe extern "C" fn wasmtime_table_grow(
}
}
/// Implementation of `table.fill`.
pub unsafe extern "C" fn wasmtime_table_fill(
vmctx: *mut VMContext,
table_index: u32,
dst: u32,
// NB: we don't know whether this is a `VMExternRef` or a pointer to a
// `VMCallerCheckedAnyfunc` until we look at the table's element type.
val: *mut u8,
len: u32,
) {
let result = {
let instance = (&mut *vmctx).instance();
let table_index = TableIndex::from_u32(table_index);
let table = instance.get_table(table_index);
match table.element_type() {
TableElementType::Func => {
let val = val as *mut VMCallerCheckedAnyfunc;
table.fill(dst, val.into(), len)
}
TableElementType::Val(ty) => {
debug_assert_eq!(ty, crate::ref_type());
let val = if val.is_null() {
None
} else {
Some(VMExternRef::clone_from_raw(val))
};
table.fill(dst, val.into(), len)
}
}
};
if let Err(trap) = result {
raise_lib_trap(trap);
}
}
/// Implementation of `table.copy`.
pub unsafe extern "C" fn wasmtime_table_copy(
vmctx: *mut VMContext,

View File

@@ -67,6 +67,26 @@ impl Table {
}
}
/// Fill `table[dst..dst + len]` with `val`.
///
/// Returns a trap error on out-of-bounds accesses.
pub fn fill(&self, dst: u32, val: TableElement, len: u32) -> Result<(), Trap> {
let start = dst;
let end = start
.checked_add(len)
.ok_or_else(|| Trap::wasm(ir::TrapCode::TableOutOfBounds))?;
if end > self.size() {
return Err(Trap::wasm(ir::TrapCode::TableOutOfBounds));
}
for i in start..end {
self.set(i, val.clone()).unwrap();
}
Ok(())
}
/// Grow table by the specified amount of elements.
///
/// Returns the previous size of the table if growth is successful.

View File

@@ -594,6 +594,10 @@ impl VMBuiltinFunctionsArray {
wasmtime_externref_global_get as usize;
ptrs[BuiltinFunctionIndex::externref_global_set().index() as usize] =
wasmtime_externref_global_set as usize;
ptrs[BuiltinFunctionIndex::table_fill_externref().index() as usize] =
wasmtime_table_fill as usize;
ptrs[BuiltinFunctionIndex::table_fill_funcref().index() as usize] =
wasmtime_table_fill as usize;
if cfg!(debug_assertions) {
for i in 0..ptrs.len() {