WebKit Bugzilla
Attachment 356353 Details for
Bug 192294
: [WHLSL] Add a handwritten lexer
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
New Account
|
Log In
Remember
[x]
|
Forgot Password
Login:
[x]
[patch]
WIP
bug-192294-20181202203840.patch (text/plain), 32.09 KB, created by
Myles C. Maxfield
on 2018-12-02 20:38:41 PST
(
hide
)
Description:
WIP
Filename:
MIME Type:
Creator:
Myles C. Maxfield
Created:
2018-12-02 20:38:41 PST
Size:
32.09 KB
patch
obsolete
>Subversion Revision: 238790 >diff --git a/Source/WebCore/ChangeLog b/Source/WebCore/ChangeLog >index dcf602f7fb289c5520d07d02d5c7f5ad5f597a3e..683226c0f48dae315c92fe1e0643b873d931e066 100644 >--- a/Source/WebCore/ChangeLog >+++ b/Source/WebCore/ChangeLog >@@ -1,3 +1,50 @@ >+2018-12-02 Myles C. Maxfield <mmaxfield@apple.com> >+ >+ [WHLSL] Add a handwritten lexer >+ https://bugs.webkit.org/show_bug.cgi?id=192294 >+ >+ Reviewed by NOBODY (OOPS!). >+ >+ No new tests (OOPS!). >+ >+ * Modules/webgpu/WHLSL/WHLSLLexer.cpp: Added. >+ (WebCore::WHLSL::Lexer::consumeTokenFromStream): >+ (WebCore::WHLSL::Lexer::skipWhitespaceAndComments): >+ (WebCore::WHLSL::isWhitespace): >+ (WebCore::WHLSL::isNewline): >+ (WebCore::WHLSL::Lexer::skipWhitespace): >+ (WebCore::WHLSL::Lexer::skipLineComment): >+ (WebCore::WHLSL::Lexer::skipLongComment): >+ (WebCore::WHLSL::Lexer::coreDecimalIntLiteral const): >+ (WebCore::WHLSL::Lexer::decimalIntLiteral const): >+ (WebCore::WHLSL::Lexer::decimalUintLiteral const): >+ (WebCore::WHLSL::isHexadecimalCharacter): >+ (WebCore::WHLSL::Lexer::coreHexadecimalIntLiteral const): >+ (WebCore::WHLSL::Lexer::hexadecimalIntLiteral const): >+ (WebCore::WHLSL::Lexer::hexadecimalUintLiteral const): >+ (WebCore::WHLSL::Lexer::intLiteral const): >+ (WebCore::WHLSL::Lexer::digit const): >+ (WebCore::WHLSL::Lexer::digitStar const): >+ (WebCore::WHLSL::Lexer::character const): >+ (WebCore::WHLSL::Lexer::coreFloatLiteralType1 const): >+ (WebCore::WHLSL::Lexer::coreFloatLiteral const): >+ (WebCore::WHLSL::Lexer::floatLiteral const): >+ (WebCore::WHLSL::Lexer::qualifier const): >+ (WebCore::WHLSL::Lexer::semantic const): >+ (WebCore::WHLSL::Lexer::numthreads const): >+ (WebCore::WHLSL::Lexer::validIdentifier const): >+ (WebCore::WHLSL::Lexer::identifier const): >+ (WebCore::WHLSL::Lexer::operatorName const): >+ * Modules/webgpu/WHLSL/WHLSLLexer.h: Added. >+ (WebCore::WHLSL::Lexer::Lexer): >+ (WebCore::WHLSL::Lexer::consumeToken): >+ (WebCore::WHLSL::Lexer::unconsumeToken): >+ (WebCore::WHLSL::Lexer::isFullyConsumed const): >+ (WebCore::WHLSL::Lexer::string const): >+ (WebCore::WHLSL::Lexer::anyCharacter const): >+ * Sources.txt: >+ * WebCore.xcodeproj/project.pbxproj: >+ > 2018-12-01 Brent Fulgham <bfulgham@apple.com> > > Lifetime of HTMLMediaElement is not properly handled in asynchronous actions >diff --git a/Source/WebCore/Modules/webgpu/WHLSL/WHLSLLexer.cpp b/Source/WebCore/Modules/webgpu/WHLSL/WHLSLLexer.cpp >new file mode 100644 >index 0000000000000000000000000000000000000000..59a4cd4dc523d3c637f52cf04424c4766d493609 >--- /dev/null >+++ b/Source/WebCore/Modules/webgpu/WHLSL/WHLSLLexer.cpp >@@ -0,0 +1,554 @@ >+/* >+ * Copyright (C) 2018 Apple Inc. All rights reserved. >+ * >+ * Redistribution and use in source and binary forms, with or without >+ * modification, are permitted provided that the following conditions >+ * are met: >+ * 1. Redistributions of source code must retain the above copyright >+ * notice, this list of conditions and the following disclaimer. >+ * 2. Redistributions in binary form must reproduce the above copyright >+ * notice, this list of conditions and the following disclaimer in the >+ * documentation and/or other materials provided with the distribution. >+ * >+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' >+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, >+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR >+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS >+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR >+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF >+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS >+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN >+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) >+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF >+ * THE POSSIBILITY OF SUCH DAMAGE. >+ */ >+ >+#pragma once >+ >+#if ENABLE(WEBGPU) >+ >+#include "config.h" >+#include "WHLSLLexer.h" >+ >+namespace WebCore { >+ >+namespace WHLSL { >+ >+typedef std::optional<unsigned> (Lexer::*ParserRule)(unsigned) const; >+ >+auto Lexer::consumeTokenFromStream() -> std::optional<Token> >+{ >+ auto prepare = [&](unsigned newOffset, Token::Type type) -> std::optional<Token> { >+ auto offset = m_offset; >+ m_offset = newOffset; >+ skipWhitespaceAndComments(); >+ return {{ m_stringView.substring(offset, m_offset - offset), type }}; >+ }; >+ >+ if (auto newOffset = intLiteral(m_offset)) >+ return prepare(*newOffset, Token::Type::IntLiteral); >+ if (auto newOffset = floatLiteral(m_offset)) >+ return prepare(*newOffset, Token::Type::FloatLiteral); >+ if (auto newOffset = string("struct", m_offset)) >+ return prepare(*newOffset, Token::Type::Struct); >+ if (auto newOffset = string("typedef", m_offset)) >+ return prepare(*newOffset, Token::Type::Typedef); >+ if (auto newOffset = string("enum", m_offset)) >+ return prepare(*newOffset, Token::Type::Enum); >+ if (auto newOffset = string("operator", m_offset)) >+ return prepare(*newOffset, Token::Type::Operator); >+ if (auto newOffset = string("if", m_offset)) >+ return prepare(*newOffset, Token::Type::If); >+ if (auto newOffset = string("else", m_offset)) >+ return prepare(*newOffset, Token::Type::Else); >+ if (auto newOffset = string("continue", m_offset)) >+ return prepare(*newOffset, Token::Type::Continue); >+ if (auto newOffset = string("break", m_offset)) >+ return prepare(*newOffset, Token::Type::Break); >+ if (auto newOffset = string("switch", m_offset)) >+ return prepare(*newOffset, Token::Type::Switch); >+ if (auto newOffset = string("case", m_offset)) >+ return prepare(*newOffset, Token::Type::Case); >+ if (auto newOffset = string("default", m_offset)) >+ return prepare(*newOffset, Token::Type::Default); >+ if (auto newOffset = string("fallthrough", m_offset)) >+ return prepare(*newOffset, Token::Type::Fallthrough); >+ if (auto newOffset = string("for", m_offset)) >+ return prepare(*newOffset, Token::Type::For); >+ if (auto newOffset = string("while", m_offset)) >+ return prepare(*newOffset, Token::Type::While); >+ if (auto newOffset = string("do", m_offset)) >+ return prepare(*newOffset, Token::Type::Do); >+ if (auto newOffset = string("return", m_offset)) >+ return prepare(*newOffset, Token::Type::Return); >+ if (auto newOffset = string("trap", m_offset)) >+ return prepare(*newOffset, Token::Type::Trap); >+ if (auto newOffset = string("null", m_offset)) >+ return prepare(*newOffset, Token::Type::Null); >+ if (auto newOffset = string("true", m_offset)) >+ return prepare(*newOffset, Token::Type::True); >+ if (auto newOffset = string("false", m_offset)) >+ return prepare(*newOffset, Token::Type::False); >+ if (auto newOffset = string("constant", m_offset)) >+ return prepare(*newOffset, Token::Type::Constant); >+ if (auto newOffset = string("device", m_offset)) >+ return prepare(*newOffset, Token::Type::Device); >+ if (auto newOffset = string("threadgroup", m_offset)) >+ return prepare(*newOffset, Token::Type::Threadgroup); >+ if (auto newOffset = string("thread", m_offset)) >+ return prepare(*newOffset, Token::Type::Thread); >+ if (auto newOffset = string("space", m_offset)) >+ return prepare(*newOffset, Token::Type::Space); >+ if (auto newOffset = string("vertex", m_offset)) >+ return prepare(*newOffset, Token::Type::Vertex); >+ if (auto newOffset = string("fragment", m_offset)) >+ return prepare(*newOffset, Token::Type::Fragment); >+ if (auto newOffset = string("compute", m_offset)) >+ return prepare(*newOffset, Token::Type::Compute); >+ if (auto newOffset = string("numthreads", m_offset)) >+ return prepare(*newOffset, Token::Type::Numthreads); >+ if (auto newOffset = string("native", m_offset)) >+ return prepare(*newOffset, Token::Type::Native); >+ if (auto newOffset = string("restricted", m_offset)) >+ return prepare(*newOffset, Token::Type::Restricted); >+ if (auto newOffset = string("_", m_offset)) >+ return prepare(*newOffset, Token::Type::Underscore); >+ if (auto newOffset = string("auto", m_offset)) >+ return prepare(*newOffset, Token::Type::Auto); >+ if (auto newOffset = string("protocol", m_offset)) >+ return prepare(*newOffset, Token::Type::Protocol); >+ if (auto newOffset = string("const", m_offset)) >+ return prepare(*newOffset, Token::Type::Const); >+ if (auto newOffset = string("static", m_offset)) >+ return prepare(*newOffset, Token::Type::Static); >+ if (auto newOffset = qualifier(m_offset)) >+ return prepare(*newOffset, Token::Type::Qualifier); >+ if (auto newOffset = semantic(m_offset)) >+ return prepare(*newOffset, Token::Type::Semantic); >+ if (auto newOffset = numthreads(m_offset)) >+ return prepare(*newOffset, Token::Type::NumthreadsSemantic); >+ if (auto newOffset = identifier(m_offset)) >+ return prepare(*newOffset, Token::Type::Identifier); >+ if (auto newOffset = operatorName(m_offset)) >+ return prepare(*newOffset, Token::Type::OperatorName); >+ >+ skipWhitespaceAndComments(); >+ return std::nullopt; >+} >+ >+void Lexer::skipWhitespaceAndComments() >+{ >+ unsigned savedOffset; >+ do { >+ savedOffset = m_offset; >+ skipWhitespace(); >+ skipLineComment(); >+ skipLongComment(); >+ } while (savedOffset != m_offset); >+} >+ >+static inline bool isWhitespace(UChar codeUnit) >+{ >+ switch (codeUnit) { >+ case ' ': >+ case '\t': >+ case '\r': >+ case '\n': >+ return true; >+ default: >+ return false; >+ } >+} >+ >+static inline bool isNewline(UChar codeUnit) >+{ >+ switch (codeUnit) { >+ case '\r': >+ case '\n': >+ return true; >+ default: >+ return false; >+ } >+} >+ >+// We can take advantage of two properties of Unicode: >+// 1. The consitutent UTF-16 code units for all non-BMP code points are surrogates, >+// which means we'll never see a false match. If we see a BMP code unit, we >+// really have a BMP code point. >+// 2. Everything we're looking for is in BMP >+ >+void Lexer::skipWhitespace() >+{ >+ for ( ; m_offset < m_stringView.length() && isWhitespace(m_stringView[m_offset]); ++m_offset) { } >+} >+ >+void Lexer::skipLineComment() >+{ >+ if (m_offset + 1 >= m_stringView.length() || m_stringView[m_offset] != '/' || m_stringView[m_offset + 1] != '/') >+ return; >+ >+ m_offset += 2; >+ for ( ; m_offset < m_stringView.length() && !isNewline(m_stringView[m_offset]); ++m_offset) { } >+} >+ >+void Lexer::skipLongComment() >+{ >+ if (m_offset + 1 >= m_stringView.length() || m_stringView[m_offset] != '/' || m_stringView[m_offset + 1] != '*') >+ return; >+ >+ m_offset += 2; >+ do { >+ for ( ; m_offset < m_stringView.length() && m_stringView[m_offset] != '*'; ++m_offset) { } >+ if (m_offset < m_stringView.length()) >+ ++m_offset; >+ if (m_offset < m_stringView.length() && m_stringView[m_offset] == '/') { >+ ++m_offset; >+ break; >+ } >+ } while (m_offset < m_stringView.length()); >+} >+ >+// Regular expression are unnecessary; we shouldn't need to compile them. >+ >+std::optional<unsigned> Lexer::coreDecimalIntLiteral(unsigned offset) const >+{ >+ if (offset >= m_stringView.length()) >+ return std::nullopt; >+ if (m_stringView[offset] == '0') >+ return offset + 1; >+ if (m_stringView[offset] >= '1' && m_stringView[offset] <= '9') { >+ ++offset; >+ for ( ; offset < m_stringView.length() && m_stringView[offset] >= '0' && m_stringView[offset] <= '9'; ++offset) { >+ } >+ return offset; >+ } >+ return std::nullopt; >+} >+ >+std::optional<unsigned> Lexer::decimalIntLiteral(unsigned offset) const >+{ >+ if (offset < m_stringView.length() && m_stringView[offset] == '-') >+ ++offset; >+ return coreDecimalIntLiteral(offset); >+} >+ >+std::optional<unsigned> Lexer::decimalUintLiteral(unsigned offset) const >+{ >+ auto result = coreDecimalIntLiteral(offset); >+ if (!result) >+ return std::nullopt; >+ if (*result < m_stringView.length() && m_stringView[*result] == 'u') >+ return *result + 1; >+ return std::nullopt; >+} >+ >+static inline bool isHexadecimalCharacter(UChar character) >+{ >+ return (character >= '0' && character <= '9') >+ || (character >= 'a' && character <= 'f') >+ || (character >= 'A' && character <= 'F'); >+} >+ >+std::optional<unsigned> Lexer::coreHexadecimalIntLiteral(unsigned offset) const >+{ >+ if (offset + 1 >= m_stringView.length() || m_stringView[offset] != '0' || m_stringView[offset + 1] != 'x') >+ return std::nullopt; >+ >+ offset += 2; >+ if (offset >= m_stringView.length() || !isHexadecimalCharacter(m_stringView[offset])) >+ return std::nullopt; >+ ++offset; >+ for ( ; offset < m_stringView.length() && isHexadecimalCharacter(m_stringView[offset]); ++offset) { >+ } >+ return offset; >+} >+ >+std::optional<unsigned> Lexer::hexadecimalIntLiteral(unsigned offset) const >+{ >+ if (offset < m_stringView.length() && m_stringView[offset] == '-') >+ ++offset; >+ return coreHexadecimalIntLiteral(offset); >+} >+ >+std::optional<unsigned> Lexer::hexadecimalUintLiteral(unsigned offset) const >+{ >+ auto result = coreHexadecimalIntLiteral(offset); >+ if (!result) >+ return std::nullopt; >+ if (*result < m_stringView.length() && m_stringView[*result] == 'u') >+ return *result + 1; >+ return std::nullopt; >+} >+ >+std::optional<unsigned> Lexer::intLiteral(unsigned offset) const >+{ >+ if (auto result = decimalIntLiteral(offset)) >+ return result; >+ if (auto result = decimalUintLiteral(offset)) >+ return result; >+ if (auto result = hexadecimalIntLiteral(offset)) >+ return result; >+ if (auto result = hexadecimalUintLiteral(offset)) >+ return result; >+ return std::nullopt; >+} >+ >+std::optional<unsigned> Lexer::digit(unsigned offset) const >+{ >+ if (offset < m_stringView.length() && m_stringView[offset] >= '0' && m_stringView[offset] <= '9') >+ return offset + 1; >+ return std::nullopt; >+} >+ >+unsigned Lexer::digitStar(unsigned offset) const >+{ >+ while (true) { >+ auto result = digit(offset); >+ if (!result) >+ return offset; >+ offset = *result; >+ } >+} >+ >+std::optional<unsigned> Lexer::character(char character, unsigned offset) const >+{ >+ if (offset < m_stringView.length() && m_stringView[offset] == character) >+ return offset + 1; >+ return std::nullopt; >+} >+ >+std::optional<unsigned> Lexer::coreFloatLiteralType1(unsigned offset) const >+{ >+ auto result = digit(offset); >+ if (!result) >+ return std::nullopt; >+ auto result2 = digitStar(*result); >+ auto result3 = character('.', result2); >+ if (!result3) >+ return std::nullopt; >+ return digitStar(*result3); >+} >+ >+std::optional<unsigned> Lexer::coreFloatLiteral(unsigned offset) const >+{ >+ if (auto type1 = coreFloatLiteralType1(offset)) >+ return type1; >+ auto result = digitStar(offset); >+ auto result2 = character('.', result); >+ if (!result2) >+ return std::nullopt; >+ auto result3 = digit(*result2); >+ if (!result3) >+ return std::nullopt; >+ return digitStar(*result3); >+} >+ >+std::optional<unsigned> Lexer::floatLiteral(unsigned offset) const >+{ >+ if (offset < m_stringView.length() && m_stringView[offset] == '-') >+ ++offset; >+ auto result = coreFloatLiteral(offset); >+ if (!result) >+ return std::nullopt; >+ offset = *result; >+ if (offset < m_stringView.length() && (m_stringView[offset] == 'f' || m_stringView[offset] == 'd')) >+ ++offset; >+ return offset; >+} >+ >+std::optional<unsigned> Lexer::qualifier(unsigned offset) const >+{ >+ if (auto result = string("nointerpolation", offset)) >+ return result; >+ if (auto result = string("noperspective", offset)) >+ return result; >+ if (auto result = string("uniform", offset)) >+ return result; >+ if (auto result = string("centroid", offset)) >+ return result; >+ if (auto result = string("sample", offset)) >+ return result; >+ return std::nullopt; >+} >+ >+std::optional<unsigned> Lexer::semantic(unsigned offset) const >+{ >+ if (auto result = string("SV_InstanceID", offset)) >+ return result; >+ if (auto result = string("SV_VertexID", offset)) >+ return result; >+ if (auto result = string("PSIZE", offset)) >+ return result; >+ if (auto result = string("SV_Position", offset)) >+ return result; >+ if (auto result = string("SV_IsFrontFace", offset)) >+ return result; >+ if (auto result = string("SV_SampleIndex", offset)) >+ return result; >+ if (auto result = string("SV_InnerCoverage", offset)) >+ return result; >+ if (auto result = string("SV_Target", offset)) >+ return coreDecimalIntLiteral(*result); >+ if (auto result = string("SV_Depth", offset)) >+ return result; >+ if (auto result = string("SV_Coverage", offset)) >+ return result; >+ if (auto result = string("SV_DispatchThreadID", offset)) >+ return result; >+ if (auto result = string("SV_GroupID", offset)) >+ return result; >+ if (auto result = string("SV_GroupIndex", offset)) >+ return result; >+ if (auto result = string("SV_GroupThreadID", offset)) >+ return result; >+ if (auto result = string("attribute", offset)) { >+ if ((result = character('(', *result))) { >+ if ((result = coreDecimalIntLiteral(*result))) >+ return character(')', *result); >+ } >+ } >+ if (auto result = string("register", offset)) { >+ if ((result = character('(', *result))) { >+ if ((result = anyCharacter("utbs", *result))) { >+ if ((result = coreDecimalIntLiteral(*result))) { >+ offset = *result; >+ if ((result = character(',', offset))) { >+ if ((result = string("space", *result))) { >+ if ((result = coreDecimalIntLiteral(*result))) >+ return character(')', *result); >+ } >+ return std::nullopt; >+ } >+ return character(')', offset); >+ } >+ } >+ } >+ } >+ if (auto result = string("specialized", offset)) >+ return result; >+ return std::nullopt; >+} >+ >+std::optional<unsigned> Lexer::numthreads(unsigned offset) const >+{ >+ auto result = string("numthreads", offset); >+ if (!result) >+ return std::nullopt; >+ result = character('(', *result); >+ if (!result) >+ return std::nullopt; >+ result = coreDecimalIntLiteral(*result); >+ if (!result) >+ return std::nullopt; >+ result = character(',', *result); >+ if (!result) >+ return std::nullopt; >+ if (auto result2 = character(' ', *result)) >+ result = result2; >+ result = coreDecimalIntLiteral(*result); >+ if (!result) >+ return std::nullopt; >+ result = character(',', *result); >+ if (!result) >+ return std::nullopt; >+ if (auto result2 = character(' ', *result)) >+ result = result2; >+ result = coreDecimalIntLiteral(*result); >+ if (!result) >+ return std::nullopt; >+ return character(')', *result); >+} >+ >+std::optional<unsigned> Lexer::validIdentifier(unsigned offset) const >+{ >+ if (offset >= m_stringView.length() >+ || !((m_stringView[offset] >= 'a' && m_stringView[offset] <= 'z') >+ || (m_stringView[offset] >= 'A' && m_stringView[offset] <= 'Z') >+ || (m_stringView[offset] == '_'))) >+ return std::nullopt; >+ ++offset; >+ while (true) { >+ if (offset >= m_stringView.length() >+ || !((m_stringView[offset] >= 'a' && m_stringView[offset] <= 'z') >+ || (m_stringView[offset] >= 'A' && m_stringView[offset] <= 'Z') >+ || (m_stringView[offset] >= '0' && m_stringView[offset] <= '9') >+ || (m_stringView[offset] == '_'))) >+ return offset; >+ ++offset; >+ } >+} >+ >+std::optional<unsigned> Lexer::identifier(unsigned offset) const >+{ >+ return validIdentifier(offset); >+} >+ >+std::optional<unsigned> Lexer::operatorName(unsigned offset) const >+{ >+ if (auto result = string("operator&.", offset)) >+ return validIdentifier(*result); >+ if (auto result = string("operator.", offset)) { >+ if ((result = validIdentifier(*result))) { >+ if (auto result2 = character('=', *result)) >+ return result2; >+ return *result; >+ } >+ } >+ if (auto result = string("operator", offset)) { >+ if (auto result2 = string(">>", *result)) >+ return result2; >+ if (auto result2 = string("<<", *result)) >+ return result2; >+ if (auto result2 = string("++", *result)) >+ return result2; >+ if (auto result2 = string("--", *result)) >+ return result2; >+ if (auto result2 = string("+", *result)) >+ return result2; >+ if (auto result2 = string("-", *result)) >+ return result2; >+ if (auto result2 = string("*", *result)) >+ return result2; >+ if (auto result2 = string("/", *result)) >+ return result2; >+ if (auto result2 = string("%", *result)) >+ return result2; >+ if (auto result2 = string("&&", *result)) >+ return result2; >+ if (auto result2 = string("||", *result)) >+ return result2; >+ if (auto result2 = string("&[]", *result)) >+ return result2; >+ if (auto result2 = string("&", *result)) >+ return result2; >+ if (auto result2 = string("^", *result)) >+ return result2; >+ if (auto result2 = string("|", *result)) >+ return result2; >+ if (auto result2 = string(">=", *result)) >+ return result2; >+ if (auto result2 = string("<=", *result)) >+ return result2; >+ if (auto result2 = string("==", *result)) >+ return result2; >+ if (auto result2 = string("<", *result)) >+ return result2; >+ if (auto result2 = string(">", *result)) >+ return result2; >+ if (auto result2 = string("!", *result)) >+ return result2; >+ if (auto result2 = string("~", *result)) >+ return result2; >+ if (auto result2 = string("[]=", *result)) >+ return result2; >+ if (auto result2 = string("[]", *result)) >+ return result2; >+ } >+ return std::nullopt; >+} >+ >+} >+ >+} >+ >+#endif >diff --git a/Source/WebCore/Modules/webgpu/WHLSL/WHLSLLexer.h b/Source/WebCore/Modules/webgpu/WHLSL/WHLSLLexer.h >new file mode 100644 >index 0000000000000000000000000000000000000000..f5c0c26b90a961b50d05c111e307313123b3340b >--- /dev/null >+++ b/Source/WebCore/Modules/webgpu/WHLSL/WHLSLLexer.h >@@ -0,0 +1,170 @@ >+/* >+ * Copyright (C) 2018 Apple Inc. All rights reserved. >+ * >+ * Redistribution and use in source and binary forms, with or without >+ * modification, are permitted provided that the following conditions >+ * are met: >+ * 1. Redistributions of source code must retain the above copyright >+ * notice, this list of conditions and the following disclaimer. >+ * 2. Redistributions in binary form must reproduce the above copyright >+ * notice, this list of conditions and the following disclaimer in the >+ * documentation and/or other materials provided with the distribution. >+ * >+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' >+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, >+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR >+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS >+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR >+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF >+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS >+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN >+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) >+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF >+ * THE POSSIBILITY OF SUCH DAMAGE. >+ */ >+ >+#if ENABLE(WEBGPU) >+ >+#include <wtf/Optional.h> >+#include <wtf/Vector.h> >+#include <wtf/text/StringView.h> >+#include <wtf/text/WTFString.h> >+ >+namespace WebCore { >+ >+namespace WHLSL { >+ >+class Lexer { >+public: >+ Lexer(StringView stringView) >+ : m_stringView(stringView) >+ { >+ skipWhitespaceAndComments(); >+ } >+ >+ struct Token { >+ StringView stringView; >+ enum class Type { >+ IntLiteral, >+ FloatLiteral, >+ Struct, >+ Typedef, >+ Enum, >+ Operator, >+ If, >+ Else, >+ Continue, >+ Break, >+ Switch, >+ Case, >+ Default, >+ Fallthrough, >+ For, >+ While, >+ Do, >+ Return, >+ Trap, >+ Null, >+ True, >+ False, >+ Constant, >+ Device, >+ Threadgroup, >+ Thread, >+ Space, >+ Vertex, >+ Fragment, >+ Compute, >+ Numthreads, >+ Native, >+ Restricted, >+ Underscore, >+ Auto, >+ Protocol, >+ Const, >+ Static, >+ Qualifier, >+ Semantic, >+ NumthreadsSemantic, >+ Identifier, >+ OperatorName >+ } type; >+ }; >+ >+ std::optional<Token> consumeToken() >+ { >+ if (!m_stack.isEmpty()) >+ return m_stack.takeLast(); >+ return consumeTokenFromStream(); >+ } >+ >+ std::optional<Token> consumeTokenFromStream(); >+ >+ void unconsumeToken(Token&& token) >+ { >+ m_stack.append(WTFMove(token)); >+ } >+ >+ bool isFullyConsumed() const >+ { >+ return m_offset == m_stringView.length(); >+ } >+ >+private: >+ void skipWhitespaceAndComments(); >+ void skipWhitespace(); >+ void skipLineComment(); >+ void skipLongComment(); >+ >+ std::optional<unsigned> coreDecimalIntLiteral(unsigned) const; >+ std::optional<unsigned> decimalIntLiteral(unsigned) const; >+ std::optional<unsigned> decimalUintLiteral(unsigned) const; >+ std::optional<unsigned> coreHexadecimalIntLiteral(unsigned) const; >+ std::optional<unsigned> hexadecimalIntLiteral(unsigned) const; >+ std::optional<unsigned> hexadecimalUintLiteral(unsigned) const; >+ std::optional<unsigned> intLiteral(unsigned) const; >+ std::optional<unsigned> digit(unsigned) const; >+ unsigned digitStar(unsigned) const; >+ std::optional<unsigned> character(char, unsigned) const; >+ template<unsigned length> std::optional<unsigned> anyCharacter(const char (&string)[length], unsigned) const; >+ std::optional<unsigned> coreFloatLiteralType1(unsigned) const; >+ std::optional<unsigned> coreFloatLiteral(unsigned) const; >+ std::optional<unsigned> floatLiteral(unsigned) const; >+ template<unsigned length> std::optional<unsigned> string(const char (&string)[length], unsigned) const; >+ std::optional<unsigned> qualifier(unsigned) const; >+ std::optional<unsigned> semantic(unsigned) const; >+ std::optional<unsigned> numthreads(unsigned) const; >+ std::optional<unsigned> validIdentifier(unsigned) const; >+ std::optional<unsigned> identifier(unsigned) const; >+ std::optional<unsigned> operatorName(unsigned) const; >+ >+ const StringView m_stringView; >+ Vector<Token> m_stack; >+ unsigned m_offset { 0 }; >+}; >+ >+template<unsigned length> std::optional<unsigned> Lexer::string(const char (&string)[length], unsigned offset) const >+{ >+ for (unsigned i = 0; i < length - 1; ++i) { >+ if (i >= m_stringView.length() || m_stringView[i] != string[i]) >+ return std::nullopt; >+ } >+ return offset + length - 1; >+} >+ >+template<unsigned length> std::optional<unsigned> Lexer::anyCharacter(const char (&string)[length], unsigned offset) const >+{ >+ if (offset >= m_stringView.length()) >+ return std::nullopt; >+ for (unsigned i = 0; i < length - 1; ++i) { >+ if (m_stringView[offset] == string[i]) >+ return offset + 1; >+ } >+ return std::nullopt; >+} >+ >+} >+ >+} >+ >+#endif >diff --git a/Source/WebCore/Sources.txt b/Source/WebCore/Sources.txt >index e745cd5a009f05504d8cb2552a15ef9b957e0262..2860451949f99aa43efc5f6be2bb0af6697077f8 100644 >--- a/Source/WebCore/Sources.txt >+++ b/Source/WebCore/Sources.txt >@@ -301,6 +301,7 @@ Modules/websockets/WebSocketHandshake.cpp > Modules/websockets/WorkerThreadableWebSocketChannel.cpp > > Modules/webgpu/DOMWindowWebGPU.cpp >+Modules/webgpu/WHLSL/WHLSLLexer.cpp > Modules/webgpu/WebGPU.cpp > Modules/webgpu/WebGPUAdapter.cpp > Modules/webgpu/WebGPUCommandBuffer.cpp >diff --git a/Source/WebCore/WebCore.xcodeproj/project.pbxproj b/Source/WebCore/WebCore.xcodeproj/project.pbxproj >index 9f4c7477cb7e6f39b1c804c2f7d552f559384188..c71e5f888af627879a5fb32489e3fd3eab4f1358 100644 >--- a/Source/WebCore/WebCore.xcodeproj/project.pbxproj >+++ b/Source/WebCore/WebCore.xcodeproj/project.pbxproj >@@ -13194,6 +13194,8 @@ > C11A9ED22140578B00CFB20A /* SwitchingGPUClient.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = SwitchingGPUClient.cpp; sourceTree = "<group>"; }; > C1E1D235203DF15400584665 /* ScreenProperties.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ScreenProperties.h; sourceTree = "<group>"; }; > C2015C091BE6FE2C00822389 /* FontVariantBuilder.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = FontVariantBuilder.h; sourceTree = "<group>"; }; >+ C210E91121B4BD1000B7F83D /* WHLSLLexer.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = WHLSLLexer.cpp; sourceTree = "<group>"; }; >+ C210E91221B4BD1000B7F83D /* WHLSLLexer.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = WHLSLLexer.h; sourceTree = "<group>"; }; > C21DF2E71D9E4E9900F5B24C /* CSSFontVariationValue.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CSSFontVariationValue.cpp; sourceTree = "<group>"; }; > C21DF2E81D9E4E9900F5B24C /* CSSFontVariationValue.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CSSFontVariationValue.h; sourceTree = "<group>"; }; > C2458E611FE8979E00594759 /* FontCacheCoreText.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = FontCacheCoreText.h; sourceTree = "<group>"; }; >@@ -25133,6 +25135,15 @@ > tabWidth = 4; > usesTabs = 0; > }; >+ C210E90D21B4BCA400B7F83D /* WHLSL */ = { >+ isa = PBXGroup; >+ children = ( >+ C210E91121B4BD1000B7F83D /* WHLSLLexer.cpp */, >+ C210E91221B4BD1000B7F83D /* WHLSLLexer.h */, >+ ); >+ path = WHLSL; >+ sourceTree = "<group>"; >+ }; > C96F5EBF1B5872260091EA9D /* mediasession */ = { > isa = PBXGroup; > children = ( >@@ -25475,6 +25486,7 @@ > D00F593E216ECC43000D71DB /* webgpu */ = { > isa = PBXGroup; > children = ( >+ C210E90D21B4BCA400B7F83D /* WHLSL */, > D00F5941216ECC7A000D71DB /* DOMWindowWebGPU.cpp */, > D00F5940216ECC7A000D71DB /* DOMWindowWebGPU.h */, > D00F5942216ECC7A000D71DB /* DOMWindowWebGPU.idl */, >@@ -27988,8 +28000,8 @@ > CD318623199F1E2A0030A0F7 /* CDMPrivateMediaSourceAVFObjC.h in Headers */, > CDE595971BF26E2100A1CBE8 /* CDMSessionMediaSourceAVFObjC.h in Headers */, > 5FA904CA178E61F5004C8A2D /* CertificateInfo.h in Headers */, >- 91B8F0B521953D65000C2B00 /* CertificateInfoBase.h in Headers */, >- FE36FD1516C7826500F887C1 /* ChangeVersionData.h in Headers */, >+ 91B8F0B521953D65000C2B00 /* CertificateInfoBase.h in Headers */, >+ FE36FD1516C7826500F887C1 /* ChangeVersionData.h in Headers */, > 97BC69DD1505F076001B74AC /* ChangeVersionWrapper.h in Headers */, > FD315FFF12B0267600C1A359 /* ChannelMergerNode.h in Headers */, > FD31600212B0267600C1A359 /* ChannelSplitterNode.h in Headers */,
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 192294
:
356353
|
357617