WebKit Bugzilla
Attachment 347673 Details for
Bug 188773
: [WHLSL] Allow native types to have type arguments (like "vector<float, 4>")
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
New Account
|
Log In
Remember
[x]
|
Forgot Password
Login:
[x]
[patch]
WIP
bug-188773-20180821130351.patch (text/plain), 54.25 KB, created by
Myles C. Maxfield
on 2018-08-21 13:03:52 PDT
(
hide
)
Description:
WIP
Filename:
MIME Type:
Creator:
Myles C. Maxfield
Created:
2018-08-21 13:03:52 PDT
Size:
54.25 KB
patch
obsolete
>Subversion Revision: 235099 >diff --git a/Tools/ChangeLog b/Tools/ChangeLog >index 16a144fa6d071bfcafff4a330f4c1e0e3260d238..4d5801e0de9e95de5e0088921847632875b09ffa 100644 >--- a/Tools/ChangeLog >+++ b/Tools/ChangeLog >@@ -1,3 +1,31 @@ >+2018-08-20 Myles C. Maxfield <mmaxfield@apple.com> >+ >+ [WHLSL] Allow native types to have type arguments (like "vector<float, 4>") >+ https://bugs.webkit.org/show_bug.cgi?id=188773 >+ >+ Reviewed by NOBODY (OOPS!). >+ >+ * WebGPUShadingLanguageRI/Intrinsics.js: >+ (Intrinsics.cast): >+ (Intrinsics.bitwiseCast): >+ (Intrinsics.castToHalf): >+ (Intrinsics.): >+ (Intrinsics): >+ * WebGPUShadingLanguageRI/NativeType.js: >+ (NativeType): >+ (NativeType.prototype.get typeArguments): >+ (NativeType.prototype.toString): >+ (NativeType.create): >+ * WebGPUShadingLanguageRI/Parse.js: >+ (isCallExpression): >+ (parseNative): >+ * WebGPUShadingLanguageRI/StandardLibrary.js: >+ (bool.operator): >+ * WebGPUShadingLanguageRI/VectorType.js: >+ (VectorType): >+ (VectorType.prototype.get elementType): >+ (VectorType.prototype.get numElementsValue): >+ > 2018-08-20 Jonathan Bedard <jbedard@apple.com> > > WebKitTestRunner: Add watchOS entitlements >diff --git a/Tools/WebGPUShadingLanguageRI/All.js b/Tools/WebGPUShadingLanguageRI/All.js >index 81525273ae65a14865964a13da45ce94ef10684a..bd093af54cf1cf76676225cd32ff405c64945415 100644 >--- a/Tools/WebGPUShadingLanguageRI/All.js >+++ b/Tools/WebGPUShadingLanguageRI/All.js >@@ -157,6 +157,7 @@ load("TrapStatement.js"); > load("TypeDef.js"); > load("TypeDefResolver.js"); > load("TypeRef.js"); >+load("TypeOverloadResolutionFailure.js"); > load("TypedValue.js"); > load("UintLiteral.js"); > load("UintLiteralType.js"); >@@ -170,4 +171,4 @@ load("WSyntaxError.js"); > load("WTrapError.js"); > load("WTypeError.js"); > load("WhileLoop.js"); >-load("WrapChecker.js"); >\ No newline at end of file >+load("WrapChecker.js"); >diff --git a/Tools/WebGPUShadingLanguageRI/CallExpression.js b/Tools/WebGPUShadingLanguageRI/CallExpression.js >index 6dba1532946cda78d7955c564bacccb68230762c..ae2741e775c37fff8d70df02c3efd078c26f054c 100644 >--- a/Tools/WebGPUShadingLanguageRI/CallExpression.js >+++ b/Tools/WebGPUShadingLanguageRI/CallExpression.js >@@ -66,7 +66,6 @@ class CallExpression extends Expression { > overload.func = func; > } > >- > if (!overload.func) { > failures.push(...overload.failures); > let message = "Did not find function named " + this.name + " for call with "; >diff --git a/Tools/WebGPUShadingLanguageRI/Checker.js b/Tools/WebGPUShadingLanguageRI/Checker.js >index 1a14c866aced4112b180f69156c06d2b664d87e2..afca02b088cdfc58a71233d28b01f5da13f25bae 100644 >--- a/Tools/WebGPUShadingLanguageRI/Checker.js >+++ b/Tools/WebGPUShadingLanguageRI/Checker.js >@@ -245,9 +245,13 @@ class Checker extends Visitor { > > visitTypeRef(node) > { >- if (!node.type) >+ if (!node.type && !node.possibleOverloads) > throw new Error("Type reference without a type in checker: " + node + " at " + node.origin); >- if (!(node.type instanceof StructType)) >+ if (!node.type) >+ node.resolve(node.possibleOverloads, this._program); >+ if (!node.type) >+ throw new Error("Type reference without a type after possibly resolving in checker: " + node + " at " + node.origin); >+ if (!(node.type instanceof StructType)) // Why don't we recurse on StructTypes? > node.type.visit(this); > } > >diff --git a/Tools/WebGPUShadingLanguageRI/InferTypesForCall.js b/Tools/WebGPUShadingLanguageRI/InferTypesForCall.js >index 5f32ed1c490a7df8941e919c130cf65eaa8b6a4d..bcfeb986caff49f0287a83678bf11562847f0389 100644 >--- a/Tools/WebGPUShadingLanguageRI/InferTypesForCall.js >+++ b/Tools/WebGPUShadingLanguageRI/InferTypesForCall.js >@@ -36,12 +36,8 @@ function inferTypesForCall(func, argumentTypes, returnType) > if (!argumentTypes[i].unify(unificationContext, func.parameters[i].type)) > return {failure: new OverloadResolutionFailure(func, "Argument #" + (i + 1) + " " + (func.parameters[i].name ? "for parameter " + func.parameters[i].name + " " : "") + "does not match (passed " + argumentTypes[i] + ", require " + func.parameters[i].type + ")")}; > } >- if (returnType && !returnType.unify(unificationContext, func.returnType)) { >- if (func.returnType.toString() == "vector") { >- returnType.unify(unificationContext, func.returnType) >- } >+ if (returnType && !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)}; >@@ -49,3 +45,21 @@ function inferTypesForCall(func, argumentTypes, returnType) > return {func, unificationContext}; > } > >+function inferTypesForTypeArguments(type, typeArguments) >+{ >+ if (typeArguments.length != type.typeArguments.length) >+ return {failure: new TypeOverloadResolutionFailure(type, "Wrong number of arguments (passed " + typeArguments.length + ", require " + type.typeArguments.length + ")")}; >+ let unificationContext = new UnificationContext(); >+ >+ for (let i = 0; i < typeArguments.length; ++i) { >+ if (!typeArguments[i]) >+ throw new Error("Null type argument at i = " + i); >+ if (!typeArguments[i].unify(unificationContext, type.typeArguments[i])) >+ return {failure: new TypeOverloadResolutionFailure(type, "Argument #" + (i + 1) + " " + (type.typeArguments[i].name ? "for parameter " + type.typeArguments[i].name + " " : "") + "does not match (passed " + typeArguments[i] + ", require " + type.typeArguments[i].type + ")")}; >+ } >+ let verificationResult = unificationContext.verify(); >+ if (!verificationResult.result) >+ return {failure: new TypeOverloadResolutionFailure(type, verificationResult.reason)}; >+ >+ return {type, unificationContext}; >+} >diff --git a/Tools/WebGPUShadingLanguageRI/Intrinsics.js b/Tools/WebGPUShadingLanguageRI/Intrinsics.js >index 50d40c0c0e47e112bc74ccfccb7049427116b0fb..fd32bc28b3b59ca2c912c8f2ea45abd355757136 100644 >--- a/Tools/WebGPUShadingLanguageRI/Intrinsics.js >+++ b/Tools/WebGPUShadingLanguageRI/Intrinsics.js >@@ -33,15 +33,7 @@ class Intrinsics { > // 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 "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", >- type => { >- this.void = type; >- type.size = 0; >- type.populateDefaultValue = () => { }; >- }); >- >+ > function isBitwiseEquivalent(left, right) > { > let doubleArray = new Float64Array(1); >@@ -56,58 +48,83 @@ class Intrinsics { > return true; > } > >+ function cast(typedArrayConstructor, number) >+ { >+ var array = new typedArrayConstructor(1); >+ array[0] = number; >+ return array[0]; >+ } >+ >+ function bitwiseCast(typedArrayConstructor1, typedArrayConstructor2, value) >+ { >+ let typedArray1 = new typedArrayConstructor1(1); >+ let typedArray2 = new typedArrayConstructor2(typedArray1.buffer); >+ typedArray1[0] = value; >+ return typedArray2[0]; >+ } >+ >+ function castToHalf(number) >+ { >+ // FIXME: Make this math obey IEEE 754. >+ if (Number.isNaN(number)) >+ return number >+ if (number > 65504) >+ return Number.POSITIVE_INFINITY; >+ if (number < -65504) >+ return Number.NEGATIVE_INFINITY; >+ if (number > 0 && number < Math.pow(2, -24)) >+ return 0; >+ if (number < 0 && number > -Math.pow(2, -24)) >+ return -0; >+ let doubleArray = new Float64Array(1); >+ let uintArray = new Uint8Array(doubleArray.buffer); >+ doubleArray[0] = number; >+ let sign = uintArray[7] & 0x80; >+ let exponent = ((uintArray[7] & 0x7f) << 4) | ((uintArray[6] & 0xf0) >>> 4); >+ let significand = ((uintArray[6] & 0x0f) << 6) | ((uintArray[5] & 0xfc) >>> 2); >+ >+ if ((exponent - 1023) < -14) { >+ exponent = 0; >+ significand = (Math.abs(number) * Math.pow(2, 24)) >>> 0; >+ let value = Math.pow(2, -14) * significand / 1024; >+ if (sign != 0) >+ value *= -1; >+ return value; >+ } >+ >+ doubleArray[0] = 0; >+ >+ uintArray[7] |= sign; >+ uintArray[7] |= (exponent >>> 4); >+ uintArray[6] |= ((exponent << 4) & 0xf0); >+ uintArray[6] |= (significand >>> 6); >+ uintArray[5] |= ((significand << 2) & 0xfc); >+ >+ return doubleArray[0]; >+ } >+ > this._map.set( >- "native typedef int", >+ "native typedef void", > type => { >- this.int = type; >- type.isPrimitive = true; >- type.isInt = true; >- type.isNumber = true; >- type.isSigned = true; >- type.canRepresent = value => isBitwiseEquivalent(value | 0, value); >- type.size = 1; >- type.defaultValue = 0; >- type.createLiteral = (origin, value) => IntLiteral.withType(origin, value | 0, type); >- type.successorValue = value => (value + 1) | 0; >- type.valuesEqual = (a, b) => a === b; >- type.populateDefaultValue = (buffer, offset) => buffer.set(offset, 0); >- type.formatValueFromIntLiteral = value => value | 0; >- type.formatValueFromUintLiteral = value => value | 0; >- type.allValues = function*() { >- for (let i = 0; i <= 0xffffffff; ++i) { >- let value = i | 0; >- yield {value: value, name: value}; >- } >- }; >+ this.void = type; >+ type.size = 0; >+ type.populateDefaultValue = () => { }; > }); > > this._map.set( >- "native typedef uint", >+ "native typedef bool", > type => { >- this.uint = type; >+ this.bool = type; > type.isPrimitive = true; >- type.isInt = true; >- type.isNumber = true; >- type.isSigned = false; >- type.canRepresent = value => isBitwiseEquivalent(value >>> 0, value); > type.size = 1; >- type.defaultValue = 0; >- type.createLiteral = (origin, value) => IntLiteral.withType(origin, value >>> 0, type); >- type.successorValue = value => (value + 1) >>> 0; >- type.valuesEqual = (a, b) => a === b; >- type.populateDefaultValue = (buffer, offset) => buffer.set(offset, 0); >- type.formatValueFromIntLiteral = value => value >>> 0; >- type.formatValueFromUintLiteral = value => value >>> 0; >- type.allValues = function*() { >- for (let i = 0; i <= 0xffffffff; ++i) >- yield {value: i, name: i}; >- }; >+ type.populateDefaultValue = (buffer, offset) => buffer.set(offset, false); > }); > > this._map.set( > "native typedef uchar", > type => { > this.uchar = type; >+ type.isPrimitive = true; > type.isInt = true; > type.isNumber = true; > type.isSigned = false; >@@ -126,149 +143,295 @@ class Intrinsics { > }; > }); > >+ >+ this._map.set( >+ "native typedef ushort", >+ type => { >+ this.ushort = type; >+ type.isPrimitive = true; >+ type.isInt = true; >+ type.isNumber = true; >+ type.isSigned = false; >+ type.canRepresent = value => isBitwiseEquivalent(value & 0xffff, value); >+ type.size = 1; >+ type.defaultValue = 0; >+ type.createLiteral = (origin, value) => IntLiteral.withType(origin, value & 0xffff, type); >+ type.successorValue = value => (value + 1) & 0xffff; >+ type.valuesEqual = (a, b) => a === b; >+ type.populateDefaultValue = (buffer, offset) => buffer.set(offset, 0); >+ type.formatValueFromIntLiteral = value => value & 0xffff; >+ type.formatValueFromUintLiteral = value => value & 0xffff; >+ type.allValues = function*() { >+ for (let i = 0; i <= 0xffff; ++i) >+ yield {value: i, name: i}; >+ }; >+ }); >+ > this._map.set( >- "native typedef float", >- type => { >- this.float = type; >- type.isPrimitive = true; >- type.size = 1; >- type.isFloating = true; >- type.isNumber = true; >- type.canRepresent = value => isBitwiseEquivalent(Math.fround(value), value); >- type.populateDefaultValue = (buffer, offset) => buffer.set(offset, 0); >- type.formatValueFromIntLiteral = value => value; >- type.formatValueFromUintLiteral = value => value; >- type.formatValueFromFloatLiteral = value => Math.fround(value); >- }); >+ "native typedef uint", >+ type => { >+ this.uint = type; >+ type.isPrimitive = true; >+ type.isInt = true; >+ type.isNumber = true; >+ type.isSigned = false; >+ type.canRepresent = value => isBitwiseEquivalent(value >>> 0, value); >+ type.size = 1; >+ type.defaultValue = 0; >+ type.createLiteral = (origin, value) => IntLiteral.withType(origin, value >>> 0, type); >+ type.successorValue = value => (value + 1) >>> 0; >+ type.valuesEqual = (a, b) => a === b; >+ type.populateDefaultValue = (buffer, offset) => buffer.set(offset, 0); >+ type.formatValueFromIntLiteral = value => value >>> 0; >+ type.formatValueFromUintLiteral = value => value >>> 0; >+ type.allValues = function*() { >+ for (let i = 0; i <= 0xffffffff; ++i) >+ yield {value: i, name: i}; >+ }; >+ }); > > this._map.set( >- "native typedef bool", >- type => { >- this.bool = type; >- type.isPrimitive = true; >- type.size = 1; >- type.populateDefaultValue = (buffer, offset) => buffer.set(offset, false); >- }); >+ "native typedef char", >+ type => { >+ this.char = type; >+ type.isPrimitive = true; >+ type.isInt = true; >+ type.isNumber = true; >+ type.isSigned = true; >+ type.canRepresent = value => isBitwiseEquivalent(cast(Int8Array, value), value); >+ type.size = 1; >+ type.defaultValue = 0; >+ type.createLiteral = (origin, value) => IntLiteral.withType(origin, cast(Int8Array, value), type); >+ type.successorValue = value => cast(Int8Array, value + 1); >+ type.valuesEqual = (a, b) => a === b; >+ type.populateDefaultValue = (buffer, offset) => buffer.set(offset, 0); >+ type.formatValueFromIntLiteral = value => cast(Int8Array, value); >+ type.formatValueFromUintLiteral = value => cast(Int8Array, value); >+ type.allValues = function*() { >+ for (let i = 0; i <= 0xff; ++i) { >+ let value = cast(Int8Array, i); >+ yield {value: value, name: value}; >+ } >+ }; >+ }); >+ >+ this._map.set( >+ "native typedef short", >+ type => { >+ this.short = type; >+ type.isPrimitive = true; >+ type.isInt = true; >+ type.isNumber = true; >+ type.isSigned = true; >+ type.canRepresent = value => isBitwiseEquivalent(cast(Int16Array, value), value); >+ type.size = 1; >+ type.defaultValue = 0; >+ type.createLiteral = (origin, value) => IntLiteral.withType(origin, cast(Int16Array, value), type); >+ type.successorValue = value => cast(Int16Array, value + 1); >+ type.valuesEqual = (a, b) => a === b; >+ type.populateDefaultValue = (buffer, offset) => buffer.set(offset, 0); >+ type.formatValueFromIntLiteral = value => cast(Int16Array, value); >+ type.formatValueFromUintLiteral = value => cast(Int16Array, value); >+ type.allValues = function*() { >+ for (let i = 0; i <= 0xffff; ++i) { >+ let value = cast(Int16Array, i); >+ yield {value: value, name: value}; >+ } >+ }; >+ }); >+ >+ this._map.set( >+ "native typedef int", >+ type => { >+ this.int = type; >+ type.isPrimitive = true; >+ type.isInt = true; >+ type.isNumber = true; >+ type.isSigned = true; >+ type.canRepresent = value => isBitwiseEquivalent(value | 0, value); >+ type.size = 1; >+ type.defaultValue = 0; >+ type.createLiteral = (origin, value) => IntLiteral.withType(origin, value | 0, type); >+ type.successorValue = value => (value + 1) | 0; >+ type.valuesEqual = (a, b) => a === b; >+ type.populateDefaultValue = (buffer, offset) => buffer.set(offset, 0); >+ type.formatValueFromIntLiteral = value => value | 0; >+ type.formatValueFromUintLiteral = value => value | 0; >+ type.allValues = function*() { >+ for (let i = 0; i <= 0xffffffff; ++i) { >+ let value = i | 0; >+ yield {value: value, name: value}; >+ } >+ }; >+ }); >+ >+ this._map.set( >+ "native typedef half", >+ type => { >+ this.half = type; >+ type.isPrimitive = true; >+ type.size = 1; >+ type.isFloating = true; >+ type.isNumber = true; >+ type.canRepresent = value => isBitwiseEquivalent(castToHalf(value), value); >+ type.populateDefaultValue = (buffer, offset) => buffer.set(offset, 0); >+ type.formatValueFromIntLiteral = value => value; >+ type.formatValueFromUintLiteral = value => value; >+ type.formatValueFromFloatLiteral = value => castToHalf(value); >+ }); >+ >+ this._map.set( >+ "native typedef float", >+ type => { >+ this.float = type; >+ type.isPrimitive = true; >+ type.size = 1; >+ type.isFloating = true; >+ type.isNumber = true; >+ type.canRepresent = value => isBitwiseEquivalent(Math.fround(value), value); >+ type.populateDefaultValue = (buffer, offset) => buffer.set(offset, 0); >+ type.formatValueFromIntLiteral = value => value; >+ type.formatValueFromUintLiteral = value => value; >+ type.formatValueFromFloatLiteral = value => Math.fround(value); >+ }); >+ >+ this._map.set( >+ "native typedef atomic_int", >+ type => { >+ this.atomic_int = type; >+ // FIXME: Figure out what to put here. >+ }); >+ >+ this._map.set( >+ "native typedef atomic_uint", >+ type => { >+ this.atomic_uint = type; >+ // FIXME: Figure out what to put here. >+ }); > > for (let vectorType of VectorElementTypes) { >- for (let vectorSize of VectorElementSizes) >- this._map.set(`native typedef vector<${vectorType}, ${vectorSize}>`, type => {}); >+ for (let vectorSize of VectorElementSizes) { >+ this._map.set(`native typedef vector<${vectorType}, ${vectorSize}>`, type => { >+ this[`vector<${vectorType}, ${vectorSize}>`] = type; >+ // FIXME: Figure out what to put here. >+ }); >+ } > } >- >+ > this._map.set( > "native operator int(uint)", > func => { > func.implementation = ([value]) => EPtr.box(value.loadValue() | 0); > }); >- >+ > this._map.set( > "native operator int(uchar)", > func => { > func.implementation = ([value]) => EPtr.box(value.loadValue() | 0); > }); >- >+ > this._map.set( > "native operator int(float)", > func => { > func.implementation = ([value]) => EPtr.box(value.loadValue() | 0); > }); >- >+ > this._map.set( > "native operator uint(int)", > func => { > func.implementation = ([value]) => EPtr.box(value.loadValue() >>> 0); > }); >- >+ > this._map.set( > "native operator uint(uchar)", > func => { > func.implementation = ([value]) => EPtr.box(value.loadValue() >>> 0); > }); >- >+ > this._map.set( > "native operator uint(float)", > func => { > func.implementation = ([value]) => EPtr.box(value.loadValue() >>> 0); > }); >- >+ > this._map.set( > "native operator uchar(int)", > func => { > func.implementation = ([value]) => EPtr.box(value.loadValue() & 0xff); > }); >- >+ > this._map.set( > "native operator uchar(uint)", > func => { > func.implementation = ([value]) => EPtr.box(value.loadValue() & 0xff); > }); >- >+ > this._map.set( > "native operator uchar(float)", > func => { > func.implementation = ([value]) => EPtr.box(value.loadValue() & 0xff); > }); >- >+ > this._map.set( > "native operator float(int)", > func => { > func.implementation = ([value]) => EPtr.box(Math.fround(value.loadValue())); > }); >- >+ > this._map.set( > "native operator float(uint)", > func => { > func.implementation = ([value]) => EPtr.box(Math.fround(value.loadValue())); > }); >- >+ > this._map.set( > "native operator float(uchar)", > func => { > func.implementation = ([value]) => EPtr.box(Math.fround(value.loadValue())); > }); >- >+ > this._map.set( > "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)", > func => { > func.implementation = ([left, right]) => > EPtr.box((left.loadValue() + right.loadValue()) >>> 0); > }); >- >+ > this._map.set( > "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)", > func => { > func.implementation = ([left, right]) => > EPtr.box((left.loadValue() - right.loadValue()) | 0); > }); >- >+ > this._map.set( > "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)", > func => { > func.implementation = ([left, right]) => > EPtr.box(Math.fround(left.loadValue() - right.loadValue())); > }); >- >+ > this._map.set( > "native int operator*(int,int)", > func => { >@@ -276,229 +439,229 @@ class Intrinsics { > return EPtr.box((left.loadValue() * right.loadValue()) | 0); > }; > }); >- >+ > this._map.set( > "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)", > func => { > func.implementation = ([left, right]) => > EPtr.box(Math.fround(left.loadValue() * right.loadValue())); > }); >- >+ > this._map.set( > "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)", > func => { > func.implementation = ([left, right]) => > EPtr.box((left.loadValue() / right.loadValue()) >>> 0); > }); >- >+ > this._map.set( > "native int operator&(int,int)", > func => { > func.implementation = ([left, right]) => > EPtr.box(left.loadValue() & right.loadValue()); > }); >- >+ > this._map.set( > "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)", > func => { > func.implementation = ([left, right]) => > EPtr.box(left.loadValue() | right.loadValue()); > }); >- >+ > this._map.set( > "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)", > func => { > func.implementation = ([left, right]) => > EPtr.box(left.loadValue() ^ right.loadValue()); > }); >- >+ > this._map.set( > "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)", > func => { > func.implementation = ([left, right]) => > EPtr.box(left.loadValue() << right.loadValue()); > }); >- >+ > this._map.set( > "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)", > func => { > func.implementation = ([left, right]) => > EPtr.box(left.loadValue() >> right.loadValue()); > }); >- >+ > this._map.set( > "native uint operator>>(uint,uint)", > func => { > func.implementation = ([left, right]) => > EPtr.box(left.loadValue() >>> right.loadValue()); > }); >- >+ > this._map.set( > "native int operator~(int)", > func => { > func.implementation = ([value]) => EPtr.box(~value.loadValue()); > }); >- >+ > this._map.set( > "native uint operator~(uint)", > func => { > func.implementation = ([value]) => EPtr.box((~value.loadValue()) >>> 0); > }); >- >+ > this._map.set( > "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)", > func => { > func.implementation = ([left, right]) => > EPtr.box(left.loadValue() == right.loadValue()); > }); >- >+ > this._map.set( > "native bool operator==(uint,uint)", > func => { > func.implementation = ([left, right]) => > EPtr.box(left.loadValue() == right.loadValue()); > }); >- >+ > this._map.set( > "native bool operator==(bool,bool)", > func => { > func.implementation = ([left, right]) => > EPtr.box(left.loadValue() == right.loadValue()); > }); >- >+ > this._map.set( > "native bool operator==(float,float)", > func => { > func.implementation = ([left, right]) => > EPtr.box(left.loadValue() == right.loadValue()); > }); >- >+ > this._map.set( > "native bool operator<(int,int)", > func => { > func.implementation = ([left, right]) => > EPtr.box(left.loadValue() < right.loadValue()); > }); >- >+ > this._map.set( > "native bool operator<(uint,uint)", > func => { > func.implementation = ([left, right]) => > EPtr.box(left.loadValue() < right.loadValue()); > }); >- >+ > this._map.set( > "native bool operator<(float,float)", > func => { > func.implementation = ([left, right]) => > EPtr.box(left.loadValue() < right.loadValue()); > }); >- >+ > this._map.set( > "native bool operator<=(int,int)", > func => { > func.implementation = ([left, right]) => > EPtr.box(left.loadValue() <= right.loadValue()); > }); >- >+ > this._map.set( > "native bool operator<=(uint,uint)", > func => { > func.implementation = ([left, right]) => > EPtr.box(left.loadValue() <= right.loadValue()); > }); >- >+ > this._map.set( > "native bool operator<=(float,float)", > func => { > func.implementation = ([left, right]) => > EPtr.box(left.loadValue() <= right.loadValue()); > }); >- >+ > this._map.set( > "native bool operator>(int,int)", > func => { > func.implementation = ([left, right]) => > EPtr.box(left.loadValue() > right.loadValue()); > }); >- >+ > this._map.set( > "native bool operator>(uint,uint)", > func => { > func.implementation = ([left, right]) => > EPtr.box(left.loadValue() > right.loadValue()); > }); >- >+ > this._map.set( > "native bool operator>(float,float)", > func => { > func.implementation = ([left, right]) => > EPtr.box(left.loadValue() > right.loadValue()); > }); >- >+ > this._map.set( > "native bool operator>=(int,int)", > func => { > func.implementation = ([left, right]) => > EPtr.box(left.loadValue() >= right.loadValue()); > }); >- >+ > this._map.set( > "native bool operator>=(uint,uint)", > func => { > func.implementation = ([left, right]) => > EPtr.box(left.loadValue() >= right.loadValue()); > }); >- >+ > this._map.set( > "native bool operator>=(float,float)", > func => { >@@ -538,7 +701,7 @@ class Intrinsics { > for (let setter of BuiltinVectorSetter.functions()) > this._map.set(setter.toString(), func => setter.instantiateImplementation(func)); > } >- >+ > add(thing) > { > let intrinsic = this._map.get(thing.toString()); >diff --git a/Tools/WebGPUShadingLanguageRI/NameContext.js b/Tools/WebGPUShadingLanguageRI/NameContext.js >index 1bab3fc5602601077b3fa885a6054ab860b0a193..b111eaf2727062c079906943c70a4a76eb08bc14 100644 >--- a/Tools/WebGPUShadingLanguageRI/NameContext.js >+++ b/Tools/WebGPUShadingLanguageRI/NameContext.js >@@ -69,11 +69,26 @@ class NameContext { > return; > } > >- if (this._map.has(thing.name)) >- throw new WTypeError(thing.origin.originString, "Duplicate name: " + thing.name); >+ if (thing.kind == Type) { >+ this._set.add(thing); >+ if (thing.name == "vector") { >+ let array = this._map.get(thing.name); >+ if (!array) { >+ array = []; >+ array.kind = Type; >+ this._map.set(thing.name, array); >+ } >+ if (array.kind != Type) >+ throw new WTypeError(thing.origin.originString, "Cannot reuse type name for function: " + thing.name); >+ array.push(thing); >+ return; >+ } else { >+ if (this._map.has(thing.name)) >+ throw new WTypeError(thing.origin.originString, "Duplicate name: " + thing.name); >+ this._map.set(thing.name, thing); >+ } >+ } > >- this._set.add(thing); >- this._map.set(thing.name, thing); > } > > get(kind, name) >@@ -102,6 +117,10 @@ class NameContext { > for (let func of thing) > yield func; > return; >+ } else if (thing.kind === Type && (thing instanceof Array)) { >+ for (let type of thing) >+ yield type; >+ return; > } > yield thing; > } >@@ -163,8 +182,8 @@ class NameContext { > { > for (let value of this._map.values()) { > if (value instanceof Array) { >- for (let func of value) >- yield func; >+ for (let thing of value) >+ yield thing; > continue; > } > yield value; >diff --git a/Tools/WebGPUShadingLanguageRI/NameResolver.js b/Tools/WebGPUShadingLanguageRI/NameResolver.js >index a2af1d933467251726c427fa064b6d74c9235575..fd6132b6063282b9e9de99b13b6d1acb7aa92d6d 100644 >--- a/Tools/WebGPUShadingLanguageRI/NameResolver.js >+++ b/Tools/WebGPUShadingLanguageRI/NameResolver.js >@@ -125,7 +125,10 @@ class NameResolver extends Visitor { > type = this._nameContext.get(Type, node.name); > if (!type) > throw new WTypeError(node.origin.originString, "Could not find type named " + node.name); >- node.type = type; >+ if (type instanceof Array) >+ node.possibleOverloads = type; >+ else >+ node.type = type; > } > } > >diff --git a/Tools/WebGPUShadingLanguageRI/NativeType.js b/Tools/WebGPUShadingLanguageRI/NativeType.js >index e2d851cbccba3a97234c7bd392907829ca9e05f2..2381b5a6b0b010e0fdd4dc53550a8ea6b4f8347b 100644 >--- a/Tools/WebGPUShadingLanguageRI/NativeType.js >+++ b/Tools/WebGPUShadingLanguageRI/NativeType.js >@@ -25,11 +25,14 @@ > "use strict"; > > class NativeType extends Type { >- constructor(origin, name) >+ constructor(origin, name, typeArguments) > { >+ if (!(typeArguments instanceof Array)) >+ throw new Error("type parameters not array: " + typeArguments); > super(); > this._origin = origin; > this._name = name; >+ this._typeArguments = typeArguments; > this._isNumber = false; > this._isInt = false; > this._isFloating = false; >@@ -38,6 +41,7 @@ class NativeType extends Type { > > get origin() { return this._origin; } > get name() { return this._name; } >+ get typeArguments() { return this._typeArguments; } > get isNative() { return true; } > > // We let Intrinsics.js set these as it likes. >@@ -52,19 +56,18 @@ class NativeType extends Type { > > toString() > { >- return `native typedef ${this.name}`; >+ let result = `native typedef ${this.name}`; >+ if (this.typeArguments.length) >+ result += "<" + this.typeArguments.join(",") + ">"; >+ return result; > } > > static create(origin, name, typeArguments) > { >- // 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 (name == "vector") >+ return new VectorType(origin, name, typeArguments); > >- if (allVectorTypeNames().indexOf(name) > -1) >- return new VectorType(origin, name); >- >- return new NativeType(origin, name); >+ return new NativeType(origin, name, typeArguments); > } > } > >diff --git a/Tools/WebGPUShadingLanguageRI/Parse.js b/Tools/WebGPUShadingLanguageRI/Parse.js >index c4ae9de7fde8562969260c1469c22b586de76df9..9a2b2015fd3524bea9d604c511c27efef6cc56e9 100644 >--- a/Tools/WebGPUShadingLanguageRI/Parse.js >+++ b/Tools/WebGPUShadingLanguageRI/Parse.js >@@ -327,10 +327,12 @@ function parse(program, origin, originKind, lineNumberOffset, text) > function isCallExpression() > { > return lexer.testScope(() => { >- consumeKind("identifier"); >- parseTypeArguments(); >- consume("("); >- }); >+ consumeKind("identifier"); >+ consume("("); >+ }) || lexer.testScope(() => { >+ parseType(); >+ consume("("); >+ }); > } > > function emitIncrement(token, old, extraArg) >diff --git a/Tools/WebGPUShadingLanguageRI/Program.js b/Tools/WebGPUShadingLanguageRI/Program.js >index 06625d98fc41e74c93dece80b70ce55c7af74dd5..1116c4f577562215fdd7428a317579a929165414 100644 >--- a/Tools/WebGPUShadingLanguageRI/Program.js >+++ b/Tools/WebGPUShadingLanguageRI/Program.js >@@ -48,19 +48,25 @@ class Program extends Node { > if (statement instanceof Func) { > let array = this._functions.get(statement.name); > if (!array) >- this._functions.set(statement.name, array = []); >+ this.functions.set(statement.name, array = []); > array.push(statement); >- } else if (statement instanceof Type) >- this._types.set(statement.name, statement); >- else >+ } else if (statement instanceof Type) { >+ if (statement.isNative && statement.name == "vector") { >+ let array = this.types.get(statement.name); >+ if (!array) >+ this.types.set(statement.name, array = []); >+ array.push(statement); >+ } else >+ this.types.set(statement.name, statement); >+ } else > throw new Error("Statement is not a function or type: " + statement); >- this._topLevelStatements.push(statement); >- this._globalNameContext.add(statement); >+ this.topLevelStatements.push(statement); >+ this.globalNameContext.add(statement); > } > > toString() > { >- if (!this._topLevelStatements.length) >+ if (!this.topLevelStatements.length) > return ""; > return this._topLevelStatements.join(";") + ";"; > } >diff --git a/Tools/WebGPUShadingLanguageRI/RecursiveTypeChecker.js b/Tools/WebGPUShadingLanguageRI/RecursiveTypeChecker.js >index 91f76742f60d14a37e6e606c3ab2f9c2c8fab116..de3d524bc5488c8705fea8f67bad87becbb97ddc 100644 >--- a/Tools/WebGPUShadingLanguageRI/RecursiveTypeChecker.js >+++ b/Tools/WebGPUShadingLanguageRI/RecursiveTypeChecker.js >@@ -51,7 +51,11 @@ class RecursiveTypeChecker extends Visitor { > visitTypeRef(node) > { > super.visitTypeRef(node); >- node.type.visit(this); >+ if (node.possibleOverloads) { >+ for (let overload of node.possibleOverloads) >+ overload.visit(this); >+ } else >+ node.type.visit(this); > } > } > >diff --git a/Tools/WebGPUShadingLanguageRI/ResolveNames.js b/Tools/WebGPUShadingLanguageRI/ResolveNames.js >index 2e402c8d6c0a36098561e0275ee53e778fd384b8..b8b53342459ae839acf7f07c2bbaea96e8a54cdf 100644 >--- a/Tools/WebGPUShadingLanguageRI/ResolveNames.js >+++ b/Tools/WebGPUShadingLanguageRI/ResolveNames.js >@@ -31,8 +31,13 @@ function createNameResolver(program) > > function resolveNamesInTypes(program, nameResolver) > { >- for (let type of program.types.values()) >- nameResolver.doStatement(type); >+ for (let type of program.types.values()) { >+ if (type instanceof Array) { >+ for (let constituentType of type) >+ nameResolver.doStatement(constituentType); >+ } else >+ nameResolver.doStatement(type); >+ } > } > > function resolveNamesInFunctions(program, nameResolver) >diff --git a/Tools/WebGPUShadingLanguageRI/ResolveOverloadImpl.js b/Tools/WebGPUShadingLanguageRI/ResolveOverloadImpl.js >index d0f1e34d617ea27266467c161707154664a449ad..51ee329ab91aa838fdec24fd5161ea6de9f68022 100644 >--- a/Tools/WebGPUShadingLanguageRI/ResolveOverloadImpl.js >+++ b/Tools/WebGPUShadingLanguageRI/ResolveOverloadImpl.js >@@ -100,3 +100,28 @@ function resolveOverloadImpl(functions, argumentTypes, returnType, allowEntryPoi > > return {failures: ambiguityList.map(overload => new OverloadResolutionFailure(overload.func, message))}; > } >+ >+function resolveTypeOverloadImpl(types, typeArguments) >+{ >+ if (!functions) >+ throw new Error("Null types; that should have been caught by the caller."); >+ >+ let failures = []; >+ let successes = []; >+ for (let type of types) { >+ let overload = inferTypesForCall(func, argumentTypes, returnType); >+ if (overload.failure) >+ failures.push(overload.failure); >+ else >+ successes.push(overload); >+ } >+ >+ if (!successes.length) >+ return {failures: failures}; >+ >+ if (successes.length == 1) >+ return successes[0]; >+ >+ let message = "Ambiguous overload - types mutually applicable"; >+ return {failures: successes.map(overload => new TypeOverloadResolutionFailure(overload.type, message))}; >+} >diff --git a/Tools/WebGPUShadingLanguageRI/ResolveTypeDefs.js b/Tools/WebGPUShadingLanguageRI/ResolveTypeDefs.js >index 9143f8e1e00a049814b90a345c5af451459d8574..0574becd5531509478a2defdc2fe7c68e61c3d35 100644 >--- a/Tools/WebGPUShadingLanguageRI/ResolveTypeDefs.js >+++ b/Tools/WebGPUShadingLanguageRI/ResolveTypeDefs.js >@@ -27,8 +27,13 @@ > function resolveTypeDefsInTypes(program) > { > let resolver = new TypeDefResolver(); >- for (let type of program.types.values()) >- type.visit(resolver); >+ for (let type of program.types.values()) { >+ if (type instanceof Array) { >+ for (let constituentType of type) >+ constituentType.visit(resolver); >+ } else >+ type.visit(resolver); >+ } > } > > function resolveTypeDefsInFunctions(program) >diff --git a/Tools/WebGPUShadingLanguageRI/Rewriter.js b/Tools/WebGPUShadingLanguageRI/Rewriter.js >index b56cd60bf6fc2636ddd4341252a46aa324fb496d..34c6448120fefae655000fae77d113de76b6a113 100644 >--- a/Tools/WebGPUShadingLanguageRI/Rewriter.js >+++ b/Tools/WebGPUShadingLanguageRI/Rewriter.js >@@ -382,7 +382,7 @@ class Rewriter { > > visitVectorType(node) > { >- const vecType = new VectorType(node.origin, node.name); >+ const vecType = new VectorType(node.origin, node.name, node.typeArguments.map(argument => argument.visit(this))); > vecType._elementType = node.elementType.visit(this); > return vecType; > } >diff --git a/Tools/WebGPUShadingLanguageRI/SPIRV.html b/Tools/WebGPUShadingLanguageRI/SPIRV.html >index c7b3940f2b11bd89614f14a9b52c47a56166ab14..7989a1b80a7318de4ca84b11a67e1f5baa107b15 100644 >--- a/Tools/WebGPUShadingLanguageRI/SPIRV.html >+++ b/Tools/WebGPUShadingLanguageRI/SPIRV.html >@@ -140,6 +140,7 @@ td { > <script src="TypeDef.js"></script> > <script src="TypeDefResolver.js"></script> > <script src="TypeRef.js"></script> >+ <script src="TypeOverloadResolutionFailure.js.js"></script> > <script src="TypedValue.js"></script> > <script src="UintLiteral.js"></script> > <script src="UintLiteralType.js"></script> >diff --git a/Tools/WebGPUShadingLanguageRI/StandardLibrary.js b/Tools/WebGPUShadingLanguageRI/StandardLibrary.js >index 06b251cf0a24819cab5065ef5445e1489d5eaafc..8190a4356923a61e5485bdd4f180d1383774898b 100644 >--- a/Tools/WebGPUShadingLanguageRI/StandardLibrary.js >+++ b/Tools/WebGPUShadingLanguageRI/StandardLibrary.js >@@ -33,17 +33,70 @@ let standardLibrary = ` > native typedef void; > native typedef bool; > native typedef uchar; >+native typedef ushort; > native typedef uint; >+native typedef char; >+native typedef short; > native typedef int; >+native typedef half; > 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 typedef atomic_int; >+native typedef atomic_uint; >+ >+native typedef vector<bool, 2>; >+typedef bool2 = vector<bool, 2>; >+native typedef vector<bool, 3>; >+typedef bool3 = vector<bool, 3>; >+native typedef vector<bool, 4>; >+typedef bool4 = vector<bool, 4>; >+native typedef vector<uchar, 2>; >+typedef uchar2 = vector<uchar, 2>; >+native typedef vector<uchar, 3>; >+typedef uchar3 = vector<uchar, 3>; >+native typedef vector<uchar, 4>; >+typedef uchar4 = vector<uchar, 4>; >+native typedef vector<ushort, 2>; >+typedef ushort2 = vector<ushort, 2>; >+native typedef vector<ushort, 3>; >+typedef ushort3 = vector<ushort, 3>; >+native typedef vector<ushort, 4>; >+typedef ushort4 = vector<ushort, 4>; >+native typedef vector<uint, 2>; >+typedef uint2 = vector<uint, 2>; >+native typedef vector<uint, 3>; >+typedef uint3 = vector<uint, 3>; >+native typedef vector<uint, 4>; >+typedef uint4 = vector<uint, 4>; >+native typedef vector<char, 2>; >+typedef char2 = vector<char, 2>; >+native typedef vector<char, 3>; >+typedef char3 = vector<char, 3>; >+native typedef vector<char, 4>; >+typedef char4 = vector<char, 4>; >+native typedef vector<short, 2>; >+typedef short2 = vector<short, 2>; >+native typedef vector<short, 3>; >+typedef short3 = vector<short, 3>; >+native typedef vector<short, 4>; >+typedef short4 = vector<short, 4>; >+native typedef vector<int, 2>; >+typedef int2 = vector<int, 2>; >+native typedef vector<int, 3>; >+typedef int3 = vector<int, 3>; >+native typedef vector<int, 4>; >+typedef int4 = vector<int, 4>; >+native typedef vector<half, 2>; >+typedef half2 = vector<half, 2>; >+native typedef vector<half, 3>; >+typedef half3 = vector<half, 3>; >+native typedef vector<half, 4>; >+typedef half4 = vector<half, 4>; >+native typedef vector<float, 2>; >+typedef float2 = vector<float, 2>; >+native typedef vector<float, 3>; >+typedef float3 = vector<float, 3>; >+native typedef vector<float, 4>; >+typedef float4 = vector<float, 4>; > > native operator int(uint); > native operator int(uchar); >@@ -147,28 +200,12 @@ bool operator~(bool value) > { > return !value; > } >- >-native typedef uchar2; >-native typedef uchar3; >-native typedef uchar4; >- >-native typedef uint2; >-native typedef uint3; >-native typedef uint4; >- >-native typedef int2; >-native typedef int3; >-native typedef int4; >- >-native typedef float2; >-native typedef float3; >-native typedef float4; > `; > > // 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 VectorElementTypes = [ "bool", "uchar", "char", "ushort", "short", "uint", "int", "half", "float" ]; > const VectorElementSizes = [ 2, 3, 4 ]; > > function allVectorTypeNames() >diff --git a/Tools/WebGPUShadingLanguageRI/StatementCloner.js b/Tools/WebGPUShadingLanguageRI/StatementCloner.js >index b3948c450c7160977975ed4e8e98ed99c4f7a059..0d0715a9854def1bfd2a808c7404112ba1a4a0c1 100644 >--- a/Tools/WebGPUShadingLanguageRI/StatementCloner.js >+++ b/Tools/WebGPUShadingLanguageRI/StatementCloner.js >@@ -50,7 +50,7 @@ class StatementCloner extends Rewriter { > > visitNativeType(node) > { >- return new NativeType(node.origin, node.name); >+ return new NativeType(node.origin, node.name, node.typeArguments.map(argument => argument.visit(this))); > } > > visitTypeDef(node) >diff --git a/Tools/WebGPUShadingLanguageRI/Test.html b/Tools/WebGPUShadingLanguageRI/Test.html >index 13f358239929d8a3e6ace52545b91ca52d6060e4..1b96109ab7ce1c101a8884030981d7b1999a4206 100644 >--- a/Tools/WebGPUShadingLanguageRI/Test.html >+++ b/Tools/WebGPUShadingLanguageRI/Test.html >@@ -134,6 +134,7 @@ > <script src="TypeDef.js"></script> > <script src="TypeDefResolver.js"></script> > <script src="TypeRef.js"></script> >+<script src="TypeOverloadResolutionFailure.js"></script> > <script src="TypedValue.js"></script> > <script src="UintLiteral.js"></script> > <script src="UintLiteralType.js"></script> >diff --git a/Tools/WebGPUShadingLanguageRI/TypeRef.js b/Tools/WebGPUShadingLanguageRI/TypeRef.js >index b5f3c0b3d92532e05c680054a161f05e0ddd646b..53ea3c51e69cf18b65607967106c4477e2dd976e 100644 >--- a/Tools/WebGPUShadingLanguageRI/TypeRef.js >+++ b/Tools/WebGPUShadingLanguageRI/TypeRef.js >@@ -64,6 +64,33 @@ class TypeRef extends Type { > this._type = newType; > } > >+ resolve(possibleOverloads, program) >+ { >+ if (!possibleOverloads) >+ throw new WTypeError(this.origin.originString, "Did not find any types named " + this.name); >+ >+ let failures = []; >+ let overload = resolveTypeOverloadImpl(possibleOverloads, this.typeArguments); >+ >+ if (!overload.type) { >+ failures.push(...overload.failures); >+ let message = "Did not find type named " + this.name + " for type arguments "; >+ message += "(" + this.typeArguments + ")"; >+ if (failures.length) >+ message += ", but considered:\n" + failures.join("\n") >+ throw new WTypeError(this.origin.originString, message); >+ } >+ >+ for (let i = 0; i < this.typeArguments.length; ++i) { >+ let typeArgument = this.typeArguments[i]; >+ let resolvedTypeArgument = overload.type.typeArguments[i].type; >+ let result = typeArgument.equalsWithCommit(resolvedTypeArgument); >+ if (!result) >+ throw new Error("At " + this.origin.originString + " argument types for Type and TypeRef not equal: argument type = " + typeArgument + ", resolved tyep argument = " + resolvedTypeArgument); >+ } >+ this.type = overload.type; >+ } >+ > get unifyNode() > { > if (!this.type) >diff --git a/Tools/WebGPUShadingLanguageRI/VectorType.js b/Tools/WebGPUShadingLanguageRI/VectorType.js >index 5014c671a07882002c234bb32f17c8860effc1c6..d351279144aaa5dd92e0149a1a38ed3fd462cad5 100644 >--- a/Tools/WebGPUShadingLanguageRI/VectorType.js >+++ b/Tools/WebGPUShadingLanguageRI/VectorType.js >@@ -25,19 +25,13 @@ > "use strict"; > > class VectorType extends NativeType { >- constructor(origin, name) >+ constructor(origin, name, typeArguments) > { >- 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]); >+ super(origin, name, typeArguments); > } > >- get elementType() { return this._elementType; } >- get numElementsValue() { return this._numElementsValue; } >+ get elementType() { return this.typeArguments[0]; } >+ get numElementsValue() { return this.typeArguments[1].value; } > get size() { return this.elementType.size * this.numElementsValue; } > > unifyImpl(unificationContext, other) >@@ -59,7 +53,7 @@ class VectorType extends NativeType { > > toString() > { >- return `native typedef ${this.elementType}${this.numElementsValue}`; >+ return `native typedef vector<${this.elementType}, ${this.numElementsValue}>`; > } > } > >diff --git a/Tools/WebGPUShadingLanguageRI/index.html b/Tools/WebGPUShadingLanguageRI/index.html >index 4c93a33e6a38662e8ba1e842403d4c02d5e9f9df..f86bb0a0df978922950c5eec34b8077069ad488d 100644 >--- a/Tools/WebGPUShadingLanguageRI/index.html >+++ b/Tools/WebGPUShadingLanguageRI/index.html >@@ -134,6 +134,7 @@ > <script src="TypeDef.js"></script> > <script src="TypeDefResolver.js"></script> > <script src="TypeRef.js"></script> >+<script src="TypeOverloadResolutionFailure.js"></script> > <script src="TypedValue.js"></script> > <script src="UintLiteral.js"></script> > <script src="UintLiteralType.js"></script>
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 188773
:
347598
|
347673
|
347718
|
347754
|
347757
|
347837
|
347846
|
347863