Skip to content

Commit

Permalink
Extract out finding a passive segment.
Browse files Browse the repository at this point in the history
This commit extracts out a common pattern of finding a passive element or data
segment into a `find_passive_segment` method.
  • Loading branch information
peterhuene committed Mar 6, 2021
1 parent cb6500a commit f624882
Showing 1 changed file with 32 additions and 28 deletions.
60 changes: 32 additions & 28 deletions crates/runtime/src/instance.rs
Original file line number Diff line number Diff line change
Expand Up @@ -545,6 +545,22 @@ impl Instance {
self.vmctx_plus_offset(self.offsets.vmctx_anyfunc(index))
}

fn find_passive_segment<'a, I, D, T>(
index: I,
index_map: &std::collections::HashMap<I, usize>,
data: &'a Vec<D>,
dropped: &RefCell<EntitySet<I>>,
) -> &'a [T]
where
D: AsRef<[T]>,
I: EntityRef + std::hash::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
/// passive element.
///
Expand All @@ -563,25 +579,17 @@ impl Instance {
// https://webassembly.github.io/bulk-memory-operations/core/exec/instructions.html#exec-table-init

let table = self.get_table(table_index);
let elem_index = self.module.passive_elements_map.get(&elem_index);
let elem = match elem_index {
Some(index) => {
if self
.dropped_elements
.borrow()
.contains(ElemIndex::new(*index))
{
&[]
} else {
self.module.passive_elements[*index].as_ref()
}
}
None => &[],
};

let elements = Self::find_passive_segment(
elem_index,
&self.module.passive_elements_map,
&self.module.passive_elements,
&self.dropped_elements,
);

if src
.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())
{
return Err(Trap::wasm(ir::TrapCode::TableOutOfBounds));
Expand All @@ -590,7 +598,7 @@ impl Instance {
// TODO(#983): investigate replacing this get/set loop with a `memcpy`.
for (dst, src) in (dst..dst + len).zip(src..src + len) {
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| {
f as *const VMCallerCheckedAnyfunc as *mut _
});
Expand Down Expand Up @@ -733,17 +741,13 @@ impl Instance {
// https://webassembly.github.io/bulk-memory-operations/core/exec/instructions.html#exec-memory-init

let memory = self.get_memory(memory_index);
let data_index = self.module.passive_data_map.get(&data_index);
let data = match data_index {
Some(index) => {
if self.dropped_data.borrow().contains(DataIndex::new(*index)) {
&[]
} else {
self.module.passive_data[*index].as_ref()
}
}
None => &[],
};

let data = Self::find_passive_segment(
data_index,
&self.module.passive_data_map,
&self.module.passive_data,
&self.dropped_data,
);

if src
.checked_add(len)
Expand Down

0 comments on commit f624882

Please sign in to comment.