Merge pull request #2585 from alexcrichton/module-linking-update
Update support for the module linking proposal
This commit is contained in:
@@ -30,7 +30,7 @@ peepmatic-traits = { path = "../peepmatic/crates/traits", optional = true, versi
|
||||
peepmatic-runtime = { path = "../peepmatic/crates/runtime", optional = true, version = "0.69.0" }
|
||||
regalloc = { version = "0.0.31" }
|
||||
souper-ir = { version = "2.1.0", optional = true }
|
||||
wast = { version = "29.0.0", optional = true }
|
||||
wast = { version = "31.0.0", optional = true }
|
||||
# It is a goal of the cranelift-codegen crate to have minimal external dependencies.
|
||||
# Please don't add any unless they are essential to the task of creating binary
|
||||
# machine code. Integration tests that need external dependencies can be
|
||||
|
||||
@@ -15,7 +15,7 @@ peepmatic-macro = { version = "0.69.0", path = "crates/macro" }
|
||||
peepmatic-runtime = { version = "0.69.0", path = "crates/runtime", features = ["construct"] }
|
||||
peepmatic-traits = { version = "0.69.0", path = "crates/traits" }
|
||||
serde = { version = "1.0.105", features = ["derive"] }
|
||||
wast = "29.0.0"
|
||||
wast = "31.0.0"
|
||||
z3 = { version = "0.7.1", features = ["static-link-z3"] }
|
||||
|
||||
[dev-dependencies]
|
||||
|
||||
@@ -21,4 +21,4 @@ peepmatic-test-operator = { path = "../test-operator" }
|
||||
peepmatic-traits = { path = "../traits" }
|
||||
rand = { version = "0.7.3", features = ["small_rng"] }
|
||||
serde = "1.0.106"
|
||||
wast = "29.0.0"
|
||||
wast = "31.0.0"
|
||||
|
||||
@@ -16,7 +16,7 @@ peepmatic-automata = { version = "0.69.0", path = "../automata", features = ["se
|
||||
peepmatic-traits = { version = "0.69.0", path = "../traits" }
|
||||
serde = { version = "1.0.105", features = ["derive"] }
|
||||
thiserror = "1.0.15"
|
||||
wast = { version = "29.0.0", optional = true }
|
||||
wast = { version = "31.0.0", optional = true }
|
||||
|
||||
[dev-dependencies]
|
||||
peepmatic-test-operator = { version = "0.69.0", path = "../test-operator" }
|
||||
|
||||
@@ -16,4 +16,4 @@ log = "0.4.8"
|
||||
[dev-dependencies]
|
||||
peepmatic = { path = "../..", version = "0.69.0" }
|
||||
peepmatic-test-operator = { version = "0.69.0", path = "../test-operator" }
|
||||
wast = "29.0.0"
|
||||
wast = "31.0.0"
|
||||
|
||||
@@ -11,4 +11,4 @@ edition = "2018"
|
||||
[dependencies]
|
||||
peepmatic-traits = { version = "0.69.0", path = "../traits" }
|
||||
serde = { version = "1.0.105", features = ["derive"] }
|
||||
wast = "29.0.0"
|
||||
wast = "31.0.0"
|
||||
|
||||
@@ -12,7 +12,7 @@ keywords = ["webassembly", "wasm"]
|
||||
edition = "2018"
|
||||
|
||||
[dependencies]
|
||||
wasmparser = { version = "0.71", default-features = false }
|
||||
wasmparser = { version = "0.72", default-features = false }
|
||||
cranelift-codegen = { path = "../codegen", version = "0.69.0", default-features = false }
|
||||
cranelift-entity = { path = "../entity", version = "0.69.0" }
|
||||
cranelift-frontend = { path = "../frontend", version = "0.69.0", default-features = false }
|
||||
|
||||
@@ -205,25 +205,34 @@ pub enum ReturnMode {
|
||||
|
||||
/// An entry in the alias section of a wasm module (from the module linking
|
||||
/// proposal)
|
||||
pub enum Alias {
|
||||
/// A parent's module is being aliased into our own index space.
|
||||
///
|
||||
/// Note that the index here is in the parent's index space, not our own.
|
||||
ParentModule(ModuleIndex),
|
||||
pub enum Alias<'a> {
|
||||
/// An outer module's module is being aliased into our own index space.
|
||||
OuterModule {
|
||||
/// The number of modules above us that we're referencing.
|
||||
relative_depth: u32,
|
||||
/// The module index in the outer module's index space we're referencing.
|
||||
index: ModuleIndex,
|
||||
},
|
||||
|
||||
/// A parent's type is being aliased into our own index space
|
||||
/// An outer module's type is being aliased into our own index space
|
||||
///
|
||||
/// Note that the index here is in the parent's index space, not our own.
|
||||
ParentType(TypeIndex),
|
||||
/// Note that the index here is in the outer module's index space, not our
|
||||
/// own.
|
||||
OuterType {
|
||||
/// The number of modules above us that we're referencing.
|
||||
relative_depth: u32,
|
||||
/// The type index in the outer module's index space we're referencing.
|
||||
index: TypeIndex,
|
||||
},
|
||||
|
||||
/// A previously created instance is having one of its exports aliased into
|
||||
/// our index space.
|
||||
Child {
|
||||
InstanceExport {
|
||||
/// The index we're aliasing.
|
||||
instance: InstanceIndex,
|
||||
/// The nth export that we're inserting into our own index space
|
||||
/// locally.
|
||||
export: usize,
|
||||
export: &'a str,
|
||||
},
|
||||
}
|
||||
|
||||
@@ -1014,30 +1023,15 @@ pub trait ModuleEnvironment<'data>: TargetEnvironment {
|
||||
drop(amount);
|
||||
}
|
||||
|
||||
/// Declares that a module will come later with the type signature provided.
|
||||
fn declare_module(&mut self, ty: TypeIndex) -> WasmResult<()> {
|
||||
drop(ty);
|
||||
Err(WasmError::Unsupported("module linking".to_string()))
|
||||
}
|
||||
|
||||
/// Called at the beginning of translating a module.
|
||||
///
|
||||
/// The `index` argument is a monotonically increasing index which
|
||||
/// corresponds to the nth module that's being translated. This is not the
|
||||
/// 32-bit index in the current module's index space. For example the first
|
||||
/// call to `module_start` will have index 0.
|
||||
///
|
||||
/// Note that for nested modules this may be called multiple times.
|
||||
fn module_start(&mut self, index: usize) {
|
||||
drop(index);
|
||||
}
|
||||
fn module_start(&mut self) {}
|
||||
|
||||
/// Called at the end of translating a module.
|
||||
///
|
||||
/// Note that for nested modules this may be called multiple times.
|
||||
fn module_end(&mut self, index: usize) {
|
||||
drop(index);
|
||||
}
|
||||
fn module_end(&mut self) {}
|
||||
|
||||
/// Indicates that this module will have `amount` instances.
|
||||
fn reserve_instances(&mut self, amount: u32) {
|
||||
@@ -1046,7 +1040,11 @@ pub trait ModuleEnvironment<'data>: TargetEnvironment {
|
||||
|
||||
/// Declares a new instance which this module will instantiate before it's
|
||||
/// instantiated.
|
||||
fn declare_instance(&mut self, module: ModuleIndex, args: Vec<EntityIndex>) -> WasmResult<()> {
|
||||
fn declare_instance(
|
||||
&mut self,
|
||||
module: ModuleIndex,
|
||||
args: Vec<(&'data str, EntityIndex)>,
|
||||
) -> WasmResult<()> {
|
||||
drop((module, args));
|
||||
Err(WasmError::Unsupported("wasm instance".to_string()))
|
||||
}
|
||||
@@ -1056,7 +1054,7 @@ pub trait ModuleEnvironment<'data>: TargetEnvironment {
|
||||
/// The alias comes from the `instance` specified (or the parent if `None`
|
||||
/// is supplied) and the index is either in the module's own index spaces
|
||||
/// for the parent or an index into the exports for nested instances.
|
||||
fn declare_alias(&mut self, alias: Alias) -> WasmResult<()> {
|
||||
fn declare_alias(&mut self, alias: Alias<'data>) -> WasmResult<()> {
|
||||
drop(alias);
|
||||
Err(WasmError::Unsupported("wasm alias".to_string()))
|
||||
}
|
||||
|
||||
@@ -4,8 +4,8 @@ use crate::environ::{ModuleEnvironment, WasmResult};
|
||||
use crate::sections_translator::{
|
||||
parse_alias_section, parse_data_section, parse_element_section, parse_event_section,
|
||||
parse_export_section, parse_function_section, parse_global_section, parse_import_section,
|
||||
parse_instance_section, parse_memory_section, parse_module_section, parse_name_section,
|
||||
parse_start_section, parse_table_section, parse_type_section,
|
||||
parse_instance_section, parse_memory_section, parse_name_section, parse_start_section,
|
||||
parse_table_section, parse_type_section,
|
||||
};
|
||||
use crate::state::ModuleTranslationState;
|
||||
use cranelift_codegen::timing;
|
||||
@@ -22,23 +22,16 @@ pub fn translate_module<'data>(
|
||||
let mut module_translation_state = ModuleTranslationState::new();
|
||||
let mut validator = Validator::new();
|
||||
validator.wasm_features(environ.wasm_features());
|
||||
let mut stack = Vec::new();
|
||||
let mut modules = 1;
|
||||
let mut cur_module = 0;
|
||||
|
||||
for payload in Parser::new(0).parse_all(data) {
|
||||
match payload? {
|
||||
Payload::Version { num, range } => {
|
||||
validator.version(num, &range)?;
|
||||
environ.module_start(cur_module);
|
||||
environ.module_start();
|
||||
}
|
||||
Payload::End => {
|
||||
validator.end()?;
|
||||
environ.module_end(cur_module);
|
||||
if let Some((other, other_index)) = stack.pop() {
|
||||
validator = other;
|
||||
cur_module = other_index;
|
||||
}
|
||||
environ.module_end();
|
||||
}
|
||||
|
||||
Payload::TypeSection(types) => {
|
||||
@@ -111,10 +104,6 @@ pub fn translate_module<'data>(
|
||||
environ.reserve_passive_data(count)?;
|
||||
}
|
||||
|
||||
Payload::ModuleSection(s) => {
|
||||
validator.module_section(&s)?;
|
||||
parse_module_section(s, environ)?;
|
||||
}
|
||||
Payload::InstanceSection(s) => {
|
||||
validator.instance_section(&s)?;
|
||||
parse_instance_section(s, environ)?;
|
||||
@@ -123,20 +112,17 @@ pub fn translate_module<'data>(
|
||||
validator.alias_section(&s)?;
|
||||
parse_alias_section(s, environ)?;
|
||||
}
|
||||
Payload::ModuleCodeSectionStart {
|
||||
Payload::ModuleSectionStart {
|
||||
count,
|
||||
range,
|
||||
size: _,
|
||||
} => {
|
||||
validator.module_code_section_start(count, &range)?;
|
||||
validator.module_section_start(count, &range)?;
|
||||
environ.reserve_modules(count);
|
||||
}
|
||||
|
||||
Payload::ModuleCodeSectionEntry { .. } => {
|
||||
let subvalidator = validator.module_code_section_entry();
|
||||
stack.push((validator, cur_module));
|
||||
validator = subvalidator;
|
||||
cur_module = modules;
|
||||
modules += 1;
|
||||
Payload::ModuleSectionEntry { .. } => {
|
||||
validator.module_section_entry();
|
||||
}
|
||||
|
||||
Payload::CustomSection {
|
||||
|
||||
@@ -504,19 +504,6 @@ pub fn parse_name_section<'data>(
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Parses the Module section of the wasm module.
|
||||
pub fn parse_module_section<'data>(
|
||||
section: wasmparser::ModuleSectionReader<'data>,
|
||||
environ: &mut dyn ModuleEnvironment<'data>,
|
||||
) -> WasmResult<()> {
|
||||
environ.reserve_modules(section.get_count());
|
||||
|
||||
for module_ty in section {
|
||||
environ.declare_module(TypeIndex::from_u32(module_ty?))?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Parses the Instance section of the wasm module.
|
||||
pub fn parse_instance_section<'data>(
|
||||
section: wasmparser::InstanceSectionReader<'data>,
|
||||
@@ -530,20 +517,23 @@ pub fn parse_instance_section<'data>(
|
||||
let args = instance
|
||||
.args()?
|
||||
.into_iter()
|
||||
.map(|result| {
|
||||
let (kind, idx) = result?;
|
||||
Ok(match kind {
|
||||
ExternalKind::Function => EntityIndex::Function(FuncIndex::from_u32(idx)),
|
||||
ExternalKind::Table => EntityIndex::Table(TableIndex::from_u32(idx)),
|
||||
ExternalKind::Memory => EntityIndex::Memory(MemoryIndex::from_u32(idx)),
|
||||
ExternalKind::Global => EntityIndex::Global(GlobalIndex::from_u32(idx)),
|
||||
ExternalKind::Module => EntityIndex::Module(ModuleIndex::from_u32(idx)),
|
||||
ExternalKind::Instance => EntityIndex::Instance(InstanceIndex::from_u32(idx)),
|
||||
.map(|arg| {
|
||||
let arg = arg?;
|
||||
let index = match arg.kind {
|
||||
ExternalKind::Function => EntityIndex::Function(FuncIndex::from_u32(arg.index)),
|
||||
ExternalKind::Table => EntityIndex::Table(TableIndex::from_u32(arg.index)),
|
||||
ExternalKind::Memory => EntityIndex::Memory(MemoryIndex::from_u32(arg.index)),
|
||||
ExternalKind::Global => EntityIndex::Global(GlobalIndex::from_u32(arg.index)),
|
||||
ExternalKind::Module => EntityIndex::Module(ModuleIndex::from_u32(arg.index)),
|
||||
ExternalKind::Instance => {
|
||||
EntityIndex::Instance(InstanceIndex::from_u32(arg.index))
|
||||
}
|
||||
ExternalKind::Event => unimplemented!(),
|
||||
|
||||
// this won't pass validation
|
||||
ExternalKind::Type => unreachable!(),
|
||||
})
|
||||
};
|
||||
Ok((arg.name, index))
|
||||
})
|
||||
.collect::<WasmResult<Vec<_>>>()?;
|
||||
environ.declare_instance(module, args)?;
|
||||
@@ -557,19 +547,28 @@ pub fn parse_alias_section<'data>(
|
||||
environ: &mut dyn ModuleEnvironment<'data>,
|
||||
) -> WasmResult<()> {
|
||||
for alias in section {
|
||||
let alias = alias?;
|
||||
let alias = match alias.instance {
|
||||
wasmparser::AliasedInstance::Parent => {
|
||||
match alias.kind {
|
||||
ExternalKind::Module => Alias::ParentModule(ModuleIndex::from_u32(alias.index)),
|
||||
ExternalKind::Type => Alias::ParentType(TypeIndex::from_u32(alias.index)),
|
||||
// shouldn't get past validation
|
||||
_ => unreachable!(),
|
||||
}
|
||||
}
|
||||
wasmparser::AliasedInstance::Child(i) => Alias::Child {
|
||||
instance: InstanceIndex::from_u32(i),
|
||||
export: alias.index as usize,
|
||||
let alias = match alias? {
|
||||
wasmparser::Alias::OuterType {
|
||||
relative_depth,
|
||||
index,
|
||||
} => Alias::OuterType {
|
||||
relative_depth,
|
||||
index: TypeIndex::from_u32(index),
|
||||
},
|
||||
wasmparser::Alias::OuterModule {
|
||||
relative_depth,
|
||||
index,
|
||||
} => Alias::OuterModule {
|
||||
relative_depth,
|
||||
index: ModuleIndex::from_u32(index),
|
||||
},
|
||||
wasmparser::Alias::InstanceExport {
|
||||
instance,
|
||||
export,
|
||||
kind: _,
|
||||
} => Alias::InstanceExport {
|
||||
instance: InstanceIndex::from_u32(instance),
|
||||
export,
|
||||
},
|
||||
};
|
||||
environ.declare_alias(alias)?;
|
||||
|
||||
Reference in New Issue
Block a user