Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 1 addition & 5 deletions crates/tests/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,7 @@ fn is_known_failing(name: &str) -> bool {
"tests_spec_tests_legacy_rethrow_wast"
| "tests_spec_tests_legacy_throw_wast"
| "tests_spec_tests_legacy_try_catch_wast"
| "tests_spec_tests_legacy_try_delegate_wast"
// 64-bit memory/table offsets not yet supported in walrus.
| "tests_spec_tests_data_wast" // active data with non-i32 offset (memory64)
| "tests_spec_tests_elem_wast" // active elem with non-i32 offset (table64)
=> true,
| "tests_spec_tests_legacy_try_delegate_wast" => true,

_ => false,
}
Expand Down
2 changes: 1 addition & 1 deletion crates/tests/tests/spec-tests
Submodule spec-tests updated 38 files
+1 −0 .github/workflows/autoupdate.yml
+1 −1 array.wast
+1 −1 array_copy.wast
+1 −1 array_fill.wast
+1 −1 array_init_data.wast
+63 −14 array_init_elem.wast
+1 −1 binary-leb128.wast
+7 −7 bulk64.wast
+99 −0 custom/branch_hint.wast
+99 −0 custom/custom_annot.wast
+38 −0 custom/name_annot.wast
+2 −2 i8x16_relaxed_swizzle.wast
+13 −0 loop.wast
+24 −0 proposals/custom-descriptors/array_new_exact.wast
+1,213 −0 proposals/custom-descriptors/binary.wast
+288 −0 proposals/custom-descriptors/br_on_cast.wast
+1,995 −0 proposals/custom-descriptors/br_on_cast_desc_eq.wast
+1,981 −0 proposals/custom-descriptors/br_on_cast_desc_eq_fail.wast
+301 −0 proposals/custom-descriptors/br_on_cast_fail.wast
+611 −7 proposals/custom-descriptors/descriptors.wast
+637 −0 proposals/custom-descriptors/exact-casts.wast
+264 −0 proposals/custom-descriptors/exact-func-import.wast
+920 −0 proposals/custom-descriptors/ref_cast_desc_eq.wast
+466 −0 proposals/custom-descriptors/ref_get_desc.wast
+592 −0 proposals/custom-descriptors/struct_new_desc.wast
+1,234 −0 proposals/custom-page-sizes/binary.wast
+3 −3 proposals/custom-page-sizes/custom-page-sizes-invalid.wast
+1 −1 proposals/custom-page-sizes/custom-page-sizes.wast
+14 −2 proposals/custom-page-sizes/memory_max.wast
+16 −4 proposals/custom-page-sizes/memory_max_i64.wast
+0 −2 relaxed_madd_nmadd.wast
+3 −3 return_call_indirect.wast
+8 −8 simd_lane.wast
+1 −1 struct.wast
+2 −2 tag.wast
+56 −1 try_table.wast
+77 −24 type-subtyping.wast
+4 −3 update-testsuite.py
22 changes: 12 additions & 10 deletions crates/tests/tests/spec-tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,20 +23,22 @@ fn run(wast: &Path) -> Result<(), anyhow::Error> {
.nth(1)
.map(|s| s.to_str().unwrap());

// The custom/ directory contains annotation syntax tests that wasm-tools
// json-from-wast does not yet support.
let in_custom_dir = wast.iter().any(|p| p == "custom");
if in_custom_dir {
return Ok(());
}

let extra_args: &[&str] = match proposal {
None => &[],
Some("annotations") => return Ok(()),
// The threads proposal testsuite has stale assert_invalid cases for
// multiple tables that predate the reference-types proposal.
Some("threads") => return Ok(()),
// custom-descriptors and custom-page-sizes are not yet supported
Some("custom-descriptors") => return Ok(()),
Some("custom-page-sizes") => return Ok(()),
Some("exception-handling") => &[],
Some("extended-const") => &[],
Some("function-references") => &[],
Some("gc") => return Ok(()),
Some("relaxed-simd") => &[],
Some("tail-call") => &[],
Some("threads") => return Ok(()),
Some("wide-arithmetic") => &[],
Some(other) => bail!("unknown wasm proposal: {}", other),
Some(_) => &[],
};

let tempdir = TempDir::new()?;
Expand Down
80 changes: 80 additions & 0 deletions src/const_expr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,86 @@ pub enum ConstOp {
}

impl ConstExpr {
/// Attempt to statically evaluate this expression to a [`Value`].
///
/// `resolve_global` is called to obtain the initialiser `ConstExpr` for a
/// global; return `None` for imported globals whose value is not known at
/// compile time. The method returns `None` whenever the expression cannot
/// be fully reduced (unknown global, non-numeric opcode, etc.).
pub fn evaluate_scalar<F>(&self, resolve_global: &F) -> Option<Value>
where
F: Fn(GlobalId) -> Option<ConstExpr>,
{
match self {
ConstExpr::Value(v) => Some(*v),
ConstExpr::Global(g) => resolve_global(*g)?.evaluate_scalar(resolve_global),
ConstExpr::Extended(ops) => {
let mut stack: Vec<Value> = Vec::new();
for op in ops {
match op {
ConstOp::I32Const(n) => stack.push(Value::I32(*n)),
ConstOp::I64Const(n) => stack.push(Value::I64(*n)),
ConstOp::F32Const(n) => stack.push(Value::F32(*n)),
ConstOp::F64Const(n) => stack.push(Value::F64(*n)),
ConstOp::V128Const(n) => stack.push(Value::V128(*n)),
ConstOp::GlobalGet(g) => {
stack.push(resolve_global(*g)?.evaluate_scalar(resolve_global)?);
}
ConstOp::I32Add => {
let (Value::I32(b), Value::I32(a)) = (stack.pop()?, stack.pop()?)
else {
return None;
};
stack.push(Value::I32(a.wrapping_add(b)));
}
ConstOp::I32Sub => {
let (Value::I32(b), Value::I32(a)) = (stack.pop()?, stack.pop()?)
else {
return None;
};
stack.push(Value::I32(a.wrapping_sub(b)));
}
ConstOp::I32Mul => {
let (Value::I32(b), Value::I32(a)) = (stack.pop()?, stack.pop()?)
else {
return None;
};
stack.push(Value::I32(a.wrapping_mul(b)));
}
ConstOp::I64Add => {
let (Value::I64(b), Value::I64(a)) = (stack.pop()?, stack.pop()?)
else {
return None;
};
stack.push(Value::I64(a.wrapping_add(b)));
}
ConstOp::I64Sub => {
let (Value::I64(b), Value::I64(a)) = (stack.pop()?, stack.pop()?)
else {
return None;
};
stack.push(Value::I64(a.wrapping_sub(b)));
}
ConstOp::I64Mul => {
let (Value::I64(b), Value::I64(a)) = (stack.pop()?, stack.pop()?)
else {
return None;
};
stack.push(Value::I64(a.wrapping_mul(b)));
}
_ => return None,
}
}
if stack.len() == 1 {
stack.pop()
} else {
None
}
}
_ => None,
}
}

pub(crate) fn eval(init: &wasmparser::ConstExpr, ids: &IndicesToIds) -> Result<ConstExpr> {
use wasmparser::Operator::*;
let mut reader = init.get_operators_reader();
Expand Down
Loading