Coverage Report

Created: 2026-11-12 06:35

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/WasmEdge/lib/driver/compilerTool.cpp
Line
Count
Source
1
// SPDX-License-Identifier: Apache-2.0
2
// SPDX-FileCopyrightText: Copyright The WasmEdge Authors
3
4
#include "common/configure.h"
5
#include "common/defines.h"
6
#include "common/filesystem.h"
7
#include "common/spdlog.h"
8
#include "common/version.h"
9
#include "driver/compiler.h"
10
#include "driver/options.h"
11
#include "loader/loader.h"
12
#include "validator/validator.h"
13
#include "llvm/codegen.h"
14
#include "llvm/compiler.h"
15
#include <algorithm>
16
#include <array>
17
#include <cstdint>
18
#include <cstdlib>
19
#include <memory>
20
#include <string>
21
#include <string_view>
22
#include <utility>
23
#include <vector>
24
25
namespace WasmEdge {
26
namespace Driver {
27
28
#ifdef WASMEDGE_USE_LLVM
29
int compileModule(const Configure &Conf, Span<const Byte> Data,
30
9.37k
                  const std::filesystem::path &OutputPath) noexcept {
31
9.37k
  using namespace std::literals;
32
33
9.37k
  Loader::Loader Loader(Conf);
34
9.37k
  std::unique_ptr<AST::Module> Module;
35
9.37k
  if (auto Res = Loader.parseModule(Data)) {
36
4.33k
    Module = std::move(*Res);
37
5.04k
  } else {
38
5.04k
    const auto Err = static_cast<uint32_t>(Res.error());
39
5.04k
    spdlog::error("Parse Module failed. Error code: {}"sv, Err);
40
5.04k
    return EXIT_FAILURE;
41
5.04k
  }
42
43
4.33k
  {
44
4.33k
    Validator::Validator ValidatorEngine(Conf);
45
4.33k
    if (auto Res = ValidatorEngine.validate(*Module); !Res) {
46
1.97k
      const auto Err = static_cast<uint32_t>(Res.error());
47
1.97k
      spdlog::error("Validate Module failed. Error code: {}"sv, Err);
48
1.97k
      return EXIT_FAILURE;
49
1.97k
    }
50
4.33k
  }
51
52
2.35k
  LLVM::Compiler Compiler(Conf);
53
2.35k
  if (auto Res = Compiler.checkConfigure(); !Res) {
54
0
    const auto Err = static_cast<uint32_t>(Res.error());
55
0
    spdlog::error("Compiler Configure failed. Error code: {}"sv, Err);
56
0
    return EXIT_FAILURE;
57
0
  }
58
2.35k
  LLVM::CodeGen CodeGen(Conf);
59
2.35k
  if (auto Res = Compiler.compile(*Module); !Res) {
60
2
    const auto Err = static_cast<uint32_t>(Res.error());
61
2
    spdlog::error("Compilation failed. Error code: {}"sv, Err);
62
2
    return EXIT_FAILURE;
63
2.35k
  } else if (auto Res2 = CodeGen.codegen(Data, std::move(*Res), OutputPath);
64
2.35k
             !Res2) {
65
0
    const auto Err = static_cast<uint32_t>(Res2.error());
66
0
    spdlog::error("Code Generation failed. Error code: {}"sv, Err);
67
0
    return EXIT_FAILURE;
68
0
  }
69
70
2.35k
  return EXIT_SUCCESS;
71
2.35k
}
72
#endif
73
74
0
int Compiler([[maybe_unused]] struct DriverCompilerOptions &Opt) noexcept {
75
0
  using namespace std::literals;
76
77
0
  std::ios::sync_with_stdio(false);
78
0
  setLoggingLevel(Opt);
79
80
0
#ifdef WASMEDGE_USE_LLVM
81
82
0
  Configure Conf = createProposalConfigure(Opt);
83
84
0
  using OptimizationLevel = CompilerConfigure::OptimizationLevel;
85
0
  static const std::array<std::pair<std::string_view, OptimizationLevel>, 6>
86
0
      OptimizationLevels{{{"0"sv, OptimizationLevel::O0},
87
0
                          {"1"sv, OptimizationLevel::O1},
88
0
                          {"2"sv, OptimizationLevel::O2},
89
0
                          {"3"sv, OptimizationLevel::O3},
90
0
                          {"s"sv, OptimizationLevel::Os},
91
0
                          {"z"sv, OptimizationLevel::Oz}}};
92
0
  const auto Level =
93
0
      std::find_if(OptimizationLevels.begin(), OptimizationLevels.end(),
94
0
                   [&Opt](const auto &L) {
95
0
                     return L.first == Opt.PropOptimizationLevel.value();
96
0
                   });
97
0
  if (Level != OptimizationLevels.end()) {
98
0
    Conf.getCompilerConfigure().setOptimizationLevel(Level->second);
99
0
  } else {
100
0
    spdlog::warn("Unknown --optimize value: \"{}\"; using 2. Valid values: 0, "
101
0
                 "1, 2, 3, s, z."sv,
102
0
                 Opt.PropOptimizationLevel.value());
103
0
    Conf.getCompilerConfigure().setOptimizationLevel(OptimizationLevel::O2);
104
0
  }
105
106
  // Set interpreter run mode here so the loader reads function bodies fully
107
  // (the AOT compiler needs the parsed instructions, not AOT symbols).
108
0
  Conf.getRuntimeConfigure().setRunMode(WasmEdge::RunMode::Interpreter);
109
110
0
  const auto InputPath =
111
0
      getAbsolutePath(Opt.WasmName.value(), "input wasm file"sv);
112
0
  const auto OutputPath = getAbsolutePath(Opt.SoName.value(), "output file"sv);
113
0
  if (!InputPath || !OutputPath) {
114
0
    return EXIT_FAILURE;
115
0
  }
116
117
0
  std::vector<Byte> Data;
118
0
  if (auto Res = Loader::Loader(Conf).loadFile(*InputPath)) {
119
0
    Data = std::move(*Res);
120
0
  } else {
121
0
    const auto Err = static_cast<uint32_t>(Res.error());
122
0
    spdlog::error("Load failed. Error code: {}"sv, Err);
123
0
    return EXIT_FAILURE;
124
0
  }
125
126
0
  if (Opt.ConfDumpIR.value()) {
127
0
    Conf.getCompilerConfigure().setDumpIR(true);
128
0
  }
129
0
  if (Opt.ConfInterruptible.value()) {
130
0
    Conf.getCompilerConfigure().setInterruptible(true);
131
0
  }
132
0
  setStatisticsConfigure(Opt, Conf);
133
0
  if (Opt.ConfGenericBinary.value()) {
134
0
    Conf.getCompilerConfigure().setGenericBinary(true);
135
0
  }
136
0
  if (u8string(OutputPath->extension()) == WASMEDGE_LIB_EXTENSION) {
137
0
    Conf.getCompilerConfigure().setOutputFormat(
138
0
        CompilerConfigure::OutputFormat::Native);
139
0
  }
140
141
0
  return compileModule(Conf, Data, *OutputPath);
142
#else
143
  spdlog::error("Compilation is not supported!"sv);
144
145
  return EXIT_FAILURE;
146
#endif
147
0
}
148
149
} // namespace Driver
150
} // namespace WasmEdge