blob: c2b86c03fad4ea738aef6fae7ff10bd8e98d6865 [file] [log] [blame]
// Copyright 2017 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Flags: --wasm-test-streaming --wasm-async-compilation --expose-wasm --allow-natives-syntax
'use strict';
load('test/mjsunit/wasm/wasm-constants.js');
load('test/mjsunit/wasm/wasm-module-builder.js');
function module(bytes) {
let buffer = bytes;
if (typeof buffer === 'string') {
buffer = new ArrayBuffer(bytes.length);
let view = new Uint8Array(buffer);
for (let i = 0; i < bytes.length; ++i) {
view[i] = bytes.charCodeAt(i);
}
}
return new WebAssembly.Module(buffer);
}
function toBuffer(binary) {
let buffer = new ArrayBuffer(binary.length);
let view = new Uint8Array(buffer);
for (let i = 0; i < binary.length; i++) {
let val = binary[i];
if ((typeof val) == 'string') val = val.charCodeAt(0);
view[i] = val | 0;
}
return buffer;
}
function testErrorPosition(bytes, pos, test_name) {
assertPromiseResult(
WebAssembly.compile(toBuffer(bytes)), assertUnreachable, e => {
print(test_name);
assertInstanceof(e, WebAssembly.CompileError);
let regex = new RegExp('@\\+' + pos);
print(e.message);
assertMatches(regex, e.message, 'Error Position');
});
}
(function testInvalidMagic() {
let bytes = new Binary;
bytes.push(
kWasmH0, kWasmH1 + 1, kWasmH2, kWasmH3, kWasmV0, kWasmV1, kWasmV2,
kWasmV3);
// Error at pos==0 because that's where the magic word is.
testErrorPosition(bytes, 0, 'testInvalidMagic');
})();
(function testInvalidVersion() {
let bytes = new Binary;
bytes.push(
kWasmH0, kWasmH1, kWasmH2, kWasmH3, kWasmV0, kWasmV1 + 1, kWasmV2,
kWasmV3);
// Error at pos==4 because that's where the version word is.
testErrorPosition(bytes, 4, 'testInvalidVersion');
})();
(function testSectionLengthInvalidVarint() {
let bytes = new Binary;
bytes.emit_header();
bytes.emit_u8(kTypeSectionCode);
bytes.push(0x80, 0x80, 0x80, 0x80, 0x80, 0x00);
let pos = bytes.length - 1 - 1;
testErrorPosition(bytes, pos, 'testSectionLengthInvalidVarint');
})();
(function testSectionLengthTooBig() {
let bytes = new Binary;
bytes.emit_header();
bytes.emit_u8(kTypeSectionCode);
bytes.emit_u32v(0xffffff23);
let pos = bytes.length - 1;
testErrorPosition(bytes, pos, 'testSectionLengthTooBig');
})();
(function testFunctionsCountInvalidVarint() {
let bytes = new Binary;
bytes.emit_header();
bytes.push(
kTypeSectionCode, // section id
1, // section length
0 // number of types
);
bytes.push(
kFunctionSectionCode, // section id
1, // section length
0 // number of functions
);
bytes.push(
kCodeSectionCode, // section id
20, // section length (arbitrary value > 6)
);
// Functions count
bytes.push(0x80, 0x80, 0x80, 0x80, 0x80, 0x00);
let pos = bytes.length - 1 - 1;
testErrorPosition(bytes, pos, 'testFunctionsCountInvalidVarint');
})();
(function testFunctionsCountTooBig() {
let bytes = new Binary;
bytes.emit_header();
bytes.push(
kTypeSectionCode, // section id
1, // section length
0 // number of types
);
bytes.push(
kFunctionSectionCode, // section id
1, // section length
0 // number of functions
);
bytes.push(
kCodeSectionCode, // section id
20, // section length (arbitrary value > 6)
);
// Functions count
bytes.emit_u32v(0xffffff23);
let pos = bytes.length - 1;
testErrorPosition(bytes, pos, 'testFunctionsCountTooBig');
})();
(function testFunctionsCountDoesNotMatch() {
let bytes = new Binary;
bytes.emit_header();
bytes.push(
kTypeSectionCode, // section id
1, // section length
0 // number of types
);
bytes.push(
kFunctionSectionCode, // section id
1, // section length
0 // number of functions
);
bytes.push(
kCodeSectionCode, // section id
20, // section length (arbitrary value > 6)
);
// Functions count (different than the count in the functions section.
bytes.emit_u32v(5);
let pos = bytes.length - 1;
testErrorPosition(bytes, pos, 'testFunctionsCountDoesNotMatch');
})();
(function testBodySizeInvalidVarint() {
let bytes = new Binary;
bytes.emit_header();
bytes.push(
kTypeSectionCode, // section id
4, // section length
1, // number of types
kWasmFunctionTypeForm, // type
0, // number of parameter
0 // number of returns
);
bytes.push(
kFunctionSectionCode, // section id
2, // section length
1, // number of functions
0 // signature index
);
bytes.push(
kCodeSectionCode, // section id
20, // section length (arbitrary value > 6)
1 // functions count
);
// Invalid function body size.
bytes.push(0x80, 0x80, 0x80, 0x80, 0x80, 0x00);
let pos = bytes.length - 1 - 1;
testErrorPosition(bytes, pos, 'testBodySizeInvalidVarint');
})();
(function testBodySizeTooBig() {
let bytes = new Binary;
bytes.emit_header();
bytes.push(
kTypeSectionCode, // section id
4, // section length
1, // number of types
kWasmFunctionTypeForm, // type
0, // number of parameter
0 // number of returns
);
bytes.push(
kFunctionSectionCode, // section id
2, // section length
1, // number of functions
0 // signature index
);
bytes.push(
kCodeSectionCode, // section id
20, // section length (arbitrary value > 6)
1 // functions count
);
// Invalid function body size.
bytes.emit_u32v(0xffffff23);
let pos = bytes.length - 1;
testErrorPosition(bytes, pos, 'testBodySizeTooBig');
})();
(function testBodySizeDoesNotFit() {
let bytes = new Binary;
bytes.emit_header();
bytes.push(
kTypeSectionCode, // section id
4, // section length
1, // number of types
kWasmFunctionTypeForm, // type
0, // number of parameter
0 // number of returns
);
bytes.push(
kFunctionSectionCode, // section id
2, // section length
1, // number of functions
0 // signature index
);
bytes.push(
kCodeSectionCode, // section id
20, // section length (arbitrary value > 6)
1 // functions count
);
// Invalid function body size (does not fit into the code section).
bytes.emit_u32v(20);
let pos = bytes.length - 1;
testErrorPosition(bytes, pos, 'testBodySizeDoesNotFit');
})();
(function testBodySizeIsZero() {
let bytes = new Binary;
bytes.emit_header();
bytes.push(
kTypeSectionCode, // section id
4, // section length
1, // number of types
kWasmFunctionTypeForm, // type
0, // number of parameter
0 // number of returns
);
bytes.push(
kFunctionSectionCode, // section id
2, // section length
1, // number of functions
0 // signature index
);
bytes.push(
kCodeSectionCode, // section id
20, // section length (arbitrary value > 6)
1 // functions count
);
// Invalid function body size (body size of 0 is invalid).
bytes.emit_u32v(0);
let pos = bytes.length - 1;
testErrorPosition(bytes, pos, 'testBodySizeIsZero');
})();
(function testStaleCodeSectionBytes() {
let bytes = new Binary;
bytes.emit_header();
bytes.push(
kTypeSectionCode, // section id
4, // section length
1, // number of types
kWasmFunctionTypeForm, // type
0, // number of parameter
0 // number of returns
);
bytes.push(
kFunctionSectionCode, // section id
2, // section length
1, // number of functions
0 // signature index
);
bytes.push(
kCodeSectionCode, // section id
20, // section length (too big)
1, // functions count
2, // body size
0, // locals count
kExprEnd // body
);
let pos = bytes.length - 1;
testErrorPosition(bytes, pos, 'testStaleCodeSectionBytes');
})();
(function testInvalidCode() {
let bytes = new Binary;
bytes.emit_header();
bytes.push(
kTypeSectionCode, // section id
4, // section length
1, // number of types
kWasmFunctionTypeForm, // type
0, // number of parameter
0 // number of returns
);
bytes.push(
kFunctionSectionCode, // section id
2, // section length
1, // number of functions
0 // signature index
);
bytes.push(
kCodeSectionCode, // section id
6, // section length (too big)
1, // functions count
4, // body size
0, // locals count
kExprGetLocal, 0, // Access a non-existing local
kExprEnd // --
);
// Find error at the index of kExprGetLocal.
let pos = bytes.length - 1 - 1;
testErrorPosition(bytes, pos, 'testInvalidCode');
})();
(function testCodeSectionSizeZero() {
let bytes = new Binary;
bytes.emit_header();
bytes.push(
kTypeSectionCode, // section id
4, // section length
1, // number of types
kWasmFunctionTypeForm, // type
0, // number of parameter
0 // number of returns
);
bytes.push(
kFunctionSectionCode, // section id
2, // section length
1, // number of functions
0 // signature index
);
bytes.push(
kCodeSectionCode, // section id
0, // section length (too big)
);
// Find error at the index of kExprGetLocal.
let pos = bytes.length - 1;
testErrorPosition(bytes, pos, 'testCodeSectionSizeZero');
})();
(function testInvalidSection() {
let bytes = new Binary;
bytes.emit_header();
bytes.push(
kTypeSectionCode, // section id
5, // section length
1, // number of types
kWasmFunctionTypeForm, // type
1, // number of parameter
0x7b, // invalid type
0 // number of returns
);
let pos = bytes.length - 1 - 1;
testErrorPosition(bytes, pos, 'testInvalidSection');
})();