2 * Copyright (C) 2018 Apple Inc. All rights reserved.
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 this.print = (text) => {
29 var span = document.createElement("pre");
30 document.getElementById("messages").appendChild(span);
31 span.innerText = text;
32 window.scrollTo(0,document.body.scrollHeight);
34 this.preciseTime = () => performance.now() / 1000;
40 return prepare("/internal/test", 0, code);
45 let lexer = new Lexer("/internal/test", "native", 0, code);
48 let next = lexer.next();
56 function makeInt(program, value)
58 return TypedValue.box(program.intrinsics.int, castAndCheckValue(castToInt, value));
61 function makeUint(program, value)
63 return TypedValue.box(program.intrinsics.uint, castAndCheckValue(castToUint, value));
66 function makeUchar(program, value)
68 return TypedValue.box(program.intrinsics.uchar, castAndCheckValue(castToUchar, value));
71 function makeBool(program, value)
73 return TypedValue.box(program.intrinsics.bool, castAndCheckValue(castToBool, value));
76 function makeFloat(program, value)
78 return TypedValue.box(program.intrinsics.float, castAndCheckValue(castToFloat, value));
81 function makeCastedFloat(program, value)
83 return TypedValue.box(program.intrinsics.float, castToFloat(value));
86 function makeHalf(program, value)
88 return TypedValue.box(program.intrinsics.half, castAndCheckValue(castToHalf, value));
91 function makeEnum(program, enumName, value)
93 let enumType = program.types.get(enumName);
95 throw new Error("No type named " + enumName);
96 let enumMember = enumType.memberByName(value);
98 throw new Error("No member named " + enumMember + " in " + enumType);
99 return TypedValue.box(enumType, enumMember.value.unifyNode.valueForSelectedType);
102 function makeSampler(program, options)
104 // enum WebGPUAddressMode {
108 // "clampToBorderColor"
111 // enum WebGPUFilterMode {
116 // enum WebGPUCompareFunction {
127 // enum WebGPUBorderColor {
128 // "transparentBlack",
133 // dictionary WebGPUSamplerDescriptor {
134 // WebGPUddressMode rAddressMode = "clampToEdge";
135 // WebGPUddressMode sAddressMode = "clampToEdge";
136 // WebGPUddressMode tAddressMode = "clampToEdge";
137 // WebGPUFilterModeEnum magFilter = "nearest";
138 // WebGPUFilterModeEnum minFilter = "nearest";
139 // WebGPUFilterModeEnum mipmapFilter = "nearest";
140 // float lodMinClamp = 0;
141 // float lodMaxClamp = Number.MAX_VALUE;
142 // unsigned long maxAnisotropy = 1;
143 // WebGPUCompareFunction compareFunction = "never";
144 // WebGPUBorderColor borderColor = "transparentBlack";
146 return TypedValue.box(program.intrinsics.sampler, new Sampler(options));
149 function make1DTexture(program, mipmaps, elementType)
151 return TypedValue.box(program.intrinsics[`Texture1D<${elementType}>`], new Texture1D(elementType, mipmaps));
154 function make1DTextureArray(program, array, elementType)
156 return TypedValue.box(program.intrinsics[`Texture1DArray<${elementType}>`], new Texture1DArray(elementType, array));
159 function make2DTexture(program, mipmaps, elementType)
161 return TypedValue.box(program.intrinsics[`Texture2D<${elementType}>`], new Texture2D(elementType, mipmaps));
164 function make2DTextureArray(program, array, elementType)
166 return TypedValue.box(program.intrinsics[`Texture2DArray<${elementType}>`], new Texture2DArray(elementType, array));
169 function make3DTexture(program, mipmaps, elementType)
171 return TypedValue.box(program.intrinsics[`Texture3D<${elementType}>`], new Texture3D(elementType, mipmaps));
174 function makeTextureCube(program, array, elementType)
176 return TypedValue.box(program.intrinsics[`TextureCube<${elementType}>`], new TextureCube(elementType, array));
179 function makeRW1DTexture(program, elements, elementType)
181 return TypedValue.box(program.intrinsics[`RWTexture1D<${elementType}>`], new Texture1DRW(elementType, elements));
184 function makeRW1DTextureArray(program, array, elementType)
186 return TypedValue.box(program.intrinsics[`RWTexture1DArray<${elementType}>`], new Texture1DArrayRW(elementType, array));
189 function makeRW2DTexture(program, rows, elementType)
191 return TypedValue.box(program.intrinsics[`RWTexture2D<${elementType}>`], new Texture2DRW(elementType, rows));
194 function makeRW2DTextureArray(program, array, elementType)
196 return TypedValue.box(program.intrinsics[`RWTexture2DArray<${elementType}>`], new Texture2DArrayRW(elementType, array));
199 function makeRW3DTexture(program, depthSlices, elementType)
201 return TypedValue.box(program.intrinsics[`RWTexture3D<${elementType}>`], new Texture3DRW(elementType, depthSlices));
204 function make2DDepthTexture(program, mipmaps, elementType)
206 return TypedValue.box(program.intrinsics[`TextureDepth2D<${elementType}>`], new TextureDepth2D(elementType, mipmaps));
209 function make2DDepthTextureArray(program, array, elementType)
211 return TypedValue.box(program.intrinsics[`TextureDepth2DArray<${elementType}>`], new TextureDepth2DArray(elementType, array));
214 function makeDepthTextureCube(program, array, elementType)
216 return TypedValue.box(program.intrinsics[`TextureDepthCube<${elementType}>`], new TextureDepthCube(elementType, array));
219 function makeRW2DDepthTexture(program, rows, elementType)
221 return TypedValue.box(program.intrinsics[`RWTextureDepth2D<${elementType}>`], new TextureDepth2DRW(elementType, rows));
224 function makeRW2DDepthTextureArray(program, array, elementType)
226 return TypedValue.box(program.intrinsics[`RWTextureDepth2DArray<${elementType}>`], new TextureDepth2DArrayRW(elementType, array));
229 function checkInt(program, result, expected)
231 if (!result.type.equals(program.intrinsics.int))
232 throw new Error("Wrong result type; result: " + result);
233 if (result.value != expected)
234 throw new Error(`Wrong result: ${result.value} (expected ${expected})`);
237 function checkEnum(program, result, expected)
239 if (!(result.type.unifyNode instanceof EnumType))
240 throw new Error("Wrong result type; result: " + result);
241 if (result.value != expected)
242 throw new Error("Wrong result: " + result.value + " (expected " + expected + ")");
245 function checkUint(program, result, expected)
247 if (!result.type.equals(program.intrinsics.uint))
248 throw new Error("Wrong result type: " + result.type);
249 if (result.value != expected)
250 throw new Error("Wrong result: " + result.value + " (expected " + expected + ")");
253 function checkUchar(program, result, expected)
255 if (!result.type.equals(program.intrinsics.uchar))
256 throw new Error("Wrong result type: " + result.type);
257 if (result.value != expected)
258 throw new Error("Wrong result: " + result.value + " (expected " + expected + ")");
261 function checkBool(program, result, expected)
263 if (!result.type.equals(program.intrinsics.bool))
264 throw new Error("Wrong result type: " + result.type);
265 if (result.value != expected)
266 throw new Error("Wrong result: " + result.value + " (expected " + expected + ")");
269 function checkFloat(program, result, expected)
271 if (!result.type.equals(program.intrinsics.float))
272 throw new Error("Wrong result type: " + result.type);
273 if (result.value != expected)
274 throw new Error("Wrong result: " + result.value + " (expected " + expected + ")");
277 function checkHalf(program, result, expected)
279 if (!result.type.equals(program.intrinsics.half))
280 throw new Error("Wrong result type: " + result.type);
281 if (result.value != expected)
282 throw new Error("Wrong result: " + result.value + " (expected " + expected + ")");
285 function checkFloat4(program, result, expected)
287 if (!result.type.equals(program.intrinsics["vector<float, 4>"]))
288 throw new Error("Wrong result type: " + result.type);
289 if (result.ePtr.get(0) != expected[0] || result.ePtr.get(1) != expected[1] || result.ePtr.get(2) != expected[2] || result.ePtr.get(3) != expected[3])
290 throw new Error("Wrong result: [" + result.ePtr.get(0) + ", " + result.ePtr.get(1) + ", " + result.ePtr.get(2) + ", " + result.ePtr.get(3) + "] (expected [" + expected[0] + ", " + expected[1] + ", " + expected[2] + ", " + expected[3] + "])");
293 function checkLexerToken(result, expectedIndex, expectedKind, expectedText)
295 if (result._index != expectedIndex)
296 throw new Error("Wrong lexer index; result: " + result._index + " (expected " + expectedIndex + ")");
297 if (result._kind != expectedKind)
298 throw new Error("Wrong lexer kind; result: " + result._kind + " (expected " + expectedKind + ")");
299 if (result._text != expectedText)
300 throw new Error("Wrong lexer text; result: " + result._text + " (expected " + expectedText + ")");
303 function checkFail(callback, predicate)
307 throw new Error("Did not throw exception");
310 print(" Caught: " + e);
317 function checkTrap(program, callback, checkFunction)
319 const result = callback();
320 // FIXME: Rewrite tests so that they return non-zero values in the case that they didn't trap.
321 // The check function is optional in the case of a void return type.
322 checkFunction(program, result, 0);
323 if (!Evaluator.lastInvocationDidTrap)
324 throw new Error("Did not trap");
328 let okToTest = false;
330 tests = new Proxy({}, {
331 set(target, property, value, receiver)
333 if (property in target)
334 throw new Error("Trying to declare duplicate test: " + property);
335 target[property] = value;
340 tests.ternaryExpression = function() {
341 let program = doPrep(`
344 return x < 3 ? 4 : 5;
348 return x < 10 ? 11 : x < 12 ? 14 : 15;
352 return 3 < 4 ? x : 5;
355 checkInt(program, callFunction(program, "foo", [makeInt(program, 767)]), 5);
356 checkInt(program, callFunction(program, "foo", [makeInt(program, 2)]), 4);
357 checkInt(program, callFunction(program, "bar", [makeInt(program, 8)]), 11);
358 checkInt(program, callFunction(program, "bar", [makeInt(program, 9)]), 11);
359 checkInt(program, callFunction(program, "bar", [makeInt(program, 10)]), 14);
360 checkInt(program, callFunction(program, "bar", [makeInt(program, 11)]), 14);
361 checkInt(program, callFunction(program, "bar", [makeInt(program, 12)]), 15);
362 checkInt(program, callFunction(program, "bar", [makeInt(program, 13)]), 15);
363 checkInt(program, callFunction(program, "baz", [makeInt(program, 14)]), 14);
372 (e) => e instanceof WTypeError);
379 (0 < 1 ? x : y) = 42;
383 (e) => e instanceof WTypeError && e.message.indexOf("not an LValue") != -1);
390 thread int* z = &(0 < 1 ? x : y);
394 (e) => e instanceof WTypeError && e.message.indexOf("not an LValue") != -1);
401 thread int[] z = @(0 < 1 ? x : y);
405 (e) => e instanceof WTypeError && e.message.indexOf("not an LValue") != -1);
412 return 4 < 5 ? x : y;
415 (e) => e instanceof WTypeError);
420 return 4 < 5 ? 6 : 7.0;
423 (e) => e instanceof WTypeError);
426 tests.literalBool = function() {
427 let program = doPrep("test bool foo() { return true; }");
428 checkBool(program, callFunction(program, "foo", []), true);
431 tests.identityBool = function() {
432 let program = doPrep("test bool foo(bool x) { return x; }");
433 checkBool(program, callFunction(program, "foo", [makeBool(program, true)]), true);
434 checkBool(program, callFunction(program, "foo", [makeBool(program, false)]), false);
437 tests.intSimpleMath = function() {
438 let program = doPrep("test int foo(int x, int y) { return x + y; }");
439 checkInt(program, callFunction(program, "foo", [makeInt(program, 7), makeInt(program, 5)]), 12);
440 program = doPrep("test int foo(int x, int y) { return x - y; }");
441 checkInt(program, callFunction(program, "foo", [makeInt(program, 7), makeInt(program, 5)]), 2);
442 checkInt(program, callFunction(program, "foo", [makeInt(program, 5), makeInt(program, 7)]), -2);
443 program = doPrep("test int foo(int x, int y) { return x * y; }");
444 checkInt(program, callFunction(program, "foo", [makeInt(program, 7), makeInt(program, 5)]), 35);
445 checkInt(program, callFunction(program, "foo", [makeInt(program, 7), makeInt(program, -5)]), -35);
446 program = doPrep("test int foo(int x, int y) { return x / y; }");
447 checkInt(program, callFunction(program, "foo", [makeInt(program, 7), makeInt(program, 2)]), 3);
448 checkInt(program, callFunction(program, "foo", [makeInt(program, 7), makeInt(program, -2)]), -3);
451 tests.incrementAndDecrement = function() {
452 let program = doPrep(`
453 test int foo1() { int x = 0; return x++; }
454 test int foo2() { int x = 0; x++; return x; }
455 test int foo3() { int x = 0; return ++x; }
456 test int foo4() { int x = 0; ++x; return x; }
457 test int foo5() { int x = 0; return x--; }
458 test int foo6() { int x = 0; x--; return x; }
459 test int foo7() { int x = 0; return --x; }
460 test int foo8() { int x = 0; --x; return x; }
462 checkInt(program, callFunction(program, "foo1", []), 0);
463 checkInt(program, callFunction(program, "foo2", []), 1);
464 checkInt(program, callFunction(program, "foo3", []), 1);
465 checkInt(program, callFunction(program, "foo4", []), 1);
466 checkInt(program, callFunction(program, "foo5", []), 0);
467 checkInt(program, callFunction(program, "foo6", []), -1);
468 checkInt(program, callFunction(program, "foo7", []), -1);
469 checkInt(program, callFunction(program, "foo8", []), -1);
472 tests.uintSimpleMath = function() {
473 let program = doPrep("test uint foo(uint x, uint y) { return x + y; }");
474 checkUint(program, callFunction(program, "foo", [makeUint(program, 7), makeUint(program, 5)]), 12);
475 program = doPrep("test uint foo(uint x, uint y) { return x - y; }");
476 checkUint(program, callFunction(program, "foo", [makeUint(program, 7), makeUint(program, 5)]), 2);
477 checkUint(program, callFunction(program, "foo", [makeUint(program, 5), makeUint(program, 7)]), 4294967294);
478 program = doPrep("test uint foo(uint x, uint y) { return x * y; }");
479 checkUint(program, callFunction(program, "foo", [makeUint(program, 7), makeUint(program, 5)]), 35);
480 program = doPrep("test uint foo(uint x, uint y) { return x / y; }");
481 checkUint(program, callFunction(program, "foo", [makeUint(program, 7), makeUint(program, 2)]), 3);
484 tests.ucharSimpleMath = function() {
485 let program = doPrep("test uchar foo(uchar x, uchar y) { return x + y; }");
486 checkUchar(program, callFunction(program, "foo", [makeUchar(program, 7), makeUchar(program, 5)]), 12);
487 program = doPrep("test uchar foo(uchar x, uchar y) { return x - y; }");
488 checkUchar(program, callFunction(program, "foo", [makeUchar(program, 7), makeUchar(program, 5)]), 2);
489 checkUchar(program, callFunction(program, "foo", [makeUchar(program, 5), makeUchar(program, 7)]), 254);
490 program = doPrep("test uchar foo(uchar x, uchar y) { return x * y; }");
491 checkUchar(program, callFunction(program, "foo", [makeUchar(program, 7), makeUchar(program, 5)]), 35);
492 program = doPrep("test uchar foo(uchar x, uchar y) { return x / y; }");
493 checkUchar(program, callFunction(program, "foo", [makeUchar(program, 7), makeUchar(program, 2)]), 3);
496 tests.equality = function() {
497 let program = doPrep("test bool foo(uint x, uint y) { return x == y; }");
498 checkBool(program, callFunction(program, "foo", [makeUint(program, 7), makeUint(program, 5)]), false);
499 checkBool(program, callFunction(program, "foo", [makeUint(program, 7), makeUint(program, 7)]), true);
500 program = doPrep("test bool foo(uchar x, uchar y) { return x == y; }");
501 checkBool(program, callFunction(program, "foo", [makeUchar(program, 7), makeUchar(program, 5)]), false);
502 checkBool(program, callFunction(program, "foo", [makeUchar(program, 7), makeUchar(program, 7)]), true);
503 program = doPrep("test bool foo(int x, int y) { return x == y; }");
504 checkBool(program, callFunction(program, "foo", [makeInt(program, 7), makeInt(program, 5)]), false);
505 checkBool(program, callFunction(program, "foo", [makeInt(program, 7), makeInt(program, 7)]), true);
506 program = doPrep("test bool foo(bool x, bool y) { return x == y; }");
507 checkBool(program, callFunction(program, "foo", [makeBool(program, false), makeBool(program, true)]), false);
508 checkBool(program, callFunction(program, "foo", [makeBool(program, true), makeBool(program, false)]), false);
509 checkBool(program, callFunction(program, "foo", [makeBool(program, false), makeBool(program, false)]), true);
510 checkBool(program, callFunction(program, "foo", [makeBool(program, true), makeBool(program, true)]), true);
513 tests.logicalNegation = function()
515 let program = doPrep("test bool foo(bool x) { return !x; }");
516 checkBool(program, callFunction(program, "foo", [makeBool(program, true)]), false);
517 checkBool(program, callFunction(program, "foo", [makeBool(program, false)]), true);
520 tests.notEquality = function() {
521 let program = doPrep("test bool foo(uint x, uint y) { return x != y; }");
522 checkBool(program, callFunction(program, "foo", [makeUint(program, 7), makeUint(program, 5)]), true);
523 checkBool(program, callFunction(program, "foo", [makeUint(program, 7), makeUint(program, 7)]), false);
524 program = doPrep("test bool foo(uchar x, uchar y) { return x != y; }");
525 checkBool(program, callFunction(program, "foo", [makeUchar(program, 7), makeUchar(program, 5)]), true);
526 checkBool(program, callFunction(program, "foo", [makeUchar(program, 7), makeUchar(program, 7)]), false);
527 program = doPrep("test bool foo(int x, int y) { return x != y; }");
528 checkBool(program, callFunction(program, "foo", [makeInt(program, 7), makeInt(program, 5)]), true);
529 checkBool(program, callFunction(program, "foo", [makeInt(program, 7), makeInt(program, 7)]), false);
530 program = doPrep("test bool foo(bool x, bool y) { return x != y; }");
531 checkBool(program, callFunction(program, "foo", [makeBool(program, false), makeBool(program, true)]), true);
532 checkBool(program, callFunction(program, "foo", [makeBool(program, true), makeBool(program, false)]), true);
533 checkBool(program, callFunction(program, "foo", [makeBool(program, false), makeBool(program, false)]), false);
534 checkBool(program, callFunction(program, "foo", [makeBool(program, true), makeBool(program, true)]), false);
537 tests.equalityTypeFailure = function()
540 () => doPrep("test bool foo(int x, uint y) { return x == y; }"),
541 (e) => e instanceof WTypeError && e.message.indexOf("/internal/test:1") != -1);
544 tests.generalNegation = function()
546 let program = doPrep("test bool foo(int x) { return !x; }");
547 checkBool(program, callFunction(program, "foo", [makeInt(program, 7)]), false);
548 checkBool(program, callFunction(program, "foo", [makeInt(program, 0)]), true);
551 tests.add1 = function() {
552 let program = doPrep("test int foo(int x) { return x + 1; }");
553 checkInt(program, callFunction(program, "foo", [makeInt(program, 42)]), 43);
556 tests.nameResolutionFailure = function()
559 () => doPrep("int foo(int x) { return x + y; }"),
560 (e) => e instanceof WTypeError && e.message.indexOf("/internal/test:1") != -1);
563 tests.simpleVariable = function()
565 let program = doPrep(`
572 checkInt(program, callFunction(program, "foo", [makeInt(program, 42)]), 42);
575 tests.simpleAssignment = function()
577 let program = doPrep(`
585 checkInt(program, callFunction(program, "foo", [makeInt(program, 42)]), 42);
588 tests.simpleDefault = function()
590 let program = doPrep(`
597 checkInt(program, callFunction(program, "foo", []), 0);
600 tests.simpleDereference = function()
602 let program = doPrep(`
603 test int foo(device int* p)
608 let buffer = new EBuffer(1);
610 checkInt(program, callFunction(program, "foo", [TypedValue.box(new PtrType(externalOrigin, "device", program.intrinsics.int), new EPtr(buffer, 0))]), 13);
613 tests.dereferenceStore = function()
615 let program = doPrep(`
616 test void foo(device int* p)
621 let buffer = new EBuffer(1);
623 callFunction(program, "foo", [TypedValue.box(new PtrType(externalOrigin, "device", program.intrinsics.int), new EPtr(buffer, 0))]);
624 if (buffer.get(0) != 52)
625 throw new Error("Expected buffer to contain 52 but it contains: " + buffer.get(0));
628 tests.simpleMakePtr = function()
630 let program = doPrep(`
631 test thread int* foo()
637 let result = callFunction(program, "foo", []);
638 if (!result.type.isPtr)
639 throw new Error("Return type is not a pointer: " + result.type);
640 if (!result.type.elementType.equals(program.intrinsics.int))
641 throw new Error("Return type is not a pointer to an int: " + result.type);
642 if (!(result.value instanceof EPtr))
643 throw new Error("Return value is not an EPtr: " + result.value);
644 let value = result.value.loadValue();
646 throw new Error("Expected 42 but got: " + value);
649 tests.threadArrayRefLoad = function()
651 let program = doPrep(`
652 test int foo(thread int[] array)
657 let buffer = new EBuffer(1);
659 let result = callFunction(program, "foo", [TypedValue.box(new ArrayRefType(externalOrigin, "thread", program.intrinsics.int), new EArrayRef(new EPtr(buffer, 0), 1))]);
660 checkInt(program, result, 89);
663 tests.threadArrayRefLoadIntLiteral = function()
665 let program = doPrep(`
666 test int foo(thread int[] array)
671 let buffer = new EBuffer(1);
673 let result = callFunction(program, "foo", [TypedValue.box(new ArrayRefType(externalOrigin, "thread", program.intrinsics.int), new EArrayRef(new EPtr(buffer, 0), 1))]);
674 checkInt(program, result, 89);
677 tests.deviceArrayRefLoad = function()
679 let program = doPrep(`
680 test int foo(device int[] array)
685 let buffer = new EBuffer(1);
687 let result = callFunction(program, "foo", [TypedValue.box(new ArrayRefType(externalOrigin, "device", program.intrinsics.int), new EArrayRef(new EPtr(buffer, 0), 1))]);
688 checkInt(program, result, 89);
691 tests.threadArrayRefStore = function()
693 let program = doPrep(`
694 test void foo(thread int[] array, int value)
699 let buffer = new EBuffer(1);
701 let arrayRef = TypedValue.box(
702 new ArrayRefType(externalOrigin, "thread", program.intrinsics.int),
703 new EArrayRef(new EPtr(buffer, 0), 1));
704 callFunction(program, "foo", [arrayRef, makeInt(program, 65)]);
705 if (buffer.get(0) != 65)
706 throw new Error("Bad value stored into buffer (expected 65): " + buffer.get(0));
707 callFunction(program, "foo", [arrayRef, makeInt(program, -111)]);
708 if (buffer.get(0) != -111)
709 throw new Error("Bad value stored into buffer (expected -111): " + buffer.get(0));
712 tests.deviceArrayRefStore = function()
714 let program = doPrep(`
715 test void foo(device int[] array, int value)
720 let buffer = new EBuffer(1);
722 let arrayRef = TypedValue.box(
723 new ArrayRefType(externalOrigin, "device", program.intrinsics.int),
724 new EArrayRef(new EPtr(buffer, 0), 1));
725 callFunction(program, "foo", [arrayRef, makeInt(program, 65)]);
726 if (buffer.get(0) != 65)
727 throw new Error("Bad value stored into buffer (expected 65): " + buffer.get(0));
728 callFunction(program, "foo", [arrayRef, makeInt(program, -111)]);
729 if (buffer.get(0) != -111)
730 throw new Error("Bad value stored into buffer (expected -111): " + buffer.get(0));
733 tests.deviceArrayRefStoreIntLiteral = function()
735 let program = doPrep(`
736 test void foo(device int[] array, int value)
741 let buffer = new EBuffer(1);
743 let arrayRef = TypedValue.box(
744 new ArrayRefType(externalOrigin, "device", program.intrinsics.int),
745 new EArrayRef(new EPtr(buffer, 0), 1));
746 callFunction(program, "foo", [arrayRef, makeInt(program, 65)]);
747 if (buffer.get(0) != 65)
748 throw new Error("Bad value stored into buffer (expected 65): " + buffer.get(0));
749 callFunction(program, "foo", [arrayRef, makeInt(program, -111)]);
750 if (buffer.get(0) != -111)
751 throw new Error("Bad value stored into buffer (expected -111): " + buffer.get(0));
754 tests.threadPointerLoad = function()
756 let program = doPrep(`
757 test int foo(thread int* ptr)
762 let buffer = new EBuffer(1);
764 let result = callFunction(program, "foo", [TypedValue.box(new PtrType(externalOrigin, "thread", program.intrinsics.int), new EPtr(buffer, 0))]);
765 checkInt(program, result, 89);
768 tests.threadPointerStore = function()
770 let program = doPrep(`
771 test void foo(thread int* ptr, int value)
776 let buffer = new EBuffer(1);
778 let pointer = TypedValue.box(new PtrType(externalOrigin, "thread", program.intrinsics.int), new EPtr(buffer, 0));
779 callFunction(program, "foo", [pointer, makeInt(program, 123)]);
780 if (buffer.get(0) != 123)
781 throw new Error("Bad value stored into buffer (expected 123): " + buffer.get(0));
782 callFunction(program, "foo", [pointer, makeInt(program, 321)]);
783 if (buffer.get(0) != 321)
784 throw new Error("Bad value stored into buffer (expected 321): " + buffer.get(0));
787 tests.devicePointerLoad = function()
789 let program = doPrep(`
790 test int foo(device int* ptr)
795 let buffer = new EBuffer(1);
797 let result = callFunction(program, "foo", [TypedValue.box(new PtrType(externalOrigin, "device", program.intrinsics.int), new EPtr(buffer, 0))]);
798 checkInt(program, result, 89);
801 tests.devicePointerStore = function()
803 let program = doPrep(`
804 test void foo(device int* ptr, int value)
809 let buffer = new EBuffer(1);
811 let pointer = TypedValue.box(new PtrType(externalOrigin, "device", program.intrinsics.int), new EPtr(buffer, 0));
812 callFunction(program, "foo", [pointer, makeInt(program, 123)]);
813 if (buffer.get(0) != 123)
814 throw new Error("Bad value stored into buffer (expected 123): " + buffer.get(0));
815 callFunction(program, "foo", [pointer, makeInt(program, 321)]);
816 if (buffer.get(0) != 321)
817 throw new Error("Bad value stored into buffer (expected 321): " + buffer.get(0));
820 tests.arrayLoad = function()
822 let program = doPrep(`
823 typedef IntArray = int[3];
824 test int foo(IntArray a)
828 test int bar(IntArray a)
832 test int baz(IntArray a)
837 let buffer = new EBuffer(3);
841 let array = new TypedValue(program.types.get("IntArray").type, new EPtr(buffer, 0));
842 let result = callFunction(program, "foo", [array]);
843 checkInt(program, result, 89);
844 result = callFunction(program, "bar", [array]);
845 checkInt(program, result, 91);
846 result = callFunction(program, "baz", [array]);
847 checkInt(program, result, 103);
850 tests.typeMismatchReturn = function()
859 (e) => e instanceof WTypeError);
862 tests.typeMismatchVariableDecl = function()
871 (e) => e instanceof WTypeError);
874 tests.typeMismatchAssignment = function()
884 (e) => e instanceof WTypeError);
887 tests.typeMismatchReturnParam = function()
896 (e) => e instanceof WTypeError);
899 tests.badAdd = function()
903 void foo(int x, uint y)
908 (e) => e instanceof WTypeError && e.message.indexOf("native int operator+(int,int)") != -1);
911 tests.lexerKeyword = function()
913 let result = doLex("ident for while 123 123u { } {asd asd{ 1a3 1.2 + 3.4 + 1. + .2 1.2f 0.f .3f && ||");
914 if (result.length != 25)
915 throw new Error("Lexer emitted an incorrect number of tokens (expected 23): " + result.length);
916 checkLexerToken(result[0], 0, "identifier", "ident");
917 checkLexerToken(result[1], 6, "keyword", "for");
918 checkLexerToken(result[2], 10, "keyword", "while");
919 checkLexerToken(result[3], 16, "intLiteral", "123");
920 checkLexerToken(result[4], 20, "uintLiteral", "123u");
921 checkLexerToken(result[5], 25, "punctuation", "{");
922 checkLexerToken(result[6], 27, "punctuation", "}");
923 checkLexerToken(result[7], 29, "punctuation", "{");
924 checkLexerToken(result[8], 30, "identifier", "asd");
925 checkLexerToken(result[9], 34, "identifier", "asd");
926 checkLexerToken(result[10], 37, "punctuation", "{");
927 checkLexerToken(result[11], 39, "intLiteral", "1");
928 checkLexerToken(result[12], 40, "identifier", "a3");
929 checkLexerToken(result[13], 43, "floatLiteral", "1.2");
930 checkLexerToken(result[14], 47, "punctuation", "+");
931 checkLexerToken(result[15], 49, "floatLiteral", "3.4");
932 checkLexerToken(result[16], 53, "punctuation", "+");
933 checkLexerToken(result[17], 55, "floatLiteral", "1.");
934 checkLexerToken(result[18], 58, "punctuation", "+");
935 checkLexerToken(result[19], 60, "floatLiteral", ".2");
936 checkLexerToken(result[20], 63, "floatLiteral", "1.2f");
937 checkLexerToken(result[21], 68, "floatLiteral", "0.f");
938 checkLexerToken(result[22], 72, "floatLiteral", ".3f");
939 checkLexerToken(result[23], 76, "punctuation", "&&");
940 checkLexerToken(result[24], 79, "punctuation", "||");
943 tests.simpleNoReturn = function()
946 () => doPrep("int foo() { }"),
947 (e) => e instanceof WTypeError);
950 tests.simpleUnreachableCode = function()
960 (e) => e instanceof WTypeError);
963 tests.simpleStruct = function()
965 let program = doPrep(`
970 test Foo foo(Foo foo)
978 let structType = program.types.get("Foo");
980 throw new Error("Did not find Foo type");
981 let buffer = new EBuffer(2);
984 let result = callFunction(program, "foo", [new TypedValue(structType, new EPtr(buffer, 0))]);
985 if (!result.type.equals(structType))
986 throw new Error("Wrong result type: " + result.type);
987 let x = result.ePtr.get(0);
988 let y = result.ePtr.get(1);
990 throw new Error("Wrong result for x: " + x + " (y = " + y + ")");
992 throw new Error("Wrong result for y: " + y + " (x + " + x + ")");
995 tests.loadNull = function()
999 void sink(thread int* x) { }
1000 void foo() { sink(*null); }
1002 (e) => e instanceof WTypeError && e.message.indexOf("Type passed to dereference is not a pointer: null") != -1);
1005 tests.storeNull = function()
1009 void foo() { *null = 42; }
1011 (e) => e instanceof WTypeError && e.message.indexOf("Type passed to dereference is not a pointer: null") != -1);
1014 tests.returnNull = function()
1016 let program = doPrep(`
1017 test thread int* foo() { return null; }
1019 let result = callFunction(program, "foo", []);
1020 if (!result.type.isPtr)
1021 throw new Error("Return type is not a pointer: " + result.type);
1022 if (!result.type.elementType.equals(program.intrinsics.int))
1023 throw new Error("Return type is not a pointer to an int: " + result.type);
1024 if (result.value != null)
1025 throw new Error("Return value is not null: " + result.value);
1028 tests.dereferenceDefaultNull = function()
1030 let program = doPrep(`
1037 checkTrap(program, () => callFunction(program, "foo", []), checkInt);
1040 tests.defaultInitializedNull = function()
1042 let program = doPrep(`
1045 thread int* p = null;;
1049 checkTrap(program, () => callFunction(program, "foo", []), checkInt);
1052 tests.passNullToPtrMonomorphic = function()
1054 let program = doPrep(`
1055 int foo(thread int* ptr)
1064 checkTrap(program, () => callFunction(program, "bar", []), checkInt);
1067 tests.loadNullArrayRef = function()
1071 void sink(thread int* x) { }
1072 void foo() { sink(null[0u]); }
1074 (e) => e instanceof WTypeError && e.message.indexOf("Cannot resolve access") != -1);
1077 tests.storeNullArrayRef = function()
1081 void foo() { null[0u] = 42; }
1083 (e) => e instanceof WTypeError && e.message.indexOf("Cannot resolve access") != -1);
1086 tests.returnNullArrayRef = function()
1088 let program = doPrep(`
1089 test thread int[] foo() { return null; }
1091 let result = callFunction(program, "foo", []);
1092 if (!result.type.isArrayRef)
1093 throw new Error("Return type is not an array reference: " + result.type);
1094 if (!result.type.elementType.equals(program.intrinsics.int))
1095 throw new Error("Return type is not an int array reference: " + result.type);
1096 if (result.value != null)
1097 throw new Error("Return value is not null: " + result.value);
1100 tests.dereferenceDefaultNullArrayRef = function()
1102 let program = doPrep(`
1109 checkTrap(program, () => callFunction(program, "foo", []), checkInt);
1112 tests.defaultInitializedNullArrayRef = function()
1114 let program = doPrep(`
1117 thread int[] p = null;
1121 checkTrap(program, () => callFunction(program, "foo", []), checkInt);
1124 tests.defaultInitializedNullArrayRefIntLiteral = function()
1126 let program = doPrep(`
1129 thread int[] p = null;
1133 checkTrap(program, () => callFunction(program, "foo", []), checkInt);
1136 tests.passNullToPtrMonomorphicArrayRef = function()
1138 let program = doPrep(`
1139 int foo(thread int[] ptr)
1148 checkTrap(program, () => callFunction(program, "bar", []), checkInt);
1151 tests.returnIntLiteralUint = function()
1153 let program = doPrep("test uint foo() { return 42; }");
1154 checkUint(program, callFunction(program, "foo", []), 42);
1157 tests.returnIntLiteralFloat = function()
1159 let program = doPrep("test float foo() { return 42; }");
1160 checkFloat(program, callFunction(program, "foo", []), 42);
1163 tests.badIntLiteralForInt = function()
1166 () => doPrep("void foo() { int x = 3000000000; }"),
1167 (e) => e instanceof WSyntaxError);
1170 tests.badIntLiteralForUint = function()
1173 () => doPrep("void foo() { uint x = 5000000000; }"),
1174 (e) => e instanceof WSyntaxError);
1177 tests.badIntLiteralForFloat = function()
1180 () => doPrep("void foo() { float x = 5000000000000000000000000000000000000; }"),
1181 (e) => e instanceof WSyntaxError);
1184 tests.doubleNot = function()
1186 let program = doPrep(`
1187 test bool foo(bool x)
1192 checkBool(program, callFunction(program, "foo", [makeBool(program, true)]), true);
1193 checkBool(program, callFunction(program, "foo", [makeBool(program, false)]), false);
1196 tests.simpleRecursion = function()
1205 (e) => e instanceof WTypeError);
1208 tests.variableShadowing = function()
1210 let program = doPrep(`
1222 checkInt(program, callFunction(program, "foo", []), 8);
1235 checkInt(program, callFunction(program, "foo", []), 7);
1238 tests.ifStatement = function()
1240 let program = doPrep(`
1250 checkInt(program, callFunction(program, "foo", [makeInt(program, 3)]), 6);
1251 checkInt(program, callFunction(program, "foo", [makeInt(program, 4)]), 6);
1252 checkInt(program, callFunction(program, "foo", [makeInt(program, 5)]), 6);
1253 checkInt(program, callFunction(program, "foo", [makeInt(program, 6)]), 6);
1254 checkInt(program, callFunction(program, "foo", [makeInt(program, 7)]), 8);
1255 checkInt(program, callFunction(program, "foo", [makeInt(program, 8)]), 6);
1256 checkInt(program, callFunction(program, "foo", [makeInt(program, 9)]), 6);
1259 tests.ifElseStatement = function()
1261 let program = doPrep(`
1273 checkInt(program, callFunction(program, "foo", [makeInt(program, 3)]), 9);
1274 checkInt(program, callFunction(program, "foo", [makeInt(program, 4)]), 9);
1275 checkInt(program, callFunction(program, "foo", [makeInt(program, 5)]), 9);
1276 checkInt(program, callFunction(program, "foo", [makeInt(program, 6)]), 9);
1277 checkInt(program, callFunction(program, "foo", [makeInt(program, 7)]), 8);
1278 checkInt(program, callFunction(program, "foo", [makeInt(program, 8)]), 9);
1279 checkInt(program, callFunction(program, "foo", [makeInt(program, 9)]), 9);
1282 tests.ifElseIfStatement = function()
1284 let program = doPrep(`
1290 } else if (x == 8) {
1296 checkInt(program, callFunction(program, "foo", [makeInt(program, 3)]), 6);
1297 checkInt(program, callFunction(program, "foo", [makeInt(program, 4)]), 6);
1298 checkInt(program, callFunction(program, "foo", [makeInt(program, 5)]), 6);
1299 checkInt(program, callFunction(program, "foo", [makeInt(program, 6)]), 6);
1300 checkInt(program, callFunction(program, "foo", [makeInt(program, 7)]), 8);
1301 checkInt(program, callFunction(program, "foo", [makeInt(program, 8)]), 9);
1302 checkInt(program, callFunction(program, "foo", [makeInt(program, 9)]), 6);
1305 tests.ifElseIfElseStatement = function()
1307 let program = doPrep(`
1313 } else if (x == 8) {
1321 checkInt(program, callFunction(program, "foo", [makeInt(program, 3)]), 10);
1322 checkInt(program, callFunction(program, "foo", [makeInt(program, 4)]), 10);
1323 checkInt(program, callFunction(program, "foo", [makeInt(program, 5)]), 10);
1324 checkInt(program, callFunction(program, "foo", [makeInt(program, 6)]), 10);
1325 checkInt(program, callFunction(program, "foo", [makeInt(program, 7)]), 8);
1326 checkInt(program, callFunction(program, "foo", [makeInt(program, 8)]), 9);
1327 checkInt(program, callFunction(program, "foo", [makeInt(program, 9)]), 10);
1330 tests.returnIf = function()
1342 (e) => e instanceof WTypeError);
1355 (e) => e instanceof WTypeError);
1368 (e) => e instanceof WTypeError);
1369 let program = doPrep(`
1380 checkInt(program, callFunction(program, "foo", [makeInt(program, 3)]), 10);
1381 checkInt(program, callFunction(program, "foo", [makeInt(program, 4)]), 10);
1382 checkInt(program, callFunction(program, "foo", [makeInt(program, 5)]), 10);
1383 checkInt(program, callFunction(program, "foo", [makeInt(program, 6)]), 10);
1384 checkInt(program, callFunction(program, "foo", [makeInt(program, 7)]), 8);
1385 checkInt(program, callFunction(program, "foo", [makeInt(program, 8)]), 10);
1386 checkInt(program, callFunction(program, "foo", [makeInt(program, 9)]), 10);
1394 } else if (x == 9) {
1399 (e) => e instanceof WTypeError);
1412 checkInt(program, callFunction(program, "foo", [makeInt(program, 3)]), 9);
1413 checkInt(program, callFunction(program, "foo", [makeInt(program, 4)]), 9);
1414 checkInt(program, callFunction(program, "foo", [makeInt(program, 5)]), 9);
1415 checkInt(program, callFunction(program, "foo", [makeInt(program, 6)]), 9);
1416 checkInt(program, callFunction(program, "foo", [makeInt(program, 7)]), 8);
1417 checkInt(program, callFunction(program, "foo", [makeInt(program, 8)]), 9);
1418 checkInt(program, callFunction(program, "foo", [makeInt(program, 9)]), 9);
1432 (e) => e instanceof WTypeError);
1442 checkInt(program, callFunction(program, "foo", [makeInt(program, 7)]), 6);
1445 tests.simpleWhile = function()
1447 let program = doPrep(`
1455 checkInt(program, callFunction(program, "foo", [makeInt(program, 1)]), 16);
1458 tests.intOverloadResolution = function()
1460 let program = doPrep(`
1461 int foo(int) { return 1; }
1462 int foo(uint) { return 2; }
1463 int foo(float) { return 3; }
1464 test int bar() { return foo(42); }
1466 checkInt(program, callFunction(program, "bar", []), 1);
1469 tests.intOverloadResolutionReverseOrder = function()
1471 let program = doPrep(`
1472 int foo(float) { return 3; }
1473 int foo(uint) { return 2; }
1474 int foo(int) { return 1; }
1475 test int bar() { return foo(42); }
1477 checkInt(program, callFunction(program, "bar", []), 1);
1480 tests.break = function()
1482 let program = doPrep(`
1483 test int foo1(int x)
1492 test int foo2(int x)
1505 test int foo3(int x)
1515 test int foo4(int x)
1529 checkInt(program, callFunction(program, "foo1", [makeInt(program, 1)]), 8);
1530 checkInt(program, callFunction(program, "foo1", [makeInt(program, 10)]), 20);
1531 checkInt(program, callFunction(program, "foo2", [makeInt(program, 1)]), 7);
1532 checkInt(program, callFunction(program, "foo2", [makeInt(program, 10)]), 19);
1533 checkInt(program, callFunction(program, "foo3", [makeInt(program, 1)]), 7);
1534 checkInt(program, callFunction(program, "foo4", [makeInt(program, 1)]), 1);
1535 checkInt(program, callFunction(program, "foo5", []), 7);
1549 (e) => e instanceof WTypeError);
1558 (e) => e instanceof WTypeError);
1569 (e) => e instanceof WTypeError);
1572 tests.continue = function()
1574 let program = doPrep(`
1587 checkInt(program, callFunction(program, "foo", [makeInt(program, 1)]), 18);
1597 (e) => e instanceof WTypeError);
1600 tests.doWhile = function()
1602 let program = doPrep(`
1603 test int foo1(int x)
1612 test int foo2(int x)
1621 test int foo3(int x)
1635 checkInt(program, callFunction(program, "foo1", [makeInt(program, 1)]), 8);
1636 checkInt(program, callFunction(program, "foo1", [makeInt(program, 11)]), 8);
1637 checkInt(program, callFunction(program, "foo2", [makeInt(program, 1)]), 8);
1638 checkInt(program, callFunction(program, "foo3", [makeInt(program, 9)]), 19);
1641 tests.forLoop = function()
1643 let program = doPrep(`
1644 test int foo1(int x)
1648 for (i = 0; i < x; i = i + 1) {
1653 test int foo2(int x)
1656 for (int i = 0; i < x; i = i + 1) {
1661 test int foo3(int x)
1665 for (int i = 0; i < x; i = i + 1) {
1670 test int foo4(int x)
1673 for (int i = 0; i < x; i = i + 1) {
1680 test int foo5(int x)
1683 for (int i = 0; i < x; i = i + 1) {
1690 test int foo6(int x)
1693 for (int i = 0; ; i = i + 1) {
1700 test int foo7(int x)
1704 for ( ; ; i = i + 1) {
1711 test int foo8(int x)
1723 test int foo9(int x)
1729 test int foo10(int x)
1736 checkInt(program, callFunction(program, "foo1", [makeInt(program, 3)]), 3);
1737 checkInt(program, callFunction(program, "foo1", [makeInt(program, 4)]), 6);
1738 checkInt(program, callFunction(program, "foo1", [makeInt(program, 5)]), 10);
1739 checkInt(program, callFunction(program, "foo2", [makeInt(program, 3)]), 3);
1740 checkInt(program, callFunction(program, "foo2", [makeInt(program, 4)]), 6);
1741 checkInt(program, callFunction(program, "foo2", [makeInt(program, 5)]), 10);
1742 checkInt(program, callFunction(program, "foo3", [makeInt(program, 3)]), 3);
1743 checkInt(program, callFunction(program, "foo3", [makeInt(program, 4)]), 6);
1744 checkInt(program, callFunction(program, "foo3", [makeInt(program, 5)]), 10);
1745 checkInt(program, callFunction(program, "foo4", [makeInt(program, 3)]), 3);
1746 checkInt(program, callFunction(program, "foo4", [makeInt(program, 4)]), 6);
1747 checkInt(program, callFunction(program, "foo4", [makeInt(program, 5)]), 6);
1748 checkInt(program, callFunction(program, "foo4", [makeInt(program, 6)]), 11);
1749 checkInt(program, callFunction(program, "foo5", [makeInt(program, 3)]), 3);
1750 checkInt(program, callFunction(program, "foo5", [makeInt(program, 4)]), 6);
1751 checkInt(program, callFunction(program, "foo5", [makeInt(program, 5)]), 10);
1752 checkInt(program, callFunction(program, "foo5", [makeInt(program, 6)]), 10);
1753 checkInt(program, callFunction(program, "foo5", [makeInt(program, 7)]), 10);
1754 checkInt(program, callFunction(program, "foo6", [makeInt(program, 3)]), 3);
1755 checkInt(program, callFunction(program, "foo6", [makeInt(program, 4)]), 6);
1756 checkInt(program, callFunction(program, "foo6", [makeInt(program, 5)]), 10);
1757 checkInt(program, callFunction(program, "foo6", [makeInt(program, 6)]), 15);
1758 checkInt(program, callFunction(program, "foo6", [makeInt(program, 7)]), 21);
1759 checkInt(program, callFunction(program, "foo7", [makeInt(program, 3)]), 3);
1760 checkInt(program, callFunction(program, "foo7", [makeInt(program, 4)]), 6);
1761 checkInt(program, callFunction(program, "foo7", [makeInt(program, 5)]), 10);
1762 checkInt(program, callFunction(program, "foo7", [makeInt(program, 6)]), 15);
1763 checkInt(program, callFunction(program, "foo7", [makeInt(program, 7)]), 21);
1764 checkInt(program, callFunction(program, "foo8", [makeInt(program, 3)]), 3);
1765 checkInt(program, callFunction(program, "foo8", [makeInt(program, 4)]), 6);
1766 checkInt(program, callFunction(program, "foo8", [makeInt(program, 5)]), 10);
1767 checkInt(program, callFunction(program, "foo8", [makeInt(program, 6)]), 15);
1768 checkInt(program, callFunction(program, "foo8", [makeInt(program, 7)]), 21);
1769 checkInt(program, callFunction(program, "foo9", [makeInt(program, 3)]), 7);
1770 checkInt(program, callFunction(program, "foo9", [makeInt(program, 4)]), 7);
1771 checkInt(program, callFunction(program, "foo9", [makeInt(program, 5)]), 7);
1772 checkInt(program, callFunction(program, "foo9", [makeInt(program, 6)]), 7);
1773 checkInt(program, callFunction(program, "foo9", [makeInt(program, 7)]), 7);
1774 checkInt(program, callFunction(program, "foo10", [makeInt(program, 3)]), 7);
1775 checkInt(program, callFunction(program, "foo10", [makeInt(program, 4)]), 7);
1776 checkInt(program, callFunction(program, "foo10", [makeInt(program, 5)]), 7);
1777 checkInt(program, callFunction(program, "foo10", [makeInt(program, 6)]), 7);
1778 checkInt(program, callFunction(program, "foo10", [makeInt(program, 7)]), 7);
1783 for (int i = 0; ; i = i + 1) {
1789 (e) => e instanceof WTypeError);
1799 (e) => e instanceof WTypeError);
1802 tests.prefixPlusPlus = function()
1804 let program = doPrep(`
1811 checkInt(program, callFunction(program, "foo", [makeInt(program, 64)]), 65);
1814 tests.prefixPlusPlusResult = function()
1816 let program = doPrep(`
1822 checkInt(program, callFunction(program, "foo", [makeInt(program, 64)]), 65);
1825 tests.postfixPlusPlus = function()
1827 let program = doPrep(`
1834 checkInt(program, callFunction(program, "foo", [makeInt(program, 64)]), 65);
1837 tests.postfixPlusPlusResult = function()
1839 let program = doPrep(`
1845 checkInt(program, callFunction(program, "foo", [makeInt(program, 64)]), 64);
1848 tests.prefixMinusMinus = function()
1850 let program = doPrep(`
1857 checkInt(program, callFunction(program, "foo", [makeInt(program, 64)]), 63);
1860 tests.prefixMinusMinusResult = function()
1862 let program = doPrep(`
1868 checkInt(program, callFunction(program, "foo", [makeInt(program, 64)]), 63);
1871 tests.postfixMinusMinus = function()
1873 let program = doPrep(`
1880 checkInt(program, callFunction(program, "foo", [makeInt(program, 64)]), 63);
1883 tests.postfixMinusMinusResult = function()
1885 let program = doPrep(`
1891 checkInt(program, callFunction(program, "foo", [makeInt(program, 64)]), 64);
1894 tests.plusEquals = function()
1896 let program = doPrep(`
1903 checkInt(program, callFunction(program, "foo", [makeInt(program, 385)]), 385 + 42);
1906 tests.plusEqualsResult = function()
1908 let program = doPrep(`
1914 checkInt(program, callFunction(program, "foo", [makeInt(program, 385)]), 385 + 42);
1917 tests.minusEquals = function()
1919 let program = doPrep(`
1926 checkInt(program, callFunction(program, "foo", [makeInt(program, 385)]), 385 - 42);
1929 tests.minusEqualsResult = function()
1931 let program = doPrep(`
1937 checkInt(program, callFunction(program, "foo", [makeInt(program, 385)]), 385 - 42);
1940 tests.timesEquals = function()
1942 let program = doPrep(`
1949 checkInt(program, callFunction(program, "foo", [makeInt(program, 385)]), 385 * 42);
1952 tests.timesEqualsResult = function()
1954 let program = doPrep(`
1960 checkInt(program, callFunction(program, "foo", [makeInt(program, 385)]), 385 * 42);
1963 tests.divideEquals = function()
1965 let program = doPrep(`
1972 checkInt(program, callFunction(program, "foo", [makeInt(program, 385)]), (385 / 42) | 0);
1975 tests.divideEqualsResult = function()
1977 let program = doPrep(`
1983 checkInt(program, callFunction(program, "foo", [makeInt(program, 385)]), (385 / 42) | 0);
1986 tests.twoIntLiterals = function()
1988 let program = doPrep(`
1994 checkBool(program, callFunction(program, "foo", []), true);
1997 tests.assignUintToInt = function()
2006 (e) => e instanceof WTypeError && e.message.indexOf("Type mismatch in variable initialization") != -1);
2009 tests.buildArrayThenSumIt = function()
2011 let program = doPrep(`
2015 for (uint i = 0; i < 42; i = i + 1)
2016 array[i] = int(i + 5);
2018 for (uint i = 0; i < 42; i = i + 1)
2019 result = result + array[i];
2023 checkInt(program, callFunction(program, "foo", []), 42 * 5 + 42 * 41 / 2);
2026 tests.buildArrayThenSumItUsingArrayReference = function()
2028 let program = doPrep(`
2029 int bar(thread int[] array)
2031 for (uint i = 0; i < 42; i = i + 1)
2032 array[i] = int(i + 5);
2034 for (uint i = 0; i < 42; i = i + 1)
2035 result = result + array[i];
2044 checkInt(program, callFunction(program, "foo", []), 42 * 5 + 42 * 41 / 2);
2047 tests.overrideSubscriptStruct = function()
2049 let program = doPrep(`
2054 thread int* operator&[](thread Foo* foo, uint index)
2067 return foo[0] + foo[1] * 3;
2070 checkInt(program, callFunction(program, "foo", []), 498 + 19 * 3);
2073 tests.overrideSubscriptStructAndDoStores = function()
2075 let program = doPrep(`
2080 thread int* operator&[](thread Foo* foo, uint index)
2093 return foo.x + foo.y;
2096 checkInt(program, callFunction(program, "foo", []), 498 + 19);
2099 tests.overrideSubscriptStructAndUsePointers = function()
2101 let program = doPrep(`
2106 thread int* operator&[](thread Foo* foo, uint index)
2114 int bar(thread Foo* foo)
2116 return (*foo)[0] + (*foo)[1];
2126 checkInt(program, callFunction(program, "foo", []), 498 + 19);
2129 tests.overrideSubscriptStructAndUsePointersIncorrectly = function()
2137 thread int* operator&[](thread Foo* foo, uint index)
2145 int bar(thread Foo* foo)
2147 return foo[0] + foo[1];
2157 (e) => e instanceof WTypeError);
2160 tests.makeArrayRefFromLocal = function()
2162 let program = doPrep(`
2163 int bar(thread int[] ref)
2173 checkInt(program, callFunction(program, "foo", []), 48);
2176 tests.makeArrayRefFromPointer = function()
2178 let program = doPrep(`
2179 int bar(thread int[] ref)
2183 int baz(thread int* ptr)
2193 checkInt(program, callFunction(program, "foo", []), 48);
2196 tests.makeArrayRefFromArrayRef = function()
2200 int bar(thread int[] ref)
2204 int baz(thread int[] ptr)
2214 (e) => e instanceof WTypeError);
2217 tests.simpleLength = function()
2219 let program = doPrep(`
2223 return (@array).length;
2226 checkUint(program, callFunction(program, "foo", []), 754);
2229 tests.nonArrayRefArrayLengthSucceed = function()
2231 let program = doPrep(`
2235 return array.length;
2240 return array.length;
2243 checkUint(program, callFunction(program, "foo", []), 754);
2244 checkUint(program, callFunction(program, "bar", []), 754);
2247 tests.nonArrayRefArrayLengthFail = function()
2251 thread uint* lengthPtr()
2254 return &(array.length);
2257 e => e instanceof WTypeError);
2260 tests.assignLength = function()
2267 (@array).length = 42;
2270 (e) => e instanceof WTypeError);
2273 tests.assignLengthHelper = function()
2277 void bar(thread float[] array)
2287 (e) => e instanceof WTypeError);
2290 tests.simpleGetter = function()
2292 let program = doPrep(`
2296 int operator.y(Foo foo)
2307 checkInt(program, callFunction(program, "foo", []), 7804);
2310 tests.simpleSetter = function()
2312 let program = doPrep(`
2316 int operator.y(Foo foo)
2320 Foo operator.y=(Foo foo, int value)
2332 checkInt(program, callFunction(program, "foo", []), 7804);
2335 tests.nestedSubscriptLValueEmulationSimple = function()
2337 let program = doPrep(`
2341 int operator[](Foo foo, uint index)
2343 return foo.array[index];
2345 Foo operator[]=(Foo foo, uint index, int value)
2347 foo.array[index] = value;
2350 uint operator.length(Foo foo)
2352 return foo.array.length;
2357 for (uint i = foo.length; i--;)
2364 uint operator.length(Bar bar)
2366 return bar.array.length;
2368 Foo operator[](Bar bar, uint index)
2370 return bar.array[index];
2372 Bar operator[]=(Bar bar, uint index, Foo value)
2374 bar.array[index] = value;
2380 for (uint i = bar.length; i--;)
2381 result += sum(bar[i]);
2387 Bar operator[](Baz baz, uint index)
2389 return baz.array[index];
2391 Baz operator[]=(Baz baz, uint index, Bar value)
2393 baz.array[index] = value;
2396 uint operator.length(Baz baz)
2398 return baz.array.length;
2403 for (uint i = baz.length; i--;)
2404 result += sum(baz[i]);
2407 void setValues(thread Baz* baz)
2409 for (uint i = baz->length; i--;) {
2410 for (uint j = (*baz)[i].length; j--;) {
2411 for (uint k = (*baz)[i][j].length; k--;)
2412 (*baz)[i][j][k] = int(i + j + k);
2416 test int testSetValuesAndSum()
2422 test int testSetValuesMutateValuesAndSum()
2426 for (uint i = baz.length; i--;) {
2427 for (uint j = baz[i].length; j--;) {
2428 for (uint k = baz[i][j].length; k--;)
2429 baz[i][j][k] *= int(k);
2435 checkInt(program, callFunction(program, "testSetValuesAndSum", []), 1575);
2436 checkInt(program, callFunction(program, "testSetValuesMutateValuesAndSum", []), 5565);
2439 tests.nestedSubscriptWithArraysInStructs = function()
2441 let program = doPrep(`
2448 for (uint i = 0; i < foo.array.length; i++)
2449 result += foo.array[i];
2458 for (uint i = 0; i < bar.array.length; i++)
2459 result += sum(bar.array[i]);
2468 for (uint i = 0; i < baz.array.length; i++)
2469 result += sum(baz.array[i]);
2472 void setValues(thread Baz* baz)
2474 for (uint i = 0; i < baz->array.length; i++) {
2475 for (uint j = 0; j < baz->array[i].array.length; j++) {
2476 for (uint k = 0; k < baz->array[i].array[j].array.length; k++)
2477 baz->array[i].array[j].array[k] = int(i + j + k);
2481 test int testSetValuesAndSum()
2487 test int testSetValuesMutateValuesAndSum()
2491 for (uint i = baz.array.length; i--;) {
2492 for (uint j = baz.array[i].array.length; j--;) {
2493 for (uint k = baz.array[i].array[j].array.length; k--;)
2494 baz.array[i].array[j].array[k] = baz.array[i].array[j].array[k] * int(k);
2500 checkInt(program, callFunction(program, "testSetValuesAndSum", []), 1575);
2501 checkInt(program, callFunction(program, "testSetValuesMutateValuesAndSum", []), 5565);
2504 tests.nestedSubscript = function()
2506 let program = doPrep(`
2507 int sum(int[7] array)
2510 for (uint i = array.length; i--;)
2514 int sum(int[6][7] array)
2517 for (uint i = array.length; i--;)
2518 result += sum(array[i]);
2521 int sum(int[5][6][7] array)
2524 for (uint i = array.length; i--;)
2525 result += sum(array[i]);
2528 void setValues(thread int[][6][7] array)
2530 for (uint i = array.length; i--;) {
2531 for (uint j = array[i].length; j--;) {
2532 for (uint k = array[i][j].length; k--;)
2533 array[i][j][k] = int(i + j + k);
2537 test int testSetValuesAndSum()
2543 test int testSetValuesMutateValuesAndSum()
2547 for (uint i = array.length; i--;) {
2548 for (uint j = array[i].length; j--;) {
2549 for (uint k = array[i][j].length; k--;)
2550 array[i][j][k] = array[i][j][k] * int(k);
2556 checkInt(program, callFunction(program, "testSetValuesAndSum", []), 1575);
2557 checkInt(program, callFunction(program, "testSetValuesMutateValuesAndSum", []), 5565);
2560 tests.lotsOfLocalVariables = function()
2562 let src = "test int sum() {\n";
2563 src += " int i = 0;\n";
2566 for (let i = 0; i < numVars; i++) {
2567 const value = i * 3;
2568 src += ` i = ${i};\n`;
2569 src += ` int V${i} = (i + 3) * (i + 3);\n`;
2570 target += (i + 3) * (i + 3);
2572 src += " int result = 0;\n";
2573 for (let i = 0; i < numVars; i++) {
2574 src += ` result += V${i};\n`;
2576 src += " return result;\n";
2578 let program = doPrep(src);
2579 checkInt(program, callFunction(program, "sum", []), target);
2582 tests.operatorBool = function()
2584 let program = doPrep(`
2585 test bool boolFromUcharFalse() { return bool(uchar(0)); }
2586 test bool boolFromUcharTrue() { return bool(uchar(1)); }
2588 test bool boolFromUintFalse() { return bool(uint(0)); }
2589 test bool boolFromUintTrue() { return bool(uint(1)); }
2591 test bool boolFromIntFalse() { return bool(int(0)); }
2592 test bool boolFromIntTrue() { return bool(int(1)); }
2594 test bool boolFromFloatFalse() { return bool(float(0)); }
2595 test bool boolFromFloatTrue() { return bool(float(1)); }
2598 checkBool(program, callFunction(program, "boolFromUcharFalse", []), false);
2599 checkBool(program, callFunction(program, "boolFromUcharTrue", []), true);
2601 checkBool(program, callFunction(program, "boolFromUintFalse", []), false);
2602 checkBool(program, callFunction(program, "boolFromUintTrue", []), true);
2604 checkBool(program, callFunction(program, "boolFromIntFalse", []), false);
2605 checkBool(program, callFunction(program, "boolFromIntTrue", []), true);
2607 checkBool(program, callFunction(program, "boolFromFloatFalse", []), false);
2608 checkBool(program, callFunction(program, "boolFromFloatTrue", []), true);
2618 e => e instanceof WTypeError);
2628 e => e instanceof WTypeError);
2631 tests.boolBitAnd = function()
2633 let program = doPrep(`
2634 test bool foo(bool a, bool b)
2639 checkBool(program, callFunction(program, "foo", [makeBool(program, false), makeBool(program, false)]), false);
2640 checkBool(program, callFunction(program, "foo", [makeBool(program, true), makeBool(program, false)]), false);
2641 checkBool(program, callFunction(program, "foo", [makeBool(program, false), makeBool(program, true)]), false);
2642 checkBool(program, callFunction(program, "foo", [makeBool(program, true), makeBool(program, true)]), true);
2645 tests.boolBitOr = function()
2647 let program = doPrep(`
2648 test bool foo(bool a, bool b)
2653 checkBool(program, callFunction(program, "foo", [makeBool(program, false), makeBool(program, false)]), false);
2654 checkBool(program, callFunction(program, "foo", [makeBool(program, true), makeBool(program, false)]), true);
2655 checkBool(program, callFunction(program, "foo", [makeBool(program, false), makeBool(program, true)]), true);
2656 checkBool(program, callFunction(program, "foo", [makeBool(program, true), makeBool(program, true)]), true);
2659 tests.boolBitXor = function()
2661 let program = doPrep(`
2662 test bool foo(bool a, bool b)
2667 checkBool(program, callFunction(program, "foo", [makeBool(program, false), makeBool(program, false)]), false);
2668 checkBool(program, callFunction(program, "foo", [makeBool(program, true), makeBool(program, false)]), true);
2669 checkBool(program, callFunction(program, "foo", [makeBool(program, false), makeBool(program, true)]), true);
2670 checkBool(program, callFunction(program, "foo", [makeBool(program, true), makeBool(program, true)]), false);
2673 tests.boolBitNot = function()
2675 let program = doPrep(`
2676 test bool foo(bool a)
2681 checkBool(program, callFunction(program, "foo", [makeBool(program, false)]), true);
2682 checkBool(program, callFunction(program, "foo", [makeBool(program, true)]), false);
2685 tests.intBitAnd = function()
2687 let program = doPrep(`
2688 test int foo(int a, int b)
2693 checkInt(program, callFunction(program, "foo", [makeInt(program, 1), makeInt(program, 7)]), 1);
2694 checkInt(program, callFunction(program, "foo", [makeInt(program, 65535), makeInt(program, 42)]), 42);
2695 checkInt(program, callFunction(program, "foo", [makeInt(program, -1), makeInt(program, -7)]), -7);
2696 checkInt(program, callFunction(program, "foo", [makeInt(program, 0), makeInt(program, 85732)]), 0);
2699 tests.intBitOr = function()
2701 let program = doPrep(`
2702 test int foo(int a, int b)
2707 checkInt(program, callFunction(program, "foo", [makeInt(program, 1), makeInt(program, 7)]), 7);
2708 checkInt(program, callFunction(program, "foo", [makeInt(program, 65535), makeInt(program, 42)]), 65535);
2709 checkInt(program, callFunction(program, "foo", [makeInt(program, -1), makeInt(program, -7)]), -1);
2710 checkInt(program, callFunction(program, "foo", [makeInt(program, 0), makeInt(program, 85732)]), 85732);
2713 tests.intBitXor = function()
2715 let program = doPrep(`
2716 test int foo(int a, int b)
2721 checkInt(program, callFunction(program, "foo", [makeInt(program, 1), makeInt(program, 7)]), 6);
2722 checkInt(program, callFunction(program, "foo", [makeInt(program, 65535), makeInt(program, 42)]), 65493);
2723 checkInt(program, callFunction(program, "foo", [makeInt(program, -1), makeInt(program, -7)]), 6);
2724 checkInt(program, callFunction(program, "foo", [makeInt(program, 0), makeInt(program, 85732)]), 85732);
2727 tests.intBitNot = function()
2729 let program = doPrep(`
2735 checkInt(program, callFunction(program, "foo", [makeInt(program, 1)]), -2);
2736 checkInt(program, callFunction(program, "foo", [makeInt(program, 65535)]), -65536);
2737 checkInt(program, callFunction(program, "foo", [makeInt(program, -1)]), 0);
2738 checkInt(program, callFunction(program, "foo", [makeInt(program, 0)]), -1);
2741 tests.intLShift = function()
2743 let program = doPrep(`
2744 test int foo(int a, uint b)
2749 checkInt(program, callFunction(program, "foo", [makeInt(program, 1), makeUint(program, 7)]), 128);
2750 checkInt(program, callFunction(program, "foo", [makeInt(program, 65535), makeUint(program, 2)]), 262140);
2751 checkInt(program, callFunction(program, "foo", [makeInt(program, -1), makeUint(program, 5)]), -32);
2752 checkInt(program, callFunction(program, "foo", [makeInt(program, 0), makeUint(program, 3)]), 0);
2755 tests.intRShift = function()
2757 let program = doPrep(`
2758 test int foo(int a, uint b)
2763 checkInt(program, callFunction(program, "foo", [makeInt(program, 1), makeUint(program, 7)]), 0);
2764 checkInt(program, callFunction(program, "foo", [makeInt(program, 65535), makeUint(program, 2)]), 16383);
2765 checkInt(program, callFunction(program, "foo", [makeInt(program, -1), makeUint(program, 5)]), -1);
2766 checkInt(program, callFunction(program, "foo", [makeInt(program, 0), makeUint(program, 3)]), 0);
2769 tests.uintBitAnd = function()
2771 let program = doPrep(`
2772 test uint foo(uint a, uint b)
2777 checkUint(program, callFunction(program, "foo", [makeUint(program, 1), makeUint(program, 7)]), 1);
2778 checkUint(program, callFunction(program, "foo", [makeUint(program, 65535), makeUint(program, 42)]), 42);
2779 checkUint(program, callFunction(program, "foo", [makeUint(program, Math.pow(2, 32) - 1), makeUint(program, Math.pow(2, 32) - 7)]), 4294967289);
2780 checkUint(program, callFunction(program, "foo", [makeUint(program, 0), makeUint(program, 85732)]), 0);
2783 tests.uintBitOr = function()
2785 let program = doPrep(`
2786 test uint foo(uint a, uint b)
2791 checkUint(program, callFunction(program, "foo", [makeUint(program, 1), makeUint(program, 7)]), 7);
2792 checkUint(program, callFunction(program, "foo", [makeUint(program, 65535), makeUint(program, 42)]), 65535);
2793 checkUint(program, callFunction(program, "foo", [makeUint(program, Math.pow(2, 32) - 1), makeUint(program, Math.pow(2, 32) - 7)]), 4294967295);
2794 checkUint(program, callFunction(program, "foo", [makeUint(program, 0), makeUint(program, 85732)]), 85732);
2797 tests.uintBitXor = function()
2799 let program = doPrep(`
2800 test uint foo(uint a, uint b)
2805 checkUint(program, callFunction(program, "foo", [makeUint(program, 1), makeUint(program, 7)]), 6);
2806 checkUint(program, callFunction(program, "foo", [makeUint(program, 65535), makeUint(program, 42)]), 65493);
2807 checkUint(program, callFunction(program, "foo", [makeUint(program, Math.pow(2, 32) - 1), makeUint(program, Math.pow(2, 32) - 7)]), 6);
2808 checkUint(program, callFunction(program, "foo", [makeUint(program, 0), makeUint(program, 85732)]), 85732);
2811 tests.uintBitNot = function()
2813 let program = doPrep(`
2814 test uint foo(uint a)
2819 checkUint(program, callFunction(program, "foo", [makeUint(program, 1)]), 4294967294);
2820 checkUint(program, callFunction(program, "foo", [makeUint(program, 65535)]), 4294901760);
2821 checkUint(program, callFunction(program, "foo", [makeUint(program, Math.pow(2, 32) - 1)]), 0);
2822 checkUint(program, callFunction(program, "foo", [makeUint(program, 0)]), 4294967295);
2825 tests.uintLShift = function()
2827 let program = doPrep(`
2828 test uint foo(uint a, uint b)
2833 checkUint(program, callFunction(program, "foo", [makeUint(program, 1), makeUint(program, 7)]), 128);
2834 checkUint(program, callFunction(program, "foo", [makeUint(program, 65535), makeUint(program, 2)]), 262140);
2835 checkUint(program, callFunction(program, "foo", [makeUint(program, Math.pow(2, 32) - 1), makeUint(program, 5)]), 4294967264);
2836 checkUint(program, callFunction(program, "foo", [makeUint(program, 0), makeUint(program, 3)]), 0);
2839 tests.uintRShift = function()
2841 let program = doPrep(`
2842 test uint foo(uint a, uint b)
2847 checkUint(program, callFunction(program, "foo", [makeUint(program, 1), makeUint(program, 7)]), 0);
2848 checkUint(program, callFunction(program, "foo", [makeUint(program, 65535), makeUint(program, 2)]), 16383);
2849 checkUint(program, callFunction(program, "foo", [makeUint(program, Math.pow(2, 32) - 1), makeUint(program, 5)]), 134217727);
2850 checkUint(program, callFunction(program, "foo", [makeUint(program, 0), makeUint(program, 3)]), 0);
2853 tests.ucharBitAnd = function()
2855 let program = doPrep(`
2856 test uchar foo(uchar a, uchar b)
2861 checkUchar(program, callFunction(program, "foo", [makeUchar(program, 1), makeUchar(program, 7)]), 1);
2862 checkUchar(program, callFunction(program, "foo", [makeUchar(program, 255), makeUchar(program, 42)]), 42);
2863 checkUchar(program, callFunction(program, "foo", [makeUchar(program, 0), makeUchar(program, 255)]), 0);
2866 tests.ucharBitOr = function()
2868 let program = doPrep(`
2869 test uchar foo(uchar a, uchar b)
2874 checkUchar(program, callFunction(program, "foo", [makeUchar(program, 1), makeUchar(program, 7)]), 7);
2875 checkUchar(program, callFunction(program, "foo", [makeUchar(program, 255), makeUchar(program, 42)]), 255);
2876 checkUchar(program, callFunction(program, "foo", [makeUchar(program, 0), makeUchar(program, 228)]), 228);
2879 tests.ucharBitXor = function()
2881 let program = doPrep(`
2882 test uchar foo(uchar a, uchar b)
2887 checkUchar(program, callFunction(program, "foo", [makeUchar(program, 1), makeUchar(program, 7)]), 6);
2888 checkUchar(program, callFunction(program, "foo", [makeUchar(program, 255), makeUchar(program, 42)]), 213);
2889 checkUchar(program, callFunction(program, "foo", [makeUchar(program, 0), makeUchar(program, 255)]), 255);
2892 tests.ucharBitNot = function()
2894 let program = doPrep(`
2895 test uchar foo(uchar a)
2900 checkUchar(program, callFunction(program, "foo", [makeUchar(program, 1)]), 254);
2901 checkUchar(program, callFunction(program, "foo", [makeUchar(program, 255)]), 0);
2902 checkUchar(program, callFunction(program, "foo", [makeUchar(program, 0)]), 255);
2905 tests.ucharLShift = function()
2907 let program = doPrep(`
2908 test uchar foo(uchar a, uint b)
2913 checkUchar(program, callFunction(program, "foo", [makeUchar(program, 1), makeUint(program, 7)]), 128);
2914 checkUchar(program, callFunction(program, "foo", [makeUchar(program, 255), makeUint(program, 2)]), 252);
2915 checkUchar(program, callFunction(program, "foo", [makeUchar(program, 0), makeUint(program, 3)]), 0);
2918 tests.ucharRShift = function()
2920 let program = doPrep(`
2921 test uchar foo(uchar a, uint b)
2926 checkUchar(program, callFunction(program, "foo", [makeUchar(program, 1), makeUint(program, 7)]), 0);
2927 checkUchar(program, callFunction(program, "foo", [makeUchar(program, 255), makeUint(program, 2)]), 63);
2928 checkUchar(program, callFunction(program, "foo", [makeUchar(program, 255), makeUint(program, 5)]), 7);
2929 checkUchar(program, callFunction(program, "foo", [makeUchar(program, 0), makeUint(program, 3)]), 0);
2932 tests.floatMath = function()
2934 let program = doPrep(`
2937 return 42.5 == 42.5;
2941 return 42.5f == 42.5;
2945 return 42.5 == 42.5f;
2949 return 42.5f == 42.5f;
2953 return 42.5f == 42.5f;
2985 checkBool(program, callFunction(program, "foo", []), true);
2986 checkBool(program, callFunction(program, "foo2", []), true);
2987 checkBool(program, callFunction(program, "foo3", []), true);
2988 checkBool(program, callFunction(program, "foo4", []), true);
2989 checkBool(program, callFunction(program, "foo5", []), true);
2990 checkFloat(program, callFunction(program, "foo6", []), 7.5);
2991 checkFloat(program, callFunction(program, "foo7", []), 7.5);
2992 checkFloat(program, callFunction(program, "foo9", []), 7.5);
2993 checkFloat(program, callFunction(program, "foo10", []), 7.5);
2994 checkFloat(program, callFunction(program, "foo12", []), 7);
2995 checkFloat(program, callFunction(program, "foo13", []), 7.5);
3007 (e) => e instanceof WTypeError);
3019 (e) => e instanceof WTypeError);
3031 (e) => e instanceof WTypeError);
3043 (e) => e instanceof WTypeError);
3055 (e) => e instanceof WTypeError);
3067 (e) => e instanceof WTypeError);
3070 tests.booleanMath = function()
3072 let program = doPrep(`
3075 return true && true;
3079 return true && false;
3083 return false && true;
3087 return false && false;
3091 return true || true;
3095 return true || false;
3099 return false || true;
3103 return false || false;
3106 checkBool(program, callFunction(program, "foo", []), true);
3107 checkBool(program, callFunction(program, "foo2", []), false);
3108 checkBool(program, callFunction(program, "foo3", []), false);
3109 checkBool(program, callFunction(program, "foo4", []), false);
3110 checkBool(program, callFunction(program, "foo5", []), true);
3111 checkBool(program, callFunction(program, "foo6", []), true);
3112 checkBool(program, callFunction(program, "foo7", []), true);
3113 checkBool(program, callFunction(program, "foo8", []), false);
3116 tests.booleanShortcircuiting = function()
3118 let program = doPrep(`
3119 bool set(thread int* ptr, int value, bool retValue)
3128 bool y = set(&x, 1, true) && set(&x, 2, false);
3135 bool y = set(&x, 1, false) && set(&x, 2, false);
3142 bool y = set(&x, 1, true) || set(&x, 2, false);
3149 bool y = set(&x, 1, false) || set(&x, 2, false);
3154 checkInt(program, callFunction(program, "andTrue", []), 2);
3155 checkInt(program, callFunction(program, "andFalse", []), 1);
3156 checkInt(program, callFunction(program, "orTrue", []), 1);
3157 checkInt(program, callFunction(program, "orFalse", []), 2);
3160 tests.typedefArray = function()
3162 let program = doPrep(`
3163 typedef ArrayTypedef = int[2];
3166 ArrayTypedef arrayTypedef;
3167 return arrayTypedef[0];
3170 checkInt(program, callFunction(program, "foo", []), 0);
3173 tests.shaderTypes = function()
3176 vertex float4 foo() : SV_Position {
3177 return float4(0, 1, 2, 3);
3181 float4 x : SV_Position;
3182 int4 y : attribute(1);
3186 z.x = float4(1, 2, 3, 4);
3187 z.y = int4(5, 6, 7, 8);
3192 float4 x : SV_Position;
3193 int4 y : attribute(1);
3197 float3 z : attribute(2);
3201 w.r.x = float4(1, 2, 3, 4);
3202 w.r.y = int4(5, 6, 7, 8);
3203 w.z = float3(9, 10, 11);
3207 vertex float4 foo(constant float* buffer : register(b0)) : SV_Position {
3208 return float4(*buffer, *buffer, *buffer, *buffer);
3211 vertex float4 foo(constant float* buffer : register(b0, space0)) : SV_Position {
3212 return float4(*buffer, *buffer, *buffer, *buffer);
3215 vertex float4 foo(constant float* buffer : register(b0, space1)) : SV_Position {
3216 return float4(*buffer, *buffer, *buffer, *buffer);
3219 vertex float4 foo(constant float[] buffer : register(b0)) : SV_Position {
3220 return float4(buffer[0], buffer[1], buffer[2], buffer[3]);
3223 vertex float4 foo(float[5] buffer : register(b0)) : SV_Position {
3224 return float4(buffer[0], buffer[1], buffer[2], buffer[3]);
3227 vertex float4 foo(device float* buffer : register(u0)) : SV_Position {
3228 return float4(*buffer, *buffer, *buffer, *buffer);
3231 vertex float4 foo(device float[] buffer : register(u0)) : SV_Position {
3232 return float4(buffer[0], buffer[1], buffer[2], buffer[3]);
3235 vertex float4 foo(uint x : SV_InstanceID) : SV_Position {
3236 return float4(float(x), float(x), float(x), float(x));
3239 fragment float4 foo(bool x : SV_IsFrontFace) : SV_Target0 {
3240 return float4(1, 2, 3, 4);
3243 fragment float4 foo(int x : specialized) : SV_Target0 {
3244 return float4(1, 2, 3, 4);
3247 fragment float4 foo(Texture1D<float4> t : register(t0), sampler s : register(s0)) : SV_Target0 {
3248 return Sample(t, s, 0.4);
3252 vertex void foo() : SV_Position {
3255 e => e instanceof WTypeError);
3258 vertex float4 foo(float x : PSIZE) : SV_Position {
3259 return float4(x, x, x, x);
3262 e => e instanceof WTypeError);
3265 vertex float4 foo(int x : SV_InstanceID) : SV_Position {
3266 return float4(float(x), float(x), float(x), float(x));
3269 e => e instanceof WTypeError);
3272 vertex float4 foo(float x) : SV_Position {
3273 return float4(x, x, x, x);
3276 e => e instanceof WTypeError);
3279 fragment float4 foo(bool x : SV_IsFrontFace, bool y : SV_IsFrontFace) : SV_Target0 {
3280 return float4(1, 2, 3, 4);
3283 e => e instanceof WTypeError);
3287 float4 x : SV_Target0;
3289 fragment R foo(bool x : SV_IsFrontFace) : SV_Depth {
3291 y.x = float4(1, 2, 3, 4);
3295 e => e instanceof WTypeError);
3299 bool x : SV_IsFrontFace;
3301 fragment float4 foo(R x : SV_SampleIndex) : SV_Target0 {
3302 return float4(1, 2, 3, 4);
3305 e => e instanceof WTypeError);
3309 bool x : SV_IsFrontFace;
3313 bool y : SV_IsFrontFace;
3315 fragment float4 foo(S x) : SV_Target0 {
3316 return float4(1, 2, 3, 4);
3319 e => e instanceof WTypeError);
3323 float x : SV_IsFrontFace;
3325 fragment float4 foo(R x) : SV_Target0 {
3326 return float4(1, 2, 3, 4);
3329 e => e instanceof WTypeError);
3333 float x : SV_IsFrontFace;
3335 vertex uint foo() : SV_VertexID {
3339 e => e instanceof WTypeError);
3342 typedef A = thread float*;
3343 vertex float4 foo(device A[] x : register(u0)) : SV_Position {
3344 return float4(1, 2, 3, 4);
3347 e => e instanceof WTypeError);
3350 typedef A = thread float*;
3351 vertex float4 foo(device A* x : register(u0)) : SV_Position {
3352 return float4(1, 2, 3, 4);
3355 e => e instanceof WTypeError);
3358 typedef A = thread float*;
3359 vertex float4 foo(A[4] x : register(u0)) : SV_Position {
3360 return float4(1, 2, 3, 4);
3363 e => e instanceof WTypeError);
3369 vertex float4 foo(Foo x : specialized) : SV_Position {
3370 return float4(1, 2, 3, 4);
3373 e => e instanceof WTypeError);
3376 [numthreads(1, 1, 1)]
3377 compute float foo() : attribute(0) {
3381 e => e instanceof WTypeError);
3384 fragment float foo() : attribute(0) {
3388 e => e instanceof WTypeError);
3391 vertex float foo(device float* x : attribute(0)) : attribute(0) {
3395 e => e instanceof WTypeError);
3398 vertex float4 foo(device float* x : register(b0)) : SV_Position {
3399 return float4(1, 2, 3, 4);
3402 e => e instanceof WTypeError);
3405 vertex float4 foo(float x : register(b0)) : SV_Position {
3406 return float4(1, 2, 3, 4);
3409 e => e instanceof WTypeError);
3412 vertex float4 foo(device float* x : register(t0)) : SV_Position {