Skip to content

Commit

Permalink
Add Engine::precompile_compatibility_key
Browse files Browse the repository at this point in the history
This method returns a key that can be used to index precompiled binaries
from one Engine instance that can be deserialized by another Engine
instance.
  • Loading branch information
lann committed Feb 17, 2023
1 parent a139ed6 commit 8a14477
Show file tree
Hide file tree
Showing 4 changed files with 30 additions and 9 deletions.
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions crates/wasmtime/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ rayon = { version = "1.0", optional = true }
object = { workspace = true }
async-trait = { workspace = true, optional = true }
encoding_rs = { version = "0.8.31", optional = true }
sha2 = "0.10.2"

[target.'cfg(target_os = "windows")'.dependencies.windows-sys]
workspace = true
Expand Down
14 changes: 14 additions & 0 deletions crates/wasmtime/src/engine.rs
Original file line number Diff line number Diff line change
Expand Up @@ -239,6 +239,20 @@ impl Engine {
Ok(mmap.to_vec())
}

/// Returns a value that can be used to check precompiled WebAssembly compatibility.
///
/// The outputs of [`Engine::precompile_module`] and [`Engine::precompile_component`]
/// are compatible with a different [`Engine`] instance only if the two engines use
/// compatible [`Config`]s. The value returned by this function will be the same for two
/// [`Engine`]s if a binary from one can be deserialized by the other.
#[cfg(compiler)]
#[cfg_attr(nightlydoc, doc(cfg(feature = "cranelift")))] // see build.rs
pub fn precompile_compatibility_key(&self) -> impl AsRef<[u8]> {
use sha2::Digest;
let data = serialization::build_compiler_info(&self);
sha2::Sha256::digest(data)
}

pub(crate) fn run_maybe_parallel<
A: Send,
B: Send,
Expand Down
23 changes: 14 additions & 9 deletions crates/wasmtime/src/engine/serialization.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,16 +37,8 @@ const VERSION: u8 = 0;
/// Produces a blob of bytes by serializing the `engine`'s configuration data to
/// be checked, perhaps in a different process, with the `check_compatible`
/// method below.
///
/// The blob of bytes is inserted into the object file specified to become part
/// of the final compiled artifact.
#[cfg(compiler)]
pub fn append_compiler_info(engine: &Engine, obj: &mut Object<'_>) {
let section = obj.add_section(
obj.segment_name(StandardSegment::Data).to_vec(),
obj::ELF_WASM_ENGINE.as_bytes().to_vec(),
SectionKind::ReadOnlyData,
);
pub fn build_compiler_info(engine: &Engine) -> Vec<u8> {
let mut data = Vec::new();
data.push(VERSION);
let version = match &engine.config().module_version {
Expand All @@ -62,6 +54,19 @@ pub fn append_compiler_info(engine: &Engine, obj: &mut Object<'_>) {
data.push(version.len() as u8);
data.extend_from_slice(version.as_bytes());
bincode::serialize_into(&mut data, &Metadata::new(engine)).unwrap();
data
}

/// Inserts the "compiler info" from build_compiler_info into the object file
/// specified to become part of the final compiled artifact.
#[cfg(compiler)]
pub fn append_compiler_info(engine: &Engine, obj: &mut Object<'_>) {
let section = obj.add_section(
obj.segment_name(StandardSegment::Data).to_vec(),
obj::ELF_WASM_ENGINE.as_bytes().to_vec(),
SectionKind::ReadOnlyData,
);
let data = build_compiler_info(engine);
obj.set_section_data(section, data, 1);
}

Expand Down

0 comments on commit 8a14477

Please sign in to comment.