Skip to content
Merged
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
11 changes: 9 additions & 2 deletions crates/api/src/instance.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ impl Resolver for SimpleResolver {
pub fn instantiate_in_context(
data: &[u8],
imports: Vec<(String, String, Extern)>,
module_name: Option<String>,
context: Context,
exports: Rc<RefCell<HashMap<String, Option<wasmtime_runtime::Export>>>>,
) -> Result<(InstanceHandle, HashSet<Context>), Error> {
Expand All @@ -38,6 +39,7 @@ pub fn instantiate_in_context(
let instance = instantiate(
&mut context.compiler(),
data,
module_name,
&mut resolver,
exports,
debug_info,
Expand Down Expand Up @@ -77,8 +79,13 @@ impl Instance {
.zip(externs.iter())
.map(|(i, e)| (i.module().to_string(), i.name().to_string(), e.clone()))
.collect::<Vec<_>>();
let (mut instance_handle, contexts) =
instantiate_in_context(module.binary().expect("binary"), imports, context, exports)?;
let (mut instance_handle, contexts) = instantiate_in_context(
module.binary().expect("binary"),
imports,
module.name().cloned(),
context,
exports,
)?;

let exports = {
let mut exports = Vec::with_capacity(module.exports().len());
Expand Down
61 changes: 55 additions & 6 deletions crates/api/src/module.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ use crate::types::{
use anyhow::{Error, Result};
use std::rc::Rc;
use wasmparser::{
validate, ExternalKind, ImportSectionEntryType, ModuleReader, OperatorValidatorConfig,
SectionCode, ValidatingParserConfig,
validate, CustomSectionKind, ExternalKind, ImportSectionEntryType, ModuleReader, Name,
OperatorValidatorConfig, SectionCode, ValidatingParserConfig,
};

fn into_memory_type(mt: wasmparser::MemoryType) -> MemoryType {
Expand Down Expand Up @@ -56,7 +56,9 @@ fn into_table_type(tt: wasmparser::TableType) -> TableType {
TableType::new(ty, limits)
}

fn read_imports_and_exports(binary: &[u8]) -> Result<(Box<[ImportType]>, Box<[ExportType]>)> {
fn read_imports_and_exports(
binary: &[u8],
) -> Result<(Box<[ImportType]>, Box<[ExportType]>, Option<String>)> {
let mut reader = ModuleReader::new(binary)?;
let mut imports = Vec::new();
let mut exports = Vec::new();
Expand All @@ -65,6 +67,7 @@ fn read_imports_and_exports(binary: &[u8]) -> Result<(Box<[ImportType]>, Box<[Ex
let mut func_sig = Vec::new();
let mut sigs = Vec::new();
let mut globals = Vec::new();
let mut module_name = None;
while !reader.eof() {
let section = reader.read()?;
match section.code {
Expand Down Expand Up @@ -157,12 +160,32 @@ fn read_imports_and_exports(binary: &[u8]) -> Result<(Box<[ImportType]>, Box<[Ex
exports.push(ExportType::new(entry.field, r#type));
}
}
SectionCode::Custom {
kind: CustomSectionKind::Name,
..
} => {
// Read name section. Per spec, ignore invalid custom section.
if let Ok(mut reader) = section.get_name_section_reader() {
while let Ok(entry) = reader.read() {
if let Name::Module(name) = entry {
if let Ok(name) = name.get_name() {
module_name = Some(name.to_string());
}
break;
}
}
}
}
_ => {
// skip other sections
}
}
}
Ok((imports.into_boxed_slice(), exports.into_boxed_slice()))
Ok((
imports.into_boxed_slice(),
exports.into_boxed_slice(),
module_name,
))
}

#[derive(Clone)]
Expand Down Expand Up @@ -196,6 +219,7 @@ struct ModuleInner {
source: ModuleCodeSource,
imports: Box<[ImportType]>,
exports: Box<[ExportType]>,
name: Option<String>,
}

impl Module {
Expand Down Expand Up @@ -239,7 +263,16 @@ impl Module {
// Note that the call to `unsafe` here should be ok because we
// previously validated the binary, meaning we're guaranteed to pass a
// valid binary for `store`.
unsafe { Self::new_unchecked(store, binary) }
unsafe { Self::create(store, binary, None) }
}

/// Creates a new WebAssembly `Module` from the given in-memory `binary`
/// data. The provided `name` will be used in traps/backtrace details.
///
/// See [`Module::new`] for other details.
pub fn new_with_name(store: &Store, binary: &[u8], name: String) -> Result<Module> {
Self::validate(store, binary)?;
unsafe { Self::create(store, binary, Some(name)) }
}

/// Creates a new WebAssembly `Module` from the given in-memory `binary`
Expand Down Expand Up @@ -269,13 +302,22 @@ impl Module {
/// be somewhat valid for decoding purposes, and the basics of decoding can
/// still fail.
pub unsafe fn new_unchecked(store: &Store, binary: &[u8]) -> Result<Module> {
let (imports, exports) = read_imports_and_exports(binary)?;
Self::create(store, binary, None)
}

unsafe fn create(
store: &Store,
binary: &[u8],
name_override: Option<String>,
) -> Result<Module> {
let (imports, exports, name) = read_imports_and_exports(binary)?;
Ok(Module {
inner: Rc::new(ModuleInner {
store: store.clone(),
source: ModuleCodeSource::Binary(binary.into()),
imports,
exports,
name: name_override.or(name),
}),
})
}
Expand Down Expand Up @@ -320,6 +362,7 @@ impl Module {
source: ModuleCodeSource::Unknown,
imports: Box::new([]),
exports,
name: None,
}),
}
}
Expand All @@ -331,6 +374,12 @@ impl Module {
}
}

/// Returns identifier/name that this [`Module`] has. This name
/// is used in traps/backtrace details.
pub fn name(&self) -> Option<&String> {
self.inner.name.as_ref()
}

/// Returns the list of imports that this [`Module`] has and must be
/// satisfied.
pub fn imports(&self) -> &[ImportType] {
Expand Down
54 changes: 54 additions & 0 deletions crates/api/tests/name.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
use wasmtime::*;
use wat::parse_str;

#[test]
fn test_module_no_name() -> Result<(), String> {
let store = Store::default();
let binary = parse_str(
r#"
(module
(func (export "run") (nop))
)
"#,
)
.map_err(|e| format!("failed to parse WebAssembly text source: {}", e))?;

let module = HostRef::new(
Module::new(&store, &binary).map_err(|e| format!("failed to compile module: {}", e))?,
);
assert_eq!(module.borrow().name().cloned(), None);

Ok(())
}

#[test]
fn test_module_name() -> Result<(), String> {
let store = Store::default();
let binary = parse_str(
r#"
(module $from_name_section
(func (export "run") (nop))
)
"#,
)
.map_err(|e| format!("failed to parse WebAssembly text source: {}", e))?;

let module = HostRef::new(
Module::new(&store, &binary).map_err(|e| format!("failed to compile module: {}", e))?,
);
assert_eq!(
module.borrow().name().cloned(),
Some("from_name_section".to_string())
);

let module = HostRef::new(
Module::new_with_name(&store, &binary, "override".to_string())
.map_err(|e| format!("failed to compile module: {}", e))?,
);
assert_eq!(
module.borrow().name().cloned(),
Some("override".to_string())
);

Ok(())
}
4 changes: 4 additions & 0 deletions crates/environ/src/module.rs
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,9 @@ pub struct Module {

/// WebAssembly table initializers.
pub table_elements: Vec<TableElements>,

/// Module name.
pub name: Option<String>,
}

impl Module {
Expand All @@ -186,6 +189,7 @@ impl Module {
exports: IndexMap::new(),
start_func: None,
table_elements: Vec::new(),
name: None,
}
}

Expand Down
9 changes: 8 additions & 1 deletion crates/fuzzing/src/oracles.rs
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,14 @@ pub fn compile(wasm: &[u8], compilation_strategy: CompilationStrategy) {
let mut compiler = Compiler::new(isa, compilation_strategy);
let mut resolver = NullResolver {};
let global_exports = Rc::new(RefCell::new(HashMap::new()));
let _ = CompiledModule::new(&mut compiler, wasm, &mut resolver, global_exports, false);
let _ = CompiledModule::new(
&mut compiler,
wasm,
None,
&mut resolver,
global_exports,
false,
);
}

/// Invoke the given API calls.
Expand Down
2 changes: 2 additions & 0 deletions crates/jit/src/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,7 @@ impl Context {
instantiate(
&mut *self.compiler,
&data,
None,
&mut self.namespace,
Rc::clone(&self.global_exports),
debug_info,
Expand Down Expand Up @@ -154,6 +155,7 @@ impl Context {
CompiledModule::new(
&mut *self.compiler,
data,
None,
&mut self.namespace,
Rc::clone(&self.global_exports),
debug_info,
Expand Down
12 changes: 9 additions & 3 deletions crates/jit/src/instantiate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -60,12 +60,13 @@ impl<'data> RawCompiledModule<'data> {
fn new(
compiler: &mut Compiler,
data: &'data [u8],
module_name: Option<String>,
resolver: &mut dyn Resolver,
debug_info: bool,
) -> Result<Self, SetupError> {
let environ = ModuleEnvironment::new(compiler.frontend_config(), compiler.tunables());

let translation = environ
let mut translation = environ
.translate(data)
.map_err(|error| SetupError::Compile(CompileError::Wasm(error)))?;

Expand All @@ -75,6 +76,8 @@ impl<'data> RawCompiledModule<'data> {
None
};

translation.module.name = module_name;

let (allocated_functions, jt_offsets, relocations, dbg_image) = compiler.compile(
&translation.module,
translation.module_translation.as_ref().unwrap(),
Expand Down Expand Up @@ -152,11 +155,13 @@ impl CompiledModule {
pub fn new<'data>(
compiler: &mut Compiler,
data: &'data [u8],
module_name: Option<String>,
resolver: &mut dyn Resolver,
global_exports: Rc<RefCell<HashMap<String, Option<Export>>>>,
debug_info: bool,
) -> Result<Self, SetupError> {
let raw = RawCompiledModule::<'data>::new(compiler, data, resolver, debug_info)?;
let raw =
RawCompiledModule::<'data>::new(compiler, data, module_name, resolver, debug_info)?;

Ok(Self::from_parts(
raw.module,
Expand Down Expand Up @@ -258,11 +263,12 @@ impl OwnedDataInitializer {
pub fn instantiate(
compiler: &mut Compiler,
data: &[u8],
module_name: Option<String>,
resolver: &mut dyn Resolver,
global_exports: Rc<RefCell<HashMap<String, Option<Export>>>>,
debug_info: bool,
) -> Result<InstanceHandle, SetupError> {
let raw = RawCompiledModule::new(compiler, data, resolver, debug_info)?;
let raw = RawCompiledModule::new(compiler, data, module_name, resolver, debug_info)?;

InstanceHandle::new(
Rc::new(raw.module),
Expand Down
9 changes: 8 additions & 1 deletion tests/instantiate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,13 @@ fn test_environ_translate() {
let mut resolver = NullResolver {};
let mut compiler = Compiler::new(isa, CompilationStrategy::Auto);
let global_exports = Rc::new(RefCell::new(HashMap::new()));
let instance = instantiate(&mut compiler, &data, &mut resolver, global_exports, false);
let instance = instantiate(
&mut compiler,
&data,
None,
&mut resolver,
global_exports,
false,
);
assert!(instance.is_ok());
}