mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-04-29 02:07:56 +00:00
wasm-executor: Support growing the memory (#12520)
* As always, start with something :P * Add support for max_heap_pages * Add support for wasmtime * Make it compile * Fix compilation * Copy wrongly merged code * Fix compilation * Some fixes * Fix * Get stuff working * More work * More fixes * ... * More * FIXEs * Switch wasmi to use `RuntimeBlob` like wasmtime * Removed unused stuff * Cleanup * More cleanups * Introduce `CallContext` * Fixes * More fixes * Add builder for creating the `WasmExecutor` * Adds some docs * FMT * First round of feedback. * Review feedback round 2 * More fixes * Fix try-runtime * Update client/executor/wasmtime/src/instance_wrapper.rs Co-authored-by: Koute <koute@users.noreply.github.com> * Update client/executor/common/src/wasm_runtime.rs Co-authored-by: Koute <koute@users.noreply.github.com> * Update client/executor/common/src/runtime_blob/runtime_blob.rs Co-authored-by: Koute <koute@users.noreply.github.com> * Update client/executor/common/src/wasm_runtime.rs Co-authored-by: Koute <koute@users.noreply.github.com> * Update client/allocator/src/freeing_bump.rs Co-authored-by: Koute <koute@users.noreply.github.com> * Update client/allocator/src/freeing_bump.rs Co-authored-by: Koute <koute@users.noreply.github.com> * Feedback round 3 * FMT * Review comments --------- Co-authored-by: Koute <koute@users.noreply.github.com>
This commit is contained in:
@@ -24,20 +24,25 @@ use wasmtime::Caller;
|
||||
use sc_allocator::{AllocationStats, FreeingBumpHeapAllocator};
|
||||
use sp_wasm_interface::{Pointer, WordSize};
|
||||
|
||||
use crate::{runtime::StoreData, util};
|
||||
use crate::{instance_wrapper::MemoryWrapper, runtime::StoreData, util};
|
||||
|
||||
/// The state required to construct a HostContext context. The context only lasts for one host
|
||||
/// call, whereas the state is maintained for the duration of a Wasm runtime call, which may make
|
||||
/// many different host calls that must share state.
|
||||
pub struct HostState {
|
||||
allocator: FreeingBumpHeapAllocator,
|
||||
/// The allocator instance to keep track of allocated memory.
|
||||
///
|
||||
/// This is stored as an `Option` as we need to temporarly set this to `None` when we are
|
||||
/// allocating/deallocating memory. The problem being that we can only mutable access `caller`
|
||||
/// once.
|
||||
allocator: Option<FreeingBumpHeapAllocator>,
|
||||
panic_message: Option<String>,
|
||||
}
|
||||
|
||||
impl HostState {
|
||||
/// Constructs a new `HostState`.
|
||||
pub fn new(allocator: FreeingBumpHeapAllocator) -> Self {
|
||||
HostState { allocator, panic_message: None }
|
||||
HostState { allocator: Some(allocator), panic_message: None }
|
||||
}
|
||||
|
||||
/// Takes the error message out of the host state, leaving a `None` in its place.
|
||||
@@ -46,7 +51,9 @@ impl HostState {
|
||||
}
|
||||
|
||||
pub(crate) fn allocation_stats(&self) -> AllocationStats {
|
||||
self.allocator.stats()
|
||||
self.allocator.as_ref()
|
||||
.expect("Allocator is always set and only unavailable when doing an allocation/deallocation; qed")
|
||||
.stats()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -81,22 +88,38 @@ impl<'a> sp_wasm_interface::FunctionContext for HostContext<'a> {
|
||||
|
||||
fn allocate_memory(&mut self, size: WordSize) -> sp_wasm_interface::Result<Pointer<u8>> {
|
||||
let memory = self.caller.data().memory();
|
||||
let (memory, data) = memory.data_and_store_mut(&mut self.caller);
|
||||
data.host_state_mut()
|
||||
.expect("host state is not empty when calling a function in wasm; qed")
|
||||
let mut allocator = self
|
||||
.host_state_mut()
|
||||
.allocator
|
||||
.allocate(memory, size)
|
||||
.map_err(|e| e.to_string())
|
||||
.take()
|
||||
.expect("allocator is not empty when calling a function in wasm; qed");
|
||||
|
||||
// We can not return on error early, as we need to store back allocator.
|
||||
let res = allocator
|
||||
.allocate(&mut MemoryWrapper(&memory, &mut self.caller), size)
|
||||
.map_err(|e| e.to_string());
|
||||
|
||||
self.host_state_mut().allocator = Some(allocator);
|
||||
|
||||
res
|
||||
}
|
||||
|
||||
fn deallocate_memory(&mut self, ptr: Pointer<u8>) -> sp_wasm_interface::Result<()> {
|
||||
let memory = self.caller.data().memory();
|
||||
let (memory, data) = memory.data_and_store_mut(&mut self.caller);
|
||||
data.host_state_mut()
|
||||
.expect("host state is not empty when calling a function in wasm; qed")
|
||||
let mut allocator = self
|
||||
.host_state_mut()
|
||||
.allocator
|
||||
.deallocate(memory, ptr)
|
||||
.map_err(|e| e.to_string())
|
||||
.take()
|
||||
.expect("allocator is not empty when calling a function in wasm; qed");
|
||||
|
||||
// We can not return on error early, as we need to store back allocator.
|
||||
let res = allocator
|
||||
.deallocate(&mut MemoryWrapper(&memory, &mut self.caller), ptr)
|
||||
.map_err(|e| e.to_string());
|
||||
|
||||
self.host_state_mut().allocator = Some(allocator);
|
||||
|
||||
res
|
||||
}
|
||||
|
||||
fn register_panic_error_message(&mut self, message: &str) {
|
||||
|
||||
Reference in New Issue
Block a user