mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-04-25 22:17:58 +00:00
Executor: Add create_runtime_from_artifact_bytes (#14184)
This commit is contained in:
@@ -188,12 +188,19 @@ fn bench_call_instance(c: &mut Criterion) {
|
||||
},
|
||||
),
|
||||
(
|
||||
"pooling_vanilla",
|
||||
"pooling_vanilla_fresh",
|
||||
Method::Compiled {
|
||||
instantiation_strategy: InstantiationStrategy::Pooling,
|
||||
precompile: false,
|
||||
},
|
||||
),
|
||||
(
|
||||
"pooling_vanilla_precompiled",
|
||||
Method::Compiled {
|
||||
instantiation_strategy: InstantiationStrategy::Pooling,
|
||||
precompile: true,
|
||||
},
|
||||
),
|
||||
(
|
||||
"pooling_cow_fresh",
|
||||
Method::Compiled {
|
||||
|
||||
@@ -37,6 +37,7 @@ mod util;
|
||||
mod tests;
|
||||
|
||||
pub use runtime::{
|
||||
create_runtime, create_runtime_from_artifact, prepare_runtime_artifact, Config,
|
||||
DeterministicStackLimit, InstantiationStrategy, Semantics,
|
||||
create_runtime, create_runtime_from_artifact, create_runtime_from_artifact_bytes,
|
||||
prepare_runtime_artifact, Config, DeterministicStackLimit, InstantiationStrategy, Semantics,
|
||||
WasmtimeRuntime,
|
||||
};
|
||||
|
||||
@@ -435,7 +435,7 @@ pub struct DeterministicStackLimit {
|
||||
/// All of the CoW strategies (with `CopyOnWrite` suffix) are only supported when either:
|
||||
/// a) we're running on Linux,
|
||||
/// b) we're running on an Unix-like system and we're precompiling
|
||||
/// our module beforehand.
|
||||
/// our module beforehand and instantiating from a file.
|
||||
///
|
||||
/// If the CoW variant of a strategy is unsupported the executor will
|
||||
/// fall back to the non-CoW equivalent.
|
||||
@@ -537,7 +537,7 @@ enum CodeSupplyMode<'a> {
|
||||
/// The runtime is instantiated using the given runtime blob.
|
||||
Fresh(RuntimeBlob),
|
||||
|
||||
/// The runtime is instantiated using a precompiled module.
|
||||
/// The runtime is instantiated using a precompiled module at the given path.
|
||||
///
|
||||
/// This assumes that the code is already prepared for execution and the same `Config` was
|
||||
/// used.
|
||||
@@ -545,6 +545,12 @@ enum CodeSupplyMode<'a> {
|
||||
/// We use a `Path` here instead of simply passing a byte slice to allow `wasmtime` to
|
||||
/// map the runtime's linear memory on supported platforms in a copy-on-write fashion.
|
||||
Precompiled(&'a Path),
|
||||
|
||||
/// The runtime is instantiated using a precompiled module with the given bytes.
|
||||
///
|
||||
/// This assumes that the code is already prepared for execution and the same `Config` was
|
||||
/// used.
|
||||
PrecompiledBytes(&'a [u8]),
|
||||
}
|
||||
|
||||
/// Create a new `WasmtimeRuntime` given the code. This function performs translation from Wasm to
|
||||
@@ -589,6 +595,31 @@ where
|
||||
do_create_runtime::<H>(CodeSupplyMode::Precompiled(compiled_artifact_path), config)
|
||||
}
|
||||
|
||||
/// The same as [`create_runtime`] but takes the bytes of a precompiled artifact,
|
||||
/// which makes this function considerably faster than [`create_runtime`],
|
||||
/// but slower than the more optimized [`create_runtime_from_artifact`].
|
||||
/// This is especially slow on non-Linux Unix systems. Useful in very niche cases.
|
||||
///
|
||||
/// # Safety
|
||||
///
|
||||
/// The caller must ensure that the compiled artifact passed here was:
|
||||
/// 1) produced by [`prepare_runtime_artifact`],
|
||||
/// 2) was not modified,
|
||||
///
|
||||
/// Failure to adhere to these requirements might lead to crashes and arbitrary code execution.
|
||||
///
|
||||
/// It is ok though if the compiled artifact was created by code of another version or with
|
||||
/// different configuration flags. In such case the caller will receive an `Err` deterministically.
|
||||
pub unsafe fn create_runtime_from_artifact_bytes<H>(
|
||||
compiled_artifact_bytes: &[u8],
|
||||
config: Config,
|
||||
) -> std::result::Result<WasmtimeRuntime, WasmError>
|
||||
where
|
||||
H: HostFunctions,
|
||||
{
|
||||
do_create_runtime::<H>(CodeSupplyMode::PrecompiledBytes(compiled_artifact_bytes), config)
|
||||
}
|
||||
|
||||
/// # Safety
|
||||
///
|
||||
/// This is only unsafe if called with [`CodeSupplyMode::Artifact`]. See
|
||||
@@ -663,6 +694,22 @@ where
|
||||
|
||||
(module, InternalInstantiationStrategy::Builtin)
|
||||
},
|
||||
CodeSupplyMode::PrecompiledBytes(compiled_artifact_bytes) => {
|
||||
if let InstantiationStrategy::LegacyInstanceReuse =
|
||||
config.semantics.instantiation_strategy
|
||||
{
|
||||
return Err(WasmError::Other("the legacy instance reuse instantiation strategy is incompatible with precompiled modules".into()));
|
||||
}
|
||||
|
||||
// SAFETY: The unsafety of `deserialize` is covered by this function. The
|
||||
// responsibilities to maintain the invariants are passed to the caller.
|
||||
//
|
||||
// See [`create_runtime_from_artifact_bytes`] for more details.
|
||||
let module = wasmtime::Module::deserialize(&engine, compiled_artifact_bytes)
|
||||
.map_err(|e| WasmError::Other(format!("cannot deserialize module: {:#}", e)))?;
|
||||
|
||||
(module, InternalInstantiationStrategy::Builtin)
|
||||
},
|
||||
};
|
||||
|
||||
let mut linker = wasmtime::Linker::new(&engine);
|
||||
|
||||
Reference in New Issue
Block a user