Skip to content

Commit 8c73ec8

Browse files
committed
Accept Into<FunctionType> as aignatures
1 parent ec04581 commit 8c73ec8

File tree

8 files changed

+86
-20
lines changed

8 files changed

+86
-20
lines changed

CHANGELOG.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
* [#1867](https://github.com/wasmerio/wasmer/pull/1867) Added `Metering::get_remaining_points` and `Metering::set_remaining_points`
1313
* [#1881](https://github.com/wasmerio/wasmer/pull/1881) Added `UnsupportedTarget` error to `CompileError`
1414
* [#1908](https://github.com/wasmerio/wasmer/pull/1908) Implemented `TryFrom<Value<T>>` for `i32`/`u32`/`i64`/`u64`/`f32`/`f64`
15-
* Implement `From<([Type; $N], [Type; $M])>` for `FunctionType`
15+
* [#1911](https://github.com/wasmerio/wasmer/pull/1911) Generalized signature type in `Function::new` and `Function::new_with_env` to accept owned and reference `FunctionType` as well as array pairs. This allows users to define signatures as constants. Implemented `From<([Type; $N], [Type; $M])>` for `FunctionType` to support this.
1616

1717
### Changed
1818

lib/api/src/externals/function.rs

+43-6
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ pub struct Function {
6969
impl Function {
7070
/// Creates a new host `Function` (dynamic) with the provided signature.
7171
///
72-
/// # Example
72+
/// # Examples
7373
///
7474
/// ```
7575
/// # use wasmer::{Function, FunctionType, Type, Store, Value};
@@ -82,11 +82,27 @@ impl Function {
8282
/// Ok(vec![Value::I32(sum)])
8383
/// });
8484
/// ```
85+
///
86+
/// With constant signature:
87+
///
88+
/// ```
89+
/// # use wasmer::{Function, FunctionType, Type, Store, Value};
90+
/// # let store = Store::default();
91+
/// #
92+
/// const I32_I32_TO_I32: ([Type; 2], [Type; 1]) = ([Type::I32, Type::I32], [Type::I32]);
93+
///
94+
/// let f = Function::new(&store, I32_I32_TO_I32, |args| {
95+
/// let sum = args[0].unwrap_i32() + args[1].unwrap_i32();
96+
/// Ok(vec![Value::I32(sum)])
97+
/// });
98+
/// ```
8599
#[allow(clippy::cast_ptr_alignment)]
86-
pub fn new<F>(store: &Store, ty: &FunctionType, func: F) -> Self
100+
pub fn new<FT, F>(store: &Store, ty: FT, func: F) -> Self
87101
where
102+
FT: Into<FunctionType>,
88103
F: Fn(&[Val]) -> Result<Vec<Val>, RuntimeError> + 'static,
89104
{
105+
let ty: FunctionType = ty.into();
90106
let dynamic_ctx = VMDynamicFunctionContext::from_context(VMDynamicFunctionWithoutEnv {
91107
func: Box::new(func),
92108
function_type: ty.clone(),
@@ -108,7 +124,7 @@ impl Function {
108124
address,
109125
kind: VMFunctionKind::Dynamic,
110126
vmctx,
111-
signature: ty.clone(),
127+
signature: ty,
112128
call_trampoline: None,
113129
instance_allocator: None,
114130
},
@@ -118,7 +134,7 @@ impl Function {
118134

119135
/// Creates a new host `Function` (dynamic) with the provided signature and environment.
120136
///
121-
/// # Example
137+
/// # Examples
122138
///
123139
/// ```
124140
/// # use wasmer::{Function, FunctionType, Type, Store, Value, WasmerEnv};
@@ -137,12 +153,33 @@ impl Function {
137153
/// Ok(vec![Value::I32(result)])
138154
/// });
139155
/// ```
156+
///
157+
/// With constant signature:
158+
///
159+
/// ```
160+
/// # use wasmer::{Function, FunctionType, Type, Store, Value, WasmerEnv};
161+
/// # let store = Store::default();
162+
/// const I32_I32_TO_I32: ([Type; 2], [Type; 1]) = ([Type::I32, Type::I32], [Type::I32]);
163+
///
164+
/// #[derive(WasmerEnv)]
165+
/// struct Env {
166+
/// multiplier: i32,
167+
/// };
168+
/// let env = Env { multiplier: 2 };
169+
///
170+
/// let f = Function::new_with_env(&store, I32_I32_TO_I32, env, |env, args| {
171+
/// let result = env.multiplier * (args[0].unwrap_i32() + args[1].unwrap_i32());
172+
/// Ok(vec![Value::I32(result)])
173+
/// });
174+
/// ```
140175
#[allow(clippy::cast_ptr_alignment)]
141-
pub fn new_with_env<F, Env>(store: &Store, ty: &FunctionType, env: Env, func: F) -> Self
176+
pub fn new_with_env<FT, F, Env>(store: &Store, ty: FT, env: Env, func: F) -> Self
142177
where
178+
FT: Into<FunctionType>,
143179
F: Fn(&Env, &[Val]) -> Result<Vec<Val>, RuntimeError> + 'static,
144180
Env: Sized + WasmerEnv + 'static,
145181
{
182+
let ty: FunctionType = ty.into();
146183
let dynamic_ctx = VMDynamicFunctionContext::from_context(VMDynamicFunctionWithEnv {
147184
env: Box::new(env),
148185
func: Box::new(func),
@@ -171,7 +208,7 @@ impl Function {
171208
address,
172209
kind: VMFunctionKind::Dynamic,
173210
vmctx,
174-
signature: ty.clone(),
211+
signature: ty,
175212
call_trampoline: None,
176213
instance_allocator: None,
177214
},

lib/api/tests/externals.rs

+22
Original file line numberDiff line numberDiff line change
@@ -250,6 +250,8 @@ fn function_new_env() -> Result<()> {
250250
#[test]
251251
fn function_new_dynamic() -> Result<()> {
252252
let store = Store::default();
253+
254+
// Using &FunctionType signature
253255
let function_type = FunctionType::new(vec![], vec![]);
254256
let function = Function::new(&store, &function_type, |_values: &[Value]| unimplemented!());
255257
assert_eq!(function.ty().clone(), function_type);
@@ -265,6 +267,13 @@ fn function_new_dynamic() -> Result<()> {
265267
let function_type = FunctionType::new(vec![], vec![Type::I32, Type::I64, Type::F32, Type::F64]);
266268
let function = Function::new(&store, &function_type, |_values: &[Value]| unimplemented!());
267269
assert_eq!(function.ty().clone(), function_type);
270+
271+
// Using array signature
272+
let function_type = ([Type::V128], [Type::I32, Type::F32, Type::F64]);
273+
let function = Function::new(&store, function_type, |_values: &[Value]| unimplemented!());
274+
assert_eq!(function.ty().params(), [Type::V128]);
275+
assert_eq!(function.ty().results(), [Type::I32, Type::F32, Type::F64]);
276+
268277
Ok(())
269278
}
270279

@@ -275,6 +284,7 @@ fn function_new_dynamic_env() -> Result<()> {
275284
struct MyEnv {};
276285
let my_env = MyEnv {};
277286

287+
// Using &FunctionType signature
278288
let function_type = FunctionType::new(vec![], vec![]);
279289
let function = Function::new_with_env(
280290
&store,
@@ -315,6 +325,18 @@ fn function_new_dynamic_env() -> Result<()> {
315325
|_env: &MyEnv, _values: &[Value]| unimplemented!(),
316326
);
317327
assert_eq!(function.ty().clone(), function_type);
328+
329+
// Using array signature
330+
let function_type = ([Type::V128], [Type::I32, Type::F32, Type::F64]);
331+
let function = Function::new_with_env(
332+
&store,
333+
function_type,
334+
my_env.clone(),
335+
|_env: &MyEnv, _values: &[Value]| unimplemented!(),
336+
);
337+
assert_eq!(function.ty().params(), [Type::V128]);
338+
assert_eq!(function.ty().results(), [Type::I32, Type::F32, Type::F64]);
339+
318340
Ok(())
319341
}
320342

lib/deprecated/runtime-core/src/typed_func.rs

+1
Original file line numberDiff line numberDiff line change
@@ -265,6 +265,7 @@ impl DynamicFunc {
265265

266266
Self {
267267
new_function: new::wasmer::Function::new_with_env::<
268+
_,
268269
fn(&DynamicCtx, &[Value]) -> Result<Vec<Value>, RuntimeError>,
269270
DynamicCtx,
270271
>(&get_global_store(), signature, ctx, inner),

lib/wasi/src/lib.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -132,7 +132,7 @@ fn get_path_open_for_store(store: &Store, env: WasiEnv) -> Function {
132132
#[cfg(all(target_os = "macos", target_arch = "aarch64",))]
133133
let path_open = Function::new_with_env(
134134
store,
135-
&FunctionType::new(
135+
FunctionType::new(
136136
vec![
137137
ValType::I32,
138138
ValType::I32,

lib/wasmer-types/src/types.rs

+6
Original file line numberDiff line numberDiff line change
@@ -303,6 +303,12 @@ implement_from_pair_to_functiontype! {
303303
9,0 9,1 9,2 9,3 9,4 9,5 9,6 9,7 9,8 9,9
304304
}
305305

306+
impl From<&FunctionType> for FunctionType {
307+
fn from(as_ref: &FunctionType) -> Self {
308+
as_ref.clone()
309+
}
310+
}
311+
306312
/// Indicator of whether a global is mutable or not
307313
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
308314
#[cfg_attr(feature = "enable-serde", derive(Serialize, Deserialize))]

tests/compilers/imports.rs

+9-9
Original file line numberDiff line numberDiff line change
@@ -52,22 +52,22 @@ fn dynamic_function() -> Result<()> {
5252
&module,
5353
&imports! {
5454
"host" => {
55-
"0" => Function::new(&store, &FunctionType::new(vec![], vec![]), |_values| {
55+
"0" => Function::new(&store, FunctionType::new(vec![], vec![]), |_values| {
5656
assert_eq!(HITS.fetch_add(1, SeqCst), 0);
5757
Ok(vec![])
5858
}),
59-
"1" => Function::new(&store, &FunctionType::new(vec![ValType::I32], vec![ValType::I32]), |values| {
59+
"1" => Function::new(&store, FunctionType::new(vec![ValType::I32], vec![ValType::I32]), |values| {
6060
assert_eq!(values[0], Value::I32(0));
6161
assert_eq!(HITS.fetch_add(1, SeqCst), 1);
6262
Ok(vec![Value::I32(1)])
6363
}),
64-
"2" => Function::new(&store, &FunctionType::new(vec![ValType::I32, ValType::I64], vec![]), |values| {
64+
"2" => Function::new(&store, FunctionType::new(vec![ValType::I32, ValType::I64], vec![]), |values| {
6565
assert_eq!(values[0], Value::I32(2));
6666
assert_eq!(values[1], Value::I64(3));
6767
assert_eq!(HITS.fetch_add(1, SeqCst), 2);
6868
Ok(vec![])
6969
}),
70-
"3" => Function::new(&store, &FunctionType::new(vec![ValType::I32, ValType::I64, ValType::I32, ValType::F32, ValType::F64], vec![]), |values| {
70+
"3" => Function::new(&store, FunctionType::new(vec![ValType::I32, ValType::I64, ValType::I32, ValType::F32, ValType::F64], vec![]), |values| {
7171
assert_eq!(values[0], Value::I32(100));
7272
assert_eq!(values[1], Value::I64(200));
7373
assert_eq!(values[2], Value::I32(300));
@@ -107,22 +107,22 @@ fn dynamic_function_with_env() -> Result<()> {
107107
&module,
108108
&imports! {
109109
"host" => {
110-
"0" => Function::new_with_env(&store, &FunctionType::new(vec![], vec![]), env.clone(), |env, _values| {
110+
"0" => Function::new_with_env(&store, FunctionType::new(vec![], vec![]), env.clone(), |env, _values| {
111111
assert_eq!(env.fetch_add(1, SeqCst), 0);
112112
Ok(vec![])
113113
}),
114-
"1" => Function::new_with_env(&store, &FunctionType::new(vec![ValType::I32], vec![ValType::I32]), env.clone(), |env, values| {
114+
"1" => Function::new_with_env(&store, FunctionType::new(vec![ValType::I32], vec![ValType::I32]), env.clone(), |env, values| {
115115
assert_eq!(values[0], Value::I32(0));
116116
assert_eq!(env.fetch_add(1, SeqCst), 1);
117117
Ok(vec![Value::I32(1)])
118118
}),
119-
"2" => Function::new_with_env(&store, &FunctionType::new(vec![ValType::I32, ValType::I64], vec![]), env.clone(), |env, values| {
119+
"2" => Function::new_with_env(&store, FunctionType::new(vec![ValType::I32, ValType::I64], vec![]), env.clone(), |env, values| {
120120
assert_eq!(values[0], Value::I32(2));
121121
assert_eq!(values[1], Value::I64(3));
122122
assert_eq!(env.fetch_add(1, SeqCst), 2);
123123
Ok(vec![])
124124
}),
125-
"3" => Function::new_with_env(&store, &FunctionType::new(vec![ValType::I32, ValType::I64, ValType::I32, ValType::F32, ValType::F64], vec![]), env.clone(), |env, values| {
125+
"3" => Function::new_with_env(&store, FunctionType::new(vec![ValType::I32, ValType::I64, ValType::I32, ValType::F32, ValType::F64], vec![]), env.clone(), |env, values| {
126126
assert_eq!(values[0], Value::I32(100));
127127
assert_eq!(values[1], Value::I64(200));
128128
assert_eq!(values[2], Value::I32(300));
@@ -332,7 +332,7 @@ fn dynamic_function_with_env_wasmer_env_init_works() -> Result<()> {
332332
&module,
333333
&imports! {
334334
"host" => {
335-
"fn" => Function::new_with_env(&store, &FunctionType::new(vec![], vec![]), env.clone(), |env, _values| {
335+
"fn" => Function::new_with_env(&store, FunctionType::new(vec![], vec![]), env.clone(), |env, _values| {
336336
assert!(env.memory_ref().is_some());
337337
Ok(vec![])
338338
}),

tests/compilers/native_functions.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -225,7 +225,7 @@ fn native_function_works_for_wasm_function_manyparams_dynamic() -> Result<()> {
225225

226226
let import_object = imports! {
227227
"env" => {
228-
"longf" => Function::new(&store, &FunctionType::new(vec![ValType::I32, ValType::I32, ValType::I32, ValType::I32, ValType::I32, ValType::I32, ValType::I64 , ValType::I64 ,ValType::I32, ValType::I32], vec![ValType::I64]), long_f_dynamic),
228+
"longf" => Function::new(&store, FunctionType::new(vec![ValType::I32, ValType::I32, ValType::I32, ValType::I32, ValType::I32, ValType::I32, ValType::I64 , ValType::I64 ,ValType::I32, ValType::I32], vec![ValType::I64]), long_f_dynamic),
229229
},
230230
};
231231

@@ -377,7 +377,7 @@ fn dynamic_host_function_without_env() -> anyhow::Result<()> {
377377

378378
let f = Function::new(
379379
&store,
380-
&FunctionType::new(
380+
FunctionType::new(
381381
vec![ValType::I32, ValType::I64, ValType::F32, ValType::F64],
382382
vec![ValType::F64, ValType::F32, ValType::I64, ValType::I32],
383383
),
@@ -415,7 +415,7 @@ fn dynamic_host_function_with_env() -> anyhow::Result<()> {
415415
let env = Env(Rc::new(RefCell::new(100)));
416416
let f = Function::new_with_env(
417417
&store,
418-
&FunctionType::new(
418+
FunctionType::new(
419419
vec![ValType::I32, ValType::I64, ValType::F32, ValType::F64],
420420
vec![ValType::F64, ValType::F32, ValType::I64, ValType::I32],
421421
),

0 commit comments

Comments
 (0)