mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-06-11 09:31:12 +00:00
Move "wasm" allocator into its own crate (#4716)
This moves the wasm-allocator (`FreeingBumpHeapAllocator`) into its own crate `sp-allocator`. This new crate can theoretically provide multiple different allocators. Besides moving the allocator, this pr also makes `FreeingBumpHeapAllocator` compile on `no_std`.
This commit is contained in:
committed by
Sergei Pepyakin
parent
670ce71009
commit
5bd6e94e64
Generated
+16
@@ -5424,6 +5424,7 @@ dependencies = [
|
||||
"derive_more 0.99.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"parity-scale-codec 1.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"sp-allocator 2.0.0",
|
||||
"sp-core 2.0.0",
|
||||
"sp-runtime-interface 2.0.0",
|
||||
"sp-serializer 2.0.0",
|
||||
@@ -5439,6 +5440,7 @@ dependencies = [
|
||||
"parity-scale-codec 1.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"parity-wasm 0.41.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"sc-executor-common 0.8.0",
|
||||
"sp-allocator 2.0.0",
|
||||
"sp-core 2.0.0",
|
||||
"sp-runtime-interface 2.0.0",
|
||||
"sp-wasm-interface 2.0.0",
|
||||
@@ -5459,6 +5461,7 @@ dependencies = [
|
||||
"parity-scale-codec 1.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"parity-wasm 0.41.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"sc-executor-common 0.8.0",
|
||||
"sp-allocator 2.0.0",
|
||||
"sp-core 2.0.0",
|
||||
"sp-runtime-interface 2.0.0",
|
||||
"sp-wasm-interface 2.0.0",
|
||||
@@ -5732,6 +5735,7 @@ dependencies = [
|
||||
name = "sc-runtime-test"
|
||||
version = "2.0.0"
|
||||
dependencies = [
|
||||
"sp-allocator 2.0.0",
|
||||
"sp-core 2.0.0",
|
||||
"sp-io 2.0.0",
|
||||
"sp-runtime 2.0.0",
|
||||
@@ -6184,6 +6188,17 @@ name = "sourcefile"
|
||||
version = "0.1.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "sp-allocator"
|
||||
version = "2.0.0"
|
||||
dependencies = [
|
||||
"derive_more 0.99.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"sp-core 2.0.0",
|
||||
"sp-std 2.0.0",
|
||||
"sp-wasm-interface 2.0.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "sp-api"
|
||||
version = "2.0.0"
|
||||
@@ -6739,6 +6754,7 @@ name = "sp-wasm-interface"
|
||||
version = "2.0.0"
|
||||
dependencies = [
|
||||
"impl-trait-for-tuples 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"sp-std 2.0.0",
|
||||
"wasmi 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
|
||||
@@ -98,6 +98,7 @@ members = [
|
||||
"frame/transaction-payment/rpc/runtime-api",
|
||||
"frame/treasury",
|
||||
"frame/utility",
|
||||
"primitives/allocator",
|
||||
"primitives/application-crypto",
|
||||
"primitives/application-crypto/test",
|
||||
"primitives/authority-discovery",
|
||||
|
||||
@@ -10,6 +10,7 @@ derive_more = "0.99.2"
|
||||
codec = { package = "parity-scale-codec", version = "1.0.0" }
|
||||
wasmi = "0.6.2"
|
||||
sp-core = { version = "2.0.0", path = "../../../primitives/core" }
|
||||
sp-allocator = { version = "2.0.0", path = "../../../primitives/allocator" }
|
||||
sp-wasm-interface = { version = "2.0.0", path = "../../../primitives/wasm-interface" }
|
||||
sp-runtime-interface = { version = "2.0.0", path = "../../../primitives/runtime-interface" }
|
||||
sp-serializer = { version = "2.0.0", path = "../../../primitives/serializer" }
|
||||
|
||||
@@ -72,17 +72,10 @@ pub enum Error {
|
||||
#[display(fmt="The runtime has the `start` function")]
|
||||
RuntimeHasStartFn,
|
||||
/// Some other error occurred
|
||||
#[from(ignore)]
|
||||
Other(String),
|
||||
/// Some error occurred in the allocator
|
||||
#[display(fmt="Error in allocator: {}", _0)]
|
||||
Allocator(&'static str),
|
||||
/// The allocator ran out of space.
|
||||
#[display(fmt="Allocator ran out of space")]
|
||||
AllocatorOutOfSpace,
|
||||
/// Someone tried to allocate more memory than the allowed maximum per allocation.
|
||||
#[display(fmt="Requested allocation size is too large")]
|
||||
RequestedAllocationTooLarge,
|
||||
Allocator(sp_allocator::Error),
|
||||
/// Execution of a host function failed.
|
||||
#[display(fmt="Host function {} execution failed with: {}", _0, _1)]
|
||||
FunctionExecution(String, String),
|
||||
@@ -101,9 +94,9 @@ impl std::error::Error for Error {
|
||||
|
||||
impl wasmi::HostError for Error {}
|
||||
|
||||
impl From<String> for Error {
|
||||
fn from(err: String) -> Error {
|
||||
Error::Other(err)
|
||||
impl From<&'static str> for Error {
|
||||
fn from(err: &'static str) -> Error {
|
||||
Error::Other(err.into())
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -19,6 +19,5 @@
|
||||
#![warn(missing_docs)]
|
||||
|
||||
pub mod sandbox;
|
||||
pub mod allocator;
|
||||
pub mod error;
|
||||
pub mod wasm_runtime;
|
||||
|
||||
@@ -11,10 +11,16 @@ sp-io = { version = "2.0.0", default-features = false, path = "../../../primitiv
|
||||
sp-sandbox = { version = "0.8.0", default-features = false, path = "../../../primitives/sandbox" }
|
||||
sp-core = { version = "2.0.0", default-features = false, path = "../../../primitives/core" }
|
||||
sp-runtime = { version = "2.0.0", default-features = false, path = "../../../primitives/runtime" }
|
||||
sp-allocator = { version = "2.0.0", default-features = false, path = "../../../primitives/allocator" }
|
||||
|
||||
[build-dependencies]
|
||||
wasm-builder-runner = { version = "1.0.4", package = "substrate-wasm-builder-runner", path = "../../../utils/wasm-builder-runner" }
|
||||
|
||||
[features]
|
||||
default = [ "std" ]
|
||||
std = ["sp-io/std", "sp-sandbox/std", "sp-std/std"]
|
||||
std = [
|
||||
"sp-io/std",
|
||||
"sp-sandbox/std",
|
||||
"sp-std/std",
|
||||
"sp-allocator/std",
|
||||
]
|
||||
|
||||
@@ -212,6 +212,11 @@ sp_core::wasm_export_functions! {
|
||||
|
||||
run().is_some()
|
||||
}
|
||||
|
||||
// Just some test to make sure that `sp-allocator` compiles on `no_std`.
|
||||
fn test_sp_allocator_compiles() {
|
||||
sp_allocator::FreeingBumpHeapAllocator::new(0);
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "std"))]
|
||||
|
||||
@@ -48,7 +48,7 @@ pub use sp_core::traits::Externalities;
|
||||
pub use sp_wasm_interface;
|
||||
pub use wasm_runtime::WasmExecutionMethod;
|
||||
|
||||
pub use sc_executor_common::{error, allocator, sandbox};
|
||||
pub use sc_executor_common::{error, sandbox};
|
||||
|
||||
/// Call the given `function` in the given wasm `code`.
|
||||
///
|
||||
|
||||
@@ -13,3 +13,4 @@ sc-executor-common = { version = "0.8", path = "../common" }
|
||||
sp-wasm-interface = { version = "2.0.0", path = "../../../primitives/wasm-interface" }
|
||||
sp-runtime-interface = { version = "2.0.0", path = "../../../primitives/runtime-interface" }
|
||||
sp-core = { version = "2.0.0", path = "../../../primitives/core" }
|
||||
sp-allocator = { version = "2.0.0", path = "../../../primitives/allocator" }
|
||||
|
||||
@@ -16,11 +16,7 @@
|
||||
|
||||
//! This crate provides an implementation of `WasmRuntime` that is baked by wasmi.
|
||||
|
||||
use sc_executor_common::{
|
||||
error::{Error, WasmError},
|
||||
sandbox,
|
||||
allocator,
|
||||
};
|
||||
use sc_executor_common::{error::{Error, WasmError}, sandbox};
|
||||
use std::{str, mem, cell::RefCell};
|
||||
use wasmi::{
|
||||
Module, ModuleInstance, MemoryInstance, MemoryRef, TableRef, ImportsBuilder, ModuleRef,
|
||||
@@ -38,7 +34,7 @@ use sc_executor_common::wasm_runtime::WasmRuntime;
|
||||
|
||||
struct FunctionExecutor<'a> {
|
||||
sandbox_store: sandbox::Store<wasmi::FuncRef>,
|
||||
heap: allocator::FreeingBumpHeapAllocator,
|
||||
heap: sp_allocator::FreeingBumpHeapAllocator,
|
||||
memory: MemoryRef,
|
||||
table: Option<TableRef>,
|
||||
host_functions: &'a [&'static dyn Function],
|
||||
@@ -57,7 +53,7 @@ impl<'a> FunctionExecutor<'a> {
|
||||
) -> Result<Self, Error> {
|
||||
Ok(FunctionExecutor {
|
||||
sandbox_store: sandbox::Store::new(),
|
||||
heap: allocator::FreeingBumpHeapAllocator::new(heap_base),
|
||||
heap: sp_allocator::FreeingBumpHeapAllocator::new(heap_base),
|
||||
memory: m,
|
||||
table: t,
|
||||
host_functions,
|
||||
@@ -79,13 +75,13 @@ impl<'a> sandbox::SandboxCapabilities for FunctionExecutor<'a> {
|
||||
fn allocate(&mut self, len: WordSize) -> Result<Pointer<u8>, Error> {
|
||||
let heap = &mut self.heap;
|
||||
self.memory.with_direct_access_mut(|mem| {
|
||||
heap.allocate(mem, len)
|
||||
heap.allocate(mem, len).map_err(Into::into)
|
||||
})
|
||||
}
|
||||
fn deallocate(&mut self, ptr: Pointer<u8>) -> Result<(), Error> {
|
||||
let heap = &mut self.heap;
|
||||
self.memory.with_direct_access_mut(|mem| {
|
||||
heap.deallocate(mem, ptr)
|
||||
heap.deallocate(mem, ptr).map_err(Into::into)
|
||||
})
|
||||
}
|
||||
fn write_memory(&mut self, ptr: Pointer<u8>, data: &[u8]) -> Result<(), Error> {
|
||||
|
||||
@@ -13,6 +13,7 @@ sc-executor-common = { version = "0.8", path = "../common" }
|
||||
sp-wasm-interface = { version = "2.0.0", path = "../../../primitives/wasm-interface" }
|
||||
sp-runtime-interface = { version = "2.0.0", path = "../../../primitives/runtime-interface" }
|
||||
sp-core = { version = "2.0.0", path = "../../../primitives/core" }
|
||||
sp-allocator = { version = "2.0.0", path = "../../../primitives/allocator" }
|
||||
|
||||
cranelift-codegen = "0.50"
|
||||
cranelift-entity = "0.50"
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Substrate. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
use sc_executor_common::allocator::FreeingBumpHeapAllocator;
|
||||
use sp_allocator::FreeingBumpHeapAllocator;
|
||||
use sc_executor_common::error::{Error, Result};
|
||||
use sc_executor_common::sandbox::{self, SandboxCapabilities, SupervisorFuncIndex};
|
||||
use crate::util::{
|
||||
@@ -127,11 +127,11 @@ impl<'a> SandboxCapabilities for FunctionExecutor<'a> {
|
||||
}
|
||||
|
||||
fn allocate(&mut self, len: WordSize) -> Result<Pointer<u8>> {
|
||||
self.heap.allocate(self.memory, len)
|
||||
self.heap.allocate(self.memory, len).map_err(Into::into)
|
||||
}
|
||||
|
||||
fn deallocate(&mut self, ptr: Pointer<u8>) -> Result<()> {
|
||||
self.heap.deallocate(self.memory, ptr)
|
||||
self.heap.deallocate(self.memory, ptr).map_err(Into::into)
|
||||
}
|
||||
|
||||
fn write_memory(&mut self, ptr: Pointer<u8>, data: &[u8]) -> Result<()> {
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
[package]
|
||||
name = "sp-allocator"
|
||||
version = "2.0.0"
|
||||
authors = ["Parity Technologies <admin@parity.io>"]
|
||||
edition = "2018"
|
||||
|
||||
[dependencies]
|
||||
sp-std = { version = "2.0.0", path = "../std", default-features = false }
|
||||
sp-core = { version = "2.0.0", path = "../core", default-features = false }
|
||||
sp-wasm-interface = { version = "2.0.0", path = "../wasm-interface", default-features = false }
|
||||
log = { version = "0.4.8", optional = true }
|
||||
derive_more = { version = "0.99.2", optional = true }
|
||||
|
||||
[features]
|
||||
default = [ "std" ]
|
||||
std = [
|
||||
"sp-std/std",
|
||||
"sp-core/std",
|
||||
"sp-wasm-interface/std",
|
||||
"log",
|
||||
"derive_more",
|
||||
]
|
||||
@@ -0,0 +1,38 @@
|
||||
// Copyright 2020 Parity Technologies (UK) Ltd.
|
||||
// This file is part of Substrate.
|
||||
|
||||
// Substrate is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
|
||||
// Substrate is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Substrate. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
/// The error type used by the allocators.
|
||||
#[derive(sp_core::RuntimeDebug)]
|
||||
#[cfg_attr(feature = "std", derive(derive_more::Display))]
|
||||
pub enum Error {
|
||||
/// Someone tried to allocate more memory than the allowed maximum per allocation.
|
||||
#[cfg_attr(feature = "std", display(fmt="Requested allocation size is too large"))]
|
||||
RequestedAllocationTooLarge,
|
||||
/// Allocator run out of space.
|
||||
#[cfg_attr(feature = "std", display(fmt="Allocator ran out of space"))]
|
||||
AllocatorOutOfSpace,
|
||||
/// Some other error occurred.
|
||||
Other(&'static str)
|
||||
}
|
||||
|
||||
#[cfg(feature = "std")]
|
||||
impl std::error::Error for Error {
|
||||
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
|
||||
match self {
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
}
|
||||
+22
-13
@@ -46,10 +46,8 @@
|
||||
//! To deallocate we use the preceding 8 bytes of the allocation to knit
|
||||
//! back the allocation into the linked list from the head.
|
||||
|
||||
use crate::error::{Error, Result};
|
||||
use log::trace;
|
||||
use std::convert::{TryFrom, TryInto};
|
||||
use std::ops::Range;
|
||||
use crate::Error;
|
||||
use sp_std::{convert::{TryFrom, TryInto}, ops::Range};
|
||||
use sp_wasm_interface::{Pointer, WordSize};
|
||||
|
||||
// The pointers need to be aligned to 8 bytes. This is because the
|
||||
@@ -81,7 +79,18 @@ pub struct FreeingBumpHeapAllocator {
|
||||
|
||||
/// Create an allocator error.
|
||||
fn error(msg: &'static str) -> Error {
|
||||
Error::Allocator(msg)
|
||||
Error::Other(msg)
|
||||
}
|
||||
|
||||
/// A custom "trace" implementation that is only activated when `feature = std`.
|
||||
///
|
||||
/// Uses `wasm-heap` as default target.
|
||||
macro_rules! trace {
|
||||
( $( $args:expr ),+ ) => {
|
||||
sp_std::if_std! {
|
||||
log::trace!(target: "wasm-heap", $( $args ),+);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl FreeingBumpHeapAllocator {
|
||||
@@ -113,9 +122,9 @@ impl FreeingBumpHeapAllocator {
|
||||
///
|
||||
/// - `mem` - a slice representing the linear memory on which this allocator operates.
|
||||
/// - `size` - size in bytes of the allocation request
|
||||
pub fn allocate(&mut self, mem: &mut [u8], size: WordSize) -> Result<Pointer<u8>> {
|
||||
pub fn allocate(&mut self, mem: &mut [u8], size: WordSize) -> Result<Pointer<u8>, Error> {
|
||||
let mem_size = u32::try_from(mem.len())
|
||||
.expect("size of Wasm linear memory is <2^32");
|
||||
.expect("size of Wasm linear memory is <2^32; qed");
|
||||
let max_heap_size = mem_size - self.ptr_offset;
|
||||
|
||||
if size > MAX_POSSIBLE_ALLOCATION {
|
||||
@@ -151,7 +160,7 @@ impl FreeingBumpHeapAllocator {
|
||||
self.set_heap_u64(mem, ptr - PREFIX_SIZE, list_index as u64)?;
|
||||
|
||||
self.total_size = self.total_size + item_size + PREFIX_SIZE;
|
||||
trace!(target: "wasm-heap", "Heap size is {} bytes after allocation", self.total_size);
|
||||
trace!("Heap size is {} bytes after allocation", self.total_size);
|
||||
|
||||
Ok(Pointer::new(self.ptr_offset + ptr))
|
||||
}
|
||||
@@ -162,7 +171,7 @@ impl FreeingBumpHeapAllocator {
|
||||
///
|
||||
/// - `mem` - a slice representing the linear memory on which this allocator operates.
|
||||
/// - `ptr` - pointer to the allocated chunk
|
||||
pub fn deallocate(&mut self, mem: &mut [u8], ptr: Pointer<u8>) -> Result<()> {
|
||||
pub fn deallocate(&mut self, mem: &mut [u8], ptr: Pointer<u8>) -> Result<(), Error> {
|
||||
let ptr = u32::from(ptr) - self.ptr_offset;
|
||||
if ptr < PREFIX_SIZE {
|
||||
return Err(error("Invalid pointer for deallocation"));
|
||||
@@ -180,7 +189,7 @@ impl FreeingBumpHeapAllocator {
|
||||
let item_size = Self::get_item_size_from_index(list_index);
|
||||
self.total_size = self.total_size.checked_sub(item_size as u32 + PREFIX_SIZE)
|
||||
.ok_or_else(|| error("Unable to subtract from total heap size without overflow"))?;
|
||||
trace!(target: "wasm-heap", "Heap size is {} bytes after deallocation", self.total_size);
|
||||
trace!("Heap size is {} bytes after deallocation", self.total_size);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
@@ -190,7 +199,7 @@ impl FreeingBumpHeapAllocator {
|
||||
/// Returns the `bumper` from before the increase.
|
||||
/// Returns an `Error::AllocatorOutOfSpace` if the operation
|
||||
/// would exhaust the heap.
|
||||
fn bump(&mut self, item_size: u32, max_heap_size: u32) -> Result<u32> {
|
||||
fn bump(&mut self, item_size: u32, max_heap_size: u32) -> Result<u32, Error> {
|
||||
if self.bumper + PREFIX_SIZE + item_size > max_heap_size {
|
||||
return Err(Error::AllocatorOutOfSpace);
|
||||
}
|
||||
@@ -206,7 +215,7 @@ impl FreeingBumpHeapAllocator {
|
||||
}
|
||||
|
||||
// Read a u64 from the heap in LE form. Used to read heap allocation prefixes.
|
||||
fn get_heap_u64(&self, heap: &[u8], offset: u32) -> Result<u64> {
|
||||
fn get_heap_u64(&self, heap: &[u8], offset: u32) -> Result<u64, Error> {
|
||||
let range = self.heap_range(offset, 8, heap.len())
|
||||
.ok_or_else(|| error("read out of heap bounds"))?;
|
||||
let bytes = heap[range].try_into()
|
||||
@@ -215,7 +224,7 @@ impl FreeingBumpHeapAllocator {
|
||||
}
|
||||
|
||||
// Write a u64 to the heap in LE form. Used to write heap allocation prefixes.
|
||||
fn set_heap_u64(&self, heap: &mut [u8], offset: u32, val: u64) -> Result<()> {
|
||||
fn set_heap_u64(&self, heap: &mut [u8], offset: u32, val: u64) -> Result<(), Error> {
|
||||
let range = self.heap_range(offset, 8, heap.len())
|
||||
.ok_or_else(|| error("write out of heap bounds"))?;
|
||||
let bytes = val.to_le_bytes();
|
||||
@@ -0,0 +1,29 @@
|
||||
// Copyright 2020 Parity Technologies (UK) Ltd.
|
||||
// This file is part of Substrate.
|
||||
|
||||
// Substrate is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
|
||||
// Substrate is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Substrate. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
//! Collection of allocator implementations.
|
||||
//!
|
||||
//! This crate provides the following allocator implementations:
|
||||
//! - A freeing-bump allocator: [`FreeingBumpHeapAllocator`](freeing_bump::FreeingBumpHeapAllocator)
|
||||
|
||||
#![cfg_attr(not(feature = "std"), no_std)]
|
||||
#![warn(missing_docs)]
|
||||
|
||||
mod error;
|
||||
mod freeing_bump;
|
||||
|
||||
pub use freeing_bump::FreeingBumpHeapAllocator;
|
||||
pub use error::Error;
|
||||
@@ -309,3 +309,43 @@ pub fn to_substrate_wasm_fn_return_value(value: &impl Encode) -> u64 {
|
||||
|
||||
res
|
||||
}
|
||||
|
||||
/// Macro for creating `Maybe*` marker traits.
|
||||
///
|
||||
/// Such a maybe-marker trait requires the given bound when `feature = std` and doesn't require
|
||||
/// the bound on `no_std`. This is useful for situations where you require that a type implements
|
||||
/// a certain trait with `feature = std`, but not on `no_std`.
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
/// ```
|
||||
/// sp_core::impl_maybe_marker! {
|
||||
/// /// A marker for a type that implements `Debug` when `feature = std`.
|
||||
/// trait MaybeDebug: std::fmt::Debug;
|
||||
/// /// A marker for a type that implements `Debug + Display` when `feature = std`.
|
||||
/// trait MaybeDebugDisplay: std::fmt::Debug, std::fmt::Display;
|
||||
/// }
|
||||
/// ```
|
||||
#[macro_export]
|
||||
macro_rules! impl_maybe_marker {
|
||||
(
|
||||
$(
|
||||
$(#[$doc:meta] )+
|
||||
trait $trait_name:ident: $( $trait_bound:path ),+;
|
||||
)+
|
||||
) => {
|
||||
$(
|
||||
$(#[$doc])+
|
||||
#[cfg(feature = "std")]
|
||||
pub trait $trait_name: $( $trait_bound + )+ {}
|
||||
#[cfg(feature = "std")]
|
||||
impl<T: $( $trait_bound + )+> $trait_name for T {}
|
||||
|
||||
$(#[$doc])+
|
||||
#[cfg(not(feature = "std"))]
|
||||
pub trait $trait_name {}
|
||||
#[cfg(not(feature = "std"))]
|
||||
impl<T> $trait_name for T {}
|
||||
)+
|
||||
}
|
||||
}
|
||||
|
||||
@@ -458,36 +458,18 @@ impl<H: PartialEq + Eq + Debug> CheckEqual for super::generic::DigestItem<H> whe
|
||||
}
|
||||
}
|
||||
|
||||
macro_rules! impl_maybe_marker {
|
||||
( $( $(#[$doc:meta])+ $trait_name:ident: $($trait_bound:path),+ );+ ) => {
|
||||
$(
|
||||
$(#[$doc])+
|
||||
#[cfg(feature = "std")]
|
||||
pub trait $trait_name: $($trait_bound +)+ {}
|
||||
#[cfg(feature = "std")]
|
||||
impl<T: $($trait_bound +)+> $trait_name for T {}
|
||||
|
||||
$(#[$doc])+
|
||||
#[cfg(not(feature = "std"))]
|
||||
pub trait $trait_name {}
|
||||
#[cfg(not(feature = "std"))]
|
||||
impl<T> $trait_name for T {}
|
||||
)+
|
||||
}
|
||||
}
|
||||
|
||||
impl_maybe_marker!(
|
||||
sp_core::impl_maybe_marker!(
|
||||
/// A type that implements Display when in std environment.
|
||||
MaybeDisplay: Display;
|
||||
trait MaybeDisplay: Display;
|
||||
|
||||
/// A type that implements Hash when in std environment.
|
||||
MaybeHash: sp_std::hash::Hash;
|
||||
trait MaybeHash: sp_std::hash::Hash;
|
||||
|
||||
/// A type that implements Serialize when in std environment.
|
||||
MaybeSerialize: Serialize;
|
||||
trait MaybeSerialize: Serialize;
|
||||
|
||||
/// A type that implements Serialize, DeserializeOwned and Debug when in std environment.
|
||||
MaybeSerializeDeserialize: DeserializeOwned, Serialize
|
||||
trait MaybeSerializeDeserialize: DeserializeOwned, Serialize;
|
||||
);
|
||||
|
||||
/// A type that provides a randomness beacon.
|
||||
|
||||
@@ -81,10 +81,7 @@ pub type HostFuncType<T> = fn(&mut T, &[TypedValue]) -> Result<ReturnValue, Host
|
||||
/// will be used by the guest module.
|
||||
///
|
||||
/// The memory can't be directly accessed by supervisor, but only
|
||||
/// through designated functions [`get`] and [`set`].
|
||||
///
|
||||
/// [`get`]: #method.get
|
||||
/// [`set`]: #method.set
|
||||
/// through designated functions [`get`](Memory::get) and [`set`](Memory::set).
|
||||
#[derive(Clone)]
|
||||
pub struct Memory {
|
||||
inner: imp::Memory,
|
||||
|
||||
@@ -5,5 +5,10 @@ authors = ["Parity Technologies <admin@parity.io>"]
|
||||
edition = "2018"
|
||||
|
||||
[dependencies]
|
||||
wasmi = "0.6.2"
|
||||
wasmi = { version = "0.6.2", optional = true }
|
||||
impl-trait-for-tuples = "0.1.2"
|
||||
sp-std = { version = "2.0.0", path = "../std", default-features = false }
|
||||
|
||||
[features]
|
||||
default = [ "std" ]
|
||||
std = [ "wasmi", "sp-std/std" ]
|
||||
|
||||
@@ -16,12 +16,20 @@
|
||||
|
||||
//! Types and traits for interfacing between the host and the wasm runtime.
|
||||
|
||||
use std::{borrow::Cow, marker::PhantomData, mem, iter::Iterator, result};
|
||||
#![cfg_attr(not(feature = "std"), no_std)]
|
||||
|
||||
use sp_std::{
|
||||
borrow::Cow, marker::PhantomData, mem, iter::Iterator, result, vec::Vec,
|
||||
};
|
||||
|
||||
#[cfg(feature = "std")]
|
||||
mod wasmi_impl;
|
||||
|
||||
/// Result type used by traits in this crate.
|
||||
#[cfg(feature = "std")]
|
||||
pub type Result<T> = result::Result<T, String>;
|
||||
#[cfg(not(feature = "std"))]
|
||||
pub type Result<T> = result::Result<T, &'static str>;
|
||||
|
||||
/// Value types supported by Substrate on the boundary between host/Wasm.
|
||||
#[derive(Copy, Clone, PartialEq, Debug, Eq)]
|
||||
@@ -189,11 +197,22 @@ impl Signature {
|
||||
return_value: None,
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/// A trait that requires `RefUnwindSafe` when `feature = std`.
|
||||
#[cfg(feature = "std")]
|
||||
pub trait MaybeRefUnwindSafe: std::panic::RefUnwindSafe {}
|
||||
#[cfg(feature = "std")]
|
||||
impl<T: std::panic::RefUnwindSafe> MaybeRefUnwindSafe for T {}
|
||||
|
||||
/// A trait that requires `RefUnwindSafe` when `feature = std`.
|
||||
#[cfg(not(feature = "std"))]
|
||||
pub trait MaybeRefUnwindSafe {}
|
||||
#[cfg(not(feature = "std"))]
|
||||
impl<T> MaybeRefUnwindSafe for T {}
|
||||
|
||||
/// Something that provides a function implementation on the host for a wasm function.
|
||||
pub trait Function: std::panic::RefUnwindSafe + Send + Sync {
|
||||
pub trait Function: MaybeRefUnwindSafe + Send + Sync {
|
||||
/// Returns the name of this function.
|
||||
fn name(&self) -> &str;
|
||||
/// Returns the signature of this function.
|
||||
|
||||
Reference in New Issue
Block a user