Browse Source

Implement the extended-const proposal (#9141)

This commit builds on the support added in #8450 to extend our simple
interpreter with support for the `extended-const` proposal to
WebAssembly. This is required when updating the spec-test-submodule
since `extended-const` was merged into the mainline specification and
some proposals are starting to rebase on that.
pull/9144/head
Alex Crichton 3 months ago
committed by GitHub
parent
commit
766620e4f4
No known key found for this signature in database GPG Key ID: B5690EEEBB952194
  1. 12
      crates/types/src/lib.rs
  2. 15
      crates/wasmtime/src/config.rs
  3. 30
      crates/wasmtime/src/runtime/vm/const_expr.rs
  4. 6
      tests/wast.rs

12
crates/types/src/lib.rs

@ -1484,6 +1484,12 @@ pub enum ConstOp {
RefI31,
RefNull,
RefFunc(FuncIndex),
I32Add,
I32Sub,
I32Mul,
I64Add,
I64Sub,
I64Mul,
}
impl ConstOp {
@ -1500,6 +1506,12 @@ impl ConstOp {
O::RefFunc { function_index } => Self::RefFunc(FuncIndex::from_u32(function_index)),
O::GlobalGet { global_index } => Self::GlobalGet(GlobalIndex::from_u32(global_index)),
O::RefI31 => Self::RefI31,
O::I32Add => Self::I32Add,
O::I32Sub => Self::I32Sub,
O::I32Mul => Self::I32Mul,
O::I64Add => Self::I64Add,
O::I64Sub => Self::I64Sub,
O::I64Mul => Self::I64Mul,
op => {
return Err(wasm_unsupported!(
"unsupported opcode in const expression at offset {offset:#x}: {op:?}",

15
crates/wasmtime/src/config.rs

@ -259,9 +259,6 @@ impl Config {
ret.cranelift_opt_level(OptLevel::Speed);
}
// Not yet implemented in Wasmtime
ret.features.set(WasmFeatures::EXTENDED_CONST, false);
// Conditionally enabled features depending on compile-time crate
// features. Note that if these features are disabled then `Config` has
// no way of re-enabling them.
@ -285,6 +282,7 @@ impl Config {
ret.wasm_multi_value(true);
ret.wasm_bulk_memory(true);
ret.wasm_simd(true);
ret.wasm_extended_const(true);
ret.wasm_backtrace_details(WasmBacktraceDetails::Environment);
ret
@ -963,6 +961,17 @@ impl Config {
self
}
/// Configures whether the WebAssembly extended-const [proposal] will
/// be enabled for compilation.
///
/// This is `true` by default.
///
/// [proposal]: https://github.com/webassembly/extended-const
pub fn wasm_extended_const(&mut self, enable: bool) -> &mut Self {
self.features.set(WasmFeatures::EXTENDED_CONST, enable);
self
}
/// Configures whether the WebAssembly component-model [proposal] will
/// be enabled for compilation.
///

30
crates/wasmtime/src/runtime/vm/const_expr.rs

@ -78,6 +78,36 @@ impl ConstExprEvaluator {
let raw = VMGcRef::from_i31(i31).as_raw_u32();
self.stack.push(ValRaw::anyref(raw));
}
wasmtime_environ::ConstOp::I32Add => {
let b = self.pop()?.get_i32();
let a = self.pop()?.get_i32();
self.stack.push(ValRaw::i32(a.wrapping_add(b)));
}
wasmtime_environ::ConstOp::I32Sub => {
let b = self.pop()?.get_i32();
let a = self.pop()?.get_i32();
self.stack.push(ValRaw::i32(a.wrapping_sub(b)));
}
wasmtime_environ::ConstOp::I32Mul => {
let b = self.pop()?.get_i32();
let a = self.pop()?.get_i32();
self.stack.push(ValRaw::i32(a.wrapping_mul(b)));
}
wasmtime_environ::ConstOp::I64Add => {
let b = self.pop()?.get_i64();
let a = self.pop()?.get_i64();
self.stack.push(ValRaw::i64(a.wrapping_add(b)));
}
wasmtime_environ::ConstOp::I64Sub => {
let b = self.pop()?.get_i64();
let a = self.pop()?.get_i64();
self.stack.push(ValRaw::i64(a.wrapping_sub(b)));
}
wasmtime_environ::ConstOp::I64Mul => {
let b = self.pop()?.get_i64();
let a = self.pop()?.get_i64();
self.stack.push(ValRaw::i64(a.wrapping_mul(b)));
}
}
}

6
tests/wast.rs

@ -74,10 +74,6 @@ fn ignore(test: &Path, strategy: Strategy) -> bool {
if part == "exception-handling" {
return true;
}
// Not implemented in Wasmtime yet
if part == "extended-const" {
return true;
}
// Wasmtime doesn't implement the table64 extension yet.
if part == "memory64" {
if [
@ -219,6 +215,7 @@ fn run_wast(wast: &Path, strategy: Strategy, pooling: bool) -> anyhow::Result<()
let tail_call = feature_found(wast, "tail-call") || feature_found(wast, "function-references");
let use_shared_memory = feature_found_src(&wast_bytes, "shared_memory")
|| feature_found_src(&wast_bytes, "shared)");
let extended_const = feature_found(wast, "extended-const");
if pooling && use_shared_memory {
log::warn!("skipping pooling test with shared memory");
@ -240,6 +237,7 @@ fn run_wast(wast: &Path, strategy: Strategy, pooling: bool) -> anyhow::Result<()
.wasm_relaxed_simd(relaxed_simd)
.wasm_tail_call(tail_call)
.wasm_custom_page_sizes(custom_page_sizes)
.wasm_extended_const(extended_const)
.strategy(strategy);
if is_cranelift {

Loading…
Cancel
Save