Skip to content

Commit 4c3139c

Browse files
refactor: move interop to separate crate
Signed-off-by: Florian Hartung <florian.hartung@dlr.de>
1 parent badec30 commit 4c3139c

File tree

21 files changed

+258
-213
lines changed

21 files changed

+258
-213
lines changed

Cargo.lock

Lines changed: 10 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,15 @@ members = [
44
"crates/benchmark",
55
"crates/checked",
66
"crates/compare-testsuite-rs",
7+
"crates/interop",
78
"crates/linker",
89
"crates/log_wrapper",
910
]
1011
resolver = "2"
1112

1213
[workspace.dependencies]
1314
checked = { path = "crates/checked" }
15+
interop = { path = "crates/interop" }
1416
linker = { path = "crates/linker" }
1517
wasm-interpreter = { path = "." }
1618

@@ -46,7 +48,8 @@ libm = "=0.2.8"
4648
log_wrapper.path = "crates/log_wrapper"
4749

4850
[dev-dependencies]
49-
checked = { workspace = true, features = ["linker"] }
51+
checked = { workspace = true, features = ["linker", "interop"] }
52+
interop.workspace = true
5053

5154
bumpalo = "3.17.0"
5255
env_logger = { workspace = true }

crates/benchmark/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ criterion = { version = "0.5.1", default-features = false, features = [
99
"cargo_bench_support",
1010
"plotters",
1111
] }
12+
interop.workspace = true
1213
wasm-interpreter = { path = "../..", default-features = false }
1314
wasmi = "0.40.0"
1415
wasmtime = { version = "27.0.0", default-features = false, features = [

crates/benchmark/benches/general_purpose.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ use criterion::{
55
Throughput,
66
};
77

8+
use interop::StoreTypedInvocationExt;
89
use wasm::{validate, Store};
910

1011
macro_rules! bench_wasm {

crates/checked/Cargo.toml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,9 @@ rust-version = "1.87.0" # Keep this in sync with the requirements!
66

77
[dependencies]
88
wasm-interpreter.workspace = true
9+
interop = { workspace = true, optional = true }
910
linker = { workspace = true, optional = true }
1011

1112
[features]
1213
# linker
13-
# TODO: interop
14+
# interop

crates/checked/src/interop.rs

Lines changed: 64 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,13 @@
11
use alloc::{fmt::Debug, vec, vec::Vec};
2+
use interop::{InteropValueList, RefExtern, StoreTypedInvocationExt};
23
use wasm::{
34
addrs::FuncAddr,
4-
interop::RefExtern,
5+
config::Config,
56
value::{ValueTypeMismatchError, F32, F64},
6-
NumType, RefType, ValType,
7+
HaltExecutionError, NumType, RefType, RuntimeError, ValType, Value,
78
};
89

9-
use crate::{stored_types::Stored, StoredRef, StoredValue};
10+
use crate::{stored_types::Stored, AbstractStored, Store, StoredRef, StoredValue};
1011

1112
/// A stored variant of [`InteropValue`](crate::execution::interop::InteropValue)
1213
pub trait StoredInteropValue
@@ -251,3 +252,63 @@ where
251252
))
252253
}
253254
}
255+
256+
impl<T: Config> Store<'_, T> {
257+
/// This is a safer variant of [`Store::func_alloc_typed_unchecked`](crate::Store::func_alloc_typed_unchecked). It is
258+
/// functionally equal, with the only difference being that this function
259+
/// returns a [`Stored<FuncAddr>`].
260+
///
261+
/// # Safety
262+
///
263+
/// The caller has to guarantee that if the [`Value`]s returned from the
264+
/// given host function are references, their addresses came either from the
265+
/// host function arguments or from the current [`Store`] object.
266+
///
267+
/// See: [`Store::func_alloc_typed_unchecked`](crate::Store::func_alloc_typed_unchecked) for more information.
268+
#[allow(clippy::let_and_return)] // reason = "to follow the 1234 structure"
269+
pub unsafe fn func_alloc_typed<Params: InteropValueList, Returns: InteropValueList>(
270+
&mut self,
271+
host_func: fn(&mut T, Vec<Value>) -> Result<Vec<Value>, HaltExecutionError>,
272+
) -> Stored<FuncAddr> {
273+
// 1. try unwrap
274+
// no stored parameters
275+
// 2. call
276+
// SAFETY: The caller ensures that if the host function returns
277+
// references, they originate either from the arguments or the current
278+
// store.
279+
let func_addr = unsafe {
280+
self.inner
281+
.func_alloc_typed_unchecked::<Params, Returns>(host_func)
282+
};
283+
// 3. rewrap
284+
// 4. return
285+
// SAFETY: The function address just came from the current store.
286+
unsafe { Stored::from_bare(func_addr, self.id) }
287+
}
288+
289+
/// This is a safe variant of [`Store::invoke_typed_without_fuel_unchecked`](crate::Store::invoke_typed_without_fuel_unchecked).
290+
pub fn invoke_typed_without_fuel<
291+
Params: StoredInteropValueList,
292+
Returns: StoredInteropValueList,
293+
>(
294+
&mut self,
295+
function: Stored<FuncAddr>,
296+
params: Params,
297+
) -> Result<Returns, RuntimeError> {
298+
// 1. try unwrap
299+
let function = function.try_unwrap_into_bare(self.id);
300+
let params = params.into_values().try_unwrap_into_bare(self.id);
301+
// 2. call
302+
// SAFETY: It was just checked that the `FuncAddr` and any addresses
303+
// contained in the parameters came from the current store through their
304+
// store ids.
305+
let returns = unsafe { self.inner.invoke_without_fuel_unchecked(function, params) }?;
306+
// 3. rewrap
307+
// SAFETY: All `Value`s just came from the current store.
308+
let stored_returns = unsafe { Vec::from_bare(returns, self.id) };
309+
// 4. return
310+
let stored_returns = Returns::try_from_values(stored_returns.into_iter())
311+
.map_err(|_| RuntimeError::FunctionInvocationSignatureMismatch)?;
312+
Ok(stored_returns)
313+
}
314+
}

crates/checked/src/lib.rs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,16 +32,19 @@ use core::sync::atomic::{AtomicU64, Ordering};
3232

3333
use alloc::vec::Vec;
3434

35-
mod interop;
3635
mod store;
3736
mod stored_types;
3837
mod value;
3938

40-
pub use interop::*;
4139
pub use store::*;
4240
pub use stored_types::*;
4341
pub use value::*;
4442

43+
#[cfg(feature = "interop")]
44+
mod interop;
45+
#[cfg(feature = "interop")]
46+
pub use interop::*;
47+
4548
#[cfg(feature = "linker")]
4649
mod linker;
4750
#[cfg(feature = "linker")]

crates/checked/src/store.rs

Lines changed: 1 addition & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,14 @@ use alloc::{string::String, vec::Vec};
22
use wasm::{
33
addrs::{FuncAddr, GlobalAddr, MemAddr, ModuleAddr, TableAddr},
44
config::Config,
5-
interop::InteropValueList,
65
resumable::Resumable,
76
FuncType, GlobalType, HaltExecutionError, MemType, RuntimeError, TableType, ValidationInfo,
87
Value,
98
};
109

1110
use crate::{
1211
stored_types::{Stored, StoredExternVal, StoredInstantiationOutcome, StoredRunState},
13-
AbstractStored, StoreId, StoredInteropValueList, StoredRef, StoredValue,
12+
AbstractStored, StoreId, StoredRef, StoredValue,
1413
};
1514

1615
pub struct Store<'b, T: Config> {
@@ -442,38 +441,6 @@ impl<'b, T: Config> Store<'b, T> {
442441
Ok(stored_run_state)
443442
}
444443

445-
/// This is a safer variant of [`Store::func_alloc_typed_unchecked`](crate::Store::func_alloc_typed_unchecked). It is
446-
/// functionally equal, with the only difference being that this function
447-
/// returns a [`Stored<FuncAddr>`].
448-
///
449-
/// # Safety
450-
///
451-
/// The caller has to guarantee that if the [`Value`]s returned from the
452-
/// given host function are references, their addresses came either from the
453-
/// host function arguments or from the current [`Store`] object.
454-
///
455-
/// See: [`Store::func_alloc_typed_unchecked`](crate::Store::func_alloc_typed_unchecked) for more information.
456-
#[allow(clippy::let_and_return)] // reason = "to follow the 1234 structure"
457-
pub unsafe fn func_alloc_typed<Params: InteropValueList, Returns: InteropValueList>(
458-
&mut self,
459-
host_func: fn(&mut T, Vec<Value>) -> Result<Vec<Value>, HaltExecutionError>,
460-
) -> Stored<FuncAddr> {
461-
// 1. try unwrap
462-
// no stored parameters
463-
// 2. call
464-
// SAFETY: The caller ensures that if the host function returns
465-
// references, they originate either from the arguments or the current
466-
// store.
467-
let func_addr = unsafe {
468-
self.inner
469-
.func_alloc_typed_unchecked::<Params, Returns>(host_func)
470-
};
471-
// 3. rewrap
472-
// 4. return
473-
// SAFETY: The function address just came from the current store.
474-
unsafe { Stored::from_bare(func_addr, self.id) }
475-
}
476-
477444
/// This is a safe variant of [`Store::invoke_without_fuel_unchecked`](crate::Store::invoke_without_fuel_unchecked).
478445
pub fn invoke_without_fuel(
479446
&mut self,
@@ -495,32 +462,6 @@ impl<'b, T: Config> Store<'b, T> {
495462
Ok(returns)
496463
}
497464

498-
/// This is a safe variant of [`Store::invoke_typed_without_fuel_unchecked`](crate::Store::invoke_typed_without_fuel_unchecked).
499-
pub fn invoke_typed_without_fuel<
500-
Params: StoredInteropValueList,
501-
Returns: StoredInteropValueList,
502-
>(
503-
&mut self,
504-
function: Stored<FuncAddr>,
505-
params: Params,
506-
) -> Result<Returns, RuntimeError> {
507-
// 1. try unwrap
508-
let function = function.try_unwrap_into_bare(self.id);
509-
let params = params.into_values().try_unwrap_into_bare(self.id);
510-
// 2. call
511-
// SAFETY: It was just checked that the `FuncAddr` and any addresses
512-
// contained in the parameters came from the current store through their
513-
// store ids.
514-
let returns = unsafe { self.inner.invoke_without_fuel_unchecked(function, params) }?;
515-
// 3. rewrap
516-
// SAFETY: All `Value`s just came from the current store.
517-
let stored_returns = unsafe { Vec::from_bare(returns, self.id) };
518-
// 4. return
519-
let stored_returns = Returns::try_from_values(stored_returns.into_iter())
520-
.map_err(|_| RuntimeError::FunctionInvocationSignatureMismatch)?;
521-
Ok(stored_returns)
522-
}
523-
524465
/// This is a safe variant of [`Store::mem_access_mut_slice_unchecked`](crate::Store::mem_access_mut_slice_unchecked).
525466
pub fn mem_access_mut_slice<R>(
526467
&self,

crates/interop/Cargo.toml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
[package]
2+
name = "interop"
3+
version = "0.2.0"
4+
edition = "2024"
5+
6+
[dependencies]
7+
wasm-interpreter.workspace = true

crates/interop/README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
# Interoperation between Rust and Wasm types

0 commit comments

Comments
 (0)