Skip to content

Commit a277cf5

Browse files
authored
Store WasmFuncType in FuncType (#2365)
This commit updates `wasmtime::FuncType` to exactly store an internal `WasmFuncType` from the cranelift crates. This allows us to remove a translation layer when we are given a `FuncType` and want to get an internal cranelift type out as a result. The other major change from this commit was changing the constructor and accessors of `FuncType` to be iterator-based instead of exposing implementation details.
1 parent ea3306e commit a277cf5

File tree

13 files changed

+118
-150
lines changed

13 files changed

+118
-150
lines changed

crates/c-api/src/types/func.rs

Lines changed: 3 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -54,17 +54,9 @@ pub extern "C" fn wasm_functype_new(
5454
params: &mut wasm_valtype_vec_t,
5555
results: &mut wasm_valtype_vec_t,
5656
) -> Box<wasm_functype_t> {
57-
let params = params
58-
.take()
59-
.into_iter()
60-
.map(|vt| vt.unwrap().ty.clone())
61-
.collect::<Vec<_>>();
62-
let results = results
63-
.take()
64-
.into_iter()
65-
.map(|vt| vt.unwrap().ty.clone())
66-
.collect::<Vec<_>>();
67-
let functype = FuncType::new(params.into_boxed_slice(), results.into_boxed_slice());
57+
let params = params.take().into_iter().map(|vt| vt.unwrap().ty.clone());
58+
let results = results.take().into_iter().map(|vt| vt.unwrap().ty.clone());
59+
let functype = FuncType::new(params, results);
6860
Box::new(wasm_functype_t::new(functype))
6961
}
7062

@@ -74,7 +66,6 @@ pub extern "C" fn wasm_functype_params(ft: &wasm_functype_t) -> &wasm_valtype_ve
7466
ft.params_cache.get_or_init(|| {
7567
ft.ty
7668
.params()
77-
.iter()
7869
.map(|p| Some(Box::new(wasm_valtype_t { ty: p.clone() })))
7970
.collect::<Vec<_>>()
8071
.into()
@@ -87,7 +78,6 @@ pub extern "C" fn wasm_functype_results(ft: &wasm_functype_t) -> &wasm_valtype_v
8778
ft.returns_cache.get_or_init(|| {
8879
ft.ty
8980
.results()
90-
.iter()
9181
.map(|p| Some(Box::new(wasm_valtype_t { ty: p.clone() })))
9282
.collect::<Vec<_>>()
9383
.into()

crates/fuzzing/src/oracles/dummy.rs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -25,15 +25,15 @@ pub fn dummy_imports<'module>(
2525
/// Construct a dummy function for the given function type
2626
pub fn dummy_func(store: &Store, ty: FuncType) -> Func {
2727
Func::new(store, ty.clone(), move |_, _, results| {
28-
for (ret_ty, result) in ty.results().iter().zip(results) {
28+
for (ret_ty, result) in ty.results().zip(results) {
2929
*result = dummy_value(ret_ty)?;
3030
}
3131
Ok(())
3232
})
3333
}
3434

3535
/// Construct a dummy value for the given value type.
36-
pub fn dummy_value(val_ty: &ValType) -> Result<Val, Trap> {
36+
pub fn dummy_value(val_ty: ValType) -> Result<Val, Trap> {
3737
Ok(match val_ty {
3838
ValType::I32 => Val::I32(0),
3939
ValType::I64 => Val::I64(0),
@@ -58,19 +58,19 @@ pub fn dummy_value(val_ty: &ValType) -> Result<Val, Trap> {
5858
}
5959

6060
/// Construct a sequence of dummy values for the given types.
61-
pub fn dummy_values(val_tys: &[ValType]) -> Result<Vec<Val>, Trap> {
62-
val_tys.iter().map(dummy_value).collect()
61+
pub fn dummy_values(val_tys: impl IntoIterator<Item = ValType>) -> Result<Vec<Val>, Trap> {
62+
val_tys.into_iter().map(dummy_value).collect()
6363
}
6464

6565
/// Construct a dummy global for the given global type.
6666
pub fn dummy_global(store: &Store, ty: GlobalType) -> Result<Global, Trap> {
67-
let val = dummy_value(ty.content())?;
67+
let val = dummy_value(ty.content().clone())?;
6868
Ok(Global::new(store, ty, val).unwrap())
6969
}
7070

7171
/// Construct a dummy table for the given table type.
7272
pub fn dummy_table(store: &Store, ty: TableType) -> Result<Table, Trap> {
73-
let init_val = dummy_value(&ty.element())?;
73+
let init_val = dummy_value(ty.element().clone())?;
7474
Ok(Table::new(store, ty, init_val).unwrap())
7575
}
7676

crates/wasmtime/src/func.rs

Lines changed: 40 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -113,8 +113,8 @@ use wasmtime_runtime::{
113113
/// // Here we need to define the type signature of our `Double` function and
114114
/// // then wrap it up in a `Func`
115115
/// let double_type = wasmtime::FuncType::new(
116-
/// Box::new([wasmtime::ValType::I32]),
117-
/// Box::new([wasmtime::ValType::I32])
116+
/// [wasmtime::ValType::I32].iter().cloned(),
117+
/// [wasmtime::ValType::I32].iter().cloned(),
118118
/// );
119119
/// let double = Func::new(&store, double_type, |_, params, results| {
120120
/// let mut value = params[0].unwrap_i32();
@@ -163,7 +163,7 @@ macro_rules! getters {
163163
// Verify all the paramers match the expected parameters, and that
164164
// there are no extra parameters...
165165
let ty = self.ty();
166-
let mut params = ty.params().iter().cloned();
166+
let mut params = ty.params();
167167
let n = 0;
168168
$(
169169
let n = n + 1;
@@ -173,7 +173,7 @@ macro_rules! getters {
173173
ensure!(params.next().is_none(), "Type mismatch: too many arguments (expected {})", n);
174174

175175
// ... then do the same for the results...
176-
let mut results = ty.results().iter().cloned();
176+
let mut results = ty.results();
177177
R::matches(&mut results)
178178
.context("Type mismatch in return type")?;
179179
ensure!(results.next().is_none(), "Type mismatch: too many return values (expected 1)");
@@ -274,7 +274,7 @@ impl Func {
274274
let mut args: SmallVec<[Val; STACK_ARGS]> =
275275
SmallVec::with_capacity(ty_clone.params().len());
276276
let store = Store::upgrade(&store_weak).unwrap();
277-
for (i, ty) in ty_clone.params().iter().enumerate() {
277+
for (i, ty) in ty_clone.params().enumerate() {
278278
unsafe {
279279
let val = Val::read_value_from(&store, values_vec.add(i), ty);
280280
args.push(val);
@@ -298,7 +298,7 @@ impl Func {
298298
// produces the wrong number or wrong types of values, and we need
299299
// to catch that here.
300300
for (i, (ret, ty)) in returns.into_iter().zip(ty_clone.results()).enumerate() {
301-
if ret.ty() != *ty {
301+
if ret.ty() != ty {
302302
return Err(Trap::new(
303303
"function attempted to return an incompatible value",
304304
));
@@ -596,9 +596,9 @@ impl Func {
596596
let mut values_vec = vec![0; max(params.len(), my_ty.results().len())];
597597

598598
// Store the argument values into `values_vec`.
599-
let param_tys = my_ty.params().iter();
599+
let param_tys = my_ty.params();
600600
for ((arg, slot), ty) in params.iter().cloned().zip(&mut values_vec).zip(param_tys) {
601-
if arg.ty() != *ty {
601+
if arg.ty() != ty {
602602
bail!(
603603
"argument type mismatch: found {} but expected {}",
604604
arg.ty(),
@@ -628,7 +628,7 @@ impl Func {
628628

629629
// Load the return values out of `values_vec`.
630630
let mut results = Vec::with_capacity(my_ty.results().len());
631-
for (index, ty) in my_ty.results().iter().enumerate() {
631+
for (index, ty) in my_ty.results().enumerate() {
632632
unsafe {
633633
let ptr = values_vec.as_ptr().add(index);
634634
results.push(Val::read_value_from(&self.instance.store, ptr, ty));
@@ -876,7 +876,7 @@ pub unsafe trait WasmTy {
876876

877877
// Add this type to the given vec of expected valtypes.
878878
#[doc(hidden)]
879-
fn push(dst: &mut Vec<ValType>);
879+
fn valtype() -> Option<ValType>;
880880

881881
// Does the next valtype(s) match this type?
882882
#[doc(hidden)]
@@ -923,7 +923,7 @@ pub unsafe trait WasmRet {
923923

924924
// Same as `WasmTy::push`.
925925
#[doc(hidden)]
926-
fn push(dst: &mut Vec<ValType>);
926+
fn valtype() -> Option<ValType>;
927927

928928
// Same as `WasmTy::matches`.
929929
#[doc(hidden)]
@@ -952,7 +952,9 @@ unsafe impl WasmTy for () {
952952
#[inline]
953953
unsafe fn from_abi<'a>(_abi: Self::Abi, _store: WeakStore<'a>) -> Self {}
954954

955-
fn push(_dst: &mut Vec<ValType>) {}
955+
fn valtype() -> Option<ValType> {
956+
None
957+
}
956958

957959
fn matches(_tys: impl Iterator<Item = ValType>) -> anyhow::Result<()> {
958960
Ok(())
@@ -983,8 +985,8 @@ unsafe impl WasmTy for i32 {
983985
abi
984986
}
985987

986-
fn push(dst: &mut Vec<ValType>) {
987-
dst.push(ValType::I32);
988+
fn valtype() -> Option<ValType> {
989+
Some(ValType::I32)
988990
}
989991

990992
fn matches(mut tys: impl Iterator<Item = ValType>) -> anyhow::Result<()> {
@@ -1028,8 +1030,8 @@ unsafe impl WasmTy for u32 {
10281030
abi as Self
10291031
}
10301032

1031-
fn push(dst: &mut Vec<ValType>) {
1032-
<i32 as WasmTy>::push(dst)
1033+
fn valtype() -> Option<ValType> {
1034+
<i32 as WasmTy>::valtype()
10331035
}
10341036

10351037
fn matches(tys: impl Iterator<Item = ValType>) -> anyhow::Result<()> {
@@ -1065,8 +1067,8 @@ unsafe impl WasmTy for i64 {
10651067
abi
10661068
}
10671069

1068-
fn push(dst: &mut Vec<ValType>) {
1069-
dst.push(ValType::I64);
1070+
fn valtype() -> Option<ValType> {
1071+
Some(ValType::I64)
10701072
}
10711073

10721074
fn matches(mut tys: impl Iterator<Item = ValType>) -> anyhow::Result<()> {
@@ -1110,8 +1112,8 @@ unsafe impl WasmTy for u64 {
11101112
abi as Self
11111113
}
11121114

1113-
fn push(dst: &mut Vec<ValType>) {
1114-
<i64 as WasmTy>::push(dst)
1115+
fn valtype() -> Option<ValType> {
1116+
<i64 as WasmTy>::valtype()
11151117
}
11161118

11171119
fn matches(tys: impl Iterator<Item = ValType>) -> anyhow::Result<()> {
@@ -1147,8 +1149,8 @@ unsafe impl WasmTy for f32 {
11471149
abi
11481150
}
11491151

1150-
fn push(dst: &mut Vec<ValType>) {
1151-
dst.push(ValType::F32);
1152+
fn valtype() -> Option<ValType> {
1153+
Some(ValType::F32)
11521154
}
11531155

11541156
fn matches(mut tys: impl Iterator<Item = ValType>) -> anyhow::Result<()> {
@@ -1192,8 +1194,8 @@ unsafe impl WasmTy for f64 {
11921194
abi
11931195
}
11941196

1195-
fn push(dst: &mut Vec<ValType>) {
1196-
dst.push(ValType::F64);
1197+
fn valtype() -> Option<ValType> {
1198+
Some(ValType::F64)
11971199
}
11981200

11991201
fn matches(mut tys: impl Iterator<Item = ValType>) -> anyhow::Result<()> {
@@ -1254,8 +1256,8 @@ unsafe impl WasmTy for Option<ExternRef> {
12541256
}
12551257
}
12561258

1257-
fn push(dst: &mut Vec<ValType>) {
1258-
dst.push(ValType::ExternRef);
1259+
fn valtype() -> Option<ValType> {
1260+
Some(ValType::ExternRef)
12591261
}
12601262

12611263
fn matches(mut tys: impl Iterator<Item = ValType>) -> anyhow::Result<()> {
@@ -1307,8 +1309,8 @@ unsafe impl WasmTy for Option<Func> {
13071309
Func::from_caller_checked_anyfunc(&store, abi)
13081310
}
13091311

1310-
fn push(dst: &mut Vec<ValType>) {
1311-
dst.push(ValType::FuncRef);
1312+
fn valtype() -> Option<ValType> {
1313+
Some(ValType::FuncRef)
13121314
}
13131315

13141316
fn matches(mut tys: impl Iterator<Item = ValType>) -> anyhow::Result<()> {
@@ -1353,9 +1355,8 @@ where
13531355
<Self as WasmTy>::from_abi(abi, store)
13541356
}
13551357

1356-
#[inline]
1357-
fn push(dst: &mut Vec<ValType>) {
1358-
<Self as WasmTy>::push(dst)
1358+
fn valtype() -> Option<ValType> {
1359+
<Self as WasmTy>::valtype()
13591360
}
13601361

13611362
#[inline]
@@ -1405,8 +1406,8 @@ where
14051406
Ok(<T as WasmTy>::from_abi(abi, store))
14061407
}
14071408

1408-
fn push(dst: &mut Vec<ValType>) {
1409-
<T as WasmTy>::push(dst)
1409+
fn valtype() -> Option<ValType> {
1410+
<T as WasmTy>::valtype()
14101411
}
14111412

14121413
fn matches(tys: impl Iterator<Item = ValType>) -> anyhow::Result<()> {
@@ -1657,11 +1658,12 @@ macro_rules! impl_into_func {
16571658
R::store_to_args(ret, args);
16581659
}
16591660

1660-
let mut _args = Vec::new();
1661-
$($args::push(&mut _args);)*
1662-
let mut ret = Vec::new();
1663-
R::push(&mut ret);
1664-
let ty = FuncType::new(_args.into(), ret.into());
1661+
let ty = FuncType::new(
1662+
None::<ValType>.into_iter()
1663+
$(.chain($args::valtype()))*
1664+
,
1665+
R::valtype(),
1666+
);
16651667

16661668
let store_weak = store.weak();
16671669
let trampoline = host_trampoline::<$($args,)* R>;

crates/wasmtime/src/linker.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -716,7 +716,7 @@ impl Linker {
716716
// Otherwise return a no-op function.
717717
Ok(Func::new(
718718
&self.store,
719-
FuncType::new(Vec::new().into_boxed_slice(), Vec::new().into_boxed_slice()),
719+
FuncType::new(None, None),
720720
move |_, _, _| Ok(()),
721721
))
722722
}

crates/wasmtime/src/trampoline/func.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -214,7 +214,7 @@ pub fn create_handle_with_function(
214214

215215
let pointer_type = isa.pointer_type();
216216
let sig = ft.get_wasmtime_signature(pointer_type);
217-
let wft = ft.to_wasm_func_type();
217+
let wft = ft.as_wasm_func_type();
218218

219219
let mut fn_builder_ctx = FunctionBuilderContext::new();
220220
let mut module = Module::new();
@@ -241,7 +241,7 @@ pub fn create_handle_with_function(
241241
&sig,
242242
mem::size_of::<u128>(),
243243
)?;
244-
store.signatures().borrow_mut().register(&wft, trampoline);
244+
store.signatures().borrow_mut().register(wft, trampoline);
245245

246246
// Next up we wrap everything up into an `InstanceHandle` by publishing our
247247
// code memory (makes it executable) and ensuring all our various bits of
@@ -265,7 +265,7 @@ pub unsafe fn create_handle_with_raw_function(
265265
store: &Store,
266266
state: Box<dyn Any>,
267267
) -> Result<StoreInstanceHandle> {
268-
let wft = ft.to_wasm_func_type();
268+
let wft = ft.as_wasm_func_type();
269269

270270
let mut module = Module::new();
271271
let mut finished_functions = PrimaryMap::new();
@@ -276,7 +276,7 @@ pub unsafe fn create_handle_with_raw_function(
276276
.exports
277277
.insert(String::new(), EntityIndex::Function(func_id));
278278
finished_functions.push(func);
279-
store.signatures().borrow_mut().register(&wft, trampoline);
279+
store.signatures().borrow_mut().register(wft, trampoline);
280280

281281
create_handle(module, store, finished_functions, state, &[])
282282
}

0 commit comments

Comments
 (0)