mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-04-26 16:57:58 +00:00
This reverts commit e5163380e7.
We found some bugs that we first need to fix.
This commit is contained in:
@@ -117,7 +117,7 @@ impl<'a> SandboxCapabilities for HostContext<'a> {
|
||||
return Err("Supervisor function returned unexpected result!".into());
|
||||
}
|
||||
}
|
||||
Err(err) => Err(err.to_string().into()),
|
||||
Err(err) => Err(err.message().to_string().into()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,8 +18,9 @@ use crate::state_holder;
|
||||
use sc_executor_common::error::WasmError;
|
||||
use sp_wasm_interface::{Function, Value, ValueType};
|
||||
use std::any::Any;
|
||||
use std::rc::Rc;
|
||||
use wasmtime::{
|
||||
Extern, ExternType, Func, FuncType, ImportType, Limits, Memory, MemoryType, Module,
|
||||
Callable, Extern, ExternType, Func, FuncType, ImportType, Limits, Memory, MemoryType, Module,
|
||||
Trap, Val,
|
||||
};
|
||||
|
||||
@@ -52,11 +53,11 @@ pub fn resolve_imports(
|
||||
let resolved = match import_ty.name() {
|
||||
"memory" => {
|
||||
memory_import_index = Some(externs.len());
|
||||
resolve_memory_import(module, &import_ty, heap_pages)?
|
||||
resolve_memory_import(module, import_ty, heap_pages)?
|
||||
}
|
||||
_ => resolve_func_import(
|
||||
module,
|
||||
&import_ty,
|
||||
import_ty,
|
||||
host_functions,
|
||||
allow_missing_func_imports,
|
||||
)?,
|
||||
@@ -130,7 +131,7 @@ fn resolve_func_import(
|
||||
{
|
||||
Some(host_func) => host_func,
|
||||
None if allow_missing_func_imports => {
|
||||
return Ok(MissingHostFuncHandler::new(import_ty).into_extern(module, &func_ty));
|
||||
return Ok(MissingHostFuncHandler::new(import_ty).into_extern(module, func_ty));
|
||||
}
|
||||
None => {
|
||||
return Err(WasmError::Other(format!(
|
||||
@@ -162,58 +163,6 @@ struct HostFuncHandler {
|
||||
host_func: &'static dyn Function,
|
||||
}
|
||||
|
||||
fn call_static(
|
||||
static_func: &'static dyn Function,
|
||||
wasmtime_params: &[Val],
|
||||
wasmtime_results: &mut [Val],
|
||||
) -> Result<(), wasmtime::Trap> {
|
||||
let unwind_result = state_holder::with_context(|host_ctx| {
|
||||
let mut host_ctx = host_ctx.expect(
|
||||
"host functions can be called only from wasm instance;
|
||||
wasm instance is always called initializing context;
|
||||
therefore host_ctx cannot be None;
|
||||
qed
|
||||
",
|
||||
);
|
||||
// `into_value` panics if it encounters a value that doesn't fit into the values
|
||||
// available in substrate.
|
||||
//
|
||||
// This, however, cannot happen since the signature of this function is created from
|
||||
// a `dyn Function` signature of which cannot have a non substrate value by definition.
|
||||
let mut params = wasmtime_params.iter().cloned().map(into_value);
|
||||
|
||||
std::panic::catch_unwind(std::panic::AssertUnwindSafe(|| {
|
||||
static_func.execute(&mut host_ctx, &mut params)
|
||||
}))
|
||||
});
|
||||
|
||||
let execution_result = match unwind_result {
|
||||
Ok(execution_result) => execution_result,
|
||||
Err(err) => return Err(Trap::new(stringify_panic_payload(err))),
|
||||
};
|
||||
|
||||
match execution_result {
|
||||
Ok(Some(ret_val)) => {
|
||||
debug_assert!(
|
||||
wasmtime_results.len() == 1,
|
||||
"wasmtime function signature, therefore the number of results, should always \
|
||||
correspond to the number of results returned by the host function",
|
||||
);
|
||||
wasmtime_results[0] = into_wasmtime_val(ret_val);
|
||||
Ok(())
|
||||
}
|
||||
Ok(None) => {
|
||||
debug_assert!(
|
||||
wasmtime_results.len() == 0,
|
||||
"wasmtime function signature, therefore the number of results, should always \
|
||||
correspond to the number of results returned by the host function",
|
||||
);
|
||||
Ok(())
|
||||
}
|
||||
Err(msg) => Err(Trap::new(msg)),
|
||||
}
|
||||
}
|
||||
|
||||
impl HostFuncHandler {
|
||||
fn new(host_func: &'static dyn Function) -> Self {
|
||||
Self {
|
||||
@@ -222,17 +171,66 @@ impl HostFuncHandler {
|
||||
}
|
||||
|
||||
fn into_extern(self, module: &Module) -> Extern {
|
||||
let host_func = self.host_func;
|
||||
let func_ty = wasmtime_func_sig(self.host_func);
|
||||
let func = Func::new(module.store(), func_ty,
|
||||
move |_, params, result| {
|
||||
call_static(host_func, params, result)
|
||||
}
|
||||
);
|
||||
let func = Func::new(module.store(), func_ty, Rc::new(self));
|
||||
Extern::Func(func)
|
||||
}
|
||||
}
|
||||
|
||||
impl Callable for HostFuncHandler {
|
||||
fn call(
|
||||
&self,
|
||||
wasmtime_params: &[Val],
|
||||
wasmtime_results: &mut [Val],
|
||||
) -> Result<(), wasmtime::Trap> {
|
||||
let unwind_result = state_holder::with_context(|host_ctx| {
|
||||
let mut host_ctx = host_ctx.expect(
|
||||
"host functions can be called only from wasm instance;
|
||||
wasm instance is always called initializing context;
|
||||
therefore host_ctx cannot be None;
|
||||
qed
|
||||
",
|
||||
);
|
||||
// `into_value` panics if it encounters a value that doesn't fit into the values
|
||||
// available in substrate.
|
||||
//
|
||||
// This, however, cannot happen since the signature of this function is created from
|
||||
// a `dyn Function` signature of which cannot have a non substrate value by definition.
|
||||
let mut params = wasmtime_params.iter().cloned().map(into_value);
|
||||
|
||||
std::panic::catch_unwind(std::panic::AssertUnwindSafe(|| {
|
||||
self.host_func.execute(&mut host_ctx, &mut params)
|
||||
}))
|
||||
});
|
||||
|
||||
let execution_result = match unwind_result {
|
||||
Ok(execution_result) => execution_result,
|
||||
Err(err) => return Err(Trap::new(stringify_panic_payload(err))),
|
||||
};
|
||||
|
||||
match execution_result {
|
||||
Ok(Some(ret_val)) => {
|
||||
debug_assert!(
|
||||
wasmtime_results.len() == 1,
|
||||
"wasmtime function signature, therefore the number of results, should always \
|
||||
correspond to the number of results returned by the host function",
|
||||
);
|
||||
wasmtime_results[0] = into_wasmtime_val(ret_val);
|
||||
Ok(())
|
||||
}
|
||||
Ok(None) => {
|
||||
debug_assert!(
|
||||
wasmtime_results.len() == 0,
|
||||
"wasmtime function signature, therefore the number of results, should always \
|
||||
correspond to the number of results returned by the host function",
|
||||
);
|
||||
Ok(())
|
||||
}
|
||||
Err(msg) => Err(Trap::new(msg)),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// A `Callable` handler for missing functions.
|
||||
struct MissingHostFuncHandler {
|
||||
module: String,
|
||||
@@ -247,18 +245,25 @@ impl MissingHostFuncHandler {
|
||||
}
|
||||
}
|
||||
|
||||
fn into_extern(self, wasmtime_module: &Module, func_ty: &FuncType) -> Extern {
|
||||
let Self { module, name } = self;
|
||||
let func = Func::new(wasmtime_module.store(), func_ty.clone(),
|
||||
move |_, _, _| Err(Trap::new(format!(
|
||||
"call to a missing function {}:{}",
|
||||
module, name
|
||||
)))
|
||||
);
|
||||
fn into_extern(self, module: &Module, func_ty: &FuncType) -> Extern {
|
||||
let func = Func::new(module.store(), func_ty.clone(), Rc::new(self));
|
||||
Extern::Func(func)
|
||||
}
|
||||
}
|
||||
|
||||
impl Callable for MissingHostFuncHandler {
|
||||
fn call(
|
||||
&self,
|
||||
_wasmtime_params: &[Val],
|
||||
_wasmtime_results: &mut [Val],
|
||||
) -> Result<(), wasmtime::Trap> {
|
||||
Err(Trap::new(format!(
|
||||
"call to a missing function {}:{}",
|
||||
self.module, self.name
|
||||
)))
|
||||
}
|
||||
}
|
||||
|
||||
fn wasmtime_func_sig(func: &dyn Function) -> wasmtime::FuncType {
|
||||
let params = func
|
||||
.signature()
|
||||
|
||||
@@ -26,7 +26,7 @@ use sc_executor_common::{
|
||||
util::{WasmModuleInfo, DataSegmentsSnapshot},
|
||||
};
|
||||
use sp_wasm_interface::{Pointer, WordSize, Value};
|
||||
use wasmtime::{Store, Instance, Module, Memory, Table, Val, Func, Extern, Global};
|
||||
use wasmtime::{Store, Instance, Module, Memory, Table, Val};
|
||||
|
||||
mod globals_snapshot;
|
||||
|
||||
@@ -88,35 +88,6 @@ pub struct InstanceWrapper {
|
||||
_not_send_nor_sync: marker::PhantomData<*const ()>,
|
||||
}
|
||||
|
||||
fn extern_memory(extern_: &Extern) -> Option<&Memory> {
|
||||
match extern_ {
|
||||
Extern::Memory(mem) => Some(mem),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
fn extern_global(extern_: &Extern) -> Option<&Global> {
|
||||
match extern_ {
|
||||
Extern::Global(glob) => Some(glob),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
fn extern_table(extern_: &Extern) -> Option<&Table> {
|
||||
match extern_ {
|
||||
Extern::Table(table) => Some(table),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
fn extern_func(extern_: &Extern) -> Option<&Func> {
|
||||
match extern_ {
|
||||
Extern::Func(func) => Some(func),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
impl InstanceWrapper {
|
||||
/// Create a new instance wrapper from the given wasm module.
|
||||
pub fn new(module_wrapper: &ModuleWrapper, imports: &Imports, heap_pages: u32) -> Result<Self> {
|
||||
@@ -125,7 +96,8 @@ impl InstanceWrapper {
|
||||
|
||||
let memory = match imports.memory_import_index {
|
||||
Some(memory_idx) => {
|
||||
extern_memory(&imports.externs[memory_idx])
|
||||
imports.externs[memory_idx]
|
||||
.memory()
|
||||
.expect("only memory can be at the `memory_idx`; qed")
|
||||
.clone()
|
||||
}
|
||||
@@ -158,7 +130,8 @@ impl InstanceWrapper {
|
||||
.instance
|
||||
.get_export(name)
|
||||
.ok_or_else(|| Error::from(format!("Exported method {} is not found", name)))?;
|
||||
let entrypoint = extern_func(&export)
|
||||
let entrypoint = export
|
||||
.func()
|
||||
.ok_or_else(|| Error::from(format!("Export {} is not a function", name)))?;
|
||||
match (entrypoint.ty().params(), entrypoint.ty().results()) {
|
||||
(&[wasmtime::ValType::I32, wasmtime::ValType::I32], &[wasmtime::ValType::I64]) => {}
|
||||
@@ -191,7 +164,8 @@ impl InstanceWrapper {
|
||||
.get_export("__heap_base")
|
||||
.ok_or_else(|| Error::from("__heap_base is not found"))?;
|
||||
|
||||
let heap_base_global = extern_global(&heap_base_export)
|
||||
let heap_base_global = heap_base_export
|
||||
.global()
|
||||
.ok_or_else(|| Error::from("__heap_base is not a global"))?;
|
||||
|
||||
let heap_base = heap_base_global
|
||||
@@ -209,7 +183,7 @@ impl InstanceWrapper {
|
||||
None => return Ok(None),
|
||||
};
|
||||
|
||||
let global = extern_global(&global).ok_or_else(|| format!("`{}` is not a global", name))?;
|
||||
let global = global.global().ok_or_else(|| format!("`{}` is not a global", name))?;
|
||||
|
||||
match global.get() {
|
||||
Val::I32(val) => Ok(Some(Value::I32(val))),
|
||||
@@ -227,7 +201,8 @@ fn get_linear_memory(instance: &Instance) -> Result<Memory> {
|
||||
.get_export("memory")
|
||||
.ok_or_else(|| Error::from("memory is not exported under `memory` name"))?;
|
||||
|
||||
let memory = extern_memory(&memory_export)
|
||||
let memory = memory_export
|
||||
.memory()
|
||||
.ok_or_else(|| Error::from("the `memory` export should have memory type"))?
|
||||
.clone();
|
||||
|
||||
@@ -238,8 +213,7 @@ fn get_linear_memory(instance: &Instance) -> Result<Memory> {
|
||||
fn get_table(instance: &Instance) -> Option<Table> {
|
||||
instance
|
||||
.get_export("__indirect_function_table")
|
||||
.as_ref()
|
||||
.and_then(extern_table)
|
||||
.and_then(|export| export.table())
|
||||
.cloned()
|
||||
}
|
||||
|
||||
|
||||
@@ -21,7 +21,6 @@ use sc_executor_common::{
|
||||
use sp_wasm_interface::Value;
|
||||
use cranelift_codegen::ir;
|
||||
use cranelift_wasm::GlobalIndex;
|
||||
use wasmtime_runtime::{ExportGlobal, Export};
|
||||
|
||||
/// A snapshot of a global variables values. This snapshot can be used later for restoring the
|
||||
/// values to the preserved state.
|
||||
@@ -44,9 +43,11 @@ impl GlobalsSnapshot {
|
||||
|
||||
for global_idx in instance_wrapper.imported_globals_count..instance_wrapper.globals_count {
|
||||
let (def, global) = match handle.lookup_by_declaration(
|
||||
&wasmtime_environ::EntityIndex::Global(GlobalIndex::from_u32(global_idx)),
|
||||
&wasmtime_environ::Export::Global(GlobalIndex::from_u32(global_idx)),
|
||||
) {
|
||||
Export::Global(ExportGlobal { definition, global, .. }) => (definition, global),
|
||||
wasmtime_runtime::Export::Global {
|
||||
definition, global, ..
|
||||
} => (definition, global),
|
||||
_ => unreachable!("only globals can be returned for a global request"),
|
||||
};
|
||||
|
||||
|
||||
@@ -158,7 +158,7 @@ fn perform_call(
|
||||
Err(trap) => {
|
||||
return Err(Error::from(format!(
|
||||
"Wasm execution trapped: {}",
|
||||
trap
|
||||
trap.message()
|
||||
)));
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user