Log Message
[WHLSL] Implement atomic operations and barriers https://bugs.webkit.org/show_bug.cgi?id=189025
Reviewed by Dean Jackson. In the interpreter, atomic operations don't need to be atomic. * WebGPUShadingLanguageRI/Intrinsics.js: (Intrinsics.): * WebGPUShadingLanguageRI/StandardLibrary.js: (let.standardLibrary): * WebGPUShadingLanguageRI/Test.js: (tests.atomics):
Modified Paths
Diff
Modified: trunk/Tools/ChangeLog (236386 => 236387)
--- trunk/Tools/ChangeLog 2018-09-22 12:54:45 UTC (rev 236386)
+++ trunk/Tools/ChangeLog 2018-09-22 23:22:55 UTC (rev 236387)
@@ -1,3 +1,19 @@
+2018-09-22 Myles C. Maxfield <mmaxfi...@apple.com>
+
+ [WHLSL] Implement atomic operations and barriers
+ https://bugs.webkit.org/show_bug.cgi?id=189025
+
+ Reviewed by Dean Jackson.
+
+ In the interpreter, atomic operations don't need to be atomic.
+
+ * WebGPUShadingLanguageRI/Intrinsics.js:
+ (Intrinsics.):
+ * WebGPUShadingLanguageRI/StandardLibrary.js:
+ (let.standardLibrary):
+ * WebGPUShadingLanguageRI/Test.js:
+ (tests.atomics):
+
2018-09-22 Thibault Saunier <tsaun...@igalia.com>
[WPE] Be very permissive in the MiniBrowser.
Modified: trunk/Tools/WebGPUShadingLanguageRI/Intrinsics.js (236386 => 236387)
--- trunk/Tools/WebGPUShadingLanguageRI/Intrinsics.js 2018-09-22 12:54:45 UTC (rev 236386)
+++ trunk/Tools/WebGPUShadingLanguageRI/Intrinsics.js 2018-09-22 23:22:55 UTC (rev 236387)
@@ -230,6 +230,8 @@
"native typedef atomic_int",
type => {
this.atomic_int = type;
+ type.size = 1;
+ type.populateDefaultValue = (buffer, offset) => buffer.set(offset, 0);
});
this._map.set(
@@ -236,6 +238,8 @@
"native typedef atomic_uint",
type => {
this.atomic_uint = type;
+ type.size = 1;
+ type.populateDefaultValue = (buffer, offset) => buffer.set(offset, 0);
});
for (let vectorType of VectorElementTypes) {
@@ -853,6 +857,248 @@
for (let setter of BuiltinMatrixSetter.functions())
this._map.set(setter.toString(), func => setter.instantiateImplementation(func));
+ for (let addressSpace of ["thread", "threadgroup", "device"]) {
+ this._map.set(
+ `native void InterlockedAdd(atomic_uint* ${addressSpace},uint,uint* thread)`,
+ func => {
+ func.implementation = function([atomic, value, originalValue]) {
+ if (!atomic.loadValue())
+ throw new WTrapError("[Atomics]", "Null atomic pointer");
+ let a = atomic.loadValue().loadValue();
+ let b = value.loadValue();
+ let result = castToUint(a + b);
+ if (originalValue.loadValue())
+ originalValue.loadValue().copyFrom(EPtr.box(a), 1);
+ atomic.loadValue().copyFrom(EPtr.box(result), 1);
+ }
+ });
+
+ this._map.set(
+ `native void InterlockedAdd(atomic_int* ${addressSpace},int,int* thread)`,
+ func => {
+ func.implementation = function([atomic, value, originalValue]) {
+ if (!atomic.loadValue())
+ throw new WTrapError("[Atomics]", "Null atomic pointer");
+ let a = atomic.loadValue().loadValue();
+ let b = value.loadValue();
+ let result = castToInt(a + b);
+ if (originalValue.loadValue())
+ originalValue.loadValue().copyFrom(EPtr.box(a), 1);
+ atomic.loadValue().copyFrom(EPtr.box(result), 1);
+ }
+ });
+
+ this._map.set(
+ `native void InterlockedAnd(atomic_uint* ${addressSpace},uint,uint* thread)`,
+ func => {
+ func.implementation = function([atomic, value, originalValue]) {
+ if (!atomic.loadValue())
+ throw new WTrapError("[Atomics]", "Null atomic pointer");
+ let a = atomic.loadValue().loadValue();
+ let b = value.loadValue();
+ let result = castToUint(a & b);
+ if (originalValue.loadValue())
+ originalValue.loadValue().copyFrom(EPtr.box(a), 1);
+ atomic.loadValue().copyFrom(EPtr.box(result), 1);
+ }
+ });
+
+ this._map.set(
+ `native void InterlockedAnd(atomic_int* ${addressSpace},int,int* thread)`,
+ func => {
+ func.implementation = function([atomic, value, originalValue]) {
+ if (!atomic.loadValue())
+ throw new WTrapError("[Atomics]", "Null atomic pointer");
+ let a = atomic.loadValue().loadValue();
+ let b = value.loadValue();
+ let result = castToInt(a & b);
+ if (originalValue.loadValue())
+ originalValue.loadValue().copyFrom(EPtr.box(a), 1);
+ atomic.loadValue().copyFrom(EPtr.box(result), 1);
+ }
+ });
+
+ this._map.set(
+ `native void InterlockedExchange(atomic_uint* ${addressSpace},uint,uint* thread)`,
+ func => {
+ func.implementation = function([atomic, value, originalValue]) {
+ if (!atomic.loadValue())
+ throw new WTrapError("[Atomics]", "Null atomic pointer");
+ let a = atomic.loadValue().loadValue();
+ let b = value.loadValue();
+ if (originalValue.loadValue())
+ originalValue.loadValue().copyFrom(EPtr.box(a), 1);
+ atomic.loadValue().copyFrom(EPtr.box(b), 1);
+ }
+ });
+
+ this._map.set(
+ `native void InterlockedExchange(atomic_int* ${addressSpace},int,int* thread)`,
+ func => {
+ func.implementation = function([atomic, value, originalValue]) {
+ if (!atomic.loadValue())
+ throw new WTrapError("[Atomics]", "Null atomic pointer");
+ let a = atomic.loadValue().loadValue();
+ let b = value.loadValue();
+ if (originalValue.loadValue())
+ originalValue.loadValue().copyFrom(EPtr.box(a), 1);
+ atomic.loadValue().copyFrom(EPtr.box(b), 1);
+ }
+ });
+
+ this._map.set(
+ `native void InterlockedMax(atomic_uint* ${addressSpace},uint,uint* thread)`,
+ func => {
+ func.implementation = function([atomic, value, originalValue]) {
+ if (!atomic.loadValue())
+ throw new WTrapError("[Atomics]", "Null atomic pointer");
+ let a = atomic.loadValue().loadValue();
+ let b = value.loadValue();
+ let result = castToUint(a > b ? a : b);
+ if (originalValue.loadValue())
+ originalValue.loadValue().copyFrom(EPtr.box(a), 1);
+ atomic.loadValue().copyFrom(EPtr.box(result), 1);
+ }
+ });
+
+ this._map.set(
+ `native void InterlockedMax(atomic_int* ${addressSpace},int,int* thread)`,
+ func => {
+ func.implementation = function([atomic, value, originalValue]) {
+ if (!atomic.loadValue())
+ throw new WTrapError("[Atomics]", "Null atomic pointer");
+ let a = atomic.loadValue().loadValue();
+ let b = value.loadValue();
+ let result = castToInt(a > b ? a : b);
+ if (originalValue.loadValue())
+ originalValue.loadValue().copyFrom(EPtr.box(a), 1);
+ atomic.loadValue().copyFrom(EPtr.box(result), 1);
+ }
+ });
+
+ this._map.set(
+ `native void InterlockedMin(atomic_uint* ${addressSpace},uint,uint* thread)`,
+ func => {
+ func.implementation = function([atomic, value, originalValue]) {
+ if (!atomic.loadValue())
+ throw new WTrapError("[Atomics]", "Null atomic pointer");
+ let a = atomic.loadValue().loadValue();
+ let b = value.loadValue();
+ let result = castToUint(a < b ? a : b);
+ if (originalValue.loadValue())
+ originalValue.loadValue().copyFrom(EPtr.box(a), 1);
+ atomic.loadValue().copyFrom(EPtr.box(result), 1);
+ }
+ });
+
+ this._map.set(
+ `native void InterlockedMin(atomic_int* ${addressSpace},int,int* thread)`,
+ func => {
+ func.implementation = function([atomic, value, originalValue]) {
+ if (!atomic.loadValue())
+ throw new WTrapError("[Atomics]", "Null atomic pointer");
+ let a = atomic.loadValue().loadValue();
+ let b = value.loadValue();
+ let result = castToInt(a < b ? a : b);
+ if (originalValue.loadValue())
+ originalValue.loadValue().copyFrom(EPtr.box(a), 1);
+ atomic.loadValue().copyFrom(EPtr.box(result), 1);
+ }
+ });
+
+ this._map.set(
+ `native void InterlockedOr(atomic_uint* ${addressSpace},uint,uint* thread)`,
+ func => {
+ func.implementation = function([atomic, value, originalValue]) {
+ if (!atomic.loadValue())
+ throw new WTrapError("[Atomics]", "Null atomic pointer");
+ let a = atomic.loadValue().loadValue();
+ let b = value.loadValue();
+ let result = castToUint(a | b);
+ if (originalValue.loadValue())
+ originalValue.loadValue().copyFrom(EPtr.box(a), 1);
+ atomic.loadValue().copyFrom(EPtr.box(result), 1);
+ }
+ });
+
+ this._map.set(
+ `native void InterlockedOr(atomic_int* ${addressSpace},int,int* thread)`,
+ func => {
+ func.implementation = function([atomic, value, originalValue]) {
+ if (!atomic.loadValue())
+ throw new WTrapError("[Atomics]", "Null atomic pointer");
+ let a = atomic.loadValue().loadValue();
+ let b = value.loadValue();
+ let result = castToInt(a | b);
+ if (originalValue.loadValue())
+ originalValue.loadValue().copyFrom(EPtr.box(a), 1);
+ atomic.loadValue().copyFrom(EPtr.box(result), 1);
+ }
+ });
+
+ this._map.set(
+ `native void InterlockedXor(atomic_uint* ${addressSpace},uint,uint* thread)`,
+ func => {
+ func.implementation = function([atomic, value, originalValue]) {
+ if (!atomic.loadValue())
+ throw new WTrapError("[Atomics]", "Null atomic pointer");
+ let a = atomic.loadValue().loadValue();
+ let b = value.loadValue();
+ let result = castToUint(a ^ b);
+ if (originalValue.loadValue())
+ originalValue.loadValue().copyFrom(EPtr.box(a), 1);
+ atomic.loadValue().copyFrom(EPtr.box(result), 1);
+ }
+ });
+
+ this._map.set(
+ `native void InterlockedXor(atomic_int* ${addressSpace},int,int* thread)`,
+ func => {
+ func.implementation = function([atomic, value, originalValue]) {
+ if (!atomic.loadValue())
+ throw new WTrapError("[Atomics]", "Null atomic pointer");
+ let a = atomic.loadValue().loadValue();
+ let b = value.loadValue();
+ let result = castToInt(a ^ b);
+ if (originalValue.loadValue())
+ originalValue.loadValue().copyFrom(EPtr.box(a), 1);
+ atomic.loadValue().copyFrom(EPtr.box(result), 1);
+ }
+ });
+
+ this._map.set(
+ `native void InterlockedCompareExchange(atomic_uint* ${addressSpace},uint,uint,uint* thread)`,
+ func => {
+ func.implementation = function([atomic, compareValue, value, originalValue]) {
+ if (!atomic.loadValue())
+ throw new WTrapError("[Atomics]", "Null atomic pointer");
+ let a = atomic.loadValue().loadValue();
+ let b = compareValue.loadValue();
+ let c = value.loadValue();
+ if (a == b)
+ atomic.loadValue().copyFrom(EPtr.box(c), 1);
+ if (originalValue.loadValue())
+ originalValue.loadValue().copyFrom(EPtr.box(a), 1);
+ }
+ });
+
+ this._map.set(
+ `native void InterlockedCompareExchange(atomic_int* ${addressSpace},int,int,int* thread)`,
+ func => {
+ func.implementation = function([atomic, compareValue, value, originalValue]) {
+ if (!atomic.loadValue())
+ throw new WTrapError("[Atomics]", "Null atomic pointer");
+ let a = atomic.loadValue().loadValue();
+ let b = compareValue.loadValue();
+ let c = value.loadValue();
+ if (a == b)
+ atomic.loadValue().copyFrom(EPtr.box(c), 1);
+ if (originalValue.loadValue())
+ originalValue.loadValue().copyFrom(EPtr.box(a), 1);
+ }
+ });
+ }
+
function checkUndefined(origin, explanation, value)
{
if (value == undefined)
Modified: trunk/Tools/WebGPUShadingLanguageRI/StandardLibrary.js (236386 => 236387)
--- trunk/Tools/WebGPUShadingLanguageRI/StandardLibrary.js 2018-09-22 12:54:45 UTC (rev 236386)
+++ trunk/Tools/WebGPUShadingLanguageRI/StandardLibrary.js 2018-09-22 23:22:55 UTC (rev 236387)
@@ -1888,15 +1888,19 @@
}
}
print();
- /*
+
for (let type of [`uint`, `int`]) {
for (let functionName of [`Add`, `And`, `Exchange`, `Max`, `Min`, `Or`, `Xor`]) {
print(`native void Interlocked${functionName}(thread atomic_${type}*, ${type}, thread ${type}*);`);
+ print(`native void Interlocked${functionName}(threadgroup atomic_${type}*, ${type}, thread ${type}*);`);
+ print(`native void Interlocked${functionName}(device atomic_${type}*, ${type}, thread ${type}*);`);
}
print(`native void InterlockedCompareExchange(thread atomic_${type}*, ${type}, ${type}, thread ${type}*);`);
+ print(`native void InterlockedCompareExchange(threadgroup atomic_${type}*, ${type}, ${type}, thread ${type}*);`);
+ print(`native void InterlockedCompareExchange(device atomic_${type}*, ${type}, ${type}, thread ${type}*);`);
}
print();
- */
+
for (let type of [`uchar`, `ushort`, `uint`, `char`, `short`, `int`, `half`, `float`]) {
for (let length of [``, `2`, `3`, `4`]) {
print(`native ${type}${length} Sample(Texture1D<${type}${length}>, sampler, float location);`);
Modified: trunk/Tools/WebGPUShadingLanguageRI/Test.js (236386 => 236387)
--- trunk/Tools/WebGPUShadingLanguageRI/Test.js 2018-09-22 12:54:45 UTC (rev 236386)
+++ trunk/Tools/WebGPUShadingLanguageRI/Test.js 2018-09-22 23:22:55 UTC (rev 236387)
@@ -5803,6 +5803,708 @@
checkInt(program, callFunction(program, "baz", [makeInt(program, 6)]), 14);
}
+tests.atomics = function()
+{
+ let program = doPrep(`
+ test int foo(int z) {
+ atomic_int x;
+ int result;
+ InterlockedAdd(&x, z, &result);
+ return result;
+ }
+ `);
+ checkInt(program, callFunction(program, "foo", [makeInt(program, 6)]), 0);
+ program = doPrep(`
+ test int foo(int z) {
+ atomic_int x;
+ int result;
+ InterlockedAdd(&x, z, &result);
+ InterlockedAdd(&x, z, &result);
+ return result;
+ }
+ `);
+ checkInt(program, callFunction(program, "foo", [makeInt(program, 6)]), 6);
+ program = doPrep(`
+ test int foo(int z) {
+ atomic_int x;
+ int result;
+ InterlockedAdd(&x, z, &result);
+ return int(x);
+ }
+ `);
+ checkInt(program, callFunction(program, "foo", [makeInt(program, 6)]), 6);
+ program = doPrep(`
+ test int foo(int z) {
+ atomic_int x;
+ int result;
+ InterlockedAdd(&x, z, &result);
+ InterlockedAdd(&x, z, &result);
+ return int(x);
+ }
+ `);
+ checkInt(program, callFunction(program, "foo", [makeInt(program, 6)]), 12);
+ program = doPrep(`
+ test uint foo(uint z) {
+ atomic_uint x;
+ uint result;
+ InterlockedAdd(&x, z, &result);
+ return result;
+ }
+ `);
+ checkUint(program, callFunction(program, "foo", [makeUint(program, 6)]), 0);
+ program = doPrep(`
+ test uint foo(uint z) {
+ atomic_uint x;
+ uint result;
+ InterlockedAdd(&x, z, &result);
+ InterlockedAdd(&x, z, &result);
+ return result;
+ }
+ `);
+ checkUint(program, callFunction(program, "foo", [makeUint(program, 6)]), 6);
+ program = doPrep(`
+ test uint foo(uint z) {
+ atomic_uint x;
+ uint result;
+ InterlockedAdd(&x, z, &result);
+ return uint(x);
+ }
+ `);
+ checkUint(program, callFunction(program, "foo", [makeUint(program, 6)]), 6);
+ program = doPrep(`
+ test uint foo(uint z) {
+ atomic_uint x;
+ uint result;
+ InterlockedAdd(&x, z, &result);
+ InterlockedAdd(&x, z, &result);
+ return uint(x);
+ }
+ `);
+ checkUint(program, callFunction(program, "foo", [makeUint(program, 6)]), 12);
+ program = doPrep(`
+ test uint foo(uint x, uint y) {
+ atomic_uint z;
+ uint result;
+ InterlockedAdd(&z, x, &result);
+ InterlockedAnd(&z, y, &result);
+ return uint(z);
+ }
+ `);
+ checkUint(program, callFunction(program, "foo", [makeUint(program, 3), makeUint(program, 5)]), 1);
+ program = doPrep(`
+ test uint foo(uint x, uint y) {
+ atomic_uint z;
+ uint result;
+ InterlockedAdd(&z, x, &result);
+ InterlockedAnd(&z, y, &result);
+ return result;
+ }
+ `);
+ checkUint(program, callFunction(program, "foo", [makeUint(program, 3), makeUint(program, 5)]), 3);
+ program = doPrep(`
+ test int foo(int x, int y) {
+ atomic_int z;
+ int result;
+ InterlockedAdd(&z, x, &result);
+ InterlockedAnd(&z, y, &result);
+ return int(z);
+ }
+ `);
+ checkInt(program, callFunction(program, "foo", [makeInt(program, 3), makeInt(program, 5)]), 1);
+ program = doPrep(`
+ test int foo(int x, int y) {
+ atomic_int z;
+ int result;
+ InterlockedAdd(&z, x, &result);
+ InterlockedAnd(&z, y, &result);
+ return result;
+ }
+ `);
+ checkInt(program, callFunction(program, "foo", [makeInt(program, 3), makeInt(program, 5)]), 3);
+ program = doPrep(`
+ test uint foo(uint x, uint y) {
+ atomic_uint z;
+ uint result;
+ InterlockedAdd(&z, x, &result);
+ InterlockedExchange(&z, y, &result);
+ return uint(z);
+ }
+ `);
+ checkUint(program, callFunction(program, "foo", [makeUint(program, 3), makeUint(program, 5)]), 5);
+ program = doPrep(`
+ test uint foo(uint x, uint y) {
+ atomic_uint z;
+ uint result;
+ InterlockedAdd(&z, x, &result);
+ InterlockedExchange(&z, y, &result);
+ return result;
+ }
+ `);
+ checkUint(program, callFunction(program, "foo", [makeUint(program, 3), makeUint(program, 5)]), 3);
+ program = doPrep(`
+ test int foo(int x, int y) {
+ atomic_int z;
+ int result;
+ InterlockedAdd(&z, x, &result);
+ InterlockedExchange(&z, y, &result);
+ return int(z);
+ }
+ `);
+ checkInt(program, callFunction(program, "foo", [makeInt(program, 3), makeInt(program, 5)]), 5);
+ program = doPrep(`
+ test int foo(int x, int y) {
+ atomic_int z;
+ int result;
+ InterlockedAdd(&z, x, &result);
+ InterlockedExchange(&z, y, &result);
+ return result;
+ }
+ `);
+ checkInt(program, callFunction(program, "foo", [makeInt(program, 3), makeInt(program, 5)]), 3);
+ program = doPrep(`
+ test uint foo(uint x, uint y) {
+ atomic_uint z;
+ uint result;
+ InterlockedAdd(&z, x, &result);
+ InterlockedMax(&z, y, &result);
+ return uint(z);
+ }
+ `);
+ checkUint(program, callFunction(program, "foo", [makeUint(program, 3), makeUint(program, 5)]), 5);
+ checkUint(program, callFunction(program, "foo", [makeUint(program, 5), makeUint(program, 3)]), 5);
+ program = doPrep(`
+ test uint foo(uint x, uint y) {
+ atomic_uint z;
+ uint result;
+ InterlockedAdd(&z, x, &result);
+ InterlockedMax(&z, y, &result);
+ return result;
+ }
+ `);
+ checkUint(program, callFunction(program, "foo", [makeUint(program, 3), makeUint(program, 5)]), 3);
+ checkUint(program, callFunction(program, "foo", [makeUint(program, 5), makeUint(program, 3)]), 5);
+ program = doPrep(`
+ test int foo(int x, int y) {
+ atomic_int z;
+ int result;
+ InterlockedAdd(&z, x, &result);
+ InterlockedMax(&z, y, &result);
+ return int(z);
+ }
+ `);
+ checkInt(program, callFunction(program, "foo", [makeInt(program, 3), makeInt(program, 5)]), 5);
+ checkInt(program, callFunction(program, "foo", [makeInt(program, 5), makeInt(program, 3)]), 5);
+ program = doPrep(`
+ test int foo(int x, int y) {
+ atomic_int z;
+ int result;
+ InterlockedAdd(&z, x, &result);
+ InterlockedMax(&z, y, &result);
+ return result;
+ }
+ `);
+ checkInt(program, callFunction(program, "foo", [makeInt(program, 3), makeInt(program, 5)]), 3);
+ checkInt(program, callFunction(program, "foo", [makeInt(program, 5), makeInt(program, 3)]), 5);
+ program = doPrep(`
+ test uint foo(uint x, uint y) {
+ atomic_uint z;
+ uint result;
+ InterlockedAdd(&z, x, &result);
+ InterlockedMin(&z, y, &result);
+ return uint(z);
+ }
+ `);
+ checkUint(program, callFunction(program, "foo", [makeUint(program, 3), makeUint(program, 5)]), 3);
+ checkUint(program, callFunction(program, "foo", [makeUint(program, 5), makeUint(program, 3)]), 3);
+ program = doPrep(`
+ test uint foo(uint x, uint y) {
+ atomic_uint z;
+ uint result;
+ InterlockedAdd(&z, x, &result);
+ InterlockedMin(&z, y, &result);
+ return result;
+ }
+ `);
+ checkUint(program, callFunction(program, "foo", [makeUint(program, 3), makeUint(program, 5)]), 3);
+ checkUint(program, callFunction(program, "foo", [makeUint(program, 5), makeUint(program, 3)]), 5);
+ program = doPrep(`
+ test int foo(int x, int y) {
+ atomic_int z;
+ int result;
+ InterlockedAdd(&z, x, &result);
+ InterlockedMin(&z, y, &result);
+ return int(z);
+ }
+ `);
+ checkInt(program, callFunction(program, "foo", [makeInt(program, 3), makeInt(program, 5)]), 3);
+ checkInt(program, callFunction(program, "foo", [makeInt(program, 5), makeInt(program, 3)]), 3);
+ program = doPrep(`
+ test int foo(int x, int y) {
+ atomic_int z;
+ int result;
+ InterlockedAdd(&z, x, &result);
+ InterlockedMin(&z, y, &result);
+ return result;
+ }
+ `);
+ checkInt(program, callFunction(program, "foo", [makeInt(program, 3), makeInt(program, 5)]), 3);
+ checkInt(program, callFunction(program, "foo", [makeInt(program, 5), makeInt(program, 3)]), 5);
+ program = doPrep(`
+ test uint foo(uint x, uint y) {
+ atomic_uint z;
+ uint result;
+ InterlockedAdd(&z, x, &result);
+ InterlockedOr(&z, y, &result);
+ return uint(z);
+ }
+ `);
+ checkUint(program, callFunction(program, "foo", [makeUint(program, 3), makeUint(program, 5)]), 7);
+ program = doPrep(`
+ test uint foo(uint x, uint y) {
+ atomic_uint z;
+ uint result;
+ InterlockedAdd(&z, x, &result);
+ InterlockedOr(&z, y, &result);
+ return result;
+ }
+ `);
+ checkUint(program, callFunction(program, "foo", [makeUint(program, 3), makeUint(program, 5)]), 3);
+ program = doPrep(`
+ test int foo(int x, int y) {
+ atomic_int z;
+ int result;
+ InterlockedAdd(&z, x, &result);
+ InterlockedOr(&z, y, &result);
+ return int(z);
+ }
+ `);
+ checkInt(program, callFunction(program, "foo", [makeInt(program, 3), makeInt(program, 5)]), 7);
+ program = doPrep(`
+ test int foo(int x, int y) {
+ atomic_int z;
+ int result;
+ InterlockedAdd(&z, x, &result);
+ InterlockedOr(&z, y, &result);
+ return result;
+ }
+ `);
+ checkInt(program, callFunction(program, "foo", [makeInt(program, 3), makeInt(program, 5)]), 3);
+ program = doPrep(`
+ test uint foo(uint x, uint y) {
+ atomic_uint z;
+ uint result;
+ InterlockedAdd(&z, x, &result);
+ InterlockedXor(&z, y, &result);
+ return uint(z);
+ }
+ `);
+ checkUint(program, callFunction(program, "foo", [makeUint(program, 3), makeUint(program, 5)]), 6);
+ program = doPrep(`
+ test uint foo(uint x, uint y) {
+ atomic_uint z;
+ uint result;
+ InterlockedAdd(&z, x, &result);
+ InterlockedXor(&z, y, &result);
+ return result;
+ }
+ `);
+ checkUint(program, callFunction(program, "foo", [makeUint(program, 3), makeUint(program, 5)]), 3);
+ program = doPrep(`
+ test int foo(int x, int y) {
+ atomic_int z;
+ int result;
+ InterlockedAdd(&z, x, &result);
+ InterlockedXor(&z, y, &result);
+ return int(z);
+ }
+ `);
+ checkInt(program, callFunction(program, "foo", [makeInt(program, 3), makeInt(program, 5)]), 6);
+ program = doPrep(`
+ test int foo(int x, int y) {
+ atomic_int z;
+ int result;
+ InterlockedAdd(&z, x, &result);
+ InterlockedXor(&z, y, &result);
+ return result;
+ }
+ `);
+ checkInt(program, callFunction(program, "foo", [makeInt(program, 3), makeInt(program, 5)]), 3);
+ program = doPrep(`
+ test uint foo(uint x, uint y, uint z) {
+ atomic_uint w;
+ uint result;
+ InterlockedAdd(&w, x, &result);
+ InterlockedCompareExchange(&w, y, z, &result);
+ return uint(w);
+ }
+ `);
+ checkUint(program, callFunction(program, "foo", [makeUint(program, 3), makeUint(program, 3), makeUint(program, 5)]), 5);
+ checkUint(program, callFunction(program, "foo", [makeUint(program, 3), makeUint(program, 4), makeUint(program, 5)]), 3);
+ program = doPrep(`
+ test uint foo(uint x, uint y, uint z) {
+ atomic_uint w;
+ uint result;
+ InterlockedAdd(&w, x, &result);
+ InterlockedCompareExchange(&w, y, z, &result);
+ return result;
+ }
+ `);
+ checkUint(program, callFunction(program, "foo", [makeUint(program, 3), makeUint(program, 3), makeUint(program, 5)]), 3);
+ checkUint(program, callFunction(program, "foo", [makeUint(program, 3), makeUint(program, 4), makeUint(program, 5)]), 3);
+ program = doPrep(`
+ test int foo(int x, int y, int z) {
+ atomic_int w;
+ int result;
+ InterlockedAdd(&w, x, &result);
+ InterlockedCompareExchange(&w, y, z, &result);
+ return int(w);
+ }
+ `);
+ checkInt(program, callFunction(program, "foo", [makeInt(program, 3), makeInt(program, 3), makeInt(program, 5)]), 5);
+ checkInt(program, callFunction(program, "foo", [makeInt(program, 3), makeInt(program, 4), makeInt(program, 5)]), 3);
+ program = doPrep(`
+ test int foo(int x, int y, int z) {
+ atomic_int w;
+ int result;
+ InterlockedAdd(&w, x, &result);
+ InterlockedCompareExchange(&w, y, z, &result);
+ return result;
+ }
+ `);
+ checkInt(program, callFunction(program, "foo", [makeInt(program, 3), makeInt(program, 3), makeInt(program, 5)]), 3);
+ checkInt(program, callFunction(program, "foo", [makeInt(program, 3), makeInt(program, 4), makeInt(program, 5)]), 3);
+}
+
+tests.atomicsNull = function()
+{
+ let program = doPrep(`
+ test int foo(int z) {
+ atomic_int x;
+ InterlockedAdd(&x, z, null);
+ return int(x);
+ }
+ `);
+ checkInt(program, callFunction(program, "foo", [makeInt(program, 6)]), 6);
+ program = doPrep(`
+ test int foo(int z) {
+ atomic_int x;
+ InterlockedAdd(&x, z, null);
+ InterlockedAdd(&x, z, null);
+ return int(x);
+ }
+ `);
+ checkInt(program, callFunction(program, "foo", [makeInt(program, 6)]), 12);
+ program = doPrep(`
+ test uint foo(uint z) {
+ atomic_uint x;
+ InterlockedAdd(&x, z, null);
+ return uint(x);
+ }
+ `);
+ checkUint(program, callFunction(program, "foo", [makeUint(program, 6)]), 6);
+ program = doPrep(`
+ test uint foo(uint z) {
+ atomic_uint x;
+ InterlockedAdd(&x, z, null);
+ InterlockedAdd(&x, z, null);
+ return uint(x);
+ }
+ `);
+ checkUint(program, callFunction(program, "foo", [makeUint(program, 6)]), 12);
+ program = doPrep(`
+ test uint foo(uint x, uint y) {
+ atomic_uint z;
+ InterlockedAdd(&z, x, null);
+ InterlockedAnd(&z, y, null);
+ return uint(z);
+ }
+ `);
+ checkUint(program, callFunction(program, "foo", [makeUint(program, 3), makeUint(program, 5)]), 1);
+ program = doPrep(`
+ test int foo(int x, int y) {
+ atomic_int z;
+ InterlockedAdd(&z, x, null);
+ InterlockedAnd(&z, y, null);
+ return int(z);
+ }
+ `);
+ checkInt(program, callFunction(program, "foo", [makeInt(program, 3), makeInt(program, 5)]), 1);
+ program = doPrep(`
+ test uint foo(uint x, uint y) {
+ atomic_uint z;
+ InterlockedAdd(&z, x, null);
+ InterlockedExchange(&z, y, null);
+ return uint(z);
+ }
+ `);
+ checkUint(program, callFunction(program, "foo", [makeUint(program, 3), makeUint(program, 5)]), 5);
+ program = doPrep(`
+ test int foo(int x, int y) {
+ atomic_int z;
+ InterlockedAdd(&z, x, null);
+ InterlockedExchange(&z, y, null);
+ return int(z);
+ }
+ `);
+ checkInt(program, callFunction(program, "foo", [makeInt(program, 3), makeInt(program, 5)]), 5);
+ program = doPrep(`
+ test uint foo(uint x, uint y) {
+ atomic_uint z;
+ InterlockedAdd(&z, x, null);
+ InterlockedMax(&z, y, null);
+ return uint(z);
+ }
+ `);
+ checkUint(program, callFunction(program, "foo", [makeUint(program, 3), makeUint(program, 5)]), 5);
+ checkUint(program, callFunction(program, "foo", [makeUint(program, 5), makeUint(program, 3)]), 5);
+ program = doPrep(`
+ test int foo(int x, int y) {
+ atomic_int z;
+ InterlockedAdd(&z, x, null);
+ InterlockedMax(&z, y, null);
+ return int(z);
+ }
+ `);
+ checkInt(program, callFunction(program, "foo", [makeInt(program, 3), makeInt(program, 5)]), 5);
+ checkInt(program, callFunction(program, "foo", [makeInt(program, 5), makeInt(program, 3)]), 5);
+ program = doPrep(`
+ test uint foo(uint x, uint y) {
+ atomic_uint z;
+ InterlockedAdd(&z, x, null);
+ InterlockedMin(&z, y, null);
+ return uint(z);
+ }
+ `);
+ checkUint(program, callFunction(program, "foo", [makeUint(program, 3), makeUint(program, 5)]), 3);
+ checkUint(program, callFunction(program, "foo", [makeUint(program, 5), makeUint(program, 3)]), 3);
+ program = doPrep(`
+ test int foo(int x, int y) {
+ atomic_int z;
+ InterlockedAdd(&z, x, null);
+ InterlockedMin(&z, y, null);
+ return int(z);
+ }
+ `);
+ checkInt(program, callFunction(program, "foo", [makeInt(program, 3), makeInt(program, 5)]), 3);
+ checkInt(program, callFunction(program, "foo", [makeInt(program, 5), makeInt(program, 3)]), 3);
+ program = doPrep(`
+ test uint foo(uint x, uint y) {
+ atomic_uint z;
+ InterlockedAdd(&z, x, null);
+ InterlockedOr(&z, y, null);
+ return uint(z);
+ }
+ `);
+ checkUint(program, callFunction(program, "foo", [makeUint(program, 3), makeUint(program, 5)]), 7);
+ program = doPrep(`
+ test int foo(int x, int y) {
+ atomic_int z;
+ InterlockedAdd(&z, x, null);
+ InterlockedOr(&z, y, null);
+ return int(z);
+ }
+ `);
+ checkInt(program, callFunction(program, "foo", [makeInt(program, 3), makeInt(program, 5)]), 7);
+ program = doPrep(`
+ test uint foo(uint x, uint y) {
+ atomic_uint z;
+ InterlockedAdd(&z, x, null);
+ InterlockedXor(&z, y, null);
+ return uint(z);
+ }
+ `);
+ checkUint(program, callFunction(program, "foo", [makeUint(program, 3), makeUint(program, 5)]), 6);
+ program = doPrep(`
+ test int foo(int x, int y) {
+ atomic_int z;
+ InterlockedAdd(&z, x, null);
+ InterlockedXor(&z, y, null);
+ return int(z);
+ }
+ `);
+ checkInt(program, callFunction(program, "foo", [makeInt(program, 3), makeInt(program, 5)]), 6);
+ program = doPrep(`
+ test uint foo(uint x, uint y, uint z) {
+ atomic_uint w;
+ InterlockedAdd(&w, x, null);
+ InterlockedCompareExchange(&w, y, z, null);
+ return uint(w);
+ }
+ `);
+ checkUint(program, callFunction(program, "foo", [makeUint(program, 3), makeUint(program, 3), makeUint(program, 5)]), 5);
+ checkUint(program, callFunction(program, "foo", [makeUint(program, 3), makeUint(program, 4), makeUint(program, 5)]), 3);
+ program = doPrep(`
+ test int foo(int x, int y, int z) {
+ atomic_int w;
+ InterlockedAdd(&w, x, null);
+ InterlockedCompareExchange(&w, y, z, null);
+ return int(w);
+ }
+ `);
+ checkInt(program, callFunction(program, "foo", [makeInt(program, 3), makeInt(program, 3), makeInt(program, 5)]), 5);
+ checkInt(program, callFunction(program, "foo", [makeInt(program, 3), makeInt(program, 4), makeInt(program, 5)]), 3);
+
+ program = doPrep(`
+ test void foo() {
+ thread atomic_int* x = null;
+ InterlockedAdd(x, 1, null);
+ }
+ `);
+ checkFail(
+ () => callFunction(program, "foo", []),
+ (e) => e instanceof WTrapError);
+
+ program = doPrep(`
+ test void foo() {
+ thread atomic_uint* x = null;
+ InterlockedAdd(x, 1, null);
+ }
+ `);
+ checkFail(
+ () => callFunction(program, "foo", []),
+ (e) => e instanceof WTrapError);
+
+ program = doPrep(`
+ test void foo() {
+ thread atomic_int* x = null;
+ InterlockedAnd(x, 1, null);
+ }
+ `);
+ checkFail(
+ () => callFunction(program, "foo", []),
+ (e) => e instanceof WTrapError);
+
+ program = doPrep(`
+ test void foo() {
+ thread atomic_uint* x = null;
+ InterlockedAnd(x, 1, null);
+ }
+ `);
+ checkFail(
+ () => callFunction(program, "foo", []),
+ (e) => e instanceof WTrapError);
+
+ program = doPrep(`
+ test void foo() {
+ thread atomic_int* x = null;
+ InterlockedExchange(x, 1, null);
+ }
+ `);
+ checkFail(
+ () => callFunction(program, "foo", []),
+ (e) => e instanceof WTrapError);
+
+ program = doPrep(`
+ test void foo() {
+ thread atomic_uint* x = null;
+ InterlockedExchange(x, 1, null);
+ }
+ `);
+ checkFail(
+ () => callFunction(program, "foo", []),
+ (e) => e instanceof WTrapError);
+
+ program = doPrep(`
+ test void foo() {
+ thread atomic_int* x = null;
+ InterlockedMax(x, 1, null);
+ }
+ `);
+ checkFail(
+ () => callFunction(program, "foo", []),
+ (e) => e instanceof WTrapError);
+
+ program = doPrep(`
+ test void foo() {
+ thread atomic_uint* x = null;
+ InterlockedMax(x, 1, null);
+ }
+ `);
+ checkFail(
+ () => callFunction(program, "foo", []),
+ (e) => e instanceof WTrapError);
+
+ program = doPrep(`
+ test void foo() {
+ thread atomic_int* x = null;
+ InterlockedMin(x, 1, null);
+ }
+ `);
+ checkFail(
+ () => callFunction(program, "foo", []),
+ (e) => e instanceof WTrapError);
+
+ program = doPrep(`
+ test void foo() {
+ thread atomic_uint* x = null;
+ InterlockedMin(x, 1, null);
+ }
+ `);
+ checkFail(
+ () => callFunction(program, "foo", []),
+ (e) => e instanceof WTrapError);
+
+ program = doPrep(`
+ test void foo() {
+ thread atomic_int* x = null;
+ InterlockedOr(x, 1, null);
+ }
+ `);
+ checkFail(
+ () => callFunction(program, "foo", []),
+ (e) => e instanceof WTrapError);
+
+ program = doPrep(`
+ test void foo() {
+ thread atomic_uint* x = null;
+ InterlockedOr(x, 1, null);
+ }
+ `);
+ checkFail(
+ () => callFunction(program, "foo", []),
+ (e) => e instanceof WTrapError);
+
+ program = doPrep(`
+ test void foo() {
+ thread atomic_int* x = null;
+ InterlockedXor(x, 1, null);
+ }
+ `);
+ checkFail(
+ () => callFunction(program, "foo", []),
+ (e) => e instanceof WTrapError);
+
+ program = doPrep(`
+ test void foo() {
+ thread atomic_uint* x = null;
+ InterlockedXor(x, 1, null);
+ }
+ `);
+ checkFail(
+ () => callFunction(program, "foo", []),
+ (e) => e instanceof WTrapError);
+
+ program = doPrep(`
+ test void foo() {
+ thread atomic_int* x = null;
+ InterlockedCompareExchange(x, 1, 2, null);
+ }
+ `);
+ checkFail(
+ () => callFunction(program, "foo", []),
+ (e) => e instanceof WTrapError);
+
+ program = doPrep(`
+ test void foo() {
+ thread atomic_uint* x = null;
+ InterlockedCompareExchange(x, 1, 2, null);
+ }
+ `);
+ checkFail(
+ () => callFunction(program, "foo", []),
+ (e) => e instanceof WTrapError);
+}
+
tests.pointerToMember = function()
{
checkFail(
_______________________________________________ webkit-changes mailing list webkit-changes@lists.webkit.org https://lists.webkit.org/mailman/listinfo/webkit-changes