Skip to content
This repository was archived by the owner on May 20, 2020. It is now read-only.
This repository was archived by the owner on May 20, 2020. It is now read-only.

Early parse error for v8x16.shuffle #44

@abrown

Description

@abrown

The SIMD testsuite contains an assert_invalid directive in which v8x16.shuffle uses a negative index. When wasmtime attempts to run this test, it fails with:

running 1 test
test Cranelift::simd::simd_lane ... FAILED

failures:

---- Cranelift::simd::simd_lane stdout ----
Error: invalid u8 number: constant out of range
     --> tests/spec_testsuite/proposals/simd/simd_lane.wast:492:18
      |
  492 |   (v8x16.shuffle -1 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14
      |                  ^
thread 'Cranelift::simd::simd_lane' panicked at 'assertion failed: `(left == right)`
  left: `1`,
 right: `0`: the test returned a termination value with a non-zero status code (1) which indicates a failure', src/libtest/lib.rs:196:5
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace.

In wast, I can alter V8x16Shuffle to use i8 as the index type (patch at bottom), but this then allows negative indexes to flow to Cranelift, which promptly fails with:

running 1 test
thread '<unnamed>' panicked at 'assertion failed: lane > 0 && lane <= 3', /home/abrown/.cargo/registry/src/github.com-1ecc6299db9ec823/cranelift-codegen-0.54.0/src/isa/x86/enc_tables.rs:1176:21
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace.
test Cranelift::simd::simd_lane ... FAILED

How should we fix this? And why isn't wasmparser's validation catching this invalid index beforehand?

Patch wast's V8x16Shuffle to use `i8`:
diff --git a/crates/wast/src/ast/expr.rs b/crates/wast/src/ast/expr.rs
index 6d55f6f..b8454e8 100644
--- a/crates/wast/src/ast/expr.rs
+++ b/crates/wast/src/ast/expr.rs
@@ -1008,7 +1008,7 @@ impl<'a> Parse<'a> for V128Const {
 #[derive(Debug)]
 pub struct V8x16Shuffle {
     #[allow(missing_docs)]
-    pub lanes: [u8; 16],
+    pub lanes: [i8; 16],
 }
 
 impl<'a> Parse<'a> for V8x16Shuffle {
diff --git a/crates/wast/src/binary.rs b/crates/wast/src/binary.rs
index baa0188..1b4d6e2 100644
--- a/crates/wast/src/binary.rs
+++ b/crates/wast/src/binary.rs
@@ -668,7 +668,8 @@ impl Encode for V128Const {
 
 impl Encode for V8x16Shuffle {
     fn encode(&self, dst: &mut Vec<u8>) {
-        dst.extend_from_slice(&self.lanes);
+        let indexes: Vec<u8> = self.lanes.iter().map(|&i| i as u8).collect();
+        dst.extend_from_slice(&indexes);
     }
 }

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions