clearloop opened Issue #2578:
Desc
Here I'm trying to define the
HostFuncType<T>
below as extern functions inwasmtime
, but I don't know how to handle the&mut T
pub type HostFuncType<T> = fn(&mut T, &[Value]) -> Result<ReturnValue, HostError>;
It might be possible using
ExternRef<Arc<RefCell<T>>>
instead to do something like this, but if there is any solution can pass the&mut T
without get/set memory directly?
clearloop edited Issue #2578:
Desc
Here I'm trying to define the
HostFuncType<T>
below as extern functions inwasmtime
, but I don't know how to handle the&mut T
pub type HostFuncType<T> = fn(&mut T, &[Value]) -> Result<ReturnValue, HostError>;
It might be possible using
ExternRef<Arc<RefCell<T>>>
instead to do something like this, but if there is any solution can pass the&mut T
without get/set memory directly?
clearloop edited Issue #2578:
Desc
Here I'm trying to define the
HostFuncType<T>
below as extern functions inwasmtime
, but I don't know how to handle the&mut T
pub type HostFuncType<T> = fn(&mut T, &[Value]) -> Result<ReturnValue, HostError>;
It might be possible using
ExternRef<Arc<RefCell<T>>>
instead to do something like this, but if there is any solution can pass the&mut T
without breaking the arguments of theHostFuncType<T>
or get/set memory directly?
clearloop edited Issue #2578:
Desc
Here I'm trying to define the
HostFuncType<T>
below as extern functions inwasmtime
, but I don't know how to handle the&mut T
pub type HostFuncType<T> = fn(&mut T, &[Value]) -> Result<ReturnValue, HostError>;
It might be possible using
ExternRef<Arc<RefCell<T>>>
instead of doing something like this, but if there is any solution can pass the&mut T
without breaking the arguments of theHostFuncType<T>
or get/set memory directly?
clearloop edited Issue #2578:
Desc
Here I'm trying to define the
HostFuncType<T>
below as extern functions inwasmtime
, but I don't know how to handle the&mut T
pub type HostFuncType<T> = fn(&mut T, &[Value]) -> Result<ReturnValue, HostError>;
It might be possible using
ExternRef<Arc<RefCell<T>>>
instead of doing something like this, but if there is any solution can pass the&mut T
without breaking the arguments of theHostFuncType<T>
?
alexcrichton commented on Issue #2578:
Thanks for the report! Can you clarify what you're trying to do, however? Host functions are generally defined with the
Func
type, which should have a number of examples on it as well. Are you unsure on how to create aFunc
, though?
clearloop commented on Issue #2578:
Thanks for your relying @alexcrichton ~
Thanks for the report! Can you clarify what you're trying to do, however? Host functions are generally defined with the
Func
type, which should have a number of examples on it as well. Are you unsure on how to create aFunc
, though?Yep, I'm trying to implement a
Func
like:fn my_host_func<T>(state: &mut T, args: &[val]) {} fn main() -> Result<()> { // ... let my_extern_host_func = Func::wrap(&store, |state: &mut T, args: &[Val]| { my_host_func(state, args); }); let instance = Instance::new(&store, &module, &[my_extern_host_func.into()])?; //... Ok(()) }
alexcrichton commented on Issue #2578:
When using
&[Val]
you'll want to useFunc::new
, andstate: &mut T
can't be given to you from wasm, so it can't be a parameter in the closure passed toFunc::wrap
. What you can do, however, is close over thestate
in the closure you provide toFunc::wrap
. If you need mutable access you'll need to use something likeRefCell
to account for the possibility that your closure is invoked recursively.
clearloop edited a comment on Issue #2578:
Thanks for your relying @alexcrichton ~
Thanks for the report! Can you clarify what you're trying to do, however? Host functions are generally defined with the
Func
type, which should have a number of examples on it as well. Are you unsure on how to create aFunc
, though?Yep, I'm trying to implement a
Func
like:fn my_host_func<T>(state: &mut T, args: &[val]) {} fn main() -> Result<()> { // ... let my_extern_host_func = Func::wrap(&store, |state: &mut T, args: &[Val]| { my_host_func(state, args); }); let instance = Instance::new(&store, &module, &[my_extern_host_func.into()])?; //... Ok(()) }
I can handle this in
wasmi
easily because theinvoke
methods of functions inwasmi
always comes withexternal: &mut T
:pub fn invoke<T: Externals>( func: &FuncRef, args: &[RuntimeValue], externals: &mut T, ) -> Result<Option<RuntimeValue>, Trap> { check_function_args(func.signature(), &args)?; match *func.as_internal() { FuncInstanceInternal::Internal { .. } => { let mut interpreter = Interpreter::new(func, args, None)?; interpreter.start_execution(externals) } FuncInstanceInternal::Host { ref host_func_index, .. } => externals.invoke_index(*host_func_index, args.into()), } }
clearloop commented on Issue #2578:
When using
&[Val]
you'll want to useFunc::new
, andstate: &mut T
can't be given to you from wasm, so it can't be a parameter in the closure passed toFunc::wrap
. What you can do, however, is close over thestate
in the closure you provide toFunc::wrap
. If you need mutable access you'll need to use something likeRefCell
to account for the possibility that your closure is invoked recursively.Thanks!
At least I'm certain about I can't pass
state
as a parameter now, I'll try to movestate
into the closure, afraid of not usingstate
as a parameter, functions implemented in wasm could not recognize the signature of the host functions.I'll do more practice and close this issue as I implement it.
Ref to https://github.com/bytecodealliance/wasmtime/issues/1678
clearloop commented on Issue #2578:
Is there any example of making a function with
&[Val]
as parameters into aFunc
?
clearloop edited a comment on Issue #2578:
Is there any example of making a function with&[Val]
as parameters into aFunc
?
clearloop edited a comment on Issue #2578:
Is there any example of making a function with
&[Val]
as parameters into aFunc
?
clearloop edited a comment on Issue #2578:
Is there any example of converting a function with
&[Val]
as parameters into aFunc
?
clearloop edited a comment on Issue #2578:
Is there any example of converting a function with
&[Val]
as parameters into aFunc
without usingFunc::new
?
clearloop edited a comment on Issue #2578:
Is there any example of converting a function with
&[Val]
as parameters into aFunc
without usingFunc::new
? Just find thatFunc::new
requiresFn
which can not use variables from the environment.
clearloop edited a comment on Issue #2578:
Is there any example of converting a function with
&[Val]
as parameters into aFunc
? Just find that bothFunc::new
andFunc::wrap
requireFn
which can not use variables from the environment. How could I move theRefCell<T>
into closure?
clearloop edited a comment on Issue #2578:
Is there any example of converting a function with
&[Val]
as parameters into aFunc
? Just find that bothFunc::new
andFunc::wrap
require'static
which can not move variables from the environment easily.
clearloop edited a comment on Issue #2578:
Is there any example of converting a function with
&[Val]
as parameters into aFunc
? Just find that bothFunc::new
andFunc::wrap
require'static
which can not move variables from the environment easily.Could
Store
offer a generic type filed for holding the state of host functions?
clearloop edited a comment on Issue #2578:
Is there any example of converting a function with
&[Val]
as parameters into aFunc
? Just find that bothFunc::new
andFunc::wrap
require'static
which can not move variables from the environment easily.Could
Store
offer a generic type field for holding the state of host functions?
clearloop edited a comment on Issue #2578:
Is there any example of converting a function with
&[Val]
as parameters into aFunc
? Just find that bothFunc::new
andFunc::wrap
require'static
which can not move variables from the environment into them easily.Could
Store
offer a generic type field for holding the state of host functions?
clearloop edited a comment on Issue #2578:
Is there any example of converting a function with
&[Val]
as parameters into aFunc
? Just find that bothFunc::new
andFunc::wrap
require'static
which can not move variables from the environment into them easily.error[E0525]: expected a closure that implements the `Fn` trait, but this closure only implements `FnOnce` --> primitives/sandbox/src/imp/wasmtime/util.rs:67:13 | 67 | let func = move |_: Caller<'_>, args: &[Val], results: &mut [Val]| { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ this closure implements `FnOnce`, not `Fn` ... 77 | match unsafe { f(state, &inner_args) } { | ----- closure is `FnOnce` because it moves the variable `state` out of its environment ... 89 | Func::new(store, wasmtime_sig(sig), func) | --------- the requirement to implement `Fn` derives from here
Could
Store
offer a generic type field for holding the state of host functions?
clearloop edited a comment on Issue #2578:
pub type HostFuncTypeA<T> = fn(RefCell<T>, &[Value]) -> Result<ReturnValue, crate::HostError>; pub fn wrap_fn_test<T>( store: &Store, state: RefCell<T>, f: HostFuncTypeA<T>, sig: FunctionType, ) -> Func { // let state_mut = state as *mut T; let func = move |_: Caller<'_>, args: &[Val], results: &mut [Val]| { let mut inner_args = vec![]; for arg in args { if let Some(arg) = from_val(arg.clone()) { inner_args.push(arg); } else { return Err(Trap::new("Could not wrap host function")); } } match unsafe { f(state, &inner_args) } { Ok(ret) => { if let Some(ret) = from_ret_val(ret) { results = &mut [ret]; } Ok(()) } Err(_) => Err(Trap::new("Could not wrap host function")), } // return Err(Trap::new("Could not wrap host function")); }; Func::new(store, wasmtime_sig(sig), func) }
Is there any example of converting a function with
&[Val]
as parameters into aFunc
? Just find that bothFunc::new
andFunc::wrap
require'static
which can not move variables from the environment into them easily.error[E0525]: expected a closure that implements the `Fn` trait, but this closure only implements `FnOnce` --> primitives/sandbox/src/imp/wasmtime/util.rs:67:13 | 67 | let func = move |_: Caller<'_>, args: &[Val], results: &mut [Val]| { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ this closure implements `FnOnce`, not `Fn` ... 77 | match unsafe { f(state, &inner_args) } { | ----- closure is `FnOnce` because it moves the variable `state` out of its environment ... 89 | Func::new(store, wasmtime_sig(sig), func) | --------- the requirement to implement `Fn` derives from here
Could
Store
offer a generic type field for holding the state of host functions?
clearloop edited a comment on Issue #2578:
pub type HostFuncTypeA<T> = fn(RefCell<T>, &[Value]) -> Result<ReturnValue, crate::HostError>; pub fn wrap_fn_test<T>( store: &Store, state: RefCell<T>, f: HostFuncTypeA<T>, sig: FunctionType, ) -> Func { // let state_mut = state as *mut T; let func = move |_: Caller<'_>, args: &[Val], results: &mut [Val]| { let mut inner_args = vec![]; for arg in args { if let Some(arg) = from_val(arg.clone()) { inner_args.push(arg); } else { return Err(Trap::new("Could not wrap host function")); } } match unsafe { f(state, &inner_args) } { Ok(ret) => { if let Some(ret) = from_ret_val(ret) { results = &mut [ret]; } Ok(()) } Err(_) => Err(Trap::new("Could not wrap host function")), } // return Err(Trap::new("Could not wrap host function")); }; Func::new(store, wasmtime_sig(sig), func) }
Is there any example of converting a function with
&[Val]
as parameters into aFunc
? Just find that bothFunc::new
andFunc::wrap
require'static
which can not move variables from the environment into them easily.error[E0525]: expected a closure that implements the `Fn` trait, but this closure only implements `FnOnce` --> primitives/sandbox/src/imp/wasmtime/util.rs:67:13 | 67 | let func = move |_: Caller<'_>, args: &[Val], results: &mut [Val]| { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ this closure implements `FnOnce`, not `Fn` ... 77 | match unsafe { f(state, &inner_args) } { | ----- closure is `FnOnce` because it moves the variable `state` out of its environment ... 89 | Func::new(store, wasmtime_sig(sig), func) | --------- the requirement to implement `Fn` derives from here
or some errors like
error[E0310]: the parameter type `T` may not live l [message truncated]
alexcrichton commented on Issue #2578:
In tthis case
HostFuncTypeA
will need to take&RefCell<T>
, not a by-value version.
clearloop commented on Issue #2578:
In tthis case
HostFuncTypeA
will need to take&RefCell<T>
, not a by-value version.error[E0621]: explicit lifetime required in the type of `state` --> primitives/sandbox/src/imp/wasmtime/util.rs:93:2 | 66 | state: &RefCell<T>, | ----------- help: add explicit lifetime `'static` to the type of `state`: `&'static RefCell<T>` ... 93 | Func::new(store, wasmtime_sig(sig), func) | ^^^^^^^^^ lifetime `'static` required error: aborting due to previous error
If use
&RefCell
, it will require'static
, I'm not sure if this situation is possible, not sure about if I have to add'static
toT
.
clearloop edited a comment on Issue #2578:
In this case
HostFuncTypeA
will need to take&RefCell<T>
, not a by-value version.error[E0621]: explicit lifetime required in the type of `state` --> primitives/sandbox/src/imp/wasmtime/util.rs:93:2 | 66 | state: &RefCell<T>, | ----------- help: add explicit lifetime `'static` to the type of `state`: `&'static RefCell<T>` ... 93 | Func::new(store, wasmtime_sig(sig), func) | ^^^^^^^^^ lifetime `'static` required error: aborting due to previous error
If using
&RefCell
, it will require'static
, I'm not sure if this situation is possible, not sure about if I have to add'static
toT
.Thanks for your reply @alexcrichton~ I know there might be some problems in my implementation, I just can't figure out how to make it work, I have stuck at this point for 1 week then : (
clearloop edited a comment on Issue #2578:
In this case
HostFuncTypeA
will need to take&RefCell<T>
, not a by-value version.error[E0621]: explicit lifetime required in the type of `state` --> primitives/sandbox/src/imp/wasmtime/util.rs:93:2 | 66 | state: &RefCell<T>, | ----------- help: add explicit lifetime `'static` to the type of `state`: `&'static RefCell<T>` ... 93 | Func::new(store, wasmtime_sig(sig), func) | ^^^^^^^^^ lifetime `'static` required error: aborting due to previous error
If using
&RefCell
, it will require'static
, I'm not sure if this situation is possible, not sure about if I have to add'static
toT
.Thanks for your reply @alexcrichton~ I know there might be some problems in my implementation, I just can't figure out how to make it work, I have stuck at this point for 1 week then : (
pub type HostFuncTypeA<T> = fn(&RefCell<T>, &[Value]) -> Result<ReturnValue, crate::HostError>; pub fn wrap_fn_test<T>( store: &Store, state: &'static RefCell<T>, f: HostFuncTypeA<T>, sig: FunctionType, ) -> Func { // let state_mut = state as *mut T; let func = move |_: Caller<'_>, args: &[Val], results: &mut [Val]| { let mut inner_args = vec![]; for arg in args { if let Some(arg) = from_val(arg.clone()) { inner_args.push(arg); } else { return Err(Trap::new("Could not wrap host function")); } } match f(state, &inner_args) { Ok(ret) => { if let Some(ret) = from_ret_val(ret) { results[0] = ret; } Ok(()) } Err(_) => Err(Trap::new("Could not wrap host function")), } }; Func::new(store, wasmtime_sig(sig), func) }
It could be compiled like this, but if I have to use
'static
?
clearloop edited a comment on Issue #2578:
When using
&[Val]
you'll want to useFunc::new
, andstate: &mut T
can't be given to you from wasm, so it can't be a parameter in the closure passed toFunc::wrap
. What you can do, however, is close over thestate
in the closure you provide toFunc::wrap
. If you need mutable access you'll need to use something likeRefCell
to account for the possibility that your closure is invoked recursively.Thanks!
At least I'm certain about I can't pass
state
as a parameter now, I'll try to movestate
into the closure, afraid of not usingstate
as a parameter, functions implemented in wasm could not recognize the signature of the host functions.I'll do more practice and close this issue as I implement it.
Ref to https://github.com/bytecodealliance/wasmtime/issues/1678, https://github.com/bytecodealliance/wasmtime/issues/2491
clearloop commented on Issue #2578:
Just got an example following #2491, https://github.com/chifflier/suricata/blob/295091c2e6598e84519d92b87dbe24d31c5fd070/rust/src/wasm/runtime_util.rs, but using
Func::wrap()
clearloop commented on Issue #2578:
Closing this because I'm certain about the problem in my implementation is not a wasmtime problem now.
clearloop closed Issue #2578:
Desc
Here I'm trying to define the
HostFuncType<T>
below as extern functions inwasmtime
, but I don't know how to handle the&mut T
pub type HostFuncType<T> = fn(&mut T, &[Value]) -> Result<ReturnValue, HostError>;
It might be possible using
ExternRef<Arc<RefCell<T>>>
instead of doing something like this, but if there is any solution can pass the&mut T
without breaking the arguments of theHostFuncType<T>
?
clearloop edited a comment on Issue #2578:
When using
&[Val]
you'll want to useFunc::new
, andstate: &mut T
can't be given to you from wasm, so it can't be a parameter in the closure passed toFunc::wrap
. What you can do, however, is close over thestate
in the closure you provide toFunc::wrap
. If you need mutable access you'll need to use something likeRefCell
to account for the possibility that your closure is invoked recursively.Thanks!
At least I'm certain about I can't pass
state
as a parameter now, I'll try to movestate
into the closure, afraid of not usingstate
as a parameter, functions implemented in wasm could not recognize the signature of the host functions.I'll do more practice and close this issue as I implement it.
Ref to https://github.com/bytecodealliance/wasmtime/issues/1678, https://github.com/bytecodealliance/wasmtime/issues/2491, https://github.com/bytecodealliance/wasmtime/issues/2159
Last updated: Nov 22 2024 at 16:03 UTC