Skip to content

Commit

Permalink
Sidetable copied to StateData
Browse files Browse the repository at this point in the history
  • Loading branch information
george-cosma committed Jan 31, 2025
1 parent 929a94f commit 2eded64
Show file tree
Hide file tree
Showing 4 changed files with 48 additions and 24 deletions.
5 changes: 4 additions & 1 deletion src/execution/execution_info.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ use alloc::vec::Vec;

use crate::core::reader::types::FuncType;
use crate::core::reader::WasmReader;
use crate::core::sidetable::Sidetable;
use crate::execution::Store;

/// ExecutionInfo is a compilation of relevant information needed by the [interpreter loop](
Expand All @@ -27,13 +28,15 @@ impl ExecutionInfo {
pub struct StateData<'r> {
pub wasm_bytecode: &'r [u8],
pub wasm_reader: WasmReader<'r>,
pub sidetables: Vec<Sidetable>,
}

impl<'r> StateData<'r> {
pub fn new(wasm_bytecode: &'r [u8]) -> Self {
pub fn new(wasm_bytecode: &'r [u8], sidetables: Vec<Sidetable>) -> Self {
StateData {
wasm_bytecode,
wasm_reader: WasmReader::new(wasm_bytecode),
sidetables,
}
}
}
37 changes: 16 additions & 21 deletions src/execution/interpreter_loop.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ use crate::{
core::{
indices::{DataIdx, FuncIdx, GlobalIdx, LabelIdx, LocalIdx, TableIdx, TypeIdx},
reader::{
types::{memarg::MemArg, BlockType, MemType},
types::{memarg::MemArg, BlockType},
WasmReadable, WasmReader,
},
sidetable::Sidetable,
Expand Down Expand Up @@ -60,7 +60,8 @@ pub(super) fn run<H: HookSet>(

// the sidetable and stp for this function, stp will reset to 0 every call
// since function instances have their own sidetable.
let mut current_sidetable: Sidetable = func_inst.sidetable.clone();
let mut current_sidetable: &Sidetable =
&state_data[*current_module_idx].sidetables[stack.current_stackframe().func_idx];
let mut stp = 0;

// unwrap is sound, because the validation assures that the function points to valid subslice of the WASM binary
Expand Down Expand Up @@ -113,15 +114,8 @@ pub(super) fn run<H: HookSet>(
wasm.pc = maybe_return_address;
stp = maybe_return_stp;

current_sidetable = modules[return_module]
.store
.funcs
.get(stack.current_stackframe().func_idx)
.unwrap_validated()
.try_into_local()
.unwrap_validated()
.sidetable
.clone();
current_sidetable =
&state_data[return_module].sidetables[stack.current_stackframe().func_idx];

*current_module_idx = return_module;
}
Expand All @@ -133,19 +127,19 @@ pub(super) fn run<H: HookSet>(
if test_val != 0 {
stp += 1;
} else {
do_sidetable_control_transfer(wasm, stack, &mut stp, &current_sidetable);
do_sidetable_control_transfer(wasm, stack, &mut stp, current_sidetable);
}
}
ELSE => {
do_sidetable_control_transfer(wasm, stack, &mut stp, &current_sidetable);
do_sidetable_control_transfer(wasm, stack, &mut stp, current_sidetable);
}
BR_IF => {
wasm.read_var_u32().unwrap_validated();

let test_val: i32 = stack.pop_value(ValType::NumType(NumType::I32)).into();

if test_val != 0 {
do_sidetable_control_transfer(wasm, stack, &mut stp, &current_sidetable);
do_sidetable_control_transfer(wasm, stack, &mut stp, current_sidetable);
} else {
stp += 1;
}
Expand All @@ -166,19 +160,19 @@ pub(super) fn run<H: HookSet>(
stp += case_val;
}

do_sidetable_control_transfer(wasm, stack, &mut stp, &current_sidetable);
do_sidetable_control_transfer(wasm, stack, &mut stp, current_sidetable);
}
BR => {
//skip n of BR n
wasm.read_var_u32().unwrap_validated();
do_sidetable_control_transfer(wasm, stack, &mut stp, &current_sidetable);
do_sidetable_control_transfer(wasm, stack, &mut stp, current_sidetable);
}
BLOCK | LOOP => {
BlockType::read_unvalidated(wasm);
}
RETURN => {
//same as BR, except no need to skip n of BR n
do_sidetable_control_transfer(wasm, stack, &mut stp, &current_sidetable);
do_sidetable_control_transfer(wasm, stack, &mut stp, current_sidetable);
}
CALL => {
let func_to_call_idx = wasm.read_var_u32().unwrap_validated() as FuncIdx;
Expand Down Expand Up @@ -215,7 +209,8 @@ pub(super) fn run<H: HookSet>(
.unwrap_validated();

stp = 0;
current_sidetable = local_func_inst.sidetable.clone();
current_sidetable =
&state_data[*current_module_idx].sidetables[func_to_call_idx];
}
FuncInst::Imported(_imported_func_inst) => {
let (next_module, next_func_idx) = lut
Expand Down Expand Up @@ -245,7 +240,7 @@ pub(super) fn run<H: HookSet>(
.unwrap_validated();

stp = 0;
current_sidetable = local_func_inst.sidetable.clone();
current_sidetable = &state_data[next_module].sidetables[next_func_idx];
}
}
}
Expand Down Expand Up @@ -315,7 +310,7 @@ pub(super) fn run<H: HookSet>(
.unwrap_validated();

stp = 0;
current_sidetable = local_func_inst.sidetable.clone();
current_sidetable = &state_data[*current_module_idx].sidetables[func_addr];
}
FuncInst::Imported(_imported_func_inst) => {
let (next_module, next_func_idx) = lut
Expand Down Expand Up @@ -347,7 +342,7 @@ pub(super) fn run<H: HookSet>(
.unwrap_validated();

stp = 0;
current_sidetable = local_func_inst.sidetable.clone();
current_sidetable = &state_data[next_module].sidetables[next_func_idx];
}
}
}
Expand Down
28 changes: 27 additions & 1 deletion src/execution/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ use crate::core::reader::types::element::{ElemItems, ElemMode};
use crate::core::reader::types::export::ExportDesc;
use crate::core::reader::types::import::ImportDesc;
use crate::core::reader::WasmReader;
use crate::core::sidetable::Sidetable;
use crate::execution::assert_validated::UnwrapValidatedExt;
use crate::execution::hooks::{EmptyHookSet, HookSet};
use crate::execution::store::{FuncInst, GlobalInst, MemInst, Store};
Expand Down Expand Up @@ -162,7 +163,32 @@ where
self.module_map
.insert(module_name.to_string(), self.modules.len());
self.modules.push(exec_info);
self.state_data.push(StateData::new(&validation_info.wasm));

let local_sidetables = validation_info
.func_blocks
.iter()
.map(|block| block.1.clone());

// In order to be able to index the `sidetables` vec from the
// `StateData` using the function index, we need to insert some blank
// sidetables for the imported functions. An alternative solution
// would've been to offset the indexing, this was just faster to
// implement.
let dummy_sidetables =
validation_info
.imports
.iter()
.filter_map(|import| match &import.desc {
ImportDesc::Func(_type_idx) => Some(Sidetable::new()),
_ => None,
});

let sidetables = dummy_sidetables
.chain(local_sidetables)
.collect::<Vec<Sidetable>>();

self.state_data
.push(StateData::new(validation_info.wasm, sidetables));

self.lut = Lut::new(&self.modules, &self.module_map);

Expand Down
2 changes: 1 addition & 1 deletion src/validation/code.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ pub fn validate_code_section(
num_imported_funcs: usize,
globals: &[Global],
memories: &[MemType],
num_imported_memories: usize,
_num_imported_memories: usize,
data_count: &Option<u32>,
tables: &[TableType],
elements: &[ElemType],
Expand Down

0 comments on commit 2eded64

Please sign in to comment.