Skip to content
This repository was archived by the owner on Nov 3, 2021. It is now read-only.

Commit 1568b35

Browse files
Generalize test generators for table.copy and table.init to multi-table (#84)
1 parent 2028231 commit 1568b35

File tree

9 files changed

+2502
-579
lines changed

9 files changed

+2502
-579
lines changed

test/core/memory_copy.wast

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
;;
22
;; Generated by ../meta/generate_memory_copy.js
3+
;; DO NOT EDIT THIS FILE. CHANGE THE SOURCE AND REGENERATE.
34
;;
45

56
(module

test/core/memory_fill.wast

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
;;
22
;; Generated by ../meta/generate_memory_fill.js
3+
;; DO NOT EDIT THIS FILE. CHANGE THE SOURCE AND REGENERATE.
34
;;
45

56
(module

test/core/memory_init.wast

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
;;
22
;; Generated by ../meta/generate_memory_init.js
3+
;; DO NOT EDIT THIS FILE. CHANGE THE SOURCE AND REGENERATE.
34
;;
45

56
(module

test/core/table_copy.wast

Lines changed: 1818 additions & 331 deletions
Large diffs are not rendered by default.

test/core/table_init.wast

Lines changed: 440 additions & 72 deletions
Large diffs are not rendered by default.

test/meta/Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
SHARED_MEM=false
22

33
# SpiderMonkey shell
4-
JSSHELL=~/m-i/js/src/build-debug/dist/bin/js -e 'const WITH_SHARED_MEMORY=$(SHARED_MEM);' -f common.js
4+
JSSHELL=~/mozilla-central/js/src/build-debug/dist/bin/js -e 'const WITH_SHARED_MEMORY=$(SHARED_MEM);' -f common.js
55

66
# Node.js
77
#JSSHELL=./noderun.sh $(SHARED_MEM)

test/meta/common.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ const PAGESIZE = 65536;
33
function print_origin(origin) {
44
print(";;");
55
print(";; Generated by ../meta/" + origin);
6+
print(";; DO NOT EDIT THIS FILE. CHANGE THE SOURCE AND REGENERATE.");
67
print(";;");
78
}
89

test/meta/generate_table_copy.js

Lines changed: 146 additions & 104 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ function emit_a() {
2626
// value 0 to 9 indicating the function called, or will throw an exception if
2727
// the table entry is empty.
2828

29-
function emit_b(insn) {
29+
function emit_b(insn, t0, t1) {
3030
print(
3131
`
3232
(module
@@ -36,22 +36,27 @@ function emit_b(insn) {
3636
(import "a" "ef2" (func (result i32)))
3737
(import "a" "ef3" (func (result i32)))
3838
(import "a" "ef4" (func (result i32))) ;; index 4
39-
(table 30 30 funcref)
40-
(elem (i32.const 2) 3 1 4 1)
39+
(table $t0 30 30 funcref)
40+
(table $t1 30 30 funcref)
41+
(elem (table $t${t0}) (i32.const 2) func 3 1 4 1)
4142
(elem funcref
4243
(ref.func 2) (ref.func 7) (ref.func 1) (ref.func 8))
43-
(elem (i32.const 12) 7 5 2 3 6)
44+
(elem (table $t${t0}) (i32.const 12) func 7 5 2 3 6)
4445
(elem funcref
4546
(ref.func 5) (ref.func 9) (ref.func 2) (ref.func 7) (ref.func 6))
47+
(elem (table $t${t1}) (i32.const 3) func 1 3 1 4)
48+
(elem (table $t${t1}) (i32.const 11) func 6 3 2 5 7)
4649
(func (result i32) (i32.const 5)) ;; index 5
4750
(func (result i32) (i32.const 6))
4851
(func (result i32) (i32.const 7))
4952
(func (result i32) (i32.const 8))
5053
(func (result i32) (i32.const 9)) ;; index 9
5154
(func (export "test")
5255
${insn})
53-
(func (export "check") (param i32) (result i32)
54-
(call_indirect (type 0) (local.get 0)))
56+
(func (export "check_t0") (param i32) (result i32)
57+
(call_indirect $t${t0} (type 0) (local.get 0)))
58+
(func (export "check_t1") (param i32) (result i32)
59+
(call_indirect $t${t1} (type 0) (local.get 0)))
5560
)
5661
`);
5762
}
@@ -60,16 +65,29 @@ function emit_b(insn) {
6065
// given |instruction| to modify the table, and then probes the table by making
6166
// indirect calls, one for each element of |expected_result_vector|. The
6267
// results are compared to those in the vector.
68+
//
69+
// "dest_table" may be t0 or t1.
6370

64-
function tab_test(instruction, expected_result_vector) {
65-
emit_b(instruction);
71+
function tab_test(args, t0, t1, dest_table, expected_t0, expected_t1) {
72+
if (typeof args != "string")
73+
emit_b("(nop)", t0, t1);
74+
else
75+
emit_b(`(table.copy $t${dest_table} $t${t0} ${args})`, t0, t1);
6676
print(`(invoke "test")`);
67-
for (let i = 0; i < expected_result_vector.length; i++) {
68-
let expected = expected_result_vector[i];
77+
for (let i = 0; i < expected_t0.length; i++) {
78+
let expected = expected_t0[i];
6979
if (expected === undefined) {
70-
print(`(assert_trap (invoke "check" (i32.const ${i})) "uninitialized element")`);
80+
print(`(assert_trap (invoke "check_t0" (i32.const ${i})) "uninitialized element")`);
7181
} else {
72-
print(`(assert_return (invoke "check" (i32.const ${i})) (i32.const ${expected}))`);
82+
print(`(assert_return (invoke "check_t0" (i32.const ${i})) (i32.const ${expected}))`);
83+
}
84+
}
85+
for (let i = 0; i < expected_t1.length; i++) {
86+
let expected = expected_t1[i];
87+
if (expected === undefined) {
88+
print(`(assert_trap (invoke "check_t1" (i32.const ${i})) "uninitialized element")`);
89+
} else {
90+
print(`(assert_return (invoke "check_t1" (i32.const ${i})) (i32.const ${expected}))`);
7391
}
7492
}
7593
}
@@ -80,50 +98,72 @@ emit_a();
8098
// to count through the vector entries when debugging.
8199
let e = undefined;
82100

83-
// This just gives the initial state of the table, with its active
84-
// initialisers applied
85-
tab_test("(nop)",
86-
[e,e,3,1,4, 1,e,e,e,e, e,e,7,5,2, 3,6,e,e,e, e,e,e,e,e, e,e,e,e,e]);
87-
88-
// Copy non-null over non-null
89-
tab_test("(table.copy (i32.const 13) (i32.const 2) (i32.const 3))",
90-
[e,e,3,1,4, 1,e,e,e,e, e,e,7,3,1, 4,6,e,e,e, e,e,e,e,e, e,e,e,e,e]);
91-
92-
// Copy non-null over null
93-
tab_test("(table.copy (i32.const 25) (i32.const 15) (i32.const 2))",
94-
[e,e,3,1,4, 1,e,e,e,e, e,e,7,5,2, 3,6,e,e,e, e,e,e,e,e, 3,6,e,e,e]);
95-
96-
// Copy null over non-null
97-
tab_test("(table.copy (i32.const 13) (i32.const 25) (i32.const 3))",
98-
[e,e,3,1,4, 1,e,e,e,e, e,e,7,e,e, e,6,e,e,e, e,e,e,e,e, e,e,e,e,e]);
99-
100-
// Copy null over null
101-
tab_test("(table.copy (i32.const 20) (i32.const 22) (i32.const 4))",
102-
[e,e,3,1,4, 1,e,e,e,e, e,e,7,5,2, 3,6,e,e,e, e,e,e,e,e, e,e,e,e,e]);
103-
104-
// Copy null and non-null entries, non overlapping
105-
tab_test("(table.copy (i32.const 25) (i32.const 1) (i32.const 3))",
106-
[e,e,3,1,4, 1,e,e,e,e, e,e,7,5,2, 3,6,e,e,e, e,e,e,e,e, e,3,1,e,e]);
107-
108-
// Copy null and non-null entries, overlapping, backwards
109-
tab_test("(table.copy (i32.const 10) (i32.const 12) (i32.const 7))",
110-
[e,e,3,1,4, 1,e,e,e,e, 7,5,2,3,6, e,e,e,e,e, e,e,e,e,e, e,e,e,e,e]);
111-
112-
// Copy null and non-null entries, overlapping, forwards
113-
tab_test("(table.copy (i32.const 12) (i32.const 10) (i32.const 7))",
114-
[e,e,3,1,4, 1,e,e,e,e, e,e,e,e,7, 5,2,3,6,e, e,e,e,e,e, e,e,e,e,e]);
101+
for ( let table of [0,1] ) {
102+
let other_table = (table + 1) % 2;
103+
104+
// Tests for copying in a single table.
105+
106+
// This just gives the initial state of the table, with its active
107+
// initialisers applied
108+
tab_test(false, table, other_table, table,
109+
[e,e,3,1,4, 1,e,e,e,e, e,e,7,5,2, 3,6,e,e,e, e,e,e,e,e, e,e,e,e,e],
110+
[e,e,e,1,3, 1,4,e,e,e, e,6,3,2,5, 7,e,e,e,e, e,e,e,e,e, e,e,e,e,e]);
111+
112+
// Copy non-null over non-null
113+
tab_test("(i32.const 13) (i32.const 2) (i32.const 3)", table, other_table, table,
114+
[e,e,3,1,4, 1,e,e,e,e, e,e,7,3,1, 4,6,e,e,e, e,e,e,e,e, e,e,e,e,e],
115+
[e,e,e,1,3, 1,4,e,e,e, e,6,3,2,5, 7,e,e,e,e, e,e,e,e,e, e,e,e,e,e]);
116+
117+
// Copy non-null over null
118+
tab_test("(i32.const 25) (i32.const 15) (i32.const 2)", table, other_table, table,
119+
[e,e,3,1,4, 1,e,e,e,e, e,e,7,5,2, 3,6,e,e,e, e,e,e,e,e, 3,6,e,e,e],
120+
[e,e,e,1,3, 1,4,e,e,e, e,6,3,2,5, 7,e,e,e,e, e,e,e,e,e, e,e,e,e,e]);
121+
122+
// Copy null over non-null
123+
tab_test("(i32.const 13) (i32.const 25) (i32.const 3)", table, other_table, table,
124+
[e,e,3,1,4, 1,e,e,e,e, e,e,7,e,e, e,6,e,e,e, e,e,e,e,e, e,e,e,e,e],
125+
[e,e,e,1,3, 1,4,e,e,e, e,6,3,2,5, 7,e,e,e,e, e,e,e,e,e, e,e,e,e,e]);
126+
127+
// Copy null over null
128+
tab_test("(i32.const 20) (i32.const 22) (i32.const 4)", table, other_table, table,
129+
[e,e,3,1,4, 1,e,e,e,e, e,e,7,5,2, 3,6,e,e,e, e,e,e,e,e, e,e,e,e,e],
130+
[e,e,e,1,3, 1,4,e,e,e, e,6,3,2,5, 7,e,e,e,e, e,e,e,e,e, e,e,e,e,e]);
131+
132+
// Copy null and non-null entries, non overlapping
133+
tab_test("(i32.const 25) (i32.const 1) (i32.const 3)", table, other_table, table,
134+
[e,e,3,1,4, 1,e,e,e,e, e,e,7,5,2, 3,6,e,e,e, e,e,e,e,e, e,3,1,e,e],
135+
[e,e,e,1,3, 1,4,e,e,e, e,6,3,2,5, 7,e,e,e,e, e,e,e,e,e, e,e,e,e,e]);
136+
137+
// Copy null and non-null entries, overlapping, backwards
138+
tab_test("(i32.const 10) (i32.const 12) (i32.const 7)", table, other_table, table,
139+
[e,e,3,1,4, 1,e,e,e,e, 7,5,2,3,6, e,e,e,e,e, e,e,e,e,e, e,e,e,e,e],
140+
[e,e,e,1,3, 1,4,e,e,e, e,6,3,2,5, 7,e,e,e,e, e,e,e,e,e, e,e,e,e,e]);
141+
142+
// Copy null and non-null entries, overlapping, forwards
143+
tab_test("(i32.const 12) (i32.const 10) (i32.const 7)", table, other_table, table,
144+
[e,e,3,1,4, 1,e,e,e,e, e,e,e,e,7, 5,2,3,6,e, e,e,e,e,e, e,e,e,e,e],
145+
[e,e,e,1,3, 1,4,e,e,e, e,6,3,2,5, 7,e,e,e,e, e,e,e,e,e, e,e,e,e,e]);
146+
147+
// Tests for copying from one table to the other. Here, overlap and copy
148+
// direction don't matter.
149+
150+
tab_test("(i32.const 10) (i32.const 0) (i32.const 20)", table, other_table, other_table,
151+
[e,e,3,1,4, 1,e,e,e,e, e,e,7,5,2, 3,6,e,e,e, e,e,e,e,e, e,e,e,e,e],
152+
[e,e,e,1,3, 1,4,e,e,e, e,e,3,1,4, 1,e,e,e,e, e,e,7,5,2, 3,6,e,e,e]);
153+
}
115154

116155
// Out-of-bounds checks.
117156

118157
function do_test(insn1, insn2, errText)
119158
{
120159
print(`
121160
(module
122-
(table 30 30 funcref)
123-
(elem (i32.const 2) 3 1 4 1)
161+
(table $t0 30 30 funcref)
162+
(table $t1 30 30 funcref)
163+
(elem (table $t0) (i32.const 2) func 3 1 4 1)
124164
(elem funcref
125165
(ref.func 2) (ref.func 7) (ref.func 1) (ref.func 8))
126-
(elem (i32.const 12) 7 5 2 3 6)
166+
(elem (table $t0) (i32.const 12) func 7 5 2 3 6)
127167
(elem funcref
128168
(ref.func 5) (ref.func 9) (ref.func 2) (ref.func 7) (ref.func 6))
129169
(func (result i32) (i32.const 0))
@@ -156,63 +196,65 @@ function tab_test_nofail(insn1, insn2) {
156196
do_test(insn1, insn2, undefined, undefined);
157197
}
158198

159-
// Here we test the boundary-failure cases. The table's valid indices are 0..29
160-
// inclusive.
161-
162-
// copy: dst range invalid
163-
tab_test2("(table.copy (i32.const 28) (i32.const 1) (i32.const 3))",
164-
"",
165-
"out of bounds");
166-
167-
// copy: dst wraparound end of 32 bit offset space
168-
tab_test2("(table.copy (i32.const 0xFFFFFFFE) (i32.const 1) (i32.const 2))",
169-
"",
170-
"out of bounds");
171-
172-
// copy: src range invalid
173-
tab_test2("(table.copy (i32.const 15) (i32.const 25) (i32.const 6))",
174-
"",
175-
"out of bounds");
176-
177-
// copy: src wraparound end of 32 bit offset space
178-
tab_test2("(table.copy (i32.const 15) (i32.const 0xFFFFFFFE) (i32.const 2))",
179-
"",
180-
"out of bounds");
181-
182-
// copy: zero length with both offsets in-bounds is OK
183-
tab_test_nofail(
184-
"(table.copy (i32.const 15) (i32.const 25) (i32.const 0))",
185-
"");
186-
187-
// copy: zero length with dst offset out of bounds at the end of the table is allowed
188-
tab_test2("(table.copy (i32.const 30) (i32.const 15) (i32.const 0))",
189-
"",
190-
undefined);
191-
192-
// copy: zero length with dst offset out of bounds past the end of the table is not allowed
193-
tab_test2("(table.copy (i32.const 31) (i32.const 15) (i32.const 0))",
194-
"",
195-
"out of bounds");
196-
197-
// copy: zero length with src offset out of bounds at the end of the table is allowed
198-
tab_test2("(table.copy (i32.const 15) (i32.const 30) (i32.const 0))",
199-
"",
200-
undefined);
201-
202-
// copy: zero length with src offset out of bounds past the end of the table is not allowed
203-
tab_test2("(table.copy (i32.const 15) (i32.const 31) (i32.const 0))",
204-
"",
205-
"out of bounds");
206-
207-
// copy: zero length with both dst and src offset out of bounds at the end of the table is allowed
208-
tab_test2("(table.copy (i32.const 30) (i32.const 30) (i32.const 0))",
209-
"",
210-
undefined);
211-
212-
// copy: zero length with both dst and src offset out of bounds past the end of the table is not allowed
213-
tab_test2("(table.copy (i32.const 31) (i32.const 31) (i32.const 0))",
214-
"",
215-
"out of bounds");
199+
for ( let dest of ["$t0","$t1"] ) {
200+
// Here we test the boundary-failure cases. The table's valid indices are 0..29
201+
// inclusive.
202+
203+
// copy: dst range invalid
204+
tab_test2(`(table.copy ${dest} $t0 (i32.const 28) (i32.const 1) (i32.const 3))`,
205+
"",
206+
"out of bounds");
207+
208+
// copy: dst wraparound end of 32 bit offset space
209+
tab_test2(`(table.copy ${dest} $t0 (i32.const 0xFFFFFFFE) (i32.const 1) (i32.const 2))`,
210+
"",
211+
"out of bounds");
212+
213+
// copy: src range invalid
214+
tab_test2(`(table.copy ${dest} $t0 (i32.const 15) (i32.const 25) (i32.const 6))`,
215+
"",
216+
"out of bounds");
217+
218+
// copy: src wraparound end of 32 bit offset space
219+
tab_test2(`(table.copy ${dest} $t0 (i32.const 15) (i32.const 0xFFFFFFFE) (i32.const 2))`,
220+
"",
221+
"out of bounds");
222+
223+
// copy: zero length with both offsets in-bounds is OK
224+
tab_test_nofail(
225+
`(table.copy ${dest} $t0 (i32.const 15) (i32.const 25) (i32.const 0))`,
226+
"");
227+
228+
// copy: zero length with dst offset out of bounds at the end of the table is allowed
229+
tab_test2(`(table.copy ${dest} $t0 (i32.const 30) (i32.const 15) (i32.const 0))`,
230+
"",
231+
undefined);
232+
233+
// copy: zero length with dst offset out of bounds past the end of the table is not allowed
234+
tab_test2(`(table.copy ${dest} $t0 (i32.const 31) (i32.const 15) (i32.const 0))`,
235+
"",
236+
"out of bounds");
237+
238+
// copy: zero length with src offset out of bounds at the end of the table is allowed
239+
tab_test2(`(table.copy ${dest} $t0 (i32.const 15) (i32.const 30) (i32.const 0))`,
240+
"",
241+
undefined);
242+
243+
// copy: zero length with src offset out of bounds past the end of the table is not allowed
244+
tab_test2(`(table.copy ${dest} $t0 (i32.const 15) (i32.const 31) (i32.const 0))`,
245+
"",
246+
"out of bounds");
247+
248+
// copy: zero length with both dst and src offset out of bounds at the end of the table is allowed
249+
tab_test2(`(table.copy ${dest} $t0 (i32.const 30) (i32.const 30) (i32.const 0))`,
250+
"",
251+
undefined);
252+
253+
// copy: zero length with both dst and src offset out of bounds past the end of the table is not allowed
254+
tab_test2(`(table.copy ${dest} $t0 (i32.const 31) (i32.const 31) (i32.const 0))`,
255+
"",
256+
"out of bounds");
257+
}
216258

217259
// table.copy: out of bounds of the table for the source or target, but should
218260
// perform the operation up to the appropriate bound. Major cases:

0 commit comments

Comments
 (0)