diff --git a/crates/wast/src/lib.rs b/crates/wast/src/lib.rs index c74d1865e1..5d65df137b 100644 --- a/crates/wast/src/lib.rs +++ b/crates/wast/src/lib.rs @@ -529,6 +529,8 @@ pub mod kw { custom_keyword!(needed); custom_keyword!(export_info = "export-info"); custom_keyword!(import_info = "import-info"); + custom_keyword!(thread); + custom_keyword!(wait); } /// Common annotations used to parse WebAssembly text files. diff --git a/crates/wast/src/wast.rs b/crates/wast/src/wast.rs index 1508edb963..1db07e3d14 100644 --- a/crates/wast/src/wast.rs +++ b/crates/wast/src/wast.rs @@ -102,6 +102,11 @@ pub enum WastDirective<'a> { span: Span, exec: WastExecute<'a>, }, + Thread(WastThread<'a>), + Wait { + span: Span, + thread: Id<'a>, + }, } impl WastDirective<'_> { @@ -119,8 +124,10 @@ impl WastDirective<'_> { | WastDirective::AssertExhaustion { span, .. } | WastDirective::AssertUnlinkable { span, .. } | WastDirective::AssertInvalid { span, .. } - | WastDirective::AssertException { span, .. } => *span, + | WastDirective::AssertException { span, .. } + | WastDirective::Wait { span, .. } => *span, WastDirective::Invoke(i) => i.span, + WastDirective::Thread(t) => t.span, } } } @@ -192,6 +199,14 @@ impl<'a> Parse<'a> for WastDirective<'a> { span, exec: parser.parens(|p| p.parse())?, }) + } else if l.peek::()? { + Ok(WastDirective::Thread(parser.parse()?)) + } else if l.peek::()? { + let span = parser.parse::()?.0; + Ok(WastDirective::Wait { + span, + thread: parser.parse()?, + }) } else { Err(l.error()) } @@ -363,3 +378,49 @@ impl<'a> Parse<'a> for WastRet<'a> { } } } + +#[derive(Debug)] +#[allow(missing_docs)] +pub struct WastThread<'a> { + pub span: Span, + pub name: Id<'a>, + pub shared_module: Option>, + pub directives: Vec>, +} + +impl<'a> Parse<'a> for WastThread<'a> { + fn parse(parser: Parser<'a>) -> Result { + parser.depth_check()?; + let span = parser.parse::()?.0; + let name = parser.parse()?; + + let shared_module = if parser.peek2::()? { + let name = parser.parens(|p| { + p.parse::()?; + p.parens(|p| { + p.parse::()?; + p.parse() + }) + })?; + Some(name) + } else { + None + }; + let mut directives = Vec::new(); + while !parser.is_empty() { + directives.push(parser.parens(|p| p.parse())?); + } + Ok(WastThread { + span, + name, + shared_module, + directives, + }) + + // if parser.peek::>()? { + // Ok(WastRet::Core(parser.parse()?)) + // } else { + // Ok(WastRet::Component(parser.parse()?)) + // } + } +} diff --git a/tests/local/upstream-threads/LB.wast b/tests/local/upstream-threads/LB.wast new file mode 100644 index 0000000000..dc5af8530d --- /dev/null +++ b/tests/local/upstream-threads/LB.wast @@ -0,0 +1,62 @@ +(module $Mem + (memory (export "shared") 1 1 shared) +) + +(thread $T1 (shared (module $Mem)) + (register "mem" $Mem) + (module + (memory (import "mem" "shared") 1 10 shared) + (func (export "run") + (local i32) + (i32.load (i32.const 4)) + (local.set 0) + (i32.store (i32.const 0) (i32.const 1)) + + ;; store results for checking + (i32.store (i32.const 24) (local.get 0)) + ) + ) + (invoke "run") +) + +(thread $T2 (shared (module $Mem)) + (register "mem" $Mem) + (module + (memory (import "mem" "shared") 1 1 shared) + (func (export "run") + (local i32) + (i32.load (i32.const 0)) + (local.set 0) + (i32.store (i32.const 4) (i32.const 1)) + + ;; store results for checking + (i32.store (i32.const 32) (local.get 0)) + ) + ) + + (invoke "run") +) + +(wait $T1) +(wait $T2) + +(module $Check + (memory (import "mem" "shared") 1 1 shared) + + (func (export "check") (result i32) + (local i32 i32) + (i32.load (i32.const 24)) + (local.set 0) + (i32.load (i32.const 32)) + (local.set 1) + + ;; allowed results: (L_0 = 0 || L_0 = 1) && (L_1 = 0 || L_1 = 1) + + (i32.or (i32.eq (local.get 0) (i32.const 1)) (i32.eq (local.get 0) (i32.const 0))) + (i32.or (i32.eq (local.get 1) (i32.const 1)) (i32.eq (local.get 0) (i32.const 0))) + (i32.and) + (return) + ) +) + +(assert_return (invoke $Check "check") (i32.const 1)) diff --git a/tests/local/upstream-threads/LB_atomic.wast b/tests/local/upstream-threads/LB_atomic.wast new file mode 100644 index 0000000000..79642713a4 --- /dev/null +++ b/tests/local/upstream-threads/LB_atomic.wast @@ -0,0 +1,64 @@ +(module $Mem + (memory (export "shared") 1 1 shared) +) + +(thread $T1 (shared (module $Mem)) + (register "mem" $Mem) + (module + (memory (import "mem" "shared") 1 10 shared) + (func (export "run") + (local i32) + (i32.atomic.load (i32.const 4)) + (local.set 0) + (i32.atomic.store (i32.const 0) (i32.const 1)) + + ;; store results for checking + (i32.store (i32.const 24) (local.get 0)) + ) + ) + (invoke "run") +) + +(thread $T2 (shared (module $Mem)) + (register "mem" $Mem) + (module + (memory (import "mem" "shared") 1 1 shared) + (func (export "run") + (local i32) + (i32.atomic.load (i32.const 0)) + (local.set 0) + (i32.atomic.store (i32.const 4) (i32.const 1)) + + ;; store results for checking + (i32.store (i32.const 32) (local.get 0)) + ) + ) + + (invoke "run") +) + +(wait $T1) +(wait $T2) + +(module $Check + (memory (import "mem" "shared") 1 1 shared) + + (func (export "check") (result i32) + (local i32 i32) + (i32.load (i32.const 24)) + (local.set 0) + (i32.load (i32.const 32)) + (local.set 1) + + ;; allowed results: (L_0 = 0 && L_1 = 0) || (L_0 = 0 && L_1 = 1) || (L_0 = 1 && L_1 = 0) + + (i32.and (i32.eq (local.get 0) (i32.const 0)) (i32.eq (local.get 1) (i32.const 0))) + (i32.and (i32.eq (local.get 0) (i32.const 0)) (i32.eq (local.get 1) (i32.const 1))) + (i32.and (i32.eq (local.get 0) (i32.const 1)) (i32.eq (local.get 1) (i32.const 0))) + (i32.or) + (i32.or) + (return) + ) +) + +(assert_return (invoke $Check "check") (i32.const 1)) diff --git a/tests/local/upstream-threads/MP.wast b/tests/local/upstream-threads/MP.wast new file mode 100644 index 0000000000..e14508596f --- /dev/null +++ b/tests/local/upstream-threads/MP.wast @@ -0,0 +1,59 @@ +(module $Mem + (memory (export "shared") 1 1 shared) +) + +(thread $T1 (shared (module $Mem)) + (register "mem" $Mem) + (module + (memory (import "mem" "shared") 1 10 shared) + (func (export "run") + (i32.store (i32.const 0) (i32.const 42)) + (i32.store (i32.const 4) (i32.const 1)) + ) + ) + (invoke "run") +) + +(thread $T2 (shared (module $Mem)) + (register "mem" $Mem) + (module + (memory (import "mem" "shared") 1 1 shared) + (func (export "run") + (local i32 i32) + (i32.load (i32.const 4)) + (local.set 0) + (i32.load (i32.const 0)) + (local.set 1) + + ;; store results for checking + (i32.store (i32.const 24) (local.get 0)) + (i32.store (i32.const 32) (local.get 1)) + ) + ) + + (invoke "run") +) + +(wait $T1) +(wait $T2) + +(module $Check + (memory (import "mem" "shared") 1 1 shared) + + (func (export "check") (result i32) + (local i32 i32) + (i32.load (i32.const 24)) + (local.set 0) + (i32.load (i32.const 32)) + (local.set 1) + + ;; allowed results: (L_0 = 0 || L_0 = 1) && (L_1 = 0 || L_1 = 42) + + (i32.or (i32.eq (local.get 0) (i32.const 1)) (i32.eq (local.get 0) (i32.const 0))) + (i32.or (i32.eq (local.get 1) (i32.const 42)) (i32.eq (local.get 0) (i32.const 0))) + (i32.and) + (return) + ) +) + +(assert_return (invoke $Check "check") (i32.const 1)) diff --git a/tests/local/upstream-threads/MP_atomic.wast b/tests/local/upstream-threads/MP_atomic.wast new file mode 100644 index 0000000000..2001634a22 --- /dev/null +++ b/tests/local/upstream-threads/MP_atomic.wast @@ -0,0 +1,61 @@ +(module $Mem + (memory (export "shared") 1 1 shared) +) + +(thread $T1 (shared (module $Mem)) + (register "mem" $Mem) + (module + (memory (import "mem" "shared") 1 10 shared) + (func (export "run") + (i32.atomic.store (i32.const 0) (i32.const 42)) + (i32.atomic.store (i32.const 4) (i32.const 1)) + ) + ) + (invoke "run") +) + +(thread $T2 (shared (module $Mem)) + (register "mem" $Mem) + (module + (memory (import "mem" "shared") 1 1 shared) + (func (export "run") + (local i32 i32) + (i32.atomic.load (i32.const 4)) + (local.set 0) + (i32.atomic.load (i32.const 0)) + (local.set 1) + + ;; store results for checking + (i32.store (i32.const 24) (local.get 0)) + (i32.store (i32.const 32) (local.get 1)) + ) + ) + + (invoke "run") +) + +(wait $T1) +(wait $T2) + +(module $Check + (memory (import "mem" "shared") 1 1 shared) + + (func (export "check") (result i32) + (local i32 i32) + (i32.load (i32.const 24)) + (local.set 0) + (i32.load (i32.const 32)) + (local.set 1) + + ;; allowed results: (L_0 = 1 && L_1 = 42) || (L_0 = 0 && L_1 = 0) || (L_0 = 0 && L_1 = 42) + + (i32.and (i32.eq (local.get 0) (i32.const 1)) (i32.eq (local.get 1) (i32.const 42))) + (i32.and (i32.eq (local.get 0) (i32.const 0)) (i32.eq (local.get 1) (i32.const 0))) + (i32.and (i32.eq (local.get 0) (i32.const 0)) (i32.eq (local.get 1) (i32.const 42))) + (i32.or) + (i32.or) + (return) + ) +) + +(assert_return (invoke $Check "check") (i32.const 1)) diff --git a/tests/local/upstream-threads/MP_wait.wast b/tests/local/upstream-threads/MP_wait.wast new file mode 100644 index 0000000000..2001634a22 --- /dev/null +++ b/tests/local/upstream-threads/MP_wait.wast @@ -0,0 +1,61 @@ +(module $Mem + (memory (export "shared") 1 1 shared) +) + +(thread $T1 (shared (module $Mem)) + (register "mem" $Mem) + (module + (memory (import "mem" "shared") 1 10 shared) + (func (export "run") + (i32.atomic.store (i32.const 0) (i32.const 42)) + (i32.atomic.store (i32.const 4) (i32.const 1)) + ) + ) + (invoke "run") +) + +(thread $T2 (shared (module $Mem)) + (register "mem" $Mem) + (module + (memory (import "mem" "shared") 1 1 shared) + (func (export "run") + (local i32 i32) + (i32.atomic.load (i32.const 4)) + (local.set 0) + (i32.atomic.load (i32.const 0)) + (local.set 1) + + ;; store results for checking + (i32.store (i32.const 24) (local.get 0)) + (i32.store (i32.const 32) (local.get 1)) + ) + ) + + (invoke "run") +) + +(wait $T1) +(wait $T2) + +(module $Check + (memory (import "mem" "shared") 1 1 shared) + + (func (export "check") (result i32) + (local i32 i32) + (i32.load (i32.const 24)) + (local.set 0) + (i32.load (i32.const 32)) + (local.set 1) + + ;; allowed results: (L_0 = 1 && L_1 = 42) || (L_0 = 0 && L_1 = 0) || (L_0 = 0 && L_1 = 42) + + (i32.and (i32.eq (local.get 0) (i32.const 1)) (i32.eq (local.get 1) (i32.const 42))) + (i32.and (i32.eq (local.get 0) (i32.const 0)) (i32.eq (local.get 1) (i32.const 0))) + (i32.and (i32.eq (local.get 0) (i32.const 0)) (i32.eq (local.get 1) (i32.const 42))) + (i32.or) + (i32.or) + (return) + ) +) + +(assert_return (invoke $Check "check") (i32.const 1)) diff --git a/tests/local/upstream-threads/SB.wast b/tests/local/upstream-threads/SB.wast new file mode 100644 index 0000000000..65fe7853d8 --- /dev/null +++ b/tests/local/upstream-threads/SB.wast @@ -0,0 +1,62 @@ +(module $Mem + (memory (export "shared") 1 1 shared) +) + +(thread $T1 (shared (module $Mem)) + (register "mem" $Mem) + (module + (memory (import "mem" "shared") 1 10 shared) + (func (export "run") + (local i32) + (i32.store (i32.const 0) (i32.const 1)) + (i32.load (i32.const 4)) + (local.set 0) + + ;; store results for checking + (i32.store (i32.const 24) (local.get 0)) + ) + ) + (invoke "run") +) + +(thread $T2 (shared (module $Mem)) + (register "mem" $Mem) + (module + (memory (import "mem" "shared") 1 1 shared) + (func (export "run") + (local i32) + (i32.store (i32.const 4) (i32.const 1)) + (i32.load (i32.const 0)) + (local.set 0) + + ;; store results for checking + (i32.store (i32.const 32) (local.get 0)) + ) + ) + + (invoke "run") +) + +(wait $T1) +(wait $T2) + +(module $Check + (memory (import "mem" "shared") 1 1 shared) + + (func (export "check") (result i32) + (local i32 i32) + (i32.load (i32.const 24)) + (local.set 0) + (i32.load (i32.const 32)) + (local.set 1) + + ;; allowed results: (L_0 = 0 || L_0 = 1) && (L_1 = 0 || L_1 = 1) + + (i32.or (i32.eq (local.get 0) (i32.const 1)) (i32.eq (local.get 0) (i32.const 0))) + (i32.or (i32.eq (local.get 1) (i32.const 1)) (i32.eq (local.get 0) (i32.const 0))) + (i32.and) + (return) + ) +) + +(assert_return (invoke $Check "check") (i32.const 1)) diff --git a/tests/local/upstream-threads/SB_atomic.wast b/tests/local/upstream-threads/SB_atomic.wast new file mode 100644 index 0000000000..3bd8c8a6db --- /dev/null +++ b/tests/local/upstream-threads/SB_atomic.wast @@ -0,0 +1,64 @@ +(module $Mem + (memory (export "shared") 1 1 shared) +) + +(thread $T1 (shared (module $Mem)) + (register "mem" $Mem) + (module + (memory (import "mem" "shared") 1 10 shared) + (func (export "run") + (local i32) + (i32.atomic.store (i32.const 0) (i32.const 1)) + (i32.atomic.load (i32.const 4)) + (local.set 0) + + ;; store results for checking + (i32.store (i32.const 24) (local.get 0)) + ) + ) + (invoke "run") +) + +(thread $T2 (shared (module $Mem)) + (register "mem" $Mem) + (module + (memory (import "mem" "shared") 1 1 shared) + (func (export "run") + (local i32) + (i32.atomic.store (i32.const 4) (i32.const 1)) + (i32.atomic.load (i32.const 0)) + (local.set 0) + + ;; store results for checking + (i32.store (i32.const 32) (local.get 0)) + ) + ) + + (invoke "run") +) + +(wait $T1) +(wait $T2) + +(module $Check + (memory (import "mem" "shared") 1 1 shared) + + (func (export "check") (result i32) + (local i32 i32) + (i32.load (i32.const 24)) + (local.set 0) + (i32.load (i32.const 32)) + (local.set 1) + + ;; allowed results: (L_0 = 1 && L_1 = 1) || (L_0 = 0 && L_1 = 1) || (L_0 = 1 && L_1 = 0) + + (i32.and (i32.eq (local.get 0) (i32.const 1)) (i32.eq (local.get 1) (i32.const 1))) + (i32.and (i32.eq (local.get 0) (i32.const 0)) (i32.eq (local.get 1) (i32.const 1))) + (i32.and (i32.eq (local.get 0) (i32.const 1)) (i32.eq (local.get 1) (i32.const 0))) + (i32.or) + (i32.or) + (return) + ) +) + +(assert_return (invoke $Check "check") (i32.const 1)) diff --git a/tests/local/upstream-threads/wait_notify.wast b/tests/local/upstream-threads/wait_notify.wast new file mode 100644 index 0000000000..270509a92d --- /dev/null +++ b/tests/local/upstream-threads/wait_notify.wast @@ -0,0 +1,41 @@ +;; test that looping notify eventually unblocks a parallel waiting thread +(module $Mem + (memory (export "shared") 1 1 shared) +) + +(thread $T1 (shared (module $Mem)) + (register "mem" $Mem) + (module + (memory (import "mem" "shared") 1 10 shared) + (func (export "run") (result i32) + (memory.atomic.wait32 (i32.const 0) (i32.const 0) (i64.const -1)) + ) + ) + ;; test that this thread eventually gets unblocked + (assert_return (invoke "run") (i32.const 0)) +) + +(thread $T2 (shared (module $Mem)) + (register "mem" $Mem) + (module + (memory (import "mem" "shared") 1 1 shared) + (func (export "notify-0") (result i32) + (memory.atomic.notify (i32.const 0) (i32.const 0)) + ) + (func (export "notify-1-while") + (loop + (i32.const 1) + (memory.atomic.notify (i32.const 0) (i32.const 1)) + (i32.ne) + (br_if 0) + ) + ) + ) + ;; notifying with a count of 0 will not unblock + (assert_return (invoke "notify-0") (i32.const 0)) + ;; loop until something is notified + (assert_return (invoke "notify-1-while")) +) + +(wait $T1) +(wait $T2) diff --git a/tests/roundtrip.rs b/tests/roundtrip.rs index 2262b3b221..d42f956ab3 100644 --- a/tests/roundtrip.rs +++ b/tests/roundtrip.rs @@ -417,6 +417,12 @@ impl TestState { } } + WastDirective::Thread(thread) => { + for (i, directive) in thread.directives.into_iter().enumerate() { + self.test_wast_directive(test, directive, idx * 1000 + i)?; + } + } + // This test suite doesn't actually execute any wasm code, so ignore // all of these assertions. WastDirective::Register { .. } @@ -425,7 +431,8 @@ impl TestState { | WastDirective::AssertReturn { .. } | WastDirective::AssertExhaustion { .. } | WastDirective::AssertUnlinkable { .. } - | WastDirective::AssertException { .. } => {} + | WastDirective::AssertException { .. } + | WastDirective::Wait { .. } => {} } Ok(()) } diff --git a/tests/snapshots/local/upstream-threads/LB.wast/0.print b/tests/snapshots/local/upstream-threads/LB.wast/0.print new file mode 100644 index 0000000000..0c5fc57030 --- /dev/null +++ b/tests/snapshots/local/upstream-threads/LB.wast/0.print @@ -0,0 +1,4 @@ +(module $Mem + (memory (;0;) 1 1 shared) + (export "shared" (memory 0)) +) \ No newline at end of file diff --git a/tests/snapshots/local/upstream-threads/LB.wast/1001.print b/tests/snapshots/local/upstream-threads/LB.wast/1001.print new file mode 100644 index 0000000000..ec4622d267 --- /dev/null +++ b/tests/snapshots/local/upstream-threads/LB.wast/1001.print @@ -0,0 +1,17 @@ +(module + (type (;0;) (func)) + (import "mem" "shared" (memory (;0;) 1 10 shared)) + (func (;0;) (type 0) + (local i32) + i32.const 4 + i32.load + local.set 0 + i32.const 0 + i32.const 1 + i32.store + i32.const 24 + local.get 0 + i32.store + ) + (export "run" (func 0)) +) \ No newline at end of file diff --git a/tests/snapshots/local/upstream-threads/LB.wast/2001.print b/tests/snapshots/local/upstream-threads/LB.wast/2001.print new file mode 100644 index 0000000000..4d46596968 --- /dev/null +++ b/tests/snapshots/local/upstream-threads/LB.wast/2001.print @@ -0,0 +1,17 @@ +(module + (type (;0;) (func)) + (import "mem" "shared" (memory (;0;) 1 1 shared)) + (func (;0;) (type 0) + (local i32) + i32.const 0 + i32.load + local.set 0 + i32.const 4 + i32.const 1 + i32.store + i32.const 32 + local.get 0 + i32.store + ) + (export "run" (func 0)) +) \ No newline at end of file diff --git a/tests/snapshots/local/upstream-threads/LB.wast/5.print b/tests/snapshots/local/upstream-threads/LB.wast/5.print new file mode 100644 index 0000000000..c5a71158bd --- /dev/null +++ b/tests/snapshots/local/upstream-threads/LB.wast/5.print @@ -0,0 +1,30 @@ +(module $Check + (type (;0;) (func (result i32))) + (import "mem" "shared" (memory (;0;) 1 1 shared)) + (func (;0;) (type 0) (result i32) + (local i32 i32) + i32.const 24 + i32.load + local.set 0 + i32.const 32 + i32.load + local.set 1 + local.get 0 + i32.const 1 + i32.eq + local.get 0 + i32.const 0 + i32.eq + i32.or + local.get 1 + i32.const 1 + i32.eq + local.get 0 + i32.const 0 + i32.eq + i32.or + i32.and + return + ) + (export "check" (func 0)) +) \ No newline at end of file diff --git a/tests/snapshots/local/upstream-threads/LB_atomic.wast/0.print b/tests/snapshots/local/upstream-threads/LB_atomic.wast/0.print new file mode 100644 index 0000000000..0c5fc57030 --- /dev/null +++ b/tests/snapshots/local/upstream-threads/LB_atomic.wast/0.print @@ -0,0 +1,4 @@ +(module $Mem + (memory (;0;) 1 1 shared) + (export "shared" (memory 0)) +) \ No newline at end of file diff --git a/tests/snapshots/local/upstream-threads/LB_atomic.wast/1001.print b/tests/snapshots/local/upstream-threads/LB_atomic.wast/1001.print new file mode 100644 index 0000000000..970c0227f9 --- /dev/null +++ b/tests/snapshots/local/upstream-threads/LB_atomic.wast/1001.print @@ -0,0 +1,17 @@ +(module + (type (;0;) (func)) + (import "mem" "shared" (memory (;0;) 1 10 shared)) + (func (;0;) (type 0) + (local i32) + i32.const 4 + i32.atomic.load + local.set 0 + i32.const 0 + i32.const 1 + i32.atomic.store + i32.const 24 + local.get 0 + i32.store + ) + (export "run" (func 0)) +) \ No newline at end of file diff --git a/tests/snapshots/local/upstream-threads/LB_atomic.wast/2001.print b/tests/snapshots/local/upstream-threads/LB_atomic.wast/2001.print new file mode 100644 index 0000000000..30a2619d1b --- /dev/null +++ b/tests/snapshots/local/upstream-threads/LB_atomic.wast/2001.print @@ -0,0 +1,17 @@ +(module + (type (;0;) (func)) + (import "mem" "shared" (memory (;0;) 1 1 shared)) + (func (;0;) (type 0) + (local i32) + i32.const 0 + i32.atomic.load + local.set 0 + i32.const 4 + i32.const 1 + i32.atomic.store + i32.const 32 + local.get 0 + i32.store + ) + (export "run" (func 0)) +) \ No newline at end of file diff --git a/tests/snapshots/local/upstream-threads/LB_atomic.wast/5.print b/tests/snapshots/local/upstream-threads/LB_atomic.wast/5.print new file mode 100644 index 0000000000..e883dc159e --- /dev/null +++ b/tests/snapshots/local/upstream-threads/LB_atomic.wast/5.print @@ -0,0 +1,38 @@ +(module $Check + (type (;0;) (func (result i32))) + (import "mem" "shared" (memory (;0;) 1 1 shared)) + (func (;0;) (type 0) (result i32) + (local i32 i32) + i32.const 24 + i32.load + local.set 0 + i32.const 32 + i32.load + local.set 1 + local.get 0 + i32.const 0 + i32.eq + local.get 1 + i32.const 0 + i32.eq + i32.and + local.get 0 + i32.const 0 + i32.eq + local.get 1 + i32.const 1 + i32.eq + i32.and + local.get 0 + i32.const 1 + i32.eq + local.get 1 + i32.const 0 + i32.eq + i32.and + i32.or + i32.or + return + ) + (export "check" (func 0)) +) \ No newline at end of file diff --git a/tests/snapshots/local/upstream-threads/MP.wast/0.print b/tests/snapshots/local/upstream-threads/MP.wast/0.print new file mode 100644 index 0000000000..0c5fc57030 --- /dev/null +++ b/tests/snapshots/local/upstream-threads/MP.wast/0.print @@ -0,0 +1,4 @@ +(module $Mem + (memory (;0;) 1 1 shared) + (export "shared" (memory 0)) +) \ No newline at end of file diff --git a/tests/snapshots/local/upstream-threads/MP.wast/1001.print b/tests/snapshots/local/upstream-threads/MP.wast/1001.print new file mode 100644 index 0000000000..b2aa175be7 --- /dev/null +++ b/tests/snapshots/local/upstream-threads/MP.wast/1001.print @@ -0,0 +1,13 @@ +(module + (type (;0;) (func)) + (import "mem" "shared" (memory (;0;) 1 10 shared)) + (func (;0;) (type 0) + i32.const 0 + i32.const 42 + i32.store + i32.const 4 + i32.const 1 + i32.store + ) + (export "run" (func 0)) +) \ No newline at end of file diff --git a/tests/snapshots/local/upstream-threads/MP.wast/2001.print b/tests/snapshots/local/upstream-threads/MP.wast/2001.print new file mode 100644 index 0000000000..48117d8458 --- /dev/null +++ b/tests/snapshots/local/upstream-threads/MP.wast/2001.print @@ -0,0 +1,20 @@ +(module + (type (;0;) (func)) + (import "mem" "shared" (memory (;0;) 1 1 shared)) + (func (;0;) (type 0) + (local i32 i32) + i32.const 4 + i32.load + local.set 0 + i32.const 0 + i32.load + local.set 1 + i32.const 24 + local.get 0 + i32.store + i32.const 32 + local.get 1 + i32.store + ) + (export "run" (func 0)) +) \ No newline at end of file diff --git a/tests/snapshots/local/upstream-threads/MP.wast/5.print b/tests/snapshots/local/upstream-threads/MP.wast/5.print new file mode 100644 index 0000000000..f7f4a0a7e3 --- /dev/null +++ b/tests/snapshots/local/upstream-threads/MP.wast/5.print @@ -0,0 +1,30 @@ +(module $Check + (type (;0;) (func (result i32))) + (import "mem" "shared" (memory (;0;) 1 1 shared)) + (func (;0;) (type 0) (result i32) + (local i32 i32) + i32.const 24 + i32.load + local.set 0 + i32.const 32 + i32.load + local.set 1 + local.get 0 + i32.const 1 + i32.eq + local.get 0 + i32.const 0 + i32.eq + i32.or + local.get 1 + i32.const 42 + i32.eq + local.get 0 + i32.const 0 + i32.eq + i32.or + i32.and + return + ) + (export "check" (func 0)) +) \ No newline at end of file diff --git a/tests/snapshots/local/upstream-threads/MP_atomic.wast/0.print b/tests/snapshots/local/upstream-threads/MP_atomic.wast/0.print new file mode 100644 index 0000000000..0c5fc57030 --- /dev/null +++ b/tests/snapshots/local/upstream-threads/MP_atomic.wast/0.print @@ -0,0 +1,4 @@ +(module $Mem + (memory (;0;) 1 1 shared) + (export "shared" (memory 0)) +) \ No newline at end of file diff --git a/tests/snapshots/local/upstream-threads/MP_atomic.wast/1001.print b/tests/snapshots/local/upstream-threads/MP_atomic.wast/1001.print new file mode 100644 index 0000000000..1daa6c6003 --- /dev/null +++ b/tests/snapshots/local/upstream-threads/MP_atomic.wast/1001.print @@ -0,0 +1,13 @@ +(module + (type (;0;) (func)) + (import "mem" "shared" (memory (;0;) 1 10 shared)) + (func (;0;) (type 0) + i32.const 0 + i32.const 42 + i32.atomic.store + i32.const 4 + i32.const 1 + i32.atomic.store + ) + (export "run" (func 0)) +) \ No newline at end of file diff --git a/tests/snapshots/local/upstream-threads/MP_atomic.wast/2001.print b/tests/snapshots/local/upstream-threads/MP_atomic.wast/2001.print new file mode 100644 index 0000000000..746ccf24a9 --- /dev/null +++ b/tests/snapshots/local/upstream-threads/MP_atomic.wast/2001.print @@ -0,0 +1,20 @@ +(module + (type (;0;) (func)) + (import "mem" "shared" (memory (;0;) 1 1 shared)) + (func (;0;) (type 0) + (local i32 i32) + i32.const 4 + i32.atomic.load + local.set 0 + i32.const 0 + i32.atomic.load + local.set 1 + i32.const 24 + local.get 0 + i32.store + i32.const 32 + local.get 1 + i32.store + ) + (export "run" (func 0)) +) \ No newline at end of file diff --git a/tests/snapshots/local/upstream-threads/MP_atomic.wast/5.print b/tests/snapshots/local/upstream-threads/MP_atomic.wast/5.print new file mode 100644 index 0000000000..ef8b3cd066 --- /dev/null +++ b/tests/snapshots/local/upstream-threads/MP_atomic.wast/5.print @@ -0,0 +1,38 @@ +(module $Check + (type (;0;) (func (result i32))) + (import "mem" "shared" (memory (;0;) 1 1 shared)) + (func (;0;) (type 0) (result i32) + (local i32 i32) + i32.const 24 + i32.load + local.set 0 + i32.const 32 + i32.load + local.set 1 + local.get 0 + i32.const 1 + i32.eq + local.get 1 + i32.const 42 + i32.eq + i32.and + local.get 0 + i32.const 0 + i32.eq + local.get 1 + i32.const 0 + i32.eq + i32.and + local.get 0 + i32.const 0 + i32.eq + local.get 1 + i32.const 42 + i32.eq + i32.and + i32.or + i32.or + return + ) + (export "check" (func 0)) +) \ No newline at end of file diff --git a/tests/snapshots/local/upstream-threads/MP_wait.wast/0.print b/tests/snapshots/local/upstream-threads/MP_wait.wast/0.print new file mode 100644 index 0000000000..0c5fc57030 --- /dev/null +++ b/tests/snapshots/local/upstream-threads/MP_wait.wast/0.print @@ -0,0 +1,4 @@ +(module $Mem + (memory (;0;) 1 1 shared) + (export "shared" (memory 0)) +) \ No newline at end of file diff --git a/tests/snapshots/local/upstream-threads/MP_wait.wast/1001.print b/tests/snapshots/local/upstream-threads/MP_wait.wast/1001.print new file mode 100644 index 0000000000..1daa6c6003 --- /dev/null +++ b/tests/snapshots/local/upstream-threads/MP_wait.wast/1001.print @@ -0,0 +1,13 @@ +(module + (type (;0;) (func)) + (import "mem" "shared" (memory (;0;) 1 10 shared)) + (func (;0;) (type 0) + i32.const 0 + i32.const 42 + i32.atomic.store + i32.const 4 + i32.const 1 + i32.atomic.store + ) + (export "run" (func 0)) +) \ No newline at end of file diff --git a/tests/snapshots/local/upstream-threads/MP_wait.wast/2001.print b/tests/snapshots/local/upstream-threads/MP_wait.wast/2001.print new file mode 100644 index 0000000000..746ccf24a9 --- /dev/null +++ b/tests/snapshots/local/upstream-threads/MP_wait.wast/2001.print @@ -0,0 +1,20 @@ +(module + (type (;0;) (func)) + (import "mem" "shared" (memory (;0;) 1 1 shared)) + (func (;0;) (type 0) + (local i32 i32) + i32.const 4 + i32.atomic.load + local.set 0 + i32.const 0 + i32.atomic.load + local.set 1 + i32.const 24 + local.get 0 + i32.store + i32.const 32 + local.get 1 + i32.store + ) + (export "run" (func 0)) +) \ No newline at end of file diff --git a/tests/snapshots/local/upstream-threads/MP_wait.wast/5.print b/tests/snapshots/local/upstream-threads/MP_wait.wast/5.print new file mode 100644 index 0000000000..ef8b3cd066 --- /dev/null +++ b/tests/snapshots/local/upstream-threads/MP_wait.wast/5.print @@ -0,0 +1,38 @@ +(module $Check + (type (;0;) (func (result i32))) + (import "mem" "shared" (memory (;0;) 1 1 shared)) + (func (;0;) (type 0) (result i32) + (local i32 i32) + i32.const 24 + i32.load + local.set 0 + i32.const 32 + i32.load + local.set 1 + local.get 0 + i32.const 1 + i32.eq + local.get 1 + i32.const 42 + i32.eq + i32.and + local.get 0 + i32.const 0 + i32.eq + local.get 1 + i32.const 0 + i32.eq + i32.and + local.get 0 + i32.const 0 + i32.eq + local.get 1 + i32.const 42 + i32.eq + i32.and + i32.or + i32.or + return + ) + (export "check" (func 0)) +) \ No newline at end of file diff --git a/tests/snapshots/local/upstream-threads/SB.wast/0.print b/tests/snapshots/local/upstream-threads/SB.wast/0.print new file mode 100644 index 0000000000..0c5fc57030 --- /dev/null +++ b/tests/snapshots/local/upstream-threads/SB.wast/0.print @@ -0,0 +1,4 @@ +(module $Mem + (memory (;0;) 1 1 shared) + (export "shared" (memory 0)) +) \ No newline at end of file diff --git a/tests/snapshots/local/upstream-threads/SB.wast/1001.print b/tests/snapshots/local/upstream-threads/SB.wast/1001.print new file mode 100644 index 0000000000..07591f2cd3 --- /dev/null +++ b/tests/snapshots/local/upstream-threads/SB.wast/1001.print @@ -0,0 +1,17 @@ +(module + (type (;0;) (func)) + (import "mem" "shared" (memory (;0;) 1 10 shared)) + (func (;0;) (type 0) + (local i32) + i32.const 0 + i32.const 1 + i32.store + i32.const 4 + i32.load + local.set 0 + i32.const 24 + local.get 0 + i32.store + ) + (export "run" (func 0)) +) \ No newline at end of file diff --git a/tests/snapshots/local/upstream-threads/SB.wast/2001.print b/tests/snapshots/local/upstream-threads/SB.wast/2001.print new file mode 100644 index 0000000000..c39039b89b --- /dev/null +++ b/tests/snapshots/local/upstream-threads/SB.wast/2001.print @@ -0,0 +1,17 @@ +(module + (type (;0;) (func)) + (import "mem" "shared" (memory (;0;) 1 1 shared)) + (func (;0;) (type 0) + (local i32) + i32.const 4 + i32.const 1 + i32.store + i32.const 0 + i32.load + local.set 0 + i32.const 32 + local.get 0 + i32.store + ) + (export "run" (func 0)) +) \ No newline at end of file diff --git a/tests/snapshots/local/upstream-threads/SB.wast/5.print b/tests/snapshots/local/upstream-threads/SB.wast/5.print new file mode 100644 index 0000000000..c5a71158bd --- /dev/null +++ b/tests/snapshots/local/upstream-threads/SB.wast/5.print @@ -0,0 +1,30 @@ +(module $Check + (type (;0;) (func (result i32))) + (import "mem" "shared" (memory (;0;) 1 1 shared)) + (func (;0;) (type 0) (result i32) + (local i32 i32) + i32.const 24 + i32.load + local.set 0 + i32.const 32 + i32.load + local.set 1 + local.get 0 + i32.const 1 + i32.eq + local.get 0 + i32.const 0 + i32.eq + i32.or + local.get 1 + i32.const 1 + i32.eq + local.get 0 + i32.const 0 + i32.eq + i32.or + i32.and + return + ) + (export "check" (func 0)) +) \ No newline at end of file diff --git a/tests/snapshots/local/upstream-threads/SB_atomic.wast/0.print b/tests/snapshots/local/upstream-threads/SB_atomic.wast/0.print new file mode 100644 index 0000000000..0c5fc57030 --- /dev/null +++ b/tests/snapshots/local/upstream-threads/SB_atomic.wast/0.print @@ -0,0 +1,4 @@ +(module $Mem + (memory (;0;) 1 1 shared) + (export "shared" (memory 0)) +) \ No newline at end of file diff --git a/tests/snapshots/local/upstream-threads/SB_atomic.wast/1001.print b/tests/snapshots/local/upstream-threads/SB_atomic.wast/1001.print new file mode 100644 index 0000000000..ee37e48867 --- /dev/null +++ b/tests/snapshots/local/upstream-threads/SB_atomic.wast/1001.print @@ -0,0 +1,17 @@ +(module + (type (;0;) (func)) + (import "mem" "shared" (memory (;0;) 1 10 shared)) + (func (;0;) (type 0) + (local i32) + i32.const 0 + i32.const 1 + i32.atomic.store + i32.const 4 + i32.atomic.load + local.set 0 + i32.const 24 + local.get 0 + i32.store + ) + (export "run" (func 0)) +) \ No newline at end of file diff --git a/tests/snapshots/local/upstream-threads/SB_atomic.wast/2001.print b/tests/snapshots/local/upstream-threads/SB_atomic.wast/2001.print new file mode 100644 index 0000000000..4d51cd1684 --- /dev/null +++ b/tests/snapshots/local/upstream-threads/SB_atomic.wast/2001.print @@ -0,0 +1,17 @@ +(module + (type (;0;) (func)) + (import "mem" "shared" (memory (;0;) 1 1 shared)) + (func (;0;) (type 0) + (local i32) + i32.const 4 + i32.const 1 + i32.atomic.store + i32.const 0 + i32.atomic.load + local.set 0 + i32.const 32 + local.get 0 + i32.store + ) + (export "run" (func 0)) +) \ No newline at end of file diff --git a/tests/snapshots/local/upstream-threads/SB_atomic.wast/5.print b/tests/snapshots/local/upstream-threads/SB_atomic.wast/5.print new file mode 100644 index 0000000000..12c951ddb9 --- /dev/null +++ b/tests/snapshots/local/upstream-threads/SB_atomic.wast/5.print @@ -0,0 +1,38 @@ +(module $Check + (type (;0;) (func (result i32))) + (import "mem" "shared" (memory (;0;) 1 1 shared)) + (func (;0;) (type 0) (result i32) + (local i32 i32) + i32.const 24 + i32.load + local.set 0 + i32.const 32 + i32.load + local.set 1 + local.get 0 + i32.const 1 + i32.eq + local.get 1 + i32.const 1 + i32.eq + i32.and + local.get 0 + i32.const 0 + i32.eq + local.get 1 + i32.const 1 + i32.eq + i32.and + local.get 0 + i32.const 1 + i32.eq + local.get 1 + i32.const 0 + i32.eq + i32.and + i32.or + i32.or + return + ) + (export "check" (func 0)) +) \ No newline at end of file diff --git a/tests/snapshots/local/upstream-threads/wait_notify.wast/0.print b/tests/snapshots/local/upstream-threads/wait_notify.wast/0.print new file mode 100644 index 0000000000..0c5fc57030 --- /dev/null +++ b/tests/snapshots/local/upstream-threads/wait_notify.wast/0.print @@ -0,0 +1,4 @@ +(module $Mem + (memory (;0;) 1 1 shared) + (export "shared" (memory 0)) +) \ No newline at end of file diff --git a/tests/snapshots/local/upstream-threads/wait_notify.wast/1001.print b/tests/snapshots/local/upstream-threads/wait_notify.wast/1001.print new file mode 100644 index 0000000000..36210b6062 --- /dev/null +++ b/tests/snapshots/local/upstream-threads/wait_notify.wast/1001.print @@ -0,0 +1,11 @@ +(module + (type (;0;) (func (result i32))) + (import "mem" "shared" (memory (;0;) 1 10 shared)) + (func (;0;) (type 0) (result i32) + i32.const 0 + i32.const 0 + i64.const -1 + memory.atomic.wait32 + ) + (export "run" (func 0)) +) \ No newline at end of file diff --git a/tests/snapshots/local/upstream-threads/wait_notify.wast/2001.print b/tests/snapshots/local/upstream-threads/wait_notify.wast/2001.print new file mode 100644 index 0000000000..4c749f4783 --- /dev/null +++ b/tests/snapshots/local/upstream-threads/wait_notify.wast/2001.print @@ -0,0 +1,22 @@ +(module + (type (;0;) (func (result i32))) + (type (;1;) (func)) + (import "mem" "shared" (memory (;0;) 1 1 shared)) + (func (;0;) (type 0) (result i32) + i32.const 0 + i32.const 0 + memory.atomic.notify + ) + (func (;1;) (type 1) + loop ;; label = @1 + i32.const 1 + i32.const 0 + i32.const 1 + memory.atomic.notify + i32.ne + br_if 0 (;@1;) + end + ) + (export "notify-0" (func 0)) + (export "notify-1-while" (func 1)) +) \ No newline at end of file