Coverage Report

Created: 2026-06-30 06:10

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/version.h"
8
#include "driver/compiler.h"
9
#include "driver/options.h"
10
#include "loader/loader.h"
11
#include "validator/validator.h"
12
#include "llvm/codegen.h"
13
#include "llvm/compiler.h"
14
#include <cstdint>
15
#include <cstdlib>
16
#include <memory>
17
#include <string>
18
#include <utility>
19
#include <vector>
20
21
namespace WasmEdge {
22
namespace Driver {
23
24
0
int Compiler([[maybe_unused]] struct DriverCompilerOptions &Opt) noexcept {
25
0
  using namespace std::literals;
26
27
0
  std::ios::sync_with_stdio(false);
28
0
  Log::setInfoLoggingLevel();
29
30
0
#ifdef WASMEDGE_USE_LLVM
31
32
0
  Configure Conf = createProposalConfigure(Opt);
33
  // TODO: EXCEPTION - enable the option.
34
0
  Conf.removeProposal(Proposal::ExceptionHandling);
35
36
0
  if (Opt.PropOptimizationLevel.value() == "0") {
37
0
    Conf.getCompilerConfigure().setOptimizationLevel(
38
0
        WasmEdge::CompilerConfigure::OptimizationLevel::O0);
39
0
  } else if (Opt.PropOptimizationLevel.value() == "1") {
40
0
    Conf.getCompilerConfigure().setOptimizationLevel(
41
0
        WasmEdge::CompilerConfigure::OptimizationLevel::O1);
42
0
  } else if (Opt.PropOptimizationLevel.value() == "3") {
43
0
    Conf.getCompilerConfigure().setOptimizationLevel(
44
0
        WasmEdge::CompilerConfigure::OptimizationLevel::O3);
45
0
  } else if (Opt.PropOptimizationLevel.value() == "s") {
46
0
    Conf.getCompilerConfigure().setOptimizationLevel(
47
0
        WasmEdge::CompilerConfigure::OptimizationLevel::Os);
48
0
  } else if (Opt.PropOptimizationLevel.value() == "z") {
49
0
    Conf.getCompilerConfigure().setOptimizationLevel(
50
0
        WasmEdge::CompilerConfigure::OptimizationLevel::Oz);
51
0
  } else {
52
0
    Conf.getCompilerConfigure().setOptimizationLevel(
53
0
        WasmEdge::CompilerConfigure::OptimizationLevel::O2);
54
0
  }
55
56
  // Set interpreter run mode here so the loader reads function bodies fully
57
  // (the AOT compiler needs the parsed instructions, not AOT symbols).
58
0
  Conf.getRuntimeConfigure().setRunMode(WasmEdge::RunMode::Interpreter);
59
60
0
  std::filesystem::path InputPath =
61
0
      std::filesystem::absolute(std::filesystem::u8path(Opt.WasmName.value()));
62
0
  std::filesystem::path OutputPath =
63
0
      std::filesystem::absolute(std::filesystem::u8path(Opt.SoName.value()));
64
0
  Loader::Loader Loader(Conf);
65
66
0
  std::vector<Byte> Data;
67
0
  if (auto Res = Loader.loadFile(InputPath)) {
68
0
    Data = std::move(*Res);
69
0
  } else {
70
0
    const auto Err = static_cast<uint32_t>(Res.error());
71
0
    spdlog::error("Load failed. Error code: {}"sv, Err);
72
0
    return EXIT_FAILURE;
73
0
  }
74
75
0
  std::unique_ptr<AST::Module> Module;
76
0
  if (auto Res = Loader.parseModule(Data)) {
77
0
    Module = std::move(*Res);
78
0
  } else {
79
0
    const auto Err = static_cast<uint32_t>(Res.error());
80
0
    spdlog::error("Parse Module failed. Error code: {}"sv, Err);
81
0
    return EXIT_FAILURE;
82
0
  }
83
84
0
  {
85
0
    Validator::Validator ValidatorEngine(Conf);
86
0
    if (auto Res = ValidatorEngine.validate(*Module); !Res) {
87
0
      const auto Err = static_cast<uint32_t>(Res.error());
88
0
      spdlog::error("Validate Module failed. Error code: {}"sv, Err);
89
0
      return EXIT_FAILURE;
90
0
    }
91
0
  }
92
93
0
  {
94
0
    if (Opt.ConfDumpIR.value()) {
95
0
      Conf.getCompilerConfigure().setDumpIR(true);
96
0
    }
97
0
    if (Opt.ConfInterruptible.value()) {
98
0
      Conf.getCompilerConfigure().setInterruptible(true);
99
0
    }
100
0
    if (Opt.ConfEnableAllStatistics.value()) {
101
0
      Conf.getStatisticsConfigure().setInstructionCounting(true);
102
0
      Conf.getStatisticsConfigure().setCostMeasuring(true);
103
0
      Conf.getStatisticsConfigure().setTimeMeasuring(true);
104
0
    } else {
105
0
      if (Opt.ConfEnableInstructionCounting.value()) {
106
0
        Conf.getStatisticsConfigure().setInstructionCounting(true);
107
0
      }
108
0
      if (Opt.ConfEnableGasMeasuring.value()) {
109
0
        Conf.getStatisticsConfigure().setCostMeasuring(true);
110
0
      }
111
0
      if (Opt.ConfEnableTimeMeasuring.value()) {
112
0
        Conf.getStatisticsConfigure().setTimeMeasuring(true);
113
0
      }
114
0
    }
115
0
    if (Opt.ConfGenericBinary.value()) {
116
0
      Conf.getCompilerConfigure().setGenericBinary(true);
117
0
    }
118
0
    if (OutputPath.extension().u8string() == WASMEDGE_LIB_EXTENSION) {
119
0
      Conf.getCompilerConfigure().setOutputFormat(
120
0
          CompilerConfigure::OutputFormat::Native);
121
0
    }
122
0
    LLVM::Compiler Compiler(Conf);
123
0
    if (auto Res = Compiler.checkConfigure(); !Res) {
124
0
      const auto Err = static_cast<uint32_t>(Res.error());
125
0
      spdlog::error("Compiler Configure failed. Error code: {}"sv, Err);
126
0
      return EXIT_FAILURE;
127
0
    }
128
0
    LLVM::CodeGen CodeGen(Conf);
129
0
    if (auto Res = Compiler.compile(*Module); !Res) {
130
0
      const auto Err = static_cast<uint32_t>(Res.error());
131
0
      spdlog::error("Compilation failed. Error code: {}"sv, Err);
132
0
      return EXIT_FAILURE;
133
0
    } else if (auto Res2 = CodeGen.codegen(Data, std::move(*Res), OutputPath);
134
0
               !Res2) {
135
0
      const auto Err = static_cast<uint32_t>(Res2.error());
136
0
      spdlog::error("Code Generation failed. Error code: {}"sv, Err);
137
0
      return EXIT_FAILURE;
138
0
    }
139
0
  }
140
141
0
  return EXIT_SUCCESS;
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