Extract out finding a passive segment.

This commit extracts out a common pattern of finding a passive element or data
segment into a `find_passive_segment` method.
This commit is contained in:
Peter Huene
2021-03-05 21:15:19 -08:00
parent 57dfe99aa5
commit 8e51aefb2c

View File

@@ -19,7 +19,9 @@ use more_asserts::assert_lt;
use std::alloc::Layout; use std::alloc::Layout;
use std::any::Any; use std::any::Any;
use std::cell::RefCell; use std::cell::RefCell;
use std::collections::HashMap;
use std::convert::TryFrom; use std::convert::TryFrom;
use std::hash::Hash;
use std::ptr::NonNull; use std::ptr::NonNull;
use std::rc::Rc; use std::rc::Rc;
use std::sync::Arc; use std::sync::Arc;
@@ -545,6 +547,22 @@ impl Instance {
self.vmctx_plus_offset(self.offsets.vmctx_anyfunc(index)) self.vmctx_plus_offset(self.offsets.vmctx_anyfunc(index))
} }
fn find_passive_segment<'a, I, D, T>(
index: I,
index_map: &HashMap<I, usize>,
data: &'a Vec<D>,
dropped: &RefCell<EntitySet<I>>,
) -> &'a [T]
where
D: AsRef<[T]>,
I: EntityRef + Hash,
{
match index_map.get(&index) {
Some(index) if !dropped.borrow().contains(I::new(*index)) => data[*index].as_ref(),
_ => &[],
}
}
/// The `table.init` operation: initializes a portion of a table with a /// The `table.init` operation: initializes a portion of a table with a
/// passive element. /// passive element.
/// ///
@@ -563,25 +581,17 @@ impl Instance {
// https://webassembly.github.io/bulk-memory-operations/core/exec/instructions.html#exec-table-init // https://webassembly.github.io/bulk-memory-operations/core/exec/instructions.html#exec-table-init
let table = self.get_table(table_index); let table = self.get_table(table_index);
let elem_index = self.module.passive_elements_map.get(&elem_index);
let elem = match elem_index { let elements = Self::find_passive_segment(
Some(index) => { elem_index,
if self &self.module.passive_elements_map,
.dropped_elements &self.module.passive_elements,
.borrow() &self.dropped_elements,
.contains(ElemIndex::new(*index)) );
{
&[]
} else {
self.module.passive_elements[*index].as_ref()
}
}
None => &[],
};
if src if src
.checked_add(len) .checked_add(len)
.map_or(true, |n| n as usize > elem.len()) .map_or(true, |n| n as usize > elements.len())
|| dst.checked_add(len).map_or(true, |m| m > table.size()) || dst.checked_add(len).map_or(true, |m| m > table.size())
{ {
return Err(Trap::wasm(ir::TrapCode::TableOutOfBounds)); return Err(Trap::wasm(ir::TrapCode::TableOutOfBounds));
@@ -590,7 +600,7 @@ impl Instance {
// TODO(#983): investigate replacing this get/set loop with a `memcpy`. // TODO(#983): investigate replacing this get/set loop with a `memcpy`.
for (dst, src) in (dst..dst + len).zip(src..src + len) { for (dst, src) in (dst..dst + len).zip(src..src + len) {
let elem = self let elem = self
.get_caller_checked_anyfunc(elem[src as usize]) .get_caller_checked_anyfunc(elements[src as usize])
.map_or(ptr::null_mut(), |f: &VMCallerCheckedAnyfunc| { .map_or(ptr::null_mut(), |f: &VMCallerCheckedAnyfunc| {
f as *const VMCallerCheckedAnyfunc as *mut _ f as *const VMCallerCheckedAnyfunc as *mut _
}); });
@@ -733,17 +743,13 @@ impl Instance {
// https://webassembly.github.io/bulk-memory-operations/core/exec/instructions.html#exec-memory-init // https://webassembly.github.io/bulk-memory-operations/core/exec/instructions.html#exec-memory-init
let memory = self.get_memory(memory_index); let memory = self.get_memory(memory_index);
let data_index = self.module.passive_data_map.get(&data_index);
let data = match data_index { let data = Self::find_passive_segment(
Some(index) => { data_index,
if self.dropped_data.borrow().contains(DataIndex::new(*index)) { &self.module.passive_data_map,
&[] &self.module.passive_data,
} else { &self.dropped_data,
self.module.passive_data[*index].as_ref() );
}
}
None => &[],
};
if src if src
.checked_add(len) .checked_add(len)