From 1ae7c7dba9b12e3f20481ff451ec717583cc70db Mon Sep 17 00:00:00 2001 From: David Neto Date: Fri, 13 Mar 2020 20:14:33 +0000 Subject: [PATCH] Add SPIR-V parser impl The parser impl saves a copy of the SPIR-V binary. Bug: tint:3 Change-Id: I5d61c87123c0bcb417d0c7004e0ef4e3c8fbb027 Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/16642 Reviewed-by: dan sinclair --- src/CMakeLists.txt | 3 ++ src/reader/spv/fail_stream.h | 4 +- src/reader/spv/parser.cc | 12 +++--- src/reader/spv/parser.h | 4 +- src/reader/spv/parser_impl.cc | 45 +++++++++++++++++++++ src/reader/spv/parser_impl.h | 75 +++++++++++++++++++++++++++++++++++ 6 files changed, 135 insertions(+), 8 deletions(-) create mode 100644 src/reader/spv/parser_impl.cc create mode 100644 src/reader/spv/parser_impl.h diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 01bed5a3af..df73e330ac 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -189,8 +189,11 @@ set(TINT_LIB_SRCS if(TINT_BUILD_SPV_PARSER) list(APPEND TINT_LIB_SRCS + reader/spv/fail_stream.h reader/spv/parser.cc reader/spv/parser.h + reader/spv/parser_impl.cc + reader/spv/parser_impl.h ) endif() diff --git a/src/reader/spv/fail_stream.h b/src/reader/spv/fail_stream.h index b9c4f370c8..aa2c5882a8 100644 --- a/src/reader/spv/fail_stream.h +++ b/src/reader/spv/fail_stream.h @@ -39,11 +39,11 @@ class FailStream { /// Converts to a boolean status. A true result indicates success, /// and a false result indicates failure. - /// @returns status + /// @returns the status operator bool() const { return *status_ptr_; } /// Returns the current status value. This can be more readable /// the conversion operator. - /// @returns status + /// @returns the status bool status() const { return *status_ptr_; } /// Records failure. diff --git a/src/reader/spv/parser.cc b/src/reader/spv/parser.cc index 12d23aed6d..ddeeb1c76b 100644 --- a/src/reader/spv/parser.cc +++ b/src/reader/spv/parser.cc @@ -14,23 +14,25 @@ #include "src/reader/spv/parser.h" -#include +#include "src/reader/spv/parser_impl.h" namespace tint { namespace reader { namespace spv { -Parser::Parser(const std::vector&) : Reader() {} +Parser::Parser(const std::vector& spv_binary) + : Reader(), impl_(std::make_unique(spv_binary)) {} Parser::~Parser() = default; bool Parser::Parse() { - set_error("SPIR-V parsing is not supported yet"); - return false; + const auto result = impl_->Parse(); + set_error(impl_->error()); + return result; } ast::Module Parser::module() { - return std::move(module_); + return impl_->module(); } } // namespace spv diff --git a/src/reader/spv/parser.h b/src/reader/spv/parser.h index e748ffa6fb..acf7a6ab01 100644 --- a/src/reader/spv/parser.h +++ b/src/reader/spv/parser.h @@ -15,6 +15,8 @@ #ifndef SRC_READER_SPV_PARSER_H_ #define SRC_READER_SPV_PARSER_H_ +#include +#include #include #include "src/reader/reader.h" @@ -42,7 +44,7 @@ class Parser : public Reader { ast::Module module() override; private: - ast::Module module_; + std::unique_ptr impl_; }; } // namespace spv diff --git a/src/reader/spv/parser_impl.cc b/src/reader/spv/parser_impl.cc new file mode 100644 index 0000000000..f06ae0840c --- /dev/null +++ b/src/reader/spv/parser_impl.cc @@ -0,0 +1,45 @@ +// Copyright 2020 The Tint Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include + +#include "src/reader/spv/parser_impl.h" + +namespace tint { +namespace reader { +namespace spv { + +ParserImpl::ParserImpl(const std::vector& spv_binary) + : Reader(), spv_binary_(spv_binary), fail_stream_(&success_, &errors_) {} + +ParserImpl::~ParserImpl() = default; + +bool ParserImpl::Parse() { + // Exit early if we've already failed. + if (success_) { + Fail() << "SPIR-V parsing is not supported yet"; + } + + return success_; +} + +ast::Module ParserImpl::module() { + // TODO(dneto): Should we clear out spv_binary_ here, to reduce + // memory usage? + return std::move(ast_module_); +} + +} // namespace spv +} // namespace reader +} // namespace tint diff --git a/src/reader/spv/parser_impl.h b/src/reader/spv/parser_impl.h new file mode 100644 index 0000000000..ac5a38bbb9 --- /dev/null +++ b/src/reader/spv/parser_impl.h @@ -0,0 +1,75 @@ +// Copyright 2020 The Tint Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef SRC_READER_SPV_PARSER_IMPL_H_ +#define SRC_READER_SPV_PARSER_IMPL_H_ + +#include +#include +#include +#include + +#include "src/reader/reader.h" +#include "src/reader/spv/fail_stream.h" + +namespace tint { +namespace reader { +namespace spv { + +/// Parser implementation for SPIR-V. +class ParserImpl : Reader { + public: + /// Creates a new parser + /// @param input the input data to parse + explicit ParserImpl(const std::vector& input); + ~ParserImpl() override; + + /// Run the parser + /// @returns true if the parse was successful, false otherwise. + bool Parse() override; + + /// @returns the module. The module in the parser will be reset after this. + ast::Module module() override; + + /// Logs failure, ands return a failure stream to accumulate diagnostic + /// messages. By convention, a failure should only be logged along with + /// a non-empty string diagnostic. + /// @returns the failure stream + FailStream& Fail() { + success_ = false; + return fail_stream_; + } + + /// @returns the accumulated error string + const std::string error() { return errors_.str(); } + + private: + // The SPIR-V binary we're parsing + std::vector spv_binary_; + + // The resulting module in Tint AST form. + ast::Module ast_module_; + + // Is the parse successful? + bool success_ = true; + // Collector for diagnostic messages. + std::stringstream errors_; + FailStream fail_stream_; +}; + +} // namespace spv +} // namespace reader +} // namespace tint + +#endif // SRC_READER_SPV_PARSER_IMPL_H_