From aa73411663c439d0d0633e1ac4eca14726699f04 Mon Sep 17 00:00:00 2001 From: vms Date: Wed, 1 Jul 2020 00:50:56 +0300 Subject: [PATCH] update the main part to the new sdk --- Cargo.toml | 11 +- crates/macro/src/lib.rs | 2 +- crates/main/Cargo.toml | 14 +- crates/main/src/eth/mod.rs | 24 --- crates/main/src/export_allocator/mod.rs | 52 ++++--- crates/main/src/lib.rs | 28 ++-- crates/main/src/logger/mod.rs | 16 +- crates/main/src/memory/errors.rs | 77 ---------- crates/main/src/memory/mod.rs | 187 ------------------------ crates/main/src/result/mod.rs | 54 +++++++ crates/main/src/side_module/mod.rs | 33 ----- rustfmt.toml | 6 +- src/lib.rs | 23 +-- 13 files changed, 120 insertions(+), 407 deletions(-) delete mode 100644 crates/main/src/eth/mod.rs delete mode 100644 crates/main/src/memory/errors.rs delete mode 100644 crates/main/src/memory/mod.rs create mode 100644 crates/main/src/result/mod.rs delete mode 100644 crates/main/src/side_module/mod.rs diff --git a/Cargo.toml b/Cargo.toml index 63add01..2722dd6 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -22,15 +22,8 @@ fluence-sdk-macro = { path = "crates/macro", version = "=0.1.11" } fluence-sdk-main = { path = "crates/main", version = "=0.1.11" } [features] -default = ["export_allocator"] -# Turn on a compilation for the module that contains Wasm logger realization. -wasm_logger = ["fluence-sdk-main/wasm_logger"] - -# Turn on a compilation for the module that contains the standard implementation of allocate/deallocate functions. -export_allocator = ["fluence-sdk-main/export_allocator"] - -# Provides additional imports to allow this module work as a side module -side_module = ["fluence-sdk-main/side_module"] +# Print some internal logs by log_utf8_string +print_logs = ["fluence-sdk-main/print_logs"] [workspace] members = [ diff --git a/crates/macro/src/lib.rs b/crates/macro/src/lib.rs index 81ebdcb..d5e06b5 100644 --- a/crates/macro/src/lib.rs +++ b/crates/macro/src/lib.rs @@ -201,7 +201,7 @@ fn invoke_handler_impl( } #[proc_macro_attribute] -pub fn invocation_handler(attr: TokenStream, input: TokenStream) -> TokenStream { +pub fn faas_export(attr: TokenStream, input: TokenStream) -> TokenStream { let fn_item = parse_macro_input!(input as ItemFn); match invoke_handler_impl(attr.into(), fn_item) { Ok(v) => v, diff --git a/crates/main/Cargo.toml b/crates/main/Cargo.toml index 7bb6712..9ce10c0 100644 --- a/crates/main/Cargo.toml +++ b/crates/main/Cargo.toml @@ -20,21 +20,11 @@ crate-type = ["rlib"] [dependencies] log = { version = "0.4.8", features = ["std"] } -syn = { version = '0.15.44', features = ['full'] } [dev-dependencies] simple_logger = "1.6.0" # used in doc test lazy_static = "1.4.0" # used in doc test [features] -# Turn on the Wasm logger. -wasm_logger = [] - -# Make this module as side module. -side_module = [] - -# Notify the VM that this module expects Ethereum blocks. -expect_eth = [] - -# Turn on the module contained implementation of allocate/deallocate functions. -export_allocator = [] +# Print some internal logs by log_utf8_string +print_logs = [] diff --git a/crates/main/src/eth/mod.rs b/crates/main/src/eth/mod.rs deleted file mode 100644 index 3b9e16f..0000000 --- a/crates/main/src/eth/mod.rs +++ /dev/null @@ -1,24 +0,0 @@ -/* - * Copyright 2019 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. - */ - -//! Notifies the VM that this module expects Ethereum blocks. -//! -//! This module contains functions for loading from and storing to memory. - -/// A temporary solution to let users configure their ethereum expectations via WASM bytecode: -/// to enable block uploading via invoke method, just export expects_eth method from the module. -#[no_mangle] -pub unsafe fn expects_eth() {} diff --git a/crates/main/src/export_allocator/mod.rs b/crates/main/src/export_allocator/mod.rs index fd44721..dc7c088 100644 --- a/crates/main/src/export_allocator/mod.rs +++ b/crates/main/src/export_allocator/mod.rs @@ -1,5 +1,5 @@ /* - * Copyright 2018 Fluence Labs Limited + * 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. @@ -14,32 +14,42 @@ * limitations under the License. */ -//! This module provides default implementations of [`allocate`] and [`deallocate`] functions that -//! can be used for array passing and returning. -//! -//! [`allocate`]: fn.allocate.html -//! [`deallocate`]: fn.deallocate.html +use crate::log_utf8_string; -use crate::memory::{alloc, dealloc}; -use std::num::NonZeroUsize; -use std::ptr::NonNull; +use std::alloc::alloc as global_alloc; +use std::alloc::dealloc as global_dealloc; +use std::alloc::Layout; /// Allocates memory area of specified size and returns its address. -/// Used from the host environment for memory allocation while parameters passing. +/// Returns 0 if supplied size is too long. #[no_mangle] -pub unsafe fn allocate(size: usize) -> NonNull { - let non_zero_size = NonZeroUsize::new(size) - .unwrap_or_else(|| panic!("[Error] Allocation of zero bytes is not allowed.")); - alloc(non_zero_size).unwrap_or_else(|_| panic!("[Error] Allocation of {} bytes failed.", size)) +pub unsafe fn allocate(size: usize) -> usize { + let layout = match Layout::from_size_align(size, std::mem::align_of::()) { + Ok(layout) => layout, + // in this case a err could be only in a case of too long allocated size, + // so just return 0 + Err(_) => return 0, + }; + + let msg = format!("sdk.allocate: {:?}\n", size); + log_utf8_string(msg.as_ptr() as _, msg.len() as _); + + global_alloc(layout) as _ } /// Deallocates memory area for provided memory pointer and size. -/// Used from the host environment for memory deallocation after reading results of function from -/// Wasm memory. +/// Does nothing if supplied size is too long. #[no_mangle] -pub unsafe fn deallocate(ptr: NonNull, size: usize) { - let non_zero_size = NonZeroUsize::new(size) - .unwrap_or_else(|| panic!("[Error] Deallocation of zero bytes is not allowed.")); - dealloc(ptr, non_zero_size) - .unwrap_or_else(|_| panic!("[Error] Deallocate failed for ptr={:?} size={}.", ptr, size)); +pub unsafe fn deallocate(ptr: *mut u8, size: usize) { + let layout = match Layout::from_size_align(size, std::mem::align_of::()) { + Ok(layout) => layout, + // in this case a err could be only in a case of too long allocated size, + // so just done nothing + Err(_) => return, + }; + + let msg = format!("sdk.deallocate: {:?} {}\n", ptr, size); + log_utf8_string(msg.as_ptr() as _, msg.len() as _); + + global_dealloc(ptr, layout); } diff --git a/crates/main/src/lib.rs b/crates/main/src/lib.rs index af301a2..6af4a7f 100644 --- a/crates/main/src/lib.rs +++ b/crates/main/src/lib.rs @@ -14,12 +14,12 @@ * limitations under the License. */ -//! The main part of Fluence backend SDK. Contains `export_allocator` (is turned on by the -//! `export_allocator` feature), `logger` (is turned on by the `wasm_logger` feature), and `memory` +//! 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/fluence-sdk-main/0.1.11")] -#![feature(allocator_api)] #![deny( dead_code, nonstandard_style, @@ -31,16 +31,16 @@ )] #![warn(rust_2018_idioms)] -pub mod memory; +mod export_allocator; +mod logger; +mod result; -#[cfg(feature = "wasm_logger")] -pub mod logger; +pub(crate) use logger::log_utf8_string; -#[cfg(feature = "side_module")] -pub mod side_module; - -#[cfg(feature = "expect_eth")] -pub mod eth; - -#[cfg(feature = "export_allocator")] -pub mod export_allocator; +pub use export_allocator::allocate; +pub use export_allocator::deallocate; +pub use logger::WasmLogger; +pub use result::get_result_ptr; +pub use result::get_result_size; +pub use result::set_result_ptr; +pub use result::set_result_size; diff --git a/crates/main/src/logger/mod.rs b/crates/main/src/logger/mod.rs index 0ae56c4..a5b99d5 100644 --- a/crates/main/src/logger/mod.rs +++ b/crates/main/src/logger/mod.rs @@ -73,8 +73,6 @@ //! [`lazy_static::initialize()`]: https://docs.rs/lazy_static/1.3.0/lazy_static/fn.initialize.html //! [`backend app debugging`]: https://fluence.dev/docs/debugging -use log; - /// The Wasm Logger. /// /// This struct implements the [`Log`] trait from the [`log`] crate, which allows it to act as a @@ -92,8 +90,8 @@ pub struct WasmLogger { } impl WasmLogger { - /// Initializes the global logger with a [`WasmLogger`] instance with - /// `max_log_level` set to a specific log level. + /// Initializes the global logger with a [`WasmLogger`] instance, sets + /// `max_log_level` to a given log level. /// /// ``` /// # use fluence::sdk::*; @@ -114,8 +112,8 @@ impl WasmLogger { Ok(()) } - /// Initializes the global logger with a [`WasmLogger`] instance with `max_log_level` set to - /// `Level::Info`. + /// Initializes the global logger with a [`WasmLogger`] instance, sets + /// `max_log_level` to `Level::Info`. /// /// ``` /// # use fluence::sdk::*; @@ -162,9 +160,9 @@ impl log::Log for WasmLogger { fn flush(&self) {} } -/// logger is a module provided by a VM that can process log messages. -#[link(wasm_import_module = "logger")] +/// log_utf8_string should be provided directly by a host. +#[link(wasm_import_module = "host")] extern "C" { // Writes a byte string of size bytes that starts from ptr to a logger - fn log_utf8_string(ptr: i32, size: i32); + pub fn log_utf8_string(ptr: i32, size: i32); } diff --git a/crates/main/src/memory/errors.rs b/crates/main/src/memory/errors.rs deleted file mode 100644 index f04d51f..0000000 --- a/crates/main/src/memory/errors.rs +++ /dev/null @@ -1,77 +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. - */ - -//! Contains definitions for memory errors. - -use core::alloc::LayoutErr; -use std::alloc::AllocErr; -use std::error::Error; -use std::fmt::{self, Display}; -use std::io; - -#[derive(Debug, Clone)] -pub struct MemError(String); - -impl Display for MemError { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> { - write!(f, "MemError({:?})", self) - } -} - -impl Error for MemError {} - -impl MemError { - pub fn new(message: &str) -> Self { - MemError(message.to_string()) - } - - pub fn from_err(err: &E) -> Self { - MemError::new(&err.to_string()) - } -} - -/// Creates `From` instance for MemError for each specified error types. -/// -/// Example: -/// -/// ``` -/// // usage of macro: -/// -/// mem_error_from![io::Error] -/// -/// // code will be generated: -/// -/// impl From for MemError { -/// fn from(err: io::Error) -> Self { -/// MemError::from_err(err) -/// } -/// } -/// -/// ``` -// TODO: move this macro to utils or use 'quick-error' or 'error-chain' crates -macro_rules! mem_error_from { - ( $( $x:ty );* ) => { - $( - impl From<$x> for MemError { - fn from(err: $x) -> Self { - MemError::from_err(&err) - } - } - )* - } -} - -mem_error_from! [LayoutErr; AllocErr; io::Error]; diff --git a/crates/main/src/memory/mod.rs b/crates/main/src/memory/mod.rs deleted file mode 100644 index de56509..0000000 --- a/crates/main/src/memory/mod.rs +++ /dev/null @@ -1,187 +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. - */ - -//! Raw API for dealing with Wasm memory. -//! -//! This module contains functions for memory initializing and manipulating. - -pub mod errors; - -use self::errors::MemError; -use std::alloc::{alloc as global_alloc, dealloc as global_dealloc, Layout}; -use std::mem; -use std::num::NonZeroUsize; -use std::ptr::{self, NonNull}; - -/// Result type for this module. -pub type MemResult = ::std::result::Result; - -/// Bytes count occupied by a length of resulted array. -pub const RESPONSE_SIZE_BYTES: usize = 4; - -/// Allocates memory area of specified size and returns its address. Actually is just a wrapper for -/// [`GlobalAlloc::alloc`]. -/// -/// # Safety -/// -/// See [`GlobalAlloc::alloc`]. -/// -/// [`GlobalAlloc::alloc`]: https://doc.rust-lang.org/core/alloc/trait.GlobalAlloc.html#tymethod.alloc -/// -pub unsafe fn alloc(size: NonZeroUsize) -> MemResult> { - let layout: Layout = Layout::from_size_align(size.get(), mem::align_of::())?; - Ok(NonNull::new_unchecked(global_alloc(layout))) -} - -/// Deallocates memory area for current memory pointer and size. Actually is just a wrapper for -/// [`GlobalAlloc::dealloc`]. -/// -/// # Safety -/// -/// See [`GlobalAlloc::dealloc`]. -/// -/// [`GlobalAlloc::dealloc`]: https://doc.rust-lang.org/core/alloc/trait.GlobalAlloc.html#tymethod.dealloc -/// -pub unsafe fn dealloc(ptr: NonNull, size: NonZeroUsize) -> MemResult<()> { - let layout = Layout::from_size_align(size.get(), mem::align_of::())?; - global_dealloc(ptr.as_ptr(), layout); - Ok(()) -} - -/// Allocates 'RESPONSE_SIZE_BYTES + result.len()' bytes, writes length of the result as little -/// endian RESPONSE_SIZE_BYTES bytes, and finally writes content of 'result'. So the final layout of -/// the result in memory is following: -/// ` -/// | array_length: RESPONSE_SIZE_BYTES bytes (little-endian) | array: $array_length bytes | -/// ` -/// This function should normally be used to return result of `invoke` function. Vm wrapper -/// expects result in this format. -/// -pub unsafe fn write_response_to_mem(result: &[u8]) -> MemResult> { - let result_len = result.len(); - let total_len = result_len - .checked_add(RESPONSE_SIZE_BYTES) - .ok_or_else(|| MemError::new("usize overflow occurred"))?; - - // converts array size to bytes in little-endian - let len_as_bytes: [u8; RESPONSE_SIZE_BYTES] = mem::transmute((result_len as u32).to_le()); - - // allocates a new memory region for the result - let result_ptr = alloc(NonZeroUsize::new_unchecked(total_len))?; - - // copies length of array to memory - ptr::copy_nonoverlapping( - len_as_bytes.as_ptr(), - result_ptr.as_ptr(), - RESPONSE_SIZE_BYTES, - ); - - // copies array to memory - ptr::copy_nonoverlapping( - result.as_ptr(), - result_ptr.as_ptr().add(RESPONSE_SIZE_BYTES), - result_len, - ); - - Ok(result_ptr) -} - -/// Reads array of bytes from a given `ptr` that must to have `len` bytes size. -/// -/// # Safety -/// -/// The ownership of `ptr` is effectively (without additional allocation) transferred to the -/// resulted `Vec` which can be then safely deallocated, reallocated or so on. -/// **There have to be only one instance of `Vec` constructed from one of such pointer since -/// there isn't any memory copied.** -/// -pub unsafe fn read_request_from_mem(ptr: *mut u8, len: usize) -> Vec { - Vec::from_raw_parts(ptr, len, len) -} - -/// Reads `u32` (assuming that it is given in little endianness order) from a specified pointer. -pub unsafe fn read_len(ptr: *mut u8) -> u32 { - let mut len_as_bytes: [u8; RESPONSE_SIZE_BYTES] = [0; RESPONSE_SIZE_BYTES]; - ptr::copy_nonoverlapping(ptr, len_as_bytes.as_mut_ptr(), RESPONSE_SIZE_BYTES); - mem::transmute(len_as_bytes) -} - -#[cfg(test)] -pub mod test { - use super::*; - use std::num::NonZeroUsize; - - pub unsafe fn read_result_from_mem(ptr: NonNull) -> MemResult> { - // read string length from current pointer - let input_len = super::read_len(ptr.as_ptr()) as usize; - - let total_len = RESPONSE_SIZE_BYTES - .checked_add(input_len) - .ok_or_else(|| MemError::new("usize overflow occurred"))?; - - // creates object from raw bytes - let mut input = Vec::from_raw_parts(ptr.as_ptr(), total_len, total_len); - - // drains RESPONSE_SIZE_BYTES from the beginning of created vector, it allows to effectively - // skips (without additional allocations) length of the result. - { - input.drain(0..RESPONSE_SIZE_BYTES); - } - - Ok(input) - } - - #[test] - fn alloc_dealloc_test() { - unsafe { - let size = NonZeroUsize::new_unchecked(123); - let ptr = alloc(size).unwrap(); - assert_eq!(dealloc(ptr, size).unwrap(), ()); - } - } - - #[test] - fn write_and_read_str_test() { - unsafe { - let src_str = "some string Ω"; - - let ptr = write_response_to_mem(src_str.as_bytes()).unwrap(); - let result_array = read_result_from_mem(ptr).unwrap(); - let result_str = String::from_utf8(result_array).unwrap(); - assert_eq!(src_str, result_str); - } - } - - /// Creates a big string with pattern "Q..Q" of the specified length. - fn create_big_str(len: usize) -> String { - unsafe { String::from_utf8_unchecked(vec!['Q' as u8; len]) } - } - - #[test] - fn lot_of_write_and_read_str_test() { - unsafe { - let mb_str = create_big_str(1024 * 1024); - - // writes and read 1mb string (takes several seconds) - for _ in 1..10_000 { - let ptr = write_response_to_mem(mb_str.as_bytes()).unwrap(); - let result_array = read_result_from_mem(ptr).unwrap(); - let result_str = String::from_utf8(result_array).unwrap(); - assert_eq!(mb_str, result_str); - } - } - } -} diff --git a/crates/main/src/result/mod.rs b/crates/main/src/result/mod.rs new file mode 100644 index 0000000..4ecb7fb --- /dev/null +++ b/crates/main/src/result/mod.rs @@ -0,0 +1,54 @@ +/* + * 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::log_utf8_string; + +use std::sync::atomic::AtomicUsize; + +static mut RESULT_PTR: AtomicUsize = AtomicUsize::new(0); +static mut RESULT_SIZE: AtomicUsize = AtomicUsize::new(0); + +#[no_mangle] +pub unsafe fn get_result_ptr() -> usize { + let msg = "sdk.get_result_ptr\n"; + log_utf8_string(msg.as_ptr() as _, msg.len() as _); + + *RESULT_PTR.get_mut() +} + +#[no_mangle] +pub unsafe fn get_result_size() -> usize { + let msg = "sdk.get_result_size\n"; + log_utf8_string(msg.as_ptr() as _, msg.len() as _); + + *RESULT_SIZE.get_mut() +} + +#[no_mangle] +pub unsafe fn set_result_ptr(ptr: usize) { + let msg = format!("sdk.set_result_ptr: {}\n", ptr); + log_utf8_string(msg.as_ptr() as _, msg.len() as _); + + *RESULT_PTR.get_mut() = ptr; +} + +#[no_mangle] +pub unsafe fn set_result_size(size: usize) { + let msg = format!("sdk.set_result_size: {}\n", size); + log_utf8_string(msg.as_ptr() as _, msg.len() as _); + + *RESULT_SIZE.get_mut() = size; +} diff --git a/crates/main/src/side_module/mod.rs b/crates/main/src/side_module/mod.rs deleted file mode 100644 index 85c1a1e..0000000 --- a/crates/main/src/side_module/mod.rs +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Copyright 2019 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. - */ - -//! Allows a module be side module. -//! -//! This module contains functions for loading from and storing to memory. - -/// Stores one byte into module memory by the given address. -/// Could be used from other modules for parameter passing. -#[no_mangle] -pub unsafe fn store(address: *mut u8, byte: u8) { - *address = byte; -} - -/// Loads one byte from module memory by the given address. -/// Could be used from other modules for obtaining results. -#[no_mangle] -pub unsafe fn load(address: *mut u8) -> u8 { - return *address; -} diff --git a/rustfmt.toml b/rustfmt.toml index 63156a8..6b8c82a 100644 --- a/rustfmt.toml +++ b/rustfmt.toml @@ -1,2 +1,4 @@ -match_block_trailing_comma = true -binop_separator = "Back" +edition = "2018" + +reorder_imports = false +reorder_modules = false diff --git a/src/lib.rs b/src/lib.rs index c946f5f..2f62561 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -23,7 +23,6 @@ //! please import this crate with `default-features = false`. //! #![doc(html_root_url = "https://docs.rs/fluence/0.1.11")] -#![feature(allocator_api)] #![deny( dead_code, nonstandard_style, @@ -38,20 +37,8 @@ extern crate fluence_sdk_macro; extern crate fluence_sdk_main; -/// A module which should be typically globally imported: -/// -/// ``` -/// use fluence::sdk::*; -/// ``` -pub mod sdk { - // TODO: need to introduce macros to avoid code duplication with crates/main/lib.rs - pub use fluence_sdk_main::memory; - - #[cfg(feature = "wasm_logger")] - pub use fluence_sdk_main::logger; - - #[cfg(feature = "export_allocator")] - pub use fluence_sdk_main::export_allocator; - - pub use fluence_sdk_macro::invocation_handler; -} +pub use fluence_sdk_macro::faas_export; +pub use fluence_sdk_main::get_result_ptr; +pub use fluence_sdk_main::get_result_size; +pub use fluence_sdk_main::set_result_ptr; +pub use fluence_sdk_main::set_result_size;