WebKit Bugzilla
Attachment 347344 Details for
Bug 187988
: [WHLSL] Remove generics from the interpreter
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
New Account
|
Log In
Remember
[x]
|
Forgot Password
Login:
[x]
[patch]
Patch
bug-187988-20180816203733.patch (text/plain), 456.18 KB, created by
Thomas Denney
on 2018-08-16 20:37:34 PDT
(
hide
)
Description:
Patch
Filename:
MIME Type:
Creator:
Thomas Denney
Created:
2018-08-16 20:37:34 PDT
Size:
456.18 KB
patch
obsolete
>Subversion Revision: 234891 >diff --git a/Tools/ChangeLog b/Tools/ChangeLog >index f6377dbbf9642284e586978ddfecb8571e6197e1..7d88dfda282abaea61a3d06e0232b86263d5ce61 100644 >--- a/Tools/ChangeLog >+++ b/Tools/ChangeLog >@@ -1,3 +1,168 @@ >+2018-08-13 Thomas Denney <tdenney@apple.com> >+ >+ [WHLSL] Remove generics from the interpreter >+ https://bugs.webkit.org/show_bug.cgi?id=187988 >+ >+ Reviewed by NOBODY (OOPS!). >+ >+ This patch completely removes generic and protocol support from WHLSL >+ whilst adding back any features that were originally implemented with >+ generics. >+ >+ Many of the changes in this patch just remove occurrences of type >+ arguments and type parameters --- although there are some cases where >+ they have been deliberately left in --- as well as removing tests only >+ relevant to those features. These changes are not listed below. >+ >+ * WebGPUShadingLanguageRI/All.js: Add/remove JS dependencies >+ * WebGPUShadingLanguageRI/AutoWrapper.js: >+ (AutoWrapper.prototype.visitConstexprTypeParameter): Deleted. >+ * WebGPUShadingLanguageRI/BuiltinVectorCasts.js: Added. The built-in >+ vectors have many constructors for different scalar and vector types. >+ These were originally implemented with generics. >+ * WebGPUShadingLanguageRI/BuiltinVectorEqualityOperator.js: Adds the >+ equality operator for built-in vectors, again this was removed with >+ generics. >+ * WebGPUShadingLanguageRI/BuiltinVectorGetter.js: Added, as above. >+ Built-in vectors only support the getter and setter, and not the ander. >+ * WebGPUShadingLanguageRI/BuiltinVectorIndexGetter.js: Added. >+ * WebGPUShadingLanguageRI/BuiltinVectorIndexSetter.js: Added. >+ * WebGPUShadingLanguageRI/BuiltinVectorSetter.js: Added. >+ * WebGPUShadingLanguageRI/CallExpression.js: Adds support for >+ instantiating functions which cannot be discovered earlier in >+ preparation because their types are absent (specifically support for the >+ operator &[] for array references and the length operator for array >+ references). Previously support for these was implemented with generics. >+ (CallExpression.resolve): >+ (CallExpression.prototype.resolve): >+ (CallExpression.prototype._resolveByInstantiation): >+ (CallExpression.prototype._resolveToOperatorAnderIndexer): >+ (CallExpression.prototype._resolveToOperatorLength): >+ (CallExpression.prototype.resolveToOverload): >+ (CallExpression.prototype.becomeCast): >+ (CallExpression.prototype.toString): >+ (CallExpression): >+ * WebGPUShadingLanguageRI/CallExpressionTypeArgumentResolver.js: Added. >+ We support syntax like vector<int, 2>(a, b) for constructing vectors; >+ this new preparation step resolves them to specific constructors. >+ * WebGPUShadingLanguageRI/CallFunction.js: >+ * WebGPUShadingLanguageRI/Checker.js: >+ * WebGPUShadingLanguageRI/ConstexprFolder.js: >+ * WebGPUShadingLanguageRI/CreateLiteralType.js: >+ * WebGPUShadingLanguageRI/ExpressionFinder.js: >+ * WebGPUShadingLanguageRI/FlattenProtocolExtends.js: Removed. >+ * WebGPUShadingLanguageRI/FlattenedStructOffsetGatherer.js: >+ * WebGPUShadingLanguageRI/Func.js: >+ * WebGPUShadingLanguageRI/FuncDef.js: >+ * WebGPUShadingLanguageRI/FuncInstantiator.js: Deleted. >+ * WebGPUShadingLanguageRI/InferTypesForCall.js: Removed usage of type arguments. >+ * WebGPUShadingLanguageRI/Inline.js: Remove use of FuncInstantiator. >+ * WebGPUShadingLanguageRI/Inliner.js: Ditto. >+ * WebGPUShadingLanguageRI/Intrinsics.js: >+ * WebGPUShadingLanguageRI/Lexer.js: >+ * WebGPUShadingLanguageRI/LiteralTypeChecker.js: >+ * WebGPUShadingLanguageRI/NameContext.js: >+ (NameContext.prototype.add): >+ (NameContext.prototype.get let): >+ (NameContext.underlyingThings.prototype.else): >+ (NameContext.prototype.resolveFuncOverload): >+ * WebGPUShadingLanguageRI/NameFinder.js: >+ * WebGPUShadingLanguageRI/NameResolver.js: >+ (NameResolver.prototype.visitFunc): >+ (NameResolver.prototype.visitFuncDef): >+ (NameResolver.prototype.visitTypeDef): >+ (NameResolver.prototype.visitStructType): >+ (NameResolver.prototype.visitTypeRef): >+ (NameResolver.prototype.visitCallExpression): >+ (NameResolver.prototype.visitVectorType): >+ (NameResolver): >+ (NameResolver.prototype._visitTypeParametersAndBuildNameContext): Deleted. >+ (NameResolver.prototype.visitProtocolDecl): Deleted. >+ * WebGPUShadingLanguageRI/NativeFunc.js: >+ (NativeFunc): >+ * WebGPUShadingLanguageRI/NativeFuncInstance.js: Deleted. >+ * WebGPUShadingLanguageRI/NativeType.js: >+ (NativeType): >+ (NativeType.prototype.get name): >+ (NativeType.prototype.toString): >+ (NativeType.prototype.get typeParameters): Deleted. >+ (NativeType.prototype.instantiate): Deleted. >+ * WebGPUShadingLanguageRI/Node.js: >+ (Node.prototype.commit): >+ (Node): >+ (Node.prototype.substitute): Deleted. >+ (Node.prototype.substituteToUnification): Deleted. >+ * WebGPUShadingLanguageRI/OperatorAnderIndex.js: Added, previously >+ implemented with generics. >+ * WebGPUShadingLanguageRI/OperatorArrayRefLength.js: Ditto. >+ * WebGPUShadingLanguageRI/OperatorBool.js: Ditto. >+ * WebGPUShadingLanguageRI/Parse.js: Removed everything related to >+ generics and protocols. >+ * WebGPUShadingLanguageRI/Prepare.js: Added new stages. >+ * WebGPUShadingLanguageRI/Program.js: >+ (Program): >+ (Program.prototype.get types): >+ (Program.prototype.add): >+ (Program.prototype.get protocols): Deleted. >+ * WebGPUShadingLanguageRI/ProtocolDecl.js: Removed. >+ * WebGPUShadingLanguageRI/ProtocolRef.js: Removed. >+ * WebGPUShadingLanguageRI/RecursiveTypeChecker.js: >+ * WebGPUShadingLanguageRI/ResolveCallExpressionsWithTypeArguments.js: Added. >+ * WebGPUShadingLanguageRI/ResolveNames.js: >+ * WebGPUShadingLanguageRI/ResolveOverloadImpl.js: >+ * WebGPUShadingLanguageRI/ResolveTypeDefs.js: >+ (resolveTypeDefsInProtocols): Deleted. >+ * WebGPUShadingLanguageRI/Rewriter.js: Changes for new classes. >+ * WebGPUShadingLanguageRI/SPIRV.html: >+ * WebGPUShadingLanguageRI/SPIRVCodegen.js: >+ * WebGPUShadingLanguageRI/StandardLibrary.js: Replace old generic features. >+ * WebGPUShadingLanguageRI/StatementCloner.js: Changes for new classes. >+ (StructLayoutBuilder): >+ * WebGPUShadingLanguageRI/StructType.js: >+ * 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: Added, >+ previously implemented with generics. >+ * WebGPUShadingLanguageRI/SynthesizeCopyConstructorOperator.js: Ditto. >+ * WebGPUShadingLanguageRI/SynthesizeDefaultConstructorOperator.js: Ditto. >+ * WebGPUShadingLanguageRI/SynthesizeEnumFunctions.js: Ditto. >+ * WebGPUShadingLanguageRI/SynthesizeOperatorBool.js: Ditto. >+ * WebGPUShadingLanguageRI/SynthesizeStructAccessors.js: >+ (synthesizeStructAccessors.setupImplementationData): >+ (synthesizeStructAccessors.createFieldType): >+ (synthesizeStructAccessors.createTypeRef): >+ (synthesizeStructAccessors.setupAnder): >+ (synthesizeStructAccessors): >+ (synthesizeStructAccessors.createTypeParameters): Deleted. >+ (synthesizeStructAccessors.): Deleted. >+ * WebGPUShadingLanguageRI/Test.html: >+ * WebGPUShadingLanguageRI/Test.js: Removed redundant tests and added new >+ tests for changed language features. >+ * WebGPUShadingLanguageRI/Type.js: >+ * WebGPUShadingLanguageRI/TypeDef.js: >+ * WebGPUShadingLanguageRI/TypeDefResolver.js: >+ * WebGPUShadingLanguageRI/TypeParameterRewriter.js: Removed. >+ * WebGPUShadingLanguageRI/TypeRef.js: >+ * WebGPUShadingLanguageRI/TypeVariable.js: Removed. >+ * WebGPUShadingLanguageRI/UnificationContext.js: >+ * WebGPUShadingLanguageRI/VectorType.js: Added. >+ * WebGPUShadingLanguageRI/Visitor.js: Changes for new classes. >+ * WebGPUShadingLanguageRI/WSL.md: Removed description of >+ generics/protocols. >+ * WebGPUShadingLanguageRI/WrapChecker.js: >+ (WrapChecker): >+ (WrapChecker.visitConstexprTypeParameter): Deleted. >+ (WrapChecker.prototype.visitFuncParameter): Deleted. >+ (WrapChecker.prototype.visitTypeVariable): Deleted. >+ * WebGPUShadingLanguageRI/index.html: >+ > 2018-08-15 Jonathan Bedard <jbedard@apple.com> > > WebKitTestRunner should support watch devices >diff --git a/Tools/WebGPUShadingLanguageRI/All.js b/Tools/WebGPUShadingLanguageRI/All.js >index 15dd7ccab94692a32acd27b9dac96c8a8f55d658..81525273ae65a14865964a13da45ce94ef10684a 100644 >--- a/Tools/WebGPUShadingLanguageRI/All.js >+++ b/Tools/WebGPUShadingLanguageRI/All.js >@@ -1,5 +1,5 @@ > /* >- * Copyright (C) 2017 Apple Inc. All rights reserved. >+ * Copyright (C) 2018 Apple Inc. All rights reserved. > * > * Redistribution and use in source and binary forms, with or without > * modification, are permitted provided that the following conditions >@@ -34,6 +34,8 @@ load("Visitor.js"); > load("CreateLiteral.js"); > load("CreateLiteralType.js"); > load("PropertyAccessExpression.js"); >+load("SwizzleOp.js"); >+load("NativeType.js"); > > load("AddressSpace.js"); > load("AnonymousVariable.js"); >@@ -44,13 +46,19 @@ load("AutoWrapper.js"); > load("Block.js"); > load("BoolLiteral.js"); > load("Break.js"); >+load("BuiltinVectorConstructors.js"); >+load("BuiltinVectorGetter.js"); >+load("BuiltinVectorSetter.js"); >+load("BuiltinVectorIndexGetter.js"); >+load("BuiltinVectorIndexSetter.js"); >+load("BuiltinVectorEqualityOperator.js"); > load("CallExpression.js"); > 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"); >@@ -58,12 +66,11 @@ load("Checker.js"); > load("CloneProgram.js"); > load("CommaExpression.js"); > 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"); >@@ -77,7 +84,6 @@ load("ExpressionFinder.js"); > load("ExternalOrigin.js"); > load("Field.js"); > load("FindHighZombies.js"); >-load("FlattenProtocolExtends.js"); > load("FlattenedStructOffsetGatherer.js"); > load("FloatLiteral.js"); > load("FloatLiteralType.js"); >@@ -85,7 +91,6 @@ load("FoldConstexprs.js"); > load("ForLoop.js"); > load("Func.js"); > load("FuncDef.js"); >-load("FuncInstantiator.js"); > load("FuncParameter.js"); > load("FunctionLikeBlock.js"); > load("HighZombieFinder.js"); >@@ -95,7 +100,6 @@ load("IndexExpression.js"); > load("InferTypesForCall.js"); > load("Inline.js"); > load("Inliner.js"); >-load("InstantiateImmediates.js"); > load("IntLiteral.js"); > load("IntLiteralType.js"); > load("Intrinsics.js"); >@@ -112,27 +116,24 @@ load("NameContext.js"); > load("NameFinder.js"); > load("NameResolver.js"); > load("NativeFunc.js"); >-load("NativeFuncInstance.js"); >-load("NativeType.js"); >-load("NativeTypeInstance.js"); > load("NormalUsePropertyResolver.js"); > load("NullLiteral.js"); > load("NullType.js"); >+load("OperatorAnderIndex.js"); >+load("OperatorArrayRefLength.js"); >+load("OperatorBool.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"); >-load("ProtocolRef.js"); > load("PtrType.js"); > load("ReadModifyWriteExpression.js"); > load("RecursionChecker.js"); > load("RecursiveTypeChecker.js"); >+load("RemoveTypeArguments.js"); > load("ResolveNames.js"); > load("ResolveOverloadImpl.js"); > load("ResolveProperties.js"); >@@ -144,19 +145,18 @@ load("StandardLibrary.js"); > load("StatementCloner.js"); > load("StructLayoutBuilder.js"); > load("StructType.js"); >-load("Substitution.js"); > load("SwitchCase.js"); > load("SwitchStatement.js"); >+load("SynthesizeArrayOperatorLength.js"); > load("SynthesizeEnumFunctions.js"); > load("SynthesizeStructAccessors.js"); >+load("SynthesizeOperatorBool.js"); >+load("SynthesizeCopyConstructorOperator.js"); >+load("SynthesizeDefaultConstructorOperator.js"); > load("TrapStatement.js"); > load("TypeDef.js"); > load("TypeDefResolver.js"); >-load("TypeOrVariableRef.js"); >-load("TypeParameterRewriter.js"); > load("TypeRef.js"); >-load("TypeVariable.js"); >-load("TypeVariableTracker.js"); > load("TypedValue.js"); > load("UintLiteral.js"); > load("UintLiteralType.js"); >@@ -164,10 +164,10 @@ load("UnificationContext.js"); > load("UnreachableCodeChecker.js"); > load("VariableDecl.js"); > load("VariableRef.js"); >+load("VectorType.js"); > load("VisitingSet.js"); > load("WSyntaxError.js"); > load("WTrapError.js"); > load("WTypeError.js"); > load("WhileLoop.js"); >-load("WrapChecker.js"); >- >+load("WrapChecker.js"); >\ No newline at end of file >diff --git a/Tools/WebGPUShadingLanguageRI/AutoWrapper.js b/Tools/WebGPUShadingLanguageRI/AutoWrapper.js >index 80ae7d92a4fa62666db2a2ff5220d149a7f38e9c..ad196b7b1747c4b273d85e5c05e9e2b640d1adcf 100644 >--- a/Tools/WebGPUShadingLanguageRI/AutoWrapper.js >+++ b/Tools/WebGPUShadingLanguageRI/AutoWrapper.js >@@ -1,5 +1,5 @@ > /* >- * Copyright (C) 2017 Apple Inc. All rights reserved. >+ * Copyright (C) 2018 Apple Inc. All rights reserved. > * > * Redistribution and use in source and binary forms, with or without > * modification, are permitted provided that the following conditions >@@ -35,11 +35,6 @@ class AutoWrapper extends Rewriter { > return node; > } > >- visitConstexprTypeParameter(node) >- { >- return VariableRef.wrap(node); >- } >- > visitFuncParameter(node) > { > return VariableRef.wrap(node); >diff --git a/Tools/WebGPUShadingLanguageRI/BuiltinVectorConstructors.js b/Tools/WebGPUShadingLanguageRI/BuiltinVectorConstructors.js >new file mode 100644 >index 0000000000000000000000000000000000000000..2704b43a06c2faed9dfa73dead33bb0c5c955985 >--- /dev/null >+++ b/Tools/WebGPUShadingLanguageRI/BuiltinVectorConstructors.js >@@ -0,0 +1,84 @@ >+/* >+ * Copyright (C) 2018 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 BuiltinVectorConstructors { >+ constructor(baseTypeName, parameterSizes) >+ { >+ this._baseTypeName = baseTypeName; >+ this._parameterSizes = parameterSizes; >+ } >+ >+ get baseTypeName() { return this._baseTypeName; } >+ get parameterSizes() { return this._parameterSizes; } >+ get outputSize() >+ { >+ return this.parameterSizes.reduce((a, b) => a + b, 0); >+ } >+ >+ 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 BuiltinVectorConstructors(typeName, paramSizes)); >+ } >+ } >+ } >+ return this._functions; >+ } >+ >+ static _vectorParameterSizesForMaximumSize(maxSize) >+ { >+ let variants = [ [ maxSize ] ]; >+ for (let splitPoint = 1; splitPoint < maxSize; splitPoint++) { >+ for (let v of BuiltinVectorConstructors._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..b183d356861941bc276e4d3c67c5e47ecafe4709 >--- /dev/null >+++ b/Tools/WebGPUShadingLanguageRI/BuiltinVectorEqualityOperator.js >@@ -0,0 +1,66 @@ >+/* >+ * Copyright (C) 2018 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..c253f7630ee9dc47cd1e1945bc87f42eaa3ccb28 >--- /dev/null >+++ b/Tools/WebGPUShadingLanguageRI/BuiltinVectorGetter.js >@@ -0,0 +1,70 @@ >+/* >+ * Copyright (C) 2018 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..f7262fc9ce2730f087d61455876b335fe024ac3a >--- /dev/null >+++ b/Tools/WebGPUShadingLanguageRI/BuiltinVectorIndexGetter.js >@@ -0,0 +1,66 @@ >+/* >+ * Copyright (C) 2018 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..2fe5d678ab705fe40b7d68e9693dd8afc4adee94 >--- /dev/null >+++ b/Tools/WebGPUShadingLanguageRI/BuiltinVectorIndexSetter.js >@@ -0,0 +1,71 @@ >+/* >+ * Copyright (C) 2018 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},uint,${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..a2d763b7509997b2410c24b801314c34a3c487a0 >--- /dev/null >+++ b/Tools/WebGPUShadingLanguageRI/BuiltinVectorSetter.js >@@ -0,0 +1,73 @@ >+/* >+ * Copyright (C) 2018 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..6dba1532946cda78d7955c564bacccb68230762c 100644 >--- a/Tools/WebGPUShadingLanguageRI/CallExpression.js >+++ b/Tools/WebGPUShadingLanguageRI/CallExpression.js >@@ -1,5 +1,5 @@ > /* >- * Copyright (C) 2017 Apple Inc. All rights reserved. >+ * Copyright (C) 2018 Apple Inc. All rights reserved. > * > * Redistribution and use in source and binary forms, with or without > * modification, are permitted provided that the following conditions >@@ -42,80 +42,121 @@ 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, name, argumentList, argumentTypes, returnType, program) > { >- let call = new CallExpression(origin, name, typeArguments, argumentList); >+ let call = new CallExpression(origin, name, [], 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, program)}; > } >- >- resolve(possibleOverloads, typeParametersInScope, typeArguments) >+ >+ resolve(possibleOverloads, program) > { > if (!possibleOverloads) > throw new WTypeError(this.origin.originString, "Did not find any functions named " + this.name); >- >- let overload = null; >+ > let failures = []; >- for (let typeParameter of typeParametersInScope) { >- if (!(typeParameter instanceof TypeVariable)) >- continue; >- if (!typeParameter.protocol) >- continue; >- let signatures = >- typeParameter.protocol.protocolDecl.signaturesByNameWithTypeVariable(this.name, typeParameter); >- if (!signatures) >- continue; >- overload = resolveOverloadImpl(signatures, this.typeArguments, this.argumentTypes, this.returnType); >- if (overload.func) >- break; >- failures.push(...overload.failures); >- overload = null; >- } >- if (!overload) { >- overload = resolveOverloadImpl( >- possibleOverloads, this.typeArguments, this.argumentTypes, this.returnType); >- if (!overload.func) { >- failures.push(...overload.failures); >- let message = "Did not find function named " + this.name + " for call with "; >- if (this.typeArguments.length) >- message += "type arguments <" + this.typeArguments + "> and "; >- message += "argument types (" + this.argumentTypes + ")"; >- if (this.returnType) >- message +=" and return type " + this.returnType; >- if (failures.length) >- message += ", but considered:\n" + failures.join("\n") >- throw new WTypeError(this.origin.originString, message); >- } >+ let overload = resolveOverloadImpl(possibleOverloads, this.argumentTypes, this.returnType); >+ >+ if (!overload.func) { >+ const func = this._resolveByInstantiation(program); >+ if (func) >+ overload.func = func; > } >- for (let i = 0; i < typeArguments.length; ++i) { >- let typeArgumentType = typeArguments[i]; >- let typeParameter = overload.func.typeParameters[i]; >- if (!(typeParameter instanceof ConstexprTypeParameter)) >- continue; >- if (!typeParameter.type.equalsWithCommit(typeArgumentType)) >- throw new Error("At " + this.origin.originString + " constexpr type argument and parameter types not equal: argument = " + typeArgumentType + ", parameter = " + typeParameter.type); >+ >+ >+ if (!overload.func) { >+ failures.push(...overload.failures); >+ let message = "Did not find function named " + this.name + " for call with "; >+ message += "argument types (" + this.argumentTypes + ")"; >+ if (this.returnType) >+ message +=" and return type " + this.returnType; >+ if (failures.length) >+ message += ", but considered:\n" + failures.join("\n") >+ throw new WTypeError(this.origin.originString, message); > } >+ > for (let i = 0; i < this.argumentTypes.length; ++i) { > let argumentType = this.argumentTypes[i]; >- let parameterType = overload.func.parameters[i].type.substituteToUnification( >- overload.func.typeParameters, overload.unificationContext); >+ let parameterType = overload.func.parameters[i].type; > let result = argumentType.equalsWithCommit(parameterType); > if (!result) > throw new Error("At " + this.origin.originString + " argument and parameter types not equal after type argument substitution: argument = " + argumentType + ", parameter = " + parameterType); > } > return this.resolveToOverload(overload); > } >+ >+ _resolveByInstantiation(program) >+ { >+ let func; >+ if (this.name == "operator&[]") >+ func = this._resolveWithOperatorAnderIndexer(program); >+ else if (this.name == "operator.length") >+ func = this._resolveWithOperatorLength(program); >+ else >+ return null; >+ >+ program.add(func); >+ return func; >+ } >+ >+ _resolveWithOperatorAnderIndexer(program) >+ { >+ 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. >+ const uintType = TypeRef.wrap(program.types.get("uint")); >+ 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); >+ const func = new NativeFunc(this.origin, "operator&[]", this.resultType, [ >+ new FuncParameter(this.origin, null, arrayRefType), >+ new FuncParameter(this.origin, null, uintType) >+ ], false, null); >+ >+ arrayRefAccessor.instantiateImplementation(func); >+ >+ return func; >+ } >+ >+ _resolveWithOperatorLength(program) >+ { >+ this.resultType = this._returnType = TypeRef.wrap(program.types.get("uint")); >+ >+ if (this.argumentTypes[0].isArray) { >+ const arrayType = this.argumentTypes[0]; >+ const func = new NativeFunc(this.origin, "operator.length", this.resultType, [ >+ new FuncParameter(this.origin, null, arrayType) >+ ], false, null); >+ func.implementation = (args, node) => EPtr.box(arrayType.numElementsValue); >+ return func; >+ } else if (this.argumentTypes[0].isArrayRef) { >+ const arrayRefType = this.argumentTypes[0]; >+ const addressSpace = arrayRefType.addressSpace; >+ const operatorLength = new OperatorArrayRefLength(arrayRefType.toString(), addressSpace); >+ const func = new NativeFunc(this.origin, "operator.length", this.resultType, [ >+ new FuncParameter(this.origin, null, arrayRefType) >+ ], false, null); >+ operatorLength.instantiateImplementation(func); >+ return func; >+ } else >+ throw new WTypeError(this.origin.originString, `Expected ${this.argumentTypes[0]} to be array/array ref type for operator.length`); >+ } > > resolveToOverload(overload) > { > this.func = overload.func; >- this.actualTypeArguments = overload.typeArguments.map(typeArgument => typeArgument instanceof Type ? typeArgument.visit(new AutoWrapper()) : typeArgument); >- this.instantiatedActualTypeArguments = this.actualTypeArguments; >- let result = overload.func.returnType.substituteToUnification( >- overload.func.typeParameters, overload.unificationContext); >+ let result = overload.func.returnType; > if (!result) > throw new Error("Null return type"); > result = result.visit(new AutoWrapper()); >@@ -125,11 +166,10 @@ class CallExpression extends Expression { > > becomeCast(returnType) > { >- this._returnType = new TypeRef(this.origin, this.name, this._typeArguments); >+ this._returnType = new TypeRef(this.origin, this.name); > this._returnType.type = returnType; > this._name = "operator cast"; > this._isCast = true; >- this._typeArguments = []; > } > > setCastData(returnType) >@@ -141,8 +181,6 @@ class CallExpression extends Expression { > toString() > { > return (this.isCast ? "operator " + this.returnType : this.name) + >- "<" + this.typeArguments + ">" + >- (this.actualTypeArguments ? "<<" + this.actualTypeArguments + ">>" : "") + > "(" + this.argumentList + ")"; > } > } >diff --git a/Tools/WebGPUShadingLanguageRI/CallFunction.js b/Tools/WebGPUShadingLanguageRI/CallFunction.js >index f0f039f5462d0781d82b3464c87478714c0a1737..7aaf0ba2249ff27ed817c8dc8e772c25da1bb5dc 100644 >--- a/Tools/WebGPUShadingLanguageRI/CallFunction.js >+++ b/Tools/WebGPUShadingLanguageRI/CallFunction.js >@@ -1,5 +1,5 @@ > /* >- * Copyright (C) 2017 Apple Inc. All rights reserved. >+ * Copyright (C) 2018 Apple Inc. All rights reserved. > * > * Redistribution and use in source and binary forms, with or without > * modification, are permitted provided that the following conditions >@@ -25,21 +25,21 @@ > "use strict"; > > // This allows you to pass structs and arrays in-place, but it's a more annoying API. >-function callFunction(program, name, typeArguments, argumentList) >+function callFunction(program, name, argumentList) > { > let argumentTypes = argumentList.map(argument => argument.type); >- let funcOrFailures = resolveInlinedFunction(program, name, typeArguments, argumentTypes, true); >+ let funcOrFailures = resolveInlinedFunction(program, name, argumentTypes, true); > if (!(funcOrFailures instanceof Func)) { > let failures = funcOrFailures; >- throw new WTypeError("<callFunction>", "Cannot resolve function call " + name + "<" + typeArguments + ">(" + argumentList + ")" + (failures.length ? "; tried:\n" + failures.join("\n") : "")); >+ throw new WTypeError("<callFunction>", "Cannot resolve function call " + name + "(" + argumentList + ")" + (failures.length ? "; tried:\n" + failures.join("\n") : "")); > } > let func = funcOrFailures; > for (let i = 0; i < func.parameters.length; ++i) { >- let type = argumentTypes[i].instantiatedType; >+ let type = argumentTypes[i]; > type.visit(new StructLayoutBuilder()); > func.parameters[i].ePtr.copyFrom(argumentList[i].ePtr, type.size); > } > let result = new Evaluator(program).runFunc(func); >- return new TypedValue(func.uninstantiatedReturnType, result); >+ return new TypedValue(func.returnType, result); > } > >diff --git a/Tools/WebGPUShadingLanguageRI/Checker.js b/Tools/WebGPUShadingLanguageRI/Checker.js >index 8d55c50d836c15486fd2580c58e9606cad596ecb..1a14c866aced4112b180f69156c06d2b664d87e2 100644 >--- a/Tools/WebGPUShadingLanguageRI/Checker.js >+++ b/Tools/WebGPUShadingLanguageRI/Checker.js >@@ -1,5 +1,5 @@ > /* >- * Copyright (C) 2017 Apple Inc. All rights reserved. >+ * Copyright (C) 2018 Apple Inc. All rights reserved. > * > * Redistribution and use in source and binary forms, with or without > * modification, are permitted provided that the following conditions >@@ -43,8 +43,6 @@ class Checker extends Visitor { > > for (let type of node.types.values()) > doStatement(type); >- for (let protocol of node.protocols.values()) >- doStatement(protocol); > for (let funcs of node.functions.values()) { > for (let func of funcs) { > this.visitFunc(func); >@@ -59,8 +57,6 @@ class Checker extends Visitor { > _checkShaderType(node) > { > // FIXME: Relax these checks once we have implemented support for textures and samplers. >- if (node.typeParameters.length != 0) >- throw new WTypeError(node.origin.originString, "Entry point " + node.name + " must not have type arguments."); > let shaderFunc = node; > switch (node.shaderType) { > case "vertex": >@@ -84,15 +80,6 @@ class Checker extends Visitor { > if (!func.name.startsWith("operator")) > throw new Error("Bad operator overload name: " + func.name); > >- let typeVariableTracker = new TypeVariableTracker(); >- for (let parameterType of func.parameterTypes) >- parameterType.visit(typeVariableTracker); >- Node.visit(func.returnTypeForOverloadResolution, typeVariableTracker); >- for (let typeParameter of func.typeParameters) { >- if (!typeVariableTracker.set.has(typeParameter)) >- throw new WTypeError(typeParameter.origin.originString, "Type parameter " + typeParameter + " to operator " + func.toDeclString() + " is not inferrable from value parameters"); >- } >- > let checkGetter = (kind) => { > let numExpectedParameters = kind == "index" ? 2 : 1; > if (func.parameters.length != numExpectedParameters) >@@ -115,11 +102,10 @@ class Checker extends Visitor { > if (!getterFuncs) > throw new WTypeError(func.origin.originString, "Every setter must have a matching getter, but did not find any function named " + getterName + " to match " + func.name); > let argumentTypes = func.parameterTypes.slice(0, numExpectedParameters - 1); >- let overload = resolveOverloadImpl(getterFuncs, [], argumentTypes, null); >+ let overload = resolveOverloadImpl(getterFuncs, argumentTypes, null); > if (!overload.func) > throw new WTypeError(func.origin.originString, "Did not find function named " + func.name + " with arguments " + argumentTypes + (overload.failures.length ? "; tried:\n" + overload.failures.join("\n") : "")); >- let resultType = overload.func.returnType.substituteToUnification( >- overload.func.typeParameters, overload.unificationContext); >+ let resultType = overload.func.returnType; > if (!resultType.equals(valueType)) > throw new WTypeError(func.origin.originString, "Setter and getter must agree on value type (getter at " + overload.func.origin.originString + " says " + resultType + " while this setter says " + valueType + ")"); > }; >@@ -207,27 +193,6 @@ class Checker extends Visitor { > node.body.visit(this); > } > >- visitNativeFunc(node) >- { >- } >- >- visitProtocolDecl(node) >- { >- for (let signature of node.signatures) { >- let typeVariableTracker = new TypeVariableTracker(); >- for (let parameterType of signature.parameterTypes) >- parameterType.visit(typeVariableTracker); >- Node.visit(signature.returnTypeForOverloadResolution, typeVariableTracker); >- for (let typeParameter of signature.typeParameters) { >- if (!typeVariableTracker.set.has(typeParameter)) >- throw WTypeError(typeParameter.origin.originString, "Type parameter to protocol signature not inferrable from value parameters"); >- } >- if (!typeVariableTracker.set.has(node.typeVariable)) >- throw new WTypeError(signature.origin.originString, "Protocol's type variable (" + node.name + ") not mentioned in signature: " + signature); >- this._checkOperatorOverload(signature, name => node.signaturesByName(name)); >- } >- } >- > visitEnumType(node) > { > node.baseType.visit(this); >@@ -278,29 +243,31 @@ class Checker extends Visitor { > throw new WTypeError(node.origin.originString, "Enum does not have a member with the value zero"); > } > >- _checkTypeArguments(origin, typeParameters, typeArguments) >- { >- for (let i = 0; i < typeParameters.length; ++i) { >- let argumentIsType = typeArguments[i] instanceof Type; >- let result = typeArguments[i].visit(this); >- if (argumentIsType) { >- let result = 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(typeParameters[i].type)) >- throw new WTypeError(origin.originString, "Wrong type for constexpr"); >- } >- } >- } >- > visitTypeRef(node) > { > if (!node.type) > 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); >+ } >+ >+ visitVectorType(node) >+ { >+ node.elementType.visit(this); >+ >+ let isKnownAllowedVectorElementType = false; >+ for (let vectorElementTypeName of VectorElementTypes) { >+ const vectorElementType = this._program.globalNameContext.get(Type, vectorElementTypeName); >+ if (!vectorElementType) >+ throw new WTypeError(`${vectorElementType} is listed in VectorElementTypes, but it is not a known native type in the standard library or intrinsics.`); >+ if (vectorElementType.equals(node.elementType)) { >+ isKnownAllowedVectorElementType = true; >+ break; >+ } >+ } >+ >+ if (!isKnownAllowedVectorElementType) >+ throw new WTypeError(`${node.elementType} is not a permitted vector element type.`); > } > > visitArrayType(node) >@@ -312,8 +279,8 @@ class Checker extends Visitor { > > let type = node.numElements.visit(this); > >- if (!type.equalsWithCommit(this._program.intrinsics.uint32)) >- throw new WTypeError(node.origin.originString, "Array length must be a uint32"); >+ if (!type.equalsWithCommit(this._program.intrinsics.uint)) >+ throw new WTypeError(node.origin.originString, "Array length must be a uint"); > } > > visitVariableDecl(node) >@@ -401,7 +368,7 @@ class Checker extends Visitor { > node.numElements = elementType.numElements; > elementType = elementType.elementType; > } else >- node.numElements = UintLiteral.withType(node.origin, 1, this._program.intrinsics.uint32); >+ node.numElements = UintLiteral.withType(node.origin, 1, this._program.intrinsics.uint); > > return new ArrayRefType(node.origin, node.lValue.addressSpace, elementType); > } >@@ -426,8 +393,8 @@ 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.origin, node.possibleGetOverloads, >+ node.getFuncName, [node.base, ...extraArgs], [baseType, ...extraArgTypes], null, this._program); > node.callForGet = result.call; > node.resultTypeForGet = result.resultType; > } catch (e) { >@@ -440,9 +407,9 @@ class Checker extends Visitor { > let baseForAnd = baseType.argumentForAndOverload(node.origin, node.base); > > let result = CallExpression.resolve( >- node.origin, node.possibleAndOverloads, this._currentStatement.typeParameters, >- node.andFuncName, [], [baseForAnd, ...extraArgs], [typeForAnd, ...extraArgTypes], >- null); >+ node.origin, node.possibleAndOverloads, >+ node.andFuncName, [baseForAnd, ...extraArgs], [typeForAnd, ...extraArgTypes], >+ null, this._program); > node.callForAnd = result.call; > node.resultTypeForAnd = result.resultType.unifyNode.returnTypeFromAndOverload(node.origin); > } catch (e) { >@@ -466,8 +433,8 @@ 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.origin, node.possibleSetOverloads, >+ node.setFuncName, [node.base, ...extraArgs, null], [baseType, ...extraArgTypes, node.resultType], null, this._program); > 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); >@@ -675,7 +642,6 @@ class Checker extends Visitor { > > visitCallExpression(node) > { >- let typeArguments = node.typeArguments.map(typeArgument => typeArgument.visit(this)); > let argumentTypes = node.argumentList.map(argument => { > let newArgument = argument.visit(this); > if (!newArgument) >@@ -687,7 +653,7 @@ class Checker extends Visitor { > if (node.returnType) > node.returnType.visit(this); > >- let result = node.resolve(node.possibleOverloads, this._currentStatement.typeParameters, typeArguments); >+ let result = node.resolve(node.possibleOverloads, this._program); > return result; > } > } >diff --git a/Tools/WebGPUShadingLanguageRI/ConstexprFolder.js b/Tools/WebGPUShadingLanguageRI/ConstexprFolder.js >index 1e5ad6615b39243c06a0c45aef7634f637653750..5451332d7f10c495cee94f6139645878abb071d2 100644 >--- a/Tools/WebGPUShadingLanguageRI/ConstexprFolder.js >+++ b/Tools/WebGPUShadingLanguageRI/ConstexprFolder.js >@@ -1,5 +1,5 @@ > /* >- * Copyright (C) 2017 Apple Inc. All rights reserved. >+ * Copyright (C) 2018 Apple Inc. All rights reserved. > * > * Redistribution and use in source and binary forms, with or without > * modification, are permitted provided that the following conditions >@@ -34,7 +34,6 @@ class ConstexprFolder extends Visitor { > super.visitCallExpression(node); > > if (node.name == "operator-" >- && !node.typeArguments.length > && node.argumentList.length == 1 > && node.argumentList[0].unifyNode.isConstexpr > && node.argumentList[0].unifyNode.negConstexpr) { >@@ -42,9 +41,5 @@ class ConstexprFolder extends Visitor { > return; > } > } >- >- visitTypeOrVariableRef(node) >- { >- } > } > >diff --git a/Tools/WebGPUShadingLanguageRI/ConstexprTypeParameter.js b/Tools/WebGPUShadingLanguageRI/ConstexprTypeParameter.js >deleted file mode 100644 >index e3c1826ed55f3fe56f7e0ed2a03dfda028da5b39..0000000000000000000000000000000000000000 >--- a/Tools/WebGPUShadingLanguageRI/ConstexprTypeParameter.js >+++ /dev/null >@@ -1,74 +0,0 @@ >-/* >- * Copyright (C) 2017 Apple Inc. All rights reserved. >- * >- * Redistribution and use in source and binary forms, with or without >- * modification, are permitted provided that the following conditions >- * are met: >- * 1. Redistributions of source code must retain the above copyright >- * notice, this list of conditions and the following disclaimer. >- * 2. Redistributions in binary form must reproduce the above copyright >- * notice, this list of conditions and the following disclaimer in the >- * documentation and/or other materials provided with the distribution. >- * >- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY >- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE >- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR >- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR >- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, >- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, >- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR >- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY >- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT >- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE >- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. >- */ >-"use strict"; >- >-class ConstexprTypeParameter extends Value { >- constructor(origin, name, type) >- { >- super(); >- this._origin = origin; >- this._name = name; >- this._type = type; >- } >- >- get origin() { return this._origin; } >- get name() { return this._name; } >- get type() { return this._type; } >- get isConstexpr() { return true; } >- get isUnifiable() { return true; } >- get varIsLValue() { return false; } >- >- typeVariableUnify(unificationContext, other) >- { >- if (!(other instanceof Value)) >- return false; >- >- if (!this.type.unify(unificationContext, other.type)) >- return false; >- >- return this._typeVariableUnifyImpl(unificationContext, other); >- } >- >- unifyImpl(unificationContext, other) >- { >- return this.typeVariableUnify(unificationContext, other); >- } >- >- verifyAsArgument(unificationContext) >- { >- return {result: true}; >- } >- >- verifyAsParameter(unificationContext) >- { >- return {result: true}; >- } >- >- toString() >- { >- return this.type + " " + this.name; >- } >-} >- >diff --git a/Tools/WebGPUShadingLanguageRI/CreateLiteralType.js b/Tools/WebGPUShadingLanguageRI/CreateLiteralType.js >index 12914da3137fd6b90feda7258627effffbd4e541..8c5df26a1dde42b74d1c5a1d608ce09754bfb02e 100644 >--- a/Tools/WebGPUShadingLanguageRI/CreateLiteralType.js >+++ b/Tools/WebGPUShadingLanguageRI/CreateLiteralType.js >@@ -1,5 +1,5 @@ > /* >- * Copyright (C) 2017 Apple Inc. All rights reserved. >+ * Copyright (C) 2018 Apple Inc. All rights reserved. > * > * Redistribution and use in source and binary forms, with or without > * modification, are permitted provided that the following conditions >@@ -32,7 +32,7 @@ function createLiteralType(config) > super(); > this._origin = origin; > this._value = value; >- this.preferredType = new TypeRef(origin, config.preferredTypeName, []); >+ this.preferredType = new TypeRef(origin, config.preferredTypeName); > } > > get origin() { return this._origin; } >@@ -58,7 +58,7 @@ function createLiteralType(config) > prepareToVerify(unificationContext) > { > let realThis = unificationContext.find(this); >- if (realThis instanceof TypeVariable || realThis.isLiteral) { >+ if (realThis.isLiteral) { > return () => { > if (realThis.unify(unificationContext, this.preferredType)) > return {result: true}; >diff --git a/Tools/WebGPUShadingLanguageRI/Evaluator.js b/Tools/WebGPUShadingLanguageRI/Evaluator.js >index 58ced89b7e47770023c7d8e1e81928751262eb38..394407efbcee1b8a0580a2f285d7453108ad0644 100644 >--- a/Tools/WebGPUShadingLanguageRI/Evaluator.js >+++ b/Tools/WebGPUShadingLanguageRI/Evaluator.js >@@ -1,5 +1,5 @@ > /* >- * Copyright (C) 2017 Apple Inc. All rights reserved. >+ * Copyright (C) 2018 Apple Inc. All rights reserved. > * > * Redistribution and use in source and binary forms, with or without > * modification, are permitted provided that the following conditions >@@ -307,7 +307,7 @@ class Evaluator extends Visitor { > let callArguments = []; > for (let i = 0; i < node.argumentList.length; ++i) { > let argument = node.argumentList[i]; >- let type = node.nativeFuncInstance.parameterTypes[i]; >+ let type = node.func.parameterTypes[i]; > if (!type || !argument) > throw new Error("Cannot get type or argument; i = " + i + ", argument = " + argument + ", type = " + type + "; in " + node); > let argumentValue = argument.visit(this); >@@ -324,7 +324,7 @@ class Evaluator extends Visitor { > let result = EBuffer.allowAllocation( > () => node.func.implementation(callArguments.map(thunk => thunk()), node)); > >- result = this._snapshot(node.nativeFuncInstance.returnType, node.resultEPtr, result); >+ result = this._snapshot(node.func.returnType, node.resultEPtr, result); > return result; > } > } >diff --git a/Tools/WebGPUShadingLanguageRI/ExpressionFinder.js b/Tools/WebGPUShadingLanguageRI/ExpressionFinder.js >index 30e6b031a6dd66597407f3f6b7fe713ed8fdcc4a..984a5434de5dbc980c464c67ee4324a162be9d4c 100644 >--- a/Tools/WebGPUShadingLanguageRI/ExpressionFinder.js >+++ b/Tools/WebGPUShadingLanguageRI/ExpressionFinder.js >@@ -1,5 +1,5 @@ > /* >- * Copyright (C) 2017 Apple Inc. All rights reserved. >+ * Copyright (C) 2018 Apple Inc. All rights reserved. > * > * Redistribution and use in source and binary forms, with or without > * modification, are permitted provided that the following conditions >@@ -35,8 +35,6 @@ class ExpressionFinder extends Visitor { > visitFunc(node) > { > this._callback(node.returnType); >- for (let typeParameter of node.typeParameters) >- typeParameter.visit(this); > for (let parameter of node.parameters) > parameter.visit(this); > } >@@ -46,11 +44,6 @@ class ExpressionFinder extends Visitor { > this._callback(node.type); > } > >- visitConstexprTypeParameter(node) >- { >- this._callback(node.type); >- } >- > visitAssignment(node) > { > this._callback(node); >diff --git a/Tools/WebGPUShadingLanguageRI/FlattenProtocolExtends.js b/Tools/WebGPUShadingLanguageRI/FlattenProtocolExtends.js >deleted file mode 100644 >index 76172d98d1e2c008edb5d8183f5eefd678dc8ee9..0000000000000000000000000000000000000000 >--- a/Tools/WebGPUShadingLanguageRI/FlattenProtocolExtends.js >+++ /dev/null >@@ -1,53 +0,0 @@ >-/* >- * Copyright (C) 2017 Apple Inc. All rights reserved. >- * >- * Redistribution and use in source and binary forms, with or without >- * modification, are permitted provided that the following conditions >- * are met: >- * 1. Redistributions of source code must retain the above copyright >- * notice, this list of conditions and the following disclaimer. >- * 2. Redistributions in binary form must reproduce the above copyright >- * notice, this list of conditions and the following disclaimer in the >- * documentation and/or other materials provided with the distribution. >- * >- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY >- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE >- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR >- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR >- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, >- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, >- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR >- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY >- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT >- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE >- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. >- */ >-"use strict"; >- >-function flattenProtocolExtends(program) >-{ >- let visiting = new VisitingSet(); >- >- function flatten(protocol) >- { >- if (!protocol.extends.length) >- return; >- >- visiting.doVisit(protocol, () => { >- for (let parent of protocol.extends) { >- parent = parent.protocolDecl; >- flatten(parent); >- for (let signature of parent.signatures) { >- let newSignature = signature.visit( >- new Substitution([parent.typeVariable], [protocol.typeVariable])); >- protocol.add(newSignature); >- } >- } >- protocol.extends = []; >- }); >- } >- >- for (let protocol of program.protocols.values()) >- flatten(protocol); >-} >- >diff --git a/Tools/WebGPUShadingLanguageRI/FlattenedStructOffsetGatherer.js b/Tools/WebGPUShadingLanguageRI/FlattenedStructOffsetGatherer.js >index 01015ce85804270125dd4789547d30731159101d..1970f8ed932cd3530a48dc31af8c9c4240dde8d0 100644 >--- a/Tools/WebGPUShadingLanguageRI/FlattenedStructOffsetGatherer.js >+++ b/Tools/WebGPUShadingLanguageRI/FlattenedStructOffsetGatherer.js >@@ -1,5 +1,5 @@ > /* >- * Copyright (C) 2017 Apple Inc. All rights reserved. >+ * Copyright (C) 2018 Apple Inc. All rights reserved. > * > * Redistribution and use in source and binary forms, with or without > * modification, are permitted provided that the following conditions >@@ -62,5 +62,17 @@ class FlattenedStructOffsetGatherer extends Visitor { > super.visitTypeRef(node); > Node.visit(node.type, this); > } >+ >+ visitVectorType(node) >+ { >+ const fieldNames = [ "x", "y", "z", "w" ]; >+ for (let i = 0; i < node.numElementsValue; i++) { >+ this._result.push({ >+ name: this._name.join(".") + "." + fieldNames[i], >+ offset: this._offset + i * node.elementType.size, >+ type: node.elementType.name >+ }); >+ } >+ } > } > >diff --git a/Tools/WebGPUShadingLanguageRI/Func.js b/Tools/WebGPUShadingLanguageRI/Func.js >index 6fa7c9d1b6f4b958335981c2728be865a56e73ae..cbc2c333f666f687c07d33dc0188cc9846a3f6d2 100644 >--- a/Tools/WebGPUShadingLanguageRI/Func.js >+++ b/Tools/WebGPUShadingLanguageRI/Func.js >@@ -1,5 +1,5 @@ > /* >- * Copyright (C) 2017 Apple Inc. All rights reserved. >+ * Copyright (C) 2018 Apple Inc. All rights reserved. > * > * Redistribution and use in source and binary forms, with or without > * modification, are permitted provided that the following conditions >@@ -25,7 +25,7 @@ > "use strict"; > > class Func extends Node { >- constructor(origin, name, returnType, typeParameters, parameters, isCast, shaderType) >+ constructor(origin, name, returnType, parameters, isCast, shaderType) > { > if (!(origin instanceof LexerToken)) > throw new Error("Bad origin: " + origin); >@@ -39,7 +39,6 @@ class Func extends Node { > this._origin = origin; > this._name = name; > this._returnType = returnType; >- this._typeParameters = typeParameters; > this._parameters = parameters; > this._isCast = isCast; > this._shaderType = shaderType; >@@ -48,8 +47,6 @@ class Func extends Node { > get origin() { return this._origin; } > get name() { return this._name; } > get returnType() { return this._returnType; } >- get typeParameters() { return this._typeParameters; } >- get typeParametersForCallResolution() { return this.typeParameters; } > get parameters() { return this._parameters; } > get parameterTypes() { return this.parameters.map(parameter => parameter.type); } > get isCast() { return this._isCast; } >@@ -65,9 +62,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/FuncDef.js b/Tools/WebGPUShadingLanguageRI/FuncDef.js >index 11fa092e3b2278e215a0a67e951e17daba136a83..d68e4030e59a571182c604b3e2bd37a704958323 100644 >--- a/Tools/WebGPUShadingLanguageRI/FuncDef.js >+++ b/Tools/WebGPUShadingLanguageRI/FuncDef.js >@@ -1,5 +1,5 @@ > /* >- * Copyright (C) 2017 Apple Inc. All rights reserved. >+ * Copyright (C) 2018 Apple Inc. All rights reserved. > * > * Redistribution and use in source and binary forms, with or without > * modification, are permitted provided that the following conditions >@@ -25,9 +25,9 @@ > "use strict"; > > class FuncDef extends Func { >- constructor(origin, name, returnType, typeParameters, parameters, body, isCast, shaderType) >+ constructor(origin, name, returnType, parameters, body, isCast, shaderType) > { >- super(origin, name, returnType, typeParameters, parameters, isCast, shaderType); >+ super(origin, name, returnType, parameters, isCast, shaderType); > this._body = body; > this.isRestricted = false; > } >@@ -36,8 +36,6 @@ class FuncDef extends Func { > > rewrite(rewriter) > { >- if (this._typeParameters.length) >- throw new Error("Cannot rewrite an uninstantiated function"); > this._returnType = this._returnType.visit(rewriter); > this._parameters = this._parameters.map(parameter => parameter.visit(rewriter)); > this._body = this.body.visit(rewriter); >diff --git a/Tools/WebGPUShadingLanguageRI/FuncInstantiator.js b/Tools/WebGPUShadingLanguageRI/FuncInstantiator.js >deleted file mode 100644 >index 892862a6dd8565ee37e420631d7af70d5227e586..0000000000000000000000000000000000000000 >--- a/Tools/WebGPUShadingLanguageRI/FuncInstantiator.js >+++ /dev/null >@@ -1,154 +0,0 @@ >-/* >- * Copyright (C) 2017 Apple Inc. All rights reserved. >- * >- * Redistribution and use in source and binary forms, with or without >- * modification, are permitted provided that the following conditions >- * are met: >- * 1. Redistributions of source code must retain the above copyright >- * notice, this list of conditions and the following disclaimer. >- * 2. Redistributions in binary form must reproduce the above copyright >- * notice, this list of conditions and the following disclaimer in the >- * documentation and/or other materials provided with the distribution. >- * >- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY >- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE >- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR >- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR >- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, >- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, >- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR >- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY >- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT >- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE >- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. >- */ >-"use strict"; >- >-class FuncInstantiator { >- constructor(program) >- { >- this._program = program; >- this._instances = new Map(); >- } >- >- get instances() { return this._instances; } >- >- // Returns a Func object that uniquely identifies a particular system of type arguments. You must >- // intantiate things with concrete types, because this code casually assumes this. Note that this >- // will return a different func from `func` no matter what. This ensures that we can use the >- // returned func for rewrites that instantiate types without destroying our ability to do overload >- // resolutions on the original Program. >- getUnique(func, typeArguments) >- { >- class FindTypeVariable extends Visitor { >- visitTypeRef(node) >- { >- for (let typeArgument of node.typeArguments) >- typeArgument.visit(this); >- } >- >- visitTypeVariable(node) { >- throw new Error("Unexpected type variable: " + node + " when instantiating " + func + " with arguments " + typeArguments); >- } >- } >- for (let typeArgument of typeArguments) >- typeArgument.visit(new FindTypeVariable()); >- >- let instances = this._instances.get(func); >- if (!instances) >- this._instances.set(func, instances = []); >- >- for (let instance of instances) { >- let ok = true; >- for (let i = instance.typeArguments.length; i--;) { >- if (!instance.typeArguments[i].equals(typeArguments[i])) { >- ok = false; >- break; >- } >- } >- if (!ok) >- continue; >- return instance.func; >- } >- >- let thisInstantiator = this; >- >- class InstantiationSubstitution extends Substitution { >- visitCallExpression(node) >- { >- let result = super.visitCallExpression(node); >- >- // We may have to re-resolve the function call, if it was a call to a protocol >- // signature. >- if (result.func instanceof ProtocolFuncDecl) { >- let overload = resolveOverloadImpl(result.possibleOverloads, result.typeArguments, result.argumentTypes, result.returnType); >- if (!overload.func) >- throw new Error("Could not resolve protocol signature function call during instantiation: " + result.func + (overload.failures.length ? "; tried:\n" + overload.failures.join("\n") : "")); >- result.resolveToOverload(overload); >- } >- >- if (result.func.isNative) >- result.nativeFuncInstance = thisInstantiator.getUnique(result.func, result.actualTypeArguments); >- >- return result; >- } >- } >- >- let substitution = new InstantiationSubstitution(func.typeParameters, typeArguments); >- >- class InstantiationInstantiateImmediates extends InstantiateImmediates { >- visitCallExpression(node) >- { >- // We need to preserve certain things that would have instantiated, but that we cannot >- // instantiate without breaking chain-instantiations (generic function calls generic >- // function so therefore the instantiated generic function must still have the original >- // (uninstantiated) types to instantiate the generic function that it calls). >- let result = new CallExpression( >- node.origin, node.name, node.typeArguments, >- node.argumentList.map(argument => Node.visit(argument, this))); >- result = this.processDerivedCallData(node, result); >- >- result.argumentTypes = Array.from(node.argumentTypes); >- if (node.isCast) >- result.setCastData(node.returnType); >- result.actualTypeArguments = Array.from(node.actualTypeArguments); >- >- return result; >- } >- } >- >- let instantiateImmediates = new InstantiationInstantiateImmediates(); >- >- class Instantiate { >- visitFuncDef(func) >- { >- let returnType = func.returnType.visit(substitution); >- returnType = returnType.visit(instantiateImmediates); >- let parameters = func.parameters.map(parameter => parameter.visit(substitution)); >- parameters = parameters.map(parameter => parameter.visit(instantiateImmediates)); >- let body = func.body.visit(substitution); >- body = body.visit(instantiateImmediates); >- return new FuncDef( >- func.origin, func.name, returnType, [], parameters, body, func.isCast, >- func.shaderType); >- } >- >- visitNativeFunc(func) >- { >- return new NativeFuncInstance( >- func, >- func.returnType.visit(substitution).visit(instantiateImmediates), >- func.parameters.map(parameter => parameter.visit(substitution).visit(instantiateImmediates)), >- func.isCast, >- func.shaderType, >- func.instantiateImplementation(substitution)); >- } >- } >- let resultingFunc = func.visit(new Instantiate()); >- resultingFunc.uninstantiatedReturnType = func.returnType.visit(substitution); >- let instance = {func: resultingFunc, typeArguments}; >- instances.push(instance); >- return resultingFunc; >- } >-} >- >diff --git a/Tools/WebGPUShadingLanguageRI/InferTypesForCall.js b/Tools/WebGPUShadingLanguageRI/InferTypesForCall.js >index 446b351da5715c68a35d7697969d698ec73e74f8..5f32ed1c490a7df8941e919c130cf65eaa8b6a4d 100644 >--- a/Tools/WebGPUShadingLanguageRI/InferTypesForCall.js >+++ b/Tools/WebGPUShadingLanguageRI/InferTypesForCall.js >@@ -1,5 +1,5 @@ > /* >- * Copyright (C) 2017 Apple Inc. All rights reserved. >+ * Copyright (C) 2018 Apple Inc. All rights reserved. > * > * Redistribution and use in source and binary forms, with or without > * modification, are permitted provided that the following conditions >@@ -20,44 +20,32 @@ > * 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. >+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. > */ > "use strict"; > >-function inferTypesForCall(func, typeArguments, argumentTypes, returnType) >+function inferTypesForCall(func, argumentTypes, returnType) > { >- if (typeArguments.length && typeArguments.length != func.typeParameters.length) >- return {failure: new OverloadResolutionFailure(func, "Wrong number of type arguments (passed " + typeArguments.length + ", require " + func.typeParameters.length + ")")}; > if (argumentTypes.length != func.parameters.length) > return {failure: new OverloadResolutionFailure(func, "Wrong number of arguments (passed " + argumentTypes.length + ", require " + func.parameters.length + ")")}; >- let unificationContext = new UnificationContext(func.typeParametersForCallResolution); >- for (let i = 0; i < typeArguments.length; ++i) { >- let argument = typeArguments[i]; >- let parameter = func.typeParameters[i]; >- if (!argument.unify(unificationContext, parameter)) >- return {failure: new OverloadResolutionFailure(func, "Type argument #" + (i + 1) + " for parameter " + parameter.name + " does not match (passed " + argument + ", require " + parameter + ")")}; >- } >+ let unificationContext = new UnificationContext(); >+ > for (let i = 0; i < argumentTypes.length; ++i) { > if (!argumentTypes[i]) > throw new Error("Null argument type at i = " + i); > 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)}; >- let shouldBuildTypeArguments = !typeArguments.length; >- if (shouldBuildTypeArguments) >- typeArguments = []; >- for (let typeParameter of func.typeParameters) { >- let typeArgument = unificationContext.find(typeParameter); >- if (typeArgument == typeParameter) >- return {failure: new OverloadResolutionFailure(func, "Type parameter " + typeParameter + " did not get assigned a type")}; >- if (shouldBuildTypeArguments) >- typeArguments.push(typeArgument); >- } >- return {func, unificationContext, typeArguments}; >+ >+ return {func, unificationContext}; > } > >diff --git a/Tools/WebGPUShadingLanguageRI/Inline.js b/Tools/WebGPUShadingLanguageRI/Inline.js >index f02873bd273d910b3df04fd2a51a3c7c0a467cef..8ba9ad74e7c2a70367225214719a61fb7fbfa3c5 100644 >--- a/Tools/WebGPUShadingLanguageRI/Inline.js >+++ b/Tools/WebGPUShadingLanguageRI/Inline.js >@@ -1,5 +1,5 @@ > /* >- * Copyright (C) 2017 Apple Inc. All rights reserved. >+ * Copyright (C) 2018 Apple Inc. All rights reserved. > * > * Redistribution and use in source and binary forms, with or without > * modification, are permitted provided that the following conditions >@@ -27,19 +27,13 @@ > function inline(program) > { > for (let funcList of program.functions.values()) { >- for (let func of funcList) { >- if (!func.typeParameters.length) { >- func = program.funcInstantiator.getUnique(func, []) >- _inlineFunction(program, func, new VisitingSet(func)); >- } >- } >+ for (let func of funcList) >+ _inlineFunction(program, func, new VisitingSet(func)); > } > } > > function _inlineFunction(program, func, visiting) > { >- if (func.typeParameters.length) >- throw new Error("Cannot inline function that has type parameters"); > if (func.inlined || func.isNative) > return; > >@@ -55,14 +49,13 @@ function _inlineFunction(program, func, visiting) > func.inlined = true; > } > >-function resolveInlinedFunction(program, name, typeArguments, argumentTypes, allowEntryPoint = false) >+function resolveInlinedFunction(program, name, argumentTypes, allowEntryPoint = false) > { >- let overload = program.globalNameContext.resolveFuncOverload(name, typeArguments, argumentTypes, undefined, allowEntryPoint); >+ let overload = program.globalNameContext.resolveFuncOverload(name, argumentTypes, undefined, allowEntryPoint); > if (!overload.func) > return overload.failures; >- if (!overload.func.typeParameters) >- return overload.func; >- let func = program.funcInstantiator.getUnique(overload.func, overload.typeArguments); >- _inlineFunction(program, func, new VisitingSet(overload.func)); >+ >+ let func = overload.func; >+ _inlineFunction(program, func, new VisitingSet(func)); > return func; > } >diff --git a/Tools/WebGPUShadingLanguageRI/Inliner.js b/Tools/WebGPUShadingLanguageRI/Inliner.js >index 491ef3e221fc06318ee0367a381699e5723bfe5a..56c40dfc717e60ebcb5b0e485003becb450b1dff 100644 >--- a/Tools/WebGPUShadingLanguageRI/Inliner.js >+++ b/Tools/WebGPUShadingLanguageRI/Inliner.js >@@ -1,5 +1,5 @@ > /* >- * Copyright (C) 2017 Apple Inc. All rights reserved. >+ * Copyright (C) 2018 Apple Inc. All rights reserved. > * > * Redistribution and use in source and binary forms, with or without > * modification, are permitted provided that the following conditions >@@ -35,10 +35,10 @@ class Inliner extends Rewriter { > visitCallExpression(node) > { > let result = super.visitCallExpression(node); >- if (result.nativeFuncInstance) >+ if (result.func.isNative) > return result; >- return this._visiting.doVisit(node.func, () => { >- let func = this._program.funcInstantiator.getUnique(result.func, result.actualTypeArguments); >+ return this._visiting.doVisit(result.func, () => { >+ let func = result.func; > if (func.isNative) > throw new Error("Unexpected native func: " + func); > _inlineFunction(this._program, func, this._visiting); >diff --git a/Tools/WebGPUShadingLanguageRI/InstantiateImmediates.js b/Tools/WebGPUShadingLanguageRI/InstantiateImmediates.js >deleted file mode 100644 >index 2b39ed6638141348abc127696b6ee31e0b0c58b6..0000000000000000000000000000000000000000 >--- a/Tools/WebGPUShadingLanguageRI/InstantiateImmediates.js >+++ /dev/null >@@ -1,44 +0,0 @@ >-/* >- * Copyright (C) 2017 Apple Inc. All rights reserved. >- * >- * Redistribution and use in source and binary forms, with or without >- * modification, are permitted provided that the following conditions >- * are met: >- * 1. Redistributions of source code must retain the above copyright >- * notice, this list of conditions and the following disclaimer. >- * 2. Redistributions in binary form must reproduce the above copyright >- * notice, this list of conditions and the following disclaimer in the >- * documentation and/or other materials provided with the distribution. >- * >- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY >- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE >- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR >- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR >- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, >- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, >- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR >- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY >- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT >- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE >- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. >- */ >-"use strict"; >- >-class InstantiateImmediates extends Rewriter { >- visitTypeRef(node) >- { >- node = super.visitTypeRef(node); >- if (!node.type.instantiate) { >- 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()); >- } >- >- visitReferenceType(node) >- { >- return node; >- } >-} >- >diff --git a/Tools/WebGPUShadingLanguageRI/Intrinsics.js b/Tools/WebGPUShadingLanguageRI/Intrinsics.js >index 933dfe011302b0fbc8344994a1a5c1f77c052a6f..50d40c0c0e47e112bc74ccfccb7049427116b0fb 100644 >--- a/Tools/WebGPUShadingLanguageRI/Intrinsics.js >+++ b/Tools/WebGPUShadingLanguageRI/Intrinsics.js >@@ -1,5 +1,5 @@ > /* >- * Copyright (C) 2017 Apple Inc. All rights reserved. >+ * Copyright (C) 2018 Apple Inc. All rights reserved. > * > * Redistribution and use in source and binary forms, with or without > * modification, are permitted provided that the following conditions >@@ -31,11 +31,11 @@ class Intrinsics { > > // NOTE: Intrinsic resolution happens before type name resolution, so the strings we use here > // to catch the intrinsics must be based on the type names that StandardLibrary.js uses. >- // For example, if a native function is declared using "int" rather than "int32", then we must >+ // For example, if a native function is declared using "int" rather than "int", then we must > // 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,9 +57,9 @@ class Intrinsics { > } > > this._map.set( >- "native typedef int32<>", >+ "native typedef int", > type => { >- this.int32 = type; >+ this.int = type; > type.isPrimitive = true; > type.isInt = true; > type.isNumber = true; >@@ -82,9 +82,9 @@ class Intrinsics { > }); > > this._map.set( >- "native typedef uint32<>", >+ "native typedef uint", > type => { >- this.uint32 = type; >+ this.uint = type; > type.isPrimitive = true; > type.isInt = true; > type.isNumber = true; >@@ -105,9 +105,9 @@ class Intrinsics { > }); > > this._map.set( >- "native typedef uint8<>", >+ "native typedef uchar", > type => { >- this.uint8 = type; >+ this.uchar = type; > type.isInt = true; > type.isNumber = true; > type.isSigned = false; >@@ -127,7 +127,7 @@ class Intrinsics { > }); > > this._map.set( >- "native typedef float32<>", >+ "native typedef float", > 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); > }); >+ >+ for (let vectorType of VectorElementTypes) { >+ for (let vectorSize of VectorElementSizes) >+ this._map.set(`native typedef vector<${vectorType}, ${vectorSize}>`, type => {}); >+ } > > this._map.set( >- "native operator<> int32(uint32)", >+ "native operator int(uint)", > func => { > func.implementation = ([value]) => EPtr.box(value.loadValue() | 0); > }); > > this._map.set( >- "native operator<> int32(uint8)", >+ "native operator int(uchar)", > func => { > func.implementation = ([value]) => EPtr.box(value.loadValue() | 0); > }); > > this._map.set( >- "native operator<> int32(float)", >+ "native operator int(float)", > func => { > func.implementation = ([value]) => EPtr.box(value.loadValue() | 0); > }); > > this._map.set( >- "native operator<> uint32(int32)", >+ "native operator uint(int)", > func => { > func.implementation = ([value]) => EPtr.box(value.loadValue() >>> 0); > }); > > this._map.set( >- "native operator<> uint32(uint8)", >+ "native operator uint(uchar)", > func => { > func.implementation = ([value]) => EPtr.box(value.loadValue() >>> 0); > }); > > this._map.set( >- "native operator<> uint32(float)", >+ "native operator uint(float)", > func => { > func.implementation = ([value]) => EPtr.box(value.loadValue() >>> 0); > }); > > this._map.set( >- "native operator<> uint8(int32)", >+ "native operator uchar(int)", > func => { > func.implementation = ([value]) => EPtr.box(value.loadValue() & 0xff); > }); > > this._map.set( >- "native operator<> uint8(uint32)", >+ "native operator uchar(uint)", > func => { > func.implementation = ([value]) => EPtr.box(value.loadValue() & 0xff); > }); > > this._map.set( >- "native operator<> uint8(float)", >+ "native operator uchar(float)", > func => { > func.implementation = ([value]) => EPtr.box(value.loadValue() & 0xff); > }); > > this._map.set( >- "native operator<> float(int32)", >+ "native operator float(int)", > func => { > func.implementation = ([value]) => EPtr.box(Math.fround(value.loadValue())); > }); > > this._map.set( >- "native operator<> float(uint32)", >+ "native operator float(uint)", > func => { > func.implementation = ([value]) => EPtr.box(Math.fround(value.loadValue())); > }); > > this._map.set( >- "native operator<> float(uint8)", >+ "native operator float(uchar)", > 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 nativeVectorTypeName of allVectorTypeNames()) >+ this._map.set(`native typedef ${nativeVectorTypeName}`, type => { >+ type.isPrimitive = true; >+ }); > >- 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 swizzle of SwizzleOp.functions()) >+ this._map.set(swizzle.toString(), func => swizzle.instantiateImplementation(func)); >+ >+ 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 BuiltinVectorConstructors.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/Lexer.js b/Tools/WebGPUShadingLanguageRI/Lexer.js >index be2165db79e83ecc28f5d346b5c5d21e3244bd0c..956dca336a2a9a3121a277285ae3db76dde72370 100644 >--- a/Tools/WebGPUShadingLanguageRI/Lexer.js >+++ b/Tools/WebGPUShadingLanguageRI/Lexer.js >@@ -1,5 +1,5 @@ > /* >- * Copyright (C) 2017 Apple Inc. All rights reserved. >+ * Copyright (C) 2018 Apple Inc. All rights reserved. > * > * Redistribution and use in source and binary forms, with or without > * modification, are permitted provided that the following conditions >@@ -122,7 +122,7 @@ class Lexer { > > // FIXME: Make this do Unicode. > if (Lexer._textIsIdentifierImpl(relevantText)) { >- if (/^(struct|protocol|typedef|if|else|enum|continue|break|switch|case|default|for|while|do|return|constant|device|threadgroup|thread|operator|null|true|false)$/.test(RegExp.lastMatch)) >+ if (/^(struct|typedef|if|else|enum|continue|break|switch|case|default|for|while|do|return|constant|device|threadgroup|thread|operator|null|true|false)$/.test(RegExp.lastMatch)) > return result("keyword"); > > if (this._originKind == "native" && /^(native|restricted)$/.test(RegExp.lastMatch)) >diff --git a/Tools/WebGPUShadingLanguageRI/LiteralTypeChecker.js b/Tools/WebGPUShadingLanguageRI/LiteralTypeChecker.js >index 849d034d53573da3bf938f905cd60b7637dcaa53..90e3417d25385f4c8ad4601ae316e4542510d799 100644 >--- a/Tools/WebGPUShadingLanguageRI/LiteralTypeChecker.js >+++ b/Tools/WebGPUShadingLanguageRI/LiteralTypeChecker.js >@@ -1,5 +1,5 @@ > /* >- * Copyright (C) 2017 Apple Inc. All rights reserved. >+ * Copyright (C) 2018 Apple Inc. All rights reserved. > * > * Redistribution and use in source and binary forms, with or without > * modification, are permitted provided that the following conditions >@@ -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..1bab3fc5602601077b3fa885a6054ab860b0a193 100644 >--- a/Tools/WebGPUShadingLanguageRI/NameContext.js >+++ b/Tools/WebGPUShadingLanguageRI/NameContext.js >@@ -1,5 +1,5 @@ > /* >- * Copyright (C) 2017 Apple Inc. All rights reserved. >+ * Copyright (C) 2018 Apple Inc. All rights reserved. > * > * Redistribution and use in source and binary forms, with or without > * modification, are permitted provided that the following conditions >@@ -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"); >@@ -68,8 +68,10 @@ class NameContext { > 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); > } >@@ -104,13 +106,13 @@ class NameContext { > yield thing; > } > >- resolveFuncOverload(name, typeArguments, argumentTypes, returnType, allowEntryPoint = false) >+ resolveFuncOverload(name, argumentTypes, returnType, allowEntryPoint = false) > { > let functions = this.get(Func, name); > if (!functions) > return {failures: []}; > >- return resolveOverloadImpl(functions, typeArguments, argumentTypes, returnType, allowEntryPoint); >+ return resolveOverloadImpl(functions, argumentTypes, returnType, allowEntryPoint); > } > > get currentStatement() >diff --git a/Tools/WebGPUShadingLanguageRI/NameFinder.js b/Tools/WebGPUShadingLanguageRI/NameFinder.js >index fc2fdbd032527ccc54cad71ba576b99221ee9c7d..50603d7a9c566d9d24b53e79365f48f91703838e 100644 >--- a/Tools/WebGPUShadingLanguageRI/NameFinder.js >+++ b/Tools/WebGPUShadingLanguageRI/NameFinder.js >@@ -1,5 +1,5 @@ > /* >- * Copyright (C) 2017 Apple Inc. All rights reserved. >+ * Copyright (C) 2018 Apple Inc. All rights reserved. > * > * Redistribution and use in source and binary forms, with or without > * modification, are permitted provided that the following conditions >@@ -43,12 +43,6 @@ class NameFinder extends Visitor { > this._worklist.push(name); > } > >- visitProtocolRef(node) >- { >- this.add(node.name); >- super.visitProtocolRef(node); >- } >- > visitTypeRef(node) > { > this.add(node.name); >@@ -60,11 +54,6 @@ class NameFinder extends Visitor { > this.add(node.name); > super.visitVariableRef(node); > } >- >- visitTypeOrVariableRef(node) >- { >- this.add(node.name); >- } > > _handlePropertyAccess(node) > { >diff --git a/Tools/WebGPUShadingLanguageRI/NameResolver.js b/Tools/WebGPUShadingLanguageRI/NameResolver.js >index 731964fc78221ae73118981252232503bcfabc30..a2af1d933467251726c427fa064b6d74c9235575 100644 >--- a/Tools/WebGPUShadingLanguageRI/NameResolver.js >+++ b/Tools/WebGPUShadingLanguageRI/NameResolver.js >@@ -1,5 +1,5 @@ > /* >- * Copyright (C) 2017 Apple Inc. All rights reserved. >+ * Copyright (C) 2018 Apple Inc. All rights reserved. > * > * Redistribution and use in source and binary forms, with or without > * modification, are permitted provided that the following conditions >@@ -41,19 +41,9 @@ class NameResolver extends Visitor { > this._nameContext.doStatement(statement, () => statement.visit(this)); > } > >- _visitTypeParametersAndBuildNameContext(node) >- { >- let nameContext = new NameContext(this._nameContext); >- for (let typeParameter of node.typeParameters) { >- nameContext.add(typeParameter); >- typeParameter.visit(this); >- } >- return nameContext; >- } >- > visitFunc(node) > { >- let checker = new NameResolver(this._visitTypeParametersAndBuildNameContext(node)); >+ let checker = new NameResolver(new NameContext(this._nameContext)); > node.returnType.visit(checker); > for (let parameter of node.parameters) > parameter.visit(checker); >@@ -61,16 +51,14 @@ class NameResolver extends Visitor { > > visitFuncDef(node) > { >- let contextWithTypeParameters = this._visitTypeParametersAndBuildNameContext(node); >- let checkerWithTypeParameters = new NameResolver(contextWithTypeParameters); >- node.returnType.visit(checkerWithTypeParameters); >- let contextWithParameters = new NameContext(contextWithTypeParameters); >+ let funcDefNameContext = new NameContext(this._nameContext); >+ let funcDefNameResolver = new NameResolver(funcDefNameContext); >+ node.returnType.visit(funcDefNameResolver); > for (let parameter of node.parameters) { >- parameter.visit(checkerWithTypeParameters); >- contextWithParameters.add(parameter); >+ parameter.visit(funcDefNameResolver); >+ funcDefNameContext.add(parameter); > } >- let checkerWithParameters = new NameResolver(contextWithParameters); >- node.body.visit(checkerWithParameters); >+ node.body.visit(funcDefNameResolver); > } > > visitBlock(node) >@@ -115,41 +103,9 @@ class NameResolver extends Visitor { > node.body.visit(newResolver); > } > >- visitProtocolDecl(node) >- { >- for (let parent of node.extends) >- parent.visit(this); >- let nameContext = new NameContext(this._nameContext); >- nameContext.add(node.typeVariable); >- let checker = new NameResolver(nameContext); >- for (let signature of node.signatures) >- signature.visit(checker); >- } >- >- visitProtocolRef(node) >- { >- let result = this._nameContext.get(Protocol, node.name); >- if (!result) >- throw new WTypeError(node.origin.originString, "Could not find protocol named " + node.name); >- node.protocolDecl = result; >- } >- >- visitProtocolFuncDecl(node) >- { >- this.visitFunc(node); >- let funcs = this._nameContext.get(Func, node.name); >- if (!funcs) >- throw new WTypeError(node.origin.originString, "Cannot find any functions named " + node.name); >- node.possibleOverloads = funcs; >- } >- > visitTypeDef(node) > { > let nameContext = new NameContext(this._nameContext); >- for (let typeParameter of node.typeParameters) { >- typeParameter.visit(this); >- nameContext.add(typeParameter); >- } > let checker = new NameResolver(nameContext); > node.type.visit(checker); > } >@@ -157,41 +113,13 @@ class NameResolver extends Visitor { > visitStructType(node) > { > let nameContext = new NameContext(this._nameContext); >- for (let typeParameter of node.typeParameters) { >- typeParameter.visit(this); >- nameContext.add(typeParameter); >- } > let checker = new NameResolver(nameContext); > for (let field of node.fields) > field.visit(checker); > } > >- _resolveTypeArguments(typeArguments) >- { >- for (let i = 0; i < typeArguments.length; ++i) { >- let typeArgument = typeArguments[i]; >- 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); >- if (thing instanceof Value) >- typeArguments[i] = new VariableRef(typeArgument.origin, typeArgument.name); >- else if (thing instanceof Type) >- typeArguments[i] = new TypeRef(typeArgument.origin, typeArgument.name, []); >- else >- throw new WTypeError(typeArgument.origin.originString, "Type argument resolved to wrong kind of thing: " + thing.kind); >- } >- >- if (typeArgument[i] instanceof Value >- && !typeArgument[i].isConstexpr) >- throw new WTypeError(typeArgument[i].origin.originString, "Expected constexpr"); >- } >- } >- > visitTypeRef(node) > { >- this._resolveTypeArguments(node.typeArguments); >- > let type = node.type; > if (!type) { > type = this._nameContext.get(Type, node.name); >@@ -199,18 +127,6 @@ class NameResolver extends Visitor { > 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) >@@ -279,8 +195,6 @@ class NameResolver extends Visitor { > > visitCallExpression(node) > { >- this._resolveTypeArguments(node.typeArguments); >- > let funcs = this._nameContext.get(Func, node.name); > if (funcs) > node.possibleOverloads = funcs; >@@ -296,5 +210,9 @@ class NameResolver extends Visitor { > > super.visitCallExpression(node); > } >-} > >+ visitVectorType(node) >+ { >+ node.elementType.visit(this); >+ } >+} >diff --git a/Tools/WebGPUShadingLanguageRI/NativeFunc.js b/Tools/WebGPUShadingLanguageRI/NativeFunc.js >index a553352d9aee60bca62ad6e123288b8905182487..997bd48974c9fe2c64026134163a302314b1a19a 100644 >--- a/Tools/WebGPUShadingLanguageRI/NativeFunc.js >+++ b/Tools/WebGPUShadingLanguageRI/NativeFunc.js >@@ -1,5 +1,5 @@ > /* >- * Copyright (C) 2017 Apple Inc. All rights reserved. >+ * Copyright (C) 2018 Apple Inc. All rights reserved. > * > * Redistribution and use in source and binary forms, with or without > * modification, are permitted provided that the following conditions >@@ -25,15 +25,14 @@ > "use strict"; > > class NativeFunc extends Func { >- constructor(origin, name, returnType, typeParameters, parameters, isCast, shaderType) >+ constructor(origin, name, returnType, parameters, isCast, shaderType) > { >- super(origin, name, returnType, typeParameters, parameters, isCast, shaderType); >+ super(origin, name, returnType, parameters, isCast, shaderType); > this.isRestricted = false; > this.implementation = null; > this._implementationData = null; > this.instantiateImplementation = (substitution) => {}; > this.visitImplementationData = (implementationData, visitor) => null; >- this.didLayoutStructsInImplementationData = implementationData => null; > } > > get isNative() { return true; } >diff --git a/Tools/WebGPUShadingLanguageRI/NativeFuncInstance.js b/Tools/WebGPUShadingLanguageRI/NativeFuncInstance.js >deleted file mode 100644 >index c99b78263535a70d9309626d585035900105d411..0000000000000000000000000000000000000000 >--- a/Tools/WebGPUShadingLanguageRI/NativeFuncInstance.js >+++ /dev/null >@@ -1,44 +0,0 @@ >-/* >- * Copyright (C) 2017 Apple Inc. All rights reserved. >- * >- * Redistribution and use in source and binary forms, with or without >- * modification, are permitted provided that the following conditions >- * are met: >- * 1. Redistributions of source code must retain the above copyright >- * notice, this list of conditions and the following disclaimer. >- * 2. Redistributions in binary form must reproduce the above copyright >- * notice, this list of conditions and the following disclaimer in the >- * documentation and/or other materials provided with the distribution. >- * >- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY >- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE >- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR >- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR >- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, >- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, >- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR >- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY >- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT >- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE >- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. >- */ >-"use strict"; >- >-class NativeFuncInstance extends Func { >- constructor(func, returnType, parameters, isCast, shaderType, implementationData) >- { >- super(func.origin, func.name, returnType, [], parameters, isCast, shaderType); >- this._func = func; >- this._implementationData = implementationData; >- } >- >- get func() { return this._func; } >- get isNative() { return true; } >- get implementationData() { return this._implementationData; } >- >- toDeclString() >- { >- return "native " + super.toDeclString(); >- } >-} >- >diff --git a/Tools/WebGPUShadingLanguageRI/NativeType.js b/Tools/WebGPUShadingLanguageRI/NativeType.js >index b8b1a47330b5fd51ff021af06586844c2acba8ea..e2d851cbccba3a97234c7bd392907829ca9e05f2 100644 >--- a/Tools/WebGPUShadingLanguageRI/NativeType.js >+++ b/Tools/WebGPUShadingLanguageRI/NativeType.js >@@ -1,5 +1,5 @@ > /* >- * Copyright (C) 2017 Apple Inc. All rights reserved. >+ * Copyright (C) 2018 Apple Inc. All rights reserved. > * > * Redistribution and use in source and binary forms, with or without > * modification, are permitted provided that the following conditions >@@ -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,21 @@ class NativeType extends Type { > get isPrimitive() { return this._isPrimitive; } > set isPrimitive(value) { this._isPrimitive = value; } > >- instantiate(typeArguments) >+ toString() > { >- 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); >+ return `native typedef ${this.name}`; > } > >- toString() >+ static create(origin, name, typeArguments) > { >- return "native typedef " + this.name + "<" + this.typeParameters + ">"; >+ // FIXME: For native types like Texture1D this should resolve the type to something concrete by changing the type name. >+ if (typeArguments.length) >+ throw new WTypeError(origin.originString, `${name}<${typeArguments.join(",")}>: Support for native types with type arguments is currently unimplemented.`); >+ >+ if (allVectorTypeNames().indexOf(name) > -1) >+ return new VectorType(origin, name); >+ >+ return new NativeType(origin, name); > } > } > >diff --git a/Tools/WebGPUShadingLanguageRI/NativeTypeInstance.js b/Tools/WebGPUShadingLanguageRI/NativeTypeInstance.js >deleted file mode 100644 >index ca39e777870049ed22d7041a52014cc8e69cbc4f..0000000000000000000000000000000000000000 >--- a/Tools/WebGPUShadingLanguageRI/NativeTypeInstance.js >+++ /dev/null >@@ -1,58 +0,0 @@ >-/* >- * Copyright (C) 2017 Apple Inc. All rights reserved. >- * >- * Redistribution and use in source and binary forms, with or without >- * modification, are permitted provided that the following conditions >- * are met: >- * 1. Redistributions of source code must retain the above copyright >- * notice, this list of conditions and the following disclaimer. >- * 2. Redistributions in binary form must reproduce the above copyright >- * notice, this list of conditions and the following disclaimer in the >- * documentation and/or other materials provided with the distribution. >- * >- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY >- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE >- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR >- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR >- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, >- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, >- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR >- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY >- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT >- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE >- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. >- */ >-"use strict"; >- >-class NativeTypeInstance extends Type { >- constructor(type, typeArguments) >- { >- super(); >- this._type = type; >- this._typeArguments = typeArguments; >- } >- >- get type() { return this._type; } >- get typeArguments() { return this._typeArguments; } >- get isPrimitive() { return this._type.isPrimitive; } >- get isNative() { return true; } >- >- unifyImpl(unificationContext, other) >- { >- if (this.type != other.type) >- return false; >- if (this.typeArguments.length != other.typeArguments.length) >- return false; >- for (let i = 0; i < this.typeArguments.length; ++i) { >- if (!this.typeArguments[i].unify(unificationContext, other.typeArguments[i])) >- return false; >- } >- return true; >- } >- >- toString() >- { >- return this.type + "<" + this.typeArguments + ">"; >- } >-} >- >diff --git a/Tools/WebGPUShadingLanguageRI/Node.js b/Tools/WebGPUShadingLanguageRI/Node.js >index 881030130773e70ea88e0ab597974cf561f9d5e4..c4ba48cb14b66cf8ffadc252988be8e1e443a149 100644 >--- a/Tools/WebGPUShadingLanguageRI/Node.js >+++ b/Tools/WebGPUShadingLanguageRI/Node.js >@@ -1,5 +1,5 @@ > /* >- * Copyright (C) 2017 Apple Inc. All rights reserved. >+ * Copyright (C) 2018 Apple Inc. All rights reserved. > * > * Redistribution and use in source and binary forms, with or without > * modification, are permitted provided that the following conditions >@@ -118,16 +118,4 @@ class Node { > unificationContext.commit(); > return unificationContext.find(this); > } >- >- substitute(parameters, argumentList) >- { >- return this.visit(new Substitution(parameters, argumentList)); >- } >- >- substituteToUnification(parameters, unificationContext) >- { >- return this.substitute( >- parameters, >- parameters.map(type => unificationContext.find(type))); >- } > } >diff --git a/Tools/WebGPUShadingLanguageRI/OperatorAnderIndex.js b/Tools/WebGPUShadingLanguageRI/OperatorAnderIndex.js >new file mode 100644 >index 0000000000000000000000000000000000000000..670371fb90f2a1fd15c2ddf6c4a396c0f239cebf >--- /dev/null >+++ b/Tools/WebGPUShadingLanguageRI/OperatorAnderIndex.js >@@ -0,0 +1,71 @@ >+/* >+ * Copyright (C) 2018 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; >+ } >+ >+ 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..63edd79d6de21a02a6ffa6f4130de9cc354c1a7f >--- /dev/null >+++ b/Tools/WebGPUShadingLanguageRI/OperatorArrayRefLength.js >@@ -0,0 +1,52 @@ >+/* >+ * Copyright (C) 2018 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 uint ${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..58bb0e09b80bee107089b1c9d200cbc68a5cb9d3 >--- /dev/null >+++ b/Tools/WebGPUShadingLanguageRI/OperatorBool.js >@@ -0,0 +1,68 @@ >+/* >+ * Copyright (C) 2018 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 OperatorBool { >+ constructor(baseTypeName) >+ { >+ this._baseTypeName = baseTypeName; >+ } >+ >+ get baseTypeName() { return this._baseTypeName; } >+ >+ toString() >+ { >+ return `native operator bool(${this.baseTypeName})`; >+ } >+ >+ static functions() >+ { >+ // FIXME: These operators should be in the standard library where possible. >+ if (!OperatorBool._functions) { >+ OperatorBool._functions = []; >+ >+ // bool is not included because this is generated by the copy constructor. >+ // FIXME: Include all native types. >+ const typeNames = [ "uchar", "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) => { >+ const size = node.argumentTypes[0].size; >+ for (let i = 0; i < size; ++i) { >+ if (!!ref.get(i)) >+ return EPtr.box(true); >+ } >+ return EPtr.box(false); >+ } >+ func.implementationData = this; >+ } >+} >\ No newline at end of file >diff --git a/Tools/WebGPUShadingLanguageRI/Parse.js b/Tools/WebGPUShadingLanguageRI/Parse.js >index 6d2b431615601ab9dd3d0938fbfb385ee2a4daf1..c4ae9de7fde8562969260c1469c22b586de76df9 100644 >--- a/Tools/WebGPUShadingLanguageRI/Parse.js >+++ b/Tools/WebGPUShadingLanguageRI/Parse.js >@@ -1,5 +1,5 @@ > /* >- * Copyright (C) 2017 Apple Inc. All rights reserved. >+ * Copyright (C) 2018 Apple Inc. All rights reserved. > * > * Redistribution and use in source and binary forms, with or without > * modification, are permitted provided that the following conditions >@@ -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(">")) { >@@ -248,13 +214,13 @@ function parse(program, origin, originKind, lineNumberOffset, text) > // In the future we'll allow constexprs to do more things, and then we'll still have > // the problem that something of the form T[1][2][3]... can either be a type or a > // constexpr, and we can figure out in the checker which it is. >- let typeOrVariableRef = lexer.backtrackingScope(() => { >+ let typeRef = lexer.backtrackingScope(() => { > let result = consumeKind("identifier"); > assertNext(",", ">", ">>"); >- return new TypeOrVariableRef(result, result.text); >+ return new TypeRef(result, result.text); > }); >- if (typeOrVariableRef) >- result.push(typeOrVariableRef); >+ if (typeRef) >+ result.push(typeRef); > else { > let constexpr = lexer.backtrackingScope(() => { > let result = parseConstexpr(); >@@ -318,11 +284,10 @@ function parse(program, origin, originKind, lineNumberOffset, text) > { > let origin = consume("typedef"); > let name = consumeKind("identifier").text; >- let typeParameters = parseTypeParameters(); > consume("="); >- let type = parseType(); >+ let type = parseType(true); > consume(";"); >- return new TypeDef(origin, name, typeParameters, type); >+ return new TypeDef(origin, name, type); > } > > function genericParseLeft(texts, nextParser, constructor) >@@ -547,7 +512,7 @@ function parse(program, origin, originKind, lineNumberOffset, text) > let operator = tryConsume("=", "+=", "-=", "*=", "/=", "%=", "^=", "|=", "&="); > if (!operator) { > if (mode == "required") >- lexer.fail("Expected assignment"); >+ lexer.fail("Expected assignment: " + lexer._text.substring(lexer._index)); > return lhs; > } > if (operator.text == "=") >@@ -858,13 +823,11 @@ function parse(program, origin, originKind, lineNumberOffset, text) > let origin; > let returnType; > let name; >- let typeParameters; > let isCast; > let shaderType; > let operatorToken = tryConsume("operator"); > if (operatorToken) { > origin = operatorToken; >- typeParameters = parseTypeParameters(); > returnType = parseType(); > name = "operator cast"; > isCast = true; >@@ -877,44 +840,17 @@ 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); >+ return new Func(origin, name, returnType, parameters, isCast, shaderType); > } > > function parseFuncDef() > { > let func = parseFuncDecl(); > let body = parseBlock(); >- 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; >+ return new FuncDef(func.origin, func.name, func.returnType, func.parameters, body, func.isCast, func.shaderType); > } > > function parseField() >@@ -929,8 +865,7 @@ function parse(program, origin, originKind, lineNumberOffset, text) > { > let origin = consume("struct"); > let name = consumeKind("identifier").text; >- let typeParameters = parseTypeParameters(); >- let result = new StructType(origin, name, typeParameters); >+ let result = new StructType(origin, name); > consume("{"); > while (!tryConsume("}")) > result.add(parseField()); >@@ -941,7 +876,7 @@ function parse(program, origin, originKind, lineNumberOffset, text) > { > let func = parseFuncDecl(); > consume(";"); >- return new NativeFunc(func.origin, func.name, func.returnType, func.typeParameters, func.parameters, func.isCast, func.shaderType); >+ return new NativeFunc(func.origin, func.name, func.returnType, func.parameters, func.isCast, func.shaderType); > } > > function parseNative() >@@ -949,9 +884,9 @@ 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); >+ return NativeType.create(origin, name.text, args); > } > return parseNativeFunc(); > } >@@ -985,7 +920,7 @@ function parse(program, origin, originKind, lineNumberOffset, text) > if (tryConsume(":")) > baseType = parseType(); > else >- baseType = new TypeRef(name, "int", []); >+ baseType = new TypeRef(name, "int"); > consume("{"); > let result = new EnumType(name, name.text, baseType); > while (!test("}")) { >@@ -1013,8 +948,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..7b16139e95b81e2e8da8354bd8c179b190baefa0 100644 >--- a/Tools/WebGPUShadingLanguageRI/Prepare.js >+++ b/Tools/WebGPUShadingLanguageRI/Prepare.js >@@ -1,5 +1,5 @@ > /* >- * Copyright (C) 2017 Apple Inc. All rights reserved. >+ * Copyright (C) 2018 Apple Inc. All rights reserved. > * > * Redistribution and use in source and binary forms, with or without > * modification, are permitted provided that the following conditions >@@ -40,18 +40,21 @@ let prepare = (() => { > } > > foldConstexprs(program); >+ removeTypeArguments(program); >+ > let nameResolver = createNameResolver(program); > resolveNamesInTypes(program, nameResolver); >- resolveNamesInProtocols(program, nameResolver); > resolveTypeDefsInTypes(program); >- resolveTypeDefsInProtocols(program); > checkRecursiveTypes(program); > synthesizeStructAccessors(program); >+ synthesizeOperatorBool(program); > synthesizeEnumFunctions(program); >+ synthesizeArrayOperatorLength(program); >+ synthesizeCopyConstructorOperator(program); >+ synthesizeDefaultConstructorOperator(program); > resolveNamesInFunctions(program, nameResolver); > resolveTypeDefsInFunctions(program); > >- flattenProtocolExtends(program); > check(program); > checkLiteralTypes(program); > resolveProperties(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/Program.js b/Tools/WebGPUShadingLanguageRI/Program.js >index bbc4b24a6227b1ce5b06d733ac20d92b596a4c73..06625d98fc41e74c93dece80b70ce55c7af74dd5 100644 >--- a/Tools/WebGPUShadingLanguageRI/Program.js >+++ b/Tools/WebGPUShadingLanguageRI/Program.js >@@ -1,5 +1,5 @@ > /* >- * Copyright (C) 2017 Apple Inc. All rights reserved. >+ * Copyright (C) 2018 Apple Inc. All rights reserved. > * > * Redistribution and use in source and binary forms, with or without > * modification, are permitted provided that the following conditions >@@ -31,8 +31,6 @@ class Program extends Node { > this._topLevelStatements = []; > this._functions = new Map(); > this._types = new Map(); >- this._protocols = new Map(); >- this._funcInstantiator = new FuncInstantiator(this); > this._globalNameContext = new NameContext(); > this._globalNameContext.program = this; > this._globalNameContext.recognizeIntrinsics(); >@@ -42,8 +40,6 @@ class Program extends Node { > get topLevelStatements() { return this._topLevelStatements; } > get functions() { return this._functions; } > get types() { return this._types; } >- get protocols() { return this._protocols; } >- get funcInstantiator() { return this._funcInstantiator; } > get globalNameContext() { return this._globalNameContext; } > > add(statement) >@@ -56,8 +52,6 @@ class Program extends Node { > array.push(statement); > } else if (statement instanceof Type) > this._types.set(statement.name, statement); >- else if (statement instanceof Protocol) >- this._protocols.set(statement.name, statement); > else > throw new Error("Statement is not a function or type: " + statement); > this._topLevelStatements.push(statement); >diff --git a/Tools/WebGPUShadingLanguageRI/Protocol.js b/Tools/WebGPUShadingLanguageRI/Protocol.js >deleted file mode 100644 >index 33f8456477eca2e8dcf66cf45c2d473ca0857d88..0000000000000000000000000000000000000000 >--- a/Tools/WebGPUShadingLanguageRI/Protocol.js >+++ /dev/null >@@ -1,43 +0,0 @@ >-/* >- * Copyright (C) 2017 Apple Inc. All rights reserved. >- * >- * Redistribution and use in source and binary forms, with or without >- * modification, are permitted provided that the following conditions >- * are met: >- * 1. Redistributions of source code must retain the above copyright >- * notice, this list of conditions and the following disclaimer. >- * 2. Redistributions in binary form must reproduce the above copyright >- * notice, this list of conditions and the following disclaimer in the >- * documentation and/or other materials provided with the distribution. >- * >- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY >- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE >- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR >- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR >- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, >- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, >- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR >- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY >- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT >- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE >- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. >- */ >-"use strict"; >- >-class Protocol extends Node { >- constructor(origin, name) >- { >- super(); >- this._origin = origin; >- this._name = name; >- } >- >- get origin() { return this._origin; } >- get name() { return this._name; } >- get kind() { return Protocol; } >- >- toString() >- { >- return this.name; >- } >-} >diff --git a/Tools/WebGPUShadingLanguageRI/ProtocolDecl.js b/Tools/WebGPUShadingLanguageRI/ProtocolDecl.js >deleted file mode 100644 >index b50bcfcf33ba7395c56d952a579d09927b0be767..0000000000000000000000000000000000000000 >--- a/Tools/WebGPUShadingLanguageRI/ProtocolDecl.js >+++ /dev/null >@@ -1,119 +0,0 @@ >-/* >- * Copyright (C) 2017 Apple Inc. All rights reserved. >- * >- * Redistribution and use in source and binary forms, with or without >- * modification, are permitted provided that the following conditions >- * are met: >- * 1. Redistributions of source code must retain the above copyright >- * notice, this list of conditions and the following disclaimer. >- * 2. Redistributions in binary form must reproduce the above copyright >- * notice, this list of conditions and the following disclaimer in the >- * documentation and/or other materials provided with the distribution. >- * >- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY >- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE >- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR >- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR >- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, >- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, >- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR >- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY >- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT >- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE >- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. >- */ >-"use strict"; >- >-class ProtocolDecl extends Protocol { >- constructor(origin, name) >- { >- super(origin, name); >- this.extends = []; >- this._signatures = []; >- this._signatureMap = new Map(); >- this._typeVariable = new TypeVariable(origin, name, null); >- } >- >- addExtends(protocol) >- { >- this.extends.push(protocol); >- } >- >- add(signature) >- { >- if (!(signature instanceof ProtocolFuncDecl)) >- throw new Error("Signature isn't a ProtocolFuncDecl but a " + signature.constructor.name); >- >- signature.protocolDecl = this; >- this._signatures.push(signature); >- let overloads = this._signatureMap.get(signature.name); >- if (!overloads) >- this._signatureMap.set(signature.name, overloads = []); >- overloads.push(signature); >- } >- >- get signatures() { return this._signatures; } >- signaturesByName(name) { return this._signatureMap.get(name); } >- get typeVariable() { return this._typeVariable; } >- >- signaturesByNameWithTypeVariable(name, typeVariable) >- { >- let substitution = new Substitution([this.typeVariable], [typeVariable]); >- let result = this.signaturesByName(name); >- if (!result) >- return null; >- return result.map(signature => signature.visit(substitution)); >- } >- >- inherits(otherProtocol) >- { >- if (!otherProtocol) >- return {result: true}; >- >- if (otherProtocol instanceof ProtocolRef) >- otherProtocol = otherProtocol.protocolDecl; >- >- for (let otherSignature of otherProtocol.signatures) { >- let signatures = this.signaturesByName(otherSignature.name); >- if (!signatures) >- return {result: false, reason: "Protocol " + this.name + " does not have a function named " + otherSignature.name + " (looking at signature " + otherSignature + ")"}; >- let overload = resolveOverloadImpl( >- signatures, [], >- otherSignature.parameterTypes, >- otherSignature.returnTypeForOverloadResolution); >- if (!overload.func) >- return {result: false, reason: "Did not find matching signature for " + otherSignature + " in " + this.name + (overload.failures.length ? " (tried: " + overload.failures.join("; ") + ")" : "")}; >- let substitutedReturnType = >- overload.func.returnType.substituteToUnification( >- overload.func.typeParameters, overload.unificationContext); >- if (!substitutedReturnType.equals(otherSignature.returnType)) >- return {result: false, reason: "Return type mismatch between " + otherSignature.returnType + " and " + substitutedReturnType}; >- } >- return {result: true}; >- } >- >- hasHeir(type) >- { >- let substitution = new Substitution([this._typeVariable], [type]); >- let signatures = this.signatures; >- for (let originalSignature of signatures) { >- let signature = originalSignature.visit(substitution); >- let overload = resolveOverloadImpl(signature.possibleOverloads, signature.typeParameters, signature.parameterTypes, signature.returnTypeForOverloadResolution); >- if (!overload.func) >- return {result: false, reason: "Did not find matching signature for " + originalSignature + " (at " + originalSignature.origin.originString + ") with type " + type + (overload.failures.length ? " (tried: " + overload.failures.join("; ") + ")" : "")}; >- >- let substitutedReturnType = overload.func.returnType.substituteToUnification( >- overload.func.typeParameters, overload.unificationContext); >- if (!substitutedReturnType.equals(signature.returnType)) >- return {result: false, reason: "At signature " + originalSignature + " (at " + originalSignature.origin.originString + "): return type mismatch between " + signature.returnType + " and " + substitutedReturnType + " in found function " + overload.func.toDeclString()}; >- } >- return {result: true}; >- } >- >- toString() >- { >- return "protocol " + this.name + " { " + this.signatures.join("; ") + "; }"; >- } >-} >- >- >diff --git a/Tools/WebGPUShadingLanguageRI/ProtocolFuncDecl.js b/Tools/WebGPUShadingLanguageRI/ProtocolFuncDecl.js >deleted file mode 100644 >index 89b5c9b8e7161868a1ce45d58866392c022244d3..0000000000000000000000000000000000000000 >--- a/Tools/WebGPUShadingLanguageRI/ProtocolFuncDecl.js >+++ /dev/null >@@ -1,33 +0,0 @@ >-/* >- * Copyright (C) 2017 Apple Inc. All rights reserved. >- * >- * Redistribution and use in source and binary forms, with or without >- * modification, are permitted provided that the following conditions >- * are met: >- * 1. Redistributions of source code must retain the above copyright >- * notice, this list of conditions and the following disclaimer. >- * 2. Redistributions in binary form must reproduce the above copyright >- * notice, this list of conditions and the following disclaimer in the >- * documentation and/or other materials provided with the distribution. >- * >- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY >- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE >- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR >- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR >- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, >- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, >- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR >- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY >- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT >- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE >- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. >- */ >-"use strict"; >- >-class ProtocolFuncDecl extends Func { >- get typeParametersForCallResolution() >- { >- return this.typeParameters.concat(this.protocolDecl.typeVariable); >- } >-} >- >diff --git a/Tools/WebGPUShadingLanguageRI/ProtocolRef.js b/Tools/WebGPUShadingLanguageRI/ProtocolRef.js >deleted file mode 100644 >index d3c0ea30d748d8b9e16107a9f808c23b32865e64..0000000000000000000000000000000000000000 >--- a/Tools/WebGPUShadingLanguageRI/ProtocolRef.js >+++ /dev/null >@@ -1,48 +0,0 @@ >-/* >- * Copyright (C) 2017 Apple Inc. All rights reserved. >- * >- * Redistribution and use in source and binary forms, with or without >- * modification, are permitted provided that the following conditions >- * are met: >- * 1. Redistributions of source code must retain the above copyright >- * notice, this list of conditions and the following disclaimer. >- * 2. Redistributions in binary form must reproduce the above copyright >- * notice, this list of conditions and the following disclaimer in the >- * documentation and/or other materials provided with the distribution. >- * >- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY >- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE >- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR >- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR >- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, >- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, >- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR >- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY >- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT >- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE >- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. >- */ >-"use strict"; >- >-class ProtocolRef extends Protocol { >- constructor(origin, name) >- { >- super(origin, name); >- this.protocolDecl = null; >- } >- >- inherits(other) >- { >- return this.protocolDecl.inherits(other); >- } >- >- hasHeir(type) >- { >- return this.protocolDecl.hasHeir(type); >- } >- >- get isPrimitive() >- { >- return this.protocolDecl.isPrimitive; >- } >-} >diff --git a/Tools/WebGPUShadingLanguageRI/RemoveTypeArguments.js b/Tools/WebGPUShadingLanguageRI/RemoveTypeArguments.js >new file mode 100644 >index 0000000000000000000000000000000000000000..7f9087032e850fe0df45fd7d7d8fbaf334fa00bc >--- /dev/null >+++ b/Tools/WebGPUShadingLanguageRI/RemoveTypeArguments.js >@@ -0,0 +1,73 @@ >+/* >+ * Copyright (C) 2018 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 removeTypeArguments(program) >+{ >+ class RemoveTypeArguments extends Visitor { >+ static resolveNameAndArguments(node) >+ { >+ if (!node.typeArguments) >+ return node.name; >+ >+ switch (node.name) { >+ case "vector": >+ if (node.typeArguments.length != 2) >+ throw new WSyntaxError(node.originString, `${node.name} should have 2 type arguments, got ${node.typeArguments.length}.`); >+ >+ const elementTypeName = node.typeArguments[0].name; >+ const lengthValue = node.typeArguments[1].value; >+ >+ if (VectorElementTypes.indexOf(elementTypeName) < 0) >+ throw new WSyntaxError(node.originString, `${elementTypeName} is not a valid vector element type.`); >+ if (VectorElementSizes.indexOf(lengthValue) < 0) >+ throw new WSyntaxError(node.originString, `${lengthValue} is not a valid size for vectors with element type ${elementTypeName}.`); >+ >+ return `${elementTypeName}${lengthValue}`; >+ // FIXME: Further cases for matrices, textures, etc. >+ default: >+ if (node.typeArguments.length) >+ throw new WSyntaxError(`${node.name}${arguments.join(", ")} is not a permitted generic type or function`); >+ return node.name; >+ } >+ } >+ >+ visitTypeRef(node) >+ { >+ node._name = RemoveTypeArguments.resolveNameAndArguments(node); >+ node._typeArguments = null; >+ } >+ >+ visitCallExpression(node) >+ { >+ node._name = RemoveTypeArguments.resolveNameAndArguments(node); >+ if (!node._name || !node._name.length) >+ throw new Error("lazy"); >+ node._typeArguments = null; >+ } >+ } >+ >+ program.visit(new RemoveTypeArguments()); >+} >\ No newline at end of file >diff --git a/Tools/WebGPUShadingLanguageRI/ResolveNames.js b/Tools/WebGPUShadingLanguageRI/ResolveNames.js >index 1922e8ec27fc39d95b4aa8bfa9a56c910f6e68b2..2e402c8d6c0a36098561e0275ee53e778fd384b8 100644 >--- a/Tools/WebGPUShadingLanguageRI/ResolveNames.js >+++ b/Tools/WebGPUShadingLanguageRI/ResolveNames.js >@@ -1,5 +1,5 @@ > /* >- * Copyright (C) 2017 Apple Inc. All rights reserved. >+ * Copyright (C) 2018 Apple Inc. All rights reserved. > * > * Redistribution and use in source and binary forms, with or without > * modification, are permitted provided that the following conditions >@@ -35,12 +35,6 @@ function resolveNamesInTypes(program, nameResolver) > nameResolver.doStatement(type); > } > >-function resolveNamesInProtocols(program, nameResolver) >-{ >- for (let protocol of program.protocols.values()) >- nameResolver.doStatement(protocol); >-} >- > function resolveNamesInFunctions(program, nameResolver) > { > for (let funcs of program.functions.values()) { >diff --git a/Tools/WebGPUShadingLanguageRI/ResolveOverloadImpl.js b/Tools/WebGPUShadingLanguageRI/ResolveOverloadImpl.js >index 7e22156de1ac5e2a6c724ad3469dc91e746f2566..d0f1e34d617ea27266467c161707154664a449ad 100644 >--- a/Tools/WebGPUShadingLanguageRI/ResolveOverloadImpl.js >+++ b/Tools/WebGPUShadingLanguageRI/ResolveOverloadImpl.js >@@ -1,5 +1,5 @@ > /* >- * Copyright (C) 2017 Apple Inc. All rights reserved. >+ * Copyright (C) 2018 Apple Inc. All rights reserved. > * > * Redistribution and use in source and binary forms, with or without > * modification, are permitted provided that the following conditions >@@ -24,7 +24,7 @@ > */ > "use strict"; > >-function resolveOverloadImpl(functions, typeArguments, argumentTypes, returnType, allowEntryPoint = false) >+function resolveOverloadImpl(functions, argumentTypes, returnType, allowEntryPoint = false) > { > if (!functions) > throw new Error("Null functions; that should have been caught by the caller."); >@@ -36,7 +36,7 @@ function resolveOverloadImpl(functions, typeArguments, argumentTypes, returnType > failures.push(new OverloadResolutionFailure(func, "Function is a " + func.shaderType + " shader, so it cannot be called from within an existing shader.")) > continue; > } >- let overload = inferTypesForCall(func, typeArguments, argumentTypes, returnType); >+ let overload = inferTypesForCall(func, argumentTypes, returnType); > if (overload.failure) > failures.push(overload.failure); > else >@@ -74,7 +74,6 @@ function resolveOverloadImpl(functions, typeArguments, argumentTypes, returnType > let parameterFunc = successes[j].func; > let overload = inferTypesForCall( > parameterFunc, >- typeArguments.length ? argumentFunc.typeParameters : [], > argumentFunc.parameterTypes, > argumentFunc.returnTypeForOverloadResolution); > if (!overload.func) { >diff --git a/Tools/WebGPUShadingLanguageRI/ResolveTypeDefs.js b/Tools/WebGPUShadingLanguageRI/ResolveTypeDefs.js >index 3bd2a4d65f564f708b0ef4759e43b2c88d48c234..9143f8e1e00a049814b90a345c5af451459d8574 100644 >--- a/Tools/WebGPUShadingLanguageRI/ResolveTypeDefs.js >+++ b/Tools/WebGPUShadingLanguageRI/ResolveTypeDefs.js >@@ -1,5 +1,5 @@ > /* >- * Copyright (C) 2017 Apple Inc. All rights reserved. >+ * Copyright (C) 2018 Apple Inc. All rights reserved. > * > * Redistribution and use in source and binary forms, with or without > * modification, are permitted provided that the following conditions >@@ -31,13 +31,6 @@ function resolveTypeDefsInTypes(program) > type.visit(resolver); > } > >-function resolveTypeDefsInProtocols(program) >-{ >- let resolver = new TypeDefResolver(); >- for (let protocol of program.protocols.values()) >- protocol.visit(resolver); >-} >- > function resolveTypeDefsInFunctions(program) > { > let resolver = new TypeDefResolver(); >diff --git a/Tools/WebGPUShadingLanguageRI/Rewriter.js b/Tools/WebGPUShadingLanguageRI/Rewriter.js >index f40d6b88b26eedcbf829f1babb10a2045b7a8e83..b56cd60bf6fc2636ddd4341252a46aa324fb496d 100644 >--- a/Tools/WebGPUShadingLanguageRI/Rewriter.js >+++ b/Tools/WebGPUShadingLanguageRI/Rewriter.js >@@ -1,5 +1,5 @@ > /* >- * Copyright (C) 2017 Apple Inc. All rights reserved. >+ * Copyright (C) 2018 Apple Inc. All rights reserved. > * > * Redistribution and use in source and binary forms, with or without > * modification, are permitted provided that the following conditions >@@ -53,40 +53,10 @@ class Rewriter { > // that. > visitFuncDef(node) { return node; } > visitNativeFunc(node) { return node; } >- visitNativeFuncInstance(node) { return node; } > visitNativeType(node) { return node; } > visitTypeDef(node) { return node; } > visitStructType(node) { return node; } >- visitConstexprTypeParameter(node) { return node; } >- visitProtocolDecl(node) { return node; } > visitEnumType(node) { return node; } >- >- // This is almost wrong. We instantiate Func in Substitution in ProtocolDecl. Then, we end up >- // not rewriting type variables. I think that just works because not rewriting them there is OK. >- // Everywhere else, it's mandatory that we don't rewrite these because we always assume that >- // type variables are outside the scope of rewriting. >- visitTypeVariable(node) { return node; } >- >- visitProtocolFuncDecl(node) >- { >- let result = new ProtocolFuncDecl( >- node.origin, node.name, >- node.returnType.visit(this), >- node.typeParameters.map(parameter => parameter.visit(this)), >- node.parameters.map(parameter => parameter.visit(this)), >- node.isCast, >- node.shaderType); >- result.protocolDecl = node.protocolDecl; >- result.possibleOverloads = node.possibleOverloads; >- return result; >- } >- >- visitNativeTypeInstance(node) >- { >- return new NativeTypeInstance( >- node.type.visit(this), >- node.typeArguments.map(argument => argument.visit(this))); >- } > > visitFuncParameter(node) > { >@@ -125,15 +95,11 @@ class Rewriter { > })); > } > >- visitProtocolRef(node) >- { >- return node; >- } >- > visitTypeRef(node) > { >- let result = new TypeRef(node.origin, node.name, node.typeArguments.map(typeArgument => typeArgument.visit(this))); >- result.type = Node.visit(node.type, this); >+ let result = new TypeRef(node.origin, node.name); >+ if (node.type) >+ result.type = Node.visit(node.type, this); > return result; > } > >@@ -317,19 +283,10 @@ class Rewriter { > > processDerivedCallData(node, result) > { >- let handleTypeArguments = actualTypeArguments => { >- if (actualTypeArguments) >- return actualTypeArguments.map(actualTypeArgument => actualTypeArgument.visit(this)); >- else >- return null; >- } >- result.actualTypeArguments = handleTypeArguments(node.actualTypeArguments); >- result.instantiatedActualTypeArguments = handleTypeArguments(node.instantiatedActualTypeArguments); > let argumentTypes = node.argumentTypes; > if (argumentTypes) > result.argumentTypes = argumentTypes.map(argumentType => argumentType.visit(this)); > result.func = node.func; >- result.nativeFuncInstance = node.nativeFuncInstance; > result.possibleOverloads = node.possibleOverloads; > if (node.isCast) > result.setCastData(node.returnType.visit(this)); >@@ -341,8 +298,7 @@ class Rewriter { > visitCallExpression(node) > { > let result = new CallExpression( >- node.origin, node.name, >- node.typeArguments.map(typeArgument => typeArgument.visit(this)), >+ node.origin, node.name, null, > node.argumentList.map(argument => Node.visit(argument, this))); > return this.processDerivedCallData(node, result); > } >@@ -412,7 +368,7 @@ class Rewriter { > > visitAnonymousVariable(node) > { >- let result = new AnonymousVariable(node.origin, node.type.visit(this)); >+ let result = new AnonymousVariable(node.origin, Node.visit(node.type, this)); > result._index = node._index; > this._mapNode(node, result); > result.ePtr = node.ePtr; >@@ -423,5 +379,12 @@ class Rewriter { > { > return new IdentityExpression(node.target.visit(this)); > } >+ >+ visitVectorType(node) >+ { >+ const vecType = new VectorType(node.origin, node.name); >+ vecType._elementType = node.elementType.visit(this); >+ return vecType; >+ } > } > >diff --git a/Tools/WebGPUShadingLanguageRI/SPIRV.html b/Tools/WebGPUShadingLanguageRI/SPIRV.html >index 93f6b9b932d272d77a3dc3167f525fa40a61ed23..c7b3940f2b11bd89614f14a9b52c47a56166ab14 100644 >--- a/Tools/WebGPUShadingLanguageRI/SPIRV.html >+++ b/Tools/WebGPUShadingLanguageRI/SPIRV.html >@@ -18,6 +18,7 @@ td { > <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> >@@ -28,6 +29,12 @@ td { > <script src="Block.js"></script> > <script src="BoolLiteral.js"></script> > <script src="Break.js"></script> >+ <script src="BuiltinVectorConstructors.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="CallExpression.js"></script> > <script src="CallFunction.js"></script> > <script src="Check.js"></script> >@@ -42,7 +49,6 @@ td { > <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> >@@ -61,7 +67,6 @@ td { > <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> >@@ -69,7 +74,6 @@ td { > <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> >@@ -79,7 +83,6 @@ td { > <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> >@@ -96,12 +99,12 @@ td { > <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="OriginKind.js"></script> > <script src="OverloadResolutionFailure.js"></script> > <script src="Parse.js"></script> >@@ -109,14 +112,11 @@ td { > <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="RemoveTypeArguments.js"></script> > <script src="ResolveNames.js"></script> > <script src="ResolveOverloadImpl.js"></script> > <script src="ResolveProperties.js"></script> >@@ -124,27 +124,22 @@ 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> > <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="SynthesizeOperatorBool.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> >@@ -152,6 +147,7 @@ td { > <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/SPIRVCodegen.js b/Tools/WebGPUShadingLanguageRI/SPIRVCodegen.js >index b4f50859a87afb60e54b360c6059c4aac8c23bca..9844e084f0887189f6e1c2aa921d3a5c6830fbba 100644 >--- a/Tools/WebGPUShadingLanguageRI/SPIRVCodegen.js >+++ b/Tools/WebGPUShadingLanguageRI/SPIRVCodegen.js >@@ -1,5 +1,5 @@ > /* >- * Copyright (C) 2017 Apple Inc. All rights reserved. >+ * Copyright (C) 2018 Apple Inc. All rights reserved. > * > * Redistribution and use in source and binary forms, with or without > * modification, are permitted provided that the following conditions >@@ -53,7 +53,7 @@ function generateSPIRV(spirv, program) > typeMap.set(program.intrinsics.uint32, currentId++); > > for (let entryPoint of findEntryPoints()) { >- let inlinedShader = program.funcInstantiator.getUnique(entryPoint, []); >+ let inlinedShader = entryPoint; > _inlineFunction(program, inlinedShader, new VisitingSet(entryPoint)); > > let typeAnalyzer = new SPIRVTypeAnalyzer(program, typeMap, currentId); >diff --git a/Tools/WebGPUShadingLanguageRI/StandardLibrary.js b/Tools/WebGPUShadingLanguageRI/StandardLibrary.js >index 1988723c3548081c667fac7862f40267f9f8b857..06b251cf0a24819cab5065ef5445e1489d5eaafc 100644 >--- a/Tools/WebGPUShadingLanguageRI/StandardLibrary.js >+++ b/Tools/WebGPUShadingLanguageRI/StandardLibrary.js >@@ -1,5 +1,5 @@ > /* >- * Copyright (C) 2017 Apple Inc. All rights reserved. >+ * Copyright (C) 2018 Apple Inc. All rights reserved. > * > * Redistribution and use in source and binary forms, with or without > * modification, are permitted provided that the following conditions >@@ -31,51 +31,54 @@ let standardLibrary = ` > > // Need to bootstrap void first. > native typedef void; >- >-native typedef uint8; >-native typedef int32; >-native typedef uint32; > native typedef bool; >-typedef int = int32; >-typedef uint = uint32; >- >-native typedef float32; >-typedef float = float32; >- >-native operator int32(uint32); >-native operator int32(uint8); >-native operator int32(float); >-native operator uint32(int32); >-native operator uint32(uint8); >-native operator uint32(float); >-native operator uint8(int32); >-native operator uint8(uint32); >-native operator uint8(float); >-native operator float(int32); >-native operator float(uint32); >-native operator float(uint8); >+native typedef uchar; >+native typedef uint; >+native typedef int; >+native typedef float; >+ >+// FIXME: Add support for these types to Intrinsics.js >+// native typedef ushort; >+// native typedef char; >+// native typedef short; >+// native typedef half; >+// native typedef atomic_int; >+// native typedef atomic_uint; >+ >+native operator int(uint); >+native operator int(uchar); >+native operator int(float); >+native operator uint(int); >+native operator uint(uchar); >+native operator uint(float); >+native operator uchar(int); >+native operator uchar(uint); >+native operator uchar(float); >+native operator float(int); >+native operator float(uint); >+native operator float(uchar); > > native int operator+(int, int); > native uint operator+(uint, uint); >-uint8 operator+(uint8 a, uint8 b) { return uint8(uint(a) + uint(b)); } >+uchar operator+(uchar a, uchar b) { return uchar(uint(a) + uint(b)); } > native float operator+(float, float); > int operator++(int value) { return value + 1; } > uint operator++(uint value) { return value + 1; } >-uint8 operator++(uint8 value) { return value + 1; } >+uchar operator++(uchar value) { return value + 1; } > native int operator-(int, int); > native uint operator-(uint, uint); >-uint8 operator-(uint8 a, uint8 b) { return uint8(uint(a) - uint(b)); } >+uchar operator-(uchar a, uchar b) { return uchar(uint(a) - uint(b)); } > native float operator-(float, float); > int operator--(int value) { return value - 1; } > uint operator--(uint value) { return value - 1; } >-uint8 operator--(uint8 value) { return value - 1; } >+uchar operator--(uchar value) { return value - 1; } > native int operator*(int, int); > native uint operator*(uint, uint); >-uint8 operator*(uint8 a, uint8 b) { return uint8(uint(a) * uint(b)); } >+uchar operator*(uchar a, uchar b) { return uchar(uint(a) * uint(b)); } > native float operator*(float, float); > native int operator/(int, int); > native uint operator/(uint, uint); >-uint8 operator/(uint8 a, uint8 b) { return uint8(uint(a) / uint(b)); } >+uchar operator/(uchar a, uchar b) { return uchar(uint(a) / uint(b)); } > native int operator&(int, int); > native int operator|(int, int); > native int operator^(int, int); >@@ -88,33 +91,33 @@ native uint operator^(uint, uint); > native uint operator~(uint); > native uint operator<<(uint, uint); > native uint operator>>(uint, uint); >-uint8 operator&(uint8 a, uint8 b) { return uint8(uint(a) & uint(b)); } >-uint8 operator|(uint8 a, uint8 b) { return uint8(uint(a) | uint(b)); } >-uint8 operator^(uint8 a, uint8 b) { return uint8(uint(a) ^ uint(b)); } >-uint8 operator~(uint8 value) { return uint8(~uint(value)); } >-uint8 operator<<(uint8 a, uint b) { return uint8(uint(a) << (b & 7)); } >-uint8 operator>>(uint8 a, uint b) { return uint8(uint(a) >> (b & 7)); } >+uchar operator&(uchar a, uchar b) { return uchar(uint(a) & uint(b)); } >+uchar operator|(uchar a, uchar b) { return uchar(uint(a) | uint(b)); } >+uchar operator^(uchar a, uchar b) { return uchar(uint(a) ^ uint(b)); } >+uchar operator~(uchar value) { return uchar(~uint(value)); } >+uchar operator<<(uchar a, uint b) { return uchar(uint(a) << (b & 7)); } >+uchar operator>>(uchar a, uint b) { return uchar(uint(a) >> (b & 7)); } > native float operator/(float, float); > native bool operator==(int, int); > native bool operator==(uint, uint); >-bool operator==(uint8 a, uint8 b) { return uint(a) == uint(b); } >+bool operator==(uchar a, uchar b) { return uint(a) == uint(b); } > native bool operator==(bool, bool); > native bool operator==(float, float); > native bool operator<(int, int); > native bool operator<(uint, uint); >-bool operator<(uint8 a, uint8 b) { return uint(a) < uint(b); } >+bool operator<(uchar a, uchar b) { return uint(a) < uint(b); } > native bool operator<(float, float); > native bool operator<=(int, int); > native bool operator<=(uint, uint); >-bool operator<=(uint8 a, uint8 b) { return uint(a) <= uint(b); } >+bool operator<=(uchar a, uchar b) { return uint(a) <= uint(b); } > native bool operator<=(float, float); > native bool operator>(int, int); > native bool operator>(uint, uint); >-bool operator>(uint8 a, uint8 b) { return uint(a) > uint(b); } >+bool operator>(uchar a, uchar b) { return uint(a) > uint(b); } > native bool operator>(float, float); > native bool operator>=(int, int); > native bool operator>=(uint, uint); >-bool operator>=(uint8 a, uint8 b) { return uint(a) >= uint(b); } >+bool operator>=(uchar a, uchar b) { return uint(a) >= uint(b); } > native bool operator>=(float, float); > > bool operator&(bool a, bool b) >@@ -145,245 +148,54 @@ 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 uchar2; >+native typedef uchar3; >+native typedef uchar4; > >-struct vec2<T> { >- T x; >- T y; >-} >+native typedef uint2; >+native typedef uint3; >+native typedef uint4; > >-typedef int2 = vec2<int>; >-typedef uint2 = vec2<uint>; >-typedef float2 = vec2<float>; >+native typedef int2; >+native typedef int3; >+native typedef int4; > >-operator<T> vec2<T>(T x, T y) >-{ >- vec2<T> result; >- result.x = x; >- result.y = y; >- return result; >-} >- >-bool operator==<T:Equatable>(vec2<T> a, vec2<T> b) >-{ >- return a.x == b.x && a.y == b.y; >-} >- >-thread T* operator&[]<T>(thread vec2<T>* foo, uint index) >-{ >- if (index == 0) >- return &foo->x; >- if (index == 1) >- return &foo->y; >- trap; >-} >- >-struct vec3<T> { >- T x; >- T y; >- T z; >-} >- >-typedef int3 = vec3<int>; >-typedef uint3 = vec3<uint>; >-typedef float3 = vec3<float>; >- >-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; >-} >+native typedef float2; >+native typedef float3; >+native typedef float4; >+`; > >-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; >-} >+// FIXME: Once the standard library has been replaced with a new version, this comments should be removed. >+// This list is used to restrict the availability of vector types available in the langauge. >+// Permissible vector element types must appear in this list and in the standard library >+const VectorElementTypes = [ /*"bool",*/ "uchar", /*"char", "ushort", "short",*/ "uint", "int", /* "half", */"float" ]; >+const VectorElementSizes = [ 2, 3, 4 ]; > >-bool operator==<T:Equatable>(vec4<T> a, vec4<T> b) >+function allVectorTypeNames() > { >- 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; >+ const names = []; >+ for (let elementType of VectorElementTypes) { >+ for (let size of VectorElementSizes) >+ names.push(`${elementType}${size}`); >+ } >+ return names; > } > >-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); >+// Provides operator&[] >+standardLibrary += OperatorAnderIndexer.functions().join(";\n") + ";\n"; > >-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[]); >+// Native vector types are like structs in the langauge, but they do not have the ander field access. >+// It is not possible to take the address of a vector field. >+standardLibrary += BuiltinVectorGetter.functions().join(";\n") + ";\n"; >+standardLibrary += BuiltinVectorSetter.functions().join(";\n") + ";\n"; >+standardLibrary += BuiltinVectorIndexGetter.functions().join(";\n") + ";\n"; >+standardLibrary += BuiltinVectorIndexSetter.functions().join(";\n") + ";\n"; > >-uint operator.length<T, uint length>(T[length]) >-{ >- return length; >-} >-`; >- >-function intToString(x) >-{ >- switch (x) { >- case 0: >- return "x"; >- case 1: >- return "y"; >- case 2: >- return "z"; >- case 3: >- return "w"; >- default: >- throw new Error("Could not generate standard library."); >- } >-} >+// FIXME: For native types these could be included as source in the standard library. >+// https://bugs.webkit.org/show_bug.cgi?id=188685 >+standardLibrary += OperatorBool.functions().join(";\n") + ";\n"; >+standardLibrary += BuiltinVectorEqualityOperator.functions().join(";\n") + ";\n"; > >-// There are 481 swizzle operators, so we compile them as native functions >-standardLibrary += SwizzleOp.allSwizzleOperators().join(";\n") + ";"; >-console.log(standardLibrary); >\ No newline at end of file >+// FIXME: These need to be included as source in the standard library. >+standardLibrary += SwizzleOp.functions().join(";\n") + ";\n"; >+standardLibrary += BuiltinVectorConstructors.functions().join(";\n") + ";\n"; >diff --git a/Tools/WebGPUShadingLanguageRI/StatementCloner.js b/Tools/WebGPUShadingLanguageRI/StatementCloner.js >index c9479a285ba0e13535dea37f7fc1a63bc71cf316..b3948c450c7160977975ed4e8e98ed99c4f7a059 100644 >--- a/Tools/WebGPUShadingLanguageRI/StatementCloner.js >+++ b/Tools/WebGPUShadingLanguageRI/StatementCloner.js >@@ -1,5 +1,5 @@ > /* >- * Copyright (C) 2017 Apple Inc. All rights reserved. >+ * Copyright (C) 2018 Apple Inc. All rights reserved. > * > * Redistribution and use in source and binary forms, with or without > * modification, are permitted provided that the following conditions >@@ -27,11 +27,9 @@ > class StatementCloner extends Rewriter { > visitFuncDef(node) > { >- let typeParameters = node.typeParameters.map(typeParameter => typeParameter.visit(this)); > let result = new FuncDef( > node.origin, node.name, > node.returnType.visit(this), >- typeParameters, > node.parameters.map(parameter => parameter.visit(this)), > node.body.visit(this), > node.isCast, node.shaderType); >@@ -44,7 +42,6 @@ class StatementCloner extends Rewriter { > let result = new NativeFunc( > node.origin, node.name, > node.returnType.visit(this), >- node.typeParameters.map(typeParameter => typeParameter.visit(this)), > node.parameters.map(parameter => parameter.visit(this)), > node.isCast, node.shaderType); > result.isRestricted = node.isRestricted; >@@ -53,63 +50,27 @@ class StatementCloner extends Rewriter { > > visitNativeType(node) > { >- return new NativeType( >- node.origin, node.name, node.typeParameters.map(typeParameter => typeParameter.visit(this))); >+ return new NativeType(node.origin, node.name); > } > > visitTypeDef(node) > { >- return new TypeDef( >- node.origin, node.name, >- node.typeParameters.map(typeParameter => typeParameter.visit(this)), >- node.type.visit(this)); >+ return new TypeDef(node.origin, node.name, node.type.visit(this)); > } > > visitStructType(node) > { >- let result = new StructType( >- node.origin, node.name, >- node.typeParameters.map(typeParameter => typeParameter.visit(this))); >+ let result = new StructType(node.origin, node.name); > for (let field of node.fields) > result.add(field.visit(this)); > return result; > } > >- visitConstexprTypeParameter(node) >- { >- return new ConstexprTypeParameter(node.origin, node.name, node.type.visit(this)); >- } >- >- visitProtocolDecl(node) >- { >- let result = new ProtocolDecl(node.origin, node.name); >- for (let protocol of node.extends) >- result.addExtends(protocol.visit(this)); >- for (let signature of node.signatures) >- result.add(signature.visit(this)); >- return result; >- } >- >- visitTypeVariable(node) >- { >- return new TypeVariable(node.origin, node.name, Node.visit(node.protocol, this)); >- } >- >- visitProtocolRef(node) >- { >- return new ProtocolRef(node.origin, node.name); >- } >- > visitBoolLiteral(node) > { > return new BoolLiteral(node.origin, node.value); > } > >- visitTypeOrVariableRef(node) >- { >- return new TypeOrVariableRef(node.origin, node.name); >- } >- > visitEnumType(node) > { > let result = new EnumType(node.origin, node.name, node.baseType.visit(this)); >diff --git a/Tools/WebGPUShadingLanguageRI/StructLayoutBuilder.js b/Tools/WebGPUShadingLanguageRI/StructLayoutBuilder.js >index 4f98c573a1a38237e16450ae10b86cb2e61d1230..11b44b93360929f3b1d4bd1575f8e6ad6b94c47c 100644 >--- a/Tools/WebGPUShadingLanguageRI/StructLayoutBuilder.js >+++ b/Tools/WebGPUShadingLanguageRI/StructLayoutBuilder.js >@@ -1,5 +1,5 @@ > /* >- * Copyright (C) 2017 Apple Inc. All rights reserved. >+ * Copyright (C) 2018 Apple Inc. All rights reserved. > * > * Redistribution and use in source and binary forms, with or without > * modification, are permitted provided that the following conditions >@@ -39,8 +39,6 @@ class StructLayoutBuilder extends Visitor { > { > if (node.size != null) > return; >- if (node.typeParameters.length) >- throw new Error("Cannot do layout for generic type: " + node); > let oldOffset = this._offset; > this._offset = 0; > super.visitStructType(node); >@@ -60,12 +58,6 @@ class StructLayoutBuilder extends Visitor { > this._offset += size; > } > >- visitNativeFuncInstance(node) >- { >- super.visitNativeFuncInstance(node); >- node.func.didLayoutStructsInImplementationData(node.implementationData); >- } >- > visitTypeRef(node) > { > super.visitTypeRef(node); >@@ -76,14 +68,6 @@ class StructLayoutBuilder extends Visitor { > { > for (let argument of node.argumentList) > Node.visit(argument, this); >- let handleTypeArguments = actualTypeArguments => { >- if (actualTypeArguments) { >- for (let argument of actualTypeArguments) >- argument.visit(this); >- } >- }; >- handleTypeArguments(node.instantiatedActualTypeArguments); >- Node.visit(node.nativeFuncInstance, this); > Node.visit(node.resultType, this); > } > } >diff --git a/Tools/WebGPUShadingLanguageRI/StructType.js b/Tools/WebGPUShadingLanguageRI/StructType.js >index f9d8c7da485832161e55d22a43876299337cb936..c0ff9583b4900a47f7634cc1b8f16905b1fa312a 100644 >--- a/Tools/WebGPUShadingLanguageRI/StructType.js >+++ b/Tools/WebGPUShadingLanguageRI/StructType.js >@@ -1,5 +1,5 @@ > /* >- * Copyright (C) 2017 Apple Inc. All rights reserved. >+ * Copyright (C) 2018 Apple Inc. All rights reserved. > * > * Redistribution and use in source and binary forms, with or without > * modification, are permitted provided that the following conditions >@@ -25,12 +25,11 @@ > "use strict"; > > class StructType extends Type { >- constructor(origin, name, typeParameters) >+ constructor(origin, name) > { > super(); > this._origin = origin; > this._name = name; >- this._typeParameters = typeParameters; > this._fields = new Map(); > } > >@@ -44,7 +43,6 @@ class StructType extends Type { > > get name() { return this._name; } > get origin() { return this._origin; } >- get typeParameters() { return this._typeParameters; } > > get fieldNames() { return this._fields.keys(); } > fieldByName(name) { return this._fields.get(name); } >@@ -58,32 +56,6 @@ class StructType extends Type { > return result; > } > >- instantiate(typeArguments = null) >- { >- let substitution = null; >- let typeParameters = this.typeParameters; >- >- if (typeArguments) { >- if (typeArguments.length != this.typeParameters.length) >- throw new WTypeError(this.origin.originString, "Wrong number of type arguments to instantiation"); >- >- substitution = new Substitution(this.typeParameters, typeArguments); >- typeParameters = []; >- } >- >- let instantiateImmediates = new InstantiateImmediates(); >- let result = new StructType(this.origin, this.name, typeParameters); >- for (let field of this.fields) { >- let newField = field; >- if (substitution) >- newField = newField.visit(substitution); >- newField = newField.visit(instantiateImmediates); >- result.add(newField); >- } >- >- return result; >- } >- > populateDefaultValue(buffer, offset) > { > if (this.size == null) >@@ -94,6 +66,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/Substitution.js b/Tools/WebGPUShadingLanguageRI/Substitution.js >deleted file mode 100644 >index 6a223f6794a856c64308df40ab918aca2086fb29..0000000000000000000000000000000000000000 >--- a/Tools/WebGPUShadingLanguageRI/Substitution.js >+++ /dev/null >@@ -1,63 +0,0 @@ >-/* >- * Copyright (C) 2017 Apple Inc. All rights reserved. >- * >- * Redistribution and use in source and binary forms, with or without >- * modification, are permitted provided that the following conditions >- * are met: >- * 1. Redistributions of source code must retain the above copyright >- * notice, this list of conditions and the following disclaimer. >- * 2. Redistributions in binary form must reproduce the above copyright >- * notice, this list of conditions and the following disclaimer in the >- * documentation and/or other materials provided with the distribution. >- * >- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY >- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE >- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR >- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR >- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, >- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, >- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR >- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY >- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT >- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE >- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. >- */ >-"use strict"; >- >-class Substitution extends Rewriter { >- constructor(parameters, argumentList) >- { >- super(); >- if (parameters.length != argumentList.length) >- throw new Error("Parameters and arguments are mismatched"); >- this._map = new Map(); >- for (let i = 0; i < parameters.length; ++i) >- this._map.set(parameters[i], argumentList[i]); >- } >- >- get map() { return this._map; } >- >- visitTypeRef(node) >- { >- let replacement = this._map.get(node.type); >- if (replacement) { >- if (node.typeArguments.length) >- throw new Error("Unexpected type arguments on type variable"); >- let result = replacement.visit(new AutoWrapper()); >- return result; >- } >- >- let result = super.visitTypeRef(node); >- return result; >- } >- >- visitVariableRef(node) >- { >- let replacement = this._map.get(node.variable); >- if (replacement) >- return replacement.visit(new AutoWrapper()); >- >- return super.visitVariableRef(node); >- } >-} >- >diff --git a/Tools/WebGPUShadingLanguageRI/SwizzleOp.js b/Tools/WebGPUShadingLanguageRI/SwizzleOp.js >index d1c5bd0e6b3920f571de7c209486036b94548a74..25998ef79d98a5288209875d346cf5509e9ba726 100644 >--- a/Tools/WebGPUShadingLanguageRI/SwizzleOp.js >+++ b/Tools/WebGPUShadingLanguageRI/SwizzleOp.js >@@ -1,5 +1,5 @@ > /* >- * Copyright (C) 2017 Apple Inc. All rights reserved. >+ * Copyright (C) 2018 Apple Inc. All rights reserved. > * > * Redistribution and use in source and binary forms, with or without > * modification, are permitted provided that the following conditions >@@ -20,54 +20,88 @@ > * 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. >+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. > */ > "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 intToString(x) > { >- if (!SwizzleOp._allSwizzleOperators) { >- SwizzleOp._allSwizzleOperators = []; >- >- function _generateSwizzle(maxDepth, maxItems, array) { >+ switch (x) { >+ case 0: >+ return "x"; >+ case 1: >+ return "y"; >+ case 2: >+ return "z"; >+ case 3: >+ return "w"; >+ default: >+ throw new Error("Could not generate standard library."); >+ } >+ } >+ >+ static functions() >+ { >+ if (!this._functions) { >+ // We can't directly use this._functions in _generateSwizzles. >+ const functions = []; >+ >+ 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); >+ array.push(SwizzleOp.intToString(i)); >+ _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..de8df5d1148c578af0db6e27d7b0179899f15d4a >--- /dev/null >+++ b/Tools/WebGPUShadingLanguageRI/SynthesizeArrayOperatorLength.js >@@ -0,0 +1,66 @@ >+/* >+ * Copyright (C) 2018 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()); >+ >+ const uint = TypeRef.wrap(program.globalNameContext.get(Type, "uint")); >+ const nameResolver = new NameResolver(program.globalNameContext); >+ uint.visit(nameResolver); >+ >+ for (let arrayType of arrayTypes) { >+ const paramType = TypeRef.wrap(arrayType); >+ paramType.visit(nameResolver); >+ paramType.type.elementType.visit(nameResolver); >+ >+ let possibleExistingFunctions = program.functions.get("operator.length"); >+ if (possibleExistingFunctions) { >+ // Ignore user-defined functions, only include those introduced below. >+ possibleExistingFunctions = possibleExistingFunctions.filter(t => t instanceof NativeFunc); >+ const overloads = resolveOverloadImpl(possibleExistingFunctions, [ paramType ], uint); >+ if (overloads.func) >+ continue; >+ } >+ >+ let nativeFunc = new NativeFunc( >+ arrayType.origin, "operator.length", uint, >+ [ new FuncParameter(arrayType.origin, null, paramType) ], >+ false, null); >+ nativeFunc.implementation = ([array]) => EPtr.box(arrayType.numElementsValue); >+ program.add(nativeFunc); >+ >+ } >+} >diff --git a/Tools/WebGPUShadingLanguageRI/SynthesizeCopyConstructorOperator.js b/Tools/WebGPUShadingLanguageRI/SynthesizeCopyConstructorOperator.js >new file mode 100644 >index 0000000000000000000000000000000000000000..cf98c467a5c12d8462f1bb0781a20e0e2ae35c39 >--- /dev/null >+++ b/Tools/WebGPUShadingLanguageRI/SynthesizeCopyConstructorOperator.js >@@ -0,0 +1,63 @@ >+/* >+ * Copyright (C) 2018 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..fefe9c03d7b10b3116b3b67f2af057f16fc1516c >--- /dev/null >+++ b/Tools/WebGPUShadingLanguageRI/SynthesizeDefaultConstructorOperator.js >@@ -0,0 +1,61 @@ >+/* >+ * Copyright (C) 2018 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/SynthesizeEnumFunctions.js b/Tools/WebGPUShadingLanguageRI/SynthesizeEnumFunctions.js >index 5af2bdf93a805fc08c29f1ea0510ce29e280a56f..137ac9fcd15887af8c76e4f64cdd5a22d27caa12 100644 >--- a/Tools/WebGPUShadingLanguageRI/SynthesizeEnumFunctions.js >+++ b/Tools/WebGPUShadingLanguageRI/SynthesizeEnumFunctions.js >@@ -1,5 +1,5 @@ > /* >- * Copyright (C) 2017 Apple Inc. All rights reserved. >+ * Copyright (C) 2018 Apple Inc. All rights reserved. > * > * Redistribution and use in source and binary forms, with or without > * modification, are permitted provided that the following conditions >@@ -20,7 +20,7 @@ > * 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. >+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. > */ > "use strict"; > >@@ -29,37 +29,37 @@ function synthesizeEnumFunctions(program) > for (let type of program.types.values()) { > if (!(type instanceof EnumType)) > continue; >- >+ > let nativeFunc; > let isCast = false; > let shaderType; >- >+ > nativeFunc = new NativeFunc( >- type.origin, "operator==", new TypeRef(type.origin, "bool", []), [], >+ type.origin, "operator==", new TypeRef(type.origin, "bool"), > [ >- new FuncParameter(type.origin, null, new TypeRef(type.origin, type.name, [])), >- new FuncParameter(type.origin, null, new TypeRef(type.origin, type.name, [])) >+ new FuncParameter(type.origin, null, new TypeRef(type.origin, type.name)), >+ new FuncParameter(type.origin, null, new TypeRef(type.origin, type.name)) > ], > isCast, shaderType); > nativeFunc.implementation = ([left, right]) => EPtr.box(left.loadValue() == right.loadValue()); > program.add(nativeFunc); >- >+ > nativeFunc = new NativeFunc( >- type.origin, "operator.value", type.baseType.visit(new Rewriter()), [], >- [new FuncParameter(type.origin, null, new TypeRef(type.origin, type.name, []))], >+ type.origin, "operator.value", type.baseType.visit(new Rewriter()), >+ [new FuncParameter(type.origin, null, new TypeRef(type.origin, type.name))], > isCast, shaderType); > nativeFunc.implementation = ([value]) => value; > program.add(nativeFunc); >- >+ > nativeFunc = new NativeFunc( >- type.origin, "operator cast", type.baseType.visit(new Rewriter()), [], >- [new FuncParameter(type.origin, null, new TypeRef(type.origin, type.name, []))], >+ type.origin, "operator cast", type.baseType.visit(new Rewriter()), >+ [new FuncParameter(type.origin, null, new TypeRef(type.origin, type.name))], > isCast, shaderType); > nativeFunc.implementation = ([value]) => value; > program.add(nativeFunc); >- >+ > nativeFunc = new NativeFunc( >- type.origin, "operator cast", new TypeRef(type.origin, type.name, []), [], >+ type.origin, "operator cast", new TypeRef(type.origin, type.name), > [new FuncParameter(type.origin, null, type.baseType.visit(new Rewriter()))], > isCast, shaderType); > nativeFunc.implementation = ([value]) => value; >diff --git a/Tools/WebGPUShadingLanguageRI/SynthesizeOperatorBool.js b/Tools/WebGPUShadingLanguageRI/SynthesizeOperatorBool.js >new file mode 100644 >index 0000000000000000000000000000000000000000..695fe13753d0a2643b095b534b119217f62538b3 >--- /dev/null >+++ b/Tools/WebGPUShadingLanguageRI/SynthesizeOperatorBool.js >@@ -0,0 +1,37 @@ >+/* >+ * Copyright (C) 2018 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 synthesizeOperatorBool(program) >+{ >+ for (let type of program.types.values()) { >+ if (!(type instanceof StructType) && !(type instanceof EnumType)) >+ continue; >+ const func = new NativeFunc(type.origin, "operator cast", TypeRef.wrap(program.types.get("bool")), [ new FuncParameter(type.origin, null, TypeRef.wrap(type)) ], true, null); >+ const operatorBool = new OperatorBool(type.name); >+ operatorBool.instantiateImplementation(func); >+ program.add(func); >+ } >+} >diff --git a/Tools/WebGPUShadingLanguageRI/SynthesizeStructAccessors.js b/Tools/WebGPUShadingLanguageRI/SynthesizeStructAccessors.js >index f7816f2b252e9ba4da9ec84def611c55e4bfe3a9..bfe604494dc725ae7e74ad4a0bfe23e93c091776 100644 >--- a/Tools/WebGPUShadingLanguageRI/SynthesizeStructAccessors.js >+++ b/Tools/WebGPUShadingLanguageRI/SynthesizeStructAccessors.js >@@ -1,5 +1,5 @@ > /* >- * Copyright (C) 2017 Apple Inc. All rights reserved. >+ * Copyright (C) 2018 Apple Inc. All rights reserved. > * > * Redistribution and use in source and binary forms, with or without > * modification, are permitted provided that the following conditions >@@ -31,81 +31,36 @@ function synthesizeStructAccessors(program) > continue; > > for (let field of type.fields) { >- function createTypeParameters() >- { >- return type.typeParameters.map( >- typeParameter => typeParameter.visit(new TypeParameterRewriter())); >- } >- >- function createTypeArguments() >- { >- return typeParameters.map(typeParameter => typeParameter.visit(new AutoWrapper())); >- } >- > function setupImplementationData(nativeFunc, implementation) > { >- nativeFunc.instantiateImplementation = substitution => { >- let newType = type.instantiate(nativeFunc.typeParameters.map(typeParameter => { >- let substitute = substitution.map.get(typeParameter); >- if (!substitute) >- throw new Error("Null substitute for type parameter " + typeParameter); >- return substitute; >- })); >- return {type: newType, fieldName: field.name}; >- }; > nativeFunc.visitImplementationData = (implementationData, visitor) => { > // Visiting the type first ensures that the struct layout builder figures out the field's > // offset. > implementationData.type.visit(visitor); > }; >- nativeFunc.didLayoutStructsInImplementationData = implementationData => { >- let structSize = implementationData.type.size; >- if (structSize == null) >- throw new Error("No struct size for " + nativeFunc); >- let field = implementationData.type.fieldByName(implementationData.fieldName); >- if (!field) >- throw new Error("Could not find field"); >- let offset = field.offset; >- let fieldSize = field.type.size; >- if (fieldSize == null) >- throw new Error("No field size for " + nativeFunc); >- if (offset == null) >- throw new Error("No offset for " + nativeFunc); >- >- implementationData.offset = offset; >- implementationData.structSize = structSize; >- implementationData.fieldSize = fieldSize; >- }; >+ > nativeFunc.implementation = (argumentList, node) => { >- let nativeFuncInstance = node.nativeFuncInstance; >- let implementationData = nativeFuncInstance.implementationData; >- return implementation( >- argumentList, >- implementationData.offset, >- implementationData.structSize, >- implementationData.fieldSize); >+ return implementation(argumentList, field.offset, type.size, field.type.size); > }; > } > > function createFieldType() > { >- return field.type.visit(new Substitution(type.typeParameters, typeParameters)); >+ return field.type.visit(new Rewriter()); > } > > function createTypeRef() > { >- return TypeRef.instantiate(type, createTypeArguments()); >+ return TypeRef.instantiate(type); > } > > let isCast = false; > let shaderType; >- let typeParameters; > let nativeFunc; > > // The getter: operator.field >- typeParameters = createTypeParameters(); > nativeFunc = new NativeFunc( >- field.origin, "operator." + field.name, createFieldType(), typeParameters, >+ field.origin, "operator." + field.name, createFieldType(), > [new FuncParameter(field.origin, null, createTypeRef())], isCast, shaderType); > setupImplementationData(nativeFunc, ([base], offset, structSize, fieldSize) => { > let result = new EPtr(new EBuffer(fieldSize), 0); >@@ -115,9 +70,8 @@ function synthesizeStructAccessors(program) > program.add(nativeFunc); > > // The setter: operator.field= >- typeParameters = createTypeParameters(); > nativeFunc = new NativeFunc( >- field.origin, "operator." + field.name + "=", createTypeRef(), typeParameters, >+ field.origin, "operator." + field.name + "=", createTypeRef(), > [ > new FuncParameter(field.origin, null, createTypeRef()), > new FuncParameter(field.origin, null, createFieldType()) >@@ -134,10 +88,8 @@ function synthesizeStructAccessors(program) > // The ander: operator&.field > function setupAnder(addressSpace) > { >- typeParameters = createTypeParameters(); > nativeFunc = new NativeFunc( > field.origin, "operator&." + field.name, new PtrType(field.origin, addressSpace, createFieldType()), >- typeParameters, > [ > new FuncParameter( > field.origin, null, >diff --git a/Tools/WebGPUShadingLanguageRI/Test.html b/Tools/WebGPUShadingLanguageRI/Test.html >index a641d3046493dabc2d745e7d0ec96d0bdd441bbc..13f358239929d8a3e6ace52545b91ca52d6060e4 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> >@@ -22,6 +23,12 @@ > <script src="Block.js"></script> > <script src="BoolLiteral.js"></script> > <script src="Break.js"></script> >+<script src="BuiltinVectorConstructors.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="CallExpression.js"></script> > <script src="CallFunction.js"></script> > <script src="Check.js"></script> >@@ -36,7 +43,6 @@ > <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> >@@ -55,7 +61,6 @@ > <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> >@@ -63,7 +68,6 @@ > <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> >@@ -73,7 +77,6 @@ > <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> >@@ -90,12 +93,12 @@ > <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="OriginKind.js"></script> > <script src="OverloadResolutionFailure.js"></script> > <script src="Parse.js"></script> >@@ -103,14 +106,11 @@ > <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="RemoveTypeArguments.js"></script> > <script src="ResolveNames.js"></script> > <script src="ResolveOverloadImpl.js"></script> > <script src="ResolveProperties.js"></script> >@@ -122,19 +122,18 @@ > <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="SynthesizeOperatorBool.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> >@@ -142,6 +141,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> >@@ -172,6 +172,12 @@ function doTestInBrowser() > } > </script> > >+<style> >+ pre { >+ margin:0; >+ } >+</style> >+ > </head> > <body onload="doTestInBrowser()"> > <div id="messages"></div> >diff --git a/Tools/WebGPUShadingLanguageRI/Test.js b/Tools/WebGPUShadingLanguageRI/Test.js >index 322a0a717850d73290848e93bf95bd3a24241c66..5d07d9b196da6de64eda2cda139df3c22f705018 100644 >--- a/Tools/WebGPUShadingLanguageRI/Test.js >+++ b/Tools/WebGPUShadingLanguageRI/Test.js >@@ -1,5 +1,5 @@ > /* >- * Copyright (C) 2017 Apple Inc. All rights reserved. >+ * Copyright (C) 2018 Apple Inc. All rights reserved. > * > * Redistribution and use in source and binary forms, with or without > * modification, are permitted provided that the following conditions >@@ -26,9 +26,9 @@ > > if (this.window) { > this.print = (text) => { >- var span = document.createElement("span"); >+ var span = document.createElement("pre"); > document.getElementById("messages").appendChild(span); >- span.innerHTML = text.replace(/ /g, " ").replace(/\n/g, "<br>") + "<br>"; >+ span.innerText = text; > window.scrollTo(0,document.body.scrollHeight); > }; > this.preciseTime = () => performance.now() / 1000; >@@ -55,17 +55,17 @@ function doLex(code) > > function makeInt(program, value) > { >- return TypedValue.box(program.intrinsics.int32, value); >+ return TypedValue.box(program.intrinsics.int, value); > } > > function makeUint(program, value) > { >- return TypedValue.box(program.intrinsics.uint32, value); >+ return TypedValue.box(program.intrinsics.uint, value); > } > >-function makeUint8(program, value) >+function makeUchar(program, value) > { >- return TypedValue.box(program.intrinsics.uint8, value); >+ return TypedValue.box(program.intrinsics.uchar, value); > } > > function makeBool(program, value) >@@ -99,7 +99,7 @@ function checkNumber(program, result, expected) > > function checkInt(program, result, expected) > { >- if (!result.type.equals(program.intrinsics.int32)) >+ if (!result.type.equals(program.intrinsics.int)) > throw new Error("Wrong result type; result: " + result); > checkNumber(program, result, expected); > } >@@ -114,15 +114,15 @@ function checkEnum(program, result, expected) > > function checkUint(program, result, expected) > { >- if (!result.type.equals(program.intrinsics.uint32)) >+ if (!result.type.equals(program.intrinsics.uint)) > throw new Error("Wrong result type: " + result.type); > if (result.value != expected) > throw new Error("Wrong result: " + result.value + " (expected " + expected + ")"); > } > >-function checkUint8(program, result, expected) >+function checkUchar(program, result, expected) > { >- if (!result.type.equals(program.intrinsics.uint8)) >+ if (!result.type.equals(program.intrinsics.uchar)) > throw new Error("Wrong result type: " + result.type); > if (result.value != expected) > throw new Error("Wrong result: " + result.value + " (expected " + expected + ")"); >@@ -187,7 +187,7 @@ tests.commentParsing = function() { > runs over multiple lines */ > bool foo() { return true; } > `); >- checkBool(program, callFunction(program, "foo", [], []), true); >+ checkBool(program, callFunction(program, "foo", []), true); > > checkFail( > () => doPrep(` >@@ -200,92 +200,92 @@ tests.commentParsing = function() { > > tests.literalBool = function() { > let program = doPrep("bool foo() { return true; }"); >- checkBool(program, callFunction(program, "foo", [], []), true); >+ checkBool(program, callFunction(program, "foo", []), true); > } > > tests.identityBool = function() { > let program = doPrep("bool foo(bool x) { return x; }"); >- checkBool(program, callFunction(program, "foo", [], [makeBool(program, true)]), true); >- checkBool(program, callFunction(program, "foo", [], [makeBool(program, false)]), false); >+ checkBool(program, callFunction(program, "foo", [makeBool(program, true)]), true); >+ checkBool(program, callFunction(program, "foo", [makeBool(program, false)]), false); > } > > tests.intSimpleMath = function() { > let program = doPrep("int foo(int x, int y) { return x + y; }"); >- checkInt(program, callFunction(program, "foo", [], [makeInt(program, 7), makeInt(program, 5)]), 12); >+ checkInt(program, callFunction(program, "foo", [makeInt(program, 7), makeInt(program, 5)]), 12); > program = doPrep("int foo(int x, int y) { return x - y; }"); >- checkInt(program, callFunction(program, "foo", [], [makeInt(program, 7), makeInt(program, 5)]), 2); >- checkInt(program, callFunction(program, "foo", [], [makeInt(program, 5), makeInt(program, 7)]), -2); >+ checkInt(program, callFunction(program, "foo", [makeInt(program, 7), makeInt(program, 5)]), 2); >+ checkInt(program, callFunction(program, "foo", [makeInt(program, 5), makeInt(program, 7)]), -2); > program = doPrep("int foo(int x, int y) { return x * y; }"); >- checkInt(program, callFunction(program, "foo", [], [makeInt(program, 7), makeInt(program, 5)]), 35); >- checkInt(program, callFunction(program, "foo", [], [makeInt(program, 7), makeInt(program, -5)]), -35); >+ checkInt(program, callFunction(program, "foo", [makeInt(program, 7), makeInt(program, 5)]), 35); >+ checkInt(program, callFunction(program, "foo", [makeInt(program, 7), makeInt(program, -5)]), -35); > program = doPrep("int foo(int x, int y) { return x / y; }"); >- checkInt(program, callFunction(program, "foo", [], [makeInt(program, 7), makeInt(program, 2)]), 3); >- checkInt(program, callFunction(program, "foo", [], [makeInt(program, 7), makeInt(program, -2)]), -3); >+ checkInt(program, callFunction(program, "foo", [makeInt(program, 7), makeInt(program, 2)]), 3); >+ checkInt(program, callFunction(program, "foo", [makeInt(program, 7), makeInt(program, -2)]), -3); > } > > tests.uintSimpleMath = function() { > let program = doPrep("uint foo(uint x, uint y) { return x + y; }"); >- checkUint(program, callFunction(program, "foo", [], [makeUint(program, 7), makeUint(program, 5)]), 12); >+ checkUint(program, callFunction(program, "foo", [makeUint(program, 7), makeUint(program, 5)]), 12); > program = doPrep("uint foo(uint x, uint y) { return x - y; }"); >- checkUint(program, callFunction(program, "foo", [], [makeUint(program, 7), makeUint(program, 5)]), 2); >- checkUint(program, callFunction(program, "foo", [], [makeUint(program, 5), makeUint(program, 7)]), 4294967294); >+ checkUint(program, callFunction(program, "foo", [makeUint(program, 7), makeUint(program, 5)]), 2); >+ checkUint(program, callFunction(program, "foo", [makeUint(program, 5), makeUint(program, 7)]), 4294967294); > program = doPrep("uint foo(uint x, uint y) { return x * y; }"); >- checkUint(program, callFunction(program, "foo", [], [makeUint(program, 7), makeUint(program, 5)]), 35); >+ checkUint(program, callFunction(program, "foo", [makeUint(program, 7), makeUint(program, 5)]), 35); > program = doPrep("uint foo(uint x, uint y) { return x / y; }"); >- checkUint(program, callFunction(program, "foo", [], [makeUint(program, 7), makeUint(program, 2)]), 3); >+ checkUint(program, callFunction(program, "foo", [makeUint(program, 7), makeUint(program, 2)]), 3); > } > >-tests.uint8SimpleMath = function() { >- let program = doPrep("uint8 foo(uint8 x, uint8 y) { return x + y; }"); >- checkUint8(program, callFunction(program, "foo", [], [makeUint8(program, 7), makeUint8(program, 5)]), 12); >- program = doPrep("uint8 foo(uint8 x, uint8 y) { return x - y; }"); >- checkUint8(program, callFunction(program, "foo", [], [makeUint8(program, 7), makeUint8(program, 5)]), 2); >- checkUint8(program, callFunction(program, "foo", [], [makeUint8(program, 5), makeUint8(program, 7)]), 254); >- program = doPrep("uint8 foo(uint8 x, uint8 y) { return x * y; }"); >- checkUint8(program, callFunction(program, "foo", [], [makeUint8(program, 7), makeUint8(program, 5)]), 35); >- program = doPrep("uint8 foo(uint8 x, uint8 y) { return x / y; }"); >- checkUint8(program, callFunction(program, "foo", [], [makeUint8(program, 7), makeUint8(program, 2)]), 3); >+tests.ucharSimpleMath = function() { >+ let program = doPrep("uchar foo(uchar x, uchar y) { return x + y; }"); >+ checkUchar(program, callFunction(program, "foo", [makeUchar(program, 7), makeUchar(program, 5)]), 12); >+ program = doPrep("uchar foo(uchar x, uchar y) { return x - y; }"); >+ checkUchar(program, callFunction(program, "foo", [makeUchar(program, 7), makeUchar(program, 5)]), 2); >+ checkUchar(program, callFunction(program, "foo", [makeUchar(program, 5), makeUchar(program, 7)]), 254); >+ program = doPrep("uchar foo(uchar x, uchar y) { return x * y; }"); >+ checkUchar(program, callFunction(program, "foo", [makeUchar(program, 7), makeUchar(program, 5)]), 35); >+ program = doPrep("uchar foo(uchar x, uchar y) { return x / y; }"); >+ checkUchar(program, callFunction(program, "foo", [makeUchar(program, 7), makeUchar(program, 2)]), 3); > } > > tests.equality = function() { > let program = doPrep("bool foo(uint x, uint y) { return x == y; }"); >- checkBool(program, callFunction(program, "foo", [], [makeUint(program, 7), makeUint(program, 5)]), false); >- checkBool(program, callFunction(program, "foo", [], [makeUint(program, 7), makeUint(program, 7)]), true); >- program = doPrep("bool foo(uint8 x, uint8 y) { return x == y; }"); >- checkBool(program, callFunction(program, "foo", [], [makeUint8(program, 7), makeUint8(program, 5)]), false); >- checkBool(program, callFunction(program, "foo", [], [makeUint8(program, 7), makeUint8(program, 7)]), true); >+ checkBool(program, callFunction(program, "foo", [makeUint(program, 7), makeUint(program, 5)]), false); >+ checkBool(program, callFunction(program, "foo", [makeUint(program, 7), makeUint(program, 7)]), true); >+ program = doPrep("bool foo(uchar x, uchar y) { return x == y; }"); >+ checkBool(program, callFunction(program, "foo", [makeUchar(program, 7), makeUchar(program, 5)]), false); >+ checkBool(program, callFunction(program, "foo", [makeUchar(program, 7), makeUchar(program, 7)]), true); > program = doPrep("bool foo(int x, int y) { return x == y; }"); >- checkBool(program, callFunction(program, "foo", [], [makeInt(program, 7), makeInt(program, 5)]), false); >- checkBool(program, callFunction(program, "foo", [], [makeInt(program, 7), makeInt(program, 7)]), true); >+ checkBool(program, callFunction(program, "foo", [makeInt(program, 7), makeInt(program, 5)]), false); >+ checkBool(program, callFunction(program, "foo", [makeInt(program, 7), makeInt(program, 7)]), true); > program = doPrep("bool foo(bool x, bool y) { return x == y; }"); >- checkBool(program, callFunction(program, "foo", [], [makeBool(program, false), makeBool(program, true)]), false); >- checkBool(program, callFunction(program, "foo", [], [makeBool(program, true), makeBool(program, false)]), false); >- checkBool(program, callFunction(program, "foo", [], [makeBool(program, false), makeBool(program, false)]), true); >- checkBool(program, callFunction(program, "foo", [], [makeBool(program, true), makeBool(program, true)]), true); >+ checkBool(program, callFunction(program, "foo", [makeBool(program, false), makeBool(program, true)]), false); >+ checkBool(program, callFunction(program, "foo", [makeBool(program, true), makeBool(program, false)]), false); >+ checkBool(program, callFunction(program, "foo", [makeBool(program, false), makeBool(program, false)]), true); >+ checkBool(program, callFunction(program, "foo", [makeBool(program, true), makeBool(program, true)]), true); > } > > tests.logicalNegation = function() > { > let program = doPrep("bool foo(bool x) { return !x; }"); >- checkBool(program, callFunction(program, "foo", [], [makeBool(program, true)]), false); >- checkBool(program, callFunction(program, "foo", [], [makeBool(program, false)]), true); >+ checkBool(program, callFunction(program, "foo", [makeBool(program, true)]), false); >+ checkBool(program, callFunction(program, "foo", [makeBool(program, false)]), true); > } > > tests.notEquality = function() { > let program = doPrep("bool foo(uint x, uint y) { return x != y; }"); >- checkBool(program, callFunction(program, "foo", [], [makeUint(program, 7), makeUint(program, 5)]), true); >- checkBool(program, callFunction(program, "foo", [], [makeUint(program, 7), makeUint(program, 7)]), false); >- program = doPrep("bool foo(uint8 x, uint8 y) { return x != y; }"); >- checkBool(program, callFunction(program, "foo", [], [makeUint8(program, 7), makeUint8(program, 5)]), true); >- checkBool(program, callFunction(program, "foo", [], [makeUint8(program, 7), makeUint8(program, 7)]), false); >+ checkBool(program, callFunction(program, "foo", [makeUint(program, 7), makeUint(program, 5)]), true); >+ checkBool(program, callFunction(program, "foo", [makeUint(program, 7), makeUint(program, 7)]), false); >+ program = doPrep("bool foo(uchar x, uchar y) { return x != y; }"); >+ checkBool(program, callFunction(program, "foo", [makeUchar(program, 7), makeUchar(program, 5)]), true); >+ checkBool(program, callFunction(program, "foo", [makeUchar(program, 7), makeUchar(program, 7)]), false); > program = doPrep("bool foo(int x, int y) { return x != y; }"); >- checkBool(program, callFunction(program, "foo", [], [makeInt(program, 7), makeInt(program, 5)]), true); >- checkBool(program, callFunction(program, "foo", [], [makeInt(program, 7), makeInt(program, 7)]), false); >+ checkBool(program, callFunction(program, "foo", [makeInt(program, 7), makeInt(program, 5)]), true); >+ checkBool(program, callFunction(program, "foo", [makeInt(program, 7), makeInt(program, 7)]), false); > program = doPrep("bool foo(bool x, bool y) { return x != y; }"); >- checkBool(program, callFunction(program, "foo", [], [makeBool(program, false), makeBool(program, true)]), true); >- checkBool(program, callFunction(program, "foo", [], [makeBool(program, true), makeBool(program, false)]), true); >- checkBool(program, callFunction(program, "foo", [], [makeBool(program, false), makeBool(program, false)]), false); >- checkBool(program, callFunction(program, "foo", [], [makeBool(program, true), makeBool(program, true)]), false); >+ checkBool(program, callFunction(program, "foo", [makeBool(program, false), makeBool(program, true)]), true); >+ checkBool(program, callFunction(program, "foo", [makeBool(program, true), makeBool(program, false)]), true); >+ checkBool(program, callFunction(program, "foo", [makeBool(program, false), makeBool(program, false)]), false); >+ checkBool(program, callFunction(program, "foo", [makeBool(program, true), makeBool(program, true)]), false); > } > > tests.equalityTypeFailure = function() >@@ -298,21 +298,13 @@ tests.equalityTypeFailure = function() > tests.generalNegation = function() > { > let program = doPrep("bool foo(int x) { return !x; }"); >- checkBool(program, callFunction(program, "foo", [], [makeInt(program, 7)]), false); >- checkBool(program, callFunction(program, "foo", [], [makeInt(program, 0)]), true); >+ checkBool(program, callFunction(program, "foo", [makeInt(program, 7)]), false); >+ checkBool(program, callFunction(program, "foo", [makeInt(program, 0)]), true); > } > > tests.add1 = function() { > let program = doPrep("int foo(int x) { return x + 1; }"); >- 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); >+ checkInt(program, callFunction(program, "foo", [makeInt(program, 42)]), 43); > } > > tests.nameResolutionFailure = function() >@@ -331,7 +323,7 @@ tests.simpleVariable = function() > return result; > } > `); >- checkInt(program, callFunction(program, "foo", [], [makeInt(program, 42)]), 42); >+ checkInt(program, callFunction(program, "foo", [makeInt(program, 42)]), 42); > } > > tests.simpleAssignment = function() >@@ -344,7 +336,7 @@ tests.simpleAssignment = function() > return result; > } > `); >- checkInt(program, callFunction(program, "foo", [], [makeInt(program, 42)]), 42); >+ checkInt(program, callFunction(program, "foo", [makeInt(program, 42)]), 42); > } > > tests.simpleDefault = function() >@@ -356,7 +348,7 @@ tests.simpleDefault = function() > return result; > } > `); >- checkInt(program, callFunction(program, "foo", [], []), 0); >+ checkInt(program, callFunction(program, "foo", []), 0); > } > > tests.simpleDereference = function() >@@ -369,7 +361,7 @@ tests.simpleDereference = function() > `); > 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); >+ checkInt(program, callFunction(program, "foo", [TypedValue.box(new PtrType(externalOrigin, "device", program.intrinsics.int), new EPtr(buffer, 0))]), 13); > } > > tests.dereferenceStore = function() >@@ -382,7 +374,7 @@ tests.dereferenceStore = function() > `); > let buffer = new EBuffer(1); > buffer.set(0, 13); >- callFunction(program, "foo", [], [TypedValue.box(new PtrType(externalOrigin, "device", program.intrinsics.int32), new EPtr(buffer, 0))]); >+ callFunction(program, "foo", [TypedValue.box(new PtrType(externalOrigin, "device", program.intrinsics.int), new EPtr(buffer, 0))]); > if (buffer.get(0) != 52) > throw new Error("Expected buffer to contain 52 but it contains: " + buffer.get(0)); > } >@@ -396,10 +388,10 @@ tests.simpleMakePtr = function() > return &x; > } > `); >- let result = callFunction(program, "foo", [], []); >+ let result = callFunction(program, "foo", []); > if (!result.type.isPtr) > throw new Error("Return type is not a pointer: " + result.type); >- if (!result.type.elementType.equals(program.intrinsics.int32)) >+ if (!result.type.elementType.equals(program.intrinsics.int)) > throw new Error("Return type is not a pointer to an int: " + result.type); > if (!(result.value instanceof EPtr)) > throw new Error("Return value is not an EPtr: " + result.value); >@@ -418,7 +410,7 @@ tests.threadArrayLoad = function() > `); > let buffer = new EBuffer(1); > buffer.set(0, 89); >- let result = callFunction(program, "foo", [], [TypedValue.box(new ArrayRefType(externalOrigin, "thread", program.intrinsics.int32), new EArrayRef(new EPtr(buffer, 0), 1))]); >+ let result = callFunction(program, "foo", [TypedValue.box(new ArrayRefType(externalOrigin, "thread", program.intrinsics.int), new EArrayRef(new EPtr(buffer, 0), 1))]); > checkInt(program, result, 89); > } > >@@ -432,7 +424,7 @@ tests.threadArrayLoadIntLiteral = function() > `); > let buffer = new EBuffer(1); > buffer.set(0, 89); >- let result = callFunction(program, "foo", [], [TypedValue.box(new ArrayRefType(externalOrigin, "thread", program.intrinsics.int32), new EArrayRef(new EPtr(buffer, 0), 1))]); >+ let result = callFunction(program, "foo", [TypedValue.box(new ArrayRefType(externalOrigin, "thread", program.intrinsics.int), new EArrayRef(new EPtr(buffer, 0), 1))]); > checkInt(program, result, 89); > } > >@@ -446,7 +438,7 @@ tests.deviceArrayLoad = function() > `); > let buffer = new EBuffer(1); > buffer.set(0, 89); >- let result = callFunction(program, "foo", [], [TypedValue.box(new ArrayRefType(externalOrigin, "device", program.intrinsics.int32), new EArrayRef(new EPtr(buffer, 0), 1))]); >+ let result = callFunction(program, "foo", [TypedValue.box(new ArrayRefType(externalOrigin, "device", program.intrinsics.int), new EArrayRef(new EPtr(buffer, 0), 1))]); > checkInt(program, result, 89); > } > >@@ -461,12 +453,12 @@ tests.threadArrayStore = function() > let buffer = new EBuffer(1); > buffer.set(0, 15); > let arrayRef = TypedValue.box( >- new ArrayRefType(externalOrigin, "thread", program.intrinsics.int32), >+ new ArrayRefType(externalOrigin, "thread", program.intrinsics.int), > new EArrayRef(new EPtr(buffer, 0), 1)); >- callFunction(program, "foo", [], [arrayRef, makeInt(program, 65)]); >+ callFunction(program, "foo", [arrayRef, makeInt(program, 65)]); > if (buffer.get(0) != 65) > throw new Error("Bad value stored into buffer (expected 65): " + buffer.get(0)); >- callFunction(program, "foo", [], [arrayRef, makeInt(program, -111)]); >+ callFunction(program, "foo", [arrayRef, makeInt(program, -111)]); > if (buffer.get(0) != -111) > throw new Error("Bad value stored into buffer (expected -111): " + buffer.get(0)); > } >@@ -482,12 +474,12 @@ tests.deviceArrayStore = function() > let buffer = new EBuffer(1); > buffer.set(0, 15); > let arrayRef = TypedValue.box( >- new ArrayRefType(externalOrigin, "device", program.intrinsics.int32), >+ new ArrayRefType(externalOrigin, "device", program.intrinsics.int), > new EArrayRef(new EPtr(buffer, 0), 1)); >- callFunction(program, "foo", [], [arrayRef, makeInt(program, 65)]); >+ callFunction(program, "foo", [arrayRef, makeInt(program, 65)]); > if (buffer.get(0) != 65) > throw new Error("Bad value stored into buffer (expected 65): " + buffer.get(0)); >- callFunction(program, "foo", [], [arrayRef, makeInt(program, -111)]); >+ callFunction(program, "foo", [arrayRef, makeInt(program, -111)]); > if (buffer.get(0) != -111) > throw new Error("Bad value stored into buffer (expected -111): " + buffer.get(0)); > } >@@ -503,34 +495,16 @@ tests.deviceArrayStoreIntLiteral = function() > let buffer = new EBuffer(1); > buffer.set(0, 15); > let arrayRef = TypedValue.box( >- new ArrayRefType(externalOrigin, "device", program.intrinsics.int32), >+ new ArrayRefType(externalOrigin, "device", program.intrinsics.int), > new EArrayRef(new EPtr(buffer, 0), 1)); >- callFunction(program, "foo", [], [arrayRef, makeInt(program, 65)]); >+ callFunction(program, "foo", [arrayRef, makeInt(program, 65)]); > if (buffer.get(0) != 65) > throw new Error("Bad value stored into buffer (expected 65): " + buffer.get(0)); >- callFunction(program, "foo", [], [arrayRef, makeInt(program, -111)]); >+ callFunction(program, "foo", [arrayRef, makeInt(program, -111)]); > if (buffer.get(0) != -111) > 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 int operator+(int,int)") != -1); > } > > tests.lexerKeyword = function() >@@ -666,7 +639,7 @@ tests.simpleStruct = function() > 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 result = callFunction(program, "foo", [new TypedValue(structType, new EPtr(buffer, 0))]); > if (!result.type.equals(structType)) > throw new Error("Wrong result type: " + result.type); > let x = result.ePtr.get(0); >@@ -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); >@@ -747,10 +674,10 @@ tests.returnNull = function() > let program = doPrep(` > thread int* foo() { return null; } > `); >- let result = callFunction(program, "foo", [], []); >+ let result = callFunction(program, "foo", []); > if (!result.type.isPtr) > throw new Error("Return type is not a pointer: " + result.type); >- if (!result.type.elementType.equals(program.intrinsics.int32)) >+ if (!result.type.elementType.equals(program.intrinsics.int)) > throw new Error("Return type is not a pointer to an int: " + result.type); > if (result.value != null) > throw new Error("Return value is not null: " + result.value); >@@ -766,7 +693,7 @@ tests.dereferenceDefaultNull = function() > } > `); > checkFail( >- () => callFunction(program, "foo", [], []), >+ () => callFunction(program, "foo", []), > (e) => e instanceof WTrapError); > } > >@@ -780,7 +707,7 @@ tests.defaultInitializedNull = function() > } > `); > checkFail( >- () => callFunction(program, "foo", [], []), >+ () => callFunction(program, "foo", []), > (e) => e instanceof WTrapError); > } > >@@ -797,47 +724,15 @@ tests.passNullToPtrMonomorphic = function() > } > `); > checkFail( >- () => callFunction(program, "bar", [], []), >+ () => callFunction(program, "bar", []), > (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); >@@ -857,10 +752,10 @@ tests.returnNullArrayRef = function() > let program = doPrep(` > thread int[] foo() { return null; } > `); >- let result = callFunction(program, "foo", [], []); >+ let result = callFunction(program, "foo", []); > if (!result.type.isArrayRef) > throw new Error("Return type is not an array reference: " + result.type); >- if (!result.type.elementType.equals(program.intrinsics.int32)) >+ if (!result.type.elementType.equals(program.intrinsics.int)) > throw new Error("Return type is not an int array reference: " + result.type); > if (result.value != null) > throw new Error("Return value is not null: " + result.value); >@@ -876,7 +771,7 @@ tests.dereferenceDefaultNullArrayRef = function() > } > `); > checkFail( >- () => callFunction(program, "foo", [], []), >+ () => callFunction(program, "foo", []), > (e) => e instanceof WTrapError); > } > >@@ -890,7 +785,7 @@ tests.defaultInitializedNullArrayRef = function() > } > `); > checkFail( >- () => callFunction(program, "foo", [], []), >+ () => callFunction(program, "foo", []), > (e) => e instanceof WTrapError); > } > >@@ -904,7 +799,7 @@ tests.defaultInitializedNullArrayRefIntLiteral = function() > } > `); > checkFail( >- () => callFunction(program, "foo", [], []), >+ () => callFunction(program, "foo", []), > (e) => e instanceof WTrapError); > } > >@@ -921,36 +816,20 @@ tests.passNullToPtrMonomorphicArrayRef = function() > } > `); > checkFail( >- () => callFunction(program, "bar", [], []), >+ () => callFunction(program, "bar", []), > (e) => e instanceof WTrapError); > } > >-tests.passNullToPtrPolymorphicArrayRef = function() >-{ >- checkFail( >- () => doPrep(` >- T foo<T>(thread T[] ptr) >- { >- return ptr[0u]; >- } >- int bar() >- { >- return foo(null); >- } >- `), >- (e) => e instanceof WTypeError); >-} >- > tests.returnIntLiteralUint = function() > { > let program = doPrep("uint foo() { return 42; }"); >- checkNumber(program, callFunction(program, "foo", [], []), 42); >+ checkNumber(program, callFunction(program, "foo", []), 42); > } > > tests.returnIntLiteralFloat = function() > { > let program = doPrep("float foo() { return 42; }"); >- checkNumber(program, callFunction(program, "foo", [], []), 42); >+ checkNumber(program, callFunction(program, "foo", []), 42); > } > > tests.badIntLiteralForInt = function() >@@ -974,115 +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); >- let right = new TypeVariable(externalOrigin, "T", null); >- if (left.equals(right)) >- throw new Error("Should not be equal but are: " + left + " and " + right); >- if (right.equals(left)) >- throw new Error("Should not be equal but are: " + left + " and " + right); >- >- function everyOrder(array, callback) >- { >- function recurse(array, callback, order) >- { >- if (!array.length) >- return callback.call(null, order); >- >- for (let i = 0; i < array.length; ++i) { >- let nextArray = array.concat(); >- nextArray.splice(i, 1); >- recurse(nextArray, callback, order.concat([array[i]])); >- } >- } >- >- recurse(array, callback, []); >- } >- >- function everyPair(things) >- { >- let result = []; >- for (let i = 0; i < things.length; ++i) { >- for (let j = 0; j < things.length; ++j) { >- if (i != j) >- result.push([things[i], things[j]]); >- } >- } >- return result; >- } >- >- everyOrder( >- everyPair(["nullType", "variableType", "ptrType"]), >- order => { >- let types = {}; >- types.nullType = new NullType(externalOrigin); >- types.variableType = new TypeVariable(externalOrigin, "T", null); >- types.ptrType = new PtrType(externalOrigin, "constant", new NativeType(externalOrigin, "foo_t", [])); >- let unificationContext = new UnificationContext([types.variableType]); >- for (let [leftName, rightName] of order) { >- let left = types[leftName]; >- let right = types[rightName]; >- let result = left.unify(unificationContext, right); >- if (!result) >- throw new Error("In order " + order + " cannot unify " + left + " with " + right); >- } >- if (!unificationContext.verify().result) >- throw new Error("In order " + order.map(value => "(" + value + ")") + " cannot verify"); >- }); >-} >- > tests.doubleNot = function() > { > let program = doPrep(` >@@ -1091,130 +861,22 @@ tests.doubleNot = function() > return !!x; > } > `); >- checkBool(program, callFunction(program, "foo", [], [makeBool(program, true)]), true); >- checkBool(program, callFunction(program, "foo", [], [makeBool(program, false)]), false); >+ checkBool(program, callFunction(program, "foo", [makeBool(program, true)]), true); >+ checkBool(program, callFunction(program, "foo", [makeBool(program, false)]), false); > } > > 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(` >@@ -1229,7 +891,7 @@ tests.variableShadowing = function() > return y; > } > `); >- checkInt(program, callFunction(program, "foo", [], []), 8); >+ checkInt(program, callFunction(program, "foo", []), 8); > program = doPrep(` > int foo() > { >@@ -1242,7 +904,7 @@ tests.variableShadowing = function() > return y; > } > `); >- checkInt(program, callFunction(program, "foo", [], []), 7); >+ checkInt(program, callFunction(program, "foo", []), 7); > } > > tests.ifStatement = function() >@@ -1257,13 +919,13 @@ tests.ifStatement = function() > return y; > } > `); >- checkInt(program, callFunction(program, "foo", [], [makeInt(program, 3)]), 6); >- checkInt(program, callFunction(program, "foo", [], [makeInt(program, 4)]), 6); >- checkInt(program, callFunction(program, "foo", [], [makeInt(program, 5)]), 6); >- checkInt(program, callFunction(program, "foo", [], [makeInt(program, 6)]), 6); >- checkInt(program, callFunction(program, "foo", [], [makeInt(program, 7)]), 8); >- checkInt(program, callFunction(program, "foo", [], [makeInt(program, 8)]), 6); >- checkInt(program, callFunction(program, "foo", [], [makeInt(program, 9)]), 6); >+ checkInt(program, callFunction(program, "foo", [makeInt(program, 3)]), 6); >+ checkInt(program, callFunction(program, "foo", [makeInt(program, 4)]), 6); >+ checkInt(program, callFunction(program, "foo", [makeInt(program, 5)]), 6); >+ checkInt(program, callFunction(program, "foo", [makeInt(program, 6)]), 6); >+ checkInt(program, callFunction(program, "foo", [makeInt(program, 7)]), 8); >+ checkInt(program, callFunction(program, "foo", [makeInt(program, 8)]), 6); >+ checkInt(program, callFunction(program, "foo", [makeInt(program, 9)]), 6); > } > > tests.ifElseStatement = function() >@@ -1280,13 +942,13 @@ tests.ifElseStatement = function() > return y; > } > `); >- checkInt(program, callFunction(program, "foo", [], [makeInt(program, 3)]), 9); >- checkInt(program, callFunction(program, "foo", [], [makeInt(program, 4)]), 9); >- checkInt(program, callFunction(program, "foo", [], [makeInt(program, 5)]), 9); >- checkInt(program, callFunction(program, "foo", [], [makeInt(program, 6)]), 9); >- checkInt(program, callFunction(program, "foo", [], [makeInt(program, 7)]), 8); >- checkInt(program, callFunction(program, "foo", [], [makeInt(program, 8)]), 9); >- checkInt(program, callFunction(program, "foo", [], [makeInt(program, 9)]), 9); >+ checkInt(program, callFunction(program, "foo", [makeInt(program, 3)]), 9); >+ checkInt(program, callFunction(program, "foo", [makeInt(program, 4)]), 9); >+ checkInt(program, callFunction(program, "foo", [makeInt(program, 5)]), 9); >+ checkInt(program, callFunction(program, "foo", [makeInt(program, 6)]), 9); >+ checkInt(program, callFunction(program, "foo", [makeInt(program, 7)]), 8); >+ checkInt(program, callFunction(program, "foo", [makeInt(program, 8)]), 9); >+ checkInt(program, callFunction(program, "foo", [makeInt(program, 9)]), 9); > } > > tests.ifElseIfStatement = function() >@@ -1303,13 +965,13 @@ tests.ifElseIfStatement = function() > return y; > } > `); >- checkInt(program, callFunction(program, "foo", [], [makeInt(program, 3)]), 6); >- checkInt(program, callFunction(program, "foo", [], [makeInt(program, 4)]), 6); >- checkInt(program, callFunction(program, "foo", [], [makeInt(program, 5)]), 6); >- checkInt(program, callFunction(program, "foo", [], [makeInt(program, 6)]), 6); >- checkInt(program, callFunction(program, "foo", [], [makeInt(program, 7)]), 8); >- checkInt(program, callFunction(program, "foo", [], [makeInt(program, 8)]), 9); >- checkInt(program, callFunction(program, "foo", [], [makeInt(program, 9)]), 6); >+ checkInt(program, callFunction(program, "foo", [makeInt(program, 3)]), 6); >+ checkInt(program, callFunction(program, "foo", [makeInt(program, 4)]), 6); >+ checkInt(program, callFunction(program, "foo", [makeInt(program, 5)]), 6); >+ checkInt(program, callFunction(program, "foo", [makeInt(program, 6)]), 6); >+ checkInt(program, callFunction(program, "foo", [makeInt(program, 7)]), 8); >+ checkInt(program, callFunction(program, "foo", [makeInt(program, 8)]), 9); >+ checkInt(program, callFunction(program, "foo", [makeInt(program, 9)]), 6); > } > > tests.ifElseIfElseStatement = function() >@@ -1328,13 +990,13 @@ tests.ifElseIfElseStatement = function() > return y; > } > `); >- checkInt(program, callFunction(program, "foo", [], [makeInt(program, 3)]), 10); >- checkInt(program, callFunction(program, "foo", [], [makeInt(program, 4)]), 10); >- checkInt(program, callFunction(program, "foo", [], [makeInt(program, 5)]), 10); >- checkInt(program, callFunction(program, "foo", [], [makeInt(program, 6)]), 10); >- checkInt(program, callFunction(program, "foo", [], [makeInt(program, 7)]), 8); >- checkInt(program, callFunction(program, "foo", [], [makeInt(program, 8)]), 9); >- checkInt(program, callFunction(program, "foo", [], [makeInt(program, 9)]), 10); >+ checkInt(program, callFunction(program, "foo", [makeInt(program, 3)]), 10); >+ checkInt(program, callFunction(program, "foo", [makeInt(program, 4)]), 10); >+ checkInt(program, callFunction(program, "foo", [makeInt(program, 5)]), 10); >+ checkInt(program, callFunction(program, "foo", [makeInt(program, 6)]), 10); >+ checkInt(program, callFunction(program, "foo", [makeInt(program, 7)]), 8); >+ checkInt(program, callFunction(program, "foo", [makeInt(program, 8)]), 9); >+ checkInt(program, callFunction(program, "foo", [makeInt(program, 9)]), 10); > } > > tests.returnIf = function() >@@ -1387,13 +1049,13 @@ tests.returnIf = function() > } > } > `); >- checkInt(program, callFunction(program, "foo", [], [makeInt(program, 3)]), 10); >- checkInt(program, callFunction(program, "foo", [], [makeInt(program, 4)]), 10); >- checkInt(program, callFunction(program, "foo", [], [makeInt(program, 5)]), 10); >- checkInt(program, callFunction(program, "foo", [], [makeInt(program, 6)]), 10); >- checkInt(program, callFunction(program, "foo", [], [makeInt(program, 7)]), 8); >- checkInt(program, callFunction(program, "foo", [], [makeInt(program, 8)]), 10); >- checkInt(program, callFunction(program, "foo", [], [makeInt(program, 9)]), 10); >+ checkInt(program, callFunction(program, "foo", [makeInt(program, 3)]), 10); >+ checkInt(program, callFunction(program, "foo", [makeInt(program, 4)]), 10); >+ checkInt(program, callFunction(program, "foo", [makeInt(program, 5)]), 10); >+ checkInt(program, callFunction(program, "foo", [makeInt(program, 6)]), 10); >+ checkInt(program, callFunction(program, "foo", [makeInt(program, 7)]), 8); >+ checkInt(program, callFunction(program, "foo", [makeInt(program, 8)]), 10); >+ checkInt(program, callFunction(program, "foo", [makeInt(program, 9)]), 10); > checkFail( > () => doPrep(` > int foo(int x) >@@ -1419,13 +1081,13 @@ tests.returnIf = function() > return y; > } > `); >- checkInt(program, callFunction(program, "foo", [], [makeInt(program, 3)]), 9); >- checkInt(program, callFunction(program, "foo", [], [makeInt(program, 4)]), 9); >- checkInt(program, callFunction(program, "foo", [], [makeInt(program, 5)]), 9); >- checkInt(program, callFunction(program, "foo", [], [makeInt(program, 6)]), 9); >- checkInt(program, callFunction(program, "foo", [], [makeInt(program, 7)]), 8); >- checkInt(program, callFunction(program, "foo", [], [makeInt(program, 8)]), 9); >- checkInt(program, callFunction(program, "foo", [], [makeInt(program, 9)]), 9); >+ checkInt(program, callFunction(program, "foo", [makeInt(program, 3)]), 9); >+ checkInt(program, callFunction(program, "foo", [makeInt(program, 4)]), 9); >+ checkInt(program, callFunction(program, "foo", [makeInt(program, 5)]), 9); >+ checkInt(program, callFunction(program, "foo", [makeInt(program, 6)]), 9); >+ checkInt(program, callFunction(program, "foo", [makeInt(program, 7)]), 8); >+ checkInt(program, callFunction(program, "foo", [makeInt(program, 8)]), 9); >+ checkInt(program, callFunction(program, "foo", [makeInt(program, 9)]), 9); > checkFail( > () => doPrep(` > int foo(int x) >@@ -1449,7 +1111,7 @@ tests.returnIf = function() > return y; > } > `); >- checkInt(program, callFunction(program, "foo", [], [makeInt(program, 7)]), 6); >+ checkInt(program, callFunction(program, "foo", [makeInt(program, 7)]), 6); > } > > tests.simpleWhile = function() >@@ -1462,71 +1124,7 @@ tests.simpleWhile = function() > return x; > } > `); >- 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); } >- `); >+ checkInt(program, callFunction(program, "foo", [makeInt(program, 1)]), 16); > } > > tests.intOverloadResolution = function() >@@ -1537,7 +1135,7 @@ tests.intOverloadResolution = function() > int foo(float) { return 3; } > int bar() { return foo(42); } > `); >- checkInt(program, callFunction(program, "bar", [], []), 1); >+ checkInt(program, callFunction(program, "bar", []), 1); > } > > tests.intOverloadResolutionReverseOrder = function() >@@ -1548,83 +1146,7 @@ tests.intOverloadResolutionReverseOrder = function() > int foo(int) { return 1; } > int bar() { return foo(42); } > `); >- 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); >+ checkInt(program, callFunction(program, "bar", []), 1); > } > > tests.break = function() >@@ -1640,8 +1162,8 @@ tests.break = function() > return x; > } > `); >- checkInt(program, callFunction(program, "foo", [], [makeInt(program, 1)]), 8); >- checkInt(program, callFunction(program, "foo", [], [makeInt(program, 10)]), 20); >+ checkInt(program, callFunction(program, "foo", [makeInt(program, 1)]), 8); >+ checkInt(program, callFunction(program, "foo", [makeInt(program, 10)]), 20); > program = doPrep(` > int foo(int x) > { >@@ -1658,8 +1180,8 @@ tests.break = function() > > } > `); >- checkInt(program, callFunction(program, "foo", [], [makeInt(program, 1)]), 7); >- checkInt(program, callFunction(program, "foo", [], [makeInt(program, 10)]), 19); >+ checkInt(program, callFunction(program, "foo", [makeInt(program, 1)]), 7); >+ checkInt(program, callFunction(program, "foo", [makeInt(program, 10)]), 19); > checkFail( > () => doPrep(` > int foo(int x) >@@ -1695,7 +1217,7 @@ tests.break = function() > return x; > } > `); >- checkInt(program, callFunction(program, "foo", [], [makeInt(program, 1)]), 7); >+ checkInt(program, callFunction(program, "foo", [makeInt(program, 1)]), 7); > program = doPrep(` > int foo(int x) > { >@@ -1705,7 +1227,7 @@ tests.break = function() > return x; > } > `); >- checkInt(program, callFunction(program, "foo", [], [makeInt(program, 1)]), 1); >+ checkInt(program, callFunction(program, "foo", [makeInt(program, 1)]), 1); > program = doPrep(` > int foo() > { >@@ -1714,7 +1236,7 @@ tests.break = function() > } > } > `); >- checkInt(program, callFunction(program, "foo", [], []), 7); >+ checkInt(program, callFunction(program, "foo", []), 7); > checkFail( > () => doPrep(` > int foo(int x) >@@ -1743,7 +1265,7 @@ tests.continue = function() > return x; > } > `); >- checkInt(program, callFunction(program, "foo", [], [makeInt(program, 1)]), 18); >+ checkInt(program, callFunction(program, "foo", [makeInt(program, 1)]), 18); > checkFail( > () => doPrep(` > int foo(int x) >@@ -1769,8 +1291,8 @@ tests.doWhile = function() > return y; > } > `); >- checkInt(program, callFunction(program, "foo", [], [makeInt(program, 1)]), 8); >- checkInt(program, callFunction(program, "foo", [], [makeInt(program, 11)]), 8); >+ checkInt(program, callFunction(program, "foo", [makeInt(program, 1)]), 8); >+ checkInt(program, callFunction(program, "foo", [makeInt(program, 11)]), 8); > program = doPrep(` > int foo(int x) > { >@@ -1782,7 +1304,7 @@ tests.doWhile = function() > return y; > } > `); >- checkInt(program, callFunction(program, "foo", [], [makeInt(program, 1)]), 8); >+ checkInt(program, callFunction(program, "foo", [makeInt(program, 1)]), 8); > program = doPrep(` > int foo(int x) > { >@@ -1798,7 +1320,7 @@ tests.doWhile = function() > return sum; > } > `); >- checkInt(program, callFunction(program, "foo", [], [makeInt(program, 9)]), 19); >+ checkInt(program, callFunction(program, "foo", [makeInt(program, 9)]), 19); > } > > tests.forLoop = function() >@@ -1814,9 +1336,9 @@ tests.forLoop = function() > return sum; > } > `); >- checkInt(program, callFunction(program, "foo", [], [makeInt(program, 3)]), 3); >- checkInt(program, callFunction(program, "foo", [], [makeInt(program, 4)]), 6); >- checkInt(program, callFunction(program, "foo", [], [makeInt(program, 5)]), 10); >+ checkInt(program, callFunction(program, "foo", [makeInt(program, 3)]), 3); >+ checkInt(program, callFunction(program, "foo", [makeInt(program, 4)]), 6); >+ checkInt(program, callFunction(program, "foo", [makeInt(program, 5)]), 10); > program = doPrep(` > int foo(int x) > { >@@ -1827,9 +1349,9 @@ tests.forLoop = function() > return sum; > } > `); >- checkInt(program, callFunction(program, "foo", [], [makeInt(program, 3)]), 3); >- checkInt(program, callFunction(program, "foo", [], [makeInt(program, 4)]), 6); >- checkInt(program, callFunction(program, "foo", [], [makeInt(program, 5)]), 10); >+ checkInt(program, callFunction(program, "foo", [makeInt(program, 3)]), 3); >+ checkInt(program, callFunction(program, "foo", [makeInt(program, 4)]), 6); >+ checkInt(program, callFunction(program, "foo", [makeInt(program, 5)]), 10); > program = doPrep(` > int foo(int x) > { >@@ -1841,9 +1363,9 @@ tests.forLoop = function() > return sum; > } > `); >- checkInt(program, callFunction(program, "foo", [], [makeInt(program, 3)]), 3); >- checkInt(program, callFunction(program, "foo", [], [makeInt(program, 4)]), 6); >- checkInt(program, callFunction(program, "foo", [], [makeInt(program, 5)]), 10); >+ checkInt(program, callFunction(program, "foo", [makeInt(program, 3)]), 3); >+ checkInt(program, callFunction(program, "foo", [makeInt(program, 4)]), 6); >+ checkInt(program, callFunction(program, "foo", [makeInt(program, 5)]), 10); > program = doPrep(` > int foo(int x) > { >@@ -1856,10 +1378,10 @@ tests.forLoop = function() > return sum; > } > `); >- checkInt(program, callFunction(program, "foo", [], [makeInt(program, 3)]), 3); >- checkInt(program, callFunction(program, "foo", [], [makeInt(program, 4)]), 6); >- checkInt(program, callFunction(program, "foo", [], [makeInt(program, 5)]), 6); >- checkInt(program, callFunction(program, "foo", [], [makeInt(program, 6)]), 11); >+ checkInt(program, callFunction(program, "foo", [makeInt(program, 3)]), 3); >+ checkInt(program, callFunction(program, "foo", [makeInt(program, 4)]), 6); >+ checkInt(program, callFunction(program, "foo", [makeInt(program, 5)]), 6); >+ checkInt(program, callFunction(program, "foo", [makeInt(program, 6)]), 11); > program = doPrep(` > int foo(int x) > { >@@ -1872,11 +1394,11 @@ tests.forLoop = function() > return sum; > } > `); >- checkInt(program, callFunction(program, "foo", [], [makeInt(program, 3)]), 3); >- checkInt(program, callFunction(program, "foo", [], [makeInt(program, 4)]), 6); >- checkInt(program, callFunction(program, "foo", [], [makeInt(program, 5)]), 10); >- checkInt(program, callFunction(program, "foo", [], [makeInt(program, 6)]), 10); >- checkInt(program, callFunction(program, "foo", [], [makeInt(program, 7)]), 10); >+ checkInt(program, callFunction(program, "foo", [makeInt(program, 3)]), 3); >+ checkInt(program, callFunction(program, "foo", [makeInt(program, 4)]), 6); >+ checkInt(program, callFunction(program, "foo", [makeInt(program, 5)]), 10); >+ checkInt(program, callFunction(program, "foo", [makeInt(program, 6)]), 10); >+ checkInt(program, callFunction(program, "foo", [makeInt(program, 7)]), 10); > program = doPrep(` > int foo(int x) > { >@@ -1889,11 +1411,11 @@ tests.forLoop = function() > return sum; > } > `); >- checkInt(program, callFunction(program, "foo", [], [makeInt(program, 3)]), 3); >- checkInt(program, callFunction(program, "foo", [], [makeInt(program, 4)]), 6); >- checkInt(program, callFunction(program, "foo", [], [makeInt(program, 5)]), 10); >- checkInt(program, callFunction(program, "foo", [], [makeInt(program, 6)]), 15); >- checkInt(program, callFunction(program, "foo", [], [makeInt(program, 7)]), 21); >+ checkInt(program, callFunction(program, "foo", [makeInt(program, 3)]), 3); >+ checkInt(program, callFunction(program, "foo", [makeInt(program, 4)]), 6); >+ checkInt(program, callFunction(program, "foo", [makeInt(program, 5)]), 10); >+ checkInt(program, callFunction(program, "foo", [makeInt(program, 6)]), 15); >+ checkInt(program, callFunction(program, "foo", [makeInt(program, 7)]), 21); > program = doPrep(` > int foo(int x) > { >@@ -1907,11 +1429,11 @@ tests.forLoop = function() > return sum; > } > `); >- checkInt(program, callFunction(program, "foo", [], [makeInt(program, 3)]), 3); >- checkInt(program, callFunction(program, "foo", [], [makeInt(program, 4)]), 6); >- checkInt(program, callFunction(program, "foo", [], [makeInt(program, 5)]), 10); >- checkInt(program, callFunction(program, "foo", [], [makeInt(program, 6)]), 15); >- checkInt(program, callFunction(program, "foo", [], [makeInt(program, 7)]), 21); >+ checkInt(program, callFunction(program, "foo", [makeInt(program, 3)]), 3); >+ checkInt(program, callFunction(program, "foo", [makeInt(program, 4)]), 6); >+ checkInt(program, callFunction(program, "foo", [makeInt(program, 5)]), 10); >+ checkInt(program, callFunction(program, "foo", [makeInt(program, 6)]), 15); >+ checkInt(program, callFunction(program, "foo", [makeInt(program, 7)]), 21); > program = doPrep(` > int foo(int x) > { >@@ -1926,11 +1448,11 @@ tests.forLoop = function() > return sum; > } > `); >- checkInt(program, callFunction(program, "foo", [], [makeInt(program, 3)]), 3); >- checkInt(program, callFunction(program, "foo", [], [makeInt(program, 4)]), 6); >- checkInt(program, callFunction(program, "foo", [], [makeInt(program, 5)]), 10); >- checkInt(program, callFunction(program, "foo", [], [makeInt(program, 6)]), 15); >- checkInt(program, callFunction(program, "foo", [], [makeInt(program, 7)]), 21); >+ checkInt(program, callFunction(program, "foo", [makeInt(program, 3)]), 3); >+ checkInt(program, callFunction(program, "foo", [makeInt(program, 4)]), 6); >+ checkInt(program, callFunction(program, "foo", [makeInt(program, 5)]), 10); >+ checkInt(program, callFunction(program, "foo", [makeInt(program, 6)]), 15); >+ checkInt(program, callFunction(program, "foo", [makeInt(program, 7)]), 21); > checkFail( > () => doPrep(` > void foo(int x) >@@ -1950,11 +1472,11 @@ tests.forLoop = function() > } > } > `); >- checkInt(program, callFunction(program, "foo", [], [makeInt(program, 3)]), 7); >- checkInt(program, callFunction(program, "foo", [], [makeInt(program, 4)]), 7); >- checkInt(program, callFunction(program, "foo", [], [makeInt(program, 5)]), 7); >- checkInt(program, callFunction(program, "foo", [], [makeInt(program, 6)]), 7); >- checkInt(program, callFunction(program, "foo", [], [makeInt(program, 7)]), 7); >+ checkInt(program, callFunction(program, "foo", [makeInt(program, 3)]), 7); >+ checkInt(program, callFunction(program, "foo", [makeInt(program, 4)]), 7); >+ checkInt(program, callFunction(program, "foo", [makeInt(program, 5)]), 7); >+ checkInt(program, callFunction(program, "foo", [makeInt(program, 6)]), 7); >+ checkInt(program, callFunction(program, "foo", [makeInt(program, 7)]), 7); > checkFail( > () => doPrep(` > int foo(int x) >@@ -1973,229 +1495,11 @@ tests.forLoop = function() > } > } > `); >- checkInt(program, callFunction(program, "foo", [], [makeInt(program, 3)]), 7); >- checkInt(program, callFunction(program, "foo", [], [makeInt(program, 4)]), 7); >- checkInt(program, callFunction(program, "foo", [], [makeInt(program, 5)]), 7); >- checkInt(program, callFunction(program, "foo", [], [makeInt(program, 6)]), 7); >- checkInt(program, callFunction(program, "foo", [], [makeInt(program, 7)]), 7); >-} >- >-tests.chainConstexpr = function() >-{ >- let program = doPrep(` >- int foo<int a>(int b) >- { >- return a + b; >- } >- int bar<int a>(int b) >- { >- return foo<a>(b); >- } >- int baz(int b) >- { >- return bar<42>(b); >- } >- `); >- checkInt(program, callFunction(program, "baz", [], [makeInt(program, 58)]), 58 + 42); >-} >- >-tests.chainGeneric = function() >-{ >- let program = doPrep(` >- T foo<T>(T x) >- { >- return x; >- } >- T bar<T>(thread T* ptr) >- { >- return *foo(ptr); >- } >- int baz(int x) >- { >- return bar(&x); >- } >- `); >- checkInt(program, callFunction(program, "baz", [], [makeInt(program, 37)]), 37); >-} >- >-tests.chainStruct = function() >-{ >- let program = doPrep(` >- struct Foo<T> { >- T f; >- } >- struct Bar<T> { >- Foo<thread T*> f; >- } >- int foo(thread Bar<int>* x) >- { >- return *x->f.f; >- } >- int bar(int a) >- { >- Bar<int> x; >- x.f.f = &a; >- return foo(&x); >- } >- `); >- checkInt(program, callFunction(program, "bar", [], [makeInt(program, 4657)]), 4657); >-} >- >-tests.chainStructNewlyValid = function() >-{ >- let program = doPrep(` >- struct Foo<T> { >- T f; >- } >- struct Bar<T> { >- Foo<device T*> f; >- } >- int foo(thread Bar<int>* x) >- { >- return *x->f.f; >- } >- int bar(device int* a) >- { >- Bar<int> x; >- x.f.f = a; >- return foo(&x); >- } >- `); >- let buffer = new EBuffer(1); >- buffer.set(0, 78453); >- checkInt(program, callFunction(program, "bar", [], [TypedValue.box(new PtrType(externalOrigin, "device", program.intrinsics.int32), new EPtr(buffer, 0))]), 78453); >-} >- >-tests.chainStructDevice = function() >-{ >- let program = doPrep(` >- struct Foo<T> { >- T f; >- } >- struct Bar<T> { >- Foo<device T*> f; >- } >- int foo(thread Bar<int>* x) >- { >- return *x->f.f; >- } >- int bar(device int* a) >- { >- Bar<int> x; >- x.f.f = a; >- return foo(&x); >- } >- `); >- let buffer = new EBuffer(1); >- buffer.set(0, 79201); >- checkInt(program, callFunction(program, "bar", [], [TypedValue.box(new PtrType(externalOrigin, "device", program.intrinsics.int32), new EPtr(buffer, 0))]), 79201); >-} >- >-tests.paramChainStructDevice = function() >-{ >- let program = doPrep(` >- struct Foo<T> { >- T f; >- } >- struct Bar<T> { >- Foo<T> f; >- } >- int foo(thread Bar<device int*>* x) >- { >- return *x->f.f; >- } >- int bar(device int* a) >- { >- Bar<device int*> x; >- x.f.f = a; >- return foo(&x); >- } >- `); >- let buffer = new EBuffer(1); >- buffer.set(0, 79201); >- checkInt(program, callFunction(program, "bar", [], [TypedValue.box(new PtrType(externalOrigin, "device", program.intrinsics.int32), new EPtr(buffer, 0))]), 79201); >-} >- >-tests.simpleProtocolExtends = function() >-{ >- let program = doPrep(` >- protocol Foo { >- void foo(thread Foo*); >- } >- protocol Bar : Foo { >- void bar(thread Bar*); >- } >- void fuzz<T:Foo>(thread T* p) >- { >- foo(p); >- } >- void buzz<T:Bar>(thread T* p) >- { >- fuzz(p); >- bar(p); >- } >- void foo(thread int* p) >- { >- *p = *p + 743; >- } >- void bar(thread int* p) >- { >- *p = *p + 91; >- } >- int thingy(int a) >- { >- buzz(&a); >- return a; >- } >- `); >- checkInt(program, callFunction(program, "thingy", [], [makeInt(program, 642)]), 642 + 743 + 91); >-} >- >-tests.protocolExtendsTwo = function() >-{ >- let program = doPrep(` >- protocol Foo { >- void foo(thread Foo*); >- } >- protocol Bar { >- void bar(thread Bar*); >- } >- protocol Baz : Foo, Bar { >- void baz(thread Baz*); >- } >- void fuzz<T:Foo>(thread T* p) >- { >- foo(p); >- } >- void buzz<T:Bar>(thread T* p) >- { >- bar(p); >- } >- void xuzz<T:Baz>(thread T* p) >- { >- fuzz(p); >- buzz(p); >- baz(p); >- } >- void foo(thread int* p) >- { >- *p = *p + 743; >- } >- void bar(thread int* p) >- { >- *p = *p + 91; >- } >- void baz(thread int* p) >- { >- *p = *p + 39; >- } >- int thingy(int a) >- { >- xuzz(&a); >- return a; >- } >- `); >- checkInt(program, callFunction(program, "thingy", [], [makeInt(program, 642)]), 642 + 743 + 91 + 39); >+ checkInt(program, callFunction(program, "foo", [makeInt(program, 3)]), 7); >+ checkInt(program, callFunction(program, "foo", [makeInt(program, 4)]), 7); >+ checkInt(program, callFunction(program, "foo", [makeInt(program, 5)]), 7); >+ checkInt(program, callFunction(program, "foo", [makeInt(program, 6)]), 7); >+ checkInt(program, callFunction(program, "foo", [makeInt(program, 7)]), 7); > } > > tests.prefixPlusPlus = function() >@@ -2207,7 +1511,7 @@ tests.prefixPlusPlus = function() > return x; > } > `); >- checkInt(program, callFunction(program, "foo", [], [makeInt(program, 64)]), 65); >+ checkInt(program, callFunction(program, "foo", [makeInt(program, 64)]), 65); > } > > tests.prefixPlusPlusResult = function() >@@ -2218,7 +1522,7 @@ tests.prefixPlusPlusResult = function() > return ++x; > } > `); >- checkInt(program, callFunction(program, "foo", [], [makeInt(program, 64)]), 65); >+ checkInt(program, callFunction(program, "foo", [makeInt(program, 64)]), 65); > } > > tests.postfixPlusPlus = function() >@@ -2230,7 +1534,7 @@ tests.postfixPlusPlus = function() > return x; > } > `); >- checkInt(program, callFunction(program, "foo", [], [makeInt(program, 64)]), 65); >+ checkInt(program, callFunction(program, "foo", [makeInt(program, 64)]), 65); > } > > tests.postfixPlusPlusResult = function() >@@ -2241,7 +1545,7 @@ tests.postfixPlusPlusResult = function() > return x++; > } > `); >- checkInt(program, callFunction(program, "foo", [], [makeInt(program, 64)]), 64); >+ checkInt(program, callFunction(program, "foo", [makeInt(program, 64)]), 64); > } > > tests.prefixMinusMinus = function() >@@ -2253,7 +1557,7 @@ tests.prefixMinusMinus = function() > return x; > } > `); >- checkInt(program, callFunction(program, "foo", [], [makeInt(program, 64)]), 63); >+ checkInt(program, callFunction(program, "foo", [makeInt(program, 64)]), 63); > } > > tests.prefixMinusMinusResult = function() >@@ -2264,7 +1568,7 @@ tests.prefixMinusMinusResult = function() > return --x; > } > `); >- checkInt(program, callFunction(program, "foo", [], [makeInt(program, 64)]), 63); >+ checkInt(program, callFunction(program, "foo", [makeInt(program, 64)]), 63); > } > > tests.postfixMinusMinus = function() >@@ -2276,7 +1580,7 @@ tests.postfixMinusMinus = function() > return x; > } > `); >- checkInt(program, callFunction(program, "foo", [], [makeInt(program, 64)]), 63); >+ checkInt(program, callFunction(program, "foo", [makeInt(program, 64)]), 63); > } > > tests.postfixMinusMinusResult = function() >@@ -2287,7 +1591,7 @@ tests.postfixMinusMinusResult = function() > return x--; > } > `); >- checkInt(program, callFunction(program, "foo", [], [makeInt(program, 64)]), 64); >+ checkInt(program, callFunction(program, "foo", [makeInt(program, 64)]), 64); > } > > tests.plusEquals = function() >@@ -2299,7 +1603,7 @@ tests.plusEquals = function() > return x; > } > `); >- checkInt(program, callFunction(program, "foo", [], [makeInt(program, 385)]), 385 + 42); >+ checkInt(program, callFunction(program, "foo", [makeInt(program, 385)]), 385 + 42); > } > > tests.plusEqualsResult = function() >@@ -2310,7 +1614,7 @@ tests.plusEqualsResult = function() > return x += 42; > } > `); >- checkInt(program, callFunction(program, "foo", [], [makeInt(program, 385)]), 385 + 42); >+ checkInt(program, callFunction(program, "foo", [makeInt(program, 385)]), 385 + 42); > } > > tests.minusEquals = function() >@@ -2322,7 +1626,7 @@ tests.minusEquals = function() > return x; > } > `); >- checkInt(program, callFunction(program, "foo", [], [makeInt(program, 385)]), 385 - 42); >+ checkInt(program, callFunction(program, "foo", [makeInt(program, 385)]), 385 - 42); > } > > tests.minusEqualsResult = function() >@@ -2333,7 +1637,7 @@ tests.minusEqualsResult = function() > return x -= 42; > } > `); >- checkInt(program, callFunction(program, "foo", [], [makeInt(program, 385)]), 385 - 42); >+ checkInt(program, callFunction(program, "foo", [makeInt(program, 385)]), 385 - 42); > } > > tests.timesEquals = function() >@@ -2345,7 +1649,7 @@ tests.timesEquals = function() > return x; > } > `); >- checkInt(program, callFunction(program, "foo", [], [makeInt(program, 385)]), 385 * 42); >+ checkInt(program, callFunction(program, "foo", [makeInt(program, 385)]), 385 * 42); > } > > tests.timesEqualsResult = function() >@@ -2356,7 +1660,7 @@ tests.timesEqualsResult = function() > return x *= 42; > } > `); >- checkInt(program, callFunction(program, "foo", [], [makeInt(program, 385)]), 385 * 42); >+ checkInt(program, callFunction(program, "foo", [makeInt(program, 385)]), 385 * 42); > } > > tests.divideEquals = function() >@@ -2368,7 +1672,7 @@ tests.divideEquals = function() > return x; > } > `); >- checkInt(program, callFunction(program, "foo", [], [makeInt(program, 385)]), (385 / 42) | 0); >+ checkInt(program, callFunction(program, "foo", [makeInt(program, 385)]), (385 / 42) | 0); > } > > tests.divideEqualsResult = function() >@@ -2379,7 +1683,7 @@ tests.divideEqualsResult = function() > return x /= 42; > } > `); >- checkInt(program, callFunction(program, "foo", [], [makeInt(program, 385)]), (385 / 42) | 0); >+ checkInt(program, callFunction(program, "foo", [makeInt(program, 385)]), (385 / 42) | 0); > } > > tests.twoIntLiterals = function() >@@ -2390,67 +1694,7 @@ tests.twoIntLiterals = function() > return 42 == 42; > } > `); >- 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); >+ checkBool(program, callFunction(program, "foo", []), true); > } > > tests.assignUintToInt = function() >@@ -2479,7 +1723,7 @@ tests.buildArrayThenSumIt = function() > return result; > } > `); >- checkInt(program, callFunction(program, "foo", [], []), 42 * 5 + 42 * 41 / 2); >+ checkInt(program, callFunction(program, "foo", []), 42 * 5 + 42 * 41 / 2); > } > > tests.buildArrayThenSumItUsingArrayReference = function() >@@ -2500,7 +1744,7 @@ tests.buildArrayThenSumItUsingArrayReference = function() > return bar(@array); > } > `); >- checkInt(program, callFunction(program, "foo", [], []), 42 * 5 + 42 * 41 / 2); >+ checkInt(program, callFunction(program, "foo", []), 42 * 5 + 42 * 41 / 2); > } > > tests.overrideSubscriptStruct = function() >@@ -2526,7 +1770,7 @@ tests.overrideSubscriptStruct = function() > return foo[0] + foo[1] * 3; > } > `); >- checkInt(program, callFunction(program, "foo", [], []), 498 + 19 * 3); >+ checkInt(program, callFunction(program, "foo", []), 498 + 19 * 3); > } > > tests.overrideSubscriptStructAndDoStores = function() >@@ -2552,7 +1796,7 @@ tests.overrideSubscriptStructAndDoStores = function() > return foo.x + foo.y; > } > `); >- checkInt(program, callFunction(program, "foo", [], []), 498 + 19); >+ checkInt(program, callFunction(program, "foo", []), 498 + 19); > } > > tests.overrideSubscriptStructAndUsePointers = function() >@@ -2582,7 +1826,7 @@ tests.overrideSubscriptStructAndUsePointers = function() > return bar(&foo); > } > `); >- checkInt(program, callFunction(program, "foo", [], []), 498 + 19); >+ checkInt(program, callFunction(program, "foo", []), 498 + 19); > } > > tests.overrideSubscriptStructAndUsePointersIncorrectly = function() >@@ -2629,7 +1873,7 @@ tests.makeArrayRefFromLocal = function() > return bar(@x); > } > `); >- checkInt(program, callFunction(program, "foo", [], []), 48); >+ checkInt(program, callFunction(program, "foo", []), 48); > } > > tests.makeArrayRefFromPointer = function() >@@ -2649,7 +1893,7 @@ tests.makeArrayRefFromPointer = function() > return baz(&x); > } > `); >- checkInt(program, callFunction(program, "foo", [], []), 48); >+ checkInt(program, callFunction(program, "foo", []), 48); > } > > tests.makeArrayRefFromArrayRef = function() >@@ -2682,7 +1926,7 @@ tests.simpleLength = function() > return (@array).length; > } > `); >- checkUint(program, callFunction(program, "foo", [], []), 754); >+ checkUint(program, callFunction(program, "foo", []), 754); > } > > tests.nonArrayRefArrayLengthSucceed = function() >@@ -2693,8 +1937,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, "foo", []), 754); >+ checkUint(program, callFunction(program, "bar", []), 754); > } > > tests.nonArrayRefArrayLengthFail = function() >@@ -2710,42 +1960,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 +1970,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 +1987,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() >@@ -2793,7 +2007,7 @@ tests.simpleGetter = function() > return foo.y; > } > `); >- checkInt(program, callFunction(program, "foo", [], []), 7804); >+ checkInt(program, callFunction(program, "foo", []), 7804); > } > > tests.simpleSetter = function() >@@ -2818,236 +2032,7 @@ tests.simpleSetter = function() > return foo.x; > } > `); >- 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); >+ checkInt(program, callFunction(program, "foo", []), 7804); > } > > tests.nestedSubscriptLValueEmulationSimple = function() >@@ -3150,119 +2135,93 @@ tests.nestedSubscriptLValueEmulationSimple = function() > return sum(baz); > } > `); >- checkInt(program, callFunction(program, "testSetValuesAndSum", [], []), 1575); >- checkInt(program, callFunction(program, "testSetValuesMutateValuesAndSum", [], []), 5565); >+ checkInt(program, callFunction(program, "testSetValuesAndSum", []), 1575); >+ checkInt(program, callFunction(program, "testSetValuesMutateValuesAndSum", []), 5565); > } > >-tests.nestedSubscriptLValueEmulationGeneric = function() >+tests.operatorBool = 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() >+ bool boolFromUcharFalse() { return bool(uchar(0)); } >+ bool boolFromUcharTrue() { return bool(uchar(1)); } >+ >+ bool boolFromUintFalse() { return bool(uint(0)); } >+ bool boolFromUintTrue() { return bool(uint(1)); } >+ >+ bool boolFromIntFalse() { return bool(int(0)); } >+ bool boolFromIntTrue() { return bool(int(1)); } >+ >+ bool boolFromFloatFalse() { return bool(float(0)); } >+ bool boolFromFloatTrue() { return bool(float(1)); } >+ >+ bool boolFromInt2False() { return bool(int2(0, 0)); } >+ bool boolFromInt2True1() { return bool(int2(1, 0)); } >+ bool boolFromInt2True2() { return bool(int2(0, 1)); } >+ >+ bool boolFromFloat3False() { return bool(float3(0, 0, 0)); } >+ bool boolFromFloat3True1() { return bool(float3(1, 0, 0)); } >+ bool boolFromFloat3True2() { return bool(float3(0, 1, 0)); } >+ bool boolFromFloat3True3() { return bool(float3(0, 0, 1)); } >+ >+ bool boolFromUint4False() { return bool(uint4(0, 0, 0, 0)); } >+ bool boolFromUint4True1() { return bool(uint4(1, 0, 0, 0)); } >+ bool boolFromUint4True2() { return bool(uint4(0, 1, 0, 0)); } >+ bool boolFromUint4True3() { return bool(uint4(0, 0, 1, 0)); } >+ bool boolFromUint4True4() { return bool(uint4(0, 0, 0, 1)); } >+ >+ struct X { int x; } >+ >+ bool boolFromStructFalse() > { >- Baz<int> baz; >- setValues(&baz); >- return sum(baz); >+ X x; >+ return bool(x); > } >- int testSetValuesMutateValuesAndSum() >+ >+ bool boolFromStructTrue() > { >- 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); >+ X x; >+ x.x = 1; >+ return bool(x); > } >+ >+ enum Y { A, B } >+ >+ bool boolFromEnumFalse() { return bool(Y.A); } >+ bool boolFromEnumTrue() { return bool(Y.B); } > `); >- checkInt(program, callFunction(program, "testSetValuesAndSum", [], []), 1575); >- checkInt(program, callFunction(program, "testSetValuesMutateValuesAndSum", [], []), 5565); >+ >+ checkBool(program, callFunction(program, "boolFromUcharFalse", []), false); >+ checkBool(program, callFunction(program, "boolFromUcharTrue", []), true); >+ >+ checkBool(program, callFunction(program, "boolFromUintFalse", []), false); >+ checkBool(program, callFunction(program, "boolFromUintTrue", []), true); >+ >+ checkBool(program, callFunction(program, "boolFromIntFalse", []), false); >+ checkBool(program, callFunction(program, "boolFromIntTrue", []), true); >+ >+ checkBool(program, callFunction(program, "boolFromFloatFalse", []), false); >+ checkBool(program, callFunction(program, "boolFromFloatTrue", []), true); >+ >+ checkBool(program, callFunction(program, "boolFromInt2False", []), false); >+ checkBool(program, callFunction(program, "boolFromInt2True1", []), true); >+ checkBool(program, callFunction(program, "boolFromInt2True2", []), true); >+ >+ checkBool(program, callFunction(program, "boolFromFloat3False", []), false); >+ checkBool(program, callFunction(program, "boolFromFloat3True1", []), true); >+ checkBool(program, callFunction(program, "boolFromFloat3True2", []), true); >+ checkBool(program, callFunction(program, "boolFromFloat3True3", []), true); >+ >+ checkBool(program, callFunction(program, "boolFromUint4False", []), false); >+ checkBool(program, callFunction(program, "boolFromUint4True1", []), true); >+ checkBool(program, callFunction(program, "boolFromUint4True2", []), true); >+ checkBool(program, callFunction(program, "boolFromUint4True3", []), true); >+ checkBool(program, callFunction(program, "boolFromUint4True4", []), true); >+ >+ checkBool(program, callFunction(program, "boolFromStructFalse", []), false); >+ checkBool(program, callFunction(program, "boolFromStructTrue", []), true); >+ >+ checkBool(program, callFunction(program, "boolFromEnumFalse", []), false); >+ checkBool(program, callFunction(program, "boolFromEnumTrue", []), true); > } > > tests.boolBitAnd = function() >@@ -3273,10 +2232,10 @@ tests.boolBitAnd = function() > return a & b; > } > `); >- checkBool(program, callFunction(program, "foo", [], [makeBool(program, false), makeBool(program, false)]), false); >- checkBool(program, callFunction(program, "foo", [], [makeBool(program, true), makeBool(program, false)]), false); >- checkBool(program, callFunction(program, "foo", [], [makeBool(program, false), makeBool(program, true)]), false); >- checkBool(program, callFunction(program, "foo", [], [makeBool(program, true), makeBool(program, true)]), true); >+ checkBool(program, callFunction(program, "foo", [makeBool(program, false), makeBool(program, false)]), false); >+ checkBool(program, callFunction(program, "foo", [makeBool(program, true), makeBool(program, false)]), false); >+ checkBool(program, callFunction(program, "foo", [makeBool(program, false), makeBool(program, true)]), false); >+ checkBool(program, callFunction(program, "foo", [makeBool(program, true), makeBool(program, true)]), true); > } > > tests.boolBitOr = function() >@@ -3287,10 +2246,10 @@ tests.boolBitOr = function() > return a | b; > } > `); >- checkBool(program, callFunction(program, "foo", [], [makeBool(program, false), makeBool(program, false)]), false); >- checkBool(program, callFunction(program, "foo", [], [makeBool(program, true), makeBool(program, false)]), true); >- checkBool(program, callFunction(program, "foo", [], [makeBool(program, false), makeBool(program, true)]), true); >- checkBool(program, callFunction(program, "foo", [], [makeBool(program, true), makeBool(program, true)]), true); >+ checkBool(program, callFunction(program, "foo", [makeBool(program, false), makeBool(program, false)]), false); >+ checkBool(program, callFunction(program, "foo", [makeBool(program, true), makeBool(program, false)]), true); >+ checkBool(program, callFunction(program, "foo", [makeBool(program, false), makeBool(program, true)]), true); >+ checkBool(program, callFunction(program, "foo", [makeBool(program, true), makeBool(program, true)]), true); > } > > tests.boolBitXor = function() >@@ -3301,10 +2260,10 @@ tests.boolBitXor = function() > return a ^ b; > } > `); >- checkBool(program, callFunction(program, "foo", [], [makeBool(program, false), makeBool(program, false)]), false); >- checkBool(program, callFunction(program, "foo", [], [makeBool(program, true), makeBool(program, false)]), true); >- checkBool(program, callFunction(program, "foo", [], [makeBool(program, false), makeBool(program, true)]), true); >- checkBool(program, callFunction(program, "foo", [], [makeBool(program, true), makeBool(program, true)]), false); >+ checkBool(program, callFunction(program, "foo", [makeBool(program, false), makeBool(program, false)]), false); >+ checkBool(program, callFunction(program, "foo", [makeBool(program, true), makeBool(program, false)]), true); >+ checkBool(program, callFunction(program, "foo", [makeBool(program, false), makeBool(program, true)]), true); >+ checkBool(program, callFunction(program, "foo", [makeBool(program, true), makeBool(program, true)]), false); > } > > tests.boolBitNot = function() >@@ -3315,8 +2274,8 @@ tests.boolBitNot = function() > return ~a; > } > `); >- checkBool(program, callFunction(program, "foo", [], [makeBool(program, false)]), true); >- checkBool(program, callFunction(program, "foo", [], [makeBool(program, true)]), false); >+ checkBool(program, callFunction(program, "foo", [makeBool(program, false)]), true); >+ checkBool(program, callFunction(program, "foo", [makeBool(program, true)]), false); > } > > tests.intBitAnd = function() >@@ -3327,10 +2286,10 @@ tests.intBitAnd = function() > return a & b; > } > `); >- checkInt(program, callFunction(program, "foo", [], [makeInt(program, 1), makeInt(program, 7)]), 1); >- checkInt(program, callFunction(program, "foo", [], [makeInt(program, 65535), makeInt(program, 42)]), 42); >- checkInt(program, callFunction(program, "foo", [], [makeInt(program, -1), makeInt(program, -7)]), -7); >- checkInt(program, callFunction(program, "foo", [], [makeInt(program, 0), makeInt(program, 85732)]), 0); >+ checkInt(program, callFunction(program, "foo", [makeInt(program, 1), makeInt(program, 7)]), 1); >+ checkInt(program, callFunction(program, "foo", [makeInt(program, 65535), makeInt(program, 42)]), 42); >+ checkInt(program, callFunction(program, "foo", [makeInt(program, -1), makeInt(program, -7)]), -7); >+ checkInt(program, callFunction(program, "foo", [makeInt(program, 0), makeInt(program, 85732)]), 0); > } > > tests.intBitOr = function() >@@ -3341,10 +2300,10 @@ tests.intBitOr = function() > return a | b; > } > `); >- checkInt(program, callFunction(program, "foo", [], [makeInt(program, 1), makeInt(program, 7)]), 7); >- checkInt(program, callFunction(program, "foo", [], [makeInt(program, 65535), makeInt(program, 42)]), 65535); >- checkInt(program, callFunction(program, "foo", [], [makeInt(program, -1), makeInt(program, -7)]), -1); >- checkInt(program, callFunction(program, "foo", [], [makeInt(program, 0), makeInt(program, 85732)]), 85732); >+ checkInt(program, callFunction(program, "foo", [makeInt(program, 1), makeInt(program, 7)]), 7); >+ checkInt(program, callFunction(program, "foo", [makeInt(program, 65535), makeInt(program, 42)]), 65535); >+ checkInt(program, callFunction(program, "foo", [makeInt(program, -1), makeInt(program, -7)]), -1); >+ checkInt(program, callFunction(program, "foo", [makeInt(program, 0), makeInt(program, 85732)]), 85732); > } > > tests.intBitXor = function() >@@ -3355,10 +2314,10 @@ tests.intBitXor = function() > return a ^ b; > } > `); >- checkInt(program, callFunction(program, "foo", [], [makeInt(program, 1), makeInt(program, 7)]), 6); >- checkInt(program, callFunction(program, "foo", [], [makeInt(program, 65535), makeInt(program, 42)]), 65493); >- checkInt(program, callFunction(program, "foo", [], [makeInt(program, -1), makeInt(program, -7)]), 6); >- checkInt(program, callFunction(program, "foo", [], [makeInt(program, 0), makeInt(program, 85732)]), 85732); >+ checkInt(program, callFunction(program, "foo", [makeInt(program, 1), makeInt(program, 7)]), 6); >+ checkInt(program, callFunction(program, "foo", [makeInt(program, 65535), makeInt(program, 42)]), 65493); >+ checkInt(program, callFunction(program, "foo", [makeInt(program, -1), makeInt(program, -7)]), 6); >+ checkInt(program, callFunction(program, "foo", [makeInt(program, 0), makeInt(program, 85732)]), 85732); > } > > tests.intBitNot = function() >@@ -3369,10 +2328,10 @@ tests.intBitNot = function() > return ~a; > } > `); >- checkInt(program, callFunction(program, "foo", [], [makeInt(program, 1)]), -2); >- checkInt(program, callFunction(program, "foo", [], [makeInt(program, 65535)]), -65536); >- checkInt(program, callFunction(program, "foo", [], [makeInt(program, -1)]), 0); >- checkInt(program, callFunction(program, "foo", [], [makeInt(program, 0)]), -1); >+ checkInt(program, callFunction(program, "foo", [makeInt(program, 1)]), -2); >+ checkInt(program, callFunction(program, "foo", [makeInt(program, 65535)]), -65536); >+ checkInt(program, callFunction(program, "foo", [makeInt(program, -1)]), 0); >+ checkInt(program, callFunction(program, "foo", [makeInt(program, 0)]), -1); > } > > tests.intLShift = function() >@@ -3383,10 +2342,10 @@ tests.intLShift = function() > return a << b; > } > `); >- checkInt(program, callFunction(program, "foo", [], [makeInt(program, 1), makeUint(program, 7)]), 128); >- checkInt(program, callFunction(program, "foo", [], [makeInt(program, 65535), makeUint(program, 2)]), 262140); >- checkInt(program, callFunction(program, "foo", [], [makeInt(program, -1), makeUint(program, 5)]), -32); >- checkInt(program, callFunction(program, "foo", [], [makeInt(program, 0), makeUint(program, 3)]), 0); >+ checkInt(program, callFunction(program, "foo", [makeInt(program, 1), makeUint(program, 7)]), 128); >+ checkInt(program, callFunction(program, "foo", [makeInt(program, 65535), makeUint(program, 2)]), 262140); >+ checkInt(program, callFunction(program, "foo", [makeInt(program, -1), makeUint(program, 5)]), -32); >+ checkInt(program, callFunction(program, "foo", [makeInt(program, 0), makeUint(program, 3)]), 0); > } > > tests.intRShift = function() >@@ -3397,10 +2356,10 @@ tests.intRShift = function() > return a >> b; > } > `); >- checkInt(program, callFunction(program, "foo", [], [makeInt(program, 1), makeUint(program, 7)]), 0); >- checkInt(program, callFunction(program, "foo", [], [makeInt(program, 65535), makeUint(program, 2)]), 16383); >- checkInt(program, callFunction(program, "foo", [], [makeInt(program, -1), makeUint(program, 5)]), -1); >- checkInt(program, callFunction(program, "foo", [], [makeInt(program, 0), makeUint(program, 3)]), 0); >+ checkInt(program, callFunction(program, "foo", [makeInt(program, 1), makeUint(program, 7)]), 0); >+ checkInt(program, callFunction(program, "foo", [makeInt(program, 65535), makeUint(program, 2)]), 16383); >+ checkInt(program, callFunction(program, "foo", [makeInt(program, -1), makeUint(program, 5)]), -1); >+ checkInt(program, callFunction(program, "foo", [makeInt(program, 0), makeUint(program, 3)]), 0); > } > > tests.uintBitAnd = function() >@@ -3411,10 +2370,10 @@ tests.uintBitAnd = function() > return a & b; > } > `); >- checkUint(program, callFunction(program, "foo", [], [makeUint(program, 1), makeUint(program, 7)]), 1); >- checkUint(program, callFunction(program, "foo", [], [makeUint(program, 65535), makeUint(program, 42)]), 42); >- checkUint(program, callFunction(program, "foo", [], [makeUint(program, -1), makeUint(program, -7)]), 4294967289); >- checkUint(program, callFunction(program, "foo", [], [makeUint(program, 0), makeUint(program, 85732)]), 0); >+ checkUint(program, callFunction(program, "foo", [makeUint(program, 1), makeUint(program, 7)]), 1); >+ checkUint(program, callFunction(program, "foo", [makeUint(program, 65535), makeUint(program, 42)]), 42); >+ checkUint(program, callFunction(program, "foo", [makeUint(program, -1), makeUint(program, -7)]), 4294967289); >+ checkUint(program, callFunction(program, "foo", [makeUint(program, 0), makeUint(program, 85732)]), 0); > } > > tests.uintBitOr = function() >@@ -3425,10 +2384,10 @@ tests.uintBitOr = function() > return a | b; > } > `); >- checkUint(program, callFunction(program, "foo", [], [makeUint(program, 1), makeUint(program, 7)]), 7); >- checkUint(program, callFunction(program, "foo", [], [makeUint(program, 65535), makeUint(program, 42)]), 65535); >- checkUint(program, callFunction(program, "foo", [], [makeUint(program, -1), makeUint(program, -7)]), 4294967295); >- checkUint(program, callFunction(program, "foo", [], [makeUint(program, 0), makeUint(program, 85732)]), 85732); >+ checkUint(program, callFunction(program, "foo", [makeUint(program, 1), makeUint(program, 7)]), 7); >+ checkUint(program, callFunction(program, "foo", [makeUint(program, 65535), makeUint(program, 42)]), 65535); >+ checkUint(program, callFunction(program, "foo", [makeUint(program, -1), makeUint(program, -7)]), 4294967295); >+ checkUint(program, callFunction(program, "foo", [makeUint(program, 0), makeUint(program, 85732)]), 85732); > } > > tests.uintBitXor = function() >@@ -3439,10 +2398,10 @@ tests.uintBitXor = function() > return a ^ b; > } > `); >- checkUint(program, callFunction(program, "foo", [], [makeUint(program, 1), makeUint(program, 7)]), 6); >- checkUint(program, callFunction(program, "foo", [], [makeUint(program, 65535), makeUint(program, 42)]), 65493); >- checkUint(program, callFunction(program, "foo", [], [makeUint(program, -1), makeUint(program, -7)]), 6); >- checkUint(program, callFunction(program, "foo", [], [makeUint(program, 0), makeUint(program, 85732)]), 85732); >+ checkUint(program, callFunction(program, "foo", [makeUint(program, 1), makeUint(program, 7)]), 6); >+ checkUint(program, callFunction(program, "foo", [makeUint(program, 65535), makeUint(program, 42)]), 65493); >+ checkUint(program, callFunction(program, "foo", [makeUint(program, -1), makeUint(program, -7)]), 6); >+ checkUint(program, callFunction(program, "foo", [makeUint(program, 0), makeUint(program, 85732)]), 85732); > } > > tests.uintBitNot = function() >@@ -3453,10 +2412,10 @@ tests.uintBitNot = function() > return ~a; > } > `); >- checkUint(program, callFunction(program, "foo", [], [makeUint(program, 1)]), 4294967294); >- checkUint(program, callFunction(program, "foo", [], [makeUint(program, 65535)]), 4294901760); >- checkUint(program, callFunction(program, "foo", [], [makeUint(program, -1)]), 0); >- checkUint(program, callFunction(program, "foo", [], [makeUint(program, 0)]), 4294967295); >+ checkUint(program, callFunction(program, "foo", [makeUint(program, 1)]), 4294967294); >+ checkUint(program, callFunction(program, "foo", [makeUint(program, 65535)]), 4294901760); >+ checkUint(program, callFunction(program, "foo", [makeUint(program, -1)]), 0); >+ checkUint(program, callFunction(program, "foo", [makeUint(program, 0)]), 4294967295); > } > > tests.uintLShift = function() >@@ -3467,10 +2426,10 @@ tests.uintLShift = function() > return a << b; > } > `); >- checkUint(program, callFunction(program, "foo", [], [makeUint(program, 1), makeUint(program, 7)]), 128); >- checkUint(program, callFunction(program, "foo", [], [makeUint(program, 65535), makeUint(program, 2)]), 262140); >- checkUint(program, callFunction(program, "foo", [], [makeUint(program, -1), makeUint(program, 5)]), 4294967264); >- checkUint(program, callFunction(program, "foo", [], [makeUint(program, 0), makeUint(program, 3)]), 0); >+ checkUint(program, callFunction(program, "foo", [makeUint(program, 1), makeUint(program, 7)]), 128); >+ checkUint(program, callFunction(program, "foo", [makeUint(program, 65535), makeUint(program, 2)]), 262140); >+ checkUint(program, callFunction(program, "foo", [makeUint(program, -1), makeUint(program, 5)]), 4294967264); >+ checkUint(program, callFunction(program, "foo", [makeUint(program, 0), makeUint(program, 3)]), 0); > } > > tests.uintRShift = function() >@@ -3481,94 +2440,94 @@ tests.uintRShift = function() > return a >> b; > } > `); >- checkUint(program, callFunction(program, "foo", [], [makeUint(program, 1), makeUint(program, 7)]), 0); >- checkUint(program, callFunction(program, "foo", [], [makeUint(program, 65535), makeUint(program, 2)]), 16383); >- checkUint(program, callFunction(program, "foo", [], [makeUint(program, -1), makeUint(program, 5)]), 134217727); >- checkUint(program, callFunction(program, "foo", [], [makeUint(program, 0), makeUint(program, 3)]), 0); >+ checkUint(program, callFunction(program, "foo", [makeUint(program, 1), makeUint(program, 7)]), 0); >+ checkUint(program, callFunction(program, "foo", [makeUint(program, 65535), makeUint(program, 2)]), 16383); >+ checkUint(program, callFunction(program, "foo", [makeUint(program, -1), makeUint(program, 5)]), 134217727); >+ checkUint(program, callFunction(program, "foo", [makeUint(program, 0), makeUint(program, 3)]), 0); > } > >-tests.uint8BitAnd = function() >+tests.ucharBitAnd = function() > { > let program = doPrep(` >- uint8 foo(uint8 a, uint8 b) >+ uchar foo(uchar a, uchar b) > { > return a & b; > } > `); >- checkUint8(program, callFunction(program, "foo", [], [makeUint8(program, 1), makeUint8(program, 7)]), 1); >- checkUint8(program, callFunction(program, "foo", [], [makeUint8(program, 65535), makeUint8(program, 42)]), 42); >- checkUint8(program, callFunction(program, "foo", [], [makeUint8(program, -1), makeUint8(program, -7)]), 249); >- checkUint8(program, callFunction(program, "foo", [], [makeUint8(program, 0), makeUint8(program, 85732)]), 0); >+ checkUchar(program, callFunction(program, "foo", [makeUchar(program, 1), makeUchar(program, 7)]), 1); >+ checkUchar(program, callFunction(program, "foo", [makeUchar(program, 65535), makeUchar(program, 42)]), 42); >+ checkUchar(program, callFunction(program, "foo", [makeUchar(program, -1), makeUchar(program, -7)]), 249); >+ checkUchar(program, callFunction(program, "foo", [makeUchar(program, 0), makeUchar(program, 85732)]), 0); > } > >-tests.uint8BitOr = function() >+tests.ucharBitOr = function() > { > let program = doPrep(` >- uint8 foo(uint8 a, uint8 b) >+ uchar foo(uchar a, uchar b) > { > return a | b; > } > `); >- checkUint8(program, callFunction(program, "foo", [], [makeUint8(program, 1), makeUint8(program, 7)]), 7); >- checkUint8(program, callFunction(program, "foo", [], [makeUint8(program, 65535), makeUint8(program, 42)]), 255); >- checkUint8(program, callFunction(program, "foo", [], [makeUint8(program, -1), makeUint8(program, -7)]), 255); >- checkUint8(program, callFunction(program, "foo", [], [makeUint8(program, 0), makeUint8(program, 85732)]), 228); >+ checkUchar(program, callFunction(program, "foo", [makeUchar(program, 1), makeUchar(program, 7)]), 7); >+ checkUchar(program, callFunction(program, "foo", [makeUchar(program, 65535), makeUchar(program, 42)]), 255); >+ checkUchar(program, callFunction(program, "foo", [makeUchar(program, -1), makeUchar(program, -7)]), 255); >+ checkUchar(program, callFunction(program, "foo", [makeUchar(program, 0), makeUchar(program, 85732)]), 228); > } > >-tests.uint8BitXor = function() >+tests.ucharBitXor = function() > { > let program = doPrep(` >- uint8 foo(uint8 a, uint8 b) >+ uchar foo(uchar a, uchar b) > { > return a ^ b; > } > `); >- checkUint8(program, callFunction(program, "foo", [], [makeUint8(program, 1), makeUint8(program, 7)]), 6); >- checkUint8(program, callFunction(program, "foo", [], [makeUint8(program, 65535), makeUint8(program, 42)]), 213); >- checkUint8(program, callFunction(program, "foo", [], [makeUint8(program, -1), makeUint8(program, -7)]), 6); >- checkUint8(program, callFunction(program, "foo", [], [makeUint8(program, 0), makeUint8(program, 85732)]), 228); >+ checkUchar(program, callFunction(program, "foo", [makeUchar(program, 1), makeUchar(program, 7)]), 6); >+ checkUchar(program, callFunction(program, "foo", [makeUchar(program, 65535), makeUchar(program, 42)]), 213); >+ checkUchar(program, callFunction(program, "foo", [makeUchar(program, -1), makeUchar(program, -7)]), 6); >+ checkUchar(program, callFunction(program, "foo", [makeUchar(program, 0), makeUchar(program, 85732)]), 228); > } > >-tests.uint8BitNot = function() >+tests.ucharBitNot = function() > { > let program = doPrep(` >- uint8 foo(uint8 a) >+ uchar foo(uchar a) > { > return ~a; > } > `); >- checkUint8(program, callFunction(program, "foo", [], [makeUint8(program, 1)]), 254); >- checkUint8(program, callFunction(program, "foo", [], [makeUint8(program, 65535)]), 0); >- checkUint8(program, callFunction(program, "foo", [], [makeUint8(program, -1)]), 0); >- checkUint8(program, callFunction(program, "foo", [], [makeUint8(program, 0)]), 255); >+ checkUchar(program, callFunction(program, "foo", [makeUchar(program, 1)]), 254); >+ checkUchar(program, callFunction(program, "foo", [makeUchar(program, 65535)]), 0); >+ checkUchar(program, callFunction(program, "foo", [makeUchar(program, -1)]), 0); >+ checkUchar(program, callFunction(program, "foo", [makeUchar(program, 0)]), 255); > } > >-tests.uint8LShift = function() >+tests.ucharLShift = function() > { > let program = doPrep(` >- uint8 foo(uint8 a, uint b) >+ uchar foo(uchar a, uint b) > { > return a << b; > } > `); >- checkUint8(program, callFunction(program, "foo", [], [makeUint8(program, 1), makeUint(program, 7)]), 128); >- checkUint8(program, callFunction(program, "foo", [], [makeUint8(program, 65535), makeUint(program, 2)]), 252); >- checkUint8(program, callFunction(program, "foo", [], [makeUint8(program, -1), makeUint(program, 5)]), 224); >- checkUint8(program, callFunction(program, "foo", [], [makeUint8(program, 0), makeUint(program, 3)]), 0); >+ checkUchar(program, callFunction(program, "foo", [makeUchar(program, 1), makeUint(program, 7)]), 128); >+ checkUchar(program, callFunction(program, "foo", [makeUchar(program, 65535), makeUint(program, 2)]), 252); >+ checkUchar(program, callFunction(program, "foo", [makeUchar(program, -1), makeUint(program, 5)]), 224); >+ checkUchar(program, callFunction(program, "foo", [makeUchar(program, 0), makeUint(program, 3)]), 0); > } > >-tests.uint8RShift = function() >+tests.ucharRShift = function() > { > let program = doPrep(` >- uint8 foo(uint8 a, uint b) >+ uchar foo(uchar a, uint b) > { > return a >> b; > } > `); >- checkUint8(program, callFunction(program, "foo", [], [makeUint8(program, 1), makeUint(program, 7)]), 0); >- checkUint8(program, callFunction(program, "foo", [], [makeUint8(program, 65535), makeUint(program, 2)]), 255); >- checkUint8(program, callFunction(program, "foo", [], [makeUint8(program, -1), makeUint(program, 5)]), 255); >- checkUint8(program, callFunction(program, "foo", [], [makeUint8(program, 0), makeUint(program, 3)]), 0); >+ checkUchar(program, callFunction(program, "foo", [makeUchar(program, 1), makeUint(program, 7)]), 0); >+ checkUchar(program, callFunction(program, "foo", [makeUchar(program, 65535), makeUint(program, 2)]), 255); >+ checkUchar(program, callFunction(program, "foo", [makeUchar(program, -1), makeUint(program, 5)]), 255); >+ checkUchar(program, callFunction(program, "foo", [makeUchar(program, 0), makeUint(program, 3)]), 0); > } > > tests.floatMath = function() >@@ -3624,17 +2583,17 @@ tests.floatMath = function() > return float(x); > } > `); >- checkBool(program, callFunction(program, "foo", [], []), true); >- checkBool(program, callFunction(program, "foo2", [], []), true); >- checkBool(program, callFunction(program, "foo3", [], []), true); >- checkBool(program, callFunction(program, "foo4", [], []), true); >- checkBool(program, callFunction(program, "foo5", [], []), true); >- checkFloat(program, callFunction(program, "foo6", [], []), 7.5); >- checkFloat(program, callFunction(program, "foo7", [], []), 7.5); >- checkFloat(program, callFunction(program, "foo9", [], []), 7.5); >- checkFloat(program, callFunction(program, "foo10", [], []), 7.5); >- checkFloat(program, callFunction(program, "foo12", [], []), 7); >- checkFloat(program, callFunction(program, "foo13", [], []), 7.5); >+ checkBool(program, callFunction(program, "foo", []), true); >+ checkBool(program, callFunction(program, "foo2", []), true); >+ checkBool(program, callFunction(program, "foo3", []), true); >+ checkBool(program, callFunction(program, "foo4", []), true); >+ checkBool(program, callFunction(program, "foo5", []), true); >+ checkFloat(program, callFunction(program, "foo6", []), 7.5); >+ checkFloat(program, callFunction(program, "foo7", []), 7.5); >+ checkFloat(program, callFunction(program, "foo9", []), 7.5); >+ checkFloat(program, callFunction(program, "foo10", []), 7.5); >+ checkFloat(program, callFunction(program, "foo12", []), 7); >+ checkFloat(program, callFunction(program, "foo13", []), 7.5); > checkFail( > () => doPrep(` > int bar(int x) >@@ -3709,29 +2668,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(` >@@ -3768,14 +2704,14 @@ tests.booleanMath = function() > return false || false; > } > `); >- checkBool(program, callFunction(program, "foo", [], []), true); >- checkBool(program, callFunction(program, "foo2", [], []), false); >- checkBool(program, callFunction(program, "foo3", [], []), false); >- checkBool(program, callFunction(program, "foo4", [], []), false); >- checkBool(program, callFunction(program, "foo5", [], []), true); >- checkBool(program, callFunction(program, "foo6", [], []), true); >- checkBool(program, callFunction(program, "foo7", [], []), true); >- checkBool(program, callFunction(program, "foo8", [], []), false); >+ checkBool(program, callFunction(program, "foo", []), true); >+ checkBool(program, callFunction(program, "foo2", []), false); >+ checkBool(program, callFunction(program, "foo3", []), false); >+ checkBool(program, callFunction(program, "foo4", []), false); >+ checkBool(program, callFunction(program, "foo5", []), true); >+ checkBool(program, callFunction(program, "foo6", []), true); >+ checkBool(program, callFunction(program, "foo7", []), true); >+ checkBool(program, callFunction(program, "foo8", []), false); > } > > tests.booleanShortcircuiting = function() >@@ -3816,10 +2752,10 @@ tests.booleanShortcircuiting = function() > } > `); > >- checkInt(program, callFunction(program, "andTrue", [], []), 2); >- checkInt(program, callFunction(program, "andFalse", [], []), 1); >- checkInt(program, callFunction(program, "orTrue", [], []), 1); >- checkInt(program, callFunction(program, "orFalse", [], []), 2); >+ checkInt(program, callFunction(program, "andTrue", []), 2); >+ checkInt(program, callFunction(program, "andFalse", []), 1); >+ checkInt(program, callFunction(program, "orTrue", []), 1); >+ checkInt(program, callFunction(program, "orFalse", []), 2); > } > > tests.typedefArray = function() >@@ -3832,7 +2768,7 @@ tests.typedefArray = function() > return arrayTypedef[0]; > } > `); >- checkInt(program, callFunction(program, "foo", [], []), 0); >+ checkInt(program, callFunction(program, "foo", []), 0); > } > > tests.shaderTypes = function() >@@ -3966,6 +2902,47 @@ tests.shaderTypes = function() > (e) => e instanceof WTypeError); > } > >+tests.vectorTypeSyntax = function() >+{ >+ const 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; >+ } >+ >+ bool vec2OperatorCast() >+ { >+ int2 x = vector<int,2>(1, 2); >+ vector<int, 2> y = int2(1, 2); >+ return x == y && x.x == 1 && x.y == 2 && y.x == 1 && y.y == 2; >+ }`); >+ >+ checkInt(program, callFunction(program, "foo2", []), 4); >+ checkInt(program, callFunction(program, "foo3", []), 5); >+ checkInt(program, callFunction(program, "foo4", []), 6); >+ >+ checkBool(program, callFunction(program, "vec2OperatorCast", []), true); >+} >+ > tests.builtinVectors = function() > { > let program = doPrep(` >@@ -4084,61 +3061,134 @@ tests.builtinVectors = function() > return b == c; > } > `); >- checkInt(program, callFunction(program, "foo", [], []), 3); >- checkInt(program, callFunction(program, "foo2", [], []), 4); >- checkInt(program, callFunction(program, "foo3", [], []), 3); >- checkInt(program, callFunction(program, "foo4", [], []), 5); >- checkBool(program, callFunction(program, "foo5", [], []), true); >- checkBool(program, callFunction(program, "foo6", [], []), false); >- checkUint(program, callFunction(program, "foou", [], []), 3); >- checkUint(program, callFunction(program, "foou2", [], []), 4); >- checkUint(program, callFunction(program, "foou3", [], []), 3); >- checkUint(program, callFunction(program, "foou4", [], []), 5); >- checkBool(program, callFunction(program, "foou5", [], []), true); >- checkBool(program, callFunction(program, "foou6", [], []), false); >- checkFloat(program, callFunction(program, "foof", [], []), 3); >- checkFloat(program, callFunction(program, "foof2", [], []), 4); >- checkFloat(program, callFunction(program, "foof3", [], []), 3); >- checkFloat(program, callFunction(program, "foof4", [], []), 5); >- checkBool(program, callFunction(program, "foof5", [], []), true); >- checkBool(program, callFunction(program, "foof6", [], []), false); >-} >- >-tests.instantiateStructInStruct = 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; >+ checkInt(program, callFunction(program, "foo", []), 3); >+ checkInt(program, callFunction(program, "foo2", []), 4); >+ checkInt(program, callFunction(program, "foo3", []), 3); >+ checkInt(program, callFunction(program, "foo4", []), 5); >+ checkBool(program, callFunction(program, "foo5", []), true); >+ checkBool(program, callFunction(program, "foo6", []), false); >+ checkUint(program, callFunction(program, "foou", []), 3); >+ checkUint(program, callFunction(program, "foou2", []), 4); >+ checkUint(program, callFunction(program, "foou3", []), 3); >+ checkUint(program, callFunction(program, "foou4", []), 5); >+ checkBool(program, callFunction(program, "foou5", []), true); >+ checkBool(program, callFunction(program, "foou6", []), false); >+ checkFloat(program, callFunction(program, "foof", []), 3); >+ checkFloat(program, callFunction(program, "foof2", []), 4); >+ checkFloat(program, callFunction(program, "foof3", []), 3); >+ checkFloat(program, callFunction(program, "foof4", []), 5); >+ checkBool(program, callFunction(program, "foof5", []), true); >+ checkBool(program, callFunction(program, "foof6", []), false); >+} >+ >+tests.builtinVectorGetters = 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(", ")}); >+ 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() >@@ -4263,32 +3313,32 @@ tests.simpleEnum = function() > return Foo(intDeath()); > } > `); >- checkEnum(program, callFunction(program, "war", [], []), 0); >- checkEnum(program, callFunction(program, "famine", [], []), 1); >- checkEnum(program, callFunction(program, "pestilence", [], []), 2); >- checkEnum(program, callFunction(program, "death", [], []), 3); >- checkBool(program, callFunction(program, "testSimpleEqual", [], []), true); >- checkBool(program, callFunction(program, "testAnotherEqual", [], []), true); >- checkBool(program, callFunction(program, "testNotEqual", [], []), false); >- checkBool(program, callFunction(program, "testSimpleNotEqual", [], []), false); >- checkBool(program, callFunction(program, "testAnotherNotEqual", [], []), false); >- checkBool(program, callFunction(program, "testNotNotEqual", [], []), true); >- checkInt(program, callFunction(program, "intWar", [], []), 0); >- checkInt(program, callFunction(program, "intFamine", [], []), 1); >- checkInt(program, callFunction(program, "intPestilence", [], []), 2); >- checkInt(program, callFunction(program, "intDeath", [], []), 3); >- checkInt(program, callFunction(program, "warValue", [], []), 0); >- checkInt(program, callFunction(program, "famineValue", [], []), 1); >- checkInt(program, callFunction(program, "pestilenceValue", [], []), 2); >- checkInt(program, callFunction(program, "deathValue", [], []), 3); >- checkInt(program, callFunction(program, "warValueLiteral", [], []), 0); >- checkInt(program, callFunction(program, "famineValueLiteral", [], []), 1); >- checkInt(program, callFunction(program, "pestilenceValueLiteral", [], []), 2); >- checkInt(program, callFunction(program, "deathValueLiteral", [], []), 3); >- checkEnum(program, callFunction(program, "intWarBackwards", [], []), 0); >- checkEnum(program, callFunction(program, "intFamineBackwards", [], []), 1); >- checkEnum(program, callFunction(program, "intPestilenceBackwards", [], []), 2); >- checkEnum(program, callFunction(program, "intDeathBackwards", [], []), 3); >+ checkEnum(program, callFunction(program, "war", []), 0); >+ checkEnum(program, callFunction(program, "famine", []), 1); >+ checkEnum(program, callFunction(program, "pestilence", []), 2); >+ checkEnum(program, callFunction(program, "death", []), 3); >+ checkBool(program, callFunction(program, "testSimpleEqual", []), true); >+ checkBool(program, callFunction(program, "testAnotherEqual", []), true); >+ checkBool(program, callFunction(program, "testNotEqual", []), false); >+ checkBool(program, callFunction(program, "testSimpleNotEqual", []), false); >+ checkBool(program, callFunction(program, "testAnotherNotEqual", []), false); >+ checkBool(program, callFunction(program, "testNotNotEqual", []), true); >+ checkInt(program, callFunction(program, "intWar", []), 0); >+ checkInt(program, callFunction(program, "intFamine", []), 1); >+ checkInt(program, callFunction(program, "intPestilence", []), 2); >+ checkInt(program, callFunction(program, "intDeath", []), 3); >+ checkInt(program, callFunction(program, "warValue", []), 0); >+ checkInt(program, callFunction(program, "famineValue", []), 1); >+ checkInt(program, callFunction(program, "pestilenceValue", []), 2); >+ checkInt(program, callFunction(program, "deathValue", []), 3); >+ checkInt(program, callFunction(program, "warValueLiteral", []), 0); >+ checkInt(program, callFunction(program, "famineValueLiteral", []), 1); >+ checkInt(program, callFunction(program, "pestilenceValueLiteral", []), 2); >+ checkInt(program, callFunction(program, "deathValueLiteral", []), 3); >+ checkEnum(program, callFunction(program, "intWarBackwards", []), 0); >+ checkEnum(program, callFunction(program, "intFamineBackwards", []), 1); >+ checkEnum(program, callFunction(program, "intPestilenceBackwards", []), 2); >+ checkEnum(program, callFunction(program, "intDeathBackwards", []), 3); > } > > tests.enumWithManualValues = function() >@@ -4317,10 +3367,10 @@ tests.enumWithManualValues = function() > return Foo.Death; > } > `); >- checkEnum(program, callFunction(program, "war", [], []), 72); >- checkEnum(program, callFunction(program, "famine", [], []), 0); >- checkEnum(program, callFunction(program, "pestilence", [], []), 23); >- checkEnum(program, callFunction(program, "death", [], []), -42); >+ checkEnum(program, callFunction(program, "war", []), 72); >+ checkEnum(program, callFunction(program, "famine", []), 0); >+ checkEnum(program, callFunction(program, "pestilence", []), 23); >+ checkEnum(program, callFunction(program, "death", []), -42); > } > > tests.enumWithoutZero = function() >@@ -4377,43 +3427,10 @@ tests.enumWithSomeManualValues = function() > return Foo.Death; > } > `); >- checkEnum(program, callFunction(program, "war", [], []), 72); >- checkEnum(program, callFunction(program, "famine", [], []), 73); >- checkEnum(program, callFunction(program, "pestilence", [], []), 0); >- 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); >+ checkEnum(program, callFunction(program, "war", []), 72); >+ checkEnum(program, callFunction(program, "famine", []), 73); >+ checkEnum(program, callFunction(program, "pestilence", []), 0); >+ checkEnum(program, callFunction(program, "death", []), 1); > } > > tests.trap = function() >@@ -4439,14 +3456,14 @@ tests.trap = function() > } > `); > checkFail( >- () => callFunction(program, "foo", [], []), >+ () => callFunction(program, "foo", []), > e => e instanceof WTrapError); >- checkInt(program, callFunction(program, "foo2", [], [makeInt(program, 1)]), 4); >+ checkInt(program, callFunction(program, "foo2", [makeInt(program, 1)]), 4); > checkFail( >- () => callFunction(program, "foo2", [], [makeInt(program, 3)]), >+ () => callFunction(program, "foo2", [makeInt(program, 3)]), > e => e instanceof WTrapError); > checkFail( >- () => callFunction(program, "foo3", [], []), >+ () => callFunction(program, "foo3", []), > e => e instanceof WTrapError); > } > >@@ -4470,9 +3487,9 @@ tests.swizzle = function() > return quix.z; > } > `); >- checkFloat(program, callFunction(program, "foo", [], []), 3); >- checkFloat(program, callFunction(program, "foo2", [], []), 6); >- checkFloat(program, callFunction(program, "foo3", [], []), 4); >+ checkFloat(program, callFunction(program, "foo", []), 3); >+ checkFloat(program, callFunction(program, "foo2", []), 6); >+ checkFloat(program, callFunction(program, "foo3", []), 4); > } > > tests.enumWithExplicitIntBase = function() >@@ -4597,32 +3614,32 @@ tests.enumWithExplicitIntBase = function() > return Foo(intDeath()); > } > `); >- checkEnum(program, callFunction(program, "war", [], []), 0); >- checkEnum(program, callFunction(program, "famine", [], []), 1); >- checkEnum(program, callFunction(program, "pestilence", [], []), 2); >- checkEnum(program, callFunction(program, "death", [], []), 3); >- checkBool(program, callFunction(program, "testSimpleEqual", [], []), true); >- checkBool(program, callFunction(program, "testAnotherEqual", [], []), true); >- checkBool(program, callFunction(program, "testNotEqual", [], []), false); >- checkBool(program, callFunction(program, "testSimpleNotEqual", [], []), false); >- checkBool(program, callFunction(program, "testAnotherNotEqual", [], []), false); >- checkBool(program, callFunction(program, "testNotNotEqual", [], []), true); >- checkInt(program, callFunction(program, "intWar", [], []), 0); >- checkInt(program, callFunction(program, "intFamine", [], []), 1); >- checkInt(program, callFunction(program, "intPestilence", [], []), 2); >- checkInt(program, callFunction(program, "intDeath", [], []), 3); >- checkInt(program, callFunction(program, "warValue", [], []), 0); >- checkInt(program, callFunction(program, "famineValue", [], []), 1); >- checkInt(program, callFunction(program, "pestilenceValue", [], []), 2); >- checkInt(program, callFunction(program, "deathValue", [], []), 3); >- checkInt(program, callFunction(program, "warValueLiteral", [], []), 0); >- checkInt(program, callFunction(program, "famineValueLiteral", [], []), 1); >- checkInt(program, callFunction(program, "pestilenceValueLiteral", [], []), 2); >- checkInt(program, callFunction(program, "deathValueLiteral", [], []), 3); >- checkEnum(program, callFunction(program, "intWarBackwards", [], []), 0); >- checkEnum(program, callFunction(program, "intFamineBackwards", [], []), 1); >- checkEnum(program, callFunction(program, "intPestilenceBackwards", [], []), 2); >- checkEnum(program, callFunction(program, "intDeathBackwards", [], []), 3); >+ checkEnum(program, callFunction(program, "war", []), 0); >+ checkEnum(program, callFunction(program, "famine", []), 1); >+ checkEnum(program, callFunction(program, "pestilence", []), 2); >+ checkEnum(program, callFunction(program, "death", []), 3); >+ checkBool(program, callFunction(program, "testSimpleEqual", []), true); >+ checkBool(program, callFunction(program, "testAnotherEqual", []), true); >+ checkBool(program, callFunction(program, "testNotEqual", []), false); >+ checkBool(program, callFunction(program, "testSimpleNotEqual", []), false); >+ checkBool(program, callFunction(program, "testAnotherNotEqual", []), false); >+ checkBool(program, callFunction(program, "testNotNotEqual", []), true); >+ checkInt(program, callFunction(program, "intWar", []), 0); >+ checkInt(program, callFunction(program, "intFamine", []), 1); >+ checkInt(program, callFunction(program, "intPestilence", []), 2); >+ checkInt(program, callFunction(program, "intDeath", []), 3); >+ checkInt(program, callFunction(program, "warValue", []), 0); >+ checkInt(program, callFunction(program, "famineValue", []), 1); >+ checkInt(program, callFunction(program, "pestilenceValue", []), 2); >+ checkInt(program, callFunction(program, "deathValue", []), 3); >+ checkInt(program, callFunction(program, "warValueLiteral", []), 0); >+ checkInt(program, callFunction(program, "famineValueLiteral", []), 1); >+ checkInt(program, callFunction(program, "pestilenceValueLiteral", []), 2); >+ checkInt(program, callFunction(program, "deathValueLiteral", []), 3); >+ checkEnum(program, callFunction(program, "intWarBackwards", []), 0); >+ checkEnum(program, callFunction(program, "intFamineBackwards", []), 1); >+ checkEnum(program, callFunction(program, "intPestilenceBackwards", []), 2); >+ checkEnum(program, callFunction(program, "intDeathBackwards", []), 3); > } > > tests.enumWithUintBase = function() >@@ -4747,32 +3764,32 @@ tests.enumWithUintBase = function() > return Foo(uintDeath()); > } > `); >- checkEnum(program, callFunction(program, "war", [], []), 0); >- checkEnum(program, callFunction(program, "famine", [], []), 1); >- checkEnum(program, callFunction(program, "pestilence", [], []), 2); >- checkEnum(program, callFunction(program, "death", [], []), 3); >- checkBool(program, callFunction(program, "testSimpleEqual", [], []), true); >- checkBool(program, callFunction(program, "testAnotherEqual", [], []), true); >- checkBool(program, callFunction(program, "testNotEqual", [], []), false); >- checkBool(program, callFunction(program, "testSimpleNotEqual", [], []), false); >- checkBool(program, callFunction(program, "testAnotherNotEqual", [], []), false); >- checkBool(program, callFunction(program, "testNotNotEqual", [], []), true); >- checkUint(program, callFunction(program, "uintWar", [], []), 0); >- checkUint(program, callFunction(program, "uintFamine", [], []), 1); >- checkUint(program, callFunction(program, "uintPestilence", [], []), 2); >- checkUint(program, callFunction(program, "uintDeath", [], []), 3); >- checkUint(program, callFunction(program, "warValue", [], []), 0); >- checkUint(program, callFunction(program, "famineValue", [], []), 1); >- checkUint(program, callFunction(program, "pestilenceValue", [], []), 2); >- checkUint(program, callFunction(program, "deathValue", [], []), 3); >- checkUint(program, callFunction(program, "warValueLiteral", [], []), 0); >- checkUint(program, callFunction(program, "famineValueLiteral", [], []), 1); >- checkUint(program, callFunction(program, "pestilenceValueLiteral", [], []), 2); >- checkUint(program, callFunction(program, "deathValueLiteral", [], []), 3); >- checkEnum(program, callFunction(program, "uintWarBackwards", [], []), 0); >- checkEnum(program, callFunction(program, "uintFamineBackwards", [], []), 1); >- checkEnum(program, callFunction(program, "uintPestilenceBackwards", [], []), 2); >- checkEnum(program, callFunction(program, "uintDeathBackwards", [], []), 3); >+ checkEnum(program, callFunction(program, "war", []), 0); >+ checkEnum(program, callFunction(program, "famine", []), 1); >+ checkEnum(program, callFunction(program, "pestilence", []), 2); >+ checkEnum(program, callFunction(program, "death", []), 3); >+ checkBool(program, callFunction(program, "testSimpleEqual", []), true); >+ checkBool(program, callFunction(program, "testAnotherEqual", []), true); >+ checkBool(program, callFunction(program, "testNotEqual", []), false); >+ checkBool(program, callFunction(program, "testSimpleNotEqual", []), false); >+ checkBool(program, callFunction(program, "testAnotherNotEqual", []), false); >+ checkBool(program, callFunction(program, "testNotNotEqual", []), true); >+ checkUint(program, callFunction(program, "uintWar", []), 0); >+ checkUint(program, callFunction(program, "uintFamine", []), 1); >+ checkUint(program, callFunction(program, "uintPestilence", []), 2); >+ checkUint(program, callFunction(program, "uintDeath", []), 3); >+ checkUint(program, callFunction(program, "warValue", []), 0); >+ checkUint(program, callFunction(program, "famineValue", []), 1); >+ checkUint(program, callFunction(program, "pestilenceValue", []), 2); >+ checkUint(program, callFunction(program, "deathValue", []), 3); >+ checkUint(program, callFunction(program, "warValueLiteral", []), 0); >+ checkUint(program, callFunction(program, "famineValueLiteral", []), 1); >+ checkUint(program, callFunction(program, "pestilenceValueLiteral", []), 2); >+ checkUint(program, callFunction(program, "deathValueLiteral", []), 3); >+ checkEnum(program, callFunction(program, "uintWarBackwards", []), 0); >+ checkEnum(program, callFunction(program, "uintFamineBackwards", []), 1); >+ checkEnum(program, callFunction(program, "uintPestilenceBackwards", []), 2); >+ checkEnum(program, callFunction(program, "uintDeathBackwards", []), 3); > } > > tests.enumFloatBase = function() >@@ -4818,7 +3835,7 @@ tests.emptyStruct = function() > return 46; > } > `); >- checkInt(program, callFunction(program, "foo", [], []), 46); >+ checkInt(program, callFunction(program, "foo", []), 46); > } > > tests.enumStructBase = function() >@@ -4857,41 +3874,41 @@ tests.simpleSwitch = function() > } > } > `); >- checkInt(program, callFunction(program, "foo", [], [makeInt(program, 767)]), 27); >- checkInt(program, callFunction(program, "foo", [], [makeInt(program, 69)]), 7624); >- checkInt(program, callFunction(program, "foo", [], [makeInt(program, 0)]), 49); >+ checkInt(program, callFunction(program, "foo", [makeInt(program, 767)]), 27); >+ checkInt(program, callFunction(program, "foo", [makeInt(program, 69)]), 7624); >+ checkInt(program, callFunction(program, "foo", [makeInt(program, 0)]), 49); > } > >-tests.exhaustiveUint8Switch = function() >+tests.exhaustiveUcharSwitch = function() > { >- let text = "float foo(uint8 x) { switch (uint8(x)) {" >+ let text = "float foo(uchar x) { switch (uchar(x)) {" > for (let i = 0; i <= 0xff; ++i) > text += "case " + i + ": return " + i * 1.5 + ";"; > text += "} }"; > let program = doPrep(text); > for (let i = 0; i < 0xff; ++i) >- checkFloat(program, callFunction(program, "foo", [], [makeUint8(program, i)]), i * 1.5); >+ checkFloat(program, callFunction(program, "foo", [makeUchar(program, i)]), i * 1.5); > } > >-tests.notQuiteExhaustiveUint8Switch = function() >+tests.notQuiteExhaustiveUcharSwitch = function() > { >- let text = "float foo(uint8 x) { switch (uint8(x)) {" >+ let text = "float foo(uchar x) { switch (uchar(x)) {" > for (let i = 0; i <= 0xfe; ++i) > text += "case " + i + ": return " + i * 1.5 + ";"; > text += "} }"; > checkFail(() => doPrep(text), e => e instanceof WTypeError); > } > >-tests.notQuiteExhaustiveUint8SwitchWithDefault = function() >+tests.notQuiteExhaustiveUcharSwitchWithDefault = function() > { >- let text = "float foo(uint8 x) { switch (uint8(x)) {" >+ let text = "float foo(uchar x) { switch (uchar(x)) {" > for (let i = 0; i <= 0xfe; ++i) > text += "case " + i + ": return " + i * 1.5 + ";"; > text += "default: return " + 0xff * 1.5 + ";"; > text += "} }"; > let program = doPrep(text); > for (let i = 0; i < 0xff; ++i) >- checkFloat(program, callFunction(program, "foo", [], [makeUint8(program, i)]), i * 1.5); >+ checkFloat(program, callFunction(program, "foo", [makeUchar(program, i)]), i * 1.5); > } > > tests.switchFallThrough = function() >@@ -4913,9 +3930,9 @@ tests.switchFallThrough = function() > return result; > } > `); >- checkInt(program, callFunction(program, "foo", [], [makeInt(program, 767)]), 27 + 7624 + 49); >- checkInt(program, callFunction(program, "foo", [], [makeInt(program, 69)]), 7624 + 49); >- checkInt(program, callFunction(program, "foo", [], [makeInt(program, 0)]), 49); >+ checkInt(program, callFunction(program, "foo", [makeInt(program, 767)]), 27 + 7624 + 49); >+ checkInt(program, callFunction(program, "foo", [makeInt(program, 69)]), 7624 + 49); >+ checkInt(program, callFunction(program, "foo", [makeInt(program, 0)]), 49); > } > > tests.switchBreak = function() >@@ -4938,9 +3955,9 @@ tests.switchBreak = function() > return result; > } > `); >- checkInt(program, callFunction(program, "foo", [], [makeInt(program, 767)]), 27); >- checkInt(program, callFunction(program, "foo", [], [makeInt(program, 69)]), 7624); >- checkInt(program, callFunction(program, "foo", [], [makeInt(program, 0)]), 49); >+ checkInt(program, callFunction(program, "foo", [makeInt(program, 767)]), 27); >+ checkInt(program, callFunction(program, "foo", [makeInt(program, 69)]), 7624); >+ checkInt(program, callFunction(program, "foo", [makeInt(program, 0)]), 49); > } > > tests.enumSwitchBreakExhaustive = function() >@@ -4966,9 +3983,9 @@ tests.enumSwitchBreakExhaustive = function() > return result; > } > `); >- checkInt(program, callFunction(program, "foo", [], [makeEnum(program, "Foo", "A")]), 27); >- checkInt(program, callFunction(program, "foo", [], [makeEnum(program, "Foo", "B")]), 7624); >- checkInt(program, callFunction(program, "foo", [], [makeEnum(program, "Foo", "C")]), 49); >+ checkInt(program, callFunction(program, "foo", [makeEnum(program, "Foo", "A")]), 27); >+ checkInt(program, callFunction(program, "foo", [makeEnum(program, "Foo", "B")]), 7624); >+ checkInt(program, callFunction(program, "foo", [makeEnum(program, "Foo", "C")]), 49); > } > > tests.enumSwitchBreakNotQuiteExhaustive = function() >@@ -5021,9 +4038,9 @@ tests.enumSwitchBreakNotQuiteExhaustiveWithDefault = function() > return result; > } > `); >- checkInt(program, callFunction(program, "foo", [], [makeEnum(program, "Foo", "A")]), 27); >- checkInt(program, callFunction(program, "foo", [], [makeEnum(program, "Foo", "B")]), 7624); >- checkInt(program, callFunction(program, "foo", [], [makeEnum(program, "Foo", "C")]), 49); >+ checkInt(program, callFunction(program, "foo", [makeEnum(program, "Foo", "A")]), 27); >+ checkInt(program, callFunction(program, "foo", [makeEnum(program, "Foo", "B")]), 7624); >+ checkInt(program, callFunction(program, "foo", [makeEnum(program, "Foo", "C")]), 49); > } > > tests.simpleRecursiveStruct = function() >@@ -5072,7 +4089,7 @@ tests.mutuallyRecursiveStructWithPointersBroken = function() > } > `); > checkFail( >- () => checkInt(program, callFunction(program, "foo", [], []), -511), >+ () => checkInt(program, callFunction(program, "foo", []), -511), > e => e instanceof WTrapError); > } > >@@ -5098,7 +4115,7 @@ tests.mutuallyRecursiveStructWithPointers = function() > return foo.bar->bar - bar.foo->foo; > } > `); >- checkInt(program, callFunction(program, "foo", [], []), -511); >+ checkInt(program, callFunction(program, "foo", []), -511); > } > > tests.linkedList = function() >@@ -5119,7 +4136,7 @@ tests.linkedList = function() > return x.next->next->value; > } > `); >- checkInt(program, callFunction(program, "foo", [], []), 3); >+ checkInt(program, callFunction(program, "foo", []), 3); > } > > tests.pointerToPointer = function() >@@ -5142,7 +4159,7 @@ tests.pointerToPointer = function() > return result; > } > `); >- checkInt(program, callFunction(program, "foo", [], []), 76 + 39 + 83); >+ checkInt(program, callFunction(program, "foo", []), 76 + 39 + 83); > } > > tests.arrayRefToArrayRef = function() >@@ -5165,7 +4182,7 @@ tests.arrayRefToArrayRef = function() > return result; > } > `); >- checkInt(program, callFunction(program, "foo", [], []), 76 + 39 + 83); >+ checkInt(program, callFunction(program, "foo", []), 76 + 39 + 83); > } > > tests.pointerGetter = function() >@@ -5246,23 +4263,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(` >@@ -5284,54 +4284,7 @@ tests.operatorWithoutUninferrableTypeVariable = function() > return (a + b).x; > } > `); >- 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); >+ checkInt(program, callFunction(program, "foo", []), 645 - 35); > } > > tests.incWrongArgumentLength = function() >@@ -5823,7 +4776,7 @@ tests.anderWithNothingWrong = function() > return x.foo; > } > `); >- checkInt(program, callFunction(program, "foo", [], []), 13); >+ checkInt(program, callFunction(program, "foo", []), 13); > } > > tests.anderWithWrongNumberOfArguments = function() >@@ -5897,7 +4850,26 @@ tests.anderWithArrayRef = function() > return (@x).foo; > } > `); >- checkInt(program, callFunction(program, "foo", [], []), 13); >+ 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() >@@ -6083,7 +5055,7 @@ tests.indexAnderWithNothingWrong = function() > return x[666]; > } > `); >- checkInt(program, callFunction(program, "foo", [], []), 13); >+ checkInt(program, callFunction(program, "foo", []), 13); > } > > tests.indexAnderWithWrongNumberOfArguments = function() >@@ -6168,7 +5140,7 @@ tests.indexAnderWithArrayRef = function() > return (@x)[float(-1)]; > } > `); >- checkInt(program, callFunction(program, "foo", [], []), 13); >+ checkInt(program, callFunction(program, "foo", []), 13); > } > > tests.devicePtrPtr = function() >@@ -6180,7 +5152,7 @@ tests.devicePtrPtr = function() > device int** p; > } > `), >- e => e instanceof WTypeError && e.message.indexOf("Illegal pointer to non-primitive type: int32* device* device") != -1); >+ e => e instanceof WTypeError && e.message.indexOf("Illegal pointer to non-primitive type: int* device* device") != -1); > } > > tests.threadgroupPtrPtr = function() >@@ -6192,7 +5164,7 @@ tests.threadgroupPtrPtr = function() > threadgroup int** p; > } > `), >- e => e instanceof WTypeError && e.message.indexOf("Illegal pointer to non-primitive type: int32* threadgroup* threadgroup") != -1); >+ e => e instanceof WTypeError && e.message.indexOf("Illegal pointer to non-primitive type: int* threadgroup* threadgroup") != -1); > } > > tests.constantPtrPtr = function() >@@ -6204,307 +5176,7 @@ tests.constantPtrPtr = function() > constant int** p; > } > `), >- 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); >+ e => e instanceof WTypeError && e.message.indexOf("Illegal pointer to non-primitive type: int* constant* constant") != -1); > } > > tests.andReturnedArrayRef = function() >@@ -6522,7 +5194,7 @@ tests.andReturnedArrayRef = function() > return *ptr; > } > `); >- checkInt(program, callFunction(program, "foo", [], []), 354); >+ checkInt(program, callFunction(program, "foo", []), 354); > } > > okToTest = true; >diff --git a/Tools/WebGPUShadingLanguageRI/Type.js b/Tools/WebGPUShadingLanguageRI/Type.js >index 7c287918953a5b1d5e35e850e330f389df6e76e8..2db158d099b326a93e7335e4e696138c5edbefdb 100644 >--- a/Tools/WebGPUShadingLanguageRI/Type.js >+++ b/Tools/WebGPUShadingLanguageRI/Type.js >@@ -1,5 +1,5 @@ > /* >- * Copyright (C) 2017 Apple Inc. All rights reserved. >+ * Copyright (C) 2018 Apple Inc. All rights reserved. > * > * Redistribution and use in source and binary forms, with or without > * modification, are permitted provided that the following conditions >@@ -25,7 +25,6 @@ > "use strict"; > > class Type extends Node { >- get typeParameters() { return []; } > get kind() { return Type; } > get isPtr() { return false; } > get isArray() { return false; } >@@ -37,15 +36,6 @@ class Type extends Node { > get isEnum() { return false; } > get isPrimitive() { return false; } > >- inherits(protocol) >- { >- if (!protocol) >- return {result: true}; >- return protocol.hasHeir(this); >- } >- >- get instantiatedType() { return this.visit(new InstantiateImmediates()); } >- > // Have to call these on the unifyNode. > argumentForAndOverload(origin, value) > { >diff --git a/Tools/WebGPUShadingLanguageRI/TypeDef.js b/Tools/WebGPUShadingLanguageRI/TypeDef.js >index 6c0f9c174f53235641f4cd302cab4c3aab27c143..5c4a34bcc343265f35ddc5bfe888845a3988fa37 100644 >--- a/Tools/WebGPUShadingLanguageRI/TypeDef.js >+++ b/Tools/WebGPUShadingLanguageRI/TypeDef.js >@@ -1,5 +1,5 @@ > /* >- * Copyright (C) 2017 Apple Inc. All rights reserved. >+ * Copyright (C) 2018 Apple Inc. All rights reserved. > * > * Redistribution and use in source and binary forms, with or without > * modification, are permitted provided that the following conditions >@@ -25,23 +25,22 @@ > "use strict"; > > class TypeDef extends Type { >- constructor(origin, name, typeParameters, type) >+ constructor(origin, name, type) > { > super(); > this._origin = origin; > this._name = name; >- this._typeParameters = typeParameters; > this._type = type; > } > >+ get unifyNode() { return this.type.unifyNode; } > get origin() { return this._origin; } > get name() { return this._name; } >- get typeParameters() { return this._typeParameters; } > get type() { return this._type; } > > toString() > { >- return "typedef " + this.name + "<" + this.typeParameters + "> = " + this.type; >+ return `typedef ${this.name} = ${this.type}`; > } > } > >diff --git a/Tools/WebGPUShadingLanguageRI/TypeDefResolver.js b/Tools/WebGPUShadingLanguageRI/TypeDefResolver.js >index a81eab42d948fca3e930c6857a964ddccfcee57f..dbfbcac50341913048cc535c0b53ea3ae169679e 100644 >--- a/Tools/WebGPUShadingLanguageRI/TypeDefResolver.js >+++ b/Tools/WebGPUShadingLanguageRI/TypeDefResolver.js >@@ -1,5 +1,5 @@ > /* >- * Copyright (C) 2017 Apple Inc. All rights reserved. >+ * Copyright (C) 2018 Apple Inc. All rights reserved. > * > * Redistribution and use in source and binary forms, with or without > * modification, are permitted provided that the following conditions >@@ -34,21 +34,10 @@ class TypeDefResolver extends Visitor { > visitTypeRef(node) > { > this._visiting.doVisit(node, () => { >- for (let typeArgument of node.typeArguments) >- typeArgument.visit(this); > if (node.type instanceof TypeDef) { >- let unificationContext = new UnificationContext(node.type.typeParameters); >- if (node.typeArguments.length != node.type.typeParameters.length) >- throw new Error("argument/parameter mismatch (should have been caught earlier)"); >- for (let i = 0; i < node.typeArguments.length; ++i) >- node.typeArguments[i].unify(unificationContext, node.type.typeParameters[i]); >- let verificationResult = unificationContext.verify(); >- if (!verificationResult.result) >- throw new WTypeError(node.origin.originString, "Type reference to a type definition violates protocol constraints: " + verificationResult.reason); >- >- let newType = node.type.type.substituteToUnification(node.type.typeParameters, unificationContext); >+ let newType = node.type.type; > newType.visit(this); >- node.setTypeAndArguments(newType, []); >+ node.type = newType; > } > }); > } >diff --git a/Tools/WebGPUShadingLanguageRI/TypeOrVariableRef.js b/Tools/WebGPUShadingLanguageRI/TypeOrVariableRef.js >deleted file mode 100644 >index c5f59f90066fdb0b7c7bb72ea618a711230d1e6e..0000000000000000000000000000000000000000 >--- a/Tools/WebGPUShadingLanguageRI/TypeOrVariableRef.js >+++ /dev/null >@@ -1,42 +0,0 @@ >-/* >- * Copyright (C) 2017 Apple Inc. All rights reserved. >- * >- * Redistribution and use in source and binary forms, with or without >- * modification, are permitted provided that the following conditions >- * are met: >- * 1. Redistributions of source code must retain the above copyright >- * notice, this list of conditions and the following disclaimer. >- * 2. Redistributions in binary form must reproduce the above copyright >- * notice, this list of conditions and the following disclaimer in the >- * documentation and/or other materials provided with the distribution. >- * >- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY >- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE >- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR >- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR >- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, >- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, >- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR >- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY >- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT >- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE >- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. >- */ >-"use strict"; >- >-class TypeOrVariableRef extends Node { >- constructor(origin, name) >- { >- super(); >- this._origin = origin; >- this._name = name; >- } >- >- get origin() { return this._origin; } >- get name() { return this._name; } >- >- toString() >- { >- return this.name; >- } >-} >diff --git a/Tools/WebGPUShadingLanguageRI/TypeParameterRewriter.js b/Tools/WebGPUShadingLanguageRI/TypeParameterRewriter.js >deleted file mode 100644 >index 3bd037c927275160fc45eb2f9a86691777116ba0..0000000000000000000000000000000000000000 >--- a/Tools/WebGPUShadingLanguageRI/TypeParameterRewriter.js >+++ /dev/null >@@ -1,38 +0,0 @@ >-/* >- * Copyright (C) 2017 Apple Inc. All rights reserved. >- * >- * Redistribution and use in source and binary forms, with or without >- * modification, are permitted provided that the following conditions >- * are met: >- * 1. Redistributions of source code must retain the above copyright >- * notice, this list of conditions and the following disclaimer. >- * 2. Redistributions in binary form must reproduce the above copyright >- * notice, this list of conditions and the following disclaimer in the >- * documentation and/or other materials provided with the distribution. >- * >- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY >- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE >- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR >- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR >- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, >- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, >- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR >- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY >- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT >- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE >- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. >- */ >-"use strict"; >- >-class TypeParameterRewriter { >- visitConstexprTypeParameter(node) >- { >- return new ConstexprTypeParameter(node.origin, node.name, node.type.visit(new Rewriter())); >- } >- >- visitTypeVariable(node) >- { >- return new TypeVariable(node.origin, node.name, node.protocol); >- } >-} >- >diff --git a/Tools/WebGPUShadingLanguageRI/TypeRef.js b/Tools/WebGPUShadingLanguageRI/TypeRef.js >index f2b322f3af6a73086141e56d693efce1c351dafc..b5f3c0b3d92532e05c680054a161f05e0ddd646b 100644 >--- a/Tools/WebGPUShadingLanguageRI/TypeRef.js >+++ b/Tools/WebGPUShadingLanguageRI/TypeRef.js >@@ -1,5 +1,5 @@ > /* >- * Copyright (C) 2017 Apple Inc. All rights reserved. >+ * Copyright (C) 2018 Apple Inc. All rights reserved. > * > * Redistribution and use in source and binary forms, with or without > * modification, are permitted provided that the following conditions >@@ -25,28 +25,27 @@ > "use strict"; > > class TypeRef extends Type { >- constructor(origin, name, typeArguments) >+ constructor(origin, name, typeArguments = null) > { > super(); > this._origin = origin; > this._name = name; >- this.type = null; >+ this._type = null; > this._typeArguments = typeArguments; > } > > static wrap(type) > { >- if (type instanceof TypeRef && !type.typeArguments) >+ if (type instanceof TypeRef) > return type; >- let name = type.name; >- let result = new TypeRef(type.origin, name, []); >+ let result = new TypeRef(type.origin, type.name); > result.type = type; > return result; > } > >- static instantiate(type, typeArguments) >+ static instantiate(type) > { >- let result = new TypeRef(type.origin, type.name, typeArguments); >+ let result = new TypeRef(type.origin, type.name); > result.type = type; > return result; > } >@@ -55,39 +54,36 @@ class TypeRef extends Type { > get name() { return this._name; } > get typeArguments() { return this._typeArguments; } > >+ get type() >+ { >+ return this._type; >+ } >+ >+ set type(newType) >+ { >+ this._type = newType; >+ } >+ > get unifyNode() > { >- if (!this.typeArguments.length) >- return this.type.unifyNode; >- return this; >+ if (!this.type) >+ throw new Error(`No type when evaluating ${this} unifyNode`); >+ 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); >- } >- >- setTypeAndArguments(type, typeArguments) >- { >- this._name = null; >- this.type = type; >- this._typeArguments = typeArguments; >+ return this.type.isPrimitive; > } > > unifyImpl(unificationContext, other) >@@ -96,12 +92,6 @@ class TypeRef extends Type { > return false; > if (!this.type.unify(unificationContext, other.type)) > return false; >- if (this.typeArguments.length != other.typeArguments.length) >- return false; >- for (let i = 0; i < this.typeArguments.length; ++i) { >- if (!this.typeArguments[i].unify(unificationContext, other.typeArguments[i])) >- return false; >- } > return true; > } > >@@ -109,9 +99,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/TypeVariable.js b/Tools/WebGPUShadingLanguageRI/TypeVariable.js >deleted file mode 100644 >index 33218a959f51d1eeb9d0514b950dec9672fa0b7e..0000000000000000000000000000000000000000 >--- a/Tools/WebGPUShadingLanguageRI/TypeVariable.js >+++ /dev/null >@@ -1,106 +0,0 @@ >-/* >- * Copyright (C) 2017 Apple Inc. All rights reserved. >- * >- * Redistribution and use in source and binary forms, with or without >- * modification, are permitted provided that the following conditions >- * are met: >- * 1. Redistributions of source code must retain the above copyright >- * notice, this list of conditions and the following disclaimer. >- * 2. Redistributions in binary form must reproduce the above copyright >- * notice, this list of conditions and the following disclaimer in the >- * documentation and/or other materials provided with the distribution. >- * >- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY >- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE >- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR >- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR >- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, >- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, >- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR >- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY >- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT >- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE >- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. >- */ >-"use strict"; >- >-class TypeVariable extends Type { >- constructor(origin, name, protocol) >- { >- super(); >- this._origin = origin; >- this._name = name; >- this._protocol = protocol; >- } >- >- get origin() { return this._origin; } >- get name() { return this._name; } >- get protocol() { return this._protocol; } >- >- get isPrimitive() >- { >- return this._protocol && this._protocol.isPrimitive; >- } >- >- get isUnifiable() { return true; } >- >- inherits(protocol) >- { >- if (!protocol) >- return {result: true}; >- if (!this.protocol) >- return {result: false, reason: "Type variable " + this + " does not have a protocol"}; >- return this.protocol.inherits(protocol); >- } >- >- typeVariableUnify(unificationContext, other) >- { >- if (!(other instanceof Type)) >- return false; >- >- return this._typeVariableUnifyImpl(unificationContext, other); >- } >- >- unifyImpl(unificationContext, other) >- { >- return this.typeVariableUnify(unificationContext, other); >- } >- >- verifyAsArgument(unificationContext) >- { >- let realThis = unificationContext.find(this); >- >- // The thing we get unified with must be a type variable that accepts a broader set of >- // things than we do. >- if (!(realThis instanceof TypeVariable)) >- return {result: false, reason: "Type variable argument " + this + " cannot be passed to non-type-variable parameter type " + realThis}; >- >- if (!this.protocol) { >- if (realThis.protocol) >- return {result: false, reason: "Type variable without protocol " + this + " cannot be passed to parameter type variable with protocol " + realThis.protocol}; >- return {result: true}; >- } >- >- let result = this.protocol.inherits(realThis.protocol); >- if (!result.result) >- return {result: false, reason: "Protocol " + this.protocol + " does not subsume protocol " + realThis.protocol + " (passing type " + this + " to type " + realThis + "): " + result.reason}; >- return {result: true}; >- } >- >- verifyAsParameter(unificationContext) >- { >- if (!this.protocol) >- return {result: true}; >- let realThis = unificationContext.find(this); >- let result = realThis.inherits(this.protocol); >- if (!result.result) >- return {result: false, reason: "Type " + realThis + " does not inherit protocol " + this.protocol + " (passing type " + realThis + " to type " + this + "): " + result.reason}; >- return {result: true}; >- } >- >- toString() >- { >- return this.name + (this.protocol ? ":" + this.protocol.name : ""); >- } >-} >- >diff --git a/Tools/WebGPUShadingLanguageRI/TypeVariableTracker.js b/Tools/WebGPUShadingLanguageRI/TypeVariableTracker.js >deleted file mode 100644 >index 2e9e29aae1454927cd0d5139c0852391f835f7c7..0000000000000000000000000000000000000000 >--- a/Tools/WebGPUShadingLanguageRI/TypeVariableTracker.js >+++ /dev/null >@@ -1,57 +0,0 @@ >-/* >- * Copyright (C) 2017 Apple Inc. All rights reserved. >- * >- * Redistribution and use in source and binary forms, with or without >- * modification, are permitted provided that the following conditions >- * are met: >- * 1. Redistributions of source code must retain the above copyright >- * notice, this list of conditions and the following disclaimer. >- * 2. Redistributions in binary form must reproduce the above copyright >- * notice, this list of conditions and the following disclaimer in the >- * documentation and/or other materials provided with the distribution. >- * >- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY >- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE >- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR >- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR >- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, >- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, >- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR >- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY >- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT >- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE >- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. >- */ >-"use strict"; >- >-class TypeVariableTracker extends Visitor { >- constructor() >- { >- super(); >- this._set = new Set(); >- } >- >- get set() { return this._set; } >- >- _consider(thing) >- { >- if (thing.isUnifiable) >- this._set.add(thing); >- } >- >- visitTypeRef(node) >- { >- if (node.typeArguments.length) { >- for (let typeArgument of node.typeArguments) >- typeArgument.visit(this); >- return; >- } >- this._consider(node.type); >- } >- >- visitVariableRef(node) >- { >- this._consider(node.variable); >- } >-} >- >diff --git a/Tools/WebGPUShadingLanguageRI/UnificationContext.js b/Tools/WebGPUShadingLanguageRI/UnificationContext.js >index 0a13de43d5326e1357c87f8859d9d6015e0cad47..2f71547b0afbe180378f37996231862a2b91a82e 100644 >--- a/Tools/WebGPUShadingLanguageRI/UnificationContext.js >+++ b/Tools/WebGPUShadingLanguageRI/UnificationContext.js >@@ -1,5 +1,5 @@ > /* >- * Copyright (C) 2017 Apple Inc. All rights reserved. >+ * Copyright (C) 2018 Apple Inc. All rights reserved. > * > * Redistribution and use in source and binary forms, with or without > * modification, are permitted provided that the following conditions >@@ -25,9 +25,8 @@ > "use strict"; > > class UnificationContext { >- constructor(typeParameters) >+ constructor() > { >- this._typeParameters = new Set(typeParameters); > this._nextMap = new Map(); > this._extraNodes = new Set(); > } >@@ -36,19 +35,16 @@ class UnificationContext { > { > a = this.find(a); > b = this.find(b); >+ > if (a == b) > return; >- >+ > if (!a.isUnifiable) { > [a, b] = [b, a]; > if (!a.isUnifiable) > throw new Error("Cannot unify non-unifiable things " + a + " and " + b); > } >- >- // Make sure that type parameters don't end up being roots. >- if (a.isUnifiable && b.isUnifiable && this._typeParameters.has(b)) >- [a, b] = [b, a]; >- >+ > this._nextMap.set(a, b); > } > >@@ -85,52 +81,23 @@ class UnificationContext { > return result; > } > >- typeParameters() { return this._typeParameters; } > *typeArguments() > { > for (let typeArgument of this.nodes) { > if (!typeArgument.isUnifiable) > continue; >- if (this._typeParameters.has(typeArgument)) >- continue; > yield typeArgument; > } > } > > verify() > { >- // We do a two-phase pre-verification. This gives literals a chance to select a more specific type. >- let preparations = []; >- for (let node of this.nodes) { >- let preparation = node.prepareToVerify(this); >- if (preparation) >- preparations.push(preparation); >- } >- for (let preparation of preparations) { >- let result = preparation(); >- if (!result.result) >- return result; >- } >- >- for (let typeParameter of this._typeParameters) { >- let result = typeParameter.verifyAsParameter(this); >- if (!result.result) >- return result; >- } >- let numTypeVariableArguments = 0; >- let argumentSet = new Set(); > for (let typeArgument of this.typeArguments()) { > let result = typeArgument.verifyAsArgument(this); > if (!result.result) > return result; >- if (typeArgument.isLiteral) >- continue; >- argumentSet.add(this.find(typeArgument)); >- numTypeVariableArguments++; > } >- if (argumentSet.size == numTypeVariableArguments) >- return {result: true}; >- return {result: false, reason: "Type variables used as arguments got unified with each other"}; >+ return {result: true}; > } > > get conversionCost() >diff --git a/Tools/WebGPUShadingLanguageRI/VectorType.js b/Tools/WebGPUShadingLanguageRI/VectorType.js >new file mode 100644 >index 0000000000000000000000000000000000000000..5014c671a07882002c234bb32f17c8860effc1c6 >--- /dev/null >+++ b/Tools/WebGPUShadingLanguageRI/VectorType.js >@@ -0,0 +1,65 @@ >+/* >+ * Copyright (C) 2018 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 NativeType { >+ constructor(origin, name) >+ { >+ super(origin, name); >+ const match = /^([A-z]+)([0-9])$/.exec(name); >+ if (!match) >+ throw new WTypeError(origin.originString, `${name} doesn't match the format for vector type names.'`); >+ >+ this._elementType = new TypeRef(origin, match[1]); >+ this._numElementsValue = parseInt(match[2]); >+ } >+ >+ get elementType() { return this._elementType; } >+ get numElementsValue() { return this._numElementsValue; } >+ get size() { return this.elementType.size * this.numElementsValue; } >+ >+ unifyImpl(unificationContext, other) >+ { >+ if (!(other instanceof VectorType)) >+ return false; >+ >+ if (this.numElementsValue !== other.numElementsValue) >+ 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.elementType}${this.numElementsValue}`; >+ } >+} >+ >diff --git a/Tools/WebGPUShadingLanguageRI/Visitor.js b/Tools/WebGPUShadingLanguageRI/Visitor.js >index 4bf05313e2857d71efe513ee1e35f050def5336d..7d387b25f2589b873918af2f44c2434ad658747f 100644 >--- a/Tools/WebGPUShadingLanguageRI/Visitor.js >+++ b/Tools/WebGPUShadingLanguageRI/Visitor.js >@@ -1,5 +1,5 @@ > /* >- * Copyright (C) 2017 Apple Inc. All rights reserved. >+ * Copyright (C) 2018 Apple Inc. All rights reserved. > * > * Redistribution and use in source and binary forms, with or without > * modification, are permitted provided that the following conditions >@@ -34,17 +34,10 @@ class Visitor { > visitFunc(node) > { > node.returnType.visit(this); >- for (let typeParameter of node.typeParameters) >- typeParameter.visit(this); > for (let parameter of node.parameters) > parameter.visit(this); > } > >- visitProtocolFuncDecl(node) >- { >- this.visitFunc(node); >- } >- > visitFuncParameter(node) > { > node.type.visit(this); >@@ -61,12 +54,6 @@ class Visitor { > this.visitFunc(node); > } > >- visitNativeFuncInstance(node) >- { >- this.visitFunc(node); >- node.func.visitImplementationData(node.implementationData, this); >- } >- > visitBlock(node) > { > for (let statement of node.statements) >@@ -79,62 +66,25 @@ class Visitor { > expression.visit(this); > } > >- visitProtocolRef(node) >- { >- } >- >- visitProtocolDecl(node) >- { >- for (let protocol of node.extends) >- protocol.visit(this); >- for (let signature of node.signatures) >- signature.visit(this); >- } >- > visitTypeRef(node) > { >- for (let typeArgument of node.typeArguments) >- typeArgument.visit(this); > } > > visitNativeType(node) > { >- for (let typeParameter of node.typeParameters) >- typeParameter.visit(this); >- } >- >- visitNativeTypeInstance(node) >- { >- node.type.visit(this); >- for (let typeArgument of node.typeArguments) >- typeArgument.visit(this); > } > > visitTypeDef(node) > { >- for (let typeParameter of node.typeParameters) >- typeParameter.visit(this); > node.type.visit(this); > } > > visitStructType(node) > { >- for (let typeParameter of node.typeParameters) >- typeParameter.visit(this); > for (let field of node.fields) > field.visit(this); > } > >- visitTypeVariable(node) >- { >- Node.visit(node.protocol, this); >- } >- >- visitConstexprTypeParameter(node) >- { >- node.type.visit(this); >- } >- > visitField(node) > { > node.type.visit(this); >@@ -336,19 +286,8 @@ class Visitor { > > visitCallExpression(node) > { >- for (let typeArgument of node.typeArguments) >- typeArgument.visit(this); > for (let argument of node.argumentList) > Node.visit(argument, this); >- let handleTypeArguments = actualTypeArguments => { >- if (actualTypeArguments) { >- for (let argument of actualTypeArguments) >- argument.visit(this); >- } >- }; >- handleTypeArguments(node.actualTypeArguments); >- handleTypeArguments(node.instantiatedActualTypeArguments); >- Node.visit(node.nativeFuncInstance, this); > Node.visit(node.returnType, this); > Node.visit(node.resultType, this); > } >@@ -384,5 +323,10 @@ class Visitor { > { > node.target.visit(this); > } >+ >+ visitVectorType(node) >+ { >+ node.elementType.visit(this); >+ } > } > >diff --git a/Tools/WebGPUShadingLanguageRI/WSL.md b/Tools/WebGPUShadingLanguageRI/WSL.md >deleted file mode 100644 >index d3b66567826a51dd6c754d4e9b24d7578972bb3d..0000000000000000000000000000000000000000 >--- a/Tools/WebGPUShadingLanguageRI/WSL.md >+++ /dev/null >@@ -1,479 +0,0 @@ >-# WebGPU Shading Language >- >-WebGPU Shading Language, or WSL for short, is a type-safe low-overhead programming language for GPUs (graphics processing units). This document explains how WSL works. >- >-# Goals >- >-WSL is designed to achieve the following goals: >- >-- WSL should feel *familiar* to C++ programmers. >-- WSL should be have a *sound* and *decidable* type system. >-- WSL should not permit *out-of-bounds* memory accesses. >-- WSL should be have *low overhead*. >- >-The combination of a sound type system and bounds checking makes WSL a secure shader language: the language itself is responsible for isolating the shader from the rest of the GPU. >- >-# Familiar Syntax >- >-WSL is based on C syntax, but excludes features that are either unnecessary, insecure, or replaced by other WSL features: >- >-- No strings. >-- No `register`, `volatile`, `const`, `restrict`, or `extern` keywords. >-- No unions. `union` is not a keyword. >-- No goto or labels. `goto` is not a keyword. >-- No `*` pointers. >-- Effectless expressions are not statements (`a + b;` is a parse error). >-- No undefined values (`int x;` initializes x to 0). >-- No automatic type conversions (`int x; uint y = x;` is a type error). >-- No recursion. >-- No dynamic memory allocation. >-- No modularity. The whole program is one file. >- >-On top of this bare C-like foundation, WSL adds secure versions of familiar C++ features: >- >-- Type-safe pointers (`^`) and array references (`[]`). >-- Generics to replace templates. >-- Operator overloading. Built-in operations like `int operator+(int, int)` are just native functions. >-- Cast overloading. Built-in casts like `operator int(double)` are just native functions. >-- Getters and setters. Property accesses like `vec.x` resolve to overloads like `float operator.field(float4)`. >-- Array access overloading. Array accesses like `vec[0]` resolve to verloads like `float operator[](float4, uint)`. >- >-In the following sections, WSL is shown by example starting with its C-like foundation and then building up to include more sophisticated features like generics. >- >-## Common subset of C and WSL >- >-The following is a valid WSL function definition: >- >- int foo(int x, int y, bool p) >- { >- if (p) >- return x - y; >- return x + y; >- } >- >-WSL source files behave similarly to C source files: >- >-- Top-level statements must be type or function definitions. >-- WSL uses structured C control flow constructs, like `if`, `while`, `for`, `do`, `break`, and `continue`. >-- WSL uses C-like `switch` statements, but does not allow them to overlap other control flow (i.e. no [Duff's device](https://en.wikipedia.org/wiki/Duff%27s_device)). >-- WSL allows variable declarations anywhere C++ would. >- >-WSL types differ from C types. For example, this is an array of 42 integers in WSL: >- >- int[42] array; >- >-The type never surrounds the variable, like it would in C (`int array[42]`). >- >-## Type-safe pointers >- >-WSL includes a secure pointer type. To emphasize that it is not like the C pointer, WSL uses `^` for the pointer type and for dereference. Like in C, `&` is used to take the address of a value. Because GPUs have different kinds of memories, pointers must be annotated with an address space (one of `thread`, `threadgroup`, `device`, or `constant`). For example: >- >- void bar(thread int^ p) >- { >- ^p += 42; >- } >- int foo() >- { >- int x = 24; >- bar(&x); >- return x; // Returns 66. >- } >- >-Pointers can be `null`. Each pointer access is null-checked, though most pointer accesses (like this one) will not have a null check. WSL places enough constraints on the programmer that programs are easy for the compiler to analyze. The compiler will always know that `^p += 42` adds `42` to `x` in this case. >- >-WSL pointers do not support casting or pointer arithmetic. All memory accessible to a shader outlives the shader. This is even true of local variables. This is possible because WSL does not support recursion. Therefore, local variables simply get global storage. Local variables are initialized at the point of their declaration. Hence, the following is a valid program, which will exhibit the same behavior on every WSL implementation: >- >- thread int^ foo() >- { >- int x = 42; >- return &x; >- } >- int bar() >- { >- thread int^ p = foo(); >- thread int^ q = foo(); >- ^p = 53; >- return ^q; // Returns 53. >- } >- int baz() >- { >- thread int^ p = foo(); >- ^p = 53; >- foo(); >- return ^p; // Returns 42. >- } >- >-It's possible to point to any kind of data type. For example, `thread double[42]^` is a pointer to an array of 42 doubles. >- >-## Type-safe array references >- >-WSL supports array references that carry a pointer to the base of the array and the array's length. This allows accesses to the array to be bounds-checked. >- >-An array reference can be created using the `@` operator: >- >- int[42] array; >- thread int[] arrayRef = @array; >- >-Both arrays and array references can be loaded from and stored to using `operator[]`: >- >- int x = array[i]; >- int y = arrayRef[i]; >- >-Both arrays and array references know their length: >- >- uint arrayLength = array.length; >- uint arrayRefLength = arrayRef.length; >- >-Given an array or array reference, it's possible to get a pointer to one of its elements: >- >- thread int^ ptr1 = &array[i]; >- thread int^ ptr2 = &arrayRef[i]; >- >-A pointer is like an array reference with one element. It's possible to perform this conversion: >- >- thread int[] ref = @ptr1; >- ref[0] // Equivalent to ^ptr1. >- ref.length // 0 if ptr1 was null, 1 if ptr1 was not null. >- >-Similarly, using `@` on a non-pointer value results in a reference of length 1: >- >- int x; >- thread int[] ref = @x; >- ref[0] // Aliases x. >- ref.length // Returns 1. >- >-It's not legal to use `@` on an array reference: >- >- thread int[] ref; >- thread int[][] referef = @ref; // Error! >- >-## Generics >- >-WSL supports generic types using a simple syntax. WSL's generic are designed to integrate cleanly into the compiler pipeline: >- >-- Generics have unambiguous syntax. >-- Generic functions can be type checked before they are instantiated. >- >-Semantic errors inside generic functions show up once regardless of the number of times the generic function is instantiated. >- >-This is a simple generic function: >- >- T identity<T>(T value) >- { >- T tmp = value; >- return tmp; >- } >- >-WSL also supports structs, which are also allowed to be generic: >- >- // Not generic. >- struct Foo { >- int x; >- double y; >- } >- // Generic. >- struct Bar<T, U> { >- T x; >- U y; >- } >- >-Type parameters can also be constant expressions. For example: >- >- void initializeArray<T, uint length>(thread T[length]^ array, T value) >- { >- for (uint i = length; i--;) >- (^array)[i] = value; >- } >- >-Constant expressions passed as type arguments must obey a very narrow definition of constantness. Only literals and references to other constant parameters qualify. >- >-WSL is guaranteed to compile generics by instantiation. This is observable, since functions can return pointers to their locals. Here is an example of this phenomenon: >- >- thread int^ allocate<uint>() >- { >- int x; >- return &x; >- } >- >-The `allocate` function will return a different pointer for each unsigned integer constant passed as a type parameter. This allocation is completely static, since the `uint` parameter must be given a compile-time constant. >- >-WSL's `typedef` uses a slightly different syntax than C. For example: >- >- struct Complex<T> { >- T real; >- T imag; >- } >- typedef FComplex = Complex<float>; >- >-`typedef` can be used to create generic types: >- >- struct Foo<T, U> { >- T x; >- U y; >- } >- typedef Bar<T> = Foo<T, T>; >- >-## Protocols >- >-Protocols enable generic functions to work with data of generic type. Because a function must be type-checkable before instantiation, the following would not be legal: >- >- int bar(int) { ... } >- double bar(double) { ... } >- >- T foo<T>(T value) >- { >- return bar(value); // Error! >- } >- >-The call to `bar` doesn't type check because the compiler cannot know that `foo<T>` will be instantiated with `T = int` or `T = double`. Protocols enable the programmer to tell the compiler what to expect of a type variable: >- >- int bar(int) { ... } >- double bar(double) { ... } >- >- protocol SupportsBar { >- SupportsBar bar(SupportsBar); >- } >- >- T foo<T:SupportsBar>(T value) >- { >- return bar(value); >- } >- >- int x = foo(42); >- double y = foo(4.2); >- >-Protocols have automatic relationships to one another based on what functions they contain: >- >- protocol Foo { >- void foo(Foo); >- } >- protocol Bar { >- void foo(Bar); >- void bar(Bar); >- } >- void fuzz<T:Foo>(T x) { ... } >- void buzz<T:Bar>(T x) >- { >- fuzz(x); // OK, because Bar is more specific than Foo. >- } >- >-Protocols can also mix other protocols in explicitly. Like in the example above, the example below relies on the fact that `Bar` is a more specific protocol than `Foo`. However, this example declares this explicitly (`protocol Bar : Foo`) instead of relying on the language to infer it: >- >- protocol Foo { >- void foo(Foo); >- } >- protocol Bar : Foo { >- void bar(Bar); >- } >- void fuzz<T:Foo>(T x) { ... } >- void buzz<T:Bar>(T x) >- { >- fuzz(x); // OK, because Bar is more specific than Foo. >- } >- >-## Overloading >- >-WSL supports overloading very similarly to how C++ does it. For example: >- >- void foo(int); // 1 >- void foo(double); // 2 >- >- int x; >- foo(x); // calls 1 >- >- double y; >- foo(y); // calls 2 >- >-WSL automatically selects the most specific overload if given multiple choices. For example: >- >- void foo(int); // 1 >- void foo(double); // 2 >- void foo<T>(T); // 3 >- >- foo(1); // calls 1 >- foo(1.); // calls 2 >- foo(1u); // calls 3 >- >-Generic functions like `foo<T>` can be called with or without all of their type arguments supplied. If they are not supplied, the function participates in overload resolution like any other function would. Functions are ranked by how specific they are; function A is more specific than function B if A's parameter types can be used as argument types for a call to B but not vice-versa. If one functions more specific than all others then this function is selected, otherwise a type error is issued. >- >-## Operator Overloading >- >-Many WSL operations desugar to calls to functions. Those functions are called *operator overloads* and are declared using syntax that involves the keyword `operator`. The following operations result in calls to operator overloads: >- >-- Numerical operators (`+`, `-`, `*`, `/`, etc.). >-- Increment and decrement (`++`, `--`). >-- Casting (`type(value)`). >-- Accessing values in arrays (`[]`, `[]=`, `&[]`). >-- Accessing fields (`.field`, `.field=`, `&.field`). >- >-WSL's operator overloading is designed to synthesize many operators for you: >- >-- Read-modify-write operators like `+=` are desugared to a load of the load value, the underlying operator (like `+`), and a store of the new value. It's not possible to override `+=`, `-=`, etc. >-- `x++` and `++x` both call the same operator overload. `operator++` takes the old value and returns a new one; for example the built-in `++` for `int` could be written as: `int operator++(int value) { return value + 1; }`. >-- `operator==` can be overloaded, but `!=` is automatically synthesized and cannot be overloaded. >- >-Some operators and overloads are restricted: >- >-- `!`, `&&`, and `||` are built-in operations on the `bool` type. >-- Self-casts (`T(T)`) are always the identity function. >-- Casts with no arguments (`T()`) always return the default value for that type. Every type has a default value (`0`, `null`, or the equivalent for each field). >- >-Cast overloading allows for supporting conversions between types and for creating constructors for custom types. Here is an example of cast overloading being used to create a constructor: >- >- 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; >- } >- >- Complex<float> i = Complex<float>(0, 1); >- >-WSL supports accessor overloading as part of the operator overloading syntax. This gives the programmer broad powers. For example: >- >- struct Foo { >- int x; >- int y; >- } >- int operator.sum(Foo foo) >- { >- return foo.x + foo.y; >- } >- >-It's possible to say `foo.sum` to call the `operator.sum` function. Both getters and setters can be provided: >- >- struct Foo { >- int value; >- } >- double operator.doubleValue(Foo value) >- { >- return double(value.value); >- } >- Foo operator.doubleValue=(Foo value, double doubleValue) >- { >- value.value = int(doubleValue); >- return value; >- } >- >-Providing both getter and setter overloads makes `doubleValue` behave almost as if it was a field of `Foo`. For example, it's possible to say: >- >- Foo foo; >- foo.value = 42; >- foo.doubleValue *= 2; // Now foo.value is 84 >- >-It's also possible to provide an address-getting overload called an *ander*: >- >- struct Foo { >- int value; >- } >- thread int^ operator&.valueAlias(thread Foo^ foo) >- { >- return &foo->value; >- } >- >-Providing just this overload for a pointer type in every address space gives the same power as overloading getters and setters. Additionally, it makes it possible to `&foo.valueAlias`. >- >-The same overloading power is provided for array accesses. For example: >- >- struct Vector<T> { >- T x; >- T y; >- } >- thread T^ operator&[](thread T^ ptr, uint index) >- { >- return index ? &ptr->y : &ptr->x; >- } >- >-Alternatively, it's possible to overload getters and setters (`operator[]` and `operator[]=`). >- >-# Mapping of API concepts >- >-WSL is designed to be useful as both a graphics shading language and as a computation language. However, these two environments have >-slightly different semantics. >- >-When using WSL as a graphics shading language, there is a distinction between *entry-points* and *non-entry-points*. Entry points are top-level functions which have either the `vertex` or `fragment` keyword in front of their declaration. Entry points may not be forward declared. An entry point annotated with the `vertex` keyword may not be used as a fragment shader, and an entry point annotated with the `fragment` keyword may not be used as a vertex shader. No argument nor return value of an entry point may be a pointer. Entry points must not accept type arguments (also known as "generics"). >- >-## Vertex entry points >- >-WebGPU's API passes data to a WSL vertex shader in four ways: >- >-- Attributes >-- Buffered data >-- Texture data >-- Samplers >- >-Each of these API objects is referred to by name from the API. Variables in WSL are not annotated with extra API-visible names (like they are in some other graphics APIs). >- >-Variables are passed to vertex shaders as arguments to a vertex entry point. Each buffer is represented as an argument with an array reference type (using the `[]` syntax). Textures and samplers are represented by arguments with the `texture` and `sampler` types, respectively. All other non-builtin arguments to a vertex entry point are implied to be attributes. >- >-Some arguments are recognized by the compiler from their name and type. These arguments provide built-in functionality inherent in the graphics pipeline. For example, an argument of the form `int wsl_vertexID` refers to the ID of the current vertex, and is not recognized as an attribute. All non-builtin arguments to a vertex entry point must be associated with an API object whenever any draw call using the vertex entry point is invoked. Otherwise, the draw call will fail. >- >-The only way to pass data between successive shader stages within a single draw call is by return value. An entry point must indicate that it returns a collection of values contained within a structure. Every variable inside this structure, recursively, is passed to the next stage in the graphics pipeline. Members of this struct may also be output built-in variables. For example, a vertex entry point may return a struct which contains a member `float4 wsl_Position`, and this variable will represent the rasterized position of the vertex. Buffers (as described by WSL array references), textures, and samplers must not be present in this returned struct. Built-in variables must never appear twice inside the returned structure. >- >-## Fragment entry points >- >-Fragment entry points may accept one argument with the type that the previous shader stage returned. The argument name for this argument must be `stageIn`. In addition to this argument, fragment entry points may accept buffers, textures, and samplers as arguments in the same way that vertex entry points accept them. Fragment entry points also must return a struct, and all members of this struct must be built-in variables. The set of recognized built-in variables which may be accepted or returned from an entry point is different between all types of entry points. >- >-For example, this would be a valid graphics program: >- >- struct VertexInput { >- float2 position; >- float3 color; >- } >- >- struct VertexOutput { >- float4 wsl_Position; >- float3 color; >- } >- >- struct FragmentOutput { >- float4 wsl_Color; >- } >- >- vertex VertexOutput vertexShader(VertexInput vertexInput) { >- VertexOutput result; >- result.wsl_Position = float4(vertexInput.position, 0., 1.); >- result.color = vertexInput.color; >- return result; >- } >- >- fragment FragmentOutput fragmentShader(VertexOutput stageIn) { >- FragmentOutput result; >- result.wsl_Color = float4(stageIn.color, 1.); >- return result; >- } >- >-## Compute entry points >- >-WebGPU's API passes data to a compute shader in three ways: >- >-- Buffered data >-- Texture data >-- Samplers >- >-Compute entry points start with the keyword `compute`. The return type for a compute entry point must be `void`. Each buffer is represented as an argument with an array reference type (using the `[]` syntax). Textures and samplers are represented by arguments with the `texture` and `sampler` types, respectively. Compute entry points may also accept built-in variables as arguments. Arguments of any other type are disallowed. Arguments may not use the `threadgroup` memory space. >- >-# Error handling >- >-Errors may occur during shader processing. For example, the shader may attempt to dereference a `null` array reference. If this occurs, the shader stage immediately completes successfully. The entry point immediately returns a struct with all fields set to 0. After this event, subsequent shader stages will proceed as if there was no problem. >- >-Buffer and texture reads and writes before the error all complete, and have the same semantics as if no error had occurred. Buffer and texture reads and writes after the error do not occur. >- >-# Summary >- >-WSL is a type-safe language based on C syntax. It eliminates some C features, like unions and pointer casts, but adds other modern features in their place, like generics and overloading. >- >-# Additional Limitations >- >-The following additional limitations may be placed on a WSL program: >- >-- `device`, `constant`, and `threadgroup` pointers cannot point to data that may have pointers in it. This safety check is not done as part of the normal type system checks. It's performed only after instantiation. >-- Pointers and array references (collectively, *references*) may be restricted to support compiling to SPIR-V *logical mode*. In this mode, arrays must not transitively hold references. References must be initialized upon declaration and never reassigned. Functions that return references must have one return point. Ternary expressions may not return references. >-- Graphics entry points must transitively never refer to the `threadgroup` memory space. >- >- >diff --git a/Tools/WebGPUShadingLanguageRI/WrapChecker.js b/Tools/WebGPUShadingLanguageRI/WrapChecker.js >index 4cadc7d0d9e6a6dfda555dab89d0271770dbd9a7..e14209da4324d78680b6a726bbb8106836931b81 100644 >--- a/Tools/WebGPUShadingLanguageRI/WrapChecker.js >+++ b/Tools/WebGPUShadingLanguageRI/WrapChecker.js >@@ -1,5 +1,5 @@ > /* >- * Copyright (C) 2017 Apple Inc. All rights reserved. >+ * Copyright (C) 2018 Apple Inc. All rights reserved. > * > * Redistribution and use in source and binary forms, with or without > * modification, are permitted provided that the following conditions >@@ -52,11 +52,6 @@ class WrapChecker extends Visitor { > throw new Error("Found unwrapped " + node.constructor.name + " at " + originString(node) + ": " + node + "\nWhile visiting " + this._startNode.constructor.name + " at " + originString(this._startNode.origin) + ": " + this._startNode); > } > >- visitConstexprTypeParameter(node) >- { >- this._foundUnwrapped(node); >- } >- > visitFuncParameter(node) > { > this._foundUnwrapped(node); >@@ -77,13 +72,5 @@ class WrapChecker extends Visitor { > this._foundUnwrapped(node); > } > >- visitTypeVariable(node) >- { >- this._foundUnwrapped(node); >- } >- >- // NOTE: This does not know how to handle NativeTypeInstance, because this is never called on instantiated >- // code. Once code is instantiated, you cannot instantiate it further. >- > // NOTE: This needs to be kept in sync with AutoWrapper. > } >diff --git a/Tools/WebGPUShadingLanguageRI/index.html b/Tools/WebGPUShadingLanguageRI/index.html >index 8094b193781b4aa9b0c3909e9a91d2815f2b2aba..4c93a33e6a38662e8ba1e842403d4c02d5e9f9df 100644 >--- a/Tools/WebGPUShadingLanguageRI/index.html >+++ b/Tools/WebGPUShadingLanguageRI/index.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> >@@ -22,6 +23,12 @@ > <script src="Block.js"></script> > <script src="BoolLiteral.js"></script> > <script src="Break.js"></script> >+<script src="BuiltinVectorConstructors.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="CallExpression.js"></script> > <script src="CallFunction.js"></script> > <script src="Check.js"></script> >@@ -36,7 +43,6 @@ > <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> >@@ -55,7 +61,6 @@ > <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> >@@ -63,7 +68,6 @@ > <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> >@@ -73,7 +77,6 @@ > <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> >@@ -90,12 +93,12 @@ > <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="OriginKind.js"></script> > <script src="OverloadResolutionFailure.js"></script> > <script src="Parse.js"></script> >@@ -103,14 +106,11 @@ > <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="RemoveTypeArguments.js"></script> > <script src="ResolveNames.js"></script> > <script src="ResolveOverloadImpl.js"></script> > <script src="ResolveProperties.js"></script> >@@ -122,19 +122,18 @@ > <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="SynthesizeOperatorBool.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> >@@ -142,6 +141,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> >@@ -201,8 +201,6 @@ let availableVertexShaders; > let availableFragmentShaders; > let currentVertexShader; > let currentFragmentShader; >-let inlinedVertexShader; >-let inlinedFragmentShader; > let allArgumentInfos; > let argumentEPtrs; > let stageInArgumentIndex; >@@ -344,12 +342,11 @@ function selectedShadersChanged(fromCompilation = false) { > currentVertexShader = availableVertexShaders[vertexShaderSelect.selectedIndex]; > currentFragmentShader = availableFragmentShaders[fragmentShaderSelect.selectedIndex]; > >- inlinedVertexShader = program.funcInstantiator.getUnique(currentVertexShader, []); >- _inlineFunction(program, inlinedVertexShader, new VisitingSet(currentVertexShader)); >+ _inlineFunction(program, currentVertexShader, new VisitingSet(currentVertexShader)); > > allArgumentInfos = []; > argumentEPtrs = []; >- for (let parameter of inlinedVertexShader.parameters) { >+ for (let parameter of currentVertexShader.parameters) { > let ePtr = new EPtr(new EBuffer(parameter.type.size), 0); > argumentEPtrs.push({ePtr: ePtr, size: parameter.type.size}); > let gatherer = new FlattenedStructOffsetGatherer(parameter.name); >@@ -389,7 +386,7 @@ function selectedShadersChanged(fromCompilation = false) { > } > > function runShaders() { >- let func = inlinedVertexShader; >+ let func = currentVertexShader; > > let index = 0; > for (let i = 0; i < dataTable.children.length; ++i) { >@@ -399,18 +396,16 @@ function runShaders() { > let value = childElement.children[1].firstChild.value; > let argumentInfo = allArgumentInfos[index]; > let type = argumentInfo.type; >+ // FIXME: Add support for all the other scalar types > switch (type) { >- case "float32": >+ case "float": > value = Math.fround(parseFloat(value)); > argumentInfo.ePtr.set(argumentInfo.offset, value); > break; >- case "float64": >- value = parseFloat(value); >- break; >- case "int32": >+ case "int": > value = parseInt(value) | 0; > break; >- case "uint32": >+ case "uint": > value = parseInt(value) >>> 0; > break; > default: >@@ -426,9 +421,8 @@ function runShaders() { > func.parameters[i].ePtr.copyFrom(argumentEPtrs[i].ePtr, argumentEPtrs[i].size); > let result = new Evaluator(program).runFunc(func); > >- inlinedFragmentShader = program.funcInstantiator.getUnique(currentFragmentShader, []); >- _inlineFunction(program, inlinedFragmentShader, new VisitingSet(currentFragmentShader)); >- func = inlinedFragmentShader; >+ _inlineFunction(program, currentFragmentShader, new VisitingSet(currentFragmentShader)); >+ func = currentFragmentShader; > > func.parameters[stageInArgumentIndex].ePtr.copyFrom(result, func.parameters[stageInArgumentIndex].type.size); >
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