Consolidate module construction.

This commit adds `Module::from_parts` as an internal constructor that shared
the implementation between `Module::from_binary` and module deserialization.
This commit is contained in:
Peter Huene
2021-04-16 12:28:27 -07:00
parent dfab471ce5
commit ef2ad6375d
2 changed files with 82 additions and 87 deletions

View File

@@ -320,12 +320,22 @@ impl Module {
} }
}; };
let mut modules = CompiledModule::from_artifacts_list( let modules = CompiledModule::from_artifacts_list(
artifacts, artifacts,
engine.compiler().isa(), engine.compiler().isa(),
&*engine.config().profiler, &*engine.config().profiler,
)?; )?;
Self::from_parts(engine, modules, main_module, Arc::new(types), &[])
}
fn from_parts(
engine: &Engine,
mut modules: Vec<Arc<CompiledModule>>,
main_module: usize,
types: Arc<TypeTables>,
module_upvars: &[serialization::SerializedModuleUpvar],
) -> Result<Self> {
// Validate the module can be used with the current allocator // Validate the module can be used with the current allocator
engine.allocator().validate(modules[main_module].module())?; engine.allocator().validate(modules[main_module].module())?;
@@ -337,17 +347,69 @@ impl Module {
let module = modules.remove(main_module); let module = modules.remove(main_module);
let module_upvars = module_upvars
.iter()
.map(|m| {
mk(
engine,
&modules,
&types,
m.index,
&m.artifact_upvars,
&m.module_upvars,
&signatures,
)
})
.collect::<Result<Vec<_>>>()?;
return Ok(Self {
inner: Arc::new(ModuleInner {
engine: engine.clone(),
types,
module,
artifact_upvars: modules,
module_upvars,
signatures,
}),
});
fn mk(
engine: &Engine,
artifacts: &[Arc<CompiledModule>],
types: &Arc<TypeTables>,
module_index: usize,
artifact_upvars: &[usize],
module_upvars: &[serialization::SerializedModuleUpvar],
signatures: &Arc<SignatureCollection>,
) -> Result<Module> {
Ok(Module { Ok(Module {
inner: Arc::new(ModuleInner { inner: Arc::new(ModuleInner {
engine: engine.clone(), engine: engine.clone(),
module, types: types.clone(),
types: Arc::new(types), module: artifacts[module_index].clone(),
artifact_upvars: modules, artifact_upvars: artifact_upvars
module_upvars: Vec::new(), .iter()
.map(|i| artifacts[*i].clone())
.collect(),
module_upvars: module_upvars
.into_iter()
.map(|m| {
mk(
engine,
artifacts,
types,
m.index,
&m.artifact_upvars,
&m.module_upvars,
signatures, signatures,
)
})
.collect::<Result<Vec<_>>>()?,
signatures: signatures.clone(),
}), }),
}) })
} }
}
/// Validates `binary` input data as a WebAssembly binary given the /// Validates `binary` input data as a WebAssembly binary given the
/// configuration in `engine`. /// configuration in `engine`.

View File

@@ -1,7 +1,6 @@
//! Implements module serialization. //! Implements module serialization.
use super::ModuleInner; use crate::{Engine, Module, OptLevel};
use crate::{signatures::SignatureCollection, Engine, Module, OptLevel};
use anyhow::{anyhow, bail, Context, Result}; use anyhow::{anyhow, bail, Context, Result};
use bincode::Options; use bincode::Options;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
@@ -124,13 +123,13 @@ impl From<settings::OptLevel> for OptLevel {
/// A small helper struct for serialized module upvars. /// A small helper struct for serialized module upvars.
#[derive(Serialize, Deserialize)] #[derive(Serialize, Deserialize)]
struct SerializedModuleUpvar { pub struct SerializedModuleUpvar {
/// The module's index into the compilation artifact. /// The module's index into the compilation artifact.
index: usize, pub index: usize,
/// Indexes into the list of all compilation artifacts for this module. /// Indexes into the list of all compilation artifacts for this module.
artifact_upvars: Vec<usize>, pub artifact_upvars: Vec<usize>,
/// Closed-over module values that are also needed for this module. /// Closed-over module values that are also needed for this module.
module_upvars: Vec<SerializedModuleUpvar>, pub module_upvars: Vec<SerializedModuleUpvar>,
} }
impl SerializedModuleUpvar { impl SerializedModuleUpvar {
@@ -285,8 +284,7 @@ impl<'a> SerializedModule<'a> {
self.check_tunables(compiler)?; self.check_tunables(compiler)?;
self.check_features(compiler)?; self.check_features(compiler)?;
let types = Arc::new(self.types.unwrap_owned()); let modules = CompiledModule::from_artifacts_list(
let mut modules = CompiledModule::from_artifacts_list(
self.artifacts self.artifacts
.into_iter() .into_iter()
.map(|i| i.unwrap_owned()) .map(|i| i.unwrap_owned())
@@ -295,82 +293,17 @@ impl<'a> SerializedModule<'a> {
&*engine.config().profiler, &*engine.config().profiler,
)?; )?;
// Validate the module can be used with the current allocator assert!(!modules.is_empty());
engine
.allocator()
.validate(modules.last().unwrap().module())?;
let signatures = Arc::new(SignatureCollection::new_for_module( let main_module = modules.len() - 1;
engine.signatures(),
&types.wasm_signatures,
modules.iter().flat_map(|m| m.trampolines().iter().cloned()),
));
let module = modules.pop().unwrap(); Module::from_parts(
let module_upvars = self
.module_upvars
.iter()
.map(|m| {
mk(
engine, engine,
&modules, modules,
&types, main_module,
m.index, Arc::new(self.types.unwrap_owned()),
&m.artifact_upvars, &self.module_upvars,
&m.module_upvars,
&signatures,
) )
})
.collect::<Result<Vec<_>>>()?;
return Ok(Module {
inner: Arc::new(ModuleInner {
engine: engine.clone(),
types,
module,
artifact_upvars: modules,
module_upvars,
signatures,
}),
});
fn mk(
engine: &Engine,
artifacts: &[Arc<CompiledModule>],
types: &Arc<TypeTables>,
module_index: usize,
artifact_upvars: &[usize],
module_upvars: &[SerializedModuleUpvar],
signatures: &Arc<SignatureCollection>,
) -> Result<Module> {
Ok(Module {
inner: Arc::new(ModuleInner {
engine: engine.clone(),
types: types.clone(),
module: artifacts[module_index].clone(),
artifact_upvars: artifact_upvars
.iter()
.map(|i| artifacts[*i].clone())
.collect(),
module_upvars: module_upvars
.into_iter()
.map(|m| {
mk(
engine,
artifacts,
types,
m.index,
&m.artifact_upvars,
&m.module_upvars,
signatures,
)
})
.collect::<Result<Vec<_>>>()?,
signatures: signatures.clone(),
}),
})
}
} }
pub fn to_bytes(&self) -> Result<Vec<u8>> { pub fn to_bytes(&self) -> Result<Vec<u8>> {