Mangled WHLSL names don't need to allocate Strings
[WebKit-https.git] / Source / WebCore / Modules / webgpu / WHLSL / Metal / WHLSLMangledNames.h
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 #pragma once
27
28 #if ENABLE(WEBGPU)
29
30 #include <wtf/Variant.h>
31 #include <wtf/text/StringConcatenate.h>
32 #include <wtf/text/StringConcatenateNumbers.h>
33
34 namespace WebCore {
35
36 namespace WHLSL {
37
38 namespace Metal {
39
40 struct MangledVariableName {
41     unsigned value;
42     static constexpr const char* prefix = "variable";
43 };
44
45 struct MangledTypeName {
46     unsigned value;
47     static constexpr const char* prefix = "type";
48 };
49
50 struct MangledStructureElementName {
51     unsigned value;
52     static constexpr const char* prefix = "structureElement";
53 };
54
55 struct MangledEnumerationMemberName {
56     unsigned value;
57     static constexpr const char* prefix = "enumerationMember";
58 };
59
60 struct MangledFunctionName {
61     unsigned value;
62     static constexpr const char* prefix = "function";
63
64     String toString() const { return makeString(prefix, value); }
65 };
66
67 using MangledOrNativeTypeName = Variant<MangledTypeName, String>;
68
69 } // namespace Metal
70
71 } // namespace WHLSL
72
73 } // namespace WebCore
74
75 namespace WTF {
76
77 template<typename MangledNameType>
78 class MangledNameAdaptor {
79 public:
80     MangledNameAdaptor(MangledNameType name)
81         : m_name { name }
82     {
83     }
84
85     unsigned length() { return strlen(MangledNameType::prefix) + lengthOfNumberAsStringUnsigned(m_name.value); }
86     bool is8Bit() { return true; }
87     template<typename CharacterType> void writeTo(CharacterType* destination)
88     {
89         StringImpl::copyCharacters(destination, reinterpret_cast<const LChar*>(MangledNameType::prefix), strlen(MangledNameType::prefix));
90         writeNumberToBufferUnsigned(m_name.value, destination + strlen(MangledNameType::prefix));
91     }
92
93 private:
94     MangledNameType m_name;
95 };
96
97 template<> class StringTypeAdapter<WebCore::WHLSL::Metal::MangledVariableName, void> : public MangledNameAdaptor<WebCore::WHLSL::Metal::MangledVariableName> {
98 public:
99     StringTypeAdapter(WebCore::WHLSL::Metal::MangledVariableName name)
100         : MangledNameAdaptor(name)
101     {
102     }
103 };
104 template<> class StringTypeAdapter<WebCore::WHLSL::Metal::MangledTypeName, void> : public MangledNameAdaptor<WebCore::WHLSL::Metal::MangledTypeName> {
105 public:
106     StringTypeAdapter(WebCore::WHLSL::Metal::MangledTypeName name)
107         : MangledNameAdaptor(name)
108     {
109     }
110 };
111 template<> class StringTypeAdapter<WebCore::WHLSL::Metal::MangledStructureElementName, void> : public MangledNameAdaptor<WebCore::WHLSL::Metal::MangledStructureElementName> {
112 public:
113     StringTypeAdapter(WebCore::WHLSL::Metal::MangledStructureElementName name)
114         : MangledNameAdaptor(name)
115     {
116     }
117 };
118 template<> class StringTypeAdapter<WebCore::WHLSL::Metal::MangledEnumerationMemberName, void> : public MangledNameAdaptor<WebCore::WHLSL::Metal::MangledEnumerationMemberName> {
119 public:
120     StringTypeAdapter(WebCore::WHLSL::Metal::MangledEnumerationMemberName name)
121         : MangledNameAdaptor(name)
122     {
123     }
124 };
125 template<> class StringTypeAdapter<WebCore::WHLSL::Metal::MangledFunctionName, void> : public MangledNameAdaptor<WebCore::WHLSL::Metal::MangledFunctionName> {
126 public:
127     StringTypeAdapter(WebCore::WHLSL::Metal::MangledFunctionName name)
128         : MangledNameAdaptor(name)
129     {
130     }
131 };
132
133 template<> class StringTypeAdapter<WebCore::WHLSL::Metal::MangledOrNativeTypeName, void> {
134 public:
135     StringTypeAdapter(const WebCore::WHLSL::Metal::MangledOrNativeTypeName& name)
136         : m_name { name }
137     {
138     }
139
140     unsigned length()
141     {
142         return WTF::switchOn(m_name,
143             [&] (const WebCore::WHLSL::Metal::MangledTypeName& mangledTypeName) {
144                 return strlen(WebCore::WHLSL::Metal::MangledTypeName::prefix) + lengthOfNumberAsStringUnsigned(mangledTypeName.value);
145             },
146             [&] (const String& string) {
147                 return string.length();
148             }
149         );
150     }
151
152     bool is8Bit()
153     {
154         return WTF::switchOn(m_name,
155             [&] (const WebCore::WHLSL::Metal::MangledTypeName&) {
156                 return true;
157             },
158             [&] (const String& string) {
159                 return string.is8Bit();
160             }
161         );
162     }
163
164     template<typename CharacterType> void writeTo(CharacterType* destination)
165     {
166         WTF::switchOn(m_name,
167             [&] (const WebCore::WHLSL::Metal::MangledTypeName& mangledTypeName) {
168                 StringImpl::copyCharacters(destination, reinterpret_cast<const LChar*>(WebCore::WHLSL::Metal::MangledTypeName::prefix), strlen(WebCore::WHLSL::Metal::MangledTypeName::prefix));
169                 writeNumberToBufferUnsigned(mangledTypeName.value, destination + strlen(WebCore::WHLSL::Metal::MangledTypeName::prefix));
170             },
171             [&] (const String& string) {
172                 StringView { string }.getCharactersWithUpconvert(destination);
173             }
174         );
175     }
176
177 private:
178     const WebCore::WHLSL::Metal::MangledOrNativeTypeName& m_name;
179 };
180
181 }
182
183 #endif