Update wasm-tools crates (#4246)

This commit updates the wasm-tools family of crates, notably pulling in
the refactorings and updates from bytecodealliance/wasm-tools#621 for
the latest iteration of the component model. This commit additionally
updates all support for the component model for these changes, notably:

* Many bits and pieces of type information was refactored. Many
  `FooTypeIndex` namings are now `TypeFooIndex`. Additionally there is
  now `TypeIndex` as well as `ComponentTypeIndex` for the two type index
  spaces in a component.

* A number of new sections are now processed to handle the core and
  component variants.

* Internal maps were split such as the `funcs` map into
  `component_funcs` and `funcs` (same for `instances`).

* Canonical options are now processed individually instead of one bulk
  `into` definition.

Overall this was not a major update to the internals of handling the
component model in Wasmtime. Instead this was mostly a surface-level
refactoring to make sure that everything lines up with the new binary
format for components.

* All text syntax used in tests was updated to the new syntax.
This commit is contained in:
Alex Crichton
2022-06-09 11:16:07 -05:00
committed by GitHub
parent c15c3061ca
commit 7d7ddceb17
32 changed files with 1201 additions and 1078 deletions

35
Cargo.lock generated
View File

@@ -3214,18 +3214,18 @@ checksum = "d554b7f530dee5964d9a9468d95c1f8b8acae4f282807e7d27d4b03099a46744"
[[package]]
name = "wasm-encoder"
version = "0.12.0"
version = "0.13.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2b47b995b096a689358ca9de6c727b94351b95b390dbbf6b7021c22797d36caa"
checksum = "31f0c17267a5ffd6ae3d897589460e21db1673c84fb7016b909c9691369a75ea"
dependencies = [
"leb128",
]
[[package]]
name = "wasm-mutate"
version = "0.2.3"
version = "0.2.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "afc948447bea01d54509cb4a6ccbeb7e572c42c4c84f778d286b7633a1c49e86"
checksum = "219c79f95ec42118a63e9df1f8b4858c2092875820d10b4d8e5b324759880212"
dependencies = [
"egg",
"log",
@@ -3237,9 +3237,9 @@ dependencies = [
[[package]]
name = "wasm-smith"
version = "0.10.1"
version = "0.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bb87569c81c298836d88405a28a68e8dfcd43b75220a4b4522831a63921b7dbc"
checksum = "4f0ed86e26ccdda3c178e557f8f2874e277c8d4f29c88e3c3320c58db12840ed"
dependencies = [
"arbitrary",
"flagset",
@@ -3284,18 +3284,18 @@ dependencies = [
[[package]]
name = "wasmparser"
version = "0.85.0"
version = "0.86.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "570460c58b21e9150d2df0eaaedbb7816c34bcec009ae0dcc976e40ba81463e7"
checksum = "4bcbfe95447da2aa7ff171857fc8427513eb57c75a729bb190e974dc695e8f5c"
dependencies = [
"indexmap",
]
[[package]]
name = "wasmprinter"
version = "0.2.35"
version = "0.2.36"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ea454634a2a7888d053f7723a26a76024e4f705cf86f7b4d38d5f15b79369c31"
checksum = "aa4cca415278da771add7c9ab7f3391f04b8d98719d2cf28a185d38d5206697e"
dependencies = [
"anyhow",
"wasmparser",
@@ -3434,7 +3434,7 @@ dependencies = [
"wasmtime-wasi-crypto",
"wasmtime-wasi-nn",
"wasmtime-wast",
"wast 41.0.0",
"wast 42.0.0",
"wat",
"winapi",
]
@@ -3648,7 +3648,7 @@ version = "0.39.0"
dependencies = [
"anyhow",
"wasmtime",
"wast 41.0.0",
"wast 42.0.0",
]
[[package]]
@@ -3662,22 +3662,23 @@ dependencies = [
[[package]]
name = "wast"
version = "41.0.0"
version = "42.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f882898b8b817cc4edc16aa3692fdc087b356edc8cc0c2164f5b5181e31c3870"
checksum = "badcb03f976f983ff0daf294da9697be659442f61e6b0942bb37a2b6cbfe9dd4"
dependencies = [
"leb128",
"memchr",
"unicode-width",
"wasm-encoder",
]
[[package]]
name = "wat"
version = "1.0.43"
version = "1.0.44"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "48b3b9b3e39e66c7fd3f8be785e74444d216260f491e93369e317ed6482ff80f"
checksum = "b92f20b742ac527066c8414bc0637352661b68cab07ef42586cefaba71c965cf"
dependencies = [
"wast 41.0.0",
"wast 42.0.0",
]
[[package]]

View File

@@ -52,13 +52,13 @@ test-programs = { path = "crates/test-programs" }
wasmtime-runtime = { path = "crates/runtime" }
tokio = { version = "1.8.0", features = ["rt", "time", "macros", "rt-multi-thread"] }
tracing-subscriber = "0.3.1"
wast = "41.0.0"
wast = "42.0.0"
criterion = "0.3.4"
num_cpus = "1.13.0"
winapi = { version = "0.3.9", features = ['memoryapi'] }
memchr = "2.4"
async-trait = "0.1"
wat = "1.0.42"
wat = "1.0.43"
once_cell = "1.9.0"
rayon = "1.5.0"

View File

@@ -12,7 +12,7 @@ keywords = ["webassembly", "wasm"]
edition = "2021"
[dependencies]
wasmparser = { version = "0.85.0", default-features = false }
wasmparser = { version = "0.86.0", default-features = false }
cranelift-codegen = { path = "../codegen", version = "0.86.0", default-features = false }
cranelift-entity = { path = "../entity", version = "0.86.0" }
cranelift-frontend = { path = "../frontend", version = "0.86.0", default-features = false }

View File

@@ -171,7 +171,7 @@ fn parse_local_decls<FE: FuncEnvironment + ?Sized>(
builder.set_srcloc(cur_srcloc(reader));
let pos = reader.original_position();
let count = reader.read_var_u32()?;
let ty = reader.read_type()?;
let ty = reader.read_val_type()?;
validator.define_locals(pos, count, ty)?;
declare_locals(builder, count, ty, &mut next_local, environ)?;
}
@@ -187,12 +187,12 @@ fn parse_local_decls<FE: FuncEnvironment + ?Sized>(
fn declare_locals<FE: FuncEnvironment + ?Sized>(
builder: &mut FunctionBuilder,
count: u32,
wasm_type: wasmparser::Type,
wasm_type: wasmparser::ValType,
next_local: &mut usize,
environ: &mut FE,
) -> WasmResult<()> {
// All locals are initialized to 0.
use wasmparser::Type::*;
use wasmparser::ValType::*;
let zeroval = match wasm_type {
I32 => builder.ins().iconst(ir::types::I32, 0),
I64 => builder.ins().iconst(ir::types::I64, 0),

View File

@@ -25,7 +25,7 @@ use wasmparser::{
ElementSectionReader, Export, ExportSectionReader, ExternalKind, FunctionSectionReader,
GlobalSectionReader, GlobalType, ImportSectionReader, MemorySectionReader, MemoryType,
NameSectionReader, Naming, Operator, TableSectionReader, TableType, TagSectionReader, TagType,
TypeDef, TypeRef, TypeSectionReader,
Type, TypeRef, TypeSectionReader,
};
fn memory(ty: MemoryType) -> Memory {
@@ -73,7 +73,7 @@ pub fn parse_type_section<'a>(
for entry in types {
match entry? {
TypeDef::Func(wasm_func_ty) => {
Type::Func(wasm_func_ty) => {
environ.declare_type_func(wasm_func_ty.clone().try_into()?)?;
module_translation_state
.wasm_types

View File

@@ -6,7 +6,7 @@ use std::vec::Vec;
/// Map of signatures to a function's parameter and return types.
pub(crate) type WasmTypes =
PrimaryMap<SignatureIndex, (Box<[wasmparser::Type]>, Box<[wasmparser::Type]>)>;
PrimaryMap<SignatureIndex, (Box<[wasmparser::ValType]>, Box<[wasmparser::ValType]>)>;
/// Contains information decoded from the Wasm module that must be referenced
/// during each Wasm function's translation.
@@ -23,13 +23,13 @@ pub struct ModuleTranslationState {
pub(crate) wasm_types: WasmTypes,
}
fn cranelift_to_wasmparser_type(ty: Type) -> WasmResult<wasmparser::Type> {
fn cranelift_to_wasmparser_type(ty: Type) -> WasmResult<wasmparser::ValType> {
Ok(match ty {
types::I32 => wasmparser::Type::I32,
types::I64 => wasmparser::Type::I64,
types::F32 => wasmparser::Type::F32,
types::F64 => wasmparser::Type::F64,
types::R32 | types::R64 => wasmparser::Type::ExternRef,
types::I32 => wasmparser::ValType::I32,
types::I64 => wasmparser::ValType::I64,
types::F32 => wasmparser::ValType::F32,
types::F64 => wasmparser::ValType::F64,
types::R32 | types::R64 => wasmparser::ValType::ExternRef,
_ => {
return Err(WasmError::Unsupported(format!(
"Cannot convert Cranelift type to Wasm signature: {:?}",
@@ -54,11 +54,11 @@ impl ModuleTranslationState {
pub fn from_func_sigs(sigs: &[(&[Type], &[Type])]) -> WasmResult<Self> {
let mut wasm_types = PrimaryMap::with_capacity(sigs.len());
for &(ref args, ref results) in sigs {
let args: Vec<wasmparser::Type> = args
let args: Vec<wasmparser::ValType> = args
.iter()
.map(|&ty| cranelift_to_wasmparser_type(ty))
.collect::<Result<_, _>>()?;
let results: Vec<wasmparser::Type> = results
let results: Vec<wasmparser::ValType> = results
.iter()
.map(|&ty| cranelift_to_wasmparser_type(ty))
.collect::<Result<_, _>>()?;

View File

@@ -21,16 +21,16 @@ pub enum TableElementType {
/// Helper function translating wasmparser types to Cranelift types when possible.
pub fn type_to_type<PE: TargetEnvironment + ?Sized>(
ty: wasmparser::Type,
ty: wasmparser::ValType,
environ: &PE,
) -> WasmResult<ir::Type> {
match ty {
wasmparser::Type::I32 => Ok(ir::types::I32),
wasmparser::Type::I64 => Ok(ir::types::I64),
wasmparser::Type::F32 => Ok(ir::types::F32),
wasmparser::Type::F64 => Ok(ir::types::F64),
wasmparser::Type::V128 => Ok(ir::types::I8X16),
wasmparser::Type::ExternRef | wasmparser::Type::FuncRef => {
wasmparser::ValType::I32 => Ok(ir::types::I32),
wasmparser::ValType::I64 => Ok(ir::types::I64),
wasmparser::ValType::F32 => Ok(ir::types::F32),
wasmparser::ValType::F64 => Ok(ir::types::F64),
wasmparser::ValType::V128 => Ok(ir::types::I8X16),
wasmparser::ValType::ExternRef | wasmparser::ValType::FuncRef => {
Ok(environ.reference_type(ty.try_into()?))
}
}
@@ -39,17 +39,17 @@ pub fn type_to_type<PE: TargetEnvironment + ?Sized>(
/// Helper function translating wasmparser possible table types to Cranelift types when possible,
/// or None for Func tables.
pub fn tabletype_to_type<PE: TargetEnvironment + ?Sized>(
ty: wasmparser::Type,
ty: wasmparser::ValType,
environ: &PE,
) -> WasmResult<Option<ir::Type>> {
match ty {
wasmparser::Type::I32 => Ok(Some(ir::types::I32)),
wasmparser::Type::I64 => Ok(Some(ir::types::I64)),
wasmparser::Type::F32 => Ok(Some(ir::types::F32)),
wasmparser::Type::F64 => Ok(Some(ir::types::F64)),
wasmparser::Type::V128 => Ok(Some(ir::types::I8X16)),
wasmparser::Type::ExternRef => Ok(Some(environ.reference_type(ty.try_into()?))),
wasmparser::Type::FuncRef => Ok(None),
wasmparser::ValType::I32 => Ok(Some(ir::types::I32)),
wasmparser::ValType::I64 => Ok(Some(ir::types::I64)),
wasmparser::ValType::F32 => Ok(Some(ir::types::F32)),
wasmparser::ValType::F64 => Ok(Some(ir::types::F64)),
wasmparser::ValType::V128 => Ok(Some(ir::types::I8X16)),
wasmparser::ValType::ExternRef => Ok(Some(environ.reference_type(ty.try_into()?))),
wasmparser::ValType::FuncRef => Ok(None),
}
}
@@ -58,31 +58,31 @@ pub fn blocktype_params_results<'a, T>(
validator: &'a FuncValidator<T>,
ty: wasmparser::BlockType,
) -> WasmResult<(
impl ExactSizeIterator<Item = wasmparser::Type> + Clone + 'a,
impl ExactSizeIterator<Item = wasmparser::Type> + Clone + 'a,
impl ExactSizeIterator<Item = wasmparser::ValType> + Clone + 'a,
impl ExactSizeIterator<Item = wasmparser::ValType> + Clone + 'a,
)>
where
T: WasmModuleResources,
{
return Ok(match ty {
wasmparser::BlockType::Empty => {
let params: &'static [wasmparser::Type] = &[];
let results: &'static [wasmparser::Type] = &[];
let params: &'static [wasmparser::ValType] = &[];
let results: &'static [wasmparser::ValType] = &[];
(
itertools::Either::Left(params.iter().copied()),
itertools::Either::Left(results.iter().copied()),
)
}
wasmparser::BlockType::Type(ty) => {
let params: &'static [wasmparser::Type] = &[];
let results: &'static [wasmparser::Type] = match ty {
wasmparser::Type::I32 => &[wasmparser::Type::I32],
wasmparser::Type::I64 => &[wasmparser::Type::I64],
wasmparser::Type::F32 => &[wasmparser::Type::F32],
wasmparser::Type::F64 => &[wasmparser::Type::F64],
wasmparser::Type::V128 => &[wasmparser::Type::V128],
wasmparser::Type::ExternRef => &[wasmparser::Type::ExternRef],
wasmparser::Type::FuncRef => &[wasmparser::Type::FuncRef],
let params: &'static [wasmparser::ValType] = &[];
let results: &'static [wasmparser::ValType] = match ty {
wasmparser::ValType::I32 => &[wasmparser::ValType::I32],
wasmparser::ValType::I64 => &[wasmparser::ValType::I64],
wasmparser::ValType::F32 => &[wasmparser::ValType::F32],
wasmparser::ValType::F64 => &[wasmparser::ValType::F64],
wasmparser::ValType::V128 => &[wasmparser::ValType::V128],
wasmparser::ValType::ExternRef => &[wasmparser::ValType::ExternRef],
wasmparser::ValType::FuncRef => &[wasmparser::ValType::FuncRef],
};
(
itertools::Either::Left(params.iter().copied()),
@@ -105,28 +105,28 @@ where
/// Create a `Block` with the given Wasm parameters.
pub fn block_with_params<PE: TargetEnvironment + ?Sized>(
builder: &mut FunctionBuilder,
params: impl IntoIterator<Item = wasmparser::Type>,
params: impl IntoIterator<Item = wasmparser::ValType>,
environ: &PE,
) -> WasmResult<ir::Block> {
let block = builder.create_block();
for ty in params {
match ty {
wasmparser::Type::I32 => {
wasmparser::ValType::I32 => {
builder.append_block_param(block, ir::types::I32);
}
wasmparser::Type::I64 => {
wasmparser::ValType::I64 => {
builder.append_block_param(block, ir::types::I64);
}
wasmparser::Type::F32 => {
wasmparser::ValType::F32 => {
builder.append_block_param(block, ir::types::F32);
}
wasmparser::Type::F64 => {
wasmparser::ValType::F64 => {
builder.append_block_param(block, ir::types::F64);
}
wasmparser::Type::ExternRef | wasmparser::Type::FuncRef => {
wasmparser::ValType::ExternRef | wasmparser::ValType::FuncRef => {
builder.append_block_param(block, environ.reference_type(ty.try_into()?));
}
wasmparser::Type::V128 => {
wasmparser::ValType::V128 => {
builder.append_block_param(block, ir::types::I8X16);
}
}

View File

@@ -19,7 +19,7 @@ cranelift-codegen = { path = "../../cranelift/codegen", version = "0.86.0" }
cranelift-frontend = { path = "../../cranelift/frontend", version = "0.86.0" }
cranelift-entity = { path = "../../cranelift/entity", version = "0.86.0" }
cranelift-native = { path = "../../cranelift/native", version = "0.86.0" }
wasmparser = "0.85.0"
wasmparser = "0.86.0"
target-lexicon = "0.12"
gimli = { version = "0.26.0", default-features = false, features = ['read', 'std'] }
object = { version = "0.28.0", default-features = false, features = ['write'] }

View File

@@ -11,7 +11,7 @@ use gimli::{self, LineEncoding};
use std::collections::{HashMap, HashSet};
use std::path::PathBuf;
use std::sync::atomic::{AtomicUsize, Ordering::SeqCst};
use wasmparser::Type as WasmType;
use wasmparser::ValType as WasmType;
use wasmtime_environ::{
DebugInfoData, DefinedFuncIndex, EntityRef, FuncIndex, FunctionMetadata, WasmFileInfo,
};

View File

@@ -14,7 +14,7 @@ edition = "2021"
anyhow = "1.0"
cranelift-entity = { path = "../../cranelift/entity", version = "0.86.0" }
wasmtime-types = { path = "../types", version = "0.39.0" }
wasmparser = "0.85.0"
wasmparser = "0.86.0"
indexmap = { version = "1.0.2", features = ["serde-1"] }
thiserror = "1.0.4"
serde = { version = "1.0.94", features = ["derive"] }

View File

@@ -291,7 +291,7 @@ pub enum Export {
/// function.
LiftedFunction {
/// The component function type of the function being created.
ty: FuncTypeIndex,
ty: TypeFuncIndex,
/// Which core WebAssembly export is being lifted.
func: CoreExport<FuncIndex>,
/// Any options, if present, associated with this lifting.

View File

@@ -41,14 +41,20 @@ pub struct Translation<'data> {
/// Modules and how they're defined (either closed-over or imported)
modules: PrimaryMap<ModuleIndex, ModuleDef>,
/// Instances and how they're defined, either as instantiations of modules
/// or "synthetically created" as a bag of named items from our other index
/// spaces.
instances: PrimaryMap<InstanceIndex, InstanceDef<'data>>,
/// Instances of components, either direct instantiations or "bundles of
/// exports".
component_instances: PrimaryMap<ComponentInstanceIndex, ComponentInstanceDef<'data>>,
/// Both core wasm and component functions, and how they're defined.
/// Instances of core wasm modules, either direct instantiations or
/// "bundles of exports".
module_instances: PrimaryMap<ModuleInstanceIndex, ModuleInstanceDef<'data>>,
/// The core wasm function index space.
funcs: PrimaryMap<FuncIndex, Func<'data>>,
/// The component function index space.
component_funcs: PrimaryMap<ComponentFuncIndex, ComponentFunc<'data>>,
/// Core wasm globals, always sourced from a previously module instance.
globals: PrimaryMap<GlobalIndex, CoreSource<'data>>,
@@ -100,17 +106,17 @@ enum ModuleDef {
/// nothing is known about it except for its type. The `import_index`
/// provided here indexes into the `Component`'s import list.
Import {
ty: ModuleTypeIndex,
ty: TypeModuleIndex,
import: RuntimeImport,
},
}
/// How instances are defined within a component.
/// Forms of creation of a core wasm module instance.
#[derive(Debug, Clone)]
enum InstanceDef<'data> {
enum ModuleInstanceDef<'data> {
/// A module instance created through the instantiation of a previous
/// module.
Module {
Instantiated {
/// The runtime index associated with this instance.
///
/// Not to be confused with `InstanceIndex` which counts "synthetic"
@@ -123,41 +129,27 @@ enum InstanceDef<'data> {
/// A "synthetic" module created as a bag of exports from other items
/// already defined within this component.
ModuleSynthetic(HashMap<&'data str, EntityIndex>),
Synthetic(HashMap<&'data str, EntityIndex>),
}
/// Forms of creation of a component instance.
#[derive(Debug, Clone)]
enum ComponentInstanceDef<'data> {
/// An instance which was imported from the host.
Import {
/// The type of the imported instance
ty: ComponentInstanceTypeIndex,
ty: TypeComponentInstanceIndex,
/// The description of where this import came from.
import: RuntimeImport,
},
/// Same as `ModuleSynthetic` except for component items.
ComponentSynthetic(HashMap<&'data str, ComponentItem>),
/// Same as `ModuleInstanceDef::Synthetic` except for component items.
Synthetic(HashMap<&'data str, ComponentItem>),
}
/// Description of the function index space and how functions are defined.
#[derive(Clone)]
enum Func<'data> {
// component functions
//
/// A component function that is imported from the host.
Import(RuntimeImport),
/// A component function that is lifted from core wasm function.
Lifted {
/// The resulting type of the lifted function
ty: FuncTypeIndex,
/// Which core wasm function is lifted, currently required to be an
/// instance export as opposed to a lowered import.
func: CoreSource<'data>,
/// The options specified when the function was lifted.
options: CanonicalOptions,
},
// core function
//
/// A core wasm function that's extracted from a core wasm instance.
Core(CoreSource<'data>),
/// A core wasm function created by lowering an imported host function.
@@ -167,6 +159,24 @@ enum Func<'data> {
Lowered(LoweredIndex),
}
/// Description of the function index space and how functions are defined.
#[derive(Clone)]
enum ComponentFunc<'data> {
/// A component function that is imported from the host.
Import(RuntimeImport),
/// A component function that is lifted from core wasm function.
Lifted {
/// The resulting type of the lifted function
ty: TypeFuncIndex,
/// Which core wasm function is lifted, currently required to be an
/// instance export as opposed to a lowered import.
func: CoreSource<'data>,
/// The options specified when the function was lifted.
options: CanonicalOptions,
},
}
/// Source of truth for where a core wasm item comes from.
#[derive(Clone)]
enum CoreSource<'data> {
@@ -278,7 +288,7 @@ impl<'a, 'data> Translator<'a, 'data> {
// Push a new scope for component types so outer aliases know
// that the 0th level is this new component.
self.types.push_component_types_scope();
self.types.push_type_scope();
}
Payload::End(offset) => {
@@ -304,7 +314,7 @@ impl<'a, 'data> Translator<'a, 'data> {
// When leaving a module be sure to pop the types scope to
// ensure that when we go back to the previous module outer
// type alias indices work correctly again.
self.types.pop_component_types_scope();
self.types.pop_type_scope();
match self.parsers.pop() {
Some(p) => self.parser = p,
@@ -323,17 +333,23 @@ impl<'a, 'data> Translator<'a, 'data> {
Payload::ComponentTypeSection(s) => {
self.validator.component_type_section(&s)?;
for ty in s {
let ty = self.types.component_type_def(&ty?)?;
let ty = self.types.intern_component_type(&ty?)?;
self.types.push_component_typedef(ty);
}
}
Payload::CoreTypeSection(s) => {
self.validator.core_type_section(&s)?;
for ty in s {
let ty = self.types.intern_core_type(&ty?)?;
self.types.push_core_typedef(ty);
}
}
Payload::ComponentImportSection(s) => {
self.validator.component_import_section(&s)?;
for import in s {
let import = import?;
let ty = TypeIndex::from_u32(import.ty);
let ty = self.types.component_outer_type(0, ty);
let ty = self.types.component_type_ref(&import.ty);
// Record the `ImportIndex` to be associated with this
// import and create the `RuntimeImport` representing the
// "root" where it has no extra `exports`
@@ -352,11 +368,13 @@ impl<'a, 'data> Translator<'a, 'data> {
}
TypeDef::ComponentInstance(ty) => {
self.result
.instances
.push(InstanceDef::Import { ty, import });
.component_instances
.push(ComponentInstanceDef::Import { ty, import });
}
TypeDef::Func(_ty) => {
self.result.funcs.push(Func::Import(import));
TypeDef::ComponentFunc(_ty) => {
self.result
.component_funcs
.push(ComponentFunc::Import(import));
}
TypeDef::Component(_) => {
unimplemented!("imports of components");
@@ -364,32 +382,36 @@ impl<'a, 'data> Translator<'a, 'data> {
TypeDef::Interface(_) => {
unimplemented!("imports of types");
}
// not possible with a valid component
TypeDef::CoreFunc(_ty) => unreachable!(),
}
}
}
Payload::ComponentFunctionSection(s) => {
self.validator.component_function_section(&s)?;
Payload::ComponentCanonicalSection(s) => {
self.validator.component_canonical_section(&s)?;
for func in s {
let func = match func? {
wasmparser::ComponentFunction::Lift {
match func? {
wasmparser::CanonicalFunction::Lift {
type_index,
core_func_index,
options,
} => {
let ty = ComponentTypeIndex::from_u32(type_index);
let func = FuncIndex::from_u32(core_func_index);
let func = self.lift_function(ty, func, &options);
self.result.component_funcs.push(func);
}
wasmparser::CanonicalFunction::Lower {
func_index,
options,
} => {
let ty = TypeIndex::from_u32(type_index);
let func = FuncIndex::from_u32(func_index);
self.lift_function(ty, func, &options)
let func = ComponentFuncIndex::from_u32(func_index);
let func = self.lower_function(func, &options);
self.result.funcs.push(func);
}
wasmparser::ComponentFunction::Lower {
func_index,
options,
} => {
let func = FuncIndex::from_u32(func_index);
self.lower_function(func, &options)
}
};
self.result.funcs.push(func);
}
}
}
@@ -425,21 +447,33 @@ impl<'a, 'data> Translator<'a, 'data> {
self.validator.instance_section(&s)?;
for instance in s {
let instance = match instance? {
wasmparser::Instance::Module { index, args } => {
self.module_instance(ModuleIndex::from_u32(index), &args)
wasmparser::Instance::Instantiate { module_index, args } => {
self.instantiate_module(ModuleIndex::from_u32(module_index), &args)
}
wasmparser::Instance::ModuleFromExports(exports) => {
self.module_instance_from_exports(&exports)
wasmparser::Instance::FromExports(exports) => {
self.instantiate_module_from_exports(&exports)
}
wasmparser::Instance::Component { index, args } => {
};
self.result.module_instances.push(instance);
}
}
Payload::ComponentInstanceSection(s) => {
self.validator.component_instance_section(&s)?;
for instance in s {
let instance = match instance? {
wasmparser::ComponentInstance::Instantiate {
component_index,
args,
} => {
let index = ComponentIndex::from_u32(component_index);
drop((index, args));
unimplemented!("instantiating a component");
}
wasmparser::Instance::ComponentFromExports(exports) => {
self.component_instance_from_exports(&exports)
wasmparser::ComponentInstance::FromExports(exports) => {
self.instantiate_component_from_exports(&exports)
}
};
self.result.instances.push(instance);
self.result.component_instances.push(instance);
}
}
@@ -458,7 +492,35 @@ impl<'a, 'data> Translator<'a, 'data> {
Payload::AliasSection(s) => {
self.validator.alias_section(&s)?;
for alias in s {
self.alias(&alias?);
match alias? {
wasmparser::Alias::InstanceExport {
kind,
instance_index,
name,
} => {
let instance = ModuleInstanceIndex::from_u32(instance_index);
self.alias_module_instance_export(kind, instance, name);
}
}
}
}
Payload::ComponentAliasSection(s) => {
self.validator.component_alias_section(&s)?;
for alias in s {
match alias? {
wasmparser::ComponentAlias::InstanceExport {
kind,
instance_index,
name,
} => {
let instance = ComponentInstanceIndex::from_u32(instance_index);
self.alias_component_instance_export(kind, instance, name);
}
wasmparser::ComponentAlias::Outer { kind, count, index } => {
self.alias_component_outer(kind, count, index);
}
}
}
}
@@ -482,17 +544,18 @@ impl<'a, 'data> Translator<'a, 'data> {
Ok(Action::KeepGoing)
}
fn module_instance(
fn instantiate_module(
&mut self,
module: ModuleIndex,
args: &[wasmparser::ModuleArg<'data>],
) -> InstanceDef<'data> {
args: &[wasmparser::InstantiationArg<'data>],
) -> ModuleInstanceDef<'data> {
// Map the flat list of `args` to instead a name-to-instance index.
let mut instance_by_name = HashMap::new();
for arg in args {
match arg.kind {
wasmparser::ModuleArgKind::Instance(idx) => {
instance_by_name.insert(arg.name, InstanceIndex::from_u32(idx));
wasmparser::InstantiationArgKind::Instance => {
let idx = ModuleInstanceIndex::from_u32(arg.index);
instance_by_name.insert(arg.name, idx);
}
}
}
@@ -544,7 +607,7 @@ impl<'a, 'data> Translator<'a, 'data> {
let instance = RuntimeInstanceIndex::from_u32(self.result.component.num_runtime_instances);
self.result.component.num_runtime_instances += 1;
InstanceDef::Module { instance, module }
ModuleInstanceDef::Instantiated { instance, module }
}
/// Calculate the `CoreDef`, a definition of a core wasm item, corresponding
@@ -555,28 +618,22 @@ impl<'a, 'data> Translator<'a, 'data> {
/// we know the module), one that must be referred to by name since the
/// module isn't known, or it's a synthesized lowering or adapter of a
/// component function.
fn lookup_core_def(&mut self, instance: InstanceIndex, name: &str) -> CoreDef {
match &self.result.instances[instance] {
InstanceDef::Module { module, instance } => {
fn lookup_core_def(&mut self, instance: ModuleInstanceIndex, name: &str) -> CoreDef {
match &self.result.module_instances[instance] {
ModuleInstanceDef::Instantiated { module, instance } => {
let (src, _ty) = self.lookup_core_source_in_module(*instance, *module, name);
src.to_core_def()
}
InstanceDef::ModuleSynthetic(defs) => match defs[&name] {
ModuleInstanceDef::Synthetic(defs) => match defs[&name] {
EntityIndex::Function(f) => match self.result.funcs[f].clone() {
Func::Core(c) => c.to_core_def(),
Func::Lowered(i) => CoreDef::Lowered(i),
// should not be possible to hit with a valid component
Func::Lifted { .. } | Func::Import { .. } => unreachable!(),
},
EntityIndex::Global(g) => self.result.globals[g].to_core_def(),
EntityIndex::Table(t) => self.result.tables[t].to_core_def(),
EntityIndex::Memory(m) => self.result.memories[m].to_core_def(),
},
// should not be possible to hit with a valid component
InstanceDef::Import { .. } | InstanceDef::ComponentSynthetic(_) => unreachable!(),
}
}
@@ -616,10 +673,10 @@ impl<'a, 'data> Translator<'a, 'data> {
/// Creates a synthetic module from the list of items currently in the
/// module and their given names.
fn module_instance_from_exports(
fn instantiate_module_from_exports(
&mut self,
exports: &[wasmparser::Export<'data>],
) -> InstanceDef<'data> {
) -> ModuleInstanceDef<'data> {
let mut map = HashMap::with_capacity(exports.len());
for export in exports {
let idx = match export.kind {
@@ -645,51 +702,51 @@ impl<'a, 'data> Translator<'a, 'data> {
};
map.insert(export.name, idx);
}
InstanceDef::ModuleSynthetic(map)
ModuleInstanceDef::Synthetic(map)
}
/// Creates a synthetic module from the list of items currently in the
/// module and their given names.
fn component_instance_from_exports(
fn instantiate_component_from_exports(
&mut self,
exports: &[wasmparser::ComponentExport<'data>],
) -> InstanceDef<'data> {
) -> ComponentInstanceDef<'data> {
let mut map = HashMap::with_capacity(exports.len());
for export in exports {
let idx = match &export.kind {
wasmparser::ComponentArgKind::Function(i) => {
let index = FuncIndex::from_u32(*i);
wasmparser::ComponentExternalKind::Func => {
let index = FuncIndex::from_u32(export.index);
ComponentItem::Func(index)
}
wasmparser::ComponentArgKind::Module(i) => {
let index = ModuleIndex::from_u32(*i);
wasmparser::ComponentExternalKind::Module => {
let index = ModuleIndex::from_u32(export.index);
ComponentItem::Module(index)
}
wasmparser::ComponentArgKind::Instance(i) => {
let index = InstanceIndex::from_u32(*i);
ComponentItem::Instance(index)
wasmparser::ComponentExternalKind::Instance => {
let index = ComponentInstanceIndex::from_u32(export.index);
ComponentItem::ComponentInstance(index)
}
wasmparser::ComponentArgKind::Component(i) => {
let index = ComponentIndex::from_u32(*i);
wasmparser::ComponentExternalKind::Component => {
let index = ComponentIndex::from_u32(export.index);
ComponentItem::Component(index)
}
wasmparser::ComponentArgKind::Value(_) => {
wasmparser::ComponentExternalKind::Value => {
unimplemented!("component values");
}
wasmparser::ComponentArgKind::Type(_) => {
wasmparser::ComponentExternalKind::Type => {
unimplemented!("component type export");
}
};
map.insert(export.name, idx);
}
InstanceDef::ComponentSynthetic(map)
ComponentInstanceDef::Synthetic(map)
}
fn export(&mut self, export: &wasmparser::ComponentExport<'data>) {
let name = export.name;
let export = match export.kind {
wasmparser::ComponentExportKind::Module(i) => {
let idx = ModuleIndex::from_u32(i);
wasmparser::ComponentExternalKind::Module => {
let idx = ModuleIndex::from_u32(export.index);
let init = match self.result.modules[idx].clone() {
ModuleDef::Upvar(idx) => Initializer::SaveModuleUpvar(idx),
ModuleDef::Import { import, .. } => {
@@ -702,20 +759,20 @@ impl<'a, 'data> Translator<'a, 'data> {
self.result.component.num_runtime_modules += 1;
Export::Module(runtime_index)
}
wasmparser::ComponentExportKind::Component(i) => {
let idx = ComponentIndex::from_u32(i);
wasmparser::ComponentExternalKind::Component => {
let idx = ComponentIndex::from_u32(export.index);
drop(idx);
unimplemented!("exporting a component");
}
wasmparser::ComponentExportKind::Instance(i) => {
let idx = InstanceIndex::from_u32(i);
wasmparser::ComponentExternalKind::Instance => {
let idx = ComponentInstanceIndex::from_u32(export.index);
drop(idx);
unimplemented!("exporting an instance");
}
wasmparser::ComponentExportKind::Function(i) => {
let idx = FuncIndex::from_u32(i);
match self.result.funcs[idx].clone() {
Func::Lifted { ty, func, options } => Export::LiftedFunction {
wasmparser::ComponentExternalKind::Func => {
let idx = ComponentFuncIndex::from_u32(export.index);
match self.result.component_funcs[idx].clone() {
ComponentFunc::Lifted { ty, func, options } => Export::LiftedFunction {
ty,
func: func.to_core_export(|i| match i {
EntityIndex::Function(i) => i,
@@ -741,17 +798,14 @@ impl<'a, 'data> Translator<'a, 'data> {
// Nevertheless this shouldn't panic, eventually when the
// component model implementation is finished this should do
// something reasonable.
Func::Import { .. } => unimplemented!("exporting an import"),
// should not be possible to hit with a valid module.
Func::Core(_) | Func::Lowered(_) => unreachable!(),
ComponentFunc::Import { .. } => unimplemented!("exporting an import"),
}
}
wasmparser::ComponentExportKind::Value(_) => {
wasmparser::ComponentExternalKind::Value => {
unimplemented!("exporting a value");
}
wasmparser::ComponentExportKind::Type(i) => {
let idx = TypeIndex::from_u32(i);
wasmparser::ComponentExternalKind::Type => {
let idx = TypeIndex::from_u32(export.index);
drop(idx);
unimplemented!("exporting a type");
}
@@ -762,23 +816,132 @@ impl<'a, 'data> Translator<'a, 'data> {
.insert(name.to_string(), export);
}
fn alias(&mut self, alias: &wasmparser::Alias<'data>) {
match alias {
wasmparser::Alias::InstanceExport {
kind,
instance,
name,
} => {
let instance = InstanceIndex::from_u32(*instance);
self.alias_instance_export(*kind, instance, name);
}
wasmparser::Alias::OuterModule { .. } => {
unimplemented!("alias outer module");
}
wasmparser::Alias::OuterComponent { .. } => {
unimplemented!("alias outer component");
fn alias_module_instance_export(
&mut self,
kind: wasmparser::ExternalKind,
instance: ModuleInstanceIndex,
name: &'data str,
) {
match &self.result.module_instances[instance] {
// The `instance` points to an instantiated module, meaning we can
// lookup the `CoreSource` associated with it and use the type
// information to insert it into the appropriate namespace.
ModuleInstanceDef::Instantiated { instance, module } => {
let (src, ty) = self.lookup_core_source_in_module(*instance, *module, name);
match ty {
EntityType::Function(_) => {
assert_eq!(kind, wasmparser::ExternalKind::Func);
self.result.funcs.push(Func::Core(src));
}
EntityType::Global(_) => {
assert_eq!(kind, wasmparser::ExternalKind::Global);
self.result.globals.push(src);
}
EntityType::Memory(_) => {
assert_eq!(kind, wasmparser::ExternalKind::Memory);
self.result.memories.push(src);
}
EntityType::Table(_) => {
assert_eq!(kind, wasmparser::ExternalKind::Table);
self.result.tables.push(src);
}
EntityType::Tag(_) => unimplemented!("wasm exceptions"),
}
}
// ... and like above for synthetic components aliasing exports from
// synthetic modules is also just copying around the identifying
// information.
ModuleInstanceDef::Synthetic(exports) => match exports[&name] {
EntityIndex::Function(i) => {
assert_eq!(kind, wasmparser::ExternalKind::Func);
self.result.funcs.push(self.result.funcs[i].clone());
}
EntityIndex::Global(i) => {
assert_eq!(kind, wasmparser::ExternalKind::Global);
self.result.globals.push(self.result.globals[i].clone());
}
EntityIndex::Table(i) => {
assert_eq!(kind, wasmparser::ExternalKind::Table);
self.result.tables.push(self.result.tables[i].clone());
}
EntityIndex::Memory(i) => {
assert_eq!(kind, wasmparser::ExternalKind::Memory);
self.result.memories.push(self.result.memories[i].clone());
}
},
}
}
fn alias_component_instance_export(
&mut self,
kind: wasmparser::ComponentExternalKind,
instance: ComponentInstanceIndex,
name: &'data str,
) {
match &self.result.component_instances[instance] {
// The `instance` points to an imported component instance, meaning
// that the item we're pushing into our index spaces is effectively
// another form of import. The `name` is appended to the `import`
// found here and then the appropriate namespace of an import is
// recorded as well.
ComponentInstanceDef::Import { import, ty } => {
let import = import.append(name);
match self.types[*ty].exports[name] {
TypeDef::Module(ty) => {
assert_eq!(kind, wasmparser::ComponentExternalKind::Module);
self.result.modules.push(ModuleDef::Import { import, ty });
}
TypeDef::ComponentInstance(ty) => {
assert_eq!(kind, wasmparser::ComponentExternalKind::Instance);
self.result
.component_instances
.push(ComponentInstanceDef::Import { import, ty });
}
TypeDef::ComponentFunc(_ty) => {
assert_eq!(kind, wasmparser::ComponentExternalKind::Func);
self.result
.component_funcs
.push(ComponentFunc::Import(import));
}
TypeDef::Interface(_) => unimplemented!("alias type export"),
TypeDef::Component(_) => unimplemented!("alias component export"),
// not possible with valid components
TypeDef::CoreFunc(_ty) => unreachable!(),
}
}
// For synthetic component/module instances we can just copy the
// definition of the original item into a new slot as well to record
// that the index describes the same item.
ComponentInstanceDef::Synthetic(exports) => match exports[&name] {
ComponentItem::Func(i) => {
assert_eq!(kind, wasmparser::ComponentExternalKind::Func);
self.result.funcs.push(self.result.funcs[i].clone());
}
ComponentItem::Module(i) => {
assert_eq!(kind, wasmparser::ComponentExternalKind::Module);
self.result.modules.push(self.result.modules[i].clone());
}
ComponentItem::ComponentInstance(i) => {
assert_eq!(kind, wasmparser::ComponentExternalKind::Instance);
self.result
.component_instances
.push(self.result.component_instances[i].clone());
}
ComponentItem::Component(_) => unimplemented!("aliasing a component export"),
},
}
}
fn alias_component_outer(
&mut self,
kind: wasmparser::ComponentOuterAliasKind,
count: u32,
index: u32,
) {
match kind {
// When aliasing a type the `ComponentTypesBuilder` is used to
// resolve the outer `count` plus the index, and then once it's
// resolved we push the type information into our local index
@@ -787,125 +950,34 @@ impl<'a, 'data> Translator<'a, 'data> {
// Note that this is just copying indices around as all type
// information is basically a pointer back into the `TypesBuilder`
// structure (and the eventual `TypeTables` that it produces).
wasmparser::Alias::OuterType { count, index } => {
let index = TypeIndex::from_u32(*index);
let ty = self.types.component_outer_type(*count, index);
wasmparser::ComponentOuterAliasKind::CoreType => {
let index = TypeIndex::from_u32(index);
let ty = self.types.core_outer_type(count, index);
self.types.push_core_typedef(ty);
}
wasmparser::ComponentOuterAliasKind::Type => {
let index = ComponentTypeIndex::from_u32(index);
let ty = self.types.component_outer_type(count, index);
self.types.push_component_typedef(ty);
}
}
}
fn alias_instance_export(
&mut self,
kind: wasmparser::AliasKind,
instance: InstanceIndex,
name: &'data str,
) {
match &self.result.instances[instance] {
// The `instance` points to an imported component instance, meaning
// that the item we're pushing into our index spaces is effectively
// another form of import. The `name` is appended to the `import`
// found here and then the appropriate namespace of an import is
// recorded as well.
InstanceDef::Import { import, ty } => {
let import = import.append(name);
match self.types[*ty].exports[name] {
TypeDef::Module(ty) => {
assert_eq!(kind, wasmparser::AliasKind::Module);
self.result.modules.push(ModuleDef::Import { import, ty });
}
TypeDef::ComponentInstance(ty) => {
assert_eq!(kind, wasmparser::AliasKind::Instance);
self.result
.instances
.push(InstanceDef::Import { import, ty });
}
TypeDef::Func(_ty) => {
assert_eq!(kind, wasmparser::AliasKind::ComponentFunc);
self.result.funcs.push(Func::Import(import));
}
TypeDef::Interface(_) => unimplemented!("alias type export"),
TypeDef::Component(_) => unimplemented!("alias component export"),
}
wasmparser::ComponentOuterAliasKind::CoreModule => {
unimplemented!("outer alias to module");
}
// The `instance` points to an instantiated module, meaning we can
// lookup the `CoreSource` associated with it and use the type
// information to insert it into the appropriate namespace.
InstanceDef::Module { instance, module } => {
let (src, ty) = self.lookup_core_source_in_module(*instance, *module, name);
match ty {
EntityType::Function(_) => {
assert_eq!(kind, wasmparser::AliasKind::Func);
self.result.funcs.push(Func::Core(src));
}
EntityType::Global(_) => {
assert_eq!(kind, wasmparser::AliasKind::Global);
self.result.globals.push(src);
}
EntityType::Memory(_) => {
assert_eq!(kind, wasmparser::AliasKind::Memory);
self.result.memories.push(src);
}
EntityType::Table(_) => {
assert_eq!(kind, wasmparser::AliasKind::Table);
self.result.tables.push(src);
}
EntityType::Tag(_) => unimplemented!("wasm exceptions"),
}
wasmparser::ComponentOuterAliasKind::Component => {
unimplemented!("outer alias to component");
}
// For synthetic component/module instances we can just copy the
// definition of the original item into a new slot as well to record
// that the index describes the same item.
InstanceDef::ComponentSynthetic(exports) => match exports[&name] {
ComponentItem::Func(i) => {
assert_eq!(kind, wasmparser::AliasKind::ComponentFunc);
self.result.funcs.push(self.result.funcs[i].clone());
}
ComponentItem::Module(i) => {
assert_eq!(kind, wasmparser::AliasKind::Module);
self.result.modules.push(self.result.modules[i].clone());
}
ComponentItem::Instance(i) => {
assert_eq!(kind, wasmparser::AliasKind::Instance);
self.result.instances.push(self.result.instances[i].clone());
}
ComponentItem::Component(_) => unimplemented!("aliasing a component export"),
},
// ... and like above for synthetic components aliasing exports from
// synthetic modules is also just copying around the identifying
// information.
InstanceDef::ModuleSynthetic(exports) => match exports[&name] {
EntityIndex::Function(i) => {
assert_eq!(kind, wasmparser::AliasKind::Func);
self.result.funcs.push(self.result.funcs[i].clone());
}
EntityIndex::Global(i) => {
assert_eq!(kind, wasmparser::AliasKind::Global);
self.result.globals.push(self.result.globals[i].clone());
}
EntityIndex::Table(i) => {
assert_eq!(kind, wasmparser::AliasKind::Table);
self.result.tables.push(self.result.tables[i].clone());
}
EntityIndex::Memory(i) => {
assert_eq!(kind, wasmparser::AliasKind::Memory);
self.result.memories.push(self.result.memories[i].clone());
}
},
}
}
fn lift_function(
&mut self,
ty: TypeIndex,
ty: ComponentTypeIndex,
func: FuncIndex,
options: &[wasmparser::CanonicalOption],
) -> Func<'data> {
) -> ComponentFunc<'data> {
let ty = match self.types.component_outer_type(0, ty) {
TypeDef::Func(ty) => ty,
TypeDef::ComponentFunc(ty) => ty,
// should not be possible after validation
_ => unreachable!(),
};
@@ -919,22 +991,19 @@ impl<'a, 'data> Translator<'a, 'data> {
// memory into core wasm (since nothing is around to call
// deallocation/free functions).
Func::Lowered(_) => unimplemented!("lifting a lowered function"),
// should not be possible after validation
Func::Lifted { .. } | Func::Import { .. } => unreachable!(),
};
let options = self.canonical_options(options);
Func::Lifted { ty, func, options }
ComponentFunc::Lifted { ty, func, options }
}
fn lower_function(
&mut self,
func: FuncIndex,
func: ComponentFuncIndex,
options: &[wasmparser::CanonicalOption],
) -> Func<'data> {
let options = self.canonical_options(options);
match self.result.funcs[func].clone() {
Func::Import(import) => {
match self.result.component_funcs[func].clone() {
ComponentFunc::Import(import) => {
let import = self.runtime_import_index(import);
let index = LoweredIndex::from_u32(self.result.component.num_lowerings);
self.result.component.num_lowerings += 1;
@@ -961,10 +1030,7 @@ impl<'a, 'data> Translator<'a, 'data> {
// function that lifts the arguments and then afterwards
// unconditionally traps. That would mean that this validates the
// arguments within the context of `options` and then traps.
Func::Lifted { .. } => unimplemented!("lower a lifted function"),
// should not be possible after validation
Func::Core(_) | Func::Lowered(_) => unreachable!(),
ComponentFunc::Lifted { .. } => unimplemented!("lower a lifted function"),
}
}
@@ -981,24 +1047,24 @@ impl<'a, 'data> Translator<'a, 'data> {
wasmparser::CanonicalOption::CompactUTF16 => {
ret.string_encoding = StringEncoding::CompactUtf16;
}
wasmparser::CanonicalOption::Into(instance) => {
let instance = InstanceIndex::from_u32(*instance);
// Note that the `unreachable!()` should not happen for
// components which have passed validation.
let memory =
self.lookup_core_def(instance, "memory")
.unwrap_export(|i| match i {
EntityIndex::Memory(i) => i,
_ => unreachable!(),
});
wasmparser::CanonicalOption::Memory(idx) => {
let idx = MemoryIndex::from_u32(*idx);
let memory = self.result.memories[idx].to_core_export(|i| match i {
EntityIndex::Memory(i) => i,
_ => unreachable!(),
});
let memory = self.runtime_memory(memory);
ret.memory = Some(memory);
let realloc = self.lookup_core_def(instance, "canonical_abi_realloc");
}
wasmparser::CanonicalOption::Realloc(idx) => {
let idx = FuncIndex::from_u32(*idx);
let realloc = self.result.funcs[idx].to_core_def();
let realloc = self.runtime_realloc(realloc);
ret.realloc = Some(realloc);
}
wasmparser::CanonicalOption::PostReturn(_) => {
unimplemented!("post-return");
}
}
}
return ret;
@@ -1065,22 +1131,11 @@ impl CoreSource<'_> {
}
}
impl CoreDef {
fn unwrap_export<T>(self, get_index: impl FnOnce(EntityIndex) -> T) -> CoreExport<T> {
let export = match self {
CoreDef::Export(export) => export,
CoreDef::Lowered(_) => unreachable!(),
};
let instance = export.instance;
match export.item {
ExportItem::Index(idx) => CoreExport {
instance,
item: ExportItem::Index(get_index(idx)),
},
ExportItem::Name(name) => CoreExport {
instance,
item: ExportItem::Name(name),
},
impl Func<'_> {
fn to_core_def(&self) -> CoreDef {
match self {
Func::Core(src) => src.to_core_def(),
Func::Lowered(idx) => CoreDef::Lowered(*idx),
}
}
}

View File

@@ -8,6 +8,9 @@ use serde::{Deserialize, Serialize};
use std::collections::HashMap;
use std::hash::Hash;
use std::ops::Index;
use wasmparser::{
ComponentAlias, ComponentOuterAliasKind, ComponentTypeDeclaration, InstanceTypeDeclaration,
};
macro_rules! indices {
($(
@@ -31,14 +34,23 @@ indices! {
// compile phase to when we're actually working with the component at
// runtime.
/// Index within a component's component type index space.
pub struct ComponentTypeIndex(u32);
/// Index within a component's module index space.
pub struct ModuleIndex(u32);
/// Index within a component's component index space.
pub struct ComponentIndex(u32);
/// Index within a component's instance index space.
pub struct InstanceIndex(u32);
/// Index within a component's module instance index space.
pub struct ModuleInstanceIndex(u32);
/// Index within a component's component instance index space.
pub struct ComponentInstanceIndex(u32);
/// Index within a component's component function index space.
pub struct ComponentFuncIndex(u32);
// ========================================================================
// These indices are used to lookup type information within a `TypeTables`
@@ -47,39 +59,39 @@ indices! {
/// Index pointing to a component's type (exports/imports with
/// component-model types)
pub struct ComponentTypeIndex(u32);
pub struct TypeComponentIndex(u32);
/// Index pointing to a component instance's type (exports with
/// component-model types, no imports)
pub struct ComponentInstanceTypeIndex(u32);
pub struct TypeComponentInstanceIndex(u32);
/// Index pointing to a core wasm module's type (exports/imports with
/// core wasm types)
pub struct ModuleTypeIndex(u32);
pub struct TypeModuleIndex(u32);
/// Index pointing to a component model function type with arguments/result
/// as interface types.
pub struct FuncTypeIndex(u32);
pub struct TypeFuncIndex(u32);
/// Index pointing to an interface type, used for recursive types such as
/// `List<T>`.
pub struct InterfaceTypeIndex(u32);
pub struct TypeInterfaceIndex(u32);
/// Index pointing to a record type in the component model (aka a struct).
pub struct RecordTypeIndex(u32);
pub struct TypeRecordIndex(u32);
/// Index pointing to a variant type in the component model (aka an enum).
pub struct VariantTypeIndex(u32);
pub struct TypeVariantIndex(u32);
/// Index pointing to a tuple type in the component model.
pub struct TupleTypeIndex(u32);
pub struct TypeTupleIndex(u32);
/// Index pointing to a flags type in the component model.
pub struct FlagsTypeIndex(u32);
pub struct TypeFlagsIndex(u32);
/// Index pointing to an enum type in the component model.
pub struct EnumTypeIndex(u32);
pub struct TypeEnumIndex(u32);
/// Index pointing to a union type in the component model.
pub struct UnionTypeIndex(u32);
pub struct TypeUnionIndex(u32);
/// Index pointing to an expected type in the component model (aka a
/// `Result<T, E>`)
pub struct ExpectedTypeIndex(u32);
pub struct TypeExpectedIndex(u32);
// ========================================================================
// These indices are actually used at runtime when managing a component at
@@ -147,8 +159,8 @@ pub use crate::{FuncIndex, GlobalIndex, MemoryIndex, TableIndex, TypeIndex};
pub enum ComponentItem {
Func(FuncIndex),
Module(ModuleIndex),
Instance(InstanceIndex),
Component(ComponentIndex),
ComponentInstance(ComponentInstanceIndex),
}
/// Runtime information about the type information contained within a component.
@@ -158,18 +170,18 @@ pub enum ComponentItem {
/// will have a pointer to this value as well.
#[derive(Default, Serialize, Deserialize)]
pub struct ComponentTypes {
modules: PrimaryMap<ModuleTypeIndex, ModuleType>,
components: PrimaryMap<ComponentTypeIndex, ComponentType>,
component_instances: PrimaryMap<ComponentInstanceTypeIndex, ComponentInstanceType>,
functions: PrimaryMap<FuncTypeIndex, FuncType>,
interface_types: PrimaryMap<InterfaceTypeIndex, InterfaceType>,
records: PrimaryMap<RecordTypeIndex, RecordType>,
variants: PrimaryMap<VariantTypeIndex, VariantType>,
tuples: PrimaryMap<TupleTypeIndex, TupleType>,
enums: PrimaryMap<EnumTypeIndex, EnumType>,
flags: PrimaryMap<FlagsTypeIndex, FlagsType>,
unions: PrimaryMap<UnionTypeIndex, UnionType>,
expecteds: PrimaryMap<ExpectedTypeIndex, ExpectedType>,
modules: PrimaryMap<TypeModuleIndex, TypeModule>,
components: PrimaryMap<TypeComponentIndex, TypeComponent>,
component_instances: PrimaryMap<TypeComponentInstanceIndex, TypeComponentInstance>,
functions: PrimaryMap<TypeFuncIndex, TypeFunc>,
interface_types: PrimaryMap<TypeInterfaceIndex, InterfaceType>,
records: PrimaryMap<TypeRecordIndex, TypeRecord>,
variants: PrimaryMap<TypeVariantIndex, TypeVariant>,
tuples: PrimaryMap<TypeTupleIndex, TypeTuple>,
enums: PrimaryMap<TypeEnumIndex, TypeEnum>,
flags: PrimaryMap<TypeFlagsIndex, TypeFlags>,
unions: PrimaryMap<TypeUnionIndex, TypeUnion>,
expecteds: PrimaryMap<TypeExpectedIndex, TypeExpected>,
module_types: ModuleTypes,
}
@@ -193,18 +205,18 @@ macro_rules! impl_index {
}
impl_index! {
impl Index<ModuleTypeIndex> for ComponentTypes { ModuleType => modules }
impl Index<ComponentTypeIndex> for ComponentTypes { ComponentType => components }
impl Index<ComponentInstanceTypeIndex> for ComponentTypes { ComponentInstanceType => component_instances }
impl Index<FuncTypeIndex> for ComponentTypes { FuncType => functions }
impl Index<InterfaceTypeIndex> for ComponentTypes { InterfaceType => interface_types }
impl Index<RecordTypeIndex> for ComponentTypes { RecordType => records }
impl Index<VariantTypeIndex> for ComponentTypes { VariantType => variants }
impl Index<TupleTypeIndex> for ComponentTypes { TupleType => tuples }
impl Index<EnumTypeIndex> for ComponentTypes { EnumType => enums }
impl Index<FlagsTypeIndex> for ComponentTypes { FlagsType => flags }
impl Index<UnionTypeIndex> for ComponentTypes { UnionType => unions }
impl Index<ExpectedTypeIndex> for ComponentTypes { ExpectedType => expecteds }
impl Index<TypeModuleIndex> for ComponentTypes { TypeModule => modules }
impl Index<TypeComponentIndex> for ComponentTypes { TypeComponent => components }
impl Index<TypeComponentInstanceIndex> for ComponentTypes { TypeComponentInstance => component_instances }
impl Index<TypeFuncIndex> for ComponentTypes { TypeFunc => functions }
impl Index<TypeInterfaceIndex> for ComponentTypes { InterfaceType => interface_types }
impl Index<TypeRecordIndex> for ComponentTypes { TypeRecord => records }
impl Index<TypeVariantIndex> for ComponentTypes { TypeVariant => variants }
impl Index<TypeTupleIndex> for ComponentTypes { TypeTuple => tuples }
impl Index<TypeEnumIndex> for ComponentTypes { TypeEnum => enums }
impl Index<TypeFlagsIndex> for ComponentTypes { TypeFlags => flags }
impl Index<TypeUnionIndex> for ComponentTypes { TypeUnion => unions }
impl Index<TypeExpectedIndex> for ComponentTypes { TypeExpected => expecteds }
}
// Additionally forward anything that can index `ModuleTypes` to `ModuleTypes`
@@ -225,21 +237,27 @@ where
/// managing building up core wasm [`ModuleTypes`] as well.
#[derive(Default)]
pub struct ComponentTypesBuilder {
type_scopes: Vec<PrimaryMap<TypeIndex, TypeDef>>,
functions: HashMap<FuncType, FuncTypeIndex>,
interface_types: HashMap<InterfaceType, InterfaceTypeIndex>,
records: HashMap<RecordType, RecordTypeIndex>,
variants: HashMap<VariantType, VariantTypeIndex>,
tuples: HashMap<TupleType, TupleTypeIndex>,
enums: HashMap<EnumType, EnumTypeIndex>,
flags: HashMap<FlagsType, FlagsTypeIndex>,
unions: HashMap<UnionType, UnionTypeIndex>,
expecteds: HashMap<ExpectedType, ExpectedTypeIndex>,
type_scopes: Vec<TypeScope>,
functions: HashMap<TypeFunc, TypeFuncIndex>,
interface_types: HashMap<InterfaceType, TypeInterfaceIndex>,
records: HashMap<TypeRecord, TypeRecordIndex>,
variants: HashMap<TypeVariant, TypeVariantIndex>,
tuples: HashMap<TypeTuple, TypeTupleIndex>,
enums: HashMap<TypeEnum, TypeEnumIndex>,
flags: HashMap<TypeFlags, TypeFlagsIndex>,
unions: HashMap<TypeUnion, TypeUnionIndex>,
expecteds: HashMap<TypeExpected, TypeExpectedIndex>,
component_types: ComponentTypes,
module_types: ModuleTypesBuilder,
}
#[derive(Default)]
struct TypeScope {
core: PrimaryMap<TypeIndex, TypeDef>,
component: PrimaryMap<ComponentTypeIndex, TypeDef>,
}
impl ComponentTypesBuilder {
/// Finishes this list of component types and returns the finished
/// structure.
@@ -261,20 +279,36 @@ impl ComponentTypesBuilder {
///
/// This happens when a component is recursed into or a module/instance
/// type is recursed into.
pub fn push_component_types_scope(&mut self) {
self.type_scopes.push(PrimaryMap::new());
pub fn push_type_scope(&mut self) {
self.type_scopes.push(Default::default());
}
/// Adds a new `TypeDef` definition within the current component types
/// scope.
///
/// Returns the `TypeIndex` associated with the type being pushed..
/// Returns the `ComponentTypeIndex` associated with the type being pushed.
///
/// # Panics
///
/// Requires that `push_component_types_scope` was called previously.
pub fn push_component_typedef(&mut self, ty: TypeDef) -> TypeIndex {
self.type_scopes.last_mut().unwrap().push(ty)
/// Requires that `push_type_scope` was called previously.
pub fn push_component_typedef(&mut self, ty: TypeDef) -> ComponentTypeIndex {
debug_assert!(!matches!(ty, TypeDef::Module(_) | TypeDef::CoreFunc(_)));
self.type_scopes.last_mut().unwrap().component.push(ty)
}
/// Adds a new `TypeDef` definition within the current core types
/// scope.
///
/// Returns the `TypeIndex` associated with the type being pushed. Note that
/// this should only be used with core-wasm-related `TypeDef` instances such
/// as `TypeDef::Module` and `TypeDef::CoreFunc`.
///
/// # Panics
///
/// Requires that `push_type_scope` was called previously.
pub fn push_core_typedef(&mut self, ty: TypeDef) -> TypeIndex {
debug_assert!(matches!(ty, TypeDef::Module(_) | TypeDef::CoreFunc(_)));
self.type_scopes.last_mut().unwrap().core.push(ty)
}
/// Looks up an "outer" type in this builder to handle outer aliases.
@@ -285,52 +319,89 @@ impl ComponentTypesBuilder {
/// # Panics
///
/// Assumes that `count` and `ty` are valid.
pub fn component_outer_type(&self, count: u32, ty: TypeIndex) -> TypeDef {
pub fn component_outer_type(&self, count: u32, ty: ComponentTypeIndex) -> TypeDef {
// Reverse the index and 0 means the "current scope"
let idx = self.type_scopes.len() - (count as usize) - 1;
self.type_scopes[idx][ty]
self.type_scopes[idx].component[ty]
}
/// Pops a scope pushed by `push_component_types_scope`.
pub fn pop_component_types_scope(&mut self) {
/// Same as `component_outer_type` but for core wasm types instead.
pub fn core_outer_type(&self, count: u32, ty: TypeIndex) -> TypeDef {
// Reverse the index and 0 means the "current scope"
let idx = self.type_scopes.len() - (count as usize) - 1;
self.type_scopes[idx].core[ty]
}
/// Pops a scope pushed by `push_type_scope`.
pub fn pop_type_scope(&mut self) {
self.type_scopes.pop().unwrap();
}
/// Translates a wasmparser `ComponentTypeDef` into a Wasmtime `TypeDef`,
/// Translates a wasmparser `TypeComponent` into a Wasmtime `TypeDef`,
/// interning types along the way.
pub fn component_type_def(&mut self, ty: &wasmparser::ComponentTypeDef<'_>) -> Result<TypeDef> {
pub fn intern_component_type(&mut self, ty: &wasmparser::ComponentType<'_>) -> Result<TypeDef> {
Ok(match ty {
wasmparser::ComponentTypeDef::Module(ty) => TypeDef::Module(self.module_type(ty)?),
wasmparser::ComponentTypeDef::Component(ty) => {
wasmparser::ComponentType::Defined(ty) => TypeDef::Interface(self.defined_type(ty)),
wasmparser::ComponentType::Func(ty) => TypeDef::ComponentFunc(self.func_type(ty)),
wasmparser::ComponentType::Component(ty) => {
TypeDef::Component(self.component_type(ty)?)
}
wasmparser::ComponentTypeDef::Instance(ty) => {
wasmparser::ComponentType::Instance(ty) => {
TypeDef::ComponentInstance(self.component_instance_type(ty)?)
}
wasmparser::ComponentTypeDef::Function(ty) => TypeDef::Func(self.func_type(ty)),
wasmparser::ComponentTypeDef::Value(_ty) => unimplemented!("value types"),
wasmparser::ComponentTypeDef::Interface(ty) => {
TypeDef::Interface(self.interface_type(ty))
}
})
}
fn module_type(&mut self, ty: &[wasmparser::ModuleType<'_>]) -> Result<ModuleTypeIndex> {
let mut result = ModuleType::default();
/// Translates a wasmparser `CoreType` into a Wasmtime `TypeDef`,
/// interning types along the way.
pub fn intern_core_type(&mut self, ty: &wasmparser::CoreType<'_>) -> Result<TypeDef> {
Ok(match ty {
wasmparser::CoreType::Func(ty) => {
TypeDef::CoreFunc(self.module_types.wasm_func_type(ty.clone().try_into()?))
}
wasmparser::CoreType::Module(ty) => TypeDef::Module(self.module_type(ty)?),
})
}
/// Translates a wasmparser `ComponentTypeRef` into a Wasmtime `TypeDef`.
pub fn component_type_ref(&self, ty: &wasmparser::ComponentTypeRef) -> TypeDef {
match ty {
wasmparser::ComponentTypeRef::Module(ty) => {
self.core_outer_type(0, TypeIndex::from_u32(*ty))
}
wasmparser::ComponentTypeRef::Func(ty)
| wasmparser::ComponentTypeRef::Instance(ty)
| wasmparser::ComponentTypeRef::Component(ty) => {
self.component_outer_type(0, ComponentTypeIndex::from_u32(*ty))
}
wasmparser::ComponentTypeRef::Value(..) => {
unimplemented!("references to value types");
}
wasmparser::ComponentTypeRef::Type(..) => {
unimplemented!("references to types");
}
}
}
fn module_type(
&mut self,
ty: &[wasmparser::ModuleTypeDeclaration<'_>],
) -> Result<TypeModuleIndex> {
let mut result = TypeModule::default();
let mut functypes: PrimaryMap<TypeIndex, SignatureIndex> = PrimaryMap::default();
for item in ty {
match item {
wasmparser::ModuleType::Type(wasmparser::TypeDef::Func(f)) => {
wasmparser::ModuleTypeDeclaration::Type(wasmparser::Type::Func(f)) => {
functypes.push(self.module_types.wasm_func_type(f.clone().try_into()?));
}
wasmparser::ModuleType::Export { name, ty } => {
wasmparser::ModuleTypeDeclaration::Export { name, ty } => {
let prev = result
.exports
.insert(name.to_string(), type_ref(ty, &functypes)?);
assert!(prev.is_none());
}
wasmparser::ModuleType::Import(import) => {
wasmparser::ModuleTypeDeclaration::Import(import) => {
let prev = result.imports.insert(
(import.module.to_string(), import.name.to_string()),
type_ref(&import.ty, &functypes)?,
@@ -362,112 +433,135 @@ impl ComponentTypesBuilder {
fn component_type(
&mut self,
ty: &[wasmparser::ComponentType<'_>],
) -> Result<ComponentTypeIndex> {
let mut result = ComponentType::default();
self.push_component_types_scope();
ty: &[ComponentTypeDeclaration<'_>],
) -> Result<TypeComponentIndex> {
let mut result = TypeComponent::default();
self.push_type_scope();
for item in ty {
match item {
wasmparser::ComponentType::Type(ty) => {
let ty = self.component_type_def(ty)?;
self.push_component_typedef(ty);
ComponentTypeDeclaration::Type(ty) => self.type_declaration_type(ty)?,
ComponentTypeDeclaration::CoreType(ty) => self.type_declaration_core_type(ty)?,
ComponentTypeDeclaration::Alias(alias) => self.type_declaration_alias(alias)?,
ComponentTypeDeclaration::Export { name, ty } => {
let ty = self.component_type_ref(ty);
result.exports.insert(name.to_string(), ty);
}
wasmparser::ComponentType::OuterType { count, index } => {
let ty = self.component_outer_type(*count, TypeIndex::from_u32(*index));
self.push_component_typedef(ty);
}
wasmparser::ComponentType::Export { name, ty } => {
result.exports.insert(
name.to_string(),
self.component_outer_type(0, TypeIndex::from_u32(*ty)),
);
}
wasmparser::ComponentType::Import(import) => {
result.imports.insert(
import.name.to_string(),
self.component_outer_type(0, TypeIndex::from_u32(import.ty)),
);
ComponentTypeDeclaration::Import(import) => {
let ty = self.component_type_ref(&import.ty);
result.imports.insert(import.name.to_string(), ty);
}
}
}
self.pop_component_types_scope();
self.pop_type_scope();
Ok(self.component_types.components.push(result))
}
fn component_instance_type(
&mut self,
ty: &[wasmparser::InstanceType<'_>],
) -> Result<ComponentInstanceTypeIndex> {
let mut result = ComponentInstanceType::default();
self.push_component_types_scope();
ty: &[InstanceTypeDeclaration<'_>],
) -> Result<TypeComponentInstanceIndex> {
let mut result = TypeComponentInstance::default();
self.push_type_scope();
for item in ty {
match item {
wasmparser::InstanceType::Type(ty) => {
let ty = self.component_type_def(ty)?;
self.push_component_typedef(ty);
}
wasmparser::InstanceType::OuterType { count, index } => {
let ty = self.component_outer_type(*count, TypeIndex::from_u32(*index));
self.push_component_typedef(ty);
}
wasmparser::InstanceType::Export { name, ty } => {
result.exports.insert(
name.to_string(),
self.component_outer_type(0, TypeIndex::from_u32(*ty)),
);
InstanceTypeDeclaration::Type(ty) => self.type_declaration_type(ty)?,
InstanceTypeDeclaration::CoreType(ty) => self.type_declaration_core_type(ty)?,
InstanceTypeDeclaration::Alias(alias) => self.type_declaration_alias(alias)?,
InstanceTypeDeclaration::Export { name, ty } => {
let ty = self.component_type_ref(ty);
result.exports.insert(name.to_string(), ty);
}
}
}
self.pop_component_types_scope();
self.pop_type_scope();
Ok(self.component_types.component_instances.push(result))
}
fn func_type(&mut self, ty: &wasmparser::ComponentFuncType<'_>) -> FuncTypeIndex {
let ty = FuncType {
fn type_declaration_type(&mut self, ty: &wasmparser::ComponentType<'_>) -> Result<()> {
let ty = self.intern_component_type(ty)?;
self.push_component_typedef(ty);
Ok(())
}
fn type_declaration_core_type(&mut self, ty: &wasmparser::CoreType<'_>) -> Result<()> {
let ty = self.intern_core_type(ty)?;
self.push_core_typedef(ty);
Ok(())
}
fn type_declaration_alias(&mut self, alias: &wasmparser::ComponentAlias<'_>) -> Result<()> {
match alias {
ComponentAlias::Outer {
kind: ComponentOuterAliasKind::CoreType,
count,
index,
} => {
let ty = self.core_outer_type(*count, TypeIndex::from_u32(*index));
self.push_core_typedef(ty);
}
ComponentAlias::Outer {
kind: ComponentOuterAliasKind::Type,
count,
index,
} => {
let ty = self.component_outer_type(*count, ComponentTypeIndex::from_u32(*index));
self.push_component_typedef(ty);
}
a => unreachable!("invalid alias {a:?}"),
}
Ok(())
}
fn func_type(&mut self, ty: &wasmparser::ComponentFuncType<'_>) -> TypeFuncIndex {
let ty = TypeFunc {
params: ty
.params
.iter()
.map(|(name, ty)| (name.map(|s| s.to_string()), self.interface_type_ref(ty)))
.map(|(name, ty)| (name.map(|s| s.to_string()), self.valtype(ty)))
.collect(),
result: self.interface_type_ref(&ty.result),
result: self.valtype(&ty.result),
};
intern(&mut self.functions, &mut self.component_types.functions, ty)
}
fn interface_type(&mut self, ty: &wasmparser::InterfaceType<'_>) -> InterfaceType {
fn defined_type(&mut self, ty: &wasmparser::ComponentDefinedType<'_>) -> InterfaceType {
match ty {
wasmparser::InterfaceType::Primitive(ty) => ty.into(),
wasmparser::InterfaceType::Record(e) => InterfaceType::Record(self.record_type(e)),
wasmparser::InterfaceType::Variant(e) => InterfaceType::Variant(self.variant_type(e)),
wasmparser::InterfaceType::List(e) => {
let ty = self.interface_type_ref(e);
wasmparser::ComponentDefinedType::Primitive(ty) => ty.into(),
wasmparser::ComponentDefinedType::Record(e) => {
InterfaceType::Record(self.record_type(e))
}
wasmparser::ComponentDefinedType::Variant(e) => {
InterfaceType::Variant(self.variant_type(e))
}
wasmparser::ComponentDefinedType::List(e) => {
let ty = self.valtype(e);
InterfaceType::List(self.intern_interface_type(ty))
}
wasmparser::InterfaceType::Tuple(e) => InterfaceType::Tuple(self.tuple_type(e)),
wasmparser::InterfaceType::Flags(e) => InterfaceType::Flags(self.flags_type(e)),
wasmparser::InterfaceType::Enum(e) => InterfaceType::Enum(self.enum_type(e)),
wasmparser::InterfaceType::Union(e) => InterfaceType::Union(self.union_type(e)),
wasmparser::InterfaceType::Option(e) => {
let ty = self.interface_type_ref(e);
wasmparser::ComponentDefinedType::Tuple(e) => InterfaceType::Tuple(self.tuple_type(e)),
wasmparser::ComponentDefinedType::Flags(e) => InterfaceType::Flags(self.flags_type(e)),
wasmparser::ComponentDefinedType::Enum(e) => InterfaceType::Enum(self.enum_type(e)),
wasmparser::ComponentDefinedType::Union(e) => InterfaceType::Union(self.union_type(e)),
wasmparser::ComponentDefinedType::Option(e) => {
let ty = self.valtype(e);
InterfaceType::Option(self.intern_interface_type(ty))
}
wasmparser::InterfaceType::Expected { ok, error } => {
wasmparser::ComponentDefinedType::Expected { ok, error } => {
InterfaceType::Expected(self.expected_type(ok, error))
}
}
}
fn interface_type_ref(&mut self, ty: &wasmparser::InterfaceTypeRef) -> InterfaceType {
fn valtype(&mut self, ty: &wasmparser::ComponentValType) -> InterfaceType {
match ty {
wasmparser::InterfaceTypeRef::Primitive(p) => p.into(),
wasmparser::InterfaceTypeRef::Type(idx) => {
let idx = TypeIndex::from_u32(*idx);
wasmparser::ComponentValType::Primitive(p) => p.into(),
wasmparser::ComponentValType::Type(idx) => {
let idx = ComponentTypeIndex::from_u32(*idx);
match self.component_outer_type(0, idx) {
TypeDef::Interface(ty) => ty,
// this should not be possible if the module validated
@@ -477,7 +571,7 @@ impl ComponentTypesBuilder {
}
}
fn intern_interface_type(&mut self, ty: InterfaceType) -> InterfaceTypeIndex {
fn intern_interface_type(&mut self, ty: InterfaceType) -> TypeInterfaceIndex {
intern(
&mut self.interface_types,
&mut self.component_types.interface_types,
@@ -485,30 +579,30 @@ impl ComponentTypesBuilder {
)
}
fn record_type(&mut self, record: &[(&str, wasmparser::InterfaceTypeRef)]) -> RecordTypeIndex {
let record = RecordType {
fn record_type(&mut self, record: &[(&str, wasmparser::ComponentValType)]) -> TypeRecordIndex {
let record = TypeRecord {
fields: record
.iter()
.map(|(name, ty)| RecordField {
name: name.to_string(),
ty: self.interface_type_ref(ty),
ty: self.valtype(ty),
})
.collect(),
};
intern(&mut self.records, &mut self.component_types.records, record)
}
fn variant_type(&mut self, cases: &[wasmparser::VariantCase<'_>]) -> VariantTypeIndex {
let variant = VariantType {
fn variant_type(&mut self, cases: &[wasmparser::VariantCase<'_>]) -> TypeVariantIndex {
let variant = TypeVariant {
cases: cases
.iter()
.map(|case| {
// FIXME: need to implement `default_to`, not sure what that
// FIXME: need to implement `refines`, not sure what that
// is at this time.
assert!(case.default_to.is_none());
assert!(case.refines.is_none());
VariantCase {
name: case.name.to_string(),
ty: self.interface_type_ref(&case.ty),
ty: self.valtype(&case.ty),
}
})
.collect(),
@@ -520,42 +614,42 @@ impl ComponentTypesBuilder {
)
}
fn tuple_type(&mut self, types: &[wasmparser::InterfaceTypeRef]) -> TupleTypeIndex {
let tuple = TupleType {
types: types.iter().map(|ty| self.interface_type_ref(ty)).collect(),
fn tuple_type(&mut self, types: &[wasmparser::ComponentValType]) -> TypeTupleIndex {
let tuple = TypeTuple {
types: types.iter().map(|ty| self.valtype(ty)).collect(),
};
intern(&mut self.tuples, &mut self.component_types.tuples, tuple)
}
fn flags_type(&mut self, flags: &[&str]) -> FlagsTypeIndex {
let flags = FlagsType {
fn flags_type(&mut self, flags: &[&str]) -> TypeFlagsIndex {
let flags = TypeFlags {
names: flags.iter().map(|s| s.to_string()).collect(),
};
intern(&mut self.flags, &mut self.component_types.flags, flags)
}
fn enum_type(&mut self, variants: &[&str]) -> EnumTypeIndex {
let e = EnumType {
fn enum_type(&mut self, variants: &[&str]) -> TypeEnumIndex {
let e = TypeEnum {
names: variants.iter().map(|s| s.to_string()).collect(),
};
intern(&mut self.enums, &mut self.component_types.enums, e)
}
fn union_type(&mut self, types: &[wasmparser::InterfaceTypeRef]) -> UnionTypeIndex {
let union = UnionType {
types: types.iter().map(|ty| self.interface_type_ref(ty)).collect(),
fn union_type(&mut self, types: &[wasmparser::ComponentValType]) -> TypeUnionIndex {
let union = TypeUnion {
types: types.iter().map(|ty| self.valtype(ty)).collect(),
};
intern(&mut self.unions, &mut self.component_types.unions, union)
}
fn expected_type(
&mut self,
ok: &wasmparser::InterfaceTypeRef,
err: &wasmparser::InterfaceTypeRef,
) -> ExpectedTypeIndex {
let expected = ExpectedType {
ok: self.interface_type_ref(ok),
err: self.interface_type_ref(err),
ok: &wasmparser::ComponentValType,
err: &wasmparser::ComponentValType,
) -> TypeExpectedIndex {
let expected = TypeExpected {
ok: self.valtype(ok),
err: self.valtype(err),
};
intern(
&mut self.expecteds,
@@ -597,16 +691,18 @@ where
/// through a sibling `ComponentTypes` structure.
#[derive(Copy, Clone, Debug, Serialize, Deserialize)]
pub enum TypeDef {
/// A core wasm module and its type.
Module(ModuleTypeIndex),
/// A component and its type.
Component(ComponentTypeIndex),
Component(TypeComponentIndex),
/// An instance of a component.
ComponentInstance(ComponentInstanceTypeIndex),
ComponentInstance(TypeComponentInstanceIndex),
/// A component function, not to be confused with a core wasm function.
Func(FuncTypeIndex),
ComponentFunc(TypeFuncIndex),
/// An interface type.
Interface(InterfaceType),
/// A core wasm module and its type.
Module(TypeModuleIndex),
/// A core wasm function using only core wasm types.
CoreFunc(SignatureIndex),
}
// NB: Note that maps below are stored as an `IndexMap` now but the order
@@ -616,10 +712,10 @@ pub enum TypeDef {
/// The type of a module in the component model.
///
/// Note that this is not to be confused with `ComponentType` below. This is
/// Note that this is not to be confused with `TypeComponent` below. This is
/// intended only for core wasm modules, not for components.
#[derive(Serialize, Deserialize, Default)]
pub struct ModuleType {
pub struct TypeModule {
/// The values that this module imports.
///
/// Note that the value of this map is a core wasm `EntityType`, not a
@@ -638,7 +734,7 @@ pub struct ModuleType {
/// The type of a component in the component model.
#[derive(Serialize, Deserialize, Default)]
pub struct ComponentType {
pub struct TypeComponent {
/// The named values that this component imports.
pub imports: IndexMap<String, TypeDef>,
/// The named values that this component exports.
@@ -650,14 +746,14 @@ pub struct ComponentType {
///
/// Component instances only have exports of types in the component model.
#[derive(Serialize, Deserialize, Default)]
pub struct ComponentInstanceType {
pub struct TypeComponentInstance {
/// The list of exports that this component has along with their types.
pub exports: IndexMap<String, TypeDef>,
}
/// A component function type in the component model.
#[derive(Serialize, Deserialize, Clone, Hash, Eq, PartialEq, Debug)]
pub struct FuncType {
pub struct TypeFunc {
/// The list of optionally named parameters for this function, and their
/// types.
pub params: Box<[(Option<String>, InterfaceType)]>,
@@ -688,34 +784,34 @@ pub enum InterfaceType {
Float64,
Char,
String,
Record(RecordTypeIndex),
Variant(VariantTypeIndex),
List(InterfaceTypeIndex),
Tuple(TupleTypeIndex),
Flags(FlagsTypeIndex),
Enum(EnumTypeIndex),
Union(UnionTypeIndex),
Option(InterfaceTypeIndex),
Expected(ExpectedTypeIndex),
Record(TypeRecordIndex),
Variant(TypeVariantIndex),
List(TypeInterfaceIndex),
Tuple(TypeTupleIndex),
Flags(TypeFlagsIndex),
Enum(TypeEnumIndex),
Union(TypeUnionIndex),
Option(TypeInterfaceIndex),
Expected(TypeExpectedIndex),
}
impl From<&wasmparser::PrimitiveInterfaceType> for InterfaceType {
fn from(ty: &wasmparser::PrimitiveInterfaceType) -> InterfaceType {
impl From<&wasmparser::PrimitiveValType> for InterfaceType {
fn from(ty: &wasmparser::PrimitiveValType) -> InterfaceType {
match ty {
wasmparser::PrimitiveInterfaceType::Unit => InterfaceType::Unit,
wasmparser::PrimitiveInterfaceType::Bool => InterfaceType::Bool,
wasmparser::PrimitiveInterfaceType::S8 => InterfaceType::S8,
wasmparser::PrimitiveInterfaceType::U8 => InterfaceType::U8,
wasmparser::PrimitiveInterfaceType::S16 => InterfaceType::S16,
wasmparser::PrimitiveInterfaceType::U16 => InterfaceType::U16,
wasmparser::PrimitiveInterfaceType::S32 => InterfaceType::S32,
wasmparser::PrimitiveInterfaceType::U32 => InterfaceType::U32,
wasmparser::PrimitiveInterfaceType::S64 => InterfaceType::S64,
wasmparser::PrimitiveInterfaceType::U64 => InterfaceType::U64,
wasmparser::PrimitiveInterfaceType::Float32 => InterfaceType::Float32,
wasmparser::PrimitiveInterfaceType::Float64 => InterfaceType::Float64,
wasmparser::PrimitiveInterfaceType::Char => InterfaceType::Char,
wasmparser::PrimitiveInterfaceType::String => InterfaceType::String,
wasmparser::PrimitiveValType::Unit => InterfaceType::Unit,
wasmparser::PrimitiveValType::Bool => InterfaceType::Bool,
wasmparser::PrimitiveValType::S8 => InterfaceType::S8,
wasmparser::PrimitiveValType::U8 => InterfaceType::U8,
wasmparser::PrimitiveValType::S16 => InterfaceType::S16,
wasmparser::PrimitiveValType::U16 => InterfaceType::U16,
wasmparser::PrimitiveValType::S32 => InterfaceType::S32,
wasmparser::PrimitiveValType::U32 => InterfaceType::U32,
wasmparser::PrimitiveValType::S64 => InterfaceType::S64,
wasmparser::PrimitiveValType::U64 => InterfaceType::U64,
wasmparser::PrimitiveValType::Float32 => InterfaceType::Float32,
wasmparser::PrimitiveValType::Float64 => InterfaceType::Float64,
wasmparser::PrimitiveValType::Char => InterfaceType::Char,
wasmparser::PrimitiveValType::String => InterfaceType::String,
}
}
}
@@ -724,7 +820,7 @@ impl From<&wasmparser::PrimitiveInterfaceType> for InterfaceType {
///
/// This is equivalent to a `struct` in Rust.
#[derive(Serialize, Deserialize, Clone, Hash, Eq, PartialEq, Debug)]
pub struct RecordType {
pub struct TypeRecord {
/// The fields that are contained within this struct type.
pub fields: Box<[RecordField]>,
}
@@ -744,7 +840,7 @@ pub struct RecordField {
/// cases and each case has a unique name and an optional payload associated
/// with it.
#[derive(Serialize, Deserialize, Clone, Hash, Eq, PartialEq, Debug)]
pub struct VariantType {
pub struct TypeVariant {
/// The list of cases that this variant can take.
pub cases: Box<[VariantCase]>,
}
@@ -764,7 +860,7 @@ pub struct VariantCase {
/// This is largely the same as a tuple in Rust, basically a record with
/// unnamed fields.
#[derive(Serialize, Deserialize, Clone, Hash, Eq, PartialEq, Debug)]
pub struct TupleType {
pub struct TypeTuple {
/// The types that are contained within this tuple.
pub types: Box<[InterfaceType]>,
}
@@ -774,7 +870,7 @@ pub struct TupleType {
/// This can be thought of as a record-of-bools, although the representation is
/// more efficient as bitflags.
#[derive(Serialize, Deserialize, Clone, Hash, Eq, PartialEq, Debug)]
pub struct FlagsType {
pub struct TypeFlags {
/// The names of all flags, all of which are unique.
pub names: Box<[String]>,
}
@@ -785,7 +881,7 @@ pub struct FlagsType {
/// In interface types enums are simply a bag of names, and can be seen as a
/// variant where all payloads are `Unit`.
#[derive(Serialize, Deserialize, Clone, Hash, Eq, PartialEq, Debug)]
pub struct EnumType {
pub struct TypeEnum {
/// The names of this enum, all of which are unique.
pub names: Box<[String]>,
}
@@ -796,14 +892,14 @@ pub struct EnumType {
/// type where each type here has a name that's numbered. This is still a
/// tagged union.
#[derive(Serialize, Deserialize, Clone, Hash, Eq, PartialEq, Debug)]
pub struct UnionType {
pub struct TypeUnion {
/// The list of types this is a union over.
pub types: Box<[InterfaceType]>,
}
/// Shape of an "expected" interface type.
#[derive(Serialize, Deserialize, Clone, Hash, Eq, PartialEq, Debug)]
pub struct ExpectedType {
pub struct TypeExpected {
/// The `T` in `Result<T, E>`
pub ok: InterfaceType,
/// The `E` in `Result<T, E>`

View File

@@ -15,8 +15,8 @@ use std::path::PathBuf;
use std::sync::Arc;
use wasmparser::{
CustomSectionReader, DataKind, ElementItem, ElementKind, Encoding, ExternalKind, FuncValidator,
FunctionBody, NameSectionReader, Naming, Operator, Parser, Payload, TypeDef, TypeRef,
Validator, ValidatorResources,
FunctionBody, NameSectionReader, Naming, Operator, Parser, Payload, Type, TypeRef, Validator,
ValidatorResources,
};
/// Object containing the standalone environment information.
@@ -130,8 +130,8 @@ pub struct WasmFileInfo {
#[derive(Debug)]
#[allow(missing_docs)]
pub struct FunctionMetadata {
pub params: Box<[wasmparser::Type]>,
pub locals: Box<[(u32, wasmparser::Type)]>,
pub params: Box<[wasmparser::ValType]>,
pub locals: Box<[(u32, wasmparser::ValType)]>,
}
impl<'a, 'data> ModuleEnvironment<'a, 'data> {
@@ -216,7 +216,7 @@ impl<'a, 'data> ModuleEnvironment<'a, 'data> {
for ty in types {
match ty? {
TypeDef::Func(wasm_func_ty) => {
Type::Func(wasm_func_ty) => {
self.declare_type_func(wasm_func_ty.try_into()?)?;
}
}

View File

@@ -15,13 +15,13 @@ log = "0.4.8"
rayon = "1.2.1"
target-lexicon = "0.12.3"
tempfile = "3.3.0"
wasmparser = "0.85.0"
wasmprinter = "0.2.35"
wasmparser = "0.86.0"
wasmprinter = "0.2.36"
wasmtime = { path = "../wasmtime" }
wasmtime-wast = { path = "../wast" }
wasm-encoder = "0.12.0"
wasm-smith = "0.10.1"
wasm-mutate = "0.2.3"
wasm-encoder = "0.13.0"
wasm-smith = "0.11.0"
wasm-mutate = "0.2.4"
wasm-spec-interpreter = { path = "./wasm-spec-interpreter", optional = true }
wasmi = "0.7.0"

View File

@@ -3,7 +3,7 @@
use arbitrary::{Arbitrary, Result, Unstructured};
use std::ops::RangeInclusive;
use wasm_encoder::{
CodeSection, EntityType, Export, ExportSection, Function, FunctionSection, GlobalSection,
CodeSection, EntityType, ExportKind, ExportSection, Function, FunctionSection, GlobalSection,
ImportSection, Instruction, Module, TableSection, TableType, TypeSection, ValType,
};
@@ -103,7 +103,7 @@ impl TableOps {
functions.function(1);
let mut exports = ExportSection::new();
exports.export("run", Export::Function(3));
exports.export("run", ExportKind::Func, 3);
// Give ourselves one scratch local that we can use in various `TableOp`
// implementations.

View File

@@ -12,4 +12,4 @@ edition = "2021"
cranelift-entity = { path = "../../cranelift/entity", version = "0.86.0", features = ['enable-serde'] }
serde = { version = "1.0.94", features = ["derive"] }
thiserror = "1.0.4"
wasmparser = { version = "0.85.0", default-features = false }
wasmparser = { version = "0.86.0", default-features = false }

View File

@@ -31,10 +31,10 @@ pub enum WasmType {
ExternRef,
}
impl TryFrom<wasmparser::Type> for WasmType {
impl TryFrom<wasmparser::ValType> for WasmType {
type Error = WasmError;
fn try_from(ty: wasmparser::Type) -> Result<Self, Self::Error> {
use wasmparser::Type::*;
fn try_from(ty: wasmparser::ValType) -> Result<Self, Self::Error> {
use wasmparser::ValType::*;
match ty {
I32 => Ok(WasmType::I32),
I64 => Ok(WasmType::I64),
@@ -47,16 +47,16 @@ impl TryFrom<wasmparser::Type> for WasmType {
}
}
impl From<WasmType> for wasmparser::Type {
fn from(ty: WasmType) -> wasmparser::Type {
impl From<WasmType> for wasmparser::ValType {
fn from(ty: WasmType) -> wasmparser::ValType {
match ty {
WasmType::I32 => wasmparser::Type::I32,
WasmType::I64 => wasmparser::Type::I64,
WasmType::F32 => wasmparser::Type::F32,
WasmType::F64 => wasmparser::Type::F64,
WasmType::V128 => wasmparser::Type::V128,
WasmType::FuncRef => wasmparser::Type::FuncRef,
WasmType::ExternRef => wasmparser::Type::ExternRef,
WasmType::I32 => wasmparser::ValType::I32,
WasmType::I64 => wasmparser::ValType::I64,
WasmType::F32 => wasmparser::ValType::F32,
WasmType::F64 => wasmparser::ValType::F64,
WasmType::V128 => wasmparser::ValType::V128,
WasmType::FuncRef => wasmparser::ValType::FuncRef,
WasmType::ExternRef => wasmparser::ValType::ExternRef,
}
}
}

View File

@@ -20,7 +20,7 @@ wasmtime-cache = { path = "../cache", version = "=0.39.0", optional = true }
wasmtime-fiber = { path = "../fiber", version = "=0.39.0", optional = true }
wasmtime-cranelift = { path = "../cranelift", version = "=0.39.0", optional = true }
target-lexicon = { version = "0.12.0", default-features = false }
wasmparser = "0.85.0"
wasmparser = "0.86.0"
anyhow = "1.0.19"
region = "2.2.0"
libc = "0.2"

View File

@@ -5,7 +5,7 @@ use anyhow::{Context, Result};
use std::mem::MaybeUninit;
use std::ptr::NonNull;
use std::sync::Arc;
use wasmtime_environ::component::{CanonicalOptions, ComponentTypes, CoreExport, FuncTypeIndex};
use wasmtime_environ::component::{CanonicalOptions, ComponentTypes, CoreExport, TypeFuncIndex};
use wasmtime_environ::FuncIndex;
use wasmtime_runtime::{Export, ExportFunction, VMTrampoline};
@@ -78,7 +78,7 @@ pub struct Func(Stored<FuncData>);
pub struct FuncData {
trampoline: VMTrampoline,
export: ExportFunction,
ty: FuncTypeIndex,
ty: TypeFuncIndex,
types: Arc<ComponentTypes>,
options: Options,
instance: Instance,
@@ -89,7 +89,7 @@ impl Func {
store: &mut StoreOpaque,
instance: &Instance,
data: &InstanceData,
ty: FuncTypeIndex,
ty: TypeFuncIndex,
func: &CoreExport<FuncIndex>,
options: &CanonicalOptions,
) -> Func {

View File

@@ -7,7 +7,7 @@ use std::mem::MaybeUninit;
use std::panic::{self, AssertUnwindSafe};
use std::ptr::NonNull;
use std::sync::Arc;
use wasmtime_environ::component::{ComponentTypes, FuncTypeIndex, StringEncoding};
use wasmtime_environ::component::{ComponentTypes, StringEncoding, TypeFuncIndex};
use wasmtime_runtime::component::{VMComponentContext, VMLowering, VMLoweringCallee};
use wasmtime_runtime::{VMCallerCheckedAnyfunc, VMMemoryDefinition, VMOpaqueContext};
@@ -38,7 +38,7 @@ pub trait IntoComponentFunc<T, Params, Return> {
pub struct HostFunc {
entrypoint: VMLoweringCallee,
typecheck: fn(FuncTypeIndex, &ComponentTypes) -> Result<()>,
typecheck: fn(TypeFuncIndex, &ComponentTypes) -> Result<()>,
func: Box<dyn Any + Send + Sync>,
}
@@ -56,7 +56,7 @@ impl HostFunc {
})
}
pub fn typecheck(&self, ty: FuncTypeIndex, types: &ComponentTypes) -> Result<()> {
pub fn typecheck(&self, ty: TypeFuncIndex, types: &ComponentTypes) -> Result<()> {
(self.typecheck)(ty, types)
}
@@ -69,7 +69,7 @@ impl HostFunc {
}
}
fn typecheck<P, R>(ty: FuncTypeIndex, types: &ComponentTypes) -> Result<()>
fn typecheck<P, R>(ty: TypeFuncIndex, types: &ComponentTypes) -> Result<()>
where
P: ComponentParams + Lift,
R: Lower,

View File

@@ -4,7 +4,7 @@ use crate::types::matching;
use crate::Module;
use anyhow::{anyhow, bail, Context, Result};
use wasmtime_environ::component::{
ComponentInstanceType, ComponentTypes, FuncTypeIndex, ModuleType, TypeDef,
ComponentTypes, TypeComponentInstance, TypeDef, TypeFuncIndex, TypeModule,
};
pub struct TypeChecker<'a> {
@@ -23,16 +23,19 @@ impl TypeChecker<'_> {
Definition::Instance(actual) => self.instance(&self.types[t], actual),
_ => bail!("expected instance found {}", actual.desc()),
},
TypeDef::Func(t) => match actual {
TypeDef::ComponentFunc(t) => match actual {
Definition::Func(actual) => self.func(t, actual),
_ => bail!("expected func found {}", actual.desc()),
},
TypeDef::Component(_) => bail!("expected component found {}", actual.desc()),
TypeDef::Interface(_) => bail!("expected type found {}", actual.desc()),
// not possible for valid components to import
TypeDef::CoreFunc(_) => unreachable!(),
}
}
fn module(&self, expected: &ModuleType, actual: &Module) -> Result<()> {
fn module(&self, expected: &TypeModule, actual: &Module) -> Result<()> {
let actual_types = actual.types();
let actual = actual.env_module();
@@ -63,7 +66,7 @@ impl TypeChecker<'_> {
Ok(())
}
fn instance(&self, expected: &ComponentInstanceType, actual: &NameMap) -> Result<()> {
fn instance(&self, expected: &TypeComponentInstance, actual: &NameMap) -> Result<()> {
// Like modules, every export in the expected type must be present in
// the actual type. It's ok, though, to have extra exports in the actual
// type.
@@ -79,7 +82,7 @@ impl TypeChecker<'_> {
Ok(())
}
fn func(&self, expected: FuncTypeIndex, actual: &HostFunc) -> Result<()> {
fn func(&self, expected: TypeFuncIndex, actual: &HostFunc) -> Result<()> {
actual.typecheck(expected, self.types)
}
}

View File

@@ -12,7 +12,7 @@ edition = "2021"
[dependencies]
anyhow = "1.0.19"
wasmtime = { path = "../wasmtime", version = "0.39.0", default-features = false, features = ['cranelift'] }
wast = "41.0.0"
wast = "42.0.0"
[badges]
maintenance = { status = "actively-developed" }

View File

@@ -8,7 +8,7 @@ mod import;
// A simple bump allocator which can be used with modules
const REALLOC_AND_FREE: &str = r#"
(global $last (mut i32) (i32.const 8))
(func $realloc (export "canonical_abi_realloc")
(func $realloc (export "realloc")
(param $old_ptr i32)
(param $old_size i32)
(param $align i32)
@@ -62,8 +62,6 @@ const REALLOC_AND_FREE: &str = r#"
(global.get $last)
(local.get $new_size)))
)
(func (export "canonical_abi_free") (param i32 i32 i32))
"#;
fn engine() -> Engine {
@@ -83,7 +81,7 @@ fn components_importing_modules() -> Result<()> {
&engine,
r#"
(component
(import "" (module))
(import "" (core module))
)
"#,
)?;
@@ -92,7 +90,7 @@ fn components_importing_modules() -> Result<()> {
&engine,
r#"
(component
(import "" (module $m1
(import "" (core module $m1
(import "" "" (func))
(import "" "x" (global i32))
@@ -102,21 +100,21 @@ fn components_importing_modules() -> Result<()> {
(export "d" (global i64))
))
(module $m2
(core module $m2
(func (export ""))
(global (export "x") i32 i32.const 0)
)
(instance $i2 (instantiate (module $m2)))
(instance $i1 (instantiate (module $m1) (with "" (instance $i2))))
(core instance $i2 (instantiate (module $m2)))
(core instance $i1 (instantiate (module $m1) (with "" (instance $i2))))
(module $m3
(core module $m3
(import "mod" "1" (memory 1))
(import "mod" "2" (table 1 funcref))
(import "mod" "3" (global i64))
(import "mod" "4" (func (result f32)))
)
(instance $i3 (instantiate (module $m3)
(core instance $i3 (instantiate (module $m3)
(with "mod" (instance
(export "1" (memory $i1 "b"))
(export "2" (table $i1 "a"))

View File

@@ -12,16 +12,16 @@ const CANON_64BIT_NAN: u64 = 0b0111111111111000000000000000000000000000000000000
fn thunks() -> Result<()> {
let component = r#"
(component
(module $m
(core module $m
(func (export "thunk"))
(func (export "thunk-trap") unreachable)
)
(instance $i (instantiate (module $m)))
(core instance $i (instantiate $m))
(func (export "thunk")
(canon.lift (func) (func $i "thunk"))
(canon lift (core func $i "thunk"))
)
(func (export "thunk-trap")
(canon.lift (func) (func $i "thunk-trap"))
(canon lift (core func $i "thunk-trap"))
)
)
"#;
@@ -46,42 +46,40 @@ fn thunks() -> Result<()> {
fn typecheck() -> Result<()> {
let component = r#"
(component
(module $m
(core module $m
(func (export "thunk"))
(func (export "take-string") (param i32 i32))
(func (export "two-args") (param i32 i32 i32))
(func (export "ret-one") (result i32) unreachable)
(memory (export "memory") 1)
(func (export "canonical_abi_realloc") (param i32 i32 i32 i32) (result i32)
unreachable)
(func (export "canonical_abi_free") (param i32 i32 i32)
(func (export "realloc") (param i32 i32 i32 i32) (result i32)
unreachable)
)
(instance $i (instantiate (module $m)))
(core instance $i (instantiate (module $m)))
(func (export "thunk")
(canon.lift (func) (func $i "thunk"))
(canon lift (core func $i "thunk"))
)
(func (export "tuple-thunk")
(canon.lift (func (param (tuple)) (result (tuple))) (func $i "thunk"))
(func (export "tuple-thunk") (param (tuple)) (result (tuple))
(canon lift (core func $i "thunk"))
)
(func (export "take-string")
(canon.lift (func (param string)) (into $i) (func $i "take-string"))
(func (export "take-string") (param string)
(canon lift (core func $i "take-string") (memory $i "memory") (realloc (func $i "realloc")))
)
(func (export "take-two-args")
(canon.lift (func (param s32) (param (list u8))) (into $i) (func $i "two-args"))
(func (export "take-two-args") (param s32) (param (list u8))
(canon lift (core func $i "two-args") (memory $i "memory") (realloc (func $i "realloc")))
)
(func (export "ret-tuple")
(canon.lift (func (result (tuple u8 s8))) (into $i) (func $i "ret-one"))
(func (export "ret-tuple") (result (tuple u8 s8))
(canon lift (core func $i "ret-one") (memory $i "memory") (realloc (func $i "realloc")))
)
(func (export "ret-tuple1")
(canon.lift (func (result (tuple u32))) (into $i) (func $i "ret-one"))
(func (export "ret-tuple1") (result (tuple u32))
(canon lift (core func $i "ret-one") (memory $i "memory") (realloc (func $i "realloc")))
)
(func (export "ret-string")
(canon.lift (func (result string)) (into $i) (func $i "ret-one"))
(func (export "ret-string") (result string)
(canon lift (core func $i "ret-one") (memory $i "memory") (realloc (func $i "realloc")))
)
(func (export "ret-list-u8")
(canon.lift (func (result (list u8))) (into $i) (func $i "ret-one"))
(func (export "ret-list-u8") (result (list u8))
(canon lift (core func $i "ret-one") (memory $i "memory") (realloc (func $i "realloc")))
)
)
"#;
@@ -129,7 +127,7 @@ fn typecheck() -> Result<()> {
fn integers() -> Result<()> {
let component = r#"
(component
(module $m
(core module $m
(func (export "take-i32-100") (param i32)
local.get 0
i32.const 100
@@ -150,40 +148,40 @@ fn integers() -> Result<()> {
(func (export "ret-i64-minus-1") (result i64) i64.const -1)
(func (export "ret-i32-100000") (result i32) i32.const 100000)
)
(instance $i (instantiate (module $m)))
(func (export "take-u8") (canon.lift (func (param u8)) (func $i "take-i32-100")))
(func (export "take-s8") (canon.lift (func (param s8)) (func $i "take-i32-100")))
(func (export "take-u16") (canon.lift (func (param u16)) (func $i "take-i32-100")))
(func (export "take-s16") (canon.lift (func (param s16)) (func $i "take-i32-100")))
(func (export "take-u32") (canon.lift (func (param u32)) (func $i "take-i32-100")))
(func (export "take-s32") (canon.lift (func (param s32)) (func $i "take-i32-100")))
(func (export "take-u64") (canon.lift (func (param u64)) (func $i "take-i64-100")))
(func (export "take-s64") (canon.lift (func (param s64)) (func $i "take-i64-100")))
(core instance $i (instantiate (module $m)))
(func (export "take-u8") (param u8) (canon lift (core func $i "take-i32-100")))
(func (export "take-s8") (param s8) (canon lift (core func $i "take-i32-100")))
(func (export "take-u16") (param u16) (canon lift (core func $i "take-i32-100")))
(func (export "take-s16") (param s16) (canon lift (core func $i "take-i32-100")))
(func (export "take-u32") (param u32) (canon lift (core func $i "take-i32-100")))
(func (export "take-s32") (param s32) (canon lift (core func $i "take-i32-100")))
(func (export "take-u64") (param u64) (canon lift (core func $i "take-i64-100")))
(func (export "take-s64") (param s64) (canon lift (core func $i "take-i64-100")))
(func (export "ret-u8") (canon.lift (func (result u8)) (func $i "ret-i32-0")))
(func (export "ret-s8") (canon.lift (func (result s8)) (func $i "ret-i32-0")))
(func (export "ret-u16") (canon.lift (func (result u16)) (func $i "ret-i32-0")))
(func (export "ret-s16") (canon.lift (func (result s16)) (func $i "ret-i32-0")))
(func (export "ret-u32") (canon.lift (func (result u32)) (func $i "ret-i32-0")))
(func (export "ret-s32") (canon.lift (func (result s32)) (func $i "ret-i32-0")))
(func (export "ret-u64") (canon.lift (func (result u64)) (func $i "ret-i64-0")))
(func (export "ret-s64") (canon.lift (func (result s64)) (func $i "ret-i64-0")))
(func (export "ret-u8") (result u8) (canon lift (core func $i "ret-i32-0")))
(func (export "ret-s8") (result s8) (canon lift (core func $i "ret-i32-0")))
(func (export "ret-u16") (result u16) (canon lift (core func $i "ret-i32-0")))
(func (export "ret-s16") (result s16) (canon lift (core func $i "ret-i32-0")))
(func (export "ret-u32") (result u32) (canon lift (core func $i "ret-i32-0")))
(func (export "ret-s32") (result s32) (canon lift (core func $i "ret-i32-0")))
(func (export "ret-u64") (result u64) (canon lift (core func $i "ret-i64-0")))
(func (export "ret-s64") (result s64) (canon lift (core func $i "ret-i64-0")))
(func (export "retm1-u8") (canon.lift (func (result u8)) (func $i "ret-i32-minus-1")))
(func (export "retm1-s8") (canon.lift (func (result s8)) (func $i "ret-i32-minus-1")))
(func (export "retm1-u16") (canon.lift (func (result u16)) (func $i "ret-i32-minus-1")))
(func (export "retm1-s16") (canon.lift (func (result s16)) (func $i "ret-i32-minus-1")))
(func (export "retm1-u32") (canon.lift (func (result u32)) (func $i "ret-i32-minus-1")))
(func (export "retm1-s32") (canon.lift (func (result s32)) (func $i "ret-i32-minus-1")))
(func (export "retm1-u64") (canon.lift (func (result u64)) (func $i "ret-i64-minus-1")))
(func (export "retm1-s64") (canon.lift (func (result s64)) (func $i "ret-i64-minus-1")))
(func (export "retm1-u8") (result u8) (canon lift (core func $i "ret-i32-minus-1")))
(func (export "retm1-s8") (result s8) (canon lift (core func $i "ret-i32-minus-1")))
(func (export "retm1-u16") (result u16) (canon lift (core func $i "ret-i32-minus-1")))
(func (export "retm1-s16") (result s16) (canon lift (core func $i "ret-i32-minus-1")))
(func (export "retm1-u32") (result u32) (canon lift (core func $i "ret-i32-minus-1")))
(func (export "retm1-s32") (result s32) (canon lift (core func $i "ret-i32-minus-1")))
(func (export "retm1-u64") (result u64) (canon lift (core func $i "ret-i64-minus-1")))
(func (export "retm1-s64") (result s64) (canon lift (core func $i "ret-i64-minus-1")))
(func (export "retbig-u8") (canon.lift (func (result u8)) (func $i "ret-i32-100000")))
(func (export "retbig-s8") (canon.lift (func (result s8)) (func $i "ret-i32-100000")))
(func (export "retbig-u16") (canon.lift (func (result u16)) (func $i "ret-i32-100000")))
(func (export "retbig-s16") (canon.lift (func (result s16)) (func $i "ret-i32-100000")))
(func (export "retbig-u32") (canon.lift (func (result u32)) (func $i "ret-i32-100000")))
(func (export "retbig-s32") (canon.lift (func (result s32)) (func $i "ret-i32-100000")))
(func (export "retbig-u8") (result u8) (canon lift (core func $i "ret-i32-100000")))
(func (export "retbig-s8") (result s8) (canon lift (core func $i "ret-i32-100000")))
(func (export "retbig-u16") (result u16) (canon lift (core func $i "ret-i32-100000")))
(func (export "retbig-s16") (result s16) (canon lift (core func $i "ret-i32-100000")))
(func (export "retbig-u32") (result u32) (canon lift (core func $i "ret-i32-100000")))
(func (export "retbig-s32") (result s32) (canon lift (core func $i "ret-i32-100000")))
)
"#;
@@ -406,7 +404,7 @@ fn integers() -> Result<()> {
fn type_layers() -> Result<()> {
let component = r#"
(component
(module $m
(core module $m
(func (export "take-i32-100") (param i32)
local.get 0
i32.const 2
@@ -415,8 +413,8 @@ fn type_layers() -> Result<()> {
unreachable
)
)
(instance $i (instantiate (module $m)))
(func (export "take-u32") (canon.lift (func (param u32)) (func $i "take-i32-100")))
(core instance $i (instantiate $m))
(func (export "take-u32") (param u32) (canon lift (core func $i "take-i32-100")))
)
"#;
@@ -448,7 +446,7 @@ fn type_layers() -> Result<()> {
fn floats() -> Result<()> {
let component = r#"
(component
(module $m
(core module $m
(func (export "i32.reinterpret_f32") (param f32) (result i32)
local.get 0
i32.reinterpret_f32
@@ -466,19 +464,19 @@ fn floats() -> Result<()> {
f64.reinterpret_i64
)
)
(instance $i (instantiate (module $m)))
(core instance $i (instantiate $m))
(func (export "f32-to-u32")
(canon.lift (func (param float32) (result u32)) (func $i "i32.reinterpret_f32"))
(func (export "f32-to-u32") (param float32) (result u32)
(canon lift (core func $i "i32.reinterpret_f32"))
)
(func (export "f64-to-u64")
(canon.lift (func (param float64) (result u64)) (func $i "i64.reinterpret_f64"))
(func (export "f64-to-u64") (param float64) (result u64)
(canon lift (core func $i "i64.reinterpret_f64"))
)
(func (export "u32-to-f32")
(canon.lift (func (param u32) (result float32)) (func $i "f32.reinterpret_i32"))
(func (export "u32-to-f32") (param u32) (result float32)
(canon lift (core func $i "f32.reinterpret_i32"))
)
(func (export "u64-to-f64")
(canon.lift (func (param u64) (result float64)) (func $i "f64.reinterpret_i64"))
(func (export "u64-to-f64") (param u64) (result float64)
(canon lift (core func $i "f64.reinterpret_i64"))
)
)
"#;
@@ -526,16 +524,16 @@ fn floats() -> Result<()> {
fn bools() -> Result<()> {
let component = r#"
(component
(module $m
(core module $m
(func (export "pass") (param i32) (result i32) local.get 0)
)
(instance $i (instantiate (module $m)))
(core instance $i (instantiate $m))
(func (export "u32-to-bool")
(canon.lift (func (param u32) (result bool)) (func $i "pass"))
(func (export "u32-to-bool") (param u32) (result bool)
(canon lift (core func $i "pass"))
)
(func (export "bool-to-u32")
(canon.lift (func (param bool) (result u32)) (func $i "pass"))
(func (export "bool-to-u32") (param bool) (result u32)
(canon lift (core func $i "pass"))
)
)
"#;
@@ -560,16 +558,16 @@ fn bools() -> Result<()> {
fn chars() -> Result<()> {
let component = r#"
(component
(module $m
(core module $m
(func (export "pass") (param i32) (result i32) local.get 0)
)
(instance $i (instantiate (module $m)))
(core instance $i (instantiate $m))
(func (export "u32-to-char")
(canon.lift (func (param u32) (result char)) (func $i "pass"))
(func (export "u32-to-char") (param u32) (result char)
(canon lift (core func $i "pass"))
)
(func (export "char-to-u32")
(canon.lift (func (param char) (result u32)) (func $i "pass"))
(func (export "char-to-u32") (param char) (result u32)
(canon lift (core func $i "pass"))
)
)
"#;
@@ -609,7 +607,7 @@ fn chars() -> Result<()> {
fn tuple_result() -> Result<()> {
let component = r#"
(component
(module $m
(core module $m
(memory (export "memory") 1)
(func (export "foo") (param i32 i32 f32 f64) (result i32)
(local $base i32)
@@ -624,24 +622,16 @@ fn tuple_result() -> Result<()> {
(func (export "invalid") (result i32)
i32.const -8
)
(func (export "canonical_abi_realloc") (param i32 i32 i32 i32) (result i32)
unreachable)
(func (export "canonical_abi_free") (param i32 i32 i32)
unreachable)
)
(instance $i (instantiate (module $m)))
(core instance $i (instantiate $m))
(type $result (tuple s8 u16 float32 float64))
(func (export "tuple")
(canon.lift
(func (param s8) (param u16) (param float32) (param float64) (result $result))
(into $i)
(func $i "foo")
)
(param s8) (param u16) (param float32) (param float64) (result $result)
(canon lift (core func $i "foo") (memory $i "memory"))
)
(func (export "invalid")
(canon.lift (func (result $result)) (into $i) (func $i "invalid"))
(func (export "invalid") (result $result)
(canon lift (core func $i "invalid") (memory $i "memory"))
)
)
"#;
@@ -673,7 +663,7 @@ fn tuple_result() -> Result<()> {
fn strings() -> Result<()> {
let component = format!(
r#"(component
(module $m
(core module $m
(memory (export "memory") 1)
(func (export "roundtrip") (param i32 i32) (result i32)
(local $base i32)
@@ -694,36 +684,36 @@ fn strings() -> Result<()> {
{REALLOC_AND_FREE}
)
(instance $i (instantiate (module $m)))
(core instance $i (instantiate $m))
(func (export "list8-to-str")
(canon.lift
(func (param (list u8)) (result string))
(into $i)
(func $i "roundtrip")
(func (export "list8-to-str") (param (list u8)) (result string)
(canon lift
(core func $i "roundtrip")
(memory $i "memory")
(realloc (func $i "realloc"))
)
)
(func (export "str-to-list8")
(canon.lift
(func (param string) (result (list u8)))
(into $i)
(func $i "roundtrip")
(func (export "str-to-list8") (param string) (result (list u8))
(canon lift
(core func $i "roundtrip")
(memory $i "memory")
(realloc (func $i "realloc"))
)
)
(func (export "list16-to-str")
(canon.lift
(func (param (list u16)) (result string))
string=utf16
(into $i)
(func $i "roundtrip")
(func (export "list16-to-str") (param (list u16)) (result string)
(canon lift
(core func $i "roundtrip")
string-encoding=utf16
(memory $i "memory")
(realloc (func $i "realloc"))
)
)
(func (export "str-to-list16")
(canon.lift
(func (param string) (result (list u16)))
string=utf16
(into $i)
(func $i "roundtrip")
(func (export "str-to-list16") (param string) (result (list u16))
(canon lift
(core func $i "roundtrip")
string-encoding=utf16
(memory $i "memory")
(realloc (func $i "realloc"))
)
)
)"#
@@ -792,7 +782,7 @@ fn strings() -> Result<()> {
fn many_parameters() -> Result<()> {
let component = format!(
r#"(component
(module $m
(core module $m
(memory (export "memory") 1)
(func (export "foo") (param i32) (result i32)
(local $base i32)
@@ -826,7 +816,7 @@ fn many_parameters() -> Result<()> {
{REALLOC_AND_FREE}
)
(instance $i (instantiate (module $m)))
(core instance $i (instantiate $m))
(type $result (tuple (list u8) u32))
(type $t (func
@@ -847,8 +837,12 @@ fn many_parameters() -> Result<()> {
(result $result)
))
(func (export "many-param")
(canon.lift (type $t) (into $i) (func $i "foo"))
(func (export "many-param") (type $t)
(canon lift
(core func $i "foo")
(memory $i "memory")
(realloc (func $i "realloc"))
)
)
)"#
);
@@ -950,23 +944,21 @@ fn some_traps() -> Result<()> {
let middle_of_memory = (i32::MAX / 2) & (!0xff);
let component = format!(
r#"(component
(module $m
(core module $m
(memory (export "memory") 1)
(func (export "take-many") (param i32))
(func (export "take-list") (param i32 i32))
(func (export "canonical_abi_realloc") (param i32 i32 i32 i32) (result i32)
unreachable)
(func (export "canonical_abi_free") (param i32 i32 i32)
(func (export "realloc") (param i32 i32 i32 i32) (result i32)
unreachable)
)
(instance $i (instantiate (module $m)))
(core instance $i (instantiate $m))
(func (export "take-list-unreachable")
(canon.lift (func (param (list u8))) (into $i) (func $i "take-list"))
(func (export "take-list-unreachable") (param (list u8))
(canon lift (core func $i "take-list") (memory $i "memory") (realloc (func $i "realloc")))
)
(func (export "take-string-unreachable")
(canon.lift (func (param string)) (into $i) (func $i "take-list"))
(func (export "take-string-unreachable") (param string)
(canon lift (core func $i "take-list") (memory $i "memory") (realloc (func $i "realloc")))
)
(type $t (func
@@ -981,60 +973,56 @@ fn some_traps() -> Result<()> {
(param string)
(param string)
))
(func (export "take-many-unreachable")
(canon.lift (type $t) (into $i) (func $i "take-many"))
(func (export "take-many-unreachable") (type $t)
(canon lift (core func $i "take-many") (memory $i "memory") (realloc (func $i "realloc")))
)
(module $m2
(core module $m2
(memory (export "memory") 1)
(func (export "take-many") (param i32))
(func (export "take-list") (param i32 i32))
(func (export "canonical_abi_realloc") (param i32 i32 i32 i32) (result i32)
(func (export "realloc") (param i32 i32 i32 i32) (result i32)
i32.const {middle_of_memory})
(func (export "canonical_abi_free") (param i32 i32 i32)
unreachable)
)
(instance $i2 (instantiate (module $m2)))
(core instance $i2 (instantiate $m2))
(func (export "take-list-base-oob")
(canon.lift (func (param (list u8))) (into $i2) (func $i2 "take-list"))
(func (export "take-list-base-oob") (param (list u8))
(canon lift (core func $i2 "take-list") (memory $i2 "memory") (realloc (func $i2 "realloc")))
)
(func (export "take-string-base-oob")
(canon.lift (func (param string)) (into $i2) (func $i2 "take-list"))
(func (export "take-string-base-oob") (param string)
(canon lift (core func $i2 "take-list") (memory $i2 "memory") (realloc (func $i2 "realloc")))
)
(func (export "take-many-base-oob")
(canon.lift (type $t) (into $i2) (func $i2 "take-many"))
(func (export "take-many-base-oob") (type $t)
(canon lift (core func $i2 "take-many") (memory $i2 "memory") (realloc (func $i2 "realloc")))
)
(module $m3
(core module $m3
(memory (export "memory") 1)
(func (export "take-many") (param i32))
(func (export "take-list") (param i32 i32))
(func (export "canonical_abi_realloc") (param i32 i32 i32 i32) (result i32)
(func (export "realloc") (param i32 i32 i32 i32) (result i32)
i32.const 65532)
(func (export "canonical_abi_free") (param i32 i32 i32)
unreachable)
)
(instance $i3 (instantiate (module $m3)))
(core instance $i3 (instantiate $m3))
(func (export "take-list-end-oob")
(canon.lift (func (param (list u8))) (into $i3) (func $i3 "take-list"))
(func (export "take-list-end-oob") (param (list u8))
(canon lift (core func $i3 "take-list") (memory $i3 "memory") (realloc (func $i3 "realloc")))
)
(func (export "take-string-end-oob")
(canon.lift (func (param string)) (into $i3) (func $i3 "take-list"))
(func (export "take-string-end-oob") (param string)
(canon lift (core func $i3 "take-list") (memory $i3 "memory") (realloc (func $i3 "realloc")))
)
(func (export "take-many-end-oob")
(canon.lift (type $t) (into $i3) (func $i3 "take-many"))
(func (export "take-many-end-oob") (type $t)
(canon lift (core func $i3 "take-many") (memory $i3 "memory") (realloc (func $i3 "realloc")))
)
(module $m4
(core module $m4
(memory (export "memory") 1)
(func (export "take-many") (param i32))
(global $cnt (mut i32) (i32.const 0))
(func (export "canonical_abi_realloc") (param i32 i32 i32 i32) (result i32)
(func (export "realloc") (param i32 i32 i32 i32) (result i32)
global.get $cnt
if (result i32)
i32.const 100000
@@ -1044,13 +1032,11 @@ fn some_traps() -> Result<()> {
i32.const 0
end
)
(func (export "canonical_abi_free") (param i32 i32 i32)
unreachable)
)
(instance $i4 (instantiate (module $m4)))
(core instance $i4 (instantiate $m4))
(func (export "take-many-second-oob")
(canon.lift (type $t) (into $i4) (func $i4 "take-many"))
(func (export "take-many-second-oob") (type $t)
(canon lift (core func $i4 "take-many") (memory $i4 "memory") (realloc (func $i4 "realloc")))
)
)"#
);
@@ -1184,7 +1170,7 @@ fn some_traps() -> Result<()> {
fn char_bool_memory() -> Result<()> {
let component = format!(
r#"(component
(module $m
(core module $m
(memory (export "memory") 1)
(func (export "ret-tuple") (param i32 i32) (result i32)
(local $base i32)
@@ -1212,10 +1198,12 @@ fn char_bool_memory() -> Result<()> {
{REALLOC_AND_FREE}
)
(instance $i (instantiate (module $m)))
(core instance $i (instantiate $m))
(func (export "ret-tuple")
(canon.lift (func (param u32) (param u32) (result (tuple bool char))) (into $i) (func $i "ret-tuple"))
(func (export "ret-tuple") (param u32) (param u32) (result (tuple bool char))
(canon lift (core func $i "ret-tuple")
(memory $i "memory")
(realloc (func $i "realloc")))
)
)"#
);
@@ -1244,7 +1232,7 @@ fn char_bool_memory() -> Result<()> {
fn string_list_oob() -> Result<()> {
let component = format!(
r#"(component
(module $m
(core module $m
(memory (export "memory") 1)
(func (export "ret-list") (result i32)
(local $base i32)
@@ -1269,13 +1257,19 @@ fn string_list_oob() -> Result<()> {
{REALLOC_AND_FREE}
)
(instance $i (instantiate (module $m)))
(core instance $i (instantiate $m))
(func (export "ret-list-u8")
(canon.lift (func (result (list u8))) (into $i) (func $i "ret-list"))
(func (export "ret-list-u8") (result (list u8))
(canon lift (core func $i "ret-list")
(memory $i "memory")
(realloc (func $i "realloc"))
)
)
(func (export "ret-string")
(canon.lift (func (result string)) (into $i) (func $i "ret-list"))
(func (export "ret-string") (result string)
(canon lift (core func $i "ret-list")
(memory $i "memory")
(realloc (func $i "realloc"))
)
)
)"#
);
@@ -1300,7 +1294,7 @@ fn string_list_oob() -> Result<()> {
fn tuples() -> Result<()> {
let component = format!(
r#"(component
(module $m
(core module $m
(memory (export "memory") 1)
(func (export "foo")
(param i32 f64 i32)
@@ -1323,23 +1317,14 @@ fn tuples() -> Result<()> {
i32.const 3
)
(func (export "canonical_abi_realloc") (param i32 i32 i32 i32) (result i32)
unreachable)
(func (export "canonical_abi_free") (param i32 i32 i32)
unreachable)
)
(instance $i (instantiate (module $m)))
(core instance $i (instantiate $m))
(func (export "foo")
(canon.lift
(func
(param (tuple s32 float64))
(param (tuple s8))
(result (tuple u16))
)
(func $i "foo")
)
(param (tuple s32 float64))
(param (tuple s8))
(result (tuple u16))
(canon lift (core func $i "foo"))
)
)"#
);
@@ -1358,7 +1343,7 @@ fn tuples() -> Result<()> {
fn option() -> Result<()> {
let component = format!(
r#"(component
(module $m
(core module $m
(memory (export "memory") 1)
(func (export "pass0") (param i32) (result i32)
local.get 0
@@ -1405,60 +1390,41 @@ fn option() -> Result<()> {
{REALLOC_AND_FREE}
)
(instance $i (instantiate (module $m)))
(core instance $i (instantiate $m))
(func (export "option-unit-to-u32")
(canon.lift
(func (param (option unit)) (result u32))
(func $i "pass0")
(func (export "option-unit-to-u32") (param (option unit)) (result u32)
(canon lift (core func $i "pass0"))
)
(func (export "option-u8-to-tuple") (param (option u8)) (result (tuple u32 u32))
(canon lift (core func $i "pass1") (memory $i "memory"))
)
(func (export "option-u32-to-tuple") (param (option u32)) (result (tuple u32 u32))
(canon lift (core func $i "pass1") (memory $i "memory"))
)
(func (export "option-string-to-tuple") (param (option string)) (result (tuple u32 string))
(canon lift
(core func $i "pass2")
(memory $i "memory")
(realloc (func $i "realloc"))
)
)
(func (export "option-u8-to-tuple")
(canon.lift
(func (param (option u8)) (result (tuple u32 u32)))
(into $i)
(func $i "pass1")
(func (export "to-option-unit") (param u32) (result (option unit))
(canon lift (core func $i "pass0"))
)
(func (export "to-option-u8") (param u32) (param u32) (result (option u8))
(canon lift (core func $i "pass1") (memory $i "memory"))
)
(func (export "to-option-u32") (param u32) (param u32) (result (option u32))
(canon lift
(core func $i "pass1")
(memory $i "memory")
)
)
(func (export "option-u32-to-tuple")
(canon.lift
(func (param (option u32)) (result (tuple u32 u32)))
(into $i)
(func $i "pass1")
)
)
(func (export "option-string-to-tuple")
(canon.lift
(func (param (option string)) (result (tuple u32 string)))
(into $i)
(func $i "pass2")
)
)
(func (export "to-option-unit")
(canon.lift
(func (param u32) (result (option unit)))
(func $i "pass0")
)
)
(func (export "to-option-u8")
(canon.lift
(func (param u32) (param u32) (result (option u8)))
(into $i)
(func $i "pass1")
)
)
(func (export "to-option-u32")
(canon.lift
(func (param u32) (param u32) (result (option u32)))
(into $i)
(func $i "pass1")
)
)
(func (export "to-option-string")
(canon.lift
(func (param u32) (param string) (result (option string)))
(into $i)
(func $i "pass2")
(func (export "to-option-string") (param u32) (param string) (result (option string))
(canon lift
(core func $i "pass2")
(memory $i "memory")
(realloc (func $i "realloc"))
)
)
)"#
@@ -1543,7 +1509,7 @@ fn option() -> Result<()> {
fn expected() -> Result<()> {
let component = format!(
r#"(component
(module $m
(core module $m
(memory (export "memory") 1)
(func (export "pass0") (param i32) (result i32)
local.get 0
@@ -1590,40 +1556,30 @@ fn expected() -> Result<()> {
{REALLOC_AND_FREE}
)
(instance $i (instantiate (module $m)))
(core instance $i (instantiate $m))
(func (export "take-expected-unit")
(canon.lift
(func (param (expected unit unit)) (result u32))
(func $i "pass0")
)
(func (export "take-expected-unit") (param (expected unit unit)) (result u32)
(canon lift (core func $i "pass0"))
)
(func (export "take-expected-u8-f32")
(canon.lift
(func (param (expected u8 float32)) (result (tuple u32 u32)))
(into $i)
(func $i "pass1")
)
(func (export "take-expected-u8-f32") (param (expected u8 float32)) (result (tuple u32 u32))
(canon lift (core func $i "pass1") (memory $i "memory"))
)
(type $list (list u8))
(func (export "take-expected-string")
(canon.lift
(func (param (expected string $list)) (result (tuple u32 string)))
(into $i)
(func $i "pass2")
(func (export "take-expected-string") (param (expected string $list)) (result (tuple u32 string))
(canon lift
(core func $i "pass2")
(memory $i "memory")
(realloc (func $i "realloc"))
)
)
(func (export "to-expected-unit")
(canon.lift
(func (param u32) (result (expected unit unit)))
(func $i "pass0")
)
(func (export "to-expected-unit") (param u32) (result (expected unit unit))
(canon lift (core func $i "pass0"))
)
(func (export "to-expected-s16-f32")
(canon.lift
(func (param u32) (param u32) (result (expected s16 float32)))
(into $i)
(func $i "pass1")
(func (export "to-expected-s16-f32") (param u32) (param u32) (result (expected s16 float32))
(canon lift
(core func $i "pass1")
(memory $i "memory")
(realloc (func $i "realloc"))
)
)
)"#
@@ -1684,7 +1640,7 @@ fn expected() -> Result<()> {
fn fancy_list() -> Result<()> {
let component = format!(
r#"(component
(module $m
(core module $m
(memory (export "memory") 1)
(func (export "take") (param i32 i32) (result i32)
(local $base i32)
@@ -1715,17 +1671,17 @@ fn fancy_list() -> Result<()> {
{REALLOC_AND_FREE}
)
(instance $i (instantiate (module $m)))
(core instance $i (instantiate $m))
(type $a (option u8))
(type $b (expected unit string))
(type $input (list (tuple $a $b)))
(type $output (tuple u32 u32 (list u8)))
(func (export "take")
(canon.lift
(func (param $input) (result $output))
(into $i)
(func $i "take")
(func (export "take") (param $input) (result $output)
(canon lift
(core func $i "take")
(memory $i "memory")
(realloc (func $i "realloc"))
)
)
)"#
@@ -1808,13 +1764,10 @@ impl<'a> SliceExt<'a> for &'a [u8] {
fn invalid_alignment() -> Result<()> {
let component = format!(
r#"(component
(module $m
(core module $m
(memory (export "memory") 1)
(func (export "canonical_abi_realloc") (param i32 i32 i32 i32) (result i32)
(func (export "realloc") (param i32 i32 i32 i32) (result i32)
i32.const 1)
(func (export "canonical_abi_free") (param i32 i32 i32)
unreachable)
(func (export "take-i32") (param i32))
(func (export "ret-1") (result i32) i32.const 1)
@@ -1823,24 +1776,31 @@ fn invalid_alignment() -> Result<()> {
(i32.store offset=4 (i32.const 8) (i32.const 1))
i32.const 8)
)
(instance $i (instantiate (module $m)))
(core instance $i (instantiate $m))
(func (export "many-params")
(canon.lift
(func
(param string) (param string) (param string) (param string)
(param string) (param string) (param string) (param string)
(param string) (param string) (param string) (param string)
)
(into $i)
(func $i "take-i32")
(param string) (param string) (param string) (param string)
(param string) (param string) (param string) (param string)
(param string) (param string) (param string) (param string)
(canon lift
(core func $i "take-i32")
(memory $i "memory")
(realloc (func $i "realloc"))
)
)
(func (export "string-ret")
(canon.lift (func (result string)) (into $i) (func $i "ret-1"))
(func (export "string-ret") (result string)
(canon lift
(core func $i "ret-1")
(memory $i "memory")
(realloc (func $i "realloc"))
)
)
(func (export "list-u32-ret")
(canon.lift (func (result (list u32))) (into $i) (func $i "ret-unaligned-list"))
(func (export "list-u32-ret") (result (list u32))
(canon lift
(core func $i "ret-unaligned-list")
(memory $i "memory")
(realloc (func $i "realloc"))
)
)
)"#
);

View File

@@ -7,20 +7,18 @@ use wasmtime::{Store, StoreContextMut, Trap};
fn can_compile() -> Result<()> {
let engine = super::engine();
let libc = r#"
(module $libc
(core module $libc
(memory (export "memory") 1)
(func (export "canonical_abi_realloc") (param i32 i32 i32 i32) (result i32)
unreachable)
(func (export "canonical_abi_free") (param i32 i32 i32)
(func (export "realloc") (param i32 i32 i32 i32) (result i32)
unreachable)
)
(instance $libc (instantiate (module $libc)))
(core instance $libc (instantiate $libc))
"#;
Component::new(
&engine,
r#"(component
(import "" (func $f))
(func (canon.lower (func $f)))
(core func (canon lower (func $f)))
)"#,
)?;
Component::new(
@@ -29,7 +27,7 @@ fn can_compile() -> Result<()> {
r#"(component
(import "" (func $f (param string)))
{libc}
(func (canon.lower (into $libc) (func $f)))
(core func (canon lower (func $f) (memory $libc "memory") (realloc (func $libc "realloc"))))
)"#
),
)?;
@@ -39,14 +37,14 @@ fn can_compile() -> Result<()> {
r#"(component
(import "f1" (func $f1 (param string) (result string)))
{libc}
(func (canon.lower (into $libc) (func $f1)))
(core func (canon lower (func $f1) (memory $libc "memory") (realloc (func $libc "realloc"))))
(import "f2" (func $f2 (param u32) (result (list u8))))
(instance $libc2 (instantiate (module $libc)))
(func (canon.lower (into $libc2) (func $f2)))
(core instance $libc2 (instantiate $libc))
(core func (canon lower (func $f2) (memory $libc2 "memory") (realloc (func $libc2 "realloc"))))
(func (canon.lower (into $libc2) (func $f1)))
(func (canon.lower (into $libc) (func $f2)))
(core func (canon lower (func $f1) (memory $libc2 "memory") (realloc (func $libc2 "realloc"))))
(core func (canon lower (func $f2) (memory $libc "memory") (realloc (func $libc "realloc"))))
)"#
),
)?;
@@ -56,9 +54,9 @@ fn can_compile() -> Result<()> {
r#"(component
(import "log" (func $log (param string)))
{libc}
(func $log_lower (canon.lower (into $libc) (func $log)))
(core func $log_lower (canon lower (func $log) (memory $libc "memory") (realloc (func $libc "realloc"))))
(module $logger
(core module $logger
(import "host" "log" (func $log (param i32 i32)))
(import "libc" "memory" (memory 1))
@@ -67,13 +65,13 @@ fn can_compile() -> Result<()> {
i32.const 0
call $log)
)
(instance $logger (instantiate (module $logger)
(core instance $logger (instantiate $logger
(with "host" (instance (export "log" (func $log_lower))))
(with "libc" (instance $libc))
))
(func (export "call")
(canon.lift (func) (func $logger "call"))
(canon lift (core func $logger "call"))
)
)"#
),
@@ -87,19 +85,17 @@ fn simple() -> Result<()> {
(component
(import "" (func $log (param string)))
(module $libc
(core module $libc
(memory (export "memory") 1)
(func (export "canonical_abi_realloc") (param i32 i32 i32 i32) (result i32)
unreachable)
(func (export "canonical_abi_free") (param i32 i32 i32)
(func (export "realloc") (param i32 i32 i32 i32) (result i32)
unreachable)
)
(instance $libc (instantiate (module $libc)))
(func $log_lower
(canon.lower (into $libc) (func $log))
(core instance $libc (instantiate $libc))
(core func $log_lower
(canon lower (func $log) (memory $libc "memory") (realloc (func $libc "realloc")))
)
(module $m
(core module $m
(import "libc" "memory" (memory 1))
(import "host" "log" (func $log (param i32 i32)))
@@ -110,12 +106,12 @@ fn simple() -> Result<()> {
(data (i32.const 5) "hello world")
)
(instance $i (instantiate (module $m)
(core instance $i (instantiate $m
(with "libc" (instance $libc))
(with "host" (instance (export "log" (func $log_lower))))
))
(func (export "call")
(canon.lift (func) (func $i "call"))
(canon lift (core func $i "call"))
)
)
"#;
@@ -150,7 +146,7 @@ fn attempt_to_leave_during_malloc() -> Result<()> {
(import "thunk" (func $thunk))
(import "ret-string" (func $ret_string (result string)))
(module $host_shim
(core module $host_shim
(table (export "table") 2 funcref)
(func $shim_thunk (export "thunk")
i32.const 0
@@ -160,21 +156,18 @@ fn attempt_to_leave_during_malloc() -> Result<()> {
i32.const 1
call_indirect (param i32))
)
(instance $host_shim (instantiate (module $host_shim)))
(core instance $host_shim (instantiate $host_shim))
(module $m
(core module $m
(import "host" "thunk" (func $thunk))
(import "host" "ret-string" (func $ret_string (param i32)))
(memory (export "memory") 1)
(func $realloc (export "canonical_abi_realloc") (param i32 i32 i32 i32) (result i32)
(func $realloc (export "realloc") (param i32 i32 i32 i32) (result i32)
call $thunk
unreachable)
(func (export "canonical_abi_free") (param i32 i32 i32)
unreachable)
(func $run (export "run")
i32.const 8
call $ret_string)
@@ -182,24 +175,24 @@ fn attempt_to_leave_during_malloc() -> Result<()> {
(func (export "take-string") (param i32 i32)
unreachable)
)
(instance $m (instantiate (module $m) (with "host" (instance $host_shim))))
(core instance $m (instantiate $m (with "host" (instance $host_shim))))
(module $host_shim_filler_inner
(core module $host_shim_filler_inner
(import "shim" "table" (table 2 funcref))
(import "host" "thunk" (func $thunk))
(import "host" "ret-string" (func $ret_string (param i32)))
(elem (i32.const 0) $thunk $ret_string)
)
(func $thunk_lower
(canon.lower (into $m) (func $thunk))
(core func $thunk_lower
(canon lower (func $thunk) (memory $m "memory") (realloc (func $m "realloc")))
)
(func $ret_string_lower
(canon.lower (into $m) (func $ret_string))
(core func $ret_string_lower
(canon lower (func $ret_string) (memory $m "memory") (realloc (func $m "realloc")))
)
(instance (instantiate (module $host_shim_filler_inner)
(core instance (instantiate $host_shim_filler_inner
(with "shim" (instance $host_shim))
(with "host" (instance
(export "thunk" (func $thunk_lower))
@@ -208,10 +201,10 @@ fn attempt_to_leave_during_malloc() -> Result<()> {
))
(func (export "run")
(canon.lift (func) (func $m "run"))
(canon lift (core func $m "run"))
)
(func (export "take-string")
(canon.lift (func (param string)) (into $m) (func $m "take-string"))
(func (export "take-string") (param string)
(canon lift (core func $m "take-string") (memory $m "memory") (realloc (func $m "realloc")))
)
)
"#;
@@ -287,20 +280,20 @@ fn attempt_to_reenter_during_host() -> Result<()> {
let component = r#"
(component
(import "thunk" (func $thunk))
(func $thunk_lower (canon.lower (func $thunk)))
(core func $thunk_lower (canon lower (func $thunk)))
(module $m
(core module $m
(import "host" "thunk" (func $thunk))
(func $run (export "run")
call $thunk)
)
(instance $m (instantiate (module $m)
(core instance $m (instantiate $m
(with "host" (instance (export "thunk" (func $thunk_lower))))
))
(func (export "run")
(canon.lift (func) (func $m "run"))
(canon lift (core func $m "run"))
)
)
"#;
@@ -348,18 +341,18 @@ fn stack_and_heap_args_and_rets() -> Result<()> {
(import "f3" (func $f3 (param u32) (result string)))
(import "f4" (func $f4 (param $many_params) (result string)))
(module $libc
(core module $libc
{REALLOC_AND_FREE}
(memory (export "memory") 1)
)
(instance $libc (instantiate (module $libc)))
(core instance $libc (instantiate (module $libc)))
(func $f1_lower (canon.lower (into $libc) (func $f1)))
(func $f2_lower (canon.lower (into $libc) (func $f2)))
(func $f3_lower (canon.lower (into $libc) (func $f3)))
(func $f4_lower (canon.lower (into $libc) (func $f4)))
(core func $f1_lower (canon lower (func $f1) (memory $libc "memory") (realloc (func $libc "realloc"))))
(core func $f2_lower (canon lower (func $f2) (memory $libc "memory") (realloc (func $libc "realloc"))))
(core func $f3_lower (canon lower (func $f3) (memory $libc "memory") (realloc (func $libc "realloc"))))
(core func $f4_lower (canon lower (func $f4) (memory $libc "memory") (realloc (func $libc "realloc"))))
(module $m
(core module $m
(import "host" "f1" (func $f1 (param i32) (result i32)))
(import "host" "f2" (func $f2 (param i32) (result i32)))
(import "host" "f3" (func $f3 (param i32 i32)))
@@ -454,7 +447,7 @@ fn stack_and_heap_args_and_rets() -> Result<()> {
(data (i32.const 1000) "abc")
)
(instance $m (instantiate (module $m)
(core instance $m (instantiate $m
(with "libc" (instance $libc))
(with "host" (instance
(export "f1" (func $f1_lower))
@@ -465,7 +458,7 @@ fn stack_and_heap_args_and_rets() -> Result<()> {
))
(func (export "run")
(canon.lift (func) (func $m "run"))
(canon lift (core func $m "run"))
)
)
"#
@@ -542,23 +535,21 @@ fn bad_import_alignment() -> Result<()> {
string
))
(import "unaligned-argptr" (func $unaligned_argptr (param $many_arg)))
(module $libc_panic
(core module $libc_panic
(memory (export "memory") 1)
(func (export "canonical_abi_realloc") (param i32 i32 i32 i32) (result i32)
unreachable)
(func (export "canonical_abi_free") (param i32 i32 i32)
(func (export "realloc") (param i32 i32 i32 i32) (result i32)
unreachable)
)
(instance $libc_panic (instantiate (module $libc_panic)))
(core instance $libc_panic (instantiate $libc_panic))
(func $unaligned_retptr_lower
(canon.lower (into $libc_panic) (func $unaligned_retptr))
(core func $unaligned_retptr_lower
(canon lower (func $unaligned_retptr) (memory $libc_panic "memory") (realloc (func $libc_panic "realloc")))
)
(func $unaligned_argptr_lower
(canon.lower (into $libc_panic) (func $unaligned_argptr))
(core func $unaligned_argptr_lower
(canon lower (func $unaligned_argptr) (memory $libc_panic "memory") (realloc (func $libc_panic "realloc")))
)
(module $m
(core module $m
(import "host" "unaligned-retptr" (func $unaligned_retptr (param i32)))
(import "host" "unaligned-argptr" (func $unaligned_argptr (param i32)))
@@ -567,7 +558,7 @@ fn bad_import_alignment() -> Result<()> {
(func (export "unaligned-argptr")
(call $unaligned_argptr (i32.const 1)))
)
(instance $m (instantiate (module $m)
(core instance $m (instantiate $m
(with "host" (instance
(export "unaligned-retptr" (func $unaligned_retptr_lower))
(export "unaligned-argptr" (func $unaligned_argptr_lower))
@@ -575,10 +566,10 @@ fn bad_import_alignment() -> Result<()> {
))
(func (export "unaligned-retptr")
(canon.lift (func) (func $m "unaligned-retptr"))
(canon lift (core func $m "unaligned-retptr"))
)
(func (export "unaligned-argptr")
(canon.lift (func) (func $m "unaligned-argptr"))
(canon lift (core func $m "unaligned-argptr"))
)
)
"#

View File

@@ -1,54 +1,72 @@
;; basic function lifting
(component
(module $m
(core module $m
(func (export ""))
)
(instance $i (instantiate (module $m)))
(core instance $i (instantiate $m))
(func (export "thunk")
(canon.lift (func) (func $i ""))
(canon lift (core func $i ""))
)
)
;; use an aliased type
(component $c
(module $m
(core module $m
(func (export ""))
)
(instance $i (instantiate (module $m)))
(core instance $i (instantiate $m))
(type $to_alias (func))
(alias outer $c $to_alias (type $alias))
(func (export "thunk")
(canon.lift (type $alias) (func $i ""))
(func (export "thunk") (type $alias)
(canon lift (core func $i ""))
)
)
;; test out some various canonical abi
(component $c
(module $m
(core module $m
(func (export "") (param i32 i32))
(memory (export "memory") 1)
(func (export "canonical_abi_realloc") (param i32 i32 i32 i32) (result i32)
(func (export "realloc") (param i32 i32 i32 i32) (result i32)
unreachable)
(func (export "canonical_abi_free") (param i32 i32 i32))
)
(instance $i (instantiate (module $m)))
(core instance $i (instantiate $m))
(func (export "thunk")
(canon.lift (func (param string)) (into $i) (func $i ""))
(func (export "thunk") (param string)
(canon lift
(core func $i "")
(memory $i "memory")
(realloc (func $i "realloc"))
)
)
(func (export "thunk8")
(canon.lift (func (param string)) string=utf8 (into $i) (func $i ""))
(func (export "thunk8") (param string)
(canon lift
(core func $i "")
string-encoding=utf8
(memory $i "memory")
(realloc (func $i "realloc"))
)
)
(func (export "thunk16")
(canon.lift (func (param string)) string=utf16 (into $i) (func $i ""))
(func (export "thunk16") (param string)
(canon lift
(core func $i "")
string-encoding=utf16
(memory $i "memory")
(realloc (func $i "realloc"))
)
)
(func (export "thunklatin16")
(canon.lift (func (param string)) string=latin1+utf16 (into $i) (func $i ""))
(func (export "thunklatin16") (param string)
(canon lift
(core func $i "")
string-encoding=latin1+utf16
(memory $i "memory")
(realloc (func $i "realloc"))
)
)
)

View File

@@ -1,30 +1,30 @@
(component
(module $m)
(instance (instantiate (module $m)))
(core module $m)
(core instance (instantiate $m))
)
(component
(module $m
(core module $m
(func (export ""))
)
(instance $i (instantiate (module $m)))
(core instance $i (instantiate $m))
(module $m2
(core module $m2
(func (import "" ""))
)
(instance (instantiate (module $m2) (with "" (instance $i))))
(core instance (instantiate $m2 (with "" (instance $i))))
)
(component
(module $m
(core module $m
(func (export "a"))
)
(instance $i (instantiate (module $m)))
(core instance $i (instantiate $m))
(module $m2
(core module $m2
(func (import "" "b"))
)
(instance (instantiate (module $m2)
(core instance (instantiate $m2
(with "" (instance (export "b" (func $i "a"))))
))
)
@@ -32,15 +32,15 @@
;; all kinds of imports for core wasm modules, and register a start function on
;; one module to ensure that everything is correct
(component
(module $m
(core module $m
(func (export "a"))
(table (export "b") 1 funcref)
(memory (export "c") 1)
(global (export "d") i32 i32.const 1)
)
(instance $i (instantiate (module $m)))
(core instance $i (instantiate $m))
(module $m2
(core module $m2
(import "" "a" (func $f))
(import "" "b" (table 1 funcref))
(import "" "c" (memory 1))
@@ -62,7 +62,7 @@
(data (i32.const 0) "hello")
(elem (i32.const 0) $start)
)
(instance (instantiate (module $m2)
(core instance (instantiate $m2
(with "" (instance $i))
))
)
@@ -71,12 +71,12 @@
;; sees the wrong value for the global import
(assert_trap
(component
(module $m
(core module $m
(global (export "g") i32 i32.const 1)
)
(instance $i (instantiate (module $m)))
(core instance $i (instantiate $m))
(module $m2
(core module $m2
(import "" "g" (global $g i32))
(func $start
@@ -90,27 +90,27 @@
(start $start)
)
(instance (instantiate (module $m2) (with "" (instance $i))))
(core instance (instantiate $m2 (with "" (instance $i))))
)
"unreachable")
;; shuffle around imports to get to what the target core wasm module needs
(component
(module $m
(core module $m
(func (export "1"))
(table (export "2") 1 funcref)
(memory (export "3") 1)
(global (export "4") i32 i32.const 1)
)
(instance $i (instantiate (module $m)))
(core instance $i (instantiate $m))
(module $m2
(core module $m2
(import "" "a" (func $f))
(import "" "b" (table 1 funcref))
(import "" "c" (memory 1))
(import "" "d" (global $g i32))
)
(instance (instantiate (module $m2)
(core instance (instantiate $m2
(with "" (instance
(export "a" (func $i "1"))
(export "b" (table $i "2"))

View File

@@ -1,6 +1,6 @@
(assert_unlinkable
(component
(import "undefined-name" (module))
(import "undefined-name" (core module))
)
"import `undefined-name` not defined")
(component $i)
@@ -8,7 +8,7 @@
(import "i" (instance))
)
(assert_unlinkable
(component (import "i" (module)))
(component (import "i" (core module)))
"expected module found instance")
(assert_unlinkable
(component (import "i" (func)))

View File

@@ -1,18 +1,18 @@
(component $foo
(module (export "a-module"))
(core module (export "a-module"))
)
;; the above instance can be imported into this component
(component
(import "foo" (instance
(export "a-module" (module))
(export "a-module" (core module))
))
)
;; specifying extra imports is ok
(component
(import "foo" (instance
(export "a-module" (module
(export "a-module" (core module
(import "foo" "bar" (func))
))
))
@@ -22,7 +22,7 @@
(assert_unlinkable
(component
(import "foo" (instance
(export "a-module" (module
(export "a-module" (core module
(export "the-export" (func))
))
))
@@ -30,7 +30,7 @@
"module export `the-export` not defined")
(component $foo
(module (export "a-module")
(core module (export "a-module")
(import "env" "something" (func))
)
)
@@ -39,14 +39,14 @@
(assert_unlinkable
(component
(import "foo" (instance
(export "a-module" (module))
(export "a-module" (core module))
))
)
"module import `env::something` not defined")
(component
(import "foo" (instance
(export "a-module" (module
(export "a-module" (core module
(import "env" "something" (func))
))
))
@@ -55,7 +55,7 @@
;; extra imports still ok
(component
(import "foo" (instance
(export "a-module" (module
(export "a-module" (core module
(import "env" "something" (func))
(import "env" "other" (global i32))
))
@@ -63,7 +63,7 @@
)
(component $foo
(module (export "a-module")
(core module (export "a-module")
(func (export "f"))
)
)
@@ -71,13 +71,13 @@
;; dropping exports is ok
(component
(import "foo" (instance
(export "a-module" (module))
(export "a-module" (core module))
))
)
(component
(import "foo" (instance
(export "a-module" (module
(export "a-module" (core module
(export "f" (func))
))
))
@@ -86,7 +86,7 @@
(assert_unlinkable
(component
(import "foo" (instance
(export "a-module" (module
(export "a-module" (core module
(export "f" (func (param i32)))
))
))
@@ -96,7 +96,7 @@
(assert_unlinkable
(component
(import "foo" (instance
(export "a-module" (module
(export "a-module" (core module
(export "f" (global i32))
))
))
@@ -104,7 +104,7 @@
"expected global found func")
(component $foo
(module (export "m")
(core module (export "m")
(func (export "f"))
(table (export "t") 1 funcref)
(memory (export "m") 1)
@@ -116,28 +116,28 @@
(assert_unlinkable
(component
(import "foo" (instance
(export "m" (module (export "f" (global i32))))
(export "m" (core module (export "f" (global i32))))
))
)
"expected global found func")
(assert_unlinkable
(component
(import "foo" (instance
(export "m" (module (export "t" (func))))
(export "m" (core module (export "t" (func))))
))
)
"expected func found table")
(assert_unlinkable
(component
(import "foo" (instance
(export "m" (module (export "m" (func))))
(export "m" (core module (export "m" (func))))
))
)
"expected func found memory")
(assert_unlinkable
(component
(import "foo" (instance
(export "m" (module (export "g" (func))))
(export "m" (core module (export "g" (func))))
))
)
"expected func found global")
@@ -146,42 +146,42 @@
(assert_unlinkable
(component
(import "foo" (instance
(export "m" (module (export "f" (func (param i32)))))
(export "m" (core module (export "f" (func (param i32)))))
))
)
"export `f` has the wrong type")
(assert_unlinkable
(component
(import "foo" (instance
(export "m" (module (export "t" (table 1 externref))))
(export "m" (core module (export "t" (table 1 externref))))
))
)
"export `t` has the wrong type")
(assert_unlinkable
(component
(import "foo" (instance
(export "m" (module (export "t" (table 2 funcref))))
(export "m" (core module (export "t" (table 2 funcref))))
))
)
"export `t` has the wrong type")
(assert_unlinkable
(component
(import "foo" (instance
(export "m" (module (export "m" (memory 2))))
(export "m" (core module (export "m" (memory 2))))
))
)
"export `m` has the wrong type")
(assert_unlinkable
(component
(import "foo" (instance
(export "m" (module (export "g" (global f32))))
(export "m" (core module (export "g" (global f32))))
))
)
"export `g` has the wrong type")
(assert_unlinkable
(component
(import "foo" (instance
(export "m" (module (export "g" (global (mut i32)))))
(export "m" (core module (export "g" (global (mut i32)))))
))
)
"export `g` has the wrong type")
@@ -189,7 +189,7 @@
;; subtyping ok
(component
(import "foo" (instance
(export "m" (module
(export "m" (core module
(export "t" (table 0 funcref))
(export "m" (memory 0))
))
@@ -197,38 +197,38 @@
)
(component $foo
(module (export "f") (func (import "" "")))
(module (export "t") (table (import "" "") 1 funcref))
(module (export "m") (memory (import "" "") 1))
(module (export "g") (global (import "" "") i32))
(core module (export "f") (func (import "" "")))
(core module (export "t") (table (import "" "") 1 funcref))
(core module (export "m") (memory (import "" "") 1))
(core module (export "g") (global (import "" "") i32))
)
;; wrong class of item
(assert_unlinkable
(component
(import "foo" (instance
(export "f" (module (import "" "" (global i32))))
(export "f" (core module (import "" "" (global i32))))
))
)
"expected func found global")
(assert_unlinkable
(component
(import "foo" (instance
(export "t" (module (import "" "" (func))))
(export "t" (core module (import "" "" (func))))
))
)
"expected table found func")
(assert_unlinkable
(component
(import "foo" (instance
(export "m" (module (import "" "" (func))))
(export "m" (core module (import "" "" (func))))
))
)
"expected memory found func")
(assert_unlinkable
(component
(import "foo" (instance
(export "g" (module (import "" "" (func))))
(export "g" (core module (import "" "" (func))))
))
)
"expected global found func")
@@ -237,42 +237,42 @@
(assert_unlinkable
(component
(import "foo" (instance
(export "f" (module (import "" "" (func (param i32)))))
(export "f" (core module (import "" "" (func (param i32)))))
))
)
"module import `::` has the wrong type")
(assert_unlinkable
(component
(import "foo" (instance
(export "t" (module (import "" "" (table 1 externref))))
(export "t" (core module (import "" "" (table 1 externref))))
))
)
"module import `::` has the wrong type")
(assert_unlinkable
(component
(import "foo" (instance
(export "t" (module (import "" "" (table 0 funcref))))
(export "t" (core module (import "" "" (table 0 funcref))))
))
)
"module import `::` has the wrong type")
(assert_unlinkable
(component
(import "foo" (instance
(export "m" (module (import "" "" (memory 0))))
(export "m" (core module (import "" "" (memory 0))))
))
)
"module import `::` has the wrong type")
(assert_unlinkable
(component
(import "foo" (instance
(export "g" (module (import "" "" (global f32))))
(export "g" (core module (import "" "" (global f32))))
))
)
"module import `::` has the wrong type")
(assert_unlinkable
(component
(import "foo" (instance
(export "g" (module (import "" "" (global (mut i32)))))
(export "g" (core module (import "" "" (global (mut i32)))))
))
)
"module import `::` has the wrong type")
@@ -280,45 +280,45 @@
;; subtyping ok, but in the opposite direction of imports
(component
(import "foo" (instance
(export "t" (module (import "" "" (table 2 funcref))))
(export "m" (module (import "" "" (memory 2))))
(export "t" (core module (import "" "" (table 2 funcref))))
(export "m" (core module (import "" "" (memory 2))))
))
)
;; An instance can reexport a module, define a module, and everything can be
;; used by something else
(component $src
(module (export "m")
(core module (export "m")
(global (export "g") i32 i32.const 2)
)
)
(component $reexport
(module $m1
(core module $m1
(global (export "g") i32 i32.const 1)
)
(import "src" (instance $src
(export "m" (module (export "g" (global i32))))
(export "m" (core module (export "g" (global i32))))
))
(module $m3
(core module $m3
(global (export "g") i32 i32.const 3)
)
(export "m1" (module $m1))
(export "m2" (module $src "m"))
(export "m3" (module $m3))
(export "m1" (core module $m1))
(export "m2" (core module $src "m"))
(export "m3" (core module $m3))
)
(component
(type $modulety (module (export "g" (global i32))))
(core type $modulety (module (export "g" (global i32))))
(import "reexport" (instance $reexport
(export "m1" (module (type $modulety)))
(export "m2" (module (type $modulety)))
(export "m3" (module (type $modulety)))
(export "m1" (core module (type $modulety)))
(export "m2" (core module (type $modulety)))
(export "m3" (core module (type $modulety)))
))
(module $assert_ok
(core module $assert_ok
(import "m1" "g" (global $m1 i32))
(import "m2" "g" (global $m2 i32))
(import "m3" "g" (global $m3 i32))
@@ -350,11 +350,11 @@
(start $assert_ok)
)
(instance $m1 (instantiate (module $reexport "m1")))
(instance $m2 (instantiate (module $reexport "m2")))
(instance $m3 (instantiate (module $reexport "m3")))
(core instance $m1 (instantiate (module $reexport "m1")))
(core instance $m2 (instantiate (module $reexport "m2")))
(core instance $m3 (instantiate (module $reexport "m3")))
(instance (instantiate (module $assert_ok)
(core instance (instantiate $assert_ok
(with "m1" (instance $m1))
(with "m2" (instance $m2))
(with "m3" (instance $m3))
@@ -364,7 +364,7 @@
;; order of imports and exports can be shuffled between definition site and
;; use-site
(component $provider
(module (export "m")
(core module (export "m")
(import "" "1" (global $i1 i32))
(import "" "2" (global $i2 i32))
(import "" "3" (global $i3 i32))
@@ -413,7 +413,7 @@
(component
(import "provider" (instance $provider
(export "m" (module
(export "m" (core module
(import "" "4" (global i32))
(import "" "3" (global i32))
(import "" "2" (global i32))
@@ -426,18 +426,18 @@
))
))
(module $imports
(core module $imports
(global (export "1") i32 (i32.const 1))
(global (export "3") i32 (i32.const 3))
(global (export "2") i32 (i32.const 2))
(global (export "4") i32 (i32.const 4))
)
(instance $imports (instantiate (module $imports)))
(instance $m (instantiate (module $provider "m")
(core instance $imports (instantiate $imports))
(core instance $m (instantiate (module $provider "m")
(with "" (instance $imports))
))
(module $import_globals
(core module $import_globals
(import "" "g4" (global $g4 i32))
(import "" "g3" (global $g3 i32))
(import "" "g2" (global $g2 i32))
@@ -473,5 +473,5 @@
(start $assert_imports)
)
(instance (instantiate (module $import_globals) (with "" (instance $m))))
(core instance (instantiate $import_globals (with "" (instance $m))))
)

View File

@@ -1,21 +1,21 @@
(component)
(component
(module)
(core module)
)
(component
(module)
(module)
(module)
(core module)
(core module)
(core module)
)
(component
(module
(core module
(func (export "a") (result i32) i32.const 0)
(func (export "b") (result i64) i64.const 0)
)
(module
(core module
(func (export "c") (result f32) f32.const 0)
(func (export "d") (result f64) f64.const 0)
)

View File

@@ -52,7 +52,8 @@
(type $empty (func))
(type (func (param string) (result u32)))
(type (component))
(type (module))
(core type (module))
(core type (func))
(type (instance))
(type (component
@@ -62,7 +63,7 @@
(type $t (instance))
(export "a" (module))
(export "a" (core module))
(export "b" (instance (type $t)))
))
@@ -73,11 +74,11 @@
(type $t (instance))
(export "a" (module))
(export "a" (core module))
(export "b" (instance (type $t)))
))
(type (module
(core type (module
(import "" "" (func (param i32)))
(import "" "1" (func (result i32)))
(export "1" (global i32))