[tint][fuzz][ir] Implement test case disassembler
Adds in ir_fuzz_dis, which takes in an IR test case binary proto and
emits the corresponding WGSL.
Also fixes up the usage message for ir_fuzz_as saying it was tint.
Fixes: 345204573
Change-Id: I2d4e77d0e24066d257d87cde3fbcc24aa5c4692e
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/196115
Reviewed-by: dan sinclair <dsinclair@chromium.org>
Commit-Queue: Ryan Harrison <rharrison@chromium.org>
Reviewed-by: James Price <jrprice@google.com>
Auto-Submit: Ryan Harrison <rharrison@chromium.org>
Commit-Queue: James Price <jrprice@google.com>
diff --git a/src/tint/cmd/fuzz/ir/BUILD.cmake b/src/tint/cmd/fuzz/ir/BUILD.cmake
index c56f524..489d2a6 100644
--- a/src/tint/cmd/fuzz/ir/BUILD.cmake
+++ b/src/tint/cmd/fuzz/ir/BUILD.cmake
@@ -35,6 +35,7 @@
################################################################################
include(cmd/fuzz/ir/as/BUILD.cmake)
+include(cmd/fuzz/ir/dis/BUILD.cmake)
if(TINT_BUILD_IR_BINARY AND TINT_BUILD_IR_FUZZER AND ((NOT IS_ASAN) OR BUILD_WITH_CHROMIUM))
################################################################################
diff --git a/src/tint/cmd/fuzz/ir/as/main.cc b/src/tint/cmd/fuzz/ir/as/main.cc
index aa381a8..64b6c49 100644
--- a/src/tint/cmd/fuzz/ir/as/main.cc
+++ b/src/tint/cmd/fuzz/ir/as/main.cc
@@ -103,7 +103,7 @@
auto show_usage = [&] {
std::cout
- << R"(Usage: tint [options] [-o|--output-filename] <output-file> <input-file> or tint [options] <io-dir>
+ << R"(Usage: ir_fuzz_as [options] [-o|--output-filename] <output-file> <input-file> or tint [options] <io-dir>
If a single WGSL file is provided, the suffix of the input file is not checked, and
'-o|--output-filename' must be provided.
diff --git a/src/tint/cmd/fuzz/ir/dis/BUILD.bazel b/src/tint/cmd/fuzz/ir/dis/BUILD.bazel
new file mode 100644
index 0000000..b427ad4
--- /dev/null
+++ b/src/tint/cmd/fuzz/ir/dis/BUILD.bazel
@@ -0,0 +1,135 @@
+# Copyright 2024 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.
+
+################################################################################
+# File generated by 'tools/src/cmd/gen' using the template:
+# tools/src/cmd/gen/build/BUILD.bazel.tmpl
+#
+# To regenerate run: './tools/run gen'
+#
+# Do not modify this file directly
+################################################################################
+
+load("//src/tint:flags.bzl", "COPTS")
+load("@bazel_skylib//lib:selects.bzl", "selects")
+cc_binary(
+ name = "cmd",
+ srcs = [
+ "main.cc",
+ ],
+ deps = [
+ "//src/tint/api",
+ "//src/tint/api/common",
+ "//src/tint/cmd/common",
+ "//src/tint/lang/core",
+ "//src/tint/lang/core/constant",
+ "//src/tint/lang/core/ir",
+ "//src/tint/lang/core/type",
+ "//src/tint/lang/wgsl",
+ "//src/tint/lang/wgsl/ast",
+ "//src/tint/lang/wgsl/common",
+ "//src/tint/lang/wgsl/features",
+ "//src/tint/lang/wgsl/inspector",
+ "//src/tint/lang/wgsl/program",
+ "//src/tint/lang/wgsl/sem",
+ "//src/tint/lang/wgsl/writer/ir_to_program",
+ "//src/tint/utils/cli",
+ "//src/tint/utils/containers",
+ "//src/tint/utils/diagnostic",
+ "//src/tint/utils/ice",
+ "//src/tint/utils/id",
+ "//src/tint/utils/macros",
+ "//src/tint/utils/math",
+ "//src/tint/utils/memory",
+ "//src/tint/utils/reflection",
+ "//src/tint/utils/result",
+ "//src/tint/utils/rtti",
+ "//src/tint/utils/strconv",
+ "//src/tint/utils/symbol",
+ "//src/tint/utils/text",
+ "//src/tint/utils/traits",
+ ] + select({
+ ":tint_build_ir_binary": [
+ "//src/tint/lang/core/ir/binary",
+ ],
+ "//conditions:default": [],
+ }) + select({
+ ":tint_build_ir_binary_and_tint_build_ir_fuzzer": [
+ "",
+ ],
+ "//conditions:default": [],
+ }) + select({
+ ":tint_build_spv_reader": [
+ "//src/tint/lang/spirv/reader/common",
+ ],
+ "//conditions:default": [],
+ }) + select({
+ ":tint_build_wgsl_writer": [
+ "//src/tint/lang/wgsl/writer",
+ ],
+ "//conditions:default": [],
+ }),
+ copts = COPTS,
+ visibility = ["//visibility:public"],
+)
+
+alias(
+ name = "tint_build_ir_binary",
+ actual = "//src/tint:tint_build_ir_binary_true",
+)
+
+alias(
+ name = "tint_build_ir_fuzzer",
+ actual = "//src/tint:tint_build_ir_fuzzer_true",
+)
+
+alias(
+ name = "tint_build_spv_reader",
+ actual = "//src/tint:tint_build_spv_reader_true",
+)
+
+alias(
+ name = "tint_build_wgsl_writer",
+ actual = "//src/tint:tint_build_wgsl_writer_true",
+)
+
+selects.config_setting_group(
+ name = "tint_build_ir_binary_and_tint_build_ir_fuzzer",
+ match_all = [
+ ":tint_build_ir_binary",
+ ":tint_build_ir_fuzzer",
+ ],
+)
+selects.config_setting_group(
+ name = "tint_build_ir_binary_and_tint_build_wgsl_writer_and_tint_build_ir_fuzzer",
+ match_all = [
+ ":tint_build_ir_binary",
+ ":tint_build_wgsl_writer",
+ ":tint_build_ir_fuzzer",
+ ],
+)
+
diff --git a/src/tint/cmd/fuzz/ir/dis/BUILD.cfg b/src/tint/cmd/fuzz/ir/dis/BUILD.cfg
new file mode 100644
index 0000000..8038547
--- /dev/null
+++ b/src/tint/cmd/fuzz/ir/dis/BUILD.cfg
@@ -0,0 +1,7 @@
+{
+ "cmd": {
+ "Condition": "tint_build_ir_binary && tint_build_wgsl_writer && tint_build_ir_fuzzer",
+ "OutputName": "ir_fuzz_dis",
+ "Internal": [ "utils/protos/ir_fuzz:proto" ],
+ },
+}
diff --git a/src/tint/cmd/fuzz/ir/dis/BUILD.cmake b/src/tint/cmd/fuzz/ir/dis/BUILD.cmake
new file mode 100644
index 0000000..e1ab456
--- /dev/null
+++ b/src/tint/cmd/fuzz/ir/dis/BUILD.cmake
@@ -0,0 +1,106 @@
+# Copyright 2024 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.
+
+################################################################################
+# File generated by 'tools/src/cmd/gen' using the template:
+# tools/src/cmd/gen/build/BUILD.cmake.tmpl
+#
+# To regenerate run: './tools/run gen'
+#
+# Do not modify this file directly
+################################################################################
+
+if(TINT_BUILD_IR_BINARY AND TINT_BUILD_WGSL_WRITER AND TINT_BUILD_IR_FUZZER)
+################################################################################
+# Target: tint_cmd_fuzz_ir_dis_cmd
+# Kind: cmd
+# Condition: TINT_BUILD_IR_BINARY AND TINT_BUILD_WGSL_WRITER AND TINT_BUILD_IR_FUZZER
+################################################################################
+tint_add_target(tint_cmd_fuzz_ir_dis_cmd cmd
+ cmd/fuzz/ir/dis/main.cc
+)
+
+tint_target_add_dependencies(tint_cmd_fuzz_ir_dis_cmd cmd
+ tint_api
+ tint_api_common
+ tint_cmd_common
+ tint_lang_core
+ tint_lang_core_constant
+ tint_lang_core_ir
+ tint_lang_core_type
+ tint_lang_wgsl
+ tint_lang_wgsl_ast
+ tint_lang_wgsl_common
+ tint_lang_wgsl_features
+ tint_lang_wgsl_inspector
+ tint_lang_wgsl_program
+ tint_lang_wgsl_sem
+ tint_lang_wgsl_writer_ir_to_program
+ tint_utils_cli
+ tint_utils_containers
+ tint_utils_diagnostic
+ tint_utils_ice
+ tint_utils_id
+ tint_utils_macros
+ tint_utils_math
+ tint_utils_memory
+ tint_utils_reflection
+ tint_utils_result
+ tint_utils_rtti
+ tint_utils_strconv
+ tint_utils_symbol
+ tint_utils_text
+ tint_utils_traits
+)
+
+if(TINT_BUILD_IR_BINARY)
+ tint_target_add_dependencies(tint_cmd_fuzz_ir_dis_cmd cmd
+ tint_lang_core_ir_binary
+ )
+endif(TINT_BUILD_IR_BINARY)
+
+if(TINT_BUILD_IR_BINARY AND TINT_BUILD_IR_FUZZER)
+ tint_target_add_dependencies(tint_cmd_fuzz_ir_dis_cmd cmd
+ tint_utils_protos_ir_fuzz_proto
+ )
+endif(TINT_BUILD_IR_BINARY AND TINT_BUILD_IR_FUZZER)
+
+if(TINT_BUILD_SPV_READER)
+ tint_target_add_dependencies(tint_cmd_fuzz_ir_dis_cmd cmd
+ tint_lang_spirv_reader_common
+ )
+endif(TINT_BUILD_SPV_READER)
+
+if(TINT_BUILD_WGSL_WRITER)
+ tint_target_add_dependencies(tint_cmd_fuzz_ir_dis_cmd cmd
+ tint_lang_wgsl_writer
+ )
+endif(TINT_BUILD_WGSL_WRITER)
+
+tint_target_set_output_name(tint_cmd_fuzz_ir_dis_cmd cmd "ir_fuzz_dis")
+
+endif(TINT_BUILD_IR_BINARY AND TINT_BUILD_WGSL_WRITER AND TINT_BUILD_IR_FUZZER)
\ No newline at end of file
diff --git a/src/tint/cmd/fuzz/ir/dis/BUILD.gn b/src/tint/cmd/fuzz/ir/dis/BUILD.gn
new file mode 100644
index 0000000..6b47007
--- /dev/null
+++ b/src/tint/cmd/fuzz/ir/dis/BUILD.gn
@@ -0,0 +1,93 @@
+# Copyright 2024 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.
+
+################################################################################
+# File generated by 'tools/src/cmd/gen' using the template:
+# tools/src/cmd/gen/build/BUILD.gn.tmpl
+#
+# To regenerate run: './tools/run gen'
+#
+# Do not modify this file directly
+################################################################################
+
+import("../../../../../../scripts/tint_overrides_with_defaults.gni")
+
+import("${tint_src_dir}/tint.gni")
+if (tint_build_ir_binary && tint_build_wgsl_writer && tint_build_ir_fuzzer) {
+ tint_executable("dis") {
+ output_name = "ir_fuzz_dis"
+ sources = [ "main.cc" ]
+ deps = [
+ "${tint_src_dir}/api",
+ "${tint_src_dir}/api/common",
+ "${tint_src_dir}/cmd/common",
+ "${tint_src_dir}/lang/core",
+ "${tint_src_dir}/lang/core/constant",
+ "${tint_src_dir}/lang/core/ir",
+ "${tint_src_dir}/lang/core/type",
+ "${tint_src_dir}/lang/wgsl",
+ "${tint_src_dir}/lang/wgsl/ast",
+ "${tint_src_dir}/lang/wgsl/common",
+ "${tint_src_dir}/lang/wgsl/features",
+ "${tint_src_dir}/lang/wgsl/inspector",
+ "${tint_src_dir}/lang/wgsl/program",
+ "${tint_src_dir}/lang/wgsl/sem",
+ "${tint_src_dir}/lang/wgsl/writer/ir_to_program",
+ "${tint_src_dir}/utils/cli",
+ "${tint_src_dir}/utils/containers",
+ "${tint_src_dir}/utils/diagnostic",
+ "${tint_src_dir}/utils/ice",
+ "${tint_src_dir}/utils/id",
+ "${tint_src_dir}/utils/macros",
+ "${tint_src_dir}/utils/math",
+ "${tint_src_dir}/utils/memory",
+ "${tint_src_dir}/utils/reflection",
+ "${tint_src_dir}/utils/result",
+ "${tint_src_dir}/utils/rtti",
+ "${tint_src_dir}/utils/strconv",
+ "${tint_src_dir}/utils/symbol",
+ "${tint_src_dir}/utils/text",
+ "${tint_src_dir}/utils/traits",
+ ]
+
+ if (tint_build_ir_binary) {
+ deps += [ "${tint_src_dir}/lang/core/ir/binary" ]
+ }
+
+ if (tint_build_ir_binary && tint_build_ir_fuzzer) {
+ deps += [ "${tint_src_dir}/utils/protos/ir_fuzz:proto" ]
+ }
+
+ if (tint_build_spv_reader) {
+ deps += [ "${tint_src_dir}/lang/spirv/reader/common" ]
+ }
+
+ if (tint_build_wgsl_writer) {
+ deps += [ "${tint_src_dir}/lang/wgsl/writer" ]
+ }
+ }
+}
diff --git a/src/tint/cmd/fuzz/ir/dis/main.cc b/src/tint/cmd/fuzz/ir/dis/main.cc
new file mode 100644
index 0000000..28e7692
--- /dev/null
+++ b/src/tint/cmd/fuzz/ir/dis/main.cc
@@ -0,0 +1,185 @@
+// Copyright 2024 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.
+
+#include <fstream>
+#include <iostream>
+#include <memory>
+#include <string>
+
+#include "src/tint/api/tint.h"
+#include "src/tint/cmd/common/helper.h"
+#include "src/tint/lang/core/ir/binary/decode.h"
+#include "src/tint/lang/core/ir/disassembler.h"
+#include "src/tint/lang/wgsl/writer/writer.h"
+#include "src/tint/utils/cli/cli.h"
+#include "src/tint/utils/containers/transform.h"
+#include "src/tint/utils/macros/defer.h"
+#include "src/tint/utils/text/color_mode.h"
+#include "src/tint/utils/text/string.h"
+#include "src/tint/utils/text/styled_text.h"
+#include "src/tint/utils/text/styled_text_printer.h"
+
+TINT_BEGIN_DISABLE_PROTOBUF_WARNINGS();
+#include "src/tint/utils/protos/ir_fuzz/ir_fuzz.pb.h"
+TINT_END_DISABLE_PROTOBUF_WARNINGS();
+
+namespace {
+
+struct Options {
+ std::unique_ptr<tint::StyledTextPrinter> printer;
+
+ std::string input_filename;
+ std::string output_filename;
+
+ bool dump_ir = false;
+};
+
+bool ParseArgs(tint::VectorRef<std::string_view> arguments, Options* opts) {
+ using namespace tint::cli; // NOLINT(build/namespaces)
+
+ OptionSet options;
+ auto& col = options.Add<EnumOption<tint::ColorMode>>(
+ "color", "Use colored output",
+ tint::Vector{
+ EnumName{tint::ColorMode::kPlain, "off"},
+ EnumName{tint::ColorMode::kDark, "dark"},
+ EnumName{tint::ColorMode::kLight, "light"},
+ },
+ ShortName{"col"}, Default{tint::ColorModeDefault()});
+ TINT_DEFER(opts->printer = CreatePrinter(*col.value));
+
+ auto& output = options.Add<StringOption>(
+ "output-filename", "Output file name, if not specified, WGSL output will go to STDOUT",
+ ShortName{"o"}, Parameter{"name"});
+ TINT_DEFER(opts->output_filename = output.value.value_or(""));
+
+ auto& dump_ir = options.Add<BoolOption>("dump-ir", "Writes the IR form of input to stdout",
+ Alias{"emit-ir"}, Default{false});
+ TINT_DEFER(opts->dump_ir = *dump_ir.value);
+
+ auto& help = options.Add<BoolOption>("help", "Show usage", ShortName{"h"});
+
+ auto show_usage = [&] {
+ std::cout << R"(Usage: ir_fuzz_dis [options] <input-file>
+
+Options:
+)";
+ options.ShowHelp(std::cout);
+ };
+
+ auto result = options.Parse(arguments);
+ if (result != tint::Success) {
+ std::cerr << result.Failure() << "\n";
+ show_usage();
+ return false;
+ }
+ if (help.value.value_or(false)) {
+ show_usage();
+ return false;
+ }
+
+ auto args = result.Get();
+ if (args.Length() > 1) {
+ std::cerr << "More than one input arg specified: "
+ << tint::Join(Transform(args, tint::Quote), ", ") << "\n";
+ return false;
+ }
+ if (args.Length() == 1) {
+ opts->input_filename = args[0];
+ }
+
+ return true;
+}
+
+/// @returns a fuzzer test case protobuf for the given file
+/// @param options program options that contains the filename to be read, etc.
+tint::Result<tint::cmd::fuzz::ir::pb::Root> GenerateFuzzCaseProto(const Options& options) {
+ tint::cmd::fuzz::ir::pb::Root fuzz_pb;
+
+ std::fstream input(options.input_filename, std::ios::in | std::ios::binary);
+ if (!fuzz_pb.ParseFromIstream(&input)) {
+ return tint::Failure{"Unable to parse bytes into test case protobuf"};
+ }
+
+ return std::move(fuzz_pb);
+}
+
+bool ProcessFile(const Options& options) {
+ auto fuzz_pb = GenerateFuzzCaseProto(options);
+ if (fuzz_pb != tint::Success) {
+ std::cerr << "Failed to read test case protobuf: " << fuzz_pb.Failure() << "\n";
+ return false;
+ }
+
+ auto module = tint::core::ir::binary::Decode(fuzz_pb.Get().module());
+ if (module != tint::Success) {
+ std::cerr << "Unable to decode ir protobuf from test case protobuf: " << module.Failure()
+ << "\n";
+ return false;
+ }
+
+ if (options.dump_ir) {
+ options.printer->Print(tint::core::ir::Disassembler(module.Get()).Text());
+ options.printer->Print(tint::StyledText{} << "\n");
+ }
+
+ tint::wgsl::writer::ProgramOptions writer_options;
+ auto output = tint::wgsl::writer::WgslFromIR(module.Get(), writer_options);
+ if (output != tint::Success) {
+ std::cerr << "Failed to convert IR to Program: " << output.Failure() << "\n";
+ return false;
+ }
+
+ return tint::cmd::WriteFile(options.output_filename, "w", output->wgsl);
+}
+
+} // namespace
+
+int main(int argc, const char** argv) {
+ tint::Vector<std::string_view, 8> arguments;
+ for (int i = 1; i < argc; i++) {
+ std::string_view arg(argv[i]);
+ if (!arg.empty()) {
+ arguments.Push(argv[i]);
+ }
+ }
+
+ Options options;
+
+ tint::Initialize();
+ tint::SetInternalCompilerErrorReporter(&tint::cmd::TintInternalCompilerErrorReporter);
+
+ if (!ParseArgs(arguments, &options)) {
+ return EXIT_FAILURE;
+ }
+
+ if (!ProcessFile(options)) {
+ return EXIT_FAILURE;
+ }
+
+ return EXIT_SUCCESS;
+}