1 | /* |
2 | * Copyright (C) 2019 Apple Inc. All rights reserved. |
3 | * |
4 | * Redistribution and use in source and binary forms, with or without |
5 | * modification, are permitted provided that the following conditions |
6 | * are met: |
7 | * 1. Redistributions of source code must retain the above copyright |
8 | * notice, this list of conditions and the following disclaimer. |
9 | * 2. Redistributions in binary form must reproduce the above copyright |
10 | * notice, this list of conditions and the following disclaimer in the |
11 | * documentation and/or other materials provided with the distribution. |
12 | * |
13 | * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' |
14 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, |
15 | * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
16 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS |
17 | * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
18 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
19 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
20 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
21 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
22 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF |
23 | * THE POSSIBILITY OF SUCH DAMAGE. |
24 | */ |
25 | |
26 | #include "config.h" |
27 | #include "WHLSLGatherEntryPointItems.h" |
28 | |
29 | #if ENABLE(WEBGPU) |
30 | |
31 | #include "WHLSLArrayReferenceType.h" |
32 | #include "WHLSLArrayType.h" |
33 | #include "WHLSLFunctionDefinition.h" |
34 | #include "WHLSLInferTypes.h" |
35 | #include "WHLSLIntrinsics.h" |
36 | #include "WHLSLPointerType.h" |
37 | #include "WHLSLStructureDefinition.h" |
38 | #include "WHLSLTypeDefinition.h" |
39 | #include "WHLSLTypeReference.h" |
40 | #include "WHLSLVariableDeclaration.h" |
41 | #include "WHLSLVisitor.h" |
42 | #include <wtf/Optional.h> |
43 | |
44 | namespace WebCore { |
45 | |
46 | namespace WHLSL { |
47 | |
48 | class Gatherer : public Visitor { |
49 | public: |
50 | Gatherer(const Intrinsics& intrinsics, AST::Semantic* semantic = nullptr) |
51 | : m_intrinsics(intrinsics) |
52 | , m_currentSemantic(semantic) |
53 | { |
54 | } |
55 | |
56 | virtual ~Gatherer() = default; |
57 | |
58 | void reset() |
59 | { |
60 | m_currentSemantic = nullptr; |
61 | } |
62 | |
63 | Vector<EntryPointItem>&& takeEntryPointItems() |
64 | { |
65 | return WTFMove(m_entryPointItems); |
66 | } |
67 | |
68 | void visit(AST::EnumerationDefinition&) |
69 | { |
70 | if (!m_currentSemantic) { |
71 | setError(); |
72 | return; |
73 | } |
74 | m_entryPointItems.append(EntryPointItem(m_typeReferences.last().get(), *m_currentSemantic, m_path)); |
75 | } |
76 | |
77 | void visit(AST::NativeTypeDeclaration& nativeTypeDeclaration) |
78 | { |
79 | if (!m_currentSemantic) { |
80 | setError(); |
81 | return; |
82 | } |
83 | if (matches(nativeTypeDeclaration, m_intrinsics.voidType())) { |
84 | setError(); |
85 | return; |
86 | } |
87 | |
88 | m_entryPointItems.append(EntryPointItem(m_typeReferences.last().get(), *m_currentSemantic, m_path)); |
89 | } |
90 | |
91 | void visit(AST::StructureDefinition& structureDefinition) |
92 | { |
93 | if (m_currentSemantic) { |
94 | setError(); |
95 | return; |
96 | } |
97 | |
98 | for (auto& structureElement : structureDefinition.structureElements()) { |
99 | if (structureElement.semantic()) |
100 | m_currentSemantic = &*structureElement.semantic(); |
101 | m_path.append(structureElement.name()); |
102 | checkErrorAndVisit(structureElement); |
103 | m_path.takeLast(); |
104 | } |
105 | } |
106 | |
107 | void visit(AST::TypeDefinition& typeDefinition) |
108 | { |
109 | checkErrorAndVisit(typeDefinition.type()); |
110 | } |
111 | |
112 | void visit(AST::TypeReference& typeReference) |
113 | { |
114 | ASSERT(typeReference.resolvedType()); |
115 | m_typeReferences.append(typeReference); |
116 | auto depth = m_typeReferences.size(); |
117 | checkErrorAndVisit(*typeReference.resolvedType()); |
118 | ASSERT_UNUSED(depth, m_typeReferences.size() == depth); |
119 | m_typeReferences.removeLast(); |
120 | } |
121 | |
122 | void visit(AST::PointerType& pointerType) |
123 | { |
124 | if (!m_currentSemantic) { |
125 | setError(); |
126 | return; |
127 | } |
128 | m_entryPointItems.append(EntryPointItem(pointerType, *m_currentSemantic, m_path)); |
129 | } |
130 | |
131 | void visit(AST::ArrayReferenceType& arrayReferenceType) |
132 | { |
133 | if (!m_currentSemantic) { |
134 | setError(); |
135 | return; |
136 | } |
137 | m_entryPointItems.append(EntryPointItem(arrayReferenceType, *m_currentSemantic, m_path)); |
138 | } |
139 | |
140 | void visit(AST::ArrayType& arrayType) |
141 | { |
142 | if (!m_currentSemantic) { |
143 | setError(); |
144 | return; |
145 | } |
146 | m_entryPointItems.append(EntryPointItem(arrayType, *m_currentSemantic, m_path)); |
147 | } |
148 | |
149 | void visit(AST::VariableDeclaration& variableDeclaration) |
150 | { |
151 | ASSERT(!m_currentSemantic); |
152 | if (variableDeclaration.semantic()) |
153 | m_currentSemantic = &*variableDeclaration.semantic(); |
154 | ASSERT(variableDeclaration.type()); |
155 | m_path.append(variableDeclaration.name()); |
156 | checkErrorAndVisit(*variableDeclaration.type()); |
157 | m_path.takeLast(); |
158 | } |
159 | |
160 | private: |
161 | Vector<String> m_path; |
162 | const Intrinsics& m_intrinsics; |
163 | AST::Semantic* m_currentSemantic { nullptr }; |
164 | Vector<std::reference_wrapper<AST::TypeReference>> m_typeReferences; |
165 | Vector<EntryPointItem> m_entryPointItems; |
166 | }; |
167 | |
168 | Optional<EntryPointItems> gatherEntryPointItems(const Intrinsics& intrinsics, AST::FunctionDefinition& functionDefinition) |
169 | { |
170 | ASSERT(functionDefinition.entryPointType()); |
171 | Gatherer inputGatherer(intrinsics); |
172 | for (auto& parameter : functionDefinition.parameters()) { |
173 | inputGatherer.reset(); |
174 | inputGatherer.checkErrorAndVisit(parameter); |
175 | if (inputGatherer.error()) |
176 | return WTF::nullopt; |
177 | } |
178 | Gatherer outputGatherer(intrinsics, functionDefinition.semantic() ? &*functionDefinition.semantic() : nullptr); |
179 | outputGatherer.checkErrorAndVisit(functionDefinition.type()); |
180 | if (outputGatherer.error()) |
181 | return WTF::nullopt; |
182 | |
183 | return {{ inputGatherer.takeEntryPointItems(), outputGatherer.takeEntryPointItems() }}; |
184 | } |
185 | |
186 | } // namespace WHLSL |
187 | |
188 | } // namespace WebCore |
189 | |
190 | #endif // ENABLE(WEBGPU) |
191 | |