Title: [246550] trunk
Revision
246550
Author
sbar...@apple.com
Date
2019-06-18 10:49:07 -0700 (Tue, 18 Jun 2019)

Log Message

[WHLSL] Do not generate duplicate constructors/copy constructors in synthesizeConstructors
https://bugs.webkit.org/show_bug.cgi?id=198580

Reviewed by Robin Morisset.

Source/WebCore:

Prior to this patch, we were generating duplicate constructors 
for unnamed types. This is bad for two reasons:
1. It's inefficient, since we'd generate a constructor for every place in
the AST where we'd visit this unnamed type.
2. It made it impossible to resolve function overloads to call
the default constructor. This made it so that the autoInitializeVariables
pass would crash if we ever generated more than one of these functions
for the same type.
        
To make this work, this patch splits up what used to be the resolveNamesInFunctions
pass. Previously, this pass would both resolve calls and resolve type names.
Synthesize constructors would run before this, since resolving calls meant we
may resolve a call to one of these synthesized constructors. However, synthesize
constructors now needs to test for the equality unnamed types, so it now requires
running the type resolution part of resolveNamesInFunctions before it runs.
        
This patch splits resolveNamesInFunctions into two parts:
resolveTypeNamesInFunctions and resolveCallsInFunctions.
        
So we used to run:
synthesizeConstructors
resolveNamesInFunctions
        
And now we run:
resolveTypeNamesInFunctions 
synthesizeConstructors
resolveCallsInFunctions

Test: webgpu/whlsl-duplicate-types-should-not-produce-duplicate-ctors.html

* Modules/webgpu/WHLSL/AST/WHLSLArrayReferenceType.h:
* Modules/webgpu/WHLSL/AST/WHLSLArrayType.h:
* Modules/webgpu/WHLSL/AST/WHLSLBooleanLiteral.h:
(WebCore::WHLSL::AST::BooleanLiteral::clone const):
* Modules/webgpu/WHLSL/AST/WHLSLEnumerationMemberLiteral.h:
(WebCore::WHLSL::AST::EnumerationMemberLiteral::clone const):
* Modules/webgpu/WHLSL/AST/WHLSLExpression.h:
(WebCore::WHLSL::AST::_expression_::copyTypeTo const):
* Modules/webgpu/WHLSL/AST/WHLSLFloatLiteral.h:
(WebCore::WHLSL::AST::FloatLiteral::clone const):
* Modules/webgpu/WHLSL/AST/WHLSLFloatLiteralType.cpp:
(WebCore::WHLSL::AST::FloatLiteralType::clone const):
* Modules/webgpu/WHLSL/AST/WHLSLFloatLiteralType.h:
* Modules/webgpu/WHLSL/AST/WHLSLIntegerLiteral.h:
(WebCore::WHLSL::AST::IntegerLiteral::clone const):
* Modules/webgpu/WHLSL/AST/WHLSLIntegerLiteralType.cpp:
(WebCore::WHLSL::AST::IntegerLiteralType::clone const):
* Modules/webgpu/WHLSL/AST/WHLSLIntegerLiteralType.h:
* Modules/webgpu/WHLSL/AST/WHLSLNullLiteral.h:
(WebCore::WHLSL::AST::NullLiteral::clone const):
* Modules/webgpu/WHLSL/AST/WHLSLPointerType.h:
* Modules/webgpu/WHLSL/AST/WHLSLTypeReference.h:
* Modules/webgpu/WHLSL/AST/WHLSLUnnamedType.h:
* Modules/webgpu/WHLSL/AST/WHLSLUnsignedIntegerLiteral.h:
(WebCore::WHLSL::AST::UnsignedIntegerLiteral::clone const):
* Modules/webgpu/WHLSL/AST/WHLSLUnsignedIntegerLiteralType.cpp:
(WebCore::WHLSL::AST::UnsignedIntegerLiteralType::clone const):
* Modules/webgpu/WHLSL/AST/WHLSLUnsignedIntegerLiteralType.h:
* Modules/webgpu/WHLSL/WHLSLASTDumper.h:
* Modules/webgpu/WHLSL/WHLSLInferTypes.cpp:
(WebCore::WHLSL::matches):
* Modules/webgpu/WHLSL/WHLSLNameResolver.cpp:
(WebCore::WHLSL::NameResolver::NameResolver):
(WebCore::WHLSL::NameResolver::visit):
(WebCore::WHLSL::resolveTypeNamesInFunctions):
(WebCore::WHLSL::resolveCallsInFunctions):
(WebCore::WHLSL::resolveNamesInFunctions): Deleted.
* Modules/webgpu/WHLSL/WHLSLNameResolver.h:
(WebCore::WHLSL::NameResolver::setIsResolvingCalls):
* Modules/webgpu/WHLSL/WHLSLPrepare.cpp:
(WebCore::WHLSL::prepareShared):
* Modules/webgpu/WHLSL/WHLSLSynthesizeConstructors.cpp:
(WebCore::WHLSL::UnnamedTypeKey::UnnamedTypeKey):
(WebCore::WHLSL::UnnamedTypeKey::isEmptyValue const):
(WebCore::WHLSL::UnnamedTypeKey::isHashTableDeletedValue const):
(WebCore::WHLSL::UnnamedTypeKey::hash const):
(WebCore::WHLSL::UnnamedTypeKey::operator== const):
(WebCore::WHLSL::UnnamedTypeKey::unnamedType const):
(WebCore::WHLSL::UnnamedTypeKey::Hash::hash):
(WebCore::WHLSL::UnnamedTypeKey::Hash::equal):
(WebCore::WHLSL::UnnamedTypeKey::Traits::isEmptyValue):
(WebCore::WHLSL::FindAllTypes::takeUnnamedTypes):
(WebCore::WHLSL::FindAllTypes::appendNamedType):
(WebCore::WHLSL::synthesizeConstructors):

LayoutTests:

* webgpu/whlsl-duplicate-types-should-not-produce-duplicate-ctors-expected.txt: Added.
* webgpu/whlsl-duplicate-types-should-not-produce-duplicate-ctors.html: Added.

Modified Paths

Added Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (246549 => 246550)


--- trunk/LayoutTests/ChangeLog	2019-06-18 17:26:07 UTC (rev 246549)
+++ trunk/LayoutTests/ChangeLog	2019-06-18 17:49:07 UTC (rev 246550)
@@ -1,3 +1,13 @@
+2019-06-18  Saam Barati  <sbar...@apple.com>
+
+        [WHLSL] Do not generate duplicate constructors/copy constructors in synthesizeConstructors
+        https://bugs.webkit.org/show_bug.cgi?id=198580
+
+        Reviewed by Robin Morisset.
+
+        * webgpu/whlsl-duplicate-types-should-not-produce-duplicate-ctors-expected.txt: Added.
+        * webgpu/whlsl-duplicate-types-should-not-produce-duplicate-ctors.html: Added.
+
 2019-06-18  Simon Fraser  <simon.fra...@apple.com>
 
         Convert macOS to scroll by changing layer boundsOrigin

Added: trunk/LayoutTests/webgpu/whlsl-duplicate-types-should-not-produce-duplicate-ctors-expected.txt (0 => 246550)


--- trunk/LayoutTests/webgpu/whlsl-duplicate-types-should-not-produce-duplicate-ctors-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/webgpu/whlsl-duplicate-types-should-not-produce-duplicate-ctors-expected.txt	2019-06-18 17:49:07 UTC (rev 246550)
@@ -0,0 +1,12 @@
+PASS successfullyParsed is true
+
+TEST COMPLETE
+PASS resultsFloat32Array[0] is 2
+PASS resultsFloat32Array[1] is 4
+PASS resultsFloat32Array[2] is 6
+PASS resultsFloat32Array[3] is 8
+PASS resultsFloat32Array[4] is 5
+PASS resultsFloat32Array[5] is 6
+PASS resultsFloat32Array[6] is 7
+PASS resultsFloat32Array[7] is 8
+

Added: trunk/LayoutTests/webgpu/whlsl-duplicate-types-should-not-produce-duplicate-ctors.html (0 => 246550)


--- trunk/LayoutTests/webgpu/whlsl-duplicate-types-should-not-produce-duplicate-ctors.html	                        (rev 0)
+++ trunk/LayoutTests/webgpu/whlsl-duplicate-types-should-not-produce-duplicate-ctors.html	2019-06-18 17:49:07 UTC (rev 246550)
@@ -0,0 +1,111 @@
+<!DOCTYPE html>
+<html>
+<head>
+<script src=""
+</head>
+<body>
+<script>
+const shaderSource = `
+struct XYZ {
+    int x;
+    int y;
+    int z;
+}
+
+typedef XYZ1 = XYZ;
+typedef XYZ2 = XYZ;
+typedef XYZ3 = XYZ;
+
+[numthreads(2, 1, 1)]
+compute void computeShader(device float[] buffer : register(u0), float3 threadID : SV_DispatchThreadID) {
+    thread int* x;
+    thread int* y;
+    thread float* f1;
+    thread float* f2;
+    XYZ1 a;
+    XYZ2 b;
+    XYZ3 c;
+    thread int[] intArrayRef1;
+    thread int[] intArrayRef2;
+    if (*x == *y && x == y && x == null && f1 == null && *f1 == 0) {
+        buffer[uint(threadID.x)] = buffer[uint(threadID.x)] * 2.0;
+    }
+}
+`;
+let resultsFloat32Array;
+async function start() {
+    const adapter = await navigator.gpu.requestAdapter();
+    const device = await adapter.requestDevice();
+
+    const shaderModule = device.createShaderModule({code: shaderSource, isWHLSL: true});
+    const computeStage = {module: shaderModule, entryPoint: "computeShader"};
+
+    const bindGroupLayoutDescriptor = {bindings: [{binding: 0, visibility: 7, type: "storage-buffer"}]};
+    const bindGroupLayout = device.createBindGroupLayout(bindGroupLayoutDescriptor);
+    const pipelineLayoutDescriptor = {bindGroupLayouts: [bindGroupLayout]};
+    const pipelineLayout = device.createPipelineLayout(pipelineLayoutDescriptor);
+
+    const computePipelineDescriptor = {computeStage, layout: pipelineLayout};
+    const computePipeline = device.createComputePipeline(computePipelineDescriptor);
+
+    const size = Float32Array.BYTES_PER_ELEMENT * 8;
+
+    const bufferDescriptor = {size, usage: GPUBufferUsage.MAP_WRITE | GPUBufferUsage.TRANSFER_SRC};
+    const buffer = device.createBuffer(bufferDescriptor);
+    const bufferArrayBuffer = await buffer.mapWriteAsync();
+    const bufferFloat32Array = new Float32Array(bufferArrayBuffer);
+    bufferFloat32Array[0] = 1;
+    bufferFloat32Array[1] = 2;
+    bufferFloat32Array[2] = 3;
+    bufferFloat32Array[3] = 4;
+    bufferFloat32Array[4] = 5;
+    bufferFloat32Array[5] = 6;
+    bufferFloat32Array[6] = 7;
+    bufferFloat32Array[7] = 8;
+    buffer.unmap();
+
+    const resultsBufferDescriptor = {size, usage: GPUBufferUsage.STORAGE | GPUBufferUsage.TRANSFER_DST | GPUBufferUsage.MAP_READ};
+    const resultsBuffer = device.createBuffer(resultsBufferDescriptor);
+
+    const bufferBinding = {buffer: resultsBuffer, size};
+    const bindGroupBinding = {binding: 0, resource: bufferBinding};
+    const bindGroupDescriptor = {layout: bindGroupLayout, bindings: [bindGroupBinding]};
+    const bindGroup = device.createBindGroup(bindGroupDescriptor);
+
+    const commandEncoder = device.createCommandEncoder(); // {}
+    commandEncoder.copyBufferToBuffer(buffer, 0, resultsBuffer, 0, Float32Array.BYTES_PER_ELEMENT * 8);
+    const computePassEncoder = commandEncoder.beginComputePass();
+    computePassEncoder.setPipeline(computePipeline);
+    computePassEncoder.setBindGroup(0, bindGroup);
+    computePassEncoder.dispatch(2, 1, 1);
+    computePassEncoder.endPass();
+    const commandBuffer = commandEncoder.finish();
+    device.getQueue().submit([commandBuffer]);
+
+    const resultsArrayBuffer = await resultsBuffer.mapReadAsync();
+    resultsFloat32Array = new Float32Array(resultsArrayBuffer);
+    shouldBe("resultsFloat32Array[0]", "2");
+    shouldBe("resultsFloat32Array[1]", "4");
+    shouldBe("resultsFloat32Array[2]", "6");
+    shouldBe("resultsFloat32Array[3]", "8");
+    shouldBe("resultsFloat32Array[4]", "5");
+    shouldBe("resultsFloat32Array[5]", "6");
+    shouldBe("resultsFloat32Array[6]", "7");
+    shouldBe("resultsFloat32Array[7]", "8");
+    resultsBuffer.unmap();
+}
+if (window.testRunner)
+    testRunner.waitUntilDone();
+window.addEventListener("load", function() {
+    start().then(function() {
+        if (window.testRunner)
+            testRunner.notifyDone();
+    }, function() {
+        if (window.testRunner)
+            testRunner.notifyDone();
+    });
+});
+</script>
+<script src=""
+</body>
+</html>

Modified: trunk/Source/WebCore/ChangeLog (246549 => 246550)


--- trunk/Source/WebCore/ChangeLog	2019-06-18 17:26:07 UTC (rev 246549)
+++ trunk/Source/WebCore/ChangeLog	2019-06-18 17:49:07 UTC (rev 246550)
@@ -1,3 +1,95 @@
+2019-06-18  Saam Barati  <sbar...@apple.com>
+
+        [WHLSL] Do not generate duplicate constructors/copy constructors in synthesizeConstructors
+        https://bugs.webkit.org/show_bug.cgi?id=198580
+
+        Reviewed by Robin Morisset.
+
+        Prior to this patch, we were generating duplicate constructors 
+        for unnamed types. This is bad for two reasons:
+        1. It's inefficient, since we'd generate a constructor for every place in
+        the AST where we'd visit this unnamed type.
+        2. It made it impossible to resolve function overloads to call
+        the default constructor. This made it so that the autoInitializeVariables
+        pass would crash if we ever generated more than one of these functions
+        for the same type.
+        
+        To make this work, this patch splits up what used to be the resolveNamesInFunctions
+        pass. Previously, this pass would both resolve calls and resolve type names.
+        Synthesize constructors would run before this, since resolving calls meant we
+        may resolve a call to one of these synthesized constructors. However, synthesize
+        constructors now needs to test for the equality unnamed types, so it now requires
+        running the type resolution part of resolveNamesInFunctions before it runs.
+        
+        This patch splits resolveNamesInFunctions into two parts:
+        resolveTypeNamesInFunctions and resolveCallsInFunctions.
+        
+        So we used to run:
+        synthesizeConstructors
+        resolveNamesInFunctions
+        
+        And now we run:
+        resolveTypeNamesInFunctions 
+        synthesizeConstructors
+        resolveCallsInFunctions
+
+        Test: webgpu/whlsl-duplicate-types-should-not-produce-duplicate-ctors.html
+
+        * Modules/webgpu/WHLSL/AST/WHLSLArrayReferenceType.h:
+        * Modules/webgpu/WHLSL/AST/WHLSLArrayType.h:
+        * Modules/webgpu/WHLSL/AST/WHLSLBooleanLiteral.h:
+        (WebCore::WHLSL::AST::BooleanLiteral::clone const):
+        * Modules/webgpu/WHLSL/AST/WHLSLEnumerationMemberLiteral.h:
+        (WebCore::WHLSL::AST::EnumerationMemberLiteral::clone const):
+        * Modules/webgpu/WHLSL/AST/WHLSLExpression.h:
+        (WebCore::WHLSL::AST::_expression_::copyTypeTo const):
+        * Modules/webgpu/WHLSL/AST/WHLSLFloatLiteral.h:
+        (WebCore::WHLSL::AST::FloatLiteral::clone const):
+        * Modules/webgpu/WHLSL/AST/WHLSLFloatLiteralType.cpp:
+        (WebCore::WHLSL::AST::FloatLiteralType::clone const):
+        * Modules/webgpu/WHLSL/AST/WHLSLFloatLiteralType.h:
+        * Modules/webgpu/WHLSL/AST/WHLSLIntegerLiteral.h:
+        (WebCore::WHLSL::AST::IntegerLiteral::clone const):
+        * Modules/webgpu/WHLSL/AST/WHLSLIntegerLiteralType.cpp:
+        (WebCore::WHLSL::AST::IntegerLiteralType::clone const):
+        * Modules/webgpu/WHLSL/AST/WHLSLIntegerLiteralType.h:
+        * Modules/webgpu/WHLSL/AST/WHLSLNullLiteral.h:
+        (WebCore::WHLSL::AST::NullLiteral::clone const):
+        * Modules/webgpu/WHLSL/AST/WHLSLPointerType.h:
+        * Modules/webgpu/WHLSL/AST/WHLSLTypeReference.h:
+        * Modules/webgpu/WHLSL/AST/WHLSLUnnamedType.h:
+        * Modules/webgpu/WHLSL/AST/WHLSLUnsignedIntegerLiteral.h:
+        (WebCore::WHLSL::AST::UnsignedIntegerLiteral::clone const):
+        * Modules/webgpu/WHLSL/AST/WHLSLUnsignedIntegerLiteralType.cpp:
+        (WebCore::WHLSL::AST::UnsignedIntegerLiteralType::clone const):
+        * Modules/webgpu/WHLSL/AST/WHLSLUnsignedIntegerLiteralType.h:
+        * Modules/webgpu/WHLSL/WHLSLASTDumper.h:
+        * Modules/webgpu/WHLSL/WHLSLInferTypes.cpp:
+        (WebCore::WHLSL::matches):
+        * Modules/webgpu/WHLSL/WHLSLNameResolver.cpp:
+        (WebCore::WHLSL::NameResolver::NameResolver):
+        (WebCore::WHLSL::NameResolver::visit):
+        (WebCore::WHLSL::resolveTypeNamesInFunctions):
+        (WebCore::WHLSL::resolveCallsInFunctions):
+        (WebCore::WHLSL::resolveNamesInFunctions): Deleted.
+        * Modules/webgpu/WHLSL/WHLSLNameResolver.h:
+        (WebCore::WHLSL::NameResolver::setIsResolvingCalls):
+        * Modules/webgpu/WHLSL/WHLSLPrepare.cpp:
+        (WebCore::WHLSL::prepareShared):
+        * Modules/webgpu/WHLSL/WHLSLSynthesizeConstructors.cpp:
+        (WebCore::WHLSL::UnnamedTypeKey::UnnamedTypeKey):
+        (WebCore::WHLSL::UnnamedTypeKey::isEmptyValue const):
+        (WebCore::WHLSL::UnnamedTypeKey::isHashTableDeletedValue const):
+        (WebCore::WHLSL::UnnamedTypeKey::hash const):
+        (WebCore::WHLSL::UnnamedTypeKey::operator== const):
+        (WebCore::WHLSL::UnnamedTypeKey::unnamedType const):
+        (WebCore::WHLSL::UnnamedTypeKey::Hash::hash):
+        (WebCore::WHLSL::UnnamedTypeKey::Hash::equal):
+        (WebCore::WHLSL::UnnamedTypeKey::Traits::isEmptyValue):
+        (WebCore::WHLSL::FindAllTypes::takeUnnamedTypes):
+        (WebCore::WHLSL::FindAllTypes::appendNamedType):
+        (WebCore::WHLSL::synthesizeConstructors):
+
 2019-06-18  Truitt Savell  <tsav...@apple.com>
 
         Unreviewed, rolling out r246524.

Modified: trunk/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLArrayReferenceType.h (246549 => 246550)


--- trunk/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLArrayReferenceType.h	2019-06-18 17:26:07 UTC (rev 246549)
+++ trunk/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLArrayReferenceType.h	2019-06-18 17:49:07 UTC (rev 246550)
@@ -63,6 +63,15 @@
         return this->Base::hash() ^ StringHasher::computeLiteralHash("array");
     }
 
+    bool operator==(const UnnamedType& other) const override
+    {
+        if (!is<ArrayReferenceType>(other))
+            return false;
+
+        return addressSpace() == downcast<ArrayReferenceType>(other).addressSpace()
+            && elementType() == downcast<ArrayReferenceType>(other).elementType();
+    }
+
 private:
 };
 

Modified: trunk/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLArrayType.h (246549 => 246550)


--- trunk/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLArrayType.h	2019-06-18 17:26:07 UTC (rev 246549)
+++ trunk/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLArrayType.h	2019-06-18 17:49:07 UTC (rev 246550)
@@ -69,6 +69,15 @@
         return WTF::IntHash<unsigned>::hash(m_numElements) ^ m_elementType->hash();
     }
 
+    bool operator==(const UnnamedType& other) const override
+    {
+        if (!is<ArrayType>(other))
+            return false;
+
+        return numElements() == downcast<ArrayType>(other).numElements()
+            && type() == downcast<ArrayType>(other).type();
+    }
+
 private:
     UniqueRef<UnnamedType> m_elementType;
     unsigned m_numElements;

Modified: trunk/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLBooleanLiteral.h (246549 => 246550)


--- trunk/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLBooleanLiteral.h	2019-06-18 17:26:07 UTC (rev 246549)
+++ trunk/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLBooleanLiteral.h	2019-06-18 17:49:07 UTC (rev 246550)
@@ -58,7 +58,9 @@
 
     BooleanLiteral clone() const
     {
-        return BooleanLiteral(Lexer::Token(origin()), m_value);
+        BooleanLiteral result(Lexer::Token(origin()), m_value);
+        copyTypeTo(result);
+        return result;
     }
 
 private:

Modified: trunk/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLEnumerationMemberLiteral.h (246549 => 246550)


--- trunk/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLEnumerationMemberLiteral.h	2019-06-18 17:26:07 UTC (rev 246549)
+++ trunk/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLEnumerationMemberLiteral.h	2019-06-18 17:49:07 UTC (rev 246550)
@@ -73,6 +73,7 @@
     {
         auto result = EnumerationMemberLiteral(Lexer::Token(origin()), String(m_left), String(m_right));
         result.m_enumerationMember = m_enumerationMember;
+        copyTypeTo(result);
         return result;
     }
 

Modified: trunk/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLExpression.h (246549 => 246550)


--- trunk/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLExpression.h	2019-06-18 17:26:07 UTC (rev 246549)
+++ trunk/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLExpression.h	2019-06-18 17:49:07 UTC (rev 246550)
@@ -84,6 +84,14 @@
         m_typeAnnotation = WTFMove(typeAnnotation);
     }
 
+    void copyTypeTo(_expression_& other) const
+    {
+        if (auto* resolvedType = const_cast<_expression_*>(this)->maybeResolvedType())
+            other.setType(resolvedType->clone());
+        if (auto* typeAnnotation = maybeTypeAnnotation())
+            other.setTypeAnnotation(TypeAnnotation(*typeAnnotation));
+    }
+
     virtual bool isAssignmentExpression() const { return false; }
     virtual bool isBooleanLiteral() const { return false; }
     virtual bool isCallExpression() const { return false; }

Modified: trunk/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLFloatLiteral.h (246549 => 246550)


--- trunk/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLFloatLiteral.h	2019-06-18 17:26:07 UTC (rev 246549)
+++ trunk/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLFloatLiteral.h	2019-06-18 17:49:07 UTC (rev 246550)
@@ -62,8 +62,10 @@
     FloatLiteral clone() const
     {
         FloatLiteral result(Lexer::Token(origin()), m_value);
+        result.m_type = m_type.clone();
         if (auto* resolvedType = m_type.maybeResolvedType())
             result.m_type.resolve(resolvedType->clone());
+        copyTypeTo(result);
         return result;
     }
 

Modified: trunk/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLFloatLiteralType.cpp (246549 => 246550)


--- trunk/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLFloatLiteralType.cpp	2019-06-18 17:26:07 UTC (rev 246549)
+++ trunk/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLFloatLiteralType.cpp	2019-06-18 17:49:07 UTC (rev 246550)
@@ -72,6 +72,16 @@
     return 1;
 }
 
+FloatLiteralType FloatLiteralType::clone() const
+{
+    FloatLiteralType result(Lexer::Token(m_preferredType->origin()), m_value);
+    if (auto* type = maybeResolvedType())
+        result.resolve(type->clone());
+    result.m_preferredType = m_preferredType->cloneTypeReference();
+    return result;
+}
+
+
 } // namespace AST
 
 }

Modified: trunk/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLFloatLiteralType.h (246549 => 246550)


--- trunk/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLFloatLiteralType.h	2019-06-18 17:26:07 UTC (rev 246549)
+++ trunk/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLFloatLiteralType.h	2019-06-18 17:49:07 UTC (rev 246550)
@@ -60,6 +60,8 @@
     bool canResolve(const Type&) const override;
     unsigned conversionCost(const UnnamedType&) const override;
 
+    FloatLiteralType clone() const;
+
 private:
     float m_value;
     // This is a unique_ptr to resolve a circular dependency between

Modified: trunk/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLIntegerLiteral.h (246549 => 246550)


--- trunk/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLIntegerLiteral.h	2019-06-18 17:26:07 UTC (rev 246549)
+++ trunk/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLIntegerLiteral.h	2019-06-18 17:49:07 UTC (rev 246550)
@@ -62,8 +62,10 @@
     IntegerLiteral clone() const
     {
         IntegerLiteral result(Lexer::Token(origin()), m_value);
+        result.m_type = m_type.clone();
         if (auto* resolvedType = m_type.maybeResolvedType())
             result.m_type.resolve(resolvedType->clone());
+        copyTypeTo(result);
         return result;
     }
 

Modified: trunk/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLIntegerLiteralType.cpp (246549 => 246550)


--- trunk/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLIntegerLiteralType.cpp	2019-06-18 17:26:07 UTC (rev 246549)
+++ trunk/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLIntegerLiteralType.cpp	2019-06-18 17:49:07 UTC (rev 246550)
@@ -73,6 +73,15 @@
     return 1;
 }
 
+IntegerLiteralType IntegerLiteralType::clone() const
+{
+    IntegerLiteralType result(Lexer::Token(m_preferredType->origin()), m_value);
+    if (auto* type = maybeResolvedType())
+        result.resolve(type->clone());
+    result.m_preferredType = m_preferredType->cloneTypeReference();
+    return result;
+}
+
 } // namespace AST
 
 }

Modified: trunk/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLIntegerLiteralType.h (246549 => 246550)


--- trunk/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLIntegerLiteralType.h	2019-06-18 17:26:07 UTC (rev 246549)
+++ trunk/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLIntegerLiteralType.h	2019-06-18 17:49:07 UTC (rev 246550)
@@ -60,6 +60,8 @@
     bool canResolve(const Type&) const override;
     unsigned conversionCost(const UnnamedType&) const override;
 
+    IntegerLiteralType clone() const;
+
 private:
     int m_value;
     // This is a unique_ptr to resolve a circular dependency between

Modified: trunk/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLNullLiteral.h (246549 => 246550)


--- trunk/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLNullLiteral.h	2019-06-18 17:26:07 UTC (rev 246549)
+++ trunk/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLNullLiteral.h	2019-06-18 17:49:07 UTC (rev 246550)
@@ -61,6 +61,7 @@
         auto result = NullLiteral(Lexer::Token(origin()));
         if (auto* resolvedType = m_type.maybeResolvedType())
             result.m_type.resolve(resolvedType->clone());
+        copyTypeTo(result);
         return result;
     }
 

Modified: trunk/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLPointerType.h (246549 => 246550)


--- trunk/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLPointerType.h	2019-06-18 17:26:07 UTC (rev 246549)
+++ trunk/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLPointerType.h	2019-06-18 17:49:07 UTC (rev 246550)
@@ -63,6 +63,15 @@
         return this->Base::hash() ^ StringHasher::computeLiteralHash("pointer");
     }
 
+    bool operator==(const UnnamedType& other) const override
+    {
+        if (!is<PointerType>(other))
+            return false;
+
+        return addressSpace() == downcast<PointerType>(other).addressSpace()
+            && elementType() == downcast<PointerType>(other).elementType();
+    }
+
 private:
 };
 

Modified: trunk/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLTypeReference.h (246549 => 246550)


--- trunk/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLTypeReference.h	2019-06-18 17:26:07 UTC (rev 246549)
+++ trunk/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLTypeReference.h	2019-06-18 17:49:07 UTC (rev 246550)
@@ -107,6 +107,15 @@
         return WTF::PtrHash<const Type*>::hash(&unifyNode());
     }
 
+    bool operator==(const UnnamedType& other) const override
+    {
+        ASSERT(m_resolvedType);
+        if (!is<TypeReference>(other))
+            return false;
+
+        return &unifyNode() == &downcast<TypeReference>(other).unifyNode();
+    }
+
 private:
     String m_name;
     TypeArguments m_typeArguments;

Modified: trunk/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLUnnamedType.h (246549 => 246550)


--- trunk/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLUnnamedType.h	2019-06-18 17:26:07 UTC (rev 246549)
+++ trunk/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLUnnamedType.h	2019-06-18 17:49:07 UTC (rev 246550)
@@ -64,6 +64,7 @@
     virtual UniqueRef<UnnamedType> clone() const = 0;
 
     virtual unsigned hash() const = 0;
+    virtual bool operator==(const UnnamedType&) const = 0;
 
     const Lexer::Token& origin() const { return m_origin; }
 

Modified: trunk/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLUnsignedIntegerLiteral.h (246549 => 246550)


--- trunk/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLUnsignedIntegerLiteral.h	2019-06-18 17:26:07 UTC (rev 246549)
+++ trunk/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLUnsignedIntegerLiteral.h	2019-06-18 17:49:07 UTC (rev 246550)
@@ -62,8 +62,10 @@
     UnsignedIntegerLiteral clone() const
     {
         UnsignedIntegerLiteral result(Lexer::Token(origin()), m_value);
+        result.m_type = m_type.clone();
         if (auto* resolvedType = m_type.maybeResolvedType())
             result.m_type.resolve(resolvedType->clone());
+        copyTypeTo(result);
         return result;
     }
 

Modified: trunk/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLUnsignedIntegerLiteralType.cpp (246549 => 246550)


--- trunk/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLUnsignedIntegerLiteralType.cpp	2019-06-18 17:26:07 UTC (rev 246549)
+++ trunk/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLUnsignedIntegerLiteralType.cpp	2019-06-18 17:49:07 UTC (rev 246550)
@@ -76,6 +76,15 @@
     return 1;
 }
 
+UnsignedIntegerLiteralType UnsignedIntegerLiteralType::clone() const
+{
+    UnsignedIntegerLiteralType result(Lexer::Token(m_preferredType->origin()), m_value);
+    if (auto* type = maybeResolvedType())
+        result.resolve(type->clone());
+    result.m_preferredType = m_preferredType->cloneTypeReference();
+    return result;
+}
+
 } // namespace AST
 
 }

Modified: trunk/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLUnsignedIntegerLiteralType.h (246549 => 246550)


--- trunk/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLUnsignedIntegerLiteralType.h	2019-06-18 17:26:07 UTC (rev 246549)
+++ trunk/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLUnsignedIntegerLiteralType.h	2019-06-18 17:49:07 UTC (rev 246550)
@@ -60,6 +60,8 @@
     bool canResolve(const Type&) const override;
     unsigned conversionCost(const UnnamedType&) const override;
 
+    UnsignedIntegerLiteralType clone() const;
+
 private:
     unsigned m_value;
     // This is a unique_ptr to resolve a circular dependency between

Modified: trunk/Source/WebCore/Modules/webgpu/WHLSL/WHLSLASTDumper.h (246549 => 246550)


--- trunk/Source/WebCore/Modules/webgpu/WHLSL/WHLSLASTDumper.h	2019-06-18 17:26:07 UTC (rev 246549)
+++ trunk/Source/WebCore/Modules/webgpu/WHLSL/WHLSLASTDumper.h	2019-06-18 17:49:07 UTC (rev 246550)
@@ -142,6 +142,7 @@
 MAKE_PRINT_ADAPTOR(ProgramDumper, Program&, dumpASTNode);
 MAKE_PRINT_ADAPTOR(StructureDefinitionDumper, AST::StructureDefinition&, dumpASTNode);
 MAKE_PRINT_ADAPTOR(FunctionDefinitionDumper, AST::FunctionDefinition&, dumpASTNode);
+MAKE_PRINT_ADAPTOR(NativeFunctionDeclarationDumper, AST::NativeFunctionDeclaration&, dumpASTNode);
 MAKE_PRINT_ADAPTOR(TypeDumper, AST::UnnamedType&, dumpASTNode);
 
 

Modified: trunk/Source/WebCore/Modules/webgpu/WHLSL/WHLSLInferTypes.cpp (246549 => 246550)


--- trunk/Source/WebCore/Modules/webgpu/WHLSL/WHLSLInferTypes.cpp	2019-06-18 17:26:07 UTC (rev 246549)
+++ trunk/Source/WebCore/Modules/webgpu/WHLSL/WHLSLInferTypes.cpp	2019-06-18 17:49:07 UTC (rev 246550)
@@ -61,28 +61,7 @@
         auto& unnamedThis = downcast<AST::UnnamedType>(unifyThis);
         auto& unnamedOther = downcast<AST::UnnamedType>(unifyOther);
         ASSERT(!is<AST::TypeReference>(unnamedThis) && !is<AST::TypeReference>(unnamedOther));
-        if (is<AST::PointerType>(unnamedThis) && is<AST::PointerType>(unnamedOther)) {
-            auto& pointerThis = downcast<AST::PointerType>(unnamedThis);
-            auto& pointerOther = downcast<AST::PointerType>(unnamedOther);
-            if (pointerThis.addressSpace() != pointerOther.addressSpace())
-                return false;
-            return matches(pointerThis.elementType(), pointerOther.elementType());
-        }
-        if (is<AST::ArrayReferenceType>(unnamedThis) && is<AST::ArrayReferenceType>(unnamedOther)) {
-            auto& arrayReferenceThis = downcast<AST::ArrayReferenceType>(unnamedThis);
-            auto& arrayReferenceOther = downcast<AST::ArrayReferenceType>(unnamedOther);
-            if (arrayReferenceThis.addressSpace() != arrayReferenceOther.addressSpace())
-                return false;
-            return matches(arrayReferenceThis.elementType(), arrayReferenceOther.elementType());
-        }
-        if (is<AST::ArrayType>(unnamedThis) && is<AST::ArrayType>(unnamedOther)) {
-            auto& arrayThis = downcast<AST::ArrayType>(unnamedThis);
-            auto& arrayOther = downcast<AST::ArrayType>(unnamedOther);
-            if (arrayThis.numElements() != arrayOther.numElements())
-                return false;
-            return matches(arrayThis.type(), arrayOther.type());
-        }
-        return false;
+        return unnamedThis == unnamedOther;
     }
     return false;
 }

Modified: trunk/Source/WebCore/Modules/webgpu/WHLSL/WHLSLNameResolver.cpp (246549 => 246550)


--- trunk/Source/WebCore/Modules/webgpu/WHLSL/WHLSLNameResolver.cpp	2019-06-18 17:26:07 UTC (rev 246549)
+++ trunk/Source/WebCore/Modules/webgpu/WHLSL/WHLSLNameResolver.cpp	2019-06-18 17:49:07 UTC (rev 246550)
@@ -56,8 +56,18 @@
 {
 }
 
+NameResolver::NameResolver(NameResolver& parentResolver, NameContext& nameContext)
+    : m_nameContext(nameContext)
+{
+    m_isResolvingCalls = parentResolver.m_isResolvingCalls;
+    setCurrentFunctionDefinition(parentResolver.m_currentFunction);
+}
+
 void NameResolver::visit(AST::TypeReference& typeReference)
 {
+    if (m_isResolvingCalls)
+        return;
+
     ScopedSetAdder<AST::TypeReference*> adder(m_typeReferences, &typeReference);
     if (!adder.isNewEntry()) {
         setError();
@@ -86,8 +96,7 @@
 void NameResolver::visit(AST::FunctionDefinition& functionDefinition)
 {
     NameContext newNameContext(&m_nameContext);
-    NameResolver newNameResolver(newNameContext);
-    newNameResolver.setCurrentFunctionDefinition(m_currentFunction);
+    NameResolver newNameResolver(*this, newNameContext);
     checkErrorAndVisit(functionDefinition.type());
     for (auto& parameter : functionDefinition.parameters())
         newNameResolver.checkErrorAndVisit(parameter);
@@ -97,8 +106,7 @@
 void NameResolver::visit(AST::Block& block)
 {
     NameContext nameContext(&m_nameContext);
-    NameResolver newNameResolver(nameContext);
-    newNameResolver.setCurrentFunctionDefinition(m_currentFunction);
+    NameResolver newNameResolver(*this, nameContext);
     newNameResolver.Visitor::visit(block);
 }
 
@@ -106,13 +114,11 @@
 {
     checkErrorAndVisit(ifStatement.conditional());
     NameContext nameContext(&m_nameContext);
-    NameResolver newNameResolver(nameContext);
-    newNameResolver.setCurrentFunctionDefinition(m_currentFunction);
+    NameResolver newNameResolver(*this, nameContext);
     newNameResolver.checkErrorAndVisit(ifStatement.body());
     if (ifStatement.elseBody()) {
         NameContext nameContext(&m_nameContext);
-        NameResolver newNameResolver(nameContext);
-        newNameResolver.setCurrentFunctionDefinition(m_currentFunction);
+        NameResolver newNameResolver(*this, nameContext);
         newNameResolver.checkErrorAndVisit(*ifStatement.elseBody());
     }
 }
@@ -121,8 +127,7 @@
 {
     checkErrorAndVisit(whileLoop.conditional());
     NameContext nameContext(&m_nameContext);
-    NameResolver newNameResolver(nameContext);
-    newNameResolver.setCurrentFunctionDefinition(m_currentFunction);
+    NameResolver newNameResolver(*this, nameContext);
     newNameResolver.checkErrorAndVisit(whileLoop.body());
 }
 
@@ -129,8 +134,7 @@
 void NameResolver::visit(AST::DoWhileLoop& whileLoop)
 {
     NameContext nameContext(&m_nameContext);
-    NameResolver newNameResolver(nameContext);
-    newNameResolver.setCurrentFunctionDefinition(m_currentFunction);
+    NameResolver newNameResolver(*this, nameContext);
     newNameResolver.checkErrorAndVisit(whileLoop.body());
     checkErrorAndVisit(whileLoop.conditional());
 }
@@ -138,8 +142,7 @@
 void NameResolver::visit(AST::ForLoop& forLoop)
 {
     NameContext nameContext(&m_nameContext);
-    NameResolver newNameResolver(nameContext);
-    newNameResolver.setCurrentFunctionDefinition(m_currentFunction);
+    NameResolver newNameResolver(*this, nameContext);
     newNameResolver.Visitor::visit(forLoop);
 }
 
@@ -174,12 +177,14 @@
 
 void NameResolver::visit(AST::PropertyAccessExpression& propertyAccessExpression)
 {
-    if (auto* getterFunctions = m_nameContext.getFunctions(propertyAccessExpression.getterFunctionName()))
-        propertyAccessExpression.setPossibleGetterOverloads(*getterFunctions);
-    if (auto* setterFunctions = m_nameContext.getFunctions(propertyAccessExpression.setterFunctionName()))
-        propertyAccessExpression.setPossibleSetterOverloads(*setterFunctions);
-    if (auto* anderFunctions = m_nameContext.getFunctions(propertyAccessExpression.anderFunctionName()))
-        propertyAccessExpression.setPossibleAnderOverloads(*anderFunctions);
+    if (m_isResolvingCalls) {
+        if (auto* getterFunctions = m_nameContext.getFunctions(propertyAccessExpression.getterFunctionName()))
+            propertyAccessExpression.setPossibleGetterOverloads(*getterFunctions);
+        if (auto* setterFunctions = m_nameContext.getFunctions(propertyAccessExpression.setterFunctionName()))
+            propertyAccessExpression.setPossibleSetterOverloads(*setterFunctions);
+        if (auto* anderFunctions = m_nameContext.getFunctions(propertyAccessExpression.anderFunctionName()))
+            propertyAccessExpression.setPossibleAnderOverloads(*anderFunctions);
+    }
     Visitor::visit(propertyAccessExpression);
 }
 
@@ -210,24 +215,26 @@
 
 void NameResolver::visit(AST::CallExpression& callExpression)
 {
-    if (!callExpression.hasOverloads()) {
-        if (auto* functions = m_nameContext.getFunctions(callExpression.name()))
-            callExpression.setOverloads(*functions);
-        else {
-            if (auto* types = m_nameContext.getTypes(callExpression.name())) {
-                if (types->size() == 1) {
-                    if (auto* functions = m_nameContext.getFunctions("operator cast"_str)) {
-                        callExpression.setCastData((*types)[0].get());
-                        callExpression.setOverloads(*functions);
+    if (m_isResolvingCalls) {
+        if (!callExpression.hasOverloads()) {
+            if (auto* functions = m_nameContext.getFunctions(callExpression.name()))
+                callExpression.setOverloads(*functions);
+            else {
+                if (auto* types = m_nameContext.getTypes(callExpression.name())) {
+                    if (types->size() == 1) {
+                        if (auto* functions = m_nameContext.getFunctions("operator cast"_str)) {
+                            callExpression.setCastData((*types)[0].get());
+                            callExpression.setOverloads(*functions);
+                        }
                     }
                 }
             }
         }
+        if (!callExpression.hasOverloads()) {
+            setError();
+            return;
+        }
     }
-    if (!callExpression.hasOverloads()) {
-        setError();
-        return;
-    }
     Visitor::visit(callExpression);
 }
 
@@ -278,7 +285,7 @@
     return true;
 }
 
-bool resolveNamesInFunctions(Program& program, NameResolver& nameResolver)
+bool resolveTypeNamesInFunctions(Program& program, NameResolver& nameResolver)
 {
     for (auto& functionDefinition : program.functionDefinitions()) {
         nameResolver.setCurrentFunctionDefinition(&functionDefinition);
@@ -295,6 +302,20 @@
     return true;
 }
 
+bool resolveCallsInFunctions(Program& program, NameResolver& nameResolver)
+{
+    nameResolver.setIsResolvingCalls(true);
+    for (auto& functionDefinition : program.functionDefinitions()) {
+        nameResolver.setCurrentFunctionDefinition(&functionDefinition);
+        nameResolver.checkErrorAndVisit(functionDefinition);
+        if (nameResolver.error())
+            return false;
+    }
+    nameResolver.setCurrentFunctionDefinition(nullptr);
+    nameResolver.setIsResolvingCalls(false);
+    return true;
+}
+
 } // namespace WHLSL
 
 } // namespace WebCore

Modified: trunk/Source/WebCore/Modules/webgpu/WHLSL/WHLSLNameResolver.h (246549 => 246550)


--- trunk/Source/WebCore/Modules/webgpu/WHLSL/WHLSLNameResolver.h	2019-06-18 17:26:07 UTC (rev 246549)
+++ trunk/Source/WebCore/Modules/webgpu/WHLSL/WHLSLNameResolver.h	2019-06-18 17:49:07 UTC (rev 246550)
@@ -40,6 +40,7 @@
 class NameResolver : public Visitor {
 public:
     NameResolver(NameContext&);
+    NameResolver(NameResolver&, NameContext&);
 
     virtual ~NameResolver() = default;
 
@@ -50,6 +51,8 @@
         m_currentFunction = functionDefinition;
     }
 
+    void setIsResolvingCalls(bool isResolvingCalls) { m_isResolvingCalls = isResolvingCalls; }
+
 private:
     void visit(AST::TypeReference&) override;
     void visit(AST::Block&) override;
@@ -68,10 +71,12 @@
     NameContext& m_nameContext;
     HashSet<AST::TypeReference*> m_typeReferences;
     AST::FunctionDefinition* m_currentFunction { nullptr };
+    bool m_isResolvingCalls { false };
 };
 
 bool resolveNamesInTypes(Program&, NameResolver&);
-bool resolveNamesInFunctions(Program&, NameResolver&);
+bool resolveTypeNamesInFunctions(Program&, NameResolver&);
+bool resolveCallsInFunctions(Program&, NameResolver&);
 
 } // namespace WHLSL
 

Modified: trunk/Source/WebCore/Modules/webgpu/WHLSL/WHLSLPrepare.cpp (246549 => 246550)


--- trunk/Source/WebCore/Modules/webgpu/WHLSL/WHLSLPrepare.cpp	2019-06-18 17:26:07 UTC (rev 246549)
+++ trunk/Source/WebCore/Modules/webgpu/WHLSL/WHLSLPrepare.cpp	2019-06-18 17:49:07 UTC (rev 246550)
@@ -125,8 +125,9 @@
     RUN_PASS(synthesizeStructureAccessors, program);
     RUN_PASS(synthesizeEnumerationFunctions, program);
     RUN_PASS(synthesizeArrayOperatorLength, program);
+    RUN_PASS(resolveTypeNamesInFunctions, program, nameResolver);
     RUN_PASS(synthesizeConstructors, program);
-    RUN_PASS(resolveNamesInFunctions, program, nameResolver);
+    RUN_PASS(resolveCallsInFunctions, program, nameResolver);
     RUN_PASS(checkDuplicateFunctions, program);
 
     RUN_PASS(check, program);

Modified: trunk/Source/WebCore/Modules/webgpu/WHLSL/WHLSLSynthesizeConstructors.cpp (246549 => 246550)


--- trunk/Source/WebCore/Modules/webgpu/WHLSL/WHLSLSynthesizeConstructors.cpp	2019-06-18 17:26:07 UTC (rev 246549)
+++ trunk/Source/WebCore/Modules/webgpu/WHLSL/WHLSLSynthesizeConstructors.cpp	2019-06-18 17:49:07 UTC (rev 246550)
@@ -45,6 +45,41 @@
 
 namespace WHLSL {
 
+class UnnamedTypeKey {
+public:
+    UnnamedTypeKey() = default;
+    UnnamedTypeKey(WTF::HashTableDeletedValueType)
+    {
+        m_type = bitwise_cast<AST::UnnamedType*>(static_cast<uintptr_t>(1));
+    }
+
+    UnnamedTypeKey(AST::UnnamedType& type)
+        : m_type(&type)
+    { }
+
+    bool isEmptyValue() const { return !m_type; }
+    bool isHashTableDeletedValue() const { return m_type == bitwise_cast<AST::UnnamedType*>(static_cast<uintptr_t>(1)); }
+
+    unsigned hash() const { return m_type->hash(); }
+    bool operator==(const UnnamedTypeKey& other) const { return *m_type == *other.m_type; }
+    AST::UnnamedType& unnamedType() const { return *m_type; }
+
+    struct Hash {
+        static unsigned hash(const UnnamedTypeKey& key) { return key.hash(); }
+        static bool equal(const UnnamedTypeKey& a, const UnnamedTypeKey& b) { return a == b; }
+        static const bool safeToCompareToEmptyOrDeleted = false;
+        static const bool emptyValueIsZero = true;
+    };
+
+    struct Traits : public WTF::SimpleClassHashTraits<UnnamedTypeKey> {
+        static const bool hasIsEmptyValueFunction = true;
+        static bool isEmptyValue(const UnnamedTypeKey& key) { return key.isEmptyValue(); }
+    };
+
+private:
+    AST::UnnamedType* m_type { nullptr };
+};
+
 class FindAllTypes : public Visitor {
 public:
     ~FindAllTypes() = default;
@@ -51,41 +86,41 @@
 
     void visit(AST::PointerType& pointerType) override
     {
-        m_unnamedTypes.append(pointerType);
+        m_unnamedTypes.add(UnnamedTypeKey { pointerType });
         Visitor::visit(pointerType);
     }
 
     void visit(AST::ArrayReferenceType& arrayReferenceType) override
     {
-        m_unnamedTypes.append(arrayReferenceType);
+        m_unnamedTypes.add(UnnamedTypeKey { arrayReferenceType });
         Visitor::visit(arrayReferenceType);
     }
 
     void visit(AST::ArrayType& arrayType) override
     {
-        m_unnamedTypes.append(arrayType);
+        m_unnamedTypes.add(UnnamedTypeKey { arrayType });
         Visitor::visit(arrayType);
     }
 
     void visit(AST::EnumerationDefinition& enumerationDefinition) override
     {
-        m_namedTypes.append(enumerationDefinition);
+        appendNamedType(enumerationDefinition);
         Visitor::visit(enumerationDefinition);
     }
 
     void visit(AST::StructureDefinition& structureDefinition) override
     {
-        m_namedTypes.append(structureDefinition);
+        appendNamedType(structureDefinition);
         Visitor::visit(structureDefinition);
     }
 
     void visit(AST::NativeTypeDeclaration& nativeTypeDeclaration) override
     {
-        m_namedTypes.append(nativeTypeDeclaration);
+        appendNamedType(nativeTypeDeclaration);
         Visitor::visit(nativeTypeDeclaration);
     }
 
-    Vector<std::reference_wrapper<AST::UnnamedType>> takeUnnamedTypes()
+    HashSet<UnnamedTypeKey, UnnamedTypeKey::Hash, UnnamedTypeKey::Traits> takeUnnamedTypes()
     {
         return WTFMove(m_unnamedTypes);
     }
@@ -96,7 +131,17 @@
     }
 
 private:
-    Vector<std::reference_wrapper<AST::UnnamedType>> m_unnamedTypes;
+    void appendNamedType(AST::NamedType& type)
+    {
+        // The way we walk the AST ensures we should never visit a named type twice.
+#if !ASSERT_DISABLED
+        for (auto& entry : m_namedTypes)
+            ASSERT(&entry.get().unifyNode() != &type.unifyNode());
+#endif
+        m_namedTypes.append(type);
+    }
+
+    HashSet<UnnamedTypeKey, UnnamedTypeKey::Hash, UnnamedTypeKey::Traits> m_unnamedTypes;
     Vector<std::reference_wrapper<AST::NamedType>> m_namedTypes;
 };
 
@@ -109,14 +154,16 @@
 
     bool isOperator = true;
 
-    for (auto& unnamedType : unnamedTypes) {
-        auto variableDeclaration = makeUniqueRef<AST::VariableDeclaration>(Lexer::Token(unnamedType.get().origin()), AST::Qualifiers(), unnamedType.get().clone(), String(), WTF::nullopt, WTF::nullopt);
+    for (auto& unnamedTypeKey : unnamedTypes) {
+        auto& unnamedType = unnamedTypeKey.unnamedType();
+
+        auto variableDeclaration = makeUniqueRef<AST::VariableDeclaration>(Lexer::Token(unnamedType.origin()), AST::Qualifiers(), unnamedType.clone(), String(), WTF::nullopt, WTF::nullopt);
         AST::VariableDeclarations parameters;
         parameters.append(WTFMove(variableDeclaration));
-        AST::NativeFunctionDeclaration copyConstructor(AST::FunctionDeclaration(Lexer::Token(unnamedType.get().origin()), AST::AttributeBlock(), WTF::nullopt, unnamedType.get().clone(), "operator cast"_str, WTFMove(parameters), WTF::nullopt, isOperator));
+        AST::NativeFunctionDeclaration copyConstructor(AST::FunctionDeclaration(Lexer::Token(unnamedType.origin()), AST::AttributeBlock(), WTF::nullopt, unnamedType.clone(), "operator cast"_str, WTFMove(parameters), WTF::nullopt, isOperator));
         program.append(WTFMove(copyConstructor));
 
-        AST::NativeFunctionDeclaration defaultConstructor(AST::FunctionDeclaration(Lexer::Token(unnamedType.get().origin()), AST::AttributeBlock(), WTF::nullopt, unnamedType.get().clone(), "operator cast"_str, AST::VariableDeclarations(), WTF::nullopt, isOperator));
+        AST::NativeFunctionDeclaration defaultConstructor(AST::FunctionDeclaration(Lexer::Token(unnamedType.origin()), AST::AttributeBlock(), WTF::nullopt, unnamedType.clone(), "operator cast"_str, AST::VariableDeclarations(), WTF::nullopt, isOperator));
         if (!program.append(WTFMove(defaultConstructor)))
             return false;
     }
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to