Improve arrays and record passing scheme (#76)

This commit is contained in:
vms 2021-04-26 14:02:26 +03:00 committed by GitHub
parent c702311595
commit 96c32b64d8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
79 changed files with 1109 additions and 1079 deletions

224
Cargo.lock generated
View File

@ -43,11 +43,10 @@ checksum = "28b2cd92db5cbd74e8e5028f7e27dd7aa3090e89e4f2a197cc7c8dfb69c7063b"
[[package]]
name = "aqua-interpreter-interface"
version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f4c49b8a5fe1336a9c6981be09cb13706c7d9083e48588d692120b5080a13278"
version = "0.4.0"
source = "git+https://github.com/fluencelabs/air?branch=bwu#ba3809ae175217ab20cb2763d5bb7612da982906"
dependencies = [
"fluence 0.2.18",
"fluence",
"fluence-it-types",
"serde",
]
@ -69,7 +68,7 @@ dependencies = [
name = "arguments-passing-test"
version = "0.1.0"
dependencies = [
"fluence 0.6.0",
"fluence",
"safe-transmute",
]
@ -83,7 +82,7 @@ checksum = "a4c527152e37cf757a3f78aae5a06fbeefdb07ccc535c980a3208ee3060dd544"
name = "arrays-passing-test"
version = "0.1.0"
dependencies = [
"fluence 0.6.0",
"fluence",
"safe-transmute",
]
@ -112,9 +111,9 @@ checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a"
[[package]]
name = "backtrace"
version = "0.3.56"
version = "0.3.57"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9d117600f438b1707d4e4ae15d3595657288f8235a0eb593e80ecc98ab34e1bc"
checksum = "78ed203b9ba68b242c62b3fb7480f589dd49829be1edb3fe8fc8b4ffda2dcb8d"
dependencies = [
"addr2line",
"cfg-if 1.0.0",
@ -205,7 +204,7 @@ checksum = "b700ce4376041dcd0a327fd0097c41095743c4c8af8887265942faf1100bd040"
name = "call_parameters"
version = "0.1.0"
dependencies = [
"fluence 0.6.0",
"fluence",
]
[[package]]
@ -445,7 +444,7 @@ dependencies = [
name = "curl_adapter"
version = "0.1.0"
dependencies = [
"fluence 0.6.0",
"fluence",
"log",
]
@ -650,7 +649,7 @@ name = "facade"
version = "0.1.0"
dependencies = [
"anyhow",
"fluence 0.6.0",
"fluence",
"log",
]
@ -688,13 +687,14 @@ dependencies = [
"fce-wit-generator",
"fce-wit-interfaces",
"fce-wit-parser",
"it-lilo",
"log",
"multimap",
"once_cell",
"parity-wasm",
"paste",
"pwasm-utils",
"reqwest 0.10.10",
"safe-transmute",
"semver 0.11.0",
"serde",
"thiserror",
@ -711,7 +711,7 @@ version = "0.1.0"
dependencies = [
"anyhow",
"chrono",
"fluence-sdk-main 0.6.0",
"fluence-sdk-main",
"semver 0.11.0",
"serde",
"thiserror",
@ -722,15 +722,15 @@ dependencies = [
[[package]]
name = "fce-sqlite-connector"
version = "0.3.0"
source = "git+https://github.com/fluencelabs/sqlite-wasm-connector?branch=fluence_0_6_0#6cf624a62b27d35351aa390cfa20b3358655fe1f"
source = "git+https://github.com/fluencelabs/sqlite-wasm-connector?branch=fluence_0_6_0#adf0dbbcc706520019380593f4db5d8c19c7a1c5"
dependencies = [
"fluence 0.6.0",
"fluence",
]
[[package]]
name = "fce-timestamp-macro"
version = "0.6.0"
source = "git+https://github.com/fluencelabs/rust-sdk#1755202195c1e2a86c962219ac1420664afe3d49"
source = "git+https://github.com/fluencelabs/rust-sdk#e8bc1db0dff8550b97675d4835cf17e0f27848ef"
dependencies = [
"chrono",
"quote",
@ -746,10 +746,12 @@ version = "0.3.0"
dependencies = [
"cargo_toml",
"fce-wit-parser",
"fluence-sdk-wit 0.6.0",
"fluence-sdk-wit",
"it-lilo",
"once_cell",
"serde",
"serde_json",
"thiserror",
"walrus",
"wasmer-interface-types-fl",
]
@ -768,6 +770,7 @@ version = "0.4.0"
dependencies = [
"anyhow",
"fce-wit-interfaces",
"nom",
"semver 0.11.0",
"serde",
"thiserror",
@ -791,27 +794,18 @@ dependencies = [
"serde",
"serde_json",
"termion",
"thiserror",
"walrus",
]
[[package]]
name = "fluence"
version = "0.2.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "27d9a5e4292d7bbd809a0e968e3c3aacac91cbc5acab3e26ee1e1d726f0aab24"
dependencies = [
"fluence-sdk-macro 0.2.18",
"fluence-sdk-main 0.2.18",
]
[[package]]
name = "fluence"
version = "0.6.0"
source = "git+https://github.com/fluencelabs/rust-sdk#1755202195c1e2a86c962219ac1420664afe3d49"
source = "git+https://github.com/fluencelabs/rust-sdk#e8bc1db0dff8550b97675d4835cf17e0f27848ef"
dependencies = [
"fce-timestamp-macro",
"fluence-sdk-macro 0.6.0",
"fluence-sdk-main 0.6.0",
"fluence-sdk-macro",
"fluence-sdk-main",
"serde",
]
@ -837,9 +831,9 @@ dependencies = [
"env_logger 0.7.1",
"fce",
"fce-utils",
"fluence 0.6.0",
"fluence-sdk-main 0.6.0",
"itertools",
"fluence",
"fluence-sdk-main",
"itertools 0.9.0",
"log",
"once_cell",
"pretty_assertions",
@ -857,9 +851,9 @@ dependencies = [
[[package]]
name = "fluence-it-types"
version = "0.1.1"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1b81c770e52b35e2406f8251f6c01b3b882c3eaed3029731d8c19c74dc1b423c"
checksum = "5006d09553345421af5dd2334cc945fc34dc2a73d7c1ed842a39a3803699619d"
dependencies = [
"it-to-bytes",
"nom",
@ -867,62 +861,28 @@ dependencies = [
"wast",
]
[[package]]
name = "fluence-sdk-macro"
version = "0.2.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ea1a7c75a617f827d1ba9a17b4d84e1565ab239915c63f5a85c41f89a9f1d4ba"
dependencies = [
"fluence-sdk-wit 0.2.18",
]
[[package]]
name = "fluence-sdk-macro"
version = "0.6.0"
source = "git+https://github.com/fluencelabs/rust-sdk#1755202195c1e2a86c962219ac1420664afe3d49"
source = "git+https://github.com/fluencelabs/rust-sdk#e8bc1db0dff8550b97675d4835cf17e0f27848ef"
dependencies = [
"fluence-sdk-wit 0.6.0",
]
[[package]]
name = "fluence-sdk-main"
version = "0.2.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6edcc983f9517c1b6bf9f851ef27f2894a3159aaa4a2fb6c9deb2ae8ecb603fa"
dependencies = [
"fluence-sdk-macro 0.2.18",
"log",
"serde",
"fluence-sdk-wit",
]
[[package]]
name = "fluence-sdk-main"
version = "0.6.0"
source = "git+https://github.com/fluencelabs/rust-sdk#1755202195c1e2a86c962219ac1420664afe3d49"
source = "git+https://github.com/fluencelabs/rust-sdk#e8bc1db0dff8550b97675d4835cf17e0f27848ef"
dependencies = [
"fluence-sdk-macro 0.6.0",
"fluence-sdk-macro",
"log",
"serde",
]
[[package]]
name = "fluence-sdk-wit"
version = "0.2.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b75dbdd0275160f3818db3218563d791e6c612b616cd3c5d6e66283f207f648d"
dependencies = [
"proc-macro2",
"quote",
"serde",
"serde_json",
"syn",
"uuid",
]
[[package]]
name = "fluence-sdk-wit"
version = "0.6.0"
source = "git+https://github.com/fluencelabs/rust-sdk#1755202195c1e2a86c962219ac1420664afe3d49"
source = "git+https://github.com/fluencelabs/rust-sdk#e8bc1db0dff8550b97675d4835cf17e0f27848ef"
dependencies = [
"proc-macro2",
"quote",
@ -972,8 +932,8 @@ dependencies = [
"clap",
"env_logger 0.7.1",
"fluence-app-service",
"fluence-sdk-main 0.6.0",
"itertools",
"fluence-sdk-main",
"itertools 0.9.0",
"log",
"rustop",
"rustyline",
@ -1244,9 +1204,9 @@ dependencies = [
[[package]]
name = "httparse"
version = "1.3.6"
version = "1.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bc35c995b9d93ec174cf9a27d425c7892722101e14993cd227fdb51d70cf9589"
checksum = "4a1ce40d6fc9764887c2fdc7305c3dcc429ba11ff981c1509416afd5697e4437"
[[package]]
name = "httpdate"
@ -1254,6 +1214,12 @@ version = "0.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "494b4d60369511e7dea41cf646832512a94e542f68bb9c49e54518e0f468eb47"
[[package]]
name = "httpdate"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "05842d0d43232b23ccb7060ecb0f0626922c21f30012e97b767b30afd4a5d4b9"
[[package]]
name = "humantime"
version = "1.3.0"
@ -1277,7 +1243,7 @@ dependencies = [
"http",
"http-body 0.3.1",
"httparse",
"httpdate",
"httpdate 0.3.2",
"itoa",
"pin-project",
"socket2 0.3.19",
@ -1289,9 +1255,9 @@ dependencies = [
[[package]]
name = "hyper"
version = "0.14.5"
version = "0.14.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8bf09f61b52cfcf4c00de50df88ae423d6c02354e385a86341133b5338630ad1"
checksum = "1e5f105c494081baa3bf9e200b279e27ec1623895cd504c7dbef8d0b080fcf54"
dependencies = [
"bytes 1.0.1",
"futures-channel",
@ -1301,7 +1267,7 @@ dependencies = [
"http",
"http-body 0.4.1",
"httparse",
"httpdate",
"httpdate 1.0.0",
"itoa",
"pin-project",
"socket2 0.4.0",
@ -1331,7 +1297,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d6183ddfa99b85da61a140bea0efc93fdf56ceaa041b37d553518030827f9905"
dependencies = [
"bytes 1.0.1",
"hyper 0.14.5",
"hyper 0.14.7",
"native-tls",
"tokio 1.5.0",
"tokio-native-tls",
@ -1415,7 +1381,7 @@ dependencies = [
name = "ipfs-effector"
version = "0.1.0"
dependencies = [
"fluence 0.6.0",
"fluence",
"log",
]
@ -1423,7 +1389,7 @@ dependencies = [
name = "ipfs-pure"
version = "0.1.0"
dependencies = [
"fluence 0.6.0",
"fluence",
"log",
]
@ -1433,6 +1399,18 @@ version = "2.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "47be2f14c678be2fdcab04ab1171db51b2762ce6f0a8ee87c8dd4a04ed216135"
[[package]]
name = "it-lilo"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "99ccf40e1e08f6f47ffbafe3cfb2e3adb721ddde80b178240f038d07dc9652fb"
dependencies = [
"fluence-it-types",
"log",
"paste",
"thiserror",
]
[[package]]
name = "it-to-bytes"
version = "0.1.0"
@ -1448,6 +1426,15 @@ dependencies = [
"either",
]
[[package]]
name = "itertools"
version = "0.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "37d572918e350e82412fe766d24b15e6682fb2ed2bbe018280caa810397cb319"
dependencies = [
"either",
]
[[package]]
name = "itoa"
version = "0.4.7"
@ -1487,9 +1474,9 @@ checksum = "3576a87f2ba00f6f106fdfcd16db1d698d648a26ad8e0573cad8537c3c362d2a"
[[package]]
name = "lexical-core"
version = "0.7.5"
version = "0.7.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "21f866863575d0e1d654fbeeabdc927292fdf862873dc3c96c6f753357e13374"
checksum = "6607c62aa161d23d17a9072cc5da0be67cdfc89d3afb1e8d9c842bebc2525ffe"
dependencies = [
"arrayvec",
"bitflags",
@ -1508,8 +1495,9 @@ checksum = "9385f66bf6105b241aa65a61cb923ef20efc665cb9f9bb50ac2f0c4b7f378d41"
name = "local_storage"
version = "0.1.0"
dependencies = [
"fluence 0.6.0",
"fluence",
"log",
"wasm-tracing-allocator",
]
[[package]]
@ -1905,6 +1893,12 @@ dependencies = [
"winapi 0.3.9",
]
[[package]]
name = "paste"
version = "1.0.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "acbf547ad0c65e31259204bd90935776d1c693cec2f4ff7abb7a1bbbd40dfe58"
[[package]]
name = "percent-encoding"
version = "2.1.0"
@ -1922,18 +1916,18 @@ dependencies = [
[[package]]
name = "pin-project"
version = "1.0.6"
version = "1.0.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bc174859768806e91ae575187ada95c91a29e96a98dc5d2cd9a1fed039501ba6"
checksum = "c7509cc106041c40a4518d2af7a61530e1eed0e6285296a3d8c5472806ccc4a4"
dependencies = [
"pin-project-internal",
]
[[package]]
name = "pin-project-internal"
version = "1.0.6"
version = "1.0.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a490329918e856ed1b083f244e3bfe2d8c4f336407e4ea9e1a9f479ff09049e5"
checksum = "48c950132583b500556b1efd71d45b319029f2b71518d979fcc208e16b42426f"
dependencies = [
"proc-macro2",
"quote",
@ -2097,7 +2091,7 @@ dependencies = [
name = "record-effector"
version = "0.1.0"
dependencies = [
"fluence 0.6.0",
"fluence",
"test-record",
]
@ -2105,7 +2099,7 @@ dependencies = [
name = "record-pure"
version = "0.1.0"
dependencies = [
"fluence 0.6.0",
"fluence",
"test-record",
]
@ -2113,7 +2107,7 @@ dependencies = [
name = "records-passing-test"
version = "0.1.0"
dependencies = [
"fluence 0.6.0",
"fluence",
"safe-transmute",
]
@ -2164,9 +2158,9 @@ dependencies = [
[[package]]
name = "regex"
version = "1.4.5"
version = "1.4.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "957056ecddbeba1b26965114e191d2e8589ce74db242b6ea25fc4062427a5c19"
checksum = "2a26af418b574bd56588335b3a3659a65725d4e636eb1016c2f9e3b38c7cc759"
dependencies = [
"aho-corasick",
"memchr",
@ -2236,7 +2230,7 @@ dependencies = [
"futures-util",
"http",
"http-body 0.4.1",
"hyper 0.14.5",
"hyper 0.14.7",
"hyper-tls 0.5.0",
"ipnet",
"js-sys",
@ -2501,9 +2495,9 @@ dependencies = [
[[package]]
name = "slab"
version = "0.4.2"
version = "0.4.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c111b5bd5695e56cffe5129854aa230b39c93a305372fdbb2668ca2394eea9f8"
checksum = "f173ac3d1a7e3b28003f40de0b5ce7fe2710f9b9dc3fc38664cebee46b3b6527"
[[package]]
name = "smallvec"
@ -2558,9 +2552,9 @@ checksum = "1e81da0851ada1f3e9d4312c704aa4f8806f0f9d69faaf8df2f3464b4a9437c2"
[[package]]
name = "syn"
version = "1.0.69"
version = "1.0.70"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "48fe99c6bd8b1cc636890bcc071842de909d902c81ac7dab53ba33c421ab8ffb"
checksum = "b9505f307c872bab8eb46f77ae357c8eba1fdacead58ee5a850116b1d7f82883"
dependencies = [
"proc-macro2",
"quote",
@ -2635,7 +2629,7 @@ dependencies = [
name = "test-record"
version = "0.1.0"
dependencies = [
"fluence 0.6.0",
"fluence",
]
[[package]]
@ -2985,9 +2979,9 @@ dependencies = [
[[package]]
name = "vcpkg"
version = "0.2.11"
version = "0.2.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b00bca6106a5e23f3eee943593759b7fcddb00554332e856d990c893966879fb"
checksum = "cbdbff6266a24120518560b5dc983096efb98462e51d0d68169895b237be3e5d"
[[package]]
name = "vec_map"
@ -3136,7 +3130,7 @@ checksum = "d9a543ae66aa233d14bb765ed9af4a33e81b8b58d1584cf1b47ff8cd0b9e4489"
name = "wasm-greeting"
version = "0.1.0"
dependencies = [
"fluence 0.6.0",
"fluence",
]
[[package]]
@ -3144,7 +3138,16 @@ name = "wasm-sqlite-test"
version = "0.1.0"
dependencies = [
"fce-sqlite-connector",
"fluence 0.6.0",
"fluence",
]
[[package]]
name = "wasm-tracing-allocator"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "00638b0f463575ce0ad7fe03809c9b86b2a3abbb6c1f2e4d5569572b74ca65ae"
dependencies = [
"wasm-bindgen",
]
[[package]]
@ -3201,18 +3204,21 @@ dependencies = [
[[package]]
name = "wasmer-interface-types-fl"
version = "0.19.0"
version = "0.20.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "be2004c1e24c8d51bd7732b8cbd968c6015b2d766fb31d19794c3ea3474cc297"
checksum = "b47648f6ed55acbd6ddf2a4efed8c2976ce19a55997eb159e511fbd11e366006"
dependencies = [
"fluence-it-types",
"it-lilo",
"it-to-bytes",
"itertools 0.10.0",
"log",
"nom",
"safe-transmute",
"semver 0.11.0",
"serde",
"serde_json",
"thiserror",
"wast",
]

View File

@ -12,7 +12,7 @@ path = "src/lib.rs"
[dependencies]
fluence-faas = { path = "../fluence-faas", version = "0.6.0" }
aqua-interpreter-interface = "0.3.1"
aqua-interpreter-interface = { git = "https://github.com/fluencelabs/air", branch = "bwu" }
maplit = "1.0.2"
serde_json = "1.0.60"

View File

@ -149,14 +149,11 @@ fn prepare_args(
init_user_id: String,
aqua: impl Into<String>,
) -> Vec<IValue> {
let prev_data = into_ibytes_array(prev_data);
let data = into_ibytes_array(data.into());
vec![
IValue::String(init_user_id),
IValue::String(aqua.into()),
IValue::Array(prev_data),
IValue::Array(data),
IValue::ByteArray(prev_data),
IValue::ByteArray(data.into()),
]
}
@ -251,10 +248,6 @@ fn make_faas_config(
}
}
fn into_ibytes_array(byte_array: Vec<u8>) -> Vec<IValue> {
byte_array.into_iter().map(IValue::U8).collect()
}
// This API is intended for testing purposes
#[cfg(feature = "raw-aquamarine-vm-api")]
impl AquamarineVM {

View File

@ -1,6 +1,6 @@
[package]
name = "fce-wit-generator"
description = "Fluence FCE interface type helper crate"
description = "Fluence FCE interface type generator"
version = "0.3.0"
authors = ["Fluence Labs"]
license = "Apache-2.0"
@ -14,8 +14,11 @@ path = "src/lib.rs"
fce-wit-parser = { path = "../wit-parser", version = "0.4.0"}
fluence-sdk-wit = { git = "https://github.com/fluencelabs/rust-sdk" }
wasmer-wit = { package = "wasmer-interface-types-fl", version = "0.20.0" }
it-lilo = "0.1.0"
thiserror = "1.0.24"
walrus = "0.18.0"
wasmer-wit = { package = "wasmer-interface-types-fl", version = "=0.19.0" }
once_cell = "1.4.0"
serde = { version = "=1.0.118", features = ["derive"] }
serde_json = "1.0.56"

View File

@ -14,39 +14,20 @@
* limitations under the License.
*/
use std::error::Error;
use thiserror::Error as ThisError;
use serde_json::Error as SerdeDeserializationError;
#[derive(Debug)]
#[derive(Debug, ThisError)]
pub enum WITGeneratorError {
/// An error related to serde deserialization.
DeserializationError(SerdeDeserializationError),
#[error("Embedded by rust-sdk metadata couldn't be parsed by serde: {0:?}")]
DeserializationError(#[from] SerdeDeserializationError),
/// Various errors related to records
#[error("{0}")]
CorruptedRecord(String),
/// Various errors occurred during the parsing/emitting a Wasm file.
#[error("I/O error occurred: {0}")]
IOError(String),
}
impl Error for WITGeneratorError {}
impl std::fmt::Display for WITGeneratorError {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> {
match self {
WITGeneratorError::DeserializationError(err) => write!(
f,
"Embedded by rust-sdk metadata could't be parsed by serde: {:?}",
err
),
WITGeneratorError::CorruptedRecord(err) => write!(f, "{:?}", err),
WITGeneratorError::IOError(err) => write!(f, "I/O error occurred: {:?}", err),
}
}
}
impl From<SerdeDeserializationError> for WITGeneratorError {
fn from(err: SerdeDeserializationError) -> Self {
WITGeneratorError::DeserializationError(err)
}
}

View File

@ -20,14 +20,15 @@ use super::utils::ptype_to_itype_checked;
use crate::default_export_api_config::*;
use crate::Result;
use fluence_sdk_wit::AstFnItem;
use fluence_sdk_wit::FnType;
use fluence_sdk_wit::ParsedType;
use wasmer_wit::interpreter::Instruction;
use wasmer_wit::ast::FunctionArg as IFunctionArg;
use wasmer_wit::IType;
use std::rc::Rc;
impl WITGenerator for AstFnItem {
impl WITGenerator for FnType {
fn generate_wit<'a>(&'a self, wit_resolver: &mut WITResolver<'a>) -> Result<()> {
use wasmer_wit::ast::Type;
use wasmer_wit::ast::Adapter;
@ -46,10 +47,12 @@ impl WITGenerator for AstFnItem {
let arguments = Rc::new(arguments);
let output_types = match self.signature.output_type {
Some(ref output_type) => vec![ptype_to_itype_checked(output_type, wit_resolver)?],
None => vec![],
};
let output_types = self
.signature
.output_types
.iter()
.map(|ty| ptype_to_itype_checked(ty, wit_resolver))
.collect::<Result<Vec<_>>>()?;
let output_types = Rc::new(output_types);
let interfaces = &mut wit_resolver.interfaces;
@ -78,11 +81,11 @@ impl WITGenerator for AstFnItem {
.iter()
.enumerate()
.try_fold::<_, _, Result<_>>(Vec::new(), |mut instructions, (arg_id, arg)| {
let mut new_instructions = arg
let new_instructions = arg
.ty
.generate_instructions_for_input_type(arg_id as _, wit_resolver)?;
instructions.append(&mut new_instructions);
instructions.extend(new_instructions);
Ok(instructions)
})?;
@ -91,10 +94,16 @@ impl WITGenerator for AstFnItem {
function_index: export_function_index,
});
instructions.extend(match &self.signature.output_type {
Some(output_type) => output_type.generate_instructions_for_output_type(wit_resolver)?,
None => vec![],
});
let instructions = self
.signature
.output_types
.iter()
.try_fold::<_, _, Result<_>>(instructions, |mut instructions, ty| {
let new_instructions = ty.generate_instructions_for_output_type(wit_resolver)?;
instructions.extend(new_instructions);
Ok(instructions)
})?;
let adapter = Adapter {
function_type: adapter_idx,
@ -131,7 +140,7 @@ impl FnInstructionGenerator for ParsedType {
#[rustfmt::skip]
fn generate_instructions_for_input_type<'a>(&self, index: u32, wit_resolver: &mut WITResolver<'a>) -> Result<Vec<Instruction>> {
let instructions = match self {
ParsedType::Boolean(_) => vec![Instruction::ArgumentGet { index }],
ParsedType::Boolean(_) => vec![Instruction::ArgumentGet { index }, Instruction::I32FromBool],
ParsedType::I8(_) => vec![Instruction::ArgumentGet { index }, Instruction::I32FromS8],
ParsedType::I16(_) => vec![Instruction::ArgumentGet { index }, Instruction::I32FromS16],
ParsedType::I32(_) => vec![Instruction::ArgumentGet { index }, Instruction::I32FromS32],
@ -142,13 +151,17 @@ impl FnInstructionGenerator for ParsedType {
ParsedType::U64(_) => vec![Instruction::ArgumentGet { index }, Instruction::I64FromU64],
ParsedType::F32(_) => vec![Instruction::ArgumentGet { index }],
ParsedType::F64(_) => vec![Instruction::ArgumentGet { index }],
ParsedType::Utf8Str(_) | ParsedType::Utf8String(_) => vec![
Instruction::ArgumentGet { index },
Instruction::StringSize,
Instruction::CallCore { function_index: ALLOCATE_FUNC.id },
Instruction::ArgumentGet { index },
Instruction::StringLowerMemory,
],
ParsedType::Utf8Str(_) | ParsedType::Utf8String(_) => {
let type_tag = it_lilo::utils::ser_type_size(&IType::U8) as i32;
vec![
Instruction::ArgumentGet { index },
Instruction::StringSize,
Instruction::PushI32 { value: type_tag },
Instruction::CallCore { function_index: ALLOCATE_FUNC.id },
Instruction::ArgumentGet { index },
Instruction::StringLowerMemory,
]
},
ParsedType::Vector(value_type, _) => {
let value_type = ptype_to_itype_checked(value_type, wit_resolver)?;
vec![
@ -174,7 +187,7 @@ impl FnInstructionGenerator for ParsedType {
#[rustfmt::skip]
fn generate_instructions_for_output_type<'a>(&self, wit_resolver: &mut WITResolver<'a>) -> Result<Vec<Instruction>> {
let instructions = match self {
ParsedType::Boolean(_) => vec![],
ParsedType::Boolean(_) => vec![Instruction::BoolFromI32],
ParsedType::I8(_) => vec![Instruction::S8FromI32],
ParsedType::I16(_) => vec![Instruction::S16FromI32],
ParsedType::I32(_) => vec![Instruction::S32FromI32],
@ -193,13 +206,21 @@ impl FnInstructionGenerator for ParsedType {
],
ParsedType::Vector(value_type, _) => {
let value_type = ptype_to_itype_checked(value_type, wit_resolver)?;
vec![
Instruction::CallCore { function_index: GET_RESULT_PTR_FUNC.id },
Instruction::CallCore { function_index: GET_RESULT_SIZE_FUNC.id },
Instruction::ArrayLiftMemory { value_type },
Instruction::CallCore { function_index: RELEASE_OBJECTS.id },
]
if let IType::U8 = value_type {
vec![
Instruction::CallCore { function_index: GET_RESULT_PTR_FUNC.id },
Instruction::CallCore { function_index: GET_RESULT_SIZE_FUNC.id },
Instruction::ByteArrayLiftMemory,
Instruction::CallCore { function_index: RELEASE_OBJECTS.id },
]
} else {
vec![
Instruction::CallCore { function_index: GET_RESULT_PTR_FUNC.id },
Instruction::CallCore { function_index: GET_RESULT_SIZE_FUNC.id },
Instruction::ArrayLiftMemory { value_type },
Instruction::CallCore { function_index: RELEASE_OBJECTS.id },
]
}
},
ParsedType::Record(record_name, _) => {
let record_type_id = wit_resolver.get_record_type_id(record_name)? as u32;

View File

@ -17,22 +17,23 @@
use super::WITGenerator;
use super::WITResolver;
use super::utils::ptype_to_itype_checked;
use crate::default_export_api_config::*;
use crate::Result;
use crate::default_export_api_config::*;
use crate::instructions_generator::utils::wtype_to_itype;
use fluence_sdk_wit::AstExternModItem;
use fluence_sdk_wit::AstExternFnItem;
use fluence_sdk_wit::ExternModType;
use fluence_sdk_wit::ExternFnType;
use fluence_sdk_wit::ParsedType;
use fluence_sdk_wit::AstFnArgument;
use fluence_sdk_wit::FnArgument;
use wasmer_wit::ast::FunctionArg as IFunctionArg;
use wasmer_wit::interpreter::Instruction;
use crate::instructions_generator::utils::wtype_to_itype;
use wasmer_wit::IType;
use std::rc::Rc;
const HOST_NAMESPACE_NAME: &str = "host";
impl WITGenerator for AstExternModItem {
impl WITGenerator for ExternModType {
fn generate_wit<'a>(&'a self, wit_resolver: &mut WITResolver<'a>) -> Result<()> {
// host imports should be left as is
if self.namespace == HOST_NAMESPACE_NAME {
@ -48,7 +49,7 @@ impl WITGenerator for AstExternModItem {
}
fn generate_wit_for_import<'a>(
import: &'a AstExternFnItem,
import: &'a ExternFnType,
namespace: &'a str,
wit_resolver: &mut WITResolver<'a>,
) -> Result<()> {
@ -68,10 +69,12 @@ fn generate_wit_for_import<'a>(
.collect::<Result<Vec<_>>>()?;
let arguments = Rc::new(arguments);
let output_types = match import.signature.output_type {
Some(ref output_type) => vec![ptype_to_itype_checked(output_type, wit_resolver)?],
None => vec![],
};
let output_types = import
.signature
.output_types
.iter()
.map(|ty| ptype_to_itype_checked(ty, wit_resolver))
.collect::<Result<Vec<_>>>()?;
let output_types = Rc::new(output_types);
let interfaces = &mut wit_resolver.interfaces;
@ -89,13 +92,18 @@ fn generate_wit_for_import<'a>(
.collect::<Vec<_>>();
let raw_inputs = Rc::new(raw_inputs);
let raw_outputs = match import.signature.output_type {
Some(ref output_type) => to_raw_output_type(output_type)
.iter()
.map(wtype_to_itype)
.collect(),
None => vec![],
};
let raw_outputs = import
.signature
.output_types
.iter()
.map(|ty| {
to_raw_output_type(ty)
.iter()
.map(wtype_to_itype)
.collect::<Vec<_>>()
})
.flatten()
.collect::<Vec<_>>();
let raw_outputs = Rc::new(raw_outputs);
interfaces.types.push(Type::Function {
@ -134,11 +142,11 @@ fn generate_wit_for_import<'a>(
.arguments
.iter()
.try_fold::<_, _, Result<_>>((0, Vec::new()), |(arg_id, mut instructions), arg| {
let (mut new_instructions, shift) = arg
let (new_instructions, shift) = arg
.ty
.generate_instructions_for_input_type(arg_id as _, wit_resolver)?;
instructions.append(&mut new_instructions);
instructions.extend(new_instructions);
Ok((arg_id + shift, instructions))
})?
.1;
@ -151,10 +159,16 @@ fn generate_wit_for_import<'a>(
function_index: import_function_index,
});
instructions.extend(match &import.signature.output_type {
Some(output_type) => output_type.generate_instructions_for_output_type(wit_resolver)?,
None => vec![],
});
let instructions = import
.signature
.output_types
.iter()
.try_fold::<_, _, Result<_>>(instructions, |mut instructions, ty| {
let new_instructions = ty.generate_instructions_for_output_type(wit_resolver)?;
instructions.extend(new_instructions);
Ok(instructions)
})?;
let adapter = Adapter {
function_type: adapter_idx,
@ -193,7 +207,7 @@ impl ForeignModInstructionGenerator for ParsedType {
wit_resolver: &mut WITResolver<'a>,
) -> Result<(Vec<Instruction>, u32)> {
let instructions = match self {
ParsedType::Boolean(_) => (vec![Instruction::ArgumentGet { index }], 1),
ParsedType::Boolean(_) => (vec![Instruction::ArgumentGet { index }, Instruction::BoolFromI32], 1),
ParsedType::I8(_) => (vec![Instruction::ArgumentGet { index }, Instruction::S8FromI32], 1),
ParsedType::I16(_) => (vec![Instruction::ArgumentGet { index }, Instruction::S16FromI32], 1),
ParsedType::I32(_) => (vec![Instruction::ArgumentGet { index }, Instruction::S32FromI32], 1),
@ -211,12 +225,19 @@ impl ForeignModInstructionGenerator for ParsedType {
], 2),
ParsedType::Vector(value_type, _) => {
let value_type = ptype_to_itype_checked(value_type, wit_resolver)?;
(vec![
Instruction::ArgumentGet { index },
Instruction::ArgumentGet { index: index + 1 },
Instruction::ArrayLiftMemory { value_type },
], 2)
if let IType::U8 = value_type {
(vec![
Instruction::ArgumentGet { index },
Instruction::ArgumentGet { index: index + 1 },
Instruction::ByteArrayLiftMemory,
], 2)
} else {
(vec![
Instruction::ArgumentGet { index },
Instruction::ArgumentGet { index: index + 1 },
Instruction::ArrayLiftMemory { value_type },
], 2)
}
},
ParsedType::Record(record_name, _) => {
let record_type_id = wit_resolver.get_record_type_id(record_name)? as u32;
@ -234,7 +255,7 @@ impl ForeignModInstructionGenerator for ParsedType {
#[rustfmt::skip]
fn generate_instructions_for_output_type<'a>(&self, wit_resolver: &mut WITResolver<'a>) -> Result<Vec<Instruction>> {
let instructions = match self {
ParsedType::Boolean(_) => vec![],
ParsedType::Boolean(_) => vec![Instruction::I32FromBool],
ParsedType::I8(_) => vec![Instruction::I32FromS8],
ParsedType::I16(_) => vec![Instruction::I32FromS16],
ParsedType::I32(_) => vec![Instruction::I32FromS32],
@ -245,15 +266,20 @@ impl ForeignModInstructionGenerator for ParsedType {
ParsedType::U64(_) => vec![Instruction::I64FromU64],
ParsedType::F32(_) => vec![],
ParsedType::F64(_) => vec![],
ParsedType::Utf8Str(_) | ParsedType::Utf8String(_) => vec![
Instruction::Dup,
Instruction::StringSize,
Instruction::CallCore { function_index: ALLOCATE_FUNC.id },
Instruction::Swap2,
Instruction::StringLowerMemory,
Instruction::CallCore { function_index: SET_RESULT_SIZE_FUNC.id },
Instruction::CallCore { function_index: SET_RESULT_PTR_FUNC.id },
],
ParsedType::Utf8Str(_) | ParsedType::Utf8String(_) => {
let type_tag = it_lilo::utils::ser_type_size(&IType::U8) as i32;
vec![
Instruction::Dup,
Instruction::StringSize,
Instruction::PushI32 { value: type_tag },
Instruction::CallCore { function_index: ALLOCATE_FUNC.id },
Instruction::Swap2,
Instruction::StringLowerMemory,
Instruction::CallCore { function_index: SET_RESULT_SIZE_FUNC.id },
Instruction::CallCore { function_index: SET_RESULT_PTR_FUNC.id },
]
},
ParsedType::Vector(value_type, _) => {
let value_type = ptype_to_itype_checked(value_type, wit_resolver)?;
@ -278,9 +304,8 @@ impl ForeignModInstructionGenerator for ParsedType {
}
use fluence_sdk_wit::RustType;
use wasmer_wit::IType;
pub fn to_raw_input_types(arg: &AstFnArgument) -> Vec<IFunctionArg> {
pub fn to_raw_input_types(arg: &FnArgument) -> Vec<IFunctionArg> {
match arg.ty {
ParsedType::Boolean(_)
| ParsedType::I8(_)

View File

@ -18,16 +18,22 @@ use super::WITGenerator;
use super::WITResolver;
use crate::Result;
use fluence_sdk_wit::AstRecordItem;
use fluence_sdk_wit::RecordType;
use fluence_sdk_wit::RecordFields;
use wasmer_wit::IRecordFieldType;
use wasmer_wit::IRecordType;
use wasmer_wit::NEVec;
impl WITGenerator for AstRecordItem {
impl WITGenerator for RecordType {
fn generate_wit<'a>(&'a self, wit_resolver: &mut WITResolver<'a>) -> Result<()> {
let fields = self
.fields
let fields = match &self.fields {
RecordFields::Named(fields) => fields,
RecordFields::Unnamed(fields) => fields,
RecordFields::Unit => return Ok(()),
};
let fields = fields
.iter()
.map(|field| IRecordFieldType {
name: field.name.clone().unwrap_or_default(),

View File

@ -37,12 +37,16 @@ pub(crate) fn ptype_to_itype_checked(
ParsedType::U64(_) => Ok(IType::U64),
ParsedType::F32(_) => Ok(IType::F32),
ParsedType::F64(_) => Ok(IType::F64),
ParsedType::Boolean(_) => Ok(IType::I32),
ParsedType::Boolean(_) => Ok(IType::Boolean),
ParsedType::Utf8Str(_) => Ok(IType::String),
ParsedType::Utf8String(_) => Ok(IType::String),
ParsedType::Vector(ty, _) => {
let array_itype = ptype_to_itype_checked(ty, wit_resolver)?;
Ok(IType::Array(Box::new(array_itype)))
if let IType::U8 = array_itype {
Ok(IType::ByteArray)
} else {
Ok(IType::Array(Box::new(array_itype)))
}
}
ParsedType::Record(record_name, _) => {
let record_type_id = wit_resolver.get_record_type_id(record_name)?;
@ -66,12 +70,16 @@ pub(crate) fn ptype_to_itype_unchecked(
ParsedType::U64(_) => IType::U64,
ParsedType::F32(_) => IType::F32,
ParsedType::F64(_) => IType::F64,
ParsedType::Boolean(_) => IType::I32,
ParsedType::Boolean(_) => IType::Boolean,
ParsedType::Utf8Str(_) => IType::String,
ParsedType::Utf8String(_) => IType::String,
ParsedType::Vector(ty, _) => {
let array_itype = ptype_to_itype_unchecked(ty, wit_resolver);
IType::Array(Box::new(array_itype))
if let IType::U8 = array_itype {
IType::ByteArray
} else {
IType::Array(Box::new(array_itype))
}
}
ParsedType::Record(record_name, _) => {
let record_type_id = wit_resolver.get_record_type_id_unchecked(record_name);

View File

@ -20,7 +20,7 @@ use crate::instructions_generator::WITGenerator;
use crate::instructions_generator::WITResolver;
use crate::Result;
pub use fluence_sdk_wit::FCEAst;
pub use fluence_sdk_wit::SDKAst;
use wasmer_wit::ast::Interfaces;
use wasmer_wit::IRecordType;
use wasmer_wit::IType;
@ -43,18 +43,18 @@ pub fn embed_wit(path: std::path::PathBuf) -> Result<()> {
}
pub(crate) struct ModuleAST {
pub(crate) records: Vec<fluence_sdk_wit::AstRecordItem>,
pub(crate) functions: Vec<fluence_sdk_wit::AstFnItem>,
pub(crate) extern_mods: Vec<fluence_sdk_wit::AstExternModItem>,
pub(crate) records: Vec<fluence_sdk_wit::RecordType>,
pub(crate) functions: Vec<fluence_sdk_wit::FnType>,
pub(crate) extern_mods: Vec<fluence_sdk_wit::ExternModType>,
}
/// Extract all custom AST types previously embedded by rust-sdk from compiled binary.
fn wasm_ast_extractor(wasm_module: &walrus::Module) -> Result<ModuleAST> {
use fluence_sdk_wit::*;
let mut records: Vec<AstRecordItem> = Vec::new();
let mut functions: Vec<AstFnItem> = Vec::new();
let mut extern_mods: Vec<AstExternModItem> = Vec::new();
let mut records: Vec<RecordType> = Vec::new();
let mut functions: Vec<FnType> = Vec::new();
let mut extern_mods: Vec<ExternModType> = Vec::new();
// consider only sections name of that starts with GENERATED_SECTION_PREFIX
for custom_module in wasm_module.customs.iter().filter(|(_, section)| {
@ -64,11 +64,11 @@ fn wasm_ast_extractor(wasm_module: &walrus::Module) -> Result<ModuleAST> {
}) {
let default_ids = walrus::IdsToIndices::default();
let raw_data = custom_module.1.data(&default_ids);
let decoded_json: FCEAst = serde_json::from_slice(&raw_data)?;
let decoded_json: SDKAst = serde_json::from_slice(&raw_data)?;
match decoded_json {
FCEAst::Record(record) => records.push(record),
FCEAst::Function(function) => functions.push(function),
FCEAst::ExternMod(extern_mod) => extern_mods.push(extern_mod),
SDKAst::Record(record) => records.push(record),
SDKAst::Function(function) => functions.push(function),
SDKAst::ExternMod(extern_mod) => extern_mods.push(extern_mod),
}
}

View File

@ -11,5 +11,5 @@ name = "fce_wit_interfaces"
path = "src/lib.rs"
[dependencies]
wasmer-wit = { package = "wasmer-interface-types-fl", version = "=0.19.0" }
wasmer-wit = { package = "wasmer-interface-types-fl", version = "0.20.0" }
multimap = "0.8.1"

View File

@ -1,6 +1,6 @@
[package]
name = "fce-wit-parser"
description = "Fluence FCE interface type helper crate"
description = "Fluence FCE interface type parser"
version = "0.4.0"
authors = ["Fluence Labs"]
license = "Apache-2.0"
@ -16,7 +16,8 @@ fce-wit-interfaces = { path = "../wit-interfaces", version = "0.2.0" }
anyhow = "1.0.31"
walrus = "0.18.0"
wasmer-core = { package = "wasmer-runtime-core-fl", version = "0.17.0"}
wasmer-wit = { package = "wasmer-interface-types-fl", version = "=0.19.0" }
wasmer-wit = { package = "wasmer-interface-types-fl", version = "0.20.0" }
nom = "5.1"
semver = "0.11.0"
serde = "=1.0.118"

View File

@ -34,8 +34,12 @@ pub enum WITParserError {
ITRemainderNotEmpty,
/// An error occurred while parsing WIT section.
#[error("IT section is corrupted")]
CorruptedITSection,
#[error(
"IT section is corrupted: {0}.\
\nProbably the module was compiled with an old version of fce cli, please try to update and recompile.\
\nTo update fce run: cargo install fcli --force"
)]
CorruptedITSection(nom::Err<(Vec<u8>, nom::error::ErrorKind)>),
/// An error related to incorrect data of wit section.
#[error("{0}")]
@ -43,7 +47,7 @@ pub enum WITParserError {
/// An error occurred while parsing file in Wat format.
#[error("provided file with IT definitions is corrupted: {0}")]
CorruptedITFile(WATError),
CorruptedITFile(#[from] WATError),
/// An error occurred while parsing Wasm file.
#[error("provided Wasm file is corrupted: {0}")]
@ -51,21 +55,9 @@ pub enum WITParserError {
/// An error occurred while manipulating with converting ast to bytes.
#[error("Convertation Wast to AST failed with: {0}")]
AstToBytesError(IOError),
AstToBytesError(#[from] IOError),
/// Wasm emitting file error.
#[error("Emitting resulted Wasm file failed with: {0}")]
WasmEmitError(anyhow::Error),
}
impl From<WATError> for WITParserError {
fn from(err: WATError) -> Self {
WITParserError::CorruptedITFile(err)
}
}
impl From<IOError> for WITParserError {
fn from(err: IOError) -> Self {
WITParserError::AstToBytesError(err)
}
}

View File

@ -66,11 +66,8 @@ fn get_exports(wit: &FCEWITInterfaces<'_>) -> Result<Vec<FCEFunctionSignature>>
wit.implementations()
.filter_map(|(adapter_function_type, core_function_type)| {
match wit.exports_by_type(*core_function_type) {
Some(export_function_name) => Some((adapter_function_type, export_function_name)),
// pass functions that aren't export
None => None,
}
wit.exports_by_type(*core_function_type)
.map(|export_function_name| (adapter_function_type, export_function_name))
})
.map(|(adapter_function_type, export_function_names)| {
export_function_names
@ -156,8 +153,8 @@ pub(crate) fn into_service_interface(fce_interface: FCEModuleInterface) -> Servi
.collect::<Vec<_>>();
ServiceInterface {
record_types,
function_signatures,
record_types,
}
}
@ -184,7 +181,7 @@ fn serialize_function_signature(
}
}
fn serialize_record_type<'a, 'b>(
fn serialize_record_type(
id: u64,
record: Rc<IRecordType>,
record_types: &FCERecordTypes,

View File

@ -63,10 +63,10 @@ pub fn extract_version_from_module(module: &walrus::Module) -> Result<semver::Ve
}
pub(crate) fn extract_wit_from_bytes(wit_section_bytes: &[u8]) -> Result<Interfaces<'_>> {
match wasmer_wit::decoders::binary::parse::<()>(wit_section_bytes) {
match wasmer_wit::decoders::binary::parse::<(&[u8], nom::error::ErrorKind)>(wit_section_bytes) {
Ok((remainder, wit)) if remainder.is_empty() => Ok(wit),
Ok(_) => Err(WITParserError::ITRemainderNotEmpty),
Err(_) => Err(WITParserError::CorruptedITSection),
Err(e) => Err(WITParserError::CorruptedITSection(e.to_owned())),
}
}

View File

@ -20,7 +20,8 @@ fce-utils = { path = "../crates/utils", version = "0.1.29" }
wasmer-runtime = { package = "wasmer-runtime-fl", version = "0.17.0" }
# dynamicfunc-fat-closures allows using state inside DynamicFunc
wasmer-core = { package = "wasmer-runtime-core-fl", version = "0.17.0", features = ["dynamicfunc-fat-closures"] }
wasmer-wit = { package = "wasmer-interface-types-fl", version = "=0.19.0" }
wasmer-wit = { package = "wasmer-interface-types-fl", version = "0.20.0" }
it-lilo = "0.1.0"
wasmer-wasi = { package = "wasmer-wasi-fl", version = "0.17.1" }
multimap = "0.8.1"
@ -28,11 +29,12 @@ boolinator = "2.4.0"
parity-wasm = "0.41.0"
pwasm-utils = "0.12.0"
once_cell = "1.7.2"
safe-transmute = "0.11.0"
semver = "0.11.0"
serde = "=1.0.118"
log = "0.4.8"
paste = "1.0.5"
anyhow = "1.0.31"
thiserror = "1.0.24"

View File

@ -14,10 +14,12 @@
* limitations under the License.
*/
use crate::IType;
use super::WType;
use super::WValue;
use it_lilo::lifter::LiError;
use it_lilo::lowerer::LoError;
use it_lilo::traits::RecordResolvableError;
use thiserror::Error as ThisError;
#[derive(Debug, ThisError)]
@ -34,19 +36,15 @@ pub enum HostImportError {
#[error("Not enough WValue arguments are provided from the Wasm side")]
MismatchWValuesCount,
/// An error related to invalid memory access during lifting IValue.
#[error("Invalid memory access while lifting IValues, offset {0}, size {1}")]
InvalidMemoryAccess(i32, i32),
#[error("{0}")]
LifterError(#[from] LiError),
/// An error related to lifting memory from arrays of pointers with odd elements count.
#[error("Arrays of pointers for value type {0:?} contains non-even count of elements")]
OddPointersCount(IType),
#[error("{0}")]
LowererError(#[from] LoError),
/// An error related to not found record in module record types.
#[error("Record with type id {0} not found")]
RecordTypeNotFound(u64),
#[error("{0}")]
RecordNotFound(#[from] RecordResolvableError),
/// An error encountered while transmiting arrays.
#[error("array of bytes with len {0} can't be transmuted to {1} type")]
TransmuteArrayError(usize, &'static str),
#[error("{0}")]
InvalidUTF8String(#[from] std::string::FromUtf8Error),
}

View File

@ -15,12 +15,14 @@
*/
use super::*;
use super::ivalues_lifting::wvalues_to_ivalues;
use super::ivalues_lowering::ivalue_to_wvalues;
use super::lifting::wvalues_to_ivalues;
use super::lifting::LiHelper;
use super::lowering::ivalue_to_wvalues;
use super::lowering::LoHelper;
use super::utils::itypes_args_to_wtypes;
use super::utils::itypes_output_to_wtypes;
use crate::RecordTypes;
use crate::RecordTypes;
use crate::init_wasm_func_once;
use crate::call_wasm_func;
use crate::HostImportDescriptor;
@ -30,9 +32,12 @@ use wasmer_core::vm::Ctx;
use wasmer_core::typed_func::DynamicFunc;
use wasmer_core::types::Value as WValue;
use wasmer_core::types::FuncSig;
use it_lilo::lifter::ILifter;
use it_lilo::lowerer::ILowerer;
use std::cell::RefCell;
use std::rc::Rc;
use std::ops::Deref;
pub(crate) fn create_host_import_func(
descriptor: HostImportDescriptor,
@ -58,9 +63,14 @@ pub(crate) fn create_host_import_func(
let raw_output = itypes_output_to_wtypes(&output_type_to_types(output_type));
let func = move |ctx: &mut Ctx, inputs: &[WValue]| -> Vec<WValue> {
init_wasm_func_once!(allocate_func, ctx, i32, i32, ALLOCATE_FUNC_NAME, 2);
let memory_index = 0;
let view = ctx.memory(memory_index).view::<u8>();
let memory = view.deref();
let result = match wvalues_to_ivalues(ctx, inputs, &argument_types, &record_types) {
let li_helper = LiHelper::new(record_types.clone());
let lifter = ILifter::new(memory, &li_helper);
let result = match wvalues_to_ivalues(&lifter, inputs, &argument_types) {
Ok(ivalues) => host_exported_func(ctx, ivalues),
Err(e) => {
log::error!("error occurred while lifting values in host import: {}", e);
@ -69,7 +79,28 @@ pub(crate) fn create_host_import_func(
.map_or_else(|| default_error_handler(&e), |h| h(&e))
}
};
let wvalues = ivalue_to_wvalues(ctx, result, &allocate_func);
init_wasm_func_once!(allocate_func, ctx, (i32, i32), i32, ALLOCATE_FUNC_NAME, 2);
let lo_helper = LoHelper::new(&ctx, &allocate_func);
let t = ILowerer::new(&lo_helper)
.map_err(|e| HostImportError::LowererError(e))
.and_then(|lowerer| ivalue_to_wvalues(&lowerer, result));
let wvalues = match t {
Ok(wvalues) => wvalues,
Err(e) => {
log::error!("host closure failed: {}", e);
// returns 0 to a Wasm module in case of errors
init_wasm_func_once!(set_result_ptr_func, ctx, i32, (), SET_PTR_FUNC_NAME, 4);
init_wasm_func_once!(set_result_size_func, ctx, i32, (), SET_SIZE_FUNC_NAME, 4);
call_wasm_func!(set_result_ptr_func, 0);
call_wasm_func!(set_result_size_func, 0);
return vec![WValue::I32(0)];
}
};
// TODO: refactor this when multi-value is supported
match wvalues.len() {

View File

@ -1,363 +0,0 @@
/*
* Copyright 2020 Fluence Labs Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/// Contain functions intended to create (lift) IValues from raw WValues (Wasm types).
use super::WType;
use super::WValue;
use super::HostImportError;
use crate::IValue;
use crate::RecordTypes;
use crate::IType;
use super::HostImportResult;
use wasmer_core::memory::ptr::{Array, WasmPtr};
use wasmer_core::vm::Ctx;
use wasmer_wit::IRecordType;
use wasmer_wit::NEVec;
use std::rc::Rc;
pub(super) fn wvalues_to_ivalues(
ctx: &Ctx,
wvalues: &[WValue],
itypes: &[IType],
record_types: &Rc<RecordTypes>,
) -> HostImportResult<Vec<IValue>> {
let mut result = Vec::new();
let mut wvalue = wvalues.iter();
macro_rules! next_wvalue(
($wtype:ident) => {
match wvalue
.next()
.ok_or_else(|| HostImportError::MismatchWValuesCount)?
{
WValue::$wtype(v) => *v,
v => return Err(HostImportError::MismatchWValues(WType::$wtype, v.clone())),
};
}
);
macro_rules! simple_wvalue_to_ivalue(
($wtype:ident, $ivalue:ident) => {
{
let w = next_wvalue!($wtype);
result.push(IValue::$ivalue(w as _))
}
}
);
for itype in itypes.iter() {
match itype {
IType::S8 => simple_wvalue_to_ivalue!(I32, S8),
IType::S16 => simple_wvalue_to_ivalue!(I32, S16),
IType::S32 => simple_wvalue_to_ivalue!(I32, S32),
IType::S64 => simple_wvalue_to_ivalue!(I64, S64),
IType::U8 => simple_wvalue_to_ivalue!(I32, U8),
IType::U16 => simple_wvalue_to_ivalue!(I32, U16),
IType::U32 => simple_wvalue_to_ivalue!(I32, U32),
IType::U64 => simple_wvalue_to_ivalue!(I64, U64),
IType::I32 => simple_wvalue_to_ivalue!(I32, I32),
IType::I64 => simple_wvalue_to_ivalue!(I64, I64),
IType::F32 => simple_wvalue_to_ivalue!(F32, F32),
IType::F64 => simple_wvalue_to_ivalue!(F64, F64),
// anyrefs aren't supported now, and isn't generated by rust-sdk
IType::Anyref => unimplemented!("anyrefs aren't supported now"),
IType::String => {
let offset = next_wvalue!(I32);
let size = next_wvalue!(I32);
let wasm_ptr = WasmPtr::<u8, Array>::new(offset as _);
let str = wasm_ptr
.get_utf8_string(ctx.memory(0), size as _)
.ok_or(HostImportError::InvalidMemoryAccess(offset, size))?;
result.push(IValue::String(str.to_string()));
}
IType::Array(ty) => {
let offset = next_wvalue!(I32);
let size = next_wvalue!(I32);
let array = lift_array(ctx, ty, offset as _, size as _, record_types)?;
result.push(IValue::Array(array));
}
IType::Record(record_type_id) => {
let record_type = record_types
.get(record_type_id)
.ok_or_else(|| HostImportError::RecordTypeNotFound(*record_type_id))?;
let offset = next_wvalue!(I32);
let record = lift_record(ctx, record_type, offset as _, record_types)?;
result.push(record);
}
}
}
Ok(result)
}
fn lift_array(
ctx: &Ctx,
value_type: &IType,
offset: usize,
size: usize,
record_types: &Rc<RecordTypes>,
) -> HostImportResult<Vec<IValue>> {
use safe_transmute::guard::AllOrNothingGuard;
use safe_transmute::transmute_many;
use safe_transmute::transmute_vec;
if size == 0 {
return Ok(vec![]);
}
let data = read_mem(ctx, offset, size)?;
macro_rules! simple_type_array_convert(
($data:ident, $itype:ident, $rtype:ident) => {
{
let data = transmute_many::<$rtype, AllOrNothingGuard>(&data)
.map_err(|_| HostImportError::TransmuteArrayError($data.len(), stringify!($rtype)))?;
data.iter().map(|v| IValue::$itype(*v)).collect::<Vec<_>>()
}
}
);
let result_array = match value_type {
IType::S8 => {
// unwrap is safe here because it could fail if data types has different size
let data = transmute_vec::<u8, i8>(data).unwrap();
data.iter().map(|v| IValue::S8(*v)).collect::<Vec<_>>()
}
IType::S16 => simple_type_array_convert!(data, S16, i16),
IType::S32 => simple_type_array_convert!(data, S32, i32),
IType::S64 => simple_type_array_convert!(data, S64, i64),
IType::U8 => data.iter().map(|v| IValue::U8(*v)).collect::<Vec<_>>(),
IType::U16 => simple_type_array_convert!(data, U16, u16),
IType::U32 => simple_type_array_convert!(data, U32, u32),
IType::U64 => simple_type_array_convert!(data, U64, u64),
IType::F32 => {
let data = transmute_many::<u32, AllOrNothingGuard>(&data)
.map_err(|_| HostImportError::TransmuteArrayError(data.len(), stringify!(f32)))?;
data.iter()
.map(|v| IValue::F32(f32::from_bits(*v)))
.collect::<Vec<_>>()
}
IType::F64 => {
let data = transmute_many::<u64, AllOrNothingGuard>(&data)
.map_err(|_| HostImportError::TransmuteArrayError(data.len(), stringify!(f64)))?;
data.iter()
.map(|v| IValue::F64(f64::from_bits(*v)))
.collect::<Vec<_>>()
}
IType::I32 => simple_type_array_convert!(data, I32, i32),
IType::I64 => simple_type_array_convert!(data, I64, i64),
// anyrefs aren't supported now, and isn't generated by rust-sdk
IType::Anyref => unimplemented!("anyrefs aren't supported now"),
IType::String => {
let data = transmute_many::<u32, AllOrNothingGuard>(&data)
.map_err(|_| HostImportError::TransmuteArrayError(data.len(), stringify!(u32)))?;
let mut data = data.into_iter();
let mut result = Vec::with_capacity(data.len() / 2);
while let Some(&string_offset) = data.next() {
let string_size = *data
.next()
.ok_or(HostImportError::OddPointersCount(IType::String))?;
let string = WasmPtr::<u8, Array>::new(string_offset as _)
.get_utf8_string(ctx.memory(0), string_size as _)
.ok_or_else(|| {
HostImportError::InvalidMemoryAccess(string_offset as _, string_size as _)
})?;
result.push(IValue::String(string.to_string()));
}
result
}
IType::Array(ty) => {
let data = transmute_many::<u32, AllOrNothingGuard>(&data)
.map_err(|_| HostImportError::TransmuteArrayError(data.len(), stringify!(u32)))?;
let mut data = data.into_iter();
let mut result = Vec::with_capacity(data.len() / 2);
while let Some(&array_offset) = data.next() {
let array_size = *data
.next()
.ok_or_else(|| HostImportError::OddPointersCount(IType::Array(ty.clone())))?;
let array = lift_array(ctx, ty, array_offset as _, array_size as _, record_types)?;
result.push(IValue::Array(array));
}
result
}
IType::Record(record_type_id) => {
let record_type = record_types
.get(record_type_id)
.ok_or_else(|| HostImportError::RecordTypeNotFound(*record_type_id))?;
let mut result = Vec::with_capacity(data.len() / 2);
for record_offset in data {
let record = lift_record(ctx, &record_type, record_offset as _, record_types)?;
result.push(record);
}
result
}
};
Ok(result_array)
}
fn lift_record(
ctx: &Ctx,
record_type: &IRecordType,
offset: usize,
record_types: &Rc<RecordTypes>,
) -> HostImportResult<IValue> {
// TODO: make it export from wasmer-interface-types crate
fn record_size(record_type: &IRecordType) -> usize {
let mut record_size = 0;
for field_type in record_type.fields.iter() {
let params_count = match field_type.ty {
IType::String | IType::Array(_) => 2,
_ => 1,
};
record_size += std::mem::size_of::<u64>() * params_count;
}
record_size
}
let length = record_type.fields.len();
let mut values = Vec::with_capacity(length);
let size = record_size(record_type);
let data = WasmPtr::<u64, Array>::new(offset as _)
.deref(ctx.memory(0), 0, size as _)
.ok_or_else(|| HostImportError::InvalidMemoryAccess(offset as _, size as _))?;
let mut field_id = 0;
for field in (*record_type.fields).iter() {
let value = data[field_id].get();
match &field.ty {
IType::S8 => {
values.push(IValue::S8(value as _));
}
IType::S16 => {
values.push(IValue::S16(value as _));
}
IType::S32 => {
values.push(IValue::S32(value as _));
}
IType::S64 => {
values.push(IValue::S64(value as _));
}
IType::I32 => {
values.push(IValue::I32(value as _));
}
IType::I64 => {
values.push(IValue::I64(value as _));
}
IType::U8 => {
values.push(IValue::U8(value as _));
}
IType::U16 => {
values.push(IValue::U16(value as _));
}
IType::U32 => {
values.push(IValue::U32(value as _));
}
IType::U64 => {
values.push(IValue::U64(value as _));
}
IType::F32 => {
values.push(IValue::F32(value as _));
}
IType::F64 => values.push(IValue::F64(f64::from_bits(value))),
// anyrefs aren't supported now, and isn't generated by rust-sdk
IType::Anyref => unimplemented!("anyrefs aren't supported now"),
IType::String => {
let string_offset = value;
field_id += 1;
let string_size = data[field_id].get();
if string_size != 0 {
let string = WasmPtr::<u8, Array>::new(string_offset as _)
.get_utf8_string(ctx.memory(0), size as _)
.ok_or(HostImportError::OddPointersCount(IType::String))?;
values.push(IValue::String(string.to_string()));
} else {
values.push(IValue::String(String::new()));
}
}
IType::Array(ty) => {
let array_offset = value;
field_id += 1;
let array_size = data[field_id].get();
if array_size != 0 {
let array =
lift_array(ctx, &ty, array_offset as _, array_size as _, record_types)?;
values.push(IValue::Array(array));
} else {
values.push(IValue::Array(vec![]));
}
}
IType::Record(record_type_id) => {
let offset = value;
let record_type = record_types
.get(record_type_id)
.ok_or_else(|| HostImportError::RecordTypeNotFound(*record_type_id))?;
values.push(lift_record(ctx, record_type, offset as _, record_types)?);
}
}
field_id += 1;
}
Ok(IValue::Record(
NEVec::new(values.into_iter().collect())
.expect("Record must have at least one field, zero given"),
))
}
// TODO: refactor it later to avoid the copying
fn read_mem(ctx: &Ctx, offset: usize, size: usize) -> HostImportResult<Vec<u8>> {
let memory_index: u32 = 0;
let memory_view = ctx.memory(memory_index).view();
let right_margin = offset + size;
if right_margin < offset || right_margin >= memory_view.len() {
return Err(HostImportError::InvalidMemoryAccess(offset as _, size as _));
}
let memory_view = memory_view[offset..right_margin]
.iter()
.map(std::cell::Cell::get)
.collect::<Vec<_>>();
Ok(memory_view)
}

View File

@ -1,172 +0,0 @@
/*
* Copyright 2020 Fluence Labs Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/// Contain functions intended to put (lower) IValues to Wasm memory
/// and pass it to a Wasm module as raw WValues (Wasm types).
use super::WValue;
use super::AllocateFunc;
use super::utils::write_to_wasm_mem;
use crate::call_wasm_func;
use crate::IValue;
use wasmer_core::vm::Ctx;
use wasmer_wit::NEVec;
pub(super) fn ivalue_to_wvalues(
ctx: &mut Ctx,
ivalue: Option<IValue>,
allocate_func: &AllocateFunc,
) -> Vec<WValue> {
match ivalue {
Some(IValue::S8(v)) => vec![WValue::I32(v as _)],
Some(IValue::S16(v)) => vec![WValue::I32(v as _)],
Some(IValue::S32(v)) => vec![WValue::I32(v as _)],
Some(IValue::S64(v)) => vec![WValue::I64(v as _)],
Some(IValue::U8(v)) => vec![WValue::I32(v as _)],
Some(IValue::U16(v)) => vec![WValue::I32(v as _)],
Some(IValue::U32(v)) => vec![WValue::I32(v as _)],
Some(IValue::U64(v)) => vec![WValue::I64(v as _)],
Some(IValue::I32(v)) => vec![WValue::I32(v as _)],
Some(IValue::I64(v)) => vec![WValue::I64(v as _)],
Some(IValue::F32(v)) => vec![WValue::F32(v)],
Some(IValue::F64(v)) => vec![WValue::F64(v)],
Some(IValue::String(str)) => {
let offset = call_wasm_func!(allocate_func, str.len() as i32);
write_to_wasm_mem(ctx, offset as usize, str.as_bytes());
vec![WValue::I32(offset as _), WValue::I32(str.len() as _)]
}
Some(IValue::Array(values)) => {
let (offset, size) = lower_array(ctx, values, allocate_func);
vec![WValue::I32(offset as _), WValue::I32(size as _)]
}
Some(IValue::Record(values)) => {
let offset = lower_record(ctx, values, allocate_func);
vec![WValue::I32(offset)]
}
None => vec![],
}
}
fn lower_array(
ctx: &mut Ctx,
array_values: Vec<IValue>,
allocate_func: &AllocateFunc,
) -> (usize, usize) {
let mut result: Vec<u64> = Vec::with_capacity(array_values.len());
for value in array_values {
match value {
IValue::S8(value) => result.push(value as _),
IValue::S16(value) => result.push(value as _),
IValue::S32(value) => result.push(value as _),
IValue::S64(value) => result.push(value as _),
IValue::U8(value) => result.push(value as _),
IValue::U16(value) => result.push(value as _),
IValue::U32(value) => result.push(value as _),
IValue::U64(value) => result.push(value as _),
IValue::I32(value) => result.push(value as _),
IValue::I64(value) => result.push(value as _),
IValue::F32(value) => result.push(value as _),
IValue::F64(value) => result.push(value.to_bits()),
IValue::String(value) => {
let offset = call_wasm_func!(allocate_func, value.len() as _);
write_to_wasm_mem(ctx, offset as _, value.as_bytes());
result.push(offset as _);
result.push(value.len() as _);
}
IValue::Array(values) => {
let (array_offset, array_size) = if !values.is_empty() {
lower_array(ctx, values, allocate_func)
} else {
(0, 0)
};
result.push(array_offset as _);
result.push(array_size as _);
}
IValue::Record(values) => {
let record_offset = lower_record(ctx, values, allocate_func);
result.push(record_offset as _);
}
}
}
let result = safe_transmute::transmute_to_bytes::<u64>(&result);
let result_pointer = call_wasm_func!(allocate_func, result.len() as _);
write_to_wasm_mem(ctx, result_pointer as _, result);
(result_pointer as _, result.len() as _)
}
fn lower_record(ctx: &mut Ctx, values: NEVec<IValue>, allocate_func: &AllocateFunc) -> i32 {
let mut result: Vec<u64> = Vec::with_capacity(values.len());
for value in values.into_vec() {
match value {
IValue::S8(value) => result.push(value as _),
IValue::S16(value) => result.push(value as _),
IValue::S32(value) => result.push(value as _),
IValue::S64(value) => result.push(value as _),
IValue::U8(value) => result.push(value as _),
IValue::U16(value) => result.push(value as _),
IValue::U32(value) => result.push(value as _),
IValue::U64(value) => result.push(value as _),
IValue::I32(value) => result.push(value as _),
IValue::I64(value) => result.push(value as _),
IValue::F32(value) => result.push(value as _),
IValue::F64(value) => result.push(value.to_bits()),
IValue::String(value) => {
let string_pointer = if !value.is_empty() {
let offset = call_wasm_func!(allocate_func, value.len() as _);
write_to_wasm_mem(ctx, offset as usize, value.as_bytes());
offset
} else {
0
};
result.push(string_pointer as _);
result.push(value.len() as _);
}
IValue::Array(values) => {
let (offset, size) = if !values.is_empty() {
lower_array(ctx, values, allocate_func)
} else {
(0, 0)
};
result.push(offset as _);
result.push(size as _);
}
IValue::Record(values) => {
let record_ptr = lower_record(ctx, values, allocate_func);
result.push(record_ptr as _);
}
}
}
let result = safe_transmute::transmute_to_bytes::<u64>(&result);
let offset = call_wasm_func!(allocate_func, result.len() as _);
write_to_wasm_mem(ctx, offset as _, result);
offset as _
}

View File

@ -0,0 +1,41 @@
/*
* Copyright 2020 Fluence Labs Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
use crate::RecordTypes;
use crate::IRecordType;
use it_lilo::traits::RecordResolvable;
use it_lilo::traits::RecordResolvableError;
use std::rc::Rc;
pub(crate) struct LiHelper {
record_types: Rc<RecordTypes>,
}
impl LiHelper {
pub(crate) fn new(record_types: Rc<RecordTypes>) -> Self {
Self { record_types }
}
}
impl RecordResolvable for LiHelper {
fn resolve_record(&self, record_type_id: u64) -> Result<&IRecordType, RecordResolvableError> {
self.record_types
.get(&record_type_id)
.map(|r| r.as_ref())
.ok_or_else(|| RecordResolvableError::RecordNotFound(record_type_id))
}
}

View File

@ -0,0 +1,105 @@
/*
* Copyright 2020 Fluence Labs Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
use super::WType;
use super::WValue;
use super::HostImportError;
use super::HostImportResult;
use crate::IValue;
use crate::IType;
use it_lilo::lifter::*;
use it_lilo::traits::RecordResolvable;
macro_rules! next_wvalue {
($wvalue_iter:ident, $wtype:ident) => {
match $wvalue_iter
.next()
.ok_or_else(|| HostImportError::MismatchWValuesCount)?
{
WValue::$wtype(v) => *v,
v => return Err(HostImportError::MismatchWValues(WType::$wtype, v.clone())),
};
};
}
macro_rules! simple_wvalue_to_ivalue {
($result:ident, $wvalue_iter:ident, $wtype:ident, $ivalue:ident) => {{
let w = next_wvalue!($wvalue_iter, $wtype);
$result.push(IValue::$ivalue(w as _))
}};
}
pub(crate) fn wvalues_to_ivalues<R: RecordResolvable>(
lifter: &ILifter<'_, '_, R>,
wvalues: &[WValue],
itypes: &[IType],
) -> HostImportResult<Vec<IValue>> {
let mut result = Vec::with_capacity(wvalues.len());
let mut wvalue = wvalues.iter();
for itype in itypes.iter() {
match itype {
IType::Boolean => {
let w = next_wvalue!(wvalue, I32);
result.push(IValue::Boolean(w != 0))
}
IType::S8 => simple_wvalue_to_ivalue!(result, wvalue, I32, S8),
IType::S16 => simple_wvalue_to_ivalue!(result, wvalue, I32, S16),
IType::S32 => simple_wvalue_to_ivalue!(result, wvalue, I32, S32),
IType::S64 => simple_wvalue_to_ivalue!(result, wvalue, I64, S64),
IType::U8 => simple_wvalue_to_ivalue!(result, wvalue, I32, U8),
IType::U16 => simple_wvalue_to_ivalue!(result, wvalue, I32, U16),
IType::U32 => simple_wvalue_to_ivalue!(result, wvalue, I32, U32),
IType::U64 => simple_wvalue_to_ivalue!(result, wvalue, I64, U64),
IType::I32 => simple_wvalue_to_ivalue!(result, wvalue, I32, I32),
IType::I64 => simple_wvalue_to_ivalue!(result, wvalue, I64, I64),
IType::F32 => simple_wvalue_to_ivalue!(result, wvalue, F32, F32),
IType::F64 => simple_wvalue_to_ivalue!(result, wvalue, F64, F64),
IType::String => {
let offset = next_wvalue!(wvalue, I32);
let size = next_wvalue!(wvalue, I32);
let raw_str = lifter.reader.read_raw_u8_array(offset as _, size as _)?;
let str = String::from_utf8(raw_str)?;
result.push(IValue::String(str));
}
IType::ByteArray => {
let offset = next_wvalue!(wvalue, I32);
let size = next_wvalue!(wvalue, I32);
let array = lifter.reader.read_raw_u8_array(offset as _, size as _)?;
result.push(IValue::ByteArray(array));
}
IType::Array(ty) => {
let offset = next_wvalue!(wvalue, I32);
let size = next_wvalue!(wvalue, I32);
let array = array_lift_memory(lifter, ty, offset as _, size as _)?;
result.push(array);
}
IType::Record(record_type_id) => {
let record_type = lifter.resolver.resolve_record(*record_type_id)?;
let offset = next_wvalue!(wvalue, I32);
let record = record_lift_memory(lifter, record_type, offset as _)?;
result.push(record);
}
}
}
Ok(result)
}

View File

@ -0,0 +1,28 @@
/*
* Copyright 2020 Fluence Labs Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/// Contain functions intended to create (lift) IValues from raw WValues (Wasm types).
mod li_helper;
mod lift_ivalues;
pub(crate) use li_helper::LiHelper;
pub(crate) use lift_ivalues::wvalues_to_ivalues;
use super::WValue;
use super::WType;
use super::HostImportError;
use super::HostImportResult;

View File

@ -0,0 +1,56 @@
/*
* Copyright 2020 Fluence Labs Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
use super::AllocateFunc;
use crate::call_wasm_func;
use it_lilo::traits::Allocatable;
use it_lilo::traits::AllocatableError;
use wasmer_core::vm::Ctx;
use wasmer_core::vm::LocalMemory;
use std::cell::Cell;
pub(crate) struct LoHelper<'c> {
ctx: &'c Ctx,
allocate_func: &'c AllocateFunc,
}
impl<'c> LoHelper<'c> {
pub(crate) fn new(ctx: &'c Ctx, allocate_func: &'c AllocateFunc) -> Self {
Self { ctx, allocate_func }
}
}
impl Allocatable for LoHelper<'_> {
fn allocate(&self, size: u32, type_tag: u32) -> Result<usize, AllocatableError> {
let offset = call_wasm_func!(self.allocate_func, size as _, type_tag as _);
Ok(offset as _)
}
fn memory_slice(&self, memory_index: usize) -> Result<&[Cell<u8>], AllocatableError> {
let memory = self.ctx.memory(memory_index as _);
let LocalMemory { base, .. } = unsafe { *memory.vm_local_memory() };
let length = memory.size().bytes().0 / std::mem::size_of::<u8>();
let mut_slice: &mut [u8] = unsafe { std::slice::from_raw_parts_mut(base, length) };
let cell_slice: &Cell<[u8]> = Cell::from_mut(mut_slice);
let slice = cell_slice.as_slice_of_cells();
Ok(slice)
}
}

View File

@ -0,0 +1,64 @@
/*
* Copyright 2020 Fluence Labs Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
use super::WValue;
use super::HostImportResult;
use crate::IValue;
use it_lilo::lowerer::*;
use it_lilo::traits::Allocatable;
pub(crate) fn ivalue_to_wvalues<A: Allocatable>(
lowerer: &ILowerer<'_, A>,
ivalue: Option<IValue>,
) -> HostImportResult<Vec<WValue>> {
let result = match ivalue {
Some(IValue::Boolean(v)) => vec![WValue::I32(v as _)],
Some(IValue::S8(v)) => vec![WValue::I32(v as _)],
Some(IValue::S16(v)) => vec![WValue::I32(v as _)],
Some(IValue::S32(v)) => vec![WValue::I32(v as _)],
Some(IValue::S64(v)) => vec![WValue::I64(v as _)],
Some(IValue::U8(v)) => vec![WValue::I32(v as _)],
Some(IValue::U16(v)) => vec![WValue::I32(v as _)],
Some(IValue::U32(v)) => vec![WValue::I32(v as _)],
Some(IValue::U64(v)) => vec![WValue::I64(v as _)],
Some(IValue::I32(v)) => vec![WValue::I32(v as _)],
Some(IValue::I64(v)) => vec![WValue::I64(v as _)],
Some(IValue::F32(v)) => vec![WValue::F32(v)],
Some(IValue::F64(v)) => vec![WValue::F64(v)],
Some(IValue::String(str)) => {
let offset = lowerer.writer.write_bytes(str.as_bytes())?;
vec![WValue::I32(offset as _), WValue::I32(str.len() as _)]
}
Some(IValue::ByteArray(array)) => {
let offset = lowerer.writer.write_bytes(&array)?;
vec![WValue::I32(offset as _), WValue::I32(array.len() as _)]
}
Some(IValue::Array(values)) => {
let LoweredArray { offset, size } = array_lower_memory(&lowerer, values)?;
vec![WValue::I32(offset as _), WValue::I32(size as _)]
}
Some(IValue::Record(values)) => {
let offset = record_lower_memory(&lowerer, values)?;
vec![WValue::I32(offset)]
}
None => vec![],
};
Ok(result)
}

View File

@ -0,0 +1,27 @@
/*
* Copyright 2020 Fluence Labs Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/// Contain functions intended to put (lower) IValues to Wasm memory
/// and pass it to a Wasm module as raw WValues (Wasm types).
mod lo_helper;
mod lower_ivalues;
pub(crate) use lo_helper::LoHelper;
pub(crate) use lower_ivalues::ivalue_to_wvalues;
use super::WValue;
use super::AllocateFunc;
use super::HostImportResult;

View File

@ -15,9 +15,9 @@
*/
mod errors;
mod lifting;
mod lowering;
mod imports;
mod ivalues_lifting;
mod ivalues_lowering;
mod utils;
use std::cell::RefCell;
@ -31,7 +31,7 @@ pub(self) use wasmer_core::types::Type as WType;
pub(self) type HostImportResult<T> = std::result::Result<T, HostImportError>;
pub(self) type WasmModuleFunc<Args, Rets> = Box<RefCell<Option<Func<'static, Args, Rets>>>>;
pub(self) type AllocateFunc = WasmModuleFunc<i32, i32>;
pub(self) type AllocateFunc = WasmModuleFunc<(i32, i32), i32>;
pub(self) type SetResultPtrFunc = WasmModuleFunc<i32, ()>;
pub(self) type SetResultSizeFunc = WasmModuleFunc<i32, ()>;

View File

@ -96,15 +96,6 @@ where
Ok(typed_func)
}
pub(super) fn write_to_wasm_mem(context: &mut Ctx, address: usize, value: &[u8]) {
let memory = context.memory(0);
memory.view::<u8>()[address..(address + value.len())]
.iter()
.zip(value.iter())
.for_each(|(cell, byte)| cell.set(*byte));
}
pub(super) fn itypes_args_to_wtypes(itypes: &[IType]) -> Vec<WType> {
itypes
.iter()
@ -161,7 +152,7 @@ macro_rules! init_wasm_func_once {
#[macro_export]
/// Call Wasm function that have Box<RefCell<Option<Func<'static, args, rets>>>> type.
macro_rules! call_wasm_func {
($func:ident, $arg:expr) => {
$func.borrow().as_ref().unwrap().call($arg).unwrap()
($func:expr, $($arg:expr),*) => {
$func.borrow().as_ref().unwrap().call($($arg),*).unwrap()
};
}

View File

@ -268,13 +268,8 @@ impl FCEModule {
wit.implementations()
.filter_map(|(adapter_function_type, core_function_type)| {
match wit.exports_by_type(*core_function_type) {
Some(export_function_name) => {
Some((adapter_function_type, export_function_name))
}
// pass functions that aren't export
None => None,
}
wit.exports_by_type(*core_function_type)
.map(|export_function_name| (adapter_function_type, export_function_name))
})
.map(|(adapter_function_type, export_function_names)| {
export_function_names
@ -392,11 +387,8 @@ impl FCEModule {
let wit_import_funcs = wit
.implementations()
.filter_map(|(adapter_function_type, core_function_type)| {
match wit.imports_by_type(*core_function_type) {
Some(import) => Some((adapter_function_type, import)),
// skip functions that aren't import
None => None,
}
wit.imports_by_type(*core_function_type)
.map(|import| (adapter_function_type, import))
})
.map(|(adapter_function_type, import_function_names)| {
import_function_names

View File

@ -26,6 +26,7 @@ use wasmer_wit::interpreter::wasm::structures::{LocalImportIndex, TypedIndex};
use wasmer_core::Instance as WasmerInstance;
use std::collections::HashMap;
use std::cell::Cell;
use std::rc::Rc;
pub type RecordTypes = HashMap<u64, Rc<IRecordType>>;
@ -195,6 +196,24 @@ impl wasm::structures::Instance<WITExport, WITFunction, WITMemory, WITMemoryView
}
}
fn memory_slice(&self, index: usize) -> Option<&[Cell<u8>]> {
use wasmer_core::vm::LocalMemory;
if index >= self.memories.len() {
return None;
}
let memory = &self.memories[index];
let LocalMemory { base, .. } = unsafe { *memory.0.vm_local_memory() };
let length = memory.0.size().bytes().0 / std::mem::size_of::<u8>();
let mut_slice: &mut [u8] = unsafe { std::slice::from_raw_parts_mut(base, length) };
let cell_slice: &Cell<[u8]> = Cell::from_mut(mut_slice);
let slice = cell_slice.as_slice_of_cells();
Some(slice)
}
fn wit_record_by_id(&self, index: u64) -> Option<&Rc<IRecordType>> {
self.record_types_by_id.get(&index)
}

View File

@ -43,7 +43,7 @@ pub fn records() {
result,
vec![IValue::Record(
wasmer_wit::NEVec::new(vec![
IValue::I32(1),
IValue::Boolean(true),
IValue::S8(1),
IValue::S16(2),
IValue::S32(3),
@ -55,7 +55,7 @@ pub fn records() {
IValue::F32(9.0),
IValue::F64(10.0),
IValue::String(String::from("field_11")),
IValue::Array(vec![IValue::U8(0x13), IValue::U8(0x37)])
IValue::ByteArray(vec![0x13, 0x37])
])
.unwrap()
)]

View File

@ -20,7 +20,7 @@ use fce::IValue;
const REDIS_DOWNLOAD_URL: &str =
"https://github.com/fluencelabs/redis/releases/download/v0.12.0_w/redis.wasm";
const SQLITE_DOWNLOAD_URL: &str =
"https://github.com/fluencelabs/sqlite/releases/download/v0.12.0_w/sqlite3.wasm";
"https://github.com/fluencelabs/sqlite/releases/download/v0.14.0_w/sqlite3.wasm";
pub async fn download(url: &str) -> bytes::Bytes {
reqwest::get(url)

View File

@ -1,7 +1,9 @@
#!/bin/sh
cargo update
fce build --release
cargo update --aggressive;
fce build --release;
rm -f artifacts/*
cp ../../target/wasm32-wasi/release/call_parameters.wasm artifacts/
rm -f artifacts/* || true;
mkdir -p artifacts;
cp ../../target/wasm32-wasi/release/call_parameters.wasm artifacts/;

View File

@ -1,8 +1,10 @@
#!/bin/sh
# This script builds all subprojects and puts all created Wasm modules in one dir
cargo update
cargo update --aggressive
fce build --release
rm artifacts/*
rm artifacts/* || true
mkdir -p artifacts
cp ../../target/wasm32-wasi/release/greeting.wasm artifacts/

View File

@ -1,14 +1,20 @@
#!/bin/sh
# This script builds all subprojects and puts all created Wasm modules in one dir
cd effector
cargo update
fce build --release
cd ../pure
cargo update
fce build --release
(
cd effector || exit;
cargo update --aggressive;
fce build --release;
)
(
cd pure || exit;
cargo update --aggressive;
fce build --release;
)
rm artifacts/* || true
mkdir -p artifacts
cd ..
rm artifacts/*
cp ../../target/wasm32-wasi/release/ipfs_effector.wasm artifacts/
cp ../../target/wasm32-wasi/release/ipfs_pure.wasm artifacts/

View File

@ -1,14 +1,20 @@
#!/bin/sh
# This script builds all subprojects and puts all created Wasm modules in one dir
cd effector
cargo update
fce build --release
cd ../pure
cargo update
fce build --release
(
cd effector || exit;
cargo update --aggressive;
fce build --release;
)
(
cd pure || exit;
cargo update --aggressive;
fce build --release;
)
rm artifacts/* || true
mkdir -p artifacts
cd ..
rm artifacts/*
cp ../../target/wasm32-wasi/release/records_effector.wasm artifacts/
cp ../../target/wasm32-wasi/release/records_pure.wasm artifacts/

View File

@ -1,10 +1,12 @@
#!/bin/sh
# This script builds all subprojects and puts all created Wasm modules in one dir
cargo update
cargo update --aggressive
fce build --release
rm artifacts/*
rm artifacts/* || true
mkdir -p artifacts
cp ../../target/wasm32-wasi/release/sqlite_test.wasm artifacts/
wget https://github.com/fluencelabs/sqlite/releases/download/v0.12.0_w/sqlite3.wasm
wget https://github.com/fluencelabs/sqlite/releases/download/v0.14.0_w/sqlite3.wasm
mv sqlite3.wasm artifacts/

View File

@ -1,18 +1,27 @@
#!/bin/sh
# This script builds all subprojects and puts all created Wasm modules in one dir
cd local_storage
cargo update
fce build --release
cd ../curl_adapter
cargo update
fce build --release
cd ../facade
cargo update
fce build --release
(
cd local_storage || exit;
cargo update --aggressive;
fce build --release;
)
(
cd curl_adapter || exit;
cargo update --aggressive;
fce build --release;
)
(
cd facade || exit;
cargo update --aggressive;
fce build --release;
)
rm -f artifacts/* || true
mkdir -p artifacts
cd ..
rm -f artifacts/*
cp ../../target/wasm32-wasi/release/local_storage.wasm artifacts/
cp ../../target/wasm32-wasi/release/curl_adapter.wasm artifacts/
cp ../../target/wasm32-wasi/release/facade.wasm artifacts/

View File

@ -31,10 +31,24 @@ pub fn main() {
#[fce]
pub fn download(url: String) -> String {
log::info!("get called with url {}", url);
log::info!("download called with url {}\n", url);
unsafe {
log::info!(
"download track: {} {} {} {} {}",
*ALLOCS.get_mut(),
*DEALLOCS.get_mut(),
*REALLOCSA.get_mut(),
*REALLOCSD.get_mut(),
*ALLOCS.get_mut() - *DEALLOCS.get_mut() - *REALLOCSD.get_mut() + *REALLOCSA.get_mut()
);
}
let result = curl(vec![url]);
String::from_utf8(result.stdout).unwrap()
let res = String::from_utf8(result.stdout).unwrap();
log::info!("download ended with {}\n", res);
res
}
/// Permissions in `Config.toml` should exist to use host functions.
@ -43,3 +57,65 @@ pub fn download(url: String) -> String {
extern "C" {
fn curl(cmd: Vec<String>) -> MountedBinaryResult;
}
use std::alloc::{GlobalAlloc, System, Layout};
#[global_allocator]
static GLOBAL_ALLOCATOR: WasmTracingAllocator<System> = WasmTracingAllocator(System);
#[derive(Debug)]
pub struct WasmTracingAllocator<A>(pub A)
where
A: GlobalAlloc;
use std::sync::atomic::AtomicUsize;
static mut ALLOCS: AtomicUsize = AtomicUsize::new(0);
static mut DEALLOCS: AtomicUsize = AtomicUsize::new(0);
static mut REALLOCSA: AtomicUsize = AtomicUsize::new(0);
static mut REALLOCSD: AtomicUsize = AtomicUsize::new(0);
unsafe impl<A> GlobalAlloc for WasmTracingAllocator<A>
where
A: GlobalAlloc,
{
unsafe fn alloc(&self, layout: Layout) -> *mut u8 {
let size = layout.size();
let t = *ALLOCS.get_mut();
*ALLOCS.get_mut() = t + size;
let pointer = self.0.alloc(layout);
pointer
}
unsafe fn dealloc(&self, pointer: *mut u8, layout: Layout) {
let size = layout.size();
let t = *DEALLOCS.get_mut();
*DEALLOCS.get_mut() = t + size;
self.0.dealloc(pointer, layout);
}
unsafe fn alloc_zeroed(&self, layout: Layout) -> *mut u8 {
let size = layout.size();
let t = *ALLOCS.get_mut();
*ALLOCS.get_mut() = t + size;
let pointer = self.0.alloc_zeroed(layout);
pointer
}
unsafe fn realloc(&self, old_pointer: *mut u8, layout: Layout, new_size: usize) -> *mut u8 {
let old_size = layout.size();
let t = *REALLOCSD.get_mut();
*REALLOCSD.get_mut() = t + old_size;
let t = *REALLOCSA.get_mut();
*REALLOCSA.get_mut() = t + layout.size();
let new_pointer = self.0.realloc(old_pointer, layout, new_size);
new_pointer
}
}

View File

@ -29,9 +29,16 @@ pub fn main() {
/// Calls `curl` and stores returned result into a file.
#[fce]
pub fn get_n_save(url: String, file_name: String) -> String {
log::info!("get_n_save called with {} {}\n", url, file_name);
let result = download(url);
log::info!("get_n_save {} download\n", result);
file_put(file_name, result.into_bytes());
log::info!("get_n_save ended with Ok\n");
String::from("Ok")
}

View File

@ -11,4 +11,6 @@ path = "src/main.rs"
[dependencies]
fluence = { git = "https://github.com/fluencelabs/rust-sdk", features = ["logger"] }
wasm-tracing-allocator = "0.1.0"
log = "0.4.8"

View File

@ -33,7 +33,17 @@ pub fn main() {
/// You can read or write files from the file system if there is permission to use directories described in `Config.toml`.
#[fce]
pub fn put(name: String, file_content: Vec<u8>) -> String {
log::info!("put called with file name {}", name);
log::info!("put called with file name {}\n", name);
unsafe {
log::info!(
"put track: {} {} {} {} {}",
*ALLOCS.get_mut(),
*DEALLOCS.get_mut(),
*REALLOCSA.get_mut(),
*REALLOCSD.get_mut(),
*ALLOCS.get_mut() - *DEALLOCS.get_mut() - *REALLOCSD.get_mut() + *REALLOCSA.get_mut()
);
}
let rpc_tmp_filepath = format!("{}{}", SITES_DIR, name);
@ -42,14 +52,92 @@ pub fn put(name: String, file_content: Vec<u8>) -> String {
return format!("file can't be written: {}", e);
}
log::info!("put ended with OK\n");
String::from("Ok")
}
#[fce]
pub fn get(file_name: String) -> Vec<u8> {
log::info!("get called with file name: {}", file_name);
log::info!("get called with file name: {}\n", file_name);
unsafe {
log::info!(
"get track: {} {} {} {} {}",
*ALLOCS.get_mut(),
*DEALLOCS.get_mut(),
*REALLOCSA.get_mut(),
*REALLOCSD.get_mut(),
*ALLOCS.get_mut() - *DEALLOCS.get_mut() - *REALLOCSD.get_mut() + *REALLOCSA.get_mut()
);
}
let tmp_filepath = format!("{}{}", SITES_DIR, file_name);
fs::read(tmp_filepath).unwrap_or_else(|_| b"error while reading file".to_vec())
let res = fs::read(tmp_filepath).unwrap_or_else(|_| b"error while reading file".to_vec());
log::info!("get ended with file name: {}\n", file_name);
res
}
use std::alloc::{GlobalAlloc, System, Layout};
#[global_allocator]
static GLOBAL_ALLOCATOR: WasmTracingAllocator<System> = WasmTracingAllocator(System);
#[derive(Debug)]
pub struct WasmTracingAllocator<A>(pub A)
where
A: GlobalAlloc;
use std::sync::atomic::AtomicUsize;
static mut ALLOCS: AtomicUsize = AtomicUsize::new(0);
static mut DEALLOCS: AtomicUsize = AtomicUsize::new(0);
static mut REALLOCSA: AtomicUsize = AtomicUsize::new(0);
static mut REALLOCSD: AtomicUsize = AtomicUsize::new(0);
unsafe impl<A> GlobalAlloc for WasmTracingAllocator<A>
where
A: GlobalAlloc,
{
unsafe fn alloc(&self, layout: Layout) -> *mut u8 {
let size = layout.size();
let t = *ALLOCS.get_mut();
*ALLOCS.get_mut() = t + size;
let pointer = self.0.alloc(layout);
pointer
}
unsafe fn dealloc(&self, pointer: *mut u8, layout: Layout) {
let size = layout.size();
let t = *DEALLOCS.get_mut();
*DEALLOCS.get_mut() = t + size;
self.0.dealloc(pointer, layout);
}
unsafe fn alloc_zeroed(&self, layout: Layout) -> *mut u8 {
let size = layout.size();
let t = *ALLOCS.get_mut();
*ALLOCS.get_mut() = t + size;
let pointer = self.0.alloc_zeroed(layout);
pointer
}
unsafe fn realloc(&self, old_pointer: *mut u8, layout: Layout, new_size: usize) -> *mut u8 {
let old_size = layout.size();
let t = *REALLOCSD.get_mut();
*REALLOCSD.get_mut() = t + old_size;
let t = *REALLOCSA.get_mut();
*REALLOCSA.get_mut() = t + layout.size();
let new_pointer = self.0.realloc(old_pointer, layout, new_size);
new_pointer
}
}

View File

@ -0,0 +1,6 @@
<HTML><HEAD><meta http-equiv="content-type" content="text/html;charset=utf-8">
<TITLE>301 Moved</TITLE></HEAD><BODY>
<H1>301 Moved</H1>
The document has moved
<A HREF="http://www.google.com/">here</A>.
</BODY></HTML>

View File

@ -59,8 +59,8 @@ pub(crate) fn into_service_interface(faas_interface: FaaSModuleInterface<'_>) ->
.collect::<Vec<_>>();
ServiceInterface {
record_types,
function_signatures,
record_types,
}
}

View File

@ -16,7 +16,7 @@ wasmer-runtime = { package = "wasmer-runtime-fl", version = "0.17.0" }
# dynamicfunc-fat-closures allows using state inside DynamicFunc
wasmer-core = { package = "wasmer-runtime-core-fl", version = "0.17.0", features = ["dynamicfunc-fat-closures"] }
wasmer-wasi = { package = "wasmer-wasi-fl", version = "0.17.1" }
wasmer-wit = { package = "wasmer-interface-types-fl", version = "=0.19.0" }
wasmer-wit = { package = "wasmer-interface-types-fl", version = "0.20.0" }
toml = "0.5.6"
serde = { version = "=1.0.118", features = ["derive"] }

View File

@ -16,8 +16,8 @@
use fce::FCEError;
use std::io::Error as IOError;
use thiserror::Error;
use std::io::Error as IOError;
use std::path::PathBuf;
#[derive(Debug, Error)]
@ -54,20 +54,20 @@ pub enum FaaSError {
NoSuchModule(String),
/// Provided arguments aren't compatible with a called function signature.
#[error("JsonArgumentsDeserializationError: {0}")]
#[error("arguments from json deserialization error: {0}")]
JsonArgumentsDeserializationError(String),
/// Returned outputs aren't compatible with a called function signature.
#[error("JsonOutputSerializationError: {0}")]
#[error("output to json serialization error: {0}")]
JsonOutputSerializationError(String),
/// Errors related to invalid config.
#[error("ParseConfigError: {0}")]
ParseConfigError(toml::de::Error),
#[error("parsing config error: {0}")]
ParseConfigError(#[from] toml::de::Error),
/// FCE errors.
#[error("EngineError: {0}")]
EngineError(FCEError),
#[error("engine error: {0}")]
EngineError(#[from] FCEError),
}
impl From<IOError> for FaaSError {
@ -76,18 +76,6 @@ impl From<IOError> for FaaSError {
}
}
impl From<FCEError> for FaaSError {
fn from(err: FCEError) -> Self {
FaaSError::EngineError(err)
}
}
impl From<toml::de::Error> for FaaSError {
fn from(err: toml::de::Error) -> Self {
FaaSError::ParseConfigError(err)
}
}
impl From<std::convert::Infallible> for FaaSError {
fn from(_: std::convert::Infallible) -> Self {
unreachable!()

View File

@ -40,7 +40,7 @@ pub(crate) fn create_mounted_binary_import(mounted_binary_path: String) -> HostI
}
pub(self) fn mounted_binary_import_impl(
mounted_binary_path: &String,
mounted_binary_path: &str,
raw_args: Vec<IValue>,
) -> Result<MountedBinaryResult, MountedBinaryResult> {
let args = parse_args(raw_args)?;

View File

@ -47,6 +47,7 @@ fn ivalue_to_json(ivalue: IValue, output: &IType, record_types: &RecordTypes) ->
// clone here needed because binding by-value and by-ref in the same pattern in unstable
match (ivalue, output.clone()) {
(IValue::Boolean(value), IType::Boolean) => Ok(json!(value)),
(IValue::S8(value), IType::S8) => Ok(json!(value)),
(IValue::S16(value), IType::S16) => Ok(json!(value)),
(IValue::S32(value), IType::S32) => Ok(json!(value)),
@ -60,6 +61,26 @@ fn ivalue_to_json(ivalue: IValue, output: &IType, record_types: &RecordTypes) ->
(IValue::F32(value), IType::F32) => Ok(json!(value)),
(IValue::F64(value), IType::F64) => Ok(json!(value)),
(IValue::String(value), IType::String) => Ok(json!(value)),
(IValue::ByteArray(value), IType::ByteArray) => {
let result = value.into_iter().map(|v| json!(v)).collect();
Ok(JValue::Array(result))
}
(IValue::Array(value), IType::ByteArray) => {
let result: Result<Vec<_>> = value
.into_iter()
.map(|v| ivalue_to_json(v, &IType::U8, record_types))
.collect();
Ok(JValue::Array(result?))
}
(IValue::ByteArray(value), IType::Array(array_ty)) => {
let result: Result<Vec<_>> = value
.into_iter()
.map(|v| ivalue_to_json(IValue::U8(v), &array_ty, record_types))
.collect();
Ok(JValue::Array(result?))
}
(IValue::Array(value), IType::Array(array_ty)) => {
let result: Result<Vec<_>> = value
.into_iter()

View File

@ -151,6 +151,7 @@ fn jvalue_to_ivalue(jvalue: JValue, ty: &IType, record_types: &RecordTypes) -> R
);
match ty {
IType::Boolean => to_ivalue!(jvalue, Boolean),
IType::S8 => to_ivalue!(jvalue, S8),
IType::S16 => to_ivalue!(jvalue, S16),
IType::S32 => to_ivalue!(jvalue, S32),
@ -162,6 +163,21 @@ fn jvalue_to_ivalue(jvalue: JValue, ty: &IType, record_types: &RecordTypes) -> R
IType::F32 => to_ivalue!(jvalue, F32),
IType::F64 => to_ivalue!(jvalue, F64),
IType::String => to_ivalue!(jvalue, String),
IType::ByteArray => {
let value = match jvalue {
JValue::Array(json_array) => {
let iargs = json_array
.into_iter()
.map(|json_value| jvalue_to_ivalue(json_value, &IType::U8, record_types))
.collect::<Result<Vec<_>>>()?;
Ok(iargs)
}
_ => Err(ArgDeError(format!("expected bytearray, got {:?}", jvalue))),
}?;
Ok(IValue::Array(value))
}
IType::Array(value_type) => {
let value = match jvalue {
JValue::Array(json_array) => {
@ -186,7 +202,6 @@ fn jvalue_to_ivalue(jvalue: JValue, ty: &IType, record_types: &RecordTypes) -> R
let value = json_record_type_to_ivalue(jvalue, record_type_id, &record_types)?;
Ok(IValue::Record(value))
}
IType::Anyref => Err(ArgDeError(String::from("anyrefs aren't supported now"))),
}
}

View File

@ -22,11 +22,11 @@ use crate::FaaSError;
use crate::Result;
use std::collections::HashMap;
use std::path::{PathBuf, Path};
use std::path::Path;
/// Loads modules from a directory at a given path. Non-recursive, ignores subdirectories.
pub(crate) fn load_modules_from_fs(
modules_dir: &PathBuf,
modules_dir: &Path,
modules: ModulesLoadStrategy<'_>,
) -> Result<HashMap<String, Vec<u8>>> {
use FaaSError::IOError;

View File

@ -80,9 +80,9 @@ pub fn get_interfaces() {
let bytearray_type_arguments = vec![fluence_faas::IFunctionArg {
name: String::from("arg"),
ty: IType::Array(Box::new(IType::U8)),
ty: IType::ByteArray,
}];
let bytearray_type_outputs = vec![IType::Array(Box::new(IType::U8))];
let bytearray_type_outputs = vec![IType::ByteArray];
let bytearray_type_sign = fluence_faas::FaaSFunctionSignature {
name: Rc::new(String::from("bytearray_type")),
@ -216,9 +216,9 @@ pub fn get_interfaces() {
let bool_type_arguments = vec![fluence_faas::IFunctionArg {
name: String::from("arg"),
ty: IType::I32,
ty: IType::Boolean,
}];
let bool_type_outputs = vec![IType::I32];
let bool_type_outputs = vec![IType::Boolean];
let bool_type_sign = fluence_faas::FaaSFunctionSignature {
name: Rc::new(String::from("bool_type")),
@ -279,10 +279,10 @@ pub fn get_interfaces() {
},
fluence_faas::IFunctionArg {
name: String::from("arg_11"),
ty: IType::Array(Box::new(IType::U8)),
ty: IType::ByteArray,
},
];
let all_types_outputs = vec![IType::Array(Box::new(IType::U8))];
let all_types_outputs = vec![IType::ByteArray];
let all_types_sign = fluence_faas::FaaSFunctionSignature {
name: Rc::new(String::from("all_types")),
@ -430,11 +430,11 @@ pub fn i32_type() {
let result5 = call_faas!(faas, MODULE_NAME, func_name, json!([[1]]));
assert_eq!(result5, expected_result);
let value = std::i32::MAX - 2;
let value = i32::MAX - 2;
let result6 = call_faas!(faas, MODULE_NAME, func_name, json!(value));
assert_eq!(result6, value + 2);
let value = std::i32::MIN;
let value = i32::MIN;
let result7 = call_faas!(faas, MODULE_NAME, func_name, json!(value));
assert_eq!(result7, value + 2);
};
@ -465,11 +465,11 @@ pub fn i64_type() {
let result5 = call_faas!(faas, MODULE_NAME, func_name, json!([1]));
assert_eq!(result5, expected_result);
let value = std::i64::MAX - 2;
let value = i64::MAX - 2;
let result6 = call_faas!(faas, MODULE_NAME, func_name, json!(value));
assert_eq!(result6, value + 2);
let value = std::i64::MIN;
let value = i64::MIN;
let result7 = call_faas!(faas, MODULE_NAME, func_name, json!(value));
assert_eq!(result7, value + 2);
};
@ -545,11 +545,11 @@ pub fn f32_type() {
let result4 = call_faas!(faas, MODULE_NAME, func_name, json!(1.0));
assert_eq!(result4, expected_result);
let value = std::f32::MAX - 2.0;
let value = f32::MAX - 2.0;
let result5 = call_faas!(faas, MODULE_NAME, func_name, json!(value));
assert_eq!(result5, value + 2.0);
let value = std::f32::MIN;
let value = f32::MIN;
let result6 = call_faas!(faas, MODULE_NAME, func_name, json!(value));
assert_eq!(result6, value + 2.0);
};
@ -577,11 +577,11 @@ pub fn f64_type() {
let result4 = call_faas!(faas, MODULE_NAME, func_name, json!(1.0));
assert_eq!(result4, expected_result);
let value = std::f64::MAX - 2.0;
let value = f64::MAX - 2.0;
let result5 = call_faas!(faas, MODULE_NAME, func_name, json!(value));
assert_eq!(result5, value + 2.0);
let value = std::f64::MIN;
let value = f64::MIN;
let result6 = call_faas!(faas, MODULE_NAME, func_name, json!(value));
assert_eq!(result6, value + 2.0);
};
@ -674,11 +674,11 @@ pub fn bool_type() {
let result2 = faas.call_with_json(MODULE_NAME, func_name, json!([]), <_>::default());
assert!(result2.is_err());
let expected_result = json!(1);
let result3 = call_faas!(faas, MODULE_NAME, func_name, json!({ "arg": 0 }));
let expected_result = json!(true);
let result3 = call_faas!(faas, MODULE_NAME, func_name, json!({ "arg": false }));
assert_eq!(result3, expected_result);
let result4 = call_faas!(faas, MODULE_NAME, func_name, json!(0));
let result4 = call_faas!(faas, MODULE_NAME, func_name, json!(false));
assert_eq!(result4, expected_result);
};

View File

@ -46,9 +46,9 @@ pub fn get_interfaces() {
let byte_type_arguments = vec![fluence_faas::IFunctionArg {
name: String::from("arg"),
ty: IType::Array(Box::new(IType::U8)),
ty: IType::ByteArray,
}];
let byte_type_outputs = vec![IType::Array(Box::new(IType::U8))];
let byte_type_outputs = vec![IType::ByteArray];
let byte_type_sign = fluence_faas::FaaSFunctionSignature {
name: Rc::new(String::from("byte_type")),
@ -59,11 +59,11 @@ pub fn get_interfaces() {
let inner_arrays_1_arguments = vec![fluence_faas::IFunctionArg {
name: String::from("arg"),
ty: IType::Array(Box::new(IType::Array(Box::new(IType::Array(Box::new(
IType::Array(Box::new(IType::U8)),
IType::ByteArray,
)))))),
}];
let inner_arrays_1_outputs = vec![IType::Array(Box::new(IType::Array(Box::new(
IType::Array(Box::new(IType::Array(Box::new(IType::U8)))),
IType::Array(Box::new(IType::ByteArray)),
))))];
let inner_arrays_1_sign = fluence_faas::FaaSFunctionSignature {
@ -185,24 +185,23 @@ pub fn get_interfaces() {
outputs: Rc::new(empty_type_outputs),
};
/*
let bool_type_arguments = vec![fluence_faas::IFunctionArg {
name: String::from("arg"),
ty: IType::I32,
ty: IType::Array(Box::new(IType::Boolean)),
}];
let bool_type_outputs = vec![IType::I32];
let bool_type_outputs = vec![IType::Array(Box::new(IType::Boolean))];
let bool_type_sign = fluence_faas::FaaSFunctionSignature {
name: "bool_type",
arguments: &bool_type_arguments,
outputs: &bool_type_outputs,
name: Rc::new(String::from("bool_type")),
arguments: Rc::new(bool_type_arguments),
outputs: Rc::new(bool_type_outputs),
};
*/
let functions = vec![
byte_type_sign,
inner_arrays_1_sign,
string_type_sign,
bool_type_sign,
f32_type_sign,
f64_type_sign,
u32_type_sign,
@ -249,7 +248,7 @@ pub fn i32_type() {
let mut faas = FluenceFaaS::with_raw_config(ARG_CONFIG.clone())
.unwrap_or_else(|e| panic!("can't create Fluence FaaS instance: {}", e));
let right_result = json!([0, 1, 2, 3, 4, 0, 2]);
let expected_result = json!([0, 1, 2, 3, 4, 0, 2]);
let result1 = faas
.call_with_json(
@ -259,7 +258,7 @@ pub fn i32_type() {
<_>::default(),
)
.unwrap_or_else(|e| panic!("can't invoke i32_type: {:?}", e));
assert_eq!(result1, right_result);
assert_eq!(result1, expected_result);
let result2 = faas
.call_with_json(
@ -269,9 +268,9 @@ pub fn i32_type() {
<_>::default(),
)
.unwrap_or_else(|e| panic!("can't invoke i32_type: {:?}", e));
assert_eq!(result2, right_result);
assert_eq!(result2, expected_result);
let right_result = json!([1, 0, 1, 2, 3, 4, 0, 2]);
let expected_result = json!([1, 0, 1, 2, 3, 4, 0, 2]);
let result3 = faas
.call_with_json(
"arrays_passing_pure",
@ -280,7 +279,7 @@ pub fn i32_type() {
<_>::default(),
)
.unwrap_or_else(|e| panic!("can't invoke i32_type: {:?}", e));
assert_eq!(result3, right_result);
assert_eq!(result3, expected_result);
}
#[test]
@ -294,7 +293,7 @@ pub fn i64_type() {
let result2 = faas.call_with_json("arrays_passing_pure", "i64_type", json!([]), <_>::default());
assert!(result2.is_err());
let right_result = json!([1, 0, 1, 2, 3, 4, 1, 1]);
let expected_result = json!([1, 0, 1, 2, 3, 4, 1, 1]);
let result3 = faas
.call_with_json(
@ -304,7 +303,7 @@ pub fn i64_type() {
<_>::default(),
)
.unwrap_or_else(|e| panic!("can't invoke i64_type: {:?}", e));
assert_eq!(result3, right_result);
assert_eq!(result3, expected_result);
let result4 = faas
.call_with_json(
@ -314,7 +313,7 @@ pub fn i64_type() {
<_>::default(),
)
.unwrap_or_else(|e| panic!("can't invoke i64_type: {:?}", e));
assert_eq!(result4, right_result);
assert_eq!(result4, expected_result);
}
#[test]
@ -328,7 +327,7 @@ pub fn u32_type() {
let result2 = faas.call_with_json("arrays_passing_pure", "u32_type", json!([]), <_>::default());
assert!(result2.is_err());
let right_result = json!([1, 0, 13, 37, 2]);
let expected_result = json!([1, 0, 13, 37, 2]);
let result3 = call_faas!(
faas,
@ -336,10 +335,10 @@ pub fn u32_type() {
"u32_type",
json!({ "arg": [1] })
);
assert_eq!(result3, right_result);
assert_eq!(result3, expected_result);
let result4 = call_faas!(faas, "arrays_passing_pure", "u32_type", json!([[1]]));
assert_eq!(result4, right_result);
assert_eq!(result4, expected_result);
}
#[test]
@ -353,7 +352,7 @@ pub fn u64_type() {
let result2 = faas.call_with_json("arrays_passing_pure", "u64_type", json!([]), <_>::default());
assert!(result2.is_err());
let right_result = json!([1, 0, 1, 2, 3, 4, 2]);
let expected_result = json!([1, 0, 1, 2, 3, 4, 2]);
let result3 = call_faas!(
faas,
@ -361,14 +360,14 @@ pub fn u64_type() {
"u64_type",
json!({ "arg": [1] })
);
assert_eq!(result3, right_result);
assert_eq!(result3, expected_result);
let result4 = call_faas!(faas, "arrays_passing_pure", "u64_type", json!([[1]]));
assert_eq!(result4, right_result);
assert_eq!(result4, expected_result);
}
#[test]
pub fn f64_type_() {
pub fn f64_type() {
let mut faas = FluenceFaaS::with_raw_config(ARG_CONFIG.clone())
.unwrap_or_else(|e| panic!("can't create Fluence FaaS instance: {}", e));
@ -378,7 +377,7 @@ pub fn f64_type_() {
let result2 = faas.call_with_json("arrays_passing_pure", "f32_type", json!([]), <_>::default());
assert!(result2.is_err());
let right_result = json!([1.0, 0.0, 13.37, 1.0]);
let expected_result = json!([1.0, 0.0, 13.37, 1.0]);
let result3 = call_faas!(
faas,
@ -386,36 +385,10 @@ pub fn f64_type_() {
"f64_type",
json!({ "arg": [1.0] })
);
assert_eq!(result3, right_result);
assert_eq!(result3, expected_result);
let result4 = call_faas!(faas, "arrays_passing_pure", "f64_type", json!([[1.0]]));
assert_eq!(result4, right_result);
}
#[test]
#[ignore]
pub fn f64_type() {
let mut faas = FluenceFaaS::with_raw_config(ARG_CONFIG.clone())
.unwrap_or_else(|e| panic!("can't create Fluence FaaS instance: {}", e));
let result1 = faas.call_with_json("arrays_passing_pure", "f64_type", json!({}), <_>::default());
assert!(result1.is_err());
let result2 = faas.call_with_json("arrays_passing_pure", "f64_type", json!([]), <_>::default());
assert!(result2.is_err());
let right_result = json!([3.0]);
let result3 = call_faas!(
faas,
"arrays_passing_pure",
"f64_type",
json!({ "arg": 1.0 })
);
assert_eq!(result3, right_result);
let result4 = call_faas!(faas, "arrays_passing_pure", "f64_type", json!(1.0));
assert_eq!(result4, right_result);
assert_eq!(result4, expected_result);
}
#[test]
@ -439,7 +412,7 @@ pub fn string_type() {
);
assert!(result2.is_err());
let right_result = json!(["Fluence", "fce", "from effector", "test"]);
let expected_result = json!(["Fluence", "fce", "from effector", "test"]);
let result3 = call_faas!(
faas,
@ -447,7 +420,7 @@ pub fn string_type() {
"string_type",
json!({ "arg": ["Fluence"] })
);
assert_eq!(result3, right_result);
assert_eq!(result3, expected_result);
let result4 = call_faas!(
faas,
@ -455,7 +428,7 @@ pub fn string_type() {
"string_type",
json!([["Fluence"]])
);
assert_eq!(result4, right_result);
assert_eq!(result4, expected_result);
}
#[test]
@ -479,14 +452,14 @@ pub fn byte_type() {
);
assert!(result2.is_err());
let right_result = json!([0x13, 0x37, 0, 1, 2]);
let expected_result = json!([0x13, 0x37, 0, 1, 2]);
let result3 = call_faas!(
faas,
"arrays_passing_pure",
"byte_type",
json!({ "arg": [0x13, 0x37] })
);
assert_eq!(result3, right_result);
assert_eq!(result3, expected_result);
let result4 = call_faas!(
faas,
@ -494,7 +467,7 @@ pub fn byte_type() {
"byte_type",
json!([[0x13, 0x37]])
);
assert_eq!(result4, right_result);
assert_eq!(result4, expected_result);
}
#[test]
@ -518,7 +491,7 @@ pub fn inner_arrays_1_type() {
);
assert!(result2.is_err());
let right_result = json!([
let expected_result = json!([
[[[0x13, 0x37]]],
[[[0]]],
[],
@ -533,7 +506,7 @@ pub fn inner_arrays_1_type() {
"inner_arrays_1",
json!({ "arg": [[[[0x13, 0x37]]]] })
);
assert_eq!(result3, right_result);
assert_eq!(result3, expected_result);
let result4 = call_faas!(
faas,
@ -541,7 +514,7 @@ pub fn inner_arrays_1_type() {
"inner_arrays_1",
json!([[[[[0x13, 0x37]]]]])
);
assert_eq!(result4, right_result);
assert_eq!(result4, expected_result);
}
#[test]
@ -565,7 +538,7 @@ pub fn inner_arrays_2_type() {
);
assert!(result2.is_err());
let right_result = json!([
let expected_result = json!([
[[[{
"field_0": 0,
"field_1": [[1]]
@ -605,7 +578,7 @@ pub fn inner_arrays_2_type() {
"inner_arrays_2",
json!({ "arg": [[[[[0, [[1]]]]]]] })
);
assert_eq!(result3, right_result);
assert_eq!(result3, expected_result);
let result4 = call_faas!(
faas,
@ -613,11 +586,10 @@ pub fn inner_arrays_2_type() {
"inner_arrays_2",
json!([[[[[{"field_0": 0, "field_1": [[1]]}]]]]])
);
assert_eq!(result4, right_result);
assert_eq!(result4, expected_result);
}
#[test]
#[ignore]
pub fn bool_type() {
let mut faas = FluenceFaaS::with_raw_config(ARG_CONFIG.clone())
.unwrap_or_else(|e| panic!("can't create Fluence FaaS instance: {}", e));
@ -638,18 +610,18 @@ pub fn bool_type() {
);
assert!(result2.is_err());
let right_result = json!(1);
let expected_result = json!([true, true, false, true, false, true]);
let result3 = call_faas!(
faas,
"arrays_passing_pure",
"bool_type",
json!({ "arg": 0 })
json!({ "arg": [false] })
);
assert_eq!(result3, right_result);
assert_eq!(result3, expected_result);
let result4 = call_faas!(faas, "arrays_passing_pure", "bool_type", json!(0));
assert_eq!(result4, right_result);
let result4 = call_faas!(faas, "arrays_passing_pure", "bool_type", json!([[false]]));
assert_eq!(result4, expected_result);
}
#[test]
@ -657,15 +629,15 @@ pub fn empty_type() {
let mut faas = FluenceFaaS::with_raw_config(ARG_CONFIG.clone())
.unwrap_or_else(|e| panic!("can't create Fluence FaaS instance: {}", e));
let right_result = json!(["from effector"]);
let expected_result = json!(["from effector"]);
let result1 = call_faas!(faas, "arrays_passing_pure", "empty_type", json!({}));
assert_eq!(result1, right_result);
assert_eq!(result1, expected_result);
let result2 = call_faas!(faas, "arrays_passing_pure", "empty_type", json!([]));
assert_eq!(result2, right_result);
assert_eq!(result2, expected_result);
let result3 = call_faas!(faas, "arrays_passing_pure", "empty_type", json!([]));
assert_eq!(result3, right_result);
assert_eq!(result3, expected_result);
let result4 = faas.call_with_json(
"arrays_passing_pure",

View File

@ -41,7 +41,9 @@ pub fn call_parameters() {
let host_id = "host_id";
let particle_id = "particle_id";
let tetraplet = fluence::SecurityTetraplet::default();
let mut tetraplet = fluence::SecurityTetraplet::default();
tetraplet.function_name = "some_func_name".to_string();
tetraplet.json_path = "some_json_path".to_string();
let tetraplets = vec![vec![tetraplet]];
let call_parameters = fluence::CallParameters {

View File

@ -38,8 +38,8 @@ pub fn records() {
.call_with_ivalues("records_pure", "invoke", &[], <_>::default())
.unwrap_or_else(|e| panic!("can't invoke pure: {:?}", e));
let right_result = json!({
"field_0": 1,
let expected_result = json!({
"field_0": true,
"field_1": 1,
"field_2": 2,
"field_3": 3,
@ -58,7 +58,7 @@ pub fn records() {
result1,
vec![IValue::Record(
wasmer_wit::NEVec::new(vec![
IValue::I32(1),
IValue::Boolean(true),
IValue::S8(1),
IValue::S16(2),
IValue::S32(3),
@ -70,7 +70,7 @@ pub fn records() {
IValue::F32(9.0),
IValue::F64(10.0),
IValue::String(String::from("field_11")),
IValue::Array(vec![IValue::U8(0x13), IValue::U8(0x37)])
IValue::ByteArray(vec![0x13, 0x37])
])
.unwrap()
)]
@ -82,7 +82,7 @@ pub fn records() {
"mutate_struct",
json!({
"test_record": {
"field_0": 0,
"field_0": false,
"field_1": 0,
"field_2": 0,
"field_3": 0,
@ -102,28 +102,28 @@ pub fn records() {
)
.unwrap_or_else(|e| panic!("can't invoke pure: {:?}", e));
assert_eq!(result2, right_result);
assert_eq!(result2, expected_result);
let result3 = faas
.call_with_json(
"records_effector",
"mutate_struct",
json!({
"test_record": [0,0,0,0,0,0,0,0,0,0,0,"",[1]]
"test_record": [false,0,0,0,0,0,0,0,0,0,0,"",[1]]
}),
<_>::default(),
)
.unwrap_or_else(|e| panic!("can't invoke pure: {:?}", e));
assert_eq!(result3, right_result);
assert_eq!(result3, expected_result);
let result4 = faas
.call_with_json(
"records_effector",
"mutate_struct",
json!([{
"field_0": 0,
"field_0": false,
"field_1": 0,
"field_2": 0,
"field_3": 0,
@ -142,18 +142,18 @@ pub fn records() {
)
.unwrap_or_else(|e| panic!("can't invoke pure: {:?}", e));
assert_eq!(result4, right_result);
assert_eq!(result4, expected_result);
let result5 = faas
.call_with_json(
"records_effector",
"mutate_struct",
json!([[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "", [1]]]),
json!([[false, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "", [1]]]),
<_>::default(),
)
.unwrap_or_else(|e| panic!("can't invoke pure: {:?}", e));
assert_eq!(result5, right_result);
assert_eq!(result5, expected_result);
}
#[test]
@ -195,7 +195,7 @@ fn records_passing() {
)
.unwrap_or_else(|e| panic!("can't invoke inner_records_pure: {:?}", e));
let right_result = json!({
let expected_result = json!({
"test_record_0": {
"field_0": 1
},
@ -209,7 +209,7 @@ fn records_passing() {
}
});
assert_eq!(result, right_result);
assert_eq!(result, expected_result);
};
test("test_record");

View File

@ -14,5 +14,6 @@ name = "arguments_passing_effector"
path = "src/effector.rs"
[dependencies]
# fluence = { git = "https://github.com/fluencelabs/rust-sdk" }
fluence = { git = "https://github.com/fluencelabs/rust-sdk" }
safe-transmute = "0.11.0"

View File

@ -101,6 +101,7 @@ pub fn str_type(arg: &str) -> String {
#[fce]
pub fn bytearray_type(mut arg: Vec<u8>) -> Vec<u8> {
println!("effector: {:?}", arg);
arg.push(1);
arg
}

View File

@ -125,6 +125,7 @@ pub fn str_type(arg: &str) -> String {
#[fce]
pub fn bytearray_type(arg: Vec<u8>) -> Vec<u8> {
let mut arg = effector::bytearray_type(arg);
println!("pure: {:?}", arg);
arg.push(1);
arg
@ -140,7 +141,8 @@ pub fn bytearray_ref_type(arg: &Vec<u8>) -> Vec<u8> {
#[fce]
pub fn bool_type(arg: bool) -> bool {
effector::bool_type(arg)
let ret = effector::bool_type(arg);
ret
}
#[fce]

View File

@ -35,6 +35,7 @@ pub fn inner_arrays_1(mut arg: Vec<Vec<Vec<Vec<u8>>>>) -> Vec<Vec<Vec<Vec<u8>>>>
}
#[fce]
#[derive(Debug, Default)]
pub struct TestRecord {
pub field_0: i32,
pub field_1: Vec<Vec<u8>>,
@ -59,15 +60,13 @@ pub fn string_type(mut arg: Vec<String>) -> Vec<String> {
arg
}
/*
#[fce]
pub fn bool_type(arg: Vec<bool>) -> Vec<bool> {
let mut arg = unsafe { effector::bool_type(arg) };
pub fn bool_type(mut arg: Vec<bool>) -> Vec<bool> {
arg.push(true);
arg.push(false);
arg.push(true);
arg
}
*/
#[fce]
pub fn f32_type(mut arg: Vec<f32>) -> Vec<f32> {

View File

@ -41,7 +41,7 @@ pub fn inner_arrays_1(mut arg: Vec<Vec<Vec<Vec<u8>>>>) -> Vec<Vec<Vec<Vec<u8>>>>
}
#[fce]
#[derive(Default)]
#[derive(Default, Debug)]
pub struct TestRecord {
pub field_0: i32,
pub field_1: Vec<Vec<u8>>,
@ -80,15 +80,15 @@ pub fn string_type(mut arg: Vec<String>) -> Vec<String> {
arg
}
/*
#[fce]
pub fn bool_type(arg: Vec<bool>) -> Vec<bool> {
let mut arg = effector::bool_type(arg);
pub fn bool_type(mut arg: Vec<bool>) -> Vec<bool> {
arg[0] = !arg[0];
let mut arg = effector::bool_type(arg);
arg.push(false);
arg.push(true);
arg
}
*/
#[fce]
pub fn f32_type(mut arg: Vec<f32>) -> Vec<f32> {
@ -172,9 +172,7 @@ mod effector {
pub fn byte_type(arg: Vec<u8>) -> Vec<u8>;
/*
pub fn bool_type(arg: Vec<bool>) -> Vec<bool>;
*/
pub fn f32_type(arg: Vec<f32>) -> Vec<f32>;

View File

@ -3,21 +3,21 @@
# This script builds all tests
(
cd arguments_passing || exit;
cargo update;
cargo update --aggressive;
fce build --release;
rm artifacts/* || true;
)
(
cd arrays_passing || exit;
cargo update;
cargo update --aggressive;
fce build --release;
rm artifacts/* || true;
)
(
cd records_passing || exit;
cargo update;
cargo update --aggressive;
fce build --release;
rm artifacts/* || true;
)

View File

@ -19,6 +19,7 @@ fce-module-info-parser = { path = "../../crates/module-info-parser", version = "
semver = "0.11.0"
walrus = "0.18.0"
thiserror = "1.0.24"
anyhow = "1.0.31"
check-latest = "1.0.0"
clap = "2.33.1"

View File

@ -17,55 +17,27 @@
use fce_wit_generator::WITGeneratorError;
use fce_wit_parser::WITParserError;
use std::io::Error as StdIOError;
use std::error::Error;
use thiserror::Error as ThisError;
#[derive(Debug)]
#[derive(Debug, ThisError)]
pub enum CLIError {
/// Unknown command was entered by user.
#[error("{0} is unknown command")]
NoSuchCommand(String),
/// An error occurred while generating interface types.
WITGeneratorError(WITGeneratorError),
#[error("{0}")]
WITGeneratorError(#[from] WITGeneratorError),
/// An error occurred while parsing interface types.
WITParserError(WITParserError),
#[error("{0}")]
WITParserError(#[from] WITParserError),
/// An error occurred when no Wasm file was compiled.
#[error("{0}")]
WasmCompilationError(String),
/// Various errors related to I/O operations.
IOError(StdIOError),
}
impl Error for CLIError {}
impl std::fmt::Display for CLIError {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> {
match self {
CLIError::NoSuchCommand(cmd) => write!(f, "{} is unknown command", cmd),
CLIError::WITGeneratorError(err) => write!(f, "{}", err),
CLIError::WITParserError(err) => write!(f, "{}", err),
CLIError::WasmCompilationError(err) => write!(f, "{}", err),
CLIError::IOError(err) => write!(f, "{:?}", err),
}
}
}
impl From<WITGeneratorError> for CLIError {
fn from(err: WITGeneratorError) -> Self {
CLIError::WITGeneratorError(err)
}
}
impl From<WITParserError> for CLIError {
fn from(err: WITParserError) -> Self {
CLIError::WITParserError(err)
}
}
impl From<StdIOError> for CLIError {
fn from(err: StdIOError) -> Self {
CLIError::IOError(err)
}
#[error("{0:?}")]
IOError(#[from] std::io::Error),
}

View File

@ -48,7 +48,7 @@ pub(super) fn init_logger() {
// set a default level Info for Wasmer components
.filter(Some("cranelift_codegen"), Info)
.filter(Some("wasmer_wasi"), Info)
.filter(Some(WIT_MODULE_PATH), Info)
//.filter(Some(WIT_MODULE_PATH), Info)
// the same for rustyline and fce
.filter(Some("rustyline"), Info)
.filter(Some("fce"), Info)