Add *.wast support for invoking components (#4526)
This commit builds on bytecodealliance/wasm-tools#690 to add support to testing of the component model to execute functions when running `*.wast` files. This support is all built on #4442 as functions are invoked through a "dynamic" API. Right now the testing and integration is fairly crude but I'm hoping that we can try to improve it over time as necessary. For now this should provide a hopefully more convenient syntax for unit tests and the like.
This commit is contained in:
@@ -22,13 +22,13 @@ wasmtime-cranelift = { path = "../cranelift", version = "=0.40.0", optional = tr
|
||||
wasmtime-component-macro = { path = "../component-macro", version = "=0.40.0", optional = true }
|
||||
wasmtime-component-util = { path = "../component-util", version = "=0.40.0", optional = true }
|
||||
target-lexicon = { version = "0.12.0", default-features = false }
|
||||
wasmparser = "0.87.0"
|
||||
wasmparser = "0.88.0"
|
||||
anyhow = "1.0.19"
|
||||
libc = "0.2"
|
||||
cfg-if = "1.0"
|
||||
backtrace = { version = "0.3.61" }
|
||||
log = "0.4.8"
|
||||
wat = { version = "1.0.45", optional = true }
|
||||
wat = { version = "1.0.47", optional = true }
|
||||
serde = { version = "1.0.94", features = ["derive"] }
|
||||
bincode = "1.2.1"
|
||||
indexmap = "1.6"
|
||||
|
||||
@@ -73,7 +73,7 @@ impl Record {
|
||||
}
|
||||
|
||||
/// Retrieve the fields of this `record` in declaration order.
|
||||
pub fn fields(&self) -> impl ExactSizeIterator<Item = Field> {
|
||||
pub fn fields(&self) -> impl ExactSizeIterator<Item = Field<'_>> {
|
||||
self.0.types[self.0.index].fields.iter().map(|field| Field {
|
||||
name: &field.name,
|
||||
ty: Type::from(&field.ty, &self.0.types),
|
||||
|
||||
@@ -30,6 +30,19 @@ impl List {
|
||||
values,
|
||||
})
|
||||
}
|
||||
|
||||
/// Returns the corresponding type of this list
|
||||
pub fn ty(&self) -> &types::List {
|
||||
&self.ty
|
||||
}
|
||||
}
|
||||
|
||||
impl Deref for List {
|
||||
type Target = [Val];
|
||||
|
||||
fn deref(&self) -> &[Val] {
|
||||
&self.values
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq, Eq, Clone)]
|
||||
@@ -76,6 +89,20 @@ impl Record {
|
||||
values: values.into(),
|
||||
})
|
||||
}
|
||||
|
||||
/// Returns the corresponding type of this record.
|
||||
pub fn ty(&self) -> &types::Record {
|
||||
&self.ty
|
||||
}
|
||||
|
||||
/// Gets the value of the specified field `name` from this record.
|
||||
pub fn fields(&self) -> impl Iterator<Item = (&str, &Val)> {
|
||||
assert_eq!(self.values.len(), self.ty.fields().len());
|
||||
self.ty
|
||||
.fields()
|
||||
.zip(self.values.iter())
|
||||
.map(|(ty, val)| (ty.name, val))
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq, Eq, Clone)]
|
||||
@@ -105,6 +132,16 @@ impl Tuple {
|
||||
values,
|
||||
})
|
||||
}
|
||||
|
||||
/// Returns the type of this tuple.
|
||||
pub fn ty(&self) -> &types::Tuple {
|
||||
&self.ty
|
||||
}
|
||||
|
||||
/// Returns the list of values that this tuple contains.
|
||||
pub fn values(&self) -> &[Val] {
|
||||
&self.values
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq, Eq, Clone)]
|
||||
@@ -139,6 +176,25 @@ impl Variant {
|
||||
value: Box::new(value),
|
||||
})
|
||||
}
|
||||
|
||||
/// Returns the type of this variant.
|
||||
pub fn ty(&self) -> &types::Variant {
|
||||
&self.ty
|
||||
}
|
||||
|
||||
/// Returns name of the discriminant of this value within the variant type.
|
||||
pub fn discriminant(&self) -> &str {
|
||||
self.ty
|
||||
.cases()
|
||||
.nth(self.discriminant as usize)
|
||||
.unwrap()
|
||||
.name
|
||||
}
|
||||
|
||||
/// Returns the payload value for this variant.
|
||||
pub fn payload(&self) -> &Val {
|
||||
&self.value
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq, Eq, Clone)]
|
||||
@@ -161,6 +217,16 @@ impl Enum {
|
||||
discriminant,
|
||||
})
|
||||
}
|
||||
|
||||
/// Returns the type of this value.
|
||||
pub fn ty(&self) -> &types::Enum {
|
||||
&self.ty
|
||||
}
|
||||
|
||||
/// Returns name of this enum value.
|
||||
pub fn discriminant(&self) -> &str {
|
||||
self.ty.names().nth(self.discriminant as usize).unwrap()
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq, Eq, Clone)]
|
||||
@@ -190,6 +256,21 @@ impl Union {
|
||||
))
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns the type of this value.
|
||||
pub fn ty(&self) -> &types::Union {
|
||||
&self.ty
|
||||
}
|
||||
|
||||
/// Returns name of the discriminant of this value within the union type.
|
||||
pub fn discriminant(&self) -> u32 {
|
||||
self.discriminant
|
||||
}
|
||||
|
||||
/// Returns the payload value for this union.
|
||||
pub fn payload(&self) -> &Val {
|
||||
&self.value
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq, Eq, Clone)]
|
||||
@@ -216,6 +297,20 @@ impl Option {
|
||||
value: Box::new(value.unwrap_or(Val::Unit)),
|
||||
})
|
||||
}
|
||||
|
||||
/// Returns the type of this value.
|
||||
pub fn ty(&self) -> &types::Option {
|
||||
&self.ty
|
||||
}
|
||||
|
||||
/// Returns the optional value contained within.
|
||||
pub fn value(&self) -> std::option::Option<&Val> {
|
||||
if self.discriminant == 0 {
|
||||
None
|
||||
} else {
|
||||
Some(&self.value)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq, Eq, Clone)]
|
||||
@@ -247,6 +342,20 @@ impl Expected {
|
||||
}),
|
||||
})
|
||||
}
|
||||
|
||||
/// Returns the type of this value.
|
||||
pub fn ty(&self) -> &types::Expected {
|
||||
&self.ty
|
||||
}
|
||||
|
||||
/// Returns the result value contained within.
|
||||
pub fn value(&self) -> Result<&Val, &Val> {
|
||||
if self.discriminant == 0 {
|
||||
Ok(&self.value)
|
||||
} else {
|
||||
Err(&self.value)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq, Eq, Clone)]
|
||||
@@ -280,6 +389,23 @@ impl Flags {
|
||||
value: values.into(),
|
||||
})
|
||||
}
|
||||
|
||||
/// Returns the type of this value.
|
||||
pub fn ty(&self) -> &types::Flags {
|
||||
&self.ty
|
||||
}
|
||||
|
||||
/// Returns an iterator over the set of names that this flags set contains.
|
||||
pub fn flags(&self) -> impl Iterator<Item = &str> {
|
||||
(0..self.count).filter_map(|i| {
|
||||
let (idx, bit) = ((i / 32) as usize, i % 32);
|
||||
if self.value[idx] & (1 << bit) != 0 {
|
||||
Some(self.ty.names().nth(i as usize).unwrap())
|
||||
} else {
|
||||
None
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
/// Represents possible runtime values which a component function can either consume or produce
|
||||
|
||||
Reference in New Issue
Block a user