| // Copyright 2021 The Dawn & Tint Authors | 
 | // | 
 | // 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. | 
 | // | 
 | // 3. Neither the name of the copyright holder nor the names of its | 
 | //    contributors may be used to endorse or promote products derived from | 
 | //    this software without specific prior written permission. | 
 | // | 
 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT HOLDER OR 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. | 
 |  | 
 | #ifndef SRC_TINT_FUZZERS_TINT_COMMON_FUZZER_H_ | 
 | #define SRC_TINT_FUZZERS_TINT_COMMON_FUZZER_H_ | 
 |  | 
 | #include <cassert> | 
 | #include <cstring> | 
 | #include <memory> | 
 | #include <string> | 
 | #include <utility> | 
 | #include <vector> | 
 |  | 
 | #include "include/tint/tint.h" | 
 |  | 
 | #include "src/tint/fuzzers/data_builder.h" | 
 |  | 
 | namespace tint::fuzzers { | 
 |  | 
 | // TODO(crbug.com/tint/1356): Add using shader reflection to generate options | 
 | //                            that are potentially valid for Generate*Options | 
 | //                            functions. | 
 | /// Generates random set of options for SPIRV generation | 
 | void GenerateSpirvOptions(DataBuilder* b, spirv::writer::Options* options); | 
 |  | 
 | /// Generates random set of options for WGSL generation | 
 | void GenerateWgslOptions(DataBuilder* b, wgsl::writer::Options* options); | 
 |  | 
 | /// Generates random set of options for HLSL generation | 
 | void GenerateHlslOptions(DataBuilder* b, hlsl::writer::Options* options); | 
 |  | 
 | /// Generates random set of options for MSL generation | 
 | void GenerateMslOptions(DataBuilder* b, msl::writer::Options* options); | 
 |  | 
 | /// Shader language the fuzzer is reading | 
 | enum class InputFormat { kWGSL, kSpv }; | 
 |  | 
 | /// Shader language the fuzzer is emitting | 
 | enum class OutputFormat { kWGSL, kSpv, kHLSL, kMSL }; | 
 |  | 
 | /// Generic runner for reading and emitting shaders using Tint, used by most | 
 | /// fuzzers to share common code. | 
 | class CommonFuzzer { | 
 |   public: | 
 |     /// Constructor | 
 |     /// @param input shader language being read | 
 |     /// @param output shader language being emitted | 
 |     CommonFuzzer(InputFormat input, OutputFormat output); | 
 |  | 
 |     /// Destructor | 
 |     ~CommonFuzzer(); | 
 |  | 
 |     /// @param tm manager for transforms to run | 
 |     /// @param inputs data for transforms to run | 
 |     void SetTransformManager(ast::transform::Manager* tm, ast::transform::DataMap* inputs) { | 
 |         assert((!tm || inputs) && "DataMap must be !nullptr if Manager !nullptr"); | 
 |         transform_manager_ = tm; | 
 |         transform_inputs_ = inputs; | 
 |     } | 
 |  | 
 |     /// @param enabled if the input shader for run should be outputted to the log | 
 |     void SetDumpInput(bool enabled) { dump_input_ = enabled; } | 
 |  | 
 |     /// @param enabled if the shader being valid after parsing is being enforced. | 
 |     /// If false, invalidation of the shader will cause an early exit, but not | 
 |     /// throw an error. | 
 |     /// If true invalidation will throw an error that is caught by libFuzzer and | 
 |     /// will generate a crash report. | 
 |     void SetEnforceValidity(bool enabled) { enforce_validity = enabled; } | 
 |  | 
 |     /// Convert given shader from input to output format. | 
 |     /// Will also apply provided transforms and run the inspector over the result. | 
 |     /// @param data buffer of data that will interpreted as a byte array or string | 
 |     ///             depending on the shader input format. | 
 |     /// @param size number of elements in buffer | 
 |     /// @returns 0, this is what libFuzzer expects | 
 |     int Run(const uint8_t* data, size_t size); | 
 |  | 
 |     /// @returns diagnostic messages generated while Run() is executed. | 
 |     const tint::diag::List& Diagnostics() const { return diagnostics_; } | 
 |  | 
 |     /// @returns if there are any errors in the diagnostic messages | 
 |     bool HasErrors() const { return diagnostics_.contains_errors(); } | 
 |  | 
 |     /// @returns generated SPIR-V binary, if SPIR-V was emitted. | 
 |     const std::vector<uint32_t>& GetGeneratedSpirv() const { return generated_spirv_; } | 
 |  | 
 |     /// @returns generated WGSL string, if WGSL was emitted. | 
 |     const std::string& GetGeneratedWgsl() const { return generated_wgsl_; } | 
 |  | 
 |     /// @returns generated HLSL string, if HLSL was emitted. | 
 |     const std::string& GetGeneratedHlsl() const { return generated_hlsl_; } | 
 |  | 
 |     /// @returns generated MSL string, if HLSL was emitted. | 
 |     const std::string& GetGeneratedMsl() const { return generated_msl_; } | 
 |  | 
 |     /// @param options SPIR-V emission options | 
 |     void SetOptionsSpirv(const spirv::writer::Options& options) { options_spirv_ = options; } | 
 |  | 
 |     /// @param options WGSL emission options | 
 |     void SetOptionsWgsl(const wgsl::writer::Options& options) { options_wgsl_ = options; } | 
 |  | 
 |     /// @param options HLSL emission options | 
 |     void SetOptionsHlsl(const hlsl::writer::Options& options) { options_hlsl_ = options; } | 
 |  | 
 |     /// @param options MSL emission options | 
 |     void SetOptionsMsl(const msl::writer::Options& options) { options_msl_ = options; } | 
 |  | 
 |   private: | 
 |     InputFormat input_; | 
 |     OutputFormat output_; | 
 |     ast::transform::Manager* transform_manager_ = nullptr; | 
 |     ast::transform::DataMap* transform_inputs_ = nullptr; | 
 |     bool dump_input_ = false; | 
 |     tint::diag::List diagnostics_; | 
 |     bool enforce_validity = false; | 
 |  | 
 |     std::vector<uint32_t> generated_spirv_; | 
 |     std::string generated_wgsl_; | 
 |     std::string generated_hlsl_; | 
 |     std::string generated_msl_; | 
 |  | 
 |     spirv::writer::Options options_spirv_; | 
 |     wgsl::writer::Options options_wgsl_; | 
 |     hlsl::writer::Options options_hlsl_; | 
 |     msl::writer::Options options_msl_; | 
 |  | 
 | #if TINT_BUILD_WGSL_READER | 
 |     /// The source file needs to live at least as long as #diagnostics_ | 
 |     std::unique_ptr<Source::File> file_; | 
 | #endif  // TINT_BUILD_WGSL_READER | 
 |  | 
 |     /// Runs a series of reflection operations to exercise the Inspector API. | 
 |     void RunInspector(Program& program); | 
 | }; | 
 |  | 
 | }  // namespace tint::fuzzers | 
 |  | 
 | #endif  // SRC_TINT_FUZZERS_TINT_COMMON_FUZZER_H_ |