Coverage Report

Created: 2025-07-01 06:18

/src/WasmEdge/lib/common/errinfo.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/errinfo.h"
5
#include "common/errcode.h"
6
#include "common/hexstr.h"
7
8
#include <spdlog/fmt/fmt.h>
9
#include <spdlog/fmt/ranges.h>
10
11
using namespace std::literals;
12
13
fmt::format_context::iterator
14
fmt::formatter<WasmEdge::ErrInfo::InfoFile>::format(
15
    const WasmEdge::ErrInfo::InfoFile &Info,
16
0
    fmt::format_context &Ctx) const noexcept {
17
0
  fmt::memory_buffer Buffer;
18
0
  fmt::format_to(std::back_inserter(Buffer), "    File name: {}"sv,
19
0
                 Info.FileName);
20
0
  return formatter<std::string_view>::format(
21
0
      std::string_view(Buffer.data(), Buffer.size()), Ctx);
22
0
}
23
24
fmt::format_context::iterator
25
fmt::formatter<WasmEdge::ErrInfo::InfoLoading>::format(
26
    const WasmEdge::ErrInfo::InfoLoading &Info,
27
0
    fmt::format_context &Ctx) const noexcept {
28
0
  fmt::memory_buffer Buffer;
29
0
  fmt::format_to(std::back_inserter(Buffer), "    Bytecode offset: 0x{:08x}"sv,
30
0
                 Info.Offset);
31
0
  return formatter<std::string_view>::format(
32
0
      std::string_view(Buffer.data(), Buffer.size()), Ctx);
33
0
}
34
35
fmt::format_context::iterator
36
fmt::formatter<WasmEdge::ErrInfo::InfoAST>::format(
37
    const WasmEdge::ErrInfo::InfoAST &Info,
38
0
    fmt::format_context &Ctx) const noexcept {
39
0
  fmt::memory_buffer Buffer;
40
0
  fmt::format_to(std::back_inserter(Buffer), "    At AST node: {}"sv,
41
0
                 Info.NodeAttr);
42
0
  return formatter<std::string_view>::format(
43
0
      std::string_view(Buffer.data(), Buffer.size()), Ctx);
44
0
}
45
46
fmt::format_context::iterator
47
fmt::formatter<WasmEdge::ErrInfo::InfoInstanceBound>::format(
48
    const WasmEdge::ErrInfo::InfoInstanceBound &Info,
49
0
    fmt::format_context &Ctx) const noexcept {
50
0
  fmt::memory_buffer Buffer;
51
0
  fmt::format_to(std::back_inserter(Buffer),
52
0
                 "    Instance {} has limited number {} , Got: {}"sv,
53
0
                 Info.Instance, Info.Limited, Info.Number);
54
0
  return formatter<std::string_view>::format(
55
0
      std::string_view(Buffer.data(), Buffer.size()), Ctx);
56
0
}
57
58
fmt::format_context::iterator
59
fmt::formatter<WasmEdge::ErrInfo::InfoForbidIndex>::format(
60
    const WasmEdge::ErrInfo::InfoForbidIndex &Info,
61
0
    fmt::format_context &Ctx) const noexcept {
62
0
  fmt::memory_buffer Buffer;
63
0
  auto Iter =
64
0
      fmt::format_to(std::back_inserter(Buffer),
65
0
                     "    When checking {} index: {} , Out of boundary: "sv,
66
0
                     Info.Category, Info.Index);
67
0
  if (Info.Boundary > 0) {
68
0
    fmt::format_to(Iter, "{}"sv, Info.Boundary - 1);
69
0
  } else {
70
0
    fmt::format_to(Iter, "empty"sv);
71
0
  }
72
0
  return formatter<std::string_view>::format(
73
0
      std::string_view(Buffer.data(), Buffer.size()), Ctx);
74
0
}
75
76
fmt::format_context::iterator
77
fmt::formatter<WasmEdge::ErrInfo::InfoExporting>::format(
78
    const WasmEdge::ErrInfo::InfoExporting &Info,
79
0
    fmt::format_context &Ctx) const noexcept {
80
0
  fmt::memory_buffer Buffer;
81
0
  fmt::format_to(std::back_inserter(Buffer),
82
0
                 "    Duplicated exporting name: \"{}\""sv, Info.ExtName);
83
0
  return formatter<std::string_view>::format(
84
0
      std::string_view(Buffer.data(), Buffer.size()), Ctx);
85
0
}
86
87
fmt::format_context::iterator
88
fmt::formatter<WasmEdge::ErrInfo::InfoLimit>::format(
89
    const WasmEdge::ErrInfo::InfoLimit &Info,
90
0
    fmt::format_context &Ctx) const noexcept {
91
0
  fmt::memory_buffer Buffer;
92
0
  auto Iter = fmt::format_to(std::back_inserter(Buffer),
93
0
                             "    In Limit type: {{ min: {}"sv, Info.LimMin);
94
0
  if (Info.LimHasMax) {
95
0
    Iter = fmt::format_to(Iter, " , max: {}"sv, Info.LimMax);
96
0
  }
97
0
  fmt::format_to(Iter, " }}"sv);
98
0
  return formatter<std::string_view>::format(
99
0
      std::string_view(Buffer.data(), Buffer.size()), Ctx);
100
0
}
101
102
fmt::format_context::iterator
103
fmt::formatter<WasmEdge::ErrInfo::InfoRegistering>::format(
104
    const WasmEdge::ErrInfo::InfoRegistering &Info,
105
0
    fmt::format_context &Ctx) const noexcept {
106
0
  fmt::memory_buffer Buffer;
107
0
  fmt::format_to(std::back_inserter(Buffer), "    Module name: \"{}\""sv,
108
0
                 Info.ModName);
109
0
  return formatter<std::string_view>::format(
110
0
      std::string_view(Buffer.data(), Buffer.size()), Ctx);
111
0
}
112
113
fmt::format_context::iterator
114
fmt::formatter<WasmEdge::ErrInfo::InfoLinking>::format(
115
    const WasmEdge::ErrInfo::InfoLinking &Info,
116
0
    fmt::format_context &Ctx) const noexcept {
117
0
  fmt::memory_buffer Buffer;
118
0
  fmt::format_to(std::back_inserter(Buffer),
119
0
                 "    When linking module: \"{}\" , {} name: \"{}\""sv,
120
0
                 Info.ModName, Info.ExtType, Info.ExtName);
121
0
  return formatter<std::string_view>::format(
122
0
      std::string_view(Buffer.data(), Buffer.size()), Ctx);
123
0
}
124
125
fmt::format_context::iterator
126
fmt::formatter<WasmEdge::ErrInfo::InfoExecuting>::format(
127
    const WasmEdge::ErrInfo::InfoExecuting &Info,
128
0
    fmt::format_context &Ctx) const noexcept {
129
0
  fmt::memory_buffer Buffer;
130
0
  auto Iter =
131
0
      fmt::format_to(std::back_inserter(Buffer), "    When executing "sv);
132
0
  if (!Info.ModName.empty()) {
133
0
    Iter = fmt::format_to(Iter, "module name: \"{}\" , "sv, Info.ModName);
134
0
  }
135
0
  fmt::format_to(Iter, "function name: \"{}\""sv, Info.FuncName);
136
0
  return formatter<std::string_view>::format(
137
0
      std::string_view(Buffer.data(), Buffer.size()), Ctx);
138
0
}
139
140
fmt::format_context::iterator
141
fmt::formatter<WasmEdge::ErrInfo::InfoMismatch>::format(
142
    const WasmEdge::ErrInfo::InfoMismatch &Info,
143
0
    fmt::format_context &Ctx) const noexcept {
144
0
  fmt::memory_buffer Buffer;
145
0
  auto Iter = fmt::format_to(std::back_inserter(Buffer),
146
0
                             "    Mismatched {}. "sv, Info.Category);
147
0
  auto FormatLimit = [](auto Out, bool LimHasMax, uint32_t LimMin,
148
0
                        uint32_t LimMax) {
149
0
    Out = fmt::format_to(Out, "Limit{{{}"sv, LimMin);
150
0
    if (LimHasMax) {
151
0
      Out = fmt::format_to(Out, " , {}"sv, LimMax);
152
0
    }
153
0
    Out = fmt::format_to(Out, "}}"sv);
154
0
    return Out;
155
0
  };
156
0
  switch (Info.Category) {
157
0
  case WasmEdge::ErrInfo::MismatchCategory::Alignment:
158
0
    if (Info.GotAlignment < Info.ExpAlignment) {
159
0
      fmt::format_to(Iter, "Expected: need to == {} , Got: {}"sv,
160
0
                     static_cast<uint32_t>(Info.ExpAlignment),
161
0
                     1UL << Info.GotAlignment);
162
0
    } else {
163
0
      fmt::format_to(Iter, "Expected: need to <= {} , Got: {}"sv,
164
0
                     static_cast<uint32_t>(Info.ExpAlignment),
165
0
                     1UL << Info.GotAlignment);
166
0
    }
167
0
    break;
168
0
  case WasmEdge::ErrInfo::MismatchCategory::ValueType:
169
0
    fmt::format_to(Iter, "Expected: {} , Got: {}"sv, Info.ExpValType,
170
0
                   Info.GotValType);
171
0
    break;
172
0
  case WasmEdge::ErrInfo::MismatchCategory::ValueTypes:
173
0
    fmt::format_to(Iter, "Expected: types{{{}}} , Got: types{{{}}}"sv,
174
0
                   fmt::join(Info.ExpParams, " , "sv),
175
0
                   fmt::join(Info.GotParams, " , "sv));
176
0
    break;
177
0
  case WasmEdge::ErrInfo::MismatchCategory::Mutation:
178
0
    fmt::format_to(Iter, "Expected: {} , Got: {}"sv, Info.ExpValMut,
179
0
                   Info.GotValMut);
180
0
    break;
181
0
  case WasmEdge::ErrInfo::MismatchCategory::ExternalType:
182
0
    fmt::format_to(Iter, "Expected: {} , Got: {}", Info.ExpExtType,
183
0
                   Info.GotExtType);
184
0
    break;
185
0
  case WasmEdge::ErrInfo::MismatchCategory::FunctionType:
186
0
    fmt::format_to(Iter,
187
0
                   "Expected: FuncType {{params{{{}}} returns{{{}}}}} , "
188
0
                   "Got: FuncType {{params{{{}}} returns{{{}}}}}"sv,
189
0
                   fmt::join(Info.ExpParams, " , "sv),
190
0
                   fmt::join(Info.ExpReturns, " , "sv),
191
0
                   fmt::join(Info.GotParams, " , "sv),
192
0
                   fmt::join(Info.GotReturns, " , "sv));
193
0
    break;
194
0
  case WasmEdge::ErrInfo::MismatchCategory::Table:
195
0
    Iter = fmt::format_to(Iter, "Expected: TableType {{RefType{{{}}} "sv,
196
0
                          static_cast<WasmEdge::ValType>(Info.ExpValType));
197
0
    Iter = FormatLimit(Iter, Info.ExpLimHasMax, Info.ExpLimMin, Info.ExpLimMax);
198
0
    Iter = fmt::format_to(Iter, "}} , Got: TableType {{RefType{{{}}} "sv,
199
0
                          static_cast<WasmEdge::ValType>(Info.GotValType));
200
0
    Iter = FormatLimit(Iter, Info.GotLimHasMax, Info.GotLimMin, Info.GotLimMax);
201
0
    fmt::format_to(Iter, "}}"sv);
202
0
    break;
203
0
  case WasmEdge::ErrInfo::MismatchCategory::Memory:
204
0
    Iter = fmt::format_to(Iter, "Expected: MemoryType {{"sv);
205
0
    Iter = FormatLimit(Iter, Info.ExpLimHasMax, Info.ExpLimMin, Info.ExpLimMax);
206
0
    Iter = fmt::format_to(Iter, "}} , Got: MemoryType {{"sv);
207
0
    Iter = FormatLimit(Iter, Info.GotLimHasMax, Info.GotLimMin, Info.GotLimMax);
208
0
    fmt::format_to(Iter, "}}"sv);
209
0
    break;
210
0
  case WasmEdge::ErrInfo::MismatchCategory::Global:
211
0
    fmt::format_to(Iter,
212
0
                   "Expected: GlobalType {{Mutation{{{}}} ValType{{{}}}}} , "
213
0
                   "Got: GlobalType {{Mutation{{{}}} ValType{{{}}}}}"sv,
214
0
                   Info.ExpValMut, Info.ExpValType, Info.GotValMut,
215
0
                   Info.GotValType);
216
0
    break;
217
0
  case WasmEdge::ErrInfo::MismatchCategory::Version:
218
0
    fmt::format_to(Iter, "Expected: {} , Got: {}"sv, Info.ExpVersion,
219
0
                   Info.GotVersion);
220
0
    break;
221
0
  default:
222
0
    break;
223
0
  }
224
0
  return formatter<std::string_view>::format(
225
0
      std::string_view(Buffer.data(), Buffer.size()), Ctx);
226
0
}
227
228
fmt::format_context::iterator
229
fmt::formatter<WasmEdge::ErrInfo::InfoInstruction>::format(
230
    const WasmEdge::ErrInfo::InfoInstruction &Info,
231
0
    fmt::format_context &Ctx) const noexcept {
232
0
  uint16_t Payload = static_cast<uint16_t>(Info.Code);
233
0
  fmt::memory_buffer Buffer;
234
0
  auto Iter = fmt::format_to(std::back_inserter(Buffer),
235
0
                             "    In instruction: {} ("sv, Info.Code);
236
0
  if ((Payload >> 8) >= static_cast<uint16_t>(0xFCU)) {
237
0
    Iter = fmt::format_to(Iter, "0x{:02x} "sv, Payload >> 8);
238
0
  }
239
0
  Iter = fmt::format_to(Iter, "0x{:02x}) , Bytecode offset: 0x{:08x}"sv,
240
0
                        Payload & 0xFFU, Info.Offset);
241
0
  if (!Info.Args.empty()) {
242
0
    Iter = fmt::format_to(Iter, " , Args: ["sv);
243
0
    for (uint32_t I = 0; I < Info.Args.size(); ++I) {
244
0
      switch (Info.ArgsTypes[I].getCode()) {
245
0
      case WasmEdge::TypeCode::I32:
246
0
        if (Info.IsSigned) {
247
0
          Iter = fmt::format_to(Iter, "{}"sv, Info.Args[I].get<int32_t>());
248
0
        } else {
249
0
          Iter = fmt::format_to(Iter, "{}"sv, Info.Args[I].get<uint32_t>());
250
0
        }
251
0
        break;
252
0
      case WasmEdge::TypeCode::I64:
253
0
        if (Info.IsSigned) {
254
0
          Iter = fmt::format_to(Iter, "{}"sv, Info.Args[I].get<int64_t>());
255
0
        } else {
256
0
          Iter = fmt::format_to(Iter, "{}"sv, Info.Args[I].get<uint64_t>());
257
0
        }
258
0
        break;
259
0
      case WasmEdge::TypeCode::F32:
260
0
        Iter = fmt::format_to(Iter, "{}"sv, Info.Args[I].get<float>());
261
0
        break;
262
0
      case WasmEdge::TypeCode::F64:
263
0
        Iter = fmt::format_to(Iter, "{}"sv, Info.Args[I].get<double>());
264
0
        break;
265
0
      case WasmEdge::TypeCode::V128: {
266
0
        const auto Value = Info.Args[I].get<WasmEdge::uint64x2_t>();
267
0
        Iter = fmt::format_to(Iter, "0x{:08x}{:08x}"sv, Value[1], Value[0]);
268
0
        break;
269
0
      }
270
0
      case WasmEdge::TypeCode::Ref:
271
0
      case WasmEdge::TypeCode::RefNull:
272
0
        Iter = fmt::format_to(Iter, "{}"sv, Info.ArgsTypes[I]);
273
0
        if (Info.Args[I].get<WasmEdge::RefVariant>().isNull()) {
274
0
          Iter = fmt::format_to(Iter, ":null"sv);
275
0
        } else {
276
0
          Iter =
277
0
              fmt::format_to(Iter, ":0x{:08x}"sv, Info.Args[I].get<uint64_t>());
278
0
        }
279
0
        break;
280
0
      default:
281
0
        break;
282
0
      }
283
0
      if (I < Info.Args.size() - 1) {
284
0
        Iter = fmt::format_to(Iter, " , "sv);
285
0
      }
286
0
    }
287
0
    Iter = fmt::format_to(Iter, "]"sv);
288
0
  }
289
0
  return formatter<std::string_view>::format(
290
0
      std::string_view(Buffer.data(), Buffer.size()), Ctx);
291
0
}
292
293
fmt::format_context::iterator
294
fmt::formatter<WasmEdge::ErrInfo::InfoBoundary>::format(
295
    const WasmEdge::ErrInfo::InfoBoundary &Info,
296
0
    fmt::format_context &Ctx) const noexcept {
297
0
  fmt::memory_buffer Buffer;
298
0
  fmt::format_to(std::back_inserter(Buffer),
299
0
                 "    Accessing offset from: 0x{:08x} to: 0x{:08x} , Out of "
300
0
                 "boundary: 0x{:08x}"sv,
301
0
                 Info.Offset,
302
0
                 Info.Offset + (Info.Size > 0U ? Info.Size - 1U : 0U),
303
0
                 Info.Limit);
304
0
  return formatter<std::string_view>::format(
305
0
      std::string_view(Buffer.data(), Buffer.size()), Ctx);
306
0
}
307
308
fmt::format_context::iterator
309
fmt::formatter<WasmEdge::ErrInfo::InfoProposal>::format(
310
    const WasmEdge::ErrInfo::InfoProposal &Info,
311
0
    fmt::format_context &Ctx) const noexcept {
312
0
  fmt::memory_buffer Buffer;
313
0
  if (auto Iter = WasmEdge::ProposalStr.find(Info.P);
314
0
      Iter != WasmEdge::ProposalStr.end()) {
315
0
    fmt::format_to(
316
0
        std::back_inserter(Buffer),
317
0
        "    This instruction or syntax requires enabling {} proposal"sv,
318
0
        Iter->second);
319
0
  } else {
320
0
    fmt::format_to(std::back_inserter(Buffer),
321
0
                   "    Unknown proposal, Code 0x{:08x}"sv,
322
0
                   static_cast<uint32_t>(Info.P));
323
0
  }
324
0
  return formatter<std::string_view>::format(
325
0
      std::string_view(Buffer.data(), Buffer.size()), Ctx);
326
0
}