Closed chenyukang closed 1 year ago
I created two sub-projects to demo how we can make it work with wasmedge-sys and wasmedge-sdk.
If we keep the API from SDK VM and Memory the same with inner data structure, such as get_data, read_data, get_memory, we could have one project to support both wasmedge-sys and wasmedge-sdk?
Any ideas on how we plan to integrate wasmedge-sdk with wasmedge-bindgen? @DarumaDocker
To make changes as small as possible, I also make some temporary changes on wasmedge-sdk:
diff --git a/src/types.rs b/src/types.rs
index b7fbc17..54e2113 100644
--- a/src/types.rs
+++ b/src/types.rs
@@ -1,7 +1,7 @@
//! Defines the general types.
use crate::FuncRef;
-use wasmedge_sys::WasmValue;
+pub use wasmedge_sys::WasmValue;
use wasmedge_types::{self, RefType};
/// Defines runtime values that a WebAssembly module can either consume or produce.
diff --git a/src/vm.rs b/src/vm.rs
index 56d17af..4136320 100644
--- a/src/vm.rs
+++ b/src/vm.rs
@@ -131,6 +131,18 @@ impl Vm {
Ok(self)
}
+ pub fn load_wasm_from_file(&mut self, path: impl AsRef<Path>) -> WasmEdgeResult<()> {
+ self.inner.load_wasm_from_file(path.as_ref())
+ }
+
+ pub fn wasi_module_mut(&mut self) -> WasmEdgeResult<wasmedge_sys::instance::module::WasiModule> {
+ self.inner.wasi_module_mut()
+ }
+
+ pub fn validate(&mut self) -> WasmEdgeResult<()> {
+ self.inner.validate()
+ }
+
/// Registers a WASM module from then given in-memory wasm bytes into the [Vm], and instantiates it.
///
/// # Arguments
@@ -207,6 +219,10 @@ impl Vm {
Ok(self)
}
+ pub fn instantiate(&mut self) -> WasmEdgeResult<()> {
+ self.inner.instantiate()
+ }
+
/// Resets the [Vm].
pub fn reset(&mut self) {
self.inner.reset()
@@ -246,6 +262,15 @@ impl Vm {
Ok(returns)
}
+ pub fn run_function(
+ &self,
+ func_name: impl AsRef<str>,
+ params: impl IntoIterator<Item = sys::WasmValue>,
+ ) -> WasmEdgeResult<Vec<sys::WasmValue>> {
+ self.inner.run_function(func_name.as_ref(), params)
+ }
+
+
/// Returns the type of a WASM function.
///
/// # Arguments
@apepkuss Can you review this? The goal is to support wasmedge-bindgen in our Rust SDK.
To make changes as small as possible, I also make some temporary changes on wasmedge-sdk:
diff --git a/src/types.rs b/src/types.rs index b7fbc17..54e2113 100644 --- a/src/types.rs +++ b/src/types.rs @@ -1,7 +1,7 @@ //! Defines the general types. use crate::FuncRef; -use wasmedge_sys::WasmValue; +pub use wasmedge_sys::WasmValue; use wasmedge_types::{self, RefType}; /// Defines runtime values that a WebAssembly module can either consume or produce. diff --git a/src/vm.rs b/src/vm.rs index 56d17af..4136320 100644 --- a/src/vm.rs +++ b/src/vm.rs @@ -131,6 +131,18 @@ impl Vm { Ok(self) } + pub fn load_wasm_from_file(&mut self, path: impl AsRef<Path>) -> WasmEdgeResult<()> { + self.inner.load_wasm_from_file(path.as_ref()) + } + + pub fn wasi_module_mut(&mut self) -> WasmEdgeResult<wasmedge_sys::instance::module::WasiModule> { + self.inner.wasi_module_mut() + } + + pub fn validate(&mut self) -> WasmEdgeResult<()> { + self.inner.validate() + } + /// Registers a WASM module from then given in-memory wasm bytes into the [Vm], and instantiates it. /// /// # Arguments @@ -207,6 +219,10 @@ impl Vm { Ok(self) } + pub fn instantiate(&mut self) -> WasmEdgeResult<()> { + self.inner.instantiate() + } + /// Resets the [Vm]. pub fn reset(&mut self) { self.inner.reset() @@ -246,6 +262,15 @@ impl Vm { Ok(returns) } + pub fn run_function( + &self, + func_name: impl AsRef<str>, + params: impl IntoIterator<Item = sys::WasmValue>, + ) -> WasmEdgeResult<Vec<sys::WasmValue>> { + self.inner.run_function(func_name.as_ref(), params) + } + + /// Returns the type of a WASM function. /// /// # Arguments
As the API design principles of wasmedge-sdk
and wasmedge-sys
are different, the wasmedge-bindgen
should provide supports for them, respectively. It is not recommended that refactoring the existing APIs of wasmedge-sdk
and wasmedge-sys
to simplify the design of wasmedge-bindgen
. I strongly recommend that wasmedge-bindgen
should focus on the support for wasmedge-sdk
, because wasmedge-sys
is a low-level layer in the architecture of WasmEdge Rust bindings, we should help the early-phase end users migrate their projects onto wasmedge-sdk
. Therefore, it would be much better to provide full support for wasmedge-sdk
and weaken the support for wasmedge-sys
gradually.
To make changes as small as possible, I also make some temporary changes on wasmedge-sdk:
diff --git a/src/types.rs b/src/types.rs index b7fbc17..54e2113 100644 --- a/src/types.rs +++ b/src/types.rs @@ -1,7 +1,7 @@ //! Defines the general types. use crate::FuncRef; -use wasmedge_sys::WasmValue; +pub use wasmedge_sys::WasmValue; use wasmedge_types::{self, RefType}; /// Defines runtime values that a WebAssembly module can either consume or produce. diff --git a/src/vm.rs b/src/vm.rs index 56d17af..4136320 100644 --- a/src/vm.rs +++ b/src/vm.rs @@ -131,6 +131,18 @@ impl Vm { Ok(self) } + pub fn load_wasm_from_file(&mut self, path: impl AsRef<Path>) -> WasmEdgeResult<()> { + self.inner.load_wasm_from_file(path.as_ref()) + } + + pub fn wasi_module_mut(&mut self) -> WasmEdgeResult<wasmedge_sys::instance::module::WasiModule> { + self.inner.wasi_module_mut() + } + + pub fn validate(&mut self) -> WasmEdgeResult<()> { + self.inner.validate() + } + /// Registers a WASM module from then given in-memory wasm bytes into the [Vm], and instantiates it. /// /// # Arguments @@ -207,6 +219,10 @@ impl Vm { Ok(self) } + pub fn instantiate(&mut self) -> WasmEdgeResult<()> { + self.inner.instantiate() + } + /// Resets the [Vm]. pub fn reset(&mut self) { self.inner.reset() @@ -246,6 +262,15 @@ impl Vm { Ok(returns) } + pub fn run_function( + &self, + func_name: impl AsRef<str>, + params: impl IntoIterator<Item = sys::WasmValue>, + ) -> WasmEdgeResult<Vec<sys::WasmValue>> { + self.inner.run_function(func_name.as_ref(), params) + } + + /// Returns the type of a WASM function. /// /// # Arguments
As the API design principles of
wasmedge-sdk
andwasmedge-sys
are different, thewasmedge-bindgen
should provide supports for them, respectively. It is not recommended that refactoring the existing APIs ofwasmedge-sdk
andwasmedge-sys
to simplify the design ofwasmedge-bindgen
. I strongly recommend thatwasmedge-bindgen
should focus on the support forwasmedge-sdk
, becausewasmedge-sys
is a low-level layer in the architecture of WasmEdge Rust bindings, we should help the early-phase end users migrate their projects ontowasmedge-sdk
. Therefore, it would be much better to provide full support forwasmedge-sdk
and weaken the support forwasmedge-sys
gradually.
Could we make wasmedge-bindgen as a part of wasmedge-sdk
? I'm not sure why wasmedge-bindgen
need to be a standalone project.
Maybe related to https://github.com/WasmEdge/WasmEdge/issues/1612.
Per my understanding, wasmedge-sdk
will expose much less APIs to user and will provide more builtin senarios support, right?
Hi @chenyukang
Q: Could we make wasmedge-bindgen as a part of wasmedge-sdk? I'm not sure why wasmedge-bindgen needs to be a standalone project.
As I know, wasmedge-bindgen
is derived from wasm-bindgen
, which is not part of WasmEdge. This is the primary reason.
Here are other considerations. According to the current phase of WasmEdge Rust bindings (including wasmedge-sdk
and its dependencies), the APIs of wasmedge-sdk
is still not stable, as there are still some new WebAssembly proposals and features under development, which could introduce some changes in C-APIs, such as the fix of WasmEdge issue #1659; in addition, wasmedge-sdk
is in the first version and we believe there are still space for improvements on APIs and even the architecture, and we will do it based on the feedback from the community. Therefore, it would be better to keep Rust bindings as simple as possible, so that we can obtain the flexibility of how to support complex interface types, wasmedge-bindgen
or runtime-native interface types.
Q: wasmedge-sdk will expose much less APIs to user and will provide more builtin senarios support, right?
Basically, the first design principle of wasmedge-sdk
is focusing on ergonomics but not "fewer APIs". We hope that the high-level APIs can provide a programming pattern Rust developers like, for example, chaining, builder pattern, etc. As the statements in the answer to the first question, wasmedge-sdk
is still at the beginning stage. We hope Rust developers like it, but honestly, we believe there is space for improvements. In addition, we also would like to verify if the APIs in the current version of wasmedge-sdk
would cover the requirements that end users need in their projects. That's also a factor that we view as a kind of "feedback" for our future improvements.
@apepkuss Thanks for answering.
As for the design principle of wasmedge-sdk
, I think the most important thing is "less suprise" and convinent for programmers.
There are some programming patterns in Rust programming, chaining
is good, but I think builder pattern maybe is not a must one.
The last time I was confused on this is at 😂 https://github.com/containers/oci-spec-rs/pull/49 https://github.com/containers/oci-spec-rs/issues/60
You see, different people have different preference.
I saw you published new version(stable version?) for wasmedge-sdk
, I will polish my changes after updating the latest wasmedge-sdk
.
And also will try to replace wasmedge-sys
with wasmedge-sdk
in https://github.com/second-state/dapr-wasm
Hi @chenyukang
Thanks for your feedback. I totally agree with the point of "less surprise and convenient". We'll put your feedback into our feedback pool so that we can make improvements to our APIs in future releases.
For the question about the stability of the current APIs in wasmedge-sdk
, according to our dev plan, runtime
will introduce some new features in the next release (which could be v0.11.0), which should bring about some breaking changes on the current APIs. Therefore, my suggestion is that you can put off the migration until the new version is released.
Thanks for your feedback and question again :)
@apepkuss
I'm trying to make the test project to work, seems the method init_wasi
is lack in WasiInstance
.
The Rust SDK return inner wasi module:
pub fn wasi_module(&mut self) -> WasmEdgeResult<WasiInstance> {
let inner_wasi_module = self.inner.wasi_module_mut()?;
Ok(WasiInstance {
inner: inner_wasi_module,
})
}
In the test code, what I want to do is:
init_wasi
don't have a public method, and inner
is private.
I will follow the principle that don't make any more changes on your Rust SDK, and make wasmedge-bindgen
to work.
@apepkuss I'm trying to make the test project to work, seems the method
init_wasi
is lack inWasiInstance
.The Rust SDK return inner wasi module:
pub fn wasi_module(&mut self) -> WasmEdgeResult<WasiInstance> { let inner_wasi_module = self.inner.wasi_module_mut()?; Ok(WasiInstance { inner: inner_wasi_module, }) }
In the test code, what I want to do is:
init_wasi
don't have a public method, andinner
is private.
@chenyukang I found that the version of wasmedge-sdk
you're using is 0.1.0
, right? Could you please update it to the latest release 0.3.0
? Then, you can use the initialize method to do the initialization. Thanks!
@apepkuss Thanks, I have solved this issue and move on.
Here is another issue, in previous wasmedge-sys
's Bindgen, here we call vm.instantiate
,
https://github.com/second-state/wasmedge-bindgen/blob/6f1fc8aa79b4d0a2211f0847583f33a60d69b93b/host/rust/src/lib.rs#L320
VM
in Rust SDK also didn't exported this function, how do I call the API, which from the inner VM (which is from wasmedge-sys).
In my local repo, I need to wrap this:
+ pub fn instantiate(&mut self) -> WasmEdgeResult<()> {
+ self.inner.instantiate()
+ }
In the test code, we use it like this:
let mut bg = Bindgen::new(vm);
bg.instantiate();
@chenyukang Yes, you're right. wasmedge-sdk
does not expose the wasmedge_sys::Vm::instantiate
method, the reason is that this method is only used to register active wasm modules (also called anonymous modules) in the context of wasmedge_sys
, so in the context of wasmedge-sdk
we abstract the design and "wrap" all the methods related to the registration of active wasm modules into the private method wasmedge_sdk::Vm::register_active_module
which is then used by the public method wasmedge_sdk::Vm::register_module
. This is why you cannot find a "instantiate" method in wasmedge-sdk::Vm
. I'm not familiar with wasmedge-bindgen
, is it possible for wasmedge-bindgen
to use a workaround to solve the issue?
This is a WIP PR, if we want to support WasmEdge Rust SDK, only some trivial API names need to fix.
The main diff is: