// Copyright 2019-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 .
//! Defines the compiled Wasm runtime that uses Wasmtime internally.
use std::rc::Rc;
use std::sync::Arc;
use crate::host::HostState;
use crate::imports::{Imports, resolve_imports};
use crate::instance_wrapper::InstanceWrapper;
use crate::state_holder;
use sc_executor_common::{
error::{Error, Result, WasmError},
wasm_runtime::{WasmModule, WasmInstance},
};
use sp_allocator::FreeingBumpHeapAllocator;
use sp_runtime_interface::unpack_ptr_and_len;
use sp_wasm_interface::{Function, Pointer, WordSize, Value};
use wasmtime::{Config, Engine, Module, Store};
/// A `WasmModule` implementation using wasmtime to compile the runtime module to machine code
/// and execute the compiled code.
pub struct WasmtimeRuntime {
module: Arc,
heap_pages: u32,
allow_missing_func_imports: bool,
host_functions: Vec<&'static dyn Function>,
}
impl WasmModule for WasmtimeRuntime {
fn new_instance(&self) -> Result> {
// Scan all imports, find the matching host functions, and create stubs that adapt arguments
// and results.
let imports = resolve_imports(
&self.module,
&self.host_functions,
self.heap_pages,
self.allow_missing_func_imports,
)?;
Ok(Box::new(WasmtimeInstance {
module: self.module.clone(),
imports,
heap_pages: self.heap_pages,
}))
}
}
/// A `WasmInstance` implementation that reuses compiled module and spawns instances
/// to execute the compiled code.
pub struct WasmtimeInstance {
module: Arc,
imports: Imports,
heap_pages: u32,
}
// This is safe because `WasmtimeInstance` does not leak reference to `self.imports`
// and all imports don't reference any anything, other than host functions and memory
unsafe impl Send for WasmtimeInstance {}
impl WasmInstance for WasmtimeInstance {
fn call(&self, method: &str, data: &[u8]) -> Result> {
// TODO: reuse the instance and reset globals after call
// https://github.com/paritytech/substrate/issues/5141
let instance = Rc::new(InstanceWrapper::new(&self.module, &self.imports, self.heap_pages)?);
call_method(
instance,
method,
data,
)
}
fn get_global_const(&self, name: &str) -> Result