Coverage Report

Created: 2026-06-30 06:10

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/WasmEdge/include/common/enum_errcode.hpp
Line
Count
Source
1
// SPDX-License-Identifier: Apache-2.0
2
// SPDX-FileCopyrightText: Copyright The WasmEdge Authors
3
4
//===-- wasmedge/common/enum_errcode.h - Error code C++ enumerations ------===//
5
//
6
// Part of the WasmEdge Project.
7
//
8
//===----------------------------------------------------------------------===//
9
///
10
/// \file
11
/// This file contains the C++ enumerations of WasmEdge error code.
12
///
13
//===----------------------------------------------------------------------===//
14
15
#pragma once
16
17
#include "common/dense_enum_map.h"
18
#include "common/fmt.h"
19
#include "common/spare_enum_map.h"
20
#include "common/spdlog.h"
21
22
#include <cstdint>
23
#include <string_view>
24
25
namespace WasmEdge {
26
27
/// WasmEdge runtime phasing C++ enumeration class.
28
enum class WasmPhase : uint8_t {
29
#define UseWasmPhase
30
#define Line(NAME, VALUE, STRING) NAME = VALUE,
31
#include "enum.inc"
32
#undef Line
33
#undef UseWasmPhase
34
};
35
36
static inline constexpr auto WasmPhaseStr = []() constexpr {
37
  using namespace std::literals::string_view_literals;
38
  std::pair<WasmPhase, std::string_view> Array[] = {
39
#define UseWasmPhase
40
#define Line(NAME, VALUE, STRING) {WasmPhase::NAME, STRING},
41
#include "enum.inc"
42
#undef Line
43
#undef UseWasmPhase
44
  };
45
  return DenseEnumMap(Array);
46
}();
47
48
/// Error category C++ enumeration class.
49
enum class ErrCategory : uint8_t {
50
#define UseErrCategory
51
#define Line(NAME, VALUE) NAME = VALUE,
52
#include "enum.inc"
53
#undef Line
54
#undef UseErrCategory
55
};
56
57
/// ErrCode wraps a compact uint32_t error code used throughout WasmEdge.
58
///
59
/// Note: Parameterized error messages (e.g., embedding function names or
60
/// indices into error strings) are intentionally NOT stored in this class.
61
/// Adding a std::string member would prevent ErrCode from being constexpr and
62
/// introduce implicit heap allocations on every copy in Expected<T, ErrCode>
63
/// return paths, causing significant performance regression (~10% release,
64
/// ~16% debug). See PR #4625 for benchmarks and discussion.
65
/// Contextual debug information should be logged separately via spdlog instead.
66
class ErrCode {
67
public:
68
  /// Error code C++ enumeration class.
69
  enum class Value : uint32_t {
70
#define UseErrCode
71
#define Line(NAME, VALUE, STRING) NAME = VALUE,
72
#include "enum.inc"
73
#undef Line
74
#undef UseErrCode
75
  };
76
77
0
  constexpr ErrCategory getCategory() const noexcept {
78
0
    return static_cast<ErrCategory>(static_cast<uint8_t>(Inner.Num >> 24));
79
0
  }
80
0
  constexpr uint32_t getCode() const noexcept {
81
0
    return Inner.Num & 0x00FFFFFFU;
82
0
  }
83
0
  constexpr ErrCode::Value getEnum() const noexcept {
84
0
    return getCategory() != ErrCategory::WASM
85
0
               ? ErrCode::Value::UserDefError
86
0
               : static_cast<ErrCode::Value>(getCode());
87
0
  }
88
0
  constexpr WasmPhase getErrCodePhase() const noexcept {
89
0
    return getCategory() != ErrCategory::WASM
90
0
               ? WasmPhase::UserDefined
91
0
               : static_cast<WasmPhase>((getCode() >> 8) & 0x0FU);
92
0
  }
93
94
0
  constexpr ErrCode() noexcept : Inner(0) {}
95
214k
  constexpr ErrCode(const ErrCode &E) noexcept : Inner(E.Inner.Num) {}
96
11.5k
  constexpr ErrCode(const ErrCode::Value E) noexcept : Inner(E) {}
97
  constexpr ErrCode(const uint32_t N) noexcept
98
0
      : Inner((static_cast<uint32_t>(ErrCategory::UserLevelError) << 24) +
99
0
              (N & 0x00FFFFFFU)) {}
100
  constexpr ErrCode(const ErrCategory C, const uint32_t N) noexcept
101
0
      : Inner((static_cast<uint32_t>(C) << 24) + (N & 0x00FFFFFFU)) {}
102
103
  friend constexpr bool operator==(const ErrCode &LHS,
104
4.31k
                                   const ErrCode::Value &RHS) noexcept {
105
4.31k
    return LHS.Inner.Code == RHS;
106
4.31k
  }
107
  friend constexpr bool operator==(const ErrCode::Value &LHS,
108
0
                                   const ErrCode &RHS) noexcept {
109
0
    return RHS.Inner.Code == LHS;
110
0
  }
111
  friend constexpr bool operator==(const ErrCode &LHS,
112
0
                                   const ErrCode &RHS) noexcept {
113
0
    return LHS.Inner.Num == RHS.Inner.Num;
114
0
  }
115
  friend constexpr bool operator!=(const ErrCode &LHS,
116
0
                                   const ErrCode::Value &RHS) noexcept {
117
0
    return !(LHS == RHS);
118
0
  }
119
  friend constexpr bool operator!=(const ErrCode::Value &LHS,
120
0
                                   const ErrCode &RHS) noexcept {
121
0
    return !(LHS == RHS);
122
0
  }
123
  friend constexpr bool operator!=(const ErrCode &LHS,
124
0
                                   const ErrCode &RHS) noexcept {
125
0
    return !(LHS == RHS);
126
0
  }
127
  constexpr ErrCode &operator=(const ErrCode &) noexcept = default;
128
7.16k
  constexpr operator uint32_t() const noexcept { return Inner.Num; }
129
130
private:
131
  union InnerT {
132
214k
    constexpr InnerT(uint32_t Num) : Num(Num) {}
133
11.5k
    constexpr InnerT(ErrCode::Value Code) : Code(Code) {}
134
    uint32_t Num;
135
    ErrCode::Value Code;
136
  } Inner;
137
};
138
139
static inline constexpr const auto ErrCodeStr = []() constexpr {
140
  using namespace std::literals::string_view_literals;
141
  std::pair<ErrCode::Value, std::string_view> Array[] = {
142
#define UseErrCode
143
#define Line(NAME, VALUE, STRING) {ErrCode::Value::NAME, STRING},
144
#include "enum.inc"
145
#undef Line
146
#undef UseErrCode
147
  };
148
  return SpareEnumMap(Array);
149
}();
150
151
} // namespace WasmEdge
152
153
template <>
154
struct fmt::formatter<WasmEdge::WasmPhase> : fmt::formatter<std::string_view> {
155
  template <typename FmtCtx>
156
  auto format(const WasmEdge::WasmPhase &Phase,
157
0
              FmtCtx &Ctx) WASMEDGE_FMT_CONST noexcept -> decltype(Ctx.out()) {
158
0
    return formatter<std::string_view>::format(WasmEdge::WasmPhaseStr[Phase],
159
0
                                               Ctx);
160
0
  }
161
};