WebKit Bugzilla
Attachment 347598 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-20180820193945.patch (text/plain), 37.49 KB, created by
Myles C. Maxfield
on 2018-08-20 19:39:46 PDT
(
hide
)
Description:
WIP
Filename:
MIME Type:
Creator:
Myles C. Maxfield
Created:
2018-08-20 19:39:46 PDT
Size:
37.49 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/Intrinsics.js b/Tools/WebGPUShadingLanguageRI/Intrinsics.js >index 50d40c0c0e47e112bc74ccfccb7049427116b0fb..97eb74b11677fef10efc956c3532ce9f74dbf5af 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[`${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/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..c6d5fc4843a163818d71f5450e3082a1175eb9f8 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) >@@ -883,10 +885,20 @@ function parse(program, origin, originKind, lineNumberOffset, text) > { > let origin = consume("native"); > if (tryConsume("typedef")) { >+ let nativeType = lexer.backtrackingScope(() => { >+ let name = consumeKind("identifier"); >+ let args = parseTypeArguments(); >+ consume(";"); >+ return NativeType.create(origin, name.text, args) >+ }); >+ if (nativeType) >+ return nativeType; >+ > let name = consumeKind("identifier"); >- let args = parseTypeArguments(); >+ consume("="); >+ let type = parseType(); > consume(";"); >- return NativeType.create(origin, name.text, args); >+ return new NativeTypeDef(origin, name, type); > } > return parseNativeFunc(); > } >diff --git a/Tools/WebGPUShadingLanguageRI/StandardLibrary.js b/Tools/WebGPUShadingLanguageRI/StandardLibrary.js >index 06b251cf0a24819cab5065ef5445e1489d5eaafc..9d1c666dc144706d9d15084cc4dc366a2647239b 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>; >+native typedef bool2 = vector<bool, 2>; >+native typedef vector<bool, 3>; >+native typedef bool3 = vector<bool, 3>; >+native typedef vector<bool, 4>; >+native typedef bool4 = vector<bool, 4>; >+native typedef vector<uchar, 2>; >+native typedef uchar2 = vector<uchar, 2>; >+native typedef vector<uchar, 3>; >+native typedef uchar3 = vector<uchar, 3>; >+native typedef vector<uchar, 4>; >+native typedef uchar4 = vector<uchar, 4>; >+native typedef vector<ushort, 2>; >+native typedef ushort2 = vector<ushort, 2>; >+native typedef vector<ushort, 3>; >+native typedef ushort3 = vector<ushort, 3>; >+native typedef vector<ushort, 4>; >+native typedef ushort4 = vector<ushort, 4>; >+native typedef vector<uint, 2>; >+native typedef uint2 = vector<uint, 2>; >+native typedef vector<uint, 3>; >+native typedef uint3 = vector<uint, 3>; >+native typedef vector<uint, 4>; >+native typedef uint4 = vector<uint, 4>; >+native typedef vector<char, 2>; >+native typedef char2 = vector<char, 2>; >+native typedef vector<char, 3>; >+native typedef char3 = vector<char, 3>; >+native typedef vector<char, 4>; >+native typedef char4 = vector<char, 4>; >+native typedef vector<short, 2>; >+native typedef short2 = vector<short, 2>; >+native typedef vector<short, 3>; >+native typedef short3 = vector<short, 3>; >+native typedef vector<short, 4>; >+native typedef short4 = vector<short, 4>; >+native typedef vector<int, 2>; >+native typedef int2 = vector<int, 2>; >+native typedef vector<int, 3>; >+native typedef int3 = vector<int, 3>; >+native typedef vector<int, 4>; >+native typedef int4 = vector<int, 4>; >+native typedef vector<half, 2>; >+native typedef half2 = vector<half, 2>; >+native typedef vector<half, 3>; >+native typedef half3 = vector<half, 3>; >+native typedef vector<half, 4>; >+native typedef half4 = vector<half, 4>; >+native typedef vector<float, 2>; >+native typedef float2 = vector<float, 2>; >+native typedef vector<float, 3>; >+native typedef float3 = vector<float, 3>; >+native typedef vector<float, 4>; >+native 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/VectorType.js b/Tools/WebGPUShadingLanguageRI/VectorType.js >index 5014c671a07882002c234bb32f17c8860effc1c6..59d7899628d40d00a983a3af84dec3dc930be89b 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)
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