Skip to content
This repository has been archived by the owner on Nov 15, 2023. It is now read-only.

Commit

Permalink
Executor: Add create_runtime_from_artifact_bytes (#14184)
Browse files Browse the repository at this point in the history
  • Loading branch information
mrcnski authored and gpestana committed May 27, 2023
1 parent cfa7181 commit 877805d
Show file tree
Hide file tree
Showing 3 changed files with 60 additions and 5 deletions.
9 changes: 8 additions & 1 deletion client/executor/benches/bench.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
5 changes: 3 additions & 2 deletions client/executor/wasmtime/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
};
51 changes: 49 additions & 2 deletions client/executor/wasmtime/src/runtime.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -537,14 +537,20 @@ 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.
///
/// 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
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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);
Expand Down

0 comments on commit 877805d

Please sign in to comment.