@@ -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,
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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() {
|
||||
|
||||
Reference in New Issue
Block a user