mirror of
https://github.com/fluencelabs/marine.git
synced 2025-06-29 14:41:39 +00:00
add complex type support
This commit is contained in:
92
Cargo.lock
generated
92
Cargo.lock
generated
@ -35,9 +35,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "anyhow"
|
name = "anyhow"
|
||||||
version = "1.0.31"
|
version = "1.0.32"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "85bb70cc08ec97ca5450e6eba421deeea5f172c0fc61f78b5357b2a8e8be195f"
|
checksum = "6b602bfe940d21c130f3895acd65221e8a61270debe89d628b9cb4e3ccb8569b"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "arrayref"
|
name = "arrayref"
|
||||||
@ -403,7 +403,7 @@ dependencies = [
|
|||||||
"parity-wasm",
|
"parity-wasm",
|
||||||
"pwasm-utils",
|
"pwasm-utils",
|
||||||
"serde",
|
"serde",
|
||||||
"wasmer-interface-types",
|
"wasmer-interface-types 0.17.0 (git+http://github.com/fluencelabs/interface-types?branch=struct_support)",
|
||||||
"wasmer-runtime",
|
"wasmer-runtime",
|
||||||
"wasmer-runtime-core",
|
"wasmer-runtime-core",
|
||||||
"wasmer-wasi",
|
"wasmer-wasi",
|
||||||
@ -415,7 +415,7 @@ name = "fce-wit-interfaces"
|
|||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"multimap",
|
"multimap",
|
||||||
"wasmer-interface-types",
|
"wasmer-interface-types 0.17.0 (git+https://github.com/fluencelabs/interface-types?branch=byte_array)",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -434,10 +434,18 @@ dependencies = [
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "fluence"
|
name = "fluence"
|
||||||
version = "0.2.0"
|
version = "0.2.0"
|
||||||
source = "git+https://github.com/fluencelabs/rust-sdk#79a5896015659ddb1c20526c4aa142b8afae35ad"
|
source = "git+https://github.com/fluencelabs/rust-sdk#e589d52c7247462f194800f50595029d224a5e43"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"fluence-sdk-macro",
|
"fluence-sdk-macro 0.2.0 (git+https://github.com/fluencelabs/rust-sdk)",
|
||||||
"fluence-sdk-main",
|
"fluence-sdk-main 0.2.0 (git+https://github.com/fluencelabs/rust-sdk)",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "fluence"
|
||||||
|
version = "0.2.0"
|
||||||
|
dependencies = [
|
||||||
|
"fluence-sdk-macro 0.2.0",
|
||||||
|
"fluence-sdk-main 0.2.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -459,15 +467,29 @@ dependencies = [
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "fluence-sdk-macro"
|
name = "fluence-sdk-macro"
|
||||||
version = "0.2.0"
|
version = "0.2.0"
|
||||||
source = "git+https://github.com/fluencelabs/rust-sdk#79a5896015659ddb1c20526c4aa142b8afae35ad"
|
source = "git+https://github.com/fluencelabs/rust-sdk#e589d52c7247462f194800f50595029d224a5e43"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"fluence-sdk-wit",
|
"fluence-sdk-wit 0.2.0 (git+https://github.com/fluencelabs/rust-sdk)",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "fluence-sdk-macro"
|
||||||
|
version = "0.2.0"
|
||||||
|
dependencies = [
|
||||||
|
"fluence-sdk-wit 0.2.0",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "fluence-sdk-main"
|
||||||
|
version = "0.2.0"
|
||||||
|
source = "git+https://github.com/fluencelabs/rust-sdk#e589d52c7247462f194800f50595029d224a5e43"
|
||||||
|
dependencies = [
|
||||||
|
"log",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "fluence-sdk-main"
|
name = "fluence-sdk-main"
|
||||||
version = "0.2.0"
|
version = "0.2.0"
|
||||||
source = "git+https://github.com/fluencelabs/rust-sdk#79a5896015659ddb1c20526c4aa142b8afae35ad"
|
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"log",
|
"log",
|
||||||
]
|
]
|
||||||
@ -475,7 +497,19 @@ dependencies = [
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "fluence-sdk-wit"
|
name = "fluence-sdk-wit"
|
||||||
version = "0.2.0"
|
version = "0.2.0"
|
||||||
source = "git+https://github.com/fluencelabs/rust-sdk#79a5896015659ddb1c20526c4aa142b8afae35ad"
|
source = "git+https://github.com/fluencelabs/rust-sdk#e589d52c7247462f194800f50595029d224a5e43"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"serde",
|
||||||
|
"serde_json",
|
||||||
|
"syn",
|
||||||
|
"uuid",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "fluence-sdk-wit"
|
||||||
|
version = "0.2.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
@ -1010,6 +1044,12 @@ version = "1.0.5"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "71d301d4193d031abdd79ff7e3dd721168a9572ef3fe51a1517aba235bd8f86e"
|
checksum = "71d301d4193d031abdd79ff7e3dd721168a9572ef3fe51a1517aba235bd8f86e"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "safe-transmute"
|
||||||
|
version = "0.11.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "50b8b2cd387f744f69469aaed197954ba4c0ecdb31e02edf99b023e0df11178a"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "scopeguard"
|
name = "scopeguard"
|
||||||
version = "1.1.0"
|
version = "1.1.0"
|
||||||
@ -1107,9 +1147,9 @@ checksum = "502d53007c02d7605a05df1c1a73ee436952781653da5d0bf57ad608f66932c1"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "syn"
|
name = "syn"
|
||||||
version = "1.0.34"
|
version = "1.0.35"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "936cae2873c940d92e697597c5eee105fb570cd5689c695806f672883653349b"
|
checksum = "fb7f4c519df8c117855e19dd8cc851e89eb746fe7a73f0157e0d95fdec5369b0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
@ -1311,14 +1351,14 @@ checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519"
|
|||||||
name = "wasm_greeting"
|
name = "wasm_greeting"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"fluence",
|
"fluence 0.2.0 (git+https://github.com/fluencelabs/rust-sdk)",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "wasm_ipfs_node"
|
name = "wasm_ipfs_node"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"fluence",
|
"fluence 0.2.0 (git+https://github.com/fluencelabs/rust-sdk)",
|
||||||
"log",
|
"log",
|
||||||
]
|
]
|
||||||
|
|
||||||
@ -1326,7 +1366,7 @@ dependencies = [
|
|||||||
name = "wasm_ipfs_rpc"
|
name = "wasm_ipfs_rpc"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"fluence",
|
"fluence 0.2.0",
|
||||||
"log",
|
"log",
|
||||||
]
|
]
|
||||||
|
|
||||||
@ -1384,13 +1424,25 @@ dependencies = [
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "wasmer-interface-types"
|
name = "wasmer-interface-types"
|
||||||
version = "0.17.0"
|
version = "0.17.0"
|
||||||
source = "git+https://github.com/fluencelabs/interface-types?branch=byte_array#b65b34b0f627b3da5cd5761fe309cefc4980449b"
|
source = "git+https://github.com/fluencelabs/interface-types?branch=byte_array#4521e79a50e39dfa155d07e74ffc7d12203fa198"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"nom",
|
"nom",
|
||||||
"serde",
|
"serde",
|
||||||
"wast",
|
"wast",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "wasmer-interface-types"
|
||||||
|
version = "0.17.0"
|
||||||
|
source = "git+http://github.com/fluencelabs/interface-types?branch=struct_support#053056c1eb5063b8aab480022301e4b5cd5baa81"
|
||||||
|
dependencies = [
|
||||||
|
"nom",
|
||||||
|
"safe-transmute",
|
||||||
|
"serde",
|
||||||
|
"serde_json",
|
||||||
|
"wast",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "wasmer-runtime"
|
name = "wasmer-runtime"
|
||||||
version = "0.17.0"
|
version = "0.17.0"
|
||||||
@ -1518,12 +1570,12 @@ checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
|
|||||||
name = "wit-generator"
|
name = "wit-generator"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"fluence-sdk-wit",
|
"fluence-sdk-wit 0.2.0 (git+https://github.com/fluencelabs/rust-sdk)",
|
||||||
"once_cell",
|
"once_cell",
|
||||||
"serde",
|
"serde",
|
||||||
"serde_json",
|
"serde_json",
|
||||||
"walrus",
|
"walrus",
|
||||||
"wasmer-interface-types",
|
"wasmer-interface-types 0.17.0 (git+http://github.com/fluencelabs/interface-types?branch=struct_support)",
|
||||||
"wit-parser",
|
"wit-parser",
|
||||||
]
|
]
|
||||||
|
|
||||||
@ -1534,6 +1586,6 @@ dependencies = [
|
|||||||
"anyhow",
|
"anyhow",
|
||||||
"fce-wit-interfaces",
|
"fce-wit-interfaces",
|
||||||
"walrus",
|
"walrus",
|
||||||
"wasmer-interface-types",
|
"wasmer-interface-types 0.17.0 (git+http://github.com/fluencelabs/interface-types?branch=struct_support)",
|
||||||
"wasmer-runtime-core",
|
"wasmer-runtime-core",
|
||||||
]
|
]
|
||||||
|
12
README.md
12
README.md
@ -22,7 +22,7 @@ FCE is intended to run various Wasm binaries. At now, it is in the heavily devel
|
|||||||
- Init simple rust project `cargo init --bin`
|
- Init simple rust project `cargo init --bin`
|
||||||
|
|
||||||
- `Config.toml`:
|
- `Config.toml`:
|
||||||
```
|
```rust
|
||||||
[[bin]]
|
[[bin]]
|
||||||
name = "wasm_application"
|
name = "wasm_application"
|
||||||
path = "src/main.rs"
|
path = "src/main.rs"
|
||||||
@ -33,7 +33,7 @@ fluence = { git = "https://github.com/fluencelabs/rust-sdk", features = ["logger
|
|||||||
```
|
```
|
||||||
|
|
||||||
- Methods that will be exported from this module marked with `#[fce]`
|
- Methods that will be exported from this module marked with `#[fce]`
|
||||||
```
|
```rust
|
||||||
use fluence::fce;
|
use fluence::fce;
|
||||||
|
|
||||||
#[fce]
|
#[fce]
|
||||||
@ -48,7 +48,7 @@ pub fn get(url: String) -> String {
|
|||||||
- Copy wasm file from `target/wasm32-wasi/debug` to directory with other modules
|
- Copy wasm file from `target/wasm32-wasi/debug` to directory with other modules
|
||||||
|
|
||||||
- To import other wasm modules to your project use similar code:
|
- To import other wasm modules to your project use similar code:
|
||||||
```
|
```rust
|
||||||
#[fce]
|
#[fce]
|
||||||
#[link(wasm_import_module = "wasm_curl.wasm")]
|
#[link(wasm_import_module = "wasm_curl.wasm")]
|
||||||
extern "C" {
|
extern "C" {
|
||||||
@ -68,7 +68,7 @@ extern "C" {
|
|||||||
|
|
||||||
- Create simple Rust project
|
- Create simple Rust project
|
||||||
- Create `Config.toml` to describe existed wasm modules and give accesses to host binaries and local storage if needed:
|
- Create `Config.toml` to describe existed wasm modules and give accesses to host binaries and local storage if needed:
|
||||||
```
|
```rust
|
||||||
core_modules_dir = "wasm/artifacts/modules"
|
core_modules_dir = "wasm/artifacts/modules"
|
||||||
|
|
||||||
[[core_module]]
|
[[core_module]]
|
||||||
@ -97,7 +97,7 @@ core_modules_dir = "wasm/artifacts/modules"
|
|||||||
`curl = "/usr/bin/curl"` - gives possibility to call binary file `/usr/bin/curl` as method `curl` in Rust code
|
`curl = "/usr/bin/curl"` - gives possibility to call binary file `/usr/bin/curl` as method `curl` in Rust code
|
||||||
|
|
||||||
Import example:
|
Import example:
|
||||||
```
|
```rust
|
||||||
#[link(wasm_import_module = "host")]
|
#[link(wasm_import_module = "host")]
|
||||||
extern "C" {
|
extern "C" {
|
||||||
fn curl(args: String) -> String;
|
fn curl(args: String) -> String;
|
||||||
@ -112,7 +112,7 @@ Call binary with arguments: `curl("-vvv ya.ru")`
|
|||||||
`mapped_dirs` - mapping between paths
|
`mapped_dirs` - mapping between paths
|
||||||
|
|
||||||
Working with files as usual:
|
Working with files as usual:
|
||||||
```
|
```rust
|
||||||
fs::write(PathBuf::from("/tmp/somefile"), vec!(1,2,3));
|
fs::write(PathBuf::from("/tmp/somefile"), vec!(1,2,3));
|
||||||
fs::read(...);
|
fs::read(...);
|
||||||
```
|
```
|
@ -9,6 +9,6 @@ wit-parser = { path = "../wit-parser" }
|
|||||||
walrus = "0.17.0"
|
walrus = "0.17.0"
|
||||||
fluence-sdk-wit = { git = "https://github.com/fluencelabs/rust-sdk" }
|
fluence-sdk-wit = { git = "https://github.com/fluencelabs/rust-sdk" }
|
||||||
once_cell = "1.4.0"
|
once_cell = "1.4.0"
|
||||||
wasmer-wit = { package = "wasmer-interface-types", git = "http://github.com/fluencelabs/interface-types", branch = "byte_array", features = ["serde"] }
|
wasmer-wit = { package = "wasmer-interface-types", git = "http://github.com/fluencelabs/interface-types", branch = "struct_support", features = ["serde"] }
|
||||||
serde = { version = "1.0.110", features = ["derive"] }
|
serde = { version = "1.0.110", features = ["derive"] }
|
||||||
serde_json = "1.0.56"
|
serde_json = "1.0.56"
|
||||||
|
@ -22,6 +22,9 @@ pub enum WITGeneratorError {
|
|||||||
/// An error related to serde deserialization.
|
/// An error related to serde deserialization.
|
||||||
DeserializationError(SerdeDeserializationError),
|
DeserializationError(SerdeDeserializationError),
|
||||||
|
|
||||||
|
/// Various errors related to records
|
||||||
|
CorruptedRecord(String),
|
||||||
|
|
||||||
/// Various errors occurred during the parsing/emitting a Wasm file.
|
/// Various errors occurred during the parsing/emitting a Wasm file.
|
||||||
IOError(String),
|
IOError(String),
|
||||||
}
|
}
|
||||||
@ -36,6 +39,7 @@ impl std::fmt::Display for WITGeneratorError {
|
|||||||
"Embedded by rust-sdk metadata could't be parsed by serde: {:?}",
|
"Embedded by rust-sdk metadata could't be parsed by serde: {:?}",
|
||||||
err
|
err
|
||||||
),
|
),
|
||||||
|
WITGeneratorError::CorruptedRecord(err) => write!(f, "{:?}", err),
|
||||||
WITGeneratorError::IOError(err) => write!(f, "I/O error occurred: {:?}", err),
|
WITGeneratorError::IOError(err) => write!(f, "I/O error occurred: {:?}", err),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -19,34 +19,47 @@ mod foreign_mod_instructions;
|
|||||||
mod record_instructions;
|
mod record_instructions;
|
||||||
mod utils;
|
mod utils;
|
||||||
|
|
||||||
use fluence_sdk_wit::FCEAst;
|
use crate::Result;
|
||||||
|
|
||||||
use wasmer_wit::types::InterfaceType as IType;
|
use wasmer_wit::types::InterfaceType as IType;
|
||||||
use wasmer_wit::ast::Interfaces;
|
use wasmer_wit::ast::Interfaces;
|
||||||
use wasmer_wit::interpreter::Instruction;
|
|
||||||
|
|
||||||
pub trait WITGenerator {
|
#[derive(PartialEq, Debug, Default)]
|
||||||
fn generate_wit<'a>(&'a self, interfaces: &mut Interfaces<'a>);
|
pub(crate) struct WITResolver<'a> {
|
||||||
|
pub(crate) types: std::collections::HashMap<String, u32>,
|
||||||
|
pub(crate) interfaces: Interfaces<'a>,
|
||||||
}
|
}
|
||||||
|
|
||||||
trait FnInstructionGenerator {
|
impl<'a> WITResolver<'a> {
|
||||||
fn generate_instructions_for_input_type(&self, arg_id: u32) -> Vec<Instruction>;
|
pub(crate) fn get_record_type_id(&self, record_name: &str) -> Result<u32> {
|
||||||
|
match self.types.get(record_name) {
|
||||||
|
Some(type_index) => Ok(*type_index),
|
||||||
|
None => Err(crate::errors::WITGeneratorError::CorruptedRecord(format!(
|
||||||
|
"Can't find record with name='{}', don't you forget to wrap it with #[fce]",
|
||||||
|
record_name
|
||||||
|
))),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn generate_instructions_for_output_type(&self) -> Vec<Instruction>;
|
pub(crate) fn get_record_type(
|
||||||
}
|
&self,
|
||||||
|
record_name: &str,
|
||||||
trait ForeignModInstructionGenerator {
|
) -> Result<wasmer_wit::types::RecordType> {
|
||||||
fn generate_instructions_for_input_type(&self, arg_id: u32) -> Vec<Instruction>;
|
match self.types.get(record_name) {
|
||||||
|
Some(type_index) => match &self.interfaces.types[*type_index as usize] {
|
||||||
fn generate_instructions_for_output_type(&self) -> Vec<Instruction>;
|
wasmer_wit::ast::Type::Function { .. } => {
|
||||||
}
|
panic!("internal error inside WITResolver")
|
||||||
|
}
|
||||||
impl WITGenerator for FCEAst {
|
wasmer_wit::ast::Type::Record(record_type) => Ok(record_type.clone()),
|
||||||
fn generate_wit<'a>(&'a self, interfaces: &mut Interfaces<'a>) {
|
},
|
||||||
match self {
|
None => Err(crate::errors::WITGeneratorError::CorruptedRecord(format!(
|
||||||
FCEAst::Function(func) => func.generate_wit(interfaces),
|
"Can't find record with name='{}', don't you forget to wrap it with #[fce]",
|
||||||
FCEAst::ExternMod(extern_mod) => extern_mod.generate_wit(interfaces),
|
record_name
|
||||||
FCEAst::Record(record) => record.generate_wit(interfaces),
|
))),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub(crate) trait WITGenerator {
|
||||||
|
fn generate_wit<'a>(&'a self, wit_resolver: &mut WITResolver<'a>) -> Result<()>;
|
||||||
|
}
|
||||||
|
@ -15,17 +15,17 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
use super::WITGenerator;
|
use super::WITGenerator;
|
||||||
use super::Interfaces;
|
use super::WITResolver;
|
||||||
use super::FnInstructionGenerator;
|
|
||||||
use super::utils::ptype_to_itype;
|
use super::utils::ptype_to_itype;
|
||||||
use crate::default_export_api_config::*;
|
use crate::default_export_api_config::*;
|
||||||
|
use crate::Result;
|
||||||
|
|
||||||
use fluence_sdk_wit::AstFunctionItem;
|
use fluence_sdk_wit::AstFunctionItem;
|
||||||
use fluence_sdk_wit::ParsedType;
|
use fluence_sdk_wit::ParsedType;
|
||||||
use wasmer_wit::interpreter::Instruction;
|
use wasmer_wit::interpreter::Instruction;
|
||||||
|
|
||||||
impl WITGenerator for AstFunctionItem {
|
impl WITGenerator for AstFunctionItem {
|
||||||
fn generate_wit<'a>(&'a self, interfaces: &mut Interfaces<'a>) {
|
fn generate_wit<'a>(&'a self, wit_resolver: &mut WITResolver<'a>) -> Result<()> {
|
||||||
use wasmer_wit::ast::Type;
|
use wasmer_wit::ast::Type;
|
||||||
use wasmer_wit::ast::Adapter;
|
use wasmer_wit::ast::Adapter;
|
||||||
|
|
||||||
@ -33,14 +33,15 @@ impl WITGenerator for AstFunctionItem {
|
|||||||
.signature
|
.signature
|
||||||
.input_types
|
.input_types
|
||||||
.iter()
|
.iter()
|
||||||
.map(ptype_to_itype)
|
.map(|input_type| ptype_to_itype(input_type, wit_resolver))
|
||||||
.collect::<Vec<_>>();
|
.collect::<Result<Vec<_>>>()?;
|
||||||
|
|
||||||
let outputs = match self.signature.output_type {
|
let outputs = match self.signature.output_type {
|
||||||
Some(ref output_type) => vec![ptype_to_itype(output_type)],
|
Some(ref output_type) => vec![ptype_to_itype(output_type, wit_resolver)?],
|
||||||
None => vec![],
|
None => vec![],
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let interfaces = &mut wit_resolver.interfaces;
|
||||||
interfaces.types.push(Type::Function {
|
interfaces.types.push(Type::Function {
|
||||||
inputs: inputs.clone(),
|
inputs: inputs.clone(),
|
||||||
outputs: outputs.clone(),
|
outputs: outputs.clone(),
|
||||||
@ -57,22 +58,27 @@ impl WITGenerator for AstFunctionItem {
|
|||||||
function_type: export_idx,
|
function_type: export_idx,
|
||||||
});
|
});
|
||||||
|
|
||||||
let mut instructions: Vec<Instruction> = self
|
// TODO: rewrite with try_fold
|
||||||
|
let mut instructions = self
|
||||||
.signature
|
.signature
|
||||||
.input_types
|
.input_types
|
||||||
.iter()
|
.iter()
|
||||||
.enumerate()
|
.enumerate()
|
||||||
.map(|(id, input_type)| input_type.generate_instructions_for_input_type(id as _))
|
.map(|(id, input_type)| {
|
||||||
|
input_type.generate_instructions_for_input_type(id as _, wit_resolver)
|
||||||
|
})
|
||||||
|
.collect::<Result<Vec<_>>>()?
|
||||||
|
.into_iter()
|
||||||
.flatten()
|
.flatten()
|
||||||
.collect();
|
.collect::<Vec<Instruction>>();
|
||||||
|
|
||||||
let export_function_index = (interfaces.exports.len() - 1) as u32;
|
let export_function_index = (wit_resolver.interfaces.exports.len() - 1) as u32;
|
||||||
instructions.push(Instruction::CallCore {
|
instructions.push(Instruction::CallCore {
|
||||||
function_index: export_function_index,
|
function_index: export_function_index,
|
||||||
});
|
});
|
||||||
|
|
||||||
instructions.extend(match &self.signature.output_type {
|
instructions.extend(match &self.signature.output_type {
|
||||||
Some(output_type) => output_type.generate_instructions_for_output_type(),
|
Some(output_type) => output_type.generate_instructions_for_output_type(wit_resolver)?,
|
||||||
None => vec![],
|
None => vec![],
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -81,20 +87,37 @@ impl WITGenerator for AstFunctionItem {
|
|||||||
instructions,
|
instructions,
|
||||||
};
|
};
|
||||||
|
|
||||||
interfaces.adapters.push(adapter);
|
wit_resolver.interfaces.adapters.push(adapter);
|
||||||
|
|
||||||
let implementation = wasmer_wit::ast::Implementation {
|
let implementation = wasmer_wit::ast::Implementation {
|
||||||
core_function_type: export_idx,
|
core_function_type: export_idx,
|
||||||
adapter_function_type: adapter_idx,
|
adapter_function_type: adapter_idx,
|
||||||
};
|
};
|
||||||
interfaces.implementations.push(implementation);
|
wit_resolver.interfaces.implementations.push(implementation);
|
||||||
|
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Generate WIT instructions for a function.
|
||||||
|
trait FnInstructionGenerator {
|
||||||
|
fn generate_instructions_for_input_type<'a>(
|
||||||
|
&self,
|
||||||
|
arg_id: u32,
|
||||||
|
wit_resolver: &mut WITResolver<'a>,
|
||||||
|
) -> Result<Vec<Instruction>>;
|
||||||
|
|
||||||
|
fn generate_instructions_for_output_type<'a>(
|
||||||
|
&self,
|
||||||
|
wit_resolver: &mut WITResolver<'a>,
|
||||||
|
) -> Result<Vec<Instruction>>;
|
||||||
|
}
|
||||||
|
|
||||||
impl FnInstructionGenerator for ParsedType {
|
impl FnInstructionGenerator for ParsedType {
|
||||||
#[rustfmt::skip]
|
#[rustfmt::skip]
|
||||||
fn generate_instructions_for_input_type(&self, index: u32) -> Vec<Instruction> {
|
fn generate_instructions_for_input_type<'a>(&self, index: u32, wit_resolver: &mut WITResolver<'a>) -> Result<Vec<Instruction>> {
|
||||||
match self {
|
let instructions = match self {
|
||||||
|
ParsedType::Boolean => vec![Instruction::ArgumentGet { index }],
|
||||||
ParsedType::I8 => vec![Instruction::ArgumentGet { index }, Instruction::I32FromS8],
|
ParsedType::I8 => vec![Instruction::ArgumentGet { index }, Instruction::I32FromS8],
|
||||||
ParsedType::I16 => vec![Instruction::ArgumentGet { index }, Instruction::I32FromS16],
|
ParsedType::I16 => vec![Instruction::ArgumentGet { index }, Instruction::I32FromS16],
|
||||||
ParsedType::I32 => vec![Instruction::ArgumentGet { index }],
|
ParsedType::I32 => vec![Instruction::ArgumentGet { index }],
|
||||||
@ -119,13 +142,23 @@ impl FnInstructionGenerator for ParsedType {
|
|||||||
Instruction::ArgumentGet { index },
|
Instruction::ArgumentGet { index },
|
||||||
Instruction::ByteArrayLowerMemory,
|
Instruction::ByteArrayLowerMemory,
|
||||||
],
|
],
|
||||||
_ => unimplemented!(),
|
ParsedType::Record(record_name) => {
|
||||||
}
|
let type_index = wit_resolver.get_record_type_id(record_name)?;
|
||||||
|
|
||||||
|
vec! [
|
||||||
|
Instruction::ArgumentGet { index },
|
||||||
|
Instruction::RecordLowerMemory { type_index },
|
||||||
|
]
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
Ok(instructions)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[rustfmt::skip]
|
#[rustfmt::skip]
|
||||||
fn generate_instructions_for_output_type(&self) -> Vec<Instruction> {
|
fn generate_instructions_for_output_type<'a>(&self, wit_resolver: &mut WITResolver<'a>) -> Result<Vec<Instruction>> {
|
||||||
match self {
|
let instructions = match self {
|
||||||
|
ParsedType::Boolean => vec![],
|
||||||
ParsedType::I8 => vec![Instruction::S8FromI32],
|
ParsedType::I8 => vec![Instruction::S8FromI32],
|
||||||
ParsedType::I16 => vec![Instruction::S16FromI32],
|
ParsedType::I16 => vec![Instruction::S16FromI32],
|
||||||
ParsedType::I32 => vec![],
|
ParsedType::I32 => vec![],
|
||||||
@ -152,7 +185,16 @@ impl FnInstructionGenerator for ParsedType {
|
|||||||
Instruction::CallCore { function_index: GET_RESULT_SIZE_FUNC.id },
|
Instruction::CallCore { function_index: GET_RESULT_SIZE_FUNC.id },
|
||||||
Instruction::CallCore { function_index: DEALLOCATE_FUNC.id },
|
Instruction::CallCore { function_index: DEALLOCATE_FUNC.id },
|
||||||
],
|
],
|
||||||
_ => unimplemented!(),
|
ParsedType::Record(record_name) => {
|
||||||
}
|
let type_index = wit_resolver.get_record_type_id(record_name)?;
|
||||||
|
|
||||||
|
vec! [
|
||||||
|
Instruction::CallCore { function_index: GET_RESULT_PTR_FUNC.id },
|
||||||
|
Instruction::RecordLiftMemory { type_index },
|
||||||
|
]
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
Ok(instructions)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -15,10 +15,10 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
use super::WITGenerator;
|
use super::WITGenerator;
|
||||||
use super::Interfaces;
|
use super::WITResolver;
|
||||||
use super::utils::ptype_to_itype;
|
use super::utils::ptype_to_itype;
|
||||||
use super::ForeignModInstructionGenerator;
|
|
||||||
use crate::default_export_api_config::*;
|
use crate::default_export_api_config::*;
|
||||||
|
use crate::Result;
|
||||||
|
|
||||||
use fluence_sdk_wit::AstExternModItem;
|
use fluence_sdk_wit::AstExternModItem;
|
||||||
use fluence_sdk_wit::AstExternFnItem;
|
use fluence_sdk_wit::AstExternFnItem;
|
||||||
@ -29,23 +29,25 @@ use crate::instructions_generator::utils::wtype_to_itype;
|
|||||||
const HOST_NAMESPACE_NAME: &str = "host";
|
const HOST_NAMESPACE_NAME: &str = "host";
|
||||||
|
|
||||||
impl WITGenerator for AstExternModItem {
|
impl WITGenerator for AstExternModItem {
|
||||||
fn generate_wit<'a>(&'a self, interfaces: &mut Interfaces<'a>) {
|
fn generate_wit<'a>(&'a self, wit_resolver: &mut WITResolver<'a>) -> Result<()> {
|
||||||
// host imports should be left as is
|
// host imports should be left as is
|
||||||
if self.namespace == HOST_NAMESPACE_NAME {
|
if self.namespace == HOST_NAMESPACE_NAME {
|
||||||
return;
|
return Ok(());
|
||||||
}
|
}
|
||||||
|
|
||||||
for import in &self.imports {
|
for import in &self.imports {
|
||||||
generate_wit_for_import(import, &self.namespace, interfaces);
|
generate_wit_for_import(import, &self.namespace, wit_resolver)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn generate_wit_for_import<'a>(
|
fn generate_wit_for_import<'a>(
|
||||||
import: &'a AstExternFnItem,
|
import: &'a AstExternFnItem,
|
||||||
namespace: &'a str,
|
namespace: &'a str,
|
||||||
interfaces: &mut Interfaces<'a>,
|
wit_resolver: &mut WITResolver<'a>,
|
||||||
) {
|
) -> Result<()> {
|
||||||
use wasmer_wit::ast::Type;
|
use wasmer_wit::ast::Type;
|
||||||
use wasmer_wit::ast::Adapter;
|
use wasmer_wit::ast::Adapter;
|
||||||
|
|
||||||
@ -53,14 +55,15 @@ fn generate_wit_for_import<'a>(
|
|||||||
.signature
|
.signature
|
||||||
.input_types
|
.input_types
|
||||||
.iter()
|
.iter()
|
||||||
.map(ptype_to_itype)
|
.map(|input_type| ptype_to_itype(input_type, wit_resolver))
|
||||||
.collect::<Vec<_>>();
|
.collect::<Result<Vec<_>>>()?;
|
||||||
|
|
||||||
let outputs = match import.signature.output_type {
|
let outputs = match import.signature.output_type {
|
||||||
Some(ref output_type) => vec![ptype_to_itype(output_type)],
|
Some(ref output_type) => vec![ptype_to_itype(output_type, wit_resolver)?],
|
||||||
None => vec![],
|
None => vec![],
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let interfaces = &mut wit_resolver.interfaces;
|
||||||
interfaces.types.push(Type::Function { inputs, outputs });
|
interfaces.types.push(Type::Function { inputs, outputs });
|
||||||
|
|
||||||
let raw_inputs = import
|
let raw_inputs = import
|
||||||
@ -116,19 +119,24 @@ fn generate_wit_for_import<'a>(
|
|||||||
.input_types
|
.input_types
|
||||||
.iter()
|
.iter()
|
||||||
.enumerate()
|
.enumerate()
|
||||||
.map(|(id, input_type)| input_type.generate_instructions_for_input_type(id as _))
|
.map(|(id, input_type)| {
|
||||||
|
input_type.generate_instructions_for_input_type(id as _, wit_resolver)
|
||||||
|
})
|
||||||
|
.collect::<Result<Vec<_>>>()?
|
||||||
|
.into_iter()
|
||||||
.flatten()
|
.flatten()
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
// TODO: refactor
|
// TODO: refactor
|
||||||
let import_function_index =
|
let import_function_index = (wit_resolver.interfaces.exports.len()
|
||||||
(interfaces.exports.len() + interfaces.imports.len() / 2 - 1) as u32;
|
+ wit_resolver.interfaces.imports.len() / 2
|
||||||
|
- 1) as u32;
|
||||||
instructions.push(Instruction::CallCore {
|
instructions.push(Instruction::CallCore {
|
||||||
function_index: import_function_index,
|
function_index: import_function_index,
|
||||||
});
|
});
|
||||||
|
|
||||||
instructions.extend(match &import.signature.output_type {
|
instructions.extend(match &import.signature.output_type {
|
||||||
Some(output_type) => output_type.generate_instructions_for_output_type(),
|
Some(output_type) => output_type.generate_instructions_for_output_type(wit_resolver)?,
|
||||||
None => vec![],
|
None => vec![],
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -136,18 +144,39 @@ fn generate_wit_for_import<'a>(
|
|||||||
function_type: adapter_idx,
|
function_type: adapter_idx,
|
||||||
instructions,
|
instructions,
|
||||||
};
|
};
|
||||||
interfaces.adapters.push(adapter);
|
wit_resolver.interfaces.adapters.push(adapter);
|
||||||
|
|
||||||
let implementation = wasmer_wit::ast::Implementation {
|
let implementation = wasmer_wit::ast::Implementation {
|
||||||
core_function_type: raw_import_idx,
|
core_function_type: raw_import_idx,
|
||||||
adapter_function_type: adapter_idx,
|
adapter_function_type: adapter_idx,
|
||||||
};
|
};
|
||||||
interfaces.implementations.push(implementation);
|
wit_resolver.interfaces.implementations.push(implementation);
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Generate WIT instructions for a foreign mod.
|
||||||
|
trait ForeignModInstructionGenerator {
|
||||||
|
fn generate_instructions_for_input_type<'a>(
|
||||||
|
&self,
|
||||||
|
arg_id: u32,
|
||||||
|
wit_resolver: &mut WITResolver<'a>,
|
||||||
|
) -> Result<Vec<Instruction>>;
|
||||||
|
|
||||||
|
fn generate_instructions_for_output_type<'a>(
|
||||||
|
&self,
|
||||||
|
wit_resolver: &mut WITResolver<'a>,
|
||||||
|
) -> Result<Vec<Instruction>>;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ForeignModInstructionGenerator for ParsedType {
|
impl ForeignModInstructionGenerator for ParsedType {
|
||||||
fn generate_instructions_for_input_type(&self, index: u32) -> Vec<Instruction> {
|
fn generate_instructions_for_input_type<'a>(
|
||||||
match self {
|
&self,
|
||||||
|
index: u32,
|
||||||
|
wit_resolver: &mut WITResolver<'a>,
|
||||||
|
) -> Result<Vec<Instruction>> {
|
||||||
|
let instructions = match self {
|
||||||
|
ParsedType::Boolean => vec![Instruction::ArgumentGet { index }],
|
||||||
ParsedType::I8 => vec![Instruction::ArgumentGet { index }, Instruction::S8FromI32],
|
ParsedType::I8 => vec![Instruction::ArgumentGet { index }, Instruction::S8FromI32],
|
||||||
ParsedType::I16 => vec![Instruction::ArgumentGet { index }, Instruction::S16FromI32],
|
ParsedType::I16 => vec![Instruction::ArgumentGet { index }, Instruction::S16FromI32],
|
||||||
ParsedType::I32 => vec![Instruction::ArgumentGet { index }],
|
ParsedType::I32 => vec![Instruction::ArgumentGet { index }],
|
||||||
@ -168,13 +197,23 @@ impl ForeignModInstructionGenerator for ParsedType {
|
|||||||
Instruction::ArgumentGet { index: index + 1 },
|
Instruction::ArgumentGet { index: index + 1 },
|
||||||
Instruction::StringLiftMemory,
|
Instruction::StringLiftMemory,
|
||||||
],
|
],
|
||||||
_ => unimplemented!(),
|
ParsedType::Record(record_name) => {
|
||||||
}
|
let type_index = wit_resolver.get_record_type_id(record_name)?;
|
||||||
|
|
||||||
|
vec![
|
||||||
|
Instruction::ArgumentGet { index },
|
||||||
|
Instruction::RecordLiftMemory { type_index },
|
||||||
|
]
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
Ok(instructions)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[rustfmt::skip]
|
#[rustfmt::skip]
|
||||||
fn generate_instructions_for_output_type(&self) -> Vec<Instruction> {
|
fn generate_instructions_for_output_type<'a>(&self, wit_resolver: &mut WITResolver<'a>) -> Result<Vec<Instruction>> {
|
||||||
match self {
|
let instructions = match self {
|
||||||
|
ParsedType::Boolean => vec![],
|
||||||
ParsedType::I8 => vec![Instruction::I32FromS8],
|
ParsedType::I8 => vec![Instruction::I32FromS8],
|
||||||
ParsedType::I16 => vec![Instruction::I32FromS16],
|
ParsedType::I16 => vec![Instruction::I32FromS16],
|
||||||
ParsedType::I32 => vec![],
|
ParsedType::I32 => vec![],
|
||||||
@ -203,8 +242,17 @@ impl ForeignModInstructionGenerator for ParsedType {
|
|||||||
Instruction::CallCore { function_index: SET_RESULT_SIZE_FUNC.id },
|
Instruction::CallCore { function_index: SET_RESULT_SIZE_FUNC.id },
|
||||||
Instruction::CallCore { function_index: SET_RESULT_PTR_FUNC.id },
|
Instruction::CallCore { function_index: SET_RESULT_PTR_FUNC.id },
|
||||||
],
|
],
|
||||||
_ => unimplemented!(),
|
ParsedType::Record(record_name) => {
|
||||||
}
|
let type_index = wit_resolver.get_record_type_id(record_name)?;
|
||||||
|
|
||||||
|
vec![
|
||||||
|
Instruction::RecordLowerMemory {type_index},
|
||||||
|
Instruction::CallCore { function_index: SET_RESULT_SIZE_FUNC.id },
|
||||||
|
]
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
Ok(instructions)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -15,12 +15,40 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
use super::WITGenerator;
|
use super::WITGenerator;
|
||||||
use super::Interfaces;
|
use super::WITResolver;
|
||||||
|
use crate::Result;
|
||||||
|
|
||||||
use fluence_sdk_wit::AstRecordItem;
|
use fluence_sdk_wit::AstRecordItem;
|
||||||
|
|
||||||
|
use wasmer_wit::ast::Type;
|
||||||
|
use wasmer_wit::types::RecordType;
|
||||||
|
use wasmer_wit::vec1::Vec1;
|
||||||
|
|
||||||
impl WITGenerator for AstRecordItem {
|
impl WITGenerator for AstRecordItem {
|
||||||
fn generate_wit<'a>(&'a self, _interfaces: &mut Interfaces<'a>) {
|
fn generate_wit<'a>(&'a self, wit_resolver: &mut WITResolver<'a>) -> Result<()> {
|
||||||
unimplemented!()
|
let fields = self
|
||||||
|
.fields
|
||||||
|
.iter()
|
||||||
|
.map(|field| super::utils::ptype_to_itype(&field.ty, wit_resolver))
|
||||||
|
.collect::<Result<Vec<_>>>()?;
|
||||||
|
|
||||||
|
let fields = Vec1::new(fields).map_err(|_| {
|
||||||
|
crate::errors::WITGeneratorError::CorruptedRecord(format!(
|
||||||
|
"serialized record with name '{}' contains no fields",
|
||||||
|
self.name
|
||||||
|
))
|
||||||
|
})?;
|
||||||
|
|
||||||
|
wit_resolver
|
||||||
|
.interfaces
|
||||||
|
.types
|
||||||
|
.push(Type::Record(RecordType { fields }));
|
||||||
|
|
||||||
|
wit_resolver.types.insert(
|
||||||
|
self.name.clone(),
|
||||||
|
(wit_resolver.interfaces.types.len() - 1) as _,
|
||||||
|
);
|
||||||
|
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -15,25 +15,30 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
use super::IType;
|
use super::IType;
|
||||||
|
use crate::instructions_generator::WITResolver;
|
||||||
|
use crate::Result;
|
||||||
|
|
||||||
use fluence_sdk_wit::ParsedType;
|
use fluence_sdk_wit::ParsedType;
|
||||||
use fluence_sdk_wit::WasmType;
|
use fluence_sdk_wit::WasmType;
|
||||||
|
|
||||||
pub(crate) fn ptype_to_itype(pty: &ParsedType) -> IType {
|
pub(crate) fn ptype_to_itype(pty: &ParsedType, wit_resolver: &WITResolver) -> Result<IType> {
|
||||||
match pty {
|
match pty {
|
||||||
ParsedType::I8 => IType::S8,
|
ParsedType::I8 => Ok(IType::S8),
|
||||||
ParsedType::I16 => IType::S16,
|
ParsedType::I16 => Ok(IType::S16),
|
||||||
ParsedType::I32 => IType::S32,
|
ParsedType::I32 => Ok(IType::S32),
|
||||||
ParsedType::I64 => IType::S64,
|
ParsedType::I64 => Ok(IType::S64),
|
||||||
ParsedType::U8 => IType::U8,
|
ParsedType::U8 => Ok(IType::U8),
|
||||||
ParsedType::U16 => IType::U16,
|
ParsedType::U16 => Ok(IType::U16),
|
||||||
ParsedType::U32 => IType::U32,
|
ParsedType::U32 => Ok(IType::U32),
|
||||||
ParsedType::U64 => IType::U64,
|
ParsedType::U64 => Ok(IType::U64),
|
||||||
ParsedType::F32 => IType::F32,
|
ParsedType::F32 => Ok(IType::F32),
|
||||||
ParsedType::F64 => IType::F64,
|
ParsedType::F64 => Ok(IType::F64),
|
||||||
ParsedType::Boolean => IType::I32,
|
ParsedType::Boolean => Ok(IType::I32),
|
||||||
ParsedType::Utf8String => IType::String,
|
ParsedType::Utf8String => Ok(IType::String),
|
||||||
ParsedType::ByteVector => IType::ByteArray,
|
ParsedType::ByteVector => Ok(IType::ByteArray),
|
||||||
ParsedType::Record(_) => unimplemented!(),
|
ParsedType::Record(record_name) => {
|
||||||
|
Ok(IType::Record(wit_resolver.get_record_type(record_name)?))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -28,20 +28,30 @@ pub fn embed_wit(path: std::path::PathBuf) -> Result<()> {
|
|||||||
.parse_file(path.clone())
|
.parse_file(path.clone())
|
||||||
.map_err(|e| WITGeneratorError::IOError(format!("{:?} can't be parsed: {:?}", path, e)))?;
|
.map_err(|e| WITGeneratorError::IOError(format!("{:?} can't be parsed: {:?}", path, e)))?;
|
||||||
|
|
||||||
let ast_set = wasm_ast_extractor(&wasm_module)?;
|
let module_ast = wasm_ast_extractor(&wasm_module)?;
|
||||||
let interfaces = generate_interfaces(&ast_set);
|
let interfaces = generate_interfaces(&module_ast)?;
|
||||||
|
|
||||||
let wasm_module = wit_parser::delete_wit_section(wasm_module);
|
let wasm_module = wit_parser::delete_wit_section(wasm_module);
|
||||||
let mut wasm_module = wit_parser::embed_wit(wasm_module, &interfaces);
|
let mut wasm_module = wit_parser::embed_wit(wasm_module, &interfaces);
|
||||||
|
|
||||||
wasm_module.emit_wasm_file(path).map_err(|e| {
|
wasm_module.emit_wasm_file(path).map_err(|e| {
|
||||||
WITGeneratorError::IOError(format!("resulted Wasm fule can't be emitted: {:?}", e))
|
WITGeneratorError::IOError(format!("resulted Wasm file can't be emitted: {:?}", e))
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub(crate) struct ModuleAST {
|
||||||
|
pub(crate) records: Vec<fluence_sdk_wit::AstRecordItem>,
|
||||||
|
pub(crate) functions: Vec<fluence_sdk_wit::AstFunctionItem>,
|
||||||
|
pub(crate) extern_mods: Vec<fluence_sdk_wit::AstExternModItem>,
|
||||||
|
}
|
||||||
|
|
||||||
/// Extract all custom AST types previously embedded by rust-sdk from compiled binary.
|
/// Extract all custom AST types previously embedded by rust-sdk from compiled binary.
|
||||||
fn wasm_ast_extractor(wasm_module: &walrus::Module) -> Result<Vec<fluence_sdk_wit::FCEAst>> {
|
fn wasm_ast_extractor(wasm_module: &walrus::Module) -> Result<ModuleAST> {
|
||||||
let mut extracted_ast = Vec::new();
|
use fluence_sdk_wit::*;
|
||||||
|
|
||||||
|
let mut records: Vec<AstRecordItem> = Vec::new();
|
||||||
|
let mut functions: Vec<AstFunctionItem> = Vec::new();
|
||||||
|
let mut extern_mods: Vec<AstExternModItem> = Vec::new();
|
||||||
|
|
||||||
// consider only sections name of that starts with GENERATED_SECTION_PREFIX
|
// consider only sections name of that starts with GENERATED_SECTION_PREFIX
|
||||||
for custom_module in wasm_module.customs.iter().filter(|(_, section)| {
|
for custom_module in wasm_module.customs.iter().filter(|(_, section)| {
|
||||||
@ -51,22 +61,36 @@ fn wasm_ast_extractor(wasm_module: &walrus::Module) -> Result<Vec<fluence_sdk_wi
|
|||||||
}) {
|
}) {
|
||||||
let default_ids = walrus::IdsToIndices::default();
|
let default_ids = walrus::IdsToIndices::default();
|
||||||
let raw_data = custom_module.1.data(&default_ids);
|
let raw_data = custom_module.1.data(&default_ids);
|
||||||
let decoded_json: fluence_sdk_wit::FCEAst = serde_json::from_slice(&raw_data)?;
|
let decoded_json: FCEAst = serde_json::from_slice(&raw_data)?;
|
||||||
extracted_ast.push(decoded_json);
|
match decoded_json {
|
||||||
|
FCEAst::Record(record) => records.push(record),
|
||||||
|
FCEAst::Function(function) => functions.push(function),
|
||||||
|
FCEAst::ExternMod(extern_mod) => extern_mods.push(extern_mod),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(extracted_ast)
|
Ok(ModuleAST {
|
||||||
|
records,
|
||||||
|
functions,
|
||||||
|
extern_mods,
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fn generate_interfaces(ast_set: &[FCEAst]) -> Interfaces<'_> {
|
fn generate_interfaces(module_ast: &ModuleAST) -> Result<Interfaces<'_>> {
|
||||||
let mut interfaces = Interfaces::default();
|
let mut wit_resolver = crate::instructions_generator::WITResolver::default();
|
||||||
generate_default_export_api(&mut interfaces);
|
generate_default_export_api(&mut wit_resolver.interfaces);
|
||||||
|
|
||||||
for ast in ast_set {
|
for record in &module_ast.records {
|
||||||
ast.generate_wit(&mut interfaces);
|
record.generate_wit(&mut wit_resolver)?;
|
||||||
|
}
|
||||||
|
for function in &module_ast.functions {
|
||||||
|
function.generate_wit(&mut wit_resolver)?;
|
||||||
|
}
|
||||||
|
for extern_mod in &module_ast.extern_mods {
|
||||||
|
extern_mod.generate_wit(&mut wit_resolver)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
interfaces
|
Ok(wit_resolver.interfaces)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn generate_default_export_api(interfaces: &mut Interfaces) {
|
fn generate_default_export_api(interfaces: &mut Interfaces) {
|
||||||
|
@ -11,7 +11,7 @@ path = "src/lib.rs"
|
|||||||
[dependencies]
|
[dependencies]
|
||||||
walrus = "0.17.0"
|
walrus = "0.17.0"
|
||||||
wasmer-core = { package = "wasmer-runtime-core", git = "https://github.com/fluencelabs/wasmer", branch = "fluence" }
|
wasmer-core = { package = "wasmer-runtime-core", git = "https://github.com/fluencelabs/wasmer", branch = "fluence" }
|
||||||
wasmer-wit = { package = "wasmer-interface-types", git = "https://github.com/fluencelabs/interface-types", branch = "byte_array" }
|
wasmer-wit = { package = "wasmer-interface-types", git = "https://github.com/fluencelabs/interface-types", branch = "struct_support" }
|
||||||
fce-wit-interfaces = { path = "../fce-wit-interfaces" }
|
fce-wit-interfaces = { path = "../fce-wit-interfaces" }
|
||||||
|
|
||||||
anyhow = "1.0.31"
|
anyhow = "1.0.31"
|
||||||
|
@ -11,7 +11,7 @@ wit-parser = { path = "../crates/wit-parser", version = "0.1.0" }
|
|||||||
wasmer-runtime = { git = "https://github.com/fluencelabs/wasmer", branch = "fluence" }
|
wasmer-runtime = { git = "https://github.com/fluencelabs/wasmer", branch = "fluence" }
|
||||||
# dynamicfunc-fat-closures allows using state inside DynamicFunc
|
# dynamicfunc-fat-closures allows using state inside DynamicFunc
|
||||||
wasmer-core = { package = "wasmer-runtime-core", git = "http://github.com/fluencelabs/wasmer", branch = "fluence", features = ["dynamicfunc-fat-closures"] }
|
wasmer-core = { package = "wasmer-runtime-core", git = "http://github.com/fluencelabs/wasmer", branch = "fluence", features = ["dynamicfunc-fat-closures"] }
|
||||||
wasmer-wit = { package = "wasmer-interface-types", git = "http://github.com/fluencelabs/interface-types", branch = "byte_array", features = ["serde"] }
|
wasmer-wit = { package = "wasmer-interface-types", git = "http://github.com/fluencelabs/interface-types", branch = "struct_support", features = ["serde"] }
|
||||||
wasmer-wasi = { git = "https://github.com/fluencelabs/wasmer", branch = "fluence" }
|
wasmer-wasi = { git = "https://github.com/fluencelabs/wasmer", branch = "fluence" }
|
||||||
serde = { version = "1.0.114", default-features = false, features = [ "derive" ] }
|
serde = { version = "1.0.114", default-features = false, features = [ "derive" ] }
|
||||||
|
|
||||||
|
@ -9,5 +9,5 @@ name = "ipfs_rpc"
|
|||||||
path = "src/main.rs"
|
path = "src/main.rs"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
fluence = { git = "https://github.com/fluencelabs/rust-sdk", features = ["logger"] }
|
fluence = { path = "/Users/mike/dev/work/fluence/wasm/rust-sdk", features = ["logger"] }
|
||||||
log = "0.4.11"
|
log = "0.4.11"
|
||||||
|
205
examples/ipfs_node/wasm/ipfs_rpc/expand.rs
Normal file
205
examples/ipfs_node/wasm/ipfs_rpc/expand.rs
Normal file
@ -0,0 +1,205 @@
|
|||||||
|
#![feature(prelude_import)]
|
||||||
|
#[prelude_import]
|
||||||
|
use std::prelude::v1::*;
|
||||||
|
#[macro_use]
|
||||||
|
extern crate std;
|
||||||
|
use fluence::fce;
|
||||||
|
use fluence::WasmLogger;
|
||||||
|
use std::fs;
|
||||||
|
use std::path::PathBuf;
|
||||||
|
const RPC_TMP_FILEPATH: &str = "/tmp/ipfs_rpc_file";
|
||||||
|
pub fn main() {
|
||||||
|
WasmLogger::init_with_level(log::Level::Info).unwrap();
|
||||||
|
}
|
||||||
|
pub struct Asadasd {
|
||||||
|
pub a: i32,
|
||||||
|
}
|
||||||
|
#[cfg(target_arch = "wasm32")]
|
||||||
|
#[doc(hidden)]
|
||||||
|
#[allow(clippy::all)]
|
||||||
|
pub(crate) fn __fce_generated_record_serializer_Asadasd(record: Asadasd) -> i32 {
|
||||||
|
let mut raw_record = Vec::new();
|
||||||
|
raw_record.push(record.a as u64);
|
||||||
|
let raw_record_ptr = raw_record.as_ptr();
|
||||||
|
std::mem::forget(raw_record);
|
||||||
|
raw_record_ptr as _
|
||||||
|
}
|
||||||
|
#[cfg(target_arch = "wasm32")]
|
||||||
|
#[doc(hidden)]
|
||||||
|
#[allow(clippy::all)]
|
||||||
|
unsafe fn __fce_generated_record_deserializer_Asadasd(offset: i32, size: i32) -> Asadasd {
|
||||||
|
let raw_record: Vec<u64> = Vec::from_raw_parts(offset as _, size as _, size as _);
|
||||||
|
let field_0 = raw_record[0usize] as i32;
|
||||||
|
Asadasd { a: field_0 }
|
||||||
|
}
|
||||||
|
#[cfg(target_arch = "wasm32")]
|
||||||
|
#[doc(hidden)]
|
||||||
|
#[allow(clippy::all)]
|
||||||
|
#[link_section = "__fce_generated_section__Asadasd"]
|
||||||
|
pub static __fce_generated_static_global_Asadasd: [u8; 73usize] = {
|
||||||
|
*b"{\"ast_type\":\"Record\",\"name\":\"Asadasd\",\"fields\":[{\"name\":\"a\",\"ty\":\"I32\"}]}"
|
||||||
|
};
|
||||||
|
pub fn invoke(_a: Asadasd) -> String {
|
||||||
|
"IPFS_RPC wasm example, it allows to:\ninvoke\nput\nget".to_string()
|
||||||
|
}
|
||||||
|
#[export_name = "invoke"]
|
||||||
|
#[no_mangle]
|
||||||
|
#[doc(hidden)]
|
||||||
|
#[allow(clippy::all)]
|
||||||
|
pub unsafe fn __fce_generated_wrapper_func_invoke(arg_0: i32, arg_1: i32) {
|
||||||
|
let converted_arg_0 = __fce_generated_record_deserializer_Asadasd(arg_0, arg_1);
|
||||||
|
let result = invoke(converted_arg_0);
|
||||||
|
fluence::internal::set_result_ptr(result.as_ptr() as _);
|
||||||
|
fluence::internal::set_result_size(result.len() as _);
|
||||||
|
std::mem::forget(result);
|
||||||
|
}
|
||||||
|
#[cfg(target_arch = "wasm32")]
|
||||||
|
#[doc(hidden)]
|
||||||
|
#[allow(clippy::all)]
|
||||||
|
#[link_section = "__fce_generated_section__invoke"]
|
||||||
|
pub static __fce_generated_static_global_invoke: [u8; 117usize] = {
|
||||||
|
* b"{\"ast_type\":\"Function\",\"signature\":{\"name\":\"invoke\",\"input_types\":[{\"Record\":\"Asadasd\"}],\"output_type\":\"Utf8String\"}}"
|
||||||
|
};
|
||||||
|
pub fn put(file_content: Vec<u8>) -> String {
|
||||||
|
{
|
||||||
|
let lvl = ::log::Level::Info;
|
||||||
|
if lvl <= ::log::STATIC_MAX_LEVEL && lvl <= ::log::max_level() {
|
||||||
|
::log::__private_api_log(
|
||||||
|
::core::fmt::Arguments::new_v1(
|
||||||
|
&["put called with "],
|
||||||
|
&match (&file_content,) {
|
||||||
|
(arg0,) => [::core::fmt::ArgumentV1::new(arg0, ::core::fmt::Debug::fmt)],
|
||||||
|
},
|
||||||
|
),
|
||||||
|
lvl,
|
||||||
|
&(
|
||||||
|
"ipfs_rpc",
|
||||||
|
"ipfs_rpc",
|
||||||
|
"examples/ipfs_node/wasm/ipfs_rpc/src/main.rs",
|
||||||
|
41u32,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
let rpc_tmp_filepath = RPC_TMP_FILEPATH.to_string();
|
||||||
|
let r = fs::write(PathBuf::from(rpc_tmp_filepath.clone()), file_content);
|
||||||
|
if let Err(e) = r {
|
||||||
|
return {
|
||||||
|
let res = ::alloc::fmt::format(::core::fmt::Arguments::new_v1(
|
||||||
|
&["file can\'t be written: "],
|
||||||
|
&match (&e,) {
|
||||||
|
(arg0,) => [::core::fmt::ArgumentV1::new(
|
||||||
|
arg0,
|
||||||
|
::core::fmt::Display::fmt,
|
||||||
|
)],
|
||||||
|
},
|
||||||
|
));
|
||||||
|
res
|
||||||
|
};
|
||||||
|
}
|
||||||
|
ipfs_put(rpc_tmp_filepath)
|
||||||
|
}
|
||||||
|
#[export_name = "put"]
|
||||||
|
#[no_mangle]
|
||||||
|
#[doc(hidden)]
|
||||||
|
#[allow(clippy::all)]
|
||||||
|
pub unsafe fn __fce_generated_wrapper_func_put(arg_0: i32, arg_1: i32) {
|
||||||
|
let converted_arg_0 = Vec::from_raw_parts(arg_0 as _, arg_1 as _, arg_1 as _);
|
||||||
|
let result = put(converted_arg_0);
|
||||||
|
fluence::internal::set_result_ptr(result.as_ptr() as _);
|
||||||
|
fluence::internal::set_result_size(result.len() as _);
|
||||||
|
std::mem::forget(result);
|
||||||
|
}
|
||||||
|
#[cfg(target_arch = "wasm32")]
|
||||||
|
#[doc(hidden)]
|
||||||
|
#[allow(clippy::all)]
|
||||||
|
#[link_section = "__fce_generated_section__put"]
|
||||||
|
pub static __fce_generated_static_global_put: [u8; 106usize] = {
|
||||||
|
* b"{\"ast_type\":\"Function\",\"signature\":{\"name\":\"put\",\"input_types\":[\"ByteVector\"],\"output_type\":\"Utf8String\"}}"
|
||||||
|
};
|
||||||
|
pub fn get(hash: String) -> Vec<u8> {
|
||||||
|
{
|
||||||
|
let lvl = ::log::Level::Info;
|
||||||
|
if lvl <= ::log::STATIC_MAX_LEVEL && lvl <= ::log::max_level() {
|
||||||
|
::log::__private_api_log(
|
||||||
|
::core::fmt::Arguments::new_v1(
|
||||||
|
&["get called with hash: "],
|
||||||
|
&match (&hash,) {
|
||||||
|
(arg0,) => [::core::fmt::ArgumentV1::new(
|
||||||
|
arg0,
|
||||||
|
::core::fmt::Display::fmt,
|
||||||
|
)],
|
||||||
|
},
|
||||||
|
),
|
||||||
|
lvl,
|
||||||
|
&(
|
||||||
|
"ipfs_rpc",
|
||||||
|
"ipfs_rpc",
|
||||||
|
"examples/ipfs_node/wasm/ipfs_rpc/src/main.rs",
|
||||||
|
55u32,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
let file_path = ipfs_get(hash);
|
||||||
|
fs::read(file_path).unwrap_or_else(|_| b"error while reading file".to_vec())
|
||||||
|
}
|
||||||
|
#[export_name = "get"]
|
||||||
|
#[no_mangle]
|
||||||
|
#[doc(hidden)]
|
||||||
|
#[allow(clippy::all)]
|
||||||
|
pub unsafe fn __fce_generated_wrapper_func_get(arg_0: i32, arg_1: i32) {
|
||||||
|
let converted_arg_0 = String::from_raw_parts(arg_0 as _, arg_1 as _, arg_1 as _);
|
||||||
|
let result = get(converted_arg_0);
|
||||||
|
fluence::internal::set_result_ptr(result.as_ptr() as _);
|
||||||
|
fluence::internal::set_result_size(result.len() as _);
|
||||||
|
std::mem::forget(result);
|
||||||
|
}
|
||||||
|
#[cfg(target_arch = "wasm32")]
|
||||||
|
#[doc(hidden)]
|
||||||
|
#[allow(clippy::all)]
|
||||||
|
#[link_section = "__fce_generated_section__get"]
|
||||||
|
pub static __fce_generated_static_global_get: [u8; 106usize] = {
|
||||||
|
* b"{\"ast_type\":\"Function\",\"signature\":{\"name\":\"get\",\"input_types\":[\"Utf8String\"],\"output_type\":\"ByteVector\"}}"
|
||||||
|
};
|
||||||
|
#[link(wasm_import_module = "ipfs_node.wasm")]
|
||||||
|
#[cfg(target_arch = "wasm32")]
|
||||||
|
extern "C" {
|
||||||
|
#[link_name = "put"]
|
||||||
|
fn __fce_generated_wrapper_func__ipfs_put(arg_0: i32, arg_1: i32);
|
||||||
|
#[link_name = "get"]
|
||||||
|
fn __fce_generated_wrapper_func__ipfs_get(arg_0: i32, arg_1: i32);
|
||||||
|
}
|
||||||
|
#[cfg(target_arch = "wasm32")]
|
||||||
|
#[doc(hidden)]
|
||||||
|
#[allow(clippy::all)]
|
||||||
|
pub fn ipfs_put(arg_0: String) -> String {
|
||||||
|
unsafe {
|
||||||
|
let result = __fce_generated_wrapper_func__ipfs_put(arg_0.as_ptr() as _, arg_0.len() as _);
|
||||||
|
String::from_raw_parts(
|
||||||
|
fluence::internal::get_result_ptr() as _,
|
||||||
|
fluence::internal::get_result_size() as _,
|
||||||
|
fluence::internal::get_result_size() as _,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#[cfg(target_arch = "wasm32")]
|
||||||
|
#[doc(hidden)]
|
||||||
|
#[allow(clippy::all)]
|
||||||
|
pub fn ipfs_get(arg_0: String) -> String {
|
||||||
|
unsafe {
|
||||||
|
let result = __fce_generated_wrapper_func__ipfs_get(arg_0.as_ptr() as _, arg_0.len() as _);
|
||||||
|
String::from_raw_parts(
|
||||||
|
fluence::internal::get_result_ptr() as _,
|
||||||
|
fluence::internal::get_result_size() as _,
|
||||||
|
fluence::internal::get_result_size() as _,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#[cfg(target_arch = "wasm32")]
|
||||||
|
#[doc(hidden)]
|
||||||
|
#[allow(clippy::all)]
|
||||||
|
#[link_section = "__fce_generated_section__ipfs_node_wasm"]
|
||||||
|
pub static __fce_generated_static_global_ipfs_node_wasm: [u8; 281usize] = {
|
||||||
|
* b"{\"ast_type\":\"ExternMod\",\"namespace\":\"ipfs_node.wasm\",\"imports\":[{\"link_name\":\"put\",\"signature\":{\"name\":\"ipfs_put\",\"input_types\":[\"Utf8String\"],\"output_type\":\"Utf8String\"}},{\"link_name\":\"get\",\"signature\":{\"name\":\"ipfs_get\",\"input_types\":[\"Utf8String\"],\"output_type\":\"Utf8String\"}}]}"
|
||||||
|
};
|
@ -27,7 +27,12 @@ pub fn main() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[fce]
|
#[fce]
|
||||||
pub fn invoke() -> String {
|
pub struct Asadasd {
|
||||||
|
pub a: i32,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[fce]
|
||||||
|
pub fn invoke(_a: Asadasd) -> String {
|
||||||
"IPFS_RPC wasm example, it allows to:\ninvoke\nput\nget".to_string()
|
"IPFS_RPC wasm example, it allows to:\ninvoke\nput\nget".to_string()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user