1 import * as assert from '../assert.js';
2 import Builder from '../Builder.js';
4 const assertOpThrows = (opFn, message) => {
5 let f = (new Builder()).Type().End().Code().Function();
6 assert.throws(opFn, Error, message, f);
9 (function EmptyModule() {
10 const b = new Builder();
11 const j = JSON.parse(b.json());
12 assert.isNotUndef(j.preamble);
13 assert.isNotUndef(j.preamble["magic number"]);
14 assert.isNotUndef(j.preamble.version);
15 assert.isNotUndef(j.section);
16 assert.eq(j.section.length, 0);
19 (function CustomMagicNumber() {
20 const b = (new Builder()).setPreamble({ "magic number": 1337 });
21 const j = JSON.parse(b.json());
22 assert.eq(j.preamble["magic number"], 1337);
23 assert.isNotUndef(j.preamble.version);
26 (function CustomVersion() {
27 const b = (new Builder()).setPreamble({ "version": 1337 });
28 const j = JSON.parse(b.json());
29 assert.eq(j.preamble["version"], 1337);
30 assert.isNotUndef(j.preamble.version);
33 (function CustomSection() {
34 const b = new Builder();
35 b.Unknown("custom section")
39 const j = JSON.parse(b.json());
40 assert.eq(j.section.length, 1);
41 assert.eq(j.section[0].name, "custom section");
42 assert.eq(j.section[0].data.length, 3);
43 assert.eq(j.section[0].data[0], 0x00);
44 assert.eq(j.section[0].data[1], 0x42);
45 assert.eq(j.section[0].data[2], 0xFF);
48 (function CustomSectionAllBytes() {
49 const b = new Builder();
50 let u = b.Unknown("custom section");
51 for (let i = 0; i !== 0xFF + 1; ++i)
53 const j = JSON.parse(b.json());
54 assert.eq(j.section[0].data.length, 256);
55 for (let i = 0; i !== 0xFF + 1; ++i)
56 assert.eq(j.section[0].data[i], i);
59 (function CustomSectionInvalidByte() {
60 const u = (new Builder()).Unknown("custom section");
61 assert.throws(() => u.Byte(0xFF + 1), Error, `Not the same: "0" and "256": Unknown section expected byte, got: "256"`);
64 (function TwoCustomSections() {
65 const b = new Builder();
66 b.Unknown("custom section")
73 const j = JSON.parse(b.json());
74 assert.eq(j.section.length, 2);
75 assert.eq(j.section[0].name, "custom section");
76 assert.eq(j.section[0].data.length, 3);
77 assert.eq(j.section[1].name, "☃");
78 assert.eq(j.section[1].data.length, 1);
79 assert.eq(j.section[1].data[0], 0x11);
82 (function SectionsWithSameCustomName() {
83 const b = (new Builder()).Unknown("foo").End();
84 assert.throws(() => b.Unknown("foo"), Error, `Expected falsy: Cannot have two sections with the same name "foo" and ID 0`);
87 (function EmptyTypeSection() {
88 const b = (new Builder()).Type().End();
89 const j = JSON.parse(b.json());
90 assert.eq(j.section.length, 1);
91 assert.eq(j.section[0].name, "Type");
92 assert.eq(j.section[0].data.length, 0);
95 (function TwoTypeSections() {
96 const b = (new Builder()).Type().End();
97 assert.throws(() => b.Type(), Error, `Expected falsy: Cannot have two sections with the same name "Type" and ID 1`);
100 (function SimpleTypeSection() {
101 const b = (new Builder()).Type()
108 .Func(["i32", "i64", "f32", "f64"])
110 const j = JSON.parse(b.json());
111 assert.eq(j.section[0].data.length, 7);
112 assert.eq(j.section[0].data[0].params, []);
113 assert.eq(j.section[0].data[0].ret, "void");
114 assert.eq(j.section[0].data[1].params, []);
115 assert.eq(j.section[0].data[1].ret, "void");
116 assert.eq(j.section[0].data[2].params, []);
117 assert.eq(j.section[0].data[2].ret, "i32");
118 assert.eq(j.section[0].data[3].params, []);
119 assert.eq(j.section[0].data[3].ret, "i64");
120 assert.eq(j.section[0].data[4].params, []);
121 assert.eq(j.section[0].data[4].ret, "f32");
122 assert.eq(j.section[0].data[5].params, []);
123 assert.eq(j.section[0].data[5].ret, "f64");
124 assert.eq(j.section[0].data[6].params, ["i32", "i64", "f32", "f64"]);
125 assert.eq(j.section[0].data[6].ret, "void");
128 (function EmptyImportSection() {
129 const b = (new Builder()).Import().End();
130 const j = JSON.parse(b.json());
131 assert.eq(j.section.length, 1);
132 assert.eq(j.section[0].name, "Import");
133 assert.eq(j.section[0].data.length, 0);
136 (function ImportBeforeTypeSections() {
137 const b = (new Builder()).Import().End();
138 assert.throws(() => b.Type(), Error, `Expected: "2" > "1": Bad section ordering: "Import" cannot precede "Type"`);
141 (function ImportFunctionWithoutTypeSection() {
142 const i = (new Builder()).Import();
143 assert.throws(() => i.Function("foo", "bar", 0), Error, `Shouldn't be undefined: Can not use type 0 if a type section is not present`);
146 (function ImportFunctionWithInvalidType() {
147 const i = (new Builder()).Type().End().Import();
148 assert.throws(() => i.Function("foo", "bar", 0), Error, `Shouldn't be undefined: Type 0 does not exist in type section`);
151 (function ImportFunction() {
152 const b = (new Builder())
153 .Type().Func([]).End()
155 .Function("foo", "bar", 0)
157 const j = JSON.parse(b.json());
158 assert.eq(j.section[1].data.length, 1);
159 assert.eq(j.section[1].data[0].module, "foo");
160 assert.eq(j.section[1].data[0].field, "bar");
161 assert.eq(j.section[1].data[0].type, 0);
162 assert.eq(j.section[1].data[0].kind, "Function");
165 (function ImportFunctionsWithExistingTypes() {
166 const b = (new Builder())
170 .Func(["i64", "i32"])
171 .Func(["i64", "i64"])
174 .Function("foo", "bar", { params: [] })
175 .Function("foo", "baz", { params: [], ret: "i32" })
176 .Function("foo", "boo", { params: ["i64", "i64"] })
178 const j = JSON.parse(b.json());
179 assert.eq(j.section[0].data.length, 4);
180 assert.eq(j.section[1].data.length, 3);
181 assert.eq(j.section[1].data[0].type, 0);
182 assert.eq(j.section[1].data[1].type, 1);
183 assert.eq(j.section[1].data[2].type, 3);
186 (function ImportFunctionWithNewType() {
187 const b = (new Builder())
190 .Function("foo", "bar", { params: [] })
191 .Function("foo", "baz", { params: [], ret: "i32" })
192 .Function("foo", "boo", { params: ["i64", "i64"] })
194 const j = JSON.parse(b.json());
195 assert.eq(j.section[0].data.length, 3);
196 assert.eq(j.section[0].data[0].ret, "void");
197 assert.eq(j.section[0].data[0].params, []);
198 assert.eq(j.section[0].data[1].ret, "i32");
199 assert.eq(j.section[0].data[1].params, []);
200 assert.eq(j.section[0].data[2].ret, "void");
201 assert.eq(j.section[0].data[2].params, ["i64", "i64"]);
204 (function EmptyExportSection() {
205 const b = (new Builder()).Export().End();
206 const j = JSON.parse(b.json());
207 assert.eq(j.section.length, 1);
208 assert.eq(j.section[0].name, "Export");
209 assert.eq(j.section[0].data.length, 0);
212 (function ExportFunctionWithoutTypeSection() {
213 const e = (new Builder()).Export();
214 assert.throws(() => e.Function("foo", 0, 0), Error, `Shouldn't be undefined: Can not use type 0 if a type section is not present`);
217 (function ExportFunctionWithInvalidType() {
218 const e = (new Builder()).Type().End().Export();
219 assert.throws(() => e.Function("foo", 0, 0), Error, `Shouldn't be undefined: Type 0 does not exist in type section`);
222 (function ExportAnImport() {
223 const b = (new Builder())
225 .Import().Function("foo", "bar", { params: [] }).End()
226 .Export().Function("ExportAnImport", { module: "foo", field: "bar" }).End();
227 const j = JSON.parse(b.json());
228 assert.eq(j.section[2].name, "Export");
229 assert.eq(j.section[2].data.length, 1);
230 assert.eq(j.section[2].data[0].field, "ExportAnImport");
231 assert.eq(j.section[2].data[0].type, 0);
232 assert.eq(j.section[2].data[0].index, 0);
233 assert.eq(j.section[2].data[0].kind, "Function");
236 (function ExportMismatchedImport() {
237 const e = (new Builder())
239 .Import().Function("foo", "bar", { params: [] }).End()
241 assert.throws(() => e.Function("foo", 0, { params: ["i32"] }), Error, `Not the same: "1" and "0": Re-exporting import "bar" as "foo" has mismatching type`);
244 (function StartInvalidNumberedFunction() {
245 const b = (new Builder())
249 assert.throws(() => b.Code().End(), Error, `Start section refers to non-existant function '0'`);
252 (function StartInvalidNamedFunction() {
253 const b = (new Builder())
257 assert.throws(() => b.Code().End(), Error, `Start section refers to non-existant function 'foo'`);
260 (function StartNamedFunction() {
261 const b = (new Builder())
266 .Function("foo", { params: [] }).End()
268 const j = JSON.parse(b.json());
269 assert.eq(j.section.length, 4);
270 assert.eq(j.section[2].name, "Start");
271 assert.eq(j.section[2].data.length, 1);
272 assert.eq(j.section[2].data[0], 0);
275 /* FIXME implement checking of signature https://bugs.webkit.org/show_bug.cgi?id=165658
276 (function StartInvalidTypeArg() {
277 const b = (new Builder())
281 assert.throws(() => b.Code().Function("foo", { params: ["i32"] }).End(), Error, `???`);
284 (function StartInvalidTypeReturn() {
285 const b = (new Builder())
289 assert.throws(() => b.Code().Function("foo", { params: [], ret: "i32" }).I32Const(42).Ret().End(), Error, `???`);
293 // FIXME test start of import or table. https://bugs.webkit.org/show_bug.cgi?id=165658
295 (function EmptyCodeSection() {
296 const b = new Builder();
298 const j = JSON.parse(b.json());
299 assert.eq(j.section.length, 1);
300 assert.eq(j.section[0].name, "Code");
301 assert.eq(j.section[0].data.length, 0);
304 (function CodeSectionWithEmptyFunction() {
305 const b = new Builder();
309 const j = JSON.parse(b.json());
310 assert.eq(j.section.length, 2);
311 assert.eq(j.section[0].name, "Type");
312 assert.eq(j.section[0].data.length, 1);
313 assert.eq(j.section[0].data[0].params, []);
314 assert.eq(j.section[0].data[0].ret, "void");
315 assert.eq(j.section[1].name, "Code");
316 assert.eq(j.section[1].data.length, 1);
317 assert.eq(j.section[1].data[0].name, undefined);
318 assert.eq(j.section[1].data[0].type, 0);
319 assert.eq(j.section[1].data[0].parameterCount, 0);
320 assert.eq(j.section[1].data[0].locals.length, 0);
321 assert.eq(j.section[1].data[0].code.length, 0);
324 (function CodeSectionWithEmptyFunctionWithParameters() {
325 const b = new Builder();
328 .Function({ params: ["i32", "i64", "f32", "f64"] });
329 const j = JSON.parse(b.json());
330 assert.eq(j.section.length, 2);
331 assert.eq(j.section[0].data.length, 1);
332 assert.eq(j.section[0].data[0].params, ["i32", "i64", "f32", "f64"]);
333 assert.eq(j.section[0].data[0].ret, "void");
334 assert.eq(j.section[1].data.length, 1);
335 assert.eq(j.section[1].data[0].type, 0);
336 assert.eq(j.section[1].data[0].parameterCount, 4);
337 assert.eq(j.section[1].data[0].locals[0], "i32");
338 assert.eq(j.section[1].data[0].locals[1], "i64");
339 assert.eq(j.section[1].data[0].locals[2], "f32");
340 assert.eq(j.section[1].data[0].locals[3], "f64");
341 assert.eq(j.section[1].data[0].code.length, 0);
344 (function InvalidFunctionParameters() {
345 for (let invalid of ["", "void", "bool", "any", "struct", 0, 3.14, undefined, [], {}]) {
346 const c = (new Builder()).Code();
347 assert.throws(() => c.Function({ params: [invalid] }), Error, `Expected truthy: Type parameter ${invalid} needs a valid value type`);
351 (function SimpleFunction() {
352 const b = new Builder();
359 const j = JSON.parse(b.json());
360 assert.eq(j.section[1].data.length, 1);
361 assert.eq(j.section[1].data[0].locals.length, 0);
362 assert.eq(j.section[1].data[0].code.length, 3);
363 assert.eq(j.section[1].data[0].code[0].name, "nop");
364 assert.eq(j.section[1].data[0].code[1].name, "nop");
365 assert.eq(j.section[1].data[0].code[2].name, "end");
368 (function TwoSimpleFunctions() {
369 const b = new Builder();
379 const j = JSON.parse(b.json());
380 assert.eq(j.section[1].data.length, 2);
381 assert.eq(j.section[1].data[0].locals.length, 0);
382 assert.eq(j.section[1].data[0].code.length, 3);
383 assert.eq(j.section[1].data[0].code[0].name, "nop");
384 assert.eq(j.section[1].data[0].code[1].name, "nop");
385 assert.eq(j.section[1].data[0].code[2].name, "end");
386 assert.eq(j.section[1].data[1].locals.length, 0);
387 assert.eq(j.section[1].data[1].code.length, 2);
388 assert.eq(j.section[1].data[1].code[0].name, "return");
389 assert.eq(j.section[1].data[1].code[1].name, "end");
392 (function NamedFunctions() {
393 const b = new Builder().Type().End().Code()
394 .Function("hello").End()
395 .Function("world", { params: ["i32"] }).End()
397 const j = JSON.parse(b.json());
398 assert.eq(j.section[1].data[0].name, "hello");
399 assert.eq(j.section[1].data[0].parameterCount, 0);
400 assert.eq(j.section[1].data[1].name, "world");
401 assert.eq(j.section[1].data[1].parameterCount, 1);
404 (function ExportSimpleFunctions() {
405 const b = (new Builder())
408 .Function("foo", 0, { params: [] })
410 .Function("betterNameForBar", "bar")
413 .Function({ params: [] }).Nop().End()
414 .Function("bar", { params: [] }).Nop().End()
416 const j = JSON.parse(b.json());
417 assert.eq(j.section[0].data.length, 1);
418 assert.eq(j.section[0].data[0].ret, "void");
419 assert.eq(j.section[0].data[0].params, []);
420 assert.eq(j.section[1].data.length, 3);
421 assert.eq(j.section[1].data[0].field, "foo");
422 assert.eq(j.section[1].data[0].type, 0);
423 assert.eq(j.section[1].data[0].index, 0);
424 assert.eq(j.section[1].data[0].kind, "Function");
425 assert.eq(j.section[1].data[1].field, "bar");
426 assert.eq(j.section[1].data[1].type, 0);
427 assert.eq(j.section[1].data[1].index, 1);
428 assert.eq(j.section[1].data[1].kind, "Function");
429 assert.eq(j.section[1].data[2].field, "betterNameForBar");
430 assert.eq(j.section[1].data[2].type, 0);
431 assert.eq(j.section[1].data[2].index, 1);
432 assert.eq(j.section[1].data[2].kind, "Function");
435 (function ExportUndefinedFunction() {
436 const c = (new Builder()).Type().End().Export().Function("foo").End().Code();
437 assert.throws(() => c.End(), Error, `Should be number, got undefined: Export section contains undefined function "foo"`);
440 (function TwoBuildersAtTheSameTime() {
441 const b = [new Builder(), new Builder()];
442 const f = b.map(builder => builder.Type().End().Code().Function());
444 f[1].Return().End().End();
445 f[0].Nop().End().End();
446 const j = b.map(builder => JSON.parse(builder.json()));
447 assert.eq(j[0].section[1].data[0].code.length, 3);
448 assert.eq(j[0].section[1].data[0].code[0].name, "nop");
449 assert.eq(j[0].section[1].data[0].code[1].name, "nop");
450 assert.eq(j[0].section[1].data[0].code[2].name, "end");
451 assert.eq(j[1].section[1].data[0].code.length, 2);
452 assert.eq(j[1].section[1].data[0].code[0].name, "return");
453 assert.eq(j[1].section[1].data[0].code[1].name, "end");
456 (function CheckedOpcodeArgumentsTooMany() {
457 assertOpThrows(f => f.Nop("uh-oh!"), `Not the same: "1" and "0": "nop" expects exactly 0 immediates, got 1`);
460 (function UncheckedOpcodeArgumentsTooMany() {
461 (new Builder()).setChecked(false).Type().End().Code().Function().Nop("This is fine.", "I'm OK with the events that are unfolding currently.");
464 (function CheckedOpcodeArgumentsNotEnough() {
465 assertOpThrows(f => f.I32Const(), `Not the same: "0" and "1": "i32.const" expects exactly 1 immediate, got 0`);
468 (function UncheckedOpcodeArgumentsNotEnough() {
469 (new Builder()).setChecked(false).Type().End().Code().Function().I32Const();
472 (function CallNoArguments() {
473 const b = (new Builder()).Type().End().Code().Function().Call(0).End().End();
474 const j = JSON.parse(b.json());
475 assert.eq(j.section[1].data[0].code.length, 2);
476 assert.eq(j.section[1].data[0].code[0].name, "call");
477 assert.eq(j.section[1].data[0].code[0].arguments.length, 0);
478 assert.eq(j.section[1].data[0].code[0].immediates.length, 1);
479 assert.eq(j.section[1].data[0].code[0].immediates[0], 0);
480 assert.eq(j.section[1].data[0].code[1].name, "end");
483 (function CallInvalid() {
484 for (let c of [-1, 0x100000000, "0", {}, Infinity, -Infinity, NaN, -NaN, null])
485 assertOpThrows(f => f.Call(c), `Expected truthy: Invalid value on call: got "${c}", expected i32`);
488 (function I32ConstValid() {
489 for (let c of [0, 1, 2, 42, 1337, 0xFF, 0xFFFF, 0x7FFFFFFF, 0xFFFFFFFE, 0xFFFFFFFF]) {
490 const b = (new Builder()).Type().End().Code().Function().I32Const(c).Return().End().End();
491 const j = JSON.parse(b.json());
492 assert.eq(j.section[1].data[0].code[0].name, "i32.const");
493 assert.eq(j.section[1].data[0].code[0].arguments.length, 0);
494 assert.eq(j.section[1].data[0].code[0].immediates.length, 1);
495 assert.eq(j.section[1].data[0].code[0].immediates[0], c);
499 (function I32ConstInvalid() {
500 for (let c of [-1, 0x100000000, 0.1, -0.1, "0", {}, Infinity, null])
501 assertOpThrows(f => f.I32Const(c), `Expected truthy: Invalid value on i32.const: got "${c}", expected i32`);
504 // FIXME: test i64. https://bugs.webkit.org/show_bug.cgi?id=163420
506 (function F32ConstValid() {
507 for (let c of [0, -0., 0.2, Math.PI, 0x100000000]) {
508 const b = (new Builder()).Type().End().Code().Function().F32Const(c).Return().End().End();
509 const j = JSON.parse(b.json());
510 assert.eq(j.section[1].data[0].code[0].name, "f32.const");
511 assert.eq(j.section[1].data[0].code[0].arguments.length, 0);
512 assert.eq(j.section[1].data[0].code[0].immediates.length, 1);
513 assert.eq(j.section[1].data[0].code[0].immediates[0], c);
517 (function F32ConstInvalid() {
518 for (let c of ["0", {}, Infinity, -Infinity, NaN, -NaN, null])
519 assertOpThrows(f => f.F32Const(c), `Expected truthy: Invalid value on f32.const: got "${c}", expected f32`);
522 (function F64ConstValid() {
523 for (let c of [0, -0., 0.2, Math.PI, 0x100000000]) {
524 const b = (new Builder()).Type().End().Code().Function().F64Const(c).Return().End().End();
525 const j = JSON.parse(b.json());
526 assert.eq(j.section[1].data[0].code[0].name, "f64.const");
527 assert.eq(j.section[1].data[0].code[0].arguments.length, 0);
528 assert.eq(j.section[1].data[0].code[0].immediates.length, 1);
529 assert.eq(j.section[1].data[0].code[0].immediates[0], c);
533 (function F64ConstInvalid() {
534 for (let c of ["0", {}, Infinity, -Infinity, NaN, -NaN, null])
535 assertOpThrows(f => f.F64Const(c), `Expected truthy: Invalid value on f64.const: got "${c}", expected f64`);
538 (function CallOneFromStack() {
539 const b = (new Builder()).Type().End().Code()
540 .Function({ params: ["i32"] })
545 const j = JSON.parse(b.json());
546 assert.eq(j.section[1].data[0].code.length, 3);
547 assert.eq(j.section[1].data[0].code[0].name, "i32.const");
548 assert.eq(j.section[1].data[0].code[0].immediates[0], 42);
549 assert.eq(j.section[1].data[0].code[1].name, "call");
550 // FIXME: assert.eq(j.section[1].data[0].code[1].arguments.length, 1); https://bugs.webkit.org/show_bug.cgi?id=163267
551 assert.eq(j.section[1].data[0].code[1].immediates.length, 1);
552 assert.eq(j.section[1].data[0].code[1].immediates[0], 0);
553 assert.eq(j.section[1].data[0].code[2].name, "end");
556 // FIXME https://bugs.webkit.org/show_bug.cgi?id=163267 all of these:
557 // test too many pops.
558 // test not enough pops (function has non-empty stack at the end).
559 // test mismatched pop types.
560 // test mismatched function signature (calling with wrong arg types).
561 // test invalid function index.
562 // test function names (both setting and calling them).
564 (function CallManyFromStack() {
565 const b = (new Builder()).Type().End().Code()
566 .Function({ params: ["i32", "i32", "i32", "i32"] })
567 .I32Const(42).I32Const(1337).I32Const(0xBEEF).I32Const(0xFFFF)
571 const j = JSON.parse(b.json());
572 assert.eq(j.section[1].data[0].code.length, 6);
573 assert.eq(j.section[1].data[0].code[4].name, "call");
574 // FIXME: assert.eq(j.section[1].data[0].code[4].arguments.length, 4); https://bugs.webkit.org/show_bug.cgi?id=163267
575 assert.eq(j.section[1].data[0].code[4].immediates.length, 1);
576 assert.eq(j.section[1].data[0].code[4].immediates[0], 0);
579 (function OpcodeAdd() {
580 const b = (new Builder()).Type().End().Code()
582 .I32Const(42).I32Const(1337)
587 const j = JSON.parse(b.json());
588 assert.eq(j.section[1].data[0].code.length, 5);
589 assert.eq(j.section[1].data[0].code[2].name, "i32.add");
590 // FIXME: assert.eq(j.section[1].data[0].code[2].arguments.length, 2); https://bugs.webkit.org/show_bug.cgi?id=163267
591 assert.eq(j.section[1].data[0].code[3].name, "return");
592 // FIXME check return. https://bugs.webkit.org/show_bug.cgi?id=163267
595 (function OpcodeUnreachable() {
596 const b = (new Builder()).Type().End().Code().Function().Unreachable().End().End();
597 const j = JSON.parse(b.json());
598 assert.eq(j.section[1].data[0].code.length, 2);
599 assert.eq(j.section[1].data[0].code[0].name, "unreachable");
602 (function OpcodeUnreachableCombinations() {
603 (new Builder()).Type().End().Code().Function().Nop().Unreachable().End().End().json();
604 (new Builder()).Type().End().Code().Function().Unreachable().Nop().End().End().json();
605 (new Builder()).Type().End().Code().Function().Return().Unreachable().End().End().json();
606 (new Builder()).Type().End().Code().Function().Unreachable().Return().End().End().json();
607 (new Builder()).Type().End().Code().Function().Call(0).Unreachable().End().End().json();
608 (new Builder()).Type().End().Code().Function().Unreachable().Call(0).End().End().json();
611 (function OpcodeSelect() {
612 const b = (new Builder()).Type().End().Code().Function()
613 .I32Const(1).I32Const(2).I32Const(0)
618 const j = JSON.parse(b.json());
619 assert.eq(j.section[1].data[0].code.length, 6);
620 assert.eq(j.section[1].data[0].code[3].name, "select");
623 (function MemoryImport() {
624 const builder = (new Builder())
627 .Memory("__module__", "__field__", {initial: 30, maximum: 31})
631 const json = JSON.parse(builder.json());
632 assert.eq(json.section.length, 3);
633 assert.eq(json.section[1].name, "Import");
634 assert.eq(json.section[1].data.length, 1);
635 assert.eq(json.section[1].data[0].module, "__module__");
636 assert.eq(json.section[1].data[0].field, "__field__");
637 assert.eq(json.section[1].data[0].kind, "Memory");
638 assert.eq(json.section[1].data[0].memoryDescription.initial, 30);
639 assert.eq(json.section[1].data[0].memoryDescription.maximum, 31);
642 // FIXME test type mismatch with select. https://bugs.webkit.org/show_bug.cgi?id=163267