v8/test/mjsunit/wasm/atomics.js
Deepti Gandluri 9c0f98c6a4 [wasm] Implement atomics Exchange, CompareExchange
BUG=v8:6532

R=binji@chromium.org, bradnelson@chromium.org

Change-Id: I376dd8e4d27cac657d5a7c05a50a0477963da7b7
Reviewed-on: https://chromium-review.googlesource.com/627476
Commit-Queue: Brad Nelson <bradnelson@chromium.org>
Reviewed-by: Brad Nelson <bradnelson@chromium.org>
Reviewed-by: Ben Smith <binji@chromium.org>
Cr-Commit-Position: refs/heads/master@{#47620}
2017-08-25 22:09:01 +00:00

258 lines
7.4 KiB
JavaScript

// 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: --experimental-wasm-threads
load("test/mjsunit/wasm/wasm-constants.js");
load("test/mjsunit/wasm/wasm-module-builder.js");
const kMemtypeSize32 = 4;
const kMemtypeSize16 = 2;
const kMemtypeSize8 = 1;
function Add(a, b) { return a + b; }
function Sub(a, b) { return a - b; }
function And(a, b) { return a & b; }
function Or(a, b) { return a | b; }
function Xor(a, b) { return a ^ b; }
function Exchange(a, b) { return b; }
let maxSize = 10;
let memory = new WebAssembly.Memory({initial: 1, maximum: maxSize, shared: true});
function GetAtomicBinOpFunction(wasmExpression) {
let builder = new WasmModuleBuilder();
builder.addImportedMemory("m", "imported_mem");
builder.addFunction("main", kSig_i_ii)
.addBody([
kExprGetLocal, 0,
kExprGetLocal, 1,
kAtomicPrefix,
wasmExpression])
.exportAs("main");
// Instantiate module, get function exports
let module = new WebAssembly.Module(builder.toBuffer());
let instance = (new WebAssembly.Instance(module,
{m: {imported_mem: memory}}));
return instance.exports.main;
}
function GetAtomicCmpExchangeFunction(wasmExpression) {
let builder = new WasmModuleBuilder();
builder.addImportedMemory("m", "imported_mem");
builder.addFunction("main", kSig_i_iii)
.addBody([
kExprGetLocal, 0,
kExprGetLocal, 1,
kExprGetLocal, 2,
kAtomicPrefix,
wasmExpression])
.exportAs("main");
// Instantiate module, get function exports
let module = new WebAssembly.Module(builder.toBuffer());
let instance = (new WebAssembly.Instance(module,
{m: {imported_mem: memory}}));
return instance.exports.main;
}
function VerifyBoundsCheck(func, memtype_size) {
const kPageSize = 65536;
// Test out of bounds at boundary
for (let i = memory.buffer.byteLength - memtype_size + 1;
i < memory.buffer.byteLength + memtype_size + 4; i++) {
assertTraps(kTrapMemOutOfBounds, () => func(i, 5, 10));
}
// Test out of bounds at maximum + 1
assertTraps(kTrapMemOutOfBounds, () => func((maxSize + 1) * kPageSize, 5, 1));
}
function Test32Op(operation, func) {
let i32 = new Uint32Array(memory.buffer);
for (let i = 0; i < i32.length; i++) {
let expected = 0x9cedf00d;
let value = 0x11111111;
i32[i] = expected;
assertEquals(expected, func(i * kMemtypeSize32, value) >>> 0);
assertEquals(operation(expected, value) >>> 0, i32[i]);
}
VerifyBoundsCheck(func, kMemtypeSize32);
}
function Test16Op(operation, func) {
let i16 = new Uint16Array(memory.buffer);
for (let i = 0; i < i16.length; i++) {
let expected = 0xd00d;
let value = 0x1111;
i16[i] = expected;
assertEquals(expected, func(i * kMemtypeSize16, value));
assertEquals(operation(expected, value), i16[i]);
}
VerifyBoundsCheck(func, kMemtypeSize16);
}
function Test8Op(operation, func) {
let i8 = new Uint8Array(memory.buffer);
for (let i = 0; i < i8.length; i++) {
let expected = 0xbe;
let value = 0x12;
i8[i] = expected;
assertEquals(expected, func(i * kMemtypeSize8, value));
assertEquals(operation(expected, value), i8[i]);
}
VerifyBoundsCheck(func, kMemtypeSize8, 10);
}
(function TestAtomicAdd() {
print("TestAtomicAdd");
let wasmAdd = GetAtomicBinOpFunction(kExprI32AtomicAdd);
Test32Op(Add, wasmAdd);
})();
(function TestAtomicAdd16U() {
print("TestAtomicAdd16U");
let wasmAdd = GetAtomicBinOpFunction(kExprI32AtomicAdd16U);
Test16Op(Add, wasmAdd);
})();
(function TestAtomicAdd8U() {
print("TestAtomicAdd8U");
let wasmAdd = GetAtomicBinOpFunction(kExprI32AtomicAdd8U);
Test8Op(Add, wasmAdd);
})();
(function TestAtomicSub() {
print("TestAtomicSub");
let wasmSub = GetAtomicBinOpFunction(kExprI32AtomicSub);
Test32Op(Sub, wasmSub);
})();
(function TestAtomicSub16U() {
print("TestAtomicSub16U");
let wasmSub = GetAtomicBinOpFunction(kExprI32AtomicSub16U);
Test16Op(Sub, wasmSub);
})();
(function TestAtomicSub8U() {
print("TestAtomicSub8U");
let wasmSub = GetAtomicBinOpFunction(kExprI32AtomicSub8U);
Test8Op(Sub, wasmSub);
})();
(function TestAtomicAnd() {
print("TestAtomicAnd");
let wasmAnd = GetAtomicBinOpFunction(kExprI32AtomicAnd);
Test32Op(And, wasmAnd);
})();
(function TestAtomicAnd16U() {
print("TestAtomicAnd16U");
let wasmAnd = GetAtomicBinOpFunction(kExprI32AtomicAnd16U);
Test16Op(And, wasmAnd);
})();
(function TestAtomicAnd8U() {
print("TestAtomicAnd8U");
let wasmAnd = GetAtomicBinOpFunction(kExprI32AtomicAnd8U);
Test8Op(And, wasmAnd);
})();
(function TestAtomicOr() {
print("TestAtomicOr");
let wasmOr = GetAtomicBinOpFunction(kExprI32AtomicOr);
Test32Op(Or, wasmOr);
})();
(function TestAtomicOr16U() {
print("TestAtomicOr16U");
let wasmOr = GetAtomicBinOpFunction(kExprI32AtomicOr16U);
Test16Op(Or, wasmOr);
})();
(function TestAtomicOr8U() {
print("TestAtomicOr8U");
let wasmOr = GetAtomicBinOpFunction(kExprI32AtomicOr8U);
Test8Op(Or, wasmOr);
})();
(function TestAtomicXor() {
print("TestAtomicXor");
let wasmXor = GetAtomicBinOpFunction(kExprI32AtomicXor);
Test32Op(Xor, wasmXor);
})();
(function TestAtomicXor16U() {
print("TestAtomicXor16U");
let wasmXor = GetAtomicBinOpFunction(kExprI32AtomicXor16U);
Test16Op(Xor, wasmXor);
})();
(function TestAtomicXor8U() {
print("TestAtomicXor8U");
let wasmXor = GetAtomicBinOpFunction(kExprI32AtomicXor8U);
Test8Op(Xor, wasmXor);
})();
(function TestAtomicExchange() {
print("TestAtomicExchange");
let wasmExchange = GetAtomicBinOpFunction(kExprI32AtomicExchange);
Test32Op(Exchange, wasmExchange);
})();
(function TestAtomicExchange16U() {
print("TestAtomicExchange16U");
let wasmExchange = GetAtomicBinOpFunction(kExprI32AtomicExchange16U);
Test16Op(Exchange, wasmExchange);
})();
(function TestAtomicExchange8U() {
print("TestAtomicExchange8U");
let wasmExchange = GetAtomicBinOpFunction(kExprI32AtomicExchange8U);
Test8Op(Exchange, wasmExchange);
})();
function TestCmpExchange(func, buffer, params, size) {
for (let i = 0; i < buffer.length; i++) {
for (let j = 0; j < params.length; j++) {
for (let k = 0; k < params.length; k++) {
buffer[i] = params[j];
let loaded = func(i * size, params[k], params[j]) >>> 0;
let expected = (params[k] == loaded) ? params[j] : loaded;
assertEquals(loaded, params[j]);
assertEquals(expected, buffer[i]);
}
}
}
VerifyBoundsCheck(func, size);
}
(function TestAtomicCompareExchange() {
print("TestAtomicCompareExchange");
let wasmCmpExchange =
GetAtomicCmpExchangeFunction(kExprI32AtomicCompareExchange);
let i32 = new Uint32Array(memory.buffer);
let params = [0x00000001, 0x00000555, 0x00099999, 0xffffffff];
TestCmpExchange(wasmCmpExchange, i32, params, kMemtypeSize32);
})();
(function TestAtomicCompareExchange16U() {
print("TestAtomicCompareExchange16U");
let wasmCmpExchange =
GetAtomicCmpExchangeFunction(kExprI32AtomicCompareExchange16U);
let i16 = new Uint16Array(memory.buffer);
let params = [0x0001, 0x0555, 0x9999];
TestCmpExchange(wasmCmpExchange, i16, params, kMemtypeSize16);
})();
(function TestAtomicCompareExchange8U() {
print("TestAtomicCompareExchange8U");
let wasmCmpExchange =
GetAtomicCmpExchangeFunction(kExprI32AtomicCompareExchange8U);
let i8 = new Uint8Array(memory.buffer);
let params = [0x01, 0x0d, 0xf9];
TestCmpExchange(wasmCmpExchange, i8, params, kMemtypeSize8);
})();