Coverage Report

Created: 2025-07-01 06:18

/src/WasmEdge/lib/driver/compilerTool.cpp
Line
Count
Source (jump to first uncovered line)
1
// SPDX-License-Identifier: Apache-2.0
2
// SPDX-FileCopyrightText: 2019-2024 Second State INC
3
4
#include "common/configure.h"
5
#include "common/defines.h"
6
#include "common/filesystem.h"
7
#include "common/version.h"
8
#include "driver/compiler.h"
9
#include "loader/loader.h"
10
#include "validator/validator.h"
11
#include "llvm/codegen.h"
12
#include "llvm/compiler.h"
13
#include <cstdint>
14
#include <cstdlib>
15
#include <memory>
16
#include <string>
17
#include <utility>
18
#include <vector>
19
20
namespace WasmEdge {
21
namespace Driver {
22
23
0
int Compiler([[maybe_unused]] struct DriverCompilerOptions &Opt) noexcept {
24
0
  using namespace std::literals;
25
26
0
  std::ios::sync_with_stdio(false);
27
0
  Log::setInfoLoggingLevel();
28
29
0
#ifdef WASMEDGE_USE_LLVM
30
31
0
  Configure Conf;
32
0
  if (Opt.PropMutGlobals.value()) {
33
0
    Conf.removeProposal(Proposal::ImportExportMutGlobals);
34
0
  }
35
0
  if (Opt.PropNonTrapF2IConvs.value()) {
36
0
    Conf.removeProposal(Proposal::NonTrapFloatToIntConversions);
37
0
  }
38
0
  if (Opt.PropSignExtendOps.value()) {
39
0
    Conf.removeProposal(Proposal::SignExtensionOperators);
40
0
  }
41
0
  if (Opt.PropMultiValue.value()) {
42
0
    Conf.removeProposal(Proposal::MultiValue);
43
0
  }
44
0
  if (Opt.PropBulkMemOps.value()) {
45
0
    Conf.removeProposal(Proposal::BulkMemoryOperations);
46
0
  }
47
0
  if (Opt.PropRefTypes.value()) {
48
0
    Conf.removeProposal(Proposal::ReferenceTypes);
49
0
  }
50
0
  if (Opt.PropSIMD.value()) {
51
0
    Conf.removeProposal(Proposal::SIMD);
52
0
  }
53
0
  if (Opt.PropRelaxedSIMD.value()) {
54
0
    Conf.addProposal(Proposal::RelaxSIMD);
55
0
  }
56
0
  if (Opt.PropMultiMem.value()) {
57
0
    Conf.addProposal(Proposal::MultiMemories);
58
0
  }
59
0
  if (Opt.PropTailCall.value()) {
60
0
    Conf.addProposal(Proposal::TailCall);
61
0
  }
62
0
  if (Opt.PropExtendConst.value()) {
63
0
    Conf.addProposal(Proposal::ExtendedConst);
64
0
  }
65
0
  if (Opt.PropThreads.value()) {
66
0
    Conf.addProposal(Proposal::Threads);
67
0
  }
68
0
  if (Opt.PropAll.value()) {
69
0
    Conf.addProposal(Proposal::MultiMemories);
70
0
    Conf.addProposal(Proposal::TailCall);
71
0
    Conf.addProposal(Proposal::ExtendedConst);
72
0
    Conf.addProposal(Proposal::Threads);
73
0
  }
74
75
0
  if (Opt.PropOptimizationLevel.value() == "0") {
76
0
    Conf.getCompilerConfigure().setOptimizationLevel(
77
0
        WasmEdge::CompilerConfigure::OptimizationLevel::O0);
78
0
  } else if (Opt.PropOptimizationLevel.value() == "1") {
79
0
    Conf.getCompilerConfigure().setOptimizationLevel(
80
0
        WasmEdge::CompilerConfigure::OptimizationLevel::O1);
81
0
  } else if (Opt.PropOptimizationLevel.value() == "3") {
82
0
    Conf.getCompilerConfigure().setOptimizationLevel(
83
0
        WasmEdge::CompilerConfigure::OptimizationLevel::O3);
84
0
  } else if (Opt.PropOptimizationLevel.value() == "s") {
85
0
    Conf.getCompilerConfigure().setOptimizationLevel(
86
0
        WasmEdge::CompilerConfigure::OptimizationLevel::Os);
87
0
  } else if (Opt.PropOptimizationLevel.value() == "z") {
88
0
    Conf.getCompilerConfigure().setOptimizationLevel(
89
0
        WasmEdge::CompilerConfigure::OptimizationLevel::Oz);
90
0
  } else {
91
0
    Conf.getCompilerConfigure().setOptimizationLevel(
92
0
        WasmEdge::CompilerConfigure::OptimizationLevel::O2);
93
0
  }
94
95
  // Set force interpreter here to load instructions of function body forcibly.
96
0
  Conf.getRuntimeConfigure().setForceInterpreter(true);
97
98
0
  std::filesystem::path InputPath =
99
0
      std::filesystem::absolute(std::filesystem::u8path(Opt.WasmName.value()));
100
0
  std::filesystem::path OutputPath =
101
0
      std::filesystem::absolute(std::filesystem::u8path(Opt.SoName.value()));
102
0
  Loader::Loader Loader(Conf);
103
104
0
  std::vector<Byte> Data;
105
0
  if (auto Res = Loader.loadFile(InputPath)) {
106
0
    Data = std::move(*Res);
107
0
  } else {
108
0
    const auto Err = static_cast<uint32_t>(Res.error());
109
0
    spdlog::error("Load failed. Error code: {}"sv, Err);
110
0
    return EXIT_FAILURE;
111
0
  }
112
113
0
  std::unique_ptr<AST::Module> Module;
114
0
  if (auto Res = Loader.parseModule(Data)) {
115
0
    Module = std::move(*Res);
116
0
  } else {
117
0
    const auto Err = static_cast<uint32_t>(Res.error());
118
0
    spdlog::error("Parse Module failed. Error code: {}"sv, Err);
119
0
    return EXIT_FAILURE;
120
0
  }
121
122
0
  {
123
0
    Validator::Validator ValidatorEngine(Conf);
124
0
    if (auto Res = ValidatorEngine.validate(*Module); !Res) {
125
0
      const auto Err = static_cast<uint32_t>(Res.error());
126
0
      spdlog::error("Validate Module failed. Error code: {}"sv, Err);
127
0
      return EXIT_FAILURE;
128
0
    }
129
0
  }
130
131
0
  {
132
0
    if (Opt.ConfDumpIR.value()) {
133
0
      Conf.getCompilerConfigure().setDumpIR(true);
134
0
    }
135
0
    if (Opt.ConfInterruptible.value()) {
136
0
      Conf.getCompilerConfigure().setInterruptible(true);
137
0
    }
138
0
    if (Opt.ConfEnableAllStatistics.value()) {
139
0
      Conf.getStatisticsConfigure().setInstructionCounting(true);
140
0
      Conf.getStatisticsConfigure().setCostMeasuring(true);
141
0
      Conf.getStatisticsConfigure().setTimeMeasuring(true);
142
0
    } else {
143
0
      if (Opt.ConfEnableInstructionCounting.value()) {
144
0
        Conf.getStatisticsConfigure().setInstructionCounting(true);
145
0
      }
146
0
      if (Opt.ConfEnableGasMeasuring.value()) {
147
0
        Conf.getStatisticsConfigure().setCostMeasuring(true);
148
0
      }
149
0
      if (Opt.ConfEnableTimeMeasuring.value()) {
150
0
        Conf.getStatisticsConfigure().setTimeMeasuring(true);
151
0
      }
152
0
    }
153
0
    if (Opt.ConfGenericBinary.value()) {
154
0
      Conf.getCompilerConfigure().setGenericBinary(true);
155
0
    }
156
0
    if (OutputPath.extension().u8string() == WASMEDGE_LIB_EXTENSION) {
157
0
      Conf.getCompilerConfigure().setOutputFormat(
158
0
          CompilerConfigure::OutputFormat::Native);
159
0
    }
160
0
    LLVM::Compiler Compiler(Conf);
161
0
    if (auto Res = Compiler.checkConfigure(); !Res) {
162
0
      const auto Err = static_cast<uint32_t>(Res.error());
163
0
      spdlog::error("Compiler Configure failed. Error code: {}"sv, Err);
164
0
      return EXIT_FAILURE;
165
0
    }
166
0
    LLVM::CodeGen CodeGen(Conf);
167
0
    if (auto Res = Compiler.compile(*Module); !Res) {
168
0
      const auto Err = static_cast<uint32_t>(Res.error());
169
0
      spdlog::error("Compilation failed. Error code: {}"sv, Err);
170
0
      return EXIT_FAILURE;
171
0
    } else if (auto Res2 = CodeGen.codegen(Data, std::move(*Res), OutputPath);
172
0
               !Res2) {
173
0
      const auto Err = static_cast<uint32_t>(Res2.error());
174
0
      spdlog::error("Code Generation failed. Error code: {}"sv, Err);
175
0
      return EXIT_FAILURE;
176
0
    }
177
0
  }
178
179
0
  return EXIT_SUCCESS;
180
#else
181
  spdlog::error("Compilation is not supported!"sv);
182
183
  return EXIT_FAILURE;
184
#endif
185
0
}
186
187
} // namespace Driver
188
} // namespace WasmEdge