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 31ee10c commit fb49f07
Show file tree
Hide file tree
Showing 4 changed files with 32 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 @@ -39,6 +39,7 @@ rayon = { version = "1.0", optional = true }
object = { workspace = true }
async-trait = { workspace = true, optional = true }
encoding_rs = { version = "0.8.31", optional = true }
hashbrown = { workspace = true }

[target.'cfg(target_os = "windows")'.dependencies.windows-sys]
workspace = true
Expand Down
16 changes: 16 additions & 0 deletions crates/wasmtime/src/engine.rs
Original file line number Diff line number Diff line change
Expand Up @@ -239,6 +239,22 @@ 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 std::hash::{BuildHasher, Hasher};
let data = serialization::build_compiler_info(&self);
let hasher = hashbrown::hash_map::DefaultHashBuilder::default().build_hasher();
hasher.write(&data);
hasher.finish().to_le_bytes()
}

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 fb49f07

Please sign in to comment.