Coverage Report

Created: 2026-08-14 06:41

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
34
0
  if (Opt.PropOptimizationLevel.value() == "0") {
35
0
    Conf.getCompilerConfigure().setOptimizationLevel(
36
0
        WasmEdge::CompilerConfigure::OptimizationLevel::O0);
37
0
  } else if (Opt.PropOptimizationLevel.value() == "1") {
38
0
    Conf.getCompilerConfigure().setOptimizationLevel(
39
0
        WasmEdge::CompilerConfigure::OptimizationLevel::O1);
40
0
  } else if (Opt.PropOptimizationLevel.value() == "3") {
41
0
    Conf.getCompilerConfigure().setOptimizationLevel(
42
0
        WasmEdge::CompilerConfigure::OptimizationLevel::O3);
43
0
  } else if (Opt.PropOptimizationLevel.value() == "s") {
44
0
    Conf.getCompilerConfigure().setOptimizationLevel(
45
0
        WasmEdge::CompilerConfigure::OptimizationLevel::Os);
46
0
  } else if (Opt.PropOptimizationLevel.value() == "z") {
47
0
    Conf.getCompilerConfigure().setOptimizationLevel(
48
0
        WasmEdge::CompilerConfigure::OptimizationLevel::Oz);
49
0
  } else {
50
0
    Conf.getCompilerConfigure().setOptimizationLevel(
51
0
        WasmEdge::CompilerConfigure::OptimizationLevel::O2);
52
0
  }
53
54
  // Set interpreter run mode here so the loader reads function bodies fully
55
  // (the AOT compiler needs the parsed instructions, not AOT symbols).
56
0
  Conf.getRuntimeConfigure().setRunMode(WasmEdge::RunMode::Interpreter);
57
58
0
  std::filesystem::path InputPath =
59
0
      std::filesystem::absolute(std::filesystem::u8path(Opt.WasmName.value()));
60
0
  std::filesystem::path OutputPath =
61
0
      std::filesystem::absolute(std::filesystem::u8path(Opt.SoName.value()));
62
0
  Loader::Loader Loader(Conf);
63
64
0
  std::vector<Byte> Data;
65
0
  if (auto Res = Loader.loadFile(InputPath)) {
66
0
    Data = std::move(*Res);
67
0
  } else {
68
0
    const auto Err = static_cast<uint32_t>(Res.error());
69
0
    spdlog::error("Load failed. Error code: {}"sv, Err);
70
0
    return EXIT_FAILURE;
71
0
  }
72
73
0
  std::unique_ptr<AST::Module> Module;
74
0
  if (auto Res = Loader.parseModule(Data)) {
75
0
    Module = std::move(*Res);
76
0
  } else {
77
0
    const auto Err = static_cast<uint32_t>(Res.error());
78
0
    spdlog::error("Parse Module failed. Error code: {}"sv, Err);
79
0
    return EXIT_FAILURE;
80
0
  }
81
82
0
  {
83
0
    Validator::Validator ValidatorEngine(Conf);
84
0
    if (auto Res = ValidatorEngine.validate(*Module); !Res) {
85
0
      const auto Err = static_cast<uint32_t>(Res.error());
86
0
      spdlog::error("Validate Module failed. Error code: {}"sv, Err);
87
0
      return EXIT_FAILURE;
88
0
    }
89
0
  }
90
91
0
  {
92
0
    if (Opt.ConfDumpIR.value()) {
93
0
      Conf.getCompilerConfigure().setDumpIR(true);
94
0
    }
95
0
    if (Opt.ConfInterruptible.value()) {
96
0
      Conf.getCompilerConfigure().setInterruptible(true);
97
0
    }
98
0
    if (Opt.ConfEnableAllStatistics.value()) {
99
0
      Conf.getStatisticsConfigure().setInstructionCounting(true);
100
0
      Conf.getStatisticsConfigure().setCostMeasuring(true);
101
0
      Conf.getStatisticsConfigure().setTimeMeasuring(true);
102
0
    } else {
103
0
      if (Opt.ConfEnableInstructionCounting.value()) {
104
0
        Conf.getStatisticsConfigure().setInstructionCounting(true);
105
0
      }
106
0
      if (Opt.ConfEnableGasMeasuring.value()) {
107
0
        Conf.getStatisticsConfigure().setCostMeasuring(true);
108
0
      }
109
0
      if (Opt.ConfEnableTimeMeasuring.value()) {
110
0
        Conf.getStatisticsConfigure().setTimeMeasuring(true);
111
0
      }
112
0
    }
113
0
    if (Opt.ConfGenericBinary.value()) {
114
0
      Conf.getCompilerConfigure().setGenericBinary(true);
115
0
    }
116
0
    if (OutputPath.extension().u8string() == WASMEDGE_LIB_EXTENSION) {
117
0
      Conf.getCompilerConfigure().setOutputFormat(
118
0
          CompilerConfigure::OutputFormat::Native);
119
0
    }
120
0
    LLVM::Compiler Compiler(Conf);
121
0
    if (auto Res = Compiler.checkConfigure(); !Res) {
122
0
      const auto Err = static_cast<uint32_t>(Res.error());
123
0
      spdlog::error("Compiler Configure failed. Error code: {}"sv, Err);
124
0
      return EXIT_FAILURE;
125
0
    }
126
0
    LLVM::CodeGen CodeGen(Conf);
127
0
    if (auto Res = Compiler.compile(*Module); !Res) {
128
0
      const auto Err = static_cast<uint32_t>(Res.error());
129
0
      spdlog::error("Compilation failed. Error code: {}"sv, Err);
130
0
      return EXIT_FAILURE;
131
0
    } else if (auto Res2 = CodeGen.codegen(Data, std::move(*Res), OutputPath);
132
0
               !Res2) {
133
0
      const auto Err = static_cast<uint32_t>(Res2.error());
134
0
      spdlog::error("Code Generation failed. Error code: {}"sv, Err);
135
0
      return EXIT_FAILURE;
136
0
    }
137
0
  }
138
139
0
  return EXIT_SUCCESS;
140
#else
141
  spdlog::error("Compilation is not supported!"sv);
142
143
  return EXIT_FAILURE;
144
#endif
145
0
}
146
147
} // namespace Driver
148
} // namespace WasmEdge