Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Module creation from premapped images #8245

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions crates/c-api/include/wasmtime/module.h
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,22 @@ WASM_API_EXTERN wasmtime_error_t *
wasmtime_module_deserialize_file(wasm_engine_t *engine, const char *path,
wasmtime_module_t **ret);

/**
* \brief Create a module from already mapped memory image.
*
* This function creates a module for which data is already mapped with proper
* permission flags in the host address space.
*
* If `finalizer` is provided it will be called with `data` argument when
* module is destroyed.
*
* This function does not take ownership of any of its arguments, but the
* returned error and module are owned by the caller.
*/
WASM_API_EXTERN wasmtime_error_t *wasmtime_module_from_premapped_image(
wasm_engine_t *engine, const uint8_t *image, size_t size, void *data,
void (*finalizer)(void *), wasmtime_module_t **ret);

/**
* \brief Returns the range of bytes in memory where this module’s compilation
* image resides.
Expand Down
27 changes: 27 additions & 0 deletions crates/c-api/src/module.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@ use crate::{
wasm_importtype_t, wasm_importtype_vec_t, wasm_store_t, wasmtime_error_t, CExternType,
};
use anyhow::Context;
use std::ffi::c_void;
use std::ffi::CStr;
use std::ops::Range;
use std::os::raw::c_char;
use wasmtime::{Engine, Module};

Expand Down Expand Up @@ -222,3 +224,28 @@ pub unsafe extern "C" fn wasmtime_module_deserialize_file(
*out = Box::into_raw(Box::new(wasmtime_module_t { module }));
})
}

#[no_mangle]
pub unsafe extern "C" fn wasmtime_module_from_premapped_image(
engine: &wasm_engine_t,
image: *const u8,
size: usize,
data: *mut c_void,
finalizer: Option<extern "C" fn(*mut c_void)>,
out: &mut *mut wasmtime_module_t,
) -> Option<Box<wasmtime_error_t>> {
let foreign = crate::ForeignData { data, finalizer };
let result = Module::from_premapped_image(
&engine.engine,
Range {
start: image,
end: image.offset(size as isize),
},
move || {
let _ = &foreign;
},
);
handle_result(result, |module| {
*out = Box::into_raw(Box::new(wasmtime_module_t { module }));
})
}
6 changes: 4 additions & 2 deletions crates/wasmtime/src/compile/code_builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -177,7 +177,9 @@ impl<'a> CodeBuilder<'a> {
Ok((code, info))
},
// Implementation of how to serialize artifacts
|(_engine, _wasm, _), (code, _info_and_types)| Some(code.mmap().to_vec()),
|(_engine, _wasm, _), (code, _info_and_types)| {
Some(code.image_slice().to_vec())
},
// Cache hit, deserialize the provided artifacts
|(engine, _wasm, _), serialized_bytes| {
let code = engine
Expand Down Expand Up @@ -290,7 +292,7 @@ impl std::hash::Hash for HashedEngineCompileEnv<'_> {

#[cfg(feature = "runtime")]
fn publish_mmap(mmap: MmapVec) -> Result<Arc<CodeMemory>> {
let mut code = CodeMemory::new(mmap)?;
let mut code = CodeMemory::new_from_mmap(mmap)?;
code.publish()?;
Ok(Arc::new(code))
}
24 changes: 23 additions & 1 deletion crates/wasmtime/src/engine.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ use anyhow::{Context, Result};
use object::write::{Object, StandardSegment};
use object::SectionKind;
use once_cell::sync::OnceCell;
use std::ops::Range;
use std::path::Path;
use std::sync::atomic::{AtomicU64, Ordering};
use std::sync::Arc;
Expand Down Expand Up @@ -703,13 +704,34 @@ impl Engine {
)
}

/// Like `load_code_bytes`, but uses image already mapped in the host
/// address space.
pub(crate) unsafe fn load_code_premapped(
&self,
image_range: Range<*const u8>,
finalizer: impl FnOnce() + Send + Sync + 'static,
expected: ObjectKind,
) -> Result<Arc<crate::CodeMemory>> {
serialization::check_compatible(
self,
&std::slice::from_raw_parts(
image_range.start,
image_range.end.offset_from(image_range.start) as usize,
),
expected,
)?;
let mut code = crate::CodeMemory::new_from_premapped_image(image_range, finalizer)?;
code.publish()?;
Ok(Arc::new(code))
}

pub(crate) fn load_code(
&self,
mmap: wasmtime_runtime::MmapVec,
expected: ObjectKind,
) -> Result<Arc<crate::CodeMemory>> {
serialization::check_compatible(self, &mmap, expected)?;
let mut code = crate::CodeMemory::new(mmap)?;
let mut code = crate::CodeMemory::new_from_mmap(mmap)?;
code.publish()?;
Ok(Arc::new(code))
}
Expand Down
Loading