WebKit Bugzilla
Attachment 346235 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]
WIP Patch
bug-187988-20180731173557.patch (text/plain), 195.94 KB, created by
Thomas Denney
on 2018-07-31 17:35:58 PDT
(
hide
)
Description:
WIP Patch
Filename:
MIME Type:
Creator:
Thomas Denney
Created:
2018-07-31 17:35:58 PDT
Size:
195.94 KB
patch
obsolete
>Subversion Revision: 234370 >diff --git a/Tools/ChangeLog b/Tools/ChangeLog >index 86d449021bfbb1d4dce25ddcf6b696a3ffa58303..d2f818e985e897faa6ebee61597648258a037aa6 100644 >--- a/Tools/ChangeLog >+++ b/Tools/ChangeLog >@@ -1,3 +1,241 @@ >+2018-07-31 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: Copied from Tools/WebGPUShadingLanguageRI/NativeTypeInstance.js. >+ (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: Copied from Tools/WebGPUShadingLanguageRI/NativeTypeInstance.js. >+ (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._checkTypeArguments): >+ (Checker.prototype.visitTypeRef): >+ (Checker.prototype.visitNativeParameterizedType): >+ (Checker.prototype.visitVectorType): >+ (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/InferTypesForCall.js: >+ (inferTypesForCall): >+ * WebGPUShadingLanguageRI/InstantiateImmediates.js: >+ (InstantiateImmediates.prototype.visitTypeRef): >+ (InstantiateImmediates.visitReferenceType): Deleted. >+ * WebGPUShadingLanguageRI/Intrinsics.js: >+ (Intrinsics): >+ * WebGPUShadingLanguageRI/LiteralTypeChecker.js: >+ (LiteralTypeChecker.prototype.visitGenericLiteralType): >+ (LiteralTypeChecker): >+ * WebGPUShadingLanguageRI/NameContext.js: >+ (NameContext.prototype.add): >+ (NameContext.prototype.get let): >+ (NameContext.underlyingThings.prototype.else): >+ * WebGPUShadingLanguageRI/NameResolver.js: >+ (NameResolver.prototype.visitProtocolDecl): >+ * WebGPUShadingLanguageRI/NativeParameterizedType.js: Copied from Tools/WebGPUShadingLanguageRI/NativeTypeInstance.js. >+ (NativeParameterizedType): >+ (NativeParameterizedType.prototype.get isPrimitive): >+ (NativeParameterizedType.fromNameAndTypeArguments): >+ (NativeParameterizedType.prototype.get kind): >+ (NativeParameterizedType.prototype.get typeArguments): >+ (NativeParameterizedType.prototype.toString): >+ * WebGPUShadingLanguageRI/NativeType.js: >+ (NativeType): >+ (NativeType.prototype.get name): >+ (NativeType.prototype.toString): >+ (NativeType.prototype.get typeParameters): Deleted. >+ (NativeType.prototype.instantiate): Deleted. >+ * 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: Copied from Tools/WebGPUShadingLanguageRI/TypeDef.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: >+ (parseTypeArguments): >+ (parseTypeDef): >+ (isCallExpression): >+ (parseFuncDecl): >+ (parseStructType): >+ (parseNative): >+ (parse): >+ (parseProtocolRef): Deleted. >+ (parseTypeParameters): Deleted. >+ (parseProtocolFuncDecl): Deleted. >+ (parseProtocolDecl): Deleted. >+ * WebGPUShadingLanguageRI/Prepare.js: >+ (let.prepare): >+ * WebGPUShadingLanguageRI/RecursiveTypeChecker.js: >+ (RecursiveTypeChecker.prototype.visitNativeParameterizedType): >+ (RecursiveTypeChecker): >+ * WebGPUShadingLanguageRI/Rewriter.js: >+ (Rewriter.prototype.visitNativeParameterizedType): >+ (Rewriter.prototype.visitVectorType): >+ (Rewriter): >+ * WebGPUShadingLanguageRI/SPIRV.html: >+ * WebGPUShadingLanguageRI/StandardLibrary.js: >+ (addFunctionsFromClass): >+ (allVectorTypeNames): >+ (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: Copied from Tools/WebGPUShadingLanguageRI/InstantiateImmediates.js. >+ (synthesizeArrayOperatorLength.FindArrayTypes.prototype.visitArrayType): >+ (synthesizeArrayOperatorLength.FindArrayTypes): >+ (synthesizeArrayOperatorLength): >+ * WebGPUShadingLanguageRI/SynthesizeCopyConstructorOperator.js: Copied from Tools/WebGPUShadingLanguageRI/InstantiateImmediates.js. >+ (synthesizeCopyConstructorOperator.FindAllTypes.prototype.visitNativeType): >+ (synthesizeCopyConstructorOperator.FindAllTypes.prototype.visitStructType): >+ (synthesizeCopyConstructorOperator.FindAllTypes.prototype.visitElementalType): >+ (synthesizeCopyConstructorOperator.FindAllTypes): >+ (synthesizeCopyConstructorOperator): >+ * WebGPUShadingLanguageRI/SynthesizeDefaultConstructorOperator.js: Copied from Tools/WebGPUShadingLanguageRI/InstantiateImmediates.js. >+ (synthesizeDefaultConstructorOperator.FindAllTypes.prototype.visitNativeType): >+ (synthesizeDefaultConstructorOperator.FindAllTypes.prototype.visitStructType): >+ (synthesizeDefaultConstructorOperator.FindAllTypes.prototype.visitElementalType): >+ (synthesizeDefaultConstructorOperator.FindAllTypes): >+ (synthesizeDefaultConstructorOperator): >+ * WebGPUShadingLanguageRI/Test.html: >+ * WebGPUShadingLanguageRI/Test.js: >+ * WebGPUShadingLanguageRI/Type.js: >+ (Type.prototype.get isStruct): >+ * WebGPUShadingLanguageRI/TypeDef.js: >+ (TypeDef.prototype.get unifyNode): >+ (TypeDef.prototype.toString): >+ (TypeDef): >+ * WebGPUShadingLanguageRI/TypeRef.js: >+ (TypeRef.prototype.get unifyNode): >+ (TypeRef.prototype.populateDefaultValue): >+ (TypeRef.prototype.get size): >+ (TypeRef.prototype.get isPrimitive): >+ (TypeRef.prototype.toString): >+ (TypeRef): >+ * WebGPUShadingLanguageRI/VectorType.js: Copied from Tools/WebGPUShadingLanguageRI/NativeTypeInstance.js. >+ (VectorType): >+ (VectorType.prototype.get elementType): >+ (VectorType.prototype.get numElements): >+ (VectorType.prototype.get numElementsValue): >+ (VectorType.prototype.get size): >+ (VectorType.prototype.unifyImpl): >+ (VectorType.prototype.populateDefaultValue): >+ (VectorType.prototype.toString): >+ * WebGPUShadingLanguageRI/Visitor.js: >+ (Visitor.prototype.visitProtocolDecl): >+ * 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-27 Michael Catanzaro <mcatanzaro@igalia.com> > > Unreviewed, fix typo in test expectations and mark another test as timing out >diff --git a/Tools/WebGPUShadingLanguageRI/All.js b/Tools/WebGPUShadingLanguageRI/All.js >index 15dd7ccab94692a32acd27b9dac96c8a8f55d658..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,9 +62,9 @@ load("ConstexprFolder.js"); > load("ConstexprTypeParameter.js"); > load("Continue.js"); > load("ConvertPtrToArrayRefExpression.js"); >-load("DereferenceExpression.js"); > load("DoWhileLoop.js"); > load("DotExpression.js"); >+load("DereferenceExpression.js"); > load("EArrayRef.js"); > load("EBuffer.js"); > load("EBufferBuilder.js"); >@@ -118,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"); >@@ -147,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..aec1195b6cb1b03cf301e8666835b36c812547aa >--- /dev/null >+++ b/Tools/WebGPUShadingLanguageRI/BuiltinVectorCasts.js >@@ -0,0 +1,87 @@ >+/* >+ * 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 = []; >+ >+ for (let typeName of VectorElementTypes) { >+ for (let size of VectorElementSizes) { >+ 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..9123bbdad6f077b34c6191bc3e25cac71cf042be >--- /dev/null >+++ b/Tools/WebGPUShadingLanguageRI/BuiltinVectorEqualityOperator.js >@@ -0,0 +1,66 @@ >+/* >+ * 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 = []; >+ >+ for (let typeName of VectorElementTypes) { >+ for (let size of VectorElementSizes) >+ 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..88a9157a4edce476c934a5a05c771c3564c35609 >--- /dev/null >+++ b/Tools/WebGPUShadingLanguageRI/BuiltinVectorGetter.js >@@ -0,0 +1,70 @@ >+/* >+ * 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 elements = [ "x", "y", "z", "w" ]; >+ >+ for (let typeName of VectorElementTypes) { >+ for (let size of VectorElementSizes) { >+ 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..8ba53a1fbc379763d9b07a623fbe080560f94a02 >--- /dev/null >+++ b/Tools/WebGPUShadingLanguageRI/BuiltinVectorIndexGetter.js >@@ -0,0 +1,66 @@ >+/* >+ * 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 = []; >+ >+ for (let typeName of VectorElementTypes) { >+ for (let size of VectorElementSizes) >+ 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..6e79d2534808aed7b39580d65f7e0298a085ff30 >--- /dev/null >+++ b/Tools/WebGPUShadingLanguageRI/BuiltinVectorIndexSetter.js >@@ -0,0 +1,71 @@ >+/* >+ * 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 = []; >+ >+ for (let typeName of VectorElementTypes) { >+ for (let size of VectorElementSizes) >+ 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..fd290c35476e957aad718058b620c3f3fa17fa52 >--- /dev/null >+++ b/Tools/WebGPUShadingLanguageRI/BuiltinVectorSetter.js >@@ -0,0 +1,73 @@ >+/* >+ * 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 elements = [ "x", "y", "z", "w" ]; >+ >+ for (let typeName of VectorElementTypes) { >+ for (let size of VectorElementSizes) { >+ 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..11c0383bfd09ed753615450dbd33bed15c0b6e6a 100644 >--- a/Tools/WebGPUShadingLanguageRI/Checker.js >+++ b/Tools/WebGPUShadingLanguageRI/Checker.js >@@ -280,6 +280,9 @@ class Checker extends Visitor { > > _checkTypeArguments(origin, typeParameters, typeArguments) > { >+ if (typeParameters.length != typeArguments.length) >+ return; >+ > for (let i = 0; i < typeParameters.length; ++i) { > let argumentIsType = typeArguments[i] instanceof Type; > let result = typeArguments[i].visit(this); >@@ -288,8 +291,9 @@ class Checker extends Visitor { > if (!result.result) > throw new WTypeError(origin.originString, "Type argument does not inherit protocol: " + result.reason); > } else { >- if (!result.equalsWithCommit(typeParameters[i].type)) >- throw new WTypeError(origin.originString, "Wrong type for constexpr"); >+ // if (!result.equalsWithCommit(typeParameters[i].type)) >+ // throw new WTypeError(origin.originString, "Wrong type for constexpr"); >+ result.type = typeParameters[i].type.type; > } > } > } >@@ -300,7 +304,46 @@ class Checker extends Visitor { > throw new Error("Type reference without a type in checker: " + node + " at " + node.origin); > if (!(node.type instanceof StructType)) > node.type.visit(this); >- this._checkTypeArguments(node.origin, node.type.typeParameters, node.typeArguments); >+ if (node.type.typeArguments && node.type.typeArguments.length) >+ this._checkTypeArguments(node.origin, node.type.typeArguments, node.typeArguments); >+ } >+ >+ visitNativeParameterizedType(node) >+ { >+ console.log(node); >+ for (let i = 0; i < node.typeArguments.length; ++i) { >+ let argumentIsType = node.typeArguments[i] instanceof Type; >+ let result = node.typeArguments[i].visit(this); >+ if (argumentIsType) { >+ // let result node.= typeArguments[i].inherits(typeParameters[i].protocol); >+ // if (!result.result) >+ // throw new WTypeError(origin.originString, "Type argument does not inherit protocol: " + result.reason); >+ } else { >+ if (!result.equalsWithCommit(node.typeArguments[i].type)) >+ throw new WTypeError(origin.originString, "Wrong type for constexpr"); >+ else >+ console.log("Should have worked fine"); >+ } >+ } >+ } >+ >+ visitVectorType(node) >+ { >+ // TODO: Enforce some restriction on the element type here >+ node.elementType.visit(this); >+ >+ if (!(node.elementType.equals(this._program.intrinsics.int32) >+ || node.elementType.equals(this._program.intrinsics.uint32) >+ || node.elementType.equals(this._program.intrinsics.float))) >+ throw new WTypeError(node.origin.originString, `Vector element type ${node.elementType} not permitted`); >+ >+ if (!node.numElements.isConstexpr) >+ throw new WTypeError(node.origin.originString, "Vector size must be constexpr"); >+ >+ let numElementsType = node.numElements.visit(this); >+ >+ if (!numElementsType.equalsWithCommit(this._program.intrinsics.uint32)) >+ throw new WTypeError(node.origin.originString, "Vector size must be a uint32"); > } > > visitArrayType(node) >@@ -427,7 +470,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 +485,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 +510,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/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/InferTypesForCall.js b/Tools/WebGPUShadingLanguageRI/InferTypesForCall.js >index 446b351da5715c68a35d7697969d698ec73e74f8..b40fb1c0841a3eab69c4825a5b77417c9a546e94 100644 >--- a/Tools/WebGPUShadingLanguageRI/InferTypesForCall.js >+++ b/Tools/WebGPUShadingLanguageRI/InferTypesForCall.js >@@ -43,8 +43,12 @@ function inferTypesForCall(func, typeArguments, argumentTypes, returnType) > if (!argumentTypes[i].unify(unificationContext, func.parameters[i].type)) > return {failure: new OverloadResolutionFailure(func, "Argument #" + (i + 1) + " " + (func.parameters[i].name ? "for parameter " + func.parameters[i].name + " " : "") + "does not match (passed " + argumentTypes[i] + ", require " + func.parameters[i].type + ")")}; > } >- if (returnType && !returnType.unify(unificationContext, func.returnType)) >+ if (returnType && !returnType.unify(unificationContext, func.returnType)) { >+ if (func.returnType.toString() == "vector") { >+ returnType.unify(unificationContext, func.returnType) >+ } > return {failure: new OverloadResolutionFailure(func, "Return type " + func.returnType + " does not match " + returnType)}; >+ } > let verificationResult = unificationContext.verify(); > if (!verificationResult.result) > return {failure: new OverloadResolutionFailure(func, verificationResult.reason)}; >diff --git a/Tools/WebGPUShadingLanguageRI/InstantiateImmediates.js b/Tools/WebGPUShadingLanguageRI/InstantiateImmediates.js >index 2b39ed6638141348abc127696b6ee31e0b0c58b6..6d9a5c4a50bc83932bd26c3eecaed77948081ea0 100644 >--- a/Tools/WebGPUShadingLanguageRI/InstantiateImmediates.js >+++ b/Tools/WebGPUShadingLanguageRI/InstantiateImmediates.js >@@ -29,8 +29,8 @@ class InstantiateImmediates extends Rewriter { > { > node = super.visitTypeRef(node); > if (!node.type.instantiate) { >- if (node.typeArguments.length) >- throw new Error("type does not support instantiation: " + type + " (" + type.constructor.name + ")"); >+ // if (node.typeArguments.length) >+ // throw new Error("type does not support instantiation: " + type + " (" + type.constructor.name + ")"); > return node; > } > return node.type.instantiate(node.typeArguments).visit(new AutoWrapper()); >diff --git a/Tools/WebGPUShadingLanguageRI/Intrinsics.js b/Tools/WebGPUShadingLanguageRI/Intrinsics.js >index 933dfe011302b0fbc8344994a1a5c1f77c052a6f..29fa118f6d9106f8f6ea1d371a89e020203d39c7 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; >@@ -142,407 +142,401 @@ class Intrinsics { > }); > > 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 = [ "int32" , "uint32", "float32" ]; >+ for (let vectorType of vectorTypes) { >+ for (let size = 2; size <= 4; size++) { >+ this._map.set( >+ `native typedef vector<${vectorType}, ${size}>`, >+ type => {} >+ ) >+ } >+ } > > this._map.set( >- "native operator<> int32(uint32)", >+ "native operator int32(uint32)", > func => { > func.implementation = ([value]) => EPtr.box(value.loadValue() | 0); > }); > > this._map.set( >- "native operator<> int32(uint8)", >+ "native operator int32(uint8)", > func => { > func.implementation = ([value]) => EPtr.box(value.loadValue() | 0); > }); > > this._map.set( >- "native operator<> int32(float)", >+ "native operator int32(float)", > func => { > func.implementation = ([value]) => EPtr.box(value.loadValue() | 0); > }); > > this._map.set( >- "native operator<> uint32(int32)", >+ "native operator uint32(int32)", > func => { > func.implementation = ([value]) => EPtr.box(value.loadValue() >>> 0); > }); > > this._map.set( >- "native operator<> uint32(uint8)", >+ "native operator uint32(uint8)", > func => { > func.implementation = ([value]) => EPtr.box(value.loadValue() >>> 0); > }); > > this._map.set( >- "native operator<> uint32(float)", >+ "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<> float(int32)", >+ "native operator float(int32)", > func => { > func.implementation = ([value]) => EPtr.box(Math.fround(value.loadValue())); > }); > > this._map.set( >- "native operator<> float(uint32)", >+ "native operator float(uint32)", > func => { > func.implementation = ([value]) => EPtr.box(Math.fround(value.loadValue())); > }); > > this._map.set( >- "native operator<> float(uint8)", >+ "native operator float(uint8)", > func => { > func.implementation = ([value]) => EPtr.box(Math.fround(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 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 int operator*<>(int,int)", >+ "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 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 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==<>(bool,bool)", >+ "native bool operator==(bool,bool)", > 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<<>(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<=<>(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><>(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>=<>(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()); > }); >- >- 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/NameContext.js b/Tools/WebGPUShadingLanguageRI/NameContext.js >index c31bc428294430bd4527796f4d7a9960539f6188..f8f38298ad37e5fec6f53d62c69306f55da095e9 100644 >--- a/Tools/WebGPUShadingLanguageRI/NameContext.js >+++ b/Tools/WebGPUShadingLanguageRI/NameContext.js >@@ -48,7 +48,7 @@ class NameContext { > return; > if (!thing.origin) > throw new Error("Thing does not have origin: " + thing); >- >+ > if (thing.isNative && !thing.implementation) { > if (!this._intrinsics) > throw new Error("Native function in a scope that does not recognize intrinsics"); >@@ -67,9 +67,23 @@ class NameContext { > throw new WTypeError(thing.origin.originString, "Cannot reuse type name for function: " + thing.name); > array.push(thing); > return; >+ } else if (thing.kind == NativeParameterizedType) { >+ this._set.add(thing); >+ let array = this._map.get(thing.name); >+ if (!array) { >+ array = []; >+ array.kind = NativeParameterizedType; >+ this._map.set(thing.name, array); >+ } >+ if (array.kind != NativeParameterizedType) >+ throw new WTypeError(thing.origin.originString, "Cannot reuse name for " + thing.name); >+ array.push(thing); >+ return; > } >+ > if (this._map.has(thing.name)) > throw new WTypeError(thing.origin.originString, "Duplicate name: " + thing.name); >+ > this._set.add(thing); > this._map.set(thing.name, thing); > } >@@ -100,6 +114,12 @@ class NameContext { > for (let func of thing) > yield func; > return; >+ } else if (thing.kind === NativeParameterizedType) { >+ if (!(thing instanceof Array)) >+ throw new Error("NativeParameterized thing is not an array " + thing); >+ for (let nativeParameterizedType of thing) >+ yield nativeParameterizedType; >+ return; > } > yield thing; > } >diff --git a/Tools/WebGPUShadingLanguageRI/NameResolver.js b/Tools/WebGPUShadingLanguageRI/NameResolver.js >index 731964fc78221ae73118981252232503bcfabc30..46ea06162073c8eacf3d5164b3499e24a8ee1ba0 100644 >--- a/Tools/WebGPUShadingLanguageRI/NameResolver.js >+++ b/Tools/WebGPUShadingLanguageRI/NameResolver.js >@@ -165,7 +165,7 @@ class NameResolver extends Visitor { > for (let field of node.fields) > field.visit(checker); > } >- >+ > _resolveTypeArguments(typeArguments) > { > for (let i = 0; i < typeArguments.length; ++i) { >@@ -173,7 +173,7 @@ class NameResolver extends Visitor { > if (typeArgument instanceof TypeOrVariableRef) { > let thing = this._nameContext.get(Anything, typeArgument.name); > if (!thing) >- new WTypeError(typeArgument.origin.originString, "Could not find type or variable named " + typeArgument.name); >+ throw WTypeError(typeArgument.origin.originString, "Could not find type or variable named " + typeArgument.name); > if (thing instanceof Value) > typeArguments[i] = new VariableRef(typeArgument.origin, typeArgument.name); > else if (thing instanceof Type) >@@ -182,8 +182,7 @@ class NameResolver extends Visitor { > throw new WTypeError(typeArgument.origin.originString, "Type argument resolved to wrong kind of thing: " + thing.kind); > } > >- if (typeArgument[i] instanceof Value >- && !typeArgument[i].isConstexpr) >+ if (typeArgument instanceof Value&& !typeArgument.isConstexpr) > throw new WTypeError(typeArgument[i].origin.originString, "Expected constexpr"); > } > } >@@ -191,26 +190,42 @@ class NameResolver extends Visitor { > visitTypeRef(node) > { > this._resolveTypeArguments(node.typeArguments); >+ for (let arg of node.typeArguments) >+ arg.visit(this); > > let type = node.type; > if (!type) { > type = this._nameContext.get(Type, node.name); >+ if (type) >+ node.type = type; >+ else { >+ let possibleTypes = this._nameContext.get(NativeParameterizedType, node.name); >+ for (let possibleType of possibleTypes) { >+ // At this point the possible type arguments might be TypeOrVariableRef, we ensure they are concrete types. >+ possibleType.visit(this); >+ if (possibleType.typeArguments.length == node.typeArguments.length) { >+ let argumentsMatch = true; >+ for (let i = 0; argumentsMatch && i < possibleType.typeArguments.length; i++) { >+ if (!node.typeArguments[i].equals(possibleType.typeArguments[i])) >+ argumentsMatch = false; >+ } >+ >+ if (argumentsMatch) { >+ type = possibleType; >+ break; >+ } >+ } >+ } >+ >+ if (!type) >+ throw new WTypeError(node.origin.originString, `Could not find type named ${node.name} with arguments ${node.typeArguments.join(", ")}`); >+ } >+ > if (!type) > throw new WTypeError(node.origin.originString, "Could not find type named " + node.name); >+ > node.type = type; > } >- >- if (type.typeParameters.length != node.typeArguments.length) >- throw new WTypeError(node.origin.originString, "Wrong number of type arguments (passed " + node.typeArguments.length + ", expected " + type.typeParameters.length + ")"); >- for (let i = 0; i < type.typeParameters.length; ++i) { >- let parameterIsType = type.typeParameters[i] instanceof TypeVariable; >- let argumentIsType = node.typeArguments[i] instanceof Type; >- node.typeArguments[i].visit(this); >- if (parameterIsType && !argumentIsType) >- throw new WTypeError(node.origin.originString, "Expected type, but got value at argument #" + i); >- if (!parameterIsType && argumentIsType) >- throw new WTypeError(node.origin.originString, "Expected value, but got type at argument #" + i); >- } > } > > visitReferenceType(node) >@@ -296,5 +311,12 @@ class NameResolver extends Visitor { > > super.visitCallExpression(node); > } >+ >+ visitVectorType(node) >+ { >+ this._resolveTypeArguments(node.typeArguments); >+ for (let arg of node.typeArguments) >+ arg.visit(this); >+ } > } > >diff --git a/Tools/WebGPUShadingLanguageRI/NativeParameterizedType.js b/Tools/WebGPUShadingLanguageRI/NativeParameterizedType.js >new file mode 100644 >index 0000000000000000000000000000000000000000..af91ec89aff1468c4525dcc834c42d8f20b35cb6 >--- /dev/null >+++ b/Tools/WebGPUShadingLanguageRI/NativeParameterizedType.js >@@ -0,0 +1,60 @@ >+/* >+ * 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 NativeParameterizedType extends NativeType { >+ constructor(origin, name, typeArguments) >+ { >+ if (!(typeArguments instanceof Array)) >+ throw new Error("type arguments not array: " + typeArguments); >+ super(origin, name); >+ >+ this._typeArguments = typeArguments; >+ } >+ >+ get isPrimitive() { return true; } >+ >+ static fromNameAndTypeArguments(origin, name, typeArguments) >+ { >+ switch (name) { >+ case "vector": >+ return new VectorType(origin, name, typeArguments); >+ case "matrix": >+ throw new Error("TODO: Implement NativeParameterizedType.fromNameAndTypeArguments case \"matrix\""); >+ default: >+ throw new Error(`Unrecognized native type ${name}`); >+ } >+ } >+ >+ get kind() { return NativeParameterizedType; } >+ >+ get typeArguments() { return this._typeArguments; } >+ >+ toString() >+ { >+ return `native typedef ${this.name}<${this.typeArguments.join(", ")}>`; >+ } >+} >+ >diff --git a/Tools/WebGPUShadingLanguageRI/NativeType.js b/Tools/WebGPUShadingLanguageRI/NativeType.js >index b8b1a47330b5fd51ff021af06586844c2acba8ea..e46e62df2554f29a2398821dd830398f550f1f45 100644 >--- a/Tools/WebGPUShadingLanguageRI/NativeType.js >+++ b/Tools/WebGPUShadingLanguageRI/NativeType.js >@@ -25,14 +25,11 @@ > "use strict"; > > class NativeType extends Type { >- constructor(origin, name, typeParameters) >+ constructor(origin, name) > { >- if (!(typeParameters instanceof Array)) >- throw new Error("type parameters not array: " + typeParameters); > super(); > this._origin = origin; > this._name = name; >- this._typeParameters = typeParameters; > this._isNumber = false; > this._isInt = false; > this._isFloating = false; >@@ -41,7 +38,6 @@ class NativeType extends Type { > > get origin() { return this._origin; } > get name() { return this._name; } >- get typeParameters() { return this._typeParameters; } > get isNative() { return true; } > > // We let Intrinsics.js set these as it likes. >@@ -54,18 +50,9 @@ class NativeType extends Type { > get isPrimitive() { return this._isPrimitive; } > set isPrimitive(value) { this._isPrimitive = value; } > >- instantiate(typeArguments) >- { >- if (typeArguments.length != this.typeParameters.length) >- throw new Error("Wrong number of type arguments to instantiation"); >- if (!typeArguments.length) >- return this; >- return new NativeTypeInstance(this, typeArguments); >- } >- > 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..8d58e4d05066af086ad18822bb1de9db9310415f >--- /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" ].concat(allVectorTypeNames()); >+ 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..94419f4406ed9b8d50c1cac37102147b2ab81627 >--- /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" ].concat(allVectorTypeNames()); >+ >+ 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 6d2b431615601ab9dd3d0938fbfb385ee2a4daf1..8dd7a92f8a1a68d60dd4a3443bf1b2f4eca3ad70 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; >@@ -233,7 +199,7 @@ function parse(program, origin, originKind, lineNumberOffset, text) > { > if (!test("<")) > return []; >- >+ > let result = []; > consume("<"); > while (!test(">")) { >@@ -318,7 +284,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(";"); >@@ -345,7 +311,7 @@ function parse(program, origin, originKind, lineNumberOffset, text) > function parseCallExpression() > { > let name = consumeKind("identifier"); >- let typeArguments = parseTypeArguments(); >+ let typeArguments = []; > consume("("); > let argumentList = []; > while (!test(")")) { >@@ -363,7 +329,6 @@ function parse(program, origin, originKind, lineNumberOffset, text) > { > return lexer.testScope(() => { > consumeKind("identifier"); >- parseTypeArguments(); > consume("("); > }); > } >@@ -858,13 +823,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; >@@ -877,18 +841,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() > { >@@ -897,26 +854,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(); >@@ -929,7 +866,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("}")) >@@ -949,9 +886,12 @@ function parse(program, origin, originKind, lineNumberOffset, text) > let origin = consume("native"); > if (tryConsume("typedef")) { > let name = consumeKind("identifier"); >- let parameters = parseTypeParameters(); >+ let args = parseTypeArguments(); > consume(";"); >- return new NativeType(origin, name.text, parameters); >+ if (args.length) >+ return NativeParameterizedType.fromNameAndTypeArguments(origin, name.text, args); >+ else >+ return new NativeType(origin, name.text); > } > return parseNativeFunc(); > } >@@ -1013,8 +953,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/RecursiveTypeChecker.js b/Tools/WebGPUShadingLanguageRI/RecursiveTypeChecker.js >index 91f76742f60d14a37e6e606c3ab2f9c2c8fab116..5c217571d03947329773a9340796e418f76effba 100644 >--- a/Tools/WebGPUShadingLanguageRI/RecursiveTypeChecker.js >+++ b/Tools/WebGPUShadingLanguageRI/RecursiveTypeChecker.js >@@ -53,5 +53,10 @@ class RecursiveTypeChecker extends Visitor { > super.visitTypeRef(node); > node.type.visit(this); > } >+ >+ visitNativeParameterizedType(node) >+ { >+ this._visiting.doVisit(node, () => super.visitNativeParameterizedType(node)); >+ } > } > >diff --git a/Tools/WebGPUShadingLanguageRI/Rewriter.js b/Tools/WebGPUShadingLanguageRI/Rewriter.js >index f40d6b88b26eedcbf829f1babb10a2045b7a8e83..f326e908236481034338e5ed12477b6e6d945819 100644 >--- a/Tools/WebGPUShadingLanguageRI/Rewriter.js >+++ b/Tools/WebGPUShadingLanguageRI/Rewriter.js >@@ -423,5 +423,17 @@ class Rewriter { > { > return new IdentityExpression(node.target.visit(this)); > } >+ >+ visitNativeParameterizedType(node) >+ { >+ let args = node.typeArguments.map(arg => arg.visit(this)); >+ return new NativeParameterizedType(node.origin, node.name, args); >+ } >+ >+ visitVectorType(node) >+ { >+ let args = node.typeArguments.map(arg => arg.visit(this)); >+ return new VectorType(node.origin, node.name, args); >+ } > } > >diff --git a/Tools/WebGPUShadingLanguageRI/SPIRV.html b/Tools/WebGPUShadingLanguageRI/SPIRV.html >index 93f6b9b932d272d77a3dc3167f525fa40a61ed23..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> >@@ -102,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> >@@ -124,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> >@@ -135,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/StandardLibrary.js b/Tools/WebGPUShadingLanguageRI/StandardLibrary.js >index 1988723c3548081c667fac7862f40267f9f8b857..86cd17afdeaef1f385cff3f9ccf60d7c76225a9c 100644 >--- a/Tools/WebGPUShadingLanguageRI/StandardLibrary.js >+++ b/Tools/WebGPUShadingLanguageRI/StandardLibrary.js >@@ -145,227 +145,32 @@ 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(); >-} >+native typedef vector<int32, 2>; >+typedef int2 = vector<int32, 2>; > >-struct vec2<T> { >- T x; >- T y; >-} >+native typedef vector<int32, 3>; >+typedef int3 = vector<int32, 3>; > >-typedef int2 = vec2<int>; >-typedef uint2 = vec2<uint>; >-typedef float2 = vec2<float>; >+native typedef vector<int32, 4>; >+typedef int4 = vector<int32, 4>; > >-operator<T> vec2<T>(T x, T y) >-{ >- vec2<T> result; >- result.x = x; >- result.y = y; >- return result; >-} >+native typedef vector<uint32, 2>; >+typedef uint2 = vector<uint32, 2>; > >-bool operator==<T:Equatable>(vec2<T> a, vec2<T> b) >-{ >- return a.x == b.x && a.y == b.y; >-} >+native typedef vector<uint32, 3>; >+typedef uint3 = vector<uint32, 3>; > >-thread T* operator&[]<T>(thread vec2<T>* foo, uint index) >-{ >- if (index == 0) >- return &foo->x; >- if (index == 1) >- return &foo->y; >- trap; >-} >+native typedef vector<uint32, 4>; >+typedef uint4 = vector<uint32, 4>; > >-struct vec3<T> { >- T x; >- T y; >- T z; >-} >+native typedef vector<float32, 2>; >+typedef float2 = vector<float32, 2>; > >-typedef int3 = vec3<int>; >-typedef uint3 = vec3<uint>; >-typedef float3 = vec3<float>; >+native typedef vector<float32, 3>; >+typedef float3 = vector<float32, 3>; > >-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; >-} >- >-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>; >- >-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; >-} >- >-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 vector<float32, 4>; >+typedef float4 = vector<float32, 4>; > `; > > function intToString(x) >@@ -384,6 +189,31 @@ function intToString(x) > } > } > >+function addFunctionsFromClass(clss) >+{ >+ standardLibrary += clss.functions().join(";\n") + "\n"; >+} >+ >+const VectorElementTypes = [ "int", "uint", "float" ]; >+const VectorElementSizes = [ 2, 3, 4 ]; >+ >+function allVectorTypeNames() >+{ >+ const names = []; >+ for (let elementType of VectorElementTypes) { >+ for (let size of VectorElementSizes) >+ names.push(`${elementType}${size}`); >+ } >+ return names; >+} >+ > // 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..3c13313cecdb3e67222da0be93c1f213ea27b8b0 100644 >--- a/Tools/WebGPUShadingLanguageRI/SwizzleOp.js >+++ b/Tools/WebGPUShadingLanguageRI/SwizzleOp.js >@@ -25,49 +25,67 @@ > "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); >+ for (let typeName of VectorElementTypes) { >+ for (let maxDepth of VectorElementSizes) { >+ 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 a641d3046493dabc2d745e7d0ec96d0bdd441bbc..9b901615f42cd5c09616cceb9896ee961f928a4e 100644 >--- a/Tools/WebGPUShadingLanguageRI/Test.html >+++ b/Tools/WebGPUShadingLanguageRI/Test.html >@@ -12,6 +12,7 @@ > <script src="CreateLiteralType.js"></script> > <script src="PropertyAccessExpression.js"></script> > <script src="SwizzleOp.js"></script> >+<script src="NativeType.js"></script> > > <script src="AddressSpace.js"></script> > <script src="AnonymousVariable.js"></script> >@@ -91,11 +92,20 @@ > <script src="NameResolver.js"></script> > <script src="NativeFunc.js"></script> > <script src="NativeFuncInstance.js"></script> >-<script src="NativeType.js"></script> >+<script src="NativeParameterizedType.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> >@@ -125,8 +135,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> >@@ -142,6 +155,7 @@ > <script src="UnreachableCodeChecker.js"></script> > <script src="VariableDecl.js"></script> > <script src="VariableRef.js"></script> >+<script src="VectorType.js"></script> > <script src="VisitingSet.js"></script> > <script src="WSyntaxError.js"></script> > <script src="WTrapError.js"></script> >diff --git a/Tools/WebGPUShadingLanguageRI/Test.js b/Tools/WebGPUShadingLanguageRI/Test.js >index 2b056902a66cc32d04a1ea720d251e3f70cf9648..0fe0e20b713ad4a3a6ef36d0432c115dd08639b3 100644 >--- a/Tools/WebGPUShadingLanguageRI/Test.js >+++ b/Tools/WebGPUShadingLanguageRI/Test.js >@@ -307,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( >@@ -513,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( >@@ -584,13 +558,12 @@ 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() >@@ -677,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); >@@ -801,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); >@@ -925,22 +820,6 @@ 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; }"); >@@ -974,57 +853,6 @@ tests.badIntLiteralForFloat = function() > (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); >@@ -1099,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(` >@@ -1465,70 +1185,6 @@ 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(` >@@ -1551,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(` >@@ -1980,237 +1560,19 @@ tests.forLoop = function() > checkInt(program, callFunction(program, "foo", [], [makeInt(program, 7)]), 7); > } > >-tests.chainConstexpr = function() >+tests.prefixPlusPlus = 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) >+ int foo(int x) > { >- return bar<42>(b); >+ ++x; >+ return x; > } > `); >- checkInt(program, callFunction(program, "baz", [], [makeInt(program, 58)]), 58 + 42); >+ checkInt(program, callFunction(program, "foo", [], [makeInt(program, 64)]), 65); > } > >-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() >-{ >- let program = doPrep(` >- int foo(int x) >- { >- ++x; >- return x; >- } >- `); >- checkInt(program, callFunction(program, "foo", [], [makeInt(program, 64)]), 65); >-} >- >-tests.prefixPlusPlusResult = function() >+tests.prefixPlusPlusResult = function() > { > let program = doPrep(` > int foo(int x) >@@ -2393,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( >@@ -2693,8 +1995,14 @@ tests.nonArrayRefArrayLengthSucceed = function() > 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() >@@ -2710,42 +2018,6 @@ 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( >@@ -2756,7 +2028,7 @@ tests.assignLength = function() > (@array).length = 42; > } > `), >- (e) => e instanceof WTypeError && e.message.indexOf("Have neither ander nor setter") != -1); >+ (e) => e instanceof WTypeError); > } > > tests.assignLengthHelper = function() >@@ -2773,7 +2045,7 @@ tests.assignLengthHelper = function() > bar(@array); > } > `), >- (e) => e instanceof WTypeError && e.message.indexOf("Have neither ander nor setter") != -1); >+ (e) => e instanceof WTypeError); > } > > tests.simpleGetter = function() >@@ -2821,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(` >@@ -3154,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(` >@@ -3709,29 +2641,6 @@ tests.floatMath = function() > (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() > { > let program = doPrep(` >@@ -3966,6 +2875,38 @@ tests.shaderTypes = function() > (e) => e instanceof WTypeError); > } > >+tests.vectorTypeSyntax = function() >+{ >+ let program = doPrep(` >+ int foo2() >+ { >+ int2 x; >+ vector<int, 2> z = int2(3, 4); >+ x = z; >+ return x.y; >+ } >+ >+ int foo3() >+ { >+ int3 x; >+ vector<int, 3> z = int3(3, 4, 5); >+ x = z; >+ return x.z; >+ } >+ >+ int foo4() >+ { >+ int4 x; >+ vector<int,4> z = int4(3, 4, 5, 6); >+ x = z; >+ return x.w; >+ } >+ `); >+ checkInt(program, callFunction(program, "foo2", [], []), 4); >+ checkInt(program, callFunction(program, "foo3", [], []), 5); >+ checkInt(program, callFunction(program, "foo4", [], []), 6); >+} >+ > tests.builtinVectors = function() > { > let program = doPrep(` >@@ -4104,41 +3045,114 @@ tests.builtinVectors = function() > checkBool(program, callFunction(program, "foof6", [], []), 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() >@@ -4383,39 +3397,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(` >@@ -5246,23 +4227,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(` >@@ -5287,53 +4251,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 float* result, int value) >- { >- *result = float(value); >- } >- operator<T:Barable> T(Foo foo) >- { >- T result; >- bar(&result, foo.x); >- return result; >- } >- int foo() >- { >- Foo foo; >- foo.x = 75; >- float x = float(foo); >- return int(x * 1.5); >- } >- `); >- checkInt(program, callFunction(program, "foo", [], []), 112); >-} >- > tests.incWrongArgumentLength = function() > { > checkFail( >@@ -5900,6 +4817,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( >@@ -6207,306 +5143,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 { >- float 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, float index); >- } >- int bar<T:Foo>(thread T[] x) >- { >- return x[1.5]; >- } >- struct Bar { } >- thread int* operator&[](thread Bar[], float) >- { >- 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..5d6a9006115263da4f48241ab905e65a2d9e2d7c 100644 >--- a/Tools/WebGPUShadingLanguageRI/TypeDef.js >+++ b/Tools/WebGPUShadingLanguageRI/TypeDef.js >@@ -34,6 +34,7 @@ class TypeDef extends Type { > this._type = type; > } > >+ get unifyNode() { return this.type.unifyNode; } > get origin() { return this._origin; } > get name() { return this._name; } > get typeParameters() { return this._typeParameters; } >@@ -41,7 +42,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..878484fbabb857e028151fa0d08787e4cf703acf 100644 >--- a/Tools/WebGPUShadingLanguageRI/TypeRef.js >+++ b/Tools/WebGPUShadingLanguageRI/TypeRef.js >@@ -57,30 +57,22 @@ class TypeRef extends Type { > > get unifyNode() > { >- if (!this.typeArguments.length) >- return this.type.unifyNode; >- return this; >+ return this.type.unifyNode; > } > > populateDefaultValue(buffer, offset) > { >- if (!this.typeArguments.length) >- return this.type.populateDefaultValue(buffer, offset); >- throw new Error("Cannot get default value of a type instantiation"); >+ return this.type.populateDefaultValue(buffer, offset); > } > > get size() > { >- if (!this.typeArguments.length) >- return this.type.size; >- throw new Error("Cannot get size of a type instantiation"); >+ return this.type.size; > } > > get isPrimitive() > { >- if (!this.typeArguments.length) >- return this.type.isPrimitive; >- throw new Error("Cannot determine if an uninstantiated type is primitive: " + this); >+ return this.type.isPrimitive; > } > > setTypeAndArguments(type, typeArguments) >@@ -109,9 +101,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/VectorType.js b/Tools/WebGPUShadingLanguageRI/VectorType.js >new file mode 100644 >index 0000000000000000000000000000000000000000..ef254df576ef282af8d9548790aea92587534aef >--- /dev/null >+++ b/Tools/WebGPUShadingLanguageRI/VectorType.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"; >+ >+class VectorType extends NativeParameterizedType { >+ constructor(origin, name, typeArguments) >+ { >+ super(origin, name, typeArguments); >+ if (typeArguments.length != 2) >+ throw new Error(`Vector type takes 2 arguments, ${typeArguments.length} given.`); >+ } >+ >+ get elementType() { return this._typeArguments[0]; } >+ get numElements() { return this._typeArguments[1]; } >+ >+ get numElementsValue() { return this.numElements.value; } >+ get size() { return this.elementType.size * this.numElementsValue; } >+ >+ unifyImpl(unificationContext, other) >+ { >+ if (!(other instanceof VectorType)) >+ return false; >+ >+ if (!this.numElements.unify(unificationContext, other.numElements)) >+ return false; >+ >+ return this.elementType.unify(unificationContext, other.elementType); >+ } >+ >+ populateDefaultValue(buffer, offset) >+ { >+ for (let i = 0; i < this.numElementsValue; ++i) >+ this.elementType.populateDefaultValue(buffer, offset + i * this.elementType.size); >+ } >+ >+ toString() >+ { >+ return `native typedef ${this.name}<${this.elementType}, ${this.numElementsValue}>`; >+ } >+} >+ >diff --git a/Tools/WebGPUShadingLanguageRI/Visitor.js b/Tools/WebGPUShadingLanguageRI/Visitor.js >index 4bf05313e2857d71efe513ee1e35f050def5336d..f024058b7decc7f005eceb3c8a396bc558c1c048 100644 >--- a/Tools/WebGPUShadingLanguageRI/Visitor.js >+++ b/Tools/WebGPUShadingLanguageRI/Visitor.js >@@ -93,14 +93,14 @@ class Visitor { > > visitTypeRef(node) > { >- for (let typeArgument of node.typeArguments) >- typeArgument.visit(this); >+ // for (let typeArgument of node.typeArguments) >+ // typeArgument.visit(this); > } > > visitNativeType(node) > { >- for (let typeParameter of node.typeParameters) >- typeParameter.visit(this); >+ // for (let typeParameter of node.typeParameters) >+ // typeParameter.visit(this); > } > > visitNativeTypeInstance(node) >@@ -384,5 +384,16 @@ class Visitor { > { > node.target.visit(this); > } >+ >+ visitNativeParameterizedType(node) >+ { >+ for (let typeArg of node.typeArguments) >+ typeArg.visit(this); >+ } >+ >+ visitVectorType(node) >+ { >+ node.elementType.visit(this); >+ } > } > >diff --git a/Tools/WebGPUShadingLanguageRI/index.html b/Tools/WebGPUShadingLanguageRI/index.html >index 8094b193781b4aa9b0c3909e9a91d2815f2b2aba..c5ec13f71676429b3eb25118e9ff67b49d0b7897 100644 >--- a/Tools/WebGPUShadingLanguageRI/index.html >+++ b/Tools/WebGPUShadingLanguageRI/index.html >@@ -1,153 +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="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; >@@ -413,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