mirror of
https://github.com/fluencelabs/marine-rs-sdk-test
synced 2024-12-04 07:10:19 +00:00
update the main part to the new sdk
This commit is contained in:
parent
d596f5034d
commit
aa73411663
11
Cargo.toml
11
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" }
|
fluence-sdk-main = { path = "crates/main", version = "=0.1.11" }
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
default = ["export_allocator"]
|
# Print some internal logs by log_utf8_string
|
||||||
# Turn on a compilation for the module that contains Wasm logger realization.
|
print_logs = ["fluence-sdk-main/print_logs"]
|
||||||
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"]
|
|
||||||
|
|
||||||
[workspace]
|
[workspace]
|
||||||
members = [
|
members = [
|
||||||
|
@ -201,7 +201,7 @@ fn invoke_handler_impl(
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[proc_macro_attribute]
|
#[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);
|
let fn_item = parse_macro_input!(input as ItemFn);
|
||||||
match invoke_handler_impl(attr.into(), fn_item) {
|
match invoke_handler_impl(attr.into(), fn_item) {
|
||||||
Ok(v) => v,
|
Ok(v) => v,
|
||||||
|
@ -20,21 +20,11 @@ crate-type = ["rlib"]
|
|||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
log = { version = "0.4.8", features = ["std"] }
|
log = { version = "0.4.8", features = ["std"] }
|
||||||
syn = { version = '0.15.44', features = ['full'] }
|
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
simple_logger = "1.6.0" # used in doc test
|
simple_logger = "1.6.0" # used in doc test
|
||||||
lazy_static = "1.4.0" # used in doc test
|
lazy_static = "1.4.0" # used in doc test
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
# Turn on the Wasm logger.
|
# Print some internal logs by log_utf8_string
|
||||||
wasm_logger = []
|
print_logs = []
|
||||||
|
|
||||||
# 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 = []
|
|
||||||
|
@ -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() {}
|
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2018 Fluence Labs Limited
|
* Copyright 2020 Fluence Labs Limited
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@ -14,32 +14,42 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
//! This module provides default implementations of [`allocate`] and [`deallocate`] functions that
|
use crate::log_utf8_string;
|
||||||
//! can be used for array passing and returning.
|
|
||||||
//!
|
|
||||||
//! [`allocate`]: fn.allocate.html
|
|
||||||
//! [`deallocate`]: fn.deallocate.html
|
|
||||||
|
|
||||||
use crate::memory::{alloc, dealloc};
|
use std::alloc::alloc as global_alloc;
|
||||||
use std::num::NonZeroUsize;
|
use std::alloc::dealloc as global_dealloc;
|
||||||
use std::ptr::NonNull;
|
use std::alloc::Layout;
|
||||||
|
|
||||||
/// Allocates memory area of specified size and returns its address.
|
/// 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]
|
#[no_mangle]
|
||||||
pub unsafe fn allocate(size: usize) -> NonNull<u8> {
|
pub unsafe fn allocate(size: usize) -> usize {
|
||||||
let non_zero_size = NonZeroUsize::new(size)
|
let layout = match Layout::from_size_align(size, std::mem::align_of::<u8>()) {
|
||||||
.unwrap_or_else(|| panic!("[Error] Allocation of zero bytes is not allowed."));
|
Ok(layout) => layout,
|
||||||
alloc(non_zero_size).unwrap_or_else(|_| panic!("[Error] Allocation of {} bytes failed.", size))
|
// 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.
|
/// Deallocates memory area for provided memory pointer and size.
|
||||||
/// Used from the host environment for memory deallocation after reading results of function from
|
/// Does nothing if supplied size is too long.
|
||||||
/// Wasm memory.
|
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub unsafe fn deallocate(ptr: NonNull<u8>, size: usize) {
|
pub unsafe fn deallocate(ptr: *mut u8, size: usize) {
|
||||||
let non_zero_size = NonZeroUsize::new(size)
|
let layout = match Layout::from_size_align(size, std::mem::align_of::<u8>()) {
|
||||||
.unwrap_or_else(|| panic!("[Error] Deallocation of zero bytes is not allowed."));
|
Ok(layout) => layout,
|
||||||
dealloc(ptr, non_zero_size)
|
// in this case a err could be only in a case of too long allocated size,
|
||||||
.unwrap_or_else(|_| panic!("[Error] Deallocate failed for ptr={:?} size={}.", ptr, 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);
|
||||||
}
|
}
|
||||||
|
@ -14,12 +14,12 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
//! The main part of Fluence backend SDK. Contains `export_allocator` (is turned on by the
|
//! The main part of Fluence backend SDK. Contains `export_allocator`, `logger` and `result`
|
||||||
//! `export_allocator` feature), `logger` (is turned on by the `wasm_logger` feature), and `memory`
|
|
||||||
//! modules.
|
//! modules.
|
||||||
|
|
||||||
|
#![allow(clippy::missing_safety_doc)]
|
||||||
|
#![allow(clippy::needless_doctest_main)]
|
||||||
#![doc(html_root_url = "https://docs.rs/fluence-sdk-main/0.1.11")]
|
#![doc(html_root_url = "https://docs.rs/fluence-sdk-main/0.1.11")]
|
||||||
#![feature(allocator_api)]
|
|
||||||
#![deny(
|
#![deny(
|
||||||
dead_code,
|
dead_code,
|
||||||
nonstandard_style,
|
nonstandard_style,
|
||||||
@ -31,16 +31,16 @@
|
|||||||
)]
|
)]
|
||||||
#![warn(rust_2018_idioms)]
|
#![warn(rust_2018_idioms)]
|
||||||
|
|
||||||
pub mod memory;
|
mod export_allocator;
|
||||||
|
mod logger;
|
||||||
|
mod result;
|
||||||
|
|
||||||
#[cfg(feature = "wasm_logger")]
|
pub(crate) use logger::log_utf8_string;
|
||||||
pub mod logger;
|
|
||||||
|
|
||||||
#[cfg(feature = "side_module")]
|
pub use export_allocator::allocate;
|
||||||
pub mod side_module;
|
pub use export_allocator::deallocate;
|
||||||
|
pub use logger::WasmLogger;
|
||||||
#[cfg(feature = "expect_eth")]
|
pub use result::get_result_ptr;
|
||||||
pub mod eth;
|
pub use result::get_result_size;
|
||||||
|
pub use result::set_result_ptr;
|
||||||
#[cfg(feature = "export_allocator")]
|
pub use result::set_result_size;
|
||||||
pub mod export_allocator;
|
|
||||||
|
@ -73,8 +73,6 @@
|
|||||||
//! [`lazy_static::initialize()`]: https://docs.rs/lazy_static/1.3.0/lazy_static/fn.initialize.html
|
//! [`lazy_static::initialize()`]: https://docs.rs/lazy_static/1.3.0/lazy_static/fn.initialize.html
|
||||||
//! [`backend app debugging`]: https://fluence.dev/docs/debugging
|
//! [`backend app debugging`]: https://fluence.dev/docs/debugging
|
||||||
|
|
||||||
use log;
|
|
||||||
|
|
||||||
/// The Wasm Logger.
|
/// The Wasm Logger.
|
||||||
///
|
///
|
||||||
/// This struct implements the [`Log`] trait from the [`log`] crate, which allows it to act as a
|
/// 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 {
|
impl WasmLogger {
|
||||||
/// Initializes the global logger with a [`WasmLogger`] instance with
|
/// Initializes the global logger with a [`WasmLogger`] instance, sets
|
||||||
/// `max_log_level` set to a specific log level.
|
/// `max_log_level` to a given log level.
|
||||||
///
|
///
|
||||||
/// ```
|
/// ```
|
||||||
/// # use fluence::sdk::*;
|
/// # use fluence::sdk::*;
|
||||||
@ -114,8 +112,8 @@ impl WasmLogger {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Initializes the global logger with a [`WasmLogger`] instance with `max_log_level` set to
|
/// Initializes the global logger with a [`WasmLogger`] instance, sets
|
||||||
/// `Level::Info`.
|
/// `max_log_level` to `Level::Info`.
|
||||||
///
|
///
|
||||||
/// ```
|
/// ```
|
||||||
/// # use fluence::sdk::*;
|
/// # use fluence::sdk::*;
|
||||||
@ -162,9 +160,9 @@ impl log::Log for WasmLogger {
|
|||||||
fn flush(&self) {}
|
fn flush(&self) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// logger is a module provided by a VM that can process log messages.
|
/// log_utf8_string should be provided directly by a host.
|
||||||
#[link(wasm_import_module = "logger")]
|
#[link(wasm_import_module = "host")]
|
||||||
extern "C" {
|
extern "C" {
|
||||||
// Writes a byte string of size bytes that starts from ptr to a logger
|
// 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);
|
||||||
}
|
}
|
||||||
|
@ -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<E: Error + Display>(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<io::Error> 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];
|
|
@ -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<T> = ::std::result::Result<T, MemError>;
|
|
||||||
|
|
||||||
/// 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<NonNull<u8>> {
|
|
||||||
let layout: Layout = Layout::from_size_align(size.get(), mem::align_of::<u8>())?;
|
|
||||||
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<u8>, size: NonZeroUsize) -> MemResult<()> {
|
|
||||||
let layout = Layout::from_size_align(size.get(), mem::align_of::<u8>())?;
|
|
||||||
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<NonNull<u8>> {
|
|
||||||
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<u8> {
|
|
||||||
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<u8>) -> MemResult<Vec<u8>> {
|
|
||||||
// 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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
54
crates/main/src/result/mod.rs
Normal file
54
crates/main/src/result/mod.rs
Normal file
@ -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;
|
||||||
|
}
|
@ -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;
|
|
||||||
}
|
|
@ -1,2 +1,4 @@
|
|||||||
match_block_trailing_comma = true
|
edition = "2018"
|
||||||
binop_separator = "Back"
|
|
||||||
|
reorder_imports = false
|
||||||
|
reorder_modules = false
|
||||||
|
23
src/lib.rs
23
src/lib.rs
@ -23,7 +23,6 @@
|
|||||||
//! please import this crate with `default-features = false`.
|
//! please import this crate with `default-features = false`.
|
||||||
//!
|
//!
|
||||||
#![doc(html_root_url = "https://docs.rs/fluence/0.1.11")]
|
#![doc(html_root_url = "https://docs.rs/fluence/0.1.11")]
|
||||||
#![feature(allocator_api)]
|
|
||||||
#![deny(
|
#![deny(
|
||||||
dead_code,
|
dead_code,
|
||||||
nonstandard_style,
|
nonstandard_style,
|
||||||
@ -38,20 +37,8 @@
|
|||||||
extern crate fluence_sdk_macro;
|
extern crate fluence_sdk_macro;
|
||||||
extern crate fluence_sdk_main;
|
extern crate fluence_sdk_main;
|
||||||
|
|
||||||
/// A module which should be typically globally imported:
|
pub use fluence_sdk_macro::faas_export;
|
||||||
///
|
pub use fluence_sdk_main::get_result_ptr;
|
||||||
/// ```
|
pub use fluence_sdk_main::get_result_size;
|
||||||
/// use fluence::sdk::*;
|
pub use fluence_sdk_main::set_result_ptr;
|
||||||
/// ```
|
pub use fluence_sdk_main::set_result_size;
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
Loading…
Reference in New Issue
Block a user