mirror of
https://github.com/fluencelabs/marine-rs-sdk-test
synced 2025-03-14 20:20:50 +00:00
Remove marine-rs-sdk code (#1)
This commit is contained in:
parent
60cc4fbd9f
commit
99ff3d2427
@ -15,17 +15,13 @@ jobs:
|
||||
rustup toolchain install nightly-2021-02-27
|
||||
rustup default nightly-2021-02-27
|
||||
rustup override set nightly-2021-02-27
|
||||
rustup target add wasm32-wasi
|
||||
rustup component add rustfmt
|
||||
rustup component add clippy
|
||||
cargo fmt --all -- --check --color always
|
||||
cargo build
|
||||
(cd crates/marine-test-macro-impl; cargo test)
|
||||
|
||||
(cd sdk; cargo build -v --target wasm32-wasi --all-features)
|
||||
(cd sdk; cargo clippy -v --target wasm32-wasi)
|
||||
(cd sdk-test; cargo build)
|
||||
(cd crates/marine-macro-impl; cargo test)
|
||||
|
||||
TARGET=wasm32-wasi cargo test -v --all-features
|
||||
cargo test -v --all-features
|
||||
|
||||
- save_cache:
|
||||
paths:
|
||||
|
6
.github/workflows/publish_release.yml
vendored
6
.github/workflows/publish_release.yml
vendored
@ -46,10 +46,10 @@ jobs:
|
||||
- name: Login to crates.io
|
||||
run: cargo login ${{ secrets.CRATES_IO_TOKEN }}
|
||||
|
||||
- name: Save marine-rs-sdk's crate version to env
|
||||
- name: Save marine-rs-sdk-test's crate version to env
|
||||
run: |
|
||||
set -x
|
||||
PKG_NAME=marine-rs-sdk
|
||||
PKG_NAME=marine-rs-sdk-test
|
||||
VERSION=$(cargo ws list -l | grep "$PKG_NAME\s" | head -n1 | awk '{ print $2 }')
|
||||
echo "VERSION=$VERSION" | tee -a $GITHUB_ENV
|
||||
echo "PKG_NAME=$PKG_NAME" | tee -a $GITHUB_ENV
|
||||
@ -65,7 +65,7 @@ jobs:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
with:
|
||||
tag_name: ${{ env.VERSION }}
|
||||
release_name: Marine Rust SDK ${{ env.VERSION }}
|
||||
release_name: Marine Test Rust SDK ${{ env.VERSION }}
|
||||
body: |
|
||||
- [${{ env.VERSION }} @ crates.io](https://crates.io/crates/${{ env.PKG_NAME }}/${{ env.VERSION }})
|
||||
draft: false
|
||||
|
142
Cargo.lock
generated
142
Cargo.lock
generated
@ -2,15 +2,6 @@
|
||||
# It is not intended for manual editing.
|
||||
version = 3
|
||||
|
||||
[[package]]
|
||||
name = "ansi_term"
|
||||
version = "0.12.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d52a9bb7ec0cf484c551830a7ce27bd20d67eac647e1befb56b0be4ee39a55d2"
|
||||
dependencies = [
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "anyhow"
|
||||
version = "1.0.43"
|
||||
@ -29,17 +20,6 @@ version = "0.5.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "23b62fc65de8e4e7f52534fb52b0f3ed04746ae267519eef2a83941e8085068b"
|
||||
|
||||
[[package]]
|
||||
name = "atty"
|
||||
version = "0.2.14"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8"
|
||||
dependencies = [
|
||||
"hermit-abi",
|
||||
"libc",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "autocfg"
|
||||
version = "1.0.1"
|
||||
@ -145,17 +125,6 @@ version = "0.7.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "475bd7aa7680b4ed8f6bb59745e882bcbaeb39326532bb79ffb1716480d9a274"
|
||||
|
||||
[[package]]
|
||||
name = "colored"
|
||||
version = "1.9.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f4ffc801dacf156c5854b9df4f425a626539c3a6ef7893cc0c5084a23f0b6c59"
|
||||
dependencies = [
|
||||
"atty",
|
||||
"lazy_static",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "constant_time_eq"
|
||||
version = "0.1.5"
|
||||
@ -321,12 +290,6 @@ dependencies = [
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "diff"
|
||||
version = "0.1.12"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0e25ea47919b1560c4e3b7fe0aaab9becf5b84a10325ddf7db0f0ba5e1026499"
|
||||
|
||||
[[package]]
|
||||
name = "digest"
|
||||
version = "0.8.1"
|
||||
@ -407,8 +370,8 @@ dependencies = [
|
||||
"itertools 0.9.0",
|
||||
"log",
|
||||
"marine-module-interface",
|
||||
"marine-rs-sdk 0.6.11",
|
||||
"marine-rs-sdk-main 0.6.10",
|
||||
"marine-rs-sdk",
|
||||
"marine-rs-sdk-main",
|
||||
"marine-runtime",
|
||||
"marine-utils",
|
||||
"safe-transmute",
|
||||
@ -707,7 +670,7 @@ dependencies = [
|
||||
"cargo_toml",
|
||||
"it-lilo",
|
||||
"marine-it-parser",
|
||||
"marine-macro-impl 0.6.10",
|
||||
"marine-macro-impl",
|
||||
"once_cell",
|
||||
"serde",
|
||||
"serde_json",
|
||||
@ -751,14 +714,7 @@ version = "0.6.10"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cd64d5febc6b2ed709a4461c510c1429dc6e4cfcbd6ca0d88463911630acd67b"
|
||||
dependencies = [
|
||||
"marine-macro-impl 0.6.10",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "marine-macro"
|
||||
version = "0.6.13"
|
||||
dependencies = [
|
||||
"marine-macro-impl 0.6.13",
|
||||
"marine-macro-impl",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -775,23 +731,11 @@ dependencies = [
|
||||
"uuid",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "marine-macro-impl"
|
||||
version = "0.6.13"
|
||||
dependencies = [
|
||||
"marine-macro-testing-utils",
|
||||
"pretty_assertions",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"syn",
|
||||
"uuid",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "marine-macro-testing-utils"
|
||||
version = "0.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1c7b78534db4804dab7e439ae93fc2478bb298a97819bbc50002187ef02f2df5"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
@ -806,7 +750,7 @@ checksum = "b4a0951d77c38171d8b2ddcc888d1153a2c4f777b3b7a7dca093a06c69b32d77"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"chrono",
|
||||
"marine-rs-sdk-main 0.6.10",
|
||||
"marine-rs-sdk-main",
|
||||
"semver 0.11.0",
|
||||
"serde",
|
||||
"thiserror",
|
||||
@ -838,23 +782,12 @@ version = "0.6.11"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9157bae63a4bbdd7a29984f6ded08f8ed72991b83ca3bdd59d2f889fa8b8ea02"
|
||||
dependencies = [
|
||||
"marine-macro 0.6.10",
|
||||
"marine-rs-sdk-main 0.6.10",
|
||||
"marine-timestamp-macro 0.6.10",
|
||||
"marine-macro",
|
||||
"marine-rs-sdk-main",
|
||||
"marine-timestamp-macro",
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "marine-rs-sdk"
|
||||
version = "0.6.13"
|
||||
dependencies = [
|
||||
"marine-macro 0.6.13",
|
||||
"marine-rs-sdk-main 0.6.13",
|
||||
"marine-timestamp-macro 0.6.13",
|
||||
"serde",
|
||||
"trybuild",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "marine-rs-sdk-main"
|
||||
version = "0.6.10"
|
||||
@ -862,21 +795,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "95c49b5893d8689589219e07cf67421cc415dc5f219ad0e9c197a9a050b5dd4f"
|
||||
dependencies = [
|
||||
"log",
|
||||
"marine-macro 0.6.10",
|
||||
"marine-macro",
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "marine-rs-sdk-main"
|
||||
version = "0.6.13"
|
||||
dependencies = [
|
||||
"lazy_static",
|
||||
"log",
|
||||
"marine-macro 0.6.13",
|
||||
"serde",
|
||||
"simple_logger",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "marine-rs-sdk-test"
|
||||
version = "0.3.0"
|
||||
@ -957,14 +879,6 @@ dependencies = [
|
||||
"quote",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "marine-timestamp-macro"
|
||||
version = "0.6.13"
|
||||
dependencies = [
|
||||
"chrono",
|
||||
"quote",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "marine-utils"
|
||||
version = "0.2.0"
|
||||
@ -1064,15 +978,6 @@ version = "1.8.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "692fcb63b64b1758029e0a96ee63e049ce8c5948587f2f7208df04625e5f6b56"
|
||||
|
||||
[[package]]
|
||||
name = "output_vt100"
|
||||
version = "0.1.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "53cdc5b785b7a58c5aad8216b3dfa114df64b0b06ae6e1501cef91df2fbdf8f9"
|
||||
dependencies = [
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "page_size"
|
||||
version = "0.4.2"
|
||||
@ -1128,18 +1033,6 @@ dependencies = [
|
||||
"ucd-trie",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pretty_assertions"
|
||||
version = "0.7.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1cab0e7c02cf376875e9335e0ba1da535775beb5450d21e1dffca068818ed98b"
|
||||
dependencies = [
|
||||
"ansi_term",
|
||||
"ctor",
|
||||
"diff",
|
||||
"output_vt100",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro-error"
|
||||
version = "1.0.4"
|
||||
@ -1344,19 +1237,6 @@ dependencies = [
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "simple_logger"
|
||||
version = "1.13.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b7de33c687404ec3045d4a0d437580455257c0436f858d702f244e7d652f9f07"
|
||||
dependencies = [
|
||||
"atty",
|
||||
"chrono",
|
||||
"colored",
|
||||
"log",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "smallvec"
|
||||
version = "1.6.1"
|
||||
|
42
Cargo.toml
42
Cargo.toml
@ -1,11 +1,35 @@
|
||||
[package]
|
||||
name = "marine-rs-sdk-test"
|
||||
version = "0.3.0" # remember to update html_root_url
|
||||
description = "Backend SDK that allows testing modules for the Marine runtime"
|
||||
documentation = "https://docs.rs/marine-rs-sdk-test"
|
||||
repository = "https://github.com/fluencelabs/marine-rs-sdk-test"
|
||||
authors = ["Fluence Labs"]
|
||||
keywords = ["fluence", "marine", "sdk", "webassembly", "test"]
|
||||
categories = ["api-bindings", "wasm", "development-tools::testing"]
|
||||
license = "Apache-2.0"
|
||||
edition = "2018"
|
||||
|
||||
[package.metadata.docs.rs]
|
||||
all-features = true
|
||||
|
||||
[lib]
|
||||
path = "src/lib.rs"
|
||||
doctest = false
|
||||
|
||||
[dev-dependencies]
|
||||
trybuild = "1.0"
|
||||
|
||||
[dependencies]
|
||||
marine-test-macro = { path = "crates/marine-test-macro", version = "=0.3.0" }
|
||||
fluence-app-service = { version = "0.9.0", features = ["raw-module-api"] }
|
||||
|
||||
serde = { version = "1.0.118", features = ["derive"] }
|
||||
serde_json = "1.0.64"
|
||||
uuid = { version = "0.8.2", features = ["v4"] }
|
||||
|
||||
[workspace]
|
||||
members = [
|
||||
"crates/main",
|
||||
"crates/marine-macro",
|
||||
"crates/marine-macro-impl",
|
||||
"crates/marine-test-macro",
|
||||
"crates/marine-test-macro-impl",
|
||||
"crates/timestamp-macro",
|
||||
"sdk",
|
||||
"sdk-test"
|
||||
]
|
||||
"crates/marine-test-macro",
|
||||
"crates/marine-test-macro-impl",
|
||||
]
|
@ -1,5 +1,4 @@
|
||||

|
||||
[](https://crates.io/crates/marine-rs-sdk-test)
|
||||
|
||||
## Marine Rust SDK
|
||||
|
||||
This SDK is intended to run backend application on the Fluence network with [Marine](https://github.com/fluencelabs/marine) runtime. More information about usage and some internals could found in [docs](https://doc.fluence.dev/docs/knowledge_knowledge/knowledge_aquamarine/marine/marine-rs-sdk).
|
||||
## Marine Test Rust SDK
|
||||
This SDK is intended to test application built with [Marine Rust SDK](https://github.com/fluencelabs/marine-rs-sdk). More information about usage and some internals could found in [docs](https://doc.fluence.dev/docs/knowledge_knowledge/knowledge_aquamarine/marine/marine-rs-sdk).
|
||||
|
@ -1,21 +0,0 @@
|
||||
[package]
|
||||
name = "marine-macro-testing-utils"
|
||||
version = "0.1.0"
|
||||
edition = "2018"
|
||||
description = "Some functions for testing procedural macros"
|
||||
documentation = "https://docs.rs/fluence/marine-macro-testing-utils"
|
||||
repository = "https://github.com/fluencelabs/marine-rs-sdk/tree/master/crates/marine-macro-testing-utils"
|
||||
authors = ["Fluence Labs"]
|
||||
keywords = ["fluence", "marine", "sdk", "webassembly"]
|
||||
categories = ["development-tools::testing"]
|
||||
license = "Apache-2.0"
|
||||
|
||||
[lib]
|
||||
path = "src/lib.rs"
|
||||
crate-type = ["rlib"]
|
||||
doctest = false
|
||||
|
||||
[dependencies]
|
||||
quote = "1.0.9"
|
||||
proc-macro2 = "1.0.26"
|
||||
syn = { version = '1.0.64', features = ['full'] }
|
@ -1,44 +0,0 @@
|
||||
/*
|
||||
* 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 std::io::Read;
|
||||
use std::path::Path;
|
||||
|
||||
pub fn stream_from_file<P>(path: P) -> proc_macro2::TokenStream
|
||||
where
|
||||
P: AsRef<Path>,
|
||||
{
|
||||
let items = items_from_file(path);
|
||||
quote::quote! { #(#items)* }
|
||||
}
|
||||
|
||||
pub fn items_from_file<P>(path: P) -> Vec<syn::Item>
|
||||
where
|
||||
P: AsRef<Path>,
|
||||
{
|
||||
let mut file = std::fs::File::open(path).expect("Unable to open file");
|
||||
|
||||
let mut src = String::new();
|
||||
file.read_to_string(&mut src).expect("Unable to read file");
|
||||
|
||||
let token_file = syn::parse_file(&src).expect("Unable to parse file");
|
||||
token_file.items
|
||||
}
|
||||
|
||||
pub fn to_syn_item(token_stream: proc_macro2::TokenStream) -> Vec<syn::Item> {
|
||||
let file: syn::File = syn::parse2(token_stream).expect("token stream should be parsed");
|
||||
file.items
|
||||
}
|
@ -1,36 +0,0 @@
|
||||
[package]
|
||||
name = "marine-rs-sdk-main"
|
||||
version = "0.6.13" # remember to update html_root_url
|
||||
edition = "2018"
|
||||
description = "Contains logger, allocators and several other modules for marine-rs-sdk"
|
||||
documentation = "https://docs.rs/marine-rs-sdk-main"
|
||||
repository = "https://github.com/fluencelabs/marine-rs-sdk/tree/master/crates/main"
|
||||
authors = ["Fluence Labs"]
|
||||
keywords = ["fluence", "marine", "sdk", "webassembly"]
|
||||
categories = ["api-bindings", "wasm"]
|
||||
license = "Apache-2.0"
|
||||
|
||||
[package.metadata.docs.rs]
|
||||
all-features = true
|
||||
|
||||
[lib]
|
||||
path = "src/lib.rs"
|
||||
crate-type = ["rlib"]
|
||||
doctest = false
|
||||
|
||||
[dependencies]
|
||||
marine-macro = { path = "../marine-macro", version = "=0.6.13" }
|
||||
|
||||
log = { version = "0.4.8", features = ["std"] }
|
||||
serde = "1.0.118"
|
||||
|
||||
[dev-dependencies]
|
||||
simple_logger = "1.6.0" # used in doc test
|
||||
lazy_static = "1.4.0" # used in doc test
|
||||
|
||||
[features]
|
||||
# Print some internal logs by log_utf8_string
|
||||
debug = []
|
||||
|
||||
# Enable logger (this will cause log_utf8_string to appear in imports)
|
||||
logger = []
|
@ -1,60 +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.
|
||||
*/
|
||||
|
||||
/// Allocates memory area of specified size and type and returns its address.
|
||||
/// The allocated memory region is intended to be use as a Vec.
|
||||
#[no_mangle]
|
||||
pub unsafe fn allocate(elem_count: usize, elem_ty: usize) -> usize {
|
||||
if elem_count == 0 {
|
||||
// otherwise 1 would be returned due to the internals of Vec in Rust
|
||||
return 0;
|
||||
}
|
||||
|
||||
let allocated_mem = allocate_impl(elem_count, elem_ty);
|
||||
crate::debug_log!(format!(
|
||||
"sdk.allocate: {} {} -> {}\n",
|
||||
elem_count, elem_ty, allocated_mem
|
||||
));
|
||||
|
||||
allocated_mem
|
||||
}
|
||||
|
||||
fn allocate_impl(elem_count: usize, elem_ty: usize) -> usize {
|
||||
match elem_ty {
|
||||
0 => allocate_vec::<u8>(elem_count), // for booleans
|
||||
1 => allocate_vec::<u8>(elem_count),
|
||||
2 => allocate_vec::<u16>(elem_count),
|
||||
3 => allocate_vec::<u32>(elem_count),
|
||||
4 => allocate_vec::<u64>(elem_count),
|
||||
5 => allocate_vec::<i8>(elem_count),
|
||||
6 => allocate_vec::<i16>(elem_count),
|
||||
7 => allocate_vec::<i32>(elem_count),
|
||||
8 => allocate_vec::<i64>(elem_count),
|
||||
9 => allocate_vec::<f32>(elem_count),
|
||||
10 => allocate_vec::<f64>(elem_count),
|
||||
_ => 0,
|
||||
}
|
||||
}
|
||||
|
||||
fn allocate_vec<T>(count: usize) -> usize {
|
||||
// TODO: handle OOM
|
||||
// This allocation scheme with vectors is needed to deal with internal Vec layout
|
||||
let vec = Vec::<T>::with_capacity(count);
|
||||
let offset = vec.as_ptr() as usize;
|
||||
std::mem::forget(vec);
|
||||
|
||||
offset
|
||||
}
|
@ -1,72 +0,0 @@
|
||||
/*
|
||||
* Copyright 2018 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.
|
||||
*/
|
||||
|
||||
//! The main part of Fluence backend SDK. Contains `export_allocator`, `logger` and `result`
|
||||
//! modules.
|
||||
|
||||
#![allow(clippy::missing_safety_doc)]
|
||||
#![allow(clippy::needless_doctest_main)]
|
||||
#![doc(html_root_url = "https://docs.rs/marine-rs-sdk-main/0.6.13")]
|
||||
#![deny(
|
||||
dead_code,
|
||||
nonstandard_style,
|
||||
unused_imports,
|
||||
unused_mut,
|
||||
unused_variables,
|
||||
unused_unsafe,
|
||||
unreachable_patterns
|
||||
)]
|
||||
#![warn(rust_2018_idioms)]
|
||||
|
||||
mod export_allocator;
|
||||
#[cfg(any(feature = "debug", feature = "logger"))]
|
||||
mod logger;
|
||||
mod module_manifest;
|
||||
mod result;
|
||||
mod sdk_version_embedder;
|
||||
|
||||
pub use export_allocator::allocate;
|
||||
|
||||
#[cfg(feature = "logger")]
|
||||
pub use logger::WasmLoggerBuilder;
|
||||
#[cfg(feature = "logger")]
|
||||
pub use logger::TargetMap;
|
||||
#[cfg(feature = "logger")]
|
||||
pub use logger::WASM_LOG_ENV_NAME;
|
||||
|
||||
pub use result::get_result_ptr;
|
||||
pub use result::get_result_size;
|
||||
pub use result::set_result_ptr;
|
||||
pub use result::set_result_size;
|
||||
pub use result::release_objects;
|
||||
pub use result::add_object_to_release;
|
||||
|
||||
pub use module_manifest::MANIFEST_SECTION_NAME;
|
||||
pub use sdk_version_embedder::VERSION_SECTION_NAME;
|
||||
|
||||
// these logs will be printed only if debug feature is enabled
|
||||
#[macro_export]
|
||||
macro_rules! debug_log {
|
||||
($msg_generator:expr) => {
|
||||
#[cfg(feature = "debug")]
|
||||
{
|
||||
let level = log::Level::Info as i32;
|
||||
let target = 0i32;
|
||||
let msg = $msg_generator;
|
||||
crate::logger::log_utf8_string(level, target, msg.as_ptr() as i32, msg.len() as i32);
|
||||
}
|
||||
};
|
||||
}
|
@ -1,349 +0,0 @@
|
||||
/*
|
||||
* Copyright 2018 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.
|
||||
*/
|
||||
|
||||
//! This module allows log messages from the Wasm side. It is implemented as a logging facade for
|
||||
//! crate [`log`].
|
||||
//!
|
||||
//! # Examples
|
||||
//!
|
||||
//! This example initializes [`WasmLogger`] with setting log level.
|
||||
//! Macros from crate [`log`] are used as a logging facade.
|
||||
//!
|
||||
//! ```ignore
|
||||
//! use marine_rs_sdk::logger;
|
||||
//! use log::{error, trace};
|
||||
//! use simple_logger;
|
||||
//!
|
||||
//! fn main() {
|
||||
//! logger::WasmLoggerBuilder::new()
|
||||
//! .with_log_leve(log::Level::Info)
|
||||
//! .build()
|
||||
//! .unwrap();
|
||||
//!
|
||||
//! error!("This message will be logged.");
|
||||
//! trace!("This message will not be logged.");
|
||||
//! }
|
||||
//!
|
||||
//! ```
|
||||
//!
|
||||
//! [`WasmLogger`]: struct.WasmLogger.html
|
||||
//! [`log`]: https://docs.rs/log
|
||||
|
||||
use log::LevelFilter;
|
||||
use std::collections::HashMap;
|
||||
|
||||
/// By default, logger will be initialized with log level from this environment variable.
|
||||
pub const WASM_LOG_ENV_NAME: &str = "WASM_LOG";
|
||||
|
||||
/// If WASM_LOG_ENV isn't set, then this level will be used as the default.
|
||||
const WASM_DEFAULT_LOG_LEVEL: LevelFilter = LevelFilter::Info;
|
||||
|
||||
/// Mapping from logging namespace string to its bitmask.
|
||||
/// TODO: use i64 for bitmask when wasmpack/bindgen issue with i64 is fixed.
|
||||
/// Currently, i64 doesn't work on some versions of V8 because log_utf8_string function
|
||||
/// isn't marked as #[wasm_bindgen]. In result, TS/JS code throws 'TypeError' on every log.
|
||||
pub type TargetMap = HashMap<&'static str, i32>;
|
||||
|
||||
/// This structure is used to save information about particular log level for a particular module.
|
||||
#[derive(Debug)]
|
||||
struct LogDirective {
|
||||
module_name: String,
|
||||
level: LevelFilter,
|
||||
}
|
||||
|
||||
impl LogDirective {
|
||||
pub fn new(module_name: String, level: LevelFilter) -> Self {
|
||||
Self { module_name, level }
|
||||
}
|
||||
}
|
||||
|
||||
/// The Wasm Logger.
|
||||
///
|
||||
/// This struct implements the [`Log`] trait from the [`log`] crate, which allows it to act as a
|
||||
/// logger.
|
||||
///
|
||||
/// Builder pattern is used here for logger initialization. Please be aware that build must be called
|
||||
/// to set the logger up.
|
||||
///
|
||||
/// [log-crate-url]: https://docs.rs/log/
|
||||
/// [`Log`]: https://docs.rs/log/0.4.11/log/trait.Log.html
|
||||
struct WasmLogger {
|
||||
target_map: TargetMap,
|
||||
modules_directives: Vec<LogDirective>,
|
||||
default_log_level: LevelFilter,
|
||||
}
|
||||
|
||||
/// The Wasm logger builder.
|
||||
///
|
||||
/// Build logger for the Fluence network, allows specifying target map and log level while building.
|
||||
pub struct WasmLoggerBuilder {
|
||||
wasm_logger: WasmLogger,
|
||||
}
|
||||
|
||||
impl WasmLoggerBuilder {
|
||||
/// Initializes a builder of the global logger. Set log level based on the WASM_LOG environment variable if it set,
|
||||
/// or [[WASM_DEFAULT_LOG_LEVEL]] otherwise. It is an initial method in this builder chain, please note,
|
||||
/// that logger wouldn't work without subsequent build() call.
|
||||
pub fn new() -> Self {
|
||||
use std::str::FromStr;
|
||||
|
||||
let default_log_level = std::env::var(WASM_LOG_ENV_NAME)
|
||||
.map_or(WASM_DEFAULT_LOG_LEVEL, |log_level_str| {
|
||||
LevelFilter::from_str(&log_level_str).unwrap_or(WASM_DEFAULT_LOG_LEVEL)
|
||||
});
|
||||
|
||||
let wasm_logger = WasmLogger {
|
||||
target_map: HashMap::new(),
|
||||
modules_directives: Vec::new(),
|
||||
default_log_level,
|
||||
};
|
||||
|
||||
Self { wasm_logger }
|
||||
}
|
||||
|
||||
/// Set the log level.
|
||||
pub fn with_log_level(mut self, level: LevelFilter) -> Self {
|
||||
self.wasm_logger.default_log_level = level;
|
||||
self
|
||||
}
|
||||
|
||||
/// Set mapping between logging targets and numbers.
|
||||
/// Used to efficiently enable & disable logs per target on the host.
|
||||
pub fn with_target_map(mut self, map: TargetMap) -> Self {
|
||||
self.wasm_logger.target_map = map;
|
||||
self
|
||||
}
|
||||
|
||||
pub fn filter(mut self, module_name: impl Into<String>, level: LevelFilter) -> Self {
|
||||
let module_name = module_name.into();
|
||||
let log_directive = LogDirective::new(module_name, level);
|
||||
|
||||
self.wasm_logger.modules_directives.push(log_directive);
|
||||
self
|
||||
}
|
||||
|
||||
/// Build the real logger.
|
||||
///
|
||||
/// This method is a last one in this builder chain and MUST be called to set logger up.
|
||||
/// Returns a error
|
||||
///
|
||||
/// ```ignore
|
||||
/// # use marine_rs_sdk::logger;
|
||||
/// # use log::info;
|
||||
/// #
|
||||
/// # fn main() {
|
||||
/// logger::WasmLoggerBuilder::new()
|
||||
/// .with_log_level(log::LevelFilter::Trace)
|
||||
/// .with_target_map(<_>::default())
|
||||
/// .build()
|
||||
/// .unwrap();
|
||||
/// # }
|
||||
/// ```
|
||||
pub fn build(mut self) -> Result<(), log::SetLoggerError> {
|
||||
let max_level = self.max_log_level();
|
||||
self.sort_directives();
|
||||
|
||||
let Self { wasm_logger } = self;
|
||||
|
||||
log::set_boxed_logger(Box::new(wasm_logger))?;
|
||||
log::set_max_level(max_level);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Sort supplied directive ny length of module names to make more efficient lookup at runtime.
|
||||
fn sort_directives(&mut self) {
|
||||
self.wasm_logger.modules_directives.sort_by(|l, r| {
|
||||
let llen = l.module_name.len();
|
||||
let rlen = r.module_name.len();
|
||||
|
||||
rlen.cmp(&llen)
|
||||
});
|
||||
}
|
||||
|
||||
fn max_log_level(&self) -> log::LevelFilter {
|
||||
let default_level = self.wasm_logger.default_log_level;
|
||||
let max_filter_level = self
|
||||
.wasm_logger
|
||||
.modules_directives
|
||||
.iter()
|
||||
.map(|d| d.level)
|
||||
.max()
|
||||
.unwrap_or(LevelFilter::Off);
|
||||
|
||||
std::cmp::max(default_level, max_filter_level)
|
||||
}
|
||||
}
|
||||
|
||||
impl log::Log for WasmLogger {
|
||||
#[inline]
|
||||
fn enabled(&self, metadata: &log::Metadata<'_>) -> bool {
|
||||
let target = metadata.target();
|
||||
|
||||
for directive in self.modules_directives.iter() {
|
||||
if target.starts_with(&directive.module_name) {
|
||||
return metadata.level() <= directive.level;
|
||||
}
|
||||
}
|
||||
|
||||
metadata.level() <= self.default_log_level
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn log(&self, record: &log::Record<'_>) {
|
||||
if !self.enabled(record.metadata()) {
|
||||
return;
|
||||
}
|
||||
|
||||
let level = record.metadata().level() as i32;
|
||||
let default_target = 0;
|
||||
let target = *self
|
||||
.target_map
|
||||
.get(record.metadata().target())
|
||||
.unwrap_or(&default_target);
|
||||
let msg = record.args().to_string();
|
||||
|
||||
log_utf8_string(level, target, msg.as_ptr() as _, msg.len() as _);
|
||||
}
|
||||
|
||||
// in our case flushing is performed by a host itself
|
||||
#[inline]
|
||||
fn flush(&self) {}
|
||||
}
|
||||
|
||||
#[cfg(target_arch = "wasm32")]
|
||||
pub fn log_utf8_string(level: i32, target: i32, msg_ptr: i32, msg_size: i32) {
|
||||
unsafe { log_utf8_string_impl(level, target, msg_ptr, msg_size) };
|
||||
}
|
||||
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
pub fn log_utf8_string(level: i32, target: i32, msg_ptr: i32, msg_size: i32) {
|
||||
use std::str::from_utf8_unchecked;
|
||||
use core::slice::from_raw_parts;
|
||||
|
||||
let level = level_from_i32(level);
|
||||
let msg = unsafe { from_utf8_unchecked(from_raw_parts(msg_ptr as _, msg_size as _)) };
|
||||
println!("[{}] {} {}", level, target, msg);
|
||||
}
|
||||
|
||||
/// TODO: mark `log_utf8_string_impl` as #[wasm_bindgen], so it is polyfilled by bindgen
|
||||
/// log_utf8_string should be provided directly by a host.
|
||||
#[cfg(target_arch = "wasm32")]
|
||||
#[link(wasm_import_module = "host")]
|
||||
extern "C" {
|
||||
// Writes a byte string of size bytes that starts from ptr to a logger
|
||||
#[link_name = "log_utf8_string"]
|
||||
fn log_utf8_string_impl(level: i32, target: i32, msg_ptr: i32, msg_size: i32);
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
fn level_from_i32(level: i32) -> log::Level {
|
||||
match level {
|
||||
1 => log::Level::Error,
|
||||
2 => log::Level::Warn,
|
||||
3 => log::Level::Info,
|
||||
4 => log::Level::Debug,
|
||||
5 => log::Level::Trace,
|
||||
_ => log::Level::max(),
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::WasmLogger;
|
||||
use super::LogDirective;
|
||||
use super::WasmLoggerBuilder;
|
||||
use log::LevelFilter;
|
||||
use log::Log;
|
||||
|
||||
use std::collections::HashMap;
|
||||
|
||||
fn create_metadata(module_name: &str, level: log::Level) -> log::Metadata<'_> {
|
||||
log::MetadataBuilder::new()
|
||||
.level(level)
|
||||
.target(module_name)
|
||||
.build()
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn enabled_by_module_name() {
|
||||
let module_1_name = "module_1";
|
||||
let module_2_name = "module_2";
|
||||
|
||||
let modules_directives = vec![
|
||||
LogDirective::new(module_1_name.to_string(), LevelFilter::Info),
|
||||
LogDirective::new(module_2_name.to_string(), LevelFilter::Warn),
|
||||
];
|
||||
|
||||
let logger = WasmLogger {
|
||||
target_map: HashMap::new(),
|
||||
modules_directives,
|
||||
default_log_level: LevelFilter::Error,
|
||||
};
|
||||
|
||||
let allowed_metadata = create_metadata(module_1_name, log::Level::Info);
|
||||
assert!(logger.enabled(&allowed_metadata));
|
||||
|
||||
let allowed_metadata = create_metadata(module_1_name, log::Level::Warn);
|
||||
assert!(logger.enabled(&allowed_metadata));
|
||||
|
||||
let allowed_metadata = create_metadata(module_2_name, log::Level::Warn);
|
||||
assert!(logger.enabled(&allowed_metadata));
|
||||
|
||||
let not_allowed_metadata = create_metadata(module_1_name, log::Level::Debug);
|
||||
assert!(!logger.enabled(¬_allowed_metadata));
|
||||
|
||||
let not_allowed_metadata = create_metadata(module_2_name, log::Level::Info);
|
||||
assert!(!logger.enabled(¬_allowed_metadata));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn default_log_level() {
|
||||
let modules_directives = vec![LogDirective::new("module_1".to_string(), LevelFilter::Info)];
|
||||
|
||||
let logger = WasmLogger {
|
||||
target_map: HashMap::new(),
|
||||
modules_directives,
|
||||
default_log_level: LevelFilter::Warn,
|
||||
};
|
||||
|
||||
let module_name = "some_module";
|
||||
let allowed_metadata = create_metadata(module_name, log::Level::Warn);
|
||||
assert!(logger.enabled(&allowed_metadata));
|
||||
|
||||
let not_allowed_metadata = create_metadata(module_name, log::Level::Info);
|
||||
assert!(!logger.enabled(¬_allowed_metadata));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn longest_directive_first() {
|
||||
let module_1_name = "module_1";
|
||||
let module_2_name = "module_1::some_name::func_name";
|
||||
|
||||
WasmLoggerBuilder::new()
|
||||
.filter(module_1_name, LevelFilter::Info)
|
||||
.filter(module_2_name, LevelFilter::Warn)
|
||||
.build()
|
||||
.unwrap();
|
||||
|
||||
let logger = log::logger();
|
||||
|
||||
let allowed_metadata = create_metadata(module_1_name, log::Level::Info);
|
||||
assert!(logger.enabled(&allowed_metadata));
|
||||
|
||||
let not_allowed_metadata = create_metadata(module_2_name, log::Level::Info);
|
||||
assert!(!logger.enabled(¬_allowed_metadata));
|
||||
}
|
||||
}
|
@ -1,93 +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.
|
||||
*/
|
||||
|
||||
// TODO: avoid duplication with the link_section when key-value attributes become stable
|
||||
pub const MANIFEST_SECTION_NAME: &str = "__fluence_wasm_module_manifest";
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! module_manifest {
|
||||
($authors:expr, $version:expr, $description:expr, $repository:expr) => {
|
||||
marine_rs_sdk::internal::build_timestamp!();
|
||||
|
||||
const __M_SDK_AUTHORS_SIZE: usize = $authors.as_bytes().len();
|
||||
const __M_SDK_VERSION_SIZE: usize = $version.as_bytes().len();
|
||||
const __M_SDK_DESCRIPTION_SIZE: usize = $description.as_bytes().len();
|
||||
const __M_SDK_REPOSITORY_SIZE: usize = $repository.as_bytes().len();
|
||||
const __M_SDK_BUILD_TIME_SIZE: usize = __M_SDK_BUILD_TIME.as_bytes().len();
|
||||
const __M_SDK_FIELD_PREFIX_SIZE: usize = std::mem::size_of::<u64>();
|
||||
|
||||
const __M_MANIFEST_SIZE: usize = __M_SDK_AUTHORS_SIZE
|
||||
+ __M_SDK_VERSION_SIZE
|
||||
+ __M_SDK_DESCRIPTION_SIZE
|
||||
+ __M_SDK_REPOSITORY_SIZE
|
||||
+ __M_SDK_BUILD_TIME_SIZE
|
||||
+ __M_SDK_FIELD_PREFIX_SIZE * 5;
|
||||
|
||||
const fn __m_sdk_append_data(
|
||||
mut manifest: [u8; __M_MANIFEST_SIZE],
|
||||
data: &'static str,
|
||||
offset: usize,
|
||||
) -> ([u8; __M_MANIFEST_SIZE], usize) {
|
||||
let data_as_bytes = data.as_bytes();
|
||||
let data_len = data_as_bytes.len();
|
||||
|
||||
// write data prefix with data size in LE
|
||||
let data_len_u64 = data_len as u64;
|
||||
let data_len_le_bytes = data_len_u64.to_le_bytes();
|
||||
let mut byte_idx = 0;
|
||||
while byte_idx < __M_SDK_FIELD_PREFIX_SIZE {
|
||||
manifest[offset + byte_idx] = data_len_le_bytes[byte_idx];
|
||||
byte_idx += 1;
|
||||
}
|
||||
|
||||
// write data
|
||||
let mut byte_idx = 0;
|
||||
while byte_idx < data_len {
|
||||
manifest[__M_SDK_FIELD_PREFIX_SIZE + offset + byte_idx] = data_as_bytes[byte_idx];
|
||||
byte_idx += 1;
|
||||
}
|
||||
|
||||
(manifest, offset + __M_SDK_FIELD_PREFIX_SIZE + data_len)
|
||||
}
|
||||
|
||||
const fn generate_manifest() -> [u8; __M_MANIFEST_SIZE] {
|
||||
let manifest: [u8; __M_MANIFEST_SIZE] = [0; __M_MANIFEST_SIZE];
|
||||
|
||||
let offset = 0;
|
||||
let (manifest, offset) = __m_sdk_append_data(manifest, $authors, offset);
|
||||
let (manifest, offset) = __m_sdk_append_data(manifest, $version, offset);
|
||||
let (manifest, offset) = __m_sdk_append_data(manifest, $description, offset);
|
||||
let (manifest, offset) = __m_sdk_append_data(manifest, $repository, offset);
|
||||
let (manifest, _) = __m_sdk_append_data(manifest, __M_SDK_BUILD_TIME, offset);
|
||||
|
||||
manifest
|
||||
}
|
||||
|
||||
#[cfg(target_arch = "wasm32")]
|
||||
#[link_section = "__fluence_wasm_module_manifest"]
|
||||
#[doc(hidden)]
|
||||
pub static __M_WASM_MODULE_MANIFEST: [u8; __M_MANIFEST_SIZE] = generate_manifest();
|
||||
};
|
||||
|
||||
() => {
|
||||
module_manifest!(
|
||||
env!("CARGO_PKG_AUTHORS"),
|
||||
env!("CARGO_PKG_VERSION"),
|
||||
env!("CARGO_PKG_DESCRIPTION"),
|
||||
env!("CARGO_PKG_REPOSITORY")
|
||||
);
|
||||
};
|
||||
}
|
@ -1,79 +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.
|
||||
*/
|
||||
|
||||
//! Contains ad-hoc implementations of returning complex data types from function calls
|
||||
//! by two global variables that contain pointer and size. Will be refactored after multi-value
|
||||
//! support in Wasmer.
|
||||
|
||||
use std::sync::atomic::AtomicUsize;
|
||||
use std::cell::RefCell;
|
||||
use std::any::Any;
|
||||
|
||||
static mut RESULT_PTR: AtomicUsize = AtomicUsize::new(0);
|
||||
static mut RESULT_SIZE: AtomicUsize = AtomicUsize::new(0);
|
||||
|
||||
thread_local!(static OBJECTS_TO_RELEASE: RefCell<Vec<Box<dyn Any>>> = RefCell::new(Vec::new()));
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe fn get_result_ptr() -> usize {
|
||||
crate::debug_log!(format!(
|
||||
"sdk.get_result_ptr, returns {}\n",
|
||||
*RESULT_PTR.get_mut()
|
||||
));
|
||||
|
||||
*RESULT_PTR.get_mut()
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe fn get_result_size() -> usize {
|
||||
crate::debug_log!(format!(
|
||||
"sdk.get_result_size, returns {}\n",
|
||||
*RESULT_SIZE.get_mut()
|
||||
));
|
||||
|
||||
*RESULT_SIZE.get_mut()
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe fn set_result_ptr(ptr: usize) {
|
||||
crate::debug_log!(format!("sdk.set_result_ptr: {}\n", ptr));
|
||||
|
||||
*RESULT_PTR.get_mut() = ptr;
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe fn set_result_size(size: usize) {
|
||||
crate::debug_log!(format!("sdk.set_result_size: {}\n", size));
|
||||
|
||||
*RESULT_SIZE.get_mut() = size;
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe fn release_objects() {
|
||||
OBJECTS_TO_RELEASE.with(|objects| {
|
||||
let mut objects = objects.borrow_mut();
|
||||
while let Some(object) = objects.pop() {
|
||||
drop(object);
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
pub fn add_object_to_release(object: Box<dyn Any>) {
|
||||
OBJECTS_TO_RELEASE.with(|objects| {
|
||||
let mut objects = objects.borrow_mut();
|
||||
objects.push(object);
|
||||
});
|
||||
}
|
@ -1,41 +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.
|
||||
*/
|
||||
|
||||
#![allow(dead_code)]
|
||||
|
||||
const PKG_VERSION: &str = env!("CARGO_PKG_VERSION");
|
||||
const VERSION_SIZE: usize = PKG_VERSION.len();
|
||||
|
||||
const fn sdk_version() -> [u8; VERSION_SIZE] {
|
||||
let version_as_slice = PKG_VERSION.as_bytes();
|
||||
|
||||
let mut version_as_array: [u8; VERSION_SIZE] = [0; VERSION_SIZE];
|
||||
let mut byte_id = 0;
|
||||
while byte_id < VERSION_SIZE {
|
||||
version_as_array[byte_id] = version_as_slice[byte_id];
|
||||
byte_id += 1;
|
||||
}
|
||||
|
||||
version_as_array
|
||||
}
|
||||
|
||||
// TODO: avoid duplication with the link_section when key-value attributes become stable
|
||||
pub const VERSION_SECTION_NAME: &str = "__fluence_sdk_version";
|
||||
|
||||
#[cfg(target_arch = "wasm32")]
|
||||
#[link_section = "__fluence_sdk_version"]
|
||||
#[doc(hidden)]
|
||||
pub static __M_SDK_VERSION: [u8; VERSION_SIZE] = sdk_version();
|
@ -1,26 +0,0 @@
|
||||
[package]
|
||||
name = "marine-macro-impl"
|
||||
version = "0.6.13" # remember to update html_root_url
|
||||
edition = "2018"
|
||||
description = "Implementation of the `#[marine]` macro"
|
||||
documentation = "https://docs.rs/fluence/marine-macro-impl"
|
||||
repository = "https://github.com/fluencelabs/marine-rs-sdk/tree/master/crates/marine-macro-impl"
|
||||
authors = ["Fluence Labs"]
|
||||
keywords = ["fluence", "marine", "sdk", "webassembly", "interface-types"]
|
||||
categories = ["api-bindings", "wasm"]
|
||||
license = "Apache-2.0"
|
||||
|
||||
[package.metadata.docs.rs]
|
||||
all-features = true
|
||||
|
||||
[dependencies]
|
||||
quote = "1.0.9"
|
||||
proc-macro2 = "1.0.24"
|
||||
serde = { version = "1.0.118", features = ["derive"] }
|
||||
serde_json = "1.0.56"
|
||||
syn = { version = '1.0.64', features = ['full', "extra-traits"] }
|
||||
uuid = { version = "0.8.2", features = ["v4"] }
|
||||
|
||||
[dev-dependencies]
|
||||
pretty_assertions = "0.7.1"
|
||||
marine-macro-testing-utils = {path = "../macro-testing-utils"}
|
@ -1,87 +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::parsed_type::ParsedType;
|
||||
|
||||
#[derive(Clone)]
|
||||
pub(crate) struct AstFnArgument {
|
||||
pub(crate) name: String,
|
||||
pub(crate) ty: ParsedType,
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
pub(crate) struct AstFnSignature {
|
||||
pub(crate) visibility: syn::Visibility,
|
||||
pub(crate) name: String,
|
||||
pub(crate) arguments: Vec<AstFnArgument>,
|
||||
// only one or zero return values are supported now,
|
||||
// waiting for adding multi-value support in Wasmer
|
||||
pub(crate) output_type: Option<ParsedType>,
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
pub(crate) struct AstRecord {
|
||||
pub(crate) name: String,
|
||||
pub(crate) fields: AstRecordFields,
|
||||
pub(crate) original: syn::ItemStruct,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq)]
|
||||
pub(crate) enum AstRecordFields {
|
||||
Named(Vec<AstRecordField>),
|
||||
|
||||
// named and unnamed variants have the same inner field types because of it's easy to handle it,
|
||||
// for additional info look at https://github.com/dtolnay/syn/issues/698
|
||||
#[allow(dead_code)] // at the moment tuple and unit structs aren't supported
|
||||
Unnamed(Vec<AstRecordField>),
|
||||
|
||||
#[allow(dead_code)] // at the moment tuple and unit structs aren't supported
|
||||
Unit,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq)]
|
||||
pub(crate) struct AstRecordField {
|
||||
/// Name of the field. Can be `None` for tuples.
|
||||
pub(crate) name: Option<String>,
|
||||
pub(crate) ty: ParsedType,
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
pub(crate) struct AstExternFn {
|
||||
pub(crate) link_name: Option<String>,
|
||||
// only imports are possible here
|
||||
pub(crate) signature: AstFnSignature,
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
pub(crate) struct AstExternMod {
|
||||
pub(crate) namespace: String,
|
||||
// only imports are possible here
|
||||
pub(crate) imports: Vec<AstExternFn>,
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
pub(crate) struct AstFn {
|
||||
pub(crate) signature: AstFnSignature,
|
||||
pub(crate) original: syn::ItemFn,
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
pub(crate) enum MarineAst {
|
||||
Function(AstFn),
|
||||
ExternMod(AstExternMod),
|
||||
Record(AstRecord),
|
||||
}
|
@ -1,196 +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::parsed_type::ParsedType;
|
||||
|
||||
use serde::Serialize;
|
||||
use serde::Deserialize;
|
||||
|
||||
#[derive(Clone, Debug, Serialize, Deserialize)]
|
||||
pub struct FnArgument {
|
||||
pub name: String,
|
||||
pub ty: ParsedType,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Serialize, Deserialize)]
|
||||
pub struct FnSignature {
|
||||
pub name: String,
|
||||
pub arguments: Vec<FnArgument>,
|
||||
pub output_types: Vec<ParsedType>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Serialize, Deserialize)]
|
||||
pub struct RecordType {
|
||||
pub name: String,
|
||||
pub fields: RecordFields,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Serialize, Deserialize)]
|
||||
pub enum RecordFields {
|
||||
Named(Vec<RecordField>),
|
||||
// named and unnamed variants have the same inner field types because of it's easy to handle it,
|
||||
// for additional info look at https://github.com/dtolnay/syn/issues/698
|
||||
Unnamed(Vec<RecordField>),
|
||||
Unit,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
|
||||
pub struct RecordField {
|
||||
// fields of tuple structs haven't got name
|
||||
pub name: Option<String>,
|
||||
pub ty: ParsedType,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Serialize, Deserialize)]
|
||||
pub struct ExternFnType {
|
||||
pub link_name: Option<String>,
|
||||
// only imports are possible here
|
||||
pub signature: FnSignature,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Serialize, Deserialize)]
|
||||
pub struct ExternModType {
|
||||
pub namespace: String,
|
||||
// only imports are possible here
|
||||
pub imports: Vec<ExternFnType>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Serialize, Deserialize)]
|
||||
pub struct FnType {
|
||||
pub signature: FnSignature,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Serialize, Deserialize)]
|
||||
#[serde(tag = "ast_type")]
|
||||
pub enum SDKAst {
|
||||
Function(FnType),
|
||||
ExternMod(ExternModType),
|
||||
Record(RecordType),
|
||||
}
|
||||
|
||||
use crate::ast_types::{
|
||||
AstFn, AstFnSignature, AstFnArgument, AstExternMod, AstExternFn, AstRecordField, AstRecord,
|
||||
AstRecordFields,
|
||||
};
|
||||
|
||||
impl From<AstFn> for SDKAst {
|
||||
fn from(ast_fn_item: AstFn) -> Self {
|
||||
let fn_item = ast_fn_item.into();
|
||||
Self::Function(fn_item)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<AstExternMod> for SDKAst {
|
||||
fn from(ast_extern_mod: AstExternMod) -> Self {
|
||||
let extern_mod = ast_extern_mod.into();
|
||||
Self::ExternMod(extern_mod)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<AstRecord> for SDKAst {
|
||||
fn from(ast_record_item: AstRecord) -> Self {
|
||||
let record_item = ast_record_item.into();
|
||||
Self::Record(record_item)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<AstFn> for FnType {
|
||||
fn from(ast_fn_item: AstFn) -> Self {
|
||||
let signature = ast_fn_item.signature.into();
|
||||
|
||||
Self { signature }
|
||||
}
|
||||
}
|
||||
|
||||
impl From<AstExternMod> for ExternModType {
|
||||
fn from(ast_extern_mod: AstExternMod) -> Self {
|
||||
let imports = ast_extern_mod.imports.into_iter().map(Into::into).collect();
|
||||
|
||||
Self {
|
||||
namespace: ast_extern_mod.namespace,
|
||||
imports,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<AstRecord> for RecordType {
|
||||
fn from(ast_record_item: AstRecord) -> Self {
|
||||
Self {
|
||||
name: ast_record_item.name,
|
||||
fields: ast_record_item.fields.into(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<AstRecordFields> for RecordFields {
|
||||
fn from(ast_record_item: AstRecordFields) -> Self {
|
||||
match ast_record_item {
|
||||
AstRecordFields::Named(fields) => {
|
||||
let fields = fields.into_iter().map(Into::into).collect();
|
||||
Self::Named(fields)
|
||||
}
|
||||
AstRecordFields::Unnamed(fields) => {
|
||||
let fields = fields.into_iter().map(Into::into).collect();
|
||||
Self::Unnamed(fields)
|
||||
}
|
||||
AstRecordFields::Unit => Self::Unit,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<AstFnSignature> for FnSignature {
|
||||
fn from(ast_fn_sig: AstFnSignature) -> Self {
|
||||
// TODO: consider to do transmute here in case of optimization issues.
|
||||
let arguments = ast_fn_sig.arguments.into_iter().map(Into::into).collect();
|
||||
let output_type = match ast_fn_sig.output_type {
|
||||
Some(output_type) => vec![output_type],
|
||||
None => Vec::new(),
|
||||
};
|
||||
|
||||
Self {
|
||||
name: ast_fn_sig.name,
|
||||
arguments,
|
||||
output_types: output_type,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<AstFnArgument> for FnArgument {
|
||||
fn from(ast_fn_arg: AstFnArgument) -> Self {
|
||||
Self {
|
||||
name: ast_fn_arg.name,
|
||||
ty: ast_fn_arg.ty,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<AstExternFn> for ExternFnType {
|
||||
fn from(ast_extern_item: AstExternFn) -> Self {
|
||||
Self {
|
||||
link_name: ast_extern_item.link_name,
|
||||
signature: ast_extern_item.signature.into(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<AstRecordField> for RecordField {
|
||||
fn from(ast_record_field: AstRecordField) -> Self {
|
||||
Self {
|
||||
name: ast_record_field.name,
|
||||
ty: ast_record_field.ty,
|
||||
}
|
||||
}
|
||||
}
|
@ -1,51 +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.
|
||||
*/
|
||||
|
||||
#![doc(html_root_url = "https://docs.rs/marine-macro-impl/0.6.13")]
|
||||
#![deny(
|
||||
dead_code,
|
||||
nonstandard_style,
|
||||
unused_imports,
|
||||
unused_mut,
|
||||
unused_variables,
|
||||
unused_unsafe,
|
||||
unreachable_patterns
|
||||
)]
|
||||
#![recursion_limit = "1024"]
|
||||
#![warn(rust_2018_idioms)]
|
||||
|
||||
/// This crate contains functions and types to support work with WebAssembly interface-types
|
||||
/// in Fluence.
|
||||
|
||||
mod ast_types;
|
||||
mod export_ast_types;
|
||||
mod marine_macro_impl;
|
||||
mod parsed_type;
|
||||
mod parse_macro_input;
|
||||
mod token_stream_generator;
|
||||
mod utils;
|
||||
mod wasm_type;
|
||||
|
||||
pub use export_ast_types::*;
|
||||
pub use crate::marine_macro_impl::marine;
|
||||
pub use parsed_type::ParsedType;
|
||||
pub use parsed_type::PassingStyle;
|
||||
pub use token_stream_generator::GENERATED_WRAPPER_FUNC_PREFIX;
|
||||
pub use token_stream_generator::GENERATED_SECTION_PREFIX;
|
||||
pub use token_stream_generator::GENERATED_GLOBAL_PREFIX;
|
||||
pub use wasm_type::RustType;
|
||||
|
||||
pub const GENERATED_SECTION_PREFIX_FCE: &str = "__fce_generated_section__";
|
@ -1,33 +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::parse_macro_input::ParseMacroInput;
|
||||
|
||||
use proc_macro2::TokenStream;
|
||||
use quote::ToTokens;
|
||||
use syn::Result;
|
||||
|
||||
pub fn marine(tokens: TokenStream) -> Result<TokenStream> {
|
||||
let item = syn::parse2::<syn::Item>(tokens)?;
|
||||
// convert proc_macro2 token to internal AST type
|
||||
let marine_ast_item = item.parse_macro_input()?;
|
||||
|
||||
// convert internal AST type to sequence of tokens
|
||||
let mut tokens = TokenStream::new();
|
||||
marine_ast_item.to_tokens(&mut tokens);
|
||||
|
||||
Ok(tokens)
|
||||
}
|
@ -1,42 +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.
|
||||
*/
|
||||
|
||||
mod item_fn;
|
||||
mod item_foreign_mod;
|
||||
mod item_record;
|
||||
mod utils;
|
||||
|
||||
use crate::ast_types::MarineAst;
|
||||
|
||||
pub(crate) trait ParseMacroInput {
|
||||
fn parse_macro_input(self) -> syn::Result<MarineAst>;
|
||||
}
|
||||
|
||||
impl ParseMacroInput for syn::Item {
|
||||
fn parse_macro_input(self) -> syn::Result<MarineAst> {
|
||||
use syn::spanned::Spanned;
|
||||
|
||||
match self {
|
||||
syn::Item::Fn(function) => function.parse_macro_input(),
|
||||
syn::Item::ForeignMod(extern_mod) => extern_mod.parse_macro_input(),
|
||||
syn::Item::Struct(item_struct) => item_struct.parse_macro_input(),
|
||||
_ => Err(syn::Error::new(
|
||||
self.span(),
|
||||
"At now, #[marine] could be applied only to a function, extern block or struct",
|
||||
)),
|
||||
}
|
||||
}
|
||||
}
|
@ -1,175 +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 super::ParseMacroInput;
|
||||
use crate::ast_types;
|
||||
use crate::ParsedType;
|
||||
use crate::ast_types::MarineAst;
|
||||
use crate::ast_types::AstFn;
|
||||
use crate::ast_types::AstFnArgument;
|
||||
use crate::syn_error;
|
||||
|
||||
use syn::Result;
|
||||
use syn::spanned::Spanned;
|
||||
|
||||
impl ParseMacroInput for syn::ItemFn {
|
||||
fn parse_macro_input(self) -> Result<MarineAst> {
|
||||
let signature = try_to_ast_signature(self.sig.clone(), self.vis.clone())?;
|
||||
|
||||
// this check specific only for export functions
|
||||
let parsed_args = signature
|
||||
.arguments
|
||||
.iter()
|
||||
.zip(self.sig.inputs.iter().map(|arg| arg.span()));
|
||||
|
||||
check_args(parsed_args)?;
|
||||
check_output_type(&signature.output_type, self.sig.output.span())?;
|
||||
|
||||
let ast_fn = MarineAst::Function(AstFn {
|
||||
signature,
|
||||
original: self,
|
||||
});
|
||||
Ok(ast_fn)
|
||||
}
|
||||
}
|
||||
|
||||
pub(super) fn try_to_ast_signature(
|
||||
signature: syn::Signature,
|
||||
visibility: syn::Visibility,
|
||||
) -> Result<ast_types::AstFnSignature> {
|
||||
use quote::ToTokens;
|
||||
|
||||
check_function(&signature)?;
|
||||
|
||||
let syn::Signature { inputs, output, .. } = signature;
|
||||
|
||||
let arguments = inputs
|
||||
.iter()
|
||||
.map(|arg| -> Result<_> {
|
||||
let pat = match arg {
|
||||
syn::FnArg::Typed(arg) => arg,
|
||||
_ => {
|
||||
return Err(syn::Error::new(
|
||||
arg.span(),
|
||||
"`self` argument types aren't supported",
|
||||
))
|
||||
}
|
||||
};
|
||||
|
||||
let name = pat
|
||||
.pat
|
||||
.to_token_stream()
|
||||
.to_string()
|
||||
.split(' ')
|
||||
.last()
|
||||
.unwrap_or_default()
|
||||
.to_string();
|
||||
let ty = ParsedType::from_type(pat.ty.as_ref())?;
|
||||
let ast_arg = AstFnArgument { name, ty };
|
||||
|
||||
Ok(ast_arg)
|
||||
})
|
||||
.collect::<Result<Vec<_>>>()?;
|
||||
|
||||
let output_type = ParsedType::from_return_type(&output)?;
|
||||
|
||||
let ast_function_item = ast_types::AstFnSignature {
|
||||
visibility,
|
||||
name: signature.ident.to_string(),
|
||||
arguments,
|
||||
output_type,
|
||||
};
|
||||
|
||||
Ok(ast_function_item)
|
||||
}
|
||||
|
||||
/// Check whether the #[marine] macro could be applied to a function.
|
||||
#[rustfmt::skip]
|
||||
fn check_function(signature: &syn::Signature) -> Result<()> {
|
||||
let syn::Signature {
|
||||
constness,
|
||||
unsafety,
|
||||
abi,
|
||||
variadic,
|
||||
generics,
|
||||
..
|
||||
} = signature;
|
||||
|
||||
if let Some(constness) = constness {
|
||||
return syn_error!(constness.span, "Marine export function shouldn't be constant");
|
||||
}
|
||||
if let Some(unsafety) = unsafety {
|
||||
return syn_error!(unsafety.span, "Marine export function shouldn't be unsafe");
|
||||
}
|
||||
if let Some(abi) = abi {
|
||||
return syn_error!(abi.extern_token.span, "Marine export function shouldn't have any custom linkage");
|
||||
}
|
||||
if generics.where_clause.is_some() {
|
||||
return syn_error!(signature.span(), "Marine export function shouldn't use template parameters");
|
||||
}
|
||||
if variadic.is_some() {
|
||||
return syn_error!(variadic.span(), "Marine export function shouldn't use variadic interface");
|
||||
}
|
||||
|
||||
// TODO: check for a lifetime
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn check_args<'a>(
|
||||
args: impl ExactSizeIterator<Item = (&'a AstFnArgument, proc_macro2::Span)>,
|
||||
) -> Result<()> {
|
||||
for (arg, span) in args {
|
||||
if contains_inner_ref(&arg.ty) {
|
||||
return crate::syn_error!(
|
||||
span,
|
||||
"a vector type in arguments of export functions shouldn't contain references"
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn check_output_type(output_type: &Option<ParsedType>, span: proc_macro2::Span) -> Result<()> {
|
||||
let ty = match output_type {
|
||||
Some(ty) => ty,
|
||||
None => return Ok(()),
|
||||
};
|
||||
|
||||
if contains_inner_ref(ty) {
|
||||
return crate::syn_error!(
|
||||
span,
|
||||
"a vector type in output types of export functions shouldn't contain references"
|
||||
);
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Returns true if the given type is a vector contains a reference inside it's parameter type.
|
||||
/// F.e.
|
||||
/// Vec<&String> => true
|
||||
/// Vec<Vec<&Vec<String>>> => true
|
||||
/// &Vec<String> => false
|
||||
fn contains_inner_ref(ty: &ParsedType) -> bool {
|
||||
use super::utils::contain_inner_ref;
|
||||
|
||||
match ty {
|
||||
ParsedType::Vector(ty, _) => contain_inner_ref(ty),
|
||||
// Structs are checked while parsing
|
||||
_ => false,
|
||||
}
|
||||
}
|
@ -1,173 +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 super::ParseMacroInput;
|
||||
use crate::ast_types;
|
||||
use crate::ast_types::MarineAst;
|
||||
use crate::syn_error;
|
||||
|
||||
use syn::Result;
|
||||
use syn::spanned::Spanned;
|
||||
|
||||
const LINK_DIRECTIVE_NAME: &str = "link";
|
||||
const LINK_NAME_DIRECTIVE_NAME: &str = "link_name";
|
||||
const WASM_IMPORT_MODULE_DIRECTIVE_NAME: &str = "wasm_import_module";
|
||||
|
||||
impl ParseMacroInput for syn::ItemForeignMod {
|
||||
fn parse_macro_input(self) -> Result<MarineAst> {
|
||||
check_foreign_section(&self)?;
|
||||
|
||||
let wasm_import_module: Option<String> = parse_wasm_import_module(&self);
|
||||
let namespace = try_extract_namespace(wasm_import_module, &self)?;
|
||||
|
||||
let imports = extract_import_functions(&self)?;
|
||||
check_imports(imports.iter().zip(self.items.iter().map(|i| i.span())))?;
|
||||
|
||||
let extern_mod_item = ast_types::AstExternMod { namespace, imports };
|
||||
Ok(MarineAst::ExternMod(extern_mod_item))
|
||||
}
|
||||
}
|
||||
|
||||
fn check_foreign_section(foreign_mod: &syn::ItemForeignMod) -> Result<()> {
|
||||
match &foreign_mod.abi.name {
|
||||
Some(name) if name.value() != "C" => {
|
||||
syn_error!(foreign_mod.span(), "only 'C' abi is allowed")
|
||||
}
|
||||
_ => Ok(()),
|
||||
}
|
||||
}
|
||||
|
||||
/// Tries to find and parse wasm module name from
|
||||
/// #[link(wasm_import_module = "host")]
|
||||
fn parse_wasm_import_module(foreign_mod: &syn::ItemForeignMod) -> Option<String> {
|
||||
foreign_mod
|
||||
.attrs
|
||||
.iter()
|
||||
.filter_map(|attr| attr.parse_meta().ok())
|
||||
.filter(|meta| meta.path().is_ident(LINK_DIRECTIVE_NAME))
|
||||
.filter_map(|meta| {
|
||||
let pair = match meta {
|
||||
syn::Meta::List(mut meta_list) if meta_list.nested.len() == 1 => {
|
||||
meta_list.nested.pop().unwrap()
|
||||
}
|
||||
_ => return None,
|
||||
};
|
||||
Some(pair.into_tuple().0)
|
||||
})
|
||||
.filter_map(|nested| match nested {
|
||||
syn::NestedMeta::Meta(meta) => Some(meta),
|
||||
_ => None,
|
||||
})
|
||||
.filter(|meta| meta.path().is_ident(WASM_IMPORT_MODULE_DIRECTIVE_NAME))
|
||||
.map(extract_value)
|
||||
.collect()
|
||||
}
|
||||
|
||||
fn try_extract_namespace(
|
||||
attr: Option<String>,
|
||||
foreign_mod: &syn::ItemForeignMod,
|
||||
) -> Result<String> {
|
||||
match attr {
|
||||
Some(namespace) if namespace.is_empty() => syn_error!(
|
||||
foreign_mod.span(),
|
||||
"import module name should be defined by 'wasm_import_module' directive"
|
||||
),
|
||||
Some(namespace) => Ok(namespace),
|
||||
None => syn_error!(
|
||||
foreign_mod.span(),
|
||||
"import module name should be defined by 'wasm_import_module' directive"
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
fn extract_import_functions(
|
||||
foreign_mod: &syn::ItemForeignMod,
|
||||
) -> Result<Vec<ast_types::AstExternFn>> {
|
||||
foreign_mod
|
||||
.items
|
||||
.iter()
|
||||
.cloned()
|
||||
.map(parse_raw_foreign_item)
|
||||
.collect::<Result<_>>()
|
||||
}
|
||||
|
||||
/// This function checks whether these imports contains inner references. In this case glue
|
||||
/// code couldn't be generated.
|
||||
fn check_imports<'i>(
|
||||
extern_fns: impl ExactSizeIterator<Item = (&'i ast_types::AstExternFn, proc_macro2::Span)>,
|
||||
) -> Result<()> {
|
||||
use super::utils::contain_inner_ref;
|
||||
|
||||
for (extern_fn, span) in extern_fns {
|
||||
if let Some(output_type) = &extern_fn.signature.output_type {
|
||||
if contain_inner_ref(output_type) {
|
||||
return crate::syn_error!(
|
||||
span,
|
||||
"import function can't return a value with references"
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn parse_raw_foreign_item(raw_item: syn::ForeignItem) -> Result<ast_types::AstExternFn> {
|
||||
let function_item = match raw_item {
|
||||
syn::ForeignItem::Fn(function_item) => function_item,
|
||||
_ => {
|
||||
return syn_error!(
|
||||
raw_item.span(),
|
||||
"#[marine] could be applied only to a function, struct ot extern block"
|
||||
)
|
||||
}
|
||||
};
|
||||
|
||||
// parse the link_name attribute
|
||||
// #[link_name = "put"]
|
||||
// fn ipfs_put(ptr: i32, size: i32);
|
||||
let link_name: Option<String> = function_item
|
||||
.attrs
|
||||
.iter()
|
||||
.filter_map(|attr| attr.parse_meta().ok())
|
||||
.filter(|meta| meta.path().is_ident(LINK_NAME_DIRECTIVE_NAME))
|
||||
.map(extract_value)
|
||||
.collect();
|
||||
|
||||
let link_name = match link_name {
|
||||
Some(name) if name.is_empty() => None,
|
||||
v @ Some(_) => v,
|
||||
None => None,
|
||||
};
|
||||
|
||||
let signature = super::item_fn::try_to_ast_signature(function_item.sig, function_item.vis)?;
|
||||
let ast_extern_fn_item = ast_types::AstExternFn {
|
||||
link_name,
|
||||
signature,
|
||||
};
|
||||
|
||||
Ok(ast_extern_fn_item)
|
||||
}
|
||||
|
||||
fn extract_value(nested_meta: syn::Meta) -> Option<String> {
|
||||
match nested_meta {
|
||||
syn::Meta::NameValue(name_value) => match name_value.lit {
|
||||
syn::Lit::Str(str) => Some(str.value()),
|
||||
_ => None,
|
||||
},
|
||||
_ => None,
|
||||
}
|
||||
}
|
@ -1,118 +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 super::ParseMacroInput;
|
||||
use crate::ast_types;
|
||||
use crate::ast_types::AstRecordField;
|
||||
use crate::ast_types::AstRecordFields;
|
||||
use crate::ast_types::MarineAst;
|
||||
use crate::syn_error;
|
||||
use crate::parsed_type::ParsedType;
|
||||
|
||||
use syn::Result;
|
||||
use syn::spanned::Spanned;
|
||||
|
||||
impl ParseMacroInput for syn::ItemStruct {
|
||||
fn parse_macro_input(self) -> Result<MarineAst> {
|
||||
check_record(&self)?;
|
||||
|
||||
let fields = match &self.fields {
|
||||
syn::Fields::Named(named_fields) => &named_fields.named,
|
||||
_ => return syn_error!(self.span(), "only named fields are allowed in structs"),
|
||||
};
|
||||
|
||||
let fields = fields_into_ast(fields)?;
|
||||
let fields = AstRecordFields::Named(fields);
|
||||
|
||||
let name = self.ident.to_string();
|
||||
let ast_record_item = ast_types::AstRecord {
|
||||
name,
|
||||
fields,
|
||||
original: self,
|
||||
};
|
||||
|
||||
Ok(MarineAst::Record(ast_record_item))
|
||||
}
|
||||
}
|
||||
|
||||
fn check_record(record: &syn::ItemStruct) -> Result<()> {
|
||||
if record.generics.lt_token.is_some()
|
||||
|| record.generics.gt_token.is_some()
|
||||
|| record.generics.where_clause.is_some()
|
||||
{
|
||||
return syn_error!(
|
||||
record.span(),
|
||||
"#[marine] couldn't be applied to a struct with generics or lifetimes"
|
||||
);
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn fields_into_ast(
|
||||
fields: &syn::punctuated::Punctuated<syn::Field, syn::Token![,]>,
|
||||
) -> Result<Vec<AstRecordField>> {
|
||||
fields
|
||||
.iter()
|
||||
.map(|field| {
|
||||
check_field(field)?;
|
||||
let name = field.ident.as_ref().map(|ident| {
|
||||
ident
|
||||
.to_string()
|
||||
.split(' ')
|
||||
.last()
|
||||
.unwrap_or_default()
|
||||
.to_string()
|
||||
});
|
||||
let ty = ParsedType::from_type(&field.ty)?;
|
||||
|
||||
let record_field = AstRecordField { name, ty };
|
||||
Ok(record_field)
|
||||
})
|
||||
.collect::<Result<Vec<_>>>()
|
||||
}
|
||||
|
||||
/// Check that record fields satisfy the following requirements:
|
||||
/// - all fields must be public
|
||||
/// - field must have only doc attributes
|
||||
fn check_field(field: &syn::Field) -> Result<()> {
|
||||
match field.vis {
|
||||
syn::Visibility::Public(_) => {}
|
||||
_ => {
|
||||
return syn_error!(
|
||||
field.span(),
|
||||
"#[marine] could be applied only to struct with all public fields"
|
||||
)
|
||||
}
|
||||
};
|
||||
|
||||
const DOC_ATTR_NAME: &str = "doc";
|
||||
|
||||
// Check that all attributes are doc attributes
|
||||
let is_all_attrs_public = field.attrs.iter().all(|attr| {
|
||||
let meta = match attr.parse_meta() {
|
||||
Ok(meta) => meta,
|
||||
Err(_) => return false,
|
||||
};
|
||||
meta.path().is_ident(DOC_ATTR_NAME)
|
||||
});
|
||||
|
||||
if !is_all_attrs_public {
|
||||
return syn_error!(field.span(), "field attributes isn't allowed");
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
@ -1,33 +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::ParsedType;
|
||||
use crate::parsed_type::PassingStyle;
|
||||
use crate::parsed_type::passing_style_of;
|
||||
|
||||
/// Checks whether a type contains a reference in one of types.
|
||||
pub(super) fn contain_inner_ref(ty: &ParsedType) -> bool {
|
||||
let passing_style = passing_style_of(ty);
|
||||
match passing_style {
|
||||
PassingStyle::ByValue => {}
|
||||
PassingStyle::ByRef | PassingStyle::ByMutRef => return true,
|
||||
};
|
||||
|
||||
match ty {
|
||||
ParsedType::Vector(ty, _) => contain_inner_ref(ty),
|
||||
_ => false,
|
||||
}
|
||||
}
|
@ -1,199 +0,0 @@
|
||||
/*
|
||||
* Copyright 2018 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 fn_arg;
|
||||
mod fn_epilog;
|
||||
mod fn_prolog;
|
||||
mod foreign_mod_arg;
|
||||
mod foreign_mod_epilog;
|
||||
mod foreign_mod_prolog;
|
||||
mod traits;
|
||||
mod utils;
|
||||
mod vector_ser_der;
|
||||
|
||||
pub(crate) use fn_arg::*;
|
||||
pub(crate) use fn_epilog::*;
|
||||
pub(crate) use fn_prolog::*;
|
||||
pub(crate) use foreign_mod_prolog::*;
|
||||
pub(crate) use foreign_mod_epilog::*;
|
||||
pub(crate) use utils::*;
|
||||
pub(crate) use vector_ser_der::*;
|
||||
|
||||
use serde::Serialize;
|
||||
use serde::Deserialize;
|
||||
use syn::parse::Error;
|
||||
use syn::spanned::Spanned;
|
||||
|
||||
/// An internal representation of supported Rust types.
|
||||
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
|
||||
pub enum ParsedType {
|
||||
I8(PassingStyle),
|
||||
I16(PassingStyle),
|
||||
I32(PassingStyle),
|
||||
I64(PassingStyle),
|
||||
U8(PassingStyle),
|
||||
U16(PassingStyle),
|
||||
U32(PassingStyle),
|
||||
U64(PassingStyle),
|
||||
F32(PassingStyle),
|
||||
F64(PassingStyle),
|
||||
Boolean(PassingStyle),
|
||||
Utf8Str(PassingStyle),
|
||||
Utf8String(PassingStyle),
|
||||
Vector(Box<ParsedType>, PassingStyle),
|
||||
Record(String, PassingStyle), // short type name
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Serialize, Deserialize)]
|
||||
pub enum PassingStyle {
|
||||
ByValue,
|
||||
ByRef,
|
||||
ByMutRef,
|
||||
}
|
||||
|
||||
impl ParsedType {
|
||||
pub fn from_type(input_type: &syn::Type) -> syn::Result<Self> {
|
||||
use quote::ToTokens;
|
||||
|
||||
let (path, passing_style) = type_to_path_passing_style(input_type)?;
|
||||
|
||||
let type_segment = path
|
||||
.segments
|
||||
// argument can be given in full path form: ::std::string::String
|
||||
// that why the last one used
|
||||
.last()
|
||||
.ok_or_else(|| Error::new(path.span(), "Type should be specified"))?;
|
||||
|
||||
match type_segment.ident.to_string().as_str() {
|
||||
"i8" => Ok(ParsedType::I8(passing_style)),
|
||||
"i16" => Ok(ParsedType::I16(passing_style)),
|
||||
"i32" => Ok(ParsedType::I32(passing_style)),
|
||||
"i64" => Ok(ParsedType::I64(passing_style)),
|
||||
"u8" => Ok(ParsedType::U8(passing_style)),
|
||||
"u16" => Ok(ParsedType::U16(passing_style)),
|
||||
"u32" => Ok(ParsedType::U32(passing_style)),
|
||||
"u64" => Ok(ParsedType::U64(passing_style)),
|
||||
"f32" => Ok(ParsedType::F32(passing_style)),
|
||||
"f64" => Ok(ParsedType::F64(passing_style)),
|
||||
"bool" => Ok(ParsedType::Boolean(passing_style)),
|
||||
"str" => Ok(ParsedType::Utf8Str(passing_style)),
|
||||
"String" => Ok(ParsedType::Utf8String(passing_style)),
|
||||
"Vec" => {
|
||||
let vec_type = parse_vec_bracket(&type_segment.arguments)?;
|
||||
let parsed_type = ParsedType::from_type(vec_type)?;
|
||||
|
||||
Ok(ParsedType::Vector(Box::new(parsed_type), passing_style))
|
||||
}
|
||||
_ if !type_segment.arguments.is_empty() => Err(Error::new(
|
||||
type_segment.span(),
|
||||
"types with lifetimes or generics aren't allowed".to_string(),
|
||||
)),
|
||||
_ => Ok(ParsedType::Record(
|
||||
(&type_segment.ident).into_token_stream().to_string(),
|
||||
passing_style,
|
||||
)),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn from_fn_arg(fn_arg: &syn::FnArg) -> syn::Result<Self> {
|
||||
match fn_arg {
|
||||
syn::FnArg::Typed(arg) => ParsedType::from_type(&arg.ty),
|
||||
_ => Err(Error::new(
|
||||
fn_arg.span(),
|
||||
"`self` argument types aren't supported",
|
||||
)),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn from_return_type(ret_type: &syn::ReturnType) -> syn::Result<Option<Self>> {
|
||||
match ret_type {
|
||||
syn::ReturnType::Type(_, t) => Ok(Some(ParsedType::from_type(t.as_ref())?)),
|
||||
syn::ReturnType::Default => Ok(None),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn is_complex_type(&self) -> bool {
|
||||
match self {
|
||||
ParsedType::Boolean(_)
|
||||
| ParsedType::I8(_)
|
||||
| ParsedType::I16(_)
|
||||
| ParsedType::I32(_)
|
||||
| ParsedType::I64(_)
|
||||
| ParsedType::U8(_)
|
||||
| ParsedType::U16(_)
|
||||
| ParsedType::U32(_)
|
||||
| ParsedType::U64(_)
|
||||
| ParsedType::F32(_)
|
||||
| ParsedType::F64(_) => false,
|
||||
ParsedType::Utf8Str(_)
|
||||
| ParsedType::Utf8String(_)
|
||||
| ParsedType::Vector(..)
|
||||
| ParsedType::Record(..) => true,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn type_to_path_passing_style(input_type: &syn::Type) -> syn::Result<(&syn::Path, PassingStyle)> {
|
||||
match input_type {
|
||||
syn::Type::Path(path) => Ok((&path.path, PassingStyle::ByValue)),
|
||||
syn::Type::Reference(type_reference) => match &*type_reference.elem {
|
||||
syn::Type::Path(path) => {
|
||||
let passing_style = match type_reference.mutability {
|
||||
Some(_) => PassingStyle::ByMutRef,
|
||||
None => PassingStyle::ByRef,
|
||||
};
|
||||
|
||||
Ok((&path.path, passing_style))
|
||||
}
|
||||
_ => Err(Error::new(
|
||||
input_type.span(),
|
||||
"Incorrect argument type, only path is available on this position",
|
||||
)),
|
||||
},
|
||||
_ => Err(Error::new(
|
||||
input_type.span(),
|
||||
"Incorrect argument type, only path or reference are available on this position",
|
||||
)),
|
||||
}
|
||||
}
|
||||
|
||||
// parse generic param T in Vec<T> to syn::Type
|
||||
fn parse_vec_bracket(args: &syn::PathArguments) -> syn::Result<&syn::Type> {
|
||||
// checks that T is angle bracketed
|
||||
let generic_arg = match args {
|
||||
syn::PathArguments::AngleBracketed(args) => Ok(args),
|
||||
_ => Err(Error::new(
|
||||
args.span(),
|
||||
"expected value in angle brackets (<>)",
|
||||
)),
|
||||
}?;
|
||||
|
||||
let arg = generic_arg.args.first().ok_or_else(|| {
|
||||
Error::new(
|
||||
generic_arg.span(),
|
||||
"Invalid type in Vec brackets. (NOTE: lifetimes, bindings, constraints and consts are not supported)",
|
||||
)
|
||||
})?;
|
||||
|
||||
// converts T to syn::Type
|
||||
match arg {
|
||||
syn::GenericArgument::Type(ty) => Ok(ty),
|
||||
_ => Err(Error::new(
|
||||
arg.span(),
|
||||
"Invalid type in Vec brackets. (NOTE: lifetimes, bindings, constraints and consts are not supported)",
|
||||
)),
|
||||
}
|
||||
}
|
@ -1,46 +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 super::ParsedType;
|
||||
use crate::ast_types::AstFnArgument;
|
||||
use crate::wasm_type::RustType;
|
||||
|
||||
/// This trait could be used to generate raw args needed to construct a export function.
|
||||
pub(crate) trait FnArgGlueCodeGenerator {
|
||||
fn generate_arguments(&self) -> Vec<RustType>;
|
||||
}
|
||||
|
||||
impl FnArgGlueCodeGenerator for AstFnArgument {
|
||||
fn generate_arguments(&self) -> Vec<RustType> {
|
||||
match self.ty {
|
||||
ParsedType::Boolean(_) => vec![RustType::I32],
|
||||
ParsedType::I8(_) => vec![RustType::I8],
|
||||
ParsedType::I16(_) => vec![RustType::I16],
|
||||
ParsedType::I32(_) => vec![RustType::I32],
|
||||
ParsedType::I64(_) => vec![RustType::I64],
|
||||
ParsedType::U8(_) => vec![RustType::U8],
|
||||
ParsedType::U16(_) => vec![RustType::U16],
|
||||
ParsedType::U32(_) => vec![RustType::U32],
|
||||
ParsedType::U64(_) => vec![RustType::U64],
|
||||
ParsedType::Record(..) => vec![RustType::U32],
|
||||
ParsedType::F32(_) => vec![RustType::F32],
|
||||
ParsedType::F64(_) => vec![RustType::F64],
|
||||
ParsedType::Utf8Str(_) | ParsedType::Utf8String(_) | ParsedType::Vector(..) => {
|
||||
vec![RustType::U32, RustType::U32]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,193 +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 super::ParsedType;
|
||||
use super::passing_style_of;
|
||||
use super::PassingStyle;
|
||||
use crate::new_ident;
|
||||
use crate::ast_types::AstFnArgument;
|
||||
|
||||
use quote::quote;
|
||||
|
||||
/// Describes various parts of a function epilog.
|
||||
pub(crate) struct FnEpilogDescriptor {
|
||||
pub(crate) fn_return_type: proc_macro2::TokenStream,
|
||||
pub(crate) return_expression: proc_macro2::TokenStream,
|
||||
pub(crate) epilog: proc_macro2::TokenStream,
|
||||
pub(crate) objs_savings: proc_macro2::TokenStream,
|
||||
}
|
||||
|
||||
/// Contains all ingredients needed for epilog creation.
|
||||
pub(crate) struct FnEpilogIngredients<'i> {
|
||||
pub(crate) args: &'i [AstFnArgument],
|
||||
pub(crate) converted_args: &'i [syn::Ident],
|
||||
pub(crate) return_type: &'i Option<ParsedType>,
|
||||
}
|
||||
|
||||
/// This trait could be used to generate various parts needed to construct epilog of an export
|
||||
/// function. They are marked with # in the following example:
|
||||
/// ```ignore
|
||||
/// quote! {
|
||||
/// pub unsafe fn foo(...) #fn_return_type {
|
||||
/// ...
|
||||
/// #return_expression original_foo(...);
|
||||
/// #epilog
|
||||
/// }
|
||||
/// }
|
||||
/// ```
|
||||
pub(crate) trait FnEpilogGlueCodeGenerator {
|
||||
fn generate_fn_epilog(&self) -> FnEpilogDescriptor;
|
||||
}
|
||||
|
||||
impl FnEpilogGlueCodeGenerator for FnEpilogIngredients<'_> {
|
||||
fn generate_fn_epilog(&self) -> FnEpilogDescriptor {
|
||||
FnEpilogDescriptor {
|
||||
fn_return_type: generate_fn_return_type(self.return_type),
|
||||
return_expression: generate_return_expression(self.return_type),
|
||||
epilog: generate_epilog(self.return_type),
|
||||
objs_savings: generate_objs_savings(self),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn generate_fn_return_type(ty: &Option<ParsedType>) -> proc_macro2::TokenStream {
|
||||
let ty = match ty {
|
||||
Some(ParsedType::Boolean(_)) => Some("i32"),
|
||||
Some(ParsedType::I8(_)) => Some("i8"),
|
||||
Some(ParsedType::I16(_)) => Some("i16"),
|
||||
Some(ParsedType::I32(_)) => Some("i32"),
|
||||
Some(ParsedType::I64(_)) => Some("i64"),
|
||||
Some(ParsedType::U8(_)) => Some("u8"),
|
||||
Some(ParsedType::U16(_)) => Some("u16"),
|
||||
Some(ParsedType::U32(_)) => Some("u32"),
|
||||
Some(ParsedType::U64(_)) => Some("u64"),
|
||||
Some(ParsedType::F32(_)) => Some("f32"),
|
||||
Some(ParsedType::F64(_)) => Some("f64"),
|
||||
None
|
||||
| Some(ParsedType::Utf8Str(_))
|
||||
| Some(ParsedType::Utf8String(_))
|
||||
| Some(ParsedType::Vector(..))
|
||||
| Some(ParsedType::Record(..)) => None,
|
||||
};
|
||||
|
||||
match ty {
|
||||
Some(ty) => {
|
||||
let ty = new_ident!(ty);
|
||||
quote! { -> #ty}
|
||||
}
|
||||
None => quote! {},
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn generate_fn_original_return_type(
|
||||
ty: &Option<ParsedType>,
|
||||
) -> proc_macro2::TokenStream {
|
||||
match &ty {
|
||||
Some(ty) => quote! {-> #ty},
|
||||
None => <_>::default(),
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn generate_return_expression(ty: &Option<ParsedType>) -> proc_macro2::TokenStream {
|
||||
match ty {
|
||||
None => quote! {},
|
||||
_ => quote! {
|
||||
let result =
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
fn generate_epilog(ty: &Option<ParsedType>) -> proc_macro2::TokenStream {
|
||||
match ty {
|
||||
None => quote!(),
|
||||
Some(ParsedType::Record(..)) => {
|
||||
quote! {
|
||||
let result_ptr = result.__m_generated_serialize();
|
||||
marine_rs_sdk::internal::set_result_ptr(result_ptr as _);
|
||||
}
|
||||
}
|
||||
Some(ParsedType::Utf8Str(_)) | Some(ParsedType::Utf8String(_)) => {
|
||||
quote! {
|
||||
marine_rs_sdk::internal::set_result_ptr(result.as_ptr() as _);
|
||||
marine_rs_sdk::internal::set_result_size(result.len() as _);
|
||||
}
|
||||
}
|
||||
Some(ParsedType::Vector(ty, _)) => {
|
||||
let generated_serializer_name = "__m_generated_vec_serializer";
|
||||
let generated_serializer_ident = new_ident!(generated_serializer_name);
|
||||
let vector_serializer =
|
||||
super::vector_ser_der::generate_vector_ser(ty, generated_serializer_name);
|
||||
|
||||
quote! {
|
||||
#vector_serializer
|
||||
{
|
||||
let (serialized_vec_ptr, serialized_vec_size) = #generated_serializer_ident(&result);
|
||||
marine_rs_sdk::internal::set_result_ptr(serialized_vec_ptr as _);
|
||||
marine_rs_sdk::internal::set_result_size(serialized_vec_size as _);
|
||||
}
|
||||
}
|
||||
}
|
||||
Some(_) => quote! {
|
||||
return result as _;
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
/// If an export function returns a reference, this is probably a reference to one
|
||||
/// of the function arguments. If that's the case, reference must be still valid after
|
||||
/// the end of the function. Their deletion will be handled by IT with calling `release_objects`.
|
||||
fn generate_objs_savings(ingredients: &FnEpilogIngredients<'_>) -> proc_macro2::TokenStream {
|
||||
match ingredients.return_type {
|
||||
// if type is empty we don't need to save arguments or objects
|
||||
Some(ty) if !ty.is_complex_type() => return proc_macro2::TokenStream::new(),
|
||||
None => return proc_macro2::TokenStream::new(),
|
||||
_ => {}
|
||||
};
|
||||
|
||||
let passing_style = ingredients.return_type.as_ref().map(passing_style_of);
|
||||
|
||||
match passing_style {
|
||||
// result will be deleted by IT side
|
||||
Some(PassingStyle::ByValue) => {
|
||||
quote! { marine_rs_sdk::internal::add_object_to_release(Box::new(result)); }
|
||||
}
|
||||
Some(PassingStyle::ByRef) | Some(PassingStyle::ByMutRef) => {
|
||||
generate_args_savings(ingredients.args, ingredients.converted_args)
|
||||
}
|
||||
None => quote! {},
|
||||
}
|
||||
}
|
||||
|
||||
fn generate_args_savings(
|
||||
args: &[AstFnArgument],
|
||||
converted_args: &[syn::Ident],
|
||||
) -> proc_macro2::TokenStream {
|
||||
debug_assert!(args.len() == converted_args.len());
|
||||
|
||||
let mut res = proc_macro2::TokenStream::new();
|
||||
for (arg, converted_arg) in args.iter().zip(converted_args) {
|
||||
let arg_passing_style = passing_style_of(&arg.ty);
|
||||
match arg_passing_style {
|
||||
// such values will be deleted inside an export function because they are being moved
|
||||
PassingStyle::ByValue => {}
|
||||
_ => res.extend(quote! {
|
||||
marine_rs_sdk::internal::add_object_to_release(Box::new(#converted_arg));
|
||||
}),
|
||||
}
|
||||
}
|
||||
|
||||
res
|
||||
}
|
@ -1,169 +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 super::ParsedType;
|
||||
use super::FnArgGlueCodeGenerator;
|
||||
use super::passing_style_of;
|
||||
use crate::new_ident;
|
||||
use crate::wasm_type::RustType;
|
||||
use crate::ast_types::AstFnArgument;
|
||||
use crate::parsed_type::PassingStyle;
|
||||
|
||||
use quote::quote;
|
||||
|
||||
/// Describes various parts of a function prolog.
|
||||
pub(crate) struct FnPrologDescriptor {
|
||||
pub(crate) raw_arg_names: Vec<syn::Ident>,
|
||||
pub(crate) raw_arg_types: Vec<RustType>,
|
||||
pub(crate) prolog: proc_macro2::TokenStream,
|
||||
pub(crate) converted_arg_idents: Vec<syn::Ident>,
|
||||
pub(crate) args: Vec<proc_macro2::TokenStream>,
|
||||
}
|
||||
|
||||
/// This trait could be used to generate various parts needed to construct prolog of an export
|
||||
/// function. They are marked with # in the following example:
|
||||
/// ```ignore
|
||||
/// quote! {
|
||||
/// fn foo(#(#raw_arg_names: #raw_arg_types),*) {
|
||||
/// #prolog
|
||||
/// let result = original_foo(#(#args), *);
|
||||
/// ...
|
||||
/// }
|
||||
/// }
|
||||
/// ```
|
||||
pub(crate) trait FnPrologGlueCodeGenerator {
|
||||
fn generate_prolog(&self) -> FnPrologDescriptor;
|
||||
}
|
||||
|
||||
impl FnPrologGlueCodeGenerator for Vec<AstFnArgument> {
|
||||
fn generate_prolog(&self) -> FnPrologDescriptor {
|
||||
let mut raw_arg_names = Vec::with_capacity(self.len());
|
||||
let mut raw_arg_types = Vec::with_capacity(self.len());
|
||||
let mut prolog = proc_macro2::TokenStream::new();
|
||||
let mut converted_arg_idents = Vec::with_capacity(self.len());
|
||||
let mut args: Vec<proc_macro2::TokenStream> = Vec::with_capacity(self.len());
|
||||
|
||||
let mut input_type_id = 0;
|
||||
for arg in self {
|
||||
let passing_style = passing_style_of(&arg.ty);
|
||||
let TypeLifter {
|
||||
converted_arg_ident,
|
||||
type_lifter_glue_code,
|
||||
} = generate_type_lifting_prolog(&arg.ty, passing_style, input_type_id, input_type_id);
|
||||
|
||||
let curr_raw_arg_types = arg.generate_arguments();
|
||||
let arg = quote! { #passing_style #converted_arg_ident };
|
||||
args.push(arg);
|
||||
|
||||
raw_arg_names.extend(
|
||||
curr_raw_arg_types
|
||||
.iter()
|
||||
.enumerate()
|
||||
.map(|(id, _)| new_ident!(format!("arg_{}", input_type_id + id))),
|
||||
);
|
||||
|
||||
input_type_id += curr_raw_arg_types.len();
|
||||
raw_arg_types.extend(curr_raw_arg_types);
|
||||
prolog.extend(type_lifter_glue_code);
|
||||
converted_arg_idents.push(converted_arg_ident);
|
||||
}
|
||||
|
||||
FnPrologDescriptor {
|
||||
raw_arg_names,
|
||||
raw_arg_types,
|
||||
prolog,
|
||||
converted_arg_idents,
|
||||
args,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct TypeLifter {
|
||||
pub(self) converted_arg_ident: syn::Ident,
|
||||
pub(self) type_lifter_glue_code: proc_macro2::TokenStream,
|
||||
}
|
||||
|
||||
fn generate_type_lifting_prolog(
|
||||
ty: &ParsedType,
|
||||
passing_style: &PassingStyle,
|
||||
generated_arg_id: usize,
|
||||
supplied_arg_start_id: usize,
|
||||
) -> TypeLifter {
|
||||
const CONVERTED_ARG_PREFIX: &str = "converted_arg";
|
||||
|
||||
let converted_arg_ident = new_ident!(format!("{}_{}", CONVERTED_ARG_PREFIX, generated_arg_id));
|
||||
let type_modifier = converted_arg_modifier(passing_style);
|
||||
|
||||
let type_lifter_glue_code = match ty {
|
||||
ParsedType::Boolean(_) => {
|
||||
let supplied_arg_start_id = new_ident!(format!("arg_{}", supplied_arg_start_id));
|
||||
quote! {
|
||||
let #type_modifier #converted_arg_ident = #supplied_arg_start_id != 0;
|
||||
}
|
||||
}
|
||||
ty if !ty.is_complex_type() => {
|
||||
let supplied_arg_start_id = new_ident!(format!("arg_{}", supplied_arg_start_id));
|
||||
quote! {
|
||||
let #type_modifier #converted_arg_ident = #supplied_arg_start_id as _;
|
||||
}
|
||||
}
|
||||
ty => {
|
||||
// all complex types are represented with pointer and size
|
||||
let ptr = new_ident!(format!("arg_{}", supplied_arg_start_id));
|
||||
let size = new_ident!(format!("arg_{}", supplied_arg_start_id + 1));
|
||||
match ty {
|
||||
ParsedType::Utf8Str(_) | ParsedType::Utf8String(_) => quote! {
|
||||
let #type_modifier #converted_arg_ident = String::from_raw_parts(#ptr as _, #size as _ , #size as _);
|
||||
},
|
||||
ParsedType::Vector(ty, _) => {
|
||||
let generated_der_name =
|
||||
format!("__m_generated_vec_deserializer_{}", supplied_arg_start_id);
|
||||
let generated_der_name = crate::utils::prepare_ident(generated_der_name);
|
||||
let generated_der_ident = new_ident!(generated_der_name);
|
||||
|
||||
let vector_deserializer =
|
||||
super::vector_ser_der::generate_vector_der(ty, &generated_der_name);
|
||||
|
||||
quote! {
|
||||
#vector_deserializer
|
||||
let #type_modifier #converted_arg_ident = #generated_der_ident(#ptr as _, #size as _);
|
||||
}
|
||||
}
|
||||
ParsedType::Record(record_name, _) => {
|
||||
let record_ident = new_ident!(record_name);
|
||||
quote! {
|
||||
let #type_modifier #converted_arg_ident = #record_ident::__m_generated_deserialize(#ptr as _);
|
||||
}
|
||||
}
|
||||
_ => panic!(
|
||||
"perhaps new type's been added to ParsedType, and this match became incomplete"
|
||||
),
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
TypeLifter {
|
||||
converted_arg_ident,
|
||||
type_lifter_glue_code,
|
||||
}
|
||||
}
|
||||
|
||||
fn converted_arg_modifier(passing_style: &PassingStyle) -> proc_macro2::TokenStream {
|
||||
match passing_style {
|
||||
PassingStyle::ByMutRef => quote! { mut },
|
||||
_ => quote! {},
|
||||
}
|
||||
}
|
@ -1,63 +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 super::ParsedType;
|
||||
use quote::quote;
|
||||
|
||||
/// This trait could be used to generate raw args needed to construct a wrapper of an import
|
||||
/// function.
|
||||
pub(crate) trait ForeignModArgGlueCodeGenerator {
|
||||
fn generate_raw_args(&self, arg_start_id: usize) -> proc_macro2::TokenStream;
|
||||
}
|
||||
|
||||
impl ForeignModArgGlueCodeGenerator for ParsedType {
|
||||
fn generate_raw_args(&self, arg_start_id: usize) -> proc_macro2::TokenStream {
|
||||
let arg = crate::new_ident!(format!("arg_{}", arg_start_id));
|
||||
|
||||
match self {
|
||||
ParsedType::Utf8Str(_) | ParsedType::Utf8String(_) => {
|
||||
quote! { #arg.as_ptr() as _, #arg.len() as _ }
|
||||
}
|
||||
ParsedType::Vector(..) => {
|
||||
quote! { #arg.0 as _, #arg.1 as _ }
|
||||
}
|
||||
ParsedType::Record(..) => quote! {
|
||||
#arg.__m_generated_serialize() as _
|
||||
},
|
||||
ty @ ParsedType::Boolean(_) => {
|
||||
let deref_sign = maybe_deref(ty);
|
||||
quote! { #deref_sign#arg as _ }
|
||||
}
|
||||
// this branch shouldn't be unite with booleans because otherwise
|
||||
// conversion errors could be lost due to `as _` usage
|
||||
ty => {
|
||||
let deref_sign = maybe_deref(ty);
|
||||
quote! { #deref_sign#arg }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn maybe_deref(ty: &ParsedType) -> proc_macro2::TokenStream {
|
||||
use crate::parsed_type::PassingStyle;
|
||||
|
||||
let passing_style = crate::parsed_type::passing_style_of(ty);
|
||||
|
||||
match passing_style {
|
||||
PassingStyle::ByValue => proc_macro2::TokenStream::new(),
|
||||
_ => quote! { * },
|
||||
}
|
||||
}
|
@ -1,85 +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 super::ParsedType;
|
||||
use crate::new_ident;
|
||||
|
||||
use quote::quote;
|
||||
|
||||
/// This trait could be used to generate various parts needed to construct epilog of an wrapper of
|
||||
/// import function.
|
||||
pub(crate) trait ForeignModEpilogGlueCodeGenerator {
|
||||
fn generate_wrapper_return_type(&self) -> proc_macro2::TokenStream;
|
||||
|
||||
fn generate_wrapper_epilog(&self) -> proc_macro2::TokenStream;
|
||||
}
|
||||
|
||||
impl ForeignModEpilogGlueCodeGenerator for Option<ParsedType> {
|
||||
fn generate_wrapper_return_type(&self) -> proc_macro2::TokenStream {
|
||||
use quote::ToTokens;
|
||||
|
||||
match self {
|
||||
Some(ty) => {
|
||||
let ty = ty.to_token_stream();
|
||||
quote! { -> #ty }
|
||||
}
|
||||
None => quote!(),
|
||||
}
|
||||
}
|
||||
|
||||
fn generate_wrapper_epilog(&self) -> proc_macro2::TokenStream {
|
||||
match self {
|
||||
None => quote!(),
|
||||
Some(ParsedType::Boolean(_)) => quote! {
|
||||
return result != 0;
|
||||
},
|
||||
Some(ty) if !ty.is_complex_type() => quote! {
|
||||
return result as _;
|
||||
},
|
||||
Some(ParsedType::Utf8String(_)) => quote! {
|
||||
String::from_raw_parts(
|
||||
marine_rs_sdk::internal::get_result_ptr() as _,
|
||||
marine_rs_sdk::internal::get_result_size() as _,
|
||||
marine_rs_sdk::internal::get_result_size() as _
|
||||
)
|
||||
},
|
||||
Some(ParsedType::Vector(ty, _)) => {
|
||||
let generated_der_name = "__m_generated_vec_deserializer";
|
||||
let generated_der_ident = new_ident!(generated_der_name);
|
||||
let vector_deserializer =
|
||||
super::vector_ser_der::generate_vector_der(ty, generated_der_name);
|
||||
|
||||
quote! {
|
||||
#vector_deserializer
|
||||
#generated_der_ident(
|
||||
marine_rs_sdk::internal::get_result_ptr() as _,
|
||||
marine_rs_sdk::internal::get_result_size() as _,
|
||||
)
|
||||
}
|
||||
}
|
||||
Some(ParsedType::Record(record_name, _)) => {
|
||||
let record_ident = new_ident!(record_name);
|
||||
|
||||
quote! {
|
||||
#record_ident::__m_generated_deserialize(marine_rs_sdk::internal::get_result_ptr() as _)
|
||||
}
|
||||
}
|
||||
_ => panic!(
|
||||
"perhaps new type's been added to ParsedType, and this match became incomplete"
|
||||
),
|
||||
}
|
||||
}
|
||||
}
|
@ -1,145 +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 super::ParsedType;
|
||||
use crate::wasm_type::RustType;
|
||||
use crate::new_ident;
|
||||
use crate::parsed_type::PassingStyle;
|
||||
use crate::ast_types::AstFnArgument;
|
||||
|
||||
pub(crate) struct WrapperDescriptor {
|
||||
pub(crate) arg_names: Vec<syn::Ident>,
|
||||
pub(crate) arg_types: Vec<proc_macro2::TokenStream>,
|
||||
pub(crate) raw_args: Vec<proc_macro2::TokenStream>,
|
||||
pub(crate) arg_transforms: proc_macro2::TokenStream,
|
||||
pub(crate) arg_drops: proc_macro2::TokenStream,
|
||||
}
|
||||
|
||||
pub(crate) struct ExternDescriptor {
|
||||
pub(crate) raw_arg_names: Vec<syn::Ident>,
|
||||
pub(crate) raw_arg_types: Vec<RustType>,
|
||||
}
|
||||
|
||||
/// This trait could be used to generate various parts needed to construct prolog of an wrapper
|
||||
/// function or extern block. They are marked with # in the following examples:
|
||||
/// ```ignore
|
||||
/// quote! {
|
||||
/// fn foo(#(#arg_names: #arg_types), *) {
|
||||
/// let arg_1 = std::mem::ManuallyDrop::new(arg_1);
|
||||
/// let result = original_foo(#(#raw_args), *);
|
||||
/// std::mem::ManuallyDrop::drop(&mut arg_1);
|
||||
/// ...
|
||||
/// }
|
||||
/// }
|
||||
/// ```
|
||||
///
|
||||
/// ```ignore
|
||||
/// quote! {
|
||||
/// extern "C" {
|
||||
/// #[link_name = "foo_link_name"]
|
||||
/// pub fn foo(#(#raw_arg_names: #raw_arg_types),*);
|
||||
/// }
|
||||
/// }
|
||||
/// ```
|
||||
pub(crate) trait ForeignModPrologGlueCodeGenerator {
|
||||
fn generate_wrapper_prolog(&self) -> WrapperDescriptor;
|
||||
fn generate_extern_prolog(&self) -> ExternDescriptor;
|
||||
}
|
||||
|
||||
impl ForeignModPrologGlueCodeGenerator for Vec<AstFnArgument> {
|
||||
fn generate_wrapper_prolog(&self) -> WrapperDescriptor {
|
||||
use crate::parsed_type::foreign_mod_arg::ForeignModArgGlueCodeGenerator;
|
||||
use quote::ToTokens;
|
||||
|
||||
let arg_types: Vec<proc_macro2::TokenStream> =
|
||||
self.iter().map(|arg| arg.ty.to_token_stream()).collect();
|
||||
|
||||
let (arg_names, arg_transforms, arg_drops) = self
|
||||
.iter()
|
||||
.enumerate()
|
||||
.fold((Vec::new(), proc_macro2::TokenStream::new(), proc_macro2::TokenStream::new()), |(mut arg_names, mut arg_transforms, mut arg_drops), (id, arg)| {
|
||||
let arg_name = format!("arg_{}", id);
|
||||
let arg_ident = new_ident!(arg_name);
|
||||
|
||||
// arguments of following two types shouldn't be deleted after transformation to raw view
|
||||
match &arg.ty {
|
||||
ParsedType::Utf8String(PassingStyle::ByValue) => {
|
||||
arg_transforms.extend(quote::quote! { let mut #arg_ident = std::mem::ManuallyDrop::new(#arg_ident); });
|
||||
arg_drops.extend(quote::quote! { std::mem::ManuallyDrop::drop(&mut #arg_ident); });
|
||||
},
|
||||
ParsedType::Vector(ty, _) => {
|
||||
let vec_arg_transforms = vector_arg_transforms(ty, &arg_name);
|
||||
arg_transforms.extend(vec_arg_transforms);
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
|
||||
arg_names.push(arg_ident);
|
||||
(arg_names, arg_transforms, arg_drops)
|
||||
});
|
||||
|
||||
let raw_args: Vec<proc_macro2::TokenStream> = self
|
||||
.iter()
|
||||
.enumerate()
|
||||
.map(|(id, arg)| arg.ty.generate_raw_args(id))
|
||||
.collect();
|
||||
|
||||
WrapperDescriptor {
|
||||
arg_names,
|
||||
arg_types,
|
||||
raw_args,
|
||||
arg_transforms,
|
||||
arg_drops,
|
||||
}
|
||||
}
|
||||
|
||||
fn generate_extern_prolog(&self) -> ExternDescriptor {
|
||||
use crate::parsed_type::FnArgGlueCodeGenerator;
|
||||
|
||||
let raw_arg_types: Vec<RustType> = self
|
||||
.iter()
|
||||
.map(|input_type| input_type.generate_arguments())
|
||||
.flatten()
|
||||
.collect();
|
||||
let raw_arg_names: Vec<syn::Ident> = raw_arg_types
|
||||
.iter()
|
||||
.enumerate()
|
||||
.map(|(id, _)| new_ident!(format!("arg_{}", id)))
|
||||
.collect();
|
||||
|
||||
ExternDescriptor {
|
||||
raw_arg_names,
|
||||
raw_arg_types,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn vector_arg_transforms(ty: &ParsedType, arg_name: &str) -> proc_macro2::TokenStream {
|
||||
let generated_ser_name = format!("__m_generated_vec_serializer_{}", arg_name);
|
||||
let generated_ser_name = crate::utils::prepare_ident(generated_ser_name);
|
||||
let generated_ser_ident = new_ident!(generated_ser_name);
|
||||
let arg_ident = new_ident!(arg_name);
|
||||
|
||||
let vector_serializer = super::vector_ser_der::generate_vector_ser(ty, &generated_ser_name);
|
||||
|
||||
let arg_transform = quote::quote! {
|
||||
#vector_serializer
|
||||
|
||||
let #arg_ident = #generated_ser_ident(&#arg_ident);
|
||||
};
|
||||
|
||||
arg_transform
|
||||
}
|
@ -1,150 +0,0 @@
|
||||
/*
|
||||
* Copyright 2018 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::PassingStyle;
|
||||
use super::ParsedType;
|
||||
|
||||
use quote::quote;
|
||||
use proc_macro2::TokenStream;
|
||||
|
||||
use std::fmt;
|
||||
|
||||
impl quote::ToTokens for PassingStyle {
|
||||
fn to_tokens(&self, tokens: &mut TokenStream) {
|
||||
tokens.extend(self.to_token_stream());
|
||||
}
|
||||
|
||||
fn to_token_stream(&self) -> TokenStream {
|
||||
match self {
|
||||
PassingStyle::ByValue => quote! {},
|
||||
PassingStyle::ByRef => quote! { & },
|
||||
PassingStyle::ByMutRef => quote! { &mut },
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl quote::ToTokens for ParsedType {
|
||||
fn to_tokens(&self, tokens: &mut TokenStream) {
|
||||
tokens.extend(self.to_token_stream());
|
||||
}
|
||||
|
||||
fn to_token_stream(&self) -> proc_macro2::TokenStream {
|
||||
match self {
|
||||
ParsedType::I8(passing_style) => quote! { #passing_style i8 },
|
||||
ParsedType::I16(passing_style) => quote! { #passing_style i16 },
|
||||
ParsedType::I32(passing_style) => quote! { #passing_style i32 },
|
||||
ParsedType::I64(passing_style) => quote! { #passing_style i64 },
|
||||
ParsedType::U8(passing_style) => quote! { #passing_style u8 },
|
||||
ParsedType::U16(passing_style) => quote! { #passing_style u16 },
|
||||
ParsedType::U32(passing_style) => quote! { #passing_style u32 },
|
||||
ParsedType::U64(passing_style) => quote! { #passing_style u64 },
|
||||
ParsedType::F32(passing_style) => quote! { #passing_style f32 },
|
||||
ParsedType::F64(passing_style) => quote! { #passing_style f64 },
|
||||
ParsedType::Boolean(passing_style) => quote! { #passing_style bool },
|
||||
ParsedType::Utf8Str(passing_style) => quote! { #passing_style str },
|
||||
ParsedType::Utf8String(passing_style) => quote! { #passing_style String },
|
||||
ParsedType::Vector(ty, passing_style) => {
|
||||
let quoted_type = ty.to_token_stream();
|
||||
quote! { #passing_style Vec<#quoted_type> }
|
||||
}
|
||||
ParsedType::Record(name, passing_style) => {
|
||||
let ty = crate::new_ident!(name);
|
||||
quote! { #passing_style #ty }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for ParsedType {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
|
||||
match self {
|
||||
ParsedType::Boolean(passing_style) => {
|
||||
passing_style.fmt(f)?;
|
||||
f.write_str("bool")
|
||||
}
|
||||
ParsedType::I8(passing_style) => {
|
||||
passing_style.fmt(f)?;
|
||||
f.write_str("i8")
|
||||
}
|
||||
ParsedType::I16(passing_style) => {
|
||||
passing_style.fmt(f)?;
|
||||
f.write_str("i16")
|
||||
}
|
||||
ParsedType::I32(passing_style) => {
|
||||
passing_style.fmt(f)?;
|
||||
f.write_str("i32")
|
||||
}
|
||||
ParsedType::I64(passing_style) => {
|
||||
passing_style.fmt(f)?;
|
||||
f.write_str("i64")
|
||||
}
|
||||
ParsedType::U8(passing_style) => {
|
||||
passing_style.fmt(f)?;
|
||||
f.write_str("u8")
|
||||
}
|
||||
ParsedType::U16(passing_style) => {
|
||||
passing_style.fmt(f)?;
|
||||
f.write_str("u16")
|
||||
}
|
||||
ParsedType::U32(passing_style) => {
|
||||
passing_style.fmt(f)?;
|
||||
f.write_str("u32")
|
||||
}
|
||||
ParsedType::U64(passing_style) => {
|
||||
passing_style.fmt(f)?;
|
||||
f.write_str("u64")
|
||||
}
|
||||
ParsedType::F32(passing_style) => {
|
||||
passing_style.fmt(f)?;
|
||||
f.write_str("f32")
|
||||
}
|
||||
ParsedType::F64(passing_style) => {
|
||||
passing_style.fmt(f)?;
|
||||
f.write_str("u64")
|
||||
}
|
||||
ParsedType::Utf8Str(passing_style) => {
|
||||
passing_style.fmt(f)?;
|
||||
f.write_str("str")
|
||||
}
|
||||
ParsedType::Utf8String(passing_style) => {
|
||||
passing_style.fmt(f)?;
|
||||
f.write_str("String")
|
||||
}
|
||||
ParsedType::Vector(ty, passing_style) => {
|
||||
passing_style.fmt(f)?;
|
||||
f.write_str("Vec<")?;
|
||||
ty.fmt(f)?;
|
||||
f.write_str(">")
|
||||
}
|
||||
ParsedType::Record(record_name, passing_style) => {
|
||||
passing_style.fmt(f)?;
|
||||
f.write_str(&record_name)
|
||||
}
|
||||
}?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for PassingStyle {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
|
||||
match self {
|
||||
PassingStyle::ByValue => Ok(()),
|
||||
PassingStyle::ByRef => f.write_str("&"),
|
||||
PassingStyle::ByMutRef => f.write_str("&mut"),
|
||||
}
|
||||
}
|
||||
}
|
@ -1,39 +0,0 @@
|
||||
/*
|
||||
* 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::ParsedType;
|
||||
use super::PassingStyle;
|
||||
|
||||
pub(crate) fn passing_style_of(ty: &ParsedType) -> &PassingStyle {
|
||||
use ParsedType::*;
|
||||
|
||||
match ty {
|
||||
Boolean(passing_style) => passing_style,
|
||||
U8(passing_style) => passing_style,
|
||||
U16(passing_style) => passing_style,
|
||||
U32(passing_style) => passing_style,
|
||||
U64(passing_style) => passing_style,
|
||||
I8(passing_style) => passing_style,
|
||||
I16(passing_style) => passing_style,
|
||||
I32(passing_style) => passing_style,
|
||||
I64(passing_style) => passing_style,
|
||||
F32(passing_style) => passing_style,
|
||||
F64(passing_style) => passing_style,
|
||||
Utf8Str(passing_style) => passing_style,
|
||||
Utf8String(passing_style) => passing_style,
|
||||
Vector(_, passing_style) => passing_style,
|
||||
Record(_, passing_style) => passing_style,
|
||||
}
|
||||
}
|
@ -1,98 +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.
|
||||
*/
|
||||
|
||||
mod der;
|
||||
mod ser;
|
||||
|
||||
use ser::*;
|
||||
use der::*;
|
||||
use super::ParsedType;
|
||||
|
||||
use quote::quote;
|
||||
|
||||
pub(crate) fn generate_vector_ser(
|
||||
value_ty: &ParsedType,
|
||||
arg_name: &str,
|
||||
) -> proc_macro2::TokenStream {
|
||||
let values_ser = match value_ty {
|
||||
ParsedType::Boolean(_) => {
|
||||
quote! {
|
||||
let converted_bool_vector: Vec<u8> = arg.into_iter().map(|v| *v as u8).collect::<_>();
|
||||
let ptr = converted_bool_vector.as_ptr();
|
||||
let len = converted_bool_vector.len();
|
||||
|
||||
marine_rs_sdk::internal::add_object_to_release(Box::new(converted_bool_vector));
|
||||
|
||||
(ptr as _, len as _)
|
||||
}
|
||||
}
|
||||
ParsedType::I8(_)
|
||||
| ParsedType::U8(_)
|
||||
| ParsedType::I16(_)
|
||||
| ParsedType::U16(_)
|
||||
| ParsedType::I32(_)
|
||||
| ParsedType::U32(_)
|
||||
| ParsedType::I64(_)
|
||||
| ParsedType::U64(_)
|
||||
| ParsedType::F32(_)
|
||||
| ParsedType::F64(_) => {
|
||||
quote! {
|
||||
(arg.as_ptr() as _, arg.len() as _)
|
||||
}
|
||||
}
|
||||
ParsedType::Utf8Str(_) | ParsedType::Utf8String(_) => string_ser(),
|
||||
ParsedType::Vector(ty, _) => vector_ser(arg_name, ty),
|
||||
ParsedType::Record(..) => record_ser(),
|
||||
};
|
||||
|
||||
let arg = crate::new_ident!(arg_name);
|
||||
|
||||
quote! {
|
||||
unsafe fn #arg(arg: &Vec<#value_ty>) -> (u32, u32) {
|
||||
#values_ser
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn generate_vector_der(
|
||||
value_ty: &ParsedType,
|
||||
arg_name: &str,
|
||||
) -> proc_macro2::TokenStream {
|
||||
let arg = crate::new_ident!(arg_name);
|
||||
|
||||
let values_deserializer = match value_ty {
|
||||
ParsedType::Boolean(_) => {
|
||||
quote! {
|
||||
let arg: Vec<u8> = Vec::from_raw_parts(offset as _, size as _, size as _);
|
||||
arg.into_iter().map(|v| v != 0).collect::<Vec<bool>>()
|
||||
}
|
||||
}
|
||||
ParsedType::Utf8Str(_) | ParsedType::Utf8String(_) => string_der(),
|
||||
ParsedType::Vector(ty, _) => vector_der(arg_name, ty),
|
||||
ParsedType::Record(record_name, _) => record_der(record_name),
|
||||
_ => {
|
||||
quote! {
|
||||
Vec::from_raw_parts(offset as _, size as _, size as _)
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
quote! {
|
||||
unsafe fn #arg(offset: u32, size: u32) -> Vec<#value_ty> {
|
||||
#values_deserializer
|
||||
}
|
||||
}
|
||||
}
|
@ -1,78 +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::ParsedType;
|
||||
|
||||
use quote::quote;
|
||||
|
||||
pub(super) fn string_der() -> proc_macro2::TokenStream {
|
||||
quote! {
|
||||
let vec_passing_size = 2;
|
||||
let mut arg: Vec<u32> = Vec::from_raw_parts(offset as _, (vec_passing_size * size) as _, (vec_passing_size * size) as _);
|
||||
let mut arg = arg.into_iter();
|
||||
let mut result = Vec::with_capacity(arg.len() / 2);
|
||||
|
||||
while let Some(offset) = arg.next() {
|
||||
let size = arg.next().unwrap();
|
||||
let value = String::from_raw_parts(offset as _, size as _, size as _);
|
||||
result.push(value);
|
||||
}
|
||||
|
||||
result
|
||||
}
|
||||
}
|
||||
|
||||
pub(super) fn vector_der(arg_name: &str, ty: &ParsedType) -> proc_macro2::TokenStream {
|
||||
let deserializer_name = format!("{}_{}", arg_name, ty);
|
||||
let deserializer_name = crate::utils::prepare_ident(deserializer_name);
|
||||
let deserializer_ident = crate::new_ident!(deserializer_name);
|
||||
|
||||
let inner_vector_deserializer = super::generate_vector_der(&*ty, &deserializer_name);
|
||||
|
||||
quote! {
|
||||
#inner_vector_deserializer
|
||||
|
||||
let vec_passing_size = 2;
|
||||
let mut arg: Vec<u32> = Vec::from_raw_parts(offset as _, (vec_passing_size * size) as _, (vec_passing_size * size) as _);
|
||||
let mut result = Vec::with_capacity(arg.len());
|
||||
|
||||
let mut arg = arg.into_iter();
|
||||
while let Some(offset) = arg.next() {
|
||||
let size = arg.next().unwrap();
|
||||
|
||||
let value = #deserializer_ident(offset as _, size as _);
|
||||
result.push(value);
|
||||
}
|
||||
|
||||
result
|
||||
}
|
||||
}
|
||||
|
||||
pub(super) fn record_der(record_name: &str) -> proc_macro2::TokenStream {
|
||||
let record_name_ident = crate::new_ident!(record_name);
|
||||
|
||||
quote! {
|
||||
let mut arg: Vec<u32> = Vec::from_raw_parts(offset as _, size as _, size as _);
|
||||
let mut result = Vec::with_capacity(arg.len());
|
||||
|
||||
for offset in arg {
|
||||
let value = #record_name_ident::__m_generated_deserialize(offset as _);
|
||||
result.push(value);
|
||||
}
|
||||
|
||||
result
|
||||
}
|
||||
}
|
@ -1,77 +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 super::ParsedType;
|
||||
|
||||
use quote::quote;
|
||||
|
||||
pub(super) fn string_ser() -> proc_macro2::TokenStream {
|
||||
quote! {
|
||||
let mut result: Vec<u32> = Vec::with_capacity(arg.len());
|
||||
|
||||
for value in arg {
|
||||
result.push(value.as_ptr() as _);
|
||||
result.push(value.len() as _);
|
||||
}
|
||||
|
||||
let result_ptr = result.as_ptr();
|
||||
let result_len = result.len() / 2;
|
||||
marine_rs_sdk::internal::add_object_to_release(Box::new(result));
|
||||
|
||||
(result_ptr as _, result_len as _)
|
||||
}
|
||||
}
|
||||
|
||||
pub(super) fn vector_ser(arg_name: &str, ty: &ParsedType) -> proc_macro2::TokenStream {
|
||||
let ser_name = format!("{}_{}", arg_name, ty);
|
||||
let ser_name = crate::utils::prepare_ident(ser_name);
|
||||
let ser_ident = crate::new_ident!(ser_name);
|
||||
|
||||
let inner_vector_ser = super::generate_vector_ser(ty, &ser_name);
|
||||
|
||||
quote! {
|
||||
#inner_vector_ser
|
||||
|
||||
let mut result: Vec<u32> = Vec::with_capacity(2 * arg.len());
|
||||
for value in arg {
|
||||
let (ptr, size) = #ser_ident(&value);
|
||||
result.push(ptr as _);
|
||||
result.push(size as _);
|
||||
}
|
||||
|
||||
let result_ptr = result.as_ptr();
|
||||
let result_len = result.len() / 2;
|
||||
marine_rs_sdk::internal::add_object_to_release(Box::new(result));
|
||||
|
||||
(result_ptr as _, result_len as _)
|
||||
}
|
||||
}
|
||||
|
||||
pub(super) fn record_ser() -> proc_macro2::TokenStream {
|
||||
quote! {
|
||||
let mut result: Vec<u32> = Vec::with_capacity(arg.len());
|
||||
|
||||
for value in arg {
|
||||
result.push(value.__m_generated_serialize() as _);
|
||||
}
|
||||
|
||||
let result_ptr = result.as_ptr();
|
||||
let result_len = result.len();
|
||||
marine_rs_sdk::internal::add_object_to_release(Box::new(result));
|
||||
|
||||
(result_ptr as _, result_len as _)
|
||||
}
|
||||
}
|
@ -1,35 +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.
|
||||
*/
|
||||
|
||||
mod fn_generator;
|
||||
mod foreign_mod_generator;
|
||||
mod record_generator;
|
||||
|
||||
use crate::ast_types::MarineAst;
|
||||
|
||||
pub const GENERATED_WRAPPER_FUNC_PREFIX: &str = "__m_generated_wrapper_func_";
|
||||
pub const GENERATED_SECTION_PREFIX: &str = "__m_generated_section__";
|
||||
pub const GENERATED_GLOBAL_PREFIX: &str = "__m_generated_static_global_";
|
||||
|
||||
impl quote::ToTokens for MarineAst {
|
||||
fn to_tokens(&self, tokens: &mut proc_macro2::TokenStream) {
|
||||
match self {
|
||||
MarineAst::Function(ast_function) => ast_function.to_tokens(tokens),
|
||||
MarineAst::ExternMod(ast_extern) => ast_extern.to_tokens(tokens),
|
||||
MarineAst::Record(ast_record) => ast_record.to_tokens(tokens),
|
||||
}
|
||||
}
|
||||
}
|
@ -1,103 +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::ast_types;
|
||||
use crate::parsed_type::FnEpilogGlueCodeGenerator;
|
||||
use crate::parsed_type::FnEpilogDescriptor;
|
||||
use crate::parsed_type::FnEpilogIngredients;
|
||||
use crate::parsed_type::FnPrologGlueCodeGenerator;
|
||||
use crate::parsed_type::FnPrologDescriptor;
|
||||
|
||||
use crate::new_ident;
|
||||
|
||||
use proc_macro2::TokenStream;
|
||||
|
||||
impl quote::ToTokens for ast_types::AstFn {
|
||||
fn to_tokens(&self, tokens: &mut TokenStream) {
|
||||
crate::prepare_global_data!(
|
||||
Function,
|
||||
self,
|
||||
self.signature.name,
|
||||
data,
|
||||
data_size,
|
||||
global_static_name,
|
||||
section_name
|
||||
);
|
||||
|
||||
let signature = &self.signature;
|
||||
let func_name = new_ident!(format!(
|
||||
"{}{}",
|
||||
super::GENERATED_WRAPPER_FUNC_PREFIX,
|
||||
signature.name
|
||||
));
|
||||
let original_func_ident = new_ident!(signature.name);
|
||||
let export_func_name = &signature.name;
|
||||
|
||||
let FnPrologDescriptor {
|
||||
raw_arg_names,
|
||||
raw_arg_types,
|
||||
prolog,
|
||||
converted_arg_idents,
|
||||
args,
|
||||
} = &signature.arguments.generate_prolog();
|
||||
|
||||
let epilog_ingredients = FnEpilogIngredients {
|
||||
args: &signature.arguments,
|
||||
converted_args: converted_arg_idents,
|
||||
return_type: &signature.output_type,
|
||||
};
|
||||
|
||||
let FnEpilogDescriptor {
|
||||
fn_return_type,
|
||||
return_expression,
|
||||
epilog,
|
||||
objs_savings,
|
||||
} = epilog_ingredients.generate_fn_epilog();
|
||||
|
||||
let original_func = &self.original;
|
||||
|
||||
let glue_code = quote::quote! {
|
||||
#original_func
|
||||
|
||||
#[cfg(target_arch = "wasm32")]
|
||||
#[export_name = #export_func_name]
|
||||
#[no_mangle]
|
||||
#[doc(hidden)]
|
||||
#[allow(clippy::all)]
|
||||
pub unsafe fn #func_name(#(#raw_arg_names: #raw_arg_types),*) #fn_return_type {
|
||||
// arguments conversation from Wasm types to Rust types
|
||||
#prolog
|
||||
|
||||
// calling the original function with converted args
|
||||
#return_expression #original_func_ident(#(#args), *);
|
||||
|
||||
// return value conversation from Rust type to a Wasm type
|
||||
#epilog
|
||||
|
||||
// save objects to keep them in memory for lifting
|
||||
#objs_savings
|
||||
}
|
||||
|
||||
#[cfg(target_arch = "wasm32")]
|
||||
#[doc(hidden)]
|
||||
#[allow(clippy::all)]
|
||||
#[link_section = #section_name]
|
||||
pub static #global_static_name: [u8; #data_size] = { *#data };
|
||||
};
|
||||
|
||||
tokens.extend(glue_code);
|
||||
}
|
||||
}
|
@ -1,191 +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::ast_types;
|
||||
use crate::new_ident;
|
||||
use crate::parsed_type::*;
|
||||
|
||||
use proc_macro2::TokenStream;
|
||||
use quote::quote;
|
||||
|
||||
impl quote::ToTokens for ast_types::AstExternMod {
|
||||
fn to_tokens(&self, tokens: &mut TokenStream) {
|
||||
crate::prepare_global_data!(
|
||||
ExternMod,
|
||||
self,
|
||||
self.namespace,
|
||||
data,
|
||||
data_size,
|
||||
global_static_name,
|
||||
section_name
|
||||
);
|
||||
|
||||
let wasm_import_module_name = &self.namespace;
|
||||
let wasm_section_items = generate_extern_section_items(&self, wasm_extern_item_generator);
|
||||
let not_wasm_section_items =
|
||||
generate_extern_section_items(&self, not_wasm_extern_item_generator);
|
||||
|
||||
let wrapper_functions = generate_wrapper_functions(&self);
|
||||
|
||||
let glue_code = quote! {
|
||||
#[link(wasm_import_module = #wasm_import_module_name)]
|
||||
#[cfg(target_arch = "wasm32")]
|
||||
extern "C" {
|
||||
#(#wasm_section_items)*
|
||||
}
|
||||
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
extern "C" {
|
||||
#(#not_wasm_section_items)*
|
||||
}
|
||||
|
||||
#wrapper_functions
|
||||
|
||||
#[cfg(target_arch = "wasm32")]
|
||||
#[doc(hidden)]
|
||||
#[allow(clippy::all)]
|
||||
#[link_section = #section_name]
|
||||
pub static #global_static_name: [u8; #data_size] = { *#data };
|
||||
};
|
||||
|
||||
tokens.extend(glue_code);
|
||||
}
|
||||
}
|
||||
|
||||
fn generate_extern_section_items(
|
||||
extern_item: &ast_types::AstExternMod,
|
||||
item_generator: fn(&ast_types::AstExternFn) -> TokenStream,
|
||||
) -> Vec<TokenStream> {
|
||||
let mut section_items = Vec::with_capacity(extern_item.imports.len());
|
||||
|
||||
for import in &extern_item.imports {
|
||||
section_items.push(item_generator(&import));
|
||||
}
|
||||
|
||||
section_items
|
||||
}
|
||||
|
||||
fn wasm_extern_item_generator(import: &ast_types::AstExternFn) -> TokenStream {
|
||||
let signature = &import.signature;
|
||||
let fn_return_type = crate::parsed_type::generate_fn_return_type(&signature.output_type);
|
||||
let link_name = import.link_name.as_ref().unwrap_or(&signature.name);
|
||||
let import_name = generate_import_name(&signature.name);
|
||||
let ExternDescriptor {
|
||||
raw_arg_names,
|
||||
raw_arg_types,
|
||||
} = signature.arguments.generate_extern_prolog();
|
||||
|
||||
quote! {
|
||||
#[link_name = #link_name]
|
||||
fn #import_name(#(#raw_arg_names: #raw_arg_types),*) #fn_return_type;
|
||||
}
|
||||
}
|
||||
|
||||
fn not_wasm_extern_item_generator(import: &ast_types::AstExternFn) -> TokenStream {
|
||||
let signature = &import.signature;
|
||||
let original_return_type =
|
||||
crate::parsed_type::generate_fn_original_return_type(&signature.output_type);
|
||||
let link_name = import.link_name.as_ref().unwrap_or(&signature.name);
|
||||
let import_name = generate_import_name(&signature.name);
|
||||
let original_arguments = generate_original_arguments(&signature.arguments);
|
||||
|
||||
quote! {
|
||||
#[link_name = #link_name]
|
||||
fn #import_name(#(#original_arguments),*) #original_return_type;
|
||||
}
|
||||
}
|
||||
|
||||
fn generate_original_arguments(
|
||||
arguments: &Vec<ast_types::AstFnArgument>,
|
||||
) -> Vec<proc_macro2::TokenStream> {
|
||||
arguments
|
||||
.iter()
|
||||
.map(|arg| {
|
||||
let name = crate::new_ident!(&arg.name);
|
||||
let ty = &arg.ty;
|
||||
quote! {#name : #ty}
|
||||
})
|
||||
.collect()
|
||||
}
|
||||
|
||||
#[rustfmt::skip]
|
||||
fn generate_import_name(import_name: &str) -> syn::Ident {
|
||||
crate::new_ident!(format!("{}_{}", super::GENERATED_WRAPPER_FUNC_PREFIX, import_name))
|
||||
}
|
||||
|
||||
fn generate_wrapper_functions(extern_item: &ast_types::AstExternMod) -> TokenStream {
|
||||
let mut token_stream = TokenStream::new();
|
||||
|
||||
for import in &extern_item.imports {
|
||||
let signature = &import.signature;
|
||||
|
||||
let visibility = &signature.visibility;
|
||||
let func_name = new_ident!(&signature.name);
|
||||
|
||||
let return_type = signature.output_type.generate_wrapper_return_type();
|
||||
let import_func_name = generate_import_name(&signature.name);
|
||||
|
||||
let WrapperDescriptor {
|
||||
arg_names,
|
||||
arg_types,
|
||||
raw_args,
|
||||
arg_transforms,
|
||||
arg_drops,
|
||||
} = signature.arguments.generate_wrapper_prolog();
|
||||
|
||||
let return_expression =
|
||||
crate::parsed_type::generate_return_expression(&signature.output_type);
|
||||
let epilog = signature.output_type.generate_wrapper_epilog();
|
||||
|
||||
let wrapper_func = quote! {
|
||||
#[cfg(target_arch = "wasm32")]
|
||||
#[doc(hidden)]
|
||||
#[allow(clippy::all)]
|
||||
#visibility fn #func_name(#(#arg_names: #arg_types), *) #return_type {
|
||||
unsafe {
|
||||
|
||||
// make complex arguments manually droppable
|
||||
#arg_transforms
|
||||
|
||||
// calling the original function with converted args
|
||||
#return_expression #import_func_name(#(#raw_args), *);
|
||||
|
||||
// drop complex arguments
|
||||
#arg_drops
|
||||
|
||||
// return value conversation from Wasm type to a Rust type
|
||||
#epilog
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
#[doc(hidden)]
|
||||
#[allow(clippy::all)]
|
||||
#visibility fn #func_name(#(#arg_names: #arg_types), *) #return_type {
|
||||
unsafe {
|
||||
// calling the original function with original args
|
||||
#import_func_name(#(#arg_names), *)
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
token_stream.extend(wrapper_func);
|
||||
}
|
||||
|
||||
token_stream
|
||||
}
|
@ -1,115 +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.
|
||||
*/
|
||||
|
||||
mod record_serializer;
|
||||
mod record_deserializer;
|
||||
mod field_values_builder;
|
||||
|
||||
use field_values_builder::*;
|
||||
use record_deserializer::*;
|
||||
use record_serializer::*;
|
||||
|
||||
use crate::new_ident;
|
||||
use crate::ast_types::AstRecord;
|
||||
use crate::ast_types::AstRecordFields;
|
||||
|
||||
impl quote::ToTokens for AstRecord {
|
||||
fn to_tokens(&self, tokens: &mut proc_macro2::TokenStream) {
|
||||
let original = &self.original;
|
||||
crate::prepare_global_data!(
|
||||
Record,
|
||||
self,
|
||||
self.name,
|
||||
data,
|
||||
data_size,
|
||||
global_static_name,
|
||||
section_name
|
||||
);
|
||||
let record_name = new_ident!(self.name);
|
||||
|
||||
let serializer_fn = generate_serializer_fn(self);
|
||||
let deserializer_fn = generate_deserializer_fn(self);
|
||||
|
||||
let glue_code = quote::quote! {
|
||||
#original
|
||||
|
||||
#[cfg(target_arch = "wasm32")]
|
||||
#[doc(hidden)]
|
||||
#[allow(clippy::all)]
|
||||
impl #record_name {
|
||||
#serializer_fn
|
||||
|
||||
#deserializer_fn
|
||||
}
|
||||
|
||||
#[cfg(target_arch = "wasm32")]
|
||||
#[doc(hidden)]
|
||||
#[allow(clippy::all)]
|
||||
#[link_section = #section_name]
|
||||
pub static #global_static_name: [u8; #data_size] = { *#data };
|
||||
};
|
||||
|
||||
tokens.extend(glue_code);
|
||||
}
|
||||
}
|
||||
|
||||
fn generate_serializer_fn(record: &AstRecord) -> proc_macro2::TokenStream {
|
||||
let serializer = record.generate_serializer();
|
||||
let fields_count = match &record.fields {
|
||||
AstRecordFields::Named(fields) => fields.len(),
|
||||
AstRecordFields::Unnamed(fields) => fields.len(),
|
||||
AstRecordFields::Unit => return proc_macro2::TokenStream::new(),
|
||||
};
|
||||
|
||||
quote::quote! {
|
||||
pub fn __m_generated_serialize(&self) -> *const u8 {
|
||||
// 4 is an average size of a possible record field
|
||||
let mut raw_record: Vec<u8> = Vec::with_capacity(4 * #fields_count);
|
||||
|
||||
#serializer
|
||||
|
||||
let raw_record_ptr = raw_record.as_ptr();
|
||||
marine_rs_sdk::internal::add_object_to_release(Box::new(raw_record));
|
||||
|
||||
raw_record_ptr as _
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn generate_deserializer_fn(record: &AstRecord) -> proc_macro2::TokenStream {
|
||||
let RecordDerDescriptor {
|
||||
fields_der,
|
||||
record_ctor,
|
||||
} = record.generate_der();
|
||||
|
||||
let fields = match &record.fields {
|
||||
AstRecordFields::Named(fields) => fields,
|
||||
AstRecordFields::Unnamed(fields) => fields,
|
||||
AstRecordFields::Unit => return proc_macro2::TokenStream::new(),
|
||||
};
|
||||
|
||||
let record_size = crate::utils::get_record_size(fields.iter().map(|ast_field| &ast_field.ty));
|
||||
|
||||
quote::quote! {
|
||||
pub unsafe fn __m_generated_deserialize(record_ptr: *const u8) -> Self {
|
||||
let raw_record: Vec<u8> = Vec::from_raw_parts(record_ptr as _, #record_size, #record_size);
|
||||
|
||||
#fields_der
|
||||
|
||||
#record_ctor
|
||||
}
|
||||
}
|
||||
}
|
@ -1,318 +0,0 @@
|
||||
/*
|
||||
* 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::new_ident;
|
||||
use crate::parsed_type::ParsedType;
|
||||
use crate::ast_types::*;
|
||||
|
||||
use proc_macro2::TokenStream;
|
||||
use quote::quote;
|
||||
|
||||
pub(super) struct FieldValuesBuilder {
|
||||
value_id: usize,
|
||||
fields_der: TokenStream,
|
||||
field_value_idents: Vec<syn::Ident>,
|
||||
}
|
||||
|
||||
/// Contains all necessary info to construct record fields.
|
||||
pub(super) struct FieldValuesOutcome {
|
||||
/// Generated deserializer for each record field.
|
||||
pub(super) fields_der: TokenStream,
|
||||
|
||||
/// Idents of each record field.
|
||||
pub(super) field_value_idents: Vec<syn::Ident>,
|
||||
}
|
||||
|
||||
impl FieldValuesBuilder {
|
||||
pub(super) fn build<'a>(
|
||||
fields: impl ExactSizeIterator<Item = &'a AstRecordField>,
|
||||
) -> FieldValuesOutcome {
|
||||
let values_builder = Self::new(fields.len());
|
||||
values_builder.build_impl(fields)
|
||||
}
|
||||
|
||||
fn new(fields_count: usize) -> Self {
|
||||
Self {
|
||||
value_id: 0,
|
||||
fields_der: TokenStream::new(),
|
||||
field_value_idents: Vec::with_capacity(fields_count),
|
||||
}
|
||||
}
|
||||
|
||||
fn build_impl<'r>(
|
||||
mut self,
|
||||
fields: impl ExactSizeIterator<Item = &'r AstRecordField>,
|
||||
) -> FieldValuesOutcome {
|
||||
for (id, ast_field) in fields.enumerate() {
|
||||
let field_value_ident = new_ident!(format!("field_{}", id));
|
||||
let field_der = self.field_der(ast_field, &field_value_ident);
|
||||
|
||||
self.field_value_idents.push(field_value_ident);
|
||||
self.fields_der.extend(field_der);
|
||||
}
|
||||
|
||||
let outcome = FieldValuesOutcome {
|
||||
fields_der: self.fields_der,
|
||||
field_value_idents: self.field_value_idents,
|
||||
};
|
||||
|
||||
outcome
|
||||
}
|
||||
|
||||
fn field_der(&mut self, ast_field: &AstRecordField, field: &syn::Ident) -> TokenStream {
|
||||
let der = match &ast_field.ty {
|
||||
ParsedType::Boolean(_) => self.bool_der(field),
|
||||
ParsedType::I8(_) => self.i8_der(field),
|
||||
ParsedType::I16(_) => self.i16_der(field),
|
||||
ParsedType::I32(_) => self.i32_der(field),
|
||||
ParsedType::I64(_) => self.i64_der(field),
|
||||
ParsedType::U8(_) => self.u8_der(field),
|
||||
ParsedType::U16(_) => self.u16_der(field),
|
||||
ParsedType::U32(_) => self.u32_der(field),
|
||||
ParsedType::U64(_) => self.u64_der(field),
|
||||
ParsedType::F32(_) => self.f32_der(field),
|
||||
ParsedType::F64(_) => self.f64_der(field),
|
||||
ParsedType::Utf8Str(_) | ParsedType::Utf8String(_) => self.string_der(field),
|
||||
ParsedType::Vector(ty, _) => self.vector_der(ty, field),
|
||||
ParsedType::Record(name, _) => self.record_der(name, field),
|
||||
};
|
||||
|
||||
der
|
||||
}
|
||||
|
||||
fn bool_der(&mut self, field: &syn::Ident) -> TokenStream {
|
||||
let value_id = self.value_id;
|
||||
let result = quote! { let #field = raw_record[#value_id] != 0; };
|
||||
self.value_id += std::mem::size_of::<u8>();
|
||||
result
|
||||
}
|
||||
|
||||
fn i8_der(&mut self, field: &syn::Ident) -> TokenStream {
|
||||
let value_id = self.value_id;
|
||||
let result = quote! { let #field = raw_record[#value_id] as i8; };
|
||||
self.value_id += std::mem::size_of::<i8>();
|
||||
result
|
||||
}
|
||||
|
||||
fn i16_der(&mut self, field: &syn::Ident) -> TokenStream {
|
||||
let value_id = self.value_id;
|
||||
let result = quote! { let #field = i16::from_le_bytes([
|
||||
raw_record[#value_id],
|
||||
raw_record[#value_id + 1],
|
||||
]);
|
||||
};
|
||||
|
||||
self.value_id += std::mem::size_of::<i16>();
|
||||
result
|
||||
}
|
||||
|
||||
fn i32_der(&mut self, field: &syn::Ident) -> TokenStream {
|
||||
let value_id = self.value_id;
|
||||
let result = quote! { let #field = i32::from_le_bytes([
|
||||
raw_record[#value_id],
|
||||
raw_record[#value_id + 1],
|
||||
raw_record[#value_id + 2],
|
||||
raw_record[#value_id + 3],
|
||||
]);
|
||||
};
|
||||
|
||||
self.value_id += std::mem::size_of::<i32>();
|
||||
result
|
||||
}
|
||||
|
||||
fn i64_der(&mut self, field: &syn::Ident) -> TokenStream {
|
||||
let value_id = self.value_id;
|
||||
let result = quote! { let #field = i64::from_le_bytes([
|
||||
raw_record[#value_id],
|
||||
raw_record[#value_id + 1],
|
||||
raw_record[#value_id + 2],
|
||||
raw_record[#value_id + 3],
|
||||
raw_record[#value_id + 4],
|
||||
raw_record[#value_id + 5],
|
||||
raw_record[#value_id + 6],
|
||||
raw_record[#value_id + 7],
|
||||
]);
|
||||
};
|
||||
|
||||
self.value_id += std::mem::size_of::<i64>();
|
||||
result
|
||||
}
|
||||
|
||||
fn u8_der(&mut self, field: &syn::Ident) -> TokenStream {
|
||||
let value_id = self.value_id;
|
||||
let result = quote! { let #field = raw_record[#value_id] as u8; };
|
||||
self.value_id += std::mem::size_of::<u8>();
|
||||
result
|
||||
}
|
||||
|
||||
fn u16_der(&mut self, field: &syn::Ident) -> TokenStream {
|
||||
let value_id = self.value_id;
|
||||
let result = quote! { let #field = u16::from_le_bytes([
|
||||
raw_record[#value_id],
|
||||
raw_record[#value_id + 1],
|
||||
]);
|
||||
};
|
||||
|
||||
self.value_id += std::mem::size_of::<u16>();
|
||||
result
|
||||
}
|
||||
|
||||
fn u32_der(&mut self, field: &syn::Ident) -> TokenStream {
|
||||
let value_id = self.value_id;
|
||||
let result = quote! { let #field = u32::from_le_bytes([
|
||||
raw_record[#value_id],
|
||||
raw_record[#value_id + 1],
|
||||
raw_record[#value_id + 2],
|
||||
raw_record[#value_id + 3],
|
||||
]);
|
||||
};
|
||||
|
||||
self.value_id += std::mem::size_of::<u32>();
|
||||
result
|
||||
}
|
||||
|
||||
fn u64_der(&mut self, field: &syn::Ident) -> TokenStream {
|
||||
let value_id = self.value_id;
|
||||
let result = quote! { let #field = u64::from_le_bytes([
|
||||
raw_record[#value_id],
|
||||
raw_record[#value_id + 1],
|
||||
raw_record[#value_id + 2],
|
||||
raw_record[#value_id + 3],
|
||||
raw_record[#value_id + 4],
|
||||
raw_record[#value_id + 5],
|
||||
raw_record[#value_id + 6],
|
||||
raw_record[#value_id + 7],
|
||||
]);
|
||||
};
|
||||
|
||||
self.value_id += std::mem::size_of::<u64>();
|
||||
result
|
||||
}
|
||||
|
||||
fn f32_der(&mut self, field: &syn::Ident) -> TokenStream {
|
||||
let value_id = self.value_id;
|
||||
let result = quote! { let #field = f32::from_le_bytes([
|
||||
raw_record[#value_id],
|
||||
raw_record[#value_id + 1],
|
||||
raw_record[#value_id + 2],
|
||||
raw_record[#value_id + 3],
|
||||
]);
|
||||
};
|
||||
|
||||
self.value_id += std::mem::size_of::<f32>();
|
||||
result
|
||||
}
|
||||
|
||||
fn f64_der(&mut self, field: &syn::Ident) -> TokenStream {
|
||||
let value_id = self.value_id;
|
||||
let result = quote! { let #field = f64::from_le_bytes([
|
||||
raw_record[#value_id],
|
||||
raw_record[#value_id + 1],
|
||||
raw_record[#value_id + 2],
|
||||
raw_record[#value_id + 3],
|
||||
raw_record[#value_id + 4],
|
||||
raw_record[#value_id + 5],
|
||||
raw_record[#value_id + 6],
|
||||
raw_record[#value_id + 7],
|
||||
]);
|
||||
};
|
||||
|
||||
self.value_id += std::mem::size_of::<f64>();
|
||||
result
|
||||
}
|
||||
|
||||
fn string_der(&mut self, field: &syn::Ident) -> TokenStream {
|
||||
let value_id = self.value_id;
|
||||
|
||||
let result = quote! {
|
||||
let #field = unsafe {
|
||||
let offset = u32::from_le_bytes([
|
||||
raw_record[#value_id],
|
||||
raw_record[#value_id + 1],
|
||||
raw_record[#value_id + 2],
|
||||
raw_record[#value_id + 3],
|
||||
]);
|
||||
|
||||
let size = u32::from_le_bytes([
|
||||
raw_record[#value_id + 4],
|
||||
raw_record[#value_id + 5],
|
||||
raw_record[#value_id + 6],
|
||||
raw_record[#value_id + 7],
|
||||
]);
|
||||
|
||||
String::from_raw_parts(offset as _, size as _, size as _)
|
||||
};
|
||||
};
|
||||
|
||||
self.value_id += 2 * std::mem::size_of::<u32>();
|
||||
|
||||
result
|
||||
}
|
||||
|
||||
fn vector_der(&mut self, ty: &ParsedType, field: &syn::Ident) -> TokenStream {
|
||||
let generated_der_name = format!("__m_generated_vec_deserializer_{}", self.value_id);
|
||||
let generated_der_name = crate::utils::prepare_ident(generated_der_name);
|
||||
let generated_der_ident = new_ident!(generated_der_name);
|
||||
|
||||
let vector_deserializer = crate::parsed_type::generate_vector_der(ty, &generated_der_name);
|
||||
|
||||
let value_id = self.value_id;
|
||||
|
||||
let result = quote! {
|
||||
#vector_deserializer
|
||||
|
||||
let offset = u32::from_le_bytes([
|
||||
raw_record[#value_id],
|
||||
raw_record[#value_id + 1],
|
||||
raw_record[#value_id + 2],
|
||||
raw_record[#value_id + 3],
|
||||
]);
|
||||
|
||||
let size = u32::from_le_bytes([
|
||||
raw_record[#value_id + 4],
|
||||
raw_record[#value_id + 5],
|
||||
raw_record[#value_id + 6],
|
||||
raw_record[#value_id + 7],
|
||||
]);
|
||||
|
||||
let #field = unsafe { #generated_der_ident(offset as _, size as _) };
|
||||
};
|
||||
|
||||
self.value_id += 2 * std::mem::size_of::<u32>();
|
||||
|
||||
result
|
||||
}
|
||||
|
||||
fn record_der(&mut self, name: &str, field: &syn::Ident) -> TokenStream {
|
||||
let value_id = self.value_id;
|
||||
let record_ident = new_ident!(name);
|
||||
|
||||
let result = quote! {
|
||||
let offset = u32::from_le_bytes([
|
||||
raw_record[#value_id],
|
||||
raw_record[#value_id + 1],
|
||||
raw_record[#value_id + 2],
|
||||
raw_record[#value_id + 3],
|
||||
]);
|
||||
|
||||
let #field = #record_ident::__m_generated_deserialize(offset as _);
|
||||
};
|
||||
|
||||
self.value_id += std::mem::size_of::<u32>();
|
||||
|
||||
result
|
||||
}
|
||||
}
|
@ -1,93 +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::new_ident;
|
||||
use crate::ast_types::*;
|
||||
use super::FieldValuesBuilder;
|
||||
|
||||
use proc_macro2::TokenStream;
|
||||
use quote::quote;
|
||||
|
||||
#[derive(Default)]
|
||||
pub(super) struct RecordDerDescriptor {
|
||||
pub(super) fields_der: TokenStream,
|
||||
pub(super) record_ctor: TokenStream,
|
||||
}
|
||||
|
||||
/// This trait could be used to generate various parts of a record serializer func.
|
||||
pub(super) trait RecordDerGlueCodeGenerator {
|
||||
fn generate_der(&self) -> RecordDerDescriptor;
|
||||
}
|
||||
|
||||
impl RecordDerGlueCodeGenerator for AstRecord {
|
||||
fn generate_der(&self) -> RecordDerDescriptor {
|
||||
match &self.fields {
|
||||
AstRecordFields::Named(fields) => record_der_from_named(fields),
|
||||
AstRecordFields::Unnamed(fields) => record_der_from_unnamed(fields),
|
||||
AstRecordFields::Unit => RecordDerDescriptor::default(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn record_der_from_named(fields: &[AstRecordField]) -> RecordDerDescriptor {
|
||||
let builder = FieldValuesBuilder::build(fields.iter());
|
||||
let record_ctor = field_ctors_from_named(fields.iter(), builder.field_value_idents.iter());
|
||||
|
||||
RecordDerDescriptor {
|
||||
fields_der: builder.fields_der,
|
||||
record_ctor,
|
||||
}
|
||||
}
|
||||
|
||||
fn record_der_from_unnamed(fields: &[AstRecordField]) -> RecordDerDescriptor {
|
||||
let builder = FieldValuesBuilder::build(fields.iter());
|
||||
let record_ctor = field_ctor_from_unnamed(builder.field_value_idents.iter());
|
||||
|
||||
RecordDerDescriptor {
|
||||
fields_der: builder.fields_der,
|
||||
record_ctor,
|
||||
}
|
||||
}
|
||||
|
||||
fn field_ctors_from_named<'a, 'v>(
|
||||
ast_fields: impl ExactSizeIterator<Item = &'a AstRecordField>,
|
||||
field_values: impl ExactSizeIterator<Item = &'v syn::Ident>,
|
||||
) -> TokenStream {
|
||||
let field_names = ast_fields
|
||||
.map(|ast_field| {
|
||||
new_ident!(ast_field
|
||||
.name
|
||||
.as_ref()
|
||||
.expect("all fields should have name"))
|
||||
})
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
quote! {
|
||||
Self {
|
||||
#(#field_names: #field_values),*
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn field_ctor_from_unnamed<'v>(
|
||||
field_values: impl ExactSizeIterator<Item = &'v syn::Ident>,
|
||||
) -> TokenStream {
|
||||
quote! {
|
||||
Self {
|
||||
#(#field_values),*
|
||||
}
|
||||
}
|
||||
}
|
@ -1,102 +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::new_ident;
|
||||
use crate::parsed_type::ParsedType;
|
||||
use crate::ast_types::AstRecord;
|
||||
use crate::ast_types::AstRecordField;
|
||||
use crate::ast_types::AstRecordFields;
|
||||
|
||||
use quote::quote;
|
||||
|
||||
/// This trait could be used to generate various parts of a record serializer func.
|
||||
pub(super) trait RecordSerGlueCodeGenerator {
|
||||
fn generate_serializer(&self) -> proc_macro2::TokenStream;
|
||||
}
|
||||
|
||||
impl RecordSerGlueCodeGenerator for AstRecord {
|
||||
fn generate_serializer(&self) -> proc_macro2::TokenStream {
|
||||
let mut serializer = proc_macro2::TokenStream::new();
|
||||
let fields = match &self.fields {
|
||||
AstRecordFields::Named(fields) => fields,
|
||||
AstRecordFields::Unnamed(fields) => fields,
|
||||
AstRecordFields::Unit => return proc_macro2::TokenStream::new(),
|
||||
};
|
||||
|
||||
for (id, field) in fields.iter().enumerate() {
|
||||
let field_ident = field_ident(field, id);
|
||||
|
||||
let field_serialization = match &field.ty {
|
||||
ParsedType::Boolean(_) => {
|
||||
quote! { raw_record.push(*&#field_ident as _); }
|
||||
}
|
||||
ParsedType::Utf8Str(_) | ParsedType::Utf8String(_) => {
|
||||
quote! {
|
||||
let field_ident_ptr = #field_ident.as_ptr() as u32;
|
||||
raw_record.extend(&field_ident_ptr.to_le_bytes());
|
||||
raw_record.extend(&(#field_ident.len() as u32).to_le_bytes());
|
||||
}
|
||||
}
|
||||
ParsedType::Vector(ty, _) => {
|
||||
let generated_ser_name = format!(
|
||||
"__m_generated_vec_serializer_{}_{}",
|
||||
field.name.as_ref().unwrap(),
|
||||
id
|
||||
);
|
||||
|
||||
let generated_ser_ident = new_ident!(generated_ser_name);
|
||||
let vector_ser =
|
||||
crate::parsed_type::generate_vector_ser(ty, &generated_ser_name);
|
||||
let serialized_field_ident = new_ident!(format!("serialized_arg_{}", id));
|
||||
|
||||
quote::quote! {
|
||||
#vector_ser
|
||||
let #serialized_field_ident = unsafe { #generated_ser_ident(&#field_ident) };
|
||||
|
||||
raw_record.extend(&#serialized_field_ident.0.to_le_bytes());
|
||||
raw_record.extend(&#serialized_field_ident.1.to_le_bytes());
|
||||
}
|
||||
}
|
||||
ParsedType::Record(..) => {
|
||||
quote! {
|
||||
let serialized_struct_ptr = #field_ident.__m_generated_serialize() as usize;
|
||||
raw_record.extend(&serialized_struct_ptr.to_le_bytes());
|
||||
}
|
||||
}
|
||||
_ => quote! {
|
||||
raw_record.extend(&#field_ident.to_le_bytes());
|
||||
},
|
||||
};
|
||||
|
||||
serializer.extend(field_serialization);
|
||||
}
|
||||
|
||||
serializer
|
||||
}
|
||||
}
|
||||
|
||||
fn field_ident(field: &AstRecordField, id: usize) -> proc_macro2::TokenStream {
|
||||
match &field.name {
|
||||
Some(name) => {
|
||||
let name = new_ident!(name);
|
||||
quote! { self.#name }
|
||||
}
|
||||
None => {
|
||||
let id = new_ident!(format!("{}", id));
|
||||
quote! { self.#id }
|
||||
}
|
||||
}
|
||||
}
|
@ -1,85 +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.
|
||||
*/
|
||||
|
||||
#[macro_export]
|
||||
/// Crates new syn::Ident with the given string and new call span
|
||||
macro_rules! new_ident {
|
||||
($string: expr) => {
|
||||
syn::Ident::new(&$string, proc_macro2::Span::call_site())
|
||||
};
|
||||
}
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! prepare_global_data {
|
||||
($mtype: ident, $self: ident, $name: expr, $data: ident, $data_size: ident, $global_static_name: ident, $section_name: ident) => {
|
||||
// TODO: change serialization protocol
|
||||
let mtype = crate::export_ast_types::SDKAst::$mtype($self.clone().into());
|
||||
let $data = serde_json::to_vec(&mtype).unwrap();
|
||||
let $data_size = $data.len();
|
||||
let $data = syn::LitByteStr::new(&$data, proc_macro2::Span::call_site());
|
||||
|
||||
let $global_static_name = crate::new_ident!(format!(
|
||||
"{}{}",
|
||||
crate::token_stream_generator::GENERATED_GLOBAL_PREFIX,
|
||||
$name.replace(".", "_"),
|
||||
));
|
||||
let $section_name = format!(
|
||||
"{}{}",
|
||||
crate::token_stream_generator::GENERATED_SECTION_PREFIX,
|
||||
$name.replace(".", "_"),
|
||||
);
|
||||
};
|
||||
}
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! syn_error {
|
||||
($span:expr, $message:expr) => {
|
||||
Err(syn::Error::new($span, $message))
|
||||
};
|
||||
}
|
||||
|
||||
/// Calculate record size in an internal serialized view.
|
||||
pub fn get_record_size<'a>(
|
||||
fields: impl Iterator<Item = &'a crate::parsed_type::ParsedType>,
|
||||
) -> usize {
|
||||
use crate::parsed_type::ParsedType;
|
||||
|
||||
let mut size = 0;
|
||||
|
||||
for field in fields {
|
||||
size += match field {
|
||||
ParsedType::U8(_) | ParsedType::I8(_) | ParsedType::Boolean(_) => 1,
|
||||
ParsedType::U16(_) | ParsedType::I16(_) => 2,
|
||||
ParsedType::U32(_) | ParsedType::I32(_) | ParsedType::F32(_) => 4,
|
||||
ParsedType::U64(_) | ParsedType::I64(_) | ParsedType::F64(_) => 8,
|
||||
ParsedType::Record(..) => 4,
|
||||
ParsedType::Vector(..) | ParsedType::Utf8Str(_) | ParsedType::Utf8String(_) => 2 * 4,
|
||||
};
|
||||
}
|
||||
|
||||
size
|
||||
}
|
||||
|
||||
pub(crate) fn prepare_ident(str: String) -> String {
|
||||
str.chars()
|
||||
.map(|c| match c {
|
||||
'<' => '_',
|
||||
'&' => '_',
|
||||
'>' => '_',
|
||||
c => c,
|
||||
})
|
||||
.collect()
|
||||
}
|
@ -1,49 +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 proc_macro2::TokenStream;
|
||||
|
||||
/// Raw Wasm types according to the spec except i128.
|
||||
pub enum RustType {
|
||||
U8,
|
||||
U16,
|
||||
U32,
|
||||
U64,
|
||||
I8,
|
||||
I16,
|
||||
I32,
|
||||
I64,
|
||||
F32,
|
||||
F64,
|
||||
}
|
||||
|
||||
impl quote::ToTokens for RustType {
|
||||
fn to_tokens(&self, tokens: &mut TokenStream) {
|
||||
let call_site = proc_macro2::Span::call_site();
|
||||
match self {
|
||||
RustType::U8 => syn::Ident::new("u8", call_site).to_tokens(tokens),
|
||||
RustType::U16 => syn::Ident::new("u16", call_site).to_tokens(tokens),
|
||||
RustType::U32 => syn::Ident::new("u32", call_site).to_tokens(tokens),
|
||||
RustType::U64 => syn::Ident::new("u64", call_site).to_tokens(tokens),
|
||||
RustType::I8 => syn::Ident::new("i8", call_site).to_tokens(tokens),
|
||||
RustType::I16 => syn::Ident::new("i16", call_site).to_tokens(tokens),
|
||||
RustType::I32 => syn::Ident::new("i32", call_site).to_tokens(tokens),
|
||||
RustType::I64 => syn::Ident::new("i64", call_site).to_tokens(tokens),
|
||||
RustType::F32 => syn::Ident::new("f32", call_site).to_tokens(tokens),
|
||||
RustType::F64 => syn::Ident::new("f64", call_site).to_tokens(tokens),
|
||||
}
|
||||
}
|
||||
}
|
@ -1,125 +0,0 @@
|
||||
pub fn inner_arrays_1(arg: Vec<Vec<Vec<Vec<u8>>>>) -> Vec<Vec<Vec<Vec<u8>>>> {
|
||||
unimplemented!()
|
||||
}
|
||||
#[cfg(target_arch = "wasm32")]
|
||||
#[export_name = "inner_arrays_1"]
|
||||
#[no_mangle]
|
||||
#[doc(hidden)]
|
||||
#[allow(clippy::all)]
|
||||
pub unsafe fn __m_generated_wrapper_func_inner_arrays_1(arg_0: u32, arg_1: u32) {
|
||||
unsafe fn __m_generated_vec_deserializer_0(offset: u32, size: u32) -> Vec<Vec<Vec<Vec<u8>>>> {
|
||||
unsafe fn __m_generated_vec_deserializer_0_Vec_Vec_u8__(
|
||||
offset: u32,
|
||||
size: u32
|
||||
) -> Vec<Vec<Vec<u8>>> {
|
||||
unsafe fn __m_generated_vec_deserializer_0_Vec_Vec_u8___Vec_u8_(
|
||||
offset: u32,
|
||||
size: u32
|
||||
) -> Vec<Vec<u8>> {
|
||||
unsafe fn __m_generated_vec_deserializer_0_Vec_Vec_u8___Vec_u8__u8(
|
||||
offset: u32,
|
||||
size: u32
|
||||
) -> Vec<u8> {
|
||||
Vec::from_raw_parts(offset as _, size as _, size as _)
|
||||
}
|
||||
let vec_passing_size = 2;
|
||||
let mut arg: Vec<u32> =
|
||||
Vec::from_raw_parts(offset as _, (vec_passing_size * size) as _, (vec_passing_size * size) as _);
|
||||
let mut result = Vec::with_capacity(arg.len());
|
||||
let mut arg = arg.into_iter();
|
||||
while let Some(offset) = arg.next() {
|
||||
let size = arg.next().unwrap();
|
||||
let value = __m_generated_vec_deserializer_0_Vec_Vec_u8___Vec_u8__u8(
|
||||
offset as _,
|
||||
size as _
|
||||
);
|
||||
result.push(value);
|
||||
}
|
||||
result
|
||||
}
|
||||
let vec_passing_size = 2;
|
||||
let mut arg: Vec<u32> =
|
||||
Vec::from_raw_parts(offset as _, (vec_passing_size * size) as _, (vec_passing_size * size) as _);
|
||||
let mut result = Vec::with_capacity(arg.len());
|
||||
let mut arg = arg.into_iter();
|
||||
while let Some(offset) = arg.next() {
|
||||
let size = arg.next().unwrap();
|
||||
let value =
|
||||
__m_generated_vec_deserializer_0_Vec_Vec_u8___Vec_u8_(offset as _, size as _);
|
||||
result.push(value);
|
||||
}
|
||||
result
|
||||
}
|
||||
let vec_passing_size = 2;
|
||||
let mut arg: Vec<u32> = Vec::from_raw_parts(offset as _, (vec_passing_size * size) as _, (vec_passing_size * size) as _);
|
||||
let mut result = Vec::with_capacity(arg.len());
|
||||
let mut arg = arg.into_iter();
|
||||
while let Some(offset) = arg.next() {
|
||||
let size = arg.next().unwrap();
|
||||
let value = __m_generated_vec_deserializer_0_Vec_Vec_u8__(offset as _, size as _);
|
||||
result.push(value);
|
||||
}
|
||||
result
|
||||
}
|
||||
let converted_arg_0 = __m_generated_vec_deserializer_0(arg_0 as _, arg_1 as _);
|
||||
let result = inner_arrays_1(converted_arg_0);
|
||||
unsafe fn __m_generated_vec_serializer(arg: &Vec<Vec<Vec<Vec<u8>>>>) -> (u32, u32) {
|
||||
unsafe fn __m_generated_vec_serializer_Vec_Vec_u8__(
|
||||
arg: &Vec<Vec<Vec<u8>>>
|
||||
) -> (u32, u32) {
|
||||
unsafe fn __m_generated_vec_serializer_Vec_Vec_u8___Vec_u8_(
|
||||
arg: &Vec<Vec<u8>>
|
||||
) -> (u32, u32) {
|
||||
unsafe fn __m_generated_vec_serializer_Vec_Vec_u8___Vec_u8__u8(
|
||||
arg: &Vec<u8>
|
||||
) -> (u32, u32) {
|
||||
(arg.as_ptr() as _, arg.len() as _)
|
||||
}
|
||||
let mut result: Vec<u32> = Vec::with_capacity(2 * arg.len());
|
||||
for value in arg {
|
||||
let (ptr, size) =
|
||||
__m_generated_vec_serializer_Vec_Vec_u8___Vec_u8__u8(&value);
|
||||
result.push(ptr as _);
|
||||
result.push(size as _);
|
||||
}
|
||||
let result_ptr = result.as_ptr();
|
||||
let result_len = result.len() / 2;
|
||||
marine_rs_sdk::internal::add_object_to_release(Box::new(result));
|
||||
(result_ptr as _, result_len as _)
|
||||
}
|
||||
let mut result: Vec<u32> = Vec::with_capacity(2 * arg.len());
|
||||
for value in arg {
|
||||
let (ptr, size) = __m_generated_vec_serializer_Vec_Vec_u8___Vec_u8_(&value);
|
||||
result.push(ptr as _);
|
||||
result.push(size as _);
|
||||
}
|
||||
let result_ptr = result.as_ptr();
|
||||
let result_len = result.len() / 2;
|
||||
marine_rs_sdk::internal::add_object_to_release(Box::new(result));
|
||||
(result_ptr as _, result_len as _)
|
||||
}
|
||||
let mut result: Vec<u32> = Vec::with_capacity(2 * arg.len());
|
||||
for value in arg {
|
||||
let (ptr, size) = __m_generated_vec_serializer_Vec_Vec_u8__(&value);
|
||||
result.push(ptr as _);
|
||||
result.push(size as _);
|
||||
}
|
||||
let result_ptr = result.as_ptr();
|
||||
let result_len = result.len() / 2;
|
||||
marine_rs_sdk::internal::add_object_to_release(Box::new(result));
|
||||
(result_ptr as _, result_len as _)
|
||||
}
|
||||
{
|
||||
let (serialized_vec_ptr, serialized_vec_size) = __m_generated_vec_serializer(&result);
|
||||
marine_rs_sdk::internal::set_result_ptr(serialized_vec_ptr as _);
|
||||
marine_rs_sdk::internal::set_result_size(serialized_vec_size as _);
|
||||
}
|
||||
marine_rs_sdk::internal::add_object_to_release(Box::new(result));
|
||||
}
|
||||
#[cfg(target_arch = "wasm32")]
|
||||
#[doc(hidden)]
|
||||
#[allow(clippy::all)]
|
||||
#[link_section = "__m_generated_section__inner_arrays_1"]
|
||||
pub static __m_generated_static_global_inner_arrays_1: [u8; 330usize] = {
|
||||
* b"{\"ast_type\":\"Function\",\"signature\":{\"name\":\"inner_arrays_1\",\"arguments\":[{\"name\":\"arg\",\"ty\":{\"Vector\":[{\"Vector\":[{\"Vector\":[{\"Vector\":[{\"U8\":\"ByValue\"},\"ByValue\"]},\"ByValue\"]},\"ByValue\"]},\"ByValue\"]}}],\"output_types\":[{\"Vector\":[{\"Vector\":[{\"Vector\":[{\"Vector\":[{\"U8\":\"ByValue\"},\"ByValue\"]},\"ByValue\"]},\"ByValue\"]},\"ByValue\"]}]}}"
|
||||
};
|
@ -1,3 +0,0 @@
|
||||
pub fn inner_arrays_1(arg: Vec<Vec<Vec<Vec<u8>>>>) -> Vec<Vec<Vec<Vec<u8>>>> {
|
||||
unimplemented!()
|
||||
}
|
@ -1,83 +0,0 @@
|
||||
pub fn all_types(
|
||||
arg_0: i8,
|
||||
arg_1: i16,
|
||||
arg_2: i32,
|
||||
arg_3: i64,
|
||||
arg_4: u8,
|
||||
arg_5: u16,
|
||||
arg_6: u32,
|
||||
arg_7: u64,
|
||||
arg_8: f32,
|
||||
arg_9: f64,
|
||||
arg_10: String,
|
||||
arg_11: Vec<u8>,
|
||||
) -> Vec<u8> {
|
||||
unimplemented!()
|
||||
}
|
||||
#[cfg(target_arch = "wasm32")]
|
||||
#[export_name = "all_types"]
|
||||
#[no_mangle]
|
||||
#[doc(hidden)]
|
||||
#[allow(clippy::all)]
|
||||
pub unsafe fn __m_generated_wrapper_func_all_types(
|
||||
arg_0: i8,
|
||||
arg_1: i16,
|
||||
arg_2: i32,
|
||||
arg_3: i64,
|
||||
arg_4: u8,
|
||||
arg_5: u16,
|
||||
arg_6: u32,
|
||||
arg_7: u64,
|
||||
arg_8: f32,
|
||||
arg_9: f64,
|
||||
arg_10: u32,
|
||||
arg_11: u32,
|
||||
arg_12: u32,
|
||||
arg_13: u32
|
||||
) {
|
||||
let converted_arg_0 = arg_0 as _;
|
||||
let converted_arg_1 = arg_1 as _;
|
||||
let converted_arg_2 = arg_2 as _;
|
||||
let converted_arg_3 = arg_3 as _;
|
||||
let converted_arg_4 = arg_4 as _;
|
||||
let converted_arg_5 = arg_5 as _;
|
||||
let converted_arg_6 = arg_6 as _;
|
||||
let converted_arg_7 = arg_7 as _;
|
||||
let converted_arg_8 = arg_8 as _;
|
||||
let converted_arg_9 = arg_9 as _;
|
||||
let converted_arg_10 = String::from_raw_parts(arg_10 as _, arg_11 as _, arg_11 as _);
|
||||
unsafe fn __m_generated_vec_deserializer_12(offset: u32, size: u32) -> Vec<u8> {
|
||||
Vec::from_raw_parts(offset as _, size as _, size as _)
|
||||
}
|
||||
let converted_arg_12 = __m_generated_vec_deserializer_12(arg_12 as _, arg_13 as _);
|
||||
let result = all_types(
|
||||
converted_arg_0,
|
||||
converted_arg_1,
|
||||
converted_arg_2,
|
||||
converted_arg_3,
|
||||
converted_arg_4,
|
||||
converted_arg_5,
|
||||
converted_arg_6,
|
||||
converted_arg_7,
|
||||
converted_arg_8,
|
||||
converted_arg_9,
|
||||
converted_arg_10,
|
||||
converted_arg_12
|
||||
);
|
||||
unsafe fn __m_generated_vec_serializer(arg: &Vec<u8>) -> (u32, u32) {
|
||||
(arg.as_ptr() as _, arg.len() as _)
|
||||
}
|
||||
{
|
||||
let (serialized_vec_ptr, serialized_vec_size) = __m_generated_vec_serializer(&result);
|
||||
marine_rs_sdk::internal::set_result_ptr(serialized_vec_ptr as _);
|
||||
marine_rs_sdk::internal::set_result_size(serialized_vec_size as _);
|
||||
}
|
||||
marine_rs_sdk::internal::add_object_to_release(Box::new(result));
|
||||
}
|
||||
#[cfg(target_arch = "wasm32")]
|
||||
#[doc(hidden)]
|
||||
#[allow(clippy::all)]
|
||||
#[link_section = "__m_generated_section__all_types"]
|
||||
pub static __m_generated_static_global_all_types: [u8; 636usize] = {
|
||||
* b"{\"ast_type\":\"Function\",\"signature\":{\"name\":\"all_types\",\"arguments\":[{\"name\":\"arg_0\",\"ty\":{\"I8\":\"ByValue\"}},{\"name\":\"arg_1\",\"ty\":{\"I16\":\"ByValue\"}},{\"name\":\"arg_2\",\"ty\":{\"I32\":\"ByValue\"}},{\"name\":\"arg_3\",\"ty\":{\"I64\":\"ByValue\"}},{\"name\":\"arg_4\",\"ty\":{\"U8\":\"ByValue\"}},{\"name\":\"arg_5\",\"ty\":{\"U16\":\"ByValue\"}},{\"name\":\"arg_6\",\"ty\":{\"U32\":\"ByValue\"}},{\"name\":\"arg_7\",\"ty\":{\"U64\":\"ByValue\"}},{\"name\":\"arg_8\",\"ty\":{\"F32\":\"ByValue\"}},{\"name\":\"arg_9\",\"ty\":{\"F64\":\"ByValue\"}},{\"name\":\"arg_10\",\"ty\":{\"Utf8String\":\"ByValue\"}},{\"name\":\"arg_11\",\"ty\":{\"Vector\":[{\"U8\":\"ByValue\"},\"ByValue\"]}}],\"output_types\":[{\"Vector\":[{\"U8\":\"ByValue\"},\"ByValue\"]}]}}"
|
||||
};
|
@ -1,16 +0,0 @@
|
||||
pub fn all_types(
|
||||
arg_0: i8,
|
||||
arg_1: i16,
|
||||
arg_2: i32,
|
||||
arg_3: i64,
|
||||
arg_4: u8,
|
||||
arg_5: u16,
|
||||
arg_6: u32,
|
||||
arg_7: u64,
|
||||
arg_8: f32,
|
||||
arg_9: f64,
|
||||
arg_10: String,
|
||||
arg_11: Vec<u8>,
|
||||
) -> Vec<u8> {
|
||||
unimplemented!()
|
||||
}
|
@ -1,105 +0,0 @@
|
||||
pub fn test_array_refs(arg: &Vec<Vec<String>>) -> &Vec<Vec<Vec<Vec<String>>>> {
|
||||
unimplemented!()
|
||||
}
|
||||
#[cfg(target_arch = "wasm32")]
|
||||
#[export_name = "test_array_refs"]
|
||||
#[no_mangle]
|
||||
#[doc(hidden)]
|
||||
#[allow(clippy::all)]
|
||||
pub unsafe fn __m_generated_wrapper_func_test_array_refs(arg_0: u32, arg_1: u32) {
|
||||
unsafe fn __m_generated_vec_deserializer_0(offset: u32, size: u32) -> Vec<Vec<String>> {
|
||||
unsafe fn __m_generated_vec_deserializer_0_String(offset: u32, size: u32) -> Vec<String> {
|
||||
let vec_passing_size = 2;
|
||||
let mut arg: Vec<u32> =
|
||||
Vec::from_raw_parts(offset as _, (vec_passing_size * size) as _, (vec_passing_size * size) as _);
|
||||
let mut arg = arg.into_iter();
|
||||
let mut result = Vec::with_capacity(arg.len() / 2);
|
||||
while let Some(offset) = arg.next() {
|
||||
let size = arg.next().unwrap();
|
||||
let value = String::from_raw_parts(offset as _, size as _, size as _);
|
||||
result.push(value);
|
||||
}
|
||||
result
|
||||
}
|
||||
let vec_passing_size = 2;
|
||||
let mut arg: Vec<u32> = Vec::from_raw_parts(offset as _, (vec_passing_size * size) as _, (vec_passing_size * size) as _);
|
||||
let mut result = Vec::with_capacity(arg.len());
|
||||
let mut arg = arg.into_iter();
|
||||
while let Some(offset) = arg.next() {
|
||||
let size = arg.next().unwrap();
|
||||
let value = __m_generated_vec_deserializer_0_String(offset as _, size as _);
|
||||
result.push(value);
|
||||
}
|
||||
result
|
||||
}
|
||||
let converted_arg_0 = __m_generated_vec_deserializer_0(arg_0 as _, arg_1 as _);
|
||||
let result = test_array_refs(&converted_arg_0);
|
||||
unsafe fn __m_generated_vec_serializer(arg: &Vec<Vec<Vec<Vec<String>>>>) -> (u32, u32) {
|
||||
unsafe fn __m_generated_vec_serializer_Vec_Vec_String__(
|
||||
arg: &Vec<Vec<Vec<String>>>
|
||||
) -> (u32, u32) {
|
||||
unsafe fn __m_generated_vec_serializer_Vec_Vec_String___Vec_String_(
|
||||
arg: &Vec<Vec<String>>
|
||||
) -> (u32, u32) {
|
||||
unsafe fn __m_generated_vec_serializer_Vec_Vec_String___Vec_String__String(
|
||||
arg: &Vec<String>
|
||||
) -> (u32, u32) {
|
||||
let mut result: Vec<u32> = Vec::with_capacity(arg.len());
|
||||
for value in arg {
|
||||
result.push(value.as_ptr() as _);
|
||||
result.push(value.len() as _);
|
||||
}
|
||||
let result_ptr = result.as_ptr();
|
||||
let result_len = result.len() / 2;
|
||||
marine_rs_sdk::internal::add_object_to_release(Box::new(result));
|
||||
(result_ptr as _, result_len as _)
|
||||
}
|
||||
let mut result: Vec<u32> = Vec::with_capacity(2 * arg.len());
|
||||
for value in arg {
|
||||
let (ptr, size) =
|
||||
__m_generated_vec_serializer_Vec_Vec_String___Vec_String__String(&value);
|
||||
result.push(ptr as _);
|
||||
result.push(size as _);
|
||||
}
|
||||
let result_ptr = result.as_ptr();
|
||||
let result_len = result.len() / 2;
|
||||
marine_rs_sdk::internal::add_object_to_release(Box::new(result));
|
||||
(result_ptr as _, result_len as _)
|
||||
}
|
||||
let mut result: Vec<u32> = Vec::with_capacity(2 * arg.len());
|
||||
for value in arg {
|
||||
let (ptr, size) =
|
||||
__m_generated_vec_serializer_Vec_Vec_String___Vec_String_(&value);
|
||||
result.push(ptr as _);
|
||||
result.push(size as _);
|
||||
}
|
||||
let result_ptr = result.as_ptr();
|
||||
let result_len = result.len() / 2;
|
||||
marine_rs_sdk::internal::add_object_to_release(Box::new(result));
|
||||
(result_ptr as _, result_len as _)
|
||||
}
|
||||
let mut result: Vec<u32> = Vec::with_capacity(2 * arg.len());
|
||||
for value in arg {
|
||||
let (ptr, size) = __m_generated_vec_serializer_Vec_Vec_String__(&value);
|
||||
result.push(ptr as _);
|
||||
result.push(size as _);
|
||||
}
|
||||
let result_ptr = result.as_ptr();
|
||||
let result_len = result.len() / 2;
|
||||
marine_rs_sdk::internal::add_object_to_release(Box::new(result));
|
||||
(result_ptr as _, result_len as _)
|
||||
}
|
||||
{
|
||||
let (serialized_vec_ptr, serialized_vec_size) = __m_generated_vec_serializer(&result);
|
||||
marine_rs_sdk::internal::set_result_ptr(serialized_vec_ptr as _);
|
||||
marine_rs_sdk::internal::set_result_size(serialized_vec_size as _);
|
||||
}
|
||||
marine_rs_sdk::internal::add_object_to_release(Box::new(converted_arg_0));
|
||||
}
|
||||
#[cfg(target_arch = "wasm32")]
|
||||
#[doc(hidden)]
|
||||
#[allow(clippy::all)]
|
||||
#[link_section = "__m_generated_section__test_array_refs"]
|
||||
pub static __m_generated_static_global_test_array_refs: [u8; 297usize] = {
|
||||
* b"{\"ast_type\":\"Function\",\"signature\":{\"name\":\"test_array_refs\",\"arguments\":[{\"name\":\"arg\",\"ty\":{\"Vector\":[{\"Vector\":[{\"Utf8String\":\"ByValue\"},\"ByValue\"]},\"ByRef\"]}}],\"output_types\":[{\"Vector\":[{\"Vector\":[{\"Vector\":[{\"Vector\":[{\"Utf8String\":\"ByValue\"},\"ByValue\"]},\"ByValue\"]},\"ByValue\"]},\"ByRef\"]}]}}"
|
||||
};
|
@ -1,3 +0,0 @@
|
||||
pub fn test_array_refs(arg: &Vec<Vec<String>>) -> &Vec<Vec<Vec<Vec<String>>>> {
|
||||
unimplemented!()
|
||||
}
|
@ -1,150 +0,0 @@
|
||||
#[link(wasm_import_module = "test")]
|
||||
#[cfg(target_arch = "wasm32")]
|
||||
extern "C" {
|
||||
#[link_name = "inner_arrays_1"]
|
||||
fn __m_generated_wrapper_func__inner_arrays_1(arg_0: u32, arg_1: u32);
|
||||
}
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
extern "C" {
|
||||
#[link_name = "inner_arrays_1"]
|
||||
fn __m_generated_wrapper_func__inner_arrays_1(
|
||||
arg: Vec<Vec<Vec<Vec<u8>>>>
|
||||
) -> Vec<Vec<Vec<Vec<u8>>>>;
|
||||
}
|
||||
#[cfg(target_arch = "wasm32")]
|
||||
#[doc(hidden)]
|
||||
#[allow(clippy::all)]
|
||||
pub fn inner_arrays_1(arg_0: Vec<Vec<Vec<Vec<u8>>>>) -> Vec<Vec<Vec<Vec<u8>>>> {
|
||||
unsafe {
|
||||
unsafe fn __m_generated_vec_serializer_arg_0(arg: &Vec<Vec<Vec<Vec<u8>>>>) -> (u32, u32) {
|
||||
unsafe fn __m_generated_vec_serializer_arg_0_Vec_Vec_u8__(
|
||||
arg: &Vec<Vec<Vec<u8>>>
|
||||
) -> (u32, u32) {
|
||||
unsafe fn __m_generated_vec_serializer_arg_0_Vec_Vec_u8___Vec_u8_(
|
||||
arg: &Vec<Vec<u8>>
|
||||
) -> (u32, u32) {
|
||||
unsafe fn __m_generated_vec_serializer_arg_0_Vec_Vec_u8___Vec_u8__u8(
|
||||
arg: &Vec<u8>
|
||||
) -> (u32, u32) {
|
||||
(arg.as_ptr() as _, arg.len() as _)
|
||||
}
|
||||
let mut result: Vec<u32> = Vec::with_capacity(2 * arg.len());
|
||||
for value in arg {
|
||||
let (ptr, size) =
|
||||
__m_generated_vec_serializer_arg_0_Vec_Vec_u8___Vec_u8__u8(&value);
|
||||
result.push(ptr as _);
|
||||
result.push(size as _);
|
||||
}
|
||||
let result_ptr = result.as_ptr();
|
||||
let result_len = result.len() / 2;
|
||||
marine_rs_sdk::internal::add_object_to_release(Box::new(result));
|
||||
(result_ptr as _, result_len as _)
|
||||
}
|
||||
let mut result: Vec<u32> = Vec::with_capacity(2 * arg.len());
|
||||
for value in arg {
|
||||
let (ptr, size) =
|
||||
__m_generated_vec_serializer_arg_0_Vec_Vec_u8___Vec_u8_(&value);
|
||||
result.push(ptr as _);
|
||||
result.push(size as _);
|
||||
}
|
||||
let result_ptr = result.as_ptr();
|
||||
let result_len = result.len() / 2;
|
||||
marine_rs_sdk::internal::add_object_to_release(Box::new(result));
|
||||
(result_ptr as _, result_len as _)
|
||||
}
|
||||
let mut result: Vec<u32> = Vec::with_capacity(2 * arg.len());
|
||||
for value in arg {
|
||||
let (ptr, size) = __m_generated_vec_serializer_arg_0_Vec_Vec_u8__(&value);
|
||||
result.push(ptr as _);
|
||||
result.push(size as _);
|
||||
}
|
||||
let result_ptr = result.as_ptr();
|
||||
let result_len = result.len() / 2;
|
||||
marine_rs_sdk::internal::add_object_to_release(Box::new(result));
|
||||
(result_ptr as _, result_len as _)
|
||||
}
|
||||
let arg_0 = __m_generated_vec_serializer_arg_0(&arg_0);
|
||||
let result = __m_generated_wrapper_func__inner_arrays_1(arg_0.0 as _, arg_0.1 as _);
|
||||
unsafe fn __m_generated_vec_deserializer(offset: u32, size: u32) -> Vec<Vec<Vec<Vec<u8>>>> {
|
||||
unsafe fn __m_generated_vec_deserializer_Vec_Vec_u8__(
|
||||
offset: u32,
|
||||
size: u32
|
||||
) -> Vec<Vec<Vec<u8>>> {
|
||||
unsafe fn __m_generated_vec_deserializer_Vec_Vec_u8___Vec_u8_(
|
||||
offset: u32,
|
||||
size: u32
|
||||
) -> Vec<Vec<u8>> {
|
||||
unsafe fn __m_generated_vec_deserializer_Vec_Vec_u8___Vec_u8__u8(
|
||||
offset: u32,
|
||||
size: u32
|
||||
) -> Vec<u8> {
|
||||
Vec::from_raw_parts(offset as _, size as _, size as _)
|
||||
}
|
||||
let vec_passing_size = 2;
|
||||
let mut arg: Vec<u32> = Vec::from_raw_parts(
|
||||
offset as _,
|
||||
(vec_passing_size * size) as _,
|
||||
(vec_passing_size * size) as _
|
||||
);
|
||||
let mut result = Vec::with_capacity(arg.len());
|
||||
let mut arg = arg.into_iter();
|
||||
while let Some(offset) = arg.next() {
|
||||
let size = arg.next().unwrap();
|
||||
let value = __m_generated_vec_deserializer_Vec_Vec_u8___Vec_u8__u8(
|
||||
offset as _,
|
||||
size as _
|
||||
);
|
||||
result.push(value);
|
||||
}
|
||||
result
|
||||
}
|
||||
let vec_passing_size = 2;
|
||||
let mut arg: Vec<u32> = Vec::from_raw_parts(
|
||||
offset as _,
|
||||
(vec_passing_size * size) as _,
|
||||
(vec_passing_size * size) as _
|
||||
);
|
||||
let mut result = Vec::with_capacity(arg.len());
|
||||
let mut arg = arg.into_iter();
|
||||
while let Some(offset) = arg.next() {
|
||||
let size = arg.next().unwrap();
|
||||
let value =
|
||||
__m_generated_vec_deserializer_Vec_Vec_u8___Vec_u8_(offset as _, size as _);
|
||||
result.push(value);
|
||||
}
|
||||
result
|
||||
}
|
||||
let vec_passing_size = 2;
|
||||
let mut arg: Vec<u32> = Vec::from_raw_parts(
|
||||
offset as _,
|
||||
(vec_passing_size * size) as _,
|
||||
(vec_passing_size * size) as _
|
||||
);
|
||||
let mut result = Vec::with_capacity(arg.len());
|
||||
let mut arg = arg.into_iter();
|
||||
while let Some(offset) = arg.next() {
|
||||
let size = arg.next().unwrap();
|
||||
let value = __m_generated_vec_deserializer_Vec_Vec_u8__(offset as _, size as _);
|
||||
result.push(value);
|
||||
}
|
||||
result
|
||||
}
|
||||
__m_generated_vec_deserializer(
|
||||
marine_rs_sdk::internal::get_result_ptr() as _,
|
||||
marine_rs_sdk::internal::get_result_size() as _,
|
||||
)
|
||||
}
|
||||
}
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
#[doc(hidden)]
|
||||
#[allow(clippy::all)]
|
||||
pub fn inner_arrays_1(arg_0: Vec<Vec<Vec<Vec<u8>>>>) -> Vec<Vec<Vec<Vec<u8>>>> {
|
||||
unsafe { __m_generated_wrapper_func__inner_arrays_1(arg_0) }
|
||||
}
|
||||
#[cfg(target_arch = "wasm32")]
|
||||
#[doc(hidden)]
|
||||
#[allow(clippy::all)]
|
||||
#[link_section = "__m_generated_section__test"]
|
||||
pub static __m_generated_static_global_test: [u8; 381usize] = {
|
||||
* b"{\"ast_type\":\"ExternMod\",\"namespace\":\"test\",\"imports\":[{\"link_name\":null,\"signature\":{\"name\":\"inner_arrays_1\",\"arguments\":[{\"name\":\"arg\",\"ty\":{\"Vector\":[{\"Vector\":[{\"Vector\":[{\"Vector\":[{\"U8\":\"ByValue\"},\"ByValue\"]},\"ByValue\"]},\"ByValue\"]},\"ByValue\"]}}],\"output_types\":[{\"Vector\":[{\"Vector\":[{\"Vector\":[{\"Vector\":[{\"U8\":\"ByValue\"},\"ByValue\"]},\"ByValue\"]},\"ByValue\"]},\"ByValue\"]}]}}]}"
|
||||
};
|
@ -1,4 +0,0 @@
|
||||
#[link(wasm_import_module = "test")]
|
||||
extern "C" {
|
||||
pub fn inner_arrays_1(arg: Vec<Vec<Vec<Vec<u8>>>>) -> Vec<Vec<Vec<Vec<u8>>>>;
|
||||
}
|
@ -1,118 +0,0 @@
|
||||
#[link(wasm_import_module = "test")]
|
||||
#[cfg(target_arch = "wasm32")]
|
||||
extern "C" {
|
||||
#[link_name = "all_types"]
|
||||
fn __m_generated_wrapper_func__all_types(
|
||||
arg_0: i8,
|
||||
arg_1: i16,
|
||||
arg_2: i32,
|
||||
arg_3: i64,
|
||||
arg_4: u8,
|
||||
arg_5: u16,
|
||||
arg_6: u32,
|
||||
arg_7: u64,
|
||||
arg_8: f32,
|
||||
arg_9: f64,
|
||||
arg_10: u32,
|
||||
arg_11: u32,
|
||||
arg_12: u32,
|
||||
arg_13: u32
|
||||
);
|
||||
}
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
extern "C" {
|
||||
#[link_name = "all_types"]
|
||||
fn __m_generated_wrapper_func__all_types(
|
||||
arg_0: i8,
|
||||
arg_1: i16,
|
||||
arg_2: i32,
|
||||
arg_3: i64,
|
||||
arg_4: u8,
|
||||
arg_5: u16,
|
||||
arg_6: u32,
|
||||
arg_7: u64,
|
||||
arg_8: f32,
|
||||
arg_9: f64,
|
||||
arg_10: String,
|
||||
arg_11: Vec<u8>
|
||||
) -> Vec<u8>;
|
||||
}
|
||||
#[cfg(target_arch = "wasm32")]
|
||||
#[doc(hidden)]
|
||||
#[allow(clippy::all)]
|
||||
pub fn all_types(
|
||||
arg_0: i8,
|
||||
arg_1: i16,
|
||||
arg_2: i32,
|
||||
arg_3: i64,
|
||||
arg_4: u8,
|
||||
arg_5: u16,
|
||||
arg_6: u32,
|
||||
arg_7: u64,
|
||||
arg_8: f32,
|
||||
arg_9: f64,
|
||||
arg_10: String,
|
||||
arg_11: Vec<u8>
|
||||
) -> Vec<u8> {
|
||||
unsafe {
|
||||
let mut arg_10 = std::mem::ManuallyDrop::new(arg_10);
|
||||
unsafe fn __m_generated_vec_serializer_arg_11(arg: &Vec<u8>) -> (u32, u32) {
|
||||
(arg.as_ptr() as _, arg.len() as _)
|
||||
}
|
||||
let arg_11 = __m_generated_vec_serializer_arg_11(&arg_11);
|
||||
let result = __m_generated_wrapper_func__all_types(
|
||||
arg_0,
|
||||
arg_1,
|
||||
arg_2,
|
||||
arg_3,
|
||||
arg_4,
|
||||
arg_5,
|
||||
arg_6,
|
||||
arg_7,
|
||||
arg_8,
|
||||
arg_9,
|
||||
arg_10.as_ptr() as _,
|
||||
arg_10.len() as _,
|
||||
arg_11.0 as _,
|
||||
arg_11.1 as _
|
||||
);
|
||||
std::mem::ManuallyDrop::drop(&mut arg_10);
|
||||
unsafe fn __m_generated_vec_deserializer(offset: u32, size: u32) -> Vec<u8> {
|
||||
Vec::from_raw_parts(offset as _, size as _, size as _)
|
||||
}
|
||||
__m_generated_vec_deserializer(
|
||||
marine_rs_sdk::internal::get_result_ptr() as _,
|
||||
marine_rs_sdk::internal::get_result_size() as _,
|
||||
)
|
||||
}
|
||||
}
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
#[doc(hidden)]
|
||||
#[allow(clippy::all)]
|
||||
pub fn all_types(
|
||||
arg_0: i8,
|
||||
arg_1: i16,
|
||||
arg_2: i32,
|
||||
arg_3: i64,
|
||||
arg_4: u8,
|
||||
arg_5: u16,
|
||||
arg_6: u32,
|
||||
arg_7: u64,
|
||||
arg_8: f32,
|
||||
arg_9: f64,
|
||||
arg_10: String,
|
||||
arg_11: Vec<u8>
|
||||
) -> Vec<u8> {
|
||||
unsafe {
|
||||
__m_generated_wrapper_func__all_types(
|
||||
arg_0, arg_1, arg_2, arg_3, arg_4, arg_5, arg_6, arg_7, arg_8, arg_9, arg_10, arg_11
|
||||
)
|
||||
}
|
||||
}
|
||||
#[cfg(target_arch = "wasm32")]
|
||||
#[doc(hidden)]
|
||||
#[allow(clippy::all)]
|
||||
#[link_section = "__m_generated_section__test"]
|
||||
pub static __m_generated_static_global_test: [u8; 687usize] = {
|
||||
* b"{\"ast_type\":\"ExternMod\",\"namespace\":\"test\",\"imports\":[{\"link_name\":null,\"signature\":{\"name\":\"all_types\",\"arguments\":[{\"name\":\"arg_0\",\"ty\":{\"I8\":\"ByValue\"}},{\"name\":\"arg_1\",\"ty\":{\"I16\":\"ByValue\"}},{\"name\":\"arg_2\",\"ty\":{\"I32\":\"ByValue\"}},{\"name\":\"arg_3\",\"ty\":{\"I64\":\"ByValue\"}},{\"name\":\"arg_4\",\"ty\":{\"U8\":\"ByValue\"}},{\"name\":\"arg_5\",\"ty\":{\"U16\":\"ByValue\"}},{\"name\":\"arg_6\",\"ty\":{\"U32\":\"ByValue\"}},{\"name\":\"arg_7\",\"ty\":{\"U64\":\"ByValue\"}},{\"name\":\"arg_8\",\"ty\":{\"F32\":\"ByValue\"}},{\"name\":\"arg_9\",\"ty\":{\"F64\":\"ByValue\"}},{\"name\":\"arg_10\",\"ty\":{\"Utf8String\":\"ByValue\"}},{\"name\":\"arg_11\",\"ty\":{\"Vector\":[{\"U8\":\"ByValue\"},\"ByValue\"]}}],\"output_types\":[{\"Vector\":[{\"U8\":\"ByValue\"},\"ByValue\"]}]}}]}"
|
||||
};
|
@ -1,17 +0,0 @@
|
||||
#[link(wasm_import_module = "test")]
|
||||
extern "C" {
|
||||
pub fn all_types(
|
||||
arg_0: i8,
|
||||
arg_1: i16,
|
||||
arg_2: i32,
|
||||
arg_3: i64,
|
||||
arg_4: u8,
|
||||
arg_5: u16,
|
||||
arg_6: u32,
|
||||
arg_7: u64,
|
||||
arg_8: f32,
|
||||
arg_9: f64,
|
||||
arg_10: String,
|
||||
arg_11: Vec<u8>,
|
||||
) -> Vec<u8>;
|
||||
}
|
@ -1,208 +0,0 @@
|
||||
pub struct CallParameters {
|
||||
/// Peer id of the AIR script initiator.
|
||||
pub init_peer_id: String,
|
||||
/// Id of the current service.
|
||||
pub service_id: String,
|
||||
/// Id of the service creator.
|
||||
pub service_creator_peer_id: String,
|
||||
/// PeerId of the peer who hosts this service.
|
||||
pub host_id: String,
|
||||
/// Id of the particle which execution resulted a call this service.
|
||||
pub particle_id: String,
|
||||
/// Security tetraplets which described origin of the arguments.
|
||||
pub tetraplets: Vec<Vec<SecurityTetraplet>>,
|
||||
}
|
||||
#[cfg(target_arch = "wasm32")]
|
||||
#[doc(hidden)]
|
||||
#[allow(clippy::all)]
|
||||
impl CallParameters {
|
||||
pub fn __m_generated_serialize(&self) -> *const u8 {
|
||||
let mut raw_record: Vec<u8> = Vec::with_capacity(4 * 6usize);
|
||||
let field_ident_ptr = self.init_peer_id.as_ptr() as u32;
|
||||
raw_record.extend(&field_ident_ptr.to_le_bytes());
|
||||
raw_record.extend(&(self.init_peer_id.len() as u32).to_le_bytes());
|
||||
let field_ident_ptr = self.service_id.as_ptr() as u32;
|
||||
raw_record.extend(&field_ident_ptr.to_le_bytes());
|
||||
raw_record.extend(&(self.service_id.len() as u32).to_le_bytes());
|
||||
let field_ident_ptr = self.service_creator_peer_id.as_ptr() as u32;
|
||||
raw_record.extend(&field_ident_ptr.to_le_bytes());
|
||||
raw_record.extend(&(self.service_creator_peer_id.len() as u32).to_le_bytes());
|
||||
let field_ident_ptr = self.host_id.as_ptr() as u32;
|
||||
raw_record.extend(&field_ident_ptr.to_le_bytes());
|
||||
raw_record.extend(&(self.host_id.len() as u32).to_le_bytes());
|
||||
let field_ident_ptr = self.particle_id.as_ptr() as u32;
|
||||
raw_record.extend(&field_ident_ptr.to_le_bytes());
|
||||
raw_record.extend(&(self.particle_id.len() as u32).to_le_bytes());
|
||||
unsafe fn __m_generated_vec_serializer_tetraplets_5(
|
||||
arg: &Vec<Vec<SecurityTetraplet>>
|
||||
) -> (u32, u32) {
|
||||
unsafe fn __m_generated_vec_serializer_tetraplets_5_SecurityTetraplet(
|
||||
arg: &Vec<SecurityTetraplet>
|
||||
) -> (u32, u32) {
|
||||
let mut result: Vec<u32> = Vec::with_capacity(arg.len());
|
||||
for value in arg {
|
||||
result.push(value.__m_generated_serialize() as _);
|
||||
}
|
||||
let result_ptr = result.as_ptr();
|
||||
let result_len = result.len();
|
||||
marine_rs_sdk::internal::add_object_to_release(Box::new(result));
|
||||
(result_ptr as _, result_len as _)
|
||||
}
|
||||
let mut result: Vec<u32> = Vec::with_capacity(2 * arg.len());
|
||||
for value in arg {
|
||||
let (ptr, size) =
|
||||
__m_generated_vec_serializer_tetraplets_5_SecurityTetraplet(&value);
|
||||
result.push(ptr as _);
|
||||
result.push(size as _);
|
||||
}
|
||||
let result_ptr = result.as_ptr();
|
||||
let result_len = result.len() / 2;
|
||||
marine_rs_sdk::internal::add_object_to_release(Box::new(result));
|
||||
(result_ptr as _, result_len as _)
|
||||
}
|
||||
let serialized_arg_5 =
|
||||
unsafe { __m_generated_vec_serializer_tetraplets_5(&self.tetraplets) };
|
||||
raw_record.extend(&serialized_arg_5.0.to_le_bytes());
|
||||
raw_record.extend(&serialized_arg_5.1.to_le_bytes());
|
||||
let raw_record_ptr = raw_record.as_ptr();
|
||||
marine_rs_sdk::internal::add_object_to_release(Box::new(raw_record));
|
||||
raw_record_ptr as _
|
||||
}
|
||||
pub unsafe fn __m_generated_deserialize(record_ptr: *const u8) -> Self {
|
||||
let raw_record: Vec<u8> = Vec::from_raw_parts(record_ptr as _, 48usize, 48usize);
|
||||
let field_0 = unsafe {
|
||||
let offset = u32::from_le_bytes([
|
||||
raw_record[0usize],
|
||||
raw_record[0usize + 1],
|
||||
raw_record[0usize + 2],
|
||||
raw_record[0usize + 3],
|
||||
]);
|
||||
let size = u32::from_le_bytes([
|
||||
raw_record[0usize + 4],
|
||||
raw_record[0usize + 5],
|
||||
raw_record[0usize + 6],
|
||||
raw_record[0usize + 7],
|
||||
]);
|
||||
String::from_raw_parts(offset as _, size as _, size as _)
|
||||
};
|
||||
let field_1 = unsafe {
|
||||
let offset = u32::from_le_bytes([
|
||||
raw_record[8usize],
|
||||
raw_record[8usize + 1],
|
||||
raw_record[8usize + 2],
|
||||
raw_record[8usize + 3],
|
||||
]);
|
||||
let size = u32::from_le_bytes([
|
||||
raw_record[8usize + 4],
|
||||
raw_record[8usize + 5],
|
||||
raw_record[8usize + 6],
|
||||
raw_record[8usize + 7],
|
||||
]);
|
||||
String::from_raw_parts(offset as _, size as _, size as _)
|
||||
};
|
||||
let field_2 = unsafe {
|
||||
let offset = u32::from_le_bytes([
|
||||
raw_record[16usize],
|
||||
raw_record[16usize + 1],
|
||||
raw_record[16usize + 2],
|
||||
raw_record[16usize + 3],
|
||||
]);
|
||||
let size = u32::from_le_bytes([
|
||||
raw_record[16usize + 4],
|
||||
raw_record[16usize + 5],
|
||||
raw_record[16usize + 6],
|
||||
raw_record[16usize + 7],
|
||||
]);
|
||||
String::from_raw_parts(offset as _, size as _, size as _)
|
||||
};
|
||||
let field_3 = unsafe {
|
||||
let offset = u32::from_le_bytes([
|
||||
raw_record[24usize],
|
||||
raw_record[24usize + 1],
|
||||
raw_record[24usize + 2],
|
||||
raw_record[24usize + 3],
|
||||
]);
|
||||
let size = u32::from_le_bytes([
|
||||
raw_record[24usize + 4],
|
||||
raw_record[24usize + 5],
|
||||
raw_record[24usize + 6],
|
||||
raw_record[24usize + 7],
|
||||
]);
|
||||
String::from_raw_parts(offset as _, size as _, size as _)
|
||||
};
|
||||
let field_4 = unsafe {
|
||||
let offset = u32::from_le_bytes([
|
||||
raw_record[32usize],
|
||||
raw_record[32usize + 1],
|
||||
raw_record[32usize + 2],
|
||||
raw_record[32usize + 3],
|
||||
]);
|
||||
let size = u32::from_le_bytes([
|
||||
raw_record[32usize + 4],
|
||||
raw_record[32usize + 5],
|
||||
raw_record[32usize + 6],
|
||||
raw_record[32usize + 7],
|
||||
]);
|
||||
String::from_raw_parts(offset as _, size as _, size as _)
|
||||
};
|
||||
unsafe fn __m_generated_vec_deserializer_40(
|
||||
offset: u32,
|
||||
size: u32
|
||||
) -> Vec<Vec<SecurityTetraplet>> {
|
||||
unsafe fn __m_generated_vec_deserializer_40_SecurityTetraplet(
|
||||
offset: u32,
|
||||
size: u32
|
||||
) -> Vec<SecurityTetraplet> {
|
||||
let mut arg: Vec<u32> = Vec::from_raw_parts(offset as _, size as _, size as _);
|
||||
let mut result = Vec::with_capacity(arg.len());
|
||||
for offset in arg {
|
||||
let value = SecurityTetraplet::__m_generated_deserialize(offset as _);
|
||||
result.push(value);
|
||||
}
|
||||
result
|
||||
}
|
||||
let vec_passing_size = 2;
|
||||
let mut arg: Vec<u32> =
|
||||
Vec::from_raw_parts(offset as _, (vec_passing_size * size) as _, (vec_passing_size * size) as _);
|
||||
let mut result = Vec::with_capacity(arg.len());
|
||||
let mut arg = arg.into_iter();
|
||||
while let Some(offset) = arg.next() {
|
||||
let size = arg.next().unwrap();
|
||||
let value = __m_generated_vec_deserializer_40_SecurityTetraplet(
|
||||
offset as _,
|
||||
size as _
|
||||
);
|
||||
result.push(value);
|
||||
}
|
||||
result
|
||||
}
|
||||
let offset = u32::from_le_bytes([
|
||||
raw_record[40usize],
|
||||
raw_record[40usize + 1],
|
||||
raw_record[40usize + 2],
|
||||
raw_record[40usize + 3],
|
||||
]);
|
||||
let size = u32::from_le_bytes([
|
||||
raw_record[40usize + 4],
|
||||
raw_record[40usize + 5],
|
||||
raw_record[40usize + 6],
|
||||
raw_record[40usize + 7],
|
||||
]);
|
||||
let field_5 = unsafe { __m_generated_vec_deserializer_40(offset as _, size as _) };
|
||||
Self {
|
||||
init_peer_id: field_0,
|
||||
service_id: field_1,
|
||||
service_creator_peer_id: field_2,
|
||||
host_id: field_3,
|
||||
particle_id: field_4,
|
||||
tetraplets: field_5
|
||||
}
|
||||
}
|
||||
}
|
||||
#[cfg(target_arch = "wasm32")]
|
||||
#[doc(hidden)]
|
||||
#[allow(clippy::all)]
|
||||
#[link_section = "__m_generated_section__CallParameters"]
|
||||
pub static __m_generated_static_global_CallParameters: [u8; 455usize] = {
|
||||
* b"{\"ast_type\":\"Record\",\"name\":\"CallParameters\",\"fields\":{\"Named\":[{\"name\":\"init_peer_id\",\"ty\":{\"Utf8String\":\"ByValue\"}},{\"name\":\"service_id\",\"ty\":{\"Utf8String\":\"ByValue\"}},{\"name\":\"service_creator_peer_id\",\"ty\":{\"Utf8String\":\"ByValue\"}},{\"name\":\"host_id\",\"ty\":{\"Utf8String\":\"ByValue\"}},{\"name\":\"particle_id\",\"ty\":{\"Utf8String\":\"ByValue\"}},{\"name\":\"tetraplets\",\"ty\":{\"Vector\":[{\"Vector\":[{\"Record\":[\"SecurityTetraplet\",\"ByValue\"]},\"ByValue\"]},\"ByValue\"]}}]}}"
|
||||
};
|
@ -1,19 +0,0 @@
|
||||
pub struct CallParameters {
|
||||
/// Peer id of the AIR script initiator.
|
||||
pub init_peer_id: String,
|
||||
|
||||
/// Id of the current service.
|
||||
pub service_id: String,
|
||||
|
||||
/// Id of the service creator.
|
||||
pub service_creator_peer_id: String,
|
||||
|
||||
/// PeerId of the peer who hosts this service.
|
||||
pub host_id: String,
|
||||
|
||||
/// Id of the particle which execution resulted a call this service.
|
||||
pub particle_id: String,
|
||||
|
||||
/// Security tetraplets which described origin of the arguments.
|
||||
pub tetraplets: Vec<Vec<SecurityTetraplet>>,
|
||||
}
|
@ -1,141 +0,0 @@
|
||||
pub fn inner_arrays_2(arg: Vec<Vec<Vec<Vec<TestRecord>>>>) -> Vec<Vec<Vec<Vec<TestRecord>>>> {
|
||||
unimplemented!()
|
||||
}
|
||||
#[cfg(target_arch = "wasm32")]
|
||||
#[export_name = "inner_arrays_2"]
|
||||
#[no_mangle]
|
||||
#[doc(hidden)]
|
||||
#[allow(clippy::all)]
|
||||
pub unsafe fn __m_generated_wrapper_func_inner_arrays_2(arg_0: u32, arg_1: u32) {
|
||||
unsafe fn __m_generated_vec_deserializer_0(
|
||||
offset: u32,
|
||||
size: u32
|
||||
) -> Vec<Vec<Vec<Vec<TestRecord>>>> {
|
||||
unsafe fn __m_generated_vec_deserializer_0_Vec_Vec_TestRecord__(
|
||||
offset: u32,
|
||||
size: u32
|
||||
) -> Vec<Vec<Vec<TestRecord>>> {
|
||||
unsafe fn __m_generated_vec_deserializer_0_Vec_Vec_TestRecord___Vec_TestRecord_(
|
||||
offset: u32,
|
||||
size: u32
|
||||
) -> Vec<Vec<TestRecord>> {
|
||||
unsafe fn __m_generated_vec_deserializer_0_Vec_Vec_TestRecord___Vec_TestRecord__TestRecord(
|
||||
offset: u32,
|
||||
size: u32
|
||||
) -> Vec<TestRecord> {
|
||||
let mut arg: Vec<u32> = Vec::from_raw_parts(offset as _, size as _, size as _);
|
||||
let mut result = Vec::with_capacity(arg.len());
|
||||
for offset in arg {
|
||||
let value = TestRecord::__m_generated_deserialize(offset as _);
|
||||
result.push(value);
|
||||
}
|
||||
result
|
||||
}
|
||||
let vec_passing_size = 2;
|
||||
let mut arg: Vec<u32> =
|
||||
Vec::from_raw_parts(offset as _, (vec_passing_size * size) as _, (vec_passing_size * size) as _);
|
||||
let mut result = Vec::with_capacity(arg.len());
|
||||
let mut arg = arg.into_iter();
|
||||
while let Some(offset) = arg.next() {
|
||||
let size = arg.next().unwrap();
|
||||
let value = __m_generated_vec_deserializer_0_Vec_Vec_TestRecord___Vec_TestRecord__TestRecord ( offset as _ , size as _ ) ;
|
||||
result.push(value);
|
||||
}
|
||||
result
|
||||
}
|
||||
let vec_passing_size = 2;
|
||||
let mut arg: Vec<u32> =
|
||||
Vec::from_raw_parts(offset as _, (vec_passing_size * size) as _, (vec_passing_size * size) as _);
|
||||
let mut result = Vec::with_capacity(arg.len());
|
||||
let mut arg = arg.into_iter();
|
||||
while let Some(offset) = arg.next() {
|
||||
let size = arg.next().unwrap();
|
||||
let value = __m_generated_vec_deserializer_0_Vec_Vec_TestRecord___Vec_TestRecord_(
|
||||
offset as _,
|
||||
size as _
|
||||
);
|
||||
result.push(value);
|
||||
}
|
||||
result
|
||||
}
|
||||
let vec_passing_size = 2;
|
||||
let mut arg: Vec<u32> = Vec::from_raw_parts(offset as _, (vec_passing_size * size) as _, (vec_passing_size * size) as _);
|
||||
let mut result = Vec::with_capacity(arg.len());
|
||||
let mut arg = arg.into_iter();
|
||||
while let Some(offset) = arg.next() {
|
||||
let size = arg.next().unwrap();
|
||||
let value =
|
||||
__m_generated_vec_deserializer_0_Vec_Vec_TestRecord__(offset as _, size as _);
|
||||
result.push(value);
|
||||
}
|
||||
result
|
||||
}
|
||||
let converted_arg_0 = __m_generated_vec_deserializer_0(arg_0 as _, arg_1 as _);
|
||||
let result = inner_arrays_2(converted_arg_0);
|
||||
unsafe fn __m_generated_vec_serializer(arg: &Vec<Vec<Vec<Vec<TestRecord>>>>) -> (u32, u32) {
|
||||
unsafe fn __m_generated_vec_serializer_Vec_Vec_TestRecord__(
|
||||
arg: &Vec<Vec<Vec<TestRecord>>>
|
||||
) -> (u32, u32) {
|
||||
unsafe fn __m_generated_vec_serializer_Vec_Vec_TestRecord___Vec_TestRecord_(
|
||||
arg: &Vec<Vec<TestRecord>>
|
||||
) -> (u32, u32) {
|
||||
unsafe fn __m_generated_vec_serializer_Vec_Vec_TestRecord___Vec_TestRecord__TestRecord(
|
||||
arg: &Vec<TestRecord>
|
||||
) -> (u32, u32) {
|
||||
let mut result: Vec<u32> = Vec::with_capacity(arg.len());
|
||||
for value in arg {
|
||||
result.push(value.__m_generated_serialize() as _);
|
||||
}
|
||||
let result_ptr = result.as_ptr();
|
||||
let result_len = result.len();
|
||||
marine_rs_sdk::internal::add_object_to_release(Box::new(result));
|
||||
(result_ptr as _, result_len as _)
|
||||
}
|
||||
let mut result: Vec<u32> = Vec::with_capacity(2 * arg.len());
|
||||
for value in arg {
|
||||
let ( ptr , size ) = __m_generated_vec_serializer_Vec_Vec_TestRecord___Vec_TestRecord__TestRecord ( & value ) ;
|
||||
result.push(ptr as _);
|
||||
result.push(size as _);
|
||||
}
|
||||
let result_ptr = result.as_ptr();
|
||||
let result_len = result.len() / 2;
|
||||
marine_rs_sdk::internal::add_object_to_release(Box::new(result));
|
||||
(result_ptr as _, result_len as _)
|
||||
}
|
||||
let mut result: Vec<u32> = Vec::with_capacity(2 * arg.len());
|
||||
for value in arg {
|
||||
let (ptr, size) =
|
||||
__m_generated_vec_serializer_Vec_Vec_TestRecord___Vec_TestRecord_(&value);
|
||||
result.push(ptr as _);
|
||||
result.push(size as _);
|
||||
}
|
||||
let result_ptr = result.as_ptr();
|
||||
let result_len = result.len() / 2;
|
||||
marine_rs_sdk::internal::add_object_to_release(Box::new(result));
|
||||
(result_ptr as _, result_len as _)
|
||||
}
|
||||
let mut result: Vec<u32> = Vec::with_capacity(2 * arg.len());
|
||||
for value in arg {
|
||||
let (ptr, size) = __m_generated_vec_serializer_Vec_Vec_TestRecord__(&value);
|
||||
result.push(ptr as _);
|
||||
result.push(size as _);
|
||||
}
|
||||
let result_ptr = result.as_ptr();
|
||||
let result_len = result.len() / 2;
|
||||
marine_rs_sdk::internal::add_object_to_release(Box::new(result));
|
||||
(result_ptr as _, result_len as _)
|
||||
}
|
||||
{
|
||||
let (serialized_vec_ptr, serialized_vec_size) = __m_generated_vec_serializer(&result);
|
||||
marine_rs_sdk::internal::set_result_ptr(serialized_vec_ptr as _);
|
||||
marine_rs_sdk::internal::set_result_size(serialized_vec_size as _);
|
||||
}
|
||||
marine_rs_sdk::internal::add_object_to_release(Box::new(result));
|
||||
}
|
||||
#[cfg(target_arch = "wasm32")]
|
||||
#[doc(hidden)]
|
||||
#[allow(clippy::all)]
|
||||
#[link_section = "__m_generated_section__inner_arrays_2"]
|
||||
pub static __m_generated_static_global_inner_arrays_2: [u8; 368usize] = {
|
||||
* b"{\"ast_type\":\"Function\",\"signature\":{\"name\":\"inner_arrays_2\",\"arguments\":[{\"name\":\"arg\",\"ty\":{\"Vector\":[{\"Vector\":[{\"Vector\":[{\"Vector\":[{\"Record\":[\"TestRecord\",\"ByValue\"]},\"ByValue\"]},\"ByValue\"]},\"ByValue\"]},\"ByValue\"]}}],\"output_types\":[{\"Vector\":[{\"Vector\":[{\"Vector\":[{\"Vector\":[{\"Record\":[\"TestRecord\",\"ByValue\"]},\"ByValue\"]},\"ByValue\"]},\"ByValue\"]},\"ByValue\"]}]}}"
|
||||
};
|
@ -1,3 +0,0 @@
|
||||
pub fn inner_arrays_2(arg: Vec<Vec<Vec<Vec<TestRecord>>>>) -> Vec<Vec<Vec<Vec<TestRecord>>>> {
|
||||
unimplemented!()
|
||||
}
|
@ -1,59 +0,0 @@
|
||||
mod utils;
|
||||
|
||||
use utils::test_marine_token_streams;
|
||||
|
||||
#[test]
|
||||
fn exports_arrays() {
|
||||
assert!(test_marine_token_streams(
|
||||
"tests/generation_tests/exports/arrays/marine.rs",
|
||||
"tests/generation_tests/exports/arrays/expanded.rs",
|
||||
));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn exports_basic_types() {
|
||||
assert!(test_marine_token_streams(
|
||||
"tests/generation_tests/exports/basic_types/marine.rs",
|
||||
"tests/generation_tests/exports/basic_types/expanded.rs",
|
||||
));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn exports_refs() {
|
||||
assert!(test_marine_token_streams(
|
||||
"tests/generation_tests/exports/refs/marine.rs",
|
||||
"tests/generation_tests/exports/refs/expanded.rs",
|
||||
));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn records_call_parameters() {
|
||||
assert!(test_marine_token_streams(
|
||||
"tests/generation_tests/records/call_parameters/marine.rs",
|
||||
"tests/generation_tests/records/call_parameters/expanded.rs",
|
||||
));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn records_use_as_type() {
|
||||
assert!(test_marine_token_streams(
|
||||
"tests/generation_tests/records/use_as_type/marine.rs",
|
||||
"tests/generation_tests/records/use_as_type/expanded.rs",
|
||||
));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn imports_arrays() {
|
||||
assert!(test_marine_token_streams(
|
||||
"tests/generation_tests/imports/arrays/marine.rs",
|
||||
"tests/generation_tests/imports/arrays/expanded.rs",
|
||||
));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn imports_basic_types() {
|
||||
assert!(test_marine_token_streams(
|
||||
"tests/generation_tests/imports/basic_types/marine.rs",
|
||||
"tests/generation_tests/imports/basic_types/expanded.rs",
|
||||
));
|
||||
}
|
@ -1,37 +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 marine_macro_impl::marine;
|
||||
|
||||
use marine_macro_testing_utils::{items_from_file, stream_from_file, to_syn_item};
|
||||
|
||||
use std::path::Path;
|
||||
|
||||
pub fn test_marine_token_streams<FP, EP>(marine_path: FP, expanded_path: EP) -> bool
|
||||
where
|
||||
FP: AsRef<Path>,
|
||||
EP: AsRef<Path>,
|
||||
{
|
||||
let marine_item = stream_from_file(marine_path);
|
||||
let test_token_stream = quote::quote! { #marine_item };
|
||||
let marine_token_streams = marine(test_token_stream)
|
||||
.unwrap_or_else(|e| panic!("failed to apply the marine macro due {}", e));
|
||||
|
||||
let expanded_item = items_from_file(expanded_path);
|
||||
let marine_item = to_syn_item(marine_token_streams);
|
||||
|
||||
marine_item == expanded_item
|
||||
}
|
@ -1,21 +0,0 @@
|
||||
[package]
|
||||
name = "marine-macro"
|
||||
version = "0.6.13" # remember to update html_root_url
|
||||
edition = "2018"
|
||||
description = "Definition of the `#[marine]` macro"
|
||||
documentation = "https://docs.rs/fluence/marine-macro"
|
||||
repository = "https://github.com/fluencelabs/marine-rs-sdk/tree/master/crates/marine-macro"
|
||||
authors = ["Fluence Labs"]
|
||||
keywords = ["fluence", "marine", "sdk", "webassembly", "procedural_macros"]
|
||||
categories = ["api-bindings", "wasm"]
|
||||
license = "Apache-2.0"
|
||||
|
||||
[package.metadata.docs.rs]
|
||||
all-features = true
|
||||
|
||||
[lib]
|
||||
proc-macro = true
|
||||
doctest = false
|
||||
|
||||
[dependencies]
|
||||
marine-macro-impl = { path = "../marine-macro-impl", version = "=0.6.13" }
|
@ -1,92 +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.
|
||||
*/
|
||||
|
||||
//! Defines the #[marine] macro that should be used with all export functions, extern blocks.
|
||||
//! At now, It supports the following types that could be used as parameters in export or foreign
|
||||
//! functions: i8, i16, i32, i64, u8, u16, u32, u64, f32, f64, bool, String, Vec<u8>. Also struct
|
||||
//! where all fields are public and have aforementioned types could be used as parameters. In this
|
||||
//! case #[marine] should be also applied to this structs.
|
||||
//!
|
||||
//! # Examples
|
||||
//!
|
||||
//! This example shows how a function could be exported:
|
||||
//! ```ignore
|
||||
//! #[marine]
|
||||
//! pub fn greeting(name: String) -> String {
|
||||
//! format!("Hi {}", name)
|
||||
//! }
|
||||
//! ```
|
||||
//!
|
||||
//! This more complex example shows how a function could be imported from another Wasm module
|
||||
//! and how a struct could be passed:
|
||||
//!
|
||||
//! ```ignore
|
||||
//! use marine_rs_sdk::MountedBinaryResult;
|
||||
//!
|
||||
//! #[marine]
|
||||
//! pub fn read_ipfs_file(file_path: String) -> MountedBinaryResult {
|
||||
//! let hash = calculate_hash(file_path);
|
||||
//! ipfs(vec![hash])
|
||||
//! }
|
||||
//!
|
||||
//! #[marine]
|
||||
//! #[link(wasm_import_module = "ipfs_node")]
|
||||
//! extern "C" {
|
||||
//! pub fn ipfs(file_hash: Vec<String>) -> MountedBinaryResult;
|
||||
//! }
|
||||
//!
|
||||
//! ```
|
||||
|
||||
#![doc(html_root_url = "https://docs.rs/marine-macro/0.6.13")]
|
||||
#![deny(
|
||||
dead_code,
|
||||
nonstandard_style,
|
||||
unused_imports,
|
||||
unused_mut,
|
||||
unused_unsafe,
|
||||
unreachable_patterns
|
||||
)]
|
||||
#![warn(rust_2018_idioms)]
|
||||
#![recursion_limit = "1024"]
|
||||
|
||||
use marine_macro_impl::marine as marine_impl;
|
||||
use proc_macro::TokenStream;
|
||||
|
||||
#[proc_macro_attribute]
|
||||
pub fn marine(_attr: TokenStream, input: TokenStream) -> TokenStream {
|
||||
// into converts proc_macro::TokenStream to proc_macro2::TokenStream
|
||||
match marine_impl(input.into()) {
|
||||
Ok(v) => v,
|
||||
// converts syn:error to proc_macro2::TokenStream
|
||||
Err(e) => e.to_compile_error(),
|
||||
}
|
||||
// converts proc_macro2::TokenStream to proc_macro::TokenStream
|
||||
.into()
|
||||
}
|
||||
|
||||
// deprecated macro for backwards compatibility
|
||||
#[deprecated(since = "0.6.2", note = "please use the #[marine] macro instead")]
|
||||
#[proc_macro_attribute]
|
||||
pub fn fce(_attr: TokenStream, input: TokenStream) -> TokenStream {
|
||||
// into converts proc_macro::TokenStream to proc_macro2::TokenStream
|
||||
match marine_impl(input.into()) {
|
||||
Ok(v) => v,
|
||||
// converts syn:error to proc_macro2::TokenStream
|
||||
Err(e) => e.to_compile_error(),
|
||||
}
|
||||
// converts proc_macro2::TokenStream to proc_macro::TokenStream
|
||||
.into()
|
||||
}
|
@ -26,4 +26,4 @@ thiserror = "1.0.24"
|
||||
static_assertions = "1.1.0"
|
||||
|
||||
[dev-dependencies]
|
||||
marine-macro-testing-utils = {path = "../macro-testing-utils"}
|
||||
marine-macro-testing-utils = "0.1.0"
|
||||
|
@ -1,19 +0,0 @@
|
||||
[package]
|
||||
name = "marine-timestamp-macro"
|
||||
version = "0.6.13" # remember to update html_root_url
|
||||
edition = "2018"
|
||||
description = "Definition of the `#[build_timestamp]` macro"
|
||||
documentation = "https://docs.rs/fluence/marine-timestamp-macro"
|
||||
repository = "https://github.com/fluencelabs/marine-rs-sdk/tree/master/crates/marine-timestamp-macro"
|
||||
authors = ["Fluence Labs"]
|
||||
keywords = ["fluence", "marine", "sdk", "webassembly", "procedural_macros"]
|
||||
categories = ["api-bindings", "wasm"]
|
||||
license = "Apache-2.0"
|
||||
|
||||
[lib]
|
||||
proc-macro = true
|
||||
doctest = false
|
||||
|
||||
[dependencies]
|
||||
chrono = "0.4.19"
|
||||
quote = "1.0.9"
|
@ -1,38 +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.
|
||||
*/
|
||||
|
||||
#![deny(
|
||||
dead_code,
|
||||
nonstandard_style,
|
||||
unused_imports,
|
||||
unused_mut,
|
||||
unused_variables,
|
||||
unused_unsafe,
|
||||
unreachable_patterns
|
||||
)]
|
||||
#![warn(rust_2018_idioms)]
|
||||
#![recursion_limit = "1024"]
|
||||
|
||||
use proc_macro::TokenStream;
|
||||
|
||||
#[proc_macro]
|
||||
pub fn build_timestamp(_: TokenStream) -> TokenStream {
|
||||
let current_utc_date = chrono::Utc::now();
|
||||
let current_utc_date = current_utc_date.to_rfc3339();
|
||||
|
||||
let glue_code = quote::quote! { const __M_SDK_BUILD_TIME: &str = #current_utc_date; };
|
||||
glue_code.into()
|
||||
}
|
@ -1,29 +0,0 @@
|
||||
[package]
|
||||
name = "marine-rs-sdk-test"
|
||||
version = "0.3.0" # remember to update html_root_url
|
||||
description = "Backend SDK that allows testing modules for the Marine runtime"
|
||||
documentation = "https://docs.rs/marine-rs-sdk-test"
|
||||
repository = "https://github.com/fluencelabs/marine-rs-sdk/tree/master/fluence-test"
|
||||
authors = ["Fluence Labs"]
|
||||
keywords = ["fluence", "marine", "sdk", "webassembly", "test"]
|
||||
categories = ["api-bindings", "wasm", "development-tools::testing"]
|
||||
license = "Apache-2.0"
|
||||
edition = "2018"
|
||||
|
||||
[package.metadata.docs.rs]
|
||||
all-features = true
|
||||
|
||||
[lib]
|
||||
path = "src/lib.rs"
|
||||
doctest = false
|
||||
|
||||
[dev-dependencies]
|
||||
trybuild = "1.0"
|
||||
|
||||
[dependencies]
|
||||
marine-test-macro = { path = "../crates/marine-test-macro", version = "=0.3.0" }
|
||||
fluence-app-service = { version = "0.9.0", features = ["raw-module-api"] }
|
||||
|
||||
serde = { version = "1.0.118", features = ["derive"] }
|
||||
serde_json = "1.0.64"
|
||||
uuid = { version = "0.8.2", features = ["v4"] }
|
@ -1,35 +0,0 @@
|
||||
[package]
|
||||
name = "marine-rs-sdk"
|
||||
version = "0.6.13" # remember to update html_root_url
|
||||
description = "Fluence backend SDK for developing backend applications for the Fluence network"
|
||||
documentation = "https://docs.rs/fluence"
|
||||
repository = "https://github.com/fluencelabs/marine-rs-sdk"
|
||||
authors = ["Fluence Labs"]
|
||||
keywords = ["fluence", "marine", "sdk", "webassembly"]
|
||||
categories = ["api-bindings", "wasm"]
|
||||
license = "Apache-2.0"
|
||||
edition = "2018"
|
||||
|
||||
[package.metadata.docs.rs]
|
||||
all-features = true
|
||||
|
||||
[lib]
|
||||
path = "src/lib.rs"
|
||||
doctest = false
|
||||
|
||||
[dependencies]
|
||||
marine-macro = { path = "../crates/marine-macro", version = "=0.6.13" }
|
||||
marine-rs-sdk-main = { path = "../crates/main", version = "=0.6.13" }
|
||||
marine-timestamp-macro = { path = "../crates/timestamp-macro", version = "=0.6.13" }
|
||||
|
||||
serde = { version = "1.0.118", features = ["derive"]}
|
||||
|
||||
[dev-dependencies]
|
||||
trybuild = "1.0"
|
||||
|
||||
[features]
|
||||
# Print some internal logs by log_utf8_string
|
||||
debug = ["marine-rs-sdk-main/debug"]
|
||||
|
||||
# Enable logger (this will cause log_utf8_string to appear in imports)
|
||||
logger = ["marine-rs-sdk-main/logger"]
|
@ -1,79 +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 marine_macro::marine;
|
||||
|
||||
use serde::Serialize;
|
||||
use serde::Deserialize;
|
||||
|
||||
/// Describes an origin that set an argument.
|
||||
#[marine]
|
||||
#[derive(Clone, PartialEq, Default, Eq, Debug, Serialize, Deserialize)]
|
||||
pub struct SecurityTetraplet {
|
||||
pub peer_pk: String,
|
||||
pub service_id: String,
|
||||
pub function_name: String,
|
||||
pub json_path: String,
|
||||
}
|
||||
|
||||
/// This struct contains parameters that would be accessible by Wasm modules.
|
||||
#[marine]
|
||||
#[derive(Clone, PartialEq, Default, Eq, Debug, Serialize, Deserialize)]
|
||||
pub struct CallParameters {
|
||||
/// Peer id of the AIR script initiator.
|
||||
pub init_peer_id: String,
|
||||
|
||||
/// Id of the current service.
|
||||
pub service_id: String,
|
||||
|
||||
/// Id of the service creator.
|
||||
pub service_creator_peer_id: String,
|
||||
|
||||
/// PeerId of the peer who hosts this service.
|
||||
pub host_id: String,
|
||||
|
||||
/// Id of the particle which execution resulted a call this service.
|
||||
pub particle_id: String,
|
||||
|
||||
/// Security tetraplets which described origin of the arguments.
|
||||
pub tetraplets: Vec<Vec<SecurityTetraplet>>,
|
||||
}
|
||||
|
||||
/// This functions takes from host current call parameters.
|
||||
/// Beware that this implies import function call which takes some time.
|
||||
#[cfg(target_arch = "wasm32")]
|
||||
pub fn get_call_parameters() -> CallParameters {
|
||||
// it's safe until it is executed on standard Fluence node with appropriate import function
|
||||
unsafe {
|
||||
get_call_raw_parameters();
|
||||
let raw_call_parameters = crate::internal::get_result_ptr();
|
||||
CallParameters::__m_generated_deserialize(raw_call_parameters as _)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
pub fn get_call_parameters() -> CallParameters {
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
#[cfg(target_arch = "wasm32")]
|
||||
#[link(wasm_import_module = "host")]
|
||||
#[allow(improper_ctypes)]
|
||||
extern "C" {
|
||||
// returns serialized current call parameters
|
||||
#[link_name = "get_call_parameters"]
|
||||
fn get_call_raw_parameters();
|
||||
}
|
105
sdk/src/lib.rs
105
sdk/src/lib.rs
@ -1,105 +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.
|
||||
*/
|
||||
|
||||
//! Rust backend SDK for applications on the Fluence network. This crate defines the procedure macro
|
||||
//! `#[marine]` that could be applied to a function, structure or extern block.
|
||||
//!
|
||||
//! Structures with `#[marine]` (hereinafter they'll be called records) could be used then in function
|
||||
//! arguments and values. All fields of a record should be public and have one of the
|
||||
//! following primitive Rust types
|
||||
//! (`bool, u8, u16, u32, u64, i8, i16, i32, i64, f32, f64, String, Vec<u8>`).
|
||||
//! ```rust
|
||||
//! use marine_rs_sdk::marine;
|
||||
//!
|
||||
//! #[marine]
|
||||
//! struct T {
|
||||
//! pub field_1: i32,
|
||||
//! pub field_2: Vec<u8>,
|
||||
//! }
|
||||
//! ```
|
||||
//!
|
||||
//! Functions with `#[marine]` will be exported from this module:
|
||||
//!
|
||||
//! ```rust
|
||||
//! use marine_rs_sdk::marine;
|
||||
//!
|
||||
//! #[marine]
|
||||
//! pub fn get(url: String) {
|
||||
//! // ...
|
||||
//! }
|
||||
//! ```
|
||||
//! At now, such functions could have arguments with primitive Rust types and record and only one
|
||||
//! return argument with such type could be used.
|
||||
//!
|
||||
//! Finally, to import other wasm modules to your project use similar code:
|
||||
//! ```rust
|
||||
//! use marine_rs_sdk::marine;
|
||||
//!
|
||||
//! #[marine]
|
||||
//! #[link(wasm_import_module = "wasm_curl.wasm")]
|
||||
//! extern "C" {
|
||||
//! #[link_name = "get"]
|
||||
//! pub fn curl_get(url: String) -> String;
|
||||
//! }
|
||||
//! ```
|
||||
#![doc(html_root_url = "https://docs.rs/sdk/0.6.13")]
|
||||
#![deny(
|
||||
dead_code,
|
||||
nonstandard_style,
|
||||
unused_imports,
|
||||
unused_mut,
|
||||
unused_variables,
|
||||
unused_unsafe,
|
||||
unreachable_patterns
|
||||
)]
|
||||
#![warn(rust_2018_idioms)]
|
||||
|
||||
mod call_parameters;
|
||||
mod mounted_binary;
|
||||
|
||||
#[allow(unused_extern_crates)]
|
||||
// sdk is used inside CallParameters and MountedBinaryResult glue code
|
||||
extern crate self as marine_rs_sdk;
|
||||
|
||||
pub use marine_macro::marine;
|
||||
pub use marine_macro::fce;
|
||||
|
||||
pub use call_parameters::CallParameters;
|
||||
pub use call_parameters::SecurityTetraplet;
|
||||
pub use call_parameters::get_call_parameters;
|
||||
|
||||
#[cfg(feature = "logger")]
|
||||
pub use marine_rs_sdk_main::WasmLoggerBuilder;
|
||||
#[cfg(feature = "logger")]
|
||||
pub use marine_rs_sdk_main::TargetMap;
|
||||
|
||||
pub use mounted_binary::MountedBinaryResult;
|
||||
pub use mounted_binary::MountedBinaryStringResult;
|
||||
pub use mounted_binary::SUCCESS_CODE as BINARY_SUCCESS_CODE;
|
||||
|
||||
pub use marine_rs_sdk_main::module_manifest;
|
||||
|
||||
/// These API functions are intended for internal usage in generated code.
|
||||
/// Normally, you shouldn't use them.
|
||||
#[doc(hidden)]
|
||||
pub mod internal {
|
||||
pub use marine_rs_sdk_main::get_result_ptr;
|
||||
pub use marine_rs_sdk_main::get_result_size;
|
||||
pub use marine_rs_sdk_main::set_result_ptr;
|
||||
pub use marine_rs_sdk_main::set_result_size;
|
||||
pub use marine_rs_sdk_main::add_object_to_release;
|
||||
pub use marine_timestamp_macro::build_timestamp;
|
||||
}
|
@ -1,115 +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 marine_macro::marine;
|
||||
|
||||
use serde::Serialize;
|
||||
use serde::Deserialize;
|
||||
|
||||
pub const SUCCESS_CODE: i32 = 0;
|
||||
|
||||
/// Describes result of calling a CLI service.
|
||||
#[marine]
|
||||
#[derive(Clone, PartialEq, Default, Eq, Debug, Serialize, Deserialize)]
|
||||
pub struct MountedBinaryResult {
|
||||
/// Return process exit code or host execution error code, where SUCCESS_CODE means success.
|
||||
pub ret_code: i32,
|
||||
|
||||
/// Contains the string representation of an error, if ret_code != SUCCESS_CODE.
|
||||
pub error: String,
|
||||
|
||||
/// The data that the process wrote to stdout.
|
||||
pub stdout: Vec<u8>,
|
||||
|
||||
/// The data that the process wrote to stderr.
|
||||
pub stderr: Vec<u8>,
|
||||
}
|
||||
|
||||
/// The same as the MountedBinaryResult, but stdout and stderr are utf8 strings.
|
||||
#[marine]
|
||||
#[derive(Clone, PartialEq, Default, Eq, Debug, Serialize, Deserialize)]
|
||||
pub struct MountedBinaryStringResult {
|
||||
/// Return process exit code or host execution error code, where SUCCESS_CODE means success.
|
||||
pub ret_code: i32,
|
||||
|
||||
/// Contains the string representation of an error, if ret_code != SUCCESS_CODE.
|
||||
pub error: String,
|
||||
|
||||
/// The data that the process wrote to stdout.
|
||||
pub stdout: String,
|
||||
|
||||
/// The data that the process wrote to stderr.
|
||||
pub stderr: String,
|
||||
}
|
||||
|
||||
impl MountedBinaryResult {
|
||||
/// Create a new failure MountedBinaryResult from the provided ret_code.
|
||||
pub fn from_error(ret_code: i32, error: impl Into<String>) -> Self {
|
||||
Self {
|
||||
ret_code,
|
||||
error: error.into(),
|
||||
stdout: Vec::new(),
|
||||
stderr: Vec::new(),
|
||||
}
|
||||
}
|
||||
|
||||
/// Return true, if this Result represents a success result, otherwise false.
|
||||
pub fn is_success(&self) -> bool {
|
||||
self.ret_code == SUCCESS_CODE
|
||||
}
|
||||
|
||||
/// This function tries to transform a result to the string representation.
|
||||
/// Internally, It checks ret_code and returns either Some(Ok(stdout)) if it was SUCCESS_CODE
|
||||
/// or Some(Err(error)) otherwise. None is returned if stdout or stderr contains non valid
|
||||
/// UTF8 string.
|
||||
pub fn into_std(self) -> Option<std::result::Result<String, String>> {
|
||||
if self.ret_code == SUCCESS_CODE {
|
||||
let stdout = String::from_utf8(self.stdout).ok()?;
|
||||
Some(Ok(stdout))
|
||||
} else {
|
||||
let stderr = String::from_utf8(self.stderr).ok()?;
|
||||
Some(Err(format!("error: {}, stderr: {}", self.error, stderr)))
|
||||
}
|
||||
}
|
||||
|
||||
/// This function tries to represent a result as a string.
|
||||
/// Internally, It checks ret_code and returns either Some(Ok(stdout)) if it was SUCCESS_CODE
|
||||
/// or Some(Err(error)) otherwise. None is returned if stdout or stderr contains non valid
|
||||
/// UTF8 string.
|
||||
pub fn as_std(&self) -> Option<std::result::Result<String, String>> {
|
||||
if self.ret_code == SUCCESS_CODE {
|
||||
let stdout = String::from_utf8(self.stdout.clone()).ok()?;
|
||||
Some(Ok(stdout))
|
||||
} else {
|
||||
let stderr = String::from_utf8(self.stderr.clone()).ok()?;
|
||||
Some(Err(format!("error: {}, stderr: {}", self.error, stderr)))
|
||||
}
|
||||
}
|
||||
|
||||
pub fn stringify(&self) -> Option<MountedBinaryStringResult> {
|
||||
let stdout = String::from_utf8(self.stdout.clone()).ok()?;
|
||||
let stderr = String::from_utf8(self.stderr.clone()).ok()?;
|
||||
|
||||
let string_result = MountedBinaryStringResult {
|
||||
ret_code: self.ret_code,
|
||||
error: self.error.clone(),
|
||||
stdout,
|
||||
stderr,
|
||||
};
|
||||
|
||||
Some(string_result)
|
||||
}
|
||||
}
|
@ -1,35 +0,0 @@
|
||||
#![allow(improper_ctypes)]
|
||||
|
||||
use marine_rs_sdk::marine;
|
||||
|
||||
pub fn main() {}
|
||||
|
||||
#[marine]
|
||||
pub fn byte_type(_arg: Vec<u8>) -> Vec<u8> {
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
#[marine]
|
||||
pub fn inner_arrays_1(_arg: Vec<&Vec<Vec<Vec<u8>>>>) -> Vec<Vec<Vec<Vec<u8>>>> {
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
#[marine]
|
||||
pub fn inner_arrays_2(_arg: Vec<Vec<&Vec<Vec<u8>>>>) -> Vec<Vec<Vec<Vec<u8>>>> {
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
#[marine]
|
||||
pub fn inner_arrays_3(_arg: Vec<Vec<Vec<&Vec<u8>>>>) -> Vec<Vec<Vec<Vec<u8>>>> {
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
#[marine]
|
||||
pub fn inner_arrays_4(_arg: Vec<Vec<Vec<Vec<&u8>>>>) -> Vec<Vec<Vec<Vec<u8>>>> {
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
#[marine]
|
||||
pub fn inner_arrays_5(_arg1: i32, _arg2: Vec<Vec<Vec<&Vec<u8>>>>, _arg3: i32) -> Vec<Vec<Vec<Vec<u8>>>> {
|
||||
unimplemented!()
|
||||
}
|
@ -1,29 +0,0 @@
|
||||
error: a vector type in arguments of export functions shouldn't contain references
|
||||
--> $DIR/array_inner_refs.rs:13:23
|
||||
|
|
||||
13 | pub fn inner_arrays_1(_arg: Vec<&Vec<Vec<Vec<u8>>>>) -> Vec<Vec<Vec<Vec<u8>>>> {
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: a vector type in arguments of export functions shouldn't contain references
|
||||
--> $DIR/array_inner_refs.rs:18:23
|
||||
|
|
||||
18 | pub fn inner_arrays_2(_arg: Vec<Vec<&Vec<Vec<u8>>>>) -> Vec<Vec<Vec<Vec<u8>>>> {
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: a vector type in arguments of export functions shouldn't contain references
|
||||
--> $DIR/array_inner_refs.rs:23:23
|
||||
|
|
||||
23 | pub fn inner_arrays_3(_arg: Vec<Vec<Vec<&Vec<u8>>>>) -> Vec<Vec<Vec<Vec<u8>>>> {
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: a vector type in arguments of export functions shouldn't contain references
|
||||
--> $DIR/array_inner_refs.rs:28:23
|
||||
|
|
||||
28 | pub fn inner_arrays_4(_arg: Vec<Vec<Vec<Vec<&u8>>>>) -> Vec<Vec<Vec<Vec<u8>>>> {
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: a vector type in arguments of export functions shouldn't contain references
|
||||
--> $DIR/array_inner_refs.rs:33:35
|
||||
|
|
||||
33 | pub fn inner_arrays_5(_arg1: i32, _arg2: Vec<Vec<Vec<&Vec<u8>>>>, _arg3: i32) -> Vec<Vec<Vec<Vec<u8>>>> {
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
@ -1,72 +0,0 @@
|
||||
#![allow(improper_ctypes)]
|
||||
|
||||
use marine_rs_sdk::marine;
|
||||
|
||||
pub fn main() {}
|
||||
|
||||
#[marine]
|
||||
pub fn byte_type(_arg: Vec<u8>) -> Vec<u8> {
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
#[marine]
|
||||
pub fn inner_arrays_1(_arg: Vec<Vec<Vec<Vec<u8>>>>) -> Vec<Vec<Vec<Vec<u8>>>> {
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
#[marine]
|
||||
#[derive(Default)]
|
||||
pub struct TestRecord {
|
||||
pub field_0: i32,
|
||||
pub field_1: Vec<Vec<u8>>,
|
||||
}
|
||||
|
||||
#[marine]
|
||||
pub fn inner_arrays_2(_arg: Vec<Vec<Vec<Vec<TestRecord>>>>) -> Vec<Vec<Vec<Vec<TestRecord>>>> {
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
#[marine]
|
||||
pub fn string_type(_arg: Vec<String>) -> Vec<String> {
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
#[marine]
|
||||
pub fn bool_type(_arg: Vec<bool>) -> Vec<bool> {
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
#[marine]
|
||||
pub fn f32_type(_arg: Vec<f32>) -> Vec<f32> {
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
#[marine]
|
||||
pub fn f64_type(_arg: Vec<f64>) -> Vec<f64> {
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
#[marine]
|
||||
pub fn u32_type(_arg: Vec<u32>) -> Vec<u32> {
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
#[marine]
|
||||
pub fn u64_type(_arg: Vec<u64>) -> Vec<u64> {
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
#[marine]
|
||||
pub fn i32_type(_arg: Vec<i32>) -> Vec<i32> {
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
#[marine]
|
||||
pub fn i64_type(_arg: Vec<i64>) -> Vec<i64> {
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
#[marine]
|
||||
pub fn empty_type() -> Vec<String> {
|
||||
unimplemented!()
|
||||
}
|
@ -1,78 +0,0 @@
|
||||
#![allow(improper_ctypes)]
|
||||
|
||||
use marine_rs_sdk::marine;
|
||||
|
||||
pub fn main() {}
|
||||
|
||||
#[marine]
|
||||
pub fn all_types(
|
||||
_arg_0: i8,
|
||||
_arg_1: i16,
|
||||
_arg_2: i32,
|
||||
_arg_3: i64,
|
||||
_arg_4: u8,
|
||||
_arg_5: u16,
|
||||
_arg_6: u32,
|
||||
_arg_7: u64,
|
||||
_arg_8: f32,
|
||||
_arg_9: f64,
|
||||
_arg_10: String,
|
||||
_arg_11: Vec<u8>,
|
||||
) -> Vec<u8> {
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
#[marine]
|
||||
pub fn string_type(_arg: String) -> String {
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
#[marine]
|
||||
pub fn str_type(_arg: &str) -> &str {
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
#[marine]
|
||||
pub fn bytearray_type(_arg: Vec<u8>) -> Vec<u8> {
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
#[marine]
|
||||
pub fn bool_type(_arg: bool) -> bool {
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
#[marine]
|
||||
pub fn f32_type(_arg: f32) -> f32 {
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
#[marine]
|
||||
pub fn f64_type(_arg: f64) -> f64 {
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
#[marine]
|
||||
pub fn u32_type(_arg: u32) -> u32 {
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
#[marine]
|
||||
pub fn u64_type(_arg: u64) -> u64 {
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
#[marine]
|
||||
pub fn i32_type(_arg: i32) -> i32 {
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
#[marine]
|
||||
pub fn i64_type(_arg: i64) -> i64 {
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
#[marine]
|
||||
pub fn empty_type() -> String {
|
||||
unimplemented!()
|
||||
}
|
@ -1,24 +0,0 @@
|
||||
#![allow(improper_ctypes)]
|
||||
|
||||
use marine_rs_sdk::marine;
|
||||
|
||||
pub fn main() {}
|
||||
|
||||
#[marine]
|
||||
fn test(_arg_1: Box<i32>) {}
|
||||
|
||||
#[marine]
|
||||
fn test2(_arg_1: std::rc::Rc<i32>) {}
|
||||
|
||||
#[marine]
|
||||
fn test3(_arg_1: std::collections::HashMap<i32, String>) {}
|
||||
|
||||
#[marine]
|
||||
fn test4(_arg_1: i32) -> (i32, i32) {
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
#[marine]
|
||||
fn test5(_arg_1: i32) -> Box<i32> {
|
||||
unimplemented!()
|
||||
}
|
@ -1,29 +0,0 @@
|
||||
error: types with lifetimes or generics aren't allowed
|
||||
--> $DIR/improper_types.rs:8:17
|
||||
|
|
||||
8 | fn test(_arg_1: Box<i32>) {}
|
||||
| ^^^^^^^^
|
||||
|
||||
error: types with lifetimes or generics aren't allowed
|
||||
--> $DIR/improper_types.rs:11:27
|
||||
|
|
||||
11 | fn test2(_arg_1: std::rc::Rc<i32>) {}
|
||||
| ^^^^^^^
|
||||
|
||||
error: types with lifetimes or generics aren't allowed
|
||||
--> $DIR/improper_types.rs:14:36
|
||||
|
|
||||
14 | fn test3(_arg_1: std::collections::HashMap<i32, String>) {}
|
||||
| ^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: Incorrect argument type, only path or reference are available on this position
|
||||
--> $DIR/improper_types.rs:17:26
|
||||
|
|
||||
17 | fn test4(_arg_1: i32) -> (i32, i32) {
|
||||
| ^^^^^^^^^^
|
||||
|
||||
error: types with lifetimes or generics aren't allowed
|
||||
--> $DIR/improper_types.rs:22:26
|
||||
|
|
||||
22 | fn test5(_arg_1: i32) -> Box<i32> {
|
||||
| ^^^^^^^^
|
@ -1,15 +0,0 @@
|
||||
#![allow(improper_ctypes)]
|
||||
|
||||
use marine_rs_sdk::marine;
|
||||
|
||||
pub fn main() {}
|
||||
|
||||
#[marine]
|
||||
pub fn inner_arrays_2(_arg: &Vec<Vec<Vec<Vec<u8>>>>) -> &Vec<Vec<&Vec<Vec<u8>>>> {
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
#[marine]
|
||||
pub fn inner_arrays_3(_arg: &Vec<Vec<Vec<Vec<u8>>>>) -> &Vec<&Vec<&Vec<&Vec<&u8>>>> {
|
||||
unimplemented!()
|
||||
}
|
@ -1,11 +0,0 @@
|
||||
error: a vector type in output types of export functions shouldn't contain references
|
||||
--> $DIR/inner_vec_refs.rs:8:54
|
||||
|
|
||||
8 | pub fn inner_arrays_2(_arg: &Vec<Vec<Vec<Vec<u8>>>>) -> &Vec<Vec<&Vec<Vec<u8>>>> {
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: a vector type in output types of export functions shouldn't contain references
|
||||
--> $DIR/inner_vec_refs.rs:13:54
|
||||
|
|
||||
13 | pub fn inner_arrays_3(_arg: &Vec<Vec<Vec<Vec<u8>>>>) -> &Vec<&Vec<&Vec<&Vec<&u8>>>> {
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
@ -1,72 +0,0 @@
|
||||
#![allow(improper_ctypes)]
|
||||
|
||||
use marine_rs_sdk::marine;
|
||||
|
||||
pub fn main() {}
|
||||
|
||||
#[marine]
|
||||
pub fn byte_type(_arg: &Vec<u8>) -> &Vec<u8> {
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
#[marine]
|
||||
pub fn inner_arrays_1(_arg: &Vec<Vec<Vec<Vec<u8>>>>) -> &Vec<Vec<Vec<Vec<u8>>>> {
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
#[marine]
|
||||
#[derive(Default)]
|
||||
pub struct TestRecord {
|
||||
pub field_0: i32,
|
||||
pub field_1: Vec<Vec<u8>>,
|
||||
}
|
||||
|
||||
#[marine]
|
||||
pub fn inner_arrays_4(_arg: &Vec<Vec<Vec<Vec<TestRecord>>>>) -> &Vec<Vec<Vec<Vec<TestRecord>>>> {
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
#[marine]
|
||||
pub fn string_type(_arg: &Vec<String>) -> &Vec<String> {
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
#[marine]
|
||||
pub fn bool_type(_arg: &Vec<bool>) -> &Vec<bool> {
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
#[marine]
|
||||
pub fn f32_type(_arg: &Vec<f32>) -> &Vec<f32> {
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
#[marine]
|
||||
pub fn f64_type(_arg: &Vec<f64>) -> &Vec<f64> {
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
#[marine]
|
||||
pub fn u32_type(_arg: &Vec<u32>) -> &Vec<u32> {
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
#[marine]
|
||||
pub fn u64_type(_arg: &Vec<u64>) -> &Vec<u64> {
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
#[marine]
|
||||
pub fn i32_type(_arg: &Vec<i32>) -> &Vec<i32> {
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
#[marine]
|
||||
pub fn i64_type(_arg: &Vec<i64>) -> &Vec<i64> {
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
#[marine]
|
||||
pub fn empty_type() -> &'static Vec<String> {
|
||||
unimplemented!()
|
||||
}
|
@ -1,73 +0,0 @@
|
||||
#![allow(improper_ctypes)]
|
||||
|
||||
use marine_rs_sdk::marine;
|
||||
|
||||
pub fn main() {}
|
||||
|
||||
#[marine]
|
||||
pub fn all_types<'v>(
|
||||
_arg_0: &i8,
|
||||
_arg_1: &i16,
|
||||
_arg_2: &i32,
|
||||
_arg_3: &i64,
|
||||
_arg_4: &u8,
|
||||
_arg_5: &u16,
|
||||
_arg_6: &u32,
|
||||
_arg_7: &u64,
|
||||
_arg_8: &f32,
|
||||
_arg_9: &f64,
|
||||
_arg_10: &String,
|
||||
_arg_11: &'v Vec<u8>,
|
||||
) -> &'v Vec<u8> {
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
#[marine]
|
||||
pub fn string_type(_arg: &String) -> &String {
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
#[marine]
|
||||
pub fn bytearray_type(_arg: &Vec<u8>) -> &Vec<u8> {
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
#[marine]
|
||||
pub fn bool_type(_arg: &bool) -> &bool {
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
#[marine]
|
||||
pub fn f32_type(_arg: &f32) -> &f32 {
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
#[marine]
|
||||
pub fn f64_type(_arg: &f64) -> &f64 {
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
#[marine]
|
||||
pub fn u32_type(_arg: &u32) -> &u32 {
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
#[marine]
|
||||
pub fn u64_type(_arg: &u64) -> &u64 {
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
#[marine]
|
||||
pub fn i32_type(_arg: &i32) -> &i32 {
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
#[marine]
|
||||
pub fn i64_type(_arg: &i64) -> &i64 {
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
#[marine]
|
||||
pub fn empty_type() -> &'static String {
|
||||
unimplemented!()
|
||||
}
|
@ -1,42 +0,0 @@
|
||||
#![allow(improper_ctypes)]
|
||||
|
||||
use marine_rs_sdk::marine;
|
||||
|
||||
pub fn main() {}
|
||||
|
||||
#[marine]
|
||||
#[derive(Default)]
|
||||
pub struct TestRecord {
|
||||
pub field_0: i32,
|
||||
pub field_1: Vec<Vec<u8>>,
|
||||
}
|
||||
|
||||
#[marine]
|
||||
#[link(wasm_import_module = "arrays_passing_effector")]
|
||||
extern "C" {
|
||||
pub fn inner_arrays_1(arg: Vec<Vec<Vec<Vec<u8>>>>) -> Vec<Vec<Vec<Vec<u8>>>>;
|
||||
|
||||
pub fn inner_arrays_2(
|
||||
arg: Vec<Vec<Vec<Vec<TestRecord>>>>,
|
||||
) -> Vec<Vec<Vec<Vec<TestRecord>>>>;
|
||||
|
||||
pub fn string_type(arg: Vec<String>) -> Vec<String>;
|
||||
|
||||
pub fn bool_type(arg: Vec<bool>) -> Vec<bool>;
|
||||
|
||||
pub fn byte_type(arg: Vec<u8>) -> Vec<u8>;
|
||||
|
||||
pub fn f32_type(arg: Vec<f32>) -> Vec<f32>;
|
||||
|
||||
pub fn f64_type(arg: Vec<f64>) -> Vec<f64>;
|
||||
|
||||
pub fn u32_type(arg: Vec<u32>) -> Vec<u32>;
|
||||
|
||||
pub fn u64_type(arg: Vec<u64>) -> Vec<u64>;
|
||||
|
||||
pub fn i32_type(arg: Vec<i32>) -> Vec<i32>;
|
||||
|
||||
pub fn i64_type(arg: Vec<i64>) -> Vec<i64>;
|
||||
|
||||
pub fn empty_type() -> Vec<String>;
|
||||
}
|
@ -1,27 +0,0 @@
|
||||
#![allow(improper_ctypes)]
|
||||
|
||||
use marine_rs_sdk::marine;
|
||||
|
||||
pub fn main() {}
|
||||
|
||||
#[marine]
|
||||
#[link(wasm_import_module = "arrays_passing_effector")]
|
||||
extern "C" {
|
||||
#[marine]
|
||||
pub fn func_1() -> &String;
|
||||
|
||||
#[marine]
|
||||
pub fn func_2() -> &Vec<Vec<Vec<Vec<u8>>>>;
|
||||
|
||||
#[marine]
|
||||
pub fn func_3() -> Vec<&Vec<Vec<Vec<u8>>>>;
|
||||
|
||||
#[marine]
|
||||
pub fn func_4() -> Vec<Vec<&Vec<Vec<u8>>>>;
|
||||
|
||||
#[marine]
|
||||
pub fn func_5() -> Vec<Vec<Vec<&Vec<u8>>>>;
|
||||
|
||||
#[marine]
|
||||
pub fn func_6() -> Vec<Vec<Vec<Vec<&u8>>>>;
|
||||
}
|
@ -1,6 +0,0 @@
|
||||
error: import function can't return a value with references
|
||||
--> $DIR/arrays_out_inner_refs.rs:10:5
|
||||
|
|
||||
10 | / #[marine]
|
||||
11 | | pub fn func_1() -> &String;
|
||||
| |_______________________________^
|
@ -1,44 +0,0 @@
|
||||
#![allow(improper_ctypes)]
|
||||
|
||||
use marine_rs_sdk::marine;
|
||||
|
||||
fn main() {}
|
||||
|
||||
#[marine]
|
||||
#[link(wasm_import_module = "arguments_passing_effector")]
|
||||
extern "C" {
|
||||
pub fn all_ref_types(
|
||||
arg_0: &i8,
|
||||
arg_1: &i16,
|
||||
arg_2: &i32,
|
||||
arg_3: &i64,
|
||||
arg_4: &u8,
|
||||
arg_5: &u16,
|
||||
arg_6: &u32,
|
||||
arg_7: &u64,
|
||||
arg_8: &f32,
|
||||
arg_9: &f64,
|
||||
arg_10: &String,
|
||||
arg_11: &Vec<u8>,
|
||||
) -> Vec<u8>;
|
||||
|
||||
pub fn string_ref_type(arg: &String) -> String;
|
||||
|
||||
pub fn str_type(arg: &str) -> String;
|
||||
|
||||
pub fn bytearray_ref_type(arg: &Vec<u8>) -> Vec<u8>;
|
||||
|
||||
pub fn bool_ref_type(arg: &bool) -> bool;
|
||||
|
||||
pub fn f32_ref_type(arg: &f32) -> f32;
|
||||
|
||||
pub fn f64_ref_type(arg: &f64) -> f64;
|
||||
|
||||
pub fn u32_ref_type(arg: &u32) -> u32;
|
||||
|
||||
pub fn u64_ref_type(arg: &u64) -> u64;
|
||||
|
||||
pub fn i32_ref_type(arg: &i32) -> i32;
|
||||
|
||||
pub fn i64_ref_type(arg: &i64) -> i64;
|
||||
}
|
@ -1,40 +0,0 @@
|
||||
#![allow(improper_ctypes)]
|
||||
|
||||
use marine_rs_sdk::marine;
|
||||
|
||||
fn main() {}
|
||||
|
||||
#[marine]
|
||||
#[link(wasm_import_module = "arguments_passing_effector")]
|
||||
extern "C" {
|
||||
pub fn all_types(
|
||||
arg_0: i8,
|
||||
arg_1: i16,
|
||||
arg_2: i32,
|
||||
arg_3: i64,
|
||||
arg_4: u8,
|
||||
arg_5: u16,
|
||||
arg_6: u32,
|
||||
arg_7: u64,
|
||||
arg_8: f32,
|
||||
arg_9: f64,
|
||||
arg_10: String,
|
||||
arg_11: Vec<u8>,
|
||||
) -> Vec<u8>;
|
||||
|
||||
pub fn string_type(arg: String) -> String;
|
||||
pub fn bytearray_type(arg: Vec<u8>) -> Vec<u8>;
|
||||
|
||||
pub fn bool_type(arg: bool) -> bool;
|
||||
|
||||
pub fn f32_type(arg: f32) -> f32;
|
||||
pub fn f64_type(arg: f64) -> f64;
|
||||
|
||||
pub fn u32_type(arg: u32) -> u32;
|
||||
pub fn u64_type(arg: u64) -> u64;
|
||||
|
||||
pub fn i32_type(arg: i32) -> i32;
|
||||
pub fn i64_type(arg: i64) -> i64;
|
||||
|
||||
pub fn empty_type() -> String;
|
||||
}
|
@ -1,24 +0,0 @@
|
||||
#![allow(improper_ctypes)]
|
||||
|
||||
use marine_rs_sdk::marine;
|
||||
|
||||
pub fn main() {}
|
||||
|
||||
#[marine]
|
||||
#[link(wasm_import_module = "arguments_passing_effector")]
|
||||
extern "C" {
|
||||
#[marine]
|
||||
fn test(_arg_1: Box<i32>);
|
||||
|
||||
#[marine]
|
||||
fn test2(_arg_1: std::rc::Rc<i32>);
|
||||
|
||||
#[marine]
|
||||
fn test3(_arg_1: std::collections::HashMap<i32, String>);
|
||||
|
||||
#[marine]
|
||||
fn test4(_arg_1: i32) -> (i32, i32);
|
||||
|
||||
#[marine]
|
||||
fn test5(_arg_1: i32) -> Box<i32>;
|
||||
}
|
@ -1,5 +0,0 @@
|
||||
error: types with lifetimes or generics aren't allowed
|
||||
--> $DIR/improper_types.rs:11:21
|
||||
|
|
||||
11 | fn test(_arg_1: Box<i32>);
|
||||
| ^^^^^^^^
|
@ -1,60 +0,0 @@
|
||||
#![allow(improper_ctypes)]
|
||||
|
||||
use marine_rs_sdk::marine;
|
||||
|
||||
pub fn main() {}
|
||||
|
||||
#[marine]
|
||||
#[derive(Default)]
|
||||
pub struct TestRecord {
|
||||
pub field_0: i32,
|
||||
pub field_1: Vec<Vec<u8>>,
|
||||
}
|
||||
|
||||
#[marine]
|
||||
#[link(wasm_import_module = "arrays_passing_effector")]
|
||||
extern "C" {
|
||||
pub fn inner_arrays_1(arg: &Vec<Vec<Vec<Vec<u8>>>>) -> Vec<Vec<Vec<Vec<u8>>>>;
|
||||
pub fn inner_arrays_2(arg: &Vec<&Vec<Vec<Vec<u8>>>>) -> Vec<Vec<Vec<Vec<u8>>>>;
|
||||
pub fn inner_arrays_3(arg: &Vec<&Vec<&Vec<Vec<u8>>>>) -> Vec<Vec<Vec<Vec<u8>>>>;
|
||||
pub fn inner_arrays_4(arg: &Vec<&Vec<&Vec<&Vec<u8>>>>) -> Vec<Vec<Vec<Vec<u8>>>>;
|
||||
pub fn inner_arrays_5(arg: &Vec<&Vec<&Vec<&Vec<&u8>>>>) -> Vec<Vec<Vec<Vec<u8>>>>;
|
||||
|
||||
pub fn inner_arrays_6(
|
||||
arg: &Vec<Vec<Vec<Vec<TestRecord>>>>,
|
||||
) -> Vec<Vec<Vec<Vec<TestRecord>>>>;
|
||||
|
||||
pub fn inner_arrays_7(
|
||||
arg: &Vec<&Vec<Vec<Vec<TestRecord>>>>,
|
||||
) -> Vec<Vec<Vec<Vec<TestRecord>>>>;
|
||||
|
||||
pub fn inner_arrays_8(
|
||||
arg: &Vec<&Vec<&Vec<Vec<TestRecord>>>>,
|
||||
) -> Vec<Vec<Vec<Vec<TestRecord>>>>;
|
||||
|
||||
pub fn inner_arrays_9(
|
||||
arg: &Vec<&Vec<&Vec<&Vec<TestRecord>>>>,
|
||||
) -> Vec<Vec<Vec<Vec<TestRecord>>>>;
|
||||
|
||||
pub fn inner_arrays_10(
|
||||
arg: &Vec<&Vec<&Vec<&Vec<&TestRecord>>>>,
|
||||
) -> Vec<Vec<Vec<Vec<TestRecord>>>>;
|
||||
|
||||
pub fn string_type(arg: &Vec<String>) -> Vec<String>;
|
||||
|
||||
pub fn bool_type(arg: &Vec<bool>) -> Vec<bool>;
|
||||
|
||||
pub fn byte_type(arg: &Vec<u8>) -> Vec<u8>;
|
||||
|
||||
pub fn f32_type(arg: &Vec<f32>) -> Vec<f32>;
|
||||
|
||||
pub fn f64_type(arg: &Vec<f64>) -> Vec<f64>;
|
||||
|
||||
pub fn u32_type(arg: &Vec<u32>) -> Vec<u32>;
|
||||
|
||||
pub fn u64_type(arg: &Vec<u64>) -> Vec<u64>;
|
||||
|
||||
pub fn i32_type(arg: &Vec<i32>) -> Vec<i32>;
|
||||
|
||||
pub fn i64_type(arg: &Vec<i64>) -> Vec<i64>;
|
||||
}
|
@ -1,38 +0,0 @@
|
||||
#![allow(improper_ctypes)]
|
||||
|
||||
use marine_rs_sdk::marine;
|
||||
|
||||
fn main() {}
|
||||
|
||||
#[marine]
|
||||
#[link(wasm_import_module = "arguments_passing_effector")]
|
||||
extern "C" {
|
||||
pub fn all_types(
|
||||
arg_0: &i8,
|
||||
arg_1: &i16,
|
||||
arg_2: &i32,
|
||||
arg_3: &i64,
|
||||
arg_4: &u8,
|
||||
arg_5: &u16,
|
||||
arg_6: &u32,
|
||||
arg_7: &u64,
|
||||
arg_8: &f32,
|
||||
arg_9: &f64,
|
||||
arg_10: &String,
|
||||
arg_11: &Vec<u8>,
|
||||
) -> Vec<u8>;
|
||||
|
||||
pub fn string_type(arg: &String) -> String;
|
||||
pub fn bytearray_type(arg: &Vec<u8>) -> Vec<u8>;
|
||||
|
||||
pub fn bool_type(arg: &bool) -> bool;
|
||||
|
||||
pub fn f32_type(arg: &f32) -> f32;
|
||||
pub fn f64_type(arg: &f64) -> f64;
|
||||
|
||||
pub fn u32_type(arg: &u32) -> u32;
|
||||
pub fn u64_type(arg: &u64) -> u64;
|
||||
|
||||
pub fn i32_type(arg: &i32) -> i32;
|
||||
pub fn i64_type(arg: &i64) -> i64;
|
||||
}
|
@ -1,80 +0,0 @@
|
||||
use marine_rs_sdk::marine;
|
||||
|
||||
fn main() {}
|
||||
|
||||
#[marine]
|
||||
pub struct TestRecord {
|
||||
pub field_0: bool,
|
||||
pub field_1: i8,
|
||||
pub field_2: i16,
|
||||
pub field_3: i32,
|
||||
pub field_4: i64,
|
||||
pub field_5: u8,
|
||||
pub field_6: u16,
|
||||
pub field_7: u32,
|
||||
pub field_8: u64,
|
||||
pub field_9: f32,
|
||||
pub field_10: f64,
|
||||
pub field_11: String,
|
||||
pub field_12: Vec<u8>,
|
||||
}
|
||||
|
||||
#[marine]
|
||||
pub struct Tx {
|
||||
pub block_hash: String,
|
||||
pub block_number: String,
|
||||
pub from: String,
|
||||
pub gas: String,
|
||||
pub gas_price: String,
|
||||
pub hash: String,
|
||||
pub input: String,
|
||||
pub nonce: String,
|
||||
pub to: String,
|
||||
pub transaction_index: String,
|
||||
pub value: String,
|
||||
}
|
||||
|
||||
#[marine]
|
||||
#[derive(Debug)]
|
||||
pub struct JsonRpcResult {
|
||||
pub json_rpc: String,
|
||||
pub result: String,
|
||||
pub error: String,
|
||||
pub id: u64,
|
||||
}
|
||||
|
||||
#[marine]
|
||||
#[derive(Clone, Debug, Default, Eq, PartialEq, Hash)]
|
||||
pub struct User {
|
||||
pub peer_id: String,
|
||||
pub relay_id: String,
|
||||
pub signature: String,
|
||||
pub name: String,
|
||||
}
|
||||
|
||||
#[marine]
|
||||
pub struct GetUsersServiceResult {
|
||||
pub ret_code: i32,
|
||||
pub err_msg: String,
|
||||
pub users: Vec<User>,
|
||||
}
|
||||
|
||||
#[marine]
|
||||
pub struct EmptyServiceResult {
|
||||
pub ret_code: i32,
|
||||
pub err_msg: String,
|
||||
}
|
||||
|
||||
#[marine]
|
||||
pub struct ExistsServiceResult {
|
||||
pub ret_code: i32,
|
||||
pub err_msg: String,
|
||||
pub is_exists: bool,
|
||||
}
|
||||
|
||||
#[marine]
|
||||
pub struct AuthResult {
|
||||
pub ret_code: i32,
|
||||
pub err_msg: String,
|
||||
pub is_authenticated: bool,
|
||||
}
|
@ -1,6 +0,0 @@
|
||||
use marine_rs_sdk::marine;
|
||||
|
||||
fn main() {}
|
||||
|
||||
#[marine]
|
||||
struct A {}
|
@ -1,18 +0,0 @@
|
||||
use marine_rs_sdk::marine;
|
||||
|
||||
fn main() {}
|
||||
|
||||
#[marine]
|
||||
struct StructWithBox {
|
||||
pub a: Box<i32>,
|
||||
}
|
||||
|
||||
#[marine]
|
||||
struct StructWithRc {
|
||||
pub a: std::rc::Rc<i32>,
|
||||
}
|
||||
|
||||
#[marine]
|
||||
struct StructWithHashMap {
|
||||
pub a: std::collections::HashMap<i32, String>,
|
||||
}
|
@ -1,17 +0,0 @@
|
||||
error: types with lifetimes or generics aren't allowed
|
||||
--> $DIR/struct_with_improper_types.rs:7:12
|
||||
|
|
||||
7 | pub a: Box<i32>,
|
||||
| ^^^^^^^^
|
||||
|
||||
error: types with lifetimes or generics aren't allowed
|
||||
--> $DIR/struct_with_improper_types.rs:12:21
|
||||
|
|
||||
12 | pub a: std::rc::Rc<i32>,
|
||||
| ^^^^^^^
|
||||
|
||||
error: types with lifetimes or generics aren't allowed
|
||||
--> $DIR/struct_with_improper_types.rs:17:30
|
||||
|
|
||||
17 | pub a: std::collections::HashMap<i32, String>,
|
||||
| ^^^^^^^^^^^^^^^^^^^^
|
@ -1,11 +0,0 @@
|
||||
#![allow(improper_ctypes)]
|
||||
|
||||
use marine_rs_sdk::marine;
|
||||
|
||||
fn main() {}
|
||||
|
||||
#[marine]
|
||||
struct StructWithPrivateFields {
|
||||
a: i32,
|
||||
b: usize,
|
||||
}
|
@ -1,5 +0,0 @@
|
||||
error: #[marine] could be applied only to struct with all public fields
|
||||
--> $DIR/struct_with_private_fields.rs:9:5
|
||||
|
|
||||
9 | a: i32,
|
||||
| ^^^^^^
|
@ -1,8 +0,0 @@
|
||||
#![allow(improper_ctypes)]
|
||||
|
||||
use marine_rs_sdk::marine;
|
||||
|
||||
fn main() {}
|
||||
|
||||
#[marine]
|
||||
struct A(pub i32, pub u32);
|
@ -1,5 +0,0 @@
|
||||
error: only named fields are allowed in structs
|
||||
--> $DIR/unnamed_structs.rs:8:1
|
||||
|
|
||||
8 | struct A(pub i32, pub u32);
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
@ -1,25 +0,0 @@
|
||||
#[test]
|
||||
fn marine_compilation_tests() {
|
||||
let tests = trybuild::TestCases::new();
|
||||
tests.compile_fail("tests/compilation_tests/export_functions/array_inner_refs.rs");
|
||||
tests.pass("tests/compilation_tests/export_functions/arrays.rs");
|
||||
tests.pass("tests/compilation_tests/export_functions/ref_arrays.rs");
|
||||
tests.compile_fail("tests/compilation_tests/export_functions/inner_vec_refs.rs");
|
||||
tests.pass("tests/compilation_tests/export_functions/basic_types.rs");
|
||||
tests.pass("tests/compilation_tests/export_functions/ref_basic_types.rs");
|
||||
tests.compile_fail("tests/compilation_tests/export_functions/improper_types.rs");
|
||||
|
||||
tests.compile_fail("tests/compilation_tests/import_functions/arrays_out_inner_refs.rs");
|
||||
tests.pass("tests/compilation_tests/import_functions/arrays.rs");
|
||||
tests.pass("tests/compilation_tests/import_functions/ref_arrays.rs");
|
||||
tests.pass("tests/compilation_tests/import_functions/basic_types.rs");
|
||||
tests.pass("tests/compilation_tests/import_functions/basic_ref_types.rs");
|
||||
tests.pass("tests/compilation_tests/import_functions/ref_basic_types.rs");
|
||||
tests.compile_fail("tests/compilation_tests/import_functions/improper_types.rs");
|
||||
|
||||
tests.pass("tests/compilation_tests/records/basic_structs.rs");
|
||||
tests.pass("tests/compilation_tests/records/empty_struct.rs");
|
||||
tests.compile_fail("tests/compilation_tests/records/struct_with_improper_types.rs");
|
||||
tests.compile_fail("tests/compilation_tests/records/struct_with_private_fields.rs");
|
||||
tests.compile_fail("tests/compilation_tests/records/unnamed_structs.rs");
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user