fcbe2827f371663aa84fdf5c10100b8178177390
[WebKit-https.git] / JSTests / wasm / js-api / element.js
1 import Builder from '../Builder.js';
2 import * as assert from '../assert.js';
3
4 {
5     // Bad element section b/c no Table section/import.
6     const builder = new Builder()
7         .Type().End()
8         .Function().End()
9         .Element()
10             .Element({tableIndex: 0, offset: 0, functionIndices: [0]})
11         .End()
12         .Code()
13             .Function("foo", {params: ["i32"], ret: "i32"})
14                 .GetLocal(0)
15                 .I32Const(42)
16                 .I32Add()
17                 .Return()
18             .End()
19         .End();
20
21     assert.throws(() => new WebAssembly.Module(builder.WebAssembly().get()), WebAssembly.CompileError, "WebAssembly.Module doesn't parse at byte 24: Element section for Table 0 exceeds available Table 0");
22 }
23
24 {
25     // Bad table index.
26     const builder = new Builder()
27         .Type().End()
28         .Function().End()
29         .Table()
30             .Table({element: "anyfunc", initial: 20})
31         .End()
32         .Element()
33             .Element({tableIndex: 1, offset: 0, functionIndices: [0]})
34         .End()
35         .Code()
36             .Function("foo", {params: ["i32"], ret: "i32"})
37                 .GetLocal(0)
38                 .I32Const(42)
39                 .I32Add()
40                 .Return()
41             .End()
42         .End();
43
44     assert.throws(() => new WebAssembly.Module(builder.WebAssembly().get()), WebAssembly.CompileError, "WebAssembly.Module doesn't parse at byte 30: Element section for Table 1 exceeds available Table 1");
45 }
46
47 {
48     // Overflow table maximum size.
49     const builder = new Builder()
50         .Type().End()
51         .Function().End()
52         .Table()
53             .Table({element: "anyfunc", initial: 20, maximum: 20})
54         .End()
55         .Element()
56             .Element({offset: 19, functionIndices: [0, 0]})
57         .End()
58         .Code()
59             .Function("foo", {params: ["i32"], ret: "i32"})
60                 .GetLocal(0)
61                 .I32Const(42)
62                 .I32Add()
63                 .Return()
64             .End()
65         .End();
66
67     const module = new WebAssembly.Module(builder.WebAssembly().get());
68     assert.throws(() => new WebAssembly.Instance(module), WebAssembly.LinkError, "Element is trying to set an out of bounds table index");
69 }
70
71 {
72     // Overflow table maximum size.
73     const builder = new Builder()
74         .Type().End()
75         .Function().End()
76         .Table()
77             .Table({element: "anyfunc", initial: 20, maximum: 20})
78         .End()
79         .Element()
80             .Element({offset: 20, functionIndices: [0]})
81         .End()
82         .Code()
83             .Function("foo", {params: ["i32"], ret: "i32"})
84                 .GetLocal(0)
85                 .I32Const(42)
86                 .I32Add()
87                 .Return()
88             .End()
89         .End();
90
91     const module = new WebAssembly.Module(builder.WebAssembly().get());
92     assert.throws(() => new WebAssembly.Instance(module), WebAssembly.LinkError, "Element is trying to set an out of bounds table index");
93 }
94
95 {
96     // Overflow function index space.
97     const builder = new Builder()
98         .Type().End()
99         .Function().End()
100         .Table()
101             .Table({element: "anyfunc", initial: 20, maximum: 20})
102         .End()
103         .Element()
104             .Element({offset: 0, functionIndices: [0, 0, 1]})
105         .End()
106         .Code()
107             .Function("foo", {params: ["i32"], ret: "i32"})
108                 .GetLocal(0)
109                 .I32Const(42)
110                 .I32Add()
111                 .Return()
112             .End()
113         .End();
114
115     assert.throws(() => new WebAssembly.Module(builder.WebAssembly().get()), WebAssembly.CompileError, "WebAssembly.Module doesn't parse at byte 38: Element section's 0th element's 2th index is 1 which exceeds the function index space size of 1 (evaluating 'new WebAssembly.Module(builder.WebAssembly().get())')");
116 }
117
118 {
119     function badInstantiation(actualTable, errorType, msg) {
120         // Overflow function index space.
121         const builder = new Builder()
122             .Type().End()
123             .Import()
124                 .Table("imp", "table", {element: "anyfunc", initial: 19}) // unspecified maximum.
125             .End()
126             .Function().End()
127             .Element()
128                 .Element({offset: 19, functionIndices: [0, 0, 0, 0, 0]})
129             .End()
130             .Code()
131                 .Function("foo", {params: ["i32"], ret: "i32"})
132                     .GetLocal(0)
133                     .I32Const(42)
134                     .I32Add()
135                     .Return()
136                 .End()
137             .End();
138
139         const bin = builder.WebAssembly().get();
140         const module = new WebAssembly.Module(bin);
141         assert.throws(() => new WebAssembly.Instance(module, {imp: {table: actualTable}}), errorType, msg);
142     }
143
144     for (let i = 19; i < 19 + 5; i++) {
145         const table = new WebAssembly.Table({element: "anyfunc", initial: i});
146         badInstantiation(table, WebAssembly.LinkError, "Element is trying to set an out of bounds table index (evaluating 'new WebAssembly.Instance(module, {imp: {table: actualTable}})')");
147     }
148 }
149
150 {
151     function makeModule() {
152         const builder = new Builder()
153             .Type().End()
154             .Import()
155                 .Table("imp", "table", {element: "anyfunc", initial: 19}) // unspecified maximum.
156                 .Global().I32("imp", "global", "immutable").End()
157             .End()
158             .Function().End()
159             .Element()
160                 .Element({offset: {op: "get_global", initValue: 0}, functionIndices: [0]})
161             .End()
162             .Code()
163                 .Function("foo", {params: ["i32"], ret: "i32"})
164                     .GetLocal(0)
165                     .I32Const(42)
166                     .I32Add()
167                     .Return()
168                 .End()
169             .End();
170
171         const bin = builder.WebAssembly().get();
172         return new WebAssembly.Module(bin);
173     }
174
175     function test(i) {
176         const table = new WebAssembly.Table({element: "anyfunc", initial: 19});
177         const global = i;
178         const module = makeModule();
179         const instance = new WebAssembly.Instance(module, {imp: {table, global}});
180         for (let j = 0; j < 19; j++) {
181             if (j === i)
182                 assert.eq(table.get(j)(i*2), i*2 + 42);
183             else
184                 assert.throws(() => table.get(j)(i*2), TypeError, "table.get(j) is not a function. (In 'table.get(j)(i*2)', 'table.get(j)' is null)");
185         }
186     }
187     for (let i = 0; i < 19; i++)
188         test(i);
189
190     assert.throws(() => test(19), Error, "Element is trying to set an out of bounds table index");
191 }
192
193 {
194     function badModule() {
195         const builder = new Builder()
196             .Type().End()
197             .Import()
198                 .Table("imp", "table", {element: "anyfunc", initial: 19}) // unspecified maximum.
199                 .Global().F32("imp", "global", "immutable").End()
200             .End()
201             .Function().End()
202             .Element()
203                 .Element({offset: {op: "get_global", initValue: 0}, functionIndices: [0]})
204             .End()
205             .Code()
206                 .Function("foo", {params: ["i32"], ret: "i32"})
207                     .GetLocal(0)
208                     .I32Const(42)
209                     .I32Add()
210                     .Return()
211                 .End()
212             .End();
213
214         const bin = builder.WebAssembly().get();
215         return new WebAssembly.Module(bin);
216     }
217
218     assert.throws(() => badModule(), WebAssembly.CompileError, "WebAssembly.Module doesn't parse at byte 58: Element init_expr must produce an i32");
219 }