Remove marine-rs-sdk code (#1)

This commit is contained in:
Valery Antopol 2021-10-07 20:05:04 +03:00 committed by GitHub
parent 60cc4fbd9f
commit 99ff3d2427
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
101 changed files with 54 additions and 6840 deletions

View File

@ -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:

View File

@ -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
View File

@ -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"

View File

@ -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",
]

View File

@ -1,5 +1,4 @@
![crates.io version](https://img.shields.io/crates/v/fluence?color=green)
[![crates.io version](https://img.shields.io/crates/v/marine-rs-sdk-test?color=green)](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).

View File

@ -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'] }

View File

@ -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
}

View File

@ -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 = []

View File

@ -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
}

View File

@ -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);
}
};
}

View File

@ -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(&not_allowed_metadata));
let not_allowed_metadata = create_metadata(module_2_name, log::Level::Info);
assert!(!logger.enabled(&not_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(&not_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(&not_allowed_metadata));
}
}

View File

@ -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")
);
};
}

View File

@ -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);
});
}

View File

@ -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();

View File

@ -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"}

View File

@ -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),
}

View File

@ -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,
}
}
}

View File

@ -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__";

View File

@ -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)
}

View File

@ -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",
)),
}
}
}

View File

@ -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,
}
}

View File

@ -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,
}
}

View File

@ -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(())
}

View File

@ -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,
}
}

View File

@ -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)",
)),
}
}

View File

@ -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]
}
}
}
}

View File

@ -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
}

View File

@ -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! {},
}
}

View File

@ -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! { * },
}
}

View File

@ -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"
),
}
}
}

View File

@ -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
}

View File

@ -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"),
}
}
}

View File

@ -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,
}
}

View File

@ -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
}
}
}

View File

@ -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
}
}

View File

@ -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 _)
}
}

View File

@ -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),
}
}
}

View File

@ -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);
}
}

View File

@ -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
}

View File

@ -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
}
}
}

View File

@ -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
}
}

View File

@ -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),*
}
}
}

View File

@ -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 }
}
}
}

View File

@ -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()
}

View File

@ -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),
}
}
}

View File

@ -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\"]}]}}"
};

View File

@ -1,3 +0,0 @@
pub fn inner_arrays_1(arg: Vec<Vec<Vec<Vec<u8>>>>) -> Vec<Vec<Vec<Vec<u8>>>> {
unimplemented!()
}

View File

@ -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\"]}]}}"
};

View File

@ -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!()
}

View File

@ -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\"]}]}}"
};

View File

@ -1,3 +0,0 @@
pub fn test_array_refs(arg: &Vec<Vec<String>>) -> &Vec<Vec<Vec<Vec<String>>>> {
unimplemented!()
}

View File

@ -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\"]}]}}]}"
};

View File

@ -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>>>>;
}

View File

@ -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\"]}]}}]}"
};

View File

@ -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>;
}

View File

@ -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\"]}}]}}"
};

View File

@ -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>>,
}

View File

@ -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\"]}]}}"
};

View File

@ -1,3 +0,0 @@
pub fn inner_arrays_2(arg: Vec<Vec<Vec<Vec<TestRecord>>>>) -> Vec<Vec<Vec<Vec<TestRecord>>>> {
unimplemented!()
}

View File

@ -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",
));
}

View File

@ -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
}

View File

@ -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" }

View File

@ -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()
}

View File

@ -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"

View File

@ -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"

View File

@ -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()
}

View File

@ -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"] }

View File

@ -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"]

View File

@ -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();
}

View File

@ -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;
}

View File

@ -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)
}
}

View File

@ -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!()
}

View File

@ -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>>>> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

View File

@ -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!()
}

View File

@ -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!()
}

View File

@ -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!()
}

View File

@ -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> {
| ^^^^^^^^

View File

@ -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!()
}

View File

@ -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>>>> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

View File

@ -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!()
}

View File

@ -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!()
}

View File

@ -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>;
}

View File

@ -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>>>>;
}

View File

@ -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;
| |_______________________________^

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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>;
}

View File

@ -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>);
| ^^^^^^^^

View File

@ -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>;
}

View File

@ -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;
}

View File

@ -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,
}

View File

@ -1,6 +0,0 @@
use marine_rs_sdk::marine;
fn main() {}
#[marine]
struct A {}

View File

@ -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>,
}

View File

@ -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>,
| ^^^^^^^^^^^^^^^^^^^^

View File

@ -1,11 +0,0 @@
#![allow(improper_ctypes)]
use marine_rs_sdk::marine;
fn main() {}
#[marine]
struct StructWithPrivateFields {
a: i32,
b: usize,
}

View File

@ -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,
| ^^^^^^

View File

@ -1,8 +0,0 @@
#![allow(improper_ctypes)]
use marine_rs_sdk::marine;
fn main() {}
#[marine]
struct A(pub i32, pub u32);

View File

@ -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);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^

View File

@ -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