diff options
Diffstat (limited to 'deps/v8/test/mjsunit/wasm')
19 files changed, 1142 insertions, 507 deletions
diff --git a/deps/v8/test/mjsunit/wasm/asm-wasm-imports.js b/deps/v8/test/mjsunit/wasm/asm-wasm-imports.js new file mode 100644 index 0000000000..bfcb25b825 --- /dev/null +++ b/deps/v8/test/mjsunit/wasm/asm-wasm-imports.js @@ -0,0 +1,181 @@ +// Copyright 2018 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: --validate-asm --allow-natives-syntax + +var stdlib = this; + +function assertValidAsm(func) { + assertTrue(%IsAsmWasmCode(func), "must be valid asm code"); +} + +function assertWasm(expected, func, ffi) { + print("Testing " + func.name + "..."); + assertEquals( + expected, func(stdlib, ffi, new ArrayBuffer(1024)).caller()); + assertValidAsm(func); +} + + +function TestForeignFunctions() { + function AsmModule(stdlib, foreign, buffer) { + "use asm"; + + var setVal = foreign.setVal; + var getVal = foreign.getVal; + + function caller(initial_value, new_value) { + initial_value = initial_value|0; + new_value = new_value|0; + if ((getVal()|0) == (initial_value|0)) { + setVal(new_value|0); + return getVal()|0; + } + return 0; + } + + return {caller:caller}; + } + + function ffi(initial_val) { + var val = initial_val; + + function getVal() { + return val; + } + + function setVal(new_val) { + val = new_val; + } + + return {getVal:getVal, setVal:setVal}; + } + + var foreign = new ffi(23); + + var module = AsmModule({Math: Math}, foreign, null); + assertValidAsm(AsmModule); + + assertEquals(103, module.caller(23, 103)); +} + +print("TestForeignFunctions..."); +TestForeignFunctions(); + + +function TestForeignFunctionMultipleUse() { + function AsmModule(stdlib, foreign, buffer) { + "use asm"; + + var getVal = foreign.getVal; + + function caller(int_val, double_val) { + int_val = int_val|0; + double_val = +double_val; + if ((getVal()|0) == (int_val|0)) { + if ((+getVal()) == (+double_val)) { + return 89; + } + } + return 0; + } + + return {caller:caller}; + } + + function ffi() { + function getVal() { + return 83.25; + } + + return {getVal:getVal}; + } + + var foreign = new ffi(); + + var module_decl = eval('(' + AsmModule.toString() + ')'); + var module = module_decl(stdlib, foreign, null); + assertValidAsm(module_decl); + + assertEquals(89, module.caller(83, 83.25)); +} + +print("TestForeignFunctionMultipleUse..."); +TestForeignFunctionMultipleUse(); + +function TestForeignVariables() { + function AsmModule(stdlib, foreign, buffer) { + "use asm"; + + var i1 = foreign.foo | 0; + var f1 = +foreign.bar; + var i2 = foreign.baz | 0; + var f2 = +foreign.baz; + + function geti1() { + return i1|0; + } + + function getf1() { + return +f1; + } + + function geti2() { + return i2|0; + } + + function getf2() { + return +f2; + } + + return {geti1:geti1, getf1:getf1, geti2:geti2, getf2:getf2}; + } + + function TestCase(env, i1, f1, i2, f2) { + print("Testing foreign variables..."); + var module_decl = eval('(' + AsmModule.toString() + ')'); + var module = module_decl(stdlib, env); + assertValidAsm(module_decl); + assertEquals(i1, module.geti1()); + assertEquals(f1, module.getf1()); + assertEquals(i2, module.geti2()); + assertEquals(f2, module.getf2()); + } + + // Check normal operation. + TestCase({foo: 123, bar: 234.5, baz: 345.7}, 123, 234.5, 345, 345.7); + // Check partial operation. + TestCase({baz: 345.7}, 0, NaN, 345, 345.7); + // Check that undefined values are converted to proper defaults. + TestCase({qux: 999}, 0, NaN, 0, NaN); + // Check that true values are converted properly. + TestCase({foo: true, bar: true, baz: true}, 1, 1.0, 1, 1.0); + // Check that false values are converted properly. + TestCase({foo: false, bar: false, baz: false}, 0, 0, 0, 0); + // Check that null values are converted properly. + TestCase({foo: null, bar: null, baz: null}, 0, 0, 0, 0); + // Check that string values are converted properly. + TestCase({foo: 'hi', bar: 'there', baz: 'dude'}, 0, NaN, 0, NaN); + TestCase({foo: '0xff', bar: '234', baz: '456.1'}, 255, 234, 456, 456.1); + // Check that function values are converted properly. + TestCase({foo: TestCase, bar: TestCase, qux: TestCase}, 0, NaN, 0, NaN); +} + +print("TestForeignVariables..."); +TestForeignVariables(); + + +function TestGlobalBlock(stdlib, foreign, buffer) { + "use asm"; + + var x = foreign.x | 0, y = foreign.y | 0; + + function test() { + return (x + y) | 0; + } + + return {caller: test}; +} + +assertWasm(15, TestGlobalBlock, { x: 4, y: 11 }); diff --git a/deps/v8/test/mjsunit/wasm/asm-wasm-memory.js b/deps/v8/test/mjsunit/wasm/asm-wasm-memory.js new file mode 100644 index 0000000000..9c2ff77998 --- /dev/null +++ b/deps/v8/test/mjsunit/wasm/asm-wasm-memory.js @@ -0,0 +1,212 @@ +// Copyright 2018 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: --validate-asm --allow-natives-syntax + +var stdlib = this; +let kMinHeapSize = 4096; + +function assertValidAsm(func) { + assertTrue(%IsAsmWasmCode(func), "must be valid asm code"); +} + +function assertWasm(expected, func, ffi) { + print("Testing " + func.name + "..."); + assertEquals( + expected, func(stdlib, ffi, new ArrayBuffer(kMinHeapSize)).caller()); + assertValidAsm(func); +} + + +function TestInt32HeapAccess(stdlib, foreign, buffer) { + "use asm"; + + var m = new stdlib.Int32Array(buffer); + function caller() { + var i = 4; + + m[0] = (i + 1) | 0; + m[i >> 2] = ((m[0]|0) + 1) | 0; + m[2] = ((m[i >> 2]|0) + 1) | 0; + return m[2] | 0; + } + + return {caller: caller}; +} + +assertWasm(7, TestInt32HeapAccess); + + +function TestInt32HeapAccessExternal() { + var memory = new ArrayBuffer(kMinHeapSize); + var memory_int32 = new Int32Array(memory); + var module_decl = eval('(' + TestInt32HeapAccess.toString() + ')'); + var module = module_decl(stdlib, null, memory); + assertValidAsm(module_decl); + assertEquals(7, module.caller()); + assertEquals(7, memory_int32[2]); +} + +TestInt32HeapAccessExternal(); + + +function TestHeapAccessIntTypes() { + var types = [ + [Int8Array, 'Int8Array', '>> 0'], + [Uint8Array, 'Uint8Array', '>> 0'], + [Int16Array, 'Int16Array', '>> 1'], + [Uint16Array, 'Uint16Array', '>> 1'], + [Int32Array, 'Int32Array', '>> 2'], + [Uint32Array, 'Uint32Array', '>> 2'], + ]; + for (var i = 0; i < types.length; i++) { + var code = TestInt32HeapAccess.toString(); + code = code.replace('Int32Array', types[i][1]); + code = code.replace(/>> 2/g, types[i][2]); + var memory = new ArrayBuffer(kMinHeapSize); + var memory_view = new types[i][0](memory); + var module_decl = eval('(' + code + ')'); + var module = module_decl(stdlib, null, memory); + assertValidAsm(module_decl); + assertEquals(7, module.caller()); + assertEquals(7, memory_view[2]); + assertValidAsm(module_decl); + } +} + +TestHeapAccessIntTypes(); + + +function TestFloatHeapAccess(stdlib, foreign, buffer) { + "use asm"; + + var f32 = new stdlib.Float32Array(buffer); + var f64 = new stdlib.Float64Array(buffer); + var fround = stdlib.Math.fround; + function caller() { + var i = 8; + var j = 8; + var v = 6.0; + + f64[2] = v + 1.0; + f64[i >> 3] = +f64[2] + 1.0; + f64[j >> 3] = +f64[j >> 3] + 1.0; + i = +f64[i >> 3] == 9.0; + return i|0; + } + + return {caller: caller}; +} + +assertWasm(1, TestFloatHeapAccess); + + +function TestFloatHeapAccessExternal() { + var memory = new ArrayBuffer(kMinHeapSize); + var memory_float64 = new Float64Array(memory); + var module_decl = eval('(' + TestFloatHeapAccess.toString() + ')'); + var module = module_decl(stdlib, null, memory); + assertValidAsm(module_decl); + assertEquals(1, module.caller()); + assertEquals(9.0, memory_float64[1]); +} + +TestFloatHeapAccessExternal(); + + +(function() { + function TestByteHeapAccessCompat(stdlib, foreign, buffer) { + "use asm"; + + var HEAP8 = new stdlib.Uint8Array(buffer); + var HEAP32 = new stdlib.Int32Array(buffer); + + function store(i, v) { + i = i | 0; + v = v | 0; + HEAP32[i >> 2] = v; + } + + function storeb(i, v) { + i = i | 0; + v = v | 0; + HEAP8[i | 0] = v; + } + + function load(i) { + i = i | 0; + return HEAP8[i] | 0; + } + + function iload(i) { + i = i | 0; + return HEAP8[HEAP32[i >> 2] | 0] | 0; + } + + return {load: load, iload: iload, store: store, storeb: storeb}; + } + + var memory = new ArrayBuffer(kMinHeapSize); + var module_decl = eval('(' + TestByteHeapAccessCompat.toString() + ')'); + var m = module_decl(stdlib, null, memory); + assertValidAsm(module_decl); + m.store(0, 20); + m.store(4, 21); + m.store(8, 22); + m.storeb(20, 123); + m.storeb(21, 42); + m.storeb(22, 77); + assertEquals(123, m.load(20)); + assertEquals(42, m.load(21)); + assertEquals(77, m.load(22)); + assertEquals(123, m.iload(0)); + assertEquals(42, m.iload(4)); + assertEquals(77, m.iload(8)); +})(); + + +function TestIntishAssignment(stdlib, foreign, heap) { + "use asm"; + var HEAP32 = new stdlib.Int32Array(heap); + function func() { + var a = 1; + var b = 2; + HEAP32[0] = a + b; + return HEAP32[0] | 0; + } + return {caller: func}; +} + +assertWasm(3, TestIntishAssignment); + + +function TestFloatishAssignment(stdlib, foreign, heap) { + "use asm"; + var HEAPF32 = new stdlib.Float32Array(heap); + var fround = stdlib.Math.fround; + function func() { + var a = fround(1.0); + var b = fround(2.0); + HEAPF32[0] = a + b; + return +HEAPF32[0]; + } + return {caller: func}; +} + +assertWasm(3, TestFloatishAssignment); + + +function TestDoubleToFloatAssignment(stdlib, foreign, heap) { + "use asm"; + var HEAPF32 = new stdlib.Float32Array(heap); + var fround = stdlib.Math.fround; + function func() { + var a = 1.23; + HEAPF32[0] = a; + return +HEAPF32[0]; + } + return {caller: func}; +} + +assertWasm(Math.fround(1.23), TestDoubleToFloatAssignment); diff --git a/deps/v8/test/mjsunit/wasm/asm-wasm.js b/deps/v8/test/mjsunit/wasm/asm-wasm.js index 71c6b10490..97219f113b 100644 --- a/deps/v8/test/mjsunit/wasm/asm-wasm.js +++ b/deps/v8/test/mjsunit/wasm/asm-wasm.js @@ -5,6 +5,7 @@ // Flags: --validate-asm --allow-natives-syntax var stdlib = this; +let kMinHeapSize = 4096; function assertValidAsm(func) { assertTrue(%IsAsmWasmCode(func), "must be valid asm code"); @@ -13,7 +14,7 @@ function assertValidAsm(func) { function assertWasm(expected, func, ffi) { print("Testing " + func.name + "..."); assertEquals( - expected, func(stdlib, ffi, new ArrayBuffer(1024)).caller()); + expected, func(stdlib, ffi, new ArrayBuffer(kMinHeapSize)).caller()); assertValidAsm(func); } @@ -514,100 +515,6 @@ function TestMixedAdd() { assertWasm(23, TestMixedAdd); -function TestInt32HeapAccess(stdlib, foreign, buffer) { - "use asm"; - - var m = new stdlib.Int32Array(buffer); - function caller() { - var i = 4; - - m[0] = (i + 1) | 0; - m[i >> 2] = ((m[0]|0) + 1) | 0; - m[2] = ((m[i >> 2]|0) + 1) | 0; - return m[2] | 0; - } - - return {caller: caller}; -} - -assertWasm(7, TestInt32HeapAccess); - - -function TestInt32HeapAccessExternal() { - var memory = new ArrayBuffer(1024); - var memory_int32 = new Int32Array(memory); - var module_decl = eval('(' + TestInt32HeapAccess.toString() + ')'); - var module = module_decl(stdlib, null, memory); - assertValidAsm(module_decl); - assertEquals(7, module.caller()); - assertEquals(7, memory_int32[2]); -} - -TestInt32HeapAccessExternal(); - - -function TestHeapAccessIntTypes() { - var types = [ - [Int8Array, 'Int8Array', '>> 0'], - [Uint8Array, 'Uint8Array', '>> 0'], - [Int16Array, 'Int16Array', '>> 1'], - [Uint16Array, 'Uint16Array', '>> 1'], - [Int32Array, 'Int32Array', '>> 2'], - [Uint32Array, 'Uint32Array', '>> 2'], - ]; - for (var i = 0; i < types.length; i++) { - var code = TestInt32HeapAccess.toString(); - code = code.replace('Int32Array', types[i][1]); - code = code.replace(/>> 2/g, types[i][2]); - var memory = new ArrayBuffer(1024); - var memory_view = new types[i][0](memory); - var module_decl = eval('(' + code + ')'); - var module = module_decl(stdlib, null, memory); - assertValidAsm(module_decl); - assertEquals(7, module.caller()); - assertEquals(7, memory_view[2]); - assertValidAsm(module_decl); - } -} - -TestHeapAccessIntTypes(); - - -function TestFloatHeapAccess(stdlib, foreign, buffer) { - "use asm"; - - var f32 = new stdlib.Float32Array(buffer); - var f64 = new stdlib.Float64Array(buffer); - var fround = stdlib.Math.fround; - function caller() { - var i = 8; - var j = 8; - var v = 6.0; - - f64[2] = v + 1.0; - f64[i >> 3] = +f64[2] + 1.0; - f64[j >> 3] = +f64[j >> 3] + 1.0; - i = +f64[i >> 3] == 9.0; - return i|0; - } - - return {caller: caller}; -} - -assertWasm(1, TestFloatHeapAccess); - - -function TestFloatHeapAccessExternal() { - var memory = new ArrayBuffer(1024); - var memory_float64 = new Float64Array(memory); - var module_decl = eval('(' + TestFloatHeapAccess.toString() + ')'); - var module = module_decl(stdlib, null, memory); - assertValidAsm(module_decl); - assertEquals(1, module.caller()); - assertEquals(9.0, memory_float64[1]); -} - -TestFloatHeapAccessExternal(); function TestConvertI32() { @@ -1031,219 +938,6 @@ assertEquals(31, module.caller(1, 0, 30, 11)); })(); -function TestForeignFunctions() { - function AsmModule(stdlib, foreign, buffer) { - "use asm"; - - var setVal = foreign.setVal; - var getVal = foreign.getVal; - - function caller(initial_value, new_value) { - initial_value = initial_value|0; - new_value = new_value|0; - if ((getVal()|0) == (initial_value|0)) { - setVal(new_value|0); - return getVal()|0; - } - return 0; - } - - return {caller:caller}; - } - - function ffi(initial_val) { - var val = initial_val; - - function getVal() { - return val; - } - - function setVal(new_val) { - val = new_val; - } - - return {getVal:getVal, setVal:setVal}; - } - - var foreign = new ffi(23); - - var module = AsmModule({Math: Math}, foreign, null); - assertValidAsm(AsmModule); - - assertEquals(103, module.caller(23, 103)); -} - -print("TestForeignFunctions..."); -TestForeignFunctions(); - - -function TestForeignFunctionMultipleUse() { - function AsmModule(stdlib, foreign, buffer) { - "use asm"; - - var getVal = foreign.getVal; - - function caller(int_val, double_val) { - int_val = int_val|0; - double_val = +double_val; - if ((getVal()|0) == (int_val|0)) { - if ((+getVal()) == (+double_val)) { - return 89; - } - } - return 0; - } - - return {caller:caller}; - } - - function ffi() { - function getVal() { - return 83.25; - } - - return {getVal:getVal}; - } - - var foreign = new ffi(); - - var module_decl = eval('(' + AsmModule.toString() + ')'); - var module = module_decl(stdlib, foreign, null); - assertValidAsm(module_decl); - - assertEquals(89, module.caller(83, 83.25)); -} - -print("TestForeignFunctionMultipleUse..."); -TestForeignFunctionMultipleUse(); - -function TestForeignVariables() { - function AsmModule(stdlib, foreign, buffer) { - "use asm"; - - var i1 = foreign.foo | 0; - var f1 = +foreign.bar; - var i2 = foreign.baz | 0; - var f2 = +foreign.baz; - - function geti1() { - return i1|0; - } - - function getf1() { - return +f1; - } - - function geti2() { - return i2|0; - } - - function getf2() { - return +f2; - } - - return {geti1:geti1, getf1:getf1, geti2:geti2, getf2:getf2}; - } - - function TestCase(env, i1, f1, i2, f2) { - print("Testing foreign variables..."); - var module_decl = eval('(' + AsmModule.toString() + ')'); - var module = module_decl(stdlib, env); - assertValidAsm(module_decl); - assertEquals(i1, module.geti1()); - assertEquals(f1, module.getf1()); - assertEquals(i2, module.geti2()); - assertEquals(f2, module.getf2()); - } - - // Check normal operation. - TestCase({foo: 123, bar: 234.5, baz: 345.7}, 123, 234.5, 345, 345.7); - // Check partial operation. - TestCase({baz: 345.7}, 0, NaN, 345, 345.7); - // Check that undefined values are converted to proper defaults. - TestCase({qux: 999}, 0, NaN, 0, NaN); - // Check that true values are converted properly. - TestCase({foo: true, bar: true, baz: true}, 1, 1.0, 1, 1.0); - // Check that false values are converted properly. - TestCase({foo: false, bar: false, baz: false}, 0, 0, 0, 0); - // Check that null values are converted properly. - TestCase({foo: null, bar: null, baz: null}, 0, 0, 0, 0); - // Check that string values are converted properly. - TestCase({foo: 'hi', bar: 'there', baz: 'dude'}, 0, NaN, 0, NaN); - TestCase({foo: '0xff', bar: '234', baz: '456.1'}, 255, 234, 456, 456.1); - // Check that function values are converted properly. - TestCase({foo: TestCase, bar: TestCase, qux: TestCase}, 0, NaN, 0, NaN); -} - -print("TestForeignVariables..."); -TestForeignVariables(); - - -(function() { - function TestByteHeapAccessCompat(stdlib, foreign, buffer) { - "use asm"; - - var HEAP8 = new stdlib.Uint8Array(buffer); - var HEAP32 = new stdlib.Int32Array(buffer); - - function store(i, v) { - i = i | 0; - v = v | 0; - HEAP32[i >> 2] = v; - } - - function storeb(i, v) { - i = i | 0; - v = v | 0; - HEAP8[i | 0] = v; - } - - function load(i) { - i = i | 0; - return HEAP8[i] | 0; - } - - function iload(i) { - i = i | 0; - return HEAP8[HEAP32[i >> 2] | 0] | 0; - } - - return {load: load, iload: iload, store: store, storeb: storeb}; - } - - var memory = new ArrayBuffer(1024); - var module_decl = eval('(' + TestByteHeapAccessCompat.toString() + ')'); - var m = module_decl(stdlib, null, memory); - assertValidAsm(module_decl); - m.store(0, 20); - m.store(4, 21); - m.store(8, 22); - m.storeb(20, 123); - m.storeb(21, 42); - m.storeb(22, 77); - assertEquals(123, m.load(20)); - assertEquals(42, m.load(21)); - assertEquals(77, m.load(22)); - assertEquals(123, m.iload(0)); - assertEquals(42, m.iload(4)); - assertEquals(77, m.iload(8)); -})(); - - -function TestGlobalBlock(stdlib, foreign, buffer) { - "use asm"; - - var x = foreign.x | 0, y = foreign.y | 0; - - function test() { - return (x + y) | 0; - } - - return {caller: test}; -} - -assertWasm(15, TestGlobalBlock, { x: 4, y: 11 }); - (function TestComma() { function CommaModule() { "use asm"; @@ -1322,52 +1016,6 @@ function TestXor() { assertWasm(1, TestXor); -function TestIntishAssignment(stdlib, foreign, heap) { - "use asm"; - var HEAP32 = new stdlib.Int32Array(heap); - function func() { - var a = 1; - var b = 2; - HEAP32[0] = a + b; - return HEAP32[0] | 0; - } - return {caller: func}; -} - -assertWasm(3, TestIntishAssignment); - - -function TestFloatishAssignment(stdlib, foreign, heap) { - "use asm"; - var HEAPF32 = new stdlib.Float32Array(heap); - var fround = stdlib.Math.fround; - function func() { - var a = fround(1.0); - var b = fround(2.0); - HEAPF32[0] = a + b; - return +HEAPF32[0]; - } - return {caller: func}; -} - -assertWasm(3, TestFloatishAssignment); - - -function TestDoubleToFloatAssignment(stdlib, foreign, heap) { - "use asm"; - var HEAPF32 = new stdlib.Float32Array(heap); - var fround = stdlib.Math.fround; - function func() { - var a = 1.23; - HEAPF32[0] = a; - return +HEAPF32[0]; - } - return {caller: func}; -} - -assertWasm(Math.fround(1.23), TestDoubleToFloatAssignment); - - function TestIntegerMultiplyBothWays(stdlib, foreign, heap) { "use asm"; function func() { diff --git a/deps/v8/test/mjsunit/wasm/atomics.js b/deps/v8/test/mjsunit/wasm/atomics.js index 63d8eb0ca8..58d3d950d5 100644 --- a/deps/v8/test/mjsunit/wasm/atomics.js +++ b/deps/v8/test/mjsunit/wasm/atomics.js @@ -145,109 +145,109 @@ function Test8Op(operation, func) { } (function TestAtomicAdd() { - print("TestAtomicAdd"); + print(arguments.callee.name); let wasmAdd = GetAtomicBinOpFunction(kExprI32AtomicAdd, 2, 0); Test32Op(Add, wasmAdd); })(); (function TestAtomicAdd16U() { - print("TestAtomicAdd16U"); + print(arguments.callee.name); let wasmAdd = GetAtomicBinOpFunction(kExprI32AtomicAdd16U, 1, 0); Test16Op(Add, wasmAdd); })(); (function TestAtomicAdd8U() { - print("TestAtomicAdd8U"); + print(arguments.callee.name); let wasmAdd = GetAtomicBinOpFunction(kExprI32AtomicAdd8U, 0, 0); Test8Op(Add, wasmAdd); })(); (function TestAtomicSub() { - print("TestAtomicSub"); + print(arguments.callee.name); let wasmSub = GetAtomicBinOpFunction(kExprI32AtomicSub, 2, 0); Test32Op(Sub, wasmSub); })(); (function TestAtomicSub16U() { - print("TestAtomicSub16U"); + print(arguments.callee.name); let wasmSub = GetAtomicBinOpFunction(kExprI32AtomicSub16U, 1, 0); Test16Op(Sub, wasmSub); })(); (function TestAtomicSub8U() { - print("TestAtomicSub8U"); + print(arguments.callee.name); let wasmSub = GetAtomicBinOpFunction(kExprI32AtomicSub8U, 0, 0); Test8Op(Sub, wasmSub); })(); (function TestAtomicAnd() { - print("TestAtomicAnd"); + print(arguments.callee.name); let wasmAnd = GetAtomicBinOpFunction(kExprI32AtomicAnd, 2, 0); Test32Op(And, wasmAnd); })(); (function TestAtomicAnd16U() { - print("TestAtomicAnd16U"); + print(arguments.callee.name); let wasmAnd = GetAtomicBinOpFunction(kExprI32AtomicAnd16U, 1, 0); Test16Op(And, wasmAnd); })(); (function TestAtomicAnd8U() { - print("TestAtomicAnd8U"); + print(arguments.callee.name); let wasmAnd = GetAtomicBinOpFunction(kExprI32AtomicAnd8U, 0, 0); Test8Op(And, wasmAnd); })(); (function TestAtomicOr() { - print("TestAtomicOr"); + print(arguments.callee.name); let wasmOr = GetAtomicBinOpFunction(kExprI32AtomicOr, 2, 0); Test32Op(Or, wasmOr); })(); (function TestAtomicOr16U() { - print("TestAtomicOr16U"); + print(arguments.callee.name); let wasmOr = GetAtomicBinOpFunction(kExprI32AtomicOr16U, 1, 0); Test16Op(Or, wasmOr); })(); (function TestAtomicOr8U() { - print("TestAtomicOr8U"); + print(arguments.callee.name); let wasmOr = GetAtomicBinOpFunction(kExprI32AtomicOr8U, 0, 0); Test8Op(Or, wasmOr); })(); (function TestAtomicXor() { - print("TestAtomicXor"); + print(arguments.callee.name); let wasmXor = GetAtomicBinOpFunction(kExprI32AtomicXor, 2, 0); Test32Op(Xor, wasmXor); })(); (function TestAtomicXor16U() { - print("TestAtomicXor16U"); + print(arguments.callee.name); let wasmXor = GetAtomicBinOpFunction(kExprI32AtomicXor16U, 1, 0); Test16Op(Xor, wasmXor); })(); (function TestAtomicXor8U() { - print("TestAtomicXor8U"); + print(arguments.callee.name); let wasmXor = GetAtomicBinOpFunction(kExprI32AtomicXor8U, 0, 0); Test8Op(Xor, wasmXor); })(); (function TestAtomicExchange() { - print("TestAtomicExchange"); + print(arguments.callee.name); let wasmExchange = GetAtomicBinOpFunction(kExprI32AtomicExchange, 2, 0); Test32Op(Exchange, wasmExchange); })(); (function TestAtomicExchange16U() { - print("TestAtomicExchange16U"); + print(arguments.callee.name); let wasmExchange = GetAtomicBinOpFunction(kExprI32AtomicExchange16U, 1, 0); Test16Op(Exchange, wasmExchange); })(); (function TestAtomicExchange8U() { - print("TestAtomicExchange8U"); + print(arguments.callee.name); let wasmExchange = GetAtomicBinOpFunction(kExprI32AtomicExchange8U, 0, 0); Test8Op(Exchange, wasmExchange); })(); @@ -268,7 +268,7 @@ function TestCmpExchange(func, buffer, params, size) { } (function TestAtomicCompareExchange() { - print("TestAtomicCompareExchange"); + print(arguments.callee.name); let wasmCmpExchange = GetAtomicCmpExchangeFunction(kExprI32AtomicCompareExchange, 2, 0); let i32 = new Uint32Array(memory.buffer); @@ -277,7 +277,7 @@ function TestCmpExchange(func, buffer, params, size) { })(); (function TestAtomicCompareExchange16U() { - print("TestAtomicCompareExchange16U"); + print(arguments.callee.name); let wasmCmpExchange = GetAtomicCmpExchangeFunction(kExprI32AtomicCompareExchange16U, 1, 0); let i16 = new Uint16Array(memory.buffer); @@ -286,7 +286,7 @@ function TestCmpExchange(func, buffer, params, size) { })(); (function TestAtomicCompareExchange8U() { - print("TestAtomicCompareExchange8U"); + print(arguments.callee.name); let wasmCmpExchange = GetAtomicCmpExchangeFunction(kExprI32AtomicCompareExchange8U, 0, 0); let i8 = new Uint8Array(memory.buffer); @@ -303,7 +303,7 @@ function TestLoad(func, buffer, value, size) { } (function TestAtomicLoad() { - print("TestAtomicLoad"); + print(arguments.callee.name); let wasmLoad = GetAtomicLoadFunction(kExprI32AtomicLoad, 2, 0); let i32 = new Uint32Array(memory.buffer); let value = 0xacedaced; @@ -311,7 +311,7 @@ function TestLoad(func, buffer, value, size) { })(); (function TestAtomicLoad16U() { - print("TestAtomicLoad16U"); + print(arguments.callee.name); let wasmLoad = GetAtomicLoadFunction(kExprI32AtomicLoad16U, 1, 0); let i16 = new Uint16Array(memory.buffer); let value = 0xaced; @@ -319,7 +319,7 @@ function TestLoad(func, buffer, value, size) { })(); (function TestAtomicLoad8U() { - print("TestAtomicLoad8U"); + print(arguments.callee.name); let wasmLoad = GetAtomicLoadFunction(kExprI32AtomicLoad8U, 0, 0); let i8 = new Uint8Array(memory.buffer); let value = 0xac; @@ -335,7 +335,7 @@ function TestStore(func, buffer, value, size) { } (function TestAtomicStore() { - print("TestAtomicStore"); + print(arguments.callee.name); let wasmStore = GetAtomicStoreFunction(kExprI32AtomicStore, 2, 0); let i32 = new Uint32Array(memory.buffer); let value = 0xacedaced; @@ -343,7 +343,7 @@ function TestStore(func, buffer, value, size) { })(); (function TestAtomicStore16U() { - print("TestAtomicStore16U"); + print(arguments.callee.name); let wasmStore = GetAtomicStoreFunction(kExprI32AtomicStore16U, 1, 0); let i16 = new Uint16Array(memory.buffer); let value = 0xaced; @@ -351,7 +351,7 @@ function TestStore(func, buffer, value, size) { })(); (function TestAtomicStore8U() { - print("TestAtomicStore8U"); + print(arguments.callee.name); let wasmStore = GetAtomicStoreFunction(kExprI32AtomicStore8U, 0, 0); let i8 = new Uint8Array(memory.buffer); let value = 0xac; @@ -359,7 +359,7 @@ function TestStore(func, buffer, value, size) { })(); (function TestAtomicLoadStoreOffset() { - print("TestAtomicLoadStoreOffset"); + print(arguments.callee.name); var builder = new WasmModuleBuilder(); let memory = new WebAssembly.Memory({ initial: 16, maximum: 128, shared: true}); @@ -390,7 +390,7 @@ function TestStore(func, buffer, value, size) { })(); (function TestAtomicOpinLoop() { - print("TestAtomicOpinLoop"); + print(arguments.callee.name); var builder = new WasmModuleBuilder(); let memory = new WebAssembly.Memory({ initial: 16, maximum: 128, shared: true}); @@ -415,3 +415,20 @@ function TestStore(func, buffer, value, size) { {m: {imported_mem: memory}})); assertEquals(20, instance.exports.main()); })(); + +(function TestUnalignedAtomicAccesses() { + print(arguments.callee.name); + let wasmAdd = GetAtomicBinOpFunction(kExprI32AtomicAdd, 2, 17); + assertTraps(kTrapUnalignedAccess, () => wasmAdd(4, 1001)); + let wasmLoad = GetAtomicLoadFunction(kExprI32AtomicLoad16U, 1, 0); + assertTraps(kTrapUnalignedAccess, () => wasmLoad(15)); + let wasmStore = GetAtomicStoreFunction(kExprI32AtomicStore, 2, 0); + assertTraps(kTrapUnalignedAccess, () => wasmStore(22, 5)); + let wasmCmpExchange = + GetAtomicCmpExchangeFunction(kExprI32AtomicCompareExchange, 2, 0x16); + assertTraps(kTrapUnalignedAccess, () => wasmCmpExchange(11, 6, 5)); + + // Building functions with bad alignment should fail to compile + assertThrows(() => GetAtomicBinOpFunction(kExprI32AtomicSub16U, 3, 0), + WebAssembly.CompileError); +})(); diff --git a/deps/v8/test/mjsunit/wasm/bounds-check-64bit.js b/deps/v8/test/mjsunit/wasm/bounds-check-64bit.js index 8643093db0..9308393da4 100644 --- a/deps/v8/test/mjsunit/wasm/bounds-check-64bit.js +++ b/deps/v8/test/mjsunit/wasm/bounds-check-64bit.js @@ -21,13 +21,14 @@ builder.addFunction('load', kSig_i_ii) const module = builder.instantiate(); let start = 12; let address = start; -for (i = 1; i < 64; i++) { +for (i = 0; i < 64; i++) { // This is the address which will be accessed in the code. We cannot use // shifts to calculate the address because JS shifts work on 32-bit integers. - address = (address * 2) % 4294967296; + print(`address=${address}`); if (address < kPageSize) { assertEquals(0, module.exports.load(start, i)); } else { assertTraps(kTrapMemOutOfBounds, _ => { module.exports.load(start, i);}); } + address = (address * 2) % 4294967296; } diff --git a/deps/v8/test/mjsunit/wasm/empirical_max_memory.js b/deps/v8/test/mjsunit/wasm/empirical_max_memory.js new file mode 100644 index 0000000000..262dfe10ef --- /dev/null +++ b/deps/v8/test/mjsunit/wasm/empirical_max_memory.js @@ -0,0 +1,85 @@ +// Copyright 2018 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: --expose-wasm + +load('test/mjsunit/wasm/wasm-constants.js'); +load('test/mjsunit/wasm/wasm-module-builder.js'); + +let k1MiB = 1 * 1024 * 1024; +let k1GiB = 1 * 1024 * 1024 * 1024; +let k4GiB = 4 * k1GiB; +let kMaxMemory = 2 * k1GiB - kPageSize; // TODO(titzer): raise this to 4GiB + +(function Test() { + var memory; + + function BuildAccessors(type, load_opcode, store_opcode) { + builder = new WasmModuleBuilder(); + builder.addImportedMemory("i", "mem"); + builder.addFunction("load", makeSig([kWasmI32], [type])) + .addBody([ // -- + kExprGetLocal, 0, // -- + load_opcode, 0, 0, // -- + ]) // -- + .exportFunc(); + builder.addFunction("store", makeSig([kWasmI32, type], [])) + .addBody([ // -- + kExprGetLocal, 0, // -- + kExprGetLocal, 1, // -- + store_opcode, 0, 0, // -- + ]) // -- + .exportFunc(); + let i = builder.instantiate({i: {mem: memory}}); + return {load: i.exports.load, store: i.exports.store}; + } + + function probe(a, f) { + print("------------------------"); + let stride = kPageSize; + let max = kMaxMemory; + for (let i = 0; i < max; i += stride) { + a.store(i, f(i)); + } + for (let i = 0; i < max; i += stride) { + // print(`${i} = ${f(i)}`); + assertEquals(f(i), a.load(i)); + } + } + + try { + let kPages = kMaxMemory / kPageSize; + memory = new WebAssembly.Memory({initial: kPages, maximum: kPages}); + } catch (e) { + print("OOM: sorry, best effort max memory size test."); + return; + } + + assertEquals(kMaxMemory, memory.buffer.byteLength); + + { + let a = BuildAccessors(kWasmI32, kExprI32LoadMem, kExprI32StoreMem); + probe(a, i => (0xaabbccee ^ ((i >> 11) * 0x110005)) | 0); + } + + { + let a = BuildAccessors(kWasmI32, kExprI32LoadMem16U, kExprI32StoreMem16); + probe(a, i => (0xccee ^ ((i >> 11) * 0x110005)) & 0xFFFF); + } + + { + let a = BuildAccessors(kWasmI32, kExprI32LoadMem8U, kExprI32StoreMem8); + probe(a, i => (0xee ^ ((i >> 11) * 0x05)) & 0xFF); + } + + { + let a = BuildAccessors(kWasmF64, kExprF64LoadMem, kExprF64StoreMem); + probe(a, i => 0xaabbccee ^ ((i >> 11) * 0x110005)); + } + + { + let a = BuildAccessors(kWasmF32, kExprF32LoadMem, kExprF32StoreMem); + probe(a, i => Math.fround(0xaabbccee ^ ((i >> 11) * 0x110005))); + } +})(); diff --git a/deps/v8/test/mjsunit/wasm/ffi-error.js b/deps/v8/test/mjsunit/wasm/ffi-error.js index e7811d2b78..2b4cb9a4eb 100644 --- a/deps/v8/test/mjsunit/wasm/ffi-error.js +++ b/deps/v8/test/mjsunit/wasm/ffi-error.js @@ -4,180 +4,222 @@ // Flags: --expose-wasm -load("test/mjsunit/wasm/wasm-constants.js"); -load("test/mjsunit/wasm/wasm-module-builder.js"); - -function instantiateWithFFI(ffi) { - var builder = new WasmModuleBuilder(); - - var sig_index = kSig_i_dd; - builder.addImport("mod", "fun", sig_index); - builder.addFunction("main", sig_index) - .addBody([ - kExprGetLocal, 0, // -- - kExprGetLocal, 1, // -- - kExprCallFunction, 0, // -- - ]) // -- - .exportFunc(); - - return builder.instantiate(ffi); +load('test/mjsunit/wasm/wasm-constants.js'); +load('test/mjsunit/wasm/wasm-module-builder.js'); + +function CreateDefaultBuilder() { + const builder = new WasmModuleBuilder(); + + const sig_index = kSig_i_dd; + builder.addImport('mod', 'fun', sig_index); + builder.addFunction('main', sig_index) + .addBody([ + kExprGetLocal, 0, // -- + kExprGetLocal, 1, // -- + kExprCallFunction, 0, // -- + ]) // -- + .exportFunc(); + return builder; } -// everything is good. -(function() { - var ffi = {"mod": {fun: function(a, b) { print(a, b); }}} - instantiateWithFFI(ffi); -})(); - - -// FFI object should be an object. -assertThrows(function() { - var ffi = 0; - instantiateWithFFI(ffi); -}); +function checkSuccessfulInstantiation(builder, ffi, handler) { + // Test synchronous instantiation. + const instance = builder.instantiate(ffi); + if (handler) handler(instance); + // Test asynchronous instantiation. + assertPromiseResult(builder.asyncInstantiate(ffi), handler); +} -// FFI object should have a "mod" property. -assertThrows(function() { - instantiateWithFFI({}); -}); +function checkFailingInstantiation(builder, ffi, error, message) { + // Test synchronous instantiation. + assertThrows(_ => builder.instantiate(ffi), error, message); + // Test asynchronous instantiation. + assertPromiseResult(builder.asyncInstantiate(ffi), assertUnreachable, e => { + assertInstanceof(e, error); + assertEquals(message, e.message); + }); +} -// FFI object should have a "fun" property. -assertThrows(function() { - instantiateWithFFI({mod: {}}); -}); +(function testValidFFI() { + print(arguments.callee.name); + let ffi = {'mod': {fun: print}}; + checkSuccessfulInstantiation(CreateDefaultBuilder(), ffi, undefined); +})(); +(function testInvalidFFIs() { + print(arguments.callee.name); + checkFailingInstantiation( + CreateDefaultBuilder(), 17, TypeError, + 'WebAssembly Instantiation: Argument 1 must be an object'); + checkFailingInstantiation( + CreateDefaultBuilder(), {}, TypeError, + 'WebAssembly Instantiation: Import #0 module="mod" error: module is not an object or function'); + checkFailingInstantiation( + CreateDefaultBuilder(), {mod: {}}, WebAssembly.LinkError, + 'WebAssembly Instantiation: Import #0 module="mod" function="fun" error: function import requires a callable'); + checkFailingInstantiation( + CreateDefaultBuilder(), {mod: {fun: {}}}, WebAssembly.LinkError, + 'WebAssembly Instantiation: Import #0 module="mod" function="fun" error: function import requires a callable'); + checkFailingInstantiation( + CreateDefaultBuilder(), {mod: {fun: 0}}, WebAssembly.LinkError, + 'WebAssembly Instantiation: Import #0 module="mod" function="fun" error: function import requires a callable'); +})(); -// "fun" should be a JS function. -assertThrows(function() { - instantiateWithFFI({mod: {fun: new Object()}}); -}); +(function testImportWithInvalidSignature() { + print(arguments.callee.name); + // "fun" should have signature "i_dd" + let builder = new WasmModuleBuilder(); + + let sig_index = kSig_i_dd; + builder.addFunction('exp', kSig_i_i) + .addBody([ + kExprGetLocal, + 0, + ]) // -- + .exportFunc(); + let exported = builder.instantiate().exports.exp; + checkFailingInstantiation( + CreateDefaultBuilder(), {mod: {fun: exported}}, WebAssembly.LinkError, + 'WebAssembly Instantiation: Import #0 module="mod" function="fun" error: imported function does not match the expected type'); +})(); -// "fun" should be a JS function. -assertThrows(function() { - instantiateWithFFI({mod: {fun: 0}}); -}); +(function regression870646() { + print(arguments.callee.name); + const ffi = {mod: {fun: function() {}}}; + Object.defineProperty(ffi, 'mod', { + get: function() { + throw new Error('my_exception'); + } + }); -// "fun" should have signature "i_dd" -assertThrows(function () { - var builder = new WasmModuleBuilder(); + checkFailingInstantiation(CreateDefaultBuilder(), ffi, Error, 'my_exception'); +})(); - var sig_index = kSig_i_dd; - builder.addFunction("exp", kSig_i_i) - .addBody([ - kExprGetLocal, 0, - ]) // -- - .exportFunc(); +// "fun" matches signature "i_dd" +(function testImportWithValidSignature() { + print(arguments.callee.name); + let builder = new WasmModuleBuilder(); + + builder.addFunction('exp', kSig_i_dd) + .addBody([ + kExprI32Const, + 33, + ]) // -- + .exportFunc(); - var exported = builder.instantiate().exports.exp; - instantiateWithFFI({mod: {fun: exported}}); -}); + let exported = builder.instantiate().exports.exp; -// "fun" matches signature "i_dd" -(function () { - var builder = new WasmModuleBuilder(); - - builder.addFunction("exp", kSig_i_dd) - .addBody([ - kExprI32Const, 33, - ]) // -- - .exportFunc(); - - var exported = builder.instantiate().exports.exp; - var instance = instantiateWithFFI({mod: {fun: exported}}); - assertEquals(33, instance.exports.main()); + checkSuccessfulInstantiation( + CreateDefaultBuilder(), {mod: {fun: exported}}, + instance => assertEquals(33, instance.exports.main())); })(); (function I64InSignatureThrows() { - var builder = new WasmModuleBuilder(); + print(arguments.callee.name); + let builder = new WasmModuleBuilder(); builder.addMemory(1, 1, true); - builder.addFunction("function_with_invalid_signature", kSig_l_ll) + builder.addFunction('function_with_invalid_signature', kSig_l_ll) .addBody([ // -- kExprGetLocal, 0, // -- kExprGetLocal, 1, // -- kExprI64Sub]) // -- .exportFunc() - var module = builder.instantiate(); - - assertThrows(function() { - module.exports.function_with_invalid_signature(33, 88); - }, TypeError); + checkSuccessfulInstantiation( + builder, undefined, + instance => assertThrows(function() { + instance.exports.function_with_invalid_signature(33, 88); + }, TypeError, 'wasm function signature contains illegal type')); })(); (function I64ParamsInSignatureThrows() { - var builder = new WasmModuleBuilder(); + print(arguments.callee.name); + let builder = new WasmModuleBuilder(); builder.addMemory(1, 1, true); - builder.addFunction("function_with_invalid_signature", kSig_i_l) - .addBody([ - kExprGetLocal, 0, - kExprI32ConvertI64 - ]) - .exportFunc() + builder.addFunction('function_with_invalid_signature', kSig_i_l) + .addBody([kExprGetLocal, 0, kExprI32ConvertI64]) + .exportFunc(); - var module = builder.instantiate(); + checkSuccessfulInstantiation( + builder, undefined, + instance => assertThrows( + _ => instance.exports.function_with_invalid_signature(12), TypeError, + 'wasm function signature contains illegal type')); - assertThrows(function() { - module.exports.function_with_invalid_signature(33); - }, TypeError); })(); (function I64JSImportThrows() { - var builder = new WasmModuleBuilder(); - var sig_index = builder.addType(kSig_i_i); - var sig_i64_index = builder.addType(kSig_i_l); - var index = builder.addImport("", "func", sig_i64_index); - builder.addFunction("main", sig_index) - .addBody([ - kExprGetLocal, 0, - kExprI64SConvertI32, - kExprCallFunction, index // -- - ]) // -- - .exportFunc(); - var func = function() {return {};}; - var main = builder.instantiate({"": {func: func}}).exports.main; - assertThrows(function() { - main(13); - }, TypeError); + print(arguments.callee.name); + let builder = new WasmModuleBuilder(); + let sig_index = builder.addType(kSig_i_i); + let sig_i64_index = builder.addType(kSig_i_l); + let index = builder.addImport('', 'func', sig_i64_index); + builder.addFunction('main', sig_index) + .addBody([ + kExprGetLocal, 0, kExprI64SConvertI32, kExprCallFunction, index // -- + ]) // -- + .exportFunc(); + + checkSuccessfulInstantiation( + builder, {'': {func: _ => {}}}, + instance => assertThrows( + instance.exports.main, TypeError, + 'wasm function signature contains illegal type')); + })(); (function ImportI64ParamWithF64ReturnThrows() { + print(arguments.callee.name); // This tests that we generate correct code by using the correct return // register. See bug 6096. - var builder = new WasmModuleBuilder(); + let builder = new WasmModuleBuilder(); builder.addImport('', 'f', makeSig([kWasmI64], [kWasmF64])); builder.addFunction('main', kSig_v_v) .addBody([kExprI64Const, 0, kExprCallFunction, 0, kExprDrop]) .exportFunc(); - var instance = builder.instantiate({'': {f: i => i}}); - assertThrows(() => instance.exports.main(), TypeError); + checkSuccessfulInstantiation( + builder, {'': {f: i => i}}, + instance => assertThrows( + instance.exports.main, TypeError, + 'wasm function signature contains illegal type')); + })(); (function ImportI64Return() { + print(arguments.callee.name); // This tests that we generate correct code by using the correct return // register(s). See bug 6104. - var builder = new WasmModuleBuilder(); + let builder = new WasmModuleBuilder(); builder.addImport('', 'f', makeSig([], [kWasmI64])); builder.addFunction('main', kSig_v_v) .addBody([kExprCallFunction, 0, kExprDrop]) .exportFunc(); - var instance = builder.instantiate({'': {f: () => 1}}); - assertThrows(() => instance.exports.main(), TypeError); + checkSuccessfulInstantiation( + builder, {'': {f: _ => 1}}, + instance => assertThrows( + instance.exports.main, TypeError, + 'wasm function signature contains illegal type')); + })(); (function ImportSymbolToNumberThrows() { - var builder = new WasmModuleBuilder(); - var index = builder.addImport("", "func", kSig_i_v); - builder.addFunction("main", kSig_i_v) + print(arguments.callee.name); + let builder = new WasmModuleBuilder(); + let index = builder.addImport('', 'f', kSig_i_v); + builder.addFunction('main', kSig_i_v) .addBody([kExprCallFunction, 0]) .exportFunc(); - var func = () => Symbol(); - var main = builder.instantiate({"": {func: func}}).exports.main; - assertThrows(() => main(), TypeError); + + checkSuccessfulInstantiation( + builder, {'': {f: _ => Symbol()}}, + instance => assertThrows( + instance.exports.main, TypeError, + 'Cannot convert a Symbol value to a number')); })(); diff --git a/deps/v8/test/mjsunit/wasm/function-names.js b/deps/v8/test/mjsunit/wasm/function-names.js index 9320c50789..fe7c401177 100644 --- a/deps/v8/test/mjsunit/wasm/function-names.js +++ b/deps/v8/test/mjsunit/wasm/function-names.js @@ -40,7 +40,7 @@ var module = builder.instantiate(); for (var i = 0; i < names.length; ++i) { var line = lines[i].trim(); if (names[i] === null) continue; - var printed_name = names[i] === undefined ? "<WASM UNNAMED>" : names[i] + var printed_name = names[i]; var expected_start = "at " + printed_name + " ("; assertTrue(line.startsWith(expected_start), "should start with '" + expected_start + "': '" + line + "'"); diff --git a/deps/v8/test/mjsunit/wasm/graceful_shutdown_during_tierup.js b/deps/v8/test/mjsunit/wasm/graceful_shutdown_during_tierup.js new file mode 100644 index 0000000000..c40bf2f11d --- /dev/null +++ b/deps/v8/test/mjsunit/wasm/graceful_shutdown_during_tierup.js @@ -0,0 +1,28 @@ +// Copyright 2018 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: --no-wait-for-wasm --wasm-tier-up + +load("test/mjsunit/wasm/wasm-constants.js"); +load("test/mjsunit/wasm/wasm-module-builder.js"); + +(function ShutdownDuringTierUp() { + // Create a big module. + var builder = new WasmModuleBuilder(); + + builder.addMemory(1, 1, true); + for (i = 0; i < 100; i++) { + builder.addFunction("sub" + i, kSig_i_i) + .addBody([ // -- + kExprGetLocal, 0, // -- + kExprI32Const, i % 61, // -- + kExprI32Sub]) // -- + .exportFunc() + } + + var buffer = builder.toBuffer(); + // Wait for compilation to finish, but then shutdown while tier-up is still + // running. + assertPromiseResult(WebAssembly.compile(buffer)); +})(); diff --git a/deps/v8/test/mjsunit/wasm/interpreter-mixed.js b/deps/v8/test/mjsunit/wasm/interpreter-mixed.js index 08cfc8c96d..6225220c8d 100644 --- a/deps/v8/test/mjsunit/wasm/interpreter-mixed.js +++ b/deps/v8/test/mjsunit/wasm/interpreter-mixed.js @@ -193,3 +193,27 @@ function redirectToInterpreter( } } })(); + +(function testInterpreterPreservedOnTierUp() { + print(arguments.callee.name); + var builder = new WasmModuleBuilder(); + var fun_body = [kExprI32Const, 23]; + var fun = builder.addFunction('fun', kSig_i_v).addBody(fun_body).exportFunc(); + var instance = builder.instantiate(); + var exp = instance.exports; + + // Initially the interpreter is not being called. + var initial_interpreted = %WasmNumInterpretedCalls(instance); + assertEquals(23, exp.fun()); + assertEquals(initial_interpreted + 0, %WasmNumInterpretedCalls(instance)); + + // Redirection will cause the interpreter to be called. + %RedirectToWasmInterpreter(instance, fun.index); + assertEquals(23, exp.fun()); + assertEquals(initial_interpreted + 1, %WasmNumInterpretedCalls(instance)); + + // Requesting a tier-up still ensure the interpreter is being called. + %WasmTierUpFunction(instance, fun.index); + assertEquals(23, exp.fun()); + assertEquals(initial_interpreted + 2, %WasmNumInterpretedCalls(instance)); +})(); diff --git a/deps/v8/test/mjsunit/wasm/interpreter.js b/deps/v8/test/mjsunit/wasm/interpreter.js index 0bf3f8610b..b887b40918 100644 --- a/deps/v8/test/mjsunit/wasm/interpreter.js +++ b/deps/v8/test/mjsunit/wasm/interpreter.js @@ -310,7 +310,7 @@ function checkStack(stack, expected_lines) { if (!(e instanceof TypeError)) throw e; checkStack(stripPath(e.stack), [ 'TypeError: ' + kTrapMsgs[kTrapTypeError], // - - ' at indirect (wasm-function[2]:1)', // - + ' at indirect (wasm-function[2]:3)', // - ' at main (wasm-function[3]:3)', // - /^ at testIllegalImports \(interpreter.js:\d+:22\)$/, // - /^ at interpreter.js:\d+:3$/ diff --git a/deps/v8/test/mjsunit/wasm/memory_1gb_oob.js b/deps/v8/test/mjsunit/wasm/memory_1gb_oob.js new file mode 100644 index 0000000000..f9593e84f7 --- /dev/null +++ b/deps/v8/test/mjsunit/wasm/memory_1gb_oob.js @@ -0,0 +1,99 @@ +// Copyright 2018 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-max-mem-pages=16384 + +load('test/mjsunit/wasm/wasm-constants.js'); +load('test/mjsunit/wasm/wasm-module-builder.js'); + +const k1MiB = 1 * 1024 * 1024; +const k1GiB = 1 * 1024 * 1024 * 1024; +const k2GiB = 2 * k1GiB; +const k3GiB = 3 * k1GiB; +const k4GiB = 4 * k1GiB; +const kMaxMemory = k1GiB; + +// Indexes (and offsets) used to systematically probe the memory. +const indexes = (() => { + const a = k1GiB, b = k2GiB, c = k3GiB, d = k4GiB; + return [ + 0, 1, 2, 3, 4, 5, 7, 8, 9, // near 0 + a-8, a-4, a+0, a+1, a+2, a+3, a+4, a+5, a+7, a+8, a+9, // near 1GiB + b-8, b-4, b+0, b+1, b+2, b+3, b+4, b+5, b+7, b+8, b+9, // near 2GiB + c-8, c-4, c+0, c+1, c+2, c+3, c+4, c+5, c+7, c+8, c+9, // near 3GiB + d-9, d-8, d-7, d-5, d-4, d-3, d-2, d-1 // near 4GiB +]; +})(); + +(function Test() { + var memory; + + function BuildAccessors(type, load_opcode, store_opcode, offset) { + builder = new WasmModuleBuilder(); + builder.addImportedMemory("i", "mem"); + const h = 0x80; + const m = 0x7f; + let offset_bytes = [h|((offset >>> 0) & m), // LEB encoding of offset + h|((offset >>> 7) & m), + h|((offset >>> 14) & m), + h|((offset >>> 21) & m), + 0|((offset >>> 28) & m)]; + builder.addFunction("load", makeSig([kWasmI32], [type])) + .addBody([ // -- + kExprGetLocal, 0, // -- + load_opcode, 0, ...offset_bytes, // -- + ]) // -- + .exportFunc(); + builder.addFunction("store", makeSig([kWasmI32, type], [])) + .addBody([ // -- + kExprGetLocal, 0, // -- + kExprGetLocal, 1, // -- + store_opcode, 0, ...offset_bytes, // -- + ]) // -- + .exportFunc(); + let i = builder.instantiate({i: {mem: memory}}); + return {offset: offset, load: i.exports.load, store: i.exports.store}; + } + + function probe(a, size, offset, f) { + print(`size=${size} offset=${offset}`); + for (let i of indexes) { + let oob = (i + size + offset) > kMaxMemory; + if (oob) { +// print(` ${i} + ${offset} OOB`); + assertThrows(() => a.store(i, f(i))); + assertThrows(() => a.load(i)); + } else { +// print(` ${i} = ${f(i)}`); + a.store(i, f(i)); + assertEquals(f(i), a.load(i)); + } + } + } + + try { + const kPages = kMaxMemory / kPageSize; + memory = new WebAssembly.Memory({initial: kPages, maximum: kPages}); + } catch (e) { + print("OOM: sorry, best effort max memory size test."); + return; + } + + assertEquals(kMaxMemory, memory.buffer.byteLength); + + for (let offset of indexes) { + let a = BuildAccessors(kWasmI32, kExprI32LoadMem, kExprI32StoreMem, offset); + probe(a, 4, offset, i => (0xaabbccee ^ ((i >> 11) * 0x110005)) | 0); + } + + for (let offset of indexes) { + let a = BuildAccessors(kWasmI32, kExprI32LoadMem8U, kExprI32StoreMem8, offset); + probe(a, 1, offset, i => (0xee ^ ((i >> 11) * 0x05)) & 0xFF); + } + + for (let offset of indexes) { + let a = BuildAccessors(kWasmF64, kExprF64LoadMem, kExprF64StoreMem, offset); + probe(a, 8, offset, i => 0xaabbccee ^ ((i >> 11) * 0x110005)); + } +})(); diff --git a/deps/v8/test/mjsunit/wasm/memory_2gb_oob.js b/deps/v8/test/mjsunit/wasm/memory_2gb_oob.js new file mode 100644 index 0000000000..db344f30f3 --- /dev/null +++ b/deps/v8/test/mjsunit/wasm/memory_2gb_oob.js @@ -0,0 +1,99 @@ +// Copyright 2018 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-max-mem-pages=32768 + +load('test/mjsunit/wasm/wasm-constants.js'); +load('test/mjsunit/wasm/wasm-module-builder.js'); + +const k1MiB = 1 * 1024 * 1024; +const k1GiB = 1 * 1024 * 1024 * 1024; +const k2GiB = 2 * k1GiB; +const k3GiB = 3 * k1GiB; +const k4GiB = 4 * k1GiB; +const kMaxMemory = k2GiB; + +// Indexes (and offsets) used to systematically probe the memory. +const indexes = (() => { + const a = k1GiB, b = k2GiB, c = k3GiB, d = k4GiB; + return [ + 0, 1, 2, 3, 4, 5, 7, 8, 9, // near 0 + a-8, a-4, a+0, a+1, a+2, a+3, a+4, a+5, a+7, a+8, a+9, // near 1GiB + b-8, b-4, b+0, b+1, b+2, b+3, b+4, b+5, b+7, b+8, b+9, // near 2GiB + c-8, c-4, c+0, c+1, c+2, c+3, c+4, c+5, c+7, c+8, c+9, // near 3GiB + d-9, d-8, d-7, d-5, d-4, d-3, d-2, d-1 // near 4GiB +]; +})(); + +(function Test() { + var memory; + + function BuildAccessors(type, load_opcode, store_opcode, offset) { + builder = new WasmModuleBuilder(); + builder.addImportedMemory("i", "mem"); + const h = 0x80; + const m = 0x7f; + let offset_bytes = [h|((offset >>> 0) & m), // LEB encoding of offset + h|((offset >>> 7) & m), + h|((offset >>> 14) & m), + h|((offset >>> 21) & m), + 0|((offset >>> 28) & m)]; + builder.addFunction("load", makeSig([kWasmI32], [type])) + .addBody([ // -- + kExprGetLocal, 0, // -- + load_opcode, 0, ...offset_bytes, // -- + ]) // -- + .exportFunc(); + builder.addFunction("store", makeSig([kWasmI32, type], [])) + .addBody([ // -- + kExprGetLocal, 0, // -- + kExprGetLocal, 1, // -- + store_opcode, 0, ...offset_bytes, // -- + ]) // -- + .exportFunc(); + let i = builder.instantiate({i: {mem: memory}}); + return {offset: offset, load: i.exports.load, store: i.exports.store}; + } + + function probe(a, size, offset, f) { + print(`size=${size} offset=${offset}`); + for (let i of indexes) { + let oob = (i + size + offset) > kMaxMemory; + if (oob) { +// print(` ${i} + ${offset} OOB`); + assertThrows(() => a.store(i, f(i))); + assertThrows(() => a.load(i)); + } else { +// print(` ${i} = ${f(i)}`); + a.store(i, f(i)); + assertEquals(f(i), a.load(i)); + } + } + } + + try { + let kPages = kMaxMemory / kPageSize; + memory = new WebAssembly.Memory({initial: kPages, maximum: kPages}); + } catch (e) { + print("OOM: sorry, best effort max memory size test."); + return; + } + + assertEquals(kMaxMemory, memory.buffer.byteLength); + + for (let offset of indexes) { + let a = BuildAccessors(kWasmI32, kExprI32LoadMem, kExprI32StoreMem, offset); + probe(a, 4, offset, i => (0xaabbccee ^ ((i >> 11) * 0x110005)) | 0); + } + + for (let offset of indexes) { + let a = BuildAccessors(kWasmI32, kExprI32LoadMem8U, kExprI32StoreMem8, offset); + probe(a, 1, offset, i => (0xee ^ ((i >> 11) * 0x05)) & 0xFF); + } + + for (let offset of indexes) { + let a = BuildAccessors(kWasmF64, kExprF64LoadMem, kExprF64StoreMem, offset); + probe(a, 8, offset, i => 0xaabbccee ^ ((i >> 11) * 0x110005)); + } +})(); diff --git a/deps/v8/test/mjsunit/wasm/memory_4gb_oob.js b/deps/v8/test/mjsunit/wasm/memory_4gb_oob.js new file mode 100644 index 0000000000..d5cb006a79 --- /dev/null +++ b/deps/v8/test/mjsunit/wasm/memory_4gb_oob.js @@ -0,0 +1,97 @@ +// Copyright 2018 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. + +load('test/mjsunit/wasm/wasm-constants.js'); +load('test/mjsunit/wasm/wasm-module-builder.js'); + +const k1MiB = 1 * 1024 * 1024; +const k1GiB = 1 * 1024 * 1024 * 1024; +const k2GiB = 2 * k1GiB; +const k3GiB = 3 * k1GiB; +const k4GiB = 4 * k1GiB; +const kMaxMemory = k4GiB; + +// Indexes (and offsets) used to systematically probe the memory. +const indexes = (() => { + const a = k1GiB, b = k2GiB, c = k3GiB, d = k4GiB; + return [ + 0, 1, 2, 3, 4, 5, 7, 8, 9, // near 0 + a-8, a-4, a+0, a+1, a+2, a+3, a+4, a+5, a+7, a+8, a+9, // near 1GiB + b-8, b-4, b+0, b+1, b+2, b+3, b+4, b+5, b+7, b+8, b+9, // near 2GiB + c-8, c-4, c+0, c+1, c+2, c+3, c+4, c+5, c+7, c+8, c+9, // near 3GiB + d-9, d-8, d-7, d-5, d-4, d-3, d-2, d-1 // near 4GiB +]; +})(); + +(function Test() { + var memory; + + function BuildAccessors(type, load_opcode, store_opcode, offset) { + builder = new WasmModuleBuilder(); + builder.addImportedMemory("i", "mem"); + const h = 0x80; + const m = 0x7f; + let offset_bytes = [h|((offset >>> 0) & m), // LEB encoding of offset + h|((offset >>> 7) & m), + h|((offset >>> 14) & m), + h|((offset >>> 21) & m), + 0|((offset >>> 28) & m)]; + builder.addFunction("load", makeSig([kWasmI32], [type])) + .addBody([ // -- + kExprGetLocal, 0, // -- + load_opcode, 0, ...offset_bytes, // -- + ]) // -- + .exportFunc(); + builder.addFunction("store", makeSig([kWasmI32, type], [])) + .addBody([ // -- + kExprGetLocal, 0, // -- + kExprGetLocal, 1, // -- + store_opcode, 0, ...offset_bytes, // -- + ]) // -- + .exportFunc(); + let i = builder.instantiate({i: {mem: memory}}); + return {offset: offset, load: i.exports.load, store: i.exports.store}; + } + + function probe(a, size, offset, f) { + print(`size=${size} offset=${offset}`); + for (let i of indexes) { + let oob = (i + size + offset) > kMaxMemory; + if (oob) { +// print(` ${i} + ${offset} OOB`); + assertThrows(() => a.store(i, f(i))); + assertThrows(() => a.load(i)); + } else { +// print(` ${i} = ${f(i)}`); + a.store(i, f(i)); + assertEquals(f(i), a.load(i)); + } + } + } + + try { + let kPages = kMaxMemory / kPageSize; + memory = new WebAssembly.Memory({initial: kPages, maximum: kPages}); + } catch (e) { + print("OOM: sorry, best effort max memory size test."); + return; + } + + assertEquals(kMaxMemory, memory.buffer.byteLength); + + for (let offset of indexes) { + let a = BuildAccessors(kWasmI32, kExprI32LoadMem, kExprI32StoreMem, offset); + probe(a, 4, offset, i => (0xaabbccee ^ ((i >> 11) * 0x110005)) | 0); + } + + for (let offset of indexes) { + let a = BuildAccessors(kWasmI32, kExprI32LoadMem8U, kExprI32StoreMem8, offset); + probe(a, 1, offset, i => (0xee ^ ((i >> 11) * 0x05)) & 0xFF); + } + + for (let offset of indexes) { + let a = BuildAccessors(kWasmF64, kExprF64LoadMem, kExprF64StoreMem, offset); + probe(a, 8, offset, i => 0xaabbccee ^ ((i >> 11) * 0x110005)); + } +})(); diff --git a/deps/v8/test/mjsunit/wasm/module-memory.js b/deps/v8/test/mjsunit/wasm/module-memory.js index de05dd4657..2ca5d9a725 100644 --- a/deps/v8/test/mjsunit/wasm/module-memory.js +++ b/deps/v8/test/mjsunit/wasm/module-memory.js @@ -160,13 +160,15 @@ function testOOBThrows() { assertEquals(0, write()); } - + // Note that this test might be run concurrently in multiple Isolates, which + // makes an exact comparison of the expected trap count unreliable. But is is + // still possible to check the lower bound for the expected trap count. for (offset = 65534; offset < 66536; offset++) { const trap_count = %GetWasmRecoveredTrapCount(); assertTraps(kTrapMemOutOfBounds, read); assertTraps(kTrapMemOutOfBounds, write); if (%IsWasmTrapHandlerEnabled()) { - assertEquals(trap_count + 2, %GetWasmRecoveredTrapCount()); + assertTrue(trap_count + 2 <= %GetWasmRecoveredTrapCount()); } } } diff --git a/deps/v8/test/mjsunit/wasm/origin-trial-flags.js b/deps/v8/test/mjsunit/wasm/origin-trial-flags.js new file mode 100644 index 0000000000..d41f581e13 --- /dev/null +++ b/deps/v8/test/mjsunit/wasm/origin-trial-flags.js @@ -0,0 +1,35 @@ +// 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: --noexperimental-wasm-threads --allow-natives-syntax + +load("test/mjsunit/wasm/wasm-constants.js"); +load("test/mjsunit/wasm/wasm-module-builder.js"); + +function instantiateModuleWithThreads() { + // Build a WebAssembly module which uses threads-features. + const builder = new WasmModuleBuilder(); + const shared = true; + builder.addMemory(2, 10, false, shared); + builder.addFunction('main', kSig_i_ii) + .addBody([ + kExprGetLocal, 0, kExprGetLocal, 1, kAtomicPrefix, kExprI32AtomicAdd, 2, + 0 + ]) + .exportFunc(); + + return builder.instantiate(); +} + +// Disable WebAssembly threads initially. +%SetWasmThreadsEnabled(false); +assertThrows(instantiateModuleWithThreads, WebAssembly.CompileError); + +// Enable WebAssembly threads. +%SetWasmThreadsEnabled(true); +assertInstanceof(instantiateModuleWithThreads(), WebAssembly.Instance); + +// Disable WebAssembly threads. +%SetWasmThreadsEnabled(false); +assertThrows(instantiateModuleWithThreads, WebAssembly.CompileError); diff --git a/deps/v8/test/mjsunit/wasm/wasm-constants.js b/deps/v8/test/mjsunit/wasm/wasm-constants.js index 8afe209e9b..f5aead9fb6 100644 --- a/deps/v8/test/mjsunit/wasm/wasm-constants.js +++ b/deps/v8/test/mjsunit/wasm/wasm-constants.js @@ -382,6 +382,7 @@ let kTrapFloatUnrepresentable = 5; let kTrapFuncInvalid = 6; let kTrapFuncSigMismatch = 7; let kTrapTypeError = 8; +let kTrapUnalignedAccess = 9; let kTrapMsgs = [ "unreachable", @@ -392,7 +393,8 @@ let kTrapMsgs = [ "float unrepresentable in integer range", "invalid index into function table", "function signature mismatch", - "wasm function signature contains illegal type" + "wasm function signature contains illegal type", + "operation does not support unaligned accesses" ]; function assertTraps(trap, code) { diff --git a/deps/v8/test/mjsunit/wasm/worker-interpreter.js b/deps/v8/test/mjsunit/wasm/worker-interpreter.js new file mode 100644 index 0000000000..d730ed7a74 --- /dev/null +++ b/deps/v8/test/mjsunit/wasm/worker-interpreter.js @@ -0,0 +1,63 @@ +// Copyright 2018 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: --allow-natives-syntax --no-wasm-disable-structured-cloning + +load("test/mjsunit/wasm/wasm-constants.js"); +load("test/mjsunit/wasm/wasm-module-builder.js"); + +(function TestPostInterpretedModule() { + let builder = new WasmModuleBuilder(); + let add = builder.addFunction("add", kSig_i_ii) + .addBody([kExprGetLocal, 0, kExprGetLocal, 1, kExprI32Add]) + .exportFunc(); + + let module = builder.toModule(); + let instance = new WebAssembly.Instance(module); + let exp = instance.exports; + + let workerScript = ` + var instance = null; + onmessage = function(message) { + try { + if (message.command == 'module') { + instance = new WebAssembly.Instance(message.module); + postMessage('OK'); + } + if (message.command == 'call') { + let result = instance.exports.add(40, 2); + postMessage(result); + } + } catch(e) { + postMessage('ERROR: ' + e); + } + } + `; + let worker = new Worker(workerScript); + + // Call method without using the interpreter. + var initial_interpreted = %WasmNumInterpretedCalls(instance); + assertEquals(23, exp.add(20, 3)); + assertEquals(initial_interpreted + 0, %WasmNumInterpretedCalls(instance)); + + // Send module to the worker, still not interpreting. + worker.postMessage({ command:'module', module:module }); + assertEquals('OK', worker.getMessage()); + worker.postMessage({ command:'call' }); + assertEquals(42, worker.getMessage()); + assertEquals(initial_interpreted + 0, %WasmNumInterpretedCalls(instance)); + + // Switch to the interpreter and call method. + %RedirectToWasmInterpreter(instance, add.index); + assertEquals(23, exp.add(20, 3)); + assertEquals(initial_interpreted + 1, %WasmNumInterpretedCalls(instance)); + + // Let worker call interpreted function. + worker.postMessage({ command:'call' }); + assertEquals(42, worker.getMessage()); + assertEquals(initial_interpreted + 1, %WasmNumInterpretedCalls(instance)); + + // All done. + worker.terminate(); +})(); diff --git a/deps/v8/test/mjsunit/wasm/worker-module.js b/deps/v8/test/mjsunit/wasm/worker-module.js index 00615b8434..72645f8dbf 100644 --- a/deps/v8/test/mjsunit/wasm/worker-module.js +++ b/deps/v8/test/mjsunit/wasm/worker-module.js @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// Flags: --no-wasm-disable-structured-cloning +// Flags: --wasm-shared-engine --no-wasm-disable-structured-cloning load("test/mjsunit/wasm/wasm-constants.js"); load("test/mjsunit/wasm/wasm-module-builder.js"); |