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

View File

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

View File

@@ -12,7 +12,7 @@ keywords = ["webassembly", "wasm"]
edition = "2021" edition = "2021"
[dependencies] [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-codegen = { path = "../codegen", version = "0.86.0", default-features = false }
cranelift-entity = { path = "../entity", version = "0.86.0" } cranelift-entity = { path = "../entity", version = "0.86.0" }
cranelift-frontend = { path = "../frontend", version = "0.86.0", default-features = false } 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)); builder.set_srcloc(cur_srcloc(reader));
let pos = reader.original_position(); let pos = reader.original_position();
let count = reader.read_var_u32()?; let count = reader.read_var_u32()?;
let ty = reader.read_type()?; let ty = reader.read_val_type()?;
validator.define_locals(pos, count, ty)?; validator.define_locals(pos, count, ty)?;
declare_locals(builder, count, ty, &mut next_local, environ)?; 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>( fn declare_locals<FE: FuncEnvironment + ?Sized>(
builder: &mut FunctionBuilder, builder: &mut FunctionBuilder,
count: u32, count: u32,
wasm_type: wasmparser::Type, wasm_type: wasmparser::ValType,
next_local: &mut usize, next_local: &mut usize,
environ: &mut FE, environ: &mut FE,
) -> WasmResult<()> { ) -> WasmResult<()> {
// All locals are initialized to 0. // All locals are initialized to 0.
use wasmparser::Type::*; use wasmparser::ValType::*;
let zeroval = match wasm_type { let zeroval = match wasm_type {
I32 => builder.ins().iconst(ir::types::I32, 0), I32 => builder.ins().iconst(ir::types::I32, 0),
I64 => builder.ins().iconst(ir::types::I64, 0), I64 => builder.ins().iconst(ir::types::I64, 0),

View File

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

View File

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

View File

@@ -21,16 +21,16 @@ pub enum TableElementType {
/// Helper function translating wasmparser types to Cranelift types when possible. /// Helper function translating wasmparser types to Cranelift types when possible.
pub fn type_to_type<PE: TargetEnvironment + ?Sized>( pub fn type_to_type<PE: TargetEnvironment + ?Sized>(
ty: wasmparser::Type, ty: wasmparser::ValType,
environ: &PE, environ: &PE,
) -> WasmResult<ir::Type> { ) -> WasmResult<ir::Type> {
match ty { match ty {
wasmparser::Type::I32 => Ok(ir::types::I32), wasmparser::ValType::I32 => Ok(ir::types::I32),
wasmparser::Type::I64 => Ok(ir::types::I64), wasmparser::ValType::I64 => Ok(ir::types::I64),
wasmparser::Type::F32 => Ok(ir::types::F32), wasmparser::ValType::F32 => Ok(ir::types::F32),
wasmparser::Type::F64 => Ok(ir::types::F64), wasmparser::ValType::F64 => Ok(ir::types::F64),
wasmparser::Type::V128 => Ok(ir::types::I8X16), wasmparser::ValType::V128 => Ok(ir::types::I8X16),
wasmparser::Type::ExternRef | wasmparser::Type::FuncRef => { wasmparser::ValType::ExternRef | wasmparser::ValType::FuncRef => {
Ok(environ.reference_type(ty.try_into()?)) 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, /// Helper function translating wasmparser possible table types to Cranelift types when possible,
/// or None for Func tables. /// or None for Func tables.
pub fn tabletype_to_type<PE: TargetEnvironment + ?Sized>( pub fn tabletype_to_type<PE: TargetEnvironment + ?Sized>(
ty: wasmparser::Type, ty: wasmparser::ValType,
environ: &PE, environ: &PE,
) -> WasmResult<Option<ir::Type>> { ) -> WasmResult<Option<ir::Type>> {
match ty { match ty {
wasmparser::Type::I32 => Ok(Some(ir::types::I32)), wasmparser::ValType::I32 => Ok(Some(ir::types::I32)),
wasmparser::Type::I64 => Ok(Some(ir::types::I64)), wasmparser::ValType::I64 => Ok(Some(ir::types::I64)),
wasmparser::Type::F32 => Ok(Some(ir::types::F32)), wasmparser::ValType::F32 => Ok(Some(ir::types::F32)),
wasmparser::Type::F64 => Ok(Some(ir::types::F64)), wasmparser::ValType::F64 => Ok(Some(ir::types::F64)),
wasmparser::Type::V128 => Ok(Some(ir::types::I8X16)), wasmparser::ValType::V128 => Ok(Some(ir::types::I8X16)),
wasmparser::Type::ExternRef => Ok(Some(environ.reference_type(ty.try_into()?))), wasmparser::ValType::ExternRef => Ok(Some(environ.reference_type(ty.try_into()?))),
wasmparser::Type::FuncRef => Ok(None), wasmparser::ValType::FuncRef => Ok(None),
} }
} }
@@ -58,31 +58,31 @@ pub fn blocktype_params_results<'a, T>(
validator: &'a FuncValidator<T>, validator: &'a FuncValidator<T>,
ty: wasmparser::BlockType, ty: wasmparser::BlockType,
) -> WasmResult<( ) -> WasmResult<(
impl ExactSizeIterator<Item = wasmparser::Type> + Clone + 'a, impl ExactSizeIterator<Item = wasmparser::ValType> + Clone + 'a,
impl ExactSizeIterator<Item = wasmparser::Type> + Clone + 'a, impl ExactSizeIterator<Item = wasmparser::ValType> + Clone + 'a,
)> )>
where where
T: WasmModuleResources, T: WasmModuleResources,
{ {
return Ok(match ty { return Ok(match ty {
wasmparser::BlockType::Empty => { wasmparser::BlockType::Empty => {
let params: &'static [wasmparser::Type] = &[]; let params: &'static [wasmparser::ValType] = &[];
let results: &'static [wasmparser::Type] = &[]; let results: &'static [wasmparser::ValType] = &[];
( (
itertools::Either::Left(params.iter().copied()), itertools::Either::Left(params.iter().copied()),
itertools::Either::Left(results.iter().copied()), itertools::Either::Left(results.iter().copied()),
) )
} }
wasmparser::BlockType::Type(ty) => { wasmparser::BlockType::Type(ty) => {
let params: &'static [wasmparser::Type] = &[]; let params: &'static [wasmparser::ValType] = &[];
let results: &'static [wasmparser::Type] = match ty { let results: &'static [wasmparser::ValType] = match ty {
wasmparser::Type::I32 => &[wasmparser::Type::I32], wasmparser::ValType::I32 => &[wasmparser::ValType::I32],
wasmparser::Type::I64 => &[wasmparser::Type::I64], wasmparser::ValType::I64 => &[wasmparser::ValType::I64],
wasmparser::Type::F32 => &[wasmparser::Type::F32], wasmparser::ValType::F32 => &[wasmparser::ValType::F32],
wasmparser::Type::F64 => &[wasmparser::Type::F64], wasmparser::ValType::F64 => &[wasmparser::ValType::F64],
wasmparser::Type::V128 => &[wasmparser::Type::V128], wasmparser::ValType::V128 => &[wasmparser::ValType::V128],
wasmparser::Type::ExternRef => &[wasmparser::Type::ExternRef], wasmparser::ValType::ExternRef => &[wasmparser::ValType::ExternRef],
wasmparser::Type::FuncRef => &[wasmparser::Type::FuncRef], wasmparser::ValType::FuncRef => &[wasmparser::ValType::FuncRef],
}; };
( (
itertools::Either::Left(params.iter().copied()), itertools::Either::Left(params.iter().copied()),
@@ -105,28 +105,28 @@ where
/// Create a `Block` with the given Wasm parameters. /// Create a `Block` with the given Wasm parameters.
pub fn block_with_params<PE: TargetEnvironment + ?Sized>( pub fn block_with_params<PE: TargetEnvironment + ?Sized>(
builder: &mut FunctionBuilder, builder: &mut FunctionBuilder,
params: impl IntoIterator<Item = wasmparser::Type>, params: impl IntoIterator<Item = wasmparser::ValType>,
environ: &PE, environ: &PE,
) -> WasmResult<ir::Block> { ) -> WasmResult<ir::Block> {
let block = builder.create_block(); let block = builder.create_block();
for ty in params { for ty in params {
match ty { match ty {
wasmparser::Type::I32 => { wasmparser::ValType::I32 => {
builder.append_block_param(block, ir::types::I32); builder.append_block_param(block, ir::types::I32);
} }
wasmparser::Type::I64 => { wasmparser::ValType::I64 => {
builder.append_block_param(block, ir::types::I64); builder.append_block_param(block, ir::types::I64);
} }
wasmparser::Type::F32 => { wasmparser::ValType::F32 => {
builder.append_block_param(block, ir::types::F32); builder.append_block_param(block, ir::types::F32);
} }
wasmparser::Type::F64 => { wasmparser::ValType::F64 => {
builder.append_block_param(block, ir::types::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()?)); 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); 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-frontend = { path = "../../cranelift/frontend", version = "0.86.0" }
cranelift-entity = { path = "../../cranelift/entity", version = "0.86.0" } cranelift-entity = { path = "../../cranelift/entity", version = "0.86.0" }
cranelift-native = { path = "../../cranelift/native", 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" target-lexicon = "0.12"
gimli = { version = "0.26.0", default-features = false, features = ['read', 'std'] } gimli = { version = "0.26.0", default-features = false, features = ['read', 'std'] }
object = { version = "0.28.0", default-features = false, features = ['write'] } 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::collections::{HashMap, HashSet};
use std::path::PathBuf; use std::path::PathBuf;
use std::sync::atomic::{AtomicUsize, Ordering::SeqCst}; use std::sync::atomic::{AtomicUsize, Ordering::SeqCst};
use wasmparser::Type as WasmType; use wasmparser::ValType as WasmType;
use wasmtime_environ::{ use wasmtime_environ::{
DebugInfoData, DefinedFuncIndex, EntityRef, FuncIndex, FunctionMetadata, WasmFileInfo, DebugInfoData, DefinedFuncIndex, EntityRef, FuncIndex, FunctionMetadata, WasmFileInfo,
}; };

View File

@@ -14,7 +14,7 @@ edition = "2021"
anyhow = "1.0" anyhow = "1.0"
cranelift-entity = { path = "../../cranelift/entity", version = "0.86.0" } cranelift-entity = { path = "../../cranelift/entity", version = "0.86.0" }
wasmtime-types = { path = "../types", version = "0.39.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"] } indexmap = { version = "1.0.2", features = ["serde-1"] }
thiserror = "1.0.4" thiserror = "1.0.4"
serde = { version = "1.0.94", features = ["derive"] } serde = { version = "1.0.94", features = ["derive"] }

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -12,4 +12,4 @@ edition = "2021"
cranelift-entity = { path = "../../cranelift/entity", version = "0.86.0", features = ['enable-serde'] } cranelift-entity = { path = "../../cranelift/entity", version = "0.86.0", features = ['enable-serde'] }
serde = { version = "1.0.94", features = ["derive"] } serde = { version = "1.0.94", features = ["derive"] }
thiserror = "1.0.4" 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, ExternRef,
} }
impl TryFrom<wasmparser::Type> for WasmType { impl TryFrom<wasmparser::ValType> for WasmType {
type Error = WasmError; type Error = WasmError;
fn try_from(ty: wasmparser::Type) -> Result<Self, Self::Error> { fn try_from(ty: wasmparser::ValType) -> Result<Self, Self::Error> {
use wasmparser::Type::*; use wasmparser::ValType::*;
match ty { match ty {
I32 => Ok(WasmType::I32), I32 => Ok(WasmType::I32),
I64 => Ok(WasmType::I64), I64 => Ok(WasmType::I64),
@@ -47,16 +47,16 @@ impl TryFrom<wasmparser::Type> for WasmType {
} }
} }
impl From<WasmType> for wasmparser::Type { impl From<WasmType> for wasmparser::ValType {
fn from(ty: WasmType) -> wasmparser::Type { fn from(ty: WasmType) -> wasmparser::ValType {
match ty { match ty {
WasmType::I32 => wasmparser::Type::I32, WasmType::I32 => wasmparser::ValType::I32,
WasmType::I64 => wasmparser::Type::I64, WasmType::I64 => wasmparser::ValType::I64,
WasmType::F32 => wasmparser::Type::F32, WasmType::F32 => wasmparser::ValType::F32,
WasmType::F64 => wasmparser::Type::F64, WasmType::F64 => wasmparser::ValType::F64,
WasmType::V128 => wasmparser::Type::V128, WasmType::V128 => wasmparser::ValType::V128,
WasmType::FuncRef => wasmparser::Type::FuncRef, WasmType::FuncRef => wasmparser::ValType::FuncRef,
WasmType::ExternRef => wasmparser::Type::ExternRef, 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-fiber = { path = "../fiber", version = "=0.39.0", optional = true }
wasmtime-cranelift = { path = "../cranelift", 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 } target-lexicon = { version = "0.12.0", default-features = false }
wasmparser = "0.85.0" wasmparser = "0.86.0"
anyhow = "1.0.19" anyhow = "1.0.19"
region = "2.2.0" region = "2.2.0"
libc = "0.2" libc = "0.2"

View File

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

View File

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

View File

@@ -4,7 +4,7 @@ use crate::types::matching;
use crate::Module; use crate::Module;
use anyhow::{anyhow, bail, Context, Result}; use anyhow::{anyhow, bail, Context, Result};
use wasmtime_environ::component::{ use wasmtime_environ::component::{
ComponentInstanceType, ComponentTypes, FuncTypeIndex, ModuleType, TypeDef, ComponentTypes, TypeComponentInstance, TypeDef, TypeFuncIndex, TypeModule,
}; };
pub struct TypeChecker<'a> { pub struct TypeChecker<'a> {
@@ -23,16 +23,19 @@ impl TypeChecker<'_> {
Definition::Instance(actual) => self.instance(&self.types[t], actual), Definition::Instance(actual) => self.instance(&self.types[t], actual),
_ => bail!("expected instance found {}", actual.desc()), _ => bail!("expected instance found {}", actual.desc()),
}, },
TypeDef::Func(t) => match actual { TypeDef::ComponentFunc(t) => match actual {
Definition::Func(actual) => self.func(t, actual), Definition::Func(actual) => self.func(t, actual),
_ => bail!("expected func found {}", actual.desc()), _ => bail!("expected func found {}", actual.desc()),
}, },
TypeDef::Component(_) => bail!("expected component found {}", actual.desc()), TypeDef::Component(_) => bail!("expected component found {}", actual.desc()),
TypeDef::Interface(_) => bail!("expected type 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_types = actual.types();
let actual = actual.env_module(); let actual = actual.env_module();
@@ -63,7 +66,7 @@ impl TypeChecker<'_> {
Ok(()) 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 // 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 // the actual type. It's ok, though, to have extra exports in the actual
// type. // type.
@@ -79,7 +82,7 @@ impl TypeChecker<'_> {
Ok(()) Ok(())
} }
fn func(&self, expected: FuncTypeIndex, actual: &HostFunc) -> Result<()> { fn func(&self, expected: TypeFuncIndex, actual: &HostFunc) -> Result<()> {
actual.typecheck(expected, self.types) actual.typecheck(expected, self.types)
} }
} }

View File

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

View File

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

View File

@@ -12,16 +12,16 @@ const CANON_64BIT_NAN: u64 = 0b0111111111111000000000000000000000000000000000000
fn thunks() -> Result<()> { fn thunks() -> Result<()> {
let component = r#" let component = r#"
(component (component
(module $m (core module $m
(func (export "thunk")) (func (export "thunk"))
(func (export "thunk-trap") unreachable) (func (export "thunk-trap") unreachable)
) )
(instance $i (instantiate (module $m))) (core instance $i (instantiate $m))
(func (export "thunk") (func (export "thunk")
(canon.lift (func) (func $i "thunk")) (canon lift (core func $i "thunk"))
) )
(func (export "thunk-trap") (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<()> { fn typecheck() -> Result<()> {
let component = r#" let component = r#"
(component (component
(module $m (core module $m
(func (export "thunk")) (func (export "thunk"))
(func (export "take-string") (param i32 i32)) (func (export "take-string") (param i32 i32))
(func (export "two-args") (param i32 i32 i32)) (func (export "two-args") (param i32 i32 i32))
(func (export "ret-one") (result i32) unreachable) (func (export "ret-one") (result i32) unreachable)
(memory (export "memory") 1) (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)
unreachable) unreachable)
) )
(instance $i (instantiate (module $m))) (core instance $i (instantiate (module $m)))
(func (export "thunk") (func (export "thunk")
(canon.lift (func) (func $i "thunk")) (canon lift (core func $i "thunk"))
) )
(func (export "tuple-thunk") (func (export "tuple-thunk") (param (tuple)) (result (tuple))
(canon.lift (func (param (tuple)) (result (tuple))) (func $i "thunk")) (canon lift (core func $i "thunk"))
) )
(func (export "take-string") (func (export "take-string") (param string)
(canon.lift (func (param string)) (into $i) (func $i "take-string")) (canon lift (core func $i "take-string") (memory $i "memory") (realloc (func $i "realloc")))
) )
(func (export "take-two-args") (func (export "take-two-args") (param s32) (param (list u8))
(canon.lift (func (param s32) (param (list u8))) (into $i) (func $i "two-args")) (canon lift (core func $i "two-args") (memory $i "memory") (realloc (func $i "realloc")))
) )
(func (export "ret-tuple") (func (export "ret-tuple") (result (tuple u8 s8))
(canon.lift (func (result (tuple u8 s8))) (into $i) (func $i "ret-one")) (canon lift (core func $i "ret-one") (memory $i "memory") (realloc (func $i "realloc")))
) )
(func (export "ret-tuple1") (func (export "ret-tuple1") (result (tuple u32))
(canon.lift (func (result (tuple u32))) (into $i) (func $i "ret-one")) (canon lift (core func $i "ret-one") (memory $i "memory") (realloc (func $i "realloc")))
) )
(func (export "ret-string") (func (export "ret-string") (result string)
(canon.lift (func (result string)) (into $i) (func $i "ret-one")) (canon lift (core func $i "ret-one") (memory $i "memory") (realloc (func $i "realloc")))
) )
(func (export "ret-list-u8") (func (export "ret-list-u8") (result (list u8))
(canon.lift (func (result (list u8))) (into $i) (func $i "ret-one")) (canon lift (core func $i "ret-one") (memory $i "memory") (realloc (func $i "realloc")))
) )
) )
"#; "#;
@@ -129,7 +127,7 @@ fn typecheck() -> Result<()> {
fn integers() -> Result<()> { fn integers() -> Result<()> {
let component = r#" let component = r#"
(component (component
(module $m (core module $m
(func (export "take-i32-100") (param i32) (func (export "take-i32-100") (param i32)
local.get 0 local.get 0
i32.const 100 i32.const 100
@@ -150,40 +148,40 @@ fn integers() -> Result<()> {
(func (export "ret-i64-minus-1") (result i64) i64.const -1) (func (export "ret-i64-minus-1") (result i64) i64.const -1)
(func (export "ret-i32-100000") (result i32) i32.const 100000) (func (export "ret-i32-100000") (result i32) i32.const 100000)
) )
(instance $i (instantiate (module $m))) (core instance $i (instantiate (module $m)))
(func (export "take-u8") (canon.lift (func (param u8)) (func $i "take-i32-100"))) (func (export "take-u8") (param u8) (canon lift (core func $i "take-i32-100")))
(func (export "take-s8") (canon.lift (func (param s8)) (func $i "take-i32-100"))) (func (export "take-s8") (param s8) (canon lift (core func $i "take-i32-100")))
(func (export "take-u16") (canon.lift (func (param u16)) (func $i "take-i32-100"))) (func (export "take-u16") (param u16) (canon lift (core func $i "take-i32-100")))
(func (export "take-s16") (canon.lift (func (param s16)) (func $i "take-i32-100"))) (func (export "take-s16") (param s16) (canon lift (core func $i "take-i32-100")))
(func (export "take-u32") (canon.lift (func (param u32)) (func $i "take-i32-100"))) (func (export "take-u32") (param u32) (canon lift (core func $i "take-i32-100")))
(func (export "take-s32") (canon.lift (func (param s32)) (func $i "take-i32-100"))) (func (export "take-s32") (param s32) (canon lift (core func $i "take-i32-100")))
(func (export "take-u64") (canon.lift (func (param u64)) (func $i "take-i64-100"))) (func (export "take-u64") (param u64) (canon lift (core func $i "take-i64-100")))
(func (export "take-s64") (canon.lift (func (param s64)) (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-u8") (result u8) (canon lift (core func $i "ret-i32-0")))
(func (export "ret-s8") (canon.lift (func (result s8)) (func $i "ret-i32-0"))) (func (export "ret-s8") (result s8) (canon lift (core func $i "ret-i32-0")))
(func (export "ret-u16") (canon.lift (func (result u16)) (func $i "ret-i32-0"))) (func (export "ret-u16") (result u16) (canon lift (core func $i "ret-i32-0")))
(func (export "ret-s16") (canon.lift (func (result s16)) (func $i "ret-i32-0"))) (func (export "ret-s16") (result s16) (canon lift (core func $i "ret-i32-0")))
(func (export "ret-u32") (canon.lift (func (result u32)) (func $i "ret-i32-0"))) (func (export "ret-u32") (result u32) (canon lift (core func $i "ret-i32-0")))
(func (export "ret-s32") (canon.lift (func (result s32)) (func $i "ret-i32-0"))) (func (export "ret-s32") (result s32) (canon lift (core func $i "ret-i32-0")))
(func (export "ret-u64") (canon.lift (func (result u64)) (func $i "ret-i64-0"))) (func (export "ret-u64") (result u64) (canon lift (core func $i "ret-i64-0")))
(func (export "ret-s64") (canon.lift (func (result s64)) (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-u8") (result u8) (canon lift (core func $i "ret-i32-minus-1")))
(func (export "retm1-s8") (canon.lift (func (result s8)) (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") (canon.lift (func (result u16)) (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") (canon.lift (func (result s16)) (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") (canon.lift (func (result u32)) (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") (canon.lift (func (result s32)) (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") (canon.lift (func (result u64)) (func $i "ret-i64-minus-1"))) (func (export "retm1-u64") (result u64) (canon lift (core func $i "ret-i64-minus-1")))
(func (export "retm1-s64") (canon.lift (func (result s64)) (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-u8") (result u8) (canon lift (core func $i "ret-i32-100000")))
(func (export "retbig-s8") (canon.lift (func (result s8)) (func $i "ret-i32-100000"))) (func (export "retbig-s8") (result s8) (canon lift (core func $i "ret-i32-100000")))
(func (export "retbig-u16") (canon.lift (func (result u16)) (func $i "ret-i32-100000"))) (func (export "retbig-u16") (result u16) (canon lift (core func $i "ret-i32-100000")))
(func (export "retbig-s16") (canon.lift (func (result s16)) (func $i "ret-i32-100000"))) (func (export "retbig-s16") (result s16) (canon lift (core func $i "ret-i32-100000")))
(func (export "retbig-u32") (canon.lift (func (result u32)) (func $i "ret-i32-100000"))) (func (export "retbig-u32") (result u32) (canon lift (core func $i "ret-i32-100000")))
(func (export "retbig-s32") (canon.lift (func (result s32)) (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<()> { fn type_layers() -> Result<()> {
let component = r#" let component = r#"
(component (component
(module $m (core module $m
(func (export "take-i32-100") (param i32) (func (export "take-i32-100") (param i32)
local.get 0 local.get 0
i32.const 2 i32.const 2
@@ -415,8 +413,8 @@ fn type_layers() -> Result<()> {
unreachable unreachable
) )
) )
(instance $i (instantiate (module $m))) (core instance $i (instantiate $m))
(func (export "take-u32") (canon.lift (func (param u32)) (func $i "take-i32-100"))) (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<()> { fn floats() -> Result<()> {
let component = r#" let component = r#"
(component (component
(module $m (core module $m
(func (export "i32.reinterpret_f32") (param f32) (result i32) (func (export "i32.reinterpret_f32") (param f32) (result i32)
local.get 0 local.get 0
i32.reinterpret_f32 i32.reinterpret_f32
@@ -466,19 +464,19 @@ fn floats() -> Result<()> {
f64.reinterpret_i64 f64.reinterpret_i64
) )
) )
(instance $i (instantiate (module $m))) (core instance $i (instantiate $m))
(func (export "f32-to-u32") (func (export "f32-to-u32") (param float32) (result u32)
(canon.lift (func (param float32) (result u32)) (func $i "i32.reinterpret_f32")) (canon lift (core func $i "i32.reinterpret_f32"))
) )
(func (export "f64-to-u64") (func (export "f64-to-u64") (param float64) (result u64)
(canon.lift (func (param float64) (result u64)) (func $i "i64.reinterpret_f64")) (canon lift (core func $i "i64.reinterpret_f64"))
) )
(func (export "u32-to-f32") (func (export "u32-to-f32") (param u32) (result float32)
(canon.lift (func (param u32) (result float32)) (func $i "f32.reinterpret_i32")) (canon lift (core func $i "f32.reinterpret_i32"))
) )
(func (export "u64-to-f64") (func (export "u64-to-f64") (param u64) (result float64)
(canon.lift (func (param u64) (result float64)) (func $i "f64.reinterpret_i64")) (canon lift (core func $i "f64.reinterpret_i64"))
) )
) )
"#; "#;
@@ -526,16 +524,16 @@ fn floats() -> Result<()> {
fn bools() -> Result<()> { fn bools() -> Result<()> {
let component = r#" let component = r#"
(component (component
(module $m (core module $m
(func (export "pass") (param i32) (result i32) local.get 0) (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") (func (export "u32-to-bool") (param u32) (result bool)
(canon.lift (func (param u32) (result bool)) (func $i "pass")) (canon lift (core func $i "pass"))
) )
(func (export "bool-to-u32") (func (export "bool-to-u32") (param bool) (result u32)
(canon.lift (func (param bool) (result u32)) (func $i "pass")) (canon lift (core func $i "pass"))
) )
) )
"#; "#;
@@ -560,16 +558,16 @@ fn bools() -> Result<()> {
fn chars() -> Result<()> { fn chars() -> Result<()> {
let component = r#" let component = r#"
(component (component
(module $m (core module $m
(func (export "pass") (param i32) (result i32) local.get 0) (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") (func (export "u32-to-char") (param u32) (result char)
(canon.lift (func (param u32) (result char)) (func $i "pass")) (canon lift (core func $i "pass"))
) )
(func (export "char-to-u32") (func (export "char-to-u32") (param char) (result u32)
(canon.lift (func (param char) (result u32)) (func $i "pass")) (canon lift (core func $i "pass"))
) )
) )
"#; "#;
@@ -609,7 +607,7 @@ fn chars() -> Result<()> {
fn tuple_result() -> Result<()> { fn tuple_result() -> Result<()> {
let component = r#" let component = r#"
(component (component
(module $m (core module $m
(memory (export "memory") 1) (memory (export "memory") 1)
(func (export "foo") (param i32 i32 f32 f64) (result i32) (func (export "foo") (param i32 i32 f32 f64) (result i32)
(local $base i32) (local $base i32)
@@ -624,24 +622,16 @@ fn tuple_result() -> Result<()> {
(func (export "invalid") (result i32) (func (export "invalid") (result i32)
i32.const -8 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)) (type $result (tuple s8 u16 float32 float64))
(func (export "tuple") (func (export "tuple")
(canon.lift (param s8) (param u16) (param float32) (param float64) (result $result)
(func (param s8) (param u16) (param float32) (param float64) (result $result)) (canon lift (core func $i "foo") (memory $i "memory"))
(into $i)
(func $i "foo")
)
) )
(func (export "invalid") (func (export "invalid") (result $result)
(canon.lift (func (result $result)) (into $i) (func $i "invalid")) (canon lift (core func $i "invalid") (memory $i "memory"))
) )
) )
"#; "#;
@@ -673,7 +663,7 @@ fn tuple_result() -> Result<()> {
fn strings() -> Result<()> { fn strings() -> Result<()> {
let component = format!( let component = format!(
r#"(component r#"(component
(module $m (core module $m
(memory (export "memory") 1) (memory (export "memory") 1)
(func (export "roundtrip") (param i32 i32) (result i32) (func (export "roundtrip") (param i32 i32) (result i32)
(local $base i32) (local $base i32)
@@ -694,36 +684,36 @@ fn strings() -> Result<()> {
{REALLOC_AND_FREE} {REALLOC_AND_FREE}
) )
(instance $i (instantiate (module $m))) (core instance $i (instantiate $m))
(func (export "list8-to-str") (func (export "list8-to-str") (param (list u8)) (result string)
(canon.lift (canon lift
(func (param (list u8)) (result string)) (core func $i "roundtrip")
(into $i) (memory $i "memory")
(func $i "roundtrip") (realloc (func $i "realloc"))
) )
) )
(func (export "str-to-list8") (func (export "str-to-list8") (param string) (result (list u8))
(canon.lift (canon lift
(func (param string) (result (list u8))) (core func $i "roundtrip")
(into $i) (memory $i "memory")
(func $i "roundtrip") (realloc (func $i "realloc"))
) )
) )
(func (export "list16-to-str") (func (export "list16-to-str") (param (list u16)) (result string)
(canon.lift (canon lift
(func (param (list u16)) (result string)) (core func $i "roundtrip")
string=utf16 string-encoding=utf16
(into $i) (memory $i "memory")
(func $i "roundtrip") (realloc (func $i "realloc"))
) )
) )
(func (export "str-to-list16") (func (export "str-to-list16") (param string) (result (list u16))
(canon.lift (canon lift
(func (param string) (result (list u16))) (core func $i "roundtrip")
string=utf16 string-encoding=utf16
(into $i) (memory $i "memory")
(func $i "roundtrip") (realloc (func $i "realloc"))
) )
) )
)"# )"#
@@ -792,7 +782,7 @@ fn strings() -> Result<()> {
fn many_parameters() -> Result<()> { fn many_parameters() -> Result<()> {
let component = format!( let component = format!(
r#"(component r#"(component
(module $m (core module $m
(memory (export "memory") 1) (memory (export "memory") 1)
(func (export "foo") (param i32) (result i32) (func (export "foo") (param i32) (result i32)
(local $base i32) (local $base i32)
@@ -826,7 +816,7 @@ fn many_parameters() -> Result<()> {
{REALLOC_AND_FREE} {REALLOC_AND_FREE}
) )
(instance $i (instantiate (module $m))) (core instance $i (instantiate $m))
(type $result (tuple (list u8) u32)) (type $result (tuple (list u8) u32))
(type $t (func (type $t (func
@@ -847,8 +837,12 @@ fn many_parameters() -> Result<()> {
(result $result) (result $result)
)) ))
(func (export "many-param") (func (export "many-param") (type $t)
(canon.lift (type $t) (into $i) (func $i "foo")) (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 middle_of_memory = (i32::MAX / 2) & (!0xff);
let component = format!( let component = format!(
r#"(component r#"(component
(module $m (core module $m
(memory (export "memory") 1) (memory (export "memory") 1)
(func (export "take-many") (param i32)) (func (export "take-many") (param i32))
(func (export "take-list") (param i32 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)
unreachable)
(func (export "canonical_abi_free") (param i32 i32 i32)
unreachable) unreachable)
) )
(instance $i (instantiate (module $m))) (core instance $i (instantiate $m))
(func (export "take-list-unreachable") (func (export "take-list-unreachable") (param (list u8))
(canon.lift (func (param (list u8))) (into $i) (func $i "take-list")) (canon lift (core func $i "take-list") (memory $i "memory") (realloc (func $i "realloc")))
) )
(func (export "take-string-unreachable") (func (export "take-string-unreachable") (param string)
(canon.lift (func (param string)) (into $i) (func $i "take-list")) (canon lift (core func $i "take-list") (memory $i "memory") (realloc (func $i "realloc")))
) )
(type $t (func (type $t (func
@@ -981,60 +973,56 @@ fn some_traps() -> Result<()> {
(param string) (param string)
(param string) (param string)
)) ))
(func (export "take-many-unreachable") (func (export "take-many-unreachable") (type $t)
(canon.lift (type $t) (into $i) (func $i "take-many")) (canon lift (core func $i "take-many") (memory $i "memory") (realloc (func $i "realloc")))
) )
(module $m2 (core module $m2
(memory (export "memory") 1) (memory (export "memory") 1)
(func (export "take-many") (param i32)) (func (export "take-many") (param i32))
(func (export "take-list") (param i32 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}) 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") (func (export "take-list-base-oob") (param (list u8))
(canon.lift (func (param (list u8))) (into $i2) (func $i2 "take-list")) (canon lift (core func $i2 "take-list") (memory $i2 "memory") (realloc (func $i2 "realloc")))
) )
(func (export "take-string-base-oob") (func (export "take-string-base-oob") (param string)
(canon.lift (func (param string)) (into $i2) (func $i2 "take-list")) (canon lift (core func $i2 "take-list") (memory $i2 "memory") (realloc (func $i2 "realloc")))
) )
(func (export "take-many-base-oob") (func (export "take-many-base-oob") (type $t)
(canon.lift (type $t) (into $i2) (func $i2 "take-many")) (canon lift (core func $i2 "take-many") (memory $i2 "memory") (realloc (func $i2 "realloc")))
) )
(module $m3 (core module $m3
(memory (export "memory") 1) (memory (export "memory") 1)
(func (export "take-many") (param i32)) (func (export "take-many") (param i32))
(func (export "take-list") (param i32 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) 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") (func (export "take-list-end-oob") (param (list u8))
(canon.lift (func (param (list u8))) (into $i3) (func $i3 "take-list")) (canon lift (core func $i3 "take-list") (memory $i3 "memory") (realloc (func $i3 "realloc")))
) )
(func (export "take-string-end-oob") (func (export "take-string-end-oob") (param string)
(canon.lift (func (param string)) (into $i3) (func $i3 "take-list")) (canon lift (core func $i3 "take-list") (memory $i3 "memory") (realloc (func $i3 "realloc")))
) )
(func (export "take-many-end-oob") (func (export "take-many-end-oob") (type $t)
(canon.lift (type $t) (into $i3) (func $i3 "take-many")) (canon lift (core func $i3 "take-many") (memory $i3 "memory") (realloc (func $i3 "realloc")))
) )
(module $m4 (core module $m4
(memory (export "memory") 1) (memory (export "memory") 1)
(func (export "take-many") (param i32)) (func (export "take-many") (param i32))
(global $cnt (mut i32) (i32.const 0)) (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 global.get $cnt
if (result i32) if (result i32)
i32.const 100000 i32.const 100000
@@ -1044,13 +1032,11 @@ fn some_traps() -> Result<()> {
i32.const 0 i32.const 0
end 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") (func (export "take-many-second-oob") (type $t)
(canon.lift (type $t) (into $i4) (func $i4 "take-many")) (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<()> { fn char_bool_memory() -> Result<()> {
let component = format!( let component = format!(
r#"(component r#"(component
(module $m (core module $m
(memory (export "memory") 1) (memory (export "memory") 1)
(func (export "ret-tuple") (param i32 i32) (result i32) (func (export "ret-tuple") (param i32 i32) (result i32)
(local $base i32) (local $base i32)
@@ -1212,10 +1198,12 @@ fn char_bool_memory() -> Result<()> {
{REALLOC_AND_FREE} {REALLOC_AND_FREE}
) )
(instance $i (instantiate (module $m))) (core instance $i (instantiate $m))
(func (export "ret-tuple") (func (export "ret-tuple") (param u32) (param u32) (result (tuple bool char))
(canon.lift (func (param u32) (param u32) (result (tuple bool char))) (into $i) (func $i "ret-tuple")) (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<()> { fn string_list_oob() -> Result<()> {
let component = format!( let component = format!(
r#"(component r#"(component
(module $m (core module $m
(memory (export "memory") 1) (memory (export "memory") 1)
(func (export "ret-list") (result i32) (func (export "ret-list") (result i32)
(local $base i32) (local $base i32)
@@ -1269,13 +1257,19 @@ fn string_list_oob() -> Result<()> {
{REALLOC_AND_FREE} {REALLOC_AND_FREE}
) )
(instance $i (instantiate (module $m))) (core instance $i (instantiate $m))
(func (export "ret-list-u8") (func (export "ret-list-u8") (result (list u8))
(canon.lift (func (result (list u8))) (into $i) (func $i "ret-list")) (canon lift (core func $i "ret-list")
(memory $i "memory")
(realloc (func $i "realloc"))
)
) )
(func (export "ret-string") (func (export "ret-string") (result string)
(canon.lift (func (result string)) (into $i) (func $i "ret-list")) (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<()> { fn tuples() -> Result<()> {
let component = format!( let component = format!(
r#"(component r#"(component
(module $m (core module $m
(memory (export "memory") 1) (memory (export "memory") 1)
(func (export "foo") (func (export "foo")
(param i32 f64 i32) (param i32 f64 i32)
@@ -1323,23 +1317,14 @@ fn tuples() -> Result<()> {
i32.const 3 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") (func (export "foo")
(canon.lift (param (tuple s32 float64))
(func (param (tuple s8))
(param (tuple s32 float64)) (result (tuple u16))
(param (tuple s8)) (canon lift (core func $i "foo"))
(result (tuple u16))
)
(func $i "foo")
)
) )
)"# )"#
); );
@@ -1358,7 +1343,7 @@ fn tuples() -> Result<()> {
fn option() -> Result<()> { fn option() -> Result<()> {
let component = format!( let component = format!(
r#"(component r#"(component
(module $m (core module $m
(memory (export "memory") 1) (memory (export "memory") 1)
(func (export "pass0") (param i32) (result i32) (func (export "pass0") (param i32) (result i32)
local.get 0 local.get 0
@@ -1405,60 +1390,41 @@ fn option() -> Result<()> {
{REALLOC_AND_FREE} {REALLOC_AND_FREE}
) )
(instance $i (instantiate (module $m))) (core instance $i (instantiate $m))
(func (export "option-unit-to-u32") (func (export "option-unit-to-u32") (param (option unit)) (result u32)
(canon.lift (canon lift (core func $i "pass0"))
(func (param (option unit)) (result u32)) )
(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") (func (export "to-option-unit") (param u32) (result (option unit))
(canon.lift (canon lift (core func $i "pass0"))
(func (param (option u8)) (result (tuple u32 u32))) )
(into $i) (func (export "to-option-u8") (param u32) (param u32) (result (option u8))
(func $i "pass1") (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") (func (export "to-option-string") (param u32) (param string) (result (option string))
(canon.lift (canon lift
(func (param (option u32)) (result (tuple u32 u32))) (core func $i "pass2")
(into $i) (memory $i "memory")
(func $i "pass1") (realloc (func $i "realloc"))
)
)
(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")
) )
) )
)"# )"#
@@ -1543,7 +1509,7 @@ fn option() -> Result<()> {
fn expected() -> Result<()> { fn expected() -> Result<()> {
let component = format!( let component = format!(
r#"(component r#"(component
(module $m (core module $m
(memory (export "memory") 1) (memory (export "memory") 1)
(func (export "pass0") (param i32) (result i32) (func (export "pass0") (param i32) (result i32)
local.get 0 local.get 0
@@ -1590,40 +1556,30 @@ fn expected() -> Result<()> {
{REALLOC_AND_FREE} {REALLOC_AND_FREE}
) )
(instance $i (instantiate (module $m))) (core instance $i (instantiate $m))
(func (export "take-expected-unit") (func (export "take-expected-unit") (param (expected unit unit)) (result u32)
(canon.lift (canon lift (core func $i "pass0"))
(func (param (expected unit unit)) (result u32))
(func $i "pass0")
)
) )
(func (export "take-expected-u8-f32") (func (export "take-expected-u8-f32") (param (expected u8 float32)) (result (tuple u32 u32))
(canon.lift (canon lift (core func $i "pass1") (memory $i "memory"))
(func (param (expected u8 float32)) (result (tuple u32 u32)))
(into $i)
(func $i "pass1")
)
) )
(type $list (list u8)) (type $list (list u8))
(func (export "take-expected-string") (func (export "take-expected-string") (param (expected string $list)) (result (tuple u32 string))
(canon.lift (canon lift
(func (param (expected string $list)) (result (tuple u32 string))) (core func $i "pass2")
(into $i) (memory $i "memory")
(func $i "pass2") (realloc (func $i "realloc"))
) )
) )
(func (export "to-expected-unit") (func (export "to-expected-unit") (param u32) (result (expected unit unit))
(canon.lift (canon lift (core func $i "pass0"))
(func (param u32) (result (expected unit unit)))
(func $i "pass0")
)
) )
(func (export "to-expected-s16-f32") (func (export "to-expected-s16-f32") (param u32) (param u32) (result (expected s16 float32))
(canon.lift (canon lift
(func (param u32) (param u32) (result (expected s16 float32))) (core func $i "pass1")
(into $i) (memory $i "memory")
(func $i "pass1") (realloc (func $i "realloc"))
) )
) )
)"# )"#
@@ -1684,7 +1640,7 @@ fn expected() -> Result<()> {
fn fancy_list() -> Result<()> { fn fancy_list() -> Result<()> {
let component = format!( let component = format!(
r#"(component r#"(component
(module $m (core module $m
(memory (export "memory") 1) (memory (export "memory") 1)
(func (export "take") (param i32 i32) (result i32) (func (export "take") (param i32 i32) (result i32)
(local $base i32) (local $base i32)
@@ -1715,17 +1671,17 @@ fn fancy_list() -> Result<()> {
{REALLOC_AND_FREE} {REALLOC_AND_FREE}
) )
(instance $i (instantiate (module $m))) (core instance $i (instantiate $m))
(type $a (option u8)) (type $a (option u8))
(type $b (expected unit string)) (type $b (expected unit string))
(type $input (list (tuple $a $b))) (type $input (list (tuple $a $b)))
(type $output (tuple u32 u32 (list u8))) (type $output (tuple u32 u32 (list u8)))
(func (export "take") (func (export "take") (param $input) (result $output)
(canon.lift (canon lift
(func (param $input) (result $output)) (core func $i "take")
(into $i) (memory $i "memory")
(func $i "take") (realloc (func $i "realloc"))
) )
) )
)"# )"#
@@ -1808,13 +1764,10 @@ impl<'a> SliceExt<'a> for &'a [u8] {
fn invalid_alignment() -> Result<()> { fn invalid_alignment() -> Result<()> {
let component = format!( let component = format!(
r#"(component r#"(component
(module $m (core module $m
(memory (export "memory") 1) (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) i32.const 1)
(func (export "canonical_abi_free") (param i32 i32 i32)
unreachable)
(func (export "take-i32") (param i32)) (func (export "take-i32") (param i32))
(func (export "ret-1") (result i32) i32.const 1) (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.store offset=4 (i32.const 8) (i32.const 1))
i32.const 8) i32.const 8)
) )
(instance $i (instantiate (module $m))) (core instance $i (instantiate $m))
(func (export "many-params") (func (export "many-params")
(canon.lift (param string) (param string) (param string) (param string)
(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)
(param string) (param string) (param string) (param string) (canon lift
(param string) (param string) (param string) (param string) (core func $i "take-i32")
) (memory $i "memory")
(into $i) (realloc (func $i "realloc"))
(func $i "take-i32")
) )
) )
(func (export "string-ret") (func (export "string-ret") (result string)
(canon.lift (func (result string)) (into $i) (func $i "ret-1")) (canon lift
(core func $i "ret-1")
(memory $i "memory")
(realloc (func $i "realloc"))
)
) )
(func (export "list-u32-ret") (func (export "list-u32-ret") (result (list u32))
(canon.lift (func (result (list u32))) (into $i) (func $i "ret-unaligned-list")) (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<()> { fn can_compile() -> Result<()> {
let engine = super::engine(); let engine = super::engine();
let libc = r#" let libc = r#"
(module $libc (core module $libc
(memory (export "memory") 1) (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)
unreachable) unreachable)
) )
(instance $libc (instantiate (module $libc))) (core instance $libc (instantiate $libc))
"#; "#;
Component::new( Component::new(
&engine, &engine,
r#"(component r#"(component
(import "" (func $f)) (import "" (func $f))
(func (canon.lower (func $f))) (core func (canon lower (func $f)))
)"#, )"#,
)?; )?;
Component::new( Component::new(
@@ -29,7 +27,7 @@ fn can_compile() -> Result<()> {
r#"(component r#"(component
(import "" (func $f (param string))) (import "" (func $f (param string)))
{libc} {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 r#"(component
(import "f1" (func $f1 (param string) (result string))) (import "f1" (func $f1 (param string) (result string)))
{libc} {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)))) (import "f2" (func $f2 (param u32) (result (list u8))))
(instance $libc2 (instantiate (module $libc))) (core instance $libc2 (instantiate $libc))
(func (canon.lower (into $libc2) (func $f2))) (core func (canon lower (func $f2) (memory $libc2 "memory") (realloc (func $libc2 "realloc"))))
(func (canon.lower (into $libc2) (func $f1))) (core func (canon lower (func $f1) (memory $libc2 "memory") (realloc (func $libc2 "realloc"))))
(func (canon.lower (into $libc) (func $f2))) (core func (canon lower (func $f2) (memory $libc "memory") (realloc (func $libc "realloc"))))
)"# )"#
), ),
)?; )?;
@@ -56,9 +54,9 @@ fn can_compile() -> Result<()> {
r#"(component r#"(component
(import "log" (func $log (param string))) (import "log" (func $log (param string)))
{libc} {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 "host" "log" (func $log (param i32 i32)))
(import "libc" "memory" (memory 1)) (import "libc" "memory" (memory 1))
@@ -67,13 +65,13 @@ fn can_compile() -> Result<()> {
i32.const 0 i32.const 0
call $log) call $log)
) )
(instance $logger (instantiate (module $logger) (core instance $logger (instantiate $logger
(with "host" (instance (export "log" (func $log_lower)))) (with "host" (instance (export "log" (func $log_lower))))
(with "libc" (instance $libc)) (with "libc" (instance $libc))
)) ))
(func (export "call") (func (export "call")
(canon.lift (func) (func $logger "call")) (canon lift (core func $logger "call"))
) )
)"# )"#
), ),
@@ -87,19 +85,17 @@ fn simple() -> Result<()> {
(component (component
(import "" (func $log (param string))) (import "" (func $log (param string)))
(module $libc (core module $libc
(memory (export "memory") 1) (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)
unreachable) unreachable)
) )
(instance $libc (instantiate (module $libc))) (core instance $libc (instantiate $libc))
(func $log_lower (core func $log_lower
(canon.lower (into $libc) (func $log)) (canon lower (func $log) (memory $libc "memory") (realloc (func $libc "realloc")))
) )
(module $m (core module $m
(import "libc" "memory" (memory 1)) (import "libc" "memory" (memory 1))
(import "host" "log" (func $log (param i32 i32))) (import "host" "log" (func $log (param i32 i32)))
@@ -110,12 +106,12 @@ fn simple() -> Result<()> {
(data (i32.const 5) "hello world") (data (i32.const 5) "hello world")
) )
(instance $i (instantiate (module $m) (core instance $i (instantiate $m
(with "libc" (instance $libc)) (with "libc" (instance $libc))
(with "host" (instance (export "log" (func $log_lower)))) (with "host" (instance (export "log" (func $log_lower))))
)) ))
(func (export "call") (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 "thunk" (func $thunk))
(import "ret-string" (func $ret_string (result string))) (import "ret-string" (func $ret_string (result string)))
(module $host_shim (core module $host_shim
(table (export "table") 2 funcref) (table (export "table") 2 funcref)
(func $shim_thunk (export "thunk") (func $shim_thunk (export "thunk")
i32.const 0 i32.const 0
@@ -160,21 +156,18 @@ fn attempt_to_leave_during_malloc() -> Result<()> {
i32.const 1 i32.const 1
call_indirect (param i32)) 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" "thunk" (func $thunk))
(import "host" "ret-string" (func $ret_string (param i32))) (import "host" "ret-string" (func $ret_string (param i32)))
(memory (export "memory") 1) (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 call $thunk
unreachable) unreachable)
(func (export "canonical_abi_free") (param i32 i32 i32)
unreachable)
(func $run (export "run") (func $run (export "run")
i32.const 8 i32.const 8
call $ret_string) call $ret_string)
@@ -182,24 +175,24 @@ fn attempt_to_leave_during_malloc() -> Result<()> {
(func (export "take-string") (param i32 i32) (func (export "take-string") (param i32 i32)
unreachable) 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 "shim" "table" (table 2 funcref))
(import "host" "thunk" (func $thunk)) (import "host" "thunk" (func $thunk))
(import "host" "ret-string" (func $ret_string (param i32))) (import "host" "ret-string" (func $ret_string (param i32)))
(elem (i32.const 0) $thunk $ret_string) (elem (i32.const 0) $thunk $ret_string)
) )
(func $thunk_lower (core func $thunk_lower
(canon.lower (into $m) (func $thunk)) (canon lower (func $thunk) (memory $m "memory") (realloc (func $m "realloc")))
) )
(func $ret_string_lower (core func $ret_string_lower
(canon.lower (into $m) (func $ret_string)) (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 "shim" (instance $host_shim))
(with "host" (instance (with "host" (instance
(export "thunk" (func $thunk_lower)) (export "thunk" (func $thunk_lower))
@@ -208,10 +201,10 @@ fn attempt_to_leave_during_malloc() -> Result<()> {
)) ))
(func (export "run") (func (export "run")
(canon.lift (func) (func $m "run")) (canon lift (core func $m "run"))
) )
(func (export "take-string") (func (export "take-string") (param string)
(canon.lift (func (param string)) (into $m) (func $m "take-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#" let component = r#"
(component (component
(import "thunk" (func $thunk)) (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)) (import "host" "thunk" (func $thunk))
(func $run (export "run") (func $run (export "run")
call $thunk) call $thunk)
) )
(instance $m (instantiate (module $m) (core instance $m (instantiate $m
(with "host" (instance (export "thunk" (func $thunk_lower)))) (with "host" (instance (export "thunk" (func $thunk_lower))))
)) ))
(func (export "run") (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 "f3" (func $f3 (param u32) (result string)))
(import "f4" (func $f4 (param $many_params) (result string))) (import "f4" (func $f4 (param $many_params) (result string)))
(module $libc (core module $libc
{REALLOC_AND_FREE} {REALLOC_AND_FREE}
(memory (export "memory") 1) (memory (export "memory") 1)
) )
(instance $libc (instantiate (module $libc))) (core instance $libc (instantiate (module $libc)))
(func $f1_lower (canon.lower (into $libc) (func $f1))) (core func $f1_lower (canon lower (func $f1) (memory $libc "memory") (realloc (func $libc "realloc"))))
(func $f2_lower (canon.lower (into $libc) (func $f2))) (core func $f2_lower (canon lower (func $f2) (memory $libc "memory") (realloc (func $libc "realloc"))))
(func $f3_lower (canon.lower (into $libc) (func $f3))) (core func $f3_lower (canon lower (func $f3) (memory $libc "memory") (realloc (func $libc "realloc"))))
(func $f4_lower (canon.lower (into $libc) (func $f4))) (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" "f1" (func $f1 (param i32) (result i32)))
(import "host" "f2" (func $f2 (param i32) (result i32))) (import "host" "f2" (func $f2 (param i32) (result i32)))
(import "host" "f3" (func $f3 (param i32 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") (data (i32.const 1000) "abc")
) )
(instance $m (instantiate (module $m) (core instance $m (instantiate $m
(with "libc" (instance $libc)) (with "libc" (instance $libc))
(with "host" (instance (with "host" (instance
(export "f1" (func $f1_lower)) (export "f1" (func $f1_lower))
@@ -465,7 +458,7 @@ fn stack_and_heap_args_and_rets() -> Result<()> {
)) ))
(func (export "run") (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 string
)) ))
(import "unaligned-argptr" (func $unaligned_argptr (param $many_arg))) (import "unaligned-argptr" (func $unaligned_argptr (param $many_arg)))
(module $libc_panic (core module $libc_panic
(memory (export "memory") 1) (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)
unreachable) unreachable)
) )
(instance $libc_panic (instantiate (module $libc_panic))) (core instance $libc_panic (instantiate $libc_panic))
(func $unaligned_retptr_lower (core func $unaligned_retptr_lower
(canon.lower (into $libc_panic) (func $unaligned_retptr)) (canon lower (func $unaligned_retptr) (memory $libc_panic "memory") (realloc (func $libc_panic "realloc")))
) )
(func $unaligned_argptr_lower (core func $unaligned_argptr_lower
(canon.lower (into $libc_panic) (func $unaligned_argptr)) (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-retptr" (func $unaligned_retptr (param i32)))
(import "host" "unaligned-argptr" (func $unaligned_argptr (param i32))) (import "host" "unaligned-argptr" (func $unaligned_argptr (param i32)))
@@ -567,7 +558,7 @@ fn bad_import_alignment() -> Result<()> {
(func (export "unaligned-argptr") (func (export "unaligned-argptr")
(call $unaligned_argptr (i32.const 1))) (call $unaligned_argptr (i32.const 1)))
) )
(instance $m (instantiate (module $m) (core instance $m (instantiate $m
(with "host" (instance (with "host" (instance
(export "unaligned-retptr" (func $unaligned_retptr_lower)) (export "unaligned-retptr" (func $unaligned_retptr_lower))
(export "unaligned-argptr" (func $unaligned_argptr_lower)) (export "unaligned-argptr" (func $unaligned_argptr_lower))
@@ -575,10 +566,10 @@ fn bad_import_alignment() -> Result<()> {
)) ))
(func (export "unaligned-retptr") (func (export "unaligned-retptr")
(canon.lift (func) (func $m "unaligned-retptr")) (canon lift (core func $m "unaligned-retptr"))
) )
(func (export "unaligned-argptr") (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 ;; basic function lifting
(component (component
(module $m (core module $m
(func (export "")) (func (export ""))
) )
(instance $i (instantiate (module $m))) (core instance $i (instantiate $m))
(func (export "thunk") (func (export "thunk")
(canon.lift (func) (func $i "")) (canon lift (core func $i ""))
) )
) )
;; use an aliased type ;; use an aliased type
(component $c (component $c
(module $m (core module $m
(func (export "")) (func (export ""))
) )
(instance $i (instantiate (module $m))) (core instance $i (instantiate $m))
(type $to_alias (func)) (type $to_alias (func))
(alias outer $c $to_alias (type $alias)) (alias outer $c $to_alias (type $alias))
(func (export "thunk") (func (export "thunk") (type $alias)
(canon.lift (type $alias) (func $i "")) (canon lift (core func $i ""))
) )
) )
;; test out some various canonical abi ;; test out some various canonical abi
(component $c (component $c
(module $m (core module $m
(func (export "") (param i32 i32)) (func (export "") (param i32 i32))
(memory (export "memory") 1) (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) unreachable)
(func (export "canonical_abi_free") (param i32 i32 i32))
) )
(instance $i (instantiate (module $m))) (core instance $i (instantiate $m))
(func (export "thunk") (func (export "thunk") (param string)
(canon.lift (func (param string)) (into $i) (func $i "")) (canon lift
(core func $i "")
(memory $i "memory")
(realloc (func $i "realloc"))
)
) )
(func (export "thunk8") (func (export "thunk8") (param string)
(canon.lift (func (param string)) string=utf8 (into $i) (func $i "")) (canon lift
(core func $i "")
string-encoding=utf8
(memory $i "memory")
(realloc (func $i "realloc"))
)
) )
(func (export "thunk16") (func (export "thunk16") (param string)
(canon.lift (func (param string)) string=utf16 (into $i) (func $i "")) (canon lift
(core func $i "")
string-encoding=utf16
(memory $i "memory")
(realloc (func $i "realloc"))
)
) )
(func (export "thunklatin16") (func (export "thunklatin16") (param string)
(canon.lift (func (param string)) string=latin1+utf16 (into $i) (func $i "")) (canon lift
(core func $i "")
string-encoding=latin1+utf16
(memory $i "memory")
(realloc (func $i "realloc"))
)
) )
) )

View File

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

View File

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

View File

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

View File

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