mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-04-27 02:17:58 +00:00
Update wasmtime to 0.29.0 (#9552)
* Start
* Move to ctx
* Make it compile for now
* More work
* Get rid off state-holder
* Use less Refcells
* 🤦
* Don't use RefCell
* Use names for parameters
* Fixes after merge
* Fixes after merge
* Review feedback
* FMT
This commit is contained in:
@@ -19,7 +19,7 @@
|
||||
//! This module defines `HostState` and `HostContext` structs which provide logic and state
|
||||
//! required for execution of host.
|
||||
|
||||
use crate::instance_wrapper::InstanceWrapper;
|
||||
use crate::{instance_wrapper::InstanceWrapper, runtime::StoreData};
|
||||
use codec::{Decode, Encode};
|
||||
use log::trace;
|
||||
use sc_allocator::FreeingBumpHeapAllocator;
|
||||
@@ -31,7 +31,7 @@ use sc_executor_common::{
|
||||
use sp_core::sandbox as sandbox_primitives;
|
||||
use sp_wasm_interface::{FunctionContext, MemoryId, Pointer, Sandbox, WordSize};
|
||||
use std::{cell::RefCell, rc::Rc};
|
||||
use wasmtime::{Func, Val};
|
||||
use wasmtime::{Caller, Func, Val};
|
||||
|
||||
/// 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
|
||||
@@ -64,45 +64,67 @@ impl HostState {
|
||||
}
|
||||
|
||||
/// Materialize `HostContext` that can be used to invoke a substrate host `dyn Function`.
|
||||
pub fn materialize<'a>(&'a self) -> HostContext<'a> {
|
||||
HostContext(self)
|
||||
pub(crate) fn materialize<'a, 'b, 'c>(
|
||||
&'a self,
|
||||
caller: &'b mut Caller<'c, StoreData>,
|
||||
) -> HostContext<'a, 'b, 'c> {
|
||||
HostContext { host_state: self, caller }
|
||||
}
|
||||
}
|
||||
|
||||
/// A `HostContext` implements `FunctionContext` for making host calls from a Wasmtime
|
||||
/// runtime. The `HostContext` exists only for the lifetime of the call and borrows state from
|
||||
/// a longer-living `HostState`.
|
||||
pub struct HostContext<'a>(&'a HostState);
|
||||
pub(crate) struct HostContext<'a, 'b, 'c> {
|
||||
host_state: &'a HostState,
|
||||
caller: &'b mut Caller<'c, StoreData>,
|
||||
}
|
||||
|
||||
impl<'a> std::ops::Deref for HostContext<'a> {
|
||||
impl<'a, 'b, 'c> std::ops::Deref for HostContext<'a, 'b, 'c> {
|
||||
type Target = HostState;
|
||||
fn deref(&self) -> &HostState {
|
||||
self.0
|
||||
self.host_state
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> sp_wasm_interface::FunctionContext for HostContext<'a> {
|
||||
impl<'a, 'b, 'c> sp_wasm_interface::FunctionContext for HostContext<'a, 'b, 'c> {
|
||||
fn read_memory_into(
|
||||
&self,
|
||||
address: Pointer<u8>,
|
||||
dest: &mut [u8],
|
||||
) -> sp_wasm_interface::Result<()> {
|
||||
self.instance.read_memory_into(address, dest).map_err(|e| e.to_string())
|
||||
let ctx = &self.caller;
|
||||
self.host_state
|
||||
.instance
|
||||
.read_memory_into(ctx, address, dest)
|
||||
.map_err(|e| e.to_string())
|
||||
}
|
||||
|
||||
fn write_memory(&mut self, address: Pointer<u8>, data: &[u8]) -> sp_wasm_interface::Result<()> {
|
||||
self.instance.write_memory_from(address, data).map_err(|e| e.to_string())
|
||||
let ctx = &mut self.caller;
|
||||
self.host_state
|
||||
.instance
|
||||
.write_memory_from(ctx, address, data)
|
||||
.map_err(|e| e.to_string())
|
||||
}
|
||||
|
||||
fn allocate_memory(&mut self, size: WordSize) -> sp_wasm_interface::Result<Pointer<u8>> {
|
||||
self.instance
|
||||
.allocate(&mut *self.allocator.borrow_mut(), size)
|
||||
let ctx = &mut self.caller;
|
||||
let allocator = &self.host_state.allocator;
|
||||
|
||||
self.host_state
|
||||
.instance
|
||||
.allocate(ctx, &mut *allocator.borrow_mut(), size)
|
||||
.map_err(|e| e.to_string())
|
||||
}
|
||||
|
||||
fn deallocate_memory(&mut self, ptr: Pointer<u8>) -> sp_wasm_interface::Result<()> {
|
||||
self.instance
|
||||
.deallocate(&mut *self.allocator.borrow_mut(), ptr)
|
||||
let ctx = &mut self.caller;
|
||||
let allocator = &self.host_state.allocator;
|
||||
|
||||
self.host_state
|
||||
.instance
|
||||
.deallocate(ctx, &mut *allocator.borrow_mut(), ptr)
|
||||
.map_err(|e| e.to_string())
|
||||
}
|
||||
|
||||
@@ -111,7 +133,7 @@ impl<'a> sp_wasm_interface::FunctionContext for HostContext<'a> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> Sandbox for HostContext<'a> {
|
||||
impl<'a, 'b, 'c> Sandbox for HostContext<'a, 'b, 'c> {
|
||||
fn memory_get(
|
||||
&mut self,
|
||||
memory_id: MemoryId,
|
||||
@@ -129,7 +151,8 @@ impl<'a> Sandbox for HostContext<'a> {
|
||||
Ok(buffer) => buffer,
|
||||
};
|
||||
|
||||
if let Err(_) = self.instance.write_memory_from(buf_ptr, &buffer) {
|
||||
let instance = self.instance.clone();
|
||||
if let Err(_) = instance.write_memory_from(&mut self.caller, buf_ptr, &buffer) {
|
||||
return Ok(sandbox_primitives::ERR_OUT_OF_BOUNDS)
|
||||
}
|
||||
|
||||
@@ -148,7 +171,7 @@ impl<'a> Sandbox for HostContext<'a> {
|
||||
|
||||
let len = val_len as usize;
|
||||
|
||||
let buffer = match self.instance.read_memory(val_ptr, len) {
|
||||
let buffer = match self.instance.read_memory(&self.caller, val_ptr, len) {
|
||||
Err(_) => return Ok(sandbox_primitives::ERR_OUT_OF_BOUNDS),
|
||||
Ok(buffer) => buffer,
|
||||
};
|
||||
@@ -241,12 +264,14 @@ impl<'a> Sandbox for HostContext<'a> {
|
||||
) -> sp_wasm_interface::Result<u32> {
|
||||
// Extract a dispatch thunk from the instance's table by the specified index.
|
||||
let dispatch_thunk = {
|
||||
let ctx = &mut self.caller;
|
||||
let table_item = self
|
||||
.host_state
|
||||
.instance
|
||||
.table()
|
||||
.as_ref()
|
||||
.ok_or_else(|| "Runtime doesn't have a table; sandbox is unavailable")?
|
||||
.get(dispatch_thunk_id);
|
||||
.get(ctx, dispatch_thunk_id);
|
||||
|
||||
table_item
|
||||
.ok_or_else(|| "dispatch_thunk_id is out of bounds")?
|
||||
@@ -295,12 +320,12 @@ impl<'a> Sandbox for HostContext<'a> {
|
||||
}
|
||||
}
|
||||
|
||||
struct SandboxContext<'a, 'b> {
|
||||
host_context: &'a mut HostContext<'b>,
|
||||
struct SandboxContext<'a, 'b, 'c, 'd> {
|
||||
host_context: &'a mut HostContext<'b, 'c, 'd>,
|
||||
dispatch_thunk: Func,
|
||||
}
|
||||
|
||||
impl<'a, 'b> sandbox::SandboxContext for SandboxContext<'a, 'b> {
|
||||
impl<'a, 'b, 'c, 'd> sandbox::SandboxContext for SandboxContext<'a, 'b, 'c, 'd> {
|
||||
fn invoke(
|
||||
&mut self,
|
||||
invoke_args_ptr: Pointer<u8>,
|
||||
@@ -308,12 +333,16 @@ impl<'a, 'b> sandbox::SandboxContext for SandboxContext<'a, 'b> {
|
||||
state: u32,
|
||||
func_idx: SupervisorFuncIndex,
|
||||
) -> Result<i64> {
|
||||
let result = self.dispatch_thunk.call(&[
|
||||
Val::I32(u32::from(invoke_args_ptr) as i32),
|
||||
Val::I32(invoke_args_len as i32),
|
||||
Val::I32(state as i32),
|
||||
Val::I32(usize::from(func_idx) as i32),
|
||||
]);
|
||||
let result = self.dispatch_thunk.call(
|
||||
&mut self.host_context.caller,
|
||||
&[
|
||||
Val::I32(u32::from(invoke_args_ptr) as i32),
|
||||
Val::I32(invoke_args_len as i32),
|
||||
Val::I32(state as i32),
|
||||
Val::I32(usize::from(func_idx) as i32),
|
||||
],
|
||||
);
|
||||
|
||||
match result {
|
||||
Ok(ret_vals) => {
|
||||
let ret_val = if ret_vals.len() != 1 {
|
||||
|
||||
Reference in New Issue
Block a user