WebKit Bugzilla
Attachment 345819 Details for
Bug 187988
: [WHLSL] Remove generics from the interpreter
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
New Account
|
Log In
Remember
[x]
|
Forgot Password
Login:
[x]
[patch]
Patch
bug-187988-20180725214142.patch (text/plain), 197.96 KB, created by
Thomas Denney
on 2018-07-25 21:41:43 PDT
(
hide
)
Description:
Patch
Filename:
MIME Type:
Creator:
Thomas Denney
Created:
2018-07-25 21:41:43 PDT
Size:
197.96 KB
patch
obsolete
>Subversion Revision: 234179 >diff --git a/Tools/ChangeLog b/Tools/ChangeLog >index 80439e0399f988fc4ed1ad0c496bce31b698ee29..bb81abb504fe055d60500ef5c5087cb24bbbb7b7 100644 >--- a/Tools/ChangeLog >+++ b/Tools/ChangeLog >@@ -1,3 +1,199 @@ >+2018-07-25 Thomas Denney <tdenney@apple.com> >+ >+ [WHLSL] Remove generics from the interpreter >+ https://bugs.webkit.org/show_bug.cgi?id=187988 >+ >+ Reviewed by NOBODY (OOPS!). >+ >+ * WebGPUShadingLanguageRI/All.js: >+ * WebGPUShadingLanguageRI/BuiltinVectorCasts.js: Added. >+ (BuiltinVectorCasts): >+ (BuiltinVectorCasts.prototype.get baseTypeName): >+ (BuiltinVectorCasts.prototype.get parameterSizes): >+ (BuiltinVectorCasts.prototype.get outputSize): >+ (BuiltinVectorCasts.prototype.toString): >+ (BuiltinVectorCasts.functions): >+ (BuiltinVectorCasts._vectorParameterSizesForMaximumSize): >+ (BuiltinVectorCasts.prototype.instantiateImplementation): >+ * WebGPUShadingLanguageRI/BuiltinVectorEqualityOperator.js: Copied from Tools/WebGPUShadingLanguageRI/NativeTypeInstance.js. >+ (BuiltinVectorEqualityOperator): >+ (BuiltinVectorEqualityOperator.prototype.get baseTypeName): >+ (BuiltinVectorEqualityOperator.prototype.get size): >+ (BuiltinVectorEqualityOperator.prototype.toString): >+ (BuiltinVectorEqualityOperator.functions): >+ (BuiltinVectorEqualityOperator.prototype.instantiateImplementation): >+ * WebGPUShadingLanguageRI/BuiltinVectorGetter.js: Copied from Tools/WebGPUShadingLanguageRI/NativeTypeInstance.js. >+ (BuiltinVectorGetter): >+ (BuiltinVectorGetter.prototype.get baseTypeName): >+ (BuiltinVectorGetter.prototype.get size): >+ (BuiltinVectorGetter.prototype.get elementName): >+ (BuiltinVectorGetter.prototype.get index): >+ (BuiltinVectorGetter.prototype.toString): >+ (BuiltinVectorGetter.functions): >+ (BuiltinVectorGetter.prototype.instantiateImplementation): >+ * WebGPUShadingLanguageRI/BuiltinVectorIndexGetter.js: Copied from Tools/WebGPUShadingLanguageRI/LiteralTypeChecker.js. >+ (BuiltinVectorIndexGetter): >+ (BuiltinVectorIndexGetter.prototype.get baseTypeName): >+ (BuiltinVectorIndexGetter.prototype.get size): >+ (BuiltinVectorIndexGetter.prototype.toString): >+ (BuiltinVectorIndexGetter.functions): >+ (BuiltinVectorIndexGetter.prototype.instantiateImplementation): >+ * WebGPUShadingLanguageRI/BuiltinVectorIndexSetter.js: Added. >+ (BuiltinVectorIndexSetter): >+ (BuiltinVectorIndexSetter.prototype.get baseTypeName): >+ (BuiltinVectorIndexSetter.prototype.get size): >+ (BuiltinVectorIndexSetter.prototype.get elementName): >+ (BuiltinVectorIndexSetter.prototype.get index): >+ (BuiltinVectorIndexSetter.prototype.toString): >+ (BuiltinVectorIndexSetter.functions): >+ (BuiltinVectorIndexSetter.prototype.instantiateImplementation): >+ * WebGPUShadingLanguageRI/BuiltinVectorSetter.js: Added. >+ (BuiltinVectorSetter): >+ (BuiltinVectorSetter.prototype.get baseTypeName): >+ (BuiltinVectorSetter.prototype.get size): >+ (BuiltinVectorSetter.prototype.get elementName): >+ (BuiltinVectorSetter.prototype.get index): >+ (BuiltinVectorSetter.prototype.toString): >+ (BuiltinVectorSetter.functions): >+ (BuiltinVectorSetter.prototype.instantiateImplementation): >+ * WebGPUShadingLanguageRI/CallExpression.js: >+ (CallExpression.resolve): >+ (CallExpression.prototype.resolve): >+ (CallExpression.prototype._resolveToOperatorAnderIndexer): >+ (CallExpression.prototype._resolveToOperatorLength): >+ (CallExpression.prototype.toString): >+ (CallExpression): >+ * WebGPUShadingLanguageRI/Checker.js: >+ (Checker.prototype._finishVisitingPropertyAccess): >+ * WebGPUShadingLanguageRI/Func.js: >+ (Func.prototype.toDeclString): >+ * WebGPUShadingLanguageRI/FuncInstantiator.js: >+ (FuncInstantiator.prototype.getUnique.FindTypeVariable.prototype.visitTypeRef): Deleted. >+ (FuncInstantiator.prototype.getUnique.FindTypeVariable.prototype.visitTypeVariable): Deleted. >+ (FuncInstantiator.prototype.getUnique.FindTypeVariable): Deleted. >+ * WebGPUShadingLanguageRI/Intrinsics.js: >+ (Intrinsics): >+ * WebGPUShadingLanguageRI/LiteralTypeChecker.js: >+ (LiteralTypeChecker.prototype.visitGenericLiteralType): >+ (LiteralTypeChecker): >+ * WebGPUShadingLanguageRI/NativeType.js: >+ (NativeType.prototype.toString): >+ (NativeType): >+ * WebGPUShadingLanguageRI/NativeTypeInstance.js: >+ (NativeTypeInstance.prototype.toString): >+ (NativeTypeInstance): >+ * WebGPUShadingLanguageRI/OperatorAnderIndex.js: Added. >+ (OperatorAnderIndexer): >+ (OperatorAnderIndexer.prototype.get addressSpace): >+ (OperatorAnderIndexer.prototype.get baseTypeName): >+ (OperatorAnderIndexer.prototype.toString): >+ (OperatorAnderIndexer.functions): >+ (OperatorAnderIndexer.prototype.instantiateImplementation): >+ * WebGPUShadingLanguageRI/OperatorArrayRefLength.js: Renamed from Tools/WebGPUShadingLanguageRI/DoubleLiteralType.js. >+ (OperatorArrayRefLength): >+ (OperatorArrayRefLength.prototype.get addressSpace): >+ (OperatorArrayRefLength.prototype.get baseTypeName): >+ (OperatorArrayRefLength.prototype.toString): >+ (OperatorArrayRefLength.prototype.instantiateImplementation): >+ * WebGPUShadingLanguageRI/OperatorBool.js: Copied from Tools/WebGPUShadingLanguageRI/NativeTypeInstance.js. >+ (OperatorBool): >+ (OperatorBool.prototype.get baseTypeName): >+ (OperatorBool.prototype.toString): >+ (OperatorBool.functions): >+ (OperatorBool.prototype.instantiateImplementation): >+ * WebGPUShadingLanguageRI/Parse.js: >+ (parseTerm): >+ (parseTypeDef): >+ (isCallExpression): >+ (parseFuncDecl): >+ (parseStructType): >+ (parseNative): >+ (parse): >+ (parseProtocolRef): Deleted. >+ (parseTypeParameters): Deleted. >+ (parseTypeArguments): Deleted. >+ (parseProtocolFuncDecl): Deleted. >+ (parseProtocolDecl): Deleted. >+ * WebGPUShadingLanguageRI/Prepare.js: >+ (let.prepare): >+ * WebGPUShadingLanguageRI/SPIRV.html: >+ * WebGPUShadingLanguageRI/SPIRVCodegen.js: >+ (ConstantFinder.prototype.visitGenericLiteralType): >+ (ConstantFinder): >+ (generateSPIRV): >+ * WebGPUShadingLanguageRI/StandardLibrary.js: >+ (addFunctionsFromClass): >+ (restricted.operator.T.T): Deleted. >+ (operator.T.Equatable.bool): Deleted. >+ (operator.T.vec2.T): Deleted. >+ (bool.operator.T.Equatable): Deleted. >+ (thread.T.operator.T): Deleted. >+ (operator.T.vec3.T): Deleted. >+ (operator.T.vec4.T): Deleted. >+ (uint.length): Deleted. >+ * WebGPUShadingLanguageRI/StructType.js: >+ (StructType.prototype.get isStruct): >+ (StructType.prototype.toString): >+ (StructType): >+ * WebGPUShadingLanguageRI/SwizzleOp.js: >+ (SwizzleOp): >+ (SwizzleOp.prototype.get baseTypeName): >+ (SwizzleOp.prototype.toString): >+ (SwizzleOp.functions.): >+ (SwizzleOp.functions): >+ (SwizzleOp.prototype.instantiateImplementation): >+ (SwizzleOp.allSwizzleOperators.): Deleted. >+ (SwizzleOp.allSwizzleOperators): Deleted. >+ * WebGPUShadingLanguageRI/SynthesizeArrayOperatorLength.js: Renamed from Tools/WebGPUShadingLanguageRI/DoubleLiteral.js. >+ (synthesizeArrayOperatorLength.FindArrayTypes.prototype.visitArrayType): >+ (synthesizeArrayOperatorLength.FindArrayTypes): >+ (synthesizeArrayOperatorLength): >+ * WebGPUShadingLanguageRI/SynthesizeCopyConstructorOperator.js: Copied from Tools/WebGPUShadingLanguageRI/NativeTypeInstance.js. >+ (synthesizeCopyConstructorOperator.FindAllTypes.prototype.visitNativeType): >+ (synthesizeCopyConstructorOperator.FindAllTypes.prototype.visitStructType): >+ (synthesizeCopyConstructorOperator.FindAllTypes.prototype.visitElementalType): >+ (synthesizeCopyConstructorOperator.FindAllTypes): >+ (synthesizeCopyConstructorOperator): >+ * WebGPUShadingLanguageRI/SynthesizeDefaultConstructorOperator.js: Copied from Tools/WebGPUShadingLanguageRI/NativeTypeInstance.js. >+ (synthesizeDefaultConstructorOperator.FindAllTypes.prototype.visitNativeType): >+ (synthesizeDefaultConstructorOperator.FindAllTypes.prototype.visitStructType): >+ (synthesizeDefaultConstructorOperator.FindAllTypes.prototype.visitElementalType): >+ (synthesizeDefaultConstructorOperator.FindAllTypes): >+ (synthesizeDefaultConstructorOperator): >+ * WebGPUShadingLanguageRI/Test.html: >+ * WebGPUShadingLanguageRI/Test.js: >+ (makeDouble): Deleted. >+ (checkDouble): Deleted. >+ * WebGPUShadingLanguageRI/Type.js: >+ (Type.prototype.get isStruct): >+ * WebGPUShadingLanguageRI/TypeDef.js: >+ (TypeDef.prototype.toString): >+ (TypeDef): >+ * WebGPUShadingLanguageRI/TypeRef.js: >+ (TypeRef.prototype.toString): >+ (TypeRef): >+ * WebGPUShadingLanguageRI/index.html: >+ >+2018-07-24 Thomas Denney <tdenney@apple.com> >+ >+ Remove support for the double type from WHLSL >+ https://bugs.webkit.org/show_bug.cgi?id=187977 >+ >+ Reviewed by Myles C. Maxfield. >+ >+ * WebGPUShadingLanguageRI/All.js: Removed DoubleLiteral.js and DoubleLiteralType.js include. >+ * WebGPUShadingLanguageRI/DoubleLiteral.js: Removed. >+ * WebGPUShadingLanguageRI/DoubleLiteralType.js: Removed. >+ * WebGPUShadingLanguageRI/Intrinsics.js: Removed double arithmetic functions. >+ * WebGPUShadingLanguageRI/Parse.js: >+ (parseTerm): Removed parsing of double literals. >+ * WebGPUShadingLanguageRI/SPIRV.html: Removed DoubleLiteral.js and DoubleLiteralType.js include. >+ * WebGPUShadingLanguageRI/SPIRVCodegen.js: Removed double type logic. >+ * WebGPUShadingLanguageRI/StandardLibrary.js: Removed double type declarations. >+ * WebGPUShadingLanguageRI/Test.html: Removed DoubleLiteral.js and DoubleLiteralType.js include. >+ * WebGPUShadingLanguageRI/Test.js: Removed tests that test doubles or ported them to use floats. >+ * WebGPUShadingLanguageRI/index.html: Removed DoubleLiteral.js and DoubleLiteralType.js include. >+ > 2018-07-24 Daniel Bates <dabates@apple.com> > > Move-constructing NeverDestroyed should move construct underlying object instead of copy constructing it >diff --git a/Tools/WebGPUShadingLanguageRI/All.js b/Tools/WebGPUShadingLanguageRI/All.js >index 30a0b099655cb50b92acd16db7451e5b397be332..d6578143e6b25ec22db5af4e63b5a9bfdfd627c0 100644 >--- a/Tools/WebGPUShadingLanguageRI/All.js >+++ b/Tools/WebGPUShadingLanguageRI/All.js >@@ -34,6 +34,7 @@ load("Visitor.js"); > load("CreateLiteral.js"); > load("CreateLiteralType.js"); > load("PropertyAccessExpression.js"); >+load("SwizzleOp.js"); > > load("AddressSpace.js"); > load("AnonymousVariable.js"); >@@ -49,8 +50,8 @@ load("CallFunction.js"); > load("Check.js"); > load("CheckLiteralTypes.js"); > load("CheckLoops.js"); >-load("CheckRecursiveTypes.js"); > load("CheckRecursion.js"); >+load("CheckRecursiveTypes.js"); > load("CheckReturns.js"); > load("CheckUnreachableCode.js"); > load("CheckWrapped.js"); >@@ -61,11 +62,9 @@ load("ConstexprFolder.js"); > load("ConstexprTypeParameter.js"); > load("Continue.js"); > load("ConvertPtrToArrayRefExpression.js"); >-load("DereferenceExpression.js"); > load("DoWhileLoop.js"); > load("DotExpression.js"); >-load("DoubleLiteral.js"); >-load("DoubleLiteralType.js"); >+load("DereferenceExpression.js"); > load("EArrayRef.js"); > load("EBuffer.js"); > load("EBufferBuilder.js"); >@@ -120,13 +119,22 @@ load("NativeTypeInstance.js"); > load("NormalUsePropertyResolver.js"); > load("NullLiteral.js"); > load("NullType.js"); >+load("OperatorAnderIndex.js"); >+load("OperatorArrayRefLength.js"); >+load("OperatorBool.js"); >+load("BuiltinVectorCasts.js"); >+load("BuiltinVectorGetter.js"); >+load("BuiltinVectorSetter.js"); >+load("BuiltinVectorIndexGetter.js"); >+load("BuiltinVectorIndexSetter.js"); >+load("BuiltinVectorEqualityOperator.js"); > load("OriginKind.js"); > load("OverloadResolutionFailure.js"); > load("Parse.js"); > load("Prepare.js"); >+load("PropertyResolver.js"); > load("Program.js"); > load("ProgramWithUnnecessaryThingsRemoved.js"); >-load("PropertyResolver.js"); > load("Protocol.js"); > load("ProtocolDecl.js"); > load("ProtocolFuncDecl.js"); >@@ -149,8 +157,11 @@ load("StructType.js"); > load("Substitution.js"); > load("SwitchCase.js"); > load("SwitchStatement.js"); >+load("SynthesizeArrayOperatorLength.js"); > load("SynthesizeEnumFunctions.js"); > load("SynthesizeStructAccessors.js"); >+load("SynthesizeCopyConstructorOperator.js"); >+load("SynthesizeDefaultConstructorOperator.js"); > load("TrapStatement.js"); > load("TypeDef.js"); > load("TypeDefResolver.js"); >diff --git a/Tools/WebGPUShadingLanguageRI/BuiltinVectorCasts.js b/Tools/WebGPUShadingLanguageRI/BuiltinVectorCasts.js >new file mode 100644 >index 0000000000000000000000000000000000000000..9c73c2ed9ad2b123120baf8c646719396bab6f59 >--- /dev/null >+++ b/Tools/WebGPUShadingLanguageRI/BuiltinVectorCasts.js >@@ -0,0 +1,90 @@ >+/* >+ * Copyright (C) 2017 Apple Inc. All rights reserved. >+ * >+ * Redistribution and use in source and binary forms, with or without >+ * modification, are permitted provided that the following conditions >+ * are met: >+ * 1. Redistributions of source code must retain the above copyright >+ * notice, this list of conditions and the following disclaimer. >+ * 2. Redistributions in binary form must reproduce the above copyright >+ * notice, this list of conditions and the following disclaimer in the >+ * documentation and/or other materials provided with the distribution. >+ * >+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY >+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE >+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR >+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR >+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, >+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, >+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR >+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY >+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT >+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE >+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. >+ */ >+"use strict"; >+ >+class BuiltinVectorCasts { >+ constructor(baseTypeName, parameterSizes) >+ { >+ this._baseTypeName = baseTypeName; >+ this._parameterSizes = parameterSizes; >+ } >+ >+ get baseTypeName() { return this._baseTypeName; } >+ get parameterSizes() { return this._parameterSizes; } >+ get outputSize() >+ { >+ let sum = 0; >+ for (let paramSize of this.parameterSizes) >+ sum += paramSize; >+ return sum; >+ } >+ >+ toString() >+ { >+ return `native operator ${this.baseTypeName}${this.outputSize}(${this.parameterSizes.map(x => x == 1 ? this.baseTypeName : this.baseTypeName + x).join(",")})`; >+ } >+ >+ static functions() >+ { >+ if (!this._functions) { >+ this._functions = []; >+ >+ const typeNames = [ "uint", "int", "float" ]; >+ const sizes = [ 2, 3, 4 ]; >+ >+ for (let typeName of typeNames) { >+ for (let size of sizes) { >+ for (let paramSizes of this._vectorParameterSizesForMaximumSize(size)) >+ this._functions.push(new BuiltinVectorCasts(typeName, paramSizes)); >+ } >+ } >+ } >+ return this._functions; >+ } >+ >+ static _vectorParameterSizesForMaximumSize(maxSize) >+ { >+ let variants = [ [ maxSize ] ]; >+ for (let splitPoint = 1; splitPoint < maxSize; splitPoint++) { >+ for (let v of BuiltinVectorCasts._vectorParameterSizesForMaximumSize(maxSize - splitPoint)) >+ variants.push([ splitPoint ].concat(v)); >+ } >+ return variants; >+ } >+ >+ instantiateImplementation(func) >+ { >+ func.implementation = (args) => { >+ const result = new EPtr(new EBuffer(this.outputSize), 0); >+ let offset = 0; >+ for (let i = 0; i < args.length; i++) { >+ for (let j = 0; j < this.parameterSizes[i]; j++) >+ result.set(offset++, args[i].get(j)); >+ } >+ return result; >+ }; >+ func.implementationData = this; >+ } >+} >\ No newline at end of file >diff --git a/Tools/WebGPUShadingLanguageRI/BuiltinVectorEqualityOperator.js b/Tools/WebGPUShadingLanguageRI/BuiltinVectorEqualityOperator.js >new file mode 100644 >index 0000000000000000000000000000000000000000..6638cec1566219e18a007cb2d924718622acb237 >--- /dev/null >+++ b/Tools/WebGPUShadingLanguageRI/BuiltinVectorEqualityOperator.js >@@ -0,0 +1,69 @@ >+/* >+ * Copyright (C) 2017 Apple Inc. All rights reserved. >+ * >+ * Redistribution and use in source and binary forms, with or without >+ * modification, are permitted provided that the following conditions >+ * are met: >+ * 1. Redistributions of source code must retain the above copyright >+ * notice, this list of conditions and the following disclaimer. >+ * 2. Redistributions in binary form must reproduce the above copyright >+ * notice, this list of conditions and the following disclaimer in the >+ * documentation and/or other materials provided with the distribution. >+ * >+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY >+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE >+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR >+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR >+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, >+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, >+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR >+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY >+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT >+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE >+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. >+ */ >+"use strict"; >+ >+class BuiltinVectorEqualityOperator { >+ constructor(baseTypeName, size) >+ { >+ this._baseTypeName = baseTypeName; >+ this._size = size; >+ } >+ >+ get baseTypeName() { return this._baseTypeName; } >+ get size() { return this._size; } >+ >+ toString() >+ { >+ return `native bool operator==(${this.baseTypeName}${this.size},${this.baseTypeName}${this.size})`; >+ } >+ >+ static functions() >+ { >+ if (!this._functions) { >+ this._functions = []; >+ >+ const typeNames = [ "uint", "int", "float" ]; >+ const sizes = [ 2, 3, 4 ]; >+ >+ for (let typeName of typeNames) { >+ for (let size of sizes) >+ this._functions.push(new BuiltinVectorEqualityOperator(typeName, size)); >+ } >+ } >+ return this._functions; >+ } >+ >+ instantiateImplementation(func) >+ { >+ func.implementation = ([ref1, ref2], node) => { >+ for (let i = 0; i < this.size; i++) { >+ if (ref1.get(i) != ref2.get(i)) >+ return EPtr.box(false); >+ } >+ return EPtr.box(true); >+ }; >+ func.implementationData = this; >+ } >+} >\ No newline at end of file >diff --git a/Tools/WebGPUShadingLanguageRI/BuiltinVectorGetter.js b/Tools/WebGPUShadingLanguageRI/BuiltinVectorGetter.js >new file mode 100644 >index 0000000000000000000000000000000000000000..3ce7937833d1046bbb31e51a09e2b7d7afb1bf7e >--- /dev/null >+++ b/Tools/WebGPUShadingLanguageRI/BuiltinVectorGetter.js >@@ -0,0 +1,72 @@ >+/* >+ * Copyright (C) 2017 Apple Inc. All rights reserved. >+ * >+ * Redistribution and use in source and binary forms, with or without >+ * modification, are permitted provided that the following conditions >+ * are met: >+ * 1. Redistributions of source code must retain the above copyright >+ * notice, this list of conditions and the following disclaimer. >+ * 2. Redistributions in binary form must reproduce the above copyright >+ * notice, this list of conditions and the following disclaimer in the >+ * documentation and/or other materials provided with the distribution. >+ * >+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY >+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE >+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR >+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR >+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, >+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, >+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR >+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY >+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT >+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE >+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. >+ */ >+"use strict"; >+ >+class BuiltinVectorGetter { >+ constructor(baseTypeName, size, elementName, index) >+ { >+ this._baseTypeName = baseTypeName; >+ this._size = size; >+ this._elementName = elementName; >+ this._index = index; >+ } >+ >+ get baseTypeName() { return this._baseTypeName; } >+ get size() { return this._size; } >+ get elementName() { return this._elementName; } >+ get index() { return this._index; } >+ >+ toString() >+ { >+ return `native ${this.baseTypeName} operator.${this.elementName}(${this.baseTypeName}${this.size})`; >+ } >+ >+ static functions() >+ { >+ if (!this._functions) { >+ this._functions = []; >+ >+ const typeNames = [ "uint", "int", "float" ]; >+ const sizes = [ 2, 3, 4 ]; >+ const elements = [ "x", "y", "z", "w" ]; >+ >+ for (let typeName of typeNames) { >+ for (let size of sizes) { >+ for (let i = 0; i < size; i++) >+ this._functions.push(new BuiltinVectorGetter(typeName, size, elements[i], i)); >+ } >+ } >+ } >+ return this._functions; >+ } >+ >+ instantiateImplementation(func) >+ { >+ func.implementation = ([vec], node) => { >+ return EPtr.box(vec.get(this.index)); >+ }; >+ func.implementationData = this; >+ } >+} >\ No newline at end of file >diff --git a/Tools/WebGPUShadingLanguageRI/BuiltinVectorIndexGetter.js b/Tools/WebGPUShadingLanguageRI/BuiltinVectorIndexGetter.js >new file mode 100644 >index 0000000000000000000000000000000000000000..d23db4673091f1e26b0db5979fbd9ce3d307aa18 >--- /dev/null >+++ b/Tools/WebGPUShadingLanguageRI/BuiltinVectorIndexGetter.js >@@ -0,0 +1,69 @@ >+/* >+ * Copyright (C) 2017 Apple Inc. All rights reserved. >+ * >+ * Redistribution and use in source and binary forms, with or without >+ * modification, are permitted provided that the following conditions >+ * are met: >+ * 1. Redistributions of source code must retain the above copyright >+ * notice, this list of conditions and the following disclaimer. >+ * 2. Redistributions in binary form must reproduce the above copyright >+ * notice, this list of conditions and the following disclaimer in the >+ * documentation and/or other materials provided with the distribution. >+ * >+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY >+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE >+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR >+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR >+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, >+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, >+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR >+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY >+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT >+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE >+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. >+ */ >+"use strict"; >+ >+class BuiltinVectorIndexGetter { >+ constructor(baseTypeName, size) >+ { >+ this._baseTypeName = baseTypeName; >+ this._size = size; >+ } >+ >+ get baseTypeName() { return this._baseTypeName; } >+ get size() { return this._size; } >+ >+ toString() >+ { >+ return `native ${this.baseTypeName} operator[](${this.baseTypeName}${this.size},uint)`; >+ } >+ >+ static functions() >+ { >+ if (!this._allIndexGetters) { >+ this._allIndexGetters = []; >+ >+ const typeNames = [ "uint", "int", "float" ]; >+ const sizes = [ 2, 3, 4 ]; >+ >+ for (let typeName of typeNames) { >+ for (let size of sizes) >+ this._allIndexGetters.push(new BuiltinVectorIndexGetter(typeName, size)); >+ } >+ } >+ return this._allIndexGetters; >+ } >+ >+ instantiateImplementation(func) >+ { >+ func.implementation = ([vec, index], node) => { >+ const indexValue = index.loadValue(); >+ if (indexValue >= 0 && indexValue < this.size) >+ return EPtr.box(vec.get(index.loadValue())); >+ else >+ throw new Error(`${indexValue} out of bounds for vector of size ${this.size}`); >+ }; >+ func.implementationData = this; >+ } >+} >\ No newline at end of file >diff --git a/Tools/WebGPUShadingLanguageRI/BuiltinVectorIndexSetter.js b/Tools/WebGPUShadingLanguageRI/BuiltinVectorIndexSetter.js >new file mode 100644 >index 0000000000000000000000000000000000000000..827111740ce8f894893aeea77af205141127296f >--- /dev/null >+++ b/Tools/WebGPUShadingLanguageRI/BuiltinVectorIndexSetter.js >@@ -0,0 +1,74 @@ >+/* >+ * Copyright (C) 2017 Apple Inc. All rights reserved. >+ * >+ * Redistribution and use in source and binary forms, with or without >+ * modification, are permitted provided that the following conditions >+ * are met: >+ * 1. Redistributions of source code must retain the above copyright >+ * notice, this list of conditions and the following disclaimer. >+ * 2. Redistributions in binary form must reproduce the above copyright >+ * notice, this list of conditions and the following disclaimer in the >+ * documentation and/or other materials provided with the distribution. >+ * >+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY >+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE >+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR >+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR >+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, >+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, >+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR >+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY >+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT >+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE >+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. >+ */ >+"use strict"; >+ >+class BuiltinVectorIndexSetter { >+ constructor(baseTypeName, size) >+ { >+ this._baseTypeName = baseTypeName; >+ this._size = size; >+ } >+ >+ get baseTypeName() { return this._baseTypeName; } >+ get size() { return this._size; } >+ get elementName() { return this._elementName; } >+ get index() { return this._index; } >+ >+ toString() >+ { >+ return `native ${this.baseTypeName}${this.size} operator[]=(${this.baseTypeName}${this.size},uint32,${this.baseTypeName})`; >+ } >+ >+ static functions() >+ { >+ if (!this._functions) { >+ this._functions = []; >+ >+ const typeNames = [ "uint", "int", "float" ]; >+ const sizes = [ 2, 3, 4 ]; >+ >+ for (let typeName of typeNames) { >+ for (let size of sizes) >+ this._functions.push(new BuiltinVectorIndexSetter(typeName, size)); >+ } >+ } >+ return this._functions; >+ } >+ >+ instantiateImplementation(func) >+ { >+ func.implementation = ([base, index, value], node) => { >+ const indexValue = index.loadValue(); >+ if (indexValue >= 0 && indexValue < this.size) { >+ let result = new EPtr(new EBuffer(this.size), 0); >+ result.copyFrom(base, this.size); >+ result.plus(indexValue).copyFrom(value, 1); >+ return result; >+ } else >+ throw new Error(`${indexValue} out of bounds for vector of size ${this.size}`); >+ }; >+ func.implementationData = this; >+ } >+} >\ No newline at end of file >diff --git a/Tools/WebGPUShadingLanguageRI/BuiltinVectorSetter.js b/Tools/WebGPUShadingLanguageRI/BuiltinVectorSetter.js >new file mode 100644 >index 0000000000000000000000000000000000000000..2bfc68fe21d850392b9af2dbbc5f65201723d0d4 >--- /dev/null >+++ b/Tools/WebGPUShadingLanguageRI/BuiltinVectorSetter.js >@@ -0,0 +1,75 @@ >+/* >+ * Copyright (C) 2017 Apple Inc. All rights reserved. >+ * >+ * Redistribution and use in source and binary forms, with or without >+ * modification, are permitted provided that the following conditions >+ * are met: >+ * 1. Redistributions of source code must retain the above copyright >+ * notice, this list of conditions and the following disclaimer. >+ * 2. Redistributions in binary form must reproduce the above copyright >+ * notice, this list of conditions and the following disclaimer in the >+ * documentation and/or other materials provided with the distribution. >+ * >+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY >+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE >+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR >+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR >+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, >+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, >+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR >+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY >+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT >+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE >+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. >+ */ >+"use strict"; >+ >+class BuiltinVectorSetter { >+ constructor(baseTypeName, size, elementName, index) >+ { >+ this._baseTypeName = baseTypeName; >+ this._size = size; >+ this._elementName = elementName; >+ this._index = index; >+ } >+ >+ get baseTypeName() { return this._baseTypeName; } >+ get size() { return this._size; } >+ get elementName() { return this._elementName; } >+ get index() { return this._index; } >+ >+ toString() >+ { >+ return `native ${this.baseTypeName}${this.size} operator.${this.elementName}=(${this.baseTypeName}${this.size},${this.baseTypeName})`; >+ } >+ >+ static functions() >+ { >+ if (!this._functions) { >+ this._functions = []; >+ >+ const typeNames = [ "uint", "int", "float" ]; >+ const sizes = [ 2, 3, 4 ]; >+ const elements = [ "x", "y", "z", "w" ]; >+ >+ for (let typeName of typeNames) { >+ for (let size of sizes) { >+ for (let i = 0; i < size; i++) >+ this._functions.push(new BuiltinVectorSetter(typeName, size, elements[i], i)); >+ } >+ } >+ } >+ return this._functions; >+ } >+ >+ instantiateImplementation(func) >+ { >+ func.implementation = ([base, value], node) => { >+ let result = new EPtr(new EBuffer(this.size), 0); >+ result.copyFrom(base, this.size); >+ result.plus(this.index).copyFrom(value, 1); >+ return result; >+ }; >+ func.implementationData = this; >+ } >+} >\ No newline at end of file >diff --git a/Tools/WebGPUShadingLanguageRI/CallExpression.js b/Tools/WebGPUShadingLanguageRI/CallExpression.js >index b5ae0fe49fcedc8fa76a66793cfe0cb1f08b4571..88eb11eb47a0dd1d222d61e2809694e7d4922c69 100644 >--- a/Tools/WebGPUShadingLanguageRI/CallExpression.js >+++ b/Tools/WebGPUShadingLanguageRI/CallExpression.js >@@ -42,17 +42,17 @@ class CallExpression extends Expression { > get isCast() { return this._isCast; } > get returnType() { return this._returnType; } > >- static resolve(origin, possibleOverloads, typeParametersInScope, name, typeArguments, argumentList, argumentTypes, returnType) >+ static resolve(origin, possibleOverloads, typeParametersInScope, name, typeArguments, argumentList, argumentTypes, returnType, uintType) > { > let call = new CallExpression(origin, name, typeArguments, argumentList); > call.argumentTypes = argumentTypes.map(argument => argument.visit(new AutoWrapper())); > call.possibleOverloads = possibleOverloads; > if (returnType) > call.setCastData(returnType); >- return {call, resultType: call.resolve(possibleOverloads, typeParametersInScope, typeArguments)}; >+ return {call, resultType: call.resolve(possibleOverloads, typeParametersInScope, typeArguments, uintType)}; > } > >- resolve(possibleOverloads, typeParametersInScope, typeArguments) >+ resolve(possibleOverloads, typeParametersInScope, typeArguments, uintType) > { > if (!possibleOverloads) > throw new WTypeError(this.origin.originString, "Did not find any functions named " + this.name); >@@ -77,6 +77,13 @@ class CallExpression extends Expression { > if (!overload) { > overload = resolveOverloadImpl( > possibleOverloads, this.typeArguments, this.argumentTypes, this.returnType); >+ >+ if (!overload.func && this.name == "operator&[]") >+ return this._resolveToOperatorAnderIndexer(uintType); >+ >+ if (!overload.func && this.name == "operator.length") >+ return this._resolveToOperatorLength(uintType); >+ > if (!overload.func) { > failures.push(...overload.failures); > let message = "Did not find function named " + this.name + " for call with "; >@@ -108,6 +115,63 @@ class CallExpression extends Expression { > } > return this.resolveToOverload(overload); > } >+ >+ _resolveToOperatorAnderIndexer(uintType) >+ { >+ let arrayRefType = this.argumentTypes[0]; >+ if (!arrayRefType.isArrayRef) >+ throw new WTypeError(this.origin.originString, `Expected ${arrayRefType} to be an array ref type for operator&[]`); >+ >+ let indexType = this.argumentTypes[1]; >+ const addressSpace = arrayRefType.addressSpace; >+ >+ // The later checkLiteralTypes stage will verify that the literal can be represented as a uint >+ uintType = TypeRef.wrap(uintType); >+ indexType.type = uintType; >+ >+ const elementType = this.argumentTypes[0].elementType; >+ this.resultType = this._returnType = TypeRef.wrap(new PtrType(this.origin, addressSpace, TypeRef.wrap(elementType))) >+ >+ let arrayRefAccessor = new OperatorAnderIndexer(this.returnType.toString(), addressSpace); >+ let nativeFunc = new NativeFunc(this.origin, "operator&[]", this.resultType, [], [ >+ new FuncParameter(this.origin, null, arrayRefType), >+ new FuncParameter(this.origin, null, uintType) >+ ], false, null); >+ >+ arrayRefAccessor.instantiateImplementation(nativeFunc); >+ >+ this.func = nativeFunc; >+ this.actualTypeArguments = []; >+ this.instantiatedActualTypeArguments = this.actualTypeArguments; >+ >+ return this.resultType; >+ } >+ >+ _resolveToOperatorLength(uintType) >+ { >+ this.resultType = this._returnType = TypeRef.wrap(uintType); >+ >+ if (this.argumentTypes[0].isArray) { >+ const arrayType = this.argumentTypes[0]; >+ this.func = new NativeFunc(this.origin, "operator.length", this.resultType, [], [ >+ new FuncParameter(this.origin, null, arrayType) >+ ], false, null); >+ this.func.implementation = (args, node) => EPtr.box(arrayType.numElementsValue); >+ } else if (this.argumentTypes[0].isArrayRef) { >+ const arrayRefType = this.argumentTypes[0]; >+ const addressSpace = arrayRefType.addressSpace; >+ const operatorLength = new OperatorArrayRefLength(arrayRefType.toString(), addressSpace); >+ this.func = new NativeFunc(this.origin, "operator.length", this.resultType, [], [ >+ new FuncParameter(this.origin, null, arrayRefType) >+ ], false, null); >+ operatorLength.instantiateImplementation(this.func); >+ } else >+ throw new WTypeError(this.origin.originString, `Expected ${this.argumentTypes[0]} to be array/array ref type for operator.length`); >+ >+ >+ this.actualTypeArguments = this.instantiatedActualTypeArguments = []; >+ return this.resultType; >+ } > > resolveToOverload(overload) > { >@@ -141,7 +205,7 @@ class CallExpression extends Expression { > toString() > { > return (this.isCast ? "operator " + this.returnType : this.name) + >- "<" + this.typeArguments + ">" + >+ // "<" + this.typeArguments + ">" + > (this.actualTypeArguments ? "<<" + this.actualTypeArguments + ">>" : "") + > "(" + this.argumentList + ")"; > } >diff --git a/Tools/WebGPUShadingLanguageRI/Checker.js b/Tools/WebGPUShadingLanguageRI/Checker.js >index 8d55c50d836c15486fd2580c58e9606cad596ecb..e5c180a05ad4f9586b1f566a58b17a32c2ef21ed 100644 >--- a/Tools/WebGPUShadingLanguageRI/Checker.js >+++ b/Tools/WebGPUShadingLanguageRI/Checker.js >@@ -427,7 +427,7 @@ class Checker extends Visitor { > try { > let result = CallExpression.resolve( > node.origin, node.possibleGetOverloads, this._currentStatement.typeParameters, >- node.getFuncName, [], [node.base, ...extraArgs], [baseType, ...extraArgTypes], null); >+ node.getFuncName, [], [node.base, ...extraArgs], [baseType, ...extraArgTypes], null, this._program.types.get("uint32")); > node.callForGet = result.call; > node.resultTypeForGet = result.resultType; > } catch (e) { >@@ -442,7 +442,7 @@ class Checker extends Visitor { > let result = CallExpression.resolve( > node.origin, node.possibleAndOverloads, this._currentStatement.typeParameters, > node.andFuncName, [], [baseForAnd, ...extraArgs], [typeForAnd, ...extraArgTypes], >- null); >+ null, this._program.types.get("uint32")); > node.callForAnd = result.call; > node.resultTypeForAnd = result.resultType.unifyNode.returnTypeFromAndOverload(node.origin); > } catch (e) { >@@ -467,7 +467,7 @@ class Checker extends Visitor { > try { > let result = CallExpression.resolve( > node.origin, node.possibleSetOverloads, this._currentStatement.typeParameters, >- node.setFuncName, [], [node.base, ...extraArgs, null], [baseType, ...extraArgTypes, node.resultType], null); >+ node.setFuncName, [], [node.base, ...extraArgs, null], [baseType, ...extraArgTypes, node.resultType], null, this._program.types.get("uint32")); > node.callForSet = result.call; > if (!result.resultType.equals(baseType)) > throw new WTypeError(node.origin.originString, "Result type of setter " + result.call.func + " is not the base type " + baseType); >diff --git a/Tools/WebGPUShadingLanguageRI/DoubleLiteral.js b/Tools/WebGPUShadingLanguageRI/DoubleLiteral.js >deleted file mode 100644 >index 7fd981306eb9e0b34f3fa55da4af9c076470fde1..0000000000000000000000000000000000000000 >--- a/Tools/WebGPUShadingLanguageRI/DoubleLiteral.js >+++ /dev/null >@@ -1,41 +0,0 @@ >-/* >- * Copyright (C) 2017 Apple Inc. All rights reserved. >- * >- * Redistribution and use in source and binary forms, with or without >- * modification, are permitted provided that the following conditions >- * are met: >- * 1. Redistributions of source code must retain the above copyright >- * notice, this list of conditions and the following disclaimer. >- * 2. Redistributions in binary form must reproduce the above copyright >- * notice, this list of conditions and the following disclaimer in the >- * documentation and/or other materials provided with the distribution. >- * >- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY >- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE >- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR >- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR >- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, >- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, >- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR >- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY >- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT >- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE >- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. >- */ >-"use strict"; >- >-let DoubleLiteral = createLiteral({ >- literalClassName: "DoubleLiteral", >- preferredTypeName: "double", >- >- negConstexpr(origin) >- { >- return new IntLiteral(origin, -this.value); >- }, >- >- createType(origin, value) >- { >- return new DoubleLiteralType(origin, value); >- } >-}); >- >diff --git a/Tools/WebGPUShadingLanguageRI/DoubleLiteralType.js b/Tools/WebGPUShadingLanguageRI/DoubleLiteralType.js >deleted file mode 100644 >index 1442fb5c105049e310f69f1ea60b873b02e9a6a1..0000000000000000000000000000000000000000 >--- a/Tools/WebGPUShadingLanguageRI/DoubleLiteralType.js >+++ /dev/null >@@ -1,39 +0,0 @@ >-/* >- * Copyright (C) 2017 Apple Inc. All rights reserved. >- * >- * Redistribution and use in source and binary forms, with or without >- * modification, are permitted provided that the following conditions >- * are met: >- * 1. Redistributions of source code must retain the above copyright >- * notice, this list of conditions and the following disclaimer. >- * 2. Redistributions in binary form must reproduce the above copyright >- * notice, this list of conditions and the following disclaimer in the >- * documentation and/or other materials provided with the distribution. >- * >- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY >- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE >- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR >- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR >- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, >- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, >- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR >- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY >- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT >- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE >- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. >- */ >-"use strict"; >- >-let DoubleLiteralType = createLiteralType({ >- preferredTypeName: "double", >- >- verifyAsArgument(unificationContext) >- { >- let realThis = unificationContext.find(this); >- if (!realThis.isFloating) >- return {result: false, reason: "Cannot use double literal with non-floating type " + realThis}; >- if (!realThis.canRepresent(this.value)) >- return {result: false, reason: "Float literal " + this.value + " does not fit in type " + realThis}; >- return {result: true}; >- } >-}); >diff --git a/Tools/WebGPUShadingLanguageRI/Func.js b/Tools/WebGPUShadingLanguageRI/Func.js >index 6fa7c9d1b6f4b958335981c2728be865a56e73ae..91f96f8c13a62111b2fe2c7f5cece7350b1b7da7 100644 >--- a/Tools/WebGPUShadingLanguageRI/Func.js >+++ b/Tools/WebGPUShadingLanguageRI/Func.js >@@ -65,9 +65,9 @@ class Func extends Node { > if (this.shaderType) > result += this.shaderType + " "; > if (this.isCast) >- result += "operator<" + this.typeParameters + "> " + this.returnType; >+ result += `operator ${this.returnType}`; > else >- result += this.returnType + " " + this.name + "<" + this.typeParameters + ">"; >+ result += `${this.returnType} ${this.name}`; > return result + "(" + this.parameters + ")"; > } > >diff --git a/Tools/WebGPUShadingLanguageRI/FuncInstantiator.js b/Tools/WebGPUShadingLanguageRI/FuncInstantiator.js >index 892862a6dd8565ee37e420631d7af70d5227e586..53e36a7916efa425f92d21cab6cba5f4151e5f24 100644 >--- a/Tools/WebGPUShadingLanguageRI/FuncInstantiator.js >+++ b/Tools/WebGPUShadingLanguageRI/FuncInstantiator.js >@@ -40,6 +40,9 @@ class FuncInstantiator { > // resolutions on the original Program. > getUnique(func, typeArguments) > { >+ if (!typeArguments) >+ typeArguments = []; >+ > class FindTypeVariable extends Visitor { > visitTypeRef(node) > { >diff --git a/Tools/WebGPUShadingLanguageRI/Intrinsics.js b/Tools/WebGPUShadingLanguageRI/Intrinsics.js >index b1d9311e184d83af95fb7179df67d7990d49fe6e..6f0f5ad83c7225e99169465c9477e99b0a2d9248 100644 >--- a/Tools/WebGPUShadingLanguageRI/Intrinsics.js >+++ b/Tools/WebGPUShadingLanguageRI/Intrinsics.js >@@ -35,7 +35,7 @@ class Intrinsics { > // use "int" here, since we don't yet know that they are the same type. > > this._map.set( >- "native typedef void<>", >+ "native typedef void", > type => { > this.void = type; > type.size = 0; >@@ -57,7 +57,7 @@ class Intrinsics { > } > > this._map.set( >- "native typedef int32<>", >+ "native typedef int32", > type => { > this.int32 = type; > type.isPrimitive = true; >@@ -82,7 +82,7 @@ class Intrinsics { > }); > > this._map.set( >- "native typedef uint32<>", >+ "native typedef uint32", > type => { > this.uint32 = type; > type.isPrimitive = true; >@@ -105,7 +105,7 @@ class Intrinsics { > }); > > this._map.set( >- "native typedef uint8<>", >+ "native typedef uint8", > type => { > this.uint8 = type; > type.isInt = true; >@@ -127,7 +127,7 @@ class Intrinsics { > }); > > this._map.set( >- "native typedef float32<>", >+ "native typedef float32", > type => { > this.float = type; > type.isPrimitive = true; >@@ -139,538 +139,414 @@ class Intrinsics { > type.formatValueFromIntLiteral = value => value; > type.formatValueFromUintLiteral = value => value; > type.formatValueFromFloatLiteral = value => Math.fround(value); >- type.formatValueFromDoubleLiteral = value => Math.fround(value); > }); > > this._map.set( >- "native typedef float64<>", >- type => { >- this.double = type; >- type.isPrimitive = true; >- type.size = 1; >- type.isFloating = true; >- type.isNumber = true; >- type.canRepresent = value => true; >- type.populateDefaultValue = (buffer, offset) => buffer.set(offset, 0); >- type.formatValueFromIntLiteral = value => value; >- type.formatValueFromUintLiteral = value => value; >- type.formatValueFromFloatLiteral = value => value; >- type.formatValueFromDoubleLiteral = value => value; >- }); >- >- this._map.set( >- "native typedef bool<>", >+ "native typedef bool", > type => { > this.bool = type; > type.isPrimitive = true; > type.size = 1; > type.populateDefaultValue = (buffer, offset) => buffer.set(offset, false); > }); >+ >+ const vectorTypes = [ "int", "uint", "float" ]; >+ for (let vectorType of vectorTypes) { >+ for (let size = 2; size <= 4; size++) { >+ const name = `${vectorType}${size}`; >+ this._map.set( >+ `native typedef ${name}`, >+ type => { >+ this[name] = type; >+ type.isPrimitive = true; >+ type.size = size; >+ type.populateDefaultValue = (buffer, offset) => { >+ for (let i = 0; i < size; i++) { >+ buffer.set(offset + i, 0); >+ } >+ } >+ } >+ ) >+ } >+ } > > this._map.set( >- "native operator<> int32(uint32)", >- func => { >- func.implementation = ([value]) => EPtr.box(value.loadValue() | 0); >- }); >- >- this._map.set( >- "native operator<> int32(uint8)", >+ "native operator int32(uint32)", > func => { > func.implementation = ([value]) => EPtr.box(value.loadValue() | 0); > }); > > this._map.set( >- "native operator<> int32(float)", >+ "native operator int32(uint8)", > func => { > func.implementation = ([value]) => EPtr.box(value.loadValue() | 0); > }); > > this._map.set( >- "native operator<> int32(double)", >+ "native operator int32(float)", > func => { > func.implementation = ([value]) => EPtr.box(value.loadValue() | 0); > }); > > this._map.set( >- "native operator<> uint32(int32)", >- func => { >- func.implementation = ([value]) => EPtr.box(value.loadValue() >>> 0); >- }); >- >- this._map.set( >- "native operator<> uint32(uint8)", >+ "native operator uint32(int32)", > func => { > func.implementation = ([value]) => EPtr.box(value.loadValue() >>> 0); > }); > > this._map.set( >- "native operator<> uint32(float)", >+ "native operator uint32(uint8)", > func => { > func.implementation = ([value]) => EPtr.box(value.loadValue() >>> 0); > }); > > this._map.set( >- "native operator<> uint32(double)", >+ "native operator uint32(float)", > func => { > func.implementation = ([value]) => EPtr.box(value.loadValue() >>> 0); > }); > > this._map.set( >- "native operator<> uint8(int32)", >+ "native operator uint8(int32)", > func => { > func.implementation = ([value]) => EPtr.box(value.loadValue() & 0xff); > }); > > this._map.set( >- "native operator<> uint8(uint32)", >+ "native operator uint8(uint32)", > func => { > func.implementation = ([value]) => EPtr.box(value.loadValue() & 0xff); > }); > > this._map.set( >- "native operator<> uint8(float)", >+ "native operator uint8(float)", > func => { > func.implementation = ([value]) => EPtr.box(value.loadValue() & 0xff); > }); > > this._map.set( >- "native operator<> uint8(double)", >- func => { >- func.implementation = ([value]) => EPtr.box(value.loadValue() & 0xff); >- }); >- >- this._map.set( >- "native operator<> float(double)", >+ "native operator float(int32)", > func => { > func.implementation = ([value]) => EPtr.box(Math.fround(value.loadValue())); > }); > > this._map.set( >- "native operator<> float(int32)", >+ "native operator float(uint32)", > func => { > func.implementation = ([value]) => EPtr.box(Math.fround(value.loadValue())); > }); > > this._map.set( >- "native operator<> float(uint32)", >+ "native operator float(uint8)", > func => { > func.implementation = ([value]) => EPtr.box(Math.fround(value.loadValue())); > }); > > this._map.set( >- "native operator<> float(uint8)", >- func => { >- func.implementation = ([value]) => EPtr.box(Math.fround(value.loadValue())); >- }); >- >- this._map.set( >- "native operator<> double(float)", >- func => { >- func.implementation = ([value]) => EPtr.box(value.loadValue()); >- }); >- >- this._map.set( >- "native operator<> double(int32)", >- func => { >- func.implementation = ([value]) => EPtr.box(value.loadValue()); >- }); >- >- this._map.set( >- "native operator<> double(uint32)", >- func => { >- func.implementation = ([value]) => EPtr.box(value.loadValue()); >- }); >- >- this._map.set( >- "native operator<> double(uint8)", >- func => { >- func.implementation = ([value]) => EPtr.box(value.loadValue()); >- }); >- >- this._map.set( >- "native int operator+<>(int,int)", >+ "native int operator+(int,int)", > func => { > func.implementation = ([left, right]) => > EPtr.box((left.loadValue() + right.loadValue()) | 0); > }); > > this._map.set( >- "native uint operator+<>(uint,uint)", >+ "native uint operator+(uint,uint)", > func => { > func.implementation = ([left, right]) => > EPtr.box((left.loadValue() + right.loadValue()) >>> 0); > }); > > this._map.set( >- "native float operator+<>(float,float)", >+ "native float operator+(float,float)", > func => { > func.implementation = ([left, right]) => > EPtr.box(Math.fround(left.loadValue() + right.loadValue())); > }); > > this._map.set( >- "native double operator+<>(double,double)", >- func => { >- func.implementation = ([left, right]) => >- EPtr.box(left.loadValue() + right.loadValue()); >- }); >- >- this._map.set( >- "native int operator-<>(int,int)", >+ "native int operator-(int,int)", > func => { > func.implementation = ([left, right]) => > EPtr.box((left.loadValue() - right.loadValue()) | 0); > }); > > this._map.set( >- "native uint operator-<>(uint,uint)", >+ "native uint operator-(uint,uint)", > func => { > func.implementation = ([left, right]) => > EPtr.box((left.loadValue() - right.loadValue()) >>> 0); > }); > > this._map.set( >- "native float operator-<>(float,float)", >+ "native float operator-(float,float)", > func => { > func.implementation = ([left, right]) => > EPtr.box(Math.fround(left.loadValue() - right.loadValue())); > }); > > this._map.set( >- "native double operator-<>(double,double)", >+ "native int operator*(int,int)", > func => { >- func.implementation = ([left, right]) => >- EPtr.box(left.loadValue() - right.loadValue()); >- }); >- >- this._map.set( >- "native int operator*<>(int,int)", >- func => { >- func.implementation = ([left, right]) => >- EPtr.box((left.loadValue() * right.loadValue()) | 0); >+ func.implementation = ([left, right]) => { >+ return EPtr.box((left.loadValue() * right.loadValue()) | 0); >+ }; > }); > > this._map.set( >- "native uint operator*<>(uint,uint)", >+ "native uint operator*(uint,uint)", > func => { > func.implementation = ([left, right]) => > EPtr.box((left.loadValue() * right.loadValue()) >>> 0); > }); > > this._map.set( >- "native float operator*<>(float,float)", >+ "native float operator*(float,float)", > func => { > func.implementation = ([left, right]) => > EPtr.box(Math.fround(left.loadValue() * right.loadValue())); > }); > > this._map.set( >- "native double operator*<>(double,double)", >- func => { >- func.implementation = ([left, right]) => >- EPtr.box(left.loadValue() * right.loadValue()); >- }); >- >- this._map.set( >- "native int operator/<>(int,int)", >+ "native int operator/(int,int)", > func => { > func.implementation = ([left, right]) => > EPtr.box((left.loadValue() / right.loadValue()) | 0); > }); > > this._map.set( >- "native uint operator/<>(uint,uint)", >+ "native uint operator/(uint,uint)", > func => { > func.implementation = ([left, right]) => > EPtr.box((left.loadValue() / right.loadValue()) >>> 0); > }); > > this._map.set( >- "native int operator&<>(int,int)", >+ "native int operator&(int,int)", > func => { > func.implementation = ([left, right]) => > EPtr.box(left.loadValue() & right.loadValue()); > }); > > this._map.set( >- "native uint operator&<>(uint,uint)", >+ "native uint operator&(uint,uint)", > func => { > func.implementation = ([left, right]) => > EPtr.box((left.loadValue() & right.loadValue()) >>> 0); > }); > > this._map.set( >- "native int operator|<>(int,int)", >+ "native int operator|(int,int)", > func => { > func.implementation = ([left, right]) => > EPtr.box(left.loadValue() | right.loadValue()); > }); > > this._map.set( >- "native uint operator|<>(uint,uint)", >+ "native uint operator|(uint,uint)", > func => { > func.implementation = ([left, right]) => > EPtr.box((left.loadValue() | right.loadValue()) >>> 0); > }); > > this._map.set( >- "native int operator^<>(int,int)", >+ "native int operator^(int,int)", > func => { > func.implementation = ([left, right]) => > EPtr.box(left.loadValue() ^ right.loadValue()); > }); > > this._map.set( >- "native uint operator^<>(uint,uint)", >+ "native uint operator^(uint,uint)", > func => { > func.implementation = ([left, right]) => > EPtr.box((left.loadValue() ^ right.loadValue()) >>> 0); > }); > > this._map.set( >- "native int operator<<<>(int,uint)", >+ "native int operator<<(int,uint)", > func => { > func.implementation = ([left, right]) => > EPtr.box(left.loadValue() << right.loadValue()); > }); > > this._map.set( >- "native uint operator<<<>(uint,uint)", >+ "native uint operator<<(uint,uint)", > func => { > func.implementation = ([left, right]) => > EPtr.box((left.loadValue() << right.loadValue()) >>> 0); > }); > > this._map.set( >- "native int operator>><>(int,uint)", >+ "native int operator>>(int,uint)", > func => { > func.implementation = ([left, right]) => > EPtr.box(left.loadValue() >> right.loadValue()); > }); > > this._map.set( >- "native uint operator>><>(uint,uint)", >+ "native uint operator>>(uint,uint)", > func => { > func.implementation = ([left, right]) => > EPtr.box(left.loadValue() >>> right.loadValue()); > }); > > this._map.set( >- "native int operator~<>(int)", >+ "native int operator~(int)", > func => { > func.implementation = ([value]) => EPtr.box(~value.loadValue()); > }); > > this._map.set( >- "native uint operator~<>(uint)", >+ "native uint operator~(uint)", > func => { > func.implementation = ([value]) => EPtr.box((~value.loadValue()) >>> 0); > }); > > this._map.set( >- "native float operator/<>(float,float)", >+ "native float operator/(float,float)", > func => { > func.implementation = ([left, right]) => > EPtr.box(Math.fround(left.loadValue() / right.loadValue())); > }); > > this._map.set( >- "native double operator/<>(double,double)", >- func => { >- func.implementation = ([left, right]) => >- EPtr.box(left.loadValue() / right.loadValue()); >- }); >- >- this._map.set( >- "native bool operator==<>(int,int)", >- func => { >- func.implementation = ([left, right]) => >- EPtr.box(left.loadValue() == right.loadValue()); >- }); >- >- this._map.set( >- "native bool operator==<>(uint,uint)", >+ "native bool operator==(int,int)", > func => { > func.implementation = ([left, right]) => > EPtr.box(left.loadValue() == right.loadValue()); > }); > > this._map.set( >- "native bool operator==<>(bool,bool)", >+ "native bool operator==(uint,uint)", > func => { > func.implementation = ([left, right]) => > EPtr.box(left.loadValue() == right.loadValue()); > }); > > this._map.set( >- "native bool operator==<>(float,float)", >+ "native bool operator==(bool,bool)", > func => { > func.implementation = ([left, right]) => > EPtr.box(left.loadValue() == right.loadValue()); > }); > > this._map.set( >- "native bool operator==<>(double,double)", >+ "native bool operator==(float,float)", > func => { > func.implementation = ([left, right]) => > EPtr.box(left.loadValue() == right.loadValue()); > }); > > this._map.set( >- "native bool operator<<>(int,int)", >- func => { >- func.implementation = ([left, right]) => >- EPtr.box(left.loadValue() < right.loadValue()); >- }); >- >- this._map.set( >- "native bool operator<<>(uint,uint)", >+ "native bool operator<(int,int)", > func => { > func.implementation = ([left, right]) => > EPtr.box(left.loadValue() < right.loadValue()); > }); > > this._map.set( >- "native bool operator<<>(float,float)", >+ "native bool operator<(uint,uint)", > func => { > func.implementation = ([left, right]) => > EPtr.box(left.loadValue() < right.loadValue()); > }); > > this._map.set( >- "native bool operator<<>(double,double)", >+ "native bool operator<(float,float)", > func => { > func.implementation = ([left, right]) => > EPtr.box(left.loadValue() < right.loadValue()); > }); > > this._map.set( >- "native bool operator<=<>(int,int)", >+ "native bool operator<=(int,int)", > func => { > func.implementation = ([left, right]) => > EPtr.box(left.loadValue() <= right.loadValue()); > }); > > this._map.set( >- "native bool operator<=<>(uint,uint)", >+ "native bool operator<=(uint,uint)", > func => { > func.implementation = ([left, right]) => > EPtr.box(left.loadValue() <= right.loadValue()); > }); > > this._map.set( >- "native bool operator<=<>(float,float)", >+ "native bool operator<=(float,float)", > func => { > func.implementation = ([left, right]) => > EPtr.box(left.loadValue() <= right.loadValue()); > }); > > this._map.set( >- "native bool operator<=<>(double,double)", >- func => { >- func.implementation = ([left, right]) => >- EPtr.box(left.loadValue() <= right.loadValue()); >- }); >- >- this._map.set( >- "native bool operator><>(int,int)", >- func => { >- func.implementation = ([left, right]) => >- EPtr.box(left.loadValue() > right.loadValue()); >- }); >- >- this._map.set( >- "native bool operator><>(uint,uint)", >+ "native bool operator>(int,int)", > func => { > func.implementation = ([left, right]) => > EPtr.box(left.loadValue() > right.loadValue()); > }); > > this._map.set( >- "native bool operator><>(float,float)", >+ "native bool operator>(uint,uint)", > func => { > func.implementation = ([left, right]) => > EPtr.box(left.loadValue() > right.loadValue()); > }); > > this._map.set( >- "native bool operator><>(double,double)", >+ "native bool operator>(float,float)", > func => { > func.implementation = ([left, right]) => > EPtr.box(left.loadValue() > right.loadValue()); > }); > > this._map.set( >- "native bool operator>=<>(int,int)", >- func => { >- func.implementation = ([left, right]) => >- EPtr.box(left.loadValue() >= right.loadValue()); >- }); >- >- this._map.set( >- "native bool operator>=<>(uint,uint)", >+ "native bool operator>=(int,int)", > func => { > func.implementation = ([left, right]) => > EPtr.box(left.loadValue() >= right.loadValue()); > }); > > this._map.set( >- "native bool operator>=<>(float,float)", >+ "native bool operator>=(uint,uint)", > func => { > func.implementation = ([left, right]) => > EPtr.box(left.loadValue() >= right.loadValue()); > }); > > this._map.set( >- "native bool operator>=<>(double,double)", >+ "native bool operator>=(float,float)", > func => { > func.implementation = ([left, right]) => > EPtr.box(left.loadValue() >= right.loadValue()); > }); >- >- for (let addressSpace of addressSpaces) { >- this._map.set( >- `native T* ${addressSpace} operator&[]<T>(T[] ${addressSpace},uint)`, >- func => { >- func.implementation = ([ref, index], node) => { >- ref = ref.loadValue(); >- if (!ref) >- throw new WTrapError(node.origin.originString, "Null dereference"); >- index = index.loadValue(); >- if (index > ref.length) >- throw new WTrapError(node.origin.originString, "Array index " + index + " is out of bounds of " + ref); >- return EPtr.box(ref.ptr.plus(index * node.instantiatedActualTypeArguments[0].size)); >- }; >- }); > >- this._map.set( >- `native uint operator.length<T>(T[] ${addressSpace})`, >- func => { >- func.implementation = ([ref], node) => { >- ref = ref.loadValue(); >- if (!ref) >- return EPtr.box(0); >- return EPtr.box(ref.length); >- }; >- }); >- } >+ for (let swizzle of SwizzleOp.functions()) >+ this._map.set(swizzle.toString(), func => swizzle.instantiateImplementation(func)); > >- for (let swizzle of SwizzleOp.allSwizzleOperators()) { >- this._map.set(swizzle.toString(), >- func => { >- func.implementation = ([vec], node) => { >- const outputBuffer = new EBuffer(swizzle.outSize); >- const readIndices = { 'x': 0, 'y': 1, 'z': 2, 'w': 3 }; >- for (let i = 0; i < swizzle.outSize; i++) >- outputBuffer.set(i, vec.get(readIndices[swizzle.components[i]])); >- >- >- return new EPtr(outputBuffer, 0); >- }, >- func.implementationData = swizzle; >- }); >- console.log(swizzle.toString()); >- } >+ for (let boolOp of OperatorBool.functions()) >+ this._map.set(boolOp.toString(), func => boolOp.instantiateImplementation(func)); >+ >+ for (let anderIndex of OperatorAnderIndexer.functions()) >+ this._map.set(anderIndex.toString(), func => anderIndex.instantiateImplementation(func)); >+ >+ for (let cast of BuiltinVectorCasts.functions()) >+ this._map.set(cast.toString(), func => cast.instantiateImplementation(func)); >+ >+ for (let getter of BuiltinVectorIndexGetter.functions()) >+ this._map.set(getter.toString(), func => getter.instantiateImplementation(func)); >+ >+ for (let setter of BuiltinVectorIndexSetter.functions()) >+ this._map.set(setter.toString(), func => setter.instantiateImplementation(func)); >+ >+ for (let equalityOperator of BuiltinVectorEqualityOperator.functions()) >+ this._map.set(equalityOperator.toString(), func => equalityOperator.instantiateImplementation(func)); >+ >+ for (let getter of BuiltinVectorGetter.functions()) >+ this._map.set(getter.toString(), func => getter.instantiateImplementation(func)); >+ >+ for (let setter of BuiltinVectorSetter.functions()) >+ this._map.set(setter.toString(), func => setter.instantiateImplementation(func)); > } > > add(thing) >diff --git a/Tools/WebGPUShadingLanguageRI/LiteralTypeChecker.js b/Tools/WebGPUShadingLanguageRI/LiteralTypeChecker.js >index 849d034d53573da3bf938f905cd60b7637dcaa53..55ae01b09018c0cda1dbc884eb5955cf87368f6c 100644 >--- a/Tools/WebGPUShadingLanguageRI/LiteralTypeChecker.js >+++ b/Tools/WebGPUShadingLanguageRI/LiteralTypeChecker.js >@@ -43,6 +43,8 @@ class LiteralTypeChecker extends Visitor { > { > if (!node.type) > throw new Error(node + " at " + node.origin.originString + " does not have type"); >+ if (!node.type.type.canRepresent(node.value)) >+ throw new Error(`${node.value} at ${node.origin.originString} cannot be represented by ${node.type}`); > } > } > >diff --git a/Tools/WebGPUShadingLanguageRI/NativeType.js b/Tools/WebGPUShadingLanguageRI/NativeType.js >index b8b1a47330b5fd51ff021af06586844c2acba8ea..7d104dd6348105af4ced1f2a62babeb6f458b4ca 100644 >--- a/Tools/WebGPUShadingLanguageRI/NativeType.js >+++ b/Tools/WebGPUShadingLanguageRI/NativeType.js >@@ -65,7 +65,7 @@ class NativeType extends Type { > > toString() > { >- return "native typedef " + this.name + "<" + this.typeParameters + ">"; >+ return `native typedef ${this.name}`; > } > } > >diff --git a/Tools/WebGPUShadingLanguageRI/NativeTypeInstance.js b/Tools/WebGPUShadingLanguageRI/NativeTypeInstance.js >index ca39e777870049ed22d7041a52014cc8e69cbc4f..25e21677c2383bcd73b9936107075f8ebaf86ad1 100644 >--- a/Tools/WebGPUShadingLanguageRI/NativeTypeInstance.js >+++ b/Tools/WebGPUShadingLanguageRI/NativeTypeInstance.js >@@ -52,7 +52,7 @@ class NativeTypeInstance extends Type { > > toString() > { >- return this.type + "<" + this.typeArguments + ">"; >+ return this.type; > } > } > >diff --git a/Tools/WebGPUShadingLanguageRI/OperatorAnderIndex.js b/Tools/WebGPUShadingLanguageRI/OperatorAnderIndex.js >new file mode 100644 >index 0000000000000000000000000000000000000000..9aac69540b6d11f31f684aacadf366c8c964f69b >--- /dev/null >+++ b/Tools/WebGPUShadingLanguageRI/OperatorAnderIndex.js >@@ -0,0 +1,77 @@ >+/* >+ * Copyright (C) 2017 Apple Inc. All rights reserved. >+ * >+ * Redistribution and use in source and binary forms, with or without >+ * modification, are permitted provided that the following conditions >+ * are met: >+ * 1. Redistributions of source code must retain the above copyright >+ * notice, this list of conditions and the following disclaimer. >+ * 2. Redistributions in binary form must reproduce the above copyright >+ * notice, this list of conditions and the following disclaimer in the >+ * documentation and/or other materials provided with the distribution. >+ * >+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY >+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE >+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR >+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR >+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, >+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, >+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR >+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY >+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT >+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE >+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. >+ */ >+"use strict"; >+ >+class OperatorAnderIndexer { >+ constructor(baseTypeName, addressSpace) >+ { >+ this._baseTypeName = baseTypeName; >+ this._addressSpace = addressSpace; >+ } >+ >+ get addressSpace() { return this._addressSpace; } >+ get baseTypeName() { return this._baseTypeName; } >+ >+ toString() >+ { >+ return `native ${this.baseTypeName}* ${this.addressSpace} operator&[](${this.baseTypeName}[] ${this.addressSpace},uint)`; >+ } >+ >+ static functions() >+ { >+ if (!this._functions) { >+ this._functions = []; >+ >+ const typeNames = [ "uint", "int", "float", "bool", "int2", "uint2", "float2", "int3", "uint3", "float3", "int4", "uint4", "float4" ]; >+ const addressSpaces = [ "thread", "threadgroup", "device", "constant" ]; >+ >+ for (let addressSpace of addressSpaces) { >+ for (let typeName of typeNames) >+ this._functions.push(new OperatorAnderIndexer(typeName, addressSpace)); >+ } >+ } >+ return this._functions; >+ } >+ >+ // static indexersForTypeName(typeName) >+ // { >+ // const addressSpaces = [ "thread", "threadgroup", "device", "constant" ]; >+ // return addressSpaces.map(addrSpace => new OperatorAnderIndexer(typeName, addrSpace)); >+ // } >+ >+ instantiateImplementation(func) >+ { >+ func.implementation = ([ref, index], node) => { >+ ref = ref.loadValue(); >+ if (!ref) >+ throw new WTrapError(node.origin.originString, "Null dereference"); >+ index = index.loadValue(); >+ if (index > ref.length) >+ throw new WTrapError(node.origin.originString, "Array index " + index + " is out of bounds of " + ref); >+ return EPtr.box(ref.ptr.plus(index * node.argumentTypes[0].elementType.size)); >+ }; >+ func.implementationData = this; >+ } >+} >\ No newline at end of file >diff --git a/Tools/WebGPUShadingLanguageRI/OperatorArrayRefLength.js b/Tools/WebGPUShadingLanguageRI/OperatorArrayRefLength.js >new file mode 100644 >index 0000000000000000000000000000000000000000..2e592073ab7b39c34ef22de00b93f37e9db846c9 >--- /dev/null >+++ b/Tools/WebGPUShadingLanguageRI/OperatorArrayRefLength.js >@@ -0,0 +1,52 @@ >+/* >+ * Copyright (C) 2017 Apple Inc. All rights reserved. >+ * >+ * Redistribution and use in source and binary forms, with or without >+ * modification, are permitted provided that the following conditions >+ * are met: >+ * 1. Redistributions of source code must retain the above copyright >+ * notice, this list of conditions and the following disclaimer. >+ * 2. Redistributions in binary form must reproduce the above copyright >+ * notice, this list of conditions and the following disclaimer in the >+ * documentation and/or other materials provided with the distribution. >+ * >+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY >+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE >+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR >+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR >+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, >+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, >+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR >+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY >+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT >+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE >+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. >+ */ >+"use strict"; >+ >+class OperatorArrayRefLength { >+ constructor(baseTypeName, addressSpace) >+ { >+ this._baseTypeName = baseTypeName; >+ this._addressSpace = addressSpace; >+ } >+ >+ get addressSpace() { return this._addressSpace; } >+ get baseTypeName() { return this._baseTypeName; } >+ >+ toString() >+ { >+ return `native uint32 ${this.addressSpace} operator.length(${this.baseTypeName}[] ${this.addressSpace})`; >+ } >+ >+ instantiateImplementation(func) >+ { >+ func.implementation = ([ref], node) => { >+ ref = ref.loadValue(); >+ if (!ref) >+ return EPtr.box(0); >+ return EPtr.box(ref.length); >+ }; >+ func.implementationData = this; >+ } >+} >\ No newline at end of file >diff --git a/Tools/WebGPUShadingLanguageRI/OperatorBool.js b/Tools/WebGPUShadingLanguageRI/OperatorBool.js >new file mode 100644 >index 0000000000000000000000000000000000000000..123a93fcadbec00ad1fbf69e865acdc299251de2 >--- /dev/null >+++ b/Tools/WebGPUShadingLanguageRI/OperatorBool.js >@@ -0,0 +1,63 @@ >+/* >+ * Copyright (C) 2017 Apple Inc. All rights reserved. >+ * >+ * Redistribution and use in source and binary forms, with or without >+ * modification, are permitted provided that the following conditions >+ * are met: >+ * 1. Redistributions of source code must retain the above copyright >+ * notice, this list of conditions and the following disclaimer. >+ * 2. Redistributions in binary form must reproduce the above copyright >+ * notice, this list of conditions and the following disclaimer in the >+ * documentation and/or other materials provided with the distribution. >+ * >+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY >+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE >+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR >+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR >+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, >+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, >+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR >+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY >+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT >+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE >+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. >+ */ >+"use strict"; >+ >+// FIXME: This needs to support registering these functions late >+ >+class OperatorBool { >+ constructor(baseTypeName) >+ { >+ this._baseTypeName = baseTypeName; >+ } >+ >+ get baseTypeName() { return this._baseTypeName; } >+ >+ toString() >+ { >+ return `native operator bool(${this.baseTypeName})`; >+ } >+ >+ static functions() >+ { >+ if (!OperatorBool._functions) { >+ OperatorBool._functions = []; >+ >+ // bool is not included because this is generated by the copy constructor >+ const typeNames = [ "uint", "int", "float", /*"bool",*/ "int2", "uint2", "float2", "int3", "uint3", "float3", "int4", "uint4", "float4" ]; >+ >+ for (let typeName of typeNames) >+ OperatorBool._functions.push(new OperatorBool(typeName)); >+ } >+ return OperatorBool._functions; >+ } >+ >+ instantiateImplementation(func) >+ { >+ func.implementation = ([ref], node) => { >+ return EPtr.box(!!ref.loadValue()); >+ } >+ func.implementationData = this; >+ } >+} >\ No newline at end of file >diff --git a/Tools/WebGPUShadingLanguageRI/Parse.js b/Tools/WebGPUShadingLanguageRI/Parse.js >index 14757478d8816b409d952b4f9038e25ebeb5e869..f2865e0a222d33a94eeddfd5fe508ff2b231f220 100644 >--- a/Tools/WebGPUShadingLanguageRI/Parse.js >+++ b/Tools/WebGPUShadingLanguageRI/Parse.js >@@ -121,12 +121,6 @@ function parse(program, origin, originKind, lineNumberOffset, text) > return result; > } > >- function parseProtocolRef() >- { >- let protocolToken = consumeKind("identifier"); >- return new ProtocolRef(protocolToken, protocolToken.text); >- } >- > function consumeEndOfTypeArgs() > { > let rightShift = tryConsume(">>"); >@@ -136,34 +130,6 @@ function parse(program, origin, originKind, lineNumberOffset, text) > consume(">"); > } > >- function parseTypeParameters() >- { >- if (!test("<")) >- return []; >- >- let result = []; >- consume("<"); >- while (!test(">")) { >- let constexpr = lexer.backtrackingScope(() => { >- let type = parseType(); >- let name = consumeKind("identifier"); >- assertNext(",", ">", ">>"); >- return new ConstexprTypeParameter(type.origin, name.text, type); >- }); >- if (constexpr) >- result.push(constexpr); >- else { >- let name = consumeKind("identifier"); >- let protocol = tryConsume(":") ? parseProtocolRef() : null; >- result.push(new TypeVariable(name, name.text, protocol)); >- } >- if (!tryConsume(",")) >- break; >- } >- consumeEndOfTypeArgs(); >- return result; >- } >- > function parseTerm() > { > let token; >@@ -201,19 +167,12 @@ function parse(program, origin, originKind, lineNumberOffset, text) > return new IntLiteral(token, intVersion); > return new UintLiteral(token, intVersion >>> 0); > } >- if (token = tryConsumeKind("doubleLiteral")) >- return new DoubleLiteral(token, +token.text); > if (token = tryConsumeKind("floatLiteral")) { > let text = token.text; >- let d = token.text.endsWith("d"); > let f = token.text.endsWith("f"); >- if (d && f) >- throw new Error("Literal cannot be both a double literal and a float literal."); >- if (d || f) >+ if (f) > text = text.substring(0, text.length - 1); > let value = parseFloat(text); >- if (d) >- return new DoubleLiteral(token, value); > return new FloatLiteral(token, Math.fround(value)); > } > if (token = tryConsume("true", "false")) >@@ -236,50 +195,6 @@ function parse(program, origin, originKind, lineNumberOffset, text) > return left; > } > >- function parseTypeArguments() >- { >- if (!test("<")) >- return []; >- >- let result = []; >- consume("<"); >- while (!test(">")) { >- // It's possible for a constexpr or type can syntactically overlap in the single >- // identifier case. Let's consider the possibilities: >- // >- // T could be type or constexpr >- // T[] only type >- // T[42] only type (constexpr cannot do indexing) >- // 42 only constexpr >- // >- // In the future we'll allow constexprs to do more things, and then we'll still have >- // the problem that something of the form T[1][2][3]... can either be a type or a >- // constexpr, and we can figure out in the checker which it is. >- let typeOrVariableRef = lexer.backtrackingScope(() => { >- let result = consumeKind("identifier"); >- assertNext(",", ">", ">>"); >- return new TypeOrVariableRef(result, result.text); >- }); >- if (typeOrVariableRef) >- result.push(typeOrVariableRef); >- else { >- let constexpr = lexer.backtrackingScope(() => { >- let result = parseConstexpr(); >- assertNext(",", ">", ">>"); >- return result; >- }); >- if (constexpr) >- result.push(constexpr); >- else >- result.push(parseType()); >- } >- if (!tryConsume(",")) >- break; >- } >- consumeEndOfTypeArgs(); >- return result; >- } >- > function parseType() > { > let token; >@@ -289,7 +204,7 @@ function parse(program, origin, originKind, lineNumberOffset, text) > addressSpace = token.text; > > let name = consumeKind("identifier"); >- let typeArguments = parseTypeArguments(); >+ let typeArguments = []; > let type = new TypeRef(name, name.text, typeArguments); > > function getAddressSpace() >@@ -325,7 +240,7 @@ function parse(program, origin, originKind, lineNumberOffset, text) > { > let origin = consume("typedef"); > let name = consumeKind("identifier").text; >- let typeParameters = parseTypeParameters(); >+ let typeParameters = []; > consume("="); > let type = parseType(); > consume(";"); >@@ -352,7 +267,7 @@ function parse(program, origin, originKind, lineNumberOffset, text) > function parseCallExpression() > { > let name = consumeKind("identifier"); >- let typeArguments = parseTypeArguments(); >+ let typeArguments = []; > consume("("); > let argumentList = []; > while (!test(")")) { >@@ -370,7 +285,6 @@ function parse(program, origin, originKind, lineNumberOffset, text) > { > return lexer.testScope(() => { > consumeKind("identifier"); >- parseTypeArguments(); > consume("("); > }); > } >@@ -865,13 +779,12 @@ function parse(program, origin, originKind, lineNumberOffset, text) > let origin; > let returnType; > let name; >- let typeParameters; >+ let typeParameters = []; > let isCast; > let shaderType; > let operatorToken = tryConsume("operator"); > if (operatorToken) { > origin = operatorToken; >- typeParameters = parseTypeParameters(); > returnType = parseType(); > name = "operator cast"; > isCast = true; >@@ -884,18 +797,11 @@ function parse(program, origin, originKind, lineNumberOffset, text) > } else > origin = returnType.origin; > name = parseFuncName(); >- typeParameters = parseTypeParameters(); > isCast = false; > } > let parameters = parseParameters(); > return new Func(origin, name, returnType, typeParameters, parameters, isCast, shaderType); > } >- >- function parseProtocolFuncDecl() >- { >- let func = parseFuncDecl(); >- return new ProtocolFuncDecl(func.origin, func.name, func.returnType, func.typeParameters, func.parameters, func.isCast, func.shaderType); >- } > > function parseFuncDef() > { >@@ -904,26 +810,6 @@ function parse(program, origin, originKind, lineNumberOffset, text) > return new FuncDef(func.origin, func.name, func.returnType, func.typeParameters, func.parameters, body, func.isCast, func.shaderType); > } > >- function parseProtocolDecl() >- { >- let origin = consume("protocol"); >- let name = consumeKind("identifier").text; >- let result = new ProtocolDecl(origin, name); >- if (tryConsume(":")) { >- while (!test("{")) { >- result.addExtends(parseProtocolRef()); >- if (!tryConsume(",")) >- break; >- } >- } >- consume("{"); >- while (!tryConsume("}")) { >- result.add(parseProtocolFuncDecl()); >- consume(";"); >- } >- return result; >- } >- > function parseField() > { > let type = parseType(); >@@ -936,7 +822,7 @@ function parse(program, origin, originKind, lineNumberOffset, text) > { > let origin = consume("struct"); > let name = consumeKind("identifier").text; >- let typeParameters = parseTypeParameters(); >+ let typeParameters = []; > let result = new StructType(origin, name, typeParameters); > consume("{"); > while (!tryConsume("}")) >@@ -956,7 +842,7 @@ function parse(program, origin, originKind, lineNumberOffset, text) > let origin = consume("native"); > if (tryConsume("typedef")) { > let name = consumeKind("identifier"); >- let parameters = parseTypeParameters(); >+ let parameters = []; > consume(";"); > return new NativeType(origin, name.text, parameters); > } >@@ -1020,8 +906,6 @@ function parse(program, origin, originKind, lineNumberOffset, text) > program.add(parseStructType()); > else if (token.text == "enum") > program.add(parseEnumType()); >- else if (token.text == "protocol") >- program.add(parseProtocolDecl()); > else > program.add(parseFuncDef()); > } >diff --git a/Tools/WebGPUShadingLanguageRI/Prepare.js b/Tools/WebGPUShadingLanguageRI/Prepare.js >index a2048a9ad3e83bd18b76444ca5546e48fe0119a0..7eb495d2b7239fe042ae0b8d48c00b8435e1b5bc 100644 >--- a/Tools/WebGPUShadingLanguageRI/Prepare.js >+++ b/Tools/WebGPUShadingLanguageRI/Prepare.js >@@ -48,6 +48,9 @@ let prepare = (() => { > checkRecursiveTypes(program); > synthesizeStructAccessors(program); > synthesizeEnumFunctions(program); >+ synthesizeArrayOperatorLength(program); >+ synthesizeCopyConstructorOperator(program); >+ synthesizeDefaultConstructorOperator(program); > resolveNamesInFunctions(program, nameResolver); > resolveTypeDefsInFunctions(program); > >@@ -64,6 +67,7 @@ let prepare = (() => { > checkRecursion(program); > checkProgramWrapped(program); > findHighZombies(program); >+ program.visit(new StructLayoutBuilder()); > inline(program); > > return program; >diff --git a/Tools/WebGPUShadingLanguageRI/SPIRV.html b/Tools/WebGPUShadingLanguageRI/SPIRV.html >index fa1f6a40a64c228fabaa75a25a47a6cebd841a97..353519c10861d877d59cfbe46b2abc0883869316 100644 >--- a/Tools/WebGPUShadingLanguageRI/SPIRV.html >+++ b/Tools/WebGPUShadingLanguageRI/SPIRV.html >@@ -18,7 +18,7 @@ td { > <script src="CreateLiteralType.js"></script> > <script src="PropertyAccessExpression.js"></script> > <script src="SwizzleOp.js"></script> >- >+ > <script src="AddressSpace.js"></script> > <script src="AnonymousVariable.js"></script> > <script src="ArrayRefType.js"></script> >@@ -47,8 +47,6 @@ td { > <script src="ConvertPtrToArrayRefExpression.js"></script> > <script src="DoWhileLoop.js"></script> > <script src="DotExpression.js"></script> >- <script src="DoubleLiteral.js"></script> >- <script src="DoubleLiteralType.js"></script> > <script src="DereferenceExpression.js"></script> > <script src="EArrayRef.js"></script> > <script src="EBuffer.js"></script> >@@ -104,6 +102,15 @@ td { > <script src="NormalUsePropertyResolver.js"></script> > <script src="NullLiteral.js"></script> > <script src="NullType.js"></script> >+ <script src="OperatorAnderIndex.js"></script> >+ <script src="OperatorArrayRefLength.js"></script> >+ <script src="OperatorBool.js"></script> >+ <script src="BuiltinVectorCasts.js"></script> >+ <script src="BuiltinVectorGetter.js"></script> >+ <script src="BuiltinVectorSetter.js"></script> >+ <script src="BuiltinVectorIndexGetter.js"></script> >+ <script src="BuiltinVectorIndexSetter.js"></script> >+ <script src="BuiltinVectorEqualityOperator.js"></script> > <script src="OriginKind.js"></script> > <script src="OverloadResolutionFailure.js"></script> > <script src="Parse.js"></script> >@@ -126,10 +133,6 @@ td { > <script src="Return.js"></script> > <script src="ReturnChecker.js"></script> > <script src="ReturnException.js"></script> >- <script src="SPIR-V.js"></script> >- <script src="SPIRVCodegen.js"></script> >- <script src="SPIRVTypeAnalyzer.js"></script> >- <script src="SPIRVVariableAnalyzer.js"></script> > <script src="StandardLibrary.js"></script> > <script src="StatementCloner.js"></script> > <script src="StructLayoutBuilder.js"></script> >@@ -137,8 +140,11 @@ td { > <script src="Substitution.js"></script> > <script src="SwitchCase.js"></script> > <script src="SwitchStatement.js"></script> >+ <script src="SynthesizeArrayOperatorLength.js"></script> > <script src="SynthesizeEnumFunctions.js"></script> > <script src="SynthesizeStructAccessors.js"></script> >+ <script src="SynthesizeCopyConstructorOperator.js"></script> >+ <script src="SynthesizeDefaultConstructorOperator.js"></script> > <script src="TrapStatement.js"></script> > <script src="TypeDef.js"></script> > <script src="TypeDefResolver.js"></script> >diff --git a/Tools/WebGPUShadingLanguageRI/SPIRVCodegen.js b/Tools/WebGPUShadingLanguageRI/SPIRVCodegen.js >index 0b54ca9a4fc408dae1168e3a7a0c82d5e87c7f9c..b4f50859a87afb60e54b360c6059c4aac8c23bca 100644 >--- a/Tools/WebGPUShadingLanguageRI/SPIRVCodegen.js >+++ b/Tools/WebGPUShadingLanguageRI/SPIRVCodegen.js >@@ -214,14 +214,6 @@ function generateSPIRV(spirv, program) > values = uintView; > break; > } >- case program.intrinsics.double: { >- let arrayBuffer = new ArrayBuffer(Math.max(Uint32Array.BYTES_PER_ELEMENT, Float64Array.BYTES_PER_ELEMENT)); >- let doubleView = new Float64Array(arrayBuffer); >- let uintView = new Uint32Array(arrayBuffer); >- doubleView[0] = node.value; >- values = uintView; >- break; >- } > default: > throw new Error("Unrecognized literal."); > } >diff --git a/Tools/WebGPUShadingLanguageRI/StandardLibrary.js b/Tools/WebGPUShadingLanguageRI/StandardLibrary.js >index 5f9ccbff1e2317e48b6eb59f7a07b119adba760c..1ddc0fc93738c026e9dc3e8f8c420833f7b4eb0e 100644 >--- a/Tools/WebGPUShadingLanguageRI/StandardLibrary.js >+++ b/Tools/WebGPUShadingLanguageRI/StandardLibrary.js >@@ -40,36 +40,25 @@ typedef int = int32; > typedef uint = uint32; > > native typedef float32; >-native typedef float64; > typedef float = float32; >-typedef double = float64; > > native operator int32(uint32); > native operator int32(uint8); > native operator int32(float); >-native operator int32(double); > native operator uint32(int32); > native operator uint32(uint8); > native operator uint32(float); >-native operator uint32(double); > native operator uint8(int32); > native operator uint8(uint32); > native operator uint8(float); >-native operator uint8(double); > native operator float(int32); > native operator float(uint32); > native operator float(uint8); >-native operator float(double); >-native operator double(float); >-native operator double(int32); >-native operator double(uint32); >-native operator double(uint8); > > native int operator+(int, int); > native uint operator+(uint, uint); > uint8 operator+(uint8 a, uint8 b) { return uint8(uint(a) + uint(b)); } > native float operator+(float, float); >-native double operator+(double, double); > int operator++(int value) { return value + 1; } > uint operator++(uint value) { return value + 1; } > uint8 operator++(uint8 value) { return value + 1; } >@@ -77,7 +66,6 @@ native int operator-(int, int); > native uint operator-(uint, uint); > uint8 operator-(uint8 a, uint8 b) { return uint8(uint(a) - uint(b)); } > native float operator-(float, float); >-native double operator-(double, double); > int operator--(int value) { return value - 1; } > uint operator--(uint value) { return value - 1; } > uint8 operator--(uint8 value) { return value - 1; } >@@ -85,7 +73,6 @@ native int operator*(int, int); > native uint operator*(uint, uint); > uint8 operator*(uint8 a, uint8 b) { return uint8(uint(a) * uint(b)); } > native float operator*(float, float); >-native double operator*(double, double); > native int operator/(int, int); > native uint operator/(uint, uint); > uint8 operator/(uint8 a, uint8 b) { return uint8(uint(a) / uint(b)); } >@@ -108,33 +95,27 @@ uint8 operator~(uint8 value) { return uint8(~uint(value)); } > uint8 operator<<(uint8 a, uint b) { return uint8(uint(a) << (b & 7)); } > uint8 operator>>(uint8 a, uint b) { return uint8(uint(a) >> (b & 7)); } > native float operator/(float, float); >-native double operator/(double, double); > native bool operator==(int, int); > native bool operator==(uint, uint); > bool operator==(uint8 a, uint8 b) { return uint(a) == uint(b); } > native bool operator==(bool, bool); > native bool operator==(float, float); >-native bool operator==(double, double); > native bool operator<(int, int); > native bool operator<(uint, uint); > bool operator<(uint8 a, uint8 b) { return uint(a) < uint(b); } > native bool operator<(float, float); >-native bool operator<(double, double); > native bool operator<=(int, int); > native bool operator<=(uint, uint); > bool operator<=(uint8 a, uint8 b) { return uint(a) <= uint(b); } > native bool operator<=(float, float); >-native bool operator<=(double, double); > native bool operator>(int, int); > native bool operator>(uint, uint); > bool operator>(uint8 a, uint8 b) { return uint(a) > uint(b); } > native bool operator>(float, float); >-native bool operator>(double, double); > native bool operator>=(int, int); > native bool operator>=(uint, uint); > bool operator>=(uint8 a, uint8 b) { return uint(a) >= uint(b); } > native bool operator>=(float, float); >-native bool operator>=(double, double); > > bool operator&(bool a, bool b) > { >@@ -164,230 +145,17 @@ bool operator~(bool value) > return !value; > } > >-protocol Addable { >- Addable operator+(Addable, Addable); >-} >- >-protocol Equatable { >- bool operator==(Equatable, Equatable); >-} >- >-restricted operator<T> T() >-{ >- T defaultValue; >- return defaultValue; >-} >- >-restricted operator<T> T(T x) >-{ >- return x; >-} >- >-operator<T:Equatable> bool(T x) >-{ >- return x != T(); >-} >- >-struct vec2<T> { >- T x; >- T y; >-} >- >-typedef int2 = vec2<int>; >-typedef uint2 = vec2<uint>; >-typedef float2 = vec2<float>; >-typedef double2 = vec2<double>; >- >-operator<T> vec2<T>(T x, T y) >-{ >- vec2<T> result; >- result.x = x; >- result.y = y; >- return result; >-} >- >-bool operator==<T:Equatable>(vec2<T> a, vec2<T> b) >-{ >- return a.x == b.x && a.y == b.y; >-} >- >-thread T* operator&[]<T>(thread vec2<T>* foo, uint index) >-{ >- if (index == 0) >- return &foo->x; >- if (index == 1) >- return &foo->y; >- trap; >-} >- >-struct vec3<T> { >- T x; >- T y; >- T z; >-} >- >-typedef int3 = vec3<int>; >-typedef uint3 = vec3<uint>; >-typedef float3 = vec3<float>; >-typedef double3 = vec3<double>; >- >-operator<T> vec3<T>(T x, T y, T z) >-{ >- vec3<T> result; >- result.x = x; >- result.y = y; >- result.z = z; >- return result; >-} >- >-operator<T> vec3<T>(vec2<T> v2, T z) >-{ >- vec3<T> result; >- result.x = v2.x; >- result.y = v2.y; >- result.z = z; >- return result; >-} >- >-operator<T> vec3<T>(T x, vec2<T> v2) >-{ >- vec3<T> result; >- result.x = x; >- result.y = v2.x; >- result.z = v2.y; >- return result; >-} >- >-bool operator==<T:Equatable>(vec3<T> a, vec3<T> b) >-{ >- return a.x == b.x && a.y == b.y && a.z == b.z; >-} >+native typedef int2; >+native typedef uint2; >+native typedef float2; > >-thread T* operator&[]<T>(thread vec3<T>* foo, uint index) >-{ >- if (index == 0) >- return &foo->x; >- if (index == 1) >- return &foo->y; >- if (index == 2) >- return &foo->z; >- trap; >-} >- >-struct vec4<T> { >- T x; >- T y; >- T z; >- T w; >-} >- >-typedef int4 = vec4<int>; >-typedef uint4 = vec4<uint>; >-typedef float4 = vec4<float>; >-typedef double4 = vec4<double>; >- >-operator<T> vec4<T>(T x, T y, T z, T w) >-{ >- vec4<T> result; >- result.x = x; >- result.y = y; >- result.z = z; >- result.w = w; >- return result; >-} >- >-operator<T> vec4<T>(vec2<T> v2, T z, T w) >-{ >- vec4<T> result; >- result.x = v2.x; >- result.y = v2.y; >- result.z = z; >- result.w = w; >- return result; >-} >- >-operator<T> vec4<T>(T x, vec2<T> v2, T w) >-{ >- vec4<T> result; >- result.x = x; >- result.y = v2.x; >- result.z = v2.y; >- result.w = w; >- return result; >-} >- >-operator<T> vec4<T>(T x, T y, vec2<T> v2) >-{ >- vec4<T> result; >- result.x = x; >- result.y = y; >- result.z = v2.x; >- result.w = v2.y; >- return result; >-} >- >-operator<T> vec4<T>(vec2<T> v2a, vec2<T> v2b) >-{ >- vec4<T> result; >- result.x = v2a.x; >- result.y = v2a.y; >- result.z = v2b.x; >- result.w = v2b.y; >- return result; >-} >+native typedef int3; >+native typedef uint3; >+native typedef float3; > >-operator<T> vec4<T>(vec3<T> v3, T w) >-{ >- vec4<T> result; >- result.x = v3.x; >- result.y = v3.y; >- result.z = v3.z; >- result.w = w; >- return result; >-} >- >-operator<T> vec4<T>(T x, vec3<T> v3) >-{ >- vec4<T> result; >- result.x = x; >- result.y = v3.x; >- result.z = v3.y; >- result.w = v3.z; >- return result; >-} >- >-bool operator==<T:Equatable>(vec4<T> a, vec4<T> b) >-{ >- return a.x == b.x && a.y == b.y && a.z == b.z && a.w == b.w; >-} >- >-thread T* operator&[]<T>(thread vec4<T>* foo, uint index) >-{ >- if (index == 0) >- return &foo->x; >- if (index == 1) >- return &foo->y; >- if (index == 2) >- return &foo->z; >- if (index == 3) >- return &foo->w; >- trap; >-} >- >-native thread T* operator&[]<T>(thread T[], uint); >-native threadgroup T* operator&[]<T>(threadgroup T[], uint); >-native device T* operator&[]<T>(device T[], uint); >-native constant T* operator&[]<T>(constant T[], uint); >- >-native uint operator.length<T>(thread T[]); >-native uint operator.length<T>(threadgroup T[]); >-native uint operator.length<T>(device T[]); >-native uint operator.length<T>(constant T[]); >- >-uint operator.length<T, uint length>(T[length]) >-{ >- return length; >-} >+native typedef int4; >+native typedef uint4; >+native typedef float4; > `; > > function intToString(x) >@@ -406,6 +174,18 @@ function intToString(x) > } > } > >+function addFunctionsFromClass(clss) >+{ >+ standardLibrary += clss.functions().join(";\n") + "\n"; >+} >+ > // There are 481 swizzle operators, so we compile them as native functions >-standardLibrary += SwizzleOp.allSwizzleOperators().join(";\n") + ";"; >-console.log(standardLibrary); >\ No newline at end of file >+standardLibrary += SwizzleOp.functions().join(";\n") + ";\n"; >+standardLibrary += OperatorBool.functions().join(";\n") + ";\n"; >+standardLibrary += OperatorAnderIndexer.functions().join(";\n") + ";\n"; >+standardLibrary += BuiltinVectorCasts.functions().join(";\n") + ";\n"; >+standardLibrary += BuiltinVectorGetter.functions().join(";\n") + ";\n"; >+standardLibrary += BuiltinVectorSetter.functions().join(";\n") + ";\n"; >+standardLibrary += BuiltinVectorIndexGetter.functions().join(";\n") + ";\n"; >+standardLibrary += BuiltinVectorIndexSetter.functions().join(";\n") + ";\n"; >+standardLibrary += BuiltinVectorEqualityOperator.functions().join(";\n") + ";\n"; >diff --git a/Tools/WebGPUShadingLanguageRI/StructType.js b/Tools/WebGPUShadingLanguageRI/StructType.js >index f9d8c7da485832161e55d22a43876299337cb936..556966d95f74a629eda208885b037ded6a6ff9b2 100644 >--- a/Tools/WebGPUShadingLanguageRI/StructType.js >+++ b/Tools/WebGPUShadingLanguageRI/StructType.js >@@ -45,6 +45,7 @@ class StructType extends Type { > get name() { return this._name; } > get origin() { return this._origin; } > get typeParameters() { return this._typeParameters; } >+ get isStruct() { return true; } > > get fieldNames() { return this._fields.keys(); } > fieldByName(name) { return this._fields.get(name); } >@@ -94,6 +95,6 @@ class StructType extends Type { > > toString() > { >- return "struct " + this.name + "<" + this.typeParameters + "> { " + Array.from(this.fields).join("; ") + "; }"; >+ return `struct ${this.name} { ${Array.from(this.fields).join("; ")}; }`; > } > } >diff --git a/Tools/WebGPUShadingLanguageRI/SwizzleOp.js b/Tools/WebGPUShadingLanguageRI/SwizzleOp.js >index d1c5bd0e6b3920f571de7c209486036b94548a74..22c9f0912949a2785900044738bdaffbbcc221da 100644 >--- a/Tools/WebGPUShadingLanguageRI/SwizzleOp.js >+++ b/Tools/WebGPUShadingLanguageRI/SwizzleOp.js >@@ -25,49 +25,69 @@ > "use strict"; > > class SwizzleOp { >- constructor(outSize, components, inSize) >+ constructor(baseTypeName, outSize, components, inSize) > { >+ this._baseTypeName = baseTypeName; > this._outSize = outSize; > this._components = components.slice(); // Shallow clone > this._inSize = inSize; > } > >+ get baseTypeName() { return this._baseTypeName; } > get outSize() { return this._outSize; } > get components() { return this._components; } > get inSize() { return this._inSize; } > > toString() > { >- return `native vec${this.outSize}<T> operator.${this.components.join("")}<T>(vec${this.inSize}<T> v)`; >+ return `native ${this.baseTypeName}${this.outSize} operator.${this.components.join("")}(${this.baseTypeName}${this.inSize} v)`; > } > >- static allSwizzleOperators() >+ static functions() > { >- if (!SwizzleOp._allSwizzleOperators) { >- SwizzleOp._allSwizzleOperators = []; >+ if (!this._functions) { >+ // We can't directly use this._functions in _generateSwizzles >+ const functions = []; > >- function _generateSwizzle(maxDepth, maxItems, array) { >+ function _generateSwizzle(baseTypeName, maxDepth, maxItems, array) { > if (!array) > array = []; > if (array.length == maxDepth) { >- SwizzleOp._allSwizzleOperators.push(new SwizzleOp(array.length, array, maxItems)); >+ functions.push(new SwizzleOp(baseTypeName, array.length, array, maxItems)); > return; > } > for (let i = 0; i < maxItems; ++i) { > array.push(intToString(i)); >- _generateSwizzle(maxDepth, maxItems, array); >+ _generateSwizzle(baseTypeName, maxDepth, maxItems, array); > array.pop(); > } > }; > >- for (let maxDepth = 2; maxDepth <= 4; maxDepth++) { >- for (let maxItems = 2; maxItems <= 4; maxItems++) >- _generateSwizzle(maxDepth, maxItems); >+ const typeNames = [ "uint", "int", "float" ]; >+ >+ for (let typeName of typeNames) { >+ for (let maxDepth = 2; maxDepth <= 4; maxDepth++) { >+ for (let maxItems = 2; maxItems <= 4; maxItems++) >+ _generateSwizzle(typeName, maxDepth, maxItems); >+ } > } >+ >+ this._functions = functions; > } >- return SwizzleOp._allSwizzleOperators; >+ return this._functions; > } >-} > >-// Initialise the static member (JS doesn't allow static fields declared in the class) >-SwizzleOp._allSwizzleOperators = null; >\ No newline at end of file >+ instantiateImplementation(func) >+ { >+ func.implementation = ([vec], node) => { >+ const outputBuffer = new EBuffer(this.outSize); >+ const readIndices = { 'x': 0, 'y': 1, 'z': 2, 'w': 3 }; >+ for (let i = 0; i < this.outSize; i++) >+ outputBuffer.set(i, vec.get(readIndices[this.components[i]])); >+ >+ >+ return new EPtr(outputBuffer, 0); >+ }; >+ func.implementationData = this; >+ } >+} >\ No newline at end of file >diff --git a/Tools/WebGPUShadingLanguageRI/SynthesizeArrayOperatorLength.js b/Tools/WebGPUShadingLanguageRI/SynthesizeArrayOperatorLength.js >new file mode 100644 >index 0000000000000000000000000000000000000000..69a817020db078d86a8ee283e4f6cb3472decf0e >--- /dev/null >+++ b/Tools/WebGPUShadingLanguageRI/SynthesizeArrayOperatorLength.js >@@ -0,0 +1,50 @@ >+/* >+ * Copyright (C) 2017 Apple Inc. All rights reserved. >+ * >+ * Redistribution and use in source and binary forms, with or without >+ * modification, are permitted provided that the following conditions >+ * are met: >+ * 1. Redistributions of source code must retain the above copyright >+ * notice, this list of conditions and the following disclaimer. >+ * 2. Redistributions in binary form must reproduce the above copyright >+ * notice, this list of conditions and the following disclaimer in the >+ * documentation and/or other materials provided with the distribution. >+ * >+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY >+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE >+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR >+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR >+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, >+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, >+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR >+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY >+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT >+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE >+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. >+ */ >+"use strict"; >+ >+function synthesizeArrayOperatorLength(program) >+{ >+ const arrayTypes = new Set(); >+ >+ class FindArrayTypes extends Visitor { >+ visitArrayType(node) >+ { >+ arrayTypes.add(node); >+ } >+ } >+ >+ program.visit(new FindArrayTypes()); >+ >+ for (let arrayType of arrayTypes) { >+ let nativeFunc = new NativeFunc( >+ arrayType.origin, "operator.length", new TypeRef(arrayType.origin, "uint32", []), [], >+ [ >+ new FuncParameter(arrayType.origin, null, TypeRef.wrap(arrayType)) >+ ], >+ false, null); >+ nativeFunc.implementation = ([array]) => EPtr.box(arrayType.size); >+ program.add(nativeFunc); >+ } >+} >diff --git a/Tools/WebGPUShadingLanguageRI/SynthesizeCopyConstructorOperator.js b/Tools/WebGPUShadingLanguageRI/SynthesizeCopyConstructorOperator.js >new file mode 100644 >index 0000000000000000000000000000000000000000..40a4b647337d493231c5aeb6e109ffb8e4ef4920 >--- /dev/null >+++ b/Tools/WebGPUShadingLanguageRI/SynthesizeCopyConstructorOperator.js >@@ -0,0 +1,63 @@ >+/* >+ * Copyright (C) 2017 Apple Inc. All rights reserved. >+ * >+ * Redistribution and use in source and binary forms, with or without >+ * modification, are permitted provided that the following conditions >+ * are met: >+ * 1. Redistributions of source code must retain the above copyright >+ * notice, this list of conditions and the following disclaimer. >+ * 2. Redistributions in binary form must reproduce the above copyright >+ * notice, this list of conditions and the following disclaimer in the >+ * documentation and/or other materials provided with the distribution. >+ * >+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY >+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE >+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR >+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR >+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, >+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, >+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR >+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY >+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT >+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE >+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. >+ */ >+"use strict"; >+ >+function synthesizeCopyConstructorOperator(program) >+{ >+ const types = new Set(); >+ >+ class FindAllTypes extends Visitor { >+ visitNativeType(node) >+ { >+ types.add(node); >+ } >+ >+ visitStructType(node) >+ { >+ types.add(node); >+ super.visitStructType(node); >+ } >+ >+ visitElementalType(node) >+ { >+ types.add(node); >+ super.visitElementalType(node); >+ } >+ } >+ >+ program.visit(new FindAllTypes()); >+ >+ for (let type of types) { >+ let nativeFunc = new NativeFunc(type.origin, "operator cast", TypeRef.wrap(type), [], [ >+ new FuncParameter(type.origin, null, TypeRef.wrap(type)) >+ ], true, null); >+ nativeFunc.implementation = ([arg], node) => { >+ let result = new EPtr(new EBuffer(type.size), 0); >+ result.copyFrom(arg, type.size); >+ return result; >+ }; >+ program.add(nativeFunc); >+ } >+} >diff --git a/Tools/WebGPUShadingLanguageRI/SynthesizeDefaultConstructorOperator.js b/Tools/WebGPUShadingLanguageRI/SynthesizeDefaultConstructorOperator.js >new file mode 100644 >index 0000000000000000000000000000000000000000..89074fae27fae0f16931bf005a6f73726fe6cab6 >--- /dev/null >+++ b/Tools/WebGPUShadingLanguageRI/SynthesizeDefaultConstructorOperator.js >@@ -0,0 +1,61 @@ >+/* >+ * Copyright (C) 2017 Apple Inc. All rights reserved. >+ * >+ * Redistribution and use in source and binary forms, with or without >+ * modification, are permitted provided that the following conditions >+ * are met: >+ * 1. Redistributions of source code must retain the above copyright >+ * notice, this list of conditions and the following disclaimer. >+ * 2. Redistributions in binary form must reproduce the above copyright >+ * notice, this list of conditions and the following disclaimer in the >+ * documentation and/or other materials provided with the distribution. >+ * >+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY >+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE >+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR >+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR >+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, >+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, >+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR >+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY >+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT >+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE >+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. >+ */ >+"use strict"; >+ >+function synthesizeDefaultConstructorOperator(program) >+{ >+ const types = new Set(); >+ >+ class FindAllTypes extends Visitor { >+ visitNativeType(node) >+ { >+ types.add(node); >+ } >+ >+ visitStructType(node) >+ { >+ types.add(node); >+ super.visitStructType(node); >+ } >+ >+ visitElementalType(node) >+ { >+ types.add(node); >+ super.visitElementalType(node); >+ } >+ } >+ >+ program.visit(new FindAllTypes()); >+ >+ for (let type of types) { >+ let nativeFunc = new NativeFunc(type.origin, "operator cast", TypeRef.wrap(type), [], [], true, null); >+ nativeFunc.implementation = ([], node) => { >+ let result = new EPtr(new EBuffer(type.size), 0); >+ node.type.populateDefaultValue(result.buffer, 0); >+ return result; >+ }; >+ program.add(nativeFunc); >+ } >+} >diff --git a/Tools/WebGPUShadingLanguageRI/Test.html b/Tools/WebGPUShadingLanguageRI/Test.html >index 21c77f6a021f55d3b441dfbd642039bf73850ffa..18ba09e1bceaf8acdc28cf7bf3a152c8b4da1f6a 100644 >--- a/Tools/WebGPUShadingLanguageRI/Test.html >+++ b/Tools/WebGPUShadingLanguageRI/Test.html >@@ -41,8 +41,6 @@ > <script src="ConvertPtrToArrayRefExpression.js"></script> > <script src="DoWhileLoop.js"></script> > <script src="DotExpression.js"></script> >-<script src="DoubleLiteral.js"></script> >-<script src="DoubleLiteralType.js"></script> > <script src="DereferenceExpression.js"></script> > <script src="EArrayRef.js"></script> > <script src="EBuffer.js"></script> >@@ -98,6 +96,15 @@ > <script src="NormalUsePropertyResolver.js"></script> > <script src="NullLiteral.js"></script> > <script src="NullType.js"></script> >+<script src="OperatorAnderIndex.js"></script> >+<script src="OperatorArrayRefLength.js"></script> >+<script src="OperatorBool.js"></script> >+<script src="BuiltinVectorCasts.js"></script> >+<script src="BuiltinVectorGetter.js"></script> >+<script src="BuiltinVectorSetter.js"></script> >+<script src="BuiltinVectorIndexGetter.js"></script> >+<script src="BuiltinVectorIndexSetter.js"></script> >+<script src="BuiltinVectorEqualityOperator.js"></script> > <script src="OriginKind.js"></script> > <script src="OverloadResolutionFailure.js"></script> > <script src="Parse.js"></script> >@@ -127,8 +134,11 @@ > <script src="Substitution.js"></script> > <script src="SwitchCase.js"></script> > <script src="SwitchStatement.js"></script> >+<script src="SynthesizeArrayOperatorLength.js"></script> > <script src="SynthesizeEnumFunctions.js"></script> > <script src="SynthesizeStructAccessors.js"></script> >+<script src="SynthesizeCopyConstructorOperator.js"></script> >+<script src="SynthesizeDefaultConstructorOperator.js"></script> > <script src="TrapStatement.js"></script> > <script src="TypeDef.js"></script> > <script src="TypeDefResolver.js"></script> >diff --git a/Tools/WebGPUShadingLanguageRI/Test.js b/Tools/WebGPUShadingLanguageRI/Test.js >index 3614ead894f2dc9f0f4c7d752385d0e09cfc4f02..789a0fd4b8faad1d53b889dcec249cdb0e9524a9 100644 >--- a/Tools/WebGPUShadingLanguageRI/Test.js >+++ b/Tools/WebGPUShadingLanguageRI/Test.js >@@ -78,11 +78,6 @@ function makeFloat(program, value) > return TypedValue.box(program.intrinsics.float, value); > } > >-function makeDouble(program, value) >-{ >- return TypedValue.box(program.intrinsics.double, value); >-} >- > function makeEnum(program, enumName, value) > { > let enumType = program.types.get(enumName); >@@ -149,14 +144,6 @@ function checkFloat(program, result, expected) > throw new Error("Wrong result: " + result.value + " (expected " + expected + ")"); > } > >-function checkDouble(program, result, expected) >-{ >- if (!result.type.equals(program.intrinsics.double)) >- throw new Error("Wrong result type: " + result.type); >- if (result.value != expected) >- throw new Error("Wrong result: " + result.value + " (expected " + expected + ")"); >-} >- > function checkLexerToken(result, expectedIndex, expectedKind, expectedText) > { > if (result._index != expectedIndex) >@@ -320,14 +307,6 @@ tests.add1 = function() { > checkInt(program, callFunction(program, "foo", [], [makeInt(program, 42)]), 43); > } > >-tests.simpleGeneric = function() { >- let program = doPrep(` >- T id<T>(T x) { return x; } >- int foo(int x) { return id(x) + 1; } >- `); >- checkInt(program, callFunction(program, "foo", [], [makeInt(program, 42)]), 43); >-} >- > tests.nameResolutionFailure = function() > { > checkFail( >@@ -526,24 +505,6 @@ tests.deviceArrayStoreIntLiteral = function() > throw new Error("Bad value stored into buffer (expected -111): " + buffer.get(0)); > } > >-tests.simpleProtocol = function() >-{ >- let program = doPrep(` >- protocol MyAddable { >- MyAddable operator+(MyAddable, MyAddable); >- } >- T add<T:MyAddable>(T a, T b) >- { >- return a + b; >- } >- int foo(int x) >- { >- return add(x, 73); >- } >- `); >- checkInt(program, callFunction(program, "foo", [], [makeInt(program, 45)]), 45 + 73); >-} >- > tests.typeMismatchReturn = function() > { > checkFail( >@@ -597,18 +558,17 @@ tests.badAdd = function() > { > checkFail( > () => doPrep(` >- void bar<T>(T) { } > void foo(int x, uint y) > { >- bar(x + y); >+ uint z = x + y; > } > `), >- (e) => e instanceof WTypeError && e.message.indexOf("native int32 operator+<>(int32,int32)") != -1); >+ (e) => e instanceof WTypeError && e.message.indexOf("native int32 operator+(int32,int32)") != -1); > } > > tests.lexerKeyword = function() > { >- let result = doLex("ident for while 123 123u { } {asd asd{ 1a3 1.2 + 3.4 + 1. + .2 1.2d 0.d .3d && ||"); >+ let result = doLex("ident for while 123 123u { } {asd asd{ 1a3 1.2 + 3.4 + 1. + .2 1.2f 0.f .3f && ||"); > if (result.length != 25) > throw new Error("Lexer emitted an incorrect number of tokens (expected 23): " + result.length); > checkLexerToken(result[0], 0, "identifier", "ident"); >@@ -631,9 +591,9 @@ tests.lexerKeyword = function() > checkLexerToken(result[17], 55, "floatLiteral", "1."); > checkLexerToken(result[18], 58, "punctuation", "+"); > checkLexerToken(result[19], 60, "floatLiteral", ".2"); >- checkLexerToken(result[20], 63, "floatLiteral", "1.2d"); >- checkLexerToken(result[21], 68, "floatLiteral", "0.d"); >- checkLexerToken(result[22], 72, "floatLiteral", ".3d"); >+ checkLexerToken(result[20], 63, "floatLiteral", "1.2f"); >+ checkLexerToken(result[21], 68, "floatLiteral", "0.f"); >+ checkLexerToken(result[22], 72, "floatLiteral", ".3f"); > checkLexerToken(result[23], 76, "punctuation", "&&"); > checkLexerToken(result[24], 79, "punctuation", "||"); > } >@@ -690,57 +650,11 @@ tests.simpleStruct = function() > throw new Error("Wrong result for y: " + y + " (x + " + x + ")"); > } > >-tests.genericStructInstance = function() >-{ >- let program = doPrep(` >- struct Foo<T> { >- T x; >- T y; >- } >- Foo<int> foo(Foo<int> foo) >- { >- Foo<int> result; >- result.x = foo.y; >- result.y = foo.x; >- return result; >- } >- `); >- let structType = TypeRef.instantiate(program.types.get("Foo"), [program.intrinsics.int32]); >- let buffer = new EBuffer(2); >- buffer.set(0, 62); >- buffer.set(1, 24); >- let result = callFunction(program, "foo", [], [new TypedValue(structType, new EPtr(buffer, 0))]); >- let x = result.ePtr.get(0); >- let y = result.ePtr.get(1); >- if (x != 24) >- throw new Error("Wrong result for x: " + x + " (y = " + y + ")"); >- if (y != 62) >- throw new Error("Wrong result for y: " + y + " (x + " + x + ")"); >-} >- >-tests.doubleGenericCallsDoubleGeneric = function() >-{ >- doPrep(` >- void foo<T, U>(T, U) { } >- void bar<V, W>(V x, W y) { foo(x, y); } >- `); >-} >- >-tests.doubleGenericCallsSingleGeneric = function() >-{ >- checkFail( >- () => doPrep(` >- void foo<T>(T, T) { } >- void bar<V, W>(V x, W y) { foo(x, y); } >- `), >- (e) => e instanceof WTypeError); >-} >- > tests.loadNull = function() > { > checkFail( > () => doPrep(` >- void sink<T>(T) { } >+ void sink(thread int* x) { } > void foo() { sink(*null); } > `), > (e) => e instanceof WTypeError && e.message.indexOf("Type passed to dereference is not a pointer: null") != -1); >@@ -814,43 +728,11 @@ tests.passNullToPtrMonomorphic = function() > (e) => e instanceof WTrapError); > } > >-tests.passNullToPtrPolymorphic = function() >-{ >- checkFail( >- () => doPrep(` >- T foo<T>(thread T* ptr) >- { >- return *ptr; >- } >- int bar() >- { >- return foo(null); >- } >- `), >- (e) => e instanceof WTypeError); >-} >- >-tests.passNullToPolymorphic = function() >-{ >- checkFail( >- () => doPrep(` >- T foo<T>(T ptr) >- { >- return ptr; >- } >- int bar() >- { >- return foo(null); >- } >- `), >- (e) => e instanceof WTypeError); >-} >- > tests.loadNullArrayRef = function() > { > checkFail( > () => doPrep(` >- void sink<T>(T) { } >+ void sink(thread int* x) { } > void foo() { sink(null[0u]); } > `), > (e) => e instanceof WTypeError && e.message.indexOf("Cannot resolve access") != -1); >@@ -938,31 +820,15 @@ tests.passNullToPtrMonomorphicArrayRef = function() > (e) => e instanceof WTrapError); > } > >-tests.passNullToPtrPolymorphicArrayRef = function() >-{ >- checkFail( >- () => doPrep(` >- T foo<T>(thread T[] ptr) >- { >- return ptr[0u]; >- } >- int bar() >- { >- return foo(null); >- } >- `), >- (e) => e instanceof WTypeError); >-} >- > tests.returnIntLiteralUint = function() > { > let program = doPrep("uint foo() { return 42; }"); > checkNumber(program, callFunction(program, "foo", [], []), 42); > } > >-tests.returnIntLiteralDouble = function() >+tests.returnIntLiteralFloat = function() > { >- let program = doPrep("double foo() { return 42; }"); >+ let program = doPrep("float foo() { return 42; }"); > checkNumber(program, callFunction(program, "foo", [], []), 42); > } > >@@ -980,64 +846,13 @@ tests.badIntLiteralForUint = function() > (e) => e instanceof WSyntaxError); > } > >-tests.badIntLiteralForDouble = function() >+tests.badIntLiteralForFloat = function() > { > checkFail( >- () => doPrep("void foo() { double x = 5000000000000000000000000000000000000; }"), >+ () => doPrep("void foo() { float x = 5000000000000000000000000000000000000; }"), > (e) => e instanceof WSyntaxError); > } > >-tests.passNullAndNotNull = function() >-{ >- let program = doPrep(` >- T bar<T>(device T* p, device T*) >- { >- return *p; >- } >- int foo(device int* p) >- { >- return bar(p, null); >- } >- `); >- let buffer = new EBuffer(1); >- buffer.set(0, 13); >- checkInt(program, callFunction(program, "foo", [], [TypedValue.box(new PtrType(externalOrigin, "device", program.intrinsics.int32), new EPtr(buffer, 0))]), 13); >-} >- >-tests.passNullAndNotNullFullPoly = function() >-{ >- let program = doPrep(` >- T bar<T>(T p, T) >- { >- return p; >- } >- int foo(device int* p) >- { >- return *bar(p, null); >- } >- `); >- let buffer = new EBuffer(1); >- buffer.set(0, 13); >- checkInt(program, callFunction(program, "foo", [], [TypedValue.box(new PtrType(externalOrigin, "device", program.intrinsics.int32), new EPtr(buffer, 0))]), 13); >-} >- >-tests.passNullAndNotNullFullPolyReverse = function() >-{ >- let program = doPrep(` >- T bar<T>(T, T p) >- { >- return p; >- } >- int foo(device int* p) >- { >- return *bar(null, p); >- } >- `); >- let buffer = new EBuffer(1); >- buffer.set(0, 13); >- checkInt(program, callFunction(program, "foo", [], [TypedValue.box(new PtrType(externalOrigin, "device", program.intrinsics.int32), new EPtr(buffer, 0))]), 13); >-} >- > tests.nullTypeVariableUnify = function() > { > let left = new NullType(externalOrigin); >@@ -1112,122 +927,14 @@ tests.simpleRecursion = function() > { > checkFail( > () => doPrep(` >- void foo<T>(T x) >+ void foo(int x) > { >- foo(&x); >+ foo(x); > } > `), > (e) => e instanceof WTypeError); > } > >-tests.protocolMonoSigPolyDef = function() >-{ >- let program = doPrep(` >- struct IntAnd<T> { >- int first; >- T second; >- } >- IntAnd<T> intAnd<T>(int first, T second) >- { >- IntAnd<T> result; >- result.first = first; >- result.second = second; >- return result; >- } >- protocol IntAndable { >- IntAnd<int> intAnd(IntAndable, int); >- } >- int foo<T:IntAndable>(T first, int second) >- { >- IntAnd<int> result = intAnd(first, second); >- return result.first + result.second; >- } >- `); >- checkInt(program, callFunction(program, "foo", [], [makeInt(program, 54), makeInt(program, 12)]), 54 + 12); >-} >- >-tests.protocolPolySigPolyDef = function() >-{ >- let program = doPrep(` >- struct IntAnd<T> { >- int first; >- T second; >- } >- IntAnd<T> intAnd<T>(int first, T second) >- { >- IntAnd<T> result; >- result.first = first; >- result.second = second; >- return result; >- } >- protocol IntAndable { >- IntAnd<T> intAnd<T>(IntAndable, T); >- } >- int foo<T:IntAndable>(T first, int second) >- { >- IntAnd<int> result = intAnd(first, second); >- return result.first + result.second; >- } >- `); >- checkInt(program, callFunction(program, "foo", [], [makeInt(program, 54), makeInt(program, 12)]), 54 + 12); >-} >- >-tests.protocolDoublePolySigDoublePolyDef = function() >-{ >- let program = doPrep(` >- struct IntAnd<T, U> { >- int first; >- T second; >- U third; >- } >- IntAnd<T, U> intAnd<T, U>(int first, T second, U third) >- { >- IntAnd<T, U> result; >- result.first = first; >- result.second = second; >- result.third = third; >- return result; >- } >- protocol IntAndable { >- IntAnd<T, U> intAnd<T, U>(IntAndable, T, U); >- } >- int foo<T:IntAndable>(T first, int second, int third) >- { >- IntAnd<int, int> result = intAnd(first, second, third); >- return result.first + result.second + result.third; >- } >- `); >- checkInt(program, callFunction(program, "foo", [], [makeInt(program, 54), makeInt(program, 12), makeInt(program, 39)]), 54 + 12 + 39); >-} >- >-tests.protocolDoublePolySigDoublePolyDefExplicit = function() >-{ >- let program = doPrep(` >- struct IntAnd<T, U> { >- int first; >- T second; >- U third; >- } >- IntAnd<T, U> intAnd<T, U>(int first, T second, U third) >- { >- IntAnd<T, U> result; >- result.first = first; >- result.second = second; >- result.third = third; >- return result; >- } >- protocol IntAndable { >- IntAnd<T, U> intAnd<T, U>(IntAndable, T, U); >- } >- int foo<T:IntAndable>(T first, int second, int third) >- { >- IntAnd<int, int> result = intAnd<int, int>(first, second, third); >- return result.first + result.second + result.third; >- } >- `); >- checkInt(program, callFunction(program, "foo", [], [makeInt(program, 54), makeInt(program, 12), makeInt(program, 39)]), 54 + 12 + 39); >-} >- > tests.variableShadowing = function() > { > let program = doPrep(` >@@ -1478,76 +1185,12 @@ tests.simpleWhile = function() > checkInt(program, callFunction(program, "foo", [], [makeInt(program, 1)]), 16); > } > >-tests.protocolMonoPolySigDoublePolyDefExplicit = function() >-{ >- checkFail( >- () => { >- let program = doPrep(` >- struct IntAnd<T, U> { >- int first; >- T second; >- U third; >- } >- IntAnd<T, U> intAnd<T, U>(int first, T second, U third) >- { >- IntAnd<T, U> result; >- result.first = first; >- result.second = second; >- result.third = third; >- return result; >- } >- protocol IntAndable { >- IntAnd<T, int> intAnd<T>(IntAndable, T, int); >- } >- int foo<T:IntAndable>(T first, int second, int third) >- { >- IntAnd<int, int> result = intAnd<int>(first, second, third); >- return result.first + result.second + result.third; >- } >- `); >- callFunction(program, "foo", [], [makeInt(program, 54), makeInt(program, 12), makeInt(program, 39)]); >- }, >- (e) => e instanceof WTypeError); >-} >- >-tests.ambiguousOverloadSimple = function() >-{ >- checkFail( >- () => doPrep(` >- void foo<T>(int, T) { } >- void foo<T>(T, int) { } >- void bar(int a, int b) { foo(a, b); } >- `), >- (e) => e instanceof WTypeError); >-} >- >-tests.ambiguousOverloadOverlapping = function() >-{ >- checkFail( >- () => doPrep(` >- void foo<T>(int, T) { } >- void foo<T>(T, T) { } >- void bar(int a, int b) { foo(a, b); } >- `), >- (e) => e instanceof WTypeError); >-} >- >-tests.ambiguousOverloadTieBreak = function() >-{ >- doPrep(` >- void foo<T>(int, T) { } >- void foo<T>(T, T) { } >- void foo(int, int) { } >- void bar(int a, int b) { foo(a, b); } >- `); >-} >- > tests.intOverloadResolution = function() > { > let program = doPrep(` > int foo(int) { return 1; } > int foo(uint) { return 2; } >- int foo(double) { return 3; } >+ int foo(float) { return 3; } > int bar() { return foo(42); } > `); > checkInt(program, callFunction(program, "bar", [], []), 1); >@@ -1556,7 +1199,7 @@ tests.intOverloadResolution = function() > tests.intOverloadResolutionReverseOrder = function() > { > let program = doPrep(` >- int foo(double) { return 3; } >+ int foo(float) { return 3; } > int foo(uint) { return 2; } > int foo(int) { return 1; } > int bar() { return foo(42); } >@@ -1564,82 +1207,6 @@ tests.intOverloadResolutionReverseOrder = function() > checkInt(program, callFunction(program, "bar", [], []), 1); > } > >-tests.intOverloadResolutionGeneric = function() >-{ >- let program = doPrep(` >- int foo(int) { return 1; } >- int foo<T>(T) { return 2; } >- int bar() { return foo(42); } >- `); >- checkInt(program, callFunction(program, "bar", [], []), 1); >-} >- >-tests.intLiteralGeneric = function() >-{ >- let program = doPrep(` >- int foo<T>(T x) { return 3478; } >- int bar() { return foo(42); } >- `); >- checkInt(program, callFunction(program, "bar", [], []), 3478); >-} >- >-tests.intLiteralGenericWithProtocols = function() >-{ >- let program = doPrep(` >- protocol MyConvertibleToInt { >- operator int(MyConvertibleToInt); >- } >- int foo<T:MyConvertibleToInt>(T x) { return int(x); } >- int bar() { return foo(42); } >- `); >- checkInt(program, callFunction(program, "bar", [], []), 42); >-} >- >-tests.uintLiteralGeneric = function() >-{ >- let program = doPrep(` >- int foo<T>(T x) { return 3478; } >- int bar() { return foo(42u); } >- `); >- checkInt(program, callFunction(program, "bar", [], []), 3478); >-} >- >-tests.uintLiteralGenericWithProtocols = function() >-{ >- let program = doPrep(` >- protocol MyConvertibleToUint { >- operator uint(MyConvertibleToUint); >- } >- uint foo<T:MyConvertibleToUint>(T x) { return uint(x); } >- uint bar() { return foo(42u); } >- `); >- checkUint(program, callFunction(program, "bar", [], []), 42); >-} >- >-tests.intLiteralGenericSpecific = function() >-{ >- let program = doPrep(` >- T foo<T>(T x) { return x; } >- int bar() { return foo(int(42)); } >- `); >- checkInt(program, callFunction(program, "bar", [], []), 42); >-} >- >-tests.simpleConstexpr = function() >-{ >- let program = doPrep(` >- int foo<int a>(int b) >- { >- return a + b; >- } >- int bar(int b) >- { >- return foo<42>(b); >- } >- `); >- checkInt(program, callFunction(program, "bar", [], [makeInt(program, 58)]), 58 + 42); >-} >- > tests.break = function() > { > let program = doPrep(` >@@ -1993,225 +1560,7 @@ tests.forLoop = function() > checkInt(program, callFunction(program, "foo", [], [makeInt(program, 7)]), 7); > } > >-tests.chainConstexpr = function() >-{ >- let program = doPrep(` >- int foo<int a>(int b) >- { >- return a + b; >- } >- int bar<int a>(int b) >- { >- return foo<a>(b); >- } >- int baz(int b) >- { >- return bar<42>(b); >- } >- `); >- checkInt(program, callFunction(program, "baz", [], [makeInt(program, 58)]), 58 + 42); >-} >- >-tests.chainGeneric = function() >-{ >- let program = doPrep(` >- T foo<T>(T x) >- { >- return x; >- } >- T bar<T>(thread T* ptr) >- { >- return *foo(ptr); >- } >- int baz(int x) >- { >- return bar(&x); >- } >- `); >- checkInt(program, callFunction(program, "baz", [], [makeInt(program, 37)]), 37); >-} >- >-tests.chainStruct = function() >-{ >- let program = doPrep(` >- struct Foo<T> { >- T f; >- } >- struct Bar<T> { >- Foo<thread T*> f; >- } >- int foo(thread Bar<int>* x) >- { >- return *x->f.f; >- } >- int bar(int a) >- { >- Bar<int> x; >- x.f.f = &a; >- return foo(&x); >- } >- `); >- checkInt(program, callFunction(program, "bar", [], [makeInt(program, 4657)]), 4657); >-} >- >-tests.chainStructNewlyValid = function() >-{ >- let program = doPrep(` >- struct Foo<T> { >- T f; >- } >- struct Bar<T> { >- Foo<device T*> f; >- } >- int foo(thread Bar<int>* x) >- { >- return *x->f.f; >- } >- int bar(device int* a) >- { >- Bar<int> x; >- x.f.f = a; >- return foo(&x); >- } >- `); >- let buffer = new EBuffer(1); >- buffer.set(0, 78453); >- checkInt(program, callFunction(program, "bar", [], [TypedValue.box(new PtrType(externalOrigin, "device", program.intrinsics.int32), new EPtr(buffer, 0))]), 78453); >-} >- >-tests.chainStructDevice = function() >-{ >- let program = doPrep(` >- struct Foo<T> { >- T f; >- } >- struct Bar<T> { >- Foo<device T*> f; >- } >- int foo(thread Bar<int>* x) >- { >- return *x->f.f; >- } >- int bar(device int* a) >- { >- Bar<int> x; >- x.f.f = a; >- return foo(&x); >- } >- `); >- let buffer = new EBuffer(1); >- buffer.set(0, 79201); >- checkInt(program, callFunction(program, "bar", [], [TypedValue.box(new PtrType(externalOrigin, "device", program.intrinsics.int32), new EPtr(buffer, 0))]), 79201); >-} >- >-tests.paramChainStructDevice = function() >-{ >- let program = doPrep(` >- struct Foo<T> { >- T f; >- } >- struct Bar<T> { >- Foo<T> f; >- } >- int foo(thread Bar<device int*>* x) >- { >- return *x->f.f; >- } >- int bar(device int* a) >- { >- Bar<device int*> x; >- x.f.f = a; >- return foo(&x); >- } >- `); >- let buffer = new EBuffer(1); >- buffer.set(0, 79201); >- checkInt(program, callFunction(program, "bar", [], [TypedValue.box(new PtrType(externalOrigin, "device", program.intrinsics.int32), new EPtr(buffer, 0))]), 79201); >-} >- >-tests.simpleProtocolExtends = function() >-{ >- let program = doPrep(` >- protocol Foo { >- void foo(thread Foo*); >- } >- protocol Bar : Foo { >- void bar(thread Bar*); >- } >- void fuzz<T:Foo>(thread T* p) >- { >- foo(p); >- } >- void buzz<T:Bar>(thread T* p) >- { >- fuzz(p); >- bar(p); >- } >- void foo(thread int* p) >- { >- *p = *p + 743; >- } >- void bar(thread int* p) >- { >- *p = *p + 91; >- } >- int thingy(int a) >- { >- buzz(&a); >- return a; >- } >- `); >- checkInt(program, callFunction(program, "thingy", [], [makeInt(program, 642)]), 642 + 743 + 91); >-} >- >-tests.protocolExtendsTwo = function() >-{ >- let program = doPrep(` >- protocol Foo { >- void foo(thread Foo*); >- } >- protocol Bar { >- void bar(thread Bar*); >- } >- protocol Baz : Foo, Bar { >- void baz(thread Baz*); >- } >- void fuzz<T:Foo>(thread T* p) >- { >- foo(p); >- } >- void buzz<T:Bar>(thread T* p) >- { >- bar(p); >- } >- void xuzz<T:Baz>(thread T* p) >- { >- fuzz(p); >- buzz(p); >- baz(p); >- } >- void foo(thread int* p) >- { >- *p = *p + 743; >- } >- void bar(thread int* p) >- { >- *p = *p + 91; >- } >- void baz(thread int* p) >- { >- *p = *p + 39; >- } >- int thingy(int a) >- { >- xuzz(&a); >- return a; >- } >- `); >- checkInt(program, callFunction(program, "thingy", [], [makeInt(program, 642)]), 642 + 743 + 91 + 39); >-} >- >-tests.prefixPlusPlus = function() >+tests.prefixPlusPlus = function() > { > let program = doPrep(` > int foo(int x) >@@ -2406,66 +1755,6 @@ tests.twoIntLiterals = function() > checkBool(program, callFunction(program, "foo", [], []), true); > } > >-tests.unifyDifferentLiterals = function() >-{ >- checkFail( >- () => doPrep(` >- void bar<T>(T, T) >- { >- } >- void foo() >- { >- bar(42, 42u); >- } >- `), >- (e) => e instanceof WTypeError); >-} >- >-tests.unifyDifferentLiteralsBackwards = function() >-{ >- checkFail( >- () => doPrep(` >- void bar<T>(T, T) >- { >- } >- void foo() >- { >- bar(42u, 42); >- } >- `), >- (e) => e instanceof WTypeError); >-} >- >-tests.unifyVeryDifferentLiterals = function() >-{ >- checkFail( >- () => doPrep(` >- void bar<T>(T, T) >- { >- } >- void foo() >- { >- bar(42, null); >- } >- `), >- (e) => e instanceof WTypeError); >-} >- >-tests.unifyVeryDifferentLiteralsBackwards = function() >-{ >- checkFail( >- () => doPrep(` >- void bar<T>(T, T) >- { >- } >- void foo() >- { >- bar(null, 42); >- } >- `), >- (e) => e instanceof WTypeError); >-} >- > tests.assignUintToInt = function() > { > checkFail( >@@ -2691,7 +1980,7 @@ tests.simpleLength = function() > let program = doPrep(` > uint foo() > { >- double[754] array; >+ float[754] array; > return (@array).length; > } > `); >@@ -2703,11 +1992,17 @@ tests.nonArrayRefArrayLengthSucceed = function() > let program = doPrep(` > uint foo() > { >- double[754] array; >+ float[754] array; >+ return array.length; >+ } >+ uint bar() >+ { >+ int[754] array; > return array.length; > } > `); > checkUint(program, callFunction(program, "foo", [], []), 754); >+ checkUint(program, callFunction(program, "bar", [], []), 754); > } > > tests.nonArrayRefArrayLengthFail = function() >@@ -2723,70 +2018,34 @@ tests.nonArrayRefArrayLengthFail = function() > e => e instanceof WTypeError); > } > >-tests.constexprIsNotLValuePtr = function() >-{ >- checkFail( >- () => doPrep(` >- thread int* foo<int x>() >- { >- return &x; >- } >- `), >- e => e instanceof WTypeError); >-} >- >-tests.constexprIsNotLValueAssign = function() >-{ >- checkFail( >- () => doPrep(` >- void foo<int x>() >- { >- x = 42; >- } >- `), >- e => e instanceof WTypeError); >-} >- >-tests.constexprIsNotLValueRMW = function() >-{ >- checkFail( >- () => doPrep(` >- void foo<int x>() >- { >- x += 42; >- } >- `), >- e => e instanceof WTypeError); >-} >- > tests.assignLength = function() > { > checkFail( > () => doPrep(` > void foo() > { >- double[754] array; >+ float[754] array; > (@array).length = 42; > } > `), >- (e) => e instanceof WTypeError && e.message.indexOf("Have neither ander nor setter") != -1); >+ (e) => e instanceof WTypeError); > } > > tests.assignLengthHelper = function() > { > checkFail( > () => doPrep(` >- void bar(thread double[] array) >+ void bar(thread float[] array) > { > array.length = 42; > } > void foo() > { >- double[754] array; >+ float[754] array; > bar(@array); > } > `), >- (e) => e instanceof WTypeError && e.message.indexOf("Have neither ander nor setter") != -1); >+ (e) => e instanceof WTypeError); > } > > tests.simpleGetter = function() >@@ -2834,235 +2093,6 @@ tests.simpleSetter = function() > checkInt(program, callFunction(program, "foo", [], []), 7804); > } > >-tests.genericAccessors = function() >-{ >- let program = doPrep(` >- struct Foo<T> { >- T x; >- T[3] y; >- } >- struct Bar<T> { >- T x; >- T y; >- } >- Bar<T> operator.z<T>(Foo<T> foo) >- { >- Bar<T> result; >- result.x = foo.x; >- result.y = foo.y[1]; >- return result; >- } >- Foo<T> operator.z=<T>(Foo<T> foo, Bar<T> bar) >- { >- foo.x = bar.x; >- foo.y[1] = bar.y; >- return foo; >- } >- T operator.sum<T:Addable>(Foo<T> foo) >- { >- return foo.x + foo.y[0] + foo.y[1] + foo.y[2]; >- } >- T operator.sum<T:Addable>(Bar<T> bar) >- { >- return bar.x + bar.y; >- } >- operator<T> Bar<T>(T x, T y) >- { >- Bar<T> result; >- result.x = x; >- result.y = y; >- return result; >- } >- void setup(thread Foo<int>* foo) >- { >- foo->x = 1; >- foo->y[0] = 2; >- foo->y[1] = 3; >- foo->y[2] = 4; >- } >- int testSuperBasic() >- { >- Foo<int> foo; >- setup(&foo); >- return foo.sum; >- } >- int testZSetterDidSetY() >- { >- Foo<int> foo; >- foo.z = Bar<int>(53, 932); >- return foo.y[1]; >- } >- int testZSetter() >- { >- Foo<int> foo; >- foo.z = Bar<int>(53, 932); >- return foo.sum; >- } >- int testZGetter() >- { >- Foo<int> foo; >- // This deliberately does not call setup() just so we test this syntax. >- foo.x = 1; >- foo.y[0] = 2; >- foo.y[1] = 3; >- foo.y[2] = 4; >- return foo.z.sum; >- } >- int testLValueEmulation() >- { >- Foo<int> foo; >- setup(&foo); >- foo.z.y *= 5; >- return foo.sum; >- } >- `); >- checkInt(program, callFunction(program, "testSuperBasic", [], []), 1 + 2 + 3 + 4); >- checkInt(program, callFunction(program, "testZSetterDidSetY", [], []), 932); >- checkInt(program, callFunction(program, "testZSetter", [], []), 53 + 932); >- checkInt(program, callFunction(program, "testZGetter", [], []), 1 + 3); >- checkInt(program, callFunction(program, "testLValueEmulation", [], []), 1 + 2 + 3 * 5 + 4); >-} >- >-tests.bitSubscriptAccessor = function() >-{ >- let program = doPrep(` >- protocol MyBitmaskable : Equatable { >- MyBitmaskable operator&(MyBitmaskable, MyBitmaskable); >- MyBitmaskable operator|(MyBitmaskable, MyBitmaskable); >- MyBitmaskable operator~(MyBitmaskable); >- MyBitmaskable operator<<(MyBitmaskable, uint); >- MyBitmaskable operator>>(MyBitmaskable, uint); >- operator MyBitmaskable(int); >- } >- T maskForBitIndex<T:MyBitmaskable>(uint index) >- { >- return T(1) << index; >- } >- bool operator[]<T:MyBitmaskable>(T value, uint index) >- { >- return bool(value & maskForBitIndex<T>(index)); >- } >- T operator[]=<T:MyBitmaskable>(T value, uint index, bool bit) >- { >- T mask = maskForBitIndex<T>(index); >- if (bit) >- value |= mask; >- else >- value &= ~mask; >- return value; >- } >- uint operator.length(int) >- { >- return 32; >- } >- uint operator.length(uint) >- { >- return 32; >- } >- int testIntSetBit3() >- { >- int foo; >- foo[3] = true; >- return foo; >- } >- bool testIntSetGetBit5() >- { >- int foo; >- foo[5] = true; >- return foo[5]; >- } >- bool testIntGetBit1() >- { >- int foo; >- return foo[1]; >- } >- int testUintSumBits() >- { >- int foo = 42; >- int result; >- for (uint i = 0; i < foo.length; ++i) { >- if (foo[i]) >- result++; >- } >- return result; >- } >- int testUintSwapBits() >- { >- int foo = 42; >- for (uint i = 0; i < foo.length / 2; ++i) { >- bool tmp = foo[i]; >- foo[i] = foo[foo.length - i - 1]; >- foo[foo.length - i - 1] = tmp; >- } >- return foo; >- } >- struct Foo { >- uint f; >- uint g; >- } >- operator Foo(uint f, uint g) >- { >- Foo result; >- result.f = f; >- result.g = g; >- return result; >- } >- int operator.h(Foo foo) >- { >- return int((foo.f & 0xffff) | ((foo.g & 0xffff) << 16)); >- } >- Foo operator.h=(Foo foo, int value) >- { >- foo.f &= ~0xffffu; >- foo.f |= uint(value) & 0xffff; >- foo.g &= ~0xffffu; >- foo.g |= (uint(value) >> 16) & 0xffff; >- return foo; >- } >- int testLValueEmulation() >- { >- Foo foo; >- foo.f = 42; >- foo.g = 37; >- for (uint i = 0; i < foo.h.length; ++i) >- foo.h[i] ^= true; >- return int(foo.f + foo.g); >- } >- struct Bar { >- Foo a; >- Foo b; >- } >- Foo operator.c(Bar bar) >- { >- return Foo(uint(bar.a.h), uint(bar.b.h)); >- } >- Bar operator.c=(Bar bar, Foo foo) >- { >- bar.a.h = int(foo.f); >- bar.b.h = int(foo.g); >- return bar; >- } >- int testCrazyLValueEmulation() >- { >- Bar bar; >- bar.a.f = 1; >- bar.a.g = 2; >- bar.b.f = 3; >- bar.b.g = 4; >- for (uint i = 0; i < bar.c.h.length; i += 2) >- bar.c.h[i] ^= true; >- return int(bar.a.f + bar.a.g + bar.b.f + bar.b.g); >- } >- `); >- checkInt(program, callFunction(program, "testIntSetBit3", [], []), 8); >- checkBool(program, callFunction(program, "testIntSetGetBit5", [], []), true); >- checkBool(program, callFunction(program, "testIntGetBit1", [], []), false); >- checkInt(program, callFunction(program, "testUintSumBits", [], []), 3); >- checkInt(program, callFunction(program, "testUintSwapBits", [], []), 1409286144); >- checkInt(program, callFunction(program, "testLValueEmulation", [], []), 130991); >- checkInt(program, callFunction(program, "testCrazyLValueEmulation", [], []), 43696); >-} >- > tests.nestedSubscriptLValueEmulationSimple = function() > { > let program = doPrep(` >@@ -3167,117 +2197,6 @@ tests.nestedSubscriptLValueEmulationSimple = function() > checkInt(program, callFunction(program, "testSetValuesMutateValuesAndSum", [], []), 5565); > } > >-tests.nestedSubscriptLValueEmulationGeneric = function() >-{ >- let program = doPrep(` >- struct Foo<T> { >- T[7] array; >- } >- T operator[]<T>(Foo<T> foo, uint index) >- { >- return foo.array[index]; >- } >- Foo<T> operator[]=<T>(Foo<T> foo, uint index, T value) >- { >- foo.array[index] = value; >- return foo; >- } >- uint operator.length<T>(Foo<T> foo) >- { >- return foo.array.length; >- } >- protocol MyAddable { >- MyAddable operator+(MyAddable, MyAddable); >- } >- T sum<T:MyAddable>(Foo<T> foo) >- { >- T result; >- for (uint i = foo.length; i--;) >- result += foo[i]; >- return result; >- } >- struct Bar<T> { >- Foo<T>[6] array; >- } >- uint operator.length<T>(Bar<T> bar) >- { >- return bar.array.length; >- } >- Foo<T> operator[]<T>(Bar<T> bar, uint index) >- { >- return bar.array[index]; >- } >- Bar<T> operator[]=<T>(Bar<T> bar, uint index, Foo<T> value) >- { >- bar.array[index] = value; >- return bar; >- } >- T sum<T:MyAddable>(Bar<T> bar) >- { >- T result; >- for (uint i = bar.length; i--;) >- result += sum(bar[i]); >- return result; >- } >- struct Baz<T> { >- Bar<T>[5] array; >- } >- Bar<T> operator[]<T>(Baz<T> baz, uint index) >- { >- return baz.array[index]; >- } >- Baz<T> operator[]=<T>(Baz<T> baz, uint index, Bar<T> value) >- { >- baz.array[index] = value; >- return baz; >- } >- uint operator.length<T>(Baz<T> baz) >- { >- return baz.array.length; >- } >- T sum<T:MyAddable>(Baz<T> baz) >- { >- T result; >- for (uint i = baz.length; i--;) >- result += sum(baz[i]); >- return result; >- } >- protocol MyConvertibleFromUint { >- operator MyConvertibleFromUint(uint); >- } >- protocol SetValuable : MyAddable, MyConvertibleFromUint { } >- void setValues<T:SetValuable>(thread Baz<T>* baz) >- { >- for (uint i = baz->length; i--;) { >- for (uint j = (*baz)[i].length; j--;) { >- for (uint k = (*baz)[i][j].length; k--;) >- (*baz)[i][j][k] = T(i + j + k); >- } >- } >- } >- int testSetValuesAndSum() >- { >- Baz<int> baz; >- setValues(&baz); >- return sum(baz); >- } >- int testSetValuesMutateValuesAndSum() >- { >- Baz<int> baz; >- setValues(&baz); >- for (uint i = baz.length; i--;) { >- for (uint j = baz[i].length; j--;) { >- for (uint k = baz[i][j].length; k--;) >- baz[i][j][k] *= int(k); >- } >- } >- return sum(baz); >- } >- `); >- checkInt(program, callFunction(program, "testSetValuesAndSum", [], []), 1575); >- checkInt(program, callFunction(program, "testSetValuesMutateValuesAndSum", [], []), 5565); >-} >- > tests.boolBitAnd = function() > { > let program = doPrep(` >@@ -3605,7 +2524,7 @@ tests.floatMath = function() > } > bool foo5() > { >- return 42.5d == 42.5d; >+ return 42.5f == 42.5f; > } > float bar(float x) > { >@@ -3619,10 +2538,6 @@ tests.floatMath = function() > { > return bar(7.5f); > } >- float foo8() >- { >- return bar(7.5d); >- } > float foo9() > { > return float(7.5); >@@ -3631,24 +2546,15 @@ tests.floatMath = function() > { > return float(7.5f); > } >- float foo11() >- { >- return float(7.5d); >- } > float foo12() > { > return float(7); > } > float foo13() > { >- double x = 7.5d; >+ float x = 7.5f; > return float(x); > } >- double foo14() >- { >- double x = 7.5f; >- return double(x); >- } > `); > checkBool(program, callFunction(program, "foo", [], []), true); > checkBool(program, callFunction(program, "foo2", [], []), true); >@@ -3657,13 +2563,10 @@ tests.floatMath = function() > checkBool(program, callFunction(program, "foo5", [], []), true); > checkFloat(program, callFunction(program, "foo6", [], []), 7.5); > checkFloat(program, callFunction(program, "foo7", [], []), 7.5); >- checkFloat(program, callFunction(program, "foo8", [], []), 7.5); > checkFloat(program, callFunction(program, "foo9", [], []), 7.5); > checkFloat(program, callFunction(program, "foo10", [], []), 7.5); >- checkFloat(program, callFunction(program, "foo11", [], []), 7.5); > checkFloat(program, callFunction(program, "foo12", [], []), 7); > checkFloat(program, callFunction(program, "foo13", [], []), 7.5); >- checkDouble(program, callFunction(program, "foo14", [], []), 7.5); > checkFail( > () => doPrep(` > int bar(int x) >@@ -3684,7 +2587,7 @@ tests.floatMath = function() > } > int foo() > { >- bar(4.d); >+ bar(4.f); > } > `), > (e) => e instanceof WTypeError); >@@ -3720,7 +2623,7 @@ tests.floatMath = function() > } > int foo() > { >- bar(4.d); >+ bar(4.f); > } > `), > (e) => e instanceof WTypeError); >@@ -3736,63 +2639,6 @@ tests.floatMath = function() > } > `), > (e) => e instanceof WTypeError); >- checkFail( >- () => doPrep(` >- float bar(float x) >- { >- return x; >- } >- void foo() >- { >- bar(16777217.d); >- } >- `), >- (e) => e instanceof WTypeError); >- checkFail( >- () => doPrep(` >- float bar(float x) >- { >- return x; >- } >- float foo() >- { >- double x = 7.; >- return bar(x); >- } >- `), >- (e) => e instanceof WTypeError); >- checkFail( >- () => doPrep(` >- float foo() >- { >- double x = 7.; >- return x; >- } >- `), >- (e) => e instanceof WTypeError); >-} >- >-tests.genericCastInfer = function() >-{ >- let program = doPrep(` >- struct Complex<T> { >- T real; >- T imag; >- } >- operator<T> Complex<T>(T real, T imag) >- { >- Complex<T> result; >- result.real = real; >- result.imag = imag; >- return result; >- } >- int foo() >- { >- Complex<int> x = Complex<int>(1, 2); >- return x.real + x.imag; >- } >- `); >- checkInt(program, callFunction(program, "foo", [], []), 3); > } > > tests.booleanMath = function() >@@ -4146,44 +2992,6 @@ tests.builtinVectors = function() > float3 c = float3(3., 4., 6.); > return b == c; > } >- double food() >- { >- double2 a = double2(3., 4.); >- return a[0]; >- } >- double food2() >- { >- double2 a = double2(3., 4.); >- double3 b = double3(a, 5.); >- return b[1]; >- } >- double food3() >- { >- double3 a = double3(3., 4., 5.); >- double4 b = double4(6., a); >- return b[1]; >- } >- double food4() >- { >- double2 a = double2(3., 4.); >- double2 b = double2(5., 6.); >- double4 c = double4(a, b); >- return c[2]; >- } >- bool food5() >- { >- double4 a = double4(3., 4., 5., 6.); >- double2 b = double2(4., 5.); >- double4 c = double4(3., b, 6.); >- return a == c; >- } >- bool food6() >- { >- double2 a = double2(4., 5.); >- double3 b = double3(3., a); >- double3 c = double3(3., 4., 6.); >- return b == c; >- } > `); > checkInt(program, callFunction(program, "foo", [], []), 3); > checkInt(program, callFunction(program, "foo2", [], []), 4); >@@ -4203,49 +3011,116 @@ tests.builtinVectors = function() > checkFloat(program, callFunction(program, "foof4", [], []), 5); > checkBool(program, callFunction(program, "foof5", [], []), true); > checkBool(program, callFunction(program, "foof6", [], []), false); >- checkDouble(program, callFunction(program, "food", [], []), 3); >- checkDouble(program, callFunction(program, "food2", [], []), 4); >- checkDouble(program, callFunction(program, "food3", [], []), 3); >- checkDouble(program, callFunction(program, "food4", [], []), 5); >- checkBool(program, callFunction(program, "food5", [], []), true); >- checkBool(program, callFunction(program, "food6", [], []), false); > } > >-tests.instantiateStructInStruct = function() >+tests.builtinVectorGetters = function() > { >- let program = doPrep(` >- struct Bar<T> { >- T x; >- } >- struct Foo { >- Bar<int> x; >- } >- int foo() >- { >- Foo x; >- x.x.x = 42; >- x.x.x++; >- return x.x.x; >+ const typeNames = [ "uint", "int", "float" ]; >+ const sizes = [ 2, 3, 4 ]; >+ const elements = [ "x", "y", "z", "w" ]; >+ const initializerList = [ 1, 2, 3, 4 ]; >+ >+ let tests = []; >+ let src = ""; >+ for (let typeName of typeNames) { >+ for (let size of sizes) { >+ for (let i = 0; i < size; i++) { >+ const functionName = `${typeName}${size}${elements[i]}`; >+ src += `${typeName} ${functionName}() >+ { >+ ${typeName}${size} x = ${typeName}${size}(${initializerList.slice(0, size).join(", ")}); >+ return x.${elements[i]}; >+ } >+ `; >+ tests.push({ type: typeName, name: functionName, expectation: initializerList[i] }); >+ } > } >- `); >- checkInt(program, callFunction(program, "foo", [], []), 43); >+ } >+ >+ let program = doPrep(src); >+ const checkFuncs = { >+ "uint": checkUint, >+ "int": checkInt, >+ "float": checkFloat >+ }; >+ for (let test of tests) { >+ const checkFunc = checkFuncs[test.type]; >+ checkFunc(program, callFunction(program, test.name, [], []), test.expectation); >+ } > } > >-tests.instantiateStructInStructWithInt2 = function() >+tests.builtinVectorSetters = function() > { >- let program = doPrep(` >- struct Foo { >- int2 x; >+ const typeNames = [ "uint", "int", "float" ]; >+ const sizes = [ 2, 3, 4 ]; >+ const elements = [ "x", "y", "z", "w" ]; >+ const initializerList = [ 1, 2, 3, 4 ]; >+ >+ let tests = []; >+ let src = ""; >+ for (let typeName of typeNames) { >+ for (let size of sizes) { >+ for (let i = 0; i < size; i++) { >+ const functionName = `${typeName}${size}${elements[i]}`; >+ src += `${typeName} ${functionName}() >+ { >+ ${typeName}${size} x = ${typeName}${size}(${initializerList.slice(0, size).join(", ")}); >+ x.${elements[i]} = 34; >+ return x.${elements[i]}; >+ } >+ `; >+ tests.push({ type: typeName, name: functionName, expectation: 34 }); >+ } > } >- int foo() >- { >- Foo x; >- x.x.x = 42; >- x.x.x++; >- return x.x.x; >+ } >+ >+ let program = doPrep(src); >+ const checkFuncs = { >+ "uint": checkUint, >+ "int": checkInt, >+ "float": checkFloat >+ }; >+ for (let test of tests) { >+ const checkFunc = checkFuncs[test.type]; >+ checkFunc(program, callFunction(program, test.name, [], []), test.expectation); >+ } >+} >+ >+tests.builtinVectorIndexSetters = function() >+{ >+ const typeNames = [ "uint", "int", "float" ]; >+ const sizes = [ 2, 3, 4 ]; >+ const elements = [ "x", "y", "z", "w" ]; >+ const initializerList = [ 1, 2, 3, 4 ]; >+ >+ let tests = []; >+ let src = ""; >+ for (let typeName of typeNames) { >+ for (let size of sizes) { >+ for (let i = 0; i < size; i++) { >+ const functionName = `${typeName}${size}${elements[i]}`; >+ src += `${typeName} ${functionName}() >+ { >+ ${typeName}${size} x = ${typeName}${size}(${initializerList.slice(0, size).join(", ")}); >+ x[${i}] = 34; >+ return x[${i}]; >+ } >+ `; >+ tests.push({ type: typeName, name: functionName, expectation: 34 }); >+ } > } >- `); >- checkInt(program, callFunction(program, "foo", [], []), 43); >+ } >+ >+ let program = doPrep(src); >+ const checkFuncs = { >+ "uint": checkUint, >+ "int": checkInt, >+ "float": checkFloat >+ }; >+ for (let test of tests) { >+ const checkFunc = checkFuncs[test.type]; >+ checkFunc(program, callFunction(program, test.name, [], []), test.expectation); >+ } > } > > tests.simpleEnum = function() >@@ -4490,39 +3365,6 @@ tests.enumWithSomeManualValues = function() > checkEnum(program, callFunction(program, "death", [], []), 1); > } > >-tests.enumConstexprGenericFunction = function() >-{ >- let program = doPrep(` >- enum Axis { X, Y } >- int foo<Axis axis>() { return int(axis); } >- int testX() { return foo<Axis.X>(); } >- int testY() { return foo<Axis.Y>(); } >- `); >- checkInt(program, callFunction(program, "testX", [], []), 0); >- checkInt(program, callFunction(program, "testY", [], []), 1); >-} >- >-tests.enumConstexprGenericStruct = function() >-{ >- let program = doPrep(` >- enum Axis { X, Y } >- struct Foo<Axis axis> { } >- int foo<Axis axis>(Foo<axis>) { return int(axis); } >- int testX() >- { >- Foo<Axis.X> f; >- return foo(f); >- } >- int testY() >- { >- Foo<Axis.Y> f; >- return foo(f); >- } >- `); >- checkInt(program, callFunction(program, "testX", [], []), 0); >- checkInt(program, callFunction(program, "testY", [], []), 1); >-} >- > tests.trap = function() > { > let program = doPrep(` >@@ -4971,18 +3813,18 @@ tests.simpleSwitch = function() > > tests.exhaustiveUint8Switch = function() > { >- let text = "double foo(uint8 x) { switch (uint8(x)) {" >+ let text = "float foo(uint8 x) { switch (uint8(x)) {" > for (let i = 0; i <= 0xff; ++i) > text += "case " + i + ": return " + i * 1.5 + ";"; > text += "} }"; > let program = doPrep(text); > for (let i = 0; i < 0xff; ++i) >- checkDouble(program, callFunction(program, "foo", [], [makeUint8(program, i)]), i * 1.5); >+ checkFloat(program, callFunction(program, "foo", [], [makeUint8(program, i)]), i * 1.5); > } > > tests.notQuiteExhaustiveUint8Switch = function() > { >- let text = "double foo(uint8 x) { switch (uint8(x)) {" >+ let text = "float foo(uint8 x) { switch (uint8(x)) {" > for (let i = 0; i <= 0xfe; ++i) > text += "case " + i + ": return " + i * 1.5 + ";"; > text += "} }"; >@@ -4991,14 +3833,14 @@ tests.notQuiteExhaustiveUint8Switch = function() > > tests.notQuiteExhaustiveUint8SwitchWithDefault = function() > { >- let text = "double foo(uint8 x) { switch (uint8(x)) {" >+ let text = "float foo(uint8 x) { switch (uint8(x)) {" > for (let i = 0; i <= 0xfe; ++i) > text += "case " + i + ": return " + i * 1.5 + ";"; > text += "default: return " + 0xff * 1.5 + ";"; > text += "} }"; > let program = doPrep(text); > for (let i = 0; i < 0xff; ++i) >- checkDouble(program, callFunction(program, "foo", [], [makeUint8(program, i)]), i * 1.5); >+ checkFloat(program, callFunction(program, "foo", [], [makeUint8(program, i)]), i * 1.5); > } > > tests.switchFallThrough = function() >@@ -5327,7 +4169,7 @@ tests.setterWithMismatchedType = function() > { > checkFail( > () => doPrep(` >- double operator.foo(int) >+ float operator.foo(int) > { > return 5.43; > } >@@ -5353,23 +4195,6 @@ tests.setterWithMatchedType = function() > `); > } > >-tests.operatorWithUninferrableTypeVariable = function() >-{ >- checkFail( >- () => doPrep(` >- struct Foo { >- int x; >- } >- Foo operator+<T>(Foo a, Foo b) >- { >- Foo result; >- result.x = a.x + b.x; >- return result; >- } >- `), >- e => e instanceof WTypeError); >-} >- > tests.operatorWithoutUninferrableTypeVariable = function() > { > let program = doPrep(` >@@ -5394,53 +4219,6 @@ tests.operatorWithoutUninferrableTypeVariable = function() > checkInt(program, callFunction(program, "foo", [], []), 645 - 35); > } > >-tests.operatorCastWithUninferrableTypeVariable = function() >-{ >- checkFail( >- () => doPrep(` >- struct Foo { >- int x; >- } >- operator<T> Foo(int x) >- { >- Foo result; >- result.x = x; >- return result; >- } >- `), >- e => e instanceof WTypeError); >-} >- >-tests.operatorCastWithTypeVariableInferredFromReturnType = function() >-{ >- let program = doPrep(` >- struct Foo { >- int x; >- } >- protocol Barable { >- void bar(thread Barable*, int); >- } >- void bar(thread double* result, int value) >- { >- *result = double(value); >- } >- operator<T:Barable> T(Foo foo) >- { >- T result; >- bar(&result, foo.x); >- return result; >- } >- int foo() >- { >- Foo foo; >- foo.x = 75; >- double x = double(foo); >- return int(x * 1.5); >- } >- `); >- checkInt(program, callFunction(program, "foo", [], []), 112); >-} >- > tests.incWrongArgumentLength = function() > { > checkFail( >@@ -5473,7 +4251,7 @@ tests.incWrongTypes = function() > { > checkFail( > () => doPrep(` >- int operator++(double) { return 32; } >+ int operator++(float) { return 32; } > `), > e => e instanceof WTypeError); > } >@@ -5482,7 +4260,7 @@ tests.decWrongTypes = function() > { > checkFail( > () => doPrep(` >- int operator--(double) { return 32; } >+ int operator--(float) { return 32; } > `), > e => e instanceof WTypeError); > } >@@ -6007,6 +4785,25 @@ tests.anderWithArrayRef = function() > checkInt(program, callFunction(program, "foo", [], []), 13); > } > >+tests.anderWithBadIndex = function() >+{ >+ checkFail(() => doPrep(` >+ int foo(thread int[] x) { return x[-1]; } >+ `), e => e instanceof Error); >+ >+ checkFail(() => doPrep(` >+ int foo(thread int[] x) { return x[1.f]; } >+ `), e => e instanceof Error); >+ >+ checkFail(() => doPrep(` >+ int foo(thread int[] x, int y) { return x[y]; } >+ `), e => e instanceof Error); >+ >+ checkFail(() => doPrep(` >+ int foo(thread int[] x, float y) { return x[y]; } >+ `), e => e instanceof Error); >+} >+ > tests.pointerIndexGetter = function() > { > checkFail( >@@ -6073,7 +4870,7 @@ tests.indexSetterWithMismatchedType = function() > { > checkFail( > () => doPrep(` >- double operator[](int, uint) >+ float operator[](int, uint) > { > return 5.43; > } >@@ -6264,7 +5061,7 @@ tests.indexAnderWithArrayRef = function() > struct Foo { > int x; > } >- thread int* operator&[](thread Foo[] array, double index) >+ thread int* operator&[](thread Foo[] array, float index) > { > return &array[uint(index + 1)].x; > } >@@ -6272,7 +5069,7 @@ tests.indexAnderWithArrayRef = function() > { > Foo x; > x.x = 13; >- return (@x)[double(-1)]; >+ return (@x)[float(-1)]; > } > `); > checkInt(program, callFunction(program, "foo", [], []), 13); >@@ -6314,306 +5111,6 @@ tests.constantPtrPtr = function() > e => e instanceof WTypeError && e.message.indexOf("Illegal pointer to non-primitive type: int32* constant* constant") != -1); > } > >-tests.pointerIndexGetterInProtocol = function() >-{ >- for (let addressSpace of addressSpaces) { >- checkFail( >- () => doPrep(` >- protocol Foo { >- int operator[](${addressSpace} Foo*, uint); >- } >- struct Bar { } >- int operator[](Bar, uint) { return 42; } >- `), >- e => e instanceof WTypeError && e.message.indexOf("Cannot have getter for pointer type") != -1); >- } >-} >- >-tests.loneIndexSetterInProtocol = function() >-{ >- checkFail( >- () => doPrep(` >- protocol Foo { >- Foo operator[]=(Foo, uint, int); >- } >- struct Bar { } >- int operator[](Bar, uint) { return 42; } >- Bar operator[]=(Bar, uint, int) { return Bar(); } >- `), >- e => e instanceof WTypeError && e.message.indexOf("Every setter must have a matching getter") != -1); >-} >- >-tests.notLoneIndexSetterInProtocol = function() >-{ >- doPrep(` >- protocol Foo { >- int operator[](Foo, uint); >- Foo operator[]=(Foo, uint, int); >- } >- struct Bar { } >- int operator[](Bar, uint) { return 42; } >- Bar operator[]=(Bar, uint, int) { return Bar(); } >- `); >-} >- >-tests.indexSetterWithMismatchedTypeInProtocol = function() >-{ >- checkFail( >- () => doPrep(` >- protocol Foo { >- double operator[](Foo, uint); >- Foo operator[]=(Foo, uint, int); >- } >- struct Bar { } >- int operator[](Bar, uint) { return 42; } >- Bar operator[]=(Bar, uint, int) { return Bar(); } >- `), >- e => e instanceof WTypeError && e.message.indexOf("Setter and getter must agree on value type") != -1); >-} >- >-tests.indexOperatorWrongArgumentLengthInProtocol = function() >-{ >- checkFail( >- () => doPrep(` >- protocol Foo { >- int operator[](); >- } >- struct Bar { } >- int operator[](Bar, uint) { return 42; } >- `), >- e => e instanceof WTypeError && e.message.indexOf("Protocol's type variable (Foo) not mentioned in signature") != -1); >- checkFail( >- () => doPrep(` >- protocol Foo { >- int operator[](Foo); >- } >- struct Bar { } >- int operator[](Bar, uint) { return 42; } >- `), >- e => e instanceof WTypeError && e.message.indexOf("Incorrect number of parameters") != -1); >- checkFail( >- () => doPrep(` >- protocol Foo { >- int operator[](Foo, int, int); >- } >- struct Bar { } >- int operator[](Bar, uint) { return 42; } >- `), >- e => e instanceof WTypeError && e.message.indexOf("Incorrect number of parameters") != -1); >-} >- >-tests.indexOperatorSetterWrongArgumentLengthInProtocol = function() >-{ >- checkFail( >- () => doPrep(` >- protocol Foo { >- int operator[]=(); >- } >- struct Bar { } >- int operator[](Bar, uint) { return 42; } >- Bar operator[]=(Bar, uint, int) { return Bar(); } >- `), >- e => e instanceof WTypeError && e.message.indexOf("Protocol's type variable (Foo) not mentioned in signature") != -1); >- checkFail( >- () => doPrep(` >- protocol Foo { >- int operator[]=(Foo); >- } >- struct Bar { } >- int operator[](Bar, uint) { return 42; } >- Bar operator[]=(Bar, uint, int) { return Bar(); } >- `), >- e => e instanceof WTypeError && e.message.indexOf("Incorrect number of parameters") != -1); >- checkFail( >- () => doPrep(` >- protocol Foo { >- int operator[]=(Foo, int); >- } >- struct Bar { } >- int operator[](Bar, uint) { return 42; } >- Bar operator[]=(Bar, uint, int) { return Bar(); } >- `), >- e => e instanceof WTypeError && e.message.indexOf("Incorrect number of parameters") != -1); >- checkFail( >- () => doPrep(` >- protocol Foo { >- int operator[]=(Foo, int, int, int); >- } >- struct Bar { } >- int operator[](Bar, uint) { return 42; } >- Bar operator[]=(Bar, uint, int) { return Bar(); } >- `), >- e => e instanceof WTypeError && e.message.indexOf("Incorrect number of parameters") != -1); >-} >- >-tests.loneIndexSetterPointerInProtocol = function() >-{ >- checkFail( >- () => doPrep(` >- protocol Foo { >- thread int* operator[]=(thread Foo* ptr, uint, int); >- } >- struct Bar { } >- int operator[](Bar, uint) { return 42; } >- Bar operator[]=(Bar, uint, int) { return Bar(); } >- `), >- e => e instanceof WTypeError && e.message.indexOf("Cannot have setter for pointer type") != -1); >-} >- >-tests.indexSetterWithNoGetterOverloadInProtocol = function() >-{ >- checkFail( >- () => doPrep(` >- protocol Foo { >- int operator[](int, Foo); >- Foo operator[]=(Foo, uint, int); >- } >- struct Bar { } >- int operator[](Bar, uint) { return 42; } >- Bar operator[]=(Bar, uint, int) { return Bar(); } >- `), >- e => e instanceof WTypeError && e.message.indexOf("Did not find function named operator[]= with arguments Foo,uint32") != -1); >-} >- >-tests.indexSetterWithNoGetterOverloadFixedInProtocol = function() >-{ >- doPrep(` >- protocol Foo { >- int operator[](Foo, uint); >- Foo operator[]=(Foo, uint, int); >- } >- struct Bar { } >- int operator[](Bar, uint) { return 42; } >- Bar operator[]=(Bar, uint, int) { return Bar(); } >- `); >-} >- >-tests.indexAnderWithNothingWrongInProtocol = function() >-{ >- let program = doPrep(` >- protocol Foo { >- thread int* operator&[](thread Foo* foo, uint); >- } >- int bar<T:Foo>(T x) >- { >- return x[42]; >- } >- struct Bar { } >- thread int* operator&[](thread Bar*, uint) >- { >- int result = 1234; >- return &result; >- } >- int foo() >- { >- return bar(Bar()); >- } >- `); >- checkInt(program, callFunction(program, "foo", [], []), 1234); >-} >- >-tests.indexAnderWithWrongNumberOfArgumentsInProtocol = function() >-{ >- checkFail( >- () => doPrep(` >- protocol Foo { >- thread int* operator&[](); >- } >- struct Bar { } >- thread int* operator&[](thread Bar*, uint) >- { >- int result = 1234; >- return &result; >- } >- `), >- e => e instanceof WTypeError && e.message.indexOf("Protocol's type variable (Foo) not mentioned in signature") != -1); >- checkFail( >- () => doPrep(` >- protocol Foo { >- thread int* operator&[](thread Foo* foo); >- } >- struct Bar { } >- thread int* operator&[](thread Bar*, uint) >- { >- int result = 1234; >- return &result; >- } >- `), >- e => e instanceof WTypeError && e.message.indexOf("Incorrect number of parameters for operator&[]") != -1); >- checkFail( >- () => doPrep(` >- protocol Foo { >- thread int* operator&[](thread Foo* foo, uint, uint); >- } >- struct Bar { } >- thread int* operator&[](thread Bar*, uint) >- { >- int result = 1234; >- return &result; >- } >- `), >- e => e instanceof WTypeError && e.message.indexOf("Incorrect number of parameters for operator&[]") != -1); >-} >- >-tests.indexAnderDoesntReturnPointerInProtocol = function() >-{ >- checkFail( >- () => doPrep(` >- protocol Foo { >- int operator&[](thread Foo* foo, uint); >- } >- struct Bar { } >- thread int* operator&[](thread Bar*, uint) >- { >- int result = 1234; >- return &result; >- } >- `), >- e => e instanceof WTypeError && e.message.indexOf("Return type of ander is not a pointer") != -1); >-} >- >-tests.indexAnderDoesntTakeReferenceInProtocol = function() >-{ >- checkFail( >- () => doPrep(` >- protocol Foo { >- thread int* operator&[](Foo foo, uint); >- } >- struct Bar { } >- thread int* operator&[](thread Bar*, uint) >- { >- int result = 1234; >- return &result; >- } >- `), >- e => e instanceof WTypeError && e.message.indexOf("Parameter to ander is not a reference") != -1); >-} >- >-tests.indexAnderWithArrayRefInProtocol = function() >-{ >- let program = doPrep(` >- protocol Foo { >- thread int* operator&[](thread Foo[] array, double index); >- } >- int bar<T:Foo>(thread T[] x) >- { >- return x[1.5]; >- } >- struct Bar { } >- thread int* operator&[](thread Bar[], double) >- { >- int result = 1234; >- return &result; >- } >- int foo() >- { >- Bar x; >- return bar(@x); >- } >- `); >- checkInt(program, callFunction(program, "foo", [], []), 1234); >-} >- > tests.andReturnedArrayRef = function() > { > let program = doPrep(` >diff --git a/Tools/WebGPUShadingLanguageRI/Type.js b/Tools/WebGPUShadingLanguageRI/Type.js >index 7c287918953a5b1d5e35e850e330f389df6e76e8..32cce237ea72b1ef018d32738c60732db14c62b9 100644 >--- a/Tools/WebGPUShadingLanguageRI/Type.js >+++ b/Tools/WebGPUShadingLanguageRI/Type.js >@@ -36,6 +36,7 @@ class Type extends Node { > get isFloating() { return false; } > get isEnum() { return false; } > get isPrimitive() { return false; } >+ get isStruct() { return false; } > > inherits(protocol) > { >diff --git a/Tools/WebGPUShadingLanguageRI/TypeDef.js b/Tools/WebGPUShadingLanguageRI/TypeDef.js >index 6c0f9c174f53235641f4cd302cab4c3aab27c143..bf76f9121e18b79a088c6c1d8a3a7f35a2b9fd45 100644 >--- a/Tools/WebGPUShadingLanguageRI/TypeDef.js >+++ b/Tools/WebGPUShadingLanguageRI/TypeDef.js >@@ -41,7 +41,7 @@ class TypeDef extends Type { > > toString() > { >- return "typedef " + this.name + "<" + this.typeParameters + "> = " + this.type; >+ return `typedef ${this.name} = ${this.type}`; > } > } > >diff --git a/Tools/WebGPUShadingLanguageRI/TypeRef.js b/Tools/WebGPUShadingLanguageRI/TypeRef.js >index f2b322f3af6a73086141e56d693efce1c351dafc..3e659b485100eed8714fc31c28cd9fd074c51261 100644 >--- a/Tools/WebGPUShadingLanguageRI/TypeRef.js >+++ b/Tools/WebGPUShadingLanguageRI/TypeRef.js >@@ -109,9 +109,7 @@ class TypeRef extends Type { > { > if (!this.name) > return this.type.toString(); >- if (!this.typeArguments.length) >- return this.name; >- return this.name + "<" + this.typeArguments + ">"; >+ return this.name; > } > } > >diff --git a/Tools/WebGPUShadingLanguageRI/index.html b/Tools/WebGPUShadingLanguageRI/index.html >index 7a7c4b42ff30e99287f61d18a256dcf827c428d3..c5ec13f71676429b3eb25118e9ff67b49d0b7897 100644 >--- a/Tools/WebGPUShadingLanguageRI/index.html >+++ b/Tools/WebGPUShadingLanguageRI/index.html >@@ -1,155 +1,165 @@ > <!DOCTYPE html> > <html> > <head> >-<script src="Node.js"></script> >-<script src="Type.js"></script> >-<script src="ReferenceType.js"></script> >-<script src="Value.js"></script> >-<script src="Expression.js"></script> >-<script src="Rewriter.js"></script> >-<script src="Visitor.js"></script> >-<script src="CreateLiteral.js"></script> >-<script src="CreateLiteralType.js"></script> >-<script src="PropertyAccessExpression.js"></script> >-<script src="SwizzleOp.js"></script> >- >-<script src="AddressSpace.js"></script> >-<script src="AnonymousVariable.js"></script> >-<script src="ArrayRefType.js"></script> >-<script src="ArrayType.js"></script> >-<script src="Assignment.js"></script> >-<script src="AutoWrapper.js"></script> >-<script src="Block.js"></script> >-<script src="BoolLiteral.js"></script> >-<script src="Break.js"></script> >-<script src="CallExpression.js"></script> >-<script src="CallFunction.js"></script> >-<script src="Check.js"></script> >-<script src="CheckLiteralTypes.js"></script> >-<script src="CheckLoops.js"></script> >-<script src="CheckRecursion.js"></script> >-<script src="CheckRecursiveTypes.js"></script> >-<script src="CheckReturns.js"></script> >-<script src="CheckUnreachableCode.js"></script> >-<script src="CheckWrapped.js"></script> >-<script src="Checker.js"></script> >-<script src="CloneProgram.js"></script> >-<script src="CommaExpression.js"></script> >-<script src="ConstexprFolder.js"></script> >-<script src="ConstexprTypeParameter.js"></script> >-<script src="Continue.js"></script> >-<script src="ConvertPtrToArrayRefExpression.js"></script> >-<script src="DoWhileLoop.js"></script> >-<script src="DotExpression.js"></script> >-<script src="DoubleLiteral.js"></script> >-<script src="DoubleLiteralType.js"></script> >-<script src="DereferenceExpression.js"></script> >-<script src="EArrayRef.js"></script> >-<script src="EBuffer.js"></script> >-<script src="EBufferBuilder.js"></script> >-<script src="EPtr.js"></script> >-<script src="EnumLiteral.js"></script> >-<script src="EnumMember.js"></script> >-<script src="EnumType.js"></script> >-<script src="EvaluationCommon.js"></script> >-<script src="Evaluator.js"></script> >-<script src="ExpressionFinder.js"></script> >-<script src="ExternalOrigin.js"></script> >-<script src="Field.js"></script> >-<script src="FindHighZombies.js"></script> >-<script src="FlattenProtocolExtends.js"></script> >-<script src="FlattenedStructOffsetGatherer.js"></script> >-<script src="FloatLiteral.js"></script> >-<script src="FloatLiteralType.js"></script> >-<script src="FoldConstexprs.js"></script> >-<script src="ForLoop.js"></script> >-<script src="Func.js"></script> >-<script src="FuncDef.js"></script> >-<script src="FuncInstantiator.js"></script> >-<script src="FuncParameter.js"></script> >-<script src="FunctionLikeBlock.js"></script> >-<script src="HighZombieFinder.js"></script> >-<script src="IdentityExpression.js"></script> >-<script src="IfStatement.js"></script> >-<script src="IndexExpression.js"></script> >-<script src="InferTypesForCall.js"></script> >-<script src="Inline.js"></script> >-<script src="Inliner.js"></script> >-<script src="InstantiateImmediates.js"></script> >-<script src="IntLiteral.js"></script> >-<script src="IntLiteralType.js"></script> >-<script src="Intrinsics.js"></script> >-<script src="LateChecker.js"></script> >-<script src="Lexer.js"></script> >-<script src="LexerToken.js"></script> >-<script src="LiteralTypeChecker.js"></script> >-<script src="LogicalExpression.js"></script> >-<script src="LogicalNot.js"></script> >-<script src="LoopChecker.js"></script> >-<script src="MakeArrayRefExpression.js"></script> >-<script src="MakePtrExpression.js"></script> >-<script src="NameContext.js"></script> >-<script src="NameFinder.js"></script> >-<script src="NameResolver.js"></script> >-<script src="NativeFunc.js"></script> >-<script src="NativeFuncInstance.js"></script> >-<script src="NativeType.js"></script> >-<script src="NativeTypeInstance.js"></script> >-<script src="NormalUsePropertyResolver.js"></script> >-<script src="NullLiteral.js"></script> >-<script src="NullType.js"></script> >-<script src="OriginKind.js"></script> >-<script src="OverloadResolutionFailure.js"></script> >-<script src="Parse.js"></script> >-<script src="Prepare.js"></script> >-<script src="PropertyResolver.js"></script> >-<script src="Program.js"></script> >-<script src="ProgramWithUnnecessaryThingsRemoved.js"></script> >-<script src="Protocol.js"></script> >-<script src="ProtocolDecl.js"></script> >-<script src="ProtocolFuncDecl.js"></script> >-<script src="ProtocolRef.js"></script> >-<script src="PtrType.js"></script> >-<script src="ReadModifyWriteExpression.js"></script> >-<script src="RecursionChecker.js"></script> >-<script src="RecursiveTypeChecker.js"></script> >-<script src="ResolveNames.js"></script> >-<script src="ResolveOverloadImpl.js"></script> >-<script src="ResolveProperties.js"></script> >-<script src="ResolveTypeDefs.js"></script> >-<script src="Return.js"></script> >-<script src="ReturnChecker.js"></script> >-<script src="ReturnException.js"></script> >-<script src="StandardLibrary.js"></script> >-<script src="StatementCloner.js"></script> >-<script src="StructLayoutBuilder.js"></script> >-<script src="StructType.js"></script> >-<script src="Substitution.js"></script> >-<script src="SwitchCase.js"></script> >-<script src="SwitchStatement.js"></script> >-<script src="SynthesizeEnumFunctions.js"></script> >-<script src="SynthesizeStructAccessors.js"></script> >-<script src="TrapStatement.js"></script> >-<script src="TypeDef.js"></script> >-<script src="TypeDefResolver.js"></script> >-<script src="TypeOrVariableRef.js"></script> >-<script src="TypeParameterRewriter.js"></script> >-<script src="TypeRef.js"></script> >-<script src="TypeVariable.js"></script> >-<script src="TypeVariableTracker.js"></script> >-<script src="TypedValue.js"></script> >-<script src="UintLiteral.js"></script> >-<script src="UintLiteralType.js"></script> >-<script src="UnificationContext.js"></script> >-<script src="UnreachableCodeChecker.js"></script> >-<script src="VariableDecl.js"></script> >-<script src="VariableRef.js"></script> >-<script src="VisitingSet.js"></script> >-<script src="WSyntaxError.js"></script> >-<script src="WTrapError.js"></script> >-<script src="WTypeError.js"></script> >-<script src="WhileLoop.js"></script> >-<script src="WrapChecker.js"></script> >+ <script src="Node.js"></script> >+ <script src="Type.js"></script> >+ <script src="ReferenceType.js"></script> >+ <script src="Value.js"></script> >+ <script src="Expression.js"></script> >+ <script src="Rewriter.js"></script> >+ <script src="Visitor.js"></script> >+ <script src="CreateLiteral.js"></script> >+ <script src="CreateLiteralType.js"></script> >+ <script src="PropertyAccessExpression.js"></script> >+ <script src="SwizzleOp.js"></script> >+ >+ <script src="AddressSpace.js"></script> >+ <script src="AnonymousVariable.js"></script> >+ <script src="ArrayRefType.js"></script> >+ <script src="ArrayType.js"></script> >+ <script src="Assignment.js"></script> >+ <script src="AutoWrapper.js"></script> >+ <script src="Block.js"></script> >+ <script src="BoolLiteral.js"></script> >+ <script src="Break.js"></script> >+ <script src="CallExpression.js"></script> >+ <script src="CallFunction.js"></script> >+ <script src="Check.js"></script> >+ <script src="CheckLiteralTypes.js"></script> >+ <script src="CheckLoops.js"></script> >+ <script src="CheckRecursion.js"></script> >+ <script src="CheckRecursiveTypes.js"></script> >+ <script src="CheckReturns.js"></script> >+ <script src="CheckUnreachableCode.js"></script> >+ <script src="CheckWrapped.js"></script> >+ <script src="Checker.js"></script> >+ <script src="CloneProgram.js"></script> >+ <script src="CommaExpression.js"></script> >+ <script src="ConstexprFolder.js"></script> >+ <script src="ConstexprTypeParameter.js"></script> >+ <script src="Continue.js"></script> >+ <script src="ConvertPtrToArrayRefExpression.js"></script> >+ <script src="DoWhileLoop.js"></script> >+ <script src="DotExpression.js"></script> >+ <script src="DereferenceExpression.js"></script> >+ <script src="EArrayRef.js"></script> >+ <script src="EBuffer.js"></script> >+ <script src="EBufferBuilder.js"></script> >+ <script src="EPtr.js"></script> >+ <script src="EnumLiteral.js"></script> >+ <script src="EnumMember.js"></script> >+ <script src="EnumType.js"></script> >+ <script src="EvaluationCommon.js"></script> >+ <script src="Evaluator.js"></script> >+ <script src="ExpressionFinder.js"></script> >+ <script src="ExternalOrigin.js"></script> >+ <script src="Field.js"></script> >+ <script src="FindHighZombies.js"></script> >+ <script src="FlattenProtocolExtends.js"></script> >+ <script src="FlattenedStructOffsetGatherer.js"></script> >+ <script src="FloatLiteral.js"></script> >+ <script src="FloatLiteralType.js"></script> >+ <script src="FoldConstexprs.js"></script> >+ <script src="ForLoop.js"></script> >+ <script src="Func.js"></script> >+ <script src="FuncDef.js"></script> >+ <script src="FuncInstantiator.js"></script> >+ <script src="FuncParameter.js"></script> >+ <script src="FunctionLikeBlock.js"></script> >+ <script src="HighZombieFinder.js"></script> >+ <script src="IdentityExpression.js"></script> >+ <script src="IfStatement.js"></script> >+ <script src="IndexExpression.js"></script> >+ <script src="InferTypesForCall.js"></script> >+ <script src="Inline.js"></script> >+ <script src="Inliner.js"></script> >+ <script src="InstantiateImmediates.js"></script> >+ <script src="IntLiteral.js"></script> >+ <script src="IntLiteralType.js"></script> >+ <script src="Intrinsics.js"></script> >+ <script src="LateChecker.js"></script> >+ <script src="Lexer.js"></script> >+ <script src="LexerToken.js"></script> >+ <script src="LiteralTypeChecker.js"></script> >+ <script src="LogicalExpression.js"></script> >+ <script src="LogicalNot.js"></script> >+ <script src="LoopChecker.js"></script> >+ <script src="MakeArrayRefExpression.js"></script> >+ <script src="MakePtrExpression.js"></script> >+ <script src="NameContext.js"></script> >+ <script src="NameFinder.js"></script> >+ <script src="NameResolver.js"></script> >+ <script src="NativeFunc.js"></script> >+ <script src="NativeFuncInstance.js"></script> >+ <script src="NativeType.js"></script> >+ <script src="NativeTypeInstance.js"></script> >+ <script src="NormalUsePropertyResolver.js"></script> >+ <script src="NullLiteral.js"></script> >+ <script src="NullType.js"></script> >+ <script src="OperatorAnderIndex.js"></script> >+ <script src="OperatorArrayRefLength.js"></script> >+ <script src="OperatorBool.js"></script> >+ <script src="BuiltinVectorCasts.js"></script> >+ <script src="BuiltinVectorGetter.js"></script> >+ <script src="BuiltinVectorSetter.js"></script> >+ <script src="BuiltinVectorIndexGetter.js"></script> >+ <script src="BuiltinVectorIndexSetter.js"></script> >+ <script src="BuiltinVectorEqualityOperator.js"></script> >+ <script src="OriginKind.js"></script> >+ <script src="OverloadResolutionFailure.js"></script> >+ <script src="Parse.js"></script> >+ <script src="Prepare.js"></script> >+ <script src="PropertyResolver.js"></script> >+ <script src="Program.js"></script> >+ <script src="ProgramWithUnnecessaryThingsRemoved.js"></script> >+ <script src="Protocol.js"></script> >+ <script src="ProtocolDecl.js"></script> >+ <script src="ProtocolFuncDecl.js"></script> >+ <script src="ProtocolRef.js"></script> >+ <script src="PtrType.js"></script> >+ <script src="ReadModifyWriteExpression.js"></script> >+ <script src="RecursionChecker.js"></script> >+ <script src="RecursiveTypeChecker.js"></script> >+ <script src="ResolveNames.js"></script> >+ <script src="ResolveOverloadImpl.js"></script> >+ <script src="ResolveProperties.js"></script> >+ <script src="ResolveTypeDefs.js"></script> >+ <script src="Return.js"></script> >+ <script src="ReturnChecker.js"></script> >+ <script src="ReturnException.js"></script> >+ <script src="StandardLibrary.js"></script> >+ <script src="StatementCloner.js"></script> >+ <script src="StructLayoutBuilder.js"></script> >+ <script src="StructType.js"></script> >+ <script src="Substitution.js"></script> >+ <script src="SwitchCase.js"></script> >+ <script src="SwitchStatement.js"></script> >+ <script src="SynthesizeArrayOperatorLength.js"></script> >+ <script src="SynthesizeEnumFunctions.js"></script> >+ <script src="SynthesizeStructAccessors.js"></script> >+ <script src="SynthesizeCopyConstructorOperator.js"></script> >+ <script src="SynthesizeDefaultConstructorOperator.js"></script> >+ <script src="TrapStatement.js"></script> >+ <script src="TypeDef.js"></script> >+ <script src="TypeDefResolver.js"></script> >+ <script src="TypeOrVariableRef.js"></script> >+ <script src="TypeParameterRewriter.js"></script> >+ <script src="TypeRef.js"></script> >+ <script src="TypeVariable.js"></script> >+ <script src="TypeVariableTracker.js"></script> >+ <script src="TypedValue.js"></script> >+ <script src="UintLiteral.js"></script> >+ <script src="UintLiteralType.js"></script> >+ <script src="UnificationContext.js"></script> >+ <script src="UnreachableCodeChecker.js"></script> >+ <script src="VariableDecl.js"></script> >+ <script src="VariableRef.js"></script> >+ <script src="VisitingSet.js"></script> >+ <script src="WSyntaxError.js"></script> >+ <script src="WTrapError.js"></script> >+ <script src="WTypeError.js"></script> >+ <script src="WhileLoop.js"></script> >+ <script src="WrapChecker.js"></script> > <style> > #ShaderSource { > font-family: monospace; >@@ -415,6 +425,7 @@ function runShaders() { > case "uint32": > value = parseInt(value) >>> 0; > break; >+ // FIXME: Parse other types > default: > presentError("I don't know how to parse values of type " + type); > }
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Formatted Diff
|
Diff
Attachments on
bug 187988
:
345819
|
346235
|
346920
|
347022
|
347023
|
347091
|
347226
|
347343
|
347344