Skip to content

Commit f07578b

Browse files
chore: refactor FunctionInstance
Signed-off-by: Henry <mail@henrygressmann.de>
1 parent 80cf746 commit f07578b

6 files changed

Lines changed: 62 additions & 66 deletions

File tree

‎crates/tinywasm/src/func.rs‎

Lines changed: 18 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use crate::interpreter::stack::CallFrame;
22
use crate::reference::StoreItem;
3-
use crate::{Error, FunctionDef, InterpreterRuntime, Result, Store, unlikely};
3+
use crate::{Error, FunctionInstance, InterpreterRuntime, Result, Store, unlikely};
44
use alloc::rc::Rc;
55
use alloc::{boxed::Box, format, string::ToString, vec, vec::Vec};
66
use tinywasm_types::{ExternRef, FuncRef, FuncType, ModuleInstanceAddr, ValType, WasmValue};
@@ -14,20 +14,19 @@ impl Function {
1414
self.item.validate_store(store)?;
1515
validate_call_params(&self.ty, params)?;
1616

17-
let func_inst = store.state.get_func(self.addr);
18-
let wasm_func = match &func_inst.func {
19-
FunctionDef::Host(host_func) => {
17+
let wasm_func = match store.state.get_func(self.addr) {
18+
FunctionInstance::Host(host_func) => {
2019
return host_func.clone().call(FuncContext { store, module_addr: self.module_addr }, params);
2120
}
22-
FunctionDef::Wasm(wasm_func) => wasm_func.clone(),
21+
FunctionInstance::Wasm(wasm_func) => wasm_func,
2322
};
2423

2524
// Reset stack, push args, allocate locals, create entry frame.
2625
store.stack.clear();
2726
store.stack.values.extend_from_wasmvalues(params)?;
28-
let locals_base = store.stack.values.enter_locals(&wasm_func.params, &wasm_func.locals)?;
29-
let stack_offset = wasm_func.locals;
30-
let callframe = CallFrame::new(self.addr, func_inst.owner, locals_base, stack_offset);
27+
let locals_base = store.stack.values.enter_locals(&wasm_func.func.params, &wasm_func.func.locals)?;
28+
let stack_offset = wasm_func.func.locals;
29+
let callframe = CallFrame::new(self.addr, wasm_func.owner, locals_base, stack_offset);
3130

3231
// Execute until completion and then collect result values from the stack.
3332
InterpreterRuntime::exec(store, callframe)?;
@@ -48,21 +47,17 @@ impl Function {
4847
self.item.validate_store(store)?;
4948
validate_call_params(&self.ty, params)?;
5049

51-
let func_inst = store.state.get_func(self.addr);
52-
let func_inst_owner = func_inst.owner;
53-
let func = func_inst.func.clone();
54-
55-
match func {
56-
FunctionDef::Host(host_func) => {
57-
let result = host_func.call(FuncContext { store, module_addr: self.module_addr }, params)?;
50+
match store.state.get_func(self.addr) {
51+
FunctionInstance::Host(host_func) => {
52+
let result = host_func.clone().call(FuncContext { store, module_addr: self.module_addr }, params)?;
5853
Ok(FuncExecution { store, state: FuncExecutionState::Completed { result: Some(result) } })
5954
}
60-
FunctionDef::Wasm(wasm_func) => {
55+
FunctionInstance::Wasm(wasm_func) => {
6156
store.stack.clear();
6257
store.stack.values.extend_from_wasmvalues(params)?;
63-
let locals_base = store.stack.values.enter_locals(&wasm_func.params, &wasm_func.locals)?;
64-
let stack_offset = wasm_func.locals;
65-
let callframe = CallFrame::new(self.addr, func_inst_owner, locals_base, stack_offset);
58+
let locals_base = store.stack.values.enter_locals(&wasm_func.func.params, &wasm_func.func.locals)?;
59+
let stack_offset = wasm_func.func.locals;
60+
let callframe = CallFrame::new(self.addr, wasm_func.owner, locals_base, stack_offset);
6661

6762
Ok(FuncExecution {
6863
store,
@@ -151,7 +146,7 @@ impl HostFunction {
151146
Ok(result)
152147
};
153148

154-
let addr = store.add_func(FunctionDef::Host(Rc::new(Self { func: Box::new(inner_func), ty: ty.clone() })), 0);
149+
let addr = store.add_func(FunctionInstance::Host(Rc::new(Self { func: Box::new(inner_func), ty: ty.clone() })));
155150
Function { item: crate::StoreItem::new(store.id(), addr), module_addr: 0, addr, ty: ty.clone() }
156151
}
157152

@@ -169,7 +164,7 @@ impl HostFunction {
169164

170165
let results = R::val_types();
171166
let ty = tinywasm_types::FuncType { params: P::val_types(), results };
172-
let addr = store.add_func(FunctionDef::Host(Rc::new(Self { func: Box::new(inner_func), ty: ty.clone() })), 0);
167+
let addr = store.add_func(FunctionInstance::Host(Rc::new(Self { func: Box::new(inner_func), ty: ty.clone() })));
173168
Function { item: crate::StoreItem::new(store.id(), addr), module_addr: 0, addr, ty }
174169
}
175170
}
@@ -317,7 +312,7 @@ impl<'store> FuncExecution<'store> {
317312

318313
match InterpreterRuntime::exec_with_fuel(self.store, exec_state.callframe, fuel)? {
319314
crate::interpreter::ExecState::Completed => {
320-
let result_ty = self.store.state.get_func(*root_func_addr).func.ty().clone();
315+
let result_ty = self.store.state.get_func(*root_func_addr).ty().clone();
321316
let result = collect_call_results(self.store, &result_ty)?;
322317
self.state = FuncExecutionState::Completed { result: None };
323318
Ok(ExecProgress::Completed(result))
@@ -354,7 +349,7 @@ impl<'store> FuncExecution<'store> {
354349

355350
match InterpreterRuntime::exec_with_time_budget(self.store, exec_state.callframe, time_budget)? {
356351
crate::interpreter::ExecState::Completed => {
357-
let result_ty = self.store.state.get_func(*root_func_addr).func.ty().clone();
352+
let result_ty = self.store.state.get_func(*root_func_addr).ty().clone();
358353
let result = collect_call_results(self.store, &result_ty)?;
359354
self.state = FuncExecutionState::Completed { result: None };
360355
Ok(ExecProgress::Completed(result))

‎crates/tinywasm/src/imports.rs‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -339,7 +339,7 @@ impl Imports {
339339
.get(*ty as usize)
340340
.ok_or_else(|| LinkingError::incompatible_import_type(import))?;
341341

342-
Self::compare_types(import, func.func.ty(), import_func_type)?;
342+
Self::compare_types(import, func.ty(), import_func_type)?;
343343
imports.funcs.push(func_addr);
344344
}
345345
_ => return Err(LinkingError::incompatible_import_type(import).into()),

‎crates/tinywasm/src/instance.rs‎

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -273,7 +273,7 @@ impl ModuleInstance {
273273
return Err(Error::Other(format!("Export is not a function: {name}")));
274274
};
275275

276-
let ty = store.state.get_func(func_addr).func.ty();
276+
let ty = store.state.get_func(func_addr).ty();
277277
Ok(Function {
278278
item: crate::StoreItem::new(self.0.store_id, func_addr),
279279
addr: func_addr,
@@ -294,7 +294,7 @@ impl ModuleInstance {
294294
self.validate_store(store)?;
295295
let func_addr = Self::index_addr(&self.0.func_addrs, func_index, "function")?;
296296

297-
let ty = store.state.get_func(func_addr).func.ty();
297+
let ty = store.state.get_func(func_addr).ty();
298298
Ok(Function {
299299
item: crate::StoreItem::new(self.0.store_id, func_addr),
300300
addr: func_addr,
@@ -437,7 +437,7 @@ impl ModuleInstance {
437437
};
438438

439439
let func_addr = self.0.resolve_func_addr(func_index);
440-
let ty = store.state.get_func(func_addr).func.ty();
440+
let ty = store.state.get_func(func_addr).ty();
441441
Ok(Some(Function {
442442
item: crate::StoreItem::new(self.0.store_id, func_addr),
443443
module_addr: self.id(),

‎crates/tinywasm/src/interpreter/executor.rs‎

Lines changed: 15 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -710,21 +710,20 @@ impl<'store, const BUDGETED: bool> Executor<'store, BUDGETED> {
710710

711711
fn exec_call<const IS_RETURN_CALL: bool>(
712712
&mut self,
713-
wasm_func: Rc<WasmFunction>,
713+
wasm_func: WasmFunctionInstance,
714714
func_addr: FuncAddr,
715-
owner: ModuleInstanceAddr,
716715
) -> Result<()> {
717-
if !Rc::ptr_eq(&self.func, &wasm_func) {
718-
self.func = wasm_func.clone();
716+
if !Rc::ptr_eq(&self.func, &wasm_func.func) {
717+
self.func = wasm_func.func.clone();
719718
}
720719

721720
if IS_RETURN_CALL {
722-
self.store.stack.values.truncate_keep_counts(self.cf.locals_base, wasm_func.params);
721+
self.store.stack.values.truncate_keep_counts(self.cf.locals_base, wasm_func.func.params);
723722
}
724723

725-
let res = self.store.stack.values.enter_locals(&wasm_func.params, &wasm_func.locals);
724+
let res = self.store.stack.values.enter_locals(&wasm_func.func.params, &wasm_func.func.locals);
726725
let locals_base = res.map_err(|err| if IS_RETURN_CALL { err } else { Error::Trap(Trap::CallStackOverflow) })?;
727-
let new_call_frame = CallFrame::new(func_addr, owner, locals_base, wasm_func.locals);
726+
let new_call_frame = CallFrame::new(func_addr, wasm_func.owner, locals_base, wasm_func.func.locals);
728727

729728
if !IS_RETURN_CALL {
730729
self.cf.incr_instr_ptr(); // skip the call instruction
@@ -748,12 +747,9 @@ impl<'store, const BUDGETED: bool> Executor<'store, BUDGETED> {
748747
fn exec_call_direct<const IS_RETURN_CALL: bool>(&mut self, v: u32) -> Result<()> {
749748
self.charge_call_fuel(FUEL_COST_CALL_TOTAL);
750749
let addr = self.module.resolve_func_addr(v);
751-
let func_inst = self.store.state.get_func(addr);
752-
match &func_inst.func {
753-
crate::FunctionDef::Wasm(wasm_func) => {
754-
self.exec_call::<IS_RETURN_CALL>(wasm_func.clone(), addr, func_inst.owner)
755-
}
756-
crate::FunctionDef::Host(host_func) => self.exec_call_host(host_func.clone()),
750+
match self.store.state.get_func(addr) {
751+
crate::FunctionInstance::Wasm(wasm_func) => self.exec_call::<IS_RETURN_CALL>(wasm_func.clone(), addr),
752+
crate::FunctionInstance::Host(host_func) => self.exec_call_host(host_func.clone()),
757753
}
758754
}
759755

@@ -790,22 +786,20 @@ impl<'store, const BUDGETED: bool> Executor<'store, BUDGETED> {
790786
table.addr().ok_or_else(|| Error::from(Trap::UninitializedElement { index: table_idx as usize }))?
791787
};
792788

793-
let func_inst = self.store.state.get_func(func_ref);
794789
let call_ty = self.module.func_ty(type_addr);
795-
796-
match &func_inst.func {
797-
crate::FunctionDef::Wasm(wasm_func) => {
798-
if wasm_func.ty != *call_ty {
790+
match self.store.state.get_func(func_ref) {
791+
crate::FunctionInstance::Wasm(wasm_func) => {
792+
if wasm_func.ty() != call_ty {
799793
return Err(Trap::IndirectCallTypeMismatch {
800-
actual: wasm_func.ty.clone(),
794+
actual: wasm_func.ty().clone(),
801795
expected: call_ty.clone(),
802796
}
803797
.into());
804798
}
805799

806-
self.exec_call::<IS_RETURN_CALL>(wasm_func.clone(), func_ref, func_inst.owner)
800+
self.exec_call::<IS_RETURN_CALL>(wasm_func.clone(), func_ref)
807801
}
808-
crate::FunctionDef::Host(host_func) => {
802+
crate::FunctionInstance::Host(host_func) => {
809803
if host_func.ty != *call_ty {
810804
return Err(Trap::IndirectCallTypeMismatch {
811805
actual: host_func.ty.clone(),

‎crates/tinywasm/src/store/function.rs‎

Lines changed: 20 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -8,33 +8,40 @@ use crate::func::HostFunction;
88
/// See <https://webassembly.github.io/spec/core/exec/runtime.html#function-instances>
99
#[derive(Clone)]
1010
#[cfg_attr(feature = "debug", derive(Debug))]
11-
pub(crate) struct FunctionInstance {
12-
pub(crate) func: FunctionDef,
13-
pub(crate) owner: ModuleInstanceAddr, // index into store.module_instances, none for host functions
14-
}
15-
16-
/// The internal representation of a function
17-
#[derive(Clone)]
18-
#[cfg_attr(feature = "debug", derive(Debug))]
19-
pub(crate) enum FunctionDef {
11+
pub(crate) enum FunctionInstance {
2012
/// A host function
2113
Host(Rc<HostFunction>),
2214

2315
/// A pointer to a WebAssembly function
24-
Wasm(Rc<WasmFunction>),
16+
Wasm(WasmFunctionInstance),
2517
}
2618

27-
impl FunctionDef {
19+
impl FunctionInstance {
20+
#[inline]
2821
pub(crate) fn ty(&self) -> &FuncType {
2922
match self {
3023
Self::Host(f) => &f.ty,
31-
Self::Wasm(f) => &f.ty,
24+
Self::Wasm(f) => f.ty(),
3225
}
3326
}
3427
}
3528

3629
impl FunctionInstance {
3730
pub(crate) fn new_wasm(func: WasmFunction, owner: ModuleInstanceAddr) -> Self {
38-
Self { func: FunctionDef::Wasm(Rc::new(func)), owner }
31+
Self::Wasm(WasmFunctionInstance { func: Rc::new(func), owner })
32+
}
33+
}
34+
35+
#[derive(Clone)]
36+
#[cfg_attr(feature = "debug", derive(Debug))]
37+
pub(crate) struct WasmFunctionInstance {
38+
pub(crate) func: Rc<WasmFunction>,
39+
pub(crate) owner: ModuleInstanceAddr,
40+
}
41+
42+
impl WasmFunctionInstance {
43+
#[inline]
44+
pub(crate) fn ty(&self) -> &FuncType {
45+
&self.func.ty
3946
}
4047
}

‎crates/tinywasm/src/store/mod.rs‎

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -117,9 +117,9 @@ impl State {
117117
/// Get a wasm function at the actual index in the store, panicking if it's a host function (which should be guaranteed by the validator)
118118
pub(crate) fn get_wasm_func(&self, addr: FuncAddr) -> &Rc<WasmFunction> {
119119
match self.funcs.get(addr as usize) {
120-
Some(func) => match &func.func {
121-
FunctionDef::Wasm(wasm_func) => wasm_func,
122-
FunctionDef::Host(_) => unreachable!(
120+
Some(func) => match func {
121+
FunctionInstance::Wasm(wasm_func) => &wasm_func.func,
122+
FunctionInstance::Host(_) => unreachable!(
123123
"expected a wasm function at address {addr}, but found a host function. This should be unreachable"
124124
),
125125
},
@@ -423,8 +423,8 @@ impl Store {
423423
Ok((data_addrs.into_boxed_slice(), None))
424424
}
425425

426-
pub(crate) fn add_func(&mut self, func: FunctionDef, idx: ModuleInstanceAddr) -> FuncAddr {
427-
self.state.funcs.push(FunctionInstance { func, owner: idx });
426+
pub(crate) fn add_func(&mut self, func: FunctionInstance) -> FuncAddr {
427+
self.state.funcs.push(func);
428428
self.state.funcs.len() as FuncAddr - 1
429429
}
430430

0 commit comments

Comments
 (0)