[test] Format two test files

Change-Id: Ia1f970cf997f12f21c1553e20fb836194f3b1a1f
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2739638
Reviewed-by: Jakob Kummerow <jkummerow@chromium.org>
Commit-Queue: Manos Koukoutos <manoskouk@chromium.org>
Cr-Commit-Position: refs/heads/master@{#73226}
This commit is contained in:
Manos Koukoutos 2021-03-05 12:03:33 +00:00 committed by Commit Bot
parent 14ac92e02c
commit 0ab981017d
2 changed files with 253 additions and 210 deletions

View File

@ -4,82 +4,81 @@
// Flags: --experimental-wasm-typed-funcref // Flags: --experimental-wasm-typed-funcref
load("test/mjsunit/wasm/wasm-module-builder.js"); load('test/mjsunit/wasm/wasm-module-builder.js');
(function TestTables() { (function TestTables() {
var exporting_instance = (function () { var exporting_instance = (function() {
var builder = new WasmModuleBuilder(); var builder = new WasmModuleBuilder();
var binary_type = builder.addType(kSig_i_ii); var binary_type = builder.addType(kSig_i_ii);
builder.addFunction("addition", kSig_i_ii) builder.addFunction('addition', kSig_i_ii)
.addBody([kExprLocalGet, 0, kExprLocalGet, 1, kExprI32Add]) .addBody([kExprLocalGet, 0, kExprLocalGet, 1, kExprI32Add])
.exportFunc(); .exportFunc();
builder.addFunction("succ", kSig_i_i) builder.addFunction('succ', kSig_i_i)
.addBody([kExprLocalGet, 0, kExprI32Const, 1, kExprI32Add]) .addBody([kExprLocalGet, 0, kExprI32Const, 1, kExprI32Add])
.exportFunc(); .exportFunc();
builder.addTable(wasmOptRefType(binary_type), 1, 100).exportAs("table"); builder.addTable(wasmOptRefType(binary_type), 1, 100).exportAs('table');
return builder.instantiate({}); return builder.instantiate({});
})(); })();
// Wrong type for imported table. // Wrong type for imported table.
assertThrows( assertThrows(() => {
() => { var builder = new WasmModuleBuilder();
var builder = new WasmModuleBuilder(); var unary_type = builder.addType(kSig_i_i);
var unary_type = builder.addType(kSig_i_i); builder.addImportedTable(
builder.addImportedTable("imports", "table", 1, 100, 'imports', 'table', 1, 100, wasmOptRefType(unary_type));
wasmOptRefType(unary_type)); builder.instantiate({imports: {table: exporting_instance.exports.table}})
builder.instantiate({imports: {table: exporting_instance.exports.table}}) }, WebAssembly.LinkError, /imported table does not match the expected type/)
},
WebAssembly.LinkError,
/imported table does not match the expected type/
)
// Type for imported table must match exactly. // Type for imported table must match exactly.
assertThrows( assertThrows(() => {
() => { var builder = new WasmModuleBuilder();
var builder = new WasmModuleBuilder(); builder.addImportedTable('imports', 'table', 1, 100, kWasmFuncRef);
builder.addImportedTable("imports", "table", 1, 100, kWasmFuncRef); builder.instantiate({imports: {table: exporting_instance.exports.table}})
builder.instantiate({imports: {table: exporting_instance.exports.table}}) }, WebAssembly.LinkError, /imported table does not match the expected type/)
},
WebAssembly.LinkError,
/imported table does not match the expected type/
)
var instance = (function () { var instance = (function() {
var builder = new WasmModuleBuilder(); var builder = new WasmModuleBuilder();
var unary_type = builder.addType(kSig_i_i); var unary_type = builder.addType(kSig_i_i);
var binary_type = builder.addType(kSig_i_ii); var binary_type = builder.addType(kSig_i_ii);
builder.addImportedTable("imports", "table", 1, 100, builder.addImportedTable(
wasmOptRefType(binary_type)); 'imports', 'table', 1, 100, wasmOptRefType(binary_type));
var table = builder.addTable(wasmOptRefType(unary_type), 10) var table =
.exportAs("table"); builder.addTable(wasmOptRefType(unary_type), 10).exportAs('table');
builder.addTable(kWasmFuncRef, 1).exportAs("generic_table"); builder.addTable(kWasmFuncRef, 1).exportAs('generic_table');
builder.addFunction("table_test", makeSig([wasmRefType(unary_type)], builder
[kWasmI32])) .addFunction(
// Set table[0] to input function, then retrieve it and call it. 'table_test', makeSig([wasmRefType(unary_type)], [kWasmI32]))
.addBody([kExprI32Const, 0, kExprLocalGet, 0, kExprTableSet, table.index, // Set table[0] to input function, then retrieve it and call it.
kExprI32Const, 42, kExprI32Const, 0, kExprTableGet, table.index, .addBody([
kExprCallRef]) kExprI32Const, 0, kExprLocalGet, 0, kExprTableSet, table.index,
.exportFunc(); kExprI32Const, 42, kExprI32Const, 0, kExprTableGet, table.index,
kExprCallRef
])
.exportFunc();
// Same, but with table[1] and call_indirect // Same, but with table[1] and call_indirect
builder.addFunction("table_indirect_test", builder
makeSig([wasmRefType(unary_type)], [kWasmI32])) .addFunction(
.addBody([kExprI32Const, 1, kExprLocalGet, 0, kExprTableSet, table.index, 'table_indirect_test',
kExprI32Const, 42, kExprI32Const, 0, makeSig([wasmRefType(unary_type)], [kWasmI32]))
kExprCallIndirect, unary_type, table.index]) .addBody([
.exportFunc(); kExprI32Const, 1, kExprLocalGet, 0, kExprTableSet, table.index,
kExprI32Const, 42, kExprI32Const, 0, kExprCallIndirect, unary_type,
table.index
])
.exportFunc();
// Instantiate with a table of the correct type. // Instantiate with a table of the correct type.
return builder.instantiate( return builder.instantiate(
{imports: {table: exporting_instance.exports.table}}); {imports: {table: exporting_instance.exports.table}});
})(); })();
// This module is valid. // This module is valid.
@ -87,19 +86,20 @@ load("test/mjsunit/wasm/wasm-module-builder.js");
// The correct function reference is preserved when setting it to and getting // The correct function reference is preserved when setting it to and getting
// it back from a table. // it back from a table.
assertEquals(43, assertEquals(
instance.exports.table_test(exporting_instance.exports.succ)); 43, instance.exports.table_test(exporting_instance.exports.succ));
// Same for call indirect (the indirect call tables are also set correctly). // Same for call indirect (the indirect call tables are also set correctly).
assertEquals(43, instance.exports.table_indirect_test( assertEquals(
exporting_instance.exports.succ)); 43,
instance.exports.table_indirect_test(exporting_instance.exports.succ));
// Setting from JS API respects types. // Setting from JS API respects types.
instance.exports.generic_table.set(0, exporting_instance.exports.succ); instance.exports.generic_table.set(0, exporting_instance.exports.succ);
instance.exports.table.set(0, exporting_instance.exports.succ); instance.exports.table.set(0, exporting_instance.exports.succ);
assertThrows( assertThrows(
() => instance.exports.table.set(0, exporting_instance.exports.addition), () => instance.exports.table.set(0, exporting_instance.exports.addition),
TypeError, TypeError,
/Argument 1 must be null or a WebAssembly function of type compatible to/); /Argument 1 must be null or a WebAssembly function of type compatible to/);
})(); })();
(function TestNonNullableTables() { (function TestNonNullableTables() {
@ -107,24 +107,30 @@ load("test/mjsunit/wasm/wasm-module-builder.js");
var binary_type = builder.addType(kSig_i_ii); var binary_type = builder.addType(kSig_i_ii);
var addition = builder.addFunction("addition", kSig_i_ii) var addition = builder.addFunction('addition', kSig_i_ii).addBody([
.addBody([kExprLocalGet, 0, kExprLocalGet, 1, kExprI32Add]); kExprLocalGet, 0, kExprLocalGet, 1, kExprI32Add
var subtraction = builder.addFunction("subtraction", kSig_i_ii) ]);
.addBody([kExprLocalGet, 0, kExprLocalGet, 1, kExprI32Sub]) var subtraction =
.exportFunc(); builder.addFunction('subtraction', kSig_i_ii)
.addBody([kExprLocalGet, 0, kExprLocalGet, 1, kExprI32Sub])
.exportFunc();
var table = builder.addTable(wasmRefType(binary_type), 3, 3, addition.index); var table = builder.addTable(wasmRefType(binary_type), 3, 3, addition.index);
builder.addFunction("init", kSig_v_v) builder.addFunction('init', kSig_v_v)
.addBody([kExprI32Const, 1, kExprRefFunc, subtraction.index, .addBody([
kExprTableSet, table.index]) kExprI32Const, 1, kExprRefFunc, subtraction.index, kExprTableSet,
.exportFunc(); table.index
])
.exportFunc();
// (index, arg1, arg2) -> table[index](arg1, arg2) // (index, arg1, arg2) -> table[index](arg1, arg2)
builder.addFunction("table_test", kSig_i_iii) builder.addFunction('table_test', kSig_i_iii)
.addBody([kExprLocalGet, 1, kExprLocalGet, 2, kExprLocalGet, 0, .addBody([
kExprCallIndirect, binary_type, table.index]) kExprLocalGet, 1, kExprLocalGet, 2, kExprLocalGet, 0, kExprCallIndirect,
.exportFunc(); binary_type, table.index
])
.exportFunc();
var instance = builder.instantiate({}); var instance = builder.instantiate({});

View File

@ -92,7 +92,7 @@ let kPassiveWithElements = 5;
let kDeclarativeWithElements = 7; let kDeclarativeWithElements = 7;
// Function declaration flags // Function declaration flags
let kDeclFunctionName = 0x01; let kDeclFunctionName = 0x01;
let kDeclFunctionImport = 0x02; let kDeclFunctionImport = 0x02;
let kDeclFunctionLocals = 0x04; let kDeclFunctionLocals = 0x04;
let kDeclFunctionExport = 0x08; let kDeclFunctionExport = 0x08;
@ -107,14 +107,18 @@ let kWasmS128 = 0x7b;
let kWasmI8 = 0x7a; let kWasmI8 = 0x7a;
let kWasmI16 = 0x79; let kWasmI16 = 0x79;
let kWasmFuncRef = 0x70; let kWasmFuncRef = 0x70;
let kWasmAnyFunc = kWasmFuncRef; // Alias named as in the JS API spec let kWasmAnyFunc = kWasmFuncRef; // Alias named as in the JS API spec
let kWasmExternRef = 0x6f; let kWasmExternRef = 0x6f;
let kWasmAnyRef = 0x6e; let kWasmAnyRef = 0x6e;
let kWasmEqRef = 0x6d; let kWasmEqRef = 0x6d;
let kWasmOptRef = 0x6c; let kWasmOptRef = 0x6c;
let kWasmRef = 0x6b; let kWasmRef = 0x6b;
function wasmOptRefType(index) { return {opcode: kWasmOptRef, index: index}; } function wasmOptRefType(index) {
function wasmRefType(index) { return {opcode: kWasmRef, index: index}; } return {opcode: kWasmOptRef, index: index};
}
function wasmRefType(index) {
return {opcode: kWasmRef, index: index};
}
let kWasmI31Ref = 0x6a; let kWasmI31Ref = 0x6a;
let kWasmRtt = 0x69; let kWasmRtt = 0x69;
function wasmRtt(index, depth) { function wasmRtt(index, depth) {
@ -723,32 +727,32 @@ let kCompilationHintTierDefault = 0x00;
let kCompilationHintTierBaseline = 0x01; let kCompilationHintTierBaseline = 0x01;
let kCompilationHintTierOptimized = 0x02; let kCompilationHintTierOptimized = 0x02;
let kTrapUnreachable = 0; let kTrapUnreachable = 0;
let kTrapMemOutOfBounds = 1; let kTrapMemOutOfBounds = 1;
let kTrapDivByZero = 2; let kTrapDivByZero = 2;
let kTrapDivUnrepresentable = 3; let kTrapDivUnrepresentable = 3;
let kTrapRemByZero = 4; let kTrapRemByZero = 4;
let kTrapFloatUnrepresentable = 5; let kTrapFloatUnrepresentable = 5;
let kTrapTableOutOfBounds = 6; let kTrapTableOutOfBounds = 6;
let kTrapFuncSigMismatch = 7; let kTrapFuncSigMismatch = 7;
let kTrapUnalignedAccess = 8; let kTrapUnalignedAccess = 8;
let kTrapDataSegmentDropped = 9; let kTrapDataSegmentDropped = 9;
let kTrapElemSegmentDropped = 10; let kTrapElemSegmentDropped = 10;
let kTrapRethrowNull = 11; let kTrapRethrowNull = 11;
let kTrapMsgs = [ let kTrapMsgs = [
"unreachable", 'unreachable',
"memory access out of bounds", 'memory access out of bounds',
"divide by zero", 'divide by zero',
"divide result unrepresentable", 'divide result unrepresentable',
"remainder by zero", 'remainder by zero',
"float unrepresentable in integer range", 'float unrepresentable in integer range',
"table index is out of bounds", 'table index is out of bounds',
"function signature mismatch", 'function signature mismatch',
"operation does not support unaligned accesses", 'operation does not support unaligned accesses',
"data segment has been dropped", 'data segment has been dropped',
"element segment has been dropped", 'element segment has been dropped',
"rethrowing null value" 'rethrowing null value'
]; ];
function assertTraps(trap, code) { function assertTraps(trap, code) {
@ -808,7 +812,7 @@ class Binary {
} }
this.buffer[this.length++] = v | 0x80; this.buffer[this.length++] = v | 0x80;
} }
throw new Error("Leb value exceeds maximum length of " + max_len); throw new Error('Leb value exceeds maximum length of ' + max_len);
} }
emit_u32v(val) { emit_u32v(val) {
@ -843,8 +847,9 @@ class Binary {
} }
emit_type(type) { emit_type(type) {
if ((typeof type) == "number") this.emit_u8(type); if ((typeof type) == 'number') {
else { this.emit_u8(type);
} else {
this.emit_u8(type.opcode); this.emit_u8(type.opcode);
if ('depth' in type) this.emit_u8(type.depth); if ('depth' in type) this.emit_u8(type.depth);
this.emit_u32v(type.index); this.emit_u32v(type.index);
@ -887,7 +892,7 @@ class WasmFunctionBuilder {
numLocalNames() { numLocalNames() {
let num_local_names = 0; let num_local_names = 0;
for (let loc_name of this.local_names) { for (let loc_name of this.local_names) {
if (typeof loc_name == "string") ++num_local_names; if (typeof loc_name == 'string') ++num_local_names;
} }
return num_local_names; return num_local_names;
} }
@ -909,8 +914,10 @@ class WasmFunctionBuilder {
addBody(body) { addBody(body) {
for (let b of body) { for (let b of body) {
if (typeof b !== 'number' || (b & (~0xFF)) !== 0 ) if (typeof b !== 'number' || (b & (~0xFF)) !== 0) {
throw new Error('invalid body (entries must be 8 bit numbers): ' + body); throw new Error(
'invalid body (entries must be 8 bit numbers): ' + body);
}
} }
this.body = body.slice(); this.body = body.slice();
// Automatically add the end for the function block to the body. // Automatically add the end for the function block to the body.
@ -954,8 +961,8 @@ class WasmGlobalBuilder {
} }
exportAs(name) { exportAs(name) {
this.module.exports.push({name: name, kind: kExternalGlobal, this.module.exports.push(
index: this.index}); {name: name, kind: kExternalGlobal, index: this.index});
return this; return this;
} }
} }
@ -972,21 +979,21 @@ class WasmTableBuilder {
} }
exportAs(name) { exportAs(name) {
this.module.exports.push({name: name, kind: kExternalTable, this.module.exports.push(
index: this.index}); {name: name, kind: kExternalTable, index: this.index});
return this; return this;
} }
} }
function makeField(type, mutability) { function makeField(type, mutability) {
assertEquals("boolean", typeof mutability, assertEquals(
"field mutability must be boolean"); 'boolean', typeof mutability, 'field mutability must be boolean');
return {type: type, mutability: mutability}; return {type: type, mutability: mutability};
} }
class WasmStruct { class WasmStruct {
constructor(fields) { constructor(fields) {
assertTrue(Array.isArray(fields), "struct fields must be an array"); assertTrue(Array.isArray(fields), 'struct fields must be an array');
this.fields = fields; this.fields = fields;
} }
} }
@ -1074,8 +1081,8 @@ class WasmModuleBuilder {
addType(type) { addType(type) {
this.types.push(type); this.types.push(type);
var pl = type.params.length; // should have params var pl = type.params.length; // should have params
var rl = type.results.length; // should have results var rl = type.results.length; // should have results
return this.types.length - 1; return this.types.length - 1;
} }
@ -1096,21 +1103,21 @@ class WasmModuleBuilder {
return glob; return glob;
} }
addTable(type, initial_size, max_size = undefined, addTable(
init_func_index = undefined) { type, initial_size, max_size = undefined, init_func_index = undefined) {
if (type == kWasmI32 || type == kWasmI64 || type == kWasmF32 || if (type == kWasmI32 || type == kWasmI64 || type == kWasmF32 ||
type == kWasmF64 || type == kWasmS128 || type == kWasmStmt) { type == kWasmF64 || type == kWasmS128 || type == kWasmStmt) {
throw new Error('Tables must be of a reference type'); throw new Error('Tables must be of a reference type');
} }
let table = new WasmTableBuilder(this, type, initial_size, max_size, let table = new WasmTableBuilder(
init_func_index); this, type, initial_size, max_size, init_func_index);
table.index = this.tables.length + this.num_imported_tables; table.index = this.tables.length + this.num_imported_tables;
this.tables.push(table); this.tables.push(table);
return table; return table;
} }
addException(type) { addException(type) {
let type_index = (typeof type) == "number" ? type : this.addType(type); let type_index = (typeof type) == 'number' ? type : this.addType(type);
let except_index = this.exceptions.length + this.num_imported_exceptions; let except_index = this.exceptions.length + this.num_imported_exceptions;
this.exceptions.push(type_index); this.exceptions.push(type_index);
return except_index; return except_index;
@ -1118,10 +1125,12 @@ class WasmModuleBuilder {
addFunction(name, type, arg_names) { addFunction(name, type, arg_names) {
arg_names = arg_names || []; arg_names = arg_names || [];
let type_index = (typeof type) == "number" ? type : this.addType(type); let type_index = (typeof type) == 'number' ? type : this.addType(type);
let num_args = this.types[type_index].params.length; let num_args = this.types[type_index].params.length;
if (num_args < arg_names.length) throw new Error("too many arg names provided"); if (num_args < arg_names.length)
if (num_args > arg_names.length) arg_names.push(num_args - arg_names.length); throw new Error('too many arg names provided');
if (num_args > arg_names.length)
arg_names.push(num_args - arg_names.length);
let func = new WasmFunctionBuilder(this, name, type_index, arg_names); let func = new WasmFunctionBuilder(this, name, type_index, arg_names);
func.index = this.functions.length + this.num_imported_funcs; func.index = this.functions.length + this.num_imported_funcs;
this.functions.push(func); this.functions.push(func);
@ -1132,9 +1141,13 @@ class WasmModuleBuilder {
if (this.functions.length != 0) { if (this.functions.length != 0) {
throw new Error('Imported functions must be declared before local ones'); throw new Error('Imported functions must be declared before local ones');
} }
let type_index = (typeof type) == "number" ? type : this.addType(type); let type_index = (typeof type) == 'number' ? type : this.addType(type);
this.imports.push({module: module, name: name, kind: kExternalFunction, this.imports.push({
type_index: type_index}); module: module,
name: name,
kind: kExternalFunction,
type_index: type_index
});
return this.num_imported_funcs++; return this.num_imported_funcs++;
} }
@ -1142,15 +1155,26 @@ class WasmModuleBuilder {
if (this.globals.length != 0) { if (this.globals.length != 0) {
throw new Error('Imported globals must be declared before local ones'); throw new Error('Imported globals must be declared before local ones');
} }
let o = {module: module, name: name, kind: kExternalGlobal, type: type, let o = {
mutable: mutable}; module: module,
name: name,
kind: kExternalGlobal,
type: type,
mutable: mutable
};
this.imports.push(o); this.imports.push(o);
return this.num_imported_globals++; return this.num_imported_globals++;
} }
addImportedMemory(module, name, initial = 0, maximum, shared) { addImportedMemory(module, name, initial = 0, maximum, shared) {
let o = {module: module, name: name, kind: kExternalMemory, let o = {
initial: initial, maximum: maximum, shared: shared}; module: module,
name: name,
kind: kExternalMemory,
initial: initial,
maximum: maximum,
shared: shared
};
this.imports.push(o); this.imports.push(o);
return this; return this;
} }
@ -1159,8 +1183,14 @@ class WasmModuleBuilder {
if (this.tables.length != 0) { if (this.tables.length != 0) {
throw new Error('Imported tables must be declared before local ones'); throw new Error('Imported tables must be declared before local ones');
} }
let o = {module: module, name: name, kind: kExternalTable, initial: initial, let o = {
maximum: maximum, type: type || kWasmFuncRef}; module: module,
name: name,
kind: kExternalTable,
initial: initial,
maximum: maximum,
type: type || kWasmFuncRef
};
this.imports.push(o); this.imports.push(o);
return this.num_imported_tables++; return this.num_imported_tables++;
} }
@ -1169,9 +1199,13 @@ class WasmModuleBuilder {
if (this.exceptions.length != 0) { if (this.exceptions.length != 0) {
throw new Error('Imported exceptions must be declared before local ones'); throw new Error('Imported exceptions must be declared before local ones');
} }
let type_index = (typeof type) == "number" ? type : this.addType(type); let type_index = (typeof type) == 'number' ? type : this.addType(type);
let o = {module: module, name: name, kind: kExternalException, let o = {
type_index: type_index}; module: module,
name: name,
kind: kExternalException,
type_index: type_index
};
this.imports.push(o); this.imports.push(o);
return this.num_imported_exceptions++; return this.num_imported_exceptions++;
} }
@ -1185,7 +1219,7 @@ class WasmModuleBuilder {
if (index == undefined && kind != kExternalTable && if (index == undefined && kind != kExternalTable &&
kind != kExternalMemory) { kind != kExternalMemory) {
throw new Error( throw new Error(
'Index for exports other than tables/memories must be provided'); 'Index for exports other than tables/memories must be provided');
} }
if (index !== undefined && (typeof index) != 'number') { if (index !== undefined && (typeof index) != 'number') {
throw new Error('Index for exports must be a number') throw new Error('Index for exports must be a number')
@ -1195,8 +1229,11 @@ class WasmModuleBuilder {
} }
setCompilationHint(strategy, baselineTier, topTier, index) { setCompilationHint(strategy, baselineTier, topTier, index) {
this.compilation_hints[index] = {strategy: strategy, baselineTier: this.compilation_hints[index] = {
baselineTier, topTier: topTier}; strategy: strategy,
baselineTier: baselineTier,
topTier: topTier
};
return this; return this;
} }
@ -1260,7 +1297,7 @@ class WasmModuleBuilder {
setTableBounds(min, max = undefined) { setTableBounds(min, max = undefined) {
if (this.tables.length != 0) { if (this.tables.length != 0) {
throw new Error("The table bounds of table '0' have already been set."); throw new Error('The table bounds of table \'0\' have already been set.');
} }
this.addTable(kWasmAnyFunc, min, max); this.addTable(kWasmAnyFunc, min, max);
return this; return this;
@ -1280,7 +1317,7 @@ class WasmModuleBuilder {
// Add type section // Add type section
if (wasm.types.length > 0) { if (wasm.types.length > 0) {
if (debug) print("emitting types @ " + binary.length); if (debug) print('emitting types @ ' + binary.length);
binary.emit_section(kTypeSectionCode, section => { binary.emit_section(kTypeSectionCode, section => {
section.emit_u32v(wasm.types.length); section.emit_u32v(wasm.types.length);
for (let type of wasm.types) { for (let type of wasm.types) {
@ -1294,7 +1331,7 @@ class WasmModuleBuilder {
} else if (type instanceof WasmArray) { } else if (type instanceof WasmArray) {
section.emit_u8(kWasmArrayTypeForm); section.emit_u8(kWasmArrayTypeForm);
section.emit_type(type.type); section.emit_type(type.type);
section.emit_u8(1); // Only mutable arrays supported currently. section.emit_u8(1); // Only mutable arrays supported currently.
} else { } else {
section.emit_u8(kWasmFunctionTypeForm); section.emit_u8(kWasmFunctionTypeForm);
section.emit_u32v(type.params.length); section.emit_u32v(type.params.length);
@ -1312,7 +1349,7 @@ class WasmModuleBuilder {
// Add imports section // Add imports section
if (wasm.imports.length > 0) { if (wasm.imports.length > 0) {
if (debug) print("emitting imports @ " + binary.length); if (debug) print('emitting imports @ ' + binary.length);
binary.emit_section(kImportSectionCode, section => { binary.emit_section(kImportSectionCode, section => {
section.emit_u32v(wasm.imports.length); section.emit_u32v(wasm.imports.length);
for (let imp of wasm.imports) { for (let imp of wasm.imports) {
@ -1325,26 +1362,26 @@ class WasmModuleBuilder {
section.emit_type(imp.type); section.emit_type(imp.type);
section.emit_u8(imp.mutable); section.emit_u8(imp.mutable);
} else if (imp.kind == kExternalMemory) { } else if (imp.kind == kExternalMemory) {
var has_max = (typeof imp.maximum) != "undefined"; var has_max = (typeof imp.maximum) != 'undefined';
var is_shared = (typeof imp.shared) != "undefined"; var is_shared = (typeof imp.shared) != 'undefined';
if (is_shared) { if (is_shared) {
section.emit_u8(has_max ? 3 : 2); // flags section.emit_u8(has_max ? 3 : 2); // flags
} else { } else {
section.emit_u8(has_max ? 1 : 0); // flags section.emit_u8(has_max ? 1 : 0); // flags
} }
section.emit_u32v(imp.initial); // initial section.emit_u32v(imp.initial); // initial
if (has_max) section.emit_u32v(imp.maximum); // maximum if (has_max) section.emit_u32v(imp.maximum); // maximum
} else if (imp.kind == kExternalTable) { } else if (imp.kind == kExternalTable) {
section.emit_type(imp.type); section.emit_type(imp.type);
var has_max = (typeof imp.maximum) != "undefined"; var has_max = (typeof imp.maximum) != 'undefined';
section.emit_u8(has_max ? 1 : 0); // flags section.emit_u8(has_max ? 1 : 0); // flags
section.emit_u32v(imp.initial); // initial section.emit_u32v(imp.initial); // initial
if (has_max) section.emit_u32v(imp.maximum); // maximum if (has_max) section.emit_u32v(imp.maximum); // maximum
} else if (imp.kind == kExternalException) { } else if (imp.kind == kExternalException) {
section.emit_u32v(kExceptionAttribute); section.emit_u32v(kExceptionAttribute);
section.emit_u32v(imp.type_index); section.emit_u32v(imp.type_index);
} else { } else {
throw new Error("unknown/unsupported import kind " + imp.kind); throw new Error('unknown/unsupported import kind ' + imp.kind);
} }
} }
}); });
@ -1352,7 +1389,7 @@ class WasmModuleBuilder {
// Add functions declarations // Add functions declarations
if (wasm.functions.length > 0) { if (wasm.functions.length > 0) {
if (debug) print("emitting function decls @ " + binary.length); if (debug) print('emitting function decls @ ' + binary.length);
binary.emit_section(kFunctionSectionCode, section => { binary.emit_section(kFunctionSectionCode, section => {
section.emit_u32v(wasm.functions.length); section.emit_u32v(wasm.functions.length);
for (let func of wasm.functions) { for (let func of wasm.functions) {
@ -1363,7 +1400,7 @@ class WasmModuleBuilder {
// Add table section // Add table section
if (wasm.tables.length > 0) { if (wasm.tables.length > 0) {
if (debug) print ("emitting tables @ " + binary.length); if (debug) print('emitting tables @ ' + binary.length);
binary.emit_section(kTableSectionCode, section => { binary.emit_section(kTableSectionCode, section => {
section.emit_u32v(wasm.tables.length); section.emit_u32v(wasm.tables.length);
for (let table of wasm.tables) { for (let table of wasm.tables) {
@ -1382,7 +1419,7 @@ class WasmModuleBuilder {
// Add memory section // Add memory section
if (wasm.memory !== undefined) { if (wasm.memory !== undefined) {
if (debug) print("emitting memory @ " + binary.length); if (debug) print('emitting memory @ ' + binary.length);
binary.emit_section(kMemorySectionCode, section => { binary.emit_section(kMemorySectionCode, section => {
section.emit_u8(1); // one memory entry section.emit_u8(1); // one memory entry
const has_max = wasm.memory.max !== undefined; const has_max = wasm.memory.max !== undefined;
@ -1407,7 +1444,7 @@ class WasmModuleBuilder {
// Add event section. // Add event section.
if (wasm.exceptions.length > 0) { if (wasm.exceptions.length > 0) {
if (debug) print("emitting events @ " + binary.length); if (debug) print('emitting events @ ' + binary.length);
binary.emit_section(kExceptionSectionCode, section => { binary.emit_section(kExceptionSectionCode, section => {
section.emit_u32v(wasm.exceptions.length); section.emit_u32v(wasm.exceptions.length);
for (let type_index of wasm.exceptions) { for (let type_index of wasm.exceptions) {
@ -1419,55 +1456,55 @@ class WasmModuleBuilder {
// Add global section. // Add global section.
if (wasm.globals.length > 0) { if (wasm.globals.length > 0) {
if (debug) print ("emitting globals @ " + binary.length); if (debug) print('emitting globals @ ' + binary.length);
binary.emit_section(kGlobalSectionCode, section => { binary.emit_section(kGlobalSectionCode, section => {
section.emit_u32v(wasm.globals.length); section.emit_u32v(wasm.globals.length);
for (let global of wasm.globals) { for (let global of wasm.globals) {
section.emit_type(global.type); section.emit_type(global.type);
section.emit_u8(global.mutable); section.emit_u8(global.mutable);
if ((typeof global.init_index) == "undefined") { if ((typeof global.init_index) == 'undefined') {
// Emit a constant initializer. // Emit a constant initializer.
switch (global.type) { switch (global.type) {
case kWasmI32: case kWasmI32:
section.emit_u8(kExprI32Const); section.emit_u8(kExprI32Const);
section.emit_u32v(global.init); section.emit_u32v(global.init);
break; break;
case kWasmI64: case kWasmI64:
section.emit_u8(kExprI64Const); section.emit_u8(kExprI64Const);
section.emit_u64v(global.init); section.emit_u64v(global.init);
break; break;
case kWasmF32: case kWasmF32:
section.emit_bytes(wasmF32Const(global.init)); section.emit_bytes(wasmF32Const(global.init));
break; break;
case kWasmF64: case kWasmF64:
section.emit_bytes(wasmF64Const(global.init)); section.emit_bytes(wasmF64Const(global.init));
break; break;
case kWasmS128: case kWasmS128:
section.emit_bytes(wasmS128Const(global.init)); section.emit_bytes(wasmS128Const(global.init));
break; break;
case kWasmExternRef: case kWasmExternRef:
section.emit_u8(kExprRefNull);
section.emit_u8(kWasmExternRef);
assertEquals(global.function_index, undefined);
break;
case kWasmAnyFunc:
if (global.function_index !== undefined) {
section.emit_u8(kExprRefFunc);
section.emit_u32v(global.function_index);
} else {
section.emit_u8(kExprRefNull); section.emit_u8(kExprRefNull);
section.emit_u8(kWasmAnyFunc); section.emit_u8(kWasmExternRef);
} assertEquals(global.function_index, undefined);
break; break;
default: case kWasmAnyFunc:
if (global.function_index !== undefined) { if (global.function_index !== undefined) {
section.emit_u8(kExprRefFunc); section.emit_u8(kExprRefFunc);
section.emit_u32v(global.function_index); section.emit_u32v(global.function_index);
} else { } else {
section.emit_u8(kExprRefNull); section.emit_u8(kExprRefNull);
section.emit_u32v(global.type.index); section.emit_u8(kWasmAnyFunc);
} }
break; break;
default:
if (global.function_index !== undefined) {
section.emit_u8(kExprRefFunc);
section.emit_u32v(global.function_index);
} else {
section.emit_u8(kExprRefNull);
section.emit_u32v(global.type.index);
}
break;
} }
} else { } else {
// Emit a global-index initializer. // Emit a global-index initializer.
@ -1483,7 +1520,7 @@ class WasmModuleBuilder {
var mem_export = (wasm.memory !== undefined && wasm.memory.exported); var mem_export = (wasm.memory !== undefined && wasm.memory.exported);
var exports_count = wasm.exports.length + (mem_export ? 1 : 0); var exports_count = wasm.exports.length + (mem_export ? 1 : 0);
if (exports_count > 0) { if (exports_count > 0) {
if (debug) print("emitting exports @ " + binary.length); if (debug) print('emitting exports @ ' + binary.length);
binary.emit_section(kExportSectionCode, section => { binary.emit_section(kExportSectionCode, section => {
section.emit_u32v(exports_count); section.emit_u32v(exports_count);
for (let exp of wasm.exports) { for (let exp of wasm.exports) {
@ -1492,7 +1529,7 @@ class WasmModuleBuilder {
section.emit_u32v(exp.index); section.emit_u32v(exp.index);
} }
if (mem_export) { if (mem_export) {
section.emit_string("memory"); section.emit_string('memory');
section.emit_u8(kExternalMemory); section.emit_u8(kExternalMemory);
section.emit_u8(0); section.emit_u8(0);
} }
@ -1501,7 +1538,7 @@ class WasmModuleBuilder {
// Add start function section. // Add start function section.
if (wasm.start_index !== undefined) { if (wasm.start_index !== undefined) {
if (debug) print("emitting start function @ " + binary.length); if (debug) print('emitting start function @ ' + binary.length);
binary.emit_section(kStartSectionCode, section => { binary.emit_section(kStartSectionCode, section => {
section.emit_u32v(wasm.start_index); section.emit_u32v(wasm.start_index);
}); });
@ -1509,7 +1546,7 @@ class WasmModuleBuilder {
// Add element segments // Add element segments
if (wasm.element_segments.length > 0) { if (wasm.element_segments.length > 0) {
if (debug) print("emitting element segments @ " + binary.length); if (debug) print('emitting element segments @ ' + binary.length);
binary.emit_section(kElementSectionCode, section => { binary.emit_section(kElementSectionCode, section => {
var inits = wasm.element_segments; var inits = wasm.element_segments;
section.emit_u32v(inits.length); section.emit_u32v(inits.length);
@ -1579,7 +1616,7 @@ class WasmModuleBuilder {
// If there are compilation hints add a custom section 'compilationHints' // If there are compilation hints add a custom section 'compilationHints'
// after the function section and before the code section. // after the function section and before the code section.
if (wasm.compilation_hints.length > 0) { if (wasm.compilation_hints.length > 0) {
if (debug) print("emitting compilation hints @ " + binary.length); if (debug) print('emitting compilation hints @ ' + binary.length);
// Build custom section payload. // Build custom section payload.
let payloadBinary = new Binary(); let payloadBinary = new Binary();
let implicit_compilation_hints_count = wasm.functions.length; let implicit_compilation_hints_count = wasm.functions.length;
@ -1594,18 +1631,18 @@ class WasmModuleBuilder {
for (let i = 0; i < implicit_compilation_hints_count; i++) { for (let i = 0; i < implicit_compilation_hints_count; i++) {
let index = wasm.num_imported_funcs + i; let index = wasm.num_imported_funcs + i;
var hintByte; var hintByte;
if(index in wasm.compilation_hints) { if (index in wasm.compilation_hints) {
let hint = wasm.compilation_hints[index]; let hint = wasm.compilation_hints[index];
hintByte = hint.strategy | (hint.baselineTier << 2) | hintByte =
(hint.topTier << 4); hint.strategy | (hint.baselineTier << 2) | (hint.topTier << 4);
} else{ } else {
hintByte = defaultHintByte; hintByte = defaultHintByte;
} }
payloadBinary.emit_u8(hintByte); payloadBinary.emit_u8(hintByte);
} }
// Finalize as custom section. // Finalize as custom section.
let name = "compilationHints"; let name = 'compilationHints';
let bytes = this.createCustomSection(name, payloadBinary.trunc_buffer()); let bytes = this.createCustomSection(name, payloadBinary.trunc_buffer());
binary.emit_bytes(bytes); binary.emit_bytes(bytes);
} }
@ -1613,7 +1650,7 @@ class WasmModuleBuilder {
// Add function bodies. // Add function bodies.
if (wasm.functions.length > 0) { if (wasm.functions.length > 0) {
// emit function bodies // emit function bodies
if (debug) print("emitting code @ " + binary.length); if (debug) print('emitting code @ ' + binary.length);
let section_length = 0; let section_length = 0;
binary.emit_section(kCodeSectionCode, section => { binary.emit_section(kCodeSectionCode, section => {
section.emit_u32v(wasm.functions.length); section.emit_u32v(wasm.functions.length);
@ -1642,7 +1679,7 @@ class WasmModuleBuilder {
// Add data segments. // Add data segments.
if (wasm.data_segments.length > 0) { if (wasm.data_segments.length > 0) {
if (debug) print("emitting data segments @ " + binary.length); if (debug) print('emitting data segments @ ' + binary.length);
binary.emit_section(kDataSectionCode, section => { binary.emit_section(kDataSectionCode, section => {
section.emit_u32v(wasm.data_segments.length); section.emit_u32v(wasm.data_segments.length);
for (let seg of wasm.data_segments) { for (let seg of wasm.data_segments) {
@ -1669,7 +1706,7 @@ class WasmModuleBuilder {
// Add any explicitly added sections // Add any explicitly added sections
for (let exp of wasm.explicit) { for (let exp of wasm.explicit) {
if (debug) print("emitting explicit @ " + binary.length); if (debug) print('emitting explicit @ ' + binary.length);
binary.emit_bytes(exp); binary.emit_bytes(exp);
} }
@ -1712,7 +1749,7 @@ class WasmModuleBuilder {
name_section.emit_u32v(func.numLocalNames()); name_section.emit_u32v(func.numLocalNames());
let name_index = 0; let name_index = 0;
for (let i = 0; i < func.local_names.length; ++i) { for (let i = 0; i < func.local_names.length; ++i) {
if (typeof func.local_names[i] == "string") { if (typeof func.local_names[i] == 'string') {
name_section.emit_u32v(name_index); name_section.emit_u32v(name_index);
name_section.emit_string(func.local_names[i]); name_section.emit_string(func.local_names[i]);
name_index++; name_index++;
@ -1781,8 +1818,8 @@ function wasmF64Const(f) {
// Write in little-endian order at offset 0. // Write in little-endian order at offset 0.
data_view.setFloat64(0, f, true); data_view.setFloat64(0, f, true);
return [ return [
kExprF64Const, byte_view[0], byte_view[1], byte_view[2], kExprF64Const, byte_view[0], byte_view[1], byte_view[2], byte_view[3],
byte_view[3], byte_view[4], byte_view[5], byte_view[6], byte_view[7] byte_view[4], byte_view[5], byte_view[6], byte_view[7]
]; ];
} }