Skip to content

Commit 88a8a89

Browse files
authored
Instantiate nested modules for module linking (#2447)
This commit implements the interpretation necessary of the instance section of the module linking proposal. Instantiating a module which itself has nested instantiated instances will now instantiate the nested instances properly. This isn't all that useful without the ability to alias exports off the result, but we can at least observe the side effects of instantiation through the `start` function. cc #2094
1 parent 40ad39f commit 88a8a89

File tree

11 files changed

+430
-102
lines changed

11 files changed

+430
-102
lines changed

build.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ fn main() -> anyhow::Result<()> {
3131
test_directory_module(out, "tests/misc_testsuite/bulk-memory-operations", strategy)?;
3232
test_directory_module(out, "tests/misc_testsuite/reference-types", strategy)?;
3333
test_directory_module(out, "tests/misc_testsuite/multi-memory", strategy)?;
34+
test_directory_module(out, "tests/misc_testsuite/module-linking", strategy)?;
3435
Ok(())
3536
})?;
3637

cranelift/wasm/src/environ/spec.rs

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,8 @@
88
99
use crate::state::FuncTranslationState;
1010
use crate::translation_utils::{
11-
DataIndex, ElemIndex, EntityType, Event, EventIndex, FuncIndex, Global, GlobalIndex, Memory,
12-
MemoryIndex, Table, TableIndex, TypeIndex,
11+
DataIndex, ElemIndex, EntityIndex, EntityType, Event, EventIndex, FuncIndex, Global,
12+
GlobalIndex, Memory, MemoryIndex, ModuleIndex, Table, TableIndex, TypeIndex,
1313
};
1414
use core::convert::From;
1515
use core::convert::TryFrom;
@@ -22,6 +22,7 @@ use cranelift_frontend::FunctionBuilder;
2222
use serde::{Deserialize, Serialize};
2323
use std::boxed::Box;
2424
use std::string::ToString;
25+
use std::vec::Vec;
2526
use thiserror::Error;
2627
use wasmparser::ValidatorResources;
2728
use wasmparser::{BinaryReaderError, FuncValidator, FunctionBody, Operator, WasmFeatures};
@@ -969,4 +970,16 @@ pub trait ModuleEnvironment<'data>: TargetEnvironment {
969970
fn module_end(&mut self, index: usize) {
970971
drop(index);
971972
}
973+
974+
/// Indicates that this module will have `amount` instances.
975+
fn reserve_instances(&mut self, amount: u32) {
976+
drop(amount);
977+
}
978+
979+
/// Declares a new instance which this module will instantiate before it's
980+
/// instantiated.
981+
fn declare_instance(&mut self, module: ModuleIndex, args: Vec<EntityIndex>) -> WasmResult<()> {
982+
drop((module, args));
983+
Err(WasmError::Unsupported("wasm instance".to_string()))
984+
}
972985
}

cranelift/wasm/src/module_translator.rs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,9 @@
33
use crate::environ::{ModuleEnvironment, WasmResult};
44
use crate::sections_translator::{
55
parse_data_section, parse_element_section, parse_event_section, parse_export_section,
6-
parse_function_section, parse_global_section, parse_import_section, parse_memory_section,
7-
parse_name_section, parse_start_section, parse_table_section, parse_type_section,
6+
parse_function_section, parse_global_section, parse_import_section, parse_instance_section,
7+
parse_memory_section, parse_name_section, parse_start_section, parse_table_section,
8+
parse_type_section,
89
};
910
use crate::state::ModuleTranslationState;
1011
use cranelift_codegen::timing;
@@ -116,7 +117,7 @@ pub fn translate_module<'data>(
116117
}
117118
Payload::InstanceSection(s) => {
118119
validator.instance_section(&s)?;
119-
unimplemented!("module linking not implemented yet")
120+
parse_instance_section(s, environ)?;
120121
}
121122
Payload::AliasSection(s) => {
122123
validator.alias_section(&s)?;

cranelift/wasm/src/sections_translator.rs

Lines changed: 37 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,9 @@
1010
use crate::environ::{ModuleEnvironment, WasmError, WasmResult};
1111
use crate::state::ModuleTranslationState;
1212
use crate::translation_utils::{
13-
tabletype_to_type, type_to_type, DataIndex, ElemIndex, EntityType, Event, EventIndex,
14-
FuncIndex, Global, GlobalIndex, GlobalInit, Memory, MemoryIndex, Table, TableElementType,
15-
TableIndex, TypeIndex,
13+
tabletype_to_type, type_to_type, DataIndex, ElemIndex, EntityIndex, EntityType, Event,
14+
EventIndex, FuncIndex, Global, GlobalIndex, GlobalInit, InstanceIndex, Memory, MemoryIndex,
15+
ModuleIndex, Table, TableElementType, TableIndex, TypeIndex,
1616
};
1717
use crate::wasm_unsupported;
1818
use core::convert::TryFrom;
@@ -475,3 +475,37 @@ pub fn parse_name_section<'data>(
475475
}
476476
Ok(())
477477
}
478+
479+
/// Parses the Instance section of the wasm module.
480+
pub fn parse_instance_section<'data>(
481+
section: wasmparser::InstanceSectionReader<'data>,
482+
environ: &mut dyn ModuleEnvironment<'data>,
483+
) -> WasmResult<()> {
484+
environ.reserve_types(section.get_count())?;
485+
486+
for instance in section {
487+
let instance = instance?;
488+
let module = ModuleIndex::from_u32(instance.module());
489+
let args = instance
490+
.args()?
491+
.into_iter()
492+
.map(|result| {
493+
let (kind, idx) = result?;
494+
Ok(match kind {
495+
ExternalKind::Function => EntityIndex::Function(FuncIndex::from_u32(idx)),
496+
ExternalKind::Table => EntityIndex::Table(TableIndex::from_u32(idx)),
497+
ExternalKind::Memory => EntityIndex::Memory(MemoryIndex::from_u32(idx)),
498+
ExternalKind::Global => EntityIndex::Global(GlobalIndex::from_u32(idx)),
499+
ExternalKind::Module => EntityIndex::Module(ModuleIndex::from_u32(idx)),
500+
ExternalKind::Instance => EntityIndex::Instance(InstanceIndex::from_u32(idx)),
501+
ExternalKind::Event => unimplemented!(),
502+
503+
// this won't pass validation
504+
ExternalKind::Type => unreachable!(),
505+
})
506+
})
507+
.collect::<WasmResult<Vec<_>>>()?;
508+
environ.declare_instance(module, args)?;
509+
}
510+
Ok(())
511+
}

crates/environ/src/module_environ.rs

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
1-
use crate::module::{MemoryPlan, Module, ModuleType, TableElements, TablePlan};
1+
use crate::module::{Instance, MemoryPlan, Module, ModuleType, TableElements, TablePlan};
22
use crate::tunables::Tunables;
33
use cranelift_codegen::ir;
44
use cranelift_codegen::ir::{AbiParam, ArgumentPurpose};
55
use cranelift_codegen::isa::TargetFrontendConfig;
66
use cranelift_entity::PrimaryMap;
77
use cranelift_wasm::{
88
self, translate_module, DataIndex, DefinedFuncIndex, ElemIndex, EntityIndex, EntityType,
9-
FuncIndex, Global, GlobalIndex, Memory, MemoryIndex, SignatureIndex, Table, TableIndex,
10-
TargetEnvironment, TypeIndex, WasmError, WasmFuncType, WasmResult,
9+
FuncIndex, Global, GlobalIndex, Memory, MemoryIndex, ModuleIndex, SignatureIndex, Table,
10+
TableIndex, TargetEnvironment, TypeIndex, WasmError, WasmFuncType, WasmResult,
1111
};
1212
use serde::{Deserialize, Serialize};
1313
use std::collections::HashMap;
@@ -60,7 +60,7 @@ pub struct ModuleTranslation<'data> {
6060

6161
/// Indexes into the returned list of translations that are submodules of
6262
/// this module.
63-
pub submodules: Vec<usize>,
63+
pub submodules: PrimaryMap<ModuleIndex, usize>,
6464

6565
code_index: u32,
6666
}
@@ -649,6 +649,18 @@ and for re-adding support for interface types you can see this issue:
649649
self.result.submodules.push(self.results.len());
650650
self.results.push(finished);
651651
}
652+
653+
fn reserve_instances(&mut self, amt: u32) {
654+
self.result.module.instances.reserve(amt as usize);
655+
}
656+
657+
fn declare_instance(&mut self, module: ModuleIndex, args: Vec<EntityIndex>) -> WasmResult<()> {
658+
self.result
659+
.module
660+
.instances
661+
.push(Instance::Instantiate { module, args });
662+
Ok(())
663+
}
652664
}
653665

654666
/// Add environment-specific function parameters.

crates/jit/src/instantiate.rs

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ use thiserror::Error;
1717
use wasmtime_debug::create_gdbjit_image;
1818
use wasmtime_environ::entity::PrimaryMap;
1919
use wasmtime_environ::isa::TargetIsa;
20-
use wasmtime_environ::wasm::{DefinedFuncIndex, SignatureIndex};
20+
use wasmtime_environ::wasm::{DefinedFuncIndex, ModuleIndex, SignatureIndex};
2121
use wasmtime_environ::{
2222
CompileError, DataInitializer, DataInitializerLocation, FunctionAddressMap, Module,
2323
ModuleEnvironment, ModuleTranslation, StackMapInformation, TrapInformation,
@@ -71,6 +71,10 @@ pub struct CompilationArtifacts {
7171

7272
/// Debug info presence flags.
7373
debug_info: bool,
74+
75+
/// Where to find this module's submodule code in the top-level list of
76+
/// modules.
77+
submodules: PrimaryMap<ModuleIndex, usize>,
7478
}
7579

7680
impl CompilationArtifacts {
@@ -98,6 +102,7 @@ impl CompilationArtifacts {
98102
let ModuleTranslation {
99103
module,
100104
data_initializers,
105+
submodules,
101106
..
102107
} = translation;
103108

@@ -118,6 +123,7 @@ impl CompilationArtifacts {
118123
obj: obj.into_boxed_slice(),
119124
unwind_info: unwind_info.into_boxed_slice(),
120125
data_initializers,
126+
submodules,
121127
funcs: funcs
122128
.into_iter()
123129
.map(|(_, func)| FunctionInfo {
@@ -336,6 +342,12 @@ impl CompiledModule {
336342
pub fn code(&self) -> &Arc<ModuleCode> {
337343
&self.code
338344
}
345+
346+
/// Returns where the specified submodule lives in this module's
347+
/// array-of-modules (store at the top-level)
348+
pub fn submodule_idx(&self, idx: ModuleIndex) -> usize {
349+
self.artifacts.submodules[idx]
350+
}
339351
}
340352

341353
/// Similar to `DataInitializer`, but owns its own copy of the data rather

crates/wasmtime/src/externals.rs

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -115,15 +115,6 @@ impl Extern {
115115
};
116116
Store::same(my_store, store)
117117
}
118-
119-
pub(crate) fn desc(&self) -> &'static str {
120-
match self {
121-
Extern::Func(_) => "function",
122-
Extern::Table(_) => "table",
123-
Extern::Memory(_) => "memory",
124-
Extern::Global(_) => "global",
125-
}
126-
}
127118
}
128119

129120
impl From<Func> for Extern {

0 commit comments

Comments
 (0)