Skip to content

Commit 582851f

Browse files
committed
feat(sp-wasm-interface): Gear sandbox (gear-tech/substrate/pull/35)
* move allocator to primitives * move HostState to sp-wasm-interface * move StoreData to sp-wasm-interface * caller method * move MemoryWrapper to sp-wasm-interface * add sp-wasm-interface util module * refactor with_caller_mut method
1 parent ffc5e55 commit 582851f

File tree

34 files changed

+2878
-1973
lines changed

34 files changed

+2878
-1973
lines changed

Cargo.lock

Lines changed: 1561 additions & 1476 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -245,7 +245,6 @@ members = [
245245
"substrate/bin/node/testing",
246246
"substrate/bin/utils/chain-spec-builder",
247247
"substrate/bin/utils/subkey",
248-
"substrate/client/allocator",
249248
"substrate/client/api",
250249
"substrate/client/authority-discovery",
251250
"substrate/client/basic-authorship",
@@ -443,6 +442,7 @@ members = [
443442
"substrate/frame/utility",
444443
"substrate/frame/vesting",
445444
"substrate/frame/whitelist",
445+
"substrate/primitives/allocator",
446446
"substrate/primitives/api",
447447
"substrate/primitives/api/proc-macro",
448448
"substrate/primitives/api/test",
@@ -1117,7 +1117,6 @@ rustix = { version = "0.36.7", default-features = false }
11171117
rustversion = { version = "1.0.17" }
11181118
rusty-fork = { version = "0.3.0", default-features = false }
11191119
safe-mix = { version = "1.0", default-features = false }
1120-
sc-allocator = { path = "substrate/client/allocator", default-features = false, version = "29.0.0" }
11211120
sc-authority-discovery = { path = "substrate/client/authority-discovery", default-features = false, version = "0.45.0" }
11221121
sc-basic-authorship = { path = "substrate/client/basic-authorship", default-features = false, version = "0.45.0" }
11231122
sc-block-builder = { path = "substrate/client/block-builder", default-features = false, version = "0.42.0" }
@@ -1215,6 +1214,7 @@ snowbridge-runtime-test-common = { path = "bridges/snowbridge/runtime/test-commo
12151214
snowbridge-system-runtime-api = { path = "bridges/snowbridge/pallets/system/runtime-api", default-features = false, version = "0.10.0" }
12161215
soketto = { version = "0.7.1" }
12171216
solochain-template-runtime = { path = "templates/solochain/runtime", version = "0.1.0" }
1217+
sp-allocator = { path = "substrate/primitives/allocator", default-features = false, version = "29.0.0" }
12181218
sp-api = { path = "substrate/primitives/api", default-features = false, version = "34.0.0" }
12191219
sp-api-proc-macro = { path = "substrate/primitives/api/proc-macro", default-features = false, version = "20.0.0" }
12201220
sp-application-crypto = { path = "substrate/primitives/application-crypto", default-features = false, version = "38.0.0" }
@@ -1272,6 +1272,7 @@ sp-trie = { path = "substrate/primitives/trie", default-features = false, versio
12721272
sp-version = { path = "substrate/primitives/version", default-features = false, version = "37.0.0" }
12731273
sp-version-proc-macro = { path = "substrate/primitives/version/proc-macro", default-features = false, version = "14.0.0" }
12741274
sp-wasm-interface = { path = "substrate/primitives/wasm-interface", default-features = false, version = "21.0.1" }
1275+
sp-wasm-interface-common = { path = "substrate/primitives/wasm-interface-common", default-features = false, version = "7.0.0" }
12751276
sp-weights = { path = "substrate/primitives/weights", default-features = false, version = "31.0.0" }
12761277
spinners = { version = "4.1.1" }
12771278
ss58-registry = { version = "1.34.0", default-features = false }

substrate/client/executor/common/Cargo.toml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,8 @@ targets = ["x86_64-unknown-linux-gnu"]
1919
[dependencies]
2020
thiserror = { workspace = true }
2121
wasm-instrument = { workspace = true, default-features = true }
22-
sc-allocator.workspace = true
23-
sc-allocator.default-features = true
22+
sp-allocator.workspace = true
23+
sp-allocator.default-features = true
2424
sp-maybe-compressed-blob.workspace = true
2525
sp-maybe-compressed-blob.default-features = true
2626
sp-wasm-interface.workspace = true

substrate/client/executor/common/src/error.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ pub enum Error {
5959
Other(String),
6060

6161
#[error(transparent)]
62-
Allocator(#[from] sc_allocator::Error),
62+
Allocator(#[from] sp_allocator::Error),
6363

6464
#[error("Host function {0} execution failed with: {1}")]
6565
FunctionExecution(String, String),

substrate/client/executor/common/src/util.rs

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -20,14 +20,6 @@
2020
2121
use crate::error::Result;
2222
use sp_wasm_interface::Pointer;
23-
use std::ops::Range;
24-
25-
/// Construct a range from an offset to a data length after the offset.
26-
/// Returns None if the end of the range would exceed some maximum offset.
27-
pub fn checked_range(offset: usize, len: usize, max: usize) -> Option<Range<usize>> {
28-
let end = offset.checked_add(len)?;
29-
(end <= max).then(|| offset..end)
30-
}
3123

3224
/// Provides safe memory access interface using an external buffer
3325
pub trait MemoryTransfer {

substrate/client/executor/common/src/wasm_runtime.rs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
2121
use crate::error::Error;
2222

23-
pub use sc_allocator::AllocationStats;
23+
pub use sp_allocator::AllocationStats;
2424

2525
/// Default heap allocation strategy.
2626
pub const DEFAULT_HEAP_ALLOC_STRATEGY: HeapAllocStrategy =
@@ -69,6 +69,11 @@ pub trait WasmInstance: Send {
6969
fn call_export(&mut self, method: &str, data: &[u8]) -> Result<Vec<u8>, Error> {
7070
self.call(method.into(), data)
7171
}
72+
73+
/// Get the value from a global with the given `name`.
74+
///
75+
/// This method is only suitable for getting immutable globals.
76+
fn get_global_const(&mut self, name: &str) -> Result<Option<sp_wasm_interface::Value>, Error>;
7277
}
7378

7479
/// Defines the heap pages allocation strategy the wasm runtime should use.

substrate/client/executor/polkavm/src/lib.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,10 @@ impl WasmInstance for Instance {
116116

117117
(Ok(output), None)
118118
}
119+
120+
fn get_global_const(&mut self, _name: &str) -> Result<Option<sp_wasm_interface::Value>, Error> {
121+
unimplemented!()
122+
}
119123
}
120124

121125
struct Context<'r, 'a>(&'r mut polkavm::Caller<'a, ()>);
@@ -153,6 +157,10 @@ impl<'r, 'a> FunctionContext for Context<'r, 'a> {
153157
fn register_panic_error_message(&mut self, _message: &str) {
154158
unimplemented!("'register_panic_error_message' is never used when running under PolkaVM");
155159
}
160+
fn with_caller_mut_impl(&mut self, _: sp_wasm_interface::FunctionContextToken, _context: *mut (), _callback: fn(*mut (), &mut sp_wasm_interface::Caller<sp_wasm_interface::StoreData>)) {
161+
162+
unimplemented!("unsupported under PolkaVM");
163+
}
156164
}
157165

158166
fn call_host_function(

substrate/client/executor/wasmi/Cargo.toml

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,9 @@ readme = "README.md"
1414
targets = ["x86_64-unknown-linux-gnu"]
1515

1616
[dependencies]
17-
log = "0.4.17"
17+
log = { workspace = true }
1818
wasmi = { git = "https://github.com/gear-tech/wasmi", branch = "v0.13.2-sign-ext", features = ["virtual_memory"] }
19-
sc-executor-common = { version = "0.10.0-dev", path = "../common" }
20-
sp-allocator = { version = "4.1.0-dev", path = "../../../primitives/allocator" }
21-
sp-runtime-interface = { version = "7.0.0", path = "../../../primitives/runtime-interface" }
22-
sp-wasm-interface = { version = "7.0.0", path = "../../../primitives/wasm-interface" }
19+
sc-executor-common = { workspace = true }
20+
sp-allocator = { workspace = true }
21+
sp-runtime-interface = { workspace = true }
22+
sp-wasm-interface = { workspace = true }

substrate/client/executor/wasmtime/Cargo.toml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,8 +31,8 @@ wasmtime = { features = [
3131
"pooling-allocator",
3232
], workspace = true }
3333
anyhow = { workspace = true }
34-
sc-allocator.workspace = true
35-
sc-allocator.default-features = true
34+
sp-allocator.workspace = true
35+
sp-allocator.default-features = true
3636
sc-executor-common.workspace = true
3737
sc-executor-common.default-features = true
3838
sp-runtime-interface.workspace = true

substrate/client/executor/wasmtime/src/host.rs

Lines changed: 19 additions & 74 deletions
Original file line numberDiff line numberDiff line change
@@ -21,41 +21,10 @@
2121
2222
use wasmtime::Caller;
2323

24-
use sc_allocator::{AllocationStats, FreeingBumpHeapAllocator};
25-
use sp_wasm_interface::{Pointer, WordSize};
24+
pub use sp_wasm_interface::HostState;
25+
use sp_wasm_interface::{util, FunctionContextToken, Pointer, WordSize};
2626

27-
use crate::{instance_wrapper::MemoryWrapper, runtime::StoreData, util};
28-
29-
/// The state required to construct a HostContext context. The context only lasts for one host
30-
/// call, whereas the state is maintained for the duration of a Wasm runtime call, which may make
31-
/// many different host calls that must share state.
32-
pub struct HostState {
33-
/// The allocator instance to keep track of allocated memory.
34-
///
35-
/// This is stored as an `Option` as we need to temporarily set this to `None` when we are
36-
/// allocating/deallocating memory. The problem being that we can only mutable access `caller`
37-
/// once.
38-
allocator: Option<FreeingBumpHeapAllocator>,
39-
panic_message: Option<String>,
40-
}
41-
42-
impl HostState {
43-
/// Constructs a new `HostState`.
44-
pub fn new(allocator: FreeingBumpHeapAllocator) -> Self {
45-
HostState { allocator: Some(allocator), panic_message: None }
46-
}
47-
48-
/// Takes the error message out of the host state, leaving a `None` in its place.
49-
pub fn take_panic_message(&mut self) -> Option<String> {
50-
self.panic_message.take()
51-
}
52-
53-
pub(crate) fn allocation_stats(&self) -> AllocationStats {
54-
self.allocator.as_ref()
55-
.expect("Allocator is always set and only unavailable when doing an allocation/deallocation; qed")
56-
.stats()
57-
}
58-
}
27+
use crate::runtime::StoreData;
5928

6029
/// A `HostContext` implements `FunctionContext` for making host calls from a Wasmtime
6130
/// runtime. The `HostContext` exists only for the lifetime of the call and borrows state from
@@ -64,15 +33,6 @@ pub(crate) struct HostContext<'a> {
6433
pub(crate) caller: Caller<'a, StoreData>,
6534
}
6635

67-
impl<'a> HostContext<'a> {
68-
fn host_state_mut(&mut self) -> &mut HostState {
69-
self.caller
70-
.data_mut()
71-
.host_state_mut()
72-
.expect("host state is not empty when calling a function in wasm; qed")
73-
}
74-
}
75-
7636
impl<'a> sp_wasm_interface::FunctionContext for HostContext<'a> {
7737
fn read_memory_into(
7838
&self,
@@ -87,42 +47,27 @@ impl<'a> sp_wasm_interface::FunctionContext for HostContext<'a> {
8747
}
8848

8949
fn allocate_memory(&mut self, size: WordSize) -> sp_wasm_interface::Result<Pointer<u8>> {
90-
let memory = self.caller.data().memory();
91-
let mut allocator = self
92-
.host_state_mut()
93-
.allocator
94-
.take()
95-
.expect("allocator is not empty when calling a function in wasm; qed");
96-
97-
// We can not return on error early, as we need to store back allocator.
98-
let res = allocator
99-
.allocate(&mut MemoryWrapper(&memory, &mut self.caller), size)
100-
.map_err(|e| e.to_string());
101-
102-
self.host_state_mut().allocator = Some(allocator);
103-
104-
res
50+
util::allocate_memory(&mut self.caller, size)
10551
}
10652

10753
fn deallocate_memory(&mut self, ptr: Pointer<u8>) -> sp_wasm_interface::Result<()> {
108-
let memory = self.caller.data().memory();
109-
let mut allocator = self
110-
.host_state_mut()
111-
.allocator
112-
.take()
113-
.expect("allocator is not empty when calling a function in wasm; qed");
114-
115-
// We can not return on error early, as we need to store back allocator.
116-
let res = allocator
117-
.deallocate(&mut MemoryWrapper(&memory, &mut self.caller), ptr)
118-
.map_err(|e| e.to_string());
119-
120-
self.host_state_mut().allocator = Some(allocator);
121-
122-
res
54+
util::deallocate_memory(&mut self.caller, ptr)
12355
}
12456

12557
fn register_panic_error_message(&mut self, message: &str) {
126-
self.host_state_mut().panic_message = Some(message.to_owned());
58+
self.caller
59+
.data_mut()
60+
.host_state_mut()
61+
.expect("host state is not empty when calling a function in wasm; qed")
62+
.panic_message = Some(message.to_owned());
63+
}
64+
65+
fn with_caller_mut_impl(
66+
&mut self,
67+
_: FunctionContextToken,
68+
context: *mut (),
69+
callback: fn(*mut (), &mut Caller<StoreData>),
70+
) {
71+
callback(context, &mut self.caller)
12772
}
12873
}

0 commit comments

Comments
 (0)