Coverage Report

Created: 2026-09-28 06:22

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
39.2k
  constexpr ErrCategory getCategory() const noexcept {
78
39.2k
    return static_cast<ErrCategory>(static_cast<uint8_t>(Inner.Num >> 24));
79
39.2k
  }
80
58.8k
  constexpr uint32_t getCode() const noexcept {
81
58.8k
    return Inner.Num & 0x00FFFFFFU;
82
58.8k
  }
83
19.6k
  constexpr ErrCode::Value getEnum() const noexcept {
84
19.6k
    return getCategory() != ErrCategory::WASM
85
19.6k
               ? ErrCode::Value::UserDefError
86
19.6k
               : static_cast<ErrCode::Value>(getCode());
87
19.6k
  }
88
  /// The phase is the low nibble of the second byte of the code, so the
89
  /// component model ranges 0x1100 ~ 0x14FF report the same phases as their
90
  /// core counterparts 0x0100 ~ 0x04FF.
91
19.5k
  constexpr WasmPhase getErrCodePhase() const noexcept {
92
19.5k
    return getCategory() != ErrCategory::WASM
93
19.5k
               ? WasmPhase::UserDefined
94
19.5k
               : static_cast<WasmPhase>((getCode() >> 8) & 0x0FU);
95
19.5k
  }
96
97
0
  constexpr ErrCode() noexcept : Inner(0) {}
98
874k
  constexpr ErrCode(const ErrCode &E) noexcept : Inner(E.Inner.Num) {}
99
48.1k
  constexpr ErrCode(const ErrCode::Value E) noexcept : Inner(E) {}
100
  constexpr ErrCode(const uint32_t N) noexcept
101
      : Inner((static_cast<uint32_t>(ErrCategory::UserLevelError) << 24) +
102
0
              (N & 0x00FFFFFFU)) {}
103
  constexpr ErrCode(const ErrCategory C, const uint32_t N) noexcept
104
0
      : Inner((static_cast<uint32_t>(C) << 24) + (N & 0x00FFFFFFU)) {}
105
106
  friend constexpr bool operator==(const ErrCode &LHS,
107
7.74k
                                   const ErrCode::Value &RHS) noexcept {
108
7.74k
    return LHS.Inner.Code == RHS;
109
7.74k
  }
110
  friend constexpr bool operator==(const ErrCode::Value &LHS,
111
0
                                   const ErrCode &RHS) noexcept {
112
0
    return RHS.Inner.Code == LHS;
113
0
  }
114
  friend constexpr bool operator==(const ErrCode &LHS,
115
0
                                   const ErrCode &RHS) noexcept {
116
0
    return LHS.Inner.Num == RHS.Inner.Num;
117
0
  }
118
  friend constexpr bool operator!=(const ErrCode &LHS,
119
0
                                   const ErrCode::Value &RHS) noexcept {
120
0
    return !(LHS == RHS);
121
0
  }
122
  friend constexpr bool operator!=(const ErrCode::Value &LHS,
123
0
                                   const ErrCode &RHS) noexcept {
124
0
    return !(LHS == RHS);
125
0
  }
126
  friend constexpr bool operator!=(const ErrCode &LHS,
127
0
                                   const ErrCode &RHS) noexcept {
128
0
    return !(LHS == RHS);
129
0
  }
130
  constexpr ErrCode &operator=(const ErrCode &) noexcept = default;
131
7.34k
  constexpr operator uint32_t() const noexcept { return Inner.Num; }
132
133
private:
134
  union InnerT {
135
874k
    constexpr InnerT(uint32_t Num) : Num(Num) {}
136
48.1k
    constexpr InnerT(ErrCode::Value Code) : Code(Code) {}
137
    uint32_t Num;
138
    ErrCode::Value Code;
139
  } Inner;
140
};
141
142
static inline constexpr const auto ErrCodeStr = []() constexpr {
143
  using namespace std::literals::string_view_literals;
144
  std::pair<ErrCode::Value, std::string_view> Array[] = {
145
#define UseErrCode
146
#define Line(NAME, VALUE, STRING) {ErrCode::Value::NAME, STRING},
147
#include "enum.inc"
148
#undef Line
149
#undef UseErrCode
150
  };
151
  return SpareEnumMap(Array);
152
}();
153
154
} // namespace WasmEdge
155
156
template <>
157
struct fmt::formatter<WasmEdge::WasmPhase> : fmt::formatter<std::string_view> {
158
  template <typename FmtCtx>
159
  auto format(const WasmEdge::WasmPhase &Phase,
160
19.5k
              FmtCtx &Ctx) WASMEDGE_FMT_CONST noexcept -> decltype(Ctx.out()) {
161
19.5k
    return formatter<std::string_view>::format(WasmEdge::WasmPhaseStr[Phase],
162
19.5k
                                               Ctx);
163
19.5k
  }
164
};