Skip to content

Commit

Permalink
Module creation from premapped images
Browse files Browse the repository at this point in the history
  • Loading branch information
Milek7 committed Mar 26, 2024
1 parent d256e25 commit f31e5aa
Show file tree
Hide file tree
Showing 9 changed files with 406 additions and 150 deletions.
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

0 comments on commit f31e5aa

Please sign in to comment.