Skip to content

Commit f289d86

Browse files
committed
Restore tests from the main-legacy branch
Fixes #238.
1 parent ff17701 commit f289d86

File tree

6 files changed

+746
-0
lines changed

6 files changed

+746
-0
lines changed

test/core/atomic.wast

Lines changed: 548 additions & 0 deletions
Large diffs are not rendered by default.

test/core/atomic_wait_notify.wast

Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
;; wait/notify
2+
(module
3+
(memory 1 1 shared)
4+
5+
(func (export "init") (param $value i64) (i64.store (i32.const 0) (local.get $value)))
6+
7+
(func (export "memory.atomic.notify") (param $addr i32) (param $count i32) (result i32)
8+
(memory.atomic.notify (local.get 0) (local.get 1)))
9+
(func (export "memory.atomic.wait32") (param $addr i32) (param $expected i32) (param $timeout i64) (result i32)
10+
(memory.atomic.wait32 (local.get 0) (local.get 1) (local.get 2)))
11+
(func (export "memory.atomic.wait64") (param $addr i32) (param $expected i64) (param $timeout i64) (result i32)
12+
(memory.atomic.wait64 (local.get 0) (local.get 1) (local.get 2)))
13+
)
14+
15+
(invoke "init" (i64.const 0xffffffffffff))
16+
17+
;; wait returns immediately if values do not match
18+
(assert_return (invoke "memory.atomic.wait32" (i32.const 0) (i32.const 0) (i64.const 0)) (i32.const 1))
19+
(assert_return (invoke "memory.atomic.wait64" (i32.const 0) (i64.const 0) (i64.const 0)) (i32.const 1))
20+
21+
;; wait times out if values do match and timeout is small
22+
(assert_return (invoke "memory.atomic.wait32" (i32.const 0) (i32.const 0xffffffff) (i64.const 10)) (i32.const 2))
23+
(assert_return (invoke "memory.atomic.wait64" (i32.const 0) (i64.const 0xffffffffffff) (i64.const 10)) (i32.const 2))
24+
25+
;; notify always returns
26+
(assert_return (invoke "memory.atomic.notify" (i32.const 0) (i32.const 0)) (i32.const 0))
27+
(assert_return (invoke "memory.atomic.notify" (i32.const 0) (i32.const 10)) (i32.const 0))
28+
29+
;; OOB wait and notify always trap
30+
(assert_trap (invoke "memory.atomic.wait32" (i32.const 65536) (i32.const 0) (i64.const 0)) "out of bounds memory access")
31+
(assert_trap (invoke "memory.atomic.wait64" (i32.const 65536) (i64.const 0) (i64.const 0)) "out of bounds memory access")
32+
33+
;; in particular, notify always traps even if waking 0 threads
34+
(assert_trap (invoke "memory.atomic.notify" (i32.const 65536) (i32.const 0)) "out of bounds memory access")
35+
36+
;; similarly, unaligned wait and notify always trap
37+
(assert_trap (invoke "memory.atomic.wait32" (i32.const 65531) (i32.const 0) (i64.const 0)) "unaligned atomic")
38+
(assert_trap (invoke "memory.atomic.wait64" (i32.const 65524) (i64.const 0) (i64.const 0)) "unaligned atomic")
39+
40+
(assert_trap (invoke "memory.atomic.notify" (i32.const 65531) (i32.const 0)) "unaligned atomic")
41+
42+
;; atomic.wait traps on unshared memory even if it wouldn't block
43+
(module
44+
(memory 1 1)
45+
46+
(func (export "init") (param $value i64) (i64.store (i32.const 0) (local.get $value)))
47+
48+
(func (export "memory.atomic.notify") (param $addr i32) (param $count i32) (result i32)
49+
(memory.atomic.notify (local.get 0) (local.get 1)))
50+
(func (export "memory.atomic.wait32") (param $addr i32) (param $expected i32) (param $timeout i64) (result i32)
51+
(memory.atomic.wait32 (local.get 0) (local.get 1) (local.get 2)))
52+
(func (export "memory.atomic.wait64") (param $addr i32) (param $expected i64) (param $timeout i64) (result i32)
53+
(memory.atomic.wait64 (local.get 0) (local.get 1) (local.get 2)))
54+
)
55+
56+
(invoke "init" (i64.const 0xffffffffffff))
57+
58+
(assert_trap (invoke "memory.atomic.wait32" (i32.const 0) (i32.const 0) (i64.const 0)) "expected shared memory")
59+
(assert_trap (invoke "memory.atomic.wait64" (i32.const 0) (i64.const 0) (i64.const 0)) "expected shared memory")
60+
61+
;; notify still works
62+
(assert_return (invoke "memory.atomic.notify" (i32.const 0) (i32.const 0)) (i32.const 0))
63+
64+
;; OOB and unaligned notify still trap
65+
(assert_trap (invoke "memory.atomic.notify" (i32.const 65536) (i32.const 0)) "out of bounds memory access")
66+
(assert_trap (invoke "memory.atomic.notify" (i32.const 65531) (i32.const 0)) "unaligned atomic")
67+
68+
;; test that looping notify eventually unblocks a parallel waiting thread
69+
(module $Mem
70+
(memory (export "shared") 1 1 shared)
71+
)
72+
73+
(thread $T1 (shared (module $Mem))
74+
(register "mem" $Mem)
75+
(module
76+
(memory (import "mem" "shared") 1 10 shared)
77+
(func (export "run") (result i32)
78+
(memory.atomic.wait32 (i32.const 0) (i32.const 0) (i64.const -1))
79+
)
80+
)
81+
;; test that this thread eventually gets unblocked
82+
(assert_return (invoke "run") (i32.const 0))
83+
)
84+
85+
(thread $T2 (shared (module $Mem))
86+
(register "mem" $Mem)
87+
(module
88+
(memory (import "mem" "shared") 1 1 shared)
89+
(func (export "notify-0") (result i32)
90+
(memory.atomic.notify (i32.const 0) (i32.const 0))
91+
)
92+
(func (export "notify-1-while")
93+
(loop
94+
(i32.const 1)
95+
(memory.atomic.notify (i32.const 0) (i32.const 1))
96+
(i32.ne)
97+
(br_if 0)
98+
)
99+
)
100+
)
101+
;; notifying with a count of 0 will not unblock
102+
(assert_return (invoke "notify-0") (i32.const 0))
103+
;; loop until something is notified
104+
(assert_return (invoke "notify-1-while"))
105+
)
106+
107+
(wait $T1)
108+
(wait $T2)

test/core/exports.wast

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -201,6 +201,13 @@
201201
(module (export "a" (memory $a)) (memory $a 0))
202202
(module (export "a" (memory $a)) (memory $a 0 1))
203203

204+
(module (memory (export "a") 0 1 shared))
205+
(module (memory 0 1 shared) (export "a" (memory 0)))
206+
(module (memory $a (export "a") 0 1 shared))
207+
(module (memory $a 0 1 shared) (export "a" (memory $a)))
208+
(module (export "a" (memory 0)) (memory 0 1 shared))
209+
(module (export "a" (memory $a)) (memory $a 0 1 shared))
210+
204211
(; TODO: access memory ;)
205212

206213
(assert_invalid

test/core/memory.wast

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,10 @@
66
(module (memory 0 1))
77
(module (memory 1 256))
88
(module (memory 0 65536))
9+
(module (memory 0 0 shared))
10+
(module (memory 1 2 shared))
11+
12+
(assert_invalid (module (memory 1 shared)) "shared memory must have maximum")
913

1014
(assert_invalid (module (memory 0) (memory 0)) "multiple memories")
1115
(assert_invalid (module (memory (import "spectest" "memory") 0) (memory 0)) "multiple memories")

test/core/thread.wast

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
(module $Mem
2+
(memory (export "shared") 1 1 shared)
3+
)
4+
5+
(thread $T1 (shared (module $Mem))
6+
(register "mem" $Mem)
7+
(module
8+
(memory (import "mem" "shared") 1 10 shared)
9+
(func (export "run")
10+
(i32.store (i32.const 0) (i32.const 42))
11+
)
12+
)
13+
(invoke "run")
14+
)
15+
16+
(thread $T2 (shared (module $Mem))
17+
(register "mem" $Mem)
18+
(module
19+
(memory (import "mem" "shared") 1 1 shared)
20+
(func (export "run") (result i32)
21+
(i32.load (i32.const 0))
22+
)
23+
)
24+
(assert_return (invoke "run") (either (i32.const 0) (i32.const 42)))
25+
)
26+
27+
(wait $T1)
28+
(wait $T2)

test/js-api/memory/constructor.any.js

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,10 @@ test(() => {
6666
assert_throws_js(RangeError, () => new WebAssembly.Memory({ "initial": 10, "maximum": 9 }));
6767
}, "Initial value exceeds maximum");
6868

69+
test(() => {
70+
assert_throws(new TypeError(), () => new WebAssembly.Memory({ "initial": 10, "shared": true }));
71+
}, "Shared memory without maximum");
72+
6973
test(() => {
7074
const proxy = new Proxy({}, {
7175
has(o, x) {
@@ -120,6 +124,47 @@ test(() => {
120124
]);
121125
}, "Order of evaluation for descriptor");
122126

127+
test(t => {
128+
const order = [];
129+
130+
new WebAssembly.Memory({
131+
get maximum() {
132+
order.push("maximum");
133+
return {
134+
valueOf() {
135+
order.push("maximum valueOf");
136+
return 1;
137+
},
138+
};
139+
},
140+
141+
get initial() {
142+
order.push("initial");
143+
return {
144+
valueOf() {
145+
order.push("initial valueOf");
146+
return 1;
147+
},
148+
};
149+
},
150+
151+
get shared() {
152+
order.push("shared");
153+
return {
154+
valueOf: t.unreached_func("should not call shared valueOf"),
155+
};
156+
},
157+
});
158+
159+
assert_array_equals(order, [
160+
"initial",
161+
"initial valueOf",
162+
"maximum",
163+
"maximum valueOf",
164+
"shared",
165+
]);
166+
}, "Order of evaluation for descriptor (with shared)");
167+
123168
test(() => {
124169
const argument = { "initial": 0 };
125170
const memory = new WebAssembly.Memory(argument);
@@ -137,3 +182,9 @@ test(() => {
137182
const memory = new WebAssembly.Memory(argument, {});
138183
assert_Memory(memory, { "size": 0 });
139184
}, "Stray argument");
185+
186+
test(() => {
187+
const argument = { "initial": 4, "maximum": 10, shared: true };
188+
const memory = new WebAssembly.Memory(argument);
189+
assert_Memory(memory, { "size": 4, "shared": true });
190+
}, "Shared memory");

0 commit comments

Comments
 (0)