Skip to content

Commit 31b4f34

Browse files
xtucbinji
authored andcommitted
[test] sync wasm-module-builder with v8 (#944)
sync with v8's one.
1 parent 94bd1f9 commit 31b4f34

File tree

2 files changed

+105
-76
lines changed

2 files changed

+105
-76
lines changed

test/js-api/wasm-constants.js

+55-45
Original file line numberDiff line numberDiff line change
@@ -21,13 +21,14 @@ var kWasmH1 = 0x61;
2121
var kWasmH2 = 0x73;
2222
var kWasmH3 = 0x6d;
2323

24-
var kWasmV0 = 1;
24+
var kWasmV0 = 0x1;
2525
var kWasmV1 = 0;
2626
var kWasmV2 = 0;
2727
var kWasmV3 = 0;
2828

2929
var kHeaderSize = 8;
3030
var kPageSize = 65536;
31+
var kSpecMaxPages = 65535;
3132

3233
function bytesWithHeader() {
3334
var buffer = new ArrayBuffer(kHeaderSize + arguments.length);
@@ -52,22 +53,27 @@ let kDeclNoLocals = 0;
5253

5354
// Section declaration constants
5455
let kUnknownSectionCode = 0;
55-
let kTypeSectionCode = 1; // Function signature declarations
56-
let kImportSectionCode = 2; // Import declarations
57-
let kFunctionSectionCode = 3; // Function declarations
58-
let kTableSectionCode = 4; // Indirect function table and other tables
59-
let kMemorySectionCode = 5; // Memory attributes
60-
let kGlobalSectionCode = 6; // Global declarations
61-
let kExportSectionCode = 7; // Exports
62-
let kStartSectionCode = 8; // Start function declaration
63-
let kElementSectionCode = 9; // Elements section
64-
let kCodeSectionCode = 10; // Function code
65-
let kDataSectionCode = 11; // Data segments
66-
let kNameSectionCode = 12; // Name section (encoded as string)
56+
let kTypeSectionCode = 1; // Function signature declarations
57+
let kImportSectionCode = 2; // Import declarations
58+
let kFunctionSectionCode = 3; // Function declarations
59+
let kTableSectionCode = 4; // Indirect function table and other tables
60+
let kMemorySectionCode = 5; // Memory attributes
61+
let kGlobalSectionCode = 6; // Global declarations
62+
let kExportSectionCode = 7; // Exports
63+
let kStartSectionCode = 8; // Start function declaration
64+
let kElementSectionCode = 9; // Elements section
65+
let kCodeSectionCode = 10; // Function code
66+
let kDataSectionCode = 11; // Data segments
67+
68+
// Name section types
69+
let kModuleNameCode = 0;
70+
let kFunctionNamesCode = 1;
71+
let kLocalNamesCode = 2;
6772

6873
let kWasmFunctionTypeForm = 0x60;
6974
let kWasmAnyFunctionTypeForm = 0x70;
7075

76+
let kHasMaximumFlag = 1;
7177
let kResizableMaximumFlag = 1;
7278

7379
// Function declaration flags
@@ -98,13 +104,15 @@ let kSig_l_l = makeSig([kWasmI64], [kWasmI64]);
98104
let kSig_i_l = makeSig([kWasmI64], [kWasmI32]);
99105
let kSig_i_ii = makeSig([kWasmI32, kWasmI32], [kWasmI32]);
100106
let kSig_i_iii = makeSig([kWasmI32, kWasmI32, kWasmI32], [kWasmI32]);
107+
let kSig_v_iiii = makeSig([kWasmI32, kWasmI32, kWasmI32, kWasmI32], []);
108+
let kSig_f_ff = makeSig([kWasmF32, kWasmF32], [kWasmF32]);
101109
let kSig_d_dd = makeSig([kWasmF64, kWasmF64], [kWasmF64]);
102110
let kSig_l_ll = makeSig([kWasmI64, kWasmI64], [kWasmI64]);
103111
let kSig_i_dd = makeSig([kWasmF64, kWasmF64], [kWasmI32]);
104112
let kSig_v_v = makeSig([], []);
105113
let kSig_i_v = makeSig([], [kWasmI32]);
106114
let kSig_l_v = makeSig([], [kWasmI64]);
107-
let kSig_f_v = makeSig([], [kWasmF64]);
115+
let kSig_f_v = makeSig([], [kWasmF32]);
108116
let kSig_d_v = makeSig([], [kWasmF64]);
109117
let kSig_v_i = makeSig([kWasmI32], []);
110118
let kSig_v_ii = makeSig([kWasmI32, kWasmI32], []);
@@ -113,7 +121,11 @@ let kSig_v_l = makeSig([kWasmI64], []);
113121
let kSig_v_d = makeSig([kWasmF64], []);
114122
let kSig_v_dd = makeSig([kWasmF64, kWasmF64], []);
115123
let kSig_v_ddi = makeSig([kWasmF64, kWasmF64, kWasmI32], []);
116-
let kSig_s_v = makeSig([], [kWasmS128]);
124+
125+
let kSig_v_f = makeSig([kWasmF32], []);
126+
let kSig_f_f = makeSig([kWasmF32], [kWasmF32]);
127+
let kSig_f_d = makeSig([kWasmF64], [kWasmF32]);
128+
let kSig_d_d = makeSig([kWasmF64], [kWasmF64]);
117129

118130
function makeSig(params, results) {
119131
return {params: params, results: results};
@@ -191,7 +203,7 @@ let kExprI64StoreMem8 = 0x3c;
191203
let kExprI64StoreMem16 = 0x3d;
192204
let kExprI64StoreMem32 = 0x3e;
193205
let kExprMemorySize = 0x3f;
194-
let kExprGrowMemory = 0x40;
206+
let kExprMemoryGrow = 0x40;
195207
let kExprI32Eqz = 0x45;
196208
let kExprI32Eq = 0x46;
197209
let kExprI32Ne = 0x47;
@@ -339,36 +351,34 @@ let kTrapMsgs = [
339351
];
340352

341353
function assertTraps(trap, code) {
342-
var threwException = true;
343-
try {
344-
if (typeof code === 'function') {
345-
code();
346-
} else {
347-
eval(code);
348-
}
349-
threwException = false;
350-
} catch (e) {
351-
assertEquals("object", typeof e);
352-
assertEquals(kTrapMsgs[trap], e.message);
353-
// Success.
354-
return;
354+
try {
355+
if (typeof code === 'function') {
356+
code();
357+
} else {
358+
eval(code);
355359
}
356-
throw new MjsUnitAssertionError("Did not trap, expected: " + kTrapMsgs[trap]);
360+
} catch (e) {
361+
assertEquals('object', typeof e);
362+
assertEquals(kTrapMsgs[trap], e.message);
363+
// Success.
364+
return;
365+
}
366+
throw new MjsUnitAssertionError('Did not trap, expected: ' + kTrapMsgs[trap]);
357367
}
358368

359-
function assertWasmThrows(value, code) {
360-
assertEquals("number", typeof(value));
361-
try {
362-
if (typeof code === 'function') {
363-
code();
364-
} else {
365-
eval(code);
366-
}
367-
} catch (e) {
368-
assertEquals("number", typeof e);
369-
assertEquals(value, e);
370-
// Success.
371-
return;
372-
}
373-
throw new MjsUnitAssertionError("Did not throw at all, expected: " + value);
369+
function wasmI32Const(val) {
370+
let bytes = [kExprI32Const];
371+
for (let i = 0; i < 4; ++i) {
372+
bytes.push(0x80 | ((val >> (7 * i)) & 0x7f));
373+
}
374+
bytes.push((val >> (7 * 4)) & 0x7f);
375+
return bytes;
376+
}
377+
378+
function wasmF32Const(f) {
379+
return [kExprF32Const].concat(Array.from(new Uint8Array((new Float32Array([f])).buffer)));
380+
}
381+
382+
function wasmF64Const(f) {
383+
return [kExprF64Const].concat(Array.from(new Uint8Array((new Float64Array([f])).buffer)));
374384
}

test/js-api/wasm-module-builder.js

+50-31
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,8 @@ class Binary extends Array {
7474
// Emit section length.
7575
this.emit_u32v(section.length);
7676
// Copy the temporary buffer.
77-
this.push(...section);
77+
// Avoid spread because {section} can be huge.
78+
for (let b of section) this.push(b);
7879
}
7980
}
8081

@@ -133,9 +134,10 @@ class WasmModuleBuilder {
133134
this.exports = [];
134135
this.globals = [];
135136
this.functions = [];
136-
this.function_table = [];
137-
this.function_table_length = 0;
138-
this.function_table_inits = [];
137+
this.table_length_min = 0;
138+
this.table_length_max = undefined;
139+
this.element_segments = [];
140+
this.data_segments = [];
139141
this.segments = [];
140142
this.explicit = [];
141143
this.num_imported_funcs = 0;
@@ -217,35 +219,49 @@ class WasmModuleBuilder {
217219
}
218220

219221
addDataSegment(addr, data, is_global = false) {
220-
this.segments.push({addr: addr, data: data, is_global: is_global});
221-
return this.segments.length - 1;
222+
this.data_segments.push(
223+
{addr: addr, data: data, is_global: is_global});
224+
return this.data_segments.length - 1;
222225
}
223226

224227
exportMemoryAs(name) {
225228
this.exports.push({name: name, kind: kExternalMemory, index: 0});
226229
}
227230

228-
addFunctionTableInit(base, is_global, array) {
229-
this.function_table_inits.push({base: base, is_global: is_global,
231+
addElementSegment(base, is_global, array, is_import = false) {
232+
this.element_segments.push({base: base, is_global: is_global,
230233
array: array});
231234
if (!is_global) {
232235
var length = base + array.length;
233-
if (length > this.function_table_length) {
234-
this.function_table_length = length;
236+
if (length > this.table_length_min && !is_import) {
237+
this.table_length_min = length;
238+
}
239+
if (length > this.table_length_max && !is_import) {
240+
this.table_length_max = length;
235241
}
236242
}
237243
return this;
238244
}
239245

240246
appendToTable(array) {
241-
return this.addFunctionTableInit(this.function_table.length, false, array);
247+
for (let n of array) {
248+
if (typeof n != 'number')
249+
throw new Error('invalid table (entries have to be numbers): ' + array);
250+
}
251+
return this.addElementSegment(this.table_length_min, false, array);
242252
}
243253

244-
setFunctionTableLength(length) {
245-
this.function_table_length = length;
254+
setTableBounds(min, max = undefined) {
255+
this.table_length_min = min;
256+
this.table_length_max = max;
246257
return this;
247258
}
248259

260+
// TODO(ssauleau): legacy, remove this
261+
setFunctionTableLength(length) {
262+
return this.setTableBounds(length);
263+
}
264+
249265
toArray(debug = false) {
250266
let binary = new Binary;
251267
let wasm = this;
@@ -319,26 +335,29 @@ class WasmModuleBuilder {
319335
});
320336
}
321337

322-
// Add function_table.
323-
if (wasm.function_table_length > 0) {
338+
// Add table section
339+
if (wasm.table_length_min > 0) {
324340
if (debug) print("emitting table @ " + binary.length);
325341
binary.emit_section(kTableSectionCode, section => {
326342
section.emit_u8(1); // one table entry
327343
section.emit_u8(kWasmAnyFunctionTypeForm);
328-
section.emit_u8(1);
329-
section.emit_u32v(wasm.function_table_length);
330-
section.emit_u32v(wasm.function_table_length);
344+
const max = wasm.table_length_max;
345+
const has_max = max !== undefined;
346+
section.emit_u8(has_max ? kHasMaximumFlag : 0);
347+
section.emit_u32v(wasm.table_length_min);
348+
if (has_max) section.emit_u32v(max);
331349
});
332350
}
333351

334352
// Add memory section
335-
if (wasm.memory != undefined) {
353+
if (wasm.memory !== undefined) {
336354
if (debug) print("emitting memory @ " + binary.length);
337355
binary.emit_section(kMemorySectionCode, section => {
338356
section.emit_u8(1); // one memory entry
339-
section.emit_u32v(kResizableMaximumFlag);
357+
const has_max = wasm.memory.max !== undefined;
358+
section.emit_u8(has_max ? 1 : 0);
340359
section.emit_u32v(wasm.memory.min);
341-
section.emit_u32v(wasm.memory.max);
360+
if (has_max) section.emit_u32v(wasm.memory.max);
342361
});
343362
}
344363

@@ -393,7 +412,7 @@ class WasmModuleBuilder {
393412
}
394413

395414
// Add export table.
396-
var mem_export = (wasm.memory != undefined && wasm.memory.exp);
415+
var mem_export = (wasm.memory !== undefined && wasm.memory.exp);
397416
var exports_count = wasm.exports.length + (mem_export ? 1 : 0);
398417
if (exports_count > 0) {
399418
if (debug) print("emitting exports @ " + binary.length);
@@ -420,15 +439,15 @@ class WasmModuleBuilder {
420439
});
421440
}
422441

423-
// Add table elements.
424-
if (wasm.function_table_inits.length > 0) {
425-
if (debug) print("emitting table @ " + binary.length);
442+
// Add element segments
443+
if (wasm.element_segments.length > 0) {
444+
if (debug) print("emitting element segments @ " + binary.length);
426445
binary.emit_section(kElementSectionCode, section => {
427-
var inits = wasm.function_table_inits;
446+
var inits = wasm.element_segments;
428447
section.emit_u32v(inits.length);
429-
section.emit_u8(0); // table index
430448

431449
for (let init of inits) {
450+
section.emit_u8(0); // table index / flags
432451
if (init.is_global) {
433452
section.emit_u8(kExprGetGlobal);
434453
} else {
@@ -485,12 +504,12 @@ class WasmModuleBuilder {
485504
}
486505

487506
// Add data segments.
488-
if (wasm.segments.length > 0) {
507+
if (wasm.data_segments.length > 0) {
489508
if (debug) print("emitting data segments @ " + binary.length);
490509
binary.emit_section(kDataSectionCode, section => {
491-
section.emit_u32v(wasm.segments.length);
492-
for (let seg of wasm.segments) {
493-
section.emit_u8(0); // linear memory index 0
510+
section.emit_u32v(wasm.data_segments.length);
511+
for (let seg of wasm.data_segments) {
512+
section.emit_u8(0); // linear memory index 0 / flags
494513
if (seg.is_global) {
495514
// initializer is a global variable
496515
section.emit_u8(kExprGetGlobal);

0 commit comments

Comments
 (0)