mirror of
https://github.com/fluencelabs/marine.git
synced 2024-12-12 06:45:32 +00:00
Print Aqua-compatible types (#86)
This commit is contained in:
parent
c51b5982d6
commit
c62a278897
171
Cargo.lock
generated
171
Cargo.lock
generated
@ -2,6 +2,16 @@
|
|||||||
# It is not intended for manual editing.
|
# It is not intended for manual editing.
|
||||||
version = 3
|
version = 3
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "Inflector"
|
||||||
|
version = "0.11.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "fe438c63458706e03479442743baae6c88256498e6431708f6dfc520a26515d3"
|
||||||
|
dependencies = [
|
||||||
|
"lazy_static",
|
||||||
|
"regex",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "addr2line"
|
name = "addr2line"
|
||||||
version = "0.15.1"
|
version = "0.15.1"
|
||||||
@ -713,6 +723,8 @@ dependencies = [
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "fluence-app-service"
|
name = "fluence-app-service"
|
||||||
version = "0.7.2"
|
version = "0.7.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "ba3b1d2c199d6bc140c9ec5ffa323ebd34ac134fb37828bbfd7aeed0339cab78"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"fluence-faas 0.7.2",
|
"fluence-faas 0.7.2",
|
||||||
"log",
|
"log",
|
||||||
@ -726,11 +738,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "fluence-app-service"
|
name = "fluence-app-service"
|
||||||
version = "0.7.2"
|
version = "0.7.3"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "ba3b1d2c199d6bc140c9ec5ffa323ebd34ac134fb37828bbfd7aeed0339cab78"
|
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"fluence-faas 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"fluence-faas 0.7.3",
|
||||||
"log",
|
"log",
|
||||||
"maplit",
|
"maplit",
|
||||||
"serde",
|
"serde",
|
||||||
@ -740,32 +750,6 @@ dependencies = [
|
|||||||
"wasmer-wasi-fl",
|
"wasmer-wasi-fl",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "fluence-faas"
|
|
||||||
version = "0.7.2"
|
|
||||||
dependencies = [
|
|
||||||
"cmd_lib",
|
|
||||||
"env_logger 0.7.1",
|
|
||||||
"fluence",
|
|
||||||
"fluence-sdk-main",
|
|
||||||
"itertools 0.9.0",
|
|
||||||
"log",
|
|
||||||
"marine-runtime 0.5.0",
|
|
||||||
"marine-utils 0.2.0",
|
|
||||||
"once_cell",
|
|
||||||
"pretty_assertions",
|
|
||||||
"safe-transmute",
|
|
||||||
"serde",
|
|
||||||
"serde_derive",
|
|
||||||
"serde_json",
|
|
||||||
"thiserror",
|
|
||||||
"toml",
|
|
||||||
"wasmer-interface-types-fl",
|
|
||||||
"wasmer-runtime-core-fl",
|
|
||||||
"wasmer-runtime-fl",
|
|
||||||
"wasmer-wasi-fl",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "fluence-faas"
|
name = "fluence-faas"
|
||||||
version = "0.7.2"
|
version = "0.7.2"
|
||||||
@ -791,6 +775,33 @@ dependencies = [
|
|||||||
"wasmer-wasi-fl",
|
"wasmer-wasi-fl",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "fluence-faas"
|
||||||
|
version = "0.7.3"
|
||||||
|
dependencies = [
|
||||||
|
"cmd_lib",
|
||||||
|
"env_logger 0.7.1",
|
||||||
|
"fluence",
|
||||||
|
"fluence-sdk-main",
|
||||||
|
"itertools 0.9.0",
|
||||||
|
"log",
|
||||||
|
"marine-module-interface",
|
||||||
|
"marine-runtime 0.5.0",
|
||||||
|
"marine-utils 0.2.0",
|
||||||
|
"once_cell",
|
||||||
|
"pretty_assertions",
|
||||||
|
"safe-transmute",
|
||||||
|
"serde",
|
||||||
|
"serde_derive",
|
||||||
|
"serde_json",
|
||||||
|
"thiserror",
|
||||||
|
"toml",
|
||||||
|
"wasmer-interface-types-fl",
|
||||||
|
"wasmer-runtime-core-fl",
|
||||||
|
"wasmer-runtime-fl",
|
||||||
|
"wasmer-wasi-fl",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "fluence-it-types"
|
name = "fluence-it-types"
|
||||||
version = "0.3.0"
|
version = "0.3.0"
|
||||||
@ -830,11 +841,11 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "fluence-test"
|
name = "fluence-test"
|
||||||
version = "0.1.7"
|
version = "0.1.9"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "7be0d7928e5e6a74a8e303b7f539116fdb4043f5788f78e9eaf32c53700c4c18"
|
checksum = "886ac15e0e95754d5d9339b541a5119dc47cc1a8d80101dc4e3e238d06a4b28b"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"fluence-app-service 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"fluence-app-service 0.7.2",
|
||||||
"marine-test-macro",
|
"marine-test-macro",
|
||||||
"serde",
|
"serde",
|
||||||
"serde_json",
|
"serde_json",
|
||||||
@ -994,9 +1005,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "getrandom"
|
name = "getrandom"
|
||||||
version = "0.2.2"
|
version = "0.2.3"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "c9495705279e7140bf035dde1f6e750c162df8b625267cd52cc44e0b156732c8"
|
checksum = "7fcd999463524c52659517fe2cea98493cfe485d10565e7b0fb07dbba7ad2753"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cfg-if 1.0.0",
|
"cfg-if 1.0.0",
|
||||||
"libc",
|
"libc",
|
||||||
@ -1064,8 +1075,8 @@ dependencies = [
|
|||||||
"http",
|
"http",
|
||||||
"indexmap",
|
"indexmap",
|
||||||
"slab",
|
"slab",
|
||||||
"tokio 1.5.0",
|
"tokio 1.6.0",
|
||||||
"tokio-util 0.6.6",
|
"tokio-util 0.6.7",
|
||||||
"tracing",
|
"tracing",
|
||||||
]
|
]
|
||||||
|
|
||||||
@ -1200,7 +1211,7 @@ dependencies = [
|
|||||||
"itoa",
|
"itoa",
|
||||||
"pin-project",
|
"pin-project",
|
||||||
"socket2 0.4.0",
|
"socket2 0.4.0",
|
||||||
"tokio 1.5.0",
|
"tokio 1.6.0",
|
||||||
"tower-service",
|
"tower-service",
|
||||||
"tracing",
|
"tracing",
|
||||||
"want",
|
"want",
|
||||||
@ -1228,7 +1239,7 @@ dependencies = [
|
|||||||
"bytes 1.0.1",
|
"bytes 1.0.1",
|
||||||
"hyper 0.14.7",
|
"hyper 0.14.7",
|
||||||
"native-tls",
|
"native-tls",
|
||||||
"tokio 1.5.0",
|
"tokio 1.6.0",
|
||||||
"tokio-native-tls",
|
"tokio-native-tls",
|
||||||
]
|
]
|
||||||
|
|
||||||
@ -1446,14 +1457,15 @@ checksum = "3e2e65a1a2e43cfcb47a895c4c8b10d1f4a61097f9f254f183aee60cad9c651d"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "marine"
|
name = "marine"
|
||||||
version = "0.6.1"
|
version = "0.6.3"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
"Inflector",
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"check-latest",
|
"check-latest",
|
||||||
"clap",
|
"clap",
|
||||||
"exitfailure",
|
"exitfailure",
|
||||||
"marine-it-generator 0.5.1",
|
"marine-it-generator 0.5.2",
|
||||||
"marine-it-parser 0.6.0",
|
"marine-it-parser 0.6.1",
|
||||||
"marine-module-info-parser 0.1.0",
|
"marine-module-info-parser 0.1.0",
|
||||||
"semver 0.11.0",
|
"semver 0.11.0",
|
||||||
"serde",
|
"serde",
|
||||||
@ -1483,11 +1495,11 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "marine-it-generator"
|
name = "marine-it-generator"
|
||||||
version = "0.5.1"
|
version = "0.5.2"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cargo_toml",
|
"cargo_toml",
|
||||||
"it-lilo",
|
"it-lilo",
|
||||||
"marine-it-parser 0.6.0",
|
"marine-it-parser 0.6.1",
|
||||||
"marine-macro-impl",
|
"marine-macro-impl",
|
||||||
"once_cell",
|
"once_cell",
|
||||||
"serde",
|
"serde",
|
||||||
@ -1534,10 +1546,12 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "marine-it-parser"
|
name = "marine-it-parser"
|
||||||
version = "0.6.0"
|
version = "0.6.1"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
|
"itertools 0.10.0",
|
||||||
"marine-it-interfaces 0.4.0",
|
"marine-it-interfaces 0.4.0",
|
||||||
|
"marine-module-interface",
|
||||||
"nom",
|
"nom",
|
||||||
"semver 0.11.0",
|
"semver 0.11.0",
|
||||||
"serde",
|
"serde",
|
||||||
@ -1600,6 +1614,22 @@ dependencies = [
|
|||||||
"wasmer-runtime-core-fl",
|
"wasmer-runtime-core-fl",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "marine-module-interface"
|
||||||
|
version = "0.1.0"
|
||||||
|
dependencies = [
|
||||||
|
"anyhow",
|
||||||
|
"itertools 0.10.0",
|
||||||
|
"marine-it-interfaces 0.4.0",
|
||||||
|
"nom",
|
||||||
|
"semver 0.11.0",
|
||||||
|
"serde",
|
||||||
|
"thiserror",
|
||||||
|
"walrus",
|
||||||
|
"wasmer-interface-types-fl",
|
||||||
|
"wasmer-runtime-core-fl",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "marine-runtime"
|
name = "marine-runtime"
|
||||||
version = "0.5.0"
|
version = "0.5.0"
|
||||||
@ -1609,10 +1639,11 @@ dependencies = [
|
|||||||
"bytes 0.5.6",
|
"bytes 0.5.6",
|
||||||
"it-lilo",
|
"it-lilo",
|
||||||
"log",
|
"log",
|
||||||
"marine-it-generator 0.5.1",
|
"marine-it-generator 0.5.2",
|
||||||
"marine-it-interfaces 0.4.0",
|
"marine-it-interfaces 0.4.0",
|
||||||
"marine-it-parser 0.6.0",
|
"marine-it-parser 0.6.1",
|
||||||
"marine-module-info-parser 0.1.0",
|
"marine-module-info-parser 0.1.0",
|
||||||
|
"marine-module-interface",
|
||||||
"marine-utils 0.2.0",
|
"marine-utils 0.2.0",
|
||||||
"multimap",
|
"multimap",
|
||||||
"once_cell",
|
"once_cell",
|
||||||
@ -1670,9 +1701,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "marine-test-macro"
|
name = "marine-test-macro"
|
||||||
version = "0.1.6"
|
version = "0.1.9"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "709eebc4ee6c8e6aa49066ab066c9f137d9cf164f298f578a67bfb11a0508f65"
|
checksum = "089a1d98ebee2fa24928e23019b477222562beda663f8625d3d490dce290e532"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"marine-test-macro-impl",
|
"marine-test-macro-impl",
|
||||||
"proc-macro-error",
|
"proc-macro-error",
|
||||||
@ -1683,12 +1714,12 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "marine-test-macro-impl"
|
name = "marine-test-macro-impl"
|
||||||
version = "0.1.5"
|
version = "0.1.9"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "e2432fd5233a088981c79324668b76f3ee2ae6d313d4522b5490226e5e7827ce"
|
checksum = "b6e79cfbde74677cbeb60fe5944c345617739aae37dc5ac5ef5f12d487472071"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"darling 0.12.4",
|
"darling 0.12.4",
|
||||||
"fluence-app-service 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"fluence-app-service 0.7.2",
|
||||||
"marine-it-parser 0.5.0",
|
"marine-it-parser 0.5.0",
|
||||||
"proc-macro-error",
|
"proc-macro-error",
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
@ -1829,13 +1860,13 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "mrepl"
|
name = "mrepl"
|
||||||
version = "0.7.2"
|
version = "0.7.3"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"check-latest",
|
"check-latest",
|
||||||
"clap",
|
"clap",
|
||||||
"env_logger 0.7.1",
|
"env_logger 0.7.1",
|
||||||
"fluence-app-service 0.7.2",
|
"fluence-app-service 0.7.3",
|
||||||
"fluence-sdk-main",
|
"fluence-sdk-main",
|
||||||
"itertools 0.9.0",
|
"itertools 0.9.0",
|
||||||
"log",
|
"log",
|
||||||
@ -2181,9 +2212,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "proc-macro2"
|
name = "proc-macro2"
|
||||||
version = "1.0.26"
|
version = "1.0.27"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "a152013215dca273577e18d2bf00fa862b89b24169fb78c4c95aeb07992c9cec"
|
checksum = "f0d8caf72986c1a598726adc988bb5984792ef84f5ee5aa50209145ee8077038"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"unicode-xid",
|
"unicode-xid",
|
||||||
]
|
]
|
||||||
@ -2242,7 +2273,7 @@ version = "0.6.2"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "34cf66eb183df1c5876e2dcf6b13d57340741e8dc255b48e40a26de954d06ae7"
|
checksum = "34cf66eb183df1c5876e2dcf6b13d57340741e8dc255b48e40a26de954d06ae7"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"getrandom 0.2.2",
|
"getrandom 0.2.3",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -2267,9 +2298,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rayon"
|
name = "rayon"
|
||||||
version = "1.5.0"
|
version = "1.5.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "8b0d8e0819fadc20c74ea8373106ead0600e3a67ef1fe8da56e39b9ae7275674"
|
checksum = "c06aca804d41dbc8ba42dfd964f0d01334eceb64314b9ecf7c5fad5188a06d90"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"autocfg",
|
"autocfg",
|
||||||
"crossbeam-deque",
|
"crossbeam-deque",
|
||||||
@ -2279,9 +2310,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rayon-core"
|
name = "rayon-core"
|
||||||
version = "1.9.0"
|
version = "1.9.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "9ab346ac5921dc62ffa9f89b7a773907511cdfa5490c572ae9be1be33e8afa4a"
|
checksum = "d78120e2c850279833f1dd3582f730c4ab53ed95aeaaaa862a2a5c71b1656d8e"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"crossbeam-channel",
|
"crossbeam-channel",
|
||||||
"crossbeam-deque",
|
"crossbeam-deque",
|
||||||
@ -2355,7 +2386,7 @@ version = "0.4.0"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "528532f3d801c87aec9def2add9ca802fe569e44a544afe633765267840abe64"
|
checksum = "528532f3d801c87aec9def2add9ca802fe569e44a544afe633765267840abe64"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"getrandom 0.2.2",
|
"getrandom 0.2.3",
|
||||||
"redox_syscall 0.2.8",
|
"redox_syscall 0.2.8",
|
||||||
]
|
]
|
||||||
|
|
||||||
@ -2446,7 +2477,7 @@ dependencies = [
|
|||||||
"serde",
|
"serde",
|
||||||
"serde_json",
|
"serde_json",
|
||||||
"serde_urlencoded",
|
"serde_urlencoded",
|
||||||
"tokio 1.5.0",
|
"tokio 1.6.0",
|
||||||
"tokio-native-tls",
|
"tokio-native-tls",
|
||||||
"url",
|
"url",
|
||||||
"wasm-bindgen",
|
"wasm-bindgen",
|
||||||
@ -2934,9 +2965,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tokio"
|
name = "tokio"
|
||||||
version = "1.5.0"
|
version = "1.6.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "83f0c8e7c0addab50b663055baf787d0af7f413a46e6e7fb9559a4e4db7137a5"
|
checksum = "bd3076b5c8cc18138b8f8814895c11eb4de37114a5d127bafdc5e55798ceef37"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"autocfg",
|
"autocfg",
|
||||||
"bytes 1.0.1",
|
"bytes 1.0.1",
|
||||||
@ -2965,7 +2996,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||||||
checksum = "f7d995660bd2b7f8c1568414c1126076c13fbb725c40112dc0120b78eb9b717b"
|
checksum = "f7d995660bd2b7f8c1568414c1126076c13fbb725c40112dc0120b78eb9b717b"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"native-tls",
|
"native-tls",
|
||||||
"tokio 1.5.0",
|
"tokio 1.6.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -2994,16 +3025,16 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tokio-util"
|
name = "tokio-util"
|
||||||
version = "0.6.6"
|
version = "0.6.7"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "940a12c99365c31ea8dd9ba04ec1be183ffe4920102bb7122c2f515437601e8e"
|
checksum = "1caa0b0c8d94a049db56b5acf8cba99dc0623aab1b26d5b5f5e2d945846b3592"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bytes 1.0.1",
|
"bytes 1.0.1",
|
||||||
"futures-core",
|
"futures-core",
|
||||||
"futures-sink",
|
"futures-sink",
|
||||||
"log",
|
"log",
|
||||||
"pin-project-lite 0.2.6",
|
"pin-project-lite 0.2.6",
|
||||||
"tokio 1.5.0",
|
"tokio 1.6.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -3183,7 +3214,7 @@ version = "0.8.2"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "bc5cf98d8186244414c848017f0e2676b3fcb46807f6668a97dfe67359a3c4b7"
|
checksum = "bc5cf98d8186244414c848017f0e2676b3fcb46807f6668a97dfe67359a3c4b7"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"getrandom 0.2.2",
|
"getrandom 0.2.3",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -4,6 +4,7 @@ members = [
|
|||||||
"crates/it-interfaces",
|
"crates/it-interfaces",
|
||||||
"crates/it-parser",
|
"crates/it-parser",
|
||||||
"crates/module-info-parser",
|
"crates/module-info-parser",
|
||||||
|
"crates/module-interface",
|
||||||
"crates/utils",
|
"crates/utils",
|
||||||
"examples/call_parameters",
|
"examples/call_parameters",
|
||||||
"examples/greeting",
|
"examples/greeting",
|
||||||
|
@ -148,7 +148,7 @@ fn generate_it_instructions<'f>(
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn generate_raw_args<'f>(signature: &FnSignature) -> Rc<Vec<IFunctionArg>> {
|
pub(crate) fn generate_raw_args(signature: &FnSignature) -> Rc<Vec<IFunctionArg>> {
|
||||||
let raw_inputs = signature
|
let raw_inputs = signature
|
||||||
.arguments
|
.arguments
|
||||||
.iter()
|
.iter()
|
||||||
@ -159,7 +159,7 @@ pub(crate) fn generate_raw_args<'f>(signature: &FnSignature) -> Rc<Vec<IFunction
|
|||||||
Rc::new(raw_inputs)
|
Rc::new(raw_inputs)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn generate_raw_output_type<'f>(signature: &FnSignature) -> Rc<Vec<IType>> {
|
pub(crate) fn generate_raw_output_type(signature: &FnSignature) -> Rc<Vec<IType>> {
|
||||||
let raw_outputs = signature
|
let raw_outputs = signature
|
||||||
.output_types
|
.output_types
|
||||||
.iter()
|
.iter()
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "marine-it-parser"
|
name = "marine-it-parser"
|
||||||
description = "Fluence Marine interface types parser"
|
description = "Fluence Marine interface types parser"
|
||||||
version = "0.6.0"
|
version = "0.6.1"
|
||||||
authors = ["Fluence Labs"]
|
authors = ["Fluence Labs"]
|
||||||
license = "Apache-2.0"
|
license = "Apache-2.0"
|
||||||
edition = "2018"
|
edition = "2018"
|
||||||
@ -12,6 +12,7 @@ path = "src/lib.rs"
|
|||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
marine-it-interfaces = { path = "../it-interfaces", version = "0.4.0" }
|
marine-it-interfaces = { path = "../it-interfaces", version = "0.4.0" }
|
||||||
|
marine-module-interface = { path = "../module-interface", version = "0.1.0" }
|
||||||
|
|
||||||
anyhow = "1.0.31"
|
anyhow = "1.0.31"
|
||||||
walrus = "0.18.0"
|
walrus = "0.18.0"
|
||||||
@ -19,6 +20,7 @@ wasmer-core = { package = "wasmer-runtime-core-fl", version = "0.17.0"}
|
|||||||
wasmer-it = { package = "wasmer-interface-types-fl", version = "0.20.0" }
|
wasmer-it = { package = "wasmer-interface-types-fl", version = "0.20.0" }
|
||||||
nom = "5.1"
|
nom = "5.1"
|
||||||
|
|
||||||
|
itertools = "0.10.0"
|
||||||
semver = "0.11.0"
|
semver = "0.11.0"
|
||||||
serde = "=1.0.118"
|
serde = "=1.0.118"
|
||||||
thiserror = "1.0.24"
|
thiserror = "1.0.24"
|
||||||
|
@ -16,7 +16,7 @@
|
|||||||
|
|
||||||
use super::custom::ITCustomSection;
|
use super::custom::ITCustomSection;
|
||||||
use super::errors::ITParserError;
|
use super::errors::ITParserError;
|
||||||
use crate::Result;
|
use crate::ParserResult;
|
||||||
|
|
||||||
use walrus::ModuleConfig;
|
use walrus::ModuleConfig;
|
||||||
use wasmer_it::{
|
use wasmer_it::{
|
||||||
@ -28,7 +28,7 @@ use wasmer_it::ToBytes;
|
|||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
|
|
||||||
/// Embed provided IT to a Wasm file by path.
|
/// Embed provided IT to a Wasm file by path.
|
||||||
pub fn embed_text_it<I, O>(in_wasm_path: I, out_wasm_path: O, it: &str) -> Result<()>
|
pub fn embed_text_it<I, O>(in_wasm_path: I, out_wasm_path: O, it: &str) -> ParserResult<()>
|
||||||
where
|
where
|
||||||
I: AsRef<Path>,
|
I: AsRef<Path>,
|
||||||
O: AsRef<Path>,
|
O: AsRef<Path>,
|
||||||
|
@ -14,6 +14,9 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
use marine_module_interface::interface::InterfaceError;
|
||||||
|
use marine_module_interface::it_interface::ITInterfaceError;
|
||||||
|
|
||||||
use wasmer_it::decoders::wat::Error as WATError;
|
use wasmer_it::decoders::wat::Error as WATError;
|
||||||
use thiserror::Error as ThisError;
|
use thiserror::Error as ThisError;
|
||||||
|
|
||||||
@ -45,6 +48,14 @@ pub enum ITParserError {
|
|||||||
#[error("{0}")]
|
#[error("{0}")]
|
||||||
IncorrectITFormat(String),
|
IncorrectITFormat(String),
|
||||||
|
|
||||||
|
/// An error occurred while processing module interface.
|
||||||
|
#[error("{0}")]
|
||||||
|
ModuleInterfaceError(#[from] InterfaceError),
|
||||||
|
|
||||||
|
/// An error occurred while processing module IT interface.
|
||||||
|
#[error("{0}")]
|
||||||
|
ModuleITInterfaceError(#[from] ITInterfaceError),
|
||||||
|
|
||||||
/// An error occurred while parsing file in Wat format.
|
/// An error occurred while parsing file in Wat format.
|
||||||
#[error("provided file with IT definitions is corrupted: {0}")]
|
#[error("provided file with IT definitions is corrupted: {0}")]
|
||||||
CorruptedITFile(#[from] WATError),
|
CorruptedITFile(#[from] WATError),
|
||||||
|
@ -14,38 +14,41 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
mod functions;
|
|
||||||
mod it;
|
mod it;
|
||||||
|
|
||||||
pub use functions::*;
|
|
||||||
pub use it::*;
|
pub use it::*;
|
||||||
|
|
||||||
use crate::Result;
|
use crate::interface::ModuleInterface;
|
||||||
|
use crate::it_interface::IModuleInterface;
|
||||||
|
use crate::ParserResult;
|
||||||
use crate::ITParserError;
|
use crate::ITParserError;
|
||||||
|
|
||||||
|
use marine_module_interface::it_interface;
|
||||||
|
use marine_module_interface::interface;
|
||||||
use marine_it_interfaces::MITInterfaces;
|
use marine_it_interfaces::MITInterfaces;
|
||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
|
|
||||||
pub fn module_interface<P>(module_path: P) -> Result<ServiceInterface>
|
pub fn module_interface<P>(module_path: P) -> ParserResult<ModuleInterface>
|
||||||
where
|
where
|
||||||
P: AsRef<Path>,
|
P: AsRef<Path>,
|
||||||
{
|
{
|
||||||
create_mit_with(module_path, |it| get_interface(&it))
|
create_mit_with(module_path, |it| interface::get_interface(&it))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn module_raw_interface<P>(module_path: P) -> Result<MModuleInterface>
|
pub fn module_it_interface<P>(module_path: P) -> ParserResult<IModuleInterface>
|
||||||
where
|
where
|
||||||
P: AsRef<Path>,
|
P: AsRef<Path>,
|
||||||
{
|
{
|
||||||
create_mit_with(module_path, |it| get_raw_interface(&it))
|
create_mit_with(module_path, |it| it_interface::get_interface(&it))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn create_mit_with<P, T>(
|
fn create_mit_with<P, T, E>(
|
||||||
module_path: P,
|
module_path: P,
|
||||||
transformer: impl FnOnce(MITInterfaces<'_>) -> Result<T>,
|
transformer: impl FnOnce(MITInterfaces<'_>) -> std::result::Result<T, E>,
|
||||||
) -> Result<T>
|
) -> ParserResult<T>
|
||||||
where
|
where
|
||||||
P: AsRef<Path>,
|
P: AsRef<Path>,
|
||||||
|
ITParserError: From<E>,
|
||||||
{
|
{
|
||||||
let module = walrus::ModuleConfig::new()
|
let module = walrus::ModuleConfig::new()
|
||||||
.parse_file(module_path)
|
.parse_file(module_path)
|
||||||
@ -56,5 +59,5 @@ where
|
|||||||
|
|
||||||
let mit = MITInterfaces::new(it);
|
let mit = MITInterfaces::new(it);
|
||||||
|
|
||||||
transformer(mit)
|
transformer(mit).map_err(Into::into)
|
||||||
}
|
}
|
||||||
|
@ -1,213 +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.
|
|
||||||
*/
|
|
||||||
|
|
||||||
use crate::Result;
|
|
||||||
use crate::ITParserError;
|
|
||||||
use marine_it_interfaces::MITInterfaces;
|
|
||||||
|
|
||||||
use wasmer_it::IRecordType;
|
|
||||||
use wasmer_it::ast::FunctionArg as IFunctionArg;
|
|
||||||
use wasmer_it::IType;
|
|
||||||
use serde::Serialize;
|
|
||||||
use serde::Deserialize;
|
|
||||||
|
|
||||||
use std::collections::HashMap;
|
|
||||||
use std::rc::Rc;
|
|
||||||
|
|
||||||
pub type MRecordTypes = HashMap<u64, Rc<IRecordType>>;
|
|
||||||
|
|
||||||
#[derive(PartialEq, Eq, Debug, Clone, Hash, Serialize, Deserialize)]
|
|
||||||
pub struct MFunctionSignature {
|
|
||||||
pub name: Rc<String>,
|
|
||||||
pub arguments: Rc<Vec<IFunctionArg>>,
|
|
||||||
pub outputs: Rc<Vec<IType>>,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(PartialEq, Eq, Debug, Clone, Serialize)]
|
|
||||||
pub struct MModuleInterface {
|
|
||||||
pub record_types: MRecordTypes,
|
|
||||||
pub function_signatures: Vec<MFunctionSignature>,
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn get_interface(mit: &MITInterfaces<'_>) -> Result<ServiceInterface> {
|
|
||||||
let marine_interface = get_raw_interface(mit)?;
|
|
||||||
let service_interface = into_service_interface(marine_interface);
|
|
||||||
|
|
||||||
Ok(service_interface)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn get_raw_interface(mit: &MITInterfaces<'_>) -> Result<MModuleInterface> {
|
|
||||||
let function_signatures = get_exports(mit)?;
|
|
||||||
let record_types = extract_record_types(mit);
|
|
||||||
|
|
||||||
let mm_interface = MModuleInterface {
|
|
||||||
record_types,
|
|
||||||
function_signatures,
|
|
||||||
};
|
|
||||||
|
|
||||||
Ok(mm_interface)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn get_exports(it: &MITInterfaces<'_>) -> Result<Vec<MFunctionSignature>> {
|
|
||||||
use marine_it_interfaces::ITAstType;
|
|
||||||
|
|
||||||
it.implementations()
|
|
||||||
.filter_map(|(adapter_function_type, core_function_type)| {
|
|
||||||
it.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
|
|
||||||
.iter()
|
|
||||||
.map(move |export_function_name| (*adapter_function_type, export_function_name))
|
|
||||||
})
|
|
||||||
.flatten()
|
|
||||||
.map(|(adapter_function_type, export_function_name)| {
|
|
||||||
let it_type = it.type_by_idx_r(adapter_function_type).unwrap();
|
|
||||||
|
|
||||||
match it_type {
|
|
||||||
ITAstType::Function {
|
|
||||||
arguments,
|
|
||||||
output_types,
|
|
||||||
} => {
|
|
||||||
let signature = MFunctionSignature {
|
|
||||||
name: Rc::new(export_function_name.to_string()),
|
|
||||||
arguments: arguments.clone(),
|
|
||||||
outputs: output_types.clone(),
|
|
||||||
};
|
|
||||||
Ok(signature)
|
|
||||||
}
|
|
||||||
_ => Err(ITParserError::IncorrectITFormat(format!(
|
|
||||||
"type with idx = {} isn't a function type",
|
|
||||||
adapter_function_type
|
|
||||||
))),
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.collect::<Result<Vec<MFunctionSignature>>>()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn extract_record_types(it: &MITInterfaces<'_>) -> MRecordTypes {
|
|
||||||
use marine_it_interfaces::ITAstType;
|
|
||||||
|
|
||||||
let (record_types_by_id, _) = it.types().fold(
|
|
||||||
(HashMap::new(), 0u64),
|
|
||||||
|(mut record_types_by_id, id), ty| {
|
|
||||||
match ty {
|
|
||||||
ITAstType::Record(record_type) => {
|
|
||||||
record_types_by_id.insert(id, record_type.clone());
|
|
||||||
}
|
|
||||||
ITAstType::Function { .. } => {}
|
|
||||||
};
|
|
||||||
(record_types_by_id, id + 1)
|
|
||||||
},
|
|
||||||
);
|
|
||||||
|
|
||||||
record_types_by_id
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Serialize)]
|
|
||||||
pub struct FunctionSignature {
|
|
||||||
pub name: String,
|
|
||||||
pub arguments: Vec<(String, String)>,
|
|
||||||
pub output_types: Vec<String>,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Serialize)]
|
|
||||||
pub struct RecordType {
|
|
||||||
pub name: String,
|
|
||||||
pub id: u64,
|
|
||||||
pub fields: Vec<(String, String)>,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Serialize)]
|
|
||||||
pub struct ServiceInterface {
|
|
||||||
pub function_signatures: Vec<FunctionSignature>,
|
|
||||||
pub record_types: Vec<RecordType>,
|
|
||||||
}
|
|
||||||
|
|
||||||
pub(crate) fn into_service_interface(mm_interface: MModuleInterface) -> ServiceInterface {
|
|
||||||
let record_types = mm_interface.record_types;
|
|
||||||
|
|
||||||
let function_signatures = mm_interface
|
|
||||||
.function_signatures
|
|
||||||
.into_iter()
|
|
||||||
.map(|sign| serialize_function_signature(sign, &record_types))
|
|
||||||
.collect();
|
|
||||||
|
|
||||||
let record_types = record_types
|
|
||||||
.iter()
|
|
||||||
.map(|(id, record)| serialize_record_type(*id, record.clone(), &record_types))
|
|
||||||
.collect::<Vec<_>>();
|
|
||||||
|
|
||||||
ServiceInterface {
|
|
||||||
function_signatures,
|
|
||||||
record_types,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn serialize_function_signature(
|
|
||||||
signature: MFunctionSignature,
|
|
||||||
record_types: &MRecordTypes,
|
|
||||||
) -> FunctionSignature {
|
|
||||||
let arguments = signature
|
|
||||||
.arguments
|
|
||||||
.iter()
|
|
||||||
.map(|arg| (arg.name.clone(), itype_text_view(&arg.ty, record_types)))
|
|
||||||
.collect();
|
|
||||||
|
|
||||||
let output_types = signature
|
|
||||||
.outputs
|
|
||||||
.iter()
|
|
||||||
.map(|itype| itype_text_view(itype, record_types))
|
|
||||||
.collect();
|
|
||||||
|
|
||||||
FunctionSignature {
|
|
||||||
name: signature.name.to_string(),
|
|
||||||
arguments,
|
|
||||||
output_types,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn serialize_record_type(
|
|
||||||
id: u64,
|
|
||||||
record: Rc<IRecordType>,
|
|
||||||
record_types: &MRecordTypes,
|
|
||||||
) -> RecordType {
|
|
||||||
let fields = record
|
|
||||||
.fields
|
|
||||||
.iter()
|
|
||||||
.map(|field| (field.name.clone(), itype_text_view(&field.ty, record_types)))
|
|
||||||
.collect::<Vec<_>>();
|
|
||||||
|
|
||||||
RecordType {
|
|
||||||
name: record.name.clone(),
|
|
||||||
id,
|
|
||||||
fields,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn itype_text_view(arg_ty: &IType, record_types: &MRecordTypes) -> String {
|
|
||||||
match arg_ty {
|
|
||||||
IType::Record(record_type_id) => {
|
|
||||||
// unwrap is safe because FaaSInterface here is well-formed
|
|
||||||
// (it was checked on the module startup stage)
|
|
||||||
let record = record_types.get(record_type_id).unwrap();
|
|
||||||
record.name.clone()
|
|
||||||
}
|
|
||||||
IType::Array(array_ty) => format!("Array<{}>", itype_text_view(array_ty, record_types)),
|
|
||||||
t => format!("{:?}", t),
|
|
||||||
}
|
|
||||||
}
|
|
@ -16,7 +16,7 @@
|
|||||||
|
|
||||||
use crate::custom::IT_SECTION_NAME;
|
use crate::custom::IT_SECTION_NAME;
|
||||||
use crate::errors::ITParserError;
|
use crate::errors::ITParserError;
|
||||||
use crate::Result;
|
use crate::ParserResult;
|
||||||
|
|
||||||
use walrus::IdsToIndices;
|
use walrus::IdsToIndices;
|
||||||
use wasmer_it::ast::Interfaces;
|
use wasmer_it::ast::Interfaces;
|
||||||
@ -26,7 +26,7 @@ use std::borrow::Cow;
|
|||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
|
|
||||||
/// Extracts IT section of provided Wasm binary and converts it to a string.
|
/// Extracts IT section of provided Wasm binary and converts it to a string.
|
||||||
pub fn extract_text_it<P>(wasm_file_path: P) -> Result<String>
|
pub fn extract_text_it<P>(wasm_file_path: P) -> ParserResult<String>
|
||||||
where
|
where
|
||||||
P: AsRef<Path>,
|
P: AsRef<Path>,
|
||||||
{
|
{
|
||||||
@ -42,7 +42,7 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Extracts IT section of provided Wasm binary and converts it to a MITInterfaces.
|
/// Extracts IT section of provided Wasm binary and converts it to a MITInterfaces.
|
||||||
pub fn extract_it_from_module(wasmer_module: &WasmerModule) -> Result<Interfaces<'_>> {
|
pub fn extract_it_from_module(wasmer_module: &WasmerModule) -> ParserResult<Interfaces<'_>> {
|
||||||
let wit_sections = wasmer_module
|
let wit_sections = wasmer_module
|
||||||
.custom_sections(IT_SECTION_NAME)
|
.custom_sections(IT_SECTION_NAME)
|
||||||
.ok_or(ITParserError::NoITSection)?;
|
.ok_or(ITParserError::NoITSection)?;
|
||||||
@ -54,7 +54,7 @@ pub fn extract_it_from_module(wasmer_module: &WasmerModule) -> Result<Interfaces
|
|||||||
extract_it_from_bytes(&wit_sections[0])
|
extract_it_from_bytes(&wit_sections[0])
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn extract_version_from_module(module: &walrus::Module) -> Result<semver::Version> {
|
pub fn extract_version_from_module(module: &walrus::Module) -> ParserResult<semver::Version> {
|
||||||
let raw_custom_section = extract_custom_section(&module)?;
|
let raw_custom_section = extract_custom_section(&module)?;
|
||||||
let wit_section_bytes = raw_custom_section.as_ref();
|
let wit_section_bytes = raw_custom_section.as_ref();
|
||||||
let it = extract_it_from_bytes(wit_section_bytes)?;
|
let it = extract_it_from_bytes(wit_section_bytes)?;
|
||||||
@ -62,7 +62,7 @@ pub fn extract_version_from_module(module: &walrus::Module) -> Result<semver::Ve
|
|||||||
Ok(it.version)
|
Ok(it.version)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn extract_it_from_bytes(wit_section_bytes: &[u8]) -> Result<Interfaces<'_>> {
|
pub(crate) fn extract_it_from_bytes(wit_section_bytes: &[u8]) -> ParserResult<Interfaces<'_>> {
|
||||||
match wasmer_it::decoders::binary::parse::<(&[u8], nom::error::ErrorKind)>(wit_section_bytes) {
|
match wasmer_it::decoders::binary::parse::<(&[u8], nom::error::ErrorKind)>(wit_section_bytes) {
|
||||||
Ok((remainder, it)) if remainder.is_empty() => Ok(it),
|
Ok((remainder, it)) if remainder.is_empty() => Ok(it),
|
||||||
Ok(_) => Err(ITParserError::ITRemainderNotEmpty),
|
Ok(_) => Err(ITParserError::ITRemainderNotEmpty),
|
||||||
@ -70,7 +70,7 @@ pub(crate) fn extract_it_from_bytes(wit_section_bytes: &[u8]) -> Result<Interfac
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn extract_custom_section(module: &walrus::Module) -> Result<Cow<'_, [u8]>> {
|
pub(crate) fn extract_custom_section(module: &walrus::Module) -> ParserResult<Cow<'_, [u8]>> {
|
||||||
let sections = module
|
let sections = module
|
||||||
.customs
|
.customs
|
||||||
.iter()
|
.iter()
|
||||||
|
@ -42,16 +42,20 @@ pub use extractor::extract_it_from_module;
|
|||||||
pub use extractor::extract_version_from_module;
|
pub use extractor::extract_version_from_module;
|
||||||
pub use extractor::extract_text_it;
|
pub use extractor::extract_text_it;
|
||||||
pub use extractor::module_interface;
|
pub use extractor::module_interface;
|
||||||
pub use extractor::module_raw_interface;
|
pub use extractor::module_it_interface;
|
||||||
|
|
||||||
pub mod interface {
|
pub mod interface {
|
||||||
pub use crate::extractor::ServiceInterface;
|
pub use marine_module_interface::interface::ModuleInterface;
|
||||||
pub use crate::extractor::RecordType;
|
pub use marine_module_interface::interface::RecordType;
|
||||||
pub use crate::extractor::FunctionSignature;
|
pub use marine_module_interface::interface::RecordField;
|
||||||
|
pub use marine_module_interface::interface::FunctionSignature;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub mod it_interface {
|
||||||
|
pub use marine_module_interface::it_interface::IModuleInterface;
|
||||||
|
pub use marine_module_interface::it_interface::IRecordTypes;
|
||||||
|
pub use marine_module_interface::it_interface::IFunctionSignature;
|
||||||
|
|
||||||
pub use crate::extractor::MModuleInterface;
|
|
||||||
pub use crate::extractor::MRecordTypes;
|
|
||||||
pub use crate::extractor::MFunctionSignature;
|
|
||||||
pub mod it {
|
pub mod it {
|
||||||
pub use wasmer_it::IType;
|
pub use wasmer_it::IType;
|
||||||
pub use wasmer_it::ast::FunctionArg as IFunctionArg;
|
pub use wasmer_it::ast::FunctionArg as IFunctionArg;
|
||||||
@ -60,4 +64,4 @@ pub mod interface {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) type Result<T> = std::result::Result<T, ITParserError>;
|
pub(crate) type ParserResult<T> = std::result::Result<T, ITParserError>;
|
||||||
|
26
crates/module-interface/Cargo.toml
Normal file
26
crates/module-interface/Cargo.toml
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
[package]
|
||||||
|
name = "marine-module-interface"
|
||||||
|
description = "Fluence Marine module interface"
|
||||||
|
version = "0.1.0"
|
||||||
|
authors = ["Fluence Labs"]
|
||||||
|
license = "Apache-2.0"
|
||||||
|
edition = "2018"
|
||||||
|
|
||||||
|
[lib]
|
||||||
|
name = "marine_module_interface"
|
||||||
|
path = "src/lib.rs"
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
marine-it-interfaces = { path = "../it-interfaces", version = "0.4.0" }
|
||||||
|
#marine-it-generator = { path = "../it-generator", verision = "0.5.2"}
|
||||||
|
|
||||||
|
anyhow = "1.0.31"
|
||||||
|
walrus = "0.18.0"
|
||||||
|
wasmer-core = { package = "wasmer-runtime-core-fl", version = "0.17.0"}
|
||||||
|
wasmer-it = { package = "wasmer-interface-types-fl", version = "0.20.0" }
|
||||||
|
nom = "5.1"
|
||||||
|
|
||||||
|
itertools = "0.10.0"
|
||||||
|
semver = "0.11.0"
|
||||||
|
serde = "=1.0.118"
|
||||||
|
thiserror = "1.0.24"
|
27
crates/module-interface/src/interface/errors.rs
Normal file
27
crates/module-interface/src/interface/errors.rs
Normal 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
use crate::it_interface::ITInterfaceError;
|
||||||
|
use thiserror::Error as ThisError;
|
||||||
|
|
||||||
|
#[derive(Debug, ThisError)]
|
||||||
|
pub enum InterfaceError {
|
||||||
|
#[error("record type with type id {0} not found")]
|
||||||
|
NotFoundRecordTypeId(u64),
|
||||||
|
|
||||||
|
#[error("{0}")]
|
||||||
|
ITInterfaceError(#[from] ITInterfaceError),
|
||||||
|
}
|
@ -0,0 +1,67 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2021 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::ModuleInterface;
|
||||||
|
use super::InterfaceResult;
|
||||||
|
use super::FunctionSignature;
|
||||||
|
use super::records_transformer::RecordsTransformer;
|
||||||
|
use crate::it_interface::IModuleInterface;
|
||||||
|
use crate::it_interface::IFunctionSignature;
|
||||||
|
use crate::it_interface::IRecordTypes;
|
||||||
|
|
||||||
|
pub fn it_to_module_interface(mm_interface: IModuleInterface) -> InterfaceResult<ModuleInterface> {
|
||||||
|
let record_types = mm_interface.export_record_types;
|
||||||
|
|
||||||
|
let function_signatures = mm_interface
|
||||||
|
.function_signatures
|
||||||
|
.into_iter()
|
||||||
|
.map(|sign| serialize_function_signature(sign, &record_types))
|
||||||
|
.collect();
|
||||||
|
|
||||||
|
let record_types = RecordsTransformer::transform(&record_types)?;
|
||||||
|
|
||||||
|
let interface = ModuleInterface {
|
||||||
|
function_signatures,
|
||||||
|
record_types,
|
||||||
|
};
|
||||||
|
|
||||||
|
Ok(interface)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn serialize_function_signature(
|
||||||
|
signature: IFunctionSignature,
|
||||||
|
record_types: &IRecordTypes,
|
||||||
|
) -> FunctionSignature {
|
||||||
|
use super::itype_text_view;
|
||||||
|
|
||||||
|
let arguments = signature
|
||||||
|
.arguments
|
||||||
|
.iter()
|
||||||
|
.map(|arg| (arg.name.clone(), itype_text_view(&arg.ty, record_types)))
|
||||||
|
.collect();
|
||||||
|
|
||||||
|
let output_types = signature
|
||||||
|
.outputs
|
||||||
|
.iter()
|
||||||
|
.map(|itype| itype_text_view(itype, record_types))
|
||||||
|
.collect();
|
||||||
|
|
||||||
|
FunctionSignature {
|
||||||
|
name: signature.name.to_string(),
|
||||||
|
arguments,
|
||||||
|
output_types,
|
||||||
|
}
|
||||||
|
}
|
50
crates/module-interface/src/interface/itype_to_text.rs
Normal file
50
crates/module-interface/src/interface/itype_to_text.rs
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2021 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::it_interface::IRecordTypes;
|
||||||
|
|
||||||
|
use wasmer_it::IType;
|
||||||
|
|
||||||
|
/// Converts the supplied IType to a Aqua0compatible text representation.
|
||||||
|
///
|
||||||
|
/// SAFETY:
|
||||||
|
/// It's assumed that arguments are well-formed and all records have a corresponded type in
|
||||||
|
/// record_types.
|
||||||
|
pub fn itype_text_view(arg_ty: &IType, record_types: &IRecordTypes) -> String {
|
||||||
|
match arg_ty {
|
||||||
|
IType::Record(record_type_id) => {
|
||||||
|
// assumed that this functions called with well-formed args
|
||||||
|
let record = record_types.get(record_type_id).unwrap();
|
||||||
|
record.name.clone()
|
||||||
|
}
|
||||||
|
IType::Array(array_ty) => format!("[]{}", itype_text_view(array_ty, record_types)),
|
||||||
|
IType::Boolean => "bool".to_string(),
|
||||||
|
IType::S8 => "i8".to_string(),
|
||||||
|
IType::S16 => "i16".to_string(),
|
||||||
|
IType::S32 => "i32".to_string(),
|
||||||
|
IType::S64 => "i64".to_string(),
|
||||||
|
IType::U8 => "u8".to_string(),
|
||||||
|
IType::U16 => "u16".to_string(),
|
||||||
|
IType::U32 => "u32".to_string(),
|
||||||
|
IType::U64 => "u64".to_string(),
|
||||||
|
IType::F32 => "f32".to_string(),
|
||||||
|
IType::F64 => "f64".to_string(),
|
||||||
|
IType::String => "string".to_string(),
|
||||||
|
IType::ByteArray => "[]u8".to_string(),
|
||||||
|
IType::I32 => "i32".to_string(),
|
||||||
|
IType::I64 => "i64".to_string(),
|
||||||
|
}
|
||||||
|
}
|
38
crates/module-interface/src/interface/mod.rs
Normal file
38
crates/module-interface/src/interface/mod.rs
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2021 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
mod errors;
|
||||||
|
mod interface_transformer;
|
||||||
|
mod itype_to_text;
|
||||||
|
mod module_interface;
|
||||||
|
mod records_transformer;
|
||||||
|
|
||||||
|
pub use errors::InterfaceError;
|
||||||
|
pub use interface_transformer::it_to_module_interface;
|
||||||
|
pub use itype_to_text::*;
|
||||||
|
pub use module_interface::*;
|
||||||
|
|
||||||
|
pub type InterfaceResult<T> = std::result::Result<T, InterfaceError>;
|
||||||
|
|
||||||
|
use marine_it_interfaces::MITInterfaces;
|
||||||
|
|
||||||
|
/// Returns interface of a Marine module.
|
||||||
|
pub fn get_interface(mit: &MITInterfaces<'_>) -> InterfaceResult<ModuleInterface> {
|
||||||
|
let it_interface = crate::it_interface::get_interface(mit)?;
|
||||||
|
let interface = it_to_module_interface(it_interface)?;
|
||||||
|
|
||||||
|
Ok(interface)
|
||||||
|
}
|
78
crates/module-interface/src/interface/module_interface.rs
Normal file
78
crates/module-interface/src/interface/module_interface.rs
Normal file
@ -0,0 +1,78 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2021 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 serde::Serialize;
|
||||||
|
use serde::Deserialize;
|
||||||
|
|
||||||
|
#[derive(PartialEq, Eq, Debug, Clone, Hash, Serialize, Deserialize)]
|
||||||
|
pub struct FunctionSignature {
|
||||||
|
pub name: String,
|
||||||
|
pub arguments: Vec<(String, String)>,
|
||||||
|
pub output_types: Vec<String>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(PartialEq, Eq, Debug, Clone, Hash, Serialize, Deserialize)]
|
||||||
|
pub struct RecordField {
|
||||||
|
pub name: String,
|
||||||
|
pub ty: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(PartialEq, Eq, Debug, Clone, Hash, Serialize, Deserialize)]
|
||||||
|
pub struct RecordType {
|
||||||
|
pub name: String,
|
||||||
|
pub id: u64,
|
||||||
|
pub fields: Vec<RecordField>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(PartialEq, Eq, Debug, Clone, Hash, Serialize, Deserialize)]
|
||||||
|
pub struct ModuleInterface {
|
||||||
|
pub function_signatures: Vec<FunctionSignature>,
|
||||||
|
// record types are guaranteed to be topological sorted
|
||||||
|
pub record_types: Vec<RecordType>,
|
||||||
|
}
|
||||||
|
|
||||||
|
use std::fmt;
|
||||||
|
|
||||||
|
impl fmt::Display for FunctionSignature {
|
||||||
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
|
use itertools::Itertools;
|
||||||
|
|
||||||
|
let output = match self.output_types.len() {
|
||||||
|
0 => "()",
|
||||||
|
1 => &self.output_types[0],
|
||||||
|
_ => unimplemented!("more than 1 output type is unsupported"),
|
||||||
|
};
|
||||||
|
|
||||||
|
if self.arguments.is_empty() {
|
||||||
|
writeln!(f, "{}: -> {}", self.name, output)
|
||||||
|
} else {
|
||||||
|
let args = self.arguments.iter().map(|(_, ty)| ty).format(",");
|
||||||
|
writeln!(f, "{}: {} -> {}", self.name, args, output)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl fmt::Display for RecordType {
|
||||||
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
|
writeln!(f, "data {}:", self.name)?;
|
||||||
|
|
||||||
|
for field in self.fields.iter() {
|
||||||
|
writeln!(f, " {}: {}", field.name, field.ty)?;
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
128
crates/module-interface/src/interface/records_transformer.rs
Normal file
128
crates/module-interface/src/interface/records_transformer.rs
Normal file
@ -0,0 +1,128 @@
|
|||||||
|
/*
|
||||||
|
* 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::RecordType;
|
||||||
|
use super::RecordField;
|
||||||
|
use super::InterfaceResult;
|
||||||
|
use super::InterfaceError;
|
||||||
|
use crate::it_interface::IRecordTypes;
|
||||||
|
|
||||||
|
use wasmer_it::IRecordType;
|
||||||
|
use wasmer_it::IType;
|
||||||
|
|
||||||
|
use std::collections::HashSet;
|
||||||
|
use std::rc::Rc;
|
||||||
|
|
||||||
|
pub(crate) struct RecordsTransformer {
|
||||||
|
used: HashSet<u64>,
|
||||||
|
sorted_order: Vec<u64>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl RecordsTransformer {
|
||||||
|
pub(crate) fn transform(record_types: &IRecordTypes) -> InterfaceResult<Vec<RecordType>> {
|
||||||
|
let records_count = record_types.len();
|
||||||
|
|
||||||
|
let mut transformer = Self {
|
||||||
|
used: HashSet::with_capacity(records_count),
|
||||||
|
sorted_order: Vec::with_capacity(records_count),
|
||||||
|
};
|
||||||
|
|
||||||
|
// TODO: check for cycles
|
||||||
|
transformer.topological_sort(record_types)?;
|
||||||
|
let record_types = transformer.into_transformed_records(record_types);
|
||||||
|
|
||||||
|
Ok(record_types)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn topological_sort(&mut self, exported_records: &IRecordTypes) -> InterfaceResult<()> {
|
||||||
|
for (id, record) in exported_records {
|
||||||
|
self.dfs(*id, record, exported_records)?;
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn dfs(
|
||||||
|
&mut self,
|
||||||
|
record_id: u64,
|
||||||
|
record: &Rc<IRecordType>,
|
||||||
|
exported_records: &IRecordTypes,
|
||||||
|
) -> InterfaceResult<()> {
|
||||||
|
if !self.used.insert(record_id) {
|
||||||
|
return Ok(());
|
||||||
|
}
|
||||||
|
|
||||||
|
for field in (&record.fields).iter() {
|
||||||
|
self.type_dfs(&field.ty, exported_records)?;
|
||||||
|
}
|
||||||
|
|
||||||
|
self.sorted_order.push(record_id);
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn type_dfs(
|
||||||
|
&mut self,
|
||||||
|
field_ty: &IType,
|
||||||
|
exported_records: &IRecordTypes,
|
||||||
|
) -> InterfaceResult<()> {
|
||||||
|
match field_ty {
|
||||||
|
IType::Record(type_id) => {
|
||||||
|
let child_record = exported_records
|
||||||
|
.get(type_id)
|
||||||
|
.ok_or(InterfaceError::NotFoundRecordTypeId(*type_id))?;
|
||||||
|
|
||||||
|
self.dfs(*type_id, child_record, exported_records)
|
||||||
|
}
|
||||||
|
IType::Array(ty) => self.type_dfs(ty, exported_records),
|
||||||
|
_ => Ok(()),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn into_transformed_records(self, record_types: &IRecordTypes) -> Vec<RecordType> {
|
||||||
|
self.sorted_order
|
||||||
|
.into_iter()
|
||||||
|
.map(|id| {
|
||||||
|
// unwrap is safe here because sorted_order is constructed based on record_types
|
||||||
|
let record = record_types.get(&id).unwrap();
|
||||||
|
Self::convert_record(id, record, &record_types)
|
||||||
|
})
|
||||||
|
.collect::<Vec<_>>()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn convert_record(
|
||||||
|
id: u64,
|
||||||
|
record: &Rc<IRecordType>,
|
||||||
|
record_types: &IRecordTypes,
|
||||||
|
) -> RecordType {
|
||||||
|
use super::itype_text_view;
|
||||||
|
|
||||||
|
let fields = record
|
||||||
|
.fields
|
||||||
|
.iter()
|
||||||
|
.map(|field| RecordField {
|
||||||
|
name: field.name.clone(),
|
||||||
|
ty: itype_text_view(&field.ty, record_types),
|
||||||
|
})
|
||||||
|
.collect::<Vec<_>>();
|
||||||
|
|
||||||
|
RecordType {
|
||||||
|
name: record.name.clone(),
|
||||||
|
id,
|
||||||
|
fields,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
33
crates/module-interface/src/it_interface/errors.rs
Normal file
33
crates/module-interface/src/it_interface/errors.rs
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
/*
|
||||||
|
* 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 marine_it_interfaces::MITInterfacesError;
|
||||||
|
use thiserror::Error as ThisError;
|
||||||
|
|
||||||
|
#[derive(Debug, ThisError)]
|
||||||
|
pub enum ITInterfaceError {
|
||||||
|
#[error("type with idx = {0} isn't a function type")]
|
||||||
|
ITTypeNotFunction(u32),
|
||||||
|
|
||||||
|
#[error("record type with type id {0} not found")]
|
||||||
|
NotFoundRecordTypeId(u64),
|
||||||
|
|
||||||
|
#[error("mailformed module: a record contains more recursion level then allowed")]
|
||||||
|
TooManyRecursionLevels,
|
||||||
|
|
||||||
|
#[error("{0}")]
|
||||||
|
MITInterfacesError(#[from] MITInterfacesError),
|
||||||
|
}
|
@ -0,0 +1,86 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2021 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::IFunctionSignature;
|
||||||
|
use super::ITInterfaceError;
|
||||||
|
use super::RIResult;
|
||||||
|
|
||||||
|
use marine_it_interfaces::MITInterfaces;
|
||||||
|
|
||||||
|
use std::rc::Rc;
|
||||||
|
|
||||||
|
pub struct ITExportFuncDescriptor<'n> {
|
||||||
|
pub adapter_function_type: u32,
|
||||||
|
pub name: &'n str,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns all exported IT functions descriptors.
|
||||||
|
pub fn get_export_funcs_descriptors<'i>(
|
||||||
|
mit: &'i MITInterfaces<'_>,
|
||||||
|
) -> Vec<ITExportFuncDescriptor<'i>> {
|
||||||
|
// An IT function is exported if it lies in export functions and have implementation.
|
||||||
|
// An export IT function without implementation is a hack and used to call core function from
|
||||||
|
// a Wasm module. This hack is needed because there is only one call instruction in the
|
||||||
|
// interface-types crates and it's needed to distinguish somehow between calling export IT or
|
||||||
|
// core functions. This scheme is a kind of mess and it needs to be refactored one day.
|
||||||
|
mit.implementations()
|
||||||
|
.filter_map(|(adapter_function_type, core_function_type)| {
|
||||||
|
mit.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
|
||||||
|
.iter()
|
||||||
|
.map(move |name| ITExportFuncDescriptor {
|
||||||
|
adapter_function_type,
|
||||||
|
name,
|
||||||
|
})
|
||||||
|
})
|
||||||
|
.flatten()
|
||||||
|
.collect::<Vec<_>>()
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns all exported IT functions.
|
||||||
|
pub fn get_export_funcs(mit: &MITInterfaces<'_>) -> RIResult<Vec<IFunctionSignature>> {
|
||||||
|
use marine_it_interfaces::ITAstType;
|
||||||
|
|
||||||
|
let funcs_descriptors = get_export_funcs_descriptors(mit);
|
||||||
|
|
||||||
|
funcs_descriptors
|
||||||
|
.into_iter()
|
||||||
|
.map(|descriptor| {
|
||||||
|
let it_type = mit.type_by_idx_r(descriptor.adapter_function_type)?;
|
||||||
|
|
||||||
|
match it_type {
|
||||||
|
ITAstType::Function {
|
||||||
|
arguments,
|
||||||
|
output_types,
|
||||||
|
} => {
|
||||||
|
let signature = IFunctionSignature {
|
||||||
|
name: Rc::new(descriptor.name.to_string()),
|
||||||
|
arguments: arguments.clone(),
|
||||||
|
outputs: output_types.clone(),
|
||||||
|
adapter_function_type: descriptor.adapter_function_type,
|
||||||
|
};
|
||||||
|
Ok(signature)
|
||||||
|
}
|
||||||
|
_ => Err(ITInterfaceError::ITTypeNotFunction(
|
||||||
|
descriptor.adapter_function_type,
|
||||||
|
)),
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.collect::<RIResult<Vec<IFunctionSignature>>>()
|
||||||
|
}
|
129
crates/module-interface/src/it_interface/export_it_records.rs
Normal file
129
crates/module-interface/src/it_interface/export_it_records.rs
Normal file
@ -0,0 +1,129 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2021 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::IRecordTypes;
|
||||||
|
use super::RIResult;
|
||||||
|
use super::ITInterfaceError;
|
||||||
|
use super::IFunctionSignature;
|
||||||
|
|
||||||
|
use marine_it_interfaces::MITInterfaces;
|
||||||
|
use wasmer_it::IType;
|
||||||
|
|
||||||
|
use std::collections::HashMap;
|
||||||
|
|
||||||
|
const TYPE_RESOLVE_RECURSION_LIMIT: u32 = 1024;
|
||||||
|
|
||||||
|
pub struct FullRecordTypes {
|
||||||
|
pub record_types: IRecordTypes,
|
||||||
|
pub export_record_types: IRecordTypes,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_record_types<'f>(
|
||||||
|
mit: &MITInterfaces<'_>,
|
||||||
|
export_funcs: impl ExactSizeIterator<Item = &'f IFunctionSignature>,
|
||||||
|
) -> RIResult<FullRecordTypes> {
|
||||||
|
let all_record_types = get_all_records(mit);
|
||||||
|
let mut export_record_types = HashMap::new();
|
||||||
|
|
||||||
|
let itypes = export_funcs.flat_map(|s| {
|
||||||
|
s.arguments
|
||||||
|
.as_ref()
|
||||||
|
.iter()
|
||||||
|
.map(|a| &a.ty)
|
||||||
|
.chain(s.outputs.as_ref().iter())
|
||||||
|
});
|
||||||
|
|
||||||
|
for itype in itypes {
|
||||||
|
handle_itype(itype, &all_record_types, &mut export_record_types, 0)?;
|
||||||
|
}
|
||||||
|
|
||||||
|
let full_record_types = FullRecordTypes {
|
||||||
|
record_types: all_record_types,
|
||||||
|
export_record_types,
|
||||||
|
};
|
||||||
|
|
||||||
|
Ok(full_record_types)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn handle_itype(
|
||||||
|
itype: &IType,
|
||||||
|
all_record_types: &IRecordTypes,
|
||||||
|
export_record_types: &mut IRecordTypes,
|
||||||
|
recursion_level: u32,
|
||||||
|
) -> RIResult<()> {
|
||||||
|
if recursion_level > TYPE_RESOLVE_RECURSION_LIMIT {
|
||||||
|
return Err(ITInterfaceError::TooManyRecursionLevels);
|
||||||
|
}
|
||||||
|
|
||||||
|
match itype {
|
||||||
|
IType::Record(record_type_id) => handle_record_type(
|
||||||
|
*record_type_id,
|
||||||
|
all_record_types,
|
||||||
|
export_record_types,
|
||||||
|
recursion_level + 1,
|
||||||
|
)?,
|
||||||
|
IType::Array(array_ty) => handle_itype(
|
||||||
|
array_ty,
|
||||||
|
all_record_types,
|
||||||
|
export_record_types,
|
||||||
|
recursion_level + 1,
|
||||||
|
)?,
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn handle_record_type(
|
||||||
|
record_type_id: u64,
|
||||||
|
all_record_types: &IRecordTypes,
|
||||||
|
export_record_types: &mut IRecordTypes,
|
||||||
|
recursion_level: u32,
|
||||||
|
) -> RIResult<()> {
|
||||||
|
let record_type = all_record_types
|
||||||
|
.get(&record_type_id)
|
||||||
|
.ok_or(ITInterfaceError::NotFoundRecordTypeId(record_type_id))?;
|
||||||
|
|
||||||
|
export_record_types.insert(record_type_id, record_type.clone());
|
||||||
|
|
||||||
|
for field in record_type.fields.iter() {
|
||||||
|
handle_itype(
|
||||||
|
&field.ty,
|
||||||
|
all_record_types,
|
||||||
|
export_record_types,
|
||||||
|
recursion_level + 1,
|
||||||
|
)?;
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_all_records(mit: &MITInterfaces<'_>) -> IRecordTypes {
|
||||||
|
use marine_it_interfaces::ITAstType;
|
||||||
|
|
||||||
|
mit.types()
|
||||||
|
.enumerate()
|
||||||
|
.fold(HashMap::new(), |mut record_types_by_id, (id, ty)| {
|
||||||
|
match ty {
|
||||||
|
ITAstType::Record(record_type) => {
|
||||||
|
record_types_by_id.insert(id as u64, record_type.clone());
|
||||||
|
}
|
||||||
|
ITAstType::Function { .. } => {}
|
||||||
|
};
|
||||||
|
|
||||||
|
record_types_by_id
|
||||||
|
})
|
||||||
|
}
|
@ -0,0 +1,44 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2021 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 wasmer_it::IType;
|
||||||
|
use wasmer_it::ast::FunctionArg as IFunctionArg;
|
||||||
|
use wasmer_it::IRecordType;
|
||||||
|
|
||||||
|
use serde::Serialize;
|
||||||
|
use serde::Deserialize;
|
||||||
|
|
||||||
|
use std::collections::HashMap;
|
||||||
|
use std::rc::Rc;
|
||||||
|
|
||||||
|
pub type IRecordTypes = HashMap<u64, Rc<IRecordType>>;
|
||||||
|
|
||||||
|
/// Represent a function type inside Marine module.
|
||||||
|
#[derive(PartialEq, Eq, Debug, Clone, Hash, Serialize, Deserialize)]
|
||||||
|
pub struct IFunctionSignature {
|
||||||
|
pub name: Rc<String>,
|
||||||
|
pub arguments: Rc<Vec<IFunctionArg>>,
|
||||||
|
pub outputs: Rc<Vec<IType>>,
|
||||||
|
pub adapter_function_type: u32,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Represent an interface of a Wasm module.
|
||||||
|
#[derive(PartialEq, Eq, Debug, Clone, Serialize, Deserialize)]
|
||||||
|
pub struct IModuleInterface {
|
||||||
|
pub export_record_types: IRecordTypes,
|
||||||
|
pub record_types: IRecordTypes,
|
||||||
|
pub function_signatures: Vec<IFunctionSignature>,
|
||||||
|
}
|
46
crates/module-interface/src/it_interface/mod.rs
Normal file
46
crates/module-interface/src/it_interface/mod.rs
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2021 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
mod errors;
|
||||||
|
mod export_it_functions;
|
||||||
|
mod export_it_records;
|
||||||
|
mod it_module_interface;
|
||||||
|
|
||||||
|
pub use errors::*;
|
||||||
|
pub use export_it_functions::*;
|
||||||
|
pub use export_it_records::*;
|
||||||
|
pub use it_module_interface::*;
|
||||||
|
|
||||||
|
pub type RIResult<T> = std::result::Result<T, ITInterfaceError>;
|
||||||
|
|
||||||
|
use marine_it_interfaces::MITInterfaces;
|
||||||
|
|
||||||
|
/// Returns Marine module interface that includes both export and all record types.
|
||||||
|
pub fn get_interface(mit: &MITInterfaces<'_>) -> RIResult<IModuleInterface> {
|
||||||
|
let function_signatures = get_export_funcs(mit)?;
|
||||||
|
let FullRecordTypes {
|
||||||
|
record_types,
|
||||||
|
export_record_types,
|
||||||
|
} = get_record_types(mit, function_signatures.iter())?;
|
||||||
|
|
||||||
|
let mm_interface = IModuleInterface {
|
||||||
|
record_types,
|
||||||
|
export_record_types,
|
||||||
|
function_signatures,
|
||||||
|
};
|
||||||
|
|
||||||
|
Ok(mm_interface)
|
||||||
|
}
|
29
crates/module-interface/src/lib.rs
Normal file
29
crates/module-interface/src/lib.rs
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2021 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#![warn(rust_2018_idioms)]
|
||||||
|
#![deny(
|
||||||
|
dead_code,
|
||||||
|
nonstandard_style,
|
||||||
|
unused_imports,
|
||||||
|
unused_mut,
|
||||||
|
unused_variables,
|
||||||
|
unused_unsafe,
|
||||||
|
unreachable_patterns
|
||||||
|
)]
|
||||||
|
|
||||||
|
pub mod interface;
|
||||||
|
pub mod it_interface;
|
@ -1,13 +1,13 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "fluence-app-service"
|
name = "fluence-app-service"
|
||||||
description = "Fluence Application Service"
|
description = "Fluence Application Service"
|
||||||
version = "0.7.2"
|
version = "0.7.3"
|
||||||
authors = ["Fluence Labs"]
|
authors = ["Fluence Labs"]
|
||||||
license = "Apache-2.0"
|
license = "Apache-2.0"
|
||||||
edition = "2018"
|
edition = "2018"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
fluence-faas = { path = "../fluence-faas", version = "0.7.2" }
|
fluence-faas = { path = "../fluence-faas", version = "0.7.3" }
|
||||||
|
|
||||||
maplit = "1.0.2"
|
maplit = "1.0.2"
|
||||||
log = "0.4.8"
|
log = "0.4.8"
|
||||||
|
@ -17,7 +17,7 @@
|
|||||||
use fluence_faas::FaaSModuleInterface;
|
use fluence_faas::FaaSModuleInterface;
|
||||||
use fluence_faas::FaaSFunctionSignature;
|
use fluence_faas::FaaSFunctionSignature;
|
||||||
use fluence_faas::IRecordType;
|
use fluence_faas::IRecordType;
|
||||||
use fluence_faas::RecordTypes;
|
use fluence_faas::MRecordTypes;
|
||||||
use fluence_faas::itype_text_view;
|
use fluence_faas::itype_text_view;
|
||||||
|
|
||||||
use serde::Serialize;
|
use serde::Serialize;
|
||||||
@ -66,7 +66,7 @@ pub(crate) fn into_service_interface(faas_interface: FaaSModuleInterface<'_>) ->
|
|||||||
|
|
||||||
fn serialize_function_signature(
|
fn serialize_function_signature(
|
||||||
signature: FaaSFunctionSignature,
|
signature: FaaSFunctionSignature,
|
||||||
record_types: &RecordTypes,
|
record_types: &MRecordTypes,
|
||||||
) -> FunctionSignature {
|
) -> FunctionSignature {
|
||||||
let arguments = signature
|
let arguments = signature
|
||||||
.arguments
|
.arguments
|
||||||
@ -90,7 +90,7 @@ fn serialize_function_signature(
|
|||||||
fn serialize_record_type(
|
fn serialize_record_type(
|
||||||
id: u64,
|
id: u64,
|
||||||
record: Rc<IRecordType>,
|
record: Rc<IRecordType>,
|
||||||
record_types: &RecordTypes,
|
record_types: &MRecordTypes,
|
||||||
) -> RecordType {
|
) -> RecordType {
|
||||||
let fields = record
|
let fields = record
|
||||||
.fields
|
.fields
|
||||||
|
@ -1,13 +1,14 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "fluence-faas"
|
name = "fluence-faas"
|
||||||
description = "Fluence FaaS"
|
description = "Fluence FaaS"
|
||||||
version = "0.7.2"
|
version = "0.7.3"
|
||||||
authors = ["Fluence Labs"]
|
authors = ["Fluence Labs"]
|
||||||
license = "Apache-2.0"
|
license = "Apache-2.0"
|
||||||
edition = "2018"
|
edition = "2018"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
marine-runtime = { path = "../runtime", version = "0.5.0" }
|
marine-runtime = { path = "../runtime", version = "0.5.0" }
|
||||||
|
marine-module-interface = { path = "../crates/module-interface", version = "0.1.0" }
|
||||||
marine-utils = { path = "../crates/utils", version = "0.2.0" }
|
marine-utils = { path = "../crates/utils", version = "0.2.0" }
|
||||||
fluence-sdk-main = { version = "0.6.9", features = ["logger"] }
|
fluence-sdk-main = { version = "0.6.9", features = ["logger"] }
|
||||||
fluence = { version = "0.6.3", features = ["logger"] }
|
fluence = { version = "0.6.3", features = ["logger"] }
|
||||||
|
@ -28,7 +28,7 @@ use crate::host_imports::logger::WASM_LOG_ENV_NAME;
|
|||||||
use marine::Marine;
|
use marine::Marine;
|
||||||
use marine::IFunctionArg;
|
use marine::IFunctionArg;
|
||||||
use marine_utils::SharedString;
|
use marine_utils::SharedString;
|
||||||
use marine::RecordTypes;
|
use marine::MRecordTypes;
|
||||||
use fluence::CallParameters;
|
use fluence::CallParameters;
|
||||||
|
|
||||||
use serde_json::Value as JValue;
|
use serde_json::Value as JValue;
|
||||||
@ -39,7 +39,7 @@ use std::rc::Rc;
|
|||||||
|
|
||||||
struct ModuleInterface {
|
struct ModuleInterface {
|
||||||
function_signatures: HashMap<SharedString, (Rc<Vec<IFunctionArg>>, Rc<Vec<IType>>)>,
|
function_signatures: HashMap<SharedString, (Rc<Vec<IFunctionArg>>, Rc<Vec<IType>>)>,
|
||||||
record_types: Rc<RecordTypes>,
|
record_types: Rc<MRecordTypes>,
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: remove and use mutex instead
|
// TODO: remove and use mutex instead
|
||||||
@ -186,7 +186,7 @@ impl FluenceFaaS {
|
|||||||
&'faas mut self,
|
&'faas mut self,
|
||||||
module_name: &str,
|
module_name: &str,
|
||||||
func_name: &str,
|
func_name: &str,
|
||||||
) -> Result<(Rc<Vec<IFunctionArg>>, Rc<Vec<IType>>, Rc<RecordTypes>)> {
|
) -> Result<(Rc<Vec<IFunctionArg>>, Rc<Vec<IType>>, Rc<MRecordTypes>)> {
|
||||||
use FaaSError::NoSuchModule;
|
use FaaSError::NoSuchModule;
|
||||||
use FaaSError::MissingFunctionError;
|
use FaaSError::MissingFunctionError;
|
||||||
|
|
||||||
|
@ -14,17 +14,15 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
use super::IType;
|
|
||||||
use super::IRecordType;
|
use super::IRecordType;
|
||||||
|
use super::itype_text_view;
|
||||||
use crate::FaaSModuleInterface;
|
use crate::FaaSModuleInterface;
|
||||||
|
|
||||||
use marine::RecordTypes;
|
|
||||||
use itertools::Itertools;
|
use itertools::Itertools;
|
||||||
use serde::Serialize;
|
use serde::Serialize;
|
||||||
|
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use std::collections::HashSet;
|
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, Eq, Clone, Serialize)]
|
#[derive(Debug, PartialEq, Eq, Clone, Serialize)]
|
||||||
pub struct FaaSInterface<'a> {
|
pub struct FaaSInterface<'a> {
|
||||||
@ -33,78 +31,80 @@ pub struct FaaSInterface<'a> {
|
|||||||
|
|
||||||
impl<'a> fmt::Display for FaaSInterface<'a> {
|
impl<'a> fmt::Display for FaaSInterface<'a> {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
let mut printed_record_types: HashSet<&IRecordType> = HashSet::new();
|
print_record_types(self.modules.values(), f)?;
|
||||||
|
print_functions_sign(self.modules.iter(), f)
|
||||||
for (_, module_interface) in self.modules.iter() {
|
|
||||||
for (_, record_type) in module_interface.record_types.iter() {
|
|
||||||
if !printed_record_types.insert(record_type) {
|
|
||||||
// do not print record if it has been already printed
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
writeln!(f, "{} {{", record_type.name)?;
|
|
||||||
|
|
||||||
for field in record_type.fields.iter() {
|
|
||||||
writeln!(
|
|
||||||
f,
|
|
||||||
" {}: {}",
|
|
||||||
field.name,
|
|
||||||
itype_text_view(&field.ty, &module_interface.record_types)
|
|
||||||
)?;
|
|
||||||
}
|
|
||||||
|
|
||||||
writeln!(f, "}}")?;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (name, module_interface) in self.modules.iter() {
|
|
||||||
writeln!(f, "\n{}:", *name)?;
|
|
||||||
|
|
||||||
for function_signature in module_interface.function_signatures.iter() {
|
|
||||||
write!(f, " fn {}(", function_signature.name)?;
|
|
||||||
|
|
||||||
let args = function_signature
|
|
||||||
.arguments
|
|
||||||
.iter()
|
|
||||||
.map(|arg| {
|
|
||||||
format!(
|
|
||||||
"{}: {}",
|
|
||||||
arg.name,
|
|
||||||
itype_text_view(&arg.ty, &module_interface.record_types)
|
|
||||||
)
|
|
||||||
})
|
|
||||||
.join(", ");
|
|
||||||
|
|
||||||
let outputs = &function_signature.outputs;
|
|
||||||
if outputs.is_empty() {
|
|
||||||
writeln!(f, "{})", args)?;
|
|
||||||
} else if outputs.len() == 1 {
|
|
||||||
writeln!(
|
|
||||||
f,
|
|
||||||
"{}) -> {}",
|
|
||||||
args,
|
|
||||||
itype_text_view(&outputs[0], &module_interface.record_types)
|
|
||||||
)?;
|
|
||||||
} else {
|
|
||||||
// At now, multi values aren't supported - only one output type is possible
|
|
||||||
unimplemented!()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn itype_text_view(arg_ty: &IType, record_types: &RecordTypes) -> String {
|
fn print_record_types<'r>(
|
||||||
match arg_ty {
|
modules: impl Iterator<Item = &'r FaaSModuleInterface<'r>>,
|
||||||
IType::Record(record_type_id) => {
|
f: &mut fmt::Formatter<'_>,
|
||||||
// unwrap is safe because FaaSInterface here is well-formed
|
) -> fmt::Result {
|
||||||
// (it was checked on the module startup stage)
|
use std::collections::HashSet;
|
||||||
let record = record_types.get(record_type_id).unwrap();
|
|
||||||
record.name.clone()
|
let mut printed_record_types: HashSet<&IRecordType> = HashSet::new();
|
||||||
|
|
||||||
|
for module in modules {
|
||||||
|
for (_, record_type) in module.record_types.iter() {
|
||||||
|
if !printed_record_types.insert(record_type) {
|
||||||
|
// do not print record if it has been already printed
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
writeln!(f, "data {}:", record_type.name)?;
|
||||||
|
|
||||||
|
for field in record_type.fields.iter() {
|
||||||
|
writeln!(
|
||||||
|
f,
|
||||||
|
" {}: {}",
|
||||||
|
field.name,
|
||||||
|
itype_text_view(&field.ty, &module.record_types)
|
||||||
|
)?;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
IType::Array(array_ty) => format!("Array<{}>", itype_text_view(array_ty, record_types)),
|
|
||||||
t => format!("{:?}", t),
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
writeln!(f)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn print_functions_sign<'r>(
|
||||||
|
modules: impl Iterator<Item = (&'r &'r str, &'r FaaSModuleInterface<'r>)>,
|
||||||
|
f: &mut fmt::Formatter<'_>,
|
||||||
|
) -> fmt::Result {
|
||||||
|
for (name, module_interface) in modules {
|
||||||
|
writeln!(f, "{}:", *name)?;
|
||||||
|
|
||||||
|
for function_signature in module_interface.function_signatures.iter() {
|
||||||
|
write!(f, " fn {}(", function_signature.name)?;
|
||||||
|
|
||||||
|
let args = function_signature
|
||||||
|
.arguments
|
||||||
|
.iter()
|
||||||
|
.map(|arg| {
|
||||||
|
format!(
|
||||||
|
"{}: {}",
|
||||||
|
arg.name,
|
||||||
|
itype_text_view(&arg.ty, &module_interface.record_types)
|
||||||
|
)
|
||||||
|
})
|
||||||
|
.join(", ");
|
||||||
|
|
||||||
|
let outputs = &function_signature.outputs;
|
||||||
|
if outputs.is_empty() {
|
||||||
|
writeln!(f, "{})", args)?;
|
||||||
|
} else if outputs.len() == 1 {
|
||||||
|
writeln!(
|
||||||
|
f,
|
||||||
|
"{}) -> {}",
|
||||||
|
args,
|
||||||
|
itype_text_view(&outputs[0], &module_interface.record_types)
|
||||||
|
)?;
|
||||||
|
} else {
|
||||||
|
// At now, multi values aren't supported - only one output type is possible
|
||||||
|
unimplemented!()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
|
@ -19,13 +19,13 @@ use crate::IType;
|
|||||||
use crate::Result;
|
use crate::Result;
|
||||||
use crate::errors::FaaSError::JsonOutputSerializationError as OutputDeError;
|
use crate::errors::FaaSError::JsonOutputSerializationError as OutputDeError;
|
||||||
|
|
||||||
use marine::RecordTypes;
|
use marine::MRecordTypes;
|
||||||
use serde_json::Value as JValue;
|
use serde_json::Value as JValue;
|
||||||
|
|
||||||
pub(crate) fn ivalues_to_json(
|
pub(crate) fn ivalues_to_json(
|
||||||
mut ivalues: Vec<IValue>,
|
mut ivalues: Vec<IValue>,
|
||||||
outputs: &[IType],
|
outputs: &[IType],
|
||||||
record_types: &RecordTypes,
|
record_types: &MRecordTypes,
|
||||||
) -> Result<JValue> {
|
) -> Result<JValue> {
|
||||||
if outputs.len() != ivalues.len() {
|
if outputs.len() != ivalues.len() {
|
||||||
return Err(OutputDeError(format!(
|
return Err(OutputDeError(format!(
|
||||||
@ -42,7 +42,7 @@ pub(crate) fn ivalues_to_json(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn ivalue_to_json(ivalue: IValue, output: &IType, record_types: &RecordTypes) -> Result<JValue> {
|
fn ivalue_to_json(ivalue: IValue, output: &IType, record_types: &MRecordTypes) -> Result<JValue> {
|
||||||
use serde_json::json;
|
use serde_json::json;
|
||||||
|
|
||||||
// clone here needed because binding by-value and by-ref in the same pattern in unstable
|
// clone here needed because binding by-value and by-ref in the same pattern in unstable
|
||||||
|
@ -19,7 +19,7 @@ use crate::IType;
|
|||||||
use crate::Result;
|
use crate::Result;
|
||||||
use crate::FaaSError::JsonArgumentsDeserializationError as ArgDeError;
|
use crate::FaaSError::JsonArgumentsDeserializationError as ArgDeError;
|
||||||
|
|
||||||
use marine::RecordTypes;
|
use marine::MRecordTypes;
|
||||||
use serde_json::Value as JValue;
|
use serde_json::Value as JValue;
|
||||||
use wasmer_it::NEVec;
|
use wasmer_it::NEVec;
|
||||||
|
|
||||||
@ -30,7 +30,7 @@ use std::iter::ExactSizeIterator;
|
|||||||
pub(crate) fn json_to_ivalues<'a, 'b>(
|
pub(crate) fn json_to_ivalues<'a, 'b>(
|
||||||
json_args: JValue,
|
json_args: JValue,
|
||||||
arg_types: impl Iterator<Item = (&'a String, &'a IType)> + ExactSizeIterator,
|
arg_types: impl Iterator<Item = (&'a String, &'a IType)> + ExactSizeIterator,
|
||||||
record_types: &'b RecordTypes,
|
record_types: &'b MRecordTypes,
|
||||||
) -> Result<Vec<IValue>> {
|
) -> Result<Vec<IValue>> {
|
||||||
let ivalues = match json_args {
|
let ivalues = match json_args {
|
||||||
JValue::Object(json_map) => json_map_to_ivalues(json_map, arg_types, &record_types)?,
|
JValue::Object(json_map) => json_map_to_ivalues(json_map, arg_types, &record_types)?,
|
||||||
@ -48,7 +48,7 @@ pub(crate) fn json_to_ivalues<'a, 'b>(
|
|||||||
fn json_map_to_ivalues<'a, 'b>(
|
fn json_map_to_ivalues<'a, 'b>(
|
||||||
mut json_map: serde_json::Map<String, JValue>,
|
mut json_map: serde_json::Map<String, JValue>,
|
||||||
arg_types: impl Iterator<Item = (&'a String, &'a IType)>,
|
arg_types: impl Iterator<Item = (&'a String, &'a IType)>,
|
||||||
record_types: &'b RecordTypes,
|
record_types: &'b MRecordTypes,
|
||||||
) -> Result<Vec<IValue>> {
|
) -> Result<Vec<IValue>> {
|
||||||
let mut iargs = Vec::new();
|
let mut iargs = Vec::new();
|
||||||
|
|
||||||
@ -75,7 +75,7 @@ fn json_map_to_ivalues<'a, 'b>(
|
|||||||
fn json_array_to_ivalues<'a, 'b>(
|
fn json_array_to_ivalues<'a, 'b>(
|
||||||
json_array: Vec<JValue>,
|
json_array: Vec<JValue>,
|
||||||
arg_types: impl Iterator<Item = &'a IType> + ExactSizeIterator,
|
arg_types: impl Iterator<Item = &'a IType> + ExactSizeIterator,
|
||||||
record_types: &'b RecordTypes,
|
record_types: &'b MRecordTypes,
|
||||||
) -> Result<Vec<IValue>> {
|
) -> Result<Vec<IValue>> {
|
||||||
if json_array.len() != arg_types.len() {
|
if json_array.len() != arg_types.len() {
|
||||||
return Err(ArgDeError(format!(
|
return Err(ArgDeError(format!(
|
||||||
@ -129,7 +129,7 @@ fn json_null_to_ivalues<'a>(
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Convert one JValue to an array of ivalues according to the supplied argument type.
|
/// Convert one JValue to an array of ivalues according to the supplied argument type.
|
||||||
fn jvalue_to_ivalue(jvalue: JValue, ty: &IType, record_types: &RecordTypes) -> Result<IValue> {
|
fn jvalue_to_ivalue(jvalue: JValue, ty: &IType, record_types: &MRecordTypes) -> Result<IValue> {
|
||||||
macro_rules! to_ivalue(
|
macro_rules! to_ivalue(
|
||||||
($json_value:expr, $ty:ident) => {
|
($json_value:expr, $ty:ident) => {
|
||||||
{
|
{
|
||||||
@ -211,7 +211,7 @@ fn jvalue_to_ivalue(jvalue: JValue, ty: &IType, record_types: &RecordTypes) -> R
|
|||||||
fn json_record_type_to_ivalue(
|
fn json_record_type_to_ivalue(
|
||||||
json_value: JValue,
|
json_value: JValue,
|
||||||
record_type_id: &u64,
|
record_type_id: &u64,
|
||||||
record_types: &RecordTypes,
|
record_types: &MRecordTypes,
|
||||||
) -> Result<NEVec<IValue>> {
|
) -> Result<NEVec<IValue>> {
|
||||||
let record_type = record_types.get(record_type_id).ok_or_else(|| {
|
let record_type = record_types.get(record_type_id).ok_or_else(|| {
|
||||||
ArgDeError(format!(
|
ArgDeError(format!(
|
||||||
|
@ -36,7 +36,6 @@ pub(crate) type Result<T> = std::result::Result<T, FaaSError>;
|
|||||||
|
|
||||||
pub use faas::FluenceFaaS;
|
pub use faas::FluenceFaaS;
|
||||||
pub use faas_interface::FaaSInterface;
|
pub use faas_interface::FaaSInterface;
|
||||||
pub use faas_interface::itype_text_view;
|
|
||||||
|
|
||||||
pub use config::FaaSConfig;
|
pub use config::FaaSConfig;
|
||||||
pub use config::FaaSModuleConfig;
|
pub use config::FaaSModuleConfig;
|
||||||
@ -57,7 +56,7 @@ pub use marine::IFunctionArg;
|
|||||||
pub use marine::IType;
|
pub use marine::IType;
|
||||||
pub use marine::MModuleInterface as FaaSModuleInterface;
|
pub use marine::MModuleInterface as FaaSModuleInterface;
|
||||||
pub use marine::MFunctionSignature as FaaSFunctionSignature;
|
pub use marine::MFunctionSignature as FaaSFunctionSignature;
|
||||||
pub use marine::RecordTypes;
|
pub use marine::MRecordTypes;
|
||||||
pub use marine::HostExportedFunc;
|
pub use marine::HostExportedFunc;
|
||||||
pub use marine::HostImportDescriptor;
|
pub use marine::HostImportDescriptor;
|
||||||
pub use marine::HostImportError;
|
pub use marine::HostImportError;
|
||||||
@ -67,6 +66,8 @@ pub use marine::ne_vec;
|
|||||||
pub use marine::min_sdk_version;
|
pub use marine::min_sdk_version;
|
||||||
pub use marine::min_it_version;
|
pub use marine::min_it_version;
|
||||||
|
|
||||||
|
pub use marine_module_interface::interface::itype_text_view;
|
||||||
|
|
||||||
pub use fluence::CallParameters;
|
pub use fluence::CallParameters;
|
||||||
pub use fluence::SecurityTetraplet;
|
pub use fluence::SecurityTetraplet;
|
||||||
|
|
||||||
|
@ -15,6 +15,7 @@ marine-module-info-parser = { path = "../crates/module-info-parser", version = "
|
|||||||
marine-it-interfaces = { path = "../crates/it-interfaces", version = "0.4.0" }
|
marine-it-interfaces = { path = "../crates/it-interfaces", version = "0.4.0" }
|
||||||
marine-it-parser = { path = "../crates/it-parser", version = "0.6.0" }
|
marine-it-parser = { path = "../crates/it-parser", version = "0.6.0" }
|
||||||
marine-it-generator = { path = "../crates/it-generator", version = "0.5.0" }
|
marine-it-generator = { path = "../crates/it-generator", version = "0.5.0" }
|
||||||
|
marine-module-interface = { path = "../crates/module-interface", version = "0.1.0" }
|
||||||
marine-utils = { path = "../crates/utils", version = "0.2.0" }
|
marine-utils = { path = "../crates/utils", version = "0.2.0" }
|
||||||
|
|
||||||
wasmer-runtime = { package = "wasmer-runtime-fl", version = "0.17.0" }
|
wasmer-runtime = { package = "wasmer-runtime-fl", version = "0.17.0" }
|
||||||
|
@ -16,7 +16,7 @@
|
|||||||
|
|
||||||
use super::*;
|
use super::*;
|
||||||
use crate::module::MModule;
|
use crate::module::MModule;
|
||||||
use crate::module::RecordTypes;
|
use crate::module::MRecordTypes;
|
||||||
|
|
||||||
use serde::Serialize;
|
use serde::Serialize;
|
||||||
|
|
||||||
@ -27,7 +27,7 @@ use std::rc::Rc;
|
|||||||
/// Represent Marine module interface.
|
/// Represent Marine module interface.
|
||||||
#[derive(PartialEq, Eq, Debug, Clone, Serialize)]
|
#[derive(PartialEq, Eq, Debug, Clone, Serialize)]
|
||||||
pub struct MModuleInterface<'a> {
|
pub struct MModuleInterface<'a> {
|
||||||
pub record_types: &'a RecordTypes,
|
pub record_types: &'a MRecordTypes,
|
||||||
pub function_signatures: Vec<MFunctionSignature>,
|
pub function_signatures: Vec<MFunctionSignature>,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -119,7 +119,7 @@ impl Marine {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Return record types exported by module with given name.
|
/// Return record types exported by module with given name.
|
||||||
pub fn module_record_types<S: AsRef<str>>(&self, module_name: S) -> Option<&RecordTypes> {
|
pub fn module_record_types<S: AsRef<str>>(&self, module_name: S) -> Option<&MRecordTypes> {
|
||||||
self.modules
|
self.modules
|
||||||
.get(module_name.as_ref())
|
.get(module_name.as_ref())
|
||||||
.map(|module| module.export_record_types())
|
.map(|module| module.export_record_types())
|
||||||
|
@ -18,6 +18,7 @@ use crate::HostImportError;
|
|||||||
use marine_it_interfaces::MITInterfacesError;
|
use marine_it_interfaces::MITInterfacesError;
|
||||||
use marine_it_parser::ITParserError;
|
use marine_it_parser::ITParserError;
|
||||||
use marine_module_info_parser::ModuleInfoError;
|
use marine_module_info_parser::ModuleInfoError;
|
||||||
|
use marine_module_interface::it_interface::ITInterfaceError;
|
||||||
|
|
||||||
use wasmer_runtime::error as wasmer_error;
|
use wasmer_runtime::error as wasmer_error;
|
||||||
|
|
||||||
@ -63,6 +64,10 @@ pub enum MError {
|
|||||||
#[error("{0}")]
|
#[error("{0}")]
|
||||||
WASIPrepareError(String),
|
WASIPrepareError(String),
|
||||||
|
|
||||||
|
/// Errors occurred inside marine-module-interface crate.
|
||||||
|
#[error("{0}")]
|
||||||
|
ModuleInterfaceError(#[from] ITInterfaceError),
|
||||||
|
|
||||||
/// Error arisen during execution of Wasm modules (especially, interface types).
|
/// Error arisen during execution of Wasm modules (especially, interface types).
|
||||||
#[error("Execution error: {0}")]
|
#[error("Execution error: {0}")]
|
||||||
ITInstructionError(#[from] wasmer_it::errors::InstructionError),
|
ITInstructionError(#[from] wasmer_it::errors::InstructionError),
|
||||||
|
@ -22,7 +22,7 @@ use super::lowering::LoHelper;
|
|||||||
use super::utils::itypes_args_to_wtypes;
|
use super::utils::itypes_args_to_wtypes;
|
||||||
use super::utils::itypes_output_to_wtypes;
|
use super::utils::itypes_output_to_wtypes;
|
||||||
|
|
||||||
use crate::RecordTypes;
|
use crate::MRecordTypes;
|
||||||
use crate::init_wasm_func_once;
|
use crate::init_wasm_func_once;
|
||||||
use crate::call_wasm_func;
|
use crate::call_wasm_func;
|
||||||
use crate::HostImportDescriptor;
|
use crate::HostImportDescriptor;
|
||||||
@ -41,7 +41,7 @@ use std::ops::Deref;
|
|||||||
|
|
||||||
pub(crate) fn create_host_import_func(
|
pub(crate) fn create_host_import_func(
|
||||||
descriptor: HostImportDescriptor,
|
descriptor: HostImportDescriptor,
|
||||||
record_types: Rc<RecordTypes>,
|
record_types: Rc<MRecordTypes>,
|
||||||
) -> DynamicFunc<'static> {
|
) -> DynamicFunc<'static> {
|
||||||
let allocate_func: AllocateFunc = Box::new(RefCell::new(None));
|
let allocate_func: AllocateFunc = Box::new(RefCell::new(None));
|
||||||
let set_result_ptr_func: SetResultPtrFunc = Box::new(RefCell::new(None));
|
let set_result_ptr_func: SetResultPtrFunc = Box::new(RefCell::new(None));
|
||||||
|
@ -14,7 +14,7 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
use crate::RecordTypes;
|
use crate::MRecordTypes;
|
||||||
use crate::IRecordType;
|
use crate::IRecordType;
|
||||||
use it_lilo::traits::RecordResolvable;
|
use it_lilo::traits::RecordResolvable;
|
||||||
use it_lilo::traits::RecordResolvableError;
|
use it_lilo::traits::RecordResolvableError;
|
||||||
@ -22,11 +22,11 @@ use it_lilo::traits::RecordResolvableError;
|
|||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
|
|
||||||
pub(crate) struct LiHelper {
|
pub(crate) struct LiHelper {
|
||||||
record_types: Rc<RecordTypes>,
|
record_types: Rc<MRecordTypes>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl LiHelper {
|
impl LiHelper {
|
||||||
pub(crate) fn new(record_types: Rc<RecordTypes>) -> Self {
|
pub(crate) fn new(record_types: Rc<MRecordTypes>) -> Self {
|
||||||
Self { record_types }
|
Self { record_types }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -45,7 +45,7 @@ pub use module::IValue;
|
|||||||
pub use module::IRecordType;
|
pub use module::IRecordType;
|
||||||
pub use module::IFunctionArg;
|
pub use module::IFunctionArg;
|
||||||
pub use module::IType;
|
pub use module::IType;
|
||||||
pub use module::RecordTypes;
|
pub use module::MRecordTypes;
|
||||||
pub use module::MFunctionSignature;
|
pub use module::MFunctionSignature;
|
||||||
pub use module::from_interface_values;
|
pub use module::from_interface_values;
|
||||||
pub use module::to_interface_value;
|
pub use module::to_interface_value;
|
||||||
|
@ -15,8 +15,9 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
use super::wit_prelude::*;
|
use super::wit_prelude::*;
|
||||||
|
use super::MFunctionSignature;
|
||||||
|
use super::MRecordTypes;
|
||||||
use super::{IType, IRecordType, IFunctionArg, IValue, WValue};
|
use super::{IType, IRecordType, IFunctionArg, IValue, WValue};
|
||||||
use super::RecordTypes;
|
|
||||||
use crate::MResult;
|
use crate::MResult;
|
||||||
use crate::MModuleConfig;
|
use crate::MModuleConfig;
|
||||||
|
|
||||||
@ -29,9 +30,6 @@ use wasmer_runtime::compile;
|
|||||||
use wasmer_runtime::ImportObject;
|
use wasmer_runtime::ImportObject;
|
||||||
use wasmer_it::interpreter::Interpreter;
|
use wasmer_it::interpreter::Interpreter;
|
||||||
|
|
||||||
use serde::Serialize;
|
|
||||||
use serde::Deserialize;
|
|
||||||
|
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use std::convert::TryInto;
|
use std::convert::TryInto;
|
||||||
use std::mem::MaybeUninit;
|
use std::mem::MaybeUninit;
|
||||||
@ -48,18 +46,10 @@ pub(super) struct ITModuleFunc {
|
|||||||
pub(super) output_types: Rc<Vec<IType>>,
|
pub(super) output_types: Rc<Vec<IType>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Represent a function type inside Marine module.
|
|
||||||
#[derive(PartialEq, Eq, Debug, Clone, Hash, Serialize, Deserialize)]
|
|
||||||
pub struct MFunctionSignature {
|
|
||||||
pub name: Rc<String>,
|
|
||||||
pub arguments: Rc<Vec<IFunctionArg>>,
|
|
||||||
pub outputs: Rc<Vec<IType>>,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub(super) struct Callable {
|
pub(super) struct Callable {
|
||||||
pub(super) wit_instance: Arc<ITInstance>,
|
pub(super) it_instance: Arc<ITInstance>,
|
||||||
pub(super) wit_module_func: ITModuleFunc,
|
pub(super) it_module_func: ITModuleFunc,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Callable {
|
impl Callable {
|
||||||
@ -67,9 +57,9 @@ impl Callable {
|
|||||||
use wasmer_it::interpreter::stack::Stackable;
|
use wasmer_it::interpreter::stack::Stackable;
|
||||||
|
|
||||||
let result = self
|
let result = self
|
||||||
.wit_module_func
|
.it_module_func
|
||||||
.interpreter
|
.interpreter
|
||||||
.run(args, Arc::make_mut(&mut self.wit_instance))?
|
.run(args, Arc::make_mut(&mut self.it_instance))?
|
||||||
.as_slice()
|
.as_slice()
|
||||||
.to_owned();
|
.to_owned();
|
||||||
|
|
||||||
@ -105,7 +95,7 @@ pub(crate) struct MModule {
|
|||||||
|
|
||||||
// TODO: save refs instead copying of a record types HashMap.
|
// TODO: save refs instead copying of a record types HashMap.
|
||||||
/// Record types used in exported functions as arguments or return values.
|
/// Record types used in exported functions as arguments or return values.
|
||||||
export_record_types: RecordTypes,
|
export_record_types: MRecordTypes,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl MModule {
|
impl MModule {
|
||||||
@ -130,7 +120,7 @@ impl MModule {
|
|||||||
Self::create_import_objects(config, &mit, wit_import_object.clone())?;
|
Self::create_import_objects(config, &mit, wit_import_object.clone())?;
|
||||||
|
|
||||||
let wasmer_instance = wasmer_module.instantiate(&wasi_import_object)?;
|
let wasmer_instance = wasmer_module.instantiate(&wasi_import_object)?;
|
||||||
let wit_instance = unsafe {
|
let it_instance = unsafe {
|
||||||
// get_mut_unchecked here is safe because currently only this modules have reference to
|
// get_mut_unchecked here is safe because currently only this modules have reference to
|
||||||
// it and the environment is single-threaded
|
// it and the environment is single-threaded
|
||||||
*Arc::get_mut_unchecked(&mut wit_instance) =
|
*Arc::get_mut_unchecked(&mut wit_instance) =
|
||||||
@ -138,8 +128,7 @@ impl MModule {
|
|||||||
std::mem::transmute::<_, Arc<ITInstance>>(wit_instance)
|
std::mem::transmute::<_, Arc<ITInstance>>(wit_instance)
|
||||||
};
|
};
|
||||||
|
|
||||||
let export_funcs = Self::instantiate_wit_exports(&wit_instance, &mit)?;
|
let (export_funcs, export_record_types) = Self::instantiate_exports(&it_instance, &mit)?;
|
||||||
let export_record_types = Self::extract_export_record_types(&export_funcs, &wit_instance)?;
|
|
||||||
|
|
||||||
// call _start to populate the WASI state of the module
|
// call _start to populate the WASI state of the module
|
||||||
#[rustfmt::skip]
|
#[rustfmt::skip]
|
||||||
@ -179,12 +168,12 @@ impl MModule {
|
|||||||
.iter()
|
.iter()
|
||||||
.map(|(func_name, func)| MFunctionSignature {
|
.map(|(func_name, func)| MFunctionSignature {
|
||||||
name: func_name.0.clone(),
|
name: func_name.0.clone(),
|
||||||
arguments: func.wit_module_func.arguments.clone(),
|
arguments: func.it_module_func.arguments.clone(),
|
||||||
outputs: func.wit_module_func.output_types.clone(),
|
outputs: func.it_module_func.output_types.clone(),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn export_record_types(&self) -> &RecordTypes {
|
pub(crate) fn export_record_types(&self) -> &MRecordTypes {
|
||||||
&self.export_record_types
|
&self.export_record_types
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -260,54 +249,36 @@ impl MModule {
|
|||||||
Ok((wasi_import_object, host_closures_import_object))
|
Ok((wasi_import_object, host_closures_import_object))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn instantiate_wit_exports(
|
fn instantiate_exports(
|
||||||
wit_instance: &Arc<ITInstance>,
|
it_instance: &Arc<ITInstance>,
|
||||||
wit: &MITInterfaces<'_>,
|
mit: &MITInterfaces<'_>,
|
||||||
) -> MResult<ExportFunctions> {
|
) -> MResult<(ExportFunctions, MRecordTypes)> {
|
||||||
use marine_it_interfaces::ITAstType;
|
let module_interface = marine_module_interface::it_interface::get_interface(mit)?;
|
||||||
|
|
||||||
wit.implementations()
|
let export_funcs = module_interface
|
||||||
.filter_map(|(adapter_function_type, core_function_type)| {
|
.function_signatures
|
||||||
wit.exports_by_type(*core_function_type)
|
.into_iter()
|
||||||
.map(|export_function_name| (adapter_function_type, export_function_name))
|
.map(|sign| {
|
||||||
|
let adapter_instructions = mit.adapter_by_type_r(sign.adapter_function_type)?;
|
||||||
|
|
||||||
|
let interpreter: ITInterpreter = adapter_instructions.clone().try_into()?;
|
||||||
|
let it_module_func = ITModuleFunc {
|
||||||
|
interpreter: Arc::new(interpreter),
|
||||||
|
arguments: sign.arguments.clone(),
|
||||||
|
output_types: sign.outputs.clone(),
|
||||||
|
};
|
||||||
|
|
||||||
|
let shared_string = SharedString(sign.name);
|
||||||
|
let callable = Rc::new(Callable {
|
||||||
|
it_instance: it_instance.clone(),
|
||||||
|
it_module_func,
|
||||||
|
});
|
||||||
|
|
||||||
|
Ok((shared_string, callable))
|
||||||
})
|
})
|
||||||
.map(|(adapter_function_type, export_function_names)| {
|
.collect::<MResult<ExportFunctions>>()?;
|
||||||
export_function_names
|
|
||||||
.iter()
|
|
||||||
.map(move |export_function_name| (*adapter_function_type, export_function_name))
|
|
||||||
})
|
|
||||||
.flatten()
|
|
||||||
.map(|(adapter_function_type, export_function_name)| {
|
|
||||||
let adapter_instructions = wit.adapter_by_type_r(adapter_function_type)?;
|
|
||||||
let wit_type = wit.type_by_idx_r(adapter_function_type)?;
|
|
||||||
|
|
||||||
match wit_type {
|
Ok((export_funcs, module_interface.export_record_types))
|
||||||
ITAstType::Function {
|
|
||||||
arguments,
|
|
||||||
output_types,
|
|
||||||
} => {
|
|
||||||
let interpreter: ITInterpreter = adapter_instructions.clone().try_into()?;
|
|
||||||
let wit_module_func = ITModuleFunc {
|
|
||||||
interpreter: Arc::new(interpreter),
|
|
||||||
arguments: arguments.clone(),
|
|
||||||
output_types: output_types.clone(),
|
|
||||||
};
|
|
||||||
|
|
||||||
let shared_string = SharedString(Rc::new(export_function_name.to_string()));
|
|
||||||
let callable = Rc::new(Callable {
|
|
||||||
wit_instance: wit_instance.clone(),
|
|
||||||
wit_module_func,
|
|
||||||
});
|
|
||||||
|
|
||||||
Ok((shared_string, callable))
|
|
||||||
}
|
|
||||||
_ => Err(MError::IncorrectWIT(format!(
|
|
||||||
"type with idx = {} isn't a function type",
|
|
||||||
adapter_function_type
|
|
||||||
))),
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.collect::<MResult<ExportFunctions>>()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// this function deals only with import functions that have an adaptor implementation
|
// this function deals only with import functions that have an adaptor implementation
|
||||||
@ -442,92 +413,4 @@ impl MModule {
|
|||||||
|
|
||||||
Ok(import_object)
|
Ok(import_object)
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO : move it to a separate crate
|
|
||||||
fn extract_export_record_types(
|
|
||||||
export_funcs: &ExportFunctions,
|
|
||||||
wit_instance: &Arc<ITInstance>,
|
|
||||||
) -> MResult<RecordTypes> {
|
|
||||||
use marine_it_generator::TYPE_RESOLVE_RECURSION_LIMIT;
|
|
||||||
use MError::RecordResolveError;
|
|
||||||
|
|
||||||
fn handle_itype(
|
|
||||||
itype: &IType,
|
|
||||||
wit_instance: &Arc<ITInstance>,
|
|
||||||
export_record_types: &mut RecordTypes,
|
|
||||||
recursion_level: u32,
|
|
||||||
) -> MResult<()> {
|
|
||||||
use wasmer_it::interpreter::wasm::structures::Instance;
|
|
||||||
|
|
||||||
if recursion_level > TYPE_RESOLVE_RECURSION_LIMIT {
|
|
||||||
return Err(RecordResolveError(String::from(
|
|
||||||
"mailformed module: a record contains more recursion level then allowed",
|
|
||||||
)));
|
|
||||||
}
|
|
||||||
|
|
||||||
fn handle_record_type(
|
|
||||||
record_type_id: u64,
|
|
||||||
wit_instance: &Arc<ITInstance>,
|
|
||||||
export_record_types: &mut RecordTypes,
|
|
||||||
recursion_level: u32,
|
|
||||||
) -> MResult<()> {
|
|
||||||
let record_type =
|
|
||||||
wit_instance
|
|
||||||
.wit_record_by_id(record_type_id)
|
|
||||||
.ok_or_else(|| {
|
|
||||||
RecordResolveError(format!(
|
|
||||||
"record type with type id {} not found",
|
|
||||||
record_type_id
|
|
||||||
))
|
|
||||||
})?;
|
|
||||||
export_record_types.insert(record_type_id, record_type.clone());
|
|
||||||
|
|
||||||
for field in record_type.fields.iter() {
|
|
||||||
handle_itype(
|
|
||||||
&field.ty,
|
|
||||||
wit_instance,
|
|
||||||
export_record_types,
|
|
||||||
recursion_level + 1,
|
|
||||||
)?;
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
match itype {
|
|
||||||
IType::Record(record_type_id) => handle_record_type(
|
|
||||||
*record_type_id,
|
|
||||||
wit_instance,
|
|
||||||
export_record_types,
|
|
||||||
recursion_level + 1,
|
|
||||||
)?,
|
|
||||||
IType::Array(array_ty) => handle_itype(
|
|
||||||
array_ty,
|
|
||||||
wit_instance,
|
|
||||||
export_record_types,
|
|
||||||
recursion_level + 1,
|
|
||||||
)?,
|
|
||||||
_ => {}
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
let mut export_record_types = HashMap::new();
|
|
||||||
|
|
||||||
let itypes = export_funcs.iter().flat_map(|(_, ref mut callable)| {
|
|
||||||
callable
|
|
||||||
.wit_module_func
|
|
||||||
.arguments
|
|
||||||
.iter()
|
|
||||||
.map(|arg| &arg.ty)
|
|
||||||
.chain(callable.wit_module_func.output_types.iter())
|
|
||||||
});
|
|
||||||
|
|
||||||
for itype in itypes {
|
|
||||||
handle_itype(itype, wit_instance, &mut export_record_types, 0)?;
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(export_record_types)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -21,16 +21,26 @@ mod wit_function;
|
|||||||
mod wit_instance;
|
mod wit_instance;
|
||||||
mod type_converters;
|
mod type_converters;
|
||||||
|
|
||||||
pub use wit_instance::RecordTypes;
|
pub use wit_instance::MRecordTypes;
|
||||||
|
|
||||||
pub use wasmer_it::IType;
|
pub use wasmer_it::IType;
|
||||||
pub use wasmer_it::IRecordType;
|
pub use wasmer_it::IRecordType;
|
||||||
pub use wasmer_it::ast::FunctionArg as IFunctionArg;
|
pub use wasmer_it::ast::FunctionArg as IFunctionArg;
|
||||||
pub use wasmer_it::IValue;
|
pub use wasmer_it::IValue;
|
||||||
pub use marine_module::MFunctionSignature;
|
|
||||||
pub use wasmer_it::from_interface_values;
|
pub use wasmer_it::from_interface_values;
|
||||||
pub use wasmer_it::to_interface_value;
|
pub use wasmer_it::to_interface_value;
|
||||||
|
|
||||||
|
use serde::Serialize;
|
||||||
|
use serde::Deserialize;
|
||||||
|
use std::rc::Rc;
|
||||||
|
|
||||||
|
/// Represent a function type inside Marine module.
|
||||||
|
#[derive(PartialEq, Eq, Debug, Clone, Hash, Serialize, Deserialize)]
|
||||||
|
pub struct MFunctionSignature {
|
||||||
|
pub name: Rc<String>,
|
||||||
|
pub arguments: Rc<Vec<IFunctionArg>>,
|
||||||
|
pub outputs: Rc<Vec<IType>>,
|
||||||
|
}
|
||||||
|
|
||||||
pub(crate) use marine_module::MModule;
|
pub(crate) use marine_module::MModule;
|
||||||
pub(self) use wasmer_core::types::Type as WType;
|
pub(self) use wasmer_core::types::Type as WType;
|
||||||
pub(self) use wasmer_core::types::Value as WValue;
|
pub(self) use wasmer_core::types::Value as WValue;
|
||||||
|
@ -29,7 +29,7 @@ use std::collections::HashMap;
|
|||||||
use std::cell::Cell;
|
use std::cell::Cell;
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
|
|
||||||
pub type RecordTypes = HashMap<u64, Rc<IRecordType>>;
|
pub type MRecordTypes = HashMap<u64, Rc<IRecordType>>;
|
||||||
|
|
||||||
/// Contains all import and export functions that could be called from IT context by call-core.
|
/// Contains all import and export functions that could be called from IT context by call-core.
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
@ -41,7 +41,7 @@ pub(super) struct ITInstance {
|
|||||||
memories: Vec<WITMemory>,
|
memories: Vec<WITMemory>,
|
||||||
|
|
||||||
/// All record types that instance contains.
|
/// All record types that instance contains.
|
||||||
record_types_by_id: RecordTypes,
|
record_types_by_id: MRecordTypes,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ITInstance {
|
impl ITInstance {
|
||||||
@ -158,7 +158,7 @@ impl ITInstance {
|
|||||||
memories
|
memories
|
||||||
}
|
}
|
||||||
|
|
||||||
fn extract_record_types(wit: &MITInterfaces<'_>) -> RecordTypes {
|
fn extract_record_types(wit: &MITInterfaces<'_>) -> MRecordTypes {
|
||||||
let (record_types_by_id, _) = wit.types().fold(
|
let (record_types_by_id, _) = wit.types().fold(
|
||||||
(HashMap::new(), 0u64),
|
(HashMap::new(), 0u64),
|
||||||
|(mut record_types_by_id, id), ty| {
|
|(mut record_types_by_id, id), ty| {
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "marine"
|
name = "marine"
|
||||||
description = "Fluence Marine command line tool"
|
description = "Fluence Marine command line tool"
|
||||||
version = "0.6.2"
|
version = "0.6.3"
|
||||||
authors = ["Fluence Labs"]
|
authors = ["Fluence Labs"]
|
||||||
repository = "https://github.com/fluencelabs/marine/tools/cli"
|
repository = "https://github.com/fluencelabs/marine/tools/cli"
|
||||||
license = "Apache-2.0"
|
license = "Apache-2.0"
|
||||||
@ -13,11 +13,12 @@ path = "src/main.rs"
|
|||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
marine-it-generator = { path = "../../crates/it-generator", version = "0.5.1" }
|
marine-it-generator = { path = "../../crates/it-generator", version = "0.5.1" }
|
||||||
marine-it-parser = { path = "../../crates/it-parser", version = "0.6.0" }
|
marine-it-parser = { path = "../../crates/it-parser", version = "0.6.1" }
|
||||||
marine-module-info-parser = { path = "../../crates/module-info-parser", version = "0.1.0" }
|
marine-module-info-parser = { path = "../../crates/module-info-parser", version = "0.1.0" }
|
||||||
|
|
||||||
semver = "0.11.0"
|
semver = "0.11.0"
|
||||||
walrus = "0.18.0"
|
walrus = "0.18.0"
|
||||||
|
Inflector = "0.11.4"
|
||||||
|
|
||||||
thiserror = "1.0.24"
|
thiserror = "1.0.24"
|
||||||
anyhow = "1.0.31"
|
anyhow = "1.0.31"
|
||||||
|
@ -23,9 +23,27 @@ pub const DESCRIPTION: &str = env!("CARGO_PKG_DESCRIPTION");
|
|||||||
pub const IN_WASM_PATH: &str = "in-wasm-path";
|
pub const IN_WASM_PATH: &str = "in-wasm-path";
|
||||||
pub const IT_PATH: &str = "it-path";
|
pub const IT_PATH: &str = "it-path";
|
||||||
pub const OUT_WASM_PATH: &str = "out-wasm-path";
|
pub const OUT_WASM_PATH: &str = "out-wasm-path";
|
||||||
|
pub const SERVICE_NAME: &str = "service-name";
|
||||||
|
|
||||||
pub const SDK_VERSION: &str = "sdk-version";
|
pub const SDK_VERSION: &str = "sdk-version";
|
||||||
|
|
||||||
|
pub fn aqua<'a, 'b>() -> App<'a, 'b> {
|
||||||
|
SubCommand::with_name("aqua")
|
||||||
|
.about("Shows data types of provided module in a format suitable for Aqua")
|
||||||
|
.args(&[
|
||||||
|
Arg::with_name(IN_WASM_PATH)
|
||||||
|
.required(true)
|
||||||
|
.takes_value(true)
|
||||||
|
.index(1)
|
||||||
|
.help("a path to a Wasm file"),
|
||||||
|
Arg::with_name(SERVICE_NAME)
|
||||||
|
.required(false)
|
||||||
|
.takes_value(true)
|
||||||
|
.short("s")
|
||||||
|
.help("optional service name"),
|
||||||
|
])
|
||||||
|
}
|
||||||
|
|
||||||
pub fn build<'a, 'b>() -> App<'a, 'b> {
|
pub fn build<'a, 'b>() -> App<'a, 'b> {
|
||||||
SubCommand::with_name("build")
|
SubCommand::with_name("build")
|
||||||
.about("Builds provided Rust project to Wasm")
|
.about("Builds provided Rust project to Wasm")
|
||||||
|
@ -25,13 +25,13 @@
|
|||||||
unreachable_patterns
|
unreachable_patterns
|
||||||
)]
|
)]
|
||||||
|
|
||||||
|
use marine_module_info_parser::manifest;
|
||||||
|
use marine_module_info_parser::sdk_version;
|
||||||
|
|
||||||
mod args;
|
mod args;
|
||||||
mod build;
|
mod build;
|
||||||
mod errors;
|
mod errors;
|
||||||
|
|
||||||
use marine_module_info_parser::manifest;
|
|
||||||
use marine_module_info_parser::sdk_version;
|
|
||||||
|
|
||||||
pub(crate) type CLIResult<T> = std::result::Result<T, crate::errors::CLIError>;
|
pub(crate) type CLIResult<T> = std::result::Result<T, crate::errors::CLIError>;
|
||||||
|
|
||||||
pub fn main() -> Result<(), anyhow::Error> {
|
pub fn main() -> Result<(), anyhow::Error> {
|
||||||
@ -39,6 +39,7 @@ pub fn main() -> Result<(), anyhow::Error> {
|
|||||||
.version(args::VERSION)
|
.version(args::VERSION)
|
||||||
.author(args::AUTHORS)
|
.author(args::AUTHORS)
|
||||||
.setting(clap::AppSettings::ArgRequiredElseHelp)
|
.setting(clap::AppSettings::ArgRequiredElseHelp)
|
||||||
|
.subcommand(args::aqua())
|
||||||
.subcommand(args::build())
|
.subcommand(args::build())
|
||||||
.subcommand(args::set())
|
.subcommand(args::set())
|
||||||
.subcommand(args::show_manifest())
|
.subcommand(args::show_manifest())
|
||||||
@ -47,6 +48,7 @@ pub fn main() -> Result<(), anyhow::Error> {
|
|||||||
let arg_matches = app.get_matches();
|
let arg_matches = app.get_matches();
|
||||||
|
|
||||||
match arg_matches.subcommand() {
|
match arg_matches.subcommand() {
|
||||||
|
("aqua", Some(args)) => aqua(args),
|
||||||
("build", Some(args)) => build(args),
|
("build", Some(args)) => build(args),
|
||||||
("set", Some(args)) => set(args),
|
("set", Some(args)) => set(args),
|
||||||
("it", Some(args)) => it(args),
|
("it", Some(args)) => it(args),
|
||||||
@ -76,6 +78,36 @@ pub fn main() -> Result<(), anyhow::Error> {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn aqua(args: &clap::ArgMatches<'_>) -> Result<(), anyhow::Error> {
|
||||||
|
use inflector::Inflector;
|
||||||
|
|
||||||
|
let wasm_path = args.value_of(args::IN_WASM_PATH).unwrap();
|
||||||
|
let wasm_path = std::path::Path::new(wasm_path);
|
||||||
|
|
||||||
|
let module_interface = marine_it_parser::module_interface(wasm_path)?;
|
||||||
|
for record in module_interface.record_types.iter() {
|
||||||
|
println!("{}", record);
|
||||||
|
}
|
||||||
|
|
||||||
|
match args.value_of(args::SERVICE_NAME) {
|
||||||
|
Some(service_name) => println!("service {}:", service_name.to_title_case()),
|
||||||
|
None => {
|
||||||
|
let service_name = wasm_path
|
||||||
|
.file_stem()
|
||||||
|
.ok_or(anyhow::Error::msg("provided path isn't a path to a file"))?;
|
||||||
|
let service_name = service_name.to_string_lossy().to_title_case();
|
||||||
|
|
||||||
|
println!("service {}:", service_name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for sign in module_interface.function_signatures {
|
||||||
|
println!(" {}", sign);
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
fn build(args: &clap::ArgMatches<'_>) -> Result<(), anyhow::Error> {
|
fn build(args: &clap::ArgMatches<'_>) -> Result<(), anyhow::Error> {
|
||||||
let trailing_args: Vec<&str> = args.values_of("optional").unwrap_or_default().collect();
|
let trailing_args: Vec<&str> = args.values_of("optional").unwrap_or_default().collect();
|
||||||
|
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "mrepl"
|
name = "mrepl"
|
||||||
description = "Fluence Marine REPL intended for testing purposes"
|
description = "Fluence Marine REPL intended for testing purposes"
|
||||||
version = "0.7.2"
|
version = "0.7.3"
|
||||||
authors = ["Fluence Labs"]
|
authors = ["Fluence Labs"]
|
||||||
repository = "https://github.com/fluencelabs/marine/tools/repl"
|
repository = "https://github.com/fluencelabs/marine/tools/repl"
|
||||||
license = "Apache-2.0"
|
license = "Apache-2.0"
|
||||||
@ -12,7 +12,7 @@ name = "mrepl"
|
|||||||
path = "src/main.rs"
|
path = "src/main.rs"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
fluence-app-service = { path = "../../fluence-app-service", version = "0.7.1", features = ["raw-module-api"] }
|
fluence-app-service = { path = "../../fluence-app-service", version = "0.7.2", features = ["raw-module-api"] }
|
||||||
fluence-sdk-main = { version = "0.6.9", features = ["logger"] }
|
fluence-sdk-main = { version = "0.6.9", features = ["logger"] }
|
||||||
|
|
||||||
anyhow = "1.0.31"
|
anyhow = "1.0.31"
|
||||||
|
Loading…
Reference in New Issue
Block a user