| Differences between
and this patch
- a/Tools/ChangeLog +196 lines
Lines 1-3 a/Tools/ChangeLog_sec1
1
2018-07-25  Thomas Denney  <tdenney@apple.com>
2
3
        [WHLSL] Remove generics from the interpreter
4
        https://bugs.webkit.org/show_bug.cgi?id=187988
5
6
        Reviewed by NOBODY (OOPS!).
7
8
        * WebGPUShadingLanguageRI/All.js:
9
        * WebGPUShadingLanguageRI/BuiltinVectorCasts.js: Added.
10
        (BuiltinVectorCasts):
11
        (BuiltinVectorCasts.prototype.get baseTypeName):
12
        (BuiltinVectorCasts.prototype.get parameterSizes):
13
        (BuiltinVectorCasts.prototype.get outputSize):
14
        (BuiltinVectorCasts.prototype.toString):
15
        (BuiltinVectorCasts.functions):
16
        (BuiltinVectorCasts._vectorParameterSizesForMaximumSize):
17
        (BuiltinVectorCasts.prototype.instantiateImplementation):
18
        * WebGPUShadingLanguageRI/BuiltinVectorEqualityOperator.js: Copied from Tools/WebGPUShadingLanguageRI/NativeTypeInstance.js.
19
        (BuiltinVectorEqualityOperator):
20
        (BuiltinVectorEqualityOperator.prototype.get baseTypeName):
21
        (BuiltinVectorEqualityOperator.prototype.get size):
22
        (BuiltinVectorEqualityOperator.prototype.toString):
23
        (BuiltinVectorEqualityOperator.functions):
24
        (BuiltinVectorEqualityOperator.prototype.instantiateImplementation):
25
        * WebGPUShadingLanguageRI/BuiltinVectorGetter.js: Copied from Tools/WebGPUShadingLanguageRI/NativeTypeInstance.js.
26
        (BuiltinVectorGetter):
27
        (BuiltinVectorGetter.prototype.get baseTypeName):
28
        (BuiltinVectorGetter.prototype.get size):
29
        (BuiltinVectorGetter.prototype.get elementName):
30
        (BuiltinVectorGetter.prototype.get index):
31
        (BuiltinVectorGetter.prototype.toString):
32
        (BuiltinVectorGetter.functions):
33
        (BuiltinVectorGetter.prototype.instantiateImplementation):
34
        * WebGPUShadingLanguageRI/BuiltinVectorIndexGetter.js: Copied from Tools/WebGPUShadingLanguageRI/LiteralTypeChecker.js.
35
        (BuiltinVectorIndexGetter):
36
        (BuiltinVectorIndexGetter.prototype.get baseTypeName):
37
        (BuiltinVectorIndexGetter.prototype.get size):
38
        (BuiltinVectorIndexGetter.prototype.toString):
39
        (BuiltinVectorIndexGetter.functions):
40
        (BuiltinVectorIndexGetter.prototype.instantiateImplementation):
41
        * WebGPUShadingLanguageRI/BuiltinVectorIndexSetter.js: Added.
42
        (BuiltinVectorIndexSetter):
43
        (BuiltinVectorIndexSetter.prototype.get baseTypeName):
44
        (BuiltinVectorIndexSetter.prototype.get size):
45
        (BuiltinVectorIndexSetter.prototype.get elementName):
46
        (BuiltinVectorIndexSetter.prototype.get index):
47
        (BuiltinVectorIndexSetter.prototype.toString):
48
        (BuiltinVectorIndexSetter.functions):
49
        (BuiltinVectorIndexSetter.prototype.instantiateImplementation):
50
        * WebGPUShadingLanguageRI/BuiltinVectorSetter.js: Added.
51
        (BuiltinVectorSetter):
52
        (BuiltinVectorSetter.prototype.get baseTypeName):
53
        (BuiltinVectorSetter.prototype.get size):
54
        (BuiltinVectorSetter.prototype.get elementName):
55
        (BuiltinVectorSetter.prototype.get index):
56
        (BuiltinVectorSetter.prototype.toString):
57
        (BuiltinVectorSetter.functions):
58
        (BuiltinVectorSetter.prototype.instantiateImplementation):
59
        * WebGPUShadingLanguageRI/CallExpression.js:
60
        (CallExpression.resolve):
61
        (CallExpression.prototype.resolve):
62
        (CallExpression.prototype._resolveToOperatorAnderIndexer):
63
        (CallExpression.prototype._resolveToOperatorLength):
64
        (CallExpression.prototype.toString):
65
        (CallExpression):
66
        * WebGPUShadingLanguageRI/Checker.js:
67
        (Checker.prototype._finishVisitingPropertyAccess):
68
        * WebGPUShadingLanguageRI/Func.js:
69
        (Func.prototype.toDeclString):
70
        * WebGPUShadingLanguageRI/FuncInstantiator.js:
71
        (FuncInstantiator.prototype.getUnique.FindTypeVariable.prototype.visitTypeRef): Deleted.
72
        (FuncInstantiator.prototype.getUnique.FindTypeVariable.prototype.visitTypeVariable): Deleted.
73
        (FuncInstantiator.prototype.getUnique.FindTypeVariable): Deleted.
74
        * WebGPUShadingLanguageRI/Intrinsics.js:
75
        (Intrinsics):
76
        * WebGPUShadingLanguageRI/LiteralTypeChecker.js:
77
        (LiteralTypeChecker.prototype.visitGenericLiteralType):
78
        (LiteralTypeChecker):
79
        * WebGPUShadingLanguageRI/NativeType.js:
80
        (NativeType.prototype.toString):
81
        (NativeType):
82
        * WebGPUShadingLanguageRI/NativeTypeInstance.js:
83
        (NativeTypeInstance.prototype.toString):
84
        (NativeTypeInstance):
85
        * WebGPUShadingLanguageRI/OperatorAnderIndex.js: Added.
86
        (OperatorAnderIndexer):
87
        (OperatorAnderIndexer.prototype.get addressSpace):
88
        (OperatorAnderIndexer.prototype.get baseTypeName):
89
        (OperatorAnderIndexer.prototype.toString):
90
        (OperatorAnderIndexer.functions):
91
        (OperatorAnderIndexer.prototype.instantiateImplementation):
92
        * WebGPUShadingLanguageRI/OperatorArrayRefLength.js: Renamed from Tools/WebGPUShadingLanguageRI/DoubleLiteralType.js.
93
        (OperatorArrayRefLength):
94
        (OperatorArrayRefLength.prototype.get addressSpace):
95
        (OperatorArrayRefLength.prototype.get baseTypeName):
96
        (OperatorArrayRefLength.prototype.toString):
97
        (OperatorArrayRefLength.prototype.instantiateImplementation):
98
        * WebGPUShadingLanguageRI/OperatorBool.js: Copied from Tools/WebGPUShadingLanguageRI/NativeTypeInstance.js.
99
        (OperatorBool):
100
        (OperatorBool.prototype.get baseTypeName):
101
        (OperatorBool.prototype.toString):
102
        (OperatorBool.functions):
103
        (OperatorBool.prototype.instantiateImplementation):
104
        * WebGPUShadingLanguageRI/Parse.js:
105
        (parseTerm):
106
        (parseTypeDef):
107
        (isCallExpression):
108
        (parseFuncDecl):
109
        (parseStructType):
110
        (parseNative):
111
        (parse):
112
        (parseProtocolRef): Deleted.
113
        (parseTypeParameters): Deleted.
114
        (parseTypeArguments): Deleted.
115
        (parseProtocolFuncDecl): Deleted.
116
        (parseProtocolDecl): Deleted.
117
        * WebGPUShadingLanguageRI/Prepare.js:
118
        (let.prepare):
119
        * WebGPUShadingLanguageRI/SPIRV.html:
120
        * WebGPUShadingLanguageRI/SPIRVCodegen.js:
121
        (ConstantFinder.prototype.visitGenericLiteralType):
122
        (ConstantFinder):
123
        (generateSPIRV):
124
        * WebGPUShadingLanguageRI/StandardLibrary.js:
125
        (addFunctionsFromClass):
126
        (restricted.operator.T.T): Deleted.
127
        (operator.T.Equatable.bool): Deleted.
128
        (operator.T.vec2.T): Deleted.
129
        (bool.operator.T.Equatable): Deleted.
130
        (thread.T.operator.T): Deleted.
131
        (operator.T.vec3.T): Deleted.
132
        (operator.T.vec4.T): Deleted.
133
        (uint.length): Deleted.
134
        * WebGPUShadingLanguageRI/StructType.js:
135
        (StructType.prototype.get isStruct):
136
        (StructType.prototype.toString):
137
        (StructType):
138
        * WebGPUShadingLanguageRI/SwizzleOp.js:
139
        (SwizzleOp):
140
        (SwizzleOp.prototype.get baseTypeName):
141
        (SwizzleOp.prototype.toString):
142
        (SwizzleOp.functions.):
143
        (SwizzleOp.functions):
144
        (SwizzleOp.prototype.instantiateImplementation):
145
        (SwizzleOp.allSwizzleOperators.): Deleted.
146
        (SwizzleOp.allSwizzleOperators): Deleted.
147
        * WebGPUShadingLanguageRI/SynthesizeArrayOperatorLength.js: Renamed from Tools/WebGPUShadingLanguageRI/DoubleLiteral.js.
148
        (synthesizeArrayOperatorLength.FindArrayTypes.prototype.visitArrayType):
149
        (synthesizeArrayOperatorLength.FindArrayTypes):
150
        (synthesizeArrayOperatorLength):
151
        * WebGPUShadingLanguageRI/SynthesizeCopyConstructorOperator.js: Copied from Tools/WebGPUShadingLanguageRI/NativeTypeInstance.js.
152
        (synthesizeCopyConstructorOperator.FindAllTypes.prototype.visitNativeType):
153
        (synthesizeCopyConstructorOperator.FindAllTypes.prototype.visitStructType):
154
        (synthesizeCopyConstructorOperator.FindAllTypes.prototype.visitElementalType):
155
        (synthesizeCopyConstructorOperator.FindAllTypes):
156
        (synthesizeCopyConstructorOperator):
157
        * WebGPUShadingLanguageRI/SynthesizeDefaultConstructorOperator.js: Copied from Tools/WebGPUShadingLanguageRI/NativeTypeInstance.js.
158
        (synthesizeDefaultConstructorOperator.FindAllTypes.prototype.visitNativeType):
159
        (synthesizeDefaultConstructorOperator.FindAllTypes.prototype.visitStructType):
160
        (synthesizeDefaultConstructorOperator.FindAllTypes.prototype.visitElementalType):
161
        (synthesizeDefaultConstructorOperator.FindAllTypes):
162
        (synthesizeDefaultConstructorOperator):
163
        * WebGPUShadingLanguageRI/Test.html:
164
        * WebGPUShadingLanguageRI/Test.js:
165
        (makeDouble): Deleted.
166
        (checkDouble): Deleted.
167
        * WebGPUShadingLanguageRI/Type.js:
168
        (Type.prototype.get isStruct):
169
        * WebGPUShadingLanguageRI/TypeDef.js:
170
        (TypeDef.prototype.toString):
171
        (TypeDef):
172
        * WebGPUShadingLanguageRI/TypeRef.js:
173
        (TypeRef.prototype.toString):
174
        (TypeRef):
175
        * WebGPUShadingLanguageRI/index.html:
176
177
2018-07-24  Thomas Denney  <tdenney@apple.com>
178
179
        Remove support for the double type from WHLSL
180
        https://bugs.webkit.org/show_bug.cgi?id=187977
181
182
        Reviewed by Myles C. Maxfield.
183
184
        * WebGPUShadingLanguageRI/All.js: Removed DoubleLiteral.js and DoubleLiteralType.js include.
185
        * WebGPUShadingLanguageRI/DoubleLiteral.js: Removed.
186
        * WebGPUShadingLanguageRI/DoubleLiteralType.js: Removed.
187
        * WebGPUShadingLanguageRI/Intrinsics.js: Removed double arithmetic functions.
188
        * WebGPUShadingLanguageRI/Parse.js:
189
        (parseTerm): Removed parsing of double literals.
190
        * WebGPUShadingLanguageRI/SPIRV.html: Removed DoubleLiteral.js and DoubleLiteralType.js include.
191
        * WebGPUShadingLanguageRI/SPIRVCodegen.js: Removed double type logic.
192
        * WebGPUShadingLanguageRI/StandardLibrary.js: Removed double type declarations.
193
        * WebGPUShadingLanguageRI/Test.html: Removed DoubleLiteral.js and DoubleLiteralType.js include.
194
        * WebGPUShadingLanguageRI/Test.js: Removed tests that test doubles or ported them to use floats.
195
        * WebGPUShadingLanguageRI/index.html: Removed DoubleLiteral.js and DoubleLiteralType.js include.
196
1
2018-07-24  Daniel Bates  <dabates@apple.com>
197
2018-07-24  Daniel Bates  <dabates@apple.com>
2
198
3
        Move-constructing NeverDestroyed should move construct underlying object instead of copy constructing it
199
        Move-constructing NeverDestroyed should move construct underlying object instead of copy constructing it
- a/Tools/WebGPUShadingLanguageRI/All.js -5 / +16 lines
Lines 34-39 load("Visitor.js"); a/Tools/WebGPUShadingLanguageRI/All.js_sec1
34
load("CreateLiteral.js");
34
load("CreateLiteral.js");
35
load("CreateLiteralType.js");
35
load("CreateLiteralType.js");
36
load("PropertyAccessExpression.js");
36
load("PropertyAccessExpression.js");
37
load("SwizzleOp.js");
37
38
38
load("AddressSpace.js");
39
load("AddressSpace.js");
39
load("AnonymousVariable.js");
40
load("AnonymousVariable.js");
Lines 49-56 load("CallFunction.js"); a/Tools/WebGPUShadingLanguageRI/All.js_sec2
49
load("Check.js");
50
load("Check.js");
50
load("CheckLiteralTypes.js");
51
load("CheckLiteralTypes.js");
51
load("CheckLoops.js");
52
load("CheckLoops.js");
52
load("CheckRecursiveTypes.js");
53
load("CheckRecursion.js");
53
load("CheckRecursion.js");
54
load("CheckRecursiveTypes.js");
54
load("CheckReturns.js");
55
load("CheckReturns.js");
55
load("CheckUnreachableCode.js");
56
load("CheckUnreachableCode.js");
56
load("CheckWrapped.js");
57
load("CheckWrapped.js");
Lines 61-71 load("ConstexprFolder.js"); a/Tools/WebGPUShadingLanguageRI/All.js_sec3
61
load("ConstexprTypeParameter.js");
62
load("ConstexprTypeParameter.js");
62
load("Continue.js");
63
load("Continue.js");
63
load("ConvertPtrToArrayRefExpression.js");
64
load("ConvertPtrToArrayRefExpression.js");
64
load("DereferenceExpression.js");
65
load("DoWhileLoop.js");
65
load("DoWhileLoop.js");
66
load("DotExpression.js");
66
load("DotExpression.js");
67
load("DoubleLiteral.js");
67
load("DereferenceExpression.js");
68
load("DoubleLiteralType.js");
69
load("EArrayRef.js");
68
load("EArrayRef.js");
70
load("EBuffer.js");
69
load("EBuffer.js");
71
load("EBufferBuilder.js");
70
load("EBufferBuilder.js");
Lines 120-132 load("NativeTypeInstance.js"); a/Tools/WebGPUShadingLanguageRI/All.js_sec4
120
load("NormalUsePropertyResolver.js");
119
load("NormalUsePropertyResolver.js");
121
load("NullLiteral.js");
120
load("NullLiteral.js");
122
load("NullType.js");
121
load("NullType.js");
122
load("OperatorAnderIndex.js");
123
load("OperatorArrayRefLength.js");
124
load("OperatorBool.js");
125
load("BuiltinVectorCasts.js");
126
load("BuiltinVectorGetter.js");
127
load("BuiltinVectorSetter.js");
128
load("BuiltinVectorIndexGetter.js");
129
load("BuiltinVectorIndexSetter.js");
130
load("BuiltinVectorEqualityOperator.js");
123
load("OriginKind.js");
131
load("OriginKind.js");
124
load("OverloadResolutionFailure.js");
132
load("OverloadResolutionFailure.js");
125
load("Parse.js");
133
load("Parse.js");
126
load("Prepare.js");
134
load("Prepare.js");
135
load("PropertyResolver.js");
127
load("Program.js");
136
load("Program.js");
128
load("ProgramWithUnnecessaryThingsRemoved.js");
137
load("ProgramWithUnnecessaryThingsRemoved.js");
129
load("PropertyResolver.js");
130
load("Protocol.js");
138
load("Protocol.js");
131
load("ProtocolDecl.js");
139
load("ProtocolDecl.js");
132
load("ProtocolFuncDecl.js");
140
load("ProtocolFuncDecl.js");
Lines 149-156 load("StructType.js"); a/Tools/WebGPUShadingLanguageRI/All.js_sec5
149
load("Substitution.js");
157
load("Substitution.js");
150
load("SwitchCase.js");
158
load("SwitchCase.js");
151
load("SwitchStatement.js");
159
load("SwitchStatement.js");
160
load("SynthesizeArrayOperatorLength.js");
152
load("SynthesizeEnumFunctions.js");
161
load("SynthesizeEnumFunctions.js");
153
load("SynthesizeStructAccessors.js");
162
load("SynthesizeStructAccessors.js");
163
load("SynthesizeCopyConstructorOperator.js");
164
load("SynthesizeDefaultConstructorOperator.js");
154
load("TrapStatement.js");
165
load("TrapStatement.js");
155
load("TypeDef.js");
166
load("TypeDef.js");
156
load("TypeDefResolver.js");
167
load("TypeDefResolver.js");
- a/Tools/WebGPUShadingLanguageRI/BuiltinVectorCasts.js +90 lines
Line 0 a/Tools/WebGPUShadingLanguageRI/BuiltinVectorCasts.js_sec1
1
/*
2
 * Copyright (C) 2017 Apple Inc. All rights reserved.
3
 *
4
 * Redistribution and use in source and binary forms, with or without
5
 * modification, are permitted provided that the following conditions
6
 * are met:
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.
12
 *
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. 
24
 */
25
"use strict";
26
27
class BuiltinVectorCasts {
28
    constructor(baseTypeName, parameterSizes)
29
    {
30
        this._baseTypeName = baseTypeName;
31
        this._parameterSizes = parameterSizes;
32
    }
33
34
    get baseTypeName() { return this._baseTypeName; }
35
    get parameterSizes() { return this._parameterSizes; }
36
    get outputSize()
37
    {
38
        let sum = 0;
39
        for (let paramSize of this.parameterSizes)
40
            sum += paramSize;
41
        return sum;
42
    }
43
44
    toString()
45
    {
46
        return `native operator ${this.baseTypeName}${this.outputSize}(${this.parameterSizes.map(x => x == 1 ? this.baseTypeName : this.baseTypeName + x).join(",")})`;
47
    }
48
49
    static functions()
50
    {
51
        if (!this._functions) {
52
            this._functions = [];
53
        
54
            const typeNames = [ "uint", "int", "float" ];
55
            const sizes = [ 2, 3, 4 ];
56
57
            for (let typeName of typeNames) {
58
                for (let size of sizes) {
59
                    for (let paramSizes of this._vectorParameterSizesForMaximumSize(size))
60
                        this._functions.push(new BuiltinVectorCasts(typeName, paramSizes));
61
                }
62
            }
63
        }
64
        return this._functions;
65
    }
66
67
    static _vectorParameterSizesForMaximumSize(maxSize)
68
    {
69
        let variants = [ [ maxSize ] ];
70
        for (let splitPoint = 1; splitPoint < maxSize; splitPoint++) {
71
            for (let v of BuiltinVectorCasts._vectorParameterSizesForMaximumSize(maxSize - splitPoint))
72
                variants.push([ splitPoint ].concat(v));
73
        }
74
        return variants;
75
    }
76
77
    instantiateImplementation(func)
78
    {
79
        func.implementation = (args) => {
80
            const result = new EPtr(new EBuffer(this.outputSize), 0);
81
            let offset = 0;
82
            for (let i = 0; i < args.length; i++) {
83
                for (let j = 0; j < this.parameterSizes[i]; j++)
84
                    result.set(offset++, args[i].get(j));
85
            }
86
            return result;
87
        };
88
        func.implementationData = this;
89
    }
90
}
- a/Tools/WebGPUShadingLanguageRI/BuiltinVectorEqualityOperator.js +69 lines
Line 0 a/Tools/WebGPUShadingLanguageRI/BuiltinVectorEqualityOperator.js_sec1
1
/*
2
 * Copyright (C) 2017 Apple Inc. All rights reserved.
3
 *
4
 * Redistribution and use in source and binary forms, with or without
5
 * modification, are permitted provided that the following conditions
6
 * are met:
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.
12
 *
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. 
24
 */
25
"use strict";
26
27
class BuiltinVectorEqualityOperator {
28
    constructor(baseTypeName, size)
29
    {
30
        this._baseTypeName = baseTypeName;
31
        this._size = size;
32
    }
33
34
    get baseTypeName() { return this._baseTypeName; }
35
    get size() { return this._size; }
36
37
    toString()
38
    {
39
        return `native bool operator==(${this.baseTypeName}${this.size},${this.baseTypeName}${this.size})`;
40
    }
41
42
    static functions()
43
    {
44
        if (!this._functions) {
45
            this._functions = [];
46
        
47
            const typeNames = [ "uint", "int", "float" ];
48
            const sizes = [ 2, 3, 4 ];
49
50
            for (let typeName of typeNames) {
51
                for (let size of sizes)
52
                    this._functions.push(new BuiltinVectorEqualityOperator(typeName, size));
53
            }
54
        }
55
        return this._functions;
56
    }
57
58
    instantiateImplementation(func)
59
    {
60
        func.implementation = ([ref1, ref2], node) => {
61
            for (let i = 0; i < this.size; i++) {
62
                if (ref1.get(i) != ref2.get(i))
63
                    return EPtr.box(false);
64
            }
65
            return EPtr.box(true);
66
        };
67
        func.implementationData = this;
68
    }
69
}
- a/Tools/WebGPUShadingLanguageRI/BuiltinVectorGetter.js +72 lines
Line 0 a/Tools/WebGPUShadingLanguageRI/BuiltinVectorGetter.js_sec1
1
/*
2
 * Copyright (C) 2017 Apple Inc. All rights reserved.
3
 *
4
 * Redistribution and use in source and binary forms, with or without
5
 * modification, are permitted provided that the following conditions
6
 * are met:
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.
12
 *
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. 
24
 */
25
"use strict";
26
27
class BuiltinVectorGetter {
28
    constructor(baseTypeName, size, elementName, index)
29
    {
30
        this._baseTypeName = baseTypeName;
31
        this._size = size;
32
        this._elementName = elementName;
33
        this._index = index;
34
    }
35
36
    get baseTypeName() { return this._baseTypeName; }
37
    get size() { return this._size; }
38
    get elementName() { return this._elementName; }
39
    get index() { return this._index; }
40
41
    toString()
42
    {
43
        return `native ${this.baseTypeName} operator.${this.elementName}(${this.baseTypeName}${this.size})`;
44
    }
45
46
    static functions()
47
    {
48
        if (!this._functions) {
49
            this._functions = [];
50
        
51
            const typeNames = [ "uint", "int", "float" ];
52
            const sizes = [ 2, 3, 4 ];
53
            const elements = [ "x", "y", "z", "w" ];
54
55
            for (let typeName of typeNames) {
56
                for (let size of sizes) {
57
                    for (let i = 0; i < size; i++)
58
                        this._functions.push(new BuiltinVectorGetter(typeName, size, elements[i], i));
59
                }
60
            }
61
        }
62
        return this._functions;
63
    }
64
65
    instantiateImplementation(func)
66
    {
67
        func.implementation = ([vec], node) => {
68
            return EPtr.box(vec.get(this.index));
69
        };
70
        func.implementationData = this;
71
    }
72
}
- a/Tools/WebGPUShadingLanguageRI/BuiltinVectorIndexGetter.js +69 lines
Line 0 a/Tools/WebGPUShadingLanguageRI/BuiltinVectorIndexGetter.js_sec1
1
/*
2
 * Copyright (C) 2017 Apple Inc. All rights reserved.
3
 *
4
 * Redistribution and use in source and binary forms, with or without
5
 * modification, are permitted provided that the following conditions
6
 * are met:
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.
12
 *
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. 
24
 */
25
"use strict";
26
27
class BuiltinVectorIndexGetter {
28
    constructor(baseTypeName, size)
29
    {
30
        this._baseTypeName = baseTypeName;
31
        this._size = size;
32
    }
33
34
    get baseTypeName() { return this._baseTypeName; }
35
    get size() { return this._size; }
36
37
    toString()
38
    {
39
        return `native ${this.baseTypeName} operator[](${this.baseTypeName}${this.size},uint)`;
40
    }
41
42
    static functions()
43
    {
44
        if (!this._allIndexGetters) {
45
            this._allIndexGetters = [];
46
        
47
            const typeNames = [ "uint", "int", "float" ];
48
            const sizes = [ 2, 3, 4 ];
49
50
            for (let typeName of typeNames) {
51
                for (let size of sizes)
52
                    this._allIndexGetters.push(new BuiltinVectorIndexGetter(typeName, size));
53
            }
54
        }
55
        return this._allIndexGetters;
56
    }
57
58
    instantiateImplementation(func)
59
    {
60
        func.implementation = ([vec, index], node) => {
61
            const indexValue = index.loadValue();
62
            if (indexValue >= 0 && indexValue < this.size)
63
                return EPtr.box(vec.get(index.loadValue()));
64
            else
65
                throw new Error(`${indexValue} out of bounds for vector of size ${this.size}`);
66
        };
67
        func.implementationData = this;
68
    }
69
}
- a/Tools/WebGPUShadingLanguageRI/BuiltinVectorIndexSetter.js +74 lines
Line 0 a/Tools/WebGPUShadingLanguageRI/BuiltinVectorIndexSetter.js_sec1
1
/*
2
 * Copyright (C) 2017 Apple Inc. All rights reserved.
3
 *
4
 * Redistribution and use in source and binary forms, with or without
5
 * modification, are permitted provided that the following conditions
6
 * are met:
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.
12
 *
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. 
24
 */
25
"use strict";
26
27
class BuiltinVectorIndexSetter {
28
    constructor(baseTypeName, size)
29
    {
30
        this._baseTypeName = baseTypeName;
31
        this._size = size;
32
    }
33
34
    get baseTypeName() { return this._baseTypeName; }
35
    get size() { return this._size; }
36
    get elementName() { return this._elementName; }
37
    get index() { return this._index; }
38
39
    toString()
40
    {
41
        return `native ${this.baseTypeName}${this.size} operator[]=(${this.baseTypeName}${this.size},uint32,${this.baseTypeName})`;
42
    }
43
44
    static functions()
45
    {
46
        if (!this._functions) {
47
            this._functions = [];
48
        
49
            const typeNames = [ "uint", "int", "float" ];
50
            const sizes = [ 2, 3, 4 ];
51
52
            for (let typeName of typeNames) {
53
                for (let size of sizes)
54
                    this._functions.push(new BuiltinVectorIndexSetter(typeName, size));
55
            }
56
        }
57
        return this._functions;
58
    }
59
60
    instantiateImplementation(func)
61
    {
62
        func.implementation = ([base, index, value], node) => {
63
            const indexValue = index.loadValue();
64
            if (indexValue >= 0 && indexValue < this.size) {
65
                let result = new EPtr(new EBuffer(this.size), 0);
66
                result.copyFrom(base, this.size);
67
                result.plus(indexValue).copyFrom(value, 1);
68
                return result;
69
            } else
70
                throw new Error(`${indexValue} out of bounds for vector of size ${this.size}`);
71
        };
72
        func.implementationData = this;
73
    }
74
}
- a/Tools/WebGPUShadingLanguageRI/BuiltinVectorSetter.js +75 lines
Line 0 a/Tools/WebGPUShadingLanguageRI/BuiltinVectorSetter.js_sec1
1
/*
2
 * Copyright (C) 2017 Apple Inc. All rights reserved.
3
 *
4
 * Redistribution and use in source and binary forms, with or without
5
 * modification, are permitted provided that the following conditions
6
 * are met:
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.
12
 *
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. 
24
 */
25
"use strict";
26
27
class BuiltinVectorSetter {
28
    constructor(baseTypeName, size, elementName, index)
29
    {
30
        this._baseTypeName = baseTypeName;
31
        this._size = size;
32
        this._elementName = elementName;
33
        this._index = index;
34
    }
35
36
    get baseTypeName() { return this._baseTypeName; }
37
    get size() { return this._size; }
38
    get elementName() { return this._elementName; }
39
    get index() { return this._index; }
40
41
    toString()
42
    {
43
        return `native ${this.baseTypeName}${this.size} operator.${this.elementName}=(${this.baseTypeName}${this.size},${this.baseTypeName})`;
44
    }
45
46
    static functions()
47
    {
48
        if (!this._functions) {
49
            this._functions = [];
50
        
51
            const typeNames = [ "uint", "int", "float" ];
52
            const sizes = [ 2, 3, 4 ];
53
            const elements = [ "x", "y", "z", "w" ];
54
55
            for (let typeName of typeNames) {
56
                for (let size of sizes) {
57
                    for (let i = 0; i < size; i++)
58
                        this._functions.push(new BuiltinVectorSetter(typeName, size, elements[i], i));
59
                }
60
            }
61
        }
62
        return this._functions;
63
    }
64
65
    instantiateImplementation(func)
66
    {
67
        func.implementation = ([base, value], node) => {
68
            let result = new EPtr(new EBuffer(this.size), 0);
69
            result.copyFrom(base, this.size);
70
            result.plus(this.index).copyFrom(value, 1);
71
            return result;
72
        };
73
        func.implementationData = this;
74
    }
75
}
- a/Tools/WebGPUShadingLanguageRI/CallExpression.js -4 / +68 lines
Lines 42-58 class CallExpression extends Expression { a/Tools/WebGPUShadingLanguageRI/CallExpression.js_sec1
42
    get isCast() { return this._isCast; }
42
    get isCast() { return this._isCast; }
43
    get returnType() { return this._returnType; }
43
    get returnType() { return this._returnType; }
44
    
44
    
45
    static resolve(origin, possibleOverloads, typeParametersInScope, name, typeArguments, argumentList, argumentTypes, returnType)
45
    static resolve(origin, possibleOverloads, typeParametersInScope, name, typeArguments, argumentList, argumentTypes, returnType, uintType)
46
    {
46
    {
47
        let call = new CallExpression(origin, name, typeArguments, argumentList);
47
        let call = new CallExpression(origin, name, typeArguments, argumentList);
48
        call.argumentTypes = argumentTypes.map(argument => argument.visit(new AutoWrapper()));
48
        call.argumentTypes = argumentTypes.map(argument => argument.visit(new AutoWrapper()));
49
        call.possibleOverloads = possibleOverloads;
49
        call.possibleOverloads = possibleOverloads;
50
        if (returnType)
50
        if (returnType)
51
            call.setCastData(returnType);
51
            call.setCastData(returnType);
52
        return {call, resultType: call.resolve(possibleOverloads, typeParametersInScope, typeArguments)};
52
        return {call, resultType: call.resolve(possibleOverloads, typeParametersInScope, typeArguments, uintType)};
53
    }
53
    }
54
    
54
    
55
    resolve(possibleOverloads, typeParametersInScope, typeArguments)
55
    resolve(possibleOverloads, typeParametersInScope, typeArguments, uintType)
56
    {
56
    {
57
        if (!possibleOverloads)
57
        if (!possibleOverloads)
58
            throw new WTypeError(this.origin.originString, "Did not find any functions named " + this.name);
58
            throw new WTypeError(this.origin.originString, "Did not find any functions named " + this.name);
Lines 77-82 class CallExpression extends Expression { a/Tools/WebGPUShadingLanguageRI/CallExpression.js_sec2
77
        if (!overload) {
77
        if (!overload) {
78
            overload = resolveOverloadImpl(
78
            overload = resolveOverloadImpl(
79
                possibleOverloads, this.typeArguments, this.argumentTypes, this.returnType);
79
                possibleOverloads, this.typeArguments, this.argumentTypes, this.returnType);
80
81
            if (!overload.func && this.name == "operator&[]")
82
                return this._resolveToOperatorAnderIndexer(uintType);
83
84
            if (!overload.func && this.name == "operator.length")
85
                return this._resolveToOperatorLength(uintType);
86
            
80
            if (!overload.func) {
87
            if (!overload.func) {
81
                failures.push(...overload.failures);
88
                failures.push(...overload.failures);
82
                let message = "Did not find function named " + this.name + " for call with ";
89
                let message = "Did not find function named " + this.name + " for call with ";
Lines 108-113 class CallExpression extends Expression { a/Tools/WebGPUShadingLanguageRI/CallExpression.js_sec3
108
        }
115
        }
109
        return this.resolveToOverload(overload);
116
        return this.resolveToOverload(overload);
110
    }
117
    }
118
119
    _resolveToOperatorAnderIndexer(uintType)
120
    {
121
        let arrayRefType = this.argumentTypes[0];
122
        if (!arrayRefType.isArrayRef)
123
            throw new WTypeError(this.origin.originString, `Expected ${arrayRefType} to be an array ref type for operator&[]`);
124
            
125
        let indexType = this.argumentTypes[1];
126
        const addressSpace = arrayRefType.addressSpace;
127
        
128
        // The later checkLiteralTypes stage will verify that the literal can be represented as a uint
129
        uintType = TypeRef.wrap(uintType);
130
        indexType.type = uintType;
131
132
        const elementType = this.argumentTypes[0].elementType;
133
        this.resultType = this._returnType = TypeRef.wrap(new PtrType(this.origin, addressSpace, TypeRef.wrap(elementType)))
134
        
135
        let arrayRefAccessor = new OperatorAnderIndexer(this.returnType.toString(), addressSpace);
136
        let nativeFunc = new NativeFunc(this.origin, "operator&[]", this.resultType, [], [
137
            new FuncParameter(this.origin, null, arrayRefType),
138
            new FuncParameter(this.origin, null, uintType)
139
        ], false, null);
140
141
        arrayRefAccessor.instantiateImplementation(nativeFunc);
142
143
        this.func = nativeFunc;
144
        this.actualTypeArguments = [];
145
        this.instantiatedActualTypeArguments = this.actualTypeArguments;
146
        
147
        return this.resultType;
148
    }
149
150
    _resolveToOperatorLength(uintType)
151
    {
152
        this.resultType = this._returnType = TypeRef.wrap(uintType);
153
                
154
        if (this.argumentTypes[0].isArray) {
155
            const arrayType = this.argumentTypes[0];
156
            this.func = new NativeFunc(this.origin, "operator.length", this.resultType, [], [
157
                new FuncParameter(this.origin, null, arrayType)
158
            ], false, null);
159
            this.func.implementation = (args, node) => EPtr.box(arrayType.numElementsValue);
160
        } else if (this.argumentTypes[0].isArrayRef) {
161
            const arrayRefType = this.argumentTypes[0];
162
            const addressSpace = arrayRefType.addressSpace;
163
            const operatorLength = new OperatorArrayRefLength(arrayRefType.toString(), addressSpace);
164
            this.func = new NativeFunc(this.origin, "operator.length", this.resultType, [], [
165
                new FuncParameter(this.origin, null, arrayRefType)
166
            ], false, null);
167
            operatorLength.instantiateImplementation(this.func);
168
        } else
169
            throw new WTypeError(this.origin.originString, `Expected ${this.argumentTypes[0]} to be array/array ref type for operator.length`);
170
171
        
172
        this.actualTypeArguments = this.instantiatedActualTypeArguments = [];
173
        return this.resultType;
174
    }
111
    
175
    
112
    resolveToOverload(overload)
176
    resolveToOverload(overload)
113
    {
177
    {
Lines 141-147 class CallExpression extends Expression { a/Tools/WebGPUShadingLanguageRI/CallExpression.js_sec4
141
    toString()
205
    toString()
142
    {
206
    {
143
        return (this.isCast ? "operator " + this.returnType : this.name) +
207
        return (this.isCast ? "operator " + this.returnType : this.name) +
144
            "<" + this.typeArguments + ">" +
208
            // "<" + this.typeArguments + ">" +
145
            (this.actualTypeArguments ? "<<" + this.actualTypeArguments + ">>" : "") +
209
            (this.actualTypeArguments ? "<<" + this.actualTypeArguments + ">>" : "") +
146
            "(" + this.argumentList + ")";
210
            "(" + this.argumentList + ")";
147
    }
211
    }
- a/Tools/WebGPUShadingLanguageRI/Checker.js -3 / +3 lines
Lines 427-433 class Checker extends Visitor { a/Tools/WebGPUShadingLanguageRI/Checker.js_sec1
427
        try {
427
        try {
428
            let result = CallExpression.resolve(
428
            let result = CallExpression.resolve(
429
                node.origin, node.possibleGetOverloads, this._currentStatement.typeParameters,
429
                node.origin, node.possibleGetOverloads, this._currentStatement.typeParameters,
430
                node.getFuncName, [], [node.base, ...extraArgs], [baseType, ...extraArgTypes], null);
430
                node.getFuncName, [], [node.base, ...extraArgs], [baseType, ...extraArgTypes], null, this._program.types.get("uint32"));
431
            node.callForGet = result.call;
431
            node.callForGet = result.call;
432
            node.resultTypeForGet = result.resultType;
432
            node.resultTypeForGet = result.resultType;
433
        } catch (e) {
433
        } catch (e) {
Lines 442-448 class Checker extends Visitor { a/Tools/WebGPUShadingLanguageRI/Checker.js_sec2
442
            let result = CallExpression.resolve(
442
            let result = CallExpression.resolve(
443
                node.origin, node.possibleAndOverloads, this._currentStatement.typeParameters,
443
                node.origin, node.possibleAndOverloads, this._currentStatement.typeParameters,
444
                node.andFuncName, [], [baseForAnd, ...extraArgs], [typeForAnd, ...extraArgTypes],
444
                node.andFuncName, [], [baseForAnd, ...extraArgs], [typeForAnd, ...extraArgTypes],
445
                null);
445
                null, this._program.types.get("uint32"));
446
            node.callForAnd = result.call;
446
            node.callForAnd = result.call;
447
            node.resultTypeForAnd = result.resultType.unifyNode.returnTypeFromAndOverload(node.origin);
447
            node.resultTypeForAnd = result.resultType.unifyNode.returnTypeFromAndOverload(node.origin);
448
        } catch (e) {
448
        } catch (e) {
Lines 467-473 class Checker extends Visitor { a/Tools/WebGPUShadingLanguageRI/Checker.js_sec3
467
        try {
467
        try {
468
            let result = CallExpression.resolve(
468
            let result = CallExpression.resolve(
469
                node.origin, node.possibleSetOverloads, this._currentStatement.typeParameters,
469
                node.origin, node.possibleSetOverloads, this._currentStatement.typeParameters,
470
                node.setFuncName, [], [node.base, ...extraArgs, null], [baseType, ...extraArgTypes, node.resultType], null);
470
                node.setFuncName, [], [node.base, ...extraArgs, null], [baseType, ...extraArgTypes, node.resultType], null, this._program.types.get("uint32"));
471
            node.callForSet = result.call;
471
            node.callForSet = result.call;
472
            if (!result.resultType.equals(baseType))
472
            if (!result.resultType.equals(baseType))
473
                throw new WTypeError(node.origin.originString, "Result type of setter " + result.call.func + " is not the base type " + baseType);
473
                throw new WTypeError(node.origin.originString, "Result type of setter " + result.call.func + " is not the base type " + baseType);
- a/Tools/WebGPUShadingLanguageRI/DoubleLiteral.js -41 lines
Lines 1-41 a/Tools/WebGPUShadingLanguageRI/DoubleLiteral.js_sec1
1
/*
2
 * Copyright (C) 2017 Apple Inc. All rights reserved.
3
 *
4
 * Redistribution and use in source and binary forms, with or without
5
 * modification, are permitted provided that the following conditions
6
 * are met:
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.
12
 *
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. 
24
 */
25
"use strict";
26
27
let DoubleLiteral = createLiteral({
28
    literalClassName: "DoubleLiteral",
29
    preferredTypeName: "double",
30
    
31
    negConstexpr(origin)
32
    {
33
        return new IntLiteral(origin, -this.value);
34
    },
35
    
36
    createType(origin, value)
37
    {
38
        return new DoubleLiteralType(origin, value);
39
    }
40
});
41
- a/Tools/WebGPUShadingLanguageRI/DoubleLiteralType.js -39 lines
Lines 1-39 a/Tools/WebGPUShadingLanguageRI/DoubleLiteralType.js_sec1
1
/*
2
 * Copyright (C) 2017 Apple Inc. All rights reserved.
3
 *
4
 * Redistribution and use in source and binary forms, with or without
5
 * modification, are permitted provided that the following conditions
6
 * are met:
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.
12
 *
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. 
24
 */
25
"use strict";
26
27
let DoubleLiteralType = createLiteralType({
28
    preferredTypeName: "double",
29
    
30
    verifyAsArgument(unificationContext)
31
    {
32
        let realThis = unificationContext.find(this);
33
        if (!realThis.isFloating)
34
            return {result: false, reason: "Cannot use double literal with non-floating type " + realThis};
35
        if (!realThis.canRepresent(this.value))
36
            return {result: false, reason: "Float literal " + this.value + " does not fit in type " + realThis};
37
        return {result: true};
38
    }
39
});
- a/Tools/WebGPUShadingLanguageRI/Func.js -2 / +2 lines
Lines 65-73 class Func extends Node { a/Tools/WebGPUShadingLanguageRI/Func.js_sec1
65
        if (this.shaderType)
65
        if (this.shaderType)
66
            result += this.shaderType + " ";
66
            result += this.shaderType + " ";
67
        if (this.isCast)
67
        if (this.isCast)
68
            result += "operator<" + this.typeParameters + "> " + this.returnType;
68
            result += `operator ${this.returnType}`;
69
        else
69
        else
70
            result += this.returnType + " " + this.name + "<" + this.typeParameters + ">";
70
            result += `${this.returnType} ${this.name}`;
71
        return result + "(" + this.parameters + ")";
71
        return result + "(" + this.parameters + ")";
72
    }
72
    }
73
    
73
    
- a/Tools/WebGPUShadingLanguageRI/FuncInstantiator.js +3 lines
Lines 40-45 class FuncInstantiator { a/Tools/WebGPUShadingLanguageRI/FuncInstantiator.js_sec1
40
    // resolutions on the original Program.
40
    // resolutions on the original Program.
41
    getUnique(func, typeArguments)
41
    getUnique(func, typeArguments)
42
    {
42
    {
43
        if (!typeArguments)
44
            typeArguments = [];
45
        
43
        class FindTypeVariable extends Visitor {
46
        class FindTypeVariable extends Visitor {
44
            visitTypeRef(node)
47
            visitTypeRef(node)
45
            {
48
            {
- a/Tools/WebGPUShadingLanguageRI/Intrinsics.js -230 / +106 lines
Lines 35-41 class Intrinsics { a/Tools/WebGPUShadingLanguageRI/Intrinsics.js_sec1
35
        // use "int" here, since we don't yet know that they are the same type.
35
        // use "int" here, since we don't yet know that they are the same type.
36
        
36
        
37
        this._map.set(
37
        this._map.set(
38
            "native typedef void<>",
38
            "native typedef void",
39
            type => {
39
            type => {
40
                this.void = type;
40
                this.void = type;
41
                type.size = 0;
41
                type.size = 0;
Lines 57-63 class Intrinsics { a/Tools/WebGPUShadingLanguageRI/Intrinsics.js_sec2
57
        }
57
        }
58
58
59
        this._map.set(
59
        this._map.set(
60
            "native typedef int32<>",
60
            "native typedef int32",
61
            type => {
61
            type => {
62
                this.int32 = type;
62
                this.int32 = type;
63
                type.isPrimitive = true;
63
                type.isPrimitive = true;
Lines 82-88 class Intrinsics { a/Tools/WebGPUShadingLanguageRI/Intrinsics.js_sec3
82
            });
82
            });
83
83
84
        this._map.set(
84
        this._map.set(
85
            "native typedef uint32<>",
85
            "native typedef uint32",
86
            type => {
86
            type => {
87
                this.uint32 = type;
87
                this.uint32 = type;
88
                type.isPrimitive = true;
88
                type.isPrimitive = true;
Lines 105-111 class Intrinsics { a/Tools/WebGPUShadingLanguageRI/Intrinsics.js_sec4
105
            });
105
            });
106
106
107
        this._map.set(
107
        this._map.set(
108
            "native typedef uint8<>",
108
            "native typedef uint8",
109
            type => {
109
            type => {
110
                this.uint8 = type;
110
                this.uint8 = type;
111
                type.isInt = true;
111
                type.isInt = true;
Lines 127-133 class Intrinsics { a/Tools/WebGPUShadingLanguageRI/Intrinsics.js_sec5
127
            });
127
            });
128
128
129
        this._map.set(
129
        this._map.set(
130
            "native typedef float32<>",
130
            "native typedef float32",
131
            type => {
131
            type => {
132
                this.float = type;
132
                this.float = type;
133
                type.isPrimitive = true;
133
                type.isPrimitive = true;
Lines 139-676 class Intrinsics { a/Tools/WebGPUShadingLanguageRI/Intrinsics.js_sec6
139
                type.formatValueFromIntLiteral = value => value;
139
                type.formatValueFromIntLiteral = value => value;
140
                type.formatValueFromUintLiteral = value => value;
140
                type.formatValueFromUintLiteral = value => value;
141
                type.formatValueFromFloatLiteral = value => Math.fround(value);
141
                type.formatValueFromFloatLiteral = value => Math.fround(value);
142
                type.formatValueFromDoubleLiteral = value => Math.fround(value);
143
            });
142
            });
144
143
145
        this._map.set(
144
        this._map.set(
146
            "native typedef float64<>",
145
            "native typedef bool",
147
            type => {
148
                this.double = type;
149
                type.isPrimitive = true;
150
                type.size = 1;
151
                type.isFloating = true;
152
                type.isNumber = true;
153
                type.canRepresent = value => true;
154
                type.populateDefaultValue = (buffer, offset) => buffer.set(offset, 0);
155
                type.formatValueFromIntLiteral = value => value;
156
                type.formatValueFromUintLiteral = value => value;
157
                type.formatValueFromFloatLiteral = value => value;
158
                type.formatValueFromDoubleLiteral = value => value;
159
            });
160
161
        this._map.set(
162
            "native typedef bool<>",
163
            type => {
146
            type => {
164
                this.bool = type;
147
                this.bool = type;
165
                type.isPrimitive = true;
148
                type.isPrimitive = true;
166
                type.size = 1;
149
                type.size = 1;
167
                type.populateDefaultValue = (buffer, offset) => buffer.set(offset, false);
150
                type.populateDefaultValue = (buffer, offset) => buffer.set(offset, false);
168
            });
151
            });
152
153
        const vectorTypes = [ "int", "uint", "float" ];
154
        for (let vectorType of vectorTypes) {
155
            for (let size = 2; size <= 4; size++) {
156
                const name = `${vectorType}${size}`;
157
                this._map.set(
158
                    `native typedef ${name}`,
159
                    type  => {
160
                        this[name] = type;
161
                        type.isPrimitive = true;
162
                        type.size = size;
163
                        type.populateDefaultValue = (buffer, offset) => {
164
                            for (let i = 0; i < size; i++) {
165
                                buffer.set(offset + i, 0);
166
                            }
167
                        }
168
                    }
169
                )
170
            }
171
        }
169
        
172
        
170
        this._map.set(
173
        this._map.set(
171
            "native operator<> int32(uint32)",
174
            "native operator int32(uint32)",
172
            func => {
173
                func.implementation = ([value]) => EPtr.box(value.loadValue() | 0);
174
            });
175
        
176
        this._map.set(
177
            "native operator<> int32(uint8)",
178
            func => {
175
            func => {
179
                func.implementation = ([value]) => EPtr.box(value.loadValue() | 0);
176
                func.implementation = ([value]) => EPtr.box(value.loadValue() | 0);
180
            });
177
            });
181
        
178
        
182
        this._map.set(
179
        this._map.set(
183
            "native operator<> int32(float)",
180
            "native operator int32(uint8)",
184
            func => {
181
            func => {
185
                func.implementation = ([value]) => EPtr.box(value.loadValue() | 0);
182
                func.implementation = ([value]) => EPtr.box(value.loadValue() | 0);
186
            });
183
            });
187
        
184
        
188
        this._map.set(
185
        this._map.set(
189
            "native operator<> int32(double)",
186
            "native operator int32(float)",
190
            func => {
187
            func => {
191
                func.implementation = ([value]) => EPtr.box(value.loadValue() | 0);
188
                func.implementation = ([value]) => EPtr.box(value.loadValue() | 0);
192
            });
189
            });
193
        
190
        
194
        this._map.set(
191
        this._map.set(
195
            "native operator<> uint32(int32)",
192
            "native operator uint32(int32)",
196
            func => {
197
                func.implementation = ([value]) => EPtr.box(value.loadValue() >>> 0);
198
            });
199
        
200
        this._map.set(
201
            "native operator<> uint32(uint8)",
202
            func => {
193
            func => {
203
                func.implementation = ([value]) => EPtr.box(value.loadValue() >>> 0);
194
                func.implementation = ([value]) => EPtr.box(value.loadValue() >>> 0);
204
            });
195
            });
205
        
196
        
206
        this._map.set(
197
        this._map.set(
207
            "native operator<> uint32(float)",
198
            "native operator uint32(uint8)",
208
            func => {
199
            func => {
209
                func.implementation = ([value]) => EPtr.box(value.loadValue() >>> 0);
200
                func.implementation = ([value]) => EPtr.box(value.loadValue() >>> 0);
210
            });
201
            });
211
        
202
        
212
        this._map.set(
203
        this._map.set(
213
            "native operator<> uint32(double)",
204
            "native operator uint32(float)",
214
            func => {
205
            func => {
215
                func.implementation = ([value]) => EPtr.box(value.loadValue() >>> 0);
206
                func.implementation = ([value]) => EPtr.box(value.loadValue() >>> 0);
216
            });
207
            });
217
        
208
        
218
        this._map.set(
209
        this._map.set(
219
            "native operator<> uint8(int32)",
210
            "native operator uint8(int32)",
220
            func => {
211
            func => {
221
                func.implementation = ([value]) => EPtr.box(value.loadValue() & 0xff);
212
                func.implementation = ([value]) => EPtr.box(value.loadValue() & 0xff);
222
            });
213
            });
223
        
214
        
224
        this._map.set(
215
        this._map.set(
225
            "native operator<> uint8(uint32)",
216
            "native operator uint8(uint32)",
226
            func => {
217
            func => {
227
                func.implementation = ([value]) => EPtr.box(value.loadValue() & 0xff);
218
                func.implementation = ([value]) => EPtr.box(value.loadValue() & 0xff);
228
            });
219
            });
229
        
220
        
230
        this._map.set(
221
        this._map.set(
231
            "native operator<> uint8(float)",
222
            "native operator uint8(float)",
232
            func => {
223
            func => {
233
                func.implementation = ([value]) => EPtr.box(value.loadValue() & 0xff);
224
                func.implementation = ([value]) => EPtr.box(value.loadValue() & 0xff);
234
            });
225
            });
235
        
226
        
236
        this._map.set(
227
        this._map.set(
237
            "native operator<> uint8(double)",
228
            "native operator float(int32)",
238
            func => {
239
                func.implementation = ([value]) => EPtr.box(value.loadValue() & 0xff);
240
            });
241
        
242
        this._map.set(
243
            "native operator<> float(double)",
244
            func => {
229
            func => {
245
                func.implementation = ([value]) => EPtr.box(Math.fround(value.loadValue()));
230
                func.implementation = ([value]) => EPtr.box(Math.fround(value.loadValue()));
246
            });
231
            });
247
        
232
        
248
        this._map.set(
233
        this._map.set(
249
            "native operator<> float(int32)",
234
            "native operator float(uint32)",
250
            func => {
235
            func => {
251
                func.implementation = ([value]) => EPtr.box(Math.fround(value.loadValue()));
236
                func.implementation = ([value]) => EPtr.box(Math.fround(value.loadValue()));
252
            });
237
            });
253
        
238
        
254
        this._map.set(
239
        this._map.set(
255
            "native operator<> float(uint32)",
240
            "native operator float(uint8)",
256
            func => {
241
            func => {
257
                func.implementation = ([value]) => EPtr.box(Math.fround(value.loadValue()));
242
                func.implementation = ([value]) => EPtr.box(Math.fround(value.loadValue()));
258
            });
243
            });
259
        
244
        
260
        this._map.set(
245
        this._map.set(
261
            "native operator<> float(uint8)",
246
            "native int operator+(int,int)",
262
            func => {
263
                func.implementation = ([value]) => EPtr.box(Math.fround(value.loadValue()));
264
            });
265
        
266
        this._map.set(
267
            "native operator<> double(float)",
268
            func => {
269
                func.implementation = ([value]) => EPtr.box(value.loadValue());
270
            });
271
        
272
        this._map.set(
273
            "native operator<> double(int32)",
274
            func => {
275
                func.implementation = ([value]) => EPtr.box(value.loadValue());
276
            });
277
        
278
        this._map.set(
279
            "native operator<> double(uint32)",
280
            func => {
281
                func.implementation = ([value]) => EPtr.box(value.loadValue());
282
            });
283
        
284
        this._map.set(
285
            "native operator<> double(uint8)",
286
            func => {
287
                func.implementation = ([value]) => EPtr.box(value.loadValue());
288
            });
289
        
290
        this._map.set(
291
            "native int operator+<>(int,int)",
292
            func => {
247
            func => {
293
                func.implementation = ([left, right]) =>
248
                func.implementation = ([left, right]) =>
294
                    EPtr.box((left.loadValue() + right.loadValue()) | 0);
249
                    EPtr.box((left.loadValue() + right.loadValue()) | 0);
295
            });
250
            });
296
        
251
        
297
        this._map.set(
252
        this._map.set(
298
            "native uint operator+<>(uint,uint)",
253
            "native uint operator+(uint,uint)",
299
            func => {
254
            func => {
300
                func.implementation = ([left, right]) =>
255
                func.implementation = ([left, right]) =>
301
                    EPtr.box((left.loadValue() + right.loadValue()) >>> 0);
256
                    EPtr.box((left.loadValue() + right.loadValue()) >>> 0);
302
            });
257
            });
303
        
258
        
304
        this._map.set(
259
        this._map.set(
305
            "native float operator+<>(float,float)",
260
            "native float operator+(float,float)",
306
            func => {
261
            func => {
307
                func.implementation = ([left, right]) =>
262
                func.implementation = ([left, right]) =>
308
                    EPtr.box(Math.fround(left.loadValue() + right.loadValue()));
263
                    EPtr.box(Math.fround(left.loadValue() + right.loadValue()));
309
            });
264
            });
310
        
265
        
311
        this._map.set(
266
        this._map.set(
312
            "native double operator+<>(double,double)",
267
            "native int operator-(int,int)",
313
            func => {
314
                func.implementation = ([left, right]) =>
315
                    EPtr.box(left.loadValue() + right.loadValue());
316
            });
317
        
318
        this._map.set(
319
            "native int operator-<>(int,int)",
320
            func => {
268
            func => {
321
                func.implementation = ([left, right]) =>
269
                func.implementation = ([left, right]) =>
322
                    EPtr.box((left.loadValue() - right.loadValue()) | 0);
270
                    EPtr.box((left.loadValue() - right.loadValue()) | 0);
323
            });
271
            });
324
        
272
        
325
        this._map.set(
273
        this._map.set(
326
            "native uint operator-<>(uint,uint)",
274
            "native uint operator-(uint,uint)",
327
            func => {
275
            func => {
328
                func.implementation = ([left, right]) =>
276
                func.implementation = ([left, right]) =>
329
                    EPtr.box((left.loadValue() - right.loadValue()) >>> 0);
277
                    EPtr.box((left.loadValue() - right.loadValue()) >>> 0);
330
            });
278
            });
331
        
279
        
332
        this._map.set(
280
        this._map.set(
333
            "native float operator-<>(float,float)",
281
            "native float operator-(float,float)",
334
            func => {
282
            func => {
335
                func.implementation = ([left, right]) =>
283
                func.implementation = ([left, right]) =>
336
                    EPtr.box(Math.fround(left.loadValue() - right.loadValue()));
284
                    EPtr.box(Math.fround(left.loadValue() - right.loadValue()));
337
            });
285
            });
338
        
286
        
339
        this._map.set(
287
        this._map.set(
340
            "native double operator-<>(double,double)",
288
            "native int operator*(int,int)",
341
            func => {
289
            func => {
342
                func.implementation = ([left, right]) =>
290
                func.implementation = ([left, right]) => {
343
                    EPtr.box(left.loadValue() - right.loadValue());
291
                    return EPtr.box((left.loadValue() * right.loadValue()) | 0);
344
            });
292
                };
345
        
346
        this._map.set(
347
            "native int operator*<>(int,int)",
348
            func => {
349
                func.implementation = ([left, right]) =>
350
                    EPtr.box((left.loadValue() * right.loadValue()) | 0);
351
            });
293
            });
352
        
294
        
353
        this._map.set(
295
        this._map.set(
354
            "native uint operator*<>(uint,uint)",
296
            "native uint operator*(uint,uint)",
355
            func => {
297
            func => {
356
                func.implementation = ([left, right]) =>
298
                func.implementation = ([left, right]) =>
357
                    EPtr.box((left.loadValue() * right.loadValue()) >>> 0);
299
                    EPtr.box((left.loadValue() * right.loadValue()) >>> 0);
358
            });
300
            });
359
        
301
        
360
        this._map.set(
302
        this._map.set(
361
            "native float operator*<>(float,float)",
303
            "native float operator*(float,float)",
362
            func => {
304
            func => {
363
                func.implementation = ([left, right]) =>
305
                func.implementation = ([left, right]) =>
364
                    EPtr.box(Math.fround(left.loadValue() * right.loadValue()));
306
                    EPtr.box(Math.fround(left.loadValue() * right.loadValue()));
365
            });
307
            });
366
        
308
        
367
        this._map.set(
309
        this._map.set(
368
            "native double operator*<>(double,double)",
310
            "native int operator/(int,int)",
369
            func => {
370
                func.implementation = ([left, right]) =>
371
                    EPtr.box(left.loadValue() * right.loadValue());
372
            });
373
        
374
        this._map.set(
375
            "native int operator/<>(int,int)",
376
            func => {
311
            func => {
377
                func.implementation = ([left, right]) =>
312
                func.implementation = ([left, right]) =>
378
                    EPtr.box((left.loadValue() / right.loadValue()) | 0);
313
                    EPtr.box((left.loadValue() / right.loadValue()) | 0);
379
            });
314
            });
380
        
315
        
381
        this._map.set(
316
        this._map.set(
382
            "native uint operator/<>(uint,uint)",
317
            "native uint operator/(uint,uint)",
383
            func => {
318
            func => {
384
                func.implementation = ([left, right]) =>
319
                func.implementation = ([left, right]) =>
385
                    EPtr.box((left.loadValue() / right.loadValue()) >>> 0);
320
                    EPtr.box((left.loadValue() / right.loadValue()) >>> 0);
386
            });
321
            });
387
        
322
        
388
        this._map.set(
323
        this._map.set(
389
            "native int operator&<>(int,int)",
324
            "native int operator&(int,int)",
390
            func => {
325
            func => {
391
                func.implementation = ([left, right]) =>
326
                func.implementation = ([left, right]) =>
392
                    EPtr.box(left.loadValue() & right.loadValue());
327
                    EPtr.box(left.loadValue() & right.loadValue());
393
            });
328
            });
394
        
329
        
395
        this._map.set(
330
        this._map.set(
396
            "native uint operator&<>(uint,uint)",
331
            "native uint operator&(uint,uint)",
397
            func => {
332
            func => {
398
                func.implementation = ([left, right]) =>
333
                func.implementation = ([left, right]) =>
399
                    EPtr.box((left.loadValue() & right.loadValue()) >>> 0);
334
                    EPtr.box((left.loadValue() & right.loadValue()) >>> 0);
400
            });
335
            });
401
        
336
        
402
        this._map.set(
337
        this._map.set(
403
            "native int operator|<>(int,int)",
338
            "native int operator|(int,int)",
404
            func => {
339
            func => {
405
                func.implementation = ([left, right]) =>
340
                func.implementation = ([left, right]) =>
406
                    EPtr.box(left.loadValue() | right.loadValue());
341
                    EPtr.box(left.loadValue() | right.loadValue());
407
            });
342
            });
408
        
343
        
409
        this._map.set(
344
        this._map.set(
410
            "native uint operator|<>(uint,uint)",
345
            "native uint operator|(uint,uint)",
411
            func => {
346
            func => {
412
                func.implementation = ([left, right]) =>
347
                func.implementation = ([left, right]) =>
413
                    EPtr.box((left.loadValue() | right.loadValue()) >>> 0);
348
                    EPtr.box((left.loadValue() | right.loadValue()) >>> 0);
414
            });
349
            });
415
        
350
        
416
        this._map.set(
351
        this._map.set(
417
            "native int operator^<>(int,int)",
352
            "native int operator^(int,int)",
418
            func => {
353
            func => {
419
                func.implementation = ([left, right]) =>
354
                func.implementation = ([left, right]) =>
420
                    EPtr.box(left.loadValue() ^ right.loadValue());
355
                    EPtr.box(left.loadValue() ^ right.loadValue());
421
            });
356
            });
422
        
357
        
423
        this._map.set(
358
        this._map.set(
424
            "native uint operator^<>(uint,uint)",
359
            "native uint operator^(uint,uint)",
425
            func => {
360
            func => {
426
                func.implementation = ([left, right]) =>
361
                func.implementation = ([left, right]) =>
427
                    EPtr.box((left.loadValue() ^ right.loadValue()) >>> 0);
362
                    EPtr.box((left.loadValue() ^ right.loadValue()) >>> 0);
428
            });
363
            });
429
        
364
        
430
        this._map.set(
365
        this._map.set(
431
            "native int operator<<<>(int,uint)",
366
            "native int operator<<(int,uint)",
432
            func => {
367
            func => {
433
                func.implementation = ([left, right]) =>
368
                func.implementation = ([left, right]) =>
434
                    EPtr.box(left.loadValue() << right.loadValue());
369
                    EPtr.box(left.loadValue() << right.loadValue());
435
            });
370
            });
436
        
371
        
437
        this._map.set(
372
        this._map.set(
438
            "native uint operator<<<>(uint,uint)",
373
            "native uint operator<<(uint,uint)",
439
            func => {
374
            func => {
440
                func.implementation = ([left, right]) =>
375
                func.implementation = ([left, right]) =>
441
                    EPtr.box((left.loadValue() << right.loadValue()) >>> 0);
376
                    EPtr.box((left.loadValue() << right.loadValue()) >>> 0);
442
            });
377
            });
443
        
378
        
444
        this._map.set(
379
        this._map.set(
445
            "native int operator>><>(int,uint)",
380
            "native int operator>>(int,uint)",
446
            func => {
381
            func => {
447
                func.implementation = ([left, right]) =>
382
                func.implementation = ([left, right]) =>
448
                    EPtr.box(left.loadValue() >> right.loadValue());
383
                    EPtr.box(left.loadValue() >> right.loadValue());
449
            });
384
            });
450
        
385
        
451
        this._map.set(
386
        this._map.set(
452
            "native uint operator>><>(uint,uint)",
387
            "native uint operator>>(uint,uint)",
453
            func => {
388
            func => {
454
                func.implementation = ([left, right]) =>
389
                func.implementation = ([left, right]) =>
455
                    EPtr.box(left.loadValue() >>> right.loadValue());
390
                    EPtr.box(left.loadValue() >>> right.loadValue());
456
            });
391
            });
457
        
392
        
458
        this._map.set(
393
        this._map.set(
459
            "native int operator~<>(int)",
394
            "native int operator~(int)",
460
            func => {
395
            func => {
461
                func.implementation = ([value]) => EPtr.box(~value.loadValue());
396
                func.implementation = ([value]) => EPtr.box(~value.loadValue());
462
            });
397
            });
463
        
398
        
464
        this._map.set(
399
        this._map.set(
465
            "native uint operator~<>(uint)",
400
            "native uint operator~(uint)",
466
            func => {
401
            func => {
467
                func.implementation = ([value]) => EPtr.box((~value.loadValue()) >>> 0);
402
                func.implementation = ([value]) => EPtr.box((~value.loadValue()) >>> 0);
468
            });
403
            });
469
        
404
        
470
        this._map.set(
405
        this._map.set(
471
            "native float operator/<>(float,float)",
406
            "native float operator/(float,float)",
472
            func => {
407
            func => {
473
                func.implementation = ([left, right]) =>
408
                func.implementation = ([left, right]) =>
474
                    EPtr.box(Math.fround(left.loadValue() / right.loadValue()));
409
                    EPtr.box(Math.fround(left.loadValue() / right.loadValue()));
475
            });
410
            });
476
        
411
        
477
        this._map.set(
412
        this._map.set(
478
            "native double operator/<>(double,double)",
413
            "native bool operator==(int,int)",
479
            func => {
480
                func.implementation = ([left, right]) =>
481
                    EPtr.box(left.loadValue() / right.loadValue());
482
            });
483
        
484
        this._map.set(
485
            "native bool operator==<>(int,int)",
486
            func => {
487
                func.implementation = ([left, right]) =>
488
                    EPtr.box(left.loadValue() == right.loadValue());
489
            });
490
        
491
        this._map.set(
492
            "native bool operator==<>(uint,uint)",
493
            func => {
414
            func => {
494
                func.implementation = ([left, right]) =>
415
                func.implementation = ([left, right]) =>
495
                    EPtr.box(left.loadValue() == right.loadValue());
416
                    EPtr.box(left.loadValue() == right.loadValue());
496
            });
417
            });
497
        
418
        
498
        this._map.set(
419
        this._map.set(
499
            "native bool operator==<>(bool,bool)",
420
            "native bool operator==(uint,uint)",
500
            func => {
421
            func => {
501
                func.implementation = ([left, right]) =>
422
                func.implementation = ([left, right]) =>
502
                    EPtr.box(left.loadValue() == right.loadValue());
423
                    EPtr.box(left.loadValue() == right.loadValue());
503
            });
424
            });
504
        
425
        
505
        this._map.set(
426
        this._map.set(
506
            "native bool operator==<>(float,float)",
427
            "native bool operator==(bool,bool)",
507
            func => {
428
            func => {
508
                func.implementation = ([left, right]) =>
429
                func.implementation = ([left, right]) =>
509
                    EPtr.box(left.loadValue() == right.loadValue());
430
                    EPtr.box(left.loadValue() == right.loadValue());
510
            });
431
            });
511
        
432
        
512
        this._map.set(
433
        this._map.set(
513
            "native bool operator==<>(double,double)",
434
            "native bool operator==(float,float)",
514
            func => {
435
            func => {
515
                func.implementation = ([left, right]) =>
436
                func.implementation = ([left, right]) =>
516
                    EPtr.box(left.loadValue() == right.loadValue());
437
                    EPtr.box(left.loadValue() == right.loadValue());
517
            });
438
            });
518
        
439
        
519
        this._map.set(
440
        this._map.set(
520
            "native bool operator<<>(int,int)",
441
            "native bool operator<(int,int)",
521
            func => {
522
                func.implementation = ([left, right]) =>
523
                    EPtr.box(left.loadValue() < right.loadValue());
524
            });
525
        
526
        this._map.set(
527
            "native bool operator<<>(uint,uint)",
528
            func => {
442
            func => {
529
                func.implementation = ([left, right]) =>
443
                func.implementation = ([left, right]) =>
530
                    EPtr.box(left.loadValue() < right.loadValue());
444
                    EPtr.box(left.loadValue() < right.loadValue());
531
            });
445
            });
532
        
446
        
533
        this._map.set(
447
        this._map.set(
534
            "native bool operator<<>(float,float)",
448
            "native bool operator<(uint,uint)",
535
            func => {
449
            func => {
536
                func.implementation = ([left, right]) =>
450
                func.implementation = ([left, right]) =>
537
                    EPtr.box(left.loadValue() < right.loadValue());
451
                    EPtr.box(left.loadValue() < right.loadValue());
538
            });
452
            });
539
        
453
        
540
        this._map.set(
454
        this._map.set(
541
            "native bool operator<<>(double,double)",
455
            "native bool operator<(float,float)",
542
            func => {
456
            func => {
543
                func.implementation = ([left, right]) =>
457
                func.implementation = ([left, right]) =>
544
                    EPtr.box(left.loadValue() < right.loadValue());
458
                    EPtr.box(left.loadValue() < right.loadValue());
545
            });
459
            });
546
        
460
        
547
        this._map.set(
461
        this._map.set(
548
            "native bool operator<=<>(int,int)",
462
            "native bool operator<=(int,int)",
549
            func => {
463
            func => {
550
                func.implementation = ([left, right]) =>
464
                func.implementation = ([left, right]) =>
551
                    EPtr.box(left.loadValue() <= right.loadValue());
465
                    EPtr.box(left.loadValue() <= right.loadValue());
552
            });
466
            });
553
        
467
        
554
        this._map.set(
468
        this._map.set(
555
            "native bool operator<=<>(uint,uint)",
469
            "native bool operator<=(uint,uint)",
556
            func => {
470
            func => {
557
                func.implementation = ([left, right]) =>
471
                func.implementation = ([left, right]) =>
558
                    EPtr.box(left.loadValue() <= right.loadValue());
472
                    EPtr.box(left.loadValue() <= right.loadValue());
559
            });
473
            });
560
        
474
        
561
        this._map.set(
475
        this._map.set(
562
            "native bool operator<=<>(float,float)",
476
            "native bool operator<=(float,float)",
563
            func => {
477
            func => {
564
                func.implementation = ([left, right]) =>
478
                func.implementation = ([left, right]) =>
565
                    EPtr.box(left.loadValue() <= right.loadValue());
479
                    EPtr.box(left.loadValue() <= right.loadValue());
566
            });
480
            });
567
        
481
        
568
        this._map.set(
482
        this._map.set(
569
            "native bool operator<=<>(double,double)",
483
            "native bool operator>(int,int)",
570
            func => {
571
                func.implementation = ([left, right]) =>
572
                    EPtr.box(left.loadValue() <= right.loadValue());
573
            });
574
        
575
        this._map.set(
576
            "native bool operator><>(int,int)",
577
            func => {
578
                func.implementation = ([left, right]) =>
579
                    EPtr.box(left.loadValue() > right.loadValue());
580
            });
581
        
582
        this._map.set(
583
            "native bool operator><>(uint,uint)",
584
            func => {
484
            func => {
585
                func.implementation = ([left, right]) =>
485
                func.implementation = ([left, right]) =>
586
                    EPtr.box(left.loadValue() > right.loadValue());
486
                    EPtr.box(left.loadValue() > right.loadValue());
587
            });
487
            });
588
        
488
        
589
        this._map.set(
489
        this._map.set(
590
            "native bool operator><>(float,float)",
490
            "native bool operator>(uint,uint)",
591
            func => {
491
            func => {
592
                func.implementation = ([left, right]) =>
492
                func.implementation = ([left, right]) =>
593
                    EPtr.box(left.loadValue() > right.loadValue());
493
                    EPtr.box(left.loadValue() > right.loadValue());
594
            });
494
            });
595
        
495
        
596
        this._map.set(
496
        this._map.set(
597
            "native bool operator><>(double,double)",
497
            "native bool operator>(float,float)",
598
            func => {
498
            func => {
599
                func.implementation = ([left, right]) =>
499
                func.implementation = ([left, right]) =>
600
                    EPtr.box(left.loadValue() > right.loadValue());
500
                    EPtr.box(left.loadValue() > right.loadValue());
601
            });
501
            });
602
        
502
        
603
        this._map.set(
503
        this._map.set(
604
            "native bool operator>=<>(int,int)",
504
            "native bool operator>=(int,int)",
605
            func => {
606
                func.implementation = ([left, right]) =>
607
                    EPtr.box(left.loadValue() >= right.loadValue());
608
            });
609
        
610
        this._map.set(
611
            "native bool operator>=<>(uint,uint)",
612
            func => {
505
            func => {
613
                func.implementation = ([left, right]) =>
506
                func.implementation = ([left, right]) =>
614
                    EPtr.box(left.loadValue() >= right.loadValue());
507
                    EPtr.box(left.loadValue() >= right.loadValue());
615
            });
508
            });
616
        
509
        
617
        this._map.set(
510
        this._map.set(
618
            "native bool operator>=<>(float,float)",
511
            "native bool operator>=(uint,uint)",
619
            func => {
512
            func => {
620
                func.implementation = ([left, right]) =>
513
                func.implementation = ([left, right]) =>
621
                    EPtr.box(left.loadValue() >= right.loadValue());
514
                    EPtr.box(left.loadValue() >= right.loadValue());
622
            });
515
            });
623
        
516
        
624
        this._map.set(
517
        this._map.set(
625
            "native bool operator>=<>(double,double)",
518
            "native bool operator>=(float,float)",
626
            func => {
519
            func => {
627
                func.implementation = ([left, right]) =>
520
                func.implementation = ([left, right]) =>
628
                    EPtr.box(left.loadValue() >= right.loadValue());
521
                    EPtr.box(left.loadValue() >= right.loadValue());
629
            });
522
            });
630
        
631
        for (let addressSpace of addressSpaces) {
632
            this._map.set(
633
                `native T* ${addressSpace} operator&[]<T>(T[] ${addressSpace},uint)`,
634
                func => {
635
                    func.implementation = ([ref, index], node) => {
636
                        ref = ref.loadValue();
637
                        if (!ref)
638
                            throw new WTrapError(node.origin.originString, "Null dereference");
639
                        index = index.loadValue();
640
                        if (index > ref.length)
641
                            throw new WTrapError(node.origin.originString, "Array index " + index + " is out of bounds of " + ref);
642
                        return EPtr.box(ref.ptr.plus(index * node.instantiatedActualTypeArguments[0].size));
643
                    };
644
                });
645
523
646
            this._map.set(
524
        for (let swizzle of SwizzleOp.functions())
647
                `native uint operator.length<T>(T[] ${addressSpace})`,
525
            this._map.set(swizzle.toString(), func => swizzle.instantiateImplementation(func));
648
                func => {
649
                    func.implementation = ([ref], node) => {
650
                        ref = ref.loadValue();
651
                        if (!ref)
652
                            return EPtr.box(0);
653
                        return EPtr.box(ref.length);
654
                    };
655
                });
656
        }
657
526
658
        for (let swizzle of SwizzleOp.allSwizzleOperators()) {
527
        for (let boolOp of OperatorBool.functions())
659
            this._map.set(swizzle.toString(), 
528
            this._map.set(boolOp.toString(), func => boolOp.instantiateImplementation(func));
660
            func => {
529
661
                func.implementation = ([vec], node) => {
530
        for (let anderIndex of OperatorAnderIndexer.functions())
662
                    const outputBuffer = new EBuffer(swizzle.outSize);
531
            this._map.set(anderIndex.toString(), func => anderIndex.instantiateImplementation(func));
663
                    const readIndices = { 'x': 0, 'y': 1, 'z': 2, 'w': 3 };
532
664
                    for (let i = 0; i < swizzle.outSize; i++)
533
        for (let cast of BuiltinVectorCasts.functions())
665
                        outputBuffer.set(i, vec.get(readIndices[swizzle.components[i]]));
534
            this._map.set(cast.toString(), func => cast.instantiateImplementation(func));
666
                    
535
667
                    
536
        for (let getter of BuiltinVectorIndexGetter.functions())
668
                    return new EPtr(outputBuffer, 0);
537
            this._map.set(getter.toString(), func => getter.instantiateImplementation(func));
669
                },
538
670
                func.implementationData = swizzle;
539
        for (let setter of BuiltinVectorIndexSetter.functions())
671
            });
540
            this._map.set(setter.toString(), func => setter.instantiateImplementation(func));
672
            console.log(swizzle.toString());
541
673
        }
542
        for (let equalityOperator of BuiltinVectorEqualityOperator.functions())
543
            this._map.set(equalityOperator.toString(), func => equalityOperator.instantiateImplementation(func));
544
545
        for (let getter of BuiltinVectorGetter.functions())
546
            this._map.set(getter.toString(), func => getter.instantiateImplementation(func));
547
548
        for (let setter of BuiltinVectorSetter.functions())
549
            this._map.set(setter.toString(), func => setter.instantiateImplementation(func));
674
    }
550
    }
675
    
551
    
676
    add(thing)
552
    add(thing)
- a/Tools/WebGPUShadingLanguageRI/LiteralTypeChecker.js +2 lines
Lines 43-48 class LiteralTypeChecker extends Visitor { a/Tools/WebGPUShadingLanguageRI/LiteralTypeChecker.js_sec1
43
    {
43
    {
44
        if (!node.type)
44
        if (!node.type)
45
            throw new Error(node + " at " + node.origin.originString + " does not have type");
45
            throw new Error(node + " at " + node.origin.originString + " does not have type");
46
        if (!node.type.type.canRepresent(node.value))
47
            throw new Error(`${node.value} at ${node.origin.originString} cannot be represented by ${node.type}`);
46
    }
48
    }
47
}
49
}
48
50
- a/Tools/WebGPUShadingLanguageRI/NativeType.js -1 / +1 lines
Lines 65-71 class NativeType extends Type { a/Tools/WebGPUShadingLanguageRI/NativeType.js_sec1
65
    
65
    
66
    toString()
66
    toString()
67
    {
67
    {
68
        return "native typedef " + this.name + "<" + this.typeParameters + ">";
68
        return `native typedef ${this.name}`;
69
    }
69
    }
70
}
70
}
71
71
- a/Tools/WebGPUShadingLanguageRI/NativeTypeInstance.js -1 / +1 lines
Lines 52-58 class NativeTypeInstance extends Type { a/Tools/WebGPUShadingLanguageRI/NativeTypeInstance.js_sec1
52
    
52
    
53
    toString()
53
    toString()
54
    {
54
    {
55
        return this.type + "<" + this.typeArguments + ">";
55
        return this.type;
56
    }
56
    }
57
}
57
}
58
58
- a/Tools/WebGPUShadingLanguageRI/OperatorAnderIndex.js +77 lines
Line 0 a/Tools/WebGPUShadingLanguageRI/OperatorAnderIndex.js_sec1
1
/*
2
 * Copyright (C) 2017 Apple Inc. All rights reserved.
3
 *
4
 * Redistribution and use in source and binary forms, with or without
5
 * modification, are permitted provided that the following conditions
6
 * are met:
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.
12
 *
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. 
24
 */
25
"use strict";
26
27
class OperatorAnderIndexer {
28
    constructor(baseTypeName, addressSpace)
29
    {
30
        this._baseTypeName = baseTypeName;
31
        this._addressSpace = addressSpace;
32
    }
33
34
    get addressSpace() { return this._addressSpace; }
35
    get baseTypeName() { return this._baseTypeName; }
36
37
    toString()
38
    {
39
        return `native ${this.baseTypeName}* ${this.addressSpace} operator&[](${this.baseTypeName}[] ${this.addressSpace},uint)`;
40
    }
41
42
    static functions()
43
    {
44
        if (!this._functions) {
45
            this._functions = [];
46
        
47
            const typeNames = [ "uint", "int", "float", "bool", "int2", "uint2", "float2", "int3", "uint3", "float3", "int4", "uint4", "float4" ];
48
            const addressSpaces = [ "thread", "threadgroup", "device", "constant" ];
49
50
            for (let addressSpace of addressSpaces) {
51
                for (let typeName of typeNames)
52
                    this._functions.push(new OperatorAnderIndexer(typeName, addressSpace));
53
            }
54
        }
55
        return this._functions;
56
    }
57
58
    // static indexersForTypeName(typeName)
59
    // {
60
    //     const addressSpaces = [ "thread", "threadgroup", "device", "constant" ];
61
    //     return addressSpaces.map(addrSpace => new OperatorAnderIndexer(typeName, addrSpace));
62
    // }
63
64
    instantiateImplementation(func)
65
    {
66
        func.implementation = ([ref, index], node) => {
67
            ref = ref.loadValue();
68
            if (!ref)
69
                throw new WTrapError(node.origin.originString, "Null dereference");
70
            index = index.loadValue();
71
            if (index > ref.length)
72
                throw new WTrapError(node.origin.originString, "Array index " + index + " is out of bounds of " + ref);
73
            return EPtr.box(ref.ptr.plus(index * node.argumentTypes[0].elementType.size));
74
        };
75
        func.implementationData = this;
76
    }
77
}
- a/Tools/WebGPUShadingLanguageRI/OperatorArrayRefLength.js +52 lines
Line 0 a/Tools/WebGPUShadingLanguageRI/OperatorArrayRefLength.js_sec1
1
/*
2
 * Copyright (C) 2017 Apple Inc. All rights reserved.
3
 *
4
 * Redistribution and use in source and binary forms, with or without
5
 * modification, are permitted provided that the following conditions
6
 * are met:
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.
12
 *
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. 
24
 */
25
"use strict";
26
27
class OperatorArrayRefLength {
28
    constructor(baseTypeName, addressSpace)
29
    {
30
        this._baseTypeName = baseTypeName;
31
        this._addressSpace = addressSpace;
32
    }
33
34
    get addressSpace() { return this._addressSpace; }
35
    get baseTypeName() { return this._baseTypeName; }
36
37
    toString()
38
    {
39
        return `native uint32 ${this.addressSpace} operator.length(${this.baseTypeName}[] ${this.addressSpace})`;
40
    }
41
42
    instantiateImplementation(func)
43
    {
44
        func.implementation = ([ref], node) => {
45
            ref = ref.loadValue();
46
            if (!ref)
47
                return EPtr.box(0);
48
            return EPtr.box(ref.length);
49
        };
50
        func.implementationData = this;
51
    }
52
}
- a/Tools/WebGPUShadingLanguageRI/OperatorBool.js +63 lines
Line 0 a/Tools/WebGPUShadingLanguageRI/OperatorBool.js_sec1
1
/*
2
 * Copyright (C) 2017 Apple Inc. All rights reserved.
3
 *
4
 * Redistribution and use in source and binary forms, with or without
5
 * modification, are permitted provided that the following conditions
6
 * are met:
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.
12
 *
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. 
24
 */
25
"use strict";
26
27
// FIXME: This needs to support registering these functions late
28
29
class OperatorBool {
30
    constructor(baseTypeName)
31
    {
32
        this._baseTypeName = baseTypeName;
33
    }
34
35
    get baseTypeName() { return this._baseTypeName; }
36
37
    toString()
38
    {
39
        return `native operator bool(${this.baseTypeName})`;
40
    }
41
42
    static functions()
43
    {
44
        if (!OperatorBool._functions) {
45
            OperatorBool._functions = [];
46
        
47
            // bool is not included because this is generated by the copy constructor
48
            const typeNames = [ "uint", "int", "float", /*"bool",*/ "int2", "uint2", "float2", "int3", "uint3", "float3", "int4", "uint4", "float4" ];
49
50
            for (let typeName of typeNames)
51
                OperatorBool._functions.push(new OperatorBool(typeName));
52
        }
53
        return OperatorBool._functions;
54
    }
55
56
    instantiateImplementation(func)
57
    {
58
        func.implementation = ([ref], node) => {
59
            return EPtr.box(!!ref.loadValue());
60
        }
61
        func.implementationData = this;
62
    }
63
}
- a/Tools/WebGPUShadingLanguageRI/Parse.js -123 / +7 lines
Lines 121-132 function parse(program, origin, originKind, lineNumberOffset, text) a/Tools/WebGPUShadingLanguageRI/Parse.js_sec1
121
        return result;
121
        return result;
122
    }
122
    }
123
    
123
    
124
    function parseProtocolRef()
125
    {
126
        let protocolToken = consumeKind("identifier");
127
        return new ProtocolRef(protocolToken, protocolToken.text);
128
    }
129
    
130
    function consumeEndOfTypeArgs()
124
    function consumeEndOfTypeArgs()
131
    {
125
    {
132
        let rightShift = tryConsume(">>");
126
        let rightShift = tryConsume(">>");
Lines 136-169 function parse(program, origin, originKind, lineNumberOffset, text) a/Tools/WebGPUShadingLanguageRI/Parse.js_sec2
136
            consume(">");
130
            consume(">");
137
    }
131
    }
138
    
132
    
139
    function parseTypeParameters()
140
    {
141
        if (!test("<"))
142
            return [];
143
        
144
        let result = [];
145
        consume("<");
146
        while (!test(">")) {
147
            let constexpr = lexer.backtrackingScope(() => {
148
                let type = parseType();
149
                let name = consumeKind("identifier");
150
                assertNext(",", ">", ">>");
151
                return new ConstexprTypeParameter(type.origin, name.text, type);
152
            });
153
            if (constexpr)
154
                result.push(constexpr);
155
            else {
156
                let name = consumeKind("identifier");
157
                let protocol = tryConsume(":") ? parseProtocolRef() : null;
158
                result.push(new TypeVariable(name, name.text, protocol));
159
            }
160
            if (!tryConsume(","))
161
                break;
162
        }
163
        consumeEndOfTypeArgs();
164
        return result;
165
    }
166
    
167
    function parseTerm()
133
    function parseTerm()
168
    {
134
    {
169
        let token;
135
        let token;
Lines 201-219 function parse(program, origin, originKind, lineNumberOffset, text) a/Tools/WebGPUShadingLanguageRI/Parse.js_sec3
201
                return new IntLiteral(token, intVersion);
167
                return new IntLiteral(token, intVersion);
202
            return new UintLiteral(token, intVersion >>> 0);
168
            return new UintLiteral(token, intVersion >>> 0);
203
        }
169
        }
204
        if (token = tryConsumeKind("doubleLiteral"))
205
            return new DoubleLiteral(token, +token.text);
206
        if (token = tryConsumeKind("floatLiteral")) {
170
        if (token = tryConsumeKind("floatLiteral")) {
207
            let text = token.text;
171
            let text = token.text;
208
            let d = token.text.endsWith("d");
209
            let f = token.text.endsWith("f");
172
            let f = token.text.endsWith("f");
210
            if (d && f)
173
            if (f)
211
                throw new Error("Literal cannot be both a double literal and a float literal.");
212
            if (d || f)
213
                text = text.substring(0, text.length - 1);
174
                text = text.substring(0, text.length - 1);
214
            let value = parseFloat(text);
175
            let value = parseFloat(text);
215
            if (d)
216
                return new DoubleLiteral(token, value);
217
            return new FloatLiteral(token, Math.fround(value));
176
            return new FloatLiteral(token, Math.fround(value));
218
        }
177
        }
219
        if (token = tryConsume("true", "false"))
178
        if (token = tryConsume("true", "false"))
Lines 236-285 function parse(program, origin, originKind, lineNumberOffset, text) a/Tools/WebGPUShadingLanguageRI/Parse.js_sec4
236
        return left;
195
        return left;
237
    }
196
    }
238
    
197
    
239
    function parseTypeArguments()
240
    {
241
        if (!test("<"))
242
            return [];
243
        
244
        let result = [];
245
        consume("<");
246
        while (!test(">")) {
247
            // It's possible for a constexpr or type can syntactically overlap in the single
248
            // identifier case. Let's consider the possibilities:
249
            //
250
            //     T          could be type or constexpr
251
            //     T[]        only type
252
            //     T[42]      only type (constexpr cannot do indexing)
253
            //     42         only constexpr
254
            //
255
            // In the future we'll allow constexprs to do more things, and then we'll still have
256
            // the problem that something of the form T[1][2][3]... can either be a type or a
257
            // constexpr, and we can figure out in the checker which it is.
258
            let typeOrVariableRef = lexer.backtrackingScope(() => {
259
                let result = consumeKind("identifier");
260
                assertNext(",", ">", ">>");
261
                return new TypeOrVariableRef(result, result.text);
262
            });
263
            if (typeOrVariableRef)
264
                result.push(typeOrVariableRef);
265
            else {
266
                let constexpr = lexer.backtrackingScope(() => {
267
                    let result = parseConstexpr();
268
                    assertNext(",", ">", ">>");
269
                    return result;
270
                });
271
                if (constexpr)
272
                    result.push(constexpr);
273
                else
274
                    result.push(parseType());
275
            }
276
            if (!tryConsume(","))
277
                break;
278
        }
279
        consumeEndOfTypeArgs();
280
        return result;
281
    }
282
    
283
    function parseType()
198
    function parseType()
284
    {
199
    {
285
        let token;
200
        let token;
Lines 289-295 function parse(program, origin, originKind, lineNumberOffset, text) a/Tools/WebGPUShadingLanguageRI/Parse.js_sec5
289
            addressSpace = token.text;
204
            addressSpace = token.text;
290
        
205
        
291
        let name = consumeKind("identifier");
206
        let name = consumeKind("identifier");
292
        let typeArguments = parseTypeArguments();
207
        let typeArguments = [];
293
        let type = new TypeRef(name, name.text, typeArguments);
208
        let type = new TypeRef(name, name.text, typeArguments);
294
        
209
        
295
        function getAddressSpace()
210
        function getAddressSpace()
Lines 325-331 function parse(program, origin, originKind, lineNumberOffset, text) a/Tools/WebGPUShadingLanguageRI/Parse.js_sec6
325
    {
240
    {
326
        let origin = consume("typedef");
241
        let origin = consume("typedef");
327
        let name = consumeKind("identifier").text;
242
        let name = consumeKind("identifier").text;
328
        let typeParameters = parseTypeParameters();
243
        let typeParameters = [];
329
        consume("=");
244
        consume("=");
330
        let type = parseType();
245
        let type = parseType();
331
        consume(";");
246
        consume(";");
Lines 352-358 function parse(program, origin, originKind, lineNumberOffset, text) a/Tools/WebGPUShadingLanguageRI/Parse.js_sec7
352
    function parseCallExpression()
267
    function parseCallExpression()
353
    {
268
    {
354
        let name = consumeKind("identifier");
269
        let name = consumeKind("identifier");
355
        let typeArguments = parseTypeArguments();
270
        let typeArguments = [];
356
        consume("(");
271
        consume("(");
357
        let argumentList = [];
272
        let argumentList = [];
358
        while (!test(")")) {
273
        while (!test(")")) {
Lines 370-376 function parse(program, origin, originKind, lineNumberOffset, text) a/Tools/WebGPUShadingLanguageRI/Parse.js_sec8
370
    {
285
    {
371
        return lexer.testScope(() => {
286
        return lexer.testScope(() => {
372
            consumeKind("identifier");
287
            consumeKind("identifier");
373
            parseTypeArguments();
374
            consume("(");
288
            consume("(");
375
        });
289
        });
376
    }
290
    }
Lines 865-877 function parse(program, origin, originKind, lineNumberOffset, text) a/Tools/WebGPUShadingLanguageRI/Parse.js_sec9
865
        let origin;
779
        let origin;
866
        let returnType;
780
        let returnType;
867
        let name;
781
        let name;
868
        let typeParameters;
782
        let typeParameters = [];
869
        let isCast;
783
        let isCast;
870
        let shaderType;
784
        let shaderType;
871
        let operatorToken = tryConsume("operator");
785
        let operatorToken = tryConsume("operator");
872
        if (operatorToken) {
786
        if (operatorToken) {
873
            origin = operatorToken;
787
            origin = operatorToken;
874
            typeParameters = parseTypeParameters();
875
            returnType = parseType();
788
            returnType = parseType();
876
            name = "operator cast";
789
            name = "operator cast";
877
            isCast = true;
790
            isCast = true;
Lines 884-901 function parse(program, origin, originKind, lineNumberOffset, text) a/Tools/WebGPUShadingLanguageRI/Parse.js_sec10
884
            } else
797
            } else
885
                origin = returnType.origin;
798
                origin = returnType.origin;
886
            name = parseFuncName();
799
            name = parseFuncName();
887
            typeParameters = parseTypeParameters();
888
            isCast = false;
800
            isCast = false;
889
        }
801
        }
890
        let parameters = parseParameters();
802
        let parameters = parseParameters();
891
        return new Func(origin, name, returnType, typeParameters, parameters, isCast, shaderType);
803
        return new Func(origin, name, returnType, typeParameters, parameters, isCast, shaderType);
892
    }
804
    }
893
894
    function parseProtocolFuncDecl()
895
    {
896
        let func = parseFuncDecl();
897
        return new ProtocolFuncDecl(func.origin, func.name, func.returnType, func.typeParameters, func.parameters, func.isCast, func.shaderType);
898
    }
899
    
805
    
900
    function parseFuncDef()
806
    function parseFuncDef()
901
    {
807
    {
Lines 904-929 function parse(program, origin, originKind, lineNumberOffset, text) a/Tools/WebGPUShadingLanguageRI/Parse.js_sec11
904
        return new FuncDef(func.origin, func.name, func.returnType, func.typeParameters, func.parameters, body, func.isCast, func.shaderType);
810
        return new FuncDef(func.origin, func.name, func.returnType, func.typeParameters, func.parameters, body, func.isCast, func.shaderType);
905
    }
811
    }
906
    
812
    
907
    function parseProtocolDecl()
908
    {
909
        let origin = consume("protocol");
910
        let name = consumeKind("identifier").text;
911
        let result = new ProtocolDecl(origin, name);
912
        if (tryConsume(":")) {
913
            while (!test("{")) {
914
                result.addExtends(parseProtocolRef());
915
                if (!tryConsume(","))
916
                    break;
917
            }
918
        }
919
        consume("{");
920
        while (!tryConsume("}")) {
921
            result.add(parseProtocolFuncDecl());
922
            consume(";");
923
        }
924
        return result;
925
    }
926
    
927
    function parseField()
813
    function parseField()
928
    {
814
    {
929
        let type = parseType();
815
        let type = parseType();
Lines 936-942 function parse(program, origin, originKind, lineNumberOffset, text) a/Tools/WebGPUShadingLanguageRI/Parse.js_sec12
936
    {
822
    {
937
        let origin = consume("struct");
823
        let origin = consume("struct");
938
        let name = consumeKind("identifier").text;
824
        let name = consumeKind("identifier").text;
939
        let typeParameters = parseTypeParameters();
825
        let typeParameters = [];
940
        let result = new StructType(origin, name, typeParameters);
826
        let result = new StructType(origin, name, typeParameters);
941
        consume("{");
827
        consume("{");
942
        while (!tryConsume("}"))
828
        while (!tryConsume("}"))
Lines 956-962 function parse(program, origin, originKind, lineNumberOffset, text) a/Tools/WebGPUShadingLanguageRI/Parse.js_sec13
956
        let origin = consume("native");
842
        let origin = consume("native");
957
        if (tryConsume("typedef")) {
843
        if (tryConsume("typedef")) {
958
            let name = consumeKind("identifier");
844
            let name = consumeKind("identifier");
959
            let parameters = parseTypeParameters();
845
            let parameters = [];
960
            consume(";");
846
            consume(";");
961
            return new NativeType(origin, name.text, parameters);
847
            return new NativeType(origin, name.text, parameters);
962
        }
848
        }
Lines 1020-1027 function parse(program, origin, originKind, lineNumberOffset, text) a/Tools/WebGPUShadingLanguageRI/Parse.js_sec14
1020
            program.add(parseStructType());
906
            program.add(parseStructType());
1021
        else if (token.text == "enum")
907
        else if (token.text == "enum")
1022
            program.add(parseEnumType());
908
            program.add(parseEnumType());
1023
        else if (token.text == "protocol")
1024
            program.add(parseProtocolDecl());
1025
        else
909
        else
1026
            program.add(parseFuncDef());
910
            program.add(parseFuncDef());
1027
    }
911
    }
- a/Tools/WebGPUShadingLanguageRI/Prepare.js +4 lines
Lines 48-53 let prepare = (() => { a/Tools/WebGPUShadingLanguageRI/Prepare.js_sec1
48
        checkRecursiveTypes(program);
48
        checkRecursiveTypes(program);
49
        synthesizeStructAccessors(program);
49
        synthesizeStructAccessors(program);
50
        synthesizeEnumFunctions(program);
50
        synthesizeEnumFunctions(program);
51
        synthesizeArrayOperatorLength(program);
52
        synthesizeCopyConstructorOperator(program);
53
        synthesizeDefaultConstructorOperator(program);
51
        resolveNamesInFunctions(program, nameResolver);
54
        resolveNamesInFunctions(program, nameResolver);
52
        resolveTypeDefsInFunctions(program);
55
        resolveTypeDefsInFunctions(program);
53
        
56
        
Lines 64-69 let prepare = (() => { a/Tools/WebGPUShadingLanguageRI/Prepare.js_sec2
64
        checkRecursion(program);
67
        checkRecursion(program);
65
        checkProgramWrapped(program);
68
        checkProgramWrapped(program);
66
        findHighZombies(program);
69
        findHighZombies(program);
70
        program.visit(new StructLayoutBuilder());
67
        inline(program);
71
        inline(program);
68
        
72
        
69
        return program;
73
        return program;
- a/Tools/WebGPUShadingLanguageRI/SPIRV.html -7 / +13 lines
Lines 18-24 td { a/Tools/WebGPUShadingLanguageRI/SPIRV.html_sec1
18
    <script src="CreateLiteralType.js"></script>
18
    <script src="CreateLiteralType.js"></script>
19
    <script src="PropertyAccessExpression.js"></script>
19
    <script src="PropertyAccessExpression.js"></script>
20
    <script src="SwizzleOp.js"></script>
20
    <script src="SwizzleOp.js"></script>
21
21
    
22
    <script src="AddressSpace.js"></script>
22
    <script src="AddressSpace.js"></script>
23
    <script src="AnonymousVariable.js"></script>
23
    <script src="AnonymousVariable.js"></script>
24
    <script src="ArrayRefType.js"></script>
24
    <script src="ArrayRefType.js"></script>
Lines 47-54 td { a/Tools/WebGPUShadingLanguageRI/SPIRV.html_sec2
47
    <script src="ConvertPtrToArrayRefExpression.js"></script>
47
    <script src="ConvertPtrToArrayRefExpression.js"></script>
48
    <script src="DoWhileLoop.js"></script>
48
    <script src="DoWhileLoop.js"></script>
49
    <script src="DotExpression.js"></script>
49
    <script src="DotExpression.js"></script>
50
    <script src="DoubleLiteral.js"></script>
51
    <script src="DoubleLiteralType.js"></script>
52
    <script src="DereferenceExpression.js"></script>
50
    <script src="DereferenceExpression.js"></script>
53
    <script src="EArrayRef.js"></script>
51
    <script src="EArrayRef.js"></script>
54
    <script src="EBuffer.js"></script>
52
    <script src="EBuffer.js"></script>
Lines 104-109 td { a/Tools/WebGPUShadingLanguageRI/SPIRV.html_sec3
104
    <script src="NormalUsePropertyResolver.js"></script>
102
    <script src="NormalUsePropertyResolver.js"></script>
105
    <script src="NullLiteral.js"></script>
103
    <script src="NullLiteral.js"></script>
106
    <script src="NullType.js"></script>
104
    <script src="NullType.js"></script>
105
    <script src="OperatorAnderIndex.js"></script>
106
    <script src="OperatorArrayRefLength.js"></script>
107
    <script src="OperatorBool.js"></script>
108
    <script src="BuiltinVectorCasts.js"></script>
109
    <script src="BuiltinVectorGetter.js"></script>
110
    <script src="BuiltinVectorSetter.js"></script>
111
    <script src="BuiltinVectorIndexGetter.js"></script>
112
    <script src="BuiltinVectorIndexSetter.js"></script>
113
    <script src="BuiltinVectorEqualityOperator.js"></script>
107
    <script src="OriginKind.js"></script>
114
    <script src="OriginKind.js"></script>
108
    <script src="OverloadResolutionFailure.js"></script>
115
    <script src="OverloadResolutionFailure.js"></script>
109
    <script src="Parse.js"></script>
116
    <script src="Parse.js"></script>
Lines 126-135 td { a/Tools/WebGPUShadingLanguageRI/SPIRV.html_sec4
126
    <script src="Return.js"></script>
133
    <script src="Return.js"></script>
127
    <script src="ReturnChecker.js"></script>
134
    <script src="ReturnChecker.js"></script>
128
    <script src="ReturnException.js"></script>
135
    <script src="ReturnException.js"></script>
129
    <script src="SPIR-V.js"></script>
130
    <script src="SPIRVCodegen.js"></script>
131
    <script src="SPIRVTypeAnalyzer.js"></script>
132
    <script src="SPIRVVariableAnalyzer.js"></script>
133
    <script src="StandardLibrary.js"></script>
136
    <script src="StandardLibrary.js"></script>
134
    <script src="StatementCloner.js"></script>
137
    <script src="StatementCloner.js"></script>
135
    <script src="StructLayoutBuilder.js"></script>
138
    <script src="StructLayoutBuilder.js"></script>
Lines 137-144 td { a/Tools/WebGPUShadingLanguageRI/SPIRV.html_sec5
137
    <script src="Substitution.js"></script>
140
    <script src="Substitution.js"></script>
138
    <script src="SwitchCase.js"></script>
141
    <script src="SwitchCase.js"></script>
139
    <script src="SwitchStatement.js"></script>
142
    <script src="SwitchStatement.js"></script>
143
    <script src="SynthesizeArrayOperatorLength.js"></script>
140
    <script src="SynthesizeEnumFunctions.js"></script>
144
    <script src="SynthesizeEnumFunctions.js"></script>
141
    <script src="SynthesizeStructAccessors.js"></script>
145
    <script src="SynthesizeStructAccessors.js"></script>
146
    <script src="SynthesizeCopyConstructorOperator.js"></script>
147
    <script src="SynthesizeDefaultConstructorOperator.js"></script>
142
    <script src="TrapStatement.js"></script>
148
    <script src="TrapStatement.js"></script>
143
    <script src="TypeDef.js"></script>
149
    <script src="TypeDef.js"></script>
144
    <script src="TypeDefResolver.js"></script>
150
    <script src="TypeDefResolver.js"></script>
- a/Tools/WebGPUShadingLanguageRI/SPIRVCodegen.js -8 lines
Lines 214-227 function generateSPIRV(spirv, program) a/Tools/WebGPUShadingLanguageRI/SPIRVCodegen.js_sec1
214
                values = uintView;
214
                values = uintView;
215
                break;
215
                break;
216
            }
216
            }
217
            case program.intrinsics.double: {
218
                let arrayBuffer = new ArrayBuffer(Math.max(Uint32Array.BYTES_PER_ELEMENT, Float64Array.BYTES_PER_ELEMENT));
219
                let doubleView = new Float64Array(arrayBuffer);
220
                let uintView = new Uint32Array(arrayBuffer);
221
                doubleView[0] = node.value;
222
                values = uintView;
223
                break;
224
            }
225
            default:
217
            default:
226
                throw new Error("Unrecognized literal.");
218
                throw new Error("Unrecognized literal.");
227
            }
219
            }
- a/Tools/WebGPUShadingLanguageRI/StandardLibrary.js -243 / +23 lines
Lines 40-75 typedef int = int32; a/Tools/WebGPUShadingLanguageRI/StandardLibrary.js_sec1
40
typedef uint = uint32;
40
typedef uint = uint32;
41
41
42
native typedef float32;
42
native typedef float32;
43
native typedef float64;
44
typedef float = float32;
43
typedef float = float32;
45
typedef double = float64;
46
44
47
native operator int32(uint32);
45
native operator int32(uint32);
48
native operator int32(uint8);
46
native operator int32(uint8);
49
native operator int32(float);
47
native operator int32(float);
50
native operator int32(double);
51
native operator uint32(int32);
48
native operator uint32(int32);
52
native operator uint32(uint8);
49
native operator uint32(uint8);
53
native operator uint32(float);
50
native operator uint32(float);
54
native operator uint32(double);
55
native operator uint8(int32);
51
native operator uint8(int32);
56
native operator uint8(uint32);
52
native operator uint8(uint32);
57
native operator uint8(float);
53
native operator uint8(float);
58
native operator uint8(double);
59
native operator float(int32);
54
native operator float(int32);
60
native operator float(uint32);
55
native operator float(uint32);
61
native operator float(uint8);
56
native operator float(uint8);
62
native operator float(double);
63
native operator double(float);
64
native operator double(int32);
65
native operator double(uint32);
66
native operator double(uint8);
67
57
68
native int operator+(int, int);
58
native int operator+(int, int);
69
native uint operator+(uint, uint);
59
native uint operator+(uint, uint);
70
uint8 operator+(uint8 a, uint8 b) { return uint8(uint(a) + uint(b)); }
60
uint8 operator+(uint8 a, uint8 b) { return uint8(uint(a) + uint(b)); }
71
native float operator+(float, float);
61
native float operator+(float, float);
72
native double operator+(double, double);
73
int operator++(int value) { return value + 1; }
62
int operator++(int value) { return value + 1; }
74
uint operator++(uint value) { return value + 1; }
63
uint operator++(uint value) { return value + 1; }
75
uint8 operator++(uint8 value) { return value + 1; }
64
uint8 operator++(uint8 value) { return value + 1; }
Lines 77-83 native int operator-(int, int); a/Tools/WebGPUShadingLanguageRI/StandardLibrary.js_sec2
77
native uint operator-(uint, uint);
66
native uint operator-(uint, uint);
78
uint8 operator-(uint8 a, uint8 b) { return uint8(uint(a) - uint(b)); }
67
uint8 operator-(uint8 a, uint8 b) { return uint8(uint(a) - uint(b)); }
79
native float operator-(float, float);
68
native float operator-(float, float);
80
native double operator-(double, double);
81
int operator--(int value) { return value - 1; }
69
int operator--(int value) { return value - 1; }
82
uint operator--(uint value) { return value - 1; }
70
uint operator--(uint value) { return value - 1; }
83
uint8 operator--(uint8 value) { return value - 1; }
71
uint8 operator--(uint8 value) { return value - 1; }
Lines 85-91 native int operator*(int, int); a/Tools/WebGPUShadingLanguageRI/StandardLibrary.js_sec3
85
native uint operator*(uint, uint);
73
native uint operator*(uint, uint);
86
uint8 operator*(uint8 a, uint8 b) { return uint8(uint(a) * uint(b)); }
74
uint8 operator*(uint8 a, uint8 b) { return uint8(uint(a) * uint(b)); }
87
native float operator*(float, float);
75
native float operator*(float, float);
88
native double operator*(double, double);
89
native int operator/(int, int);
76
native int operator/(int, int);
90
native uint operator/(uint, uint);
77
native uint operator/(uint, uint);
91
uint8 operator/(uint8 a, uint8 b) { return uint8(uint(a) / uint(b)); }
78
uint8 operator/(uint8 a, uint8 b) { return uint8(uint(a) / uint(b)); }
Lines 108-140 uint8 operator~(uint8 value) { return uint8(~uint(value)); } a/Tools/WebGPUShadingLanguageRI/StandardLibrary.js_sec4
108
uint8 operator<<(uint8 a, uint b) { return uint8(uint(a) << (b & 7)); }
95
uint8 operator<<(uint8 a, uint b) { return uint8(uint(a) << (b & 7)); }
109
uint8 operator>>(uint8 a, uint b) { return uint8(uint(a) >> (b & 7)); }
96
uint8 operator>>(uint8 a, uint b) { return uint8(uint(a) >> (b & 7)); }
110
native float operator/(float, float);
97
native float operator/(float, float);
111
native double operator/(double, double);
112
native bool operator==(int, int);
98
native bool operator==(int, int);
113
native bool operator==(uint, uint);
99
native bool operator==(uint, uint);
114
bool operator==(uint8 a, uint8 b) { return uint(a) == uint(b); }
100
bool operator==(uint8 a, uint8 b) { return uint(a) == uint(b); }
115
native bool operator==(bool, bool);
101
native bool operator==(bool, bool);
116
native bool operator==(float, float);
102
native bool operator==(float, float);
117
native bool operator==(double, double);
118
native bool operator<(int, int);
103
native bool operator<(int, int);
119
native bool operator<(uint, uint);
104
native bool operator<(uint, uint);
120
bool operator<(uint8 a, uint8 b) { return uint(a) < uint(b); }
105
bool operator<(uint8 a, uint8 b) { return uint(a) < uint(b); }
121
native bool operator<(float, float);
106
native bool operator<(float, float);
122
native bool operator<(double, double);
123
native bool operator<=(int, int);
107
native bool operator<=(int, int);
124
native bool operator<=(uint, uint);
108
native bool operator<=(uint, uint);
125
bool operator<=(uint8 a, uint8 b) { return uint(a) <= uint(b); }
109
bool operator<=(uint8 a, uint8 b) { return uint(a) <= uint(b); }
126
native bool operator<=(float, float);
110
native bool operator<=(float, float);
127
native bool operator<=(double, double);
128
native bool operator>(int, int);
111
native bool operator>(int, int);
129
native bool operator>(uint, uint);
112
native bool operator>(uint, uint);
130
bool operator>(uint8 a, uint8 b) { return uint(a) > uint(b); }
113
bool operator>(uint8 a, uint8 b) { return uint(a) > uint(b); }
131
native bool operator>(float, float);
114
native bool operator>(float, float);
132
native bool operator>(double, double);
133
native bool operator>=(int, int);
115
native bool operator>=(int, int);
134
native bool operator>=(uint, uint);
116
native bool operator>=(uint, uint);
135
bool operator>=(uint8 a, uint8 b) { return uint(a) >= uint(b); }
117
bool operator>=(uint8 a, uint8 b) { return uint(a) >= uint(b); }
136
native bool operator>=(float, float);
118
native bool operator>=(float, float);
137
native bool operator>=(double, double);
138
119
139
bool operator&(bool a, bool b)
120
bool operator&(bool a, bool b)
140
{
121
{
Lines 164-393 bool operator~(bool value) a/Tools/WebGPUShadingLanguageRI/StandardLibrary.js_sec5
164
    return !value;
145
    return !value;
165
}
146
}
166
147
167
protocol Addable {
148
native typedef int2;
168
    Addable operator+(Addable, Addable);
149
native typedef uint2;
169
}
150
native typedef float2;
170
171
protocol Equatable {
172
    bool operator==(Equatable, Equatable);
173
}
174
175
restricted operator<T> T()
176
{
177
    T defaultValue;
178
    return defaultValue;
179
}
180
181
restricted operator<T> T(T x)
182
{
183
    return x;
184
}
185
186
operator<T:Equatable> bool(T x)
187
{
188
    return x != T();
189
}
190
191
struct vec2<T> {
192
    T x;
193
    T y;
194
}
195
196
typedef int2 = vec2<int>;
197
typedef uint2 = vec2<uint>;
198
typedef float2 = vec2<float>;
199
typedef double2 = vec2<double>;
200
201
operator<T> vec2<T>(T x, T y)
202
{
203
    vec2<T> result;
204
    result.x = x;
205
    result.y = y;
206
    return result;
207
}
208
209
bool operator==<T:Equatable>(vec2<T> a, vec2<T> b)
210
{
211
    return a.x == b.x && a.y == b.y;
212
}
213
214
thread T* operator&[]<T>(thread vec2<T>* foo, uint index)
215
{
216
    if (index == 0)
217
        return &foo->x;
218
    if (index == 1)
219
        return &foo->y;
220
    trap;
221
}
222
223
struct vec3<T> {
224
    T x;
225
    T y;
226
    T z;
227
}
228
229
typedef int3 = vec3<int>;
230
typedef uint3 = vec3<uint>;
231
typedef float3 = vec3<float>;
232
typedef double3 = vec3<double>;
233
234
operator<T> vec3<T>(T x, T y, T z)
235
{
236
    vec3<T> result;
237
    result.x = x;
238
    result.y = y;
239
    result.z = z;
240
    return result;
241
}
242
243
operator<T> vec3<T>(vec2<T> v2, T z)
244
{
245
    vec3<T> result;
246
    result.x = v2.x;
247
    result.y = v2.y;
248
    result.z = z;
249
    return result;
250
}
251
252
operator<T> vec3<T>(T x, vec2<T> v2)
253
{
254
    vec3<T> result;
255
    result.x = x;
256
    result.y = v2.x;
257
    result.z = v2.y;
258
    return result;
259
}
260
261
bool operator==<T:Equatable>(vec3<T> a, vec3<T> b)
262
{
263
    return a.x == b.x && a.y == b.y && a.z == b.z;
264
}
265
151
266
thread T* operator&[]<T>(thread vec3<T>* foo, uint index)
152
native typedef int3;
267
{
153
native typedef uint3;
268
    if (index == 0)
154
native typedef float3;
269
        return &foo->x;
270
    if (index == 1)
271
        return &foo->y;
272
    if (index == 2)
273
        return &foo->z;
274
    trap;
275
}
276
277
struct vec4<T> {
278
    T x;
279
    T y;
280
    T z;
281
    T w;
282
}
283
284
typedef int4 = vec4<int>;
285
typedef uint4 = vec4<uint>;
286
typedef float4 = vec4<float>;
287
typedef double4 = vec4<double>;
288
289
operator<T> vec4<T>(T x, T y, T z, T w)
290
{
291
    vec4<T> result;
292
    result.x = x;
293
    result.y = y;
294
    result.z = z;
295
    result.w = w;
296
    return result;
297
}
298
299
operator<T> vec4<T>(vec2<T> v2, T z, T w)
300
{
301
    vec4<T> result;
302
    result.x = v2.x;
303
    result.y = v2.y;
304
    result.z = z;
305
    result.w = w;
306
    return result;
307
}
308
309
operator<T> vec4<T>(T x, vec2<T> v2, T w)
310
{
311
    vec4<T> result;
312
    result.x = x;
313
    result.y = v2.x;
314
    result.z = v2.y;
315
    result.w = w;
316
    return result;
317
}
318
319
operator<T> vec4<T>(T x, T y, vec2<T> v2)
320
{
321
    vec4<T> result;
322
    result.x = x;
323
    result.y = y;
324
    result.z = v2.x;
325
    result.w = v2.y;
326
    return result;
327
}
328
329
operator<T> vec4<T>(vec2<T> v2a, vec2<T> v2b)
330
{
331
    vec4<T> result;
332
    result.x = v2a.x;
333
    result.y = v2a.y;
334
    result.z = v2b.x;
335
    result.w = v2b.y;
336
    return result;
337
}
338
155
339
operator<T> vec4<T>(vec3<T> v3, T w)
156
native typedef int4;
340
{
157
native typedef uint4;
341
    vec4<T> result;
158
native typedef float4;
342
    result.x = v3.x;
343
    result.y = v3.y;
344
    result.z = v3.z;
345
    result.w = w;
346
    return result;
347
}
348
349
operator<T> vec4<T>(T x, vec3<T> v3)
350
{
351
    vec4<T> result;
352
    result.x = x;
353
    result.y = v3.x;
354
    result.z = v3.y;
355
    result.w = v3.z;
356
    return result;
357
}
358
359
bool operator==<T:Equatable>(vec4<T> a, vec4<T> b)
360
{
361
    return a.x == b.x && a.y == b.y && a.z == b.z && a.w == b.w;
362
}
363
364
thread T* operator&[]<T>(thread vec4<T>* foo, uint index)
365
{
366
    if (index == 0)
367
        return &foo->x;
368
    if (index == 1)
369
        return &foo->y;
370
    if (index == 2)
371
        return &foo->z;
372
    if (index == 3)
373
        return &foo->w;
374
    trap;
375
}
376
377
native thread T* operator&[]<T>(thread T[], uint);
378
native threadgroup T* operator&[]<T>(threadgroup T[], uint);
379
native device T* operator&[]<T>(device T[], uint);
380
native constant T* operator&[]<T>(constant T[], uint);
381
382
native uint operator.length<T>(thread T[]);
383
native uint operator.length<T>(threadgroup T[]);
384
native uint operator.length<T>(device T[]);
385
native uint operator.length<T>(constant T[]);
386
387
uint operator.length<T, uint length>(T[length])
388
{
389
    return length;
390
}
391
`;
159
`;
392
160
393
function intToString(x)
161
function intToString(x)
Lines 406-411 function intToString(x) a/Tools/WebGPUShadingLanguageRI/StandardLibrary.js_sec6
406
    }
174
    }
407
}
175
}
408
176
177
function addFunctionsFromClass(clss)
178
{
179
    standardLibrary += clss.functions().join(";\n") + "\n";
180
}
181
409
// There are 481 swizzle operators, so we compile them as native functions
182
// There are 481 swizzle operators, so we compile them as native functions
410
standardLibrary += SwizzleOp.allSwizzleOperators().join(";\n") + ";";
183
standardLibrary += SwizzleOp.functions().join(";\n") + ";\n";
411
console.log(standardLibrary);
184
standardLibrary += OperatorBool.functions().join(";\n") + ";\n";
185
standardLibrary += OperatorAnderIndexer.functions().join(";\n") + ";\n";
186
standardLibrary += BuiltinVectorCasts.functions().join(";\n") + ";\n";
187
standardLibrary += BuiltinVectorGetter.functions().join(";\n") + ";\n";
188
standardLibrary += BuiltinVectorSetter.functions().join(";\n") + ";\n";
189
standardLibrary += BuiltinVectorIndexGetter.functions().join(";\n") + ";\n";
190
standardLibrary += BuiltinVectorIndexSetter.functions().join(";\n") + ";\n";
191
standardLibrary += BuiltinVectorEqualityOperator.functions().join(";\n") + ";\n";
- a/Tools/WebGPUShadingLanguageRI/StructType.js -1 / +2 lines
Lines 45-50 class StructType extends Type { a/Tools/WebGPUShadingLanguageRI/StructType.js_sec1
45
    get name() { return this._name; }
45
    get name() { return this._name; }
46
    get origin() { return this._origin; }
46
    get origin() { return this._origin; }
47
    get typeParameters() { return this._typeParameters; }
47
    get typeParameters() { return this._typeParameters; }
48
    get isStruct() { return true; }
48
    
49
    
49
    get fieldNames() { return this._fields.keys(); }
50
    get fieldNames() { return this._fields.keys(); }
50
    fieldByName(name) { return this._fields.get(name); }
51
    fieldByName(name) { return this._fields.get(name); }
Lines 94-99 class StructType extends Type { a/Tools/WebGPUShadingLanguageRI/StructType.js_sec2
94
    
95
    
95
    toString()
96
    toString()
96
    {
97
    {
97
        return "struct " + this.name + "<" + this.typeParameters + "> { " + Array.from(this.fields).join("; ") + "; }";
98
        return `struct ${this.name} { ${Array.from(this.fields).join("; ")}; }`;
98
    }
99
    }
99
}
100
}
- a/Tools/WebGPUShadingLanguageRI/SwizzleOp.js -15 / +35 lines
Lines 25-73 a/Tools/WebGPUShadingLanguageRI/SwizzleOp.js_sec1
25
"use strict";
25
"use strict";
26
26
27
class SwizzleOp {
27
class SwizzleOp {
28
    constructor(outSize, components, inSize)
28
    constructor(baseTypeName, outSize, components, inSize)
29
    {
29
    {
30
        this._baseTypeName = baseTypeName;
30
        this._outSize = outSize;
31
        this._outSize = outSize;
31
        this._components = components.slice(); // Shallow clone
32
        this._components = components.slice(); // Shallow clone
32
        this._inSize = inSize;
33
        this._inSize = inSize;
33
    }
34
    }
34
35
36
    get baseTypeName() { return this._baseTypeName; }
35
    get outSize() { return this._outSize; }
37
    get outSize() { return this._outSize; }
36
    get components() { return this._components; }
38
    get components() { return this._components; }
37
    get inSize() { return this._inSize; }
39
    get inSize() { return this._inSize; }
38
40
39
    toString()
41
    toString()
40
    {
42
    {
41
        return `native vec${this.outSize}<T> operator.${this.components.join("")}<T>(vec${this.inSize}<T> v)`;
43
        return `native ${this.baseTypeName}${this.outSize} operator.${this.components.join("")}(${this.baseTypeName}${this.inSize} v)`;
42
    }
44
    }
43
45
44
    static allSwizzleOperators()
46
    static functions()
45
    {
47
    {
46
        if (!SwizzleOp._allSwizzleOperators) {
48
        if (!this._functions) {
47
            SwizzleOp._allSwizzleOperators = [];
49
            // We can't directly use this._functions in _generateSwizzles
50
            const functions = [];
48
            
51
            
49
            function _generateSwizzle(maxDepth, maxItems, array) {
52
            function _generateSwizzle(baseTypeName, maxDepth, maxItems, array) {
50
                if (!array)
53
                if (!array)
51
                    array = [];
54
                    array = [];
52
                if (array.length == maxDepth) {
55
                if (array.length == maxDepth) {
53
                    SwizzleOp._allSwizzleOperators.push(new SwizzleOp(array.length, array, maxItems));
56
                    functions.push(new SwizzleOp(baseTypeName, array.length, array, maxItems));
54
                    return;
57
                    return;
55
                }
58
                }
56
                for (let i = 0; i < maxItems; ++i) {
59
                for (let i = 0; i < maxItems; ++i) {
57
                    array.push(intToString(i));
60
                    array.push(intToString(i));
58
                    _generateSwizzle(maxDepth, maxItems, array);
61
                    _generateSwizzle(baseTypeName, maxDepth, maxItems, array);
59
                    array.pop();
62
                    array.pop();
60
                }
63
                }
61
            };
64
            };
62
        
65
        
63
            for (let maxDepth = 2; maxDepth <= 4; maxDepth++) {
66
            const typeNames = [ "uint", "int", "float" ];
64
                for (let maxItems = 2; maxItems <= 4; maxItems++)
67
65
                    _generateSwizzle(maxDepth, maxItems);
68
            for (let typeName of typeNames) {
69
                for (let maxDepth = 2; maxDepth <= 4; maxDepth++) {
70
                    for (let maxItems = 2; maxItems <= 4; maxItems++)
71
                        _generateSwizzle(typeName, maxDepth, maxItems);
72
                }
66
            }
73
            }
74
75
            this._functions = functions;
67
        }
76
        }
68
        return SwizzleOp._allSwizzleOperators;
77
        return this._functions;
69
    }
78
    }
70
}
71
79
72
// Initialise the static member (JS doesn't allow static fields declared in the class)
80
    instantiateImplementation(func)
73
SwizzleOp._allSwizzleOperators = null;
81
    {
82
        func.implementation = ([vec], node) => {
83
            const outputBuffer = new EBuffer(this.outSize);
84
            const readIndices = { 'x': 0, 'y': 1, 'z': 2, 'w': 3 };
85
            for (let i = 0; i < this.outSize; i++)
86
                outputBuffer.set(i, vec.get(readIndices[this.components[i]]));
87
            
88
            
89
            return new EPtr(outputBuffer, 0);
90
        };
91
        func.implementationData = this;
92
    }
93
}
- a/Tools/WebGPUShadingLanguageRI/SynthesizeArrayOperatorLength.js +50 lines
Line 0 a/Tools/WebGPUShadingLanguageRI/SynthesizeArrayOperatorLength.js_sec1
1
/*
2
 * Copyright (C) 2017 Apple Inc. All rights reserved.
3
 *
4
 * Redistribution and use in source and binary forms, with or without
5
 * modification, are permitted provided that the following conditions
6
 * are met:
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.
12
 *
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. 
24
 */
25
"use strict";
26
27
function synthesizeArrayOperatorLength(program)
28
{
29
    const arrayTypes = new Set();
30
31
    class FindArrayTypes extends Visitor {
32
        visitArrayType(node)
33
        {
34
            arrayTypes.add(node);
35
        }
36
    }
37
    
38
    program.visit(new FindArrayTypes());
39
40
    for (let arrayType of arrayTypes) {
41
        let nativeFunc = new NativeFunc(
42
            arrayType.origin, "operator.length", new TypeRef(arrayType.origin, "uint32", []), [],
43
            [
44
                new FuncParameter(arrayType.origin, null, TypeRef.wrap(arrayType))
45
            ],
46
            false, null);
47
        nativeFunc.implementation = ([array]) => EPtr.box(arrayType.size);
48
        program.add(nativeFunc);
49
    }
50
}
- a/Tools/WebGPUShadingLanguageRI/SynthesizeCopyConstructorOperator.js +63 lines
Line 0 a/Tools/WebGPUShadingLanguageRI/SynthesizeCopyConstructorOperator.js_sec1
1
/*
2
 * Copyright (C) 2017 Apple Inc. All rights reserved.
3
 *
4
 * Redistribution and use in source and binary forms, with or without
5
 * modification, are permitted provided that the following conditions
6
 * are met:
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.
12
 *
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. 
24
 */
25
"use strict";
26
27
function synthesizeCopyConstructorOperator(program)
28
{
29
    const types = new Set();
30
31
    class FindAllTypes extends Visitor {
32
        visitNativeType(node)
33
        { 
34
            types.add(node); 
35
        }
36
37
        visitStructType(node)
38
        {
39
            types.add(node);
40
            super.visitStructType(node);
41
        }
42
43
        visitElementalType(node)
44
        {
45
            types.add(node);
46
            super.visitElementalType(node);
47
        }
48
    }
49
50
    program.visit(new FindAllTypes());
51
52
    for (let type of types) {
53
        let nativeFunc = new NativeFunc(type.origin, "operator cast", TypeRef.wrap(type), [], [
54
            new FuncParameter(type.origin, null, TypeRef.wrap(type))
55
        ], true, null);
56
        nativeFunc.implementation = ([arg], node) => {
57
            let result = new EPtr(new EBuffer(type.size), 0);
58
            result.copyFrom(arg, type.size);
59
            return result;
60
        };
61
        program.add(nativeFunc);
62
    }
63
}
- a/Tools/WebGPUShadingLanguageRI/SynthesizeDefaultConstructorOperator.js +61 lines
Line 0 a/Tools/WebGPUShadingLanguageRI/SynthesizeDefaultConstructorOperator.js_sec1
1
/*
2
 * Copyright (C) 2017 Apple Inc. All rights reserved.
3
 *
4
 * Redistribution and use in source and binary forms, with or without
5
 * modification, are permitted provided that the following conditions
6
 * are met:
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.
12
 *
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. 
24
 */
25
"use strict";
26
27
function synthesizeDefaultConstructorOperator(program)
28
{
29
    const types = new Set();
30
31
    class FindAllTypes extends Visitor {
32
        visitNativeType(node)
33
        { 
34
            types.add(node); 
35
        }
36
37
        visitStructType(node)
38
        {
39
            types.add(node);
40
            super.visitStructType(node);
41
        }
42
43
        visitElementalType(node)
44
        {
45
            types.add(node);
46
            super.visitElementalType(node);
47
        }
48
    }
49
50
    program.visit(new FindAllTypes());
51
52
    for (let type of types) {
53
        let nativeFunc = new NativeFunc(type.origin, "operator cast", TypeRef.wrap(type), [], [], true, null);
54
        nativeFunc.implementation = ([], node) => {
55
            let result = new EPtr(new EBuffer(type.size), 0);
56
            node.type.populateDefaultValue(result.buffer, 0);
57
            return result;
58
        };
59
        program.add(nativeFunc);
60
    }
61
}
- a/Tools/WebGPUShadingLanguageRI/Test.html -2 / +12 lines
Lines 41-48 a/Tools/WebGPUShadingLanguageRI/Test.html_sec1
41
<script src="ConvertPtrToArrayRefExpression.js"></script>
41
<script src="ConvertPtrToArrayRefExpression.js"></script>
42
<script src="DoWhileLoop.js"></script>
42
<script src="DoWhileLoop.js"></script>
43
<script src="DotExpression.js"></script>
43
<script src="DotExpression.js"></script>
44
<script src="DoubleLiteral.js"></script>
45
<script src="DoubleLiteralType.js"></script>
46
<script src="DereferenceExpression.js"></script>
44
<script src="DereferenceExpression.js"></script>
47
<script src="EArrayRef.js"></script>
45
<script src="EArrayRef.js"></script>
48
<script src="EBuffer.js"></script>
46
<script src="EBuffer.js"></script>
Lines 98-103 a/Tools/WebGPUShadingLanguageRI/Test.html_sec2
98
<script src="NormalUsePropertyResolver.js"></script>
96
<script src="NormalUsePropertyResolver.js"></script>
99
<script src="NullLiteral.js"></script>
97
<script src="NullLiteral.js"></script>
100
<script src="NullType.js"></script>
98
<script src="NullType.js"></script>
99
<script src="OperatorAnderIndex.js"></script>
100
<script src="OperatorArrayRefLength.js"></script>
101
<script src="OperatorBool.js"></script>
102
<script src="BuiltinVectorCasts.js"></script>
103
<script src="BuiltinVectorGetter.js"></script>
104
<script src="BuiltinVectorSetter.js"></script>
105
<script src="BuiltinVectorIndexGetter.js"></script>
106
<script src="BuiltinVectorIndexSetter.js"></script>
107
<script src="BuiltinVectorEqualityOperator.js"></script>
101
<script src="OriginKind.js"></script>
108
<script src="OriginKind.js"></script>
102
<script src="OverloadResolutionFailure.js"></script>
109
<script src="OverloadResolutionFailure.js"></script>
103
<script src="Parse.js"></script>
110
<script src="Parse.js"></script>
Lines 127-134 a/Tools/WebGPUShadingLanguageRI/Test.html_sec3
127
<script src="Substitution.js"></script>
134
<script src="Substitution.js"></script>
128
<script src="SwitchCase.js"></script>
135
<script src="SwitchCase.js"></script>
129
<script src="SwitchStatement.js"></script>
136
<script src="SwitchStatement.js"></script>
137
<script src="SynthesizeArrayOperatorLength.js"></script>
130
<script src="SynthesizeEnumFunctions.js"></script>
138
<script src="SynthesizeEnumFunctions.js"></script>
131
<script src="SynthesizeStructAccessors.js"></script>
139
<script src="SynthesizeStructAccessors.js"></script>
140
<script src="SynthesizeCopyConstructorOperator.js"></script>
141
<script src="SynthesizeDefaultConstructorOperator.js"></script>
132
<script src="TrapStatement.js"></script>
142
<script src="TrapStatement.js"></script>
133
<script src="TypeDef.js"></script>
143
<script src="TypeDef.js"></script>
134
<script src="TypeDefResolver.js"></script>
144
<script src="TypeDefResolver.js"></script>
- a/Tools/WebGPUShadingLanguageRI/Test.js -1668 / +165 lines
Lines 78-88 function makeFloat(program, value) a/Tools/WebGPUShadingLanguageRI/Test.js_sec1
78
    return TypedValue.box(program.intrinsics.float, value);
78
    return TypedValue.box(program.intrinsics.float, value);
79
}
79
}
80
80
81
function makeDouble(program, value)
82
{
83
    return TypedValue.box(program.intrinsics.double, value);
84
}
85
86
function makeEnum(program, enumName, value)
81
function makeEnum(program, enumName, value)
87
{
82
{
88
    let enumType = program.types.get(enumName);
83
    let enumType = program.types.get(enumName);
Lines 149-162 function checkFloat(program, result, expected) a/Tools/WebGPUShadingLanguageRI/Test.js_sec2
149
        throw new Error("Wrong result: " + result.value + " (expected " + expected + ")");
144
        throw new Error("Wrong result: " + result.value + " (expected " + expected + ")");
150
}
145
}
151
146
152
function checkDouble(program, result, expected)
153
{
154
    if (!result.type.equals(program.intrinsics.double))
155
        throw new Error("Wrong result type: " + result.type);
156
    if (result.value != expected)
157
        throw new Error("Wrong result: " + result.value + " (expected " + expected + ")");
158
}
159
160
function checkLexerToken(result, expectedIndex, expectedKind, expectedText)
147
function checkLexerToken(result, expectedIndex, expectedKind, expectedText)
161
{
148
{
162
    if (result._index != expectedIndex)
149
    if (result._index != expectedIndex)
Lines 320-333 tests.add1 = function() { a/Tools/WebGPUShadingLanguageRI/Test.js_sec3
320
    checkInt(program, callFunction(program, "foo", [], [makeInt(program, 42)]), 43);
307
    checkInt(program, callFunction(program, "foo", [], [makeInt(program, 42)]), 43);
321
}
308
}
322
309
323
tests.simpleGeneric = function() {
324
    let program = doPrep(`
325
        T id<T>(T x) { return x; }
326
        int foo(int x) { return id(x) + 1; }
327
    `);
328
    checkInt(program, callFunction(program, "foo", [], [makeInt(program, 42)]), 43);
329
}
330
331
tests.nameResolutionFailure = function()
310
tests.nameResolutionFailure = function()
332
{
311
{
333
    checkFail(
312
    checkFail(
Lines 526-549 tests.deviceArrayStoreIntLiteral = function() a/Tools/WebGPUShadingLanguageRI/Test.js_sec4
526
        throw new Error("Bad value stored into buffer (expected -111): " + buffer.get(0));
505
        throw new Error("Bad value stored into buffer (expected -111): " + buffer.get(0));
527
}
506
}
528
507
529
tests.simpleProtocol = function()
530
{
531
    let program = doPrep(`
532
        protocol MyAddable {
533
            MyAddable operator+(MyAddable, MyAddable);
534
        }
535
        T add<T:MyAddable>(T a, T b)
536
        {
537
            return a + b;
538
        }
539
        int foo(int x)
540
        {
541
            return add(x, 73);
542
        }
543
    `);
544
    checkInt(program, callFunction(program, "foo", [], [makeInt(program, 45)]), 45 + 73);
545
}
546
547
tests.typeMismatchReturn = function()
508
tests.typeMismatchReturn = function()
548
{
509
{
549
    checkFail(
510
    checkFail(
Lines 597-614 tests.badAdd = function() a/Tools/WebGPUShadingLanguageRI/Test.js_sec5
597
{
558
{
598
    checkFail(
559
    checkFail(
599
        () => doPrep(`
560
        () => doPrep(`
600
            void bar<T>(T) { }
601
            void foo(int x, uint y)
561
            void foo(int x, uint y)
602
            {
562
            {
603
                bar(x + y);
563
                uint z = x + y;
604
            }
564
            }
605
        `),
565
        `),
606
        (e) => e instanceof WTypeError && e.message.indexOf("native int32 operator+<>(int32,int32)") != -1);
566
        (e) => e instanceof WTypeError && e.message.indexOf("native int32 operator+(int32,int32)") != -1);
607
}
567
}
608
568
609
tests.lexerKeyword = function()
569
tests.lexerKeyword = function()
610
{
570
{
611
    let result = doLex("ident for while 123 123u { } {asd asd{ 1a3 1.2 + 3.4 + 1. + .2 1.2d 0.d .3d && ||");
571
    let result = doLex("ident for while 123 123u { } {asd asd{ 1a3 1.2 + 3.4 + 1. + .2 1.2f 0.f .3f && ||");
612
    if (result.length != 25)
572
    if (result.length != 25)
613
        throw new Error("Lexer emitted an incorrect number of tokens (expected 23): " + result.length);
573
        throw new Error("Lexer emitted an incorrect number of tokens (expected 23): " + result.length);
614
    checkLexerToken(result[0],  0,  "identifier",    "ident");
574
    checkLexerToken(result[0],  0,  "identifier",    "ident");
Lines 631-639 tests.lexerKeyword = function() a/Tools/WebGPUShadingLanguageRI/Test.js_sec6
631
    checkLexerToken(result[17], 55, "floatLiteral",  "1.");
591
    checkLexerToken(result[17], 55, "floatLiteral",  "1.");
632
    checkLexerToken(result[18], 58, "punctuation",   "+");
592
    checkLexerToken(result[18], 58, "punctuation",   "+");
633
    checkLexerToken(result[19], 60, "floatLiteral",  ".2");
593
    checkLexerToken(result[19], 60, "floatLiteral",  ".2");
634
    checkLexerToken(result[20], 63, "floatLiteral",  "1.2d");
594
    checkLexerToken(result[20], 63, "floatLiteral",  "1.2f");
635
    checkLexerToken(result[21], 68, "floatLiteral",  "0.d");
595
    checkLexerToken(result[21], 68, "floatLiteral",  "0.f");
636
    checkLexerToken(result[22], 72, "floatLiteral",  ".3d");
596
    checkLexerToken(result[22], 72, "floatLiteral",  ".3f");
637
    checkLexerToken(result[23], 76, "punctuation",   "&&");
597
    checkLexerToken(result[23], 76, "punctuation",   "&&");
638
    checkLexerToken(result[24], 79, "punctuation",   "||");
598
    checkLexerToken(result[24], 79, "punctuation",   "||");
639
}
599
}
Lines 690-746 tests.simpleStruct = function() a/Tools/WebGPUShadingLanguageRI/Test.js_sec7
690
        throw new Error("Wrong result for y: " + y + " (x + " + x + ")");
650
        throw new Error("Wrong result for y: " + y + " (x + " + x + ")");
691
}
651
}
692
652
693
tests.genericStructInstance = function()
694
{
695
    let program = doPrep(`
696
        struct Foo<T> {
697
            T x;
698
            T y;
699
        }
700
        Foo<int> foo(Foo<int> foo)
701
        {
702
            Foo<int> result;
703
            result.x = foo.y;
704
            result.y = foo.x;
705
            return result;
706
        }
707
    `);
708
    let structType = TypeRef.instantiate(program.types.get("Foo"), [program.intrinsics.int32]);
709
    let buffer = new EBuffer(2);
710
    buffer.set(0, 62);
711
    buffer.set(1, 24);
712
    let result = callFunction(program, "foo", [], [new TypedValue(structType, new EPtr(buffer, 0))]);
713
    let x = result.ePtr.get(0);
714
    let y = result.ePtr.get(1);
715
    if (x != 24)
716
        throw new Error("Wrong result for x: " + x + " (y = " + y + ")");
717
    if (y != 62)
718
        throw new Error("Wrong result for y: " + y + " (x + " + x + ")");
719
}
720
721
tests.doubleGenericCallsDoubleGeneric = function()
722
{
723
    doPrep(`
724
        void foo<T, U>(T, U) { }
725
        void bar<V, W>(V x, W y) { foo(x, y); }
726
    `);
727
}
728
729
tests.doubleGenericCallsSingleGeneric = function()
730
{
731
    checkFail(
732
        () => doPrep(`
733
            void foo<T>(T, T) { }
734
            void bar<V, W>(V x, W y) { foo(x, y); }
735
        `),
736
        (e) => e instanceof WTypeError);
737
}
738
739
tests.loadNull = function()
653
tests.loadNull = function()
740
{
654
{
741
    checkFail(
655
    checkFail(
742
        () => doPrep(`
656
        () => doPrep(`
743
            void sink<T>(T) { }
657
            void sink(thread int* x) { }
744
            void foo() { sink(*null); }
658
            void foo() { sink(*null); }
745
        `),
659
        `),
746
        (e) => e instanceof WTypeError && e.message.indexOf("Type passed to dereference is not a pointer: null") != -1);
660
        (e) => e instanceof WTypeError && e.message.indexOf("Type passed to dereference is not a pointer: null") != -1);
Lines 814-856 tests.passNullToPtrMonomorphic = function() a/Tools/WebGPUShadingLanguageRI/Test.js_sec8
814
        (e) => e instanceof WTrapError);
728
        (e) => e instanceof WTrapError);
815
}
729
}
816
730
817
tests.passNullToPtrPolymorphic = function()
818
{
819
    checkFail(
820
        () => doPrep(`
821
            T foo<T>(thread T* ptr)
822
            {
823
                return *ptr;
824
            }
825
            int bar()
826
            {
827
                return foo(null);
828
            }
829
        `),
830
        (e) => e instanceof WTypeError);
831
}
832
833
tests.passNullToPolymorphic = function()
834
{
835
    checkFail(
836
        () => doPrep(`
837
            T foo<T>(T ptr)
838
            {
839
                return ptr;
840
            }
841
            int bar()
842
            {
843
                return foo(null);
844
            }
845
        `),
846
        (e) => e instanceof WTypeError);
847
}
848
849
tests.loadNullArrayRef = function()
731
tests.loadNullArrayRef = function()
850
{
732
{
851
    checkFail(
733
    checkFail(
852
        () => doPrep(`
734
        () => doPrep(`
853
            void sink<T>(T) { }
735
            void sink(thread int* x) { }
854
            void foo() { sink(null[0u]); }
736
            void foo() { sink(null[0u]); }
855
        `),
737
        `),
856
        (e) => e instanceof WTypeError && e.message.indexOf("Cannot resolve access") != -1);
738
        (e) => e instanceof WTypeError && e.message.indexOf("Cannot resolve access") != -1);
Lines 938-968 tests.passNullToPtrMonomorphicArrayRef = function() a/Tools/WebGPUShadingLanguageRI/Test.js_sec9
938
        (e) => e instanceof WTrapError);
820
        (e) => e instanceof WTrapError);
939
}
821
}
940
822
941
tests.passNullToPtrPolymorphicArrayRef = function()
942
{
943
    checkFail(
944
        () => doPrep(`
945
            T foo<T>(thread T[] ptr)
946
            {
947
                return ptr[0u];
948
            }
949
            int bar()
950
            {
951
                return foo(null);
952
            }
953
        `),
954
        (e) => e instanceof WTypeError);
955
}
956
957
tests.returnIntLiteralUint = function()
823
tests.returnIntLiteralUint = function()
958
{
824
{
959
    let program = doPrep("uint foo() { return 42; }");
825
    let program = doPrep("uint foo() { return 42; }");
960
    checkNumber(program, callFunction(program, "foo", [], []), 42);
826
    checkNumber(program, callFunction(program, "foo", [], []), 42);
961
}
827
}
962
828
963
tests.returnIntLiteralDouble = function()
829
tests.returnIntLiteralFloat = function()
964
{
830
{
965
    let program = doPrep("double foo() { return 42; }");
831
    let program = doPrep("float foo() { return 42; }");
966
    checkNumber(program, callFunction(program, "foo", [], []), 42);
832
    checkNumber(program, callFunction(program, "foo", [], []), 42);
967
}
833
}
968
834
Lines 980-1043 tests.badIntLiteralForUint = function() a/Tools/WebGPUShadingLanguageRI/Test.js_sec10
980
        (e) => e instanceof WSyntaxError);
846
        (e) => e instanceof WSyntaxError);
981
}
847
}
982
848
983
tests.badIntLiteralForDouble = function()
849
tests.badIntLiteralForFloat = function()
984
{
850
{
985
    checkFail(
851
    checkFail(
986
        () => doPrep("void foo() { double x = 5000000000000000000000000000000000000; }"),
852
        () => doPrep("void foo() { float x = 5000000000000000000000000000000000000; }"),
987
        (e) => e instanceof WSyntaxError);
853
        (e) => e instanceof WSyntaxError);
988
}
854
}
989
855
990
tests.passNullAndNotNull = function()
991
{
992
    let program = doPrep(`
993
        T bar<T>(device T* p, device T*)
994
        {
995
            return *p;
996
        }
997
        int foo(device int* p)
998
        {
999
            return bar(p, null);
1000
        }
1001
    `);
1002
    let buffer = new EBuffer(1);
1003
    buffer.set(0, 13);
1004
    checkInt(program, callFunction(program, "foo", [], [TypedValue.box(new PtrType(externalOrigin, "device", program.intrinsics.int32), new EPtr(buffer, 0))]), 13);
1005
}
1006
1007
tests.passNullAndNotNullFullPoly = function()
1008
{
1009
    let program = doPrep(`
1010
        T bar<T>(T p, T)
1011
        {
1012
            return p;
1013
        }
1014
        int foo(device int* p)
1015
        {
1016
            return *bar(p, null);
1017
        }
1018
    `);
1019
    let buffer = new EBuffer(1);
1020
    buffer.set(0, 13);
1021
    checkInt(program, callFunction(program, "foo", [], [TypedValue.box(new PtrType(externalOrigin, "device", program.intrinsics.int32), new EPtr(buffer, 0))]), 13);
1022
}
1023
1024
tests.passNullAndNotNullFullPolyReverse = function()
1025
{
1026
    let program = doPrep(`
1027
        T bar<T>(T, T p)
1028
        {
1029
            return p;
1030
        }
1031
        int foo(device int* p)
1032
        {
1033
            return *bar(null, p);
1034
        }
1035
    `);
1036
    let buffer = new EBuffer(1);
1037
    buffer.set(0, 13);
1038
    checkInt(program, callFunction(program, "foo", [], [TypedValue.box(new PtrType(externalOrigin, "device", program.intrinsics.int32), new EPtr(buffer, 0))]), 13);
1039
}
1040
1041
tests.nullTypeVariableUnify = function()
856
tests.nullTypeVariableUnify = function()
1042
{
857
{
1043
    let left = new NullType(externalOrigin);
858
    let left = new NullType(externalOrigin);
Lines 1112-1233 tests.simpleRecursion = function() a/Tools/WebGPUShadingLanguageRI/Test.js_sec11
1112
{
927
{
1113
    checkFail(
928
    checkFail(
1114
        () => doPrep(`
929
        () => doPrep(`
1115
            void foo<T>(T x)
930
            void foo(int x)
1116
            {
931
            {
1117
                foo(&x);
932
                foo(x);
1118
            }
933
            }
1119
        `),
934
        `),
1120
        (e) => e instanceof WTypeError);
935
        (e) => e instanceof WTypeError);
1121
}
936
}
1122
937
1123
tests.protocolMonoSigPolyDef = function()
1124
{
1125
    let program = doPrep(`
1126
        struct IntAnd<T> {
1127
            int first;
1128
            T second;
1129
        }
1130
        IntAnd<T> intAnd<T>(int first, T second)
1131
        {
1132
            IntAnd<T> result;
1133
            result.first = first;
1134
            result.second = second;
1135
            return result;
1136
        }
1137
        protocol IntAndable {
1138
            IntAnd<int> intAnd(IntAndable, int);
1139
        }
1140
        int foo<T:IntAndable>(T first, int second)
1141
        {
1142
            IntAnd<int> result = intAnd(first, second);
1143
            return result.first + result.second;
1144
        }
1145
    `);
1146
    checkInt(program, callFunction(program, "foo", [], [makeInt(program, 54), makeInt(program, 12)]), 54 + 12);
1147
}
1148
1149
tests.protocolPolySigPolyDef = function()
1150
{
1151
    let program = doPrep(`
1152
        struct IntAnd<T> {
1153
            int first;
1154
            T second;
1155
        }
1156
        IntAnd<T> intAnd<T>(int first, T second)
1157
        {
1158
            IntAnd<T> result;
1159
            result.first = first;
1160
            result.second = second;
1161
            return result;
1162
        }
1163
        protocol IntAndable {
1164
            IntAnd<T> intAnd<T>(IntAndable, T);
1165
        }
1166
        int foo<T:IntAndable>(T first, int second)
1167
        {
1168
            IntAnd<int> result = intAnd(first, second);
1169
            return result.first + result.second;
1170
        }
1171
    `);
1172
    checkInt(program, callFunction(program, "foo", [], [makeInt(program, 54), makeInt(program, 12)]), 54 + 12);
1173
}
1174
1175
tests.protocolDoublePolySigDoublePolyDef = function()
1176
{
1177
    let program = doPrep(`
1178
        struct IntAnd<T, U> {
1179
            int first;
1180
            T second;
1181
            U third;
1182
        }
1183
        IntAnd<T, U> intAnd<T, U>(int first, T second, U third)
1184
        {
1185
            IntAnd<T, U> result;
1186
            result.first = first;
1187
            result.second = second;
1188
            result.third = third;
1189
            return result;
1190
        }
1191
        protocol IntAndable {
1192
            IntAnd<T, U> intAnd<T, U>(IntAndable, T, U);
1193
        }
1194
        int foo<T:IntAndable>(T first, int second, int third)
1195
        {
1196
            IntAnd<int, int> result = intAnd(first, second, third);
1197
            return result.first + result.second + result.third;
1198
        }
1199
    `);
1200
    checkInt(program, callFunction(program, "foo", [], [makeInt(program, 54), makeInt(program, 12), makeInt(program, 39)]), 54 + 12 + 39);
1201
}
1202
1203
tests.protocolDoublePolySigDoublePolyDefExplicit = function()
1204
{
1205
    let program = doPrep(`
1206
        struct IntAnd<T, U> {
1207
            int first;
1208
            T second;
1209
            U third;
1210
        }
1211
        IntAnd<T, U> intAnd<T, U>(int first, T second, U third)
1212
        {
1213
            IntAnd<T, U> result;
1214
            result.first = first;
1215
            result.second = second;
1216
            result.third = third;
1217
            return result;
1218
        }
1219
        protocol IntAndable {
1220
            IntAnd<T, U> intAnd<T, U>(IntAndable, T, U);
1221
        }
1222
        int foo<T:IntAndable>(T first, int second, int third)
1223
        {
1224
            IntAnd<int, int> result = intAnd<int, int>(first, second, third);
1225
            return result.first + result.second + result.third;
1226
        }
1227
    `);
1228
    checkInt(program, callFunction(program, "foo", [], [makeInt(program, 54), makeInt(program, 12), makeInt(program, 39)]), 54 + 12 + 39);
1229
}
1230
1231
tests.variableShadowing = function()
938
tests.variableShadowing = function()
1232
{
939
{
1233
    let program = doPrep(`
940
    let program = doPrep(`
Lines 1478-1553 tests.simpleWhile = function() a/Tools/WebGPUShadingLanguageRI/Test.js_sec12
1478
    checkInt(program, callFunction(program, "foo", [], [makeInt(program, 1)]), 16);
1185
    checkInt(program, callFunction(program, "foo", [], [makeInt(program, 1)]), 16);
1479
}
1186
}
1480
1187
1481
tests.protocolMonoPolySigDoublePolyDefExplicit = function()
1482
{
1483
    checkFail(
1484
        () => {
1485
            let program = doPrep(`
1486
                struct IntAnd<T, U> {
1487
                    int first;
1488
                    T second;
1489
                    U third;
1490
                }
1491
                IntAnd<T, U> intAnd<T, U>(int first, T second, U third)
1492
                {
1493
                    IntAnd<T, U> result;
1494
                    result.first = first;
1495
                    result.second = second;
1496
                    result.third = third;
1497
                    return result;
1498
                }
1499
                protocol IntAndable {
1500
                    IntAnd<T, int> intAnd<T>(IntAndable, T, int);
1501
                }
1502
                int foo<T:IntAndable>(T first, int second, int third)
1503
                {
1504
                    IntAnd<int, int> result = intAnd<int>(first, second, third);
1505
                    return result.first + result.second + result.third;
1506
                }
1507
            `);
1508
            callFunction(program, "foo", [], [makeInt(program, 54), makeInt(program, 12), makeInt(program, 39)]);
1509
        },
1510
        (e) => e instanceof WTypeError);
1511
}
1512
1513
tests.ambiguousOverloadSimple = function()
1514
{
1515
    checkFail(
1516
        () => doPrep(`
1517
            void foo<T>(int, T) { }
1518
            void foo<T>(T, int) { }
1519
            void bar(int a, int b) { foo(a, b); }
1520
        `),
1521
        (e) => e instanceof WTypeError);
1522
}
1523
1524
tests.ambiguousOverloadOverlapping = function()
1525
{
1526
    checkFail(
1527
        () => doPrep(`
1528
            void foo<T>(int, T) { }
1529
            void foo<T>(T, T) { }
1530
            void bar(int a, int b) { foo(a, b); }
1531
        `),
1532
        (e) => e instanceof WTypeError);
1533
}
1534
1535
tests.ambiguousOverloadTieBreak = function()
1536
{
1537
    doPrep(`
1538
        void foo<T>(int, T) { }
1539
        void foo<T>(T, T) { }
1540
        void foo(int, int) { }
1541
        void bar(int a, int b) { foo(a, b); }
1542
    `);
1543
}
1544
1545
tests.intOverloadResolution = function()
1188
tests.intOverloadResolution = function()
1546
{
1189
{
1547
    let program = doPrep(`
1190
    let program = doPrep(`
1548
        int foo(int) { return 1; }
1191
        int foo(int) { return 1; }
1549
        int foo(uint) { return 2; }
1192
        int foo(uint) { return 2; }
1550
        int foo(double) { return 3; }
1193
        int foo(float) { return 3; }
1551
        int bar() { return foo(42); }
1194
        int bar() { return foo(42); }
1552
    `);
1195
    `);
1553
    checkInt(program, callFunction(program, "bar", [], []), 1);
1196
    checkInt(program, callFunction(program, "bar", [], []), 1);
Lines 1556-1562 tests.intOverloadResolution = function() a/Tools/WebGPUShadingLanguageRI/Test.js_sec13
1556
tests.intOverloadResolutionReverseOrder = function()
1199
tests.intOverloadResolutionReverseOrder = function()
1557
{
1200
{
1558
    let program = doPrep(`
1201
    let program = doPrep(`
1559
        int foo(double) { return 3; }
1202
        int foo(float) { return 3; }
1560
        int foo(uint) { return 2; }
1203
        int foo(uint) { return 2; }
1561
        int foo(int) { return 1; }
1204
        int foo(int) { return 1; }
1562
        int bar() { return foo(42); }
1205
        int bar() { return foo(42); }
Lines 1564-1645 tests.intOverloadResolutionReverseOrder = function() a/Tools/WebGPUShadingLanguageRI/Test.js_sec14
1564
    checkInt(program, callFunction(program, "bar", [], []), 1);
1207
    checkInt(program, callFunction(program, "bar", [], []), 1);
1565
}
1208
}
1566
1209
1567
tests.intOverloadResolutionGeneric = function()
1568
{
1569
    let program = doPrep(`
1570
        int foo(int) { return 1; }
1571
        int foo<T>(T) { return 2; }
1572
        int bar() { return foo(42); }
1573
    `);
1574
    checkInt(program, callFunction(program, "bar", [], []), 1);
1575
}
1576
1577
tests.intLiteralGeneric = function()
1578
{
1579
    let program = doPrep(`
1580
        int foo<T>(T x) { return 3478; }
1581
        int bar() { return foo(42); }
1582
    `);
1583
    checkInt(program, callFunction(program, "bar", [], []), 3478);
1584
}
1585
1586
tests.intLiteralGenericWithProtocols = function()
1587
{
1588
    let program = doPrep(`
1589
        protocol MyConvertibleToInt {
1590
            operator int(MyConvertibleToInt);
1591
        }
1592
        int foo<T:MyConvertibleToInt>(T x) { return int(x); }
1593
        int bar() { return foo(42); }
1594
    `);
1595
    checkInt(program, callFunction(program, "bar", [], []), 42);
1596
}
1597
1598
tests.uintLiteralGeneric = function()
1599
{
1600
    let program = doPrep(`
1601
        int foo<T>(T x) { return 3478; }
1602
        int bar() { return foo(42u); }
1603
    `);
1604
    checkInt(program, callFunction(program, "bar", [], []), 3478);
1605
}
1606
1607
tests.uintLiteralGenericWithProtocols = function()
1608
{
1609
    let program = doPrep(`
1610
        protocol MyConvertibleToUint {
1611
            operator uint(MyConvertibleToUint);
1612
        }
1613
        uint foo<T:MyConvertibleToUint>(T x) { return uint(x); }
1614
        uint bar() { return foo(42u); }
1615
    `);
1616
    checkUint(program, callFunction(program, "bar", [], []), 42);
1617
}
1618
1619
tests.intLiteralGenericSpecific = function()
1620
{
1621
    let program = doPrep(`
1622
        T foo<T>(T x) { return x; }
1623
        int bar() { return foo(int(42)); }
1624
    `);
1625
    checkInt(program, callFunction(program, "bar", [], []), 42);
1626
}
1627
1628
tests.simpleConstexpr = function()
1629
{
1630
    let program = doPrep(`
1631
        int foo<int a>(int b)
1632
        {
1633
            return a + b;
1634
        }
1635
        int bar(int b)
1636
        {
1637
            return foo<42>(b);
1638
        }
1639
    `);
1640
    checkInt(program, callFunction(program, "bar", [], [makeInt(program, 58)]), 58 + 42);
1641
}
1642
1643
tests.break = function()
1210
tests.break = function()
1644
{
1211
{
1645
    let program = doPrep(`
1212
    let program = doPrep(`
Lines 1993-2217 tests.forLoop = function() a/Tools/WebGPUShadingLanguageRI/Test.js_sec15
1993
    checkInt(program, callFunction(program, "foo", [], [makeInt(program, 7)]), 7);
1560
    checkInt(program, callFunction(program, "foo", [], [makeInt(program, 7)]), 7);
1994
}
1561
}
1995
1562
1996
tests.chainConstexpr = function()
1563
tests.prefixPlusPlus = function()
1997
{
1998
    let program = doPrep(`
1999
        int foo<int a>(int b)
2000
        {
2001
            return a + b;
2002
        }
2003
        int bar<int a>(int b)
2004
        {
2005
            return foo<a>(b);
2006
        }
2007
        int baz(int b)
2008
        {
2009
            return bar<42>(b);
2010
        }
2011
    `);
2012
    checkInt(program, callFunction(program, "baz", [], [makeInt(program, 58)]), 58 + 42);
2013
}
2014
2015
tests.chainGeneric = function()
2016
{
2017
    let program = doPrep(`
2018
        T foo<T>(T x)
2019
        {
2020
            return x;
2021
        }
2022
        T bar<T>(thread T* ptr)
2023
        {
2024
            return *foo(ptr);
2025
        }
2026
        int baz(int x)
2027
        {
2028
            return bar(&x);
2029
        }
2030
    `);
2031
    checkInt(program, callFunction(program, "baz", [], [makeInt(program, 37)]), 37);
2032
}
2033
2034
tests.chainStruct = function()
2035
{
2036
    let program = doPrep(`
2037
        struct Foo<T> {
2038
            T f;
2039
        }
2040
        struct Bar<T> {
2041
            Foo<thread T*> f;
2042
        }
2043
        int foo(thread Bar<int>* x)
2044
        {
2045
            return *x->f.f;
2046
        }
2047
        int bar(int a)
2048
        {
2049
            Bar<int> x;
2050
            x.f.f = &a;
2051
            return foo(&x);
2052
        }
2053
    `);
2054
    checkInt(program, callFunction(program, "bar", [], [makeInt(program, 4657)]), 4657);
2055
}
2056
2057
tests.chainStructNewlyValid = function()
2058
{
2059
    let program = doPrep(`
2060
        struct Foo<T> {
2061
            T f;
2062
        }
2063
        struct Bar<T> {
2064
            Foo<device T*> f;
2065
        }
2066
        int foo(thread Bar<int>* x)
2067
        {
2068
            return *x->f.f;
2069
        }
2070
        int bar(device int* a)
2071
        {
2072
            Bar<int> x;
2073
            x.f.f = a;
2074
            return foo(&x);
2075
        }
2076
    `);
2077
    let buffer = new EBuffer(1);
2078
    buffer.set(0, 78453);
2079
    checkInt(program, callFunction(program, "bar", [], [TypedValue.box(new PtrType(externalOrigin, "device", program.intrinsics.int32), new EPtr(buffer, 0))]), 78453);
2080
}
2081
2082
tests.chainStructDevice = function()
2083
{
2084
    let program = doPrep(`
2085
        struct Foo<T> {
2086
            T f;
2087
        }
2088
        struct Bar<T> {
2089
            Foo<device T*> f;
2090
        }
2091
        int foo(thread Bar<int>* x)
2092
        {
2093
            return *x->f.f;
2094
        }
2095
        int bar(device int* a)
2096
        {
2097
            Bar<int> x;
2098
            x.f.f = a;
2099
            return foo(&x);
2100
        }
2101
    `);
2102
    let buffer = new EBuffer(1);
2103
    buffer.set(0, 79201);
2104
    checkInt(program, callFunction(program, "bar", [], [TypedValue.box(new PtrType(externalOrigin, "device", program.intrinsics.int32), new EPtr(buffer, 0))]), 79201);
2105
}
2106
2107
tests.paramChainStructDevice = function()
2108
{
2109
    let program = doPrep(`
2110
        struct Foo<T> {
2111
            T f;
2112
        }
2113
        struct Bar<T> {
2114
            Foo<T> f;
2115
        }
2116
        int foo(thread Bar<device int*>* x)
2117
        {
2118
            return *x->f.f;
2119
        }
2120
        int bar(device int* a)
2121
        {
2122
            Bar<device int*> x;
2123
            x.f.f = a;
2124
            return foo(&x);
2125
        }
2126
    `);
2127
    let buffer = new EBuffer(1);
2128
    buffer.set(0, 79201);
2129
    checkInt(program, callFunction(program, "bar", [], [TypedValue.box(new PtrType(externalOrigin, "device", program.intrinsics.int32), new EPtr(buffer, 0))]), 79201);
2130
}
2131
2132
tests.simpleProtocolExtends = function()
2133
{
2134
    let program = doPrep(`
2135
        protocol Foo {
2136
            void foo(thread Foo*);
2137
        }
2138
        protocol Bar : Foo {
2139
            void bar(thread Bar*);
2140
        }
2141
        void fuzz<T:Foo>(thread T* p)
2142
        {
2143
            foo(p);
2144
        }
2145
        void buzz<T:Bar>(thread T* p)
2146
        {
2147
            fuzz(p);
2148
            bar(p);
2149
        }
2150
        void foo(thread int* p)
2151
        {
2152
            *p = *p + 743;
2153
        }
2154
        void bar(thread int* p)
2155
        {
2156
            *p = *p + 91;
2157
        }
2158
        int thingy(int a)
2159
        {
2160
            buzz(&a);
2161
            return a;
2162
        }
2163
    `);
2164
    checkInt(program, callFunction(program, "thingy", [], [makeInt(program, 642)]), 642 + 743 + 91);
2165
}
2166
2167
tests.protocolExtendsTwo = function()
2168
{
2169
    let program = doPrep(`
2170
        protocol Foo {
2171
            void foo(thread Foo*);
2172
        }
2173
        protocol Bar {
2174
            void bar(thread Bar*);
2175
        }
2176
        protocol Baz : Foo, Bar {
2177
            void baz(thread Baz*);
2178
        }
2179
        void fuzz<T:Foo>(thread T* p)
2180
        {
2181
            foo(p);
2182
        }
2183
        void buzz<T:Bar>(thread T* p)
2184
        {
2185
            bar(p);
2186
        }
2187
        void xuzz<T:Baz>(thread T* p)
2188
        {
2189
            fuzz(p);
2190
            buzz(p);
2191
            baz(p);
2192
        }
2193
        void foo(thread int* p)
2194
        {
2195
            *p = *p + 743;
2196
        }
2197
        void bar(thread int* p)
2198
        {
2199
            *p = *p + 91;
2200
        }
2201
        void baz(thread int* p)
2202
        {
2203
            *p = *p + 39;
2204
        }
2205
        int thingy(int a)
2206
        {
2207
            xuzz(&a);
2208
            return a;
2209
        }
2210
    `);
2211
    checkInt(program, callFunction(program, "thingy", [], [makeInt(program, 642)]), 642 + 743 + 91 + 39);
2212
}
2213
2214
tests.prefixPlusPlus = function()
2215
{
1564
{
2216
    let program = doPrep(`
1565
    let program = doPrep(`
2217
        int foo(int x)
1566
        int foo(int x)
Lines 2406-2471 tests.twoIntLiterals = function() a/Tools/WebGPUShadingLanguageRI/Test.js_sec16
2406
    checkBool(program, callFunction(program, "foo", [], []), true);
1755
    checkBool(program, callFunction(program, "foo", [], []), true);
2407
}
1756
}
2408
1757
2409
tests.unifyDifferentLiterals = function()
2410
{
2411
    checkFail(
2412
        () => doPrep(`
2413
            void bar<T>(T, T)
2414
            {
2415
            }
2416
            void foo()
2417
            {
2418
                bar(42, 42u);
2419
            }
2420
        `),
2421
        (e) => e instanceof WTypeError);
2422
}
2423
2424
tests.unifyDifferentLiteralsBackwards = function()
2425
{
2426
    checkFail(
2427
        () => doPrep(`
2428
            void bar<T>(T, T)
2429
            {
2430
            }
2431
            void foo()
2432
            {
2433
                bar(42u, 42);
2434
            }
2435
        `),
2436
        (e) => e instanceof WTypeError);
2437
}
2438
2439
tests.unifyVeryDifferentLiterals = function()
2440
{
2441
    checkFail(
2442
        () => doPrep(`
2443
            void bar<T>(T, T)
2444
            {
2445
            }
2446
            void foo()
2447
            {
2448
                bar(42, null);
2449
            }
2450
        `),
2451
        (e) => e instanceof WTypeError);
2452
}
2453
2454
tests.unifyVeryDifferentLiteralsBackwards = function()
2455
{
2456
    checkFail(
2457
        () => doPrep(`
2458
            void bar<T>(T, T)
2459
            {
2460
            }
2461
            void foo()
2462
            {
2463
                bar(null, 42);
2464
            }
2465
        `),
2466
        (e) => e instanceof WTypeError);
2467
}
2468
2469
tests.assignUintToInt = function()
1758
tests.assignUintToInt = function()
2470
{
1759
{
2471
    checkFail(
1760
    checkFail(
Lines 2691-2697 tests.simpleLength = function() a/Tools/WebGPUShadingLanguageRI/Test.js_sec17
2691
    let program = doPrep(`
1980
    let program = doPrep(`
2692
        uint foo()
1981
        uint foo()
2693
        {
1982
        {
2694
            double[754] array;
1983
            float[754] array;
2695
            return (@array).length;
1984
            return (@array).length;
2696
        }
1985
        }
2697
    `);
1986
    `);
Lines 2703-2713 tests.nonArrayRefArrayLengthSucceed = function() a/Tools/WebGPUShadingLanguageRI/Test.js_sec18
2703
    let program = doPrep(`
1992
    let program = doPrep(`
2704
        uint foo()
1993
        uint foo()
2705
        {
1994
        {
2706
            double[754] array;
1995
            float[754] array;
1996
            return array.length;
1997
        }
1998
        uint bar()
1999
        {
2000
            int[754] array;
2707
            return array.length;
2001
            return array.length;
2708
        }
2002
        }
2709
    `);
2003
    `);
2710
    checkUint(program, callFunction(program, "foo", [], []), 754);
2004
    checkUint(program, callFunction(program, "foo", [], []), 754);
2005
    checkUint(program, callFunction(program, "bar", [], []), 754);
2711
}
2006
}
2712
2007
2713
tests.nonArrayRefArrayLengthFail = function()
2008
tests.nonArrayRefArrayLengthFail = function()
Lines 2723-2792 tests.nonArrayRefArrayLengthFail = function() a/Tools/WebGPUShadingLanguageRI/Test.js_sec19
2723
        e => e instanceof WTypeError);
2018
        e => e instanceof WTypeError);
2724
}
2019
}
2725
2020
2726
tests.constexprIsNotLValuePtr = function()
2727
{
2728
    checkFail(
2729
        () => doPrep(`
2730
            thread int* foo<int x>()
2731
            {
2732
                return &x;
2733
            }
2734
        `),
2735
        e => e instanceof WTypeError);
2736
}
2737
2738
tests.constexprIsNotLValueAssign = function()
2739
{
2740
    checkFail(
2741
        () => doPrep(`
2742
            void foo<int x>()
2743
            {
2744
                x = 42;
2745
            }
2746
        `),
2747
        e => e instanceof WTypeError);
2748
}
2749
2750
tests.constexprIsNotLValueRMW = function()
2751
{
2752
    checkFail(
2753
        () => doPrep(`
2754
            void foo<int x>()
2755
            {
2756
                x += 42;
2757
            }
2758
        `),
2759
        e => e instanceof WTypeError);
2760
}
2761
2762
tests.assignLength = function()
2021
tests.assignLength = function()
2763
{
2022
{
2764
    checkFail(
2023
    checkFail(
2765
        () => doPrep(`
2024
        () => doPrep(`
2766
            void foo()
2025
            void foo()
2767
            {
2026
            {
2768
                double[754] array;
2027
                float[754] array;
2769
                (@array).length = 42;
2028
                (@array).length = 42;
2770
            }
2029
            }
2771
        `),
2030
        `),
2772
        (e) => e instanceof WTypeError && e.message.indexOf("Have neither ander nor setter") != -1);
2031
        (e) => e instanceof WTypeError);
2773
}
2032
}
2774
2033
2775
tests.assignLengthHelper = function()
2034
tests.assignLengthHelper = function()
2776
{
2035
{
2777
    checkFail(
2036
    checkFail(
2778
        () => doPrep(`
2037
        () => doPrep(`
2779
            void bar(thread double[] array)
2038
            void bar(thread float[] array)
2780
            {
2039
            {
2781
                array.length = 42;
2040
                array.length = 42;
2782
            }
2041
            }
2783
            void foo()
2042
            void foo()
2784
            {
2043
            {
2785
                double[754] array;
2044
                float[754] array;
2786
                bar(@array);
2045
                bar(@array);
2787
            }
2046
            }
2788
        `),
2047
        `),
2789
        (e) => e instanceof WTypeError && e.message.indexOf("Have neither ander nor setter") != -1);
2048
        (e) => e instanceof WTypeError);
2790
}
2049
}
2791
2050
2792
tests.simpleGetter = function()
2051
tests.simpleGetter = function()
Lines 2834-3068 tests.simpleSetter = function() a/Tools/WebGPUShadingLanguageRI/Test.js_sec20
2834
    checkInt(program, callFunction(program, "foo", [], []), 7804);
2093
    checkInt(program, callFunction(program, "foo", [], []), 7804);
2835
}
2094
}
2836
2095
2837
tests.genericAccessors = function()
2838
{
2839
    let program = doPrep(`
2840
        struct Foo<T> {
2841
            T x;
2842
            T[3] y;
2843
        }
2844
        struct Bar<T> {
2845
            T x;
2846
            T y;
2847
        }
2848
        Bar<T> operator.z<T>(Foo<T> foo)
2849
        {
2850
            Bar<T> result;
2851
            result.x = foo.x;
2852
            result.y = foo.y[1];
2853
            return result;
2854
        }
2855
        Foo<T> operator.z=<T>(Foo<T> foo, Bar<T> bar)
2856
        {
2857
            foo.x = bar.x;
2858
            foo.y[1] = bar.y;
2859
            return foo;
2860
        }
2861
        T operator.sum<T:Addable>(Foo<T> foo)
2862
        {
2863
            return foo.x + foo.y[0] + foo.y[1] + foo.y[2];
2864
        }
2865
        T operator.sum<T:Addable>(Bar<T> bar)
2866
        {
2867
            return bar.x + bar.y;
2868
        }
2869
        operator<T> Bar<T>(T x, T y)
2870
        {
2871
            Bar<T> result;
2872
            result.x = x;
2873
            result.y = y;
2874
            return result;
2875
        }
2876
        void setup(thread Foo<int>* foo)
2877
        {
2878
            foo->x = 1;
2879
            foo->y[0] = 2;
2880
            foo->y[1] = 3;
2881
            foo->y[2] = 4;
2882
        }
2883
        int testSuperBasic()
2884
        {
2885
            Foo<int> foo;
2886
            setup(&foo);
2887
            return foo.sum;
2888
        }
2889
        int testZSetterDidSetY()
2890
        {
2891
            Foo<int> foo;
2892
            foo.z = Bar<int>(53, 932);
2893
            return foo.y[1];
2894
        }
2895
        int testZSetter()
2896
        {
2897
            Foo<int> foo;
2898
            foo.z = Bar<int>(53, 932);
2899
            return foo.sum;
2900
        }
2901
        int testZGetter()
2902
        {
2903
            Foo<int> foo;
2904
            // This deliberately does not call setup() just so we test this syntax.
2905
            foo.x = 1;
2906
            foo.y[0] = 2;
2907
            foo.y[1] = 3;
2908
            foo.y[2] = 4;
2909
            return foo.z.sum;
2910
        }
2911
        int testLValueEmulation()
2912
        {
2913
            Foo<int> foo;
2914
            setup(&foo);
2915
            foo.z.y *= 5;
2916
            return foo.sum;
2917
        }
2918
    `);
2919
    checkInt(program, callFunction(program, "testSuperBasic", [], []), 1 + 2 + 3 + 4);
2920
    checkInt(program, callFunction(program, "testZSetterDidSetY", [], []), 932);
2921
    checkInt(program, callFunction(program, "testZSetter", [], []), 53 + 932);
2922
    checkInt(program, callFunction(program, "testZGetter", [], []), 1 + 3);
2923
    checkInt(program, callFunction(program, "testLValueEmulation", [], []), 1 + 2 + 3 * 5 + 4);
2924
}
2925
2926
tests.bitSubscriptAccessor = function()
2927
{
2928
    let program = doPrep(`
2929
        protocol MyBitmaskable : Equatable {
2930
            MyBitmaskable operator&(MyBitmaskable, MyBitmaskable);
2931
            MyBitmaskable operator|(MyBitmaskable, MyBitmaskable);
2932
            MyBitmaskable operator~(MyBitmaskable);
2933
            MyBitmaskable operator<<(MyBitmaskable, uint);
2934
            MyBitmaskable operator>>(MyBitmaskable, uint);
2935
            operator MyBitmaskable(int);
2936
        }
2937
        T maskForBitIndex<T:MyBitmaskable>(uint index)
2938
        {
2939
            return T(1) << index;
2940
        }
2941
        bool operator[]<T:MyBitmaskable>(T value, uint index)
2942
        {
2943
            return bool(value & maskForBitIndex<T>(index));
2944
        }
2945
        T operator[]=<T:MyBitmaskable>(T value, uint index, bool bit)
2946
        {
2947
            T mask = maskForBitIndex<T>(index);
2948
            if (bit)
2949
                value |= mask;
2950
            else
2951
                value &= ~mask;
2952
            return value;
2953
        }
2954
        uint operator.length(int)
2955
        {
2956
            return 32;
2957
        }
2958
        uint operator.length(uint)
2959
        {
2960
            return 32;
2961
        }
2962
        int testIntSetBit3()
2963
        {
2964
            int foo;
2965
            foo[3] = true;
2966
            return foo;
2967
        }
2968
        bool testIntSetGetBit5()
2969
        {
2970
            int foo;
2971
            foo[5] = true;
2972
            return foo[5];
2973
        }
2974
        bool testIntGetBit1()
2975
        {
2976
            int foo;
2977
            return foo[1];
2978
        }
2979
        int testUintSumBits()
2980
        {
2981
            int foo = 42;
2982
            int result;
2983
            for (uint i = 0; i < foo.length; ++i) {
2984
                if (foo[i])
2985
                    result++;
2986
            }
2987
            return result;
2988
        }
2989
        int testUintSwapBits()
2990
        {
2991
            int foo = 42;
2992
            for (uint i = 0; i < foo.length / 2; ++i) {
2993
                bool tmp = foo[i];
2994
                foo[i] = foo[foo.length - i - 1];
2995
                foo[foo.length - i - 1] = tmp;
2996
            }
2997
            return foo;
2998
        }
2999
        struct Foo {
3000
            uint f;
3001
            uint g;
3002
        }
3003
        operator Foo(uint f, uint g)
3004
        {
3005
            Foo result;
3006
            result.f = f;
3007
            result.g = g;
3008
            return result;
3009
        }
3010
        int operator.h(Foo foo)
3011
        {
3012
            return int((foo.f & 0xffff) | ((foo.g & 0xffff) << 16));
3013
        }
3014
        Foo operator.h=(Foo foo, int value)
3015
        {
3016
            foo.f &= ~0xffffu;
3017
            foo.f |= uint(value) & 0xffff;
3018
            foo.g &= ~0xffffu;
3019
            foo.g |= (uint(value) >> 16) & 0xffff;
3020
            return foo;
3021
        }
3022
        int testLValueEmulation()
3023
        {
3024
            Foo foo;
3025
            foo.f = 42;
3026
            foo.g = 37;
3027
            for (uint i = 0; i < foo.h.length; ++i)
3028
                foo.h[i] ^= true;
3029
            return int(foo.f + foo.g);
3030
        }
3031
        struct Bar {
3032
            Foo a;
3033
            Foo b;
3034
        }
3035
        Foo operator.c(Bar bar)
3036
        {
3037
            return Foo(uint(bar.a.h), uint(bar.b.h));
3038
        }
3039
        Bar operator.c=(Bar bar, Foo foo)
3040
        {
3041
            bar.a.h = int(foo.f);
3042
            bar.b.h = int(foo.g);
3043
            return bar;
3044
        }
3045
        int testCrazyLValueEmulation()
3046
        {
3047
            Bar bar;
3048
            bar.a.f = 1;
3049
            bar.a.g = 2;
3050
            bar.b.f = 3;
3051
            bar.b.g = 4;
3052
            for (uint i = 0; i < bar.c.h.length; i += 2)
3053
                bar.c.h[i] ^= true;
3054
            return int(bar.a.f + bar.a.g + bar.b.f + bar.b.g);
3055
        }
3056
    `);
3057
    checkInt(program, callFunction(program, "testIntSetBit3", [], []), 8);
3058
    checkBool(program, callFunction(program, "testIntSetGetBit5", [], []), true);
3059
    checkBool(program, callFunction(program, "testIntGetBit1", [], []), false);
3060
    checkInt(program, callFunction(program, "testUintSumBits", [], []), 3);
3061
    checkInt(program, callFunction(program, "testUintSwapBits", [], []), 1409286144);
3062
    checkInt(program, callFunction(program, "testLValueEmulation", [], []), 130991);
3063
    checkInt(program, callFunction(program, "testCrazyLValueEmulation", [], []), 43696);
3064
}
3065
3066
tests.nestedSubscriptLValueEmulationSimple = function()
2096
tests.nestedSubscriptLValueEmulationSimple = function()
3067
{
2097
{
3068
    let program = doPrep(`
2098
    let program = doPrep(`
Lines 3167-3283 tests.nestedSubscriptLValueEmulationSimple = function() a/Tools/WebGPUShadingLanguageRI/Test.js_sec21
3167
    checkInt(program, callFunction(program, "testSetValuesMutateValuesAndSum", [], []), 5565);
2197
    checkInt(program, callFunction(program, "testSetValuesMutateValuesAndSum", [], []), 5565);
3168
}
2198
}
3169
2199
3170
tests.nestedSubscriptLValueEmulationGeneric = function()
3171
{
3172
    let program = doPrep(`
3173
        struct Foo<T> {
3174
            T[7] array;
3175
        }
3176
        T operator[]<T>(Foo<T> foo, uint index)
3177
        {
3178
            return foo.array[index];
3179
        }
3180
        Foo<T> operator[]=<T>(Foo<T> foo, uint index, T value)
3181
        {
3182
            foo.array[index] = value;
3183
            return foo;
3184
        }
3185
        uint operator.length<T>(Foo<T> foo)
3186
        {
3187
            return foo.array.length;
3188
        }
3189
        protocol MyAddable {
3190
            MyAddable operator+(MyAddable, MyAddable);
3191
        }
3192
        T sum<T:MyAddable>(Foo<T> foo)
3193
        {
3194
            T result;
3195
            for (uint i = foo.length; i--;)
3196
                result += foo[i];
3197
            return result;
3198
        }
3199
        struct Bar<T> {
3200
            Foo<T>[6] array;
3201
        }
3202
        uint operator.length<T>(Bar<T> bar)
3203
        {
3204
            return bar.array.length;
3205
        }
3206
        Foo<T> operator[]<T>(Bar<T> bar, uint index)
3207
        {
3208
            return bar.array[index];
3209
        }
3210
        Bar<T> operator[]=<T>(Bar<T> bar, uint index, Foo<T> value)
3211
        {
3212
            bar.array[index] = value;
3213
            return bar;
3214
        }
3215
        T sum<T:MyAddable>(Bar<T> bar)
3216
        {
3217
            T result;
3218
            for (uint i = bar.length; i--;)
3219
                result += sum(bar[i]);
3220
            return result;
3221
        }
3222
        struct Baz<T> {
3223
            Bar<T>[5] array;
3224
        }
3225
        Bar<T> operator[]<T>(Baz<T> baz, uint index)
3226
        {
3227
            return baz.array[index];
3228
        }
3229
        Baz<T> operator[]=<T>(Baz<T> baz, uint index, Bar<T> value)
3230
        {
3231
            baz.array[index] = value;
3232
            return baz;
3233
        }
3234
        uint operator.length<T>(Baz<T> baz)
3235
        {
3236
            return baz.array.length;
3237
        }
3238
        T sum<T:MyAddable>(Baz<T> baz)
3239
        {
3240
            T result;
3241
            for (uint i = baz.length; i--;)
3242
                result += sum(baz[i]);
3243
            return result;
3244
        }
3245
        protocol MyConvertibleFromUint {
3246
            operator MyConvertibleFromUint(uint);
3247
        }
3248
        protocol SetValuable : MyAddable, MyConvertibleFromUint { }
3249
        void setValues<T:SetValuable>(thread Baz<T>* baz)
3250
        {
3251
            for (uint i = baz->length; i--;) {
3252
                for (uint j = (*baz)[i].length; j--;) {
3253
                    for (uint k = (*baz)[i][j].length; k--;)
3254
                        (*baz)[i][j][k] = T(i + j + k);
3255
                }
3256
            }
3257
        }
3258
        int testSetValuesAndSum()
3259
        {
3260
            Baz<int> baz;
3261
            setValues(&baz);
3262
            return sum(baz);
3263
        }
3264
        int testSetValuesMutateValuesAndSum()
3265
        {
3266
            Baz<int> baz;
3267
            setValues(&baz);
3268
            for (uint i = baz.length; i--;) {
3269
                for (uint j = baz[i].length; j--;) {
3270
                    for (uint k = baz[i][j].length; k--;)
3271
                        baz[i][j][k] *= int(k);
3272
                }
3273
            }
3274
            return sum(baz);
3275
        }
3276
    `);
3277
    checkInt(program, callFunction(program, "testSetValuesAndSum", [], []), 1575);
3278
    checkInt(program, callFunction(program, "testSetValuesMutateValuesAndSum", [], []), 5565);
3279
}
3280
3281
tests.boolBitAnd = function()
2200
tests.boolBitAnd = function()
3282
{
2201
{
3283
    let program = doPrep(`
2202
    let program = doPrep(`
Lines 3605-3611 tests.floatMath = function() a/Tools/WebGPUShadingLanguageRI/Test.js_sec22
3605
        }
2524
        }
3606
        bool foo5()
2525
        bool foo5()
3607
        {
2526
        {
3608
            return 42.5d == 42.5d;
2527
            return 42.5f == 42.5f;
3609
        }
2528
        }
3610
        float bar(float x)
2529
        float bar(float x)
3611
        {
2530
        {
Lines 3619-3628 tests.floatMath = function() a/Tools/WebGPUShadingLanguageRI/Test.js_sec23
3619
        {
2538
        {
3620
            return bar(7.5f);
2539
            return bar(7.5f);
3621
        }
2540
        }
3622
        float foo8()
3623
        {
3624
            return bar(7.5d);
3625
        }
3626
        float foo9()
2541
        float foo9()
3627
        {
2542
        {
3628
            return float(7.5);
2543
            return float(7.5);
Lines 3631-3654 tests.floatMath = function() a/Tools/WebGPUShadingLanguageRI/Test.js_sec24
3631
        {
2546
        {
3632
            return float(7.5f);
2547
            return float(7.5f);
3633
        }
2548
        }
3634
        float foo11()
3635
        {
3636
            return float(7.5d);
3637
        }
3638
        float foo12()
2549
        float foo12()
3639
        {
2550
        {
3640
            return float(7);
2551
            return float(7);
3641
        }
2552
        }
3642
        float foo13()
2553
        float foo13()
3643
        {
2554
        {
3644
            double x = 7.5d;
2555
            float x = 7.5f;
3645
            return float(x);
2556
            return float(x);
3646
        }
2557
        }
3647
        double foo14()
3648
        {
3649
            double x = 7.5f;
3650
            return double(x);
3651
        }
3652
    `);
2558
    `);
3653
    checkBool(program, callFunction(program, "foo", [], []), true);
2559
    checkBool(program, callFunction(program, "foo", [], []), true);
3654
    checkBool(program, callFunction(program, "foo2", [], []), true);
2560
    checkBool(program, callFunction(program, "foo2", [], []), true);
Lines 3657-3669 tests.floatMath = function() a/Tools/WebGPUShadingLanguageRI/Test.js_sec25
3657
    checkBool(program, callFunction(program, "foo5", [], []), true);
2563
    checkBool(program, callFunction(program, "foo5", [], []), true);
3658
    checkFloat(program, callFunction(program, "foo6", [], []), 7.5);
2564
    checkFloat(program, callFunction(program, "foo6", [], []), 7.5);
3659
    checkFloat(program, callFunction(program, "foo7", [], []), 7.5);
2565
    checkFloat(program, callFunction(program, "foo7", [], []), 7.5);
3660
    checkFloat(program, callFunction(program, "foo8", [], []), 7.5);
3661
    checkFloat(program, callFunction(program, "foo9", [], []), 7.5);
2566
    checkFloat(program, callFunction(program, "foo9", [], []), 7.5);
3662
    checkFloat(program, callFunction(program, "foo10", [], []), 7.5);
2567
    checkFloat(program, callFunction(program, "foo10", [], []), 7.5);
3663
    checkFloat(program, callFunction(program, "foo11", [], []), 7.5);
3664
    checkFloat(program, callFunction(program, "foo12", [], []), 7);
2568
    checkFloat(program, callFunction(program, "foo12", [], []), 7);
3665
    checkFloat(program, callFunction(program, "foo13", [], []), 7.5);
2569
    checkFloat(program, callFunction(program, "foo13", [], []), 7.5);
3666
    checkDouble(program, callFunction(program, "foo14", [], []), 7.5);
3667
    checkFail(
2570
    checkFail(
3668
        () => doPrep(`
2571
        () => doPrep(`
3669
            int bar(int x)
2572
            int bar(int x)
Lines 3684-3690 tests.floatMath = function() a/Tools/WebGPUShadingLanguageRI/Test.js_sec26
3684
            }
2587
            }
3685
            int foo()
2588
            int foo()
3686
            {
2589
            {
3687
                bar(4.d);
2590
                bar(4.f);
3688
            }
2591
            }
3689
        `),
2592
        `),
3690
        (e) => e instanceof WTypeError);
2593
        (e) => e instanceof WTypeError);
Lines 3720-3726 tests.floatMath = function() a/Tools/WebGPUShadingLanguageRI/Test.js_sec27
3720
            }
2623
            }
3721
            int foo()
2624
            int foo()
3722
            {
2625
            {
3723
                bar(4.d);
2626
                bar(4.f);
3724
            }
2627
            }
3725
        `),
2628
        `),
3726
        (e) => e instanceof WTypeError);
2629
        (e) => e instanceof WTypeError);
Lines 3736-3798 tests.floatMath = function() a/Tools/WebGPUShadingLanguageRI/Test.js_sec28
3736
            }
2639
            }
3737
        `),
2640
        `),
3738
        (e) => e instanceof WTypeError);
2641
        (e) => e instanceof WTypeError);
3739
    checkFail(
3740
        () => doPrep(`
3741
            float bar(float x)
3742
            {
3743
                return x;
3744
            }
3745
            void foo()
3746
            {
3747
                bar(16777217.d);
3748
            }
3749
        `),
3750
        (e) => e instanceof WTypeError);
3751
    checkFail(
3752
        () => doPrep(`
3753
            float bar(float x)
3754
            {
3755
                return x;
3756
            }
3757
            float foo()
3758
            {
3759
                double x = 7.;
3760
                return bar(x);
3761
            }
3762
        `),
3763
        (e) => e instanceof WTypeError);
3764
    checkFail(
3765
        () => doPrep(`
3766
            float foo()
3767
            {
3768
                double x = 7.;
3769
                return x;
3770
            }
3771
        `),
3772
        (e) => e instanceof WTypeError);
3773
}
3774
3775
tests.genericCastInfer = function()
3776
{
3777
    let program = doPrep(`
3778
        struct Complex<T> {
3779
            T real;
3780
            T imag;
3781
        }
3782
        operator<T> Complex<T>(T real, T imag)
3783
        {
3784
            Complex<T> result;
3785
            result.real = real;
3786
            result.imag = imag;
3787
            return result;
3788
        }
3789
        int foo()
3790
        {
3791
            Complex<int> x = Complex<int>(1, 2);
3792
            return x.real + x.imag;
3793
        }
3794
    `);
3795
    checkInt(program, callFunction(program, "foo", [], []), 3);
3796
}
2642
}
3797
2643
3798
tests.booleanMath = function()
2644
tests.booleanMath = function()
Lines 4146-4189 tests.builtinVectors = function() a/Tools/WebGPUShadingLanguageRI/Test.js_sec29
4146
            float3 c = float3(3., 4., 6.);
2992
            float3 c = float3(3., 4., 6.);
4147
            return b == c;
2993
            return b == c;
4148
        }
2994
        }
4149
        double food()
4150
        {
4151
            double2 a = double2(3., 4.);
4152
            return a[0];
4153
        }
4154
        double food2()
4155
        {
4156
            double2 a = double2(3., 4.);
4157
            double3 b = double3(a, 5.);
4158
            return b[1];
4159
        }
4160
        double food3()
4161
        {
4162
            double3 a = double3(3., 4., 5.);
4163
            double4 b = double4(6., a);
4164
            return b[1];
4165
        }
4166
        double food4()
4167
        {
4168
            double2 a = double2(3., 4.);
4169
            double2 b = double2(5., 6.);
4170
            double4 c = double4(a, b);
4171
            return c[2];
4172
        }
4173
        bool food5()
4174
        {
4175
            double4 a = double4(3., 4., 5., 6.);
4176
            double2 b = double2(4., 5.);
4177
            double4 c = double4(3., b, 6.);
4178
            return a == c;
4179
        }
4180
        bool food6()
4181
        {
4182
            double2 a = double2(4., 5.);
4183
            double3 b = double3(3., a);
4184
            double3 c = double3(3., 4., 6.);
4185
            return b == c;
4186
        }
4187
    `);
2995
    `);
4188
    checkInt(program, callFunction(program, "foo", [], []), 3);
2996
    checkInt(program, callFunction(program, "foo", [], []), 3);
4189
    checkInt(program, callFunction(program, "foo2", [], []), 4);
2997
    checkInt(program, callFunction(program, "foo2", [], []), 4);
Lines 4203-4251 tests.builtinVectors = function() a/Tools/WebGPUShadingLanguageRI/Test.js_sec30
4203
    checkFloat(program, callFunction(program, "foof4", [], []), 5);
3011
    checkFloat(program, callFunction(program, "foof4", [], []), 5);
4204
    checkBool(program, callFunction(program, "foof5", [], []), true);
3012
    checkBool(program, callFunction(program, "foof5", [], []), true);
4205
    checkBool(program, callFunction(program, "foof6", [], []), false);
3013
    checkBool(program, callFunction(program, "foof6", [], []), false);
4206
    checkDouble(program, callFunction(program, "food", [], []), 3);
4207
    checkDouble(program, callFunction(program, "food2", [], []), 4);
4208
    checkDouble(program, callFunction(program, "food3", [], []), 3);
4209
    checkDouble(program, callFunction(program, "food4", [], []), 5);
4210
    checkBool(program, callFunction(program, "food5", [], []), true);
4211
    checkBool(program, callFunction(program, "food6", [], []), false);
4212
}
3014
}
4213
3015
4214
tests.instantiateStructInStruct = function()
3016
tests.builtinVectorGetters = function()
4215
{
3017
{
4216
    let program = doPrep(`
3018
    const typeNames = [ "uint", "int", "float" ];
4217
        struct Bar<T> {
3019
    const sizes = [ 2, 3, 4 ];
4218
            T x;
3020
    const elements = [ "x", "y", "z", "w" ];
4219
        }
3021
    const initializerList = [ 1, 2, 3, 4 ];
4220
        struct Foo {
3022
4221
            Bar<int> x;
3023
    let tests = [];
4222
        }
3024
    let src = "";
4223
        int foo()
3025
    for (let typeName of typeNames) {
4224
        {
3026
        for (let size of sizes) {
4225
            Foo x;
3027
            for (let i = 0; i < size; i++) {
4226
            x.x.x = 42;
3028
                const functionName = `${typeName}${size}${elements[i]}`;
4227
            x.x.x++;
3029
                src += `${typeName} ${functionName}()
4228
            return x.x.x;
3030
                        {
3031
                            ${typeName}${size} x = ${typeName}${size}(${initializerList.slice(0, size).join(", ")});
3032
                            return x.${elements[i]};
3033
                        }
3034
                        `;
3035
                tests.push({ type: typeName, name: functionName, expectation: initializerList[i] });
3036
            }
4229
        }
3037
        }
4230
    `);
3038
    }
4231
    checkInt(program, callFunction(program, "foo", [], []), 43);
3039
3040
    let program = doPrep(src);
3041
    const checkFuncs = {
3042
        "uint": checkUint,
3043
        "int": checkInt,
3044
        "float": checkFloat
3045
    };
3046
    for (let test of tests) {
3047
        const checkFunc = checkFuncs[test.type];
3048
        checkFunc(program, callFunction(program, test.name, [], []), test.expectation);
3049
    }
4232
}
3050
}
4233
3051
4234
tests.instantiateStructInStructWithInt2 = function()
3052
tests.builtinVectorSetters = function()
4235
{
3053
{
4236
    let program = doPrep(`
3054
    const typeNames = [ "uint", "int", "float" ];
4237
        struct Foo {
3055
    const sizes = [ 2, 3, 4 ];
4238
            int2 x;
3056
    const elements = [ "x", "y", "z", "w" ];
3057
    const initializerList = [ 1, 2, 3, 4 ];
3058
3059
    let tests = [];
3060
    let src = "";
3061
    for (let typeName of typeNames) {
3062
        for (let size of sizes) {
3063
            for (let i = 0; i < size; i++) {
3064
                const functionName = `${typeName}${size}${elements[i]}`;
3065
                src += `${typeName} ${functionName}()
3066
                        {
3067
                            ${typeName}${size} x = ${typeName}${size}(${initializerList.slice(0, size).join(", ")});
3068
                            x.${elements[i]} = 34;
3069
                            return x.${elements[i]};
3070
                        }
3071
                        `;
3072
                tests.push({ type: typeName, name: functionName, expectation: 34 });
3073
            }
4239
        }
3074
        }
4240
        int foo()
3075
    }
4241
        {
3076
4242
            Foo x;
3077
    let program = doPrep(src);
4243
            x.x.x = 42;
3078
    const checkFuncs = {
4244
            x.x.x++;
3079
        "uint": checkUint,
4245
            return x.x.x;
3080
        "int": checkInt,
3081
        "float": checkFloat
3082
    };
3083
    for (let test of tests) {
3084
        const checkFunc = checkFuncs[test.type];
3085
        checkFunc(program, callFunction(program, test.name, [], []), test.expectation);
3086
    }
3087
}
3088
3089
tests.builtinVectorIndexSetters = function()
3090
{
3091
    const typeNames = [ "uint", "int", "float" ];
3092
    const sizes = [ 2, 3, 4 ];
3093
    const elements = [ "x", "y", "z", "w" ];
3094
    const initializerList = [ 1, 2, 3, 4 ];
3095
3096
    let tests = [];
3097
    let src = "";
3098
    for (let typeName of typeNames) {
3099
        for (let size of sizes) {
3100
            for (let i = 0; i < size; i++) {
3101
                const functionName = `${typeName}${size}${elements[i]}`;
3102
                src += `${typeName} ${functionName}()
3103
                        {
3104
                            ${typeName}${size} x = ${typeName}${size}(${initializerList.slice(0, size).join(", ")});
3105
                            x[${i}] = 34;
3106
                            return x[${i}];
3107
                        }
3108
                        `;
3109
                tests.push({ type: typeName, name: functionName, expectation: 34 });
3110
            }
4246
        }
3111
        }
4247
    `);
3112
    }
4248
    checkInt(program, callFunction(program, "foo", [], []), 43);
3113
3114
    let program = doPrep(src);
3115
    const checkFuncs = {
3116
        "uint": checkUint,
3117
        "int": checkInt,
3118
        "float": checkFloat
3119
    };
3120
    for (let test of tests) {
3121
        const checkFunc = checkFuncs[test.type];
3122
        checkFunc(program, callFunction(program, test.name, [], []), test.expectation);
3123
    }
4249
}
3124
}
4250
3125
4251
tests.simpleEnum = function()
3126
tests.simpleEnum = function()
Lines 4490-4528 tests.enumWithSomeManualValues = function() a/Tools/WebGPUShadingLanguageRI/Test.js_sec31
4490
    checkEnum(program, callFunction(program, "death", [], []), 1);
3365
    checkEnum(program, callFunction(program, "death", [], []), 1);
4491
}
3366
}
4492
3367
4493
tests.enumConstexprGenericFunction = function()
4494
{
4495
    let program = doPrep(`
4496
        enum Axis { X, Y }
4497
        int foo<Axis axis>() { return int(axis); }
4498
        int testX() { return foo<Axis.X>(); }
4499
        int testY() { return foo<Axis.Y>(); }
4500
    `);
4501
    checkInt(program, callFunction(program, "testX", [], []), 0);
4502
    checkInt(program, callFunction(program, "testY", [], []), 1);
4503
}
4504
4505
tests.enumConstexprGenericStruct = function()
4506
{
4507
    let program = doPrep(`
4508
        enum Axis { X, Y }
4509
        struct Foo<Axis axis> { }
4510
        int foo<Axis axis>(Foo<axis>) { return int(axis); }
4511
        int testX()
4512
        {   
4513
            Foo<Axis.X> f;
4514
            return foo(f);
4515
        }
4516
        int testY()
4517
        {   
4518
            Foo<Axis.Y> f;
4519
            return foo(f);
4520
        }
4521
    `);
4522
    checkInt(program, callFunction(program, "testX", [], []), 0);
4523
    checkInt(program, callFunction(program, "testY", [], []), 1);
4524
}
4525
4526
tests.trap = function()
3368
tests.trap = function()
4527
{
3369
{
4528
    let program = doPrep(`
3370
    let program = doPrep(`
Lines 4971-4988 tests.simpleSwitch = function() a/Tools/WebGPUShadingLanguageRI/Test.js_sec32
4971
3813
4972
tests.exhaustiveUint8Switch = function()
3814
tests.exhaustiveUint8Switch = function()
4973
{
3815
{
4974
    let text = "double foo(uint8 x) { switch (uint8(x)) {"
3816
    let text = "float foo(uint8 x) { switch (uint8(x)) {"
4975
    for (let i = 0; i <= 0xff; ++i)
3817
    for (let i = 0; i <= 0xff; ++i)
4976
        text += "case " + i + ": return " + i * 1.5 + ";";
3818
        text += "case " + i + ": return " + i * 1.5 + ";";
4977
    text += "} }";
3819
    text += "} }";
4978
    let program = doPrep(text);
3820
    let program = doPrep(text);
4979
    for (let i = 0; i < 0xff; ++i)
3821
    for (let i = 0; i < 0xff; ++i)
4980
        checkDouble(program, callFunction(program, "foo", [], [makeUint8(program, i)]), i * 1.5);
3822
        checkFloat(program, callFunction(program, "foo", [], [makeUint8(program, i)]), i * 1.5);
4981
}
3823
}
4982
3824
4983
tests.notQuiteExhaustiveUint8Switch = function()
3825
tests.notQuiteExhaustiveUint8Switch = function()
4984
{
3826
{
4985
    let text = "double foo(uint8 x) { switch (uint8(x)) {"
3827
    let text = "float foo(uint8 x) { switch (uint8(x)) {"
4986
    for (let i = 0; i <= 0xfe; ++i)
3828
    for (let i = 0; i <= 0xfe; ++i)
4987
        text += "case " + i + ": return " + i * 1.5 + ";";
3829
        text += "case " + i + ": return " + i * 1.5 + ";";
4988
    text += "} }";
3830
    text += "} }";
Lines 4991-5004 tests.notQuiteExhaustiveUint8Switch = function() a/Tools/WebGPUShadingLanguageRI/Test.js_sec33
4991
3833
4992
tests.notQuiteExhaustiveUint8SwitchWithDefault = function()
3834
tests.notQuiteExhaustiveUint8SwitchWithDefault = function()
4993
{
3835
{
4994
    let text = "double foo(uint8 x) { switch (uint8(x)) {"
3836
    let text = "float foo(uint8 x) { switch (uint8(x)) {"
4995
    for (let i = 0; i <= 0xfe; ++i)
3837
    for (let i = 0; i <= 0xfe; ++i)
4996
        text += "case " + i + ": return " + i * 1.5 + ";";
3838
        text += "case " + i + ": return " + i * 1.5 + ";";
4997
    text += "default: return " + 0xff * 1.5 + ";";
3839
    text += "default: return " + 0xff * 1.5 + ";";
4998
    text += "} }";
3840
    text += "} }";
4999
    let program = doPrep(text);
3841
    let program = doPrep(text);
5000
    for (let i = 0; i < 0xff; ++i)
3842
    for (let i = 0; i < 0xff; ++i)
5001
        checkDouble(program, callFunction(program, "foo", [], [makeUint8(program, i)]), i * 1.5);
3843
        checkFloat(program, callFunction(program, "foo", [], [makeUint8(program, i)]), i * 1.5);
5002
}
3844
}
5003
3845
5004
tests.switchFallThrough = function()
3846
tests.switchFallThrough = function()
Lines 5327-5333 tests.setterWithMismatchedType = function() a/Tools/WebGPUShadingLanguageRI/Test.js_sec34
5327
{
4169
{
5328
    checkFail(
4170
    checkFail(
5329
        () => doPrep(`
4171
        () => doPrep(`
5330
            double operator.foo(int)
4172
            float operator.foo(int)
5331
            {
4173
            {
5332
                return 5.43;
4174
                return 5.43;
5333
            }
4175
            }
Lines 5353-5375 tests.setterWithMatchedType = function() a/Tools/WebGPUShadingLanguageRI/Test.js_sec35
5353
    `);
4195
    `);
5354
}
4196
}
5355
4197
5356
tests.operatorWithUninferrableTypeVariable = function()
5357
{
5358
    checkFail(
5359
        () => doPrep(`
5360
            struct Foo {
5361
                int x;
5362
            }
5363
            Foo operator+<T>(Foo a, Foo b)
5364
            {
5365
                Foo result;
5366
                result.x = a.x + b.x;
5367
                return result;
5368
            }
5369
        `),
5370
        e => e instanceof WTypeError);
5371
}
5372
5373
tests.operatorWithoutUninferrableTypeVariable = function()
4198
tests.operatorWithoutUninferrableTypeVariable = function()
5374
{
4199
{
5375
    let program = doPrep(`
4200
    let program = doPrep(`
Lines 5394-5446 tests.operatorWithoutUninferrableTypeVariable = function() a/Tools/WebGPUShadingLanguageRI/Test.js_sec36
5394
    checkInt(program, callFunction(program, "foo", [], []), 645 - 35);
4219
    checkInt(program, callFunction(program, "foo", [], []), 645 - 35);
5395
}
4220
}
5396
4221
5397
tests.operatorCastWithUninferrableTypeVariable = function()
5398
{
5399
    checkFail(
5400
        () => doPrep(`
5401
            struct Foo {
5402
                int x;
5403
            }
5404
            operator<T> Foo(int x)
5405
            {
5406
                Foo result;
5407
                result.x = x;
5408
                return result;
5409
            }
5410
        `),
5411
        e => e instanceof WTypeError);
5412
}
5413
5414
tests.operatorCastWithTypeVariableInferredFromReturnType = function()
5415
{
5416
    let program = doPrep(`
5417
        struct Foo {
5418
            int x;
5419
        }
5420
        protocol Barable {
5421
            void bar(thread Barable*, int);
5422
        }
5423
        void bar(thread double* result, int value)
5424
        {
5425
            *result = double(value);
5426
        }
5427
        operator<T:Barable> T(Foo foo)
5428
        {
5429
            T result;
5430
            bar(&result, foo.x);
5431
            return result;
5432
        }
5433
        int foo()
5434
        {
5435
            Foo foo;
5436
            foo.x = 75;
5437
            double x = double(foo);
5438
            return int(x * 1.5);
5439
        }
5440
    `);
5441
    checkInt(program, callFunction(program, "foo", [], []), 112);
5442
}
5443
5444
tests.incWrongArgumentLength = function()
4222
tests.incWrongArgumentLength = function()
5445
{
4223
{
5446
    checkFail(
4224
    checkFail(
Lines 5473-5479 tests.incWrongTypes = function() a/Tools/WebGPUShadingLanguageRI/Test.js_sec37
5473
{
4251
{
5474
    checkFail(
4252
    checkFail(
5475
        () => doPrep(`
4253
        () => doPrep(`
5476
            int operator++(double) { return 32; }
4254
            int operator++(float) { return 32; }
5477
        `),
4255
        `),
5478
        e => e instanceof WTypeError);
4256
        e => e instanceof WTypeError);
5479
}
4257
}
Lines 5482-5488 tests.decWrongTypes = function() a/Tools/WebGPUShadingLanguageRI/Test.js_sec38
5482
{
4260
{
5483
    checkFail(
4261
    checkFail(
5484
        () => doPrep(`
4262
        () => doPrep(`
5485
            int operator--(double) { return 32; }
4263
            int operator--(float) { return 32; }
5486
        `),
4264
        `),
5487
        e => e instanceof WTypeError);
4265
        e => e instanceof WTypeError);
5488
}
4266
}
Lines 6007-6012 tests.anderWithArrayRef = function() a/Tools/WebGPUShadingLanguageRI/Test.js_sec39
6007
    checkInt(program, callFunction(program, "foo", [], []), 13);
4785
    checkInt(program, callFunction(program, "foo", [], []), 13);
6008
}
4786
}
6009
4787
4788
tests.anderWithBadIndex = function()
4789
{
4790
    checkFail(() => doPrep(`
4791
        int foo(thread int[] x) { return x[-1]; }
4792
    `), e => e instanceof Error);
4793
4794
    checkFail(() => doPrep(`
4795
        int foo(thread int[] x) { return x[1.f]; }
4796
    `), e => e instanceof Error);
4797
4798
    checkFail(() => doPrep(`
4799
        int foo(thread int[] x, int y) { return x[y]; }
4800
    `), e => e instanceof Error);
4801
4802
    checkFail(() => doPrep(`
4803
        int foo(thread int[] x, float y) { return x[y]; }
4804
    `), e => e instanceof Error);
4805
}
4806
6010
tests.pointerIndexGetter = function()
4807
tests.pointerIndexGetter = function()
6011
{
4808
{
6012
    checkFail(
4809
    checkFail(
Lines 6073-6079 tests.indexSetterWithMismatchedType = function() a/Tools/WebGPUShadingLanguageRI/Test.js_sec40
6073
{
4870
{
6074
    checkFail(
4871
    checkFail(
6075
        () => doPrep(`
4872
        () => doPrep(`
6076
            double operator[](int, uint)
4873
            float operator[](int, uint)
6077
            {
4874
            {
6078
                return 5.43;
4875
                return 5.43;
6079
            }
4876
            }
Lines 6264-6270 tests.indexAnderWithArrayRef = function() a/Tools/WebGPUShadingLanguageRI/Test.js_sec41
6264
        struct Foo {
5061
        struct Foo {
6265
            int x;
5062
            int x;
6266
        }
5063
        }
6267
        thread int* operator&[](thread Foo[] array, double index)
5064
        thread int* operator&[](thread Foo[] array, float index)
6268
        {
5065
        {
6269
            return &array[uint(index + 1)].x;
5066
            return &array[uint(index + 1)].x;
6270
        }
5067
        }
Lines 6272-6278 tests.indexAnderWithArrayRef = function() a/Tools/WebGPUShadingLanguageRI/Test.js_sec42
6272
        {
5069
        {
6273
            Foo x;
5070
            Foo x;
6274
            x.x = 13;
5071
            x.x = 13;
6275
            return (@x)[double(-1)];
5072
            return (@x)[float(-1)];
6276
        }
5073
        }
6277
    `);
5074
    `);
6278
    checkInt(program, callFunction(program, "foo", [], []), 13);
5075
    checkInt(program, callFunction(program, "foo", [], []), 13);
Lines 6314-6619 tests.constantPtrPtr = function() a/Tools/WebGPUShadingLanguageRI/Test.js_sec43
6314
        e => e instanceof WTypeError && e.message.indexOf("Illegal pointer to non-primitive type: int32* constant* constant") != -1);
5111
        e => e instanceof WTypeError && e.message.indexOf("Illegal pointer to non-primitive type: int32* constant* constant") != -1);
6315
}
5112
}
6316
5113
6317
tests.pointerIndexGetterInProtocol = function()
6318
{
6319
    for (let addressSpace of addressSpaces) {
6320
        checkFail(
6321
            () => doPrep(`
6322
                protocol Foo {
6323
                    int operator[](${addressSpace} Foo*, uint);
6324
                }
6325
                struct Bar { }
6326
                int operator[](Bar, uint) { return 42; }
6327
            `),
6328
            e => e instanceof WTypeError && e.message.indexOf("Cannot have getter for pointer type") != -1);
6329
    }
6330
}
6331
6332
tests.loneIndexSetterInProtocol = function()
6333
{
6334
    checkFail(
6335
        () => doPrep(`
6336
            protocol Foo {
6337
                Foo operator[]=(Foo, uint, int);
6338
            }
6339
            struct Bar { }
6340
            int operator[](Bar, uint) { return 42; }
6341
            Bar operator[]=(Bar, uint, int) { return Bar(); }
6342
        `),
6343
        e => e instanceof WTypeError && e.message.indexOf("Every setter must have a matching getter") != -1);
6344
}
6345
6346
tests.notLoneIndexSetterInProtocol = function()
6347
{
6348
    doPrep(`
6349
        protocol Foo {
6350
            int operator[](Foo, uint);
6351
            Foo operator[]=(Foo, uint, int);
6352
        }
6353
        struct Bar { }
6354
        int operator[](Bar, uint) { return 42; }
6355
        Bar operator[]=(Bar, uint, int) { return Bar(); }
6356
    `);
6357
}
6358
6359
tests.indexSetterWithMismatchedTypeInProtocol = function()
6360
{
6361
    checkFail(
6362
        () => doPrep(`
6363
            protocol Foo {
6364
                double operator[](Foo, uint);
6365
                Foo operator[]=(Foo, uint, int);
6366
            }
6367
            struct Bar { }
6368
            int operator[](Bar, uint) { return 42; }
6369
            Bar operator[]=(Bar, uint, int) { return Bar(); }
6370
        `),
6371
        e => e instanceof WTypeError && e.message.indexOf("Setter and getter must agree on value type") != -1);
6372
}
6373
6374
tests.indexOperatorWrongArgumentLengthInProtocol = function()
6375
{
6376
    checkFail(
6377
        () => doPrep(`
6378
            protocol Foo {
6379
                int operator[]();
6380
            }
6381
            struct Bar { }
6382
            int operator[](Bar, uint) { return 42; }
6383
        `),
6384
        e => e instanceof WTypeError && e.message.indexOf("Protocol's type variable (Foo) not mentioned in signature") != -1);
6385
    checkFail(
6386
        () => doPrep(`
6387
            protocol Foo {
6388
                int operator[](Foo);
6389
            }
6390
            struct Bar { }
6391
            int operator[](Bar, uint) { return 42; }
6392
        `),
6393
        e => e instanceof WTypeError && e.message.indexOf("Incorrect number of parameters") != -1);
6394
    checkFail(
6395
        () => doPrep(`
6396
            protocol Foo {
6397
                int operator[](Foo, int, int);
6398
            }
6399
            struct Bar { }
6400
            int operator[](Bar, uint) { return 42; }
6401
        `),
6402
        e => e instanceof WTypeError && e.message.indexOf("Incorrect number of parameters") != -1);
6403
}
6404
6405
tests.indexOperatorSetterWrongArgumentLengthInProtocol = function()
6406
{
6407
    checkFail(
6408
        () => doPrep(`
6409
            protocol Foo {
6410
                int operator[]=();
6411
            }
6412
            struct Bar { }
6413
            int operator[](Bar, uint) { return 42; }
6414
            Bar operator[]=(Bar, uint, int) { return Bar(); }
6415
        `),
6416
        e => e instanceof WTypeError && e.message.indexOf("Protocol's type variable (Foo) not mentioned in signature") != -1);
6417
    checkFail(
6418
        () => doPrep(`
6419
            protocol Foo {
6420
                int operator[]=(Foo);
6421
            }
6422
            struct Bar { }
6423
            int operator[](Bar, uint) { return 42; }
6424
            Bar operator[]=(Bar, uint, int) { return Bar(); }
6425
        `),
6426
        e => e instanceof WTypeError && e.message.indexOf("Incorrect number of parameters") != -1);
6427
    checkFail(
6428
        () => doPrep(`
6429
            protocol Foo {
6430
                int operator[]=(Foo, int);
6431
            }
6432
            struct Bar { }
6433
            int operator[](Bar, uint) { return 42; }
6434
            Bar operator[]=(Bar, uint, int) { return Bar(); }
6435
        `),
6436
        e => e instanceof WTypeError && e.message.indexOf("Incorrect number of parameters") != -1);
6437
    checkFail(
6438
        () => doPrep(`
6439
            protocol Foo {
6440
                int operator[]=(Foo, int, int, int);
6441
            }
6442
            struct Bar { }
6443
            int operator[](Bar, uint) { return 42; }
6444
            Bar operator[]=(Bar, uint, int) { return Bar(); }
6445
        `),
6446
        e => e instanceof WTypeError && e.message.indexOf("Incorrect number of parameters") != -1);
6447
}
6448
6449
tests.loneIndexSetterPointerInProtocol = function()
6450
{
6451
    checkFail(
6452
        () => doPrep(`
6453
            protocol Foo {
6454
                thread int* operator[]=(thread Foo* ptr, uint, int);
6455
            }
6456
            struct Bar { }
6457
            int operator[](Bar, uint) { return 42; }
6458
            Bar operator[]=(Bar, uint, int) { return Bar(); }
6459
        `),
6460
        e => e instanceof WTypeError && e.message.indexOf("Cannot have setter for pointer type") != -1);
6461
}
6462
6463
tests.indexSetterWithNoGetterOverloadInProtocol = function()
6464
{
6465
    checkFail(
6466
        () => doPrep(`
6467
            protocol Foo {
6468
                int operator[](int, Foo);
6469
                Foo operator[]=(Foo, uint, int);
6470
            }
6471
            struct Bar { }
6472
            int operator[](Bar, uint) { return 42; }
6473
            Bar operator[]=(Bar, uint, int) { return Bar(); }
6474
        `),
6475
        e => e instanceof WTypeError && e.message.indexOf("Did not find function named operator[]= with arguments Foo,uint32") != -1);
6476
}
6477
6478
tests.indexSetterWithNoGetterOverloadFixedInProtocol = function()
6479
{
6480
    doPrep(`
6481
        protocol Foo {
6482
            int operator[](Foo, uint);
6483
            Foo operator[]=(Foo, uint, int);
6484
        }
6485
        struct Bar { }
6486
        int operator[](Bar, uint) { return 42; }
6487
        Bar operator[]=(Bar, uint, int) { return Bar(); }
6488
    `);
6489
}
6490
6491
tests.indexAnderWithNothingWrongInProtocol = function()
6492
{
6493
    let program = doPrep(`
6494
        protocol Foo {
6495
            thread int* operator&[](thread Foo* foo, uint);
6496
        }
6497
        int bar<T:Foo>(T x)
6498
        {
6499
            return x[42];
6500
        }
6501
        struct Bar { }
6502
        thread int* operator&[](thread Bar*, uint)
6503
        {
6504
            int result = 1234;
6505
            return &result;
6506
        }
6507
        int foo()
6508
        {
6509
            return bar(Bar());
6510
        }
6511
    `);
6512
    checkInt(program, callFunction(program, "foo", [], []), 1234);
6513
}
6514
6515
tests.indexAnderWithWrongNumberOfArgumentsInProtocol = function()
6516
{
6517
    checkFail(
6518
        () => doPrep(`
6519
            protocol Foo {
6520
                thread int* operator&[]();
6521
            }
6522
            struct Bar { }
6523
            thread int* operator&[](thread Bar*, uint)
6524
            {
6525
                int result = 1234;
6526
                return &result;
6527
            }
6528
        `),
6529
        e => e instanceof WTypeError && e.message.indexOf("Protocol's type variable (Foo) not mentioned in signature") != -1);
6530
    checkFail(
6531
        () => doPrep(`
6532
            protocol Foo {
6533
                thread int* operator&[](thread Foo* foo);
6534
            }
6535
            struct Bar { }
6536
            thread int* operator&[](thread Bar*, uint)
6537
            {
6538
                int result = 1234;
6539
                return &result;
6540
            }
6541
        `),
6542
        e => e instanceof WTypeError && e.message.indexOf("Incorrect number of parameters for operator&[]") != -1);
6543
    checkFail(
6544
        () => doPrep(`
6545
            protocol Foo {
6546
                thread int* operator&[](thread Foo* foo, uint, uint);
6547
            }
6548
            struct Bar { }
6549
            thread int* operator&[](thread Bar*, uint)
6550
            {
6551
                int result = 1234;
6552
                return &result;
6553
            }
6554
        `),
6555
        e => e instanceof WTypeError && e.message.indexOf("Incorrect number of parameters for operator&[]") != -1);
6556
}
6557
6558
tests.indexAnderDoesntReturnPointerInProtocol = function()
6559
{
6560
    checkFail(
6561
        () => doPrep(`
6562
            protocol Foo {
6563
                int operator&[](thread Foo* foo, uint);
6564
            }
6565
            struct Bar { }
6566
            thread int* operator&[](thread Bar*, uint)
6567
            {
6568
                int result = 1234;
6569
                return &result;
6570
            }
6571
        `),
6572
        e => e instanceof WTypeError && e.message.indexOf("Return type of ander is not a pointer") != -1);
6573
}
6574
6575
tests.indexAnderDoesntTakeReferenceInProtocol = function()
6576
{
6577
    checkFail(
6578
        () => doPrep(`
6579
            protocol Foo {
6580
                thread int* operator&[](Foo foo, uint);
6581
            }
6582
            struct Bar { }
6583
            thread int* operator&[](thread Bar*, uint)
6584
            {
6585
                int result = 1234;
6586
                return &result;
6587
            }
6588
        `),
6589
        e => e instanceof WTypeError && e.message.indexOf("Parameter to ander is not a reference") != -1);
6590
}
6591
6592
tests.indexAnderWithArrayRefInProtocol = function()
6593
{
6594
    let program = doPrep(`
6595
        protocol Foo {
6596
            thread int* operator&[](thread Foo[] array, double index);
6597
        }
6598
        int bar<T:Foo>(thread T[] x)
6599
        {
6600
            return x[1.5];
6601
        }
6602
        struct Bar { }
6603
        thread int* operator&[](thread Bar[], double)
6604
        {
6605
            int result = 1234;
6606
            return &result;
6607
        }
6608
        int foo()
6609
        {
6610
            Bar x;
6611
            return bar(@x);
6612
        }
6613
    `);
6614
    checkInt(program, callFunction(program, "foo", [], []), 1234);
6615
}
6616
6617
tests.andReturnedArrayRef = function()
5114
tests.andReturnedArrayRef = function()
6618
{
5115
{
6619
    let program = doPrep(`
5116
    let program = doPrep(`
- a/Tools/WebGPUShadingLanguageRI/Type.js +1 lines
Lines 36-41 class Type extends Node { a/Tools/WebGPUShadingLanguageRI/Type.js_sec1
36
    get isFloating() { return false; }
36
    get isFloating() { return false; }
37
    get isEnum() { return false; }
37
    get isEnum() { return false; }
38
    get isPrimitive() { return false; }
38
    get isPrimitive() { return false; }
39
    get isStruct() { return false; }
39
    
40
    
40
    inherits(protocol)
41
    inherits(protocol)
41
    {
42
    {
- a/Tools/WebGPUShadingLanguageRI/TypeDef.js -1 / +1 lines
Lines 41-47 class TypeDef extends Type { a/Tools/WebGPUShadingLanguageRI/TypeDef.js_sec1
41
    
41
    
42
    toString()
42
    toString()
43
    {
43
    {
44
        return "typedef " + this.name + "<" + this.typeParameters + "> = " + this.type;
44
        return `typedef ${this.name} = ${this.type}`;
45
    }
45
    }
46
}
46
}
47
47
- a/Tools/WebGPUShadingLanguageRI/TypeRef.js -3 / +1 lines
Lines 109-117 class TypeRef extends Type { a/Tools/WebGPUShadingLanguageRI/TypeRef.js_sec1
109
    {
109
    {
110
        if (!this.name)
110
        if (!this.name)
111
            return this.type.toString();
111
            return this.type.toString();
112
        if (!this.typeArguments.length)
112
        return this.name;
113
            return this.name;
114
        return this.name + "<" + this.typeArguments + ">";
115
    }
113
    }
116
}
114
}
117
115
- a/Tools/WebGPUShadingLanguageRI/index.html -149 / +160 lines
Lines 1-155 a/Tools/WebGPUShadingLanguageRI/index.html_sec1
1
<!DOCTYPE html>
1
<!DOCTYPE html>
2
<html>
2
<html>
3
<head>
3
<head>
4
<script src="Node.js"></script>
4
    <script src="Node.js"></script>
5
<script src="Type.js"></script>
5
    <script src="Type.js"></script>
6
<script src="ReferenceType.js"></script>
6
    <script src="ReferenceType.js"></script>
7
<script src="Value.js"></script>
7
    <script src="Value.js"></script>
8
<script src="Expression.js"></script>
8
    <script src="Expression.js"></script>
9
<script src="Rewriter.js"></script>
9
    <script src="Rewriter.js"></script>
10
<script src="Visitor.js"></script>
10
    <script src="Visitor.js"></script>
11
<script src="CreateLiteral.js"></script>
11
    <script src="CreateLiteral.js"></script>
12
<script src="CreateLiteralType.js"></script>
12
    <script src="CreateLiteralType.js"></script>
13
<script src="PropertyAccessExpression.js"></script>
13
    <script src="PropertyAccessExpression.js"></script>
14
<script src="SwizzleOp.js"></script>
14
    <script src="SwizzleOp.js"></script>
15
15
    
16
<script src="AddressSpace.js"></script>
16
    <script src="AddressSpace.js"></script>
17
<script src="AnonymousVariable.js"></script>
17
    <script src="AnonymousVariable.js"></script>
18
<script src="ArrayRefType.js"></script>
18
    <script src="ArrayRefType.js"></script>
19
<script src="ArrayType.js"></script>
19
    <script src="ArrayType.js"></script>
20
<script src="Assignment.js"></script>
20
    <script src="Assignment.js"></script>
21
<script src="AutoWrapper.js"></script>
21
    <script src="AutoWrapper.js"></script>
22
<script src="Block.js"></script>
22
    <script src="Block.js"></script>
23
<script src="BoolLiteral.js"></script>
23
    <script src="BoolLiteral.js"></script>
24
<script src="Break.js"></script>
24
    <script src="Break.js"></script>
25
<script src="CallExpression.js"></script>
25
    <script src="CallExpression.js"></script>
26
<script src="CallFunction.js"></script>
26
    <script src="CallFunction.js"></script>
27
<script src="Check.js"></script>
27
    <script src="Check.js"></script>
28
<script src="CheckLiteralTypes.js"></script>
28
    <script src="CheckLiteralTypes.js"></script>
29
<script src="CheckLoops.js"></script>
29
    <script src="CheckLoops.js"></script>
30
<script src="CheckRecursion.js"></script>
30
    <script src="CheckRecursion.js"></script>
31
<script src="CheckRecursiveTypes.js"></script>
31
    <script src="CheckRecursiveTypes.js"></script>
32
<script src="CheckReturns.js"></script>
32
    <script src="CheckReturns.js"></script>
33
<script src="CheckUnreachableCode.js"></script>
33
    <script src="CheckUnreachableCode.js"></script>
34
<script src="CheckWrapped.js"></script>
34
    <script src="CheckWrapped.js"></script>
35
<script src="Checker.js"></script>
35
    <script src="Checker.js"></script>
36
<script src="CloneProgram.js"></script>
36
    <script src="CloneProgram.js"></script>
37
<script src="CommaExpression.js"></script>
37
    <script src="CommaExpression.js"></script>
38
<script src="ConstexprFolder.js"></script>
38
    <script src="ConstexprFolder.js"></script>
39
<script src="ConstexprTypeParameter.js"></script>
39
    <script src="ConstexprTypeParameter.js"></script>
40
<script src="Continue.js"></script>
40
    <script src="Continue.js"></script>
41
<script src="ConvertPtrToArrayRefExpression.js"></script>
41
    <script src="ConvertPtrToArrayRefExpression.js"></script>
42
<script src="DoWhileLoop.js"></script>
42
    <script src="DoWhileLoop.js"></script>
43
<script src="DotExpression.js"></script>
43
    <script src="DotExpression.js"></script>
44
<script src="DoubleLiteral.js"></script>
44
    <script src="DereferenceExpression.js"></script>
45
<script src="DoubleLiteralType.js"></script>
45
    <script src="EArrayRef.js"></script>
46
<script src="DereferenceExpression.js"></script>
46
    <script src="EBuffer.js"></script>
47
<script src="EArrayRef.js"></script>
47
    <script src="EBufferBuilder.js"></script>
48
<script src="EBuffer.js"></script>
48
    <script src="EPtr.js"></script>
49
<script src="EBufferBuilder.js"></script>
49
    <script src="EnumLiteral.js"></script>
50
<script src="EPtr.js"></script>
50
    <script src="EnumMember.js"></script>
51
<script src="EnumLiteral.js"></script>
51
    <script src="EnumType.js"></script>
52
<script src="EnumMember.js"></script>
52
    <script src="EvaluationCommon.js"></script>
53
<script src="EnumType.js"></script>
53
    <script src="Evaluator.js"></script>
54
<script src="EvaluationCommon.js"></script>
54
    <script src="ExpressionFinder.js"></script>
55
<script src="Evaluator.js"></script>
55
    <script src="ExternalOrigin.js"></script>
56
<script src="ExpressionFinder.js"></script>
56
    <script src="Field.js"></script>
57
<script src="ExternalOrigin.js"></script>
57
    <script src="FindHighZombies.js"></script>
58
<script src="Field.js"></script>
58
    <script src="FlattenProtocolExtends.js"></script>
59
<script src="FindHighZombies.js"></script>
59
    <script src="FlattenedStructOffsetGatherer.js"></script>
60
<script src="FlattenProtocolExtends.js"></script>
60
    <script src="FloatLiteral.js"></script>
61
<script src="FlattenedStructOffsetGatherer.js"></script>
61
    <script src="FloatLiteralType.js"></script>
62
<script src="FloatLiteral.js"></script>
62
    <script src="FoldConstexprs.js"></script>
63
<script src="FloatLiteralType.js"></script>
63
    <script src="ForLoop.js"></script>
64
<script src="FoldConstexprs.js"></script>
64
    <script src="Func.js"></script>
65
<script src="ForLoop.js"></script>
65
    <script src="FuncDef.js"></script>
66
<script src="Func.js"></script>
66
    <script src="FuncInstantiator.js"></script>
67
<script src="FuncDef.js"></script>
67
    <script src="FuncParameter.js"></script>
68
<script src="FuncInstantiator.js"></script>
68
    <script src="FunctionLikeBlock.js"></script>
69
<script src="FuncParameter.js"></script>
69
    <script src="HighZombieFinder.js"></script>
70
<script src="FunctionLikeBlock.js"></script>
70
    <script src="IdentityExpression.js"></script>
71
<script src="HighZombieFinder.js"></script>
71
    <script src="IfStatement.js"></script>
72
<script src="IdentityExpression.js"></script>
72
    <script src="IndexExpression.js"></script>
73
<script src="IfStatement.js"></script>
73
    <script src="InferTypesForCall.js"></script>
74
<script src="IndexExpression.js"></script>
74
    <script src="Inline.js"></script>
75
<script src="InferTypesForCall.js"></script>
75
    <script src="Inliner.js"></script>
76
<script src="Inline.js"></script>
76
    <script src="InstantiateImmediates.js"></script>
77
<script src="Inliner.js"></script>
77
    <script src="IntLiteral.js"></script>
78
<script src="InstantiateImmediates.js"></script>
78
    <script src="IntLiteralType.js"></script>
79
<script src="IntLiteral.js"></script>
79
    <script src="Intrinsics.js"></script>
80
<script src="IntLiteralType.js"></script>
80
    <script src="LateChecker.js"></script>
81
<script src="Intrinsics.js"></script>
81
    <script src="Lexer.js"></script>
82
<script src="LateChecker.js"></script>
82
    <script src="LexerToken.js"></script>
83
<script src="Lexer.js"></script>
83
    <script src="LiteralTypeChecker.js"></script>
84
<script src="LexerToken.js"></script>
84
    <script src="LogicalExpression.js"></script>
85
<script src="LiteralTypeChecker.js"></script>
85
    <script src="LogicalNot.js"></script>
86
<script src="LogicalExpression.js"></script>
86
    <script src="LoopChecker.js"></script>
87
<script src="LogicalNot.js"></script>
87
    <script src="MakeArrayRefExpression.js"></script>
88
<script src="LoopChecker.js"></script>
88
    <script src="MakePtrExpression.js"></script>
89
<script src="MakeArrayRefExpression.js"></script>
89
    <script src="NameContext.js"></script>
90
<script src="MakePtrExpression.js"></script>
90
    <script src="NameFinder.js"></script>
91
<script src="NameContext.js"></script>
91
    <script src="NameResolver.js"></script>
92
<script src="NameFinder.js"></script>
92
    <script src="NativeFunc.js"></script>
93
<script src="NameResolver.js"></script>
93
    <script src="NativeFuncInstance.js"></script>
94
<script src="NativeFunc.js"></script>
94
    <script src="NativeType.js"></script>
95
<script src="NativeFuncInstance.js"></script>
95
    <script src="NativeTypeInstance.js"></script>
96
<script src="NativeType.js"></script>
96
    <script src="NormalUsePropertyResolver.js"></script>
97
<script src="NativeTypeInstance.js"></script>
97
    <script src="NullLiteral.js"></script>
98
<script src="NormalUsePropertyResolver.js"></script>
98
    <script src="NullType.js"></script>
99
<script src="NullLiteral.js"></script>
99
    <script src="OperatorAnderIndex.js"></script>
100
<script src="NullType.js"></script>
100
    <script src="OperatorArrayRefLength.js"></script>
101
<script src="OriginKind.js"></script>
101
    <script src="OperatorBool.js"></script>
102
<script src="OverloadResolutionFailure.js"></script>
102
    <script src="BuiltinVectorCasts.js"></script>
103
<script src="Parse.js"></script>
103
    <script src="BuiltinVectorGetter.js"></script>
104
<script src="Prepare.js"></script>
104
    <script src="BuiltinVectorSetter.js"></script>
105
<script src="PropertyResolver.js"></script>
105
    <script src="BuiltinVectorIndexGetter.js"></script>
106
<script src="Program.js"></script>
106
    <script src="BuiltinVectorIndexSetter.js"></script>
107
<script src="ProgramWithUnnecessaryThingsRemoved.js"></script>
107
    <script src="BuiltinVectorEqualityOperator.js"></script>
108
<script src="Protocol.js"></script>
108
    <script src="OriginKind.js"></script>
109
<script src="ProtocolDecl.js"></script>
109
    <script src="OverloadResolutionFailure.js"></script>
110
<script src="ProtocolFuncDecl.js"></script>
110
    <script src="Parse.js"></script>
111
<script src="ProtocolRef.js"></script>
111
    <script src="Prepare.js"></script>
112
<script src="PtrType.js"></script>
112
    <script src="PropertyResolver.js"></script>
113
<script src="ReadModifyWriteExpression.js"></script>
113
    <script src="Program.js"></script>
114
<script src="RecursionChecker.js"></script>
114
    <script src="ProgramWithUnnecessaryThingsRemoved.js"></script>
115
<script src="RecursiveTypeChecker.js"></script>
115
    <script src="Protocol.js"></script>
116
<script src="ResolveNames.js"></script>
116
    <script src="ProtocolDecl.js"></script>
117
<script src="ResolveOverloadImpl.js"></script>
117
    <script src="ProtocolFuncDecl.js"></script>
118
<script src="ResolveProperties.js"></script>
118
    <script src="ProtocolRef.js"></script>
119
<script src="ResolveTypeDefs.js"></script>
119
    <script src="PtrType.js"></script>
120
<script src="Return.js"></script>
120
    <script src="ReadModifyWriteExpression.js"></script>
121
<script src="ReturnChecker.js"></script>
121
    <script src="RecursionChecker.js"></script>
122
<script src="ReturnException.js"></script>
122
    <script src="RecursiveTypeChecker.js"></script>
123
<script src="StandardLibrary.js"></script>
123
    <script src="ResolveNames.js"></script>
124
<script src="StatementCloner.js"></script>
124
    <script src="ResolveOverloadImpl.js"></script>
125
<script src="StructLayoutBuilder.js"></script>
125
    <script src="ResolveProperties.js"></script>
126
<script src="StructType.js"></script>
126
    <script src="ResolveTypeDefs.js"></script>
127
<script src="Substitution.js"></script>
127
    <script src="Return.js"></script>
128
<script src="SwitchCase.js"></script>
128
    <script src="ReturnChecker.js"></script>
129
<script src="SwitchStatement.js"></script>
129
    <script src="ReturnException.js"></script>
130
<script src="SynthesizeEnumFunctions.js"></script>
130
    <script src="StandardLibrary.js"></script>
131
<script src="SynthesizeStructAccessors.js"></script>
131
    <script src="StatementCloner.js"></script>
132
<script src="TrapStatement.js"></script>
132
    <script src="StructLayoutBuilder.js"></script>
133
<script src="TypeDef.js"></script>
133
    <script src="StructType.js"></script>
134
<script src="TypeDefResolver.js"></script>
134
    <script src="Substitution.js"></script>
135
<script src="TypeOrVariableRef.js"></script>
135
    <script src="SwitchCase.js"></script>
136
<script src="TypeParameterRewriter.js"></script>
136
    <script src="SwitchStatement.js"></script>
137
<script src="TypeRef.js"></script>
137
    <script src="SynthesizeArrayOperatorLength.js"></script>
138
<script src="TypeVariable.js"></script>
138
    <script src="SynthesizeEnumFunctions.js"></script>
139
<script src="TypeVariableTracker.js"></script>
139
    <script src="SynthesizeStructAccessors.js"></script>
140
<script src="TypedValue.js"></script>
140
    <script src="SynthesizeCopyConstructorOperator.js"></script>
141
<script src="UintLiteral.js"></script>
141
    <script src="SynthesizeDefaultConstructorOperator.js"></script>
142
<script src="UintLiteralType.js"></script>
142
    <script src="TrapStatement.js"></script>
143
<script src="UnificationContext.js"></script>
143
    <script src="TypeDef.js"></script>
144
<script src="UnreachableCodeChecker.js"></script>
144
    <script src="TypeDefResolver.js"></script>
145
<script src="VariableDecl.js"></script>
145
    <script src="TypeOrVariableRef.js"></script>
146
<script src="VariableRef.js"></script>
146
    <script src="TypeParameterRewriter.js"></script>
147
<script src="VisitingSet.js"></script>
147
    <script src="TypeRef.js"></script>
148
<script src="WSyntaxError.js"></script>
148
    <script src="TypeVariable.js"></script>
149
<script src="WTrapError.js"></script>
149
    <script src="TypeVariableTracker.js"></script>
150
<script src="WTypeError.js"></script>
150
    <script src="TypedValue.js"></script>
151
<script src="WhileLoop.js"></script>
151
    <script src="UintLiteral.js"></script>
152
<script src="WrapChecker.js"></script>
152
    <script src="UintLiteralType.js"></script>
153
    <script src="UnificationContext.js"></script>
154
    <script src="UnreachableCodeChecker.js"></script>
155
    <script src="VariableDecl.js"></script>
156
    <script src="VariableRef.js"></script>
157
    <script src="VisitingSet.js"></script>
158
    <script src="WSyntaxError.js"></script>
159
    <script src="WTrapError.js"></script>
160
    <script src="WTypeError.js"></script>
161
    <script src="WhileLoop.js"></script>
162
    <script src="WrapChecker.js"></script>
153
<style>
163
<style>
154
#ShaderSource {
164
#ShaderSource {
155
    font-family: monospace;
165
    font-family: monospace;
Lines 415-420 function runShaders() { a/Tools/WebGPUShadingLanguageRI/index.html_sec2
415
        case "uint32":
425
        case "uint32":
416
            value = parseInt(value) >>> 0;
426
            value = parseInt(value) >>> 0;
417
            break;
427
            break;
428
        // FIXME: Parse other types
418
        default:
429
        default:
419
            presentError("I don't know how to parse values of type " + type);
430
            presentError("I don't know how to parse values of type " + type);
420
        }
431
        }

Return to Bug 187988